1 /****************************** builtin.c **************************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
7 Contains C functions for JavaVM Instructions that cannot be translated
8 to machine language directly. Consequently, the generated machine code
9 for these instructions contains function calls instead of machine
10 instructions, using the C calling convention.
12 Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
13 Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
14 Mark Probst EMAIL: cacao@complang.tuwien.ac.at
16 Last Change: 2003/02/12
18 *******************************************************************************/
29 #include "threads/thread.h"
30 #include "threads/locks.h" /* schani */
32 #include "native-math.h"
34 builtin_descriptor builtin_desc[] = {
35 {(functionptr) builtin_instanceof, "instanceof"},
36 {(functionptr) builtin_checkcast, "checkcast"},
37 {(functionptr) asm_builtin_checkcast, "checkcast"},
38 {(functionptr) builtin_arrayinstanceof, "arrayinstanceof"},
39 {(functionptr) builtin_checkarraycast, "checkarraycast"},
40 {(functionptr) asm_builtin_checkarraycast, "checkarraycast"},
41 {(functionptr) asm_builtin_aastore, "aastore"},
42 {(functionptr) builtin_new, "new"},
45 * anewarray has 2 parameters (needs stack manipulation)
47 {(functionptr) asm_builtin_anewarray, "anewarray"},
49 {(functionptr) builtin_anewarray, "anewarray"},
51 {(functionptr) builtin_newarray_array, "newarray_array"},
52 {(functionptr) builtin_newarray_boolean, "newarray_boolean"},
53 {(functionptr) builtin_newarray_char, "newarray_char"},
54 {(functionptr) builtin_newarray_float, "newarray_float"},
55 {(functionptr) builtin_newarray_double, "newarray_double"},
56 {(functionptr) builtin_newarray_byte, "newarray_byte"},
57 {(functionptr) builtin_newarray_short, "newarray_short"},
58 {(functionptr) builtin_newarray_int, "newarray_int"},
59 {(functionptr) builtin_newarray_long, "newarray_long"},
60 {(functionptr) builtin_displaymethodstart, "displaymethodstart"},
61 {(functionptr) builtin_displaymethodstop, "displaymethodstop"},
62 {(functionptr) builtin_monitorenter, "monitorenter"},
63 {(functionptr) asm_builtin_monitorenter, "monitorenter"},
64 {(functionptr) builtin_monitorexit, "monitorexit"},
65 {(functionptr) asm_builtin_monitorexit, "monitorexit"},
66 {(functionptr) builtin_idiv, "idiv"},
67 {(functionptr) asm_builtin_idiv, "idiv"},
68 {(functionptr) builtin_irem, "irem"},
69 {(functionptr) asm_builtin_irem, "irem"},
70 {(functionptr) builtin_ladd, "ladd"},
71 {(functionptr) builtin_lsub, "lsub"},
72 {(functionptr) builtin_lmul, "lmul"},
73 {(functionptr) builtin_ldiv, "ldiv"},
74 {(functionptr) asm_builtin_ldiv, "ldiv"},
75 {(functionptr) builtin_lrem, "lrem"},
76 {(functionptr) asm_builtin_lrem, "lrem"},
77 {(functionptr) builtin_lshl, "lshl"},
78 {(functionptr) builtin_lshr, "lshr"},
79 {(functionptr) builtin_lushr, "lushr"},
80 {(functionptr) builtin_land, "land"},
81 {(functionptr) builtin_lor, "lor"},
82 {(functionptr) builtin_lxor, "lxor"},
83 {(functionptr) builtin_lneg, "lneg"},
84 {(functionptr) builtin_lcmp, "lcmp"},
85 {(functionptr) builtin_fadd, "fadd"},
86 {(functionptr) builtin_fsub, "fsub"},
87 {(functionptr) builtin_fmul, "fmul"},
88 {(functionptr) builtin_fdiv, "fdiv"},
89 {(functionptr) builtin_frem, "frem"},
90 {(functionptr) builtin_fneg, "fneg"},
91 {(functionptr) builtin_fcmpl, "fcmpl"},
92 {(functionptr) builtin_fcmpg, "fcmpg"},
93 {(functionptr) builtin_dadd, "dadd"},
94 {(functionptr) builtin_dsub, "dsub"},
95 {(functionptr) builtin_dmul, "dmul"},
96 {(functionptr) builtin_ddiv, "ddiv"},
97 {(functionptr) builtin_drem, "drem"},
98 {(functionptr) builtin_dneg, "dneg"},
99 {(functionptr) builtin_dcmpl, "dcmpl"},
100 {(functionptr) builtin_dcmpg, "dcmpg"},
101 {(functionptr) builtin_i2l, "i2l"},
102 {(functionptr) builtin_i2f, "i2f"},
103 {(functionptr) builtin_i2d, "i2d"},
104 {(functionptr) builtin_l2i, "l2i"},
105 {(functionptr) builtin_l2f, "l2f"},
106 {(functionptr) builtin_l2d, "l2d"},
107 {(functionptr) builtin_f2i, "f2i"},
108 {(functionptr) builtin_f2l, "f2l"},
109 {(functionptr) builtin_f2d, "f2d"},
110 {(functionptr) builtin_d2i, "d2i"},
111 {(functionptr) builtin_d2l, "d2l"},
112 {(functionptr) builtin_d2f, "d2f"},
113 {(functionptr) NULL, "unknown"}
117 /*****************************************************************************
119 *****************************************************************************/
123 /*************** internal function: builtin_isanysubclass *********************
125 Checks a subclass relation between two classes. Implemented interfaces
126 are interpreted as super classes.
127 Return value: 1 ... sub is subclass of super
130 *****************************************************************************/
132 s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
134 if (super->flags & ACC_INTERFACE)
135 return (sub->vftbl->interfacetablelength > super->index) &&
136 (sub->vftbl->interfacetable[-super->index] != NULL);
148 return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <=
149 (unsigned) (super->vftbl->diffval);
153 /****************** function: builtin_instanceof *****************************
155 Checks if an object is an instance of some given class (or subclass of
156 that class). If class is an interface, checks if the interface is
158 Return value: 1 ... obj is an instance of class or implements the interface
159 0 ... otherwise or if obj == NULL
161 *****************************************************************************/
163 s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
166 log_text ("builtin_instanceof called");
170 return builtin_isanysubclass (obj->vftbl->class, class);
175 /**************** function: builtin_checkcast *******************************
177 The same as builtin_instanceof except that 1 is returned when
180 ****************************************************************************/
182 s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
185 log_text ("builtin_checkcast called");
190 if (builtin_isanysubclass (obj->vftbl->class, class))
194 printf ("#### checkcast failed ");
195 utf_display (obj->vftbl->class->name);
197 utf_display (class->name);
205 /*********** internal function: builtin_descriptorscompatible ******************
207 Checks if two array type descriptors are assignment compatible
208 Return value: 1 ... target = desc is possible
211 ******************************************************************************/
213 static s4 builtin_descriptorscompatible
214 (constant_arraydescriptor *desc, constant_arraydescriptor *target)
216 if (desc==target) return 1;
217 if (desc->arraytype != target->arraytype) return 0;
218 switch (target->arraytype) {
219 case ARRAYTYPE_OBJECT:
220 return builtin_isanysubclass (desc->objectclass, target->objectclass);
221 case ARRAYTYPE_ARRAY:
222 return builtin_descriptorscompatible
223 (desc->elementdescriptor, target->elementdescriptor);
230 /******************** function: builtin_checkarraycast ***********************
232 Checks if an object is really a subtype of the requested array type.
233 The object has to be an array to begin with. For simple arrays (int, short,
234 double, etc.) the types have to match exactly.
235 For arrays of objects, the type of elements in the array has to be a
236 subtype (or the same type) of the requested element type. For arrays of
237 arrays (which in turn can again be arrays of arrays), the types at the
238 lowest level have to satisfy the corresponding sub class relation.
240 Return value: 1 ... cast is possible
243 ATTENTION: a cast with a NULL pointer is always possible.
245 *****************************************************************************/
247 s4 builtin_checkarraycast(java_objectheader *o, constant_arraydescriptor *desc)
249 java_arrayheader *a = (java_arrayheader*) o;
252 if (o->vftbl->class != class_array) {
254 printf ("#### checkarraycast failed 1\n");
259 if (a->arraytype != desc->arraytype) {
261 printf ("#### checkarraycast failed 2\n");
266 switch (a->arraytype) {
267 case ARRAYTYPE_OBJECT: {
268 java_objectarray *oa = (java_objectarray*) o;
269 int result = builtin_isanysubclass (oa->elementtype, desc->objectclass);
273 printf ("#### checkarraycast failed 3\n");
277 case ARRAYTYPE_ARRAY: {
278 java_arrayarray *aa = (java_arrayarray*) o;
279 int result = builtin_descriptorscompatible
280 (aa->elementdescriptor, desc->elementdescriptor);
284 printf ("#### checkarraycast failed 4\n");
294 s4 builtin_arrayinstanceof
295 (java_objectheader *obj, constant_arraydescriptor *desc)
298 return builtin_checkarraycast (obj, desc);
302 /************************** exception functions *******************************
304 ******************************************************************************/
306 java_objectheader *builtin_throw_exception (java_objectheader *local_exceptionptr) {
308 sprintf(logtext, "Builtin exception thrown: ");
309 utf_sprint(logtext + strlen(logtext), local_exceptionptr->vftbl->class->name);
312 exceptionptr = local_exceptionptr;
313 return local_exceptionptr;
317 /******************* function: builtin_canstore *******************************
319 Checks, if an object can be stored in an array.
320 Return value: 1 ... possible
323 ******************************************************************************/
326 s4 builtin_canstore (java_objectarray *a, java_objectheader *o)
330 switch (a->header.arraytype) {
331 case ARRAYTYPE_OBJECT:
332 if ( ! builtin_checkcast (o, a->elementtype) ) {
338 case ARRAYTYPE_ARRAY:
339 if ( ! builtin_checkarraycast
340 (o, ((java_arrayarray*)a)->elementdescriptor) ) {
347 panic ("builtin_canstore called with invalid arraytype");
354 /*****************************************************************************
356 *****************************************************************************/
360 /******************** Function: builtin_new **********************************
362 Creates a new instance of class c on the heap.
363 Return value: pointer to the object or NULL if no memory is
366 *****************************************************************************/
369 #define align_size(size) ((size + ((1 << ALIGNMENT) - 1)) & ~((1 << ALIGNMENT) - 1))
371 java_objectheader *builtin_new (classinfo *c)
373 java_objectheader *o;
377 #ifdef SIZE_FROM_CLASSINFO
378 c->alignedsize = align_size(c->instancesize);
379 o = heap_allocate ( c->alignedsize, true, c->finalizer );
381 o = heap_allocate ( c->instancesize, true, c->finalizer );
385 memset (o, 0, c->instancesize);
387 o -> vftbl = c -> vftbl;
393 /******************** function: builtin_anewarray ****************************
395 Creates an array of pointers to objects on the heap.
397 size ......... number of elements
398 elementtype .. pointer to the classinfo structure for the element type
400 Return value: pointer to the array or NULL if no memory is available
402 *****************************************************************************/
405 void* __builtin_newarray(s4 base_size,
412 #ifdef SIZE_FROM_CLASSINFO
413 s4 alignedsize = align_size(base_size + (size-1) * elementsize);
414 a = heap_allocate ( alignedsize, true, NULL );
416 a = heap_allocate ( sizeof(java_objectarray) + (size-1) * elementsize,
422 #ifdef SIZE_FROM_CLASSINFO
423 memset(a, 0, alignedsize);
425 memset(a, 0, base_size + (size-1) * elementsize);
428 a -> objheader.vftbl = class_array -> vftbl;
430 #ifdef SIZE_FROM_CLASSINFO
431 a -> alignedsize = alignedsize;
433 a -> arraytype = arraytype;
439 java_objectarray *builtin_anewarray (s4 size, classinfo *elementtype)
442 a = (java_objectarray*)__builtin_newarray(sizeof(java_objectarray),
449 a -> elementtype = elementtype;
455 /******************** function: builtin_newarray_array ***********************
457 Creates an array of pointers to arrays on the heap.
459 size ......... number of elements
460 elementdesc .. pointer to the array description structure for the
463 Return value: pointer to the array or NULL if no memory is available
465 *****************************************************************************/
467 java_arrayarray *builtin_newarray_array
468 (s4 size, constant_arraydescriptor *elementdesc)
471 a = (java_arrayarray*)__builtin_newarray(sizeof(java_arrayarray),
478 a -> elementdescriptor = elementdesc;
483 /******************** function: builtin_newarray_boolean ************************
485 Creates an array of bytes on the heap. The array is designated as an array
486 of booleans (important for casts)
488 Return value: pointer to the array or NULL if no memory is available
490 *****************************************************************************/
492 java_booleanarray *builtin_newarray_boolean (s4 size)
494 java_booleanarray *a;
495 a = (java_booleanarray*)__builtin_newarray(sizeof(java_booleanarray),
503 /******************** function: builtin_newarray_char ************************
505 Creates an array of characters on the heap.
507 Return value: pointer to the array or NULL if no memory is available
509 *****************************************************************************/
511 java_chararray *builtin_newarray_char (s4 size)
514 a = (java_chararray*)__builtin_newarray(sizeof(java_chararray),
523 /******************** function: builtin_newarray_float ***********************
525 Creates an array of 32 bit IEEE floats on the heap.
527 Return value: pointer to the array or NULL if no memory is available
529 *****************************************************************************/
531 java_floatarray *builtin_newarray_float (s4 size)
534 a = (java_floatarray*)__builtin_newarray(sizeof(java_floatarray),
543 /******************** function: builtin_newarray_double ***********************
545 Creates an array of 64 bit IEEE floats on the heap.
547 Return value: pointer to the array or NULL if no memory is available
549 *****************************************************************************/
551 java_doublearray *builtin_newarray_double (s4 size)
554 a = (java_doublearray*)__builtin_newarray(sizeof(java_doublearray),
565 /******************** function: builtin_newarray_byte ***********************
567 Creates an array of 8 bit Integers on the heap.
569 Return value: pointer to the array or NULL if no memory is available
571 *****************************************************************************/
573 java_bytearray *builtin_newarray_byte (s4 size)
576 a = (java_bytearray*)__builtin_newarray(sizeof(java_bytearray),
585 /******************** function: builtin_newarray_short ***********************
587 Creates an array of 16 bit Integers on the heap.
589 Return value: pointer to the array or NULL if no memory is available
591 *****************************************************************************/
593 java_shortarray *builtin_newarray_short (s4 size)
596 a = (java_shortarray*)__builtin_newarray(sizeof(java_shortarray),
605 /******************** Function: builtin_newarray_int ***********************
607 Creates an array of 32 bit Integers on the heap.
609 Return value: pointer to the array or NULL if no memory is available
611 *****************************************************************************/
613 java_intarray *builtin_newarray_int (s4 size)
616 a = (java_intarray*)__builtin_newarray(sizeof(java_intarray),
625 /******************** Function: builtin_newarray_long ***********************
627 Creates an array of 64 bit Integers on the heap.
629 Return value: pointer to the array or NULL if no memory is available
631 *****************************************************************************/
633 java_longarray *builtin_newarray_long (s4 size)
636 a = (java_longarray*)__builtin_newarray(sizeof(java_longarray),
646 /***************** function: builtin_multianewarray ***************************
648 Creates a multi-dimensional array on the heap. The dimensions are passed in
649 an array of Integers. The type for the array is passed as a reference to a
650 constant_arraydescriptor structure.
652 Return value: pointer to the array or NULL if no memory is available
654 ******************************************************************************/
656 /* Helper functions */
658 static java_arrayheader *multianewarray_part (java_intarray *dims, int thisdim,
659 constant_arraydescriptor *desc)
664 size = dims -> data[thisdim];
666 if (thisdim == (dims->header.size-1)) {
667 /* last dimension reached */
669 switch (desc -> arraytype) {
670 case ARRAYTYPE_BOOLEAN:
671 return (java_arrayheader*) builtin_newarray_boolean (size);
673 return (java_arrayheader*) builtin_newarray_char (size);
674 case ARRAYTYPE_FLOAT:
675 return (java_arrayheader*) builtin_newarray_float (size);
676 case ARRAYTYPE_DOUBLE:
677 return (java_arrayheader*) builtin_newarray_double (size);
679 return (java_arrayheader*) builtin_newarray_byte (size);
680 case ARRAYTYPE_SHORT:
681 return (java_arrayheader*) builtin_newarray_short (size);
683 return (java_arrayheader*) builtin_newarray_int (size);
685 return (java_arrayheader*) builtin_newarray_long (size);
686 case ARRAYTYPE_OBJECT:
687 return (java_arrayheader*) builtin_anewarray (size, desc->objectclass);
689 case ARRAYTYPE_ARRAY:
690 return (java_arrayheader*) builtin_newarray_array (size, desc->elementdescriptor);
692 default: panic ("Invalid arraytype in multianewarray");
696 /* if the last dimension has not been reached yet */
698 if (desc->arraytype != ARRAYTYPE_ARRAY)
699 panic ("multianewarray with too many dimensions");
701 a = builtin_newarray_array (size, desc->elementdescriptor);
704 for (i=0; i<size; i++) {
705 java_arrayheader *ea =
706 multianewarray_part (dims, thisdim+1, desc->elementdescriptor);
707 if (!ea) return NULL;
712 return (java_arrayheader*) a;
716 java_arrayheader *builtin_multianewarray (java_intarray *dims,
717 constant_arraydescriptor *desc)
719 return multianewarray_part (dims, 0, desc);
723 static java_arrayheader *nmultianewarray_part (int n, long *dims, int thisdim,
724 constant_arraydescriptor *desc)
729 size = (int) dims[thisdim];
731 if (thisdim == (n - 1)) {
732 /* last dimension reached */
734 switch (desc -> arraytype) {
735 case ARRAYTYPE_BOOLEAN:
736 return (java_arrayheader*) builtin_newarray_boolean(size);
738 return (java_arrayheader*) builtin_newarray_char(size);
739 case ARRAYTYPE_FLOAT:
740 return (java_arrayheader*) builtin_newarray_float(size);
741 case ARRAYTYPE_DOUBLE:
742 return (java_arrayheader*) builtin_newarray_double(size);
744 return (java_arrayheader*) builtin_newarray_byte(size);
745 case ARRAYTYPE_SHORT:
746 return (java_arrayheader*) builtin_newarray_short(size);
748 return (java_arrayheader*) builtin_newarray_int(size);
750 return (java_arrayheader*) builtin_newarray_long(size);
751 case ARRAYTYPE_OBJECT:
752 return (java_arrayheader*) builtin_anewarray(size,
754 case ARRAYTYPE_ARRAY:
755 return (java_arrayheader*) builtin_newarray_array(size,
756 desc->elementdescriptor);
758 default: panic ("Invalid arraytype in multianewarray");
762 /* if the last dimension has not been reached yet */
764 if (desc->arraytype != ARRAYTYPE_ARRAY)
765 panic ("multianewarray with too many dimensions");
767 a = builtin_newarray_array(size, desc->elementdescriptor);
770 for (i = 0; i < size; i++) {
771 java_arrayheader *ea =
772 nmultianewarray_part(n, dims, thisdim + 1, desc->elementdescriptor);
773 if (!ea) return NULL;
778 return (java_arrayheader*) a;
782 java_arrayheader *builtin_nmultianewarray (int size,
783 constant_arraydescriptor *desc, long *dims)
785 (void) builtin_newarray_int(size); /* for compatibility with -old */
786 return nmultianewarray_part (size, dims, 0, desc);
792 /************************* function: builtin_aastore *************************
794 Stores a reference to an object into an object array or into an array
795 array. Before any action is performed, the validity of the operation is
798 Return value: 1 ... ok
799 0 ... this object cannot be stored into this array
801 *****************************************************************************/
803 s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o)
805 if (builtin_canstore(a,o)) {
817 /*****************************************************************************
820 Various functions for printing a message at method entry or exit (for
823 *****************************************************************************/
828 java_objectheader *builtin_trace_exception (java_objectheader *exceptionptr,
829 methodinfo *method, int *pos, int noindent) {
833 if (verbose || runverbose) {
834 printf("Exception ");
835 utf_display (exceptionptr->vftbl->class->name);
836 printf(" thrown in ");
838 utf_display (method->class->name);
840 utf_display (method->name);
841 if (method->flags & ACC_SYNCHRONIZED)
845 printf("(%p) at position %p\n", method->entrypoint, pos);
848 printf("call_java_method\n");
855 #ifdef TRACE_ARGS_NUM
856 void builtin_trace_args(long a0, long a1, long a2, long a3, long a4, long a5,
857 #if TRACE_ARGS_NUM > 6
862 sprintf (logtext, " ");
863 sprintf (logtext+methodindent, "called: ");
864 utf_sprint (logtext+strlen(logtext), method->class->name);
865 sprintf (logtext+strlen(logtext), ".");
866 utf_sprint (logtext+strlen(logtext), method->name);
867 utf_sprint (logtext+strlen(logtext), method->descriptor);
868 sprintf (logtext+strlen(logtext), "(");
869 switch (method->paramcount) {
870 #if TRACE_ARGS_NUM > 6
872 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx",
873 a0, a1, a2, a3, a4, a5, a6, a7);
876 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx",
877 a0, a1, a2, a3, a4, a5, a6);
881 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx",
882 a0, a1, a2, a3, a4, a5);
885 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx",
889 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx",
893 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2);
896 sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1);
899 sprintf(logtext+strlen(logtext), "%lx", a0);
902 sprintf (logtext+strlen(logtext), ")");
909 void builtin_displaymethodstart(methodinfo *method)
911 sprintf (logtext, " ");
912 sprintf (logtext+methodindent, "called: ");
913 utf_sprint (logtext+strlen(logtext), method->class->name);
914 sprintf (logtext+strlen(logtext), ".");
915 utf_sprint (logtext+strlen(logtext), method->name);
916 utf_sprint (logtext+strlen(logtext), method->descriptor);
921 void builtin_displaymethodstop(methodinfo *method, long l, double d, float f)
924 sprintf (logtext, " ");
925 sprintf (logtext+methodindent, "finished: ");
926 utf_sprint (logtext+strlen(logtext), method->class->name);
927 sprintf (logtext+strlen(logtext), ".");
928 utf_sprint (logtext+strlen(logtext), method->name);
929 utf_sprint (logtext+strlen(logtext), method->descriptor);
930 switch (method->returntype) {
934 sprintf (logtext+strlen(logtext), "->%ld", l);
937 sprintf (logtext+strlen(logtext), "->%g", f);
940 sprintf (logtext+strlen(logtext), "->%g", d);
946 void builtin_displaymethodexception(methodinfo *method)
948 sprintf (logtext, " ");
949 sprintf (logtext+methodindent, "exception abort: ");
950 utf_sprint (logtext+strlen(logtext), method->class->name);
951 sprintf (logtext+strlen(logtext), ".");
952 utf_sprint (logtext+strlen(logtext), method->name);
953 utf_sprint (logtext+strlen(logtext), method->descriptor);
958 /****************************************************************************
959 SYNCHRONIZATION FUNCTIONS
960 *****************************************************************************/
963 * Lock the mutex of an object.
967 internal_lock_mutex_for_object (java_objectheader *object)
969 mutexHashEntry *entry;
974 hashValue = MUTEX_HASH_VALUE(object);
975 entry = &mutexHashTable[hashValue];
977 if (entry->object != 0)
979 if (entry->mutex.count == 0 && entry->conditionCount == 0)
982 entry->mutex.holder = 0;
983 entry->mutex.count = 0;
984 entry->mutex.muxWaiters = 0;
988 while (entry->next != 0 && entry->object != object)
991 if (entry->object != object)
993 entry->next = firstFreeOverflowEntry;
994 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
999 assert(entry->conditionCount == 0);
1005 entry->mutex.holder = 0;
1006 entry->mutex.count = 0;
1007 entry->mutex.muxWaiters = 0;
1010 if (entry->object == 0)
1011 entry->object = object;
1013 internal_lock_mutex(&entry->mutex);
1019 * Unlocks the mutex of an object.
1023 internal_unlock_mutex_for_object (java_objectheader *object)
1026 mutexHashEntry *entry;
1028 hashValue = MUTEX_HASH_VALUE(object);
1029 entry = &mutexHashTable[hashValue];
1031 if (entry->object == object)
1032 internal_unlock_mutex(&entry->mutex);
1035 while (entry->next != 0 && entry->next->object != object)
1036 entry = entry->next;
1038 assert(entry->next != 0);
1040 internal_unlock_mutex(&entry->next->mutex);
1042 if (entry->next->mutex.count == 0 && entry->conditionCount == 0)
1044 mutexHashEntry *unlinked = entry->next;
1046 entry->next = unlinked->next;
1047 unlinked->next = firstFreeOverflowEntry;
1048 firstFreeOverflowEntry = unlinked;
1055 builtin_monitorenter (java_objectheader *o)
1060 assert(blockInts == 0);
1064 hashValue = MUTEX_HASH_VALUE(o);
1065 if (mutexHashTable[hashValue].object == o
1066 && mutexHashTable[hashValue].mutex.holder == currentThread)
1067 ++mutexHashTable[hashValue].mutex.count;
1069 internal_lock_mutex_for_object(o);
1073 assert(blockInts == 0);
1077 void builtin_monitorexit (java_objectheader *o)
1082 assert(blockInts == 0);
1086 hashValue = MUTEX_HASH_VALUE(o);
1087 if (mutexHashTable[hashValue].object == o)
1089 if (mutexHashTable[hashValue].mutex.count == 1
1090 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1091 internal_unlock_mutex_for_object(o);
1093 --mutexHashTable[hashValue].mutex.count;
1096 internal_unlock_mutex_for_object(o);
1100 assert(blockInts == 0);
1105 /*****************************************************************************
1106 MISCELLANEOUS HELPER FUNCTIONS
1107 *****************************************************************************/
1111 /*********** Functions for integer divisions *****************************
1113 On some systems (eg. DEC ALPHA), integer division is not supported by the
1114 CPU. These helper functions implement the missing functionality.
1116 ******************************************************************************/
1118 s4 builtin_idiv (s4 a, s4 b) { return a/b; }
1119 s4 builtin_irem (s4 a, s4 b) { return a%b; }
1122 /************** Functions for long arithmetics *******************************
1124 On systems where 64 bit Integers are not supported by the CPU, these
1125 functions are needed.
1127 ******************************************************************************/
1130 s8 builtin_ladd (s8 a, s8 b)
1135 return builtin_i2l(0);
1139 s8 builtin_lsub (s8 a, s8 b)
1144 return builtin_i2l(0);
1148 s8 builtin_lmul (s8 a, s8 b)
1153 return builtin_i2l(0);
1157 s8 builtin_ldiv (s8 a, s8 b)
1162 return builtin_i2l(0);
1166 s8 builtin_lrem (s8 a, s8 b)
1171 return builtin_i2l(0);
1175 s8 builtin_lshl (s8 a, s4 b)
1180 return builtin_i2l(0);
1184 s8 builtin_lshr (s8 a, s4 b)
1189 return builtin_i2l(0);
1193 s8 builtin_lushr (s8 a, s4 b)
1196 return ((u8)a)>>(b&63);
1198 return builtin_i2l(0);
1202 s8 builtin_land (s8 a, s8 b)
1207 return builtin_i2l(0);
1211 s8 builtin_lor (s8 a, s8 b)
1216 return builtin_i2l(0);
1220 s8 builtin_lxor (s8 a, s8 b)
1225 return builtin_i2l(0);
1229 s8 builtin_lneg (s8 a)
1234 return builtin_i2l(0);
1238 s4 builtin_lcmp (s8 a, s8 b)
1253 /*********** Functions for floating point operations *************************/
1255 float builtin_fadd (float a, float b)
1257 if (isnanf(a)) return FLT_NAN;
1258 if (isnanf(b)) return FLT_NAN;
1260 if (finitef(b)) return a+b;
1264 if (finitef(b)) return a;
1266 if (copysignf(1.0, a)==copysignf(1.0, b)) return a;
1267 else return FLT_NAN;
1272 float builtin_fsub (float a, float b)
1274 return builtin_fadd (a, builtin_fneg(b));
1277 float builtin_fmul (float a, float b)
1279 if (isnanf(a)) return FLT_NAN;
1280 if (isnanf(b)) return FLT_NAN;
1282 if (finitef(b)) return a*b;
1284 if (a==0) return FLT_NAN;
1285 else return copysignf(b, copysignf(1.0, b)*a);
1290 if (b==0) return FLT_NAN;
1291 else return copysignf(a, copysignf(1.0, a)*b);
1294 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1299 float builtin_fdiv (float a, float b)
1301 if (finitef(a) && finitef(b)) {
1314 float builtin_frem (float a, float b)
1317 /* return (float) builtin_drem((double) a, (double) b); */
1321 if (finite((double) a) && finite((double) b)) {
1323 if (finite((double) f))
1327 if (isnan((double) b))
1329 if (finite((double) a))
1335 if (finitef(a) && finitef(b)) {
1338 return a - floorf(f) * b;
1349 float builtin_fneg (float a)
1351 if (isnanf(a)) return a;
1353 if (finitef(a)) return -a;
1354 else return copysignf(a,-copysignf(1.0, a));
1358 s4 builtin_fcmpl (float a, float b)
1360 if (isnanf(a)) return -1;
1361 if (isnanf(b)) return -1;
1362 if (!finitef(a) || !finitef(b)) {
1363 a = finitef(a) ? 0 : copysignf(1.0, a);
1364 b = finitef(b) ? 0 : copysignf(1.0, b);
1371 s4 builtin_fcmpg (float a, float b)
1373 if (isnanf(a)) return 1;
1374 if (isnanf(b)) return 1;
1375 if (!finitef(a) || !finitef(b)) {
1376 a = finitef(a) ? 0 : copysignf(1.0, a);
1377 b = finitef(b) ? 0 : copysignf(1.0, b);
1386 /************************* Functions for doubles ****************************/
1388 double builtin_dadd (double a, double b)
1390 if (isnan(a)) return DBL_NAN;
1391 if (isnan(b)) return DBL_NAN;
1393 if (finite(b)) return a+b;
1397 if (finite(b)) return a;
1399 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1400 else return DBL_NAN;
1405 double builtin_dsub (double a, double b)
1407 return builtin_dadd (a, builtin_dneg(b));
1410 double builtin_dmul (double a, double b)
1412 if (isnan(a)) return DBL_NAN;
1413 if (isnan(b)) return DBL_NAN;
1415 if (finite(b)) return a*b;
1417 if (a==0) return DBL_NAN;
1418 else return copysign(b, copysign(1.0, b)*a);
1423 if (b==0) return DBL_NAN;
1424 else return copysign(a, copysign(1.0, a)*b);
1427 return copysign(a, copysign(1.0, a)*copysign(1.0, b));
1432 double builtin_ddiv (double a, double b)
1434 if (finite(a) && finite(b)) {
1447 double builtin_drem (double a, double b)
1451 if (finite(a) && finite(b)) {
1454 if ((d < 1.0) && (d > 0.0))
1467 double builtin_dneg (double a)
1469 if (isnan(a)) return a;
1471 if (finite(a)) return -a;
1472 else return copysign(a,-copysign(1.0, a));
1476 s4 builtin_dcmpl (double a, double b)
1478 if (isnan(a)) return -1;
1479 if (isnan(b)) return -1;
1480 if (!finite(a) || !finite(b)) {
1481 a = finite(a) ? 0 : copysign(1.0, a);
1482 b = finite(b) ? 0 : copysign(1.0, b);
1489 s4 builtin_dcmpg (double a, double b)
1491 if (isnan(a)) return 1;
1492 if (isnan(b)) return 1;
1493 if (!finite(a) || !finite(b)) {
1494 a = finite(a) ? 0 : copysign(1.0, a);
1495 b = finite(b) ? 0 : copysign(1.0, b);
1503 /*********************** Conversion operations ****************************/
1505 s8 builtin_i2l (s4 i)
1510 s8 v; v.high = 0; v.low=i; return v;
1514 float builtin_i2f (s4 a)
1516 float f = (float) a;
1520 double builtin_i2d (s4 a)
1522 double d = (double) a;
1527 s4 builtin_l2i (s8 l)
1536 float builtin_l2f (s8 a)
1539 float f = (float) a;
1546 double builtin_l2d (s8 a)
1549 double d = (double) a;
1557 s4 builtin_f2i(float a)
1560 return builtin_d2i((double) a);
1569 if (a < (-2147483648))
1570 return (-2147483648);
1573 f = copysignf((float) 1.0, a);
1576 return (-2147483648); */
1580 s8 builtin_f2l (float a)
1583 return builtin_d2l((double) a);
1588 if (a > 9223372036854775807L)
1589 return 9223372036854775807L;
1590 if (a < (-9223372036854775808L))
1591 return (-9223372036854775808L);
1596 f = copysignf((float) 1.0, a);
1598 return 9223372036854775807L;
1599 return (-9223372036854775808L); */
1603 double builtin_f2d (float a)
1605 if (finitef(a)) return (double) a;
1607 if (isnanf(a)) return DBL_NAN;
1608 else return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1613 s4 builtin_d2i (double a)
1618 if (a >= 2147483647)
1620 if (a <= (-2147483648))
1621 return (-2147483648);
1626 d = copysign(1.0, a);
1629 return (-2147483648);
1633 s8 builtin_d2l (double a)
1638 if (a >= 9223372036854775807L)
1639 return 9223372036854775807L;
1640 if (a <= (-9223372036854775807L-1))
1641 return (-9223372036854775807L-1);
1646 d = copysign(1.0, a);
1648 return 9223372036854775807L;
1649 return (-9223372036854775807L-1);
1653 float builtin_d2f (double a)
1655 if (finite(a)) return (float) a;
1657 if (isnan(a)) return FLT_NAN;
1658 else return copysignf (FLT_POSINF, (float) copysign(1.0, a));
1664 * These are local overrides for various environment variables in Emacs.
1665 * Please do not remove this and leave it at the end of the file, where
1666 * Emacs will automagically detect them.
1667 * ---------------------------------------------------------------------
1670 * indent-tabs-mode: t