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: 1996/12/03
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"},
43 {(functionptr) builtin_anewarray, "anewarray"},
44 {(functionptr) builtin_newarray_array, "newarray_array"},
45 {(functionptr) builtin_newarray_boolean, "newarray_boolean"},
46 {(functionptr) builtin_newarray_char, "newarray_char"},
47 {(functionptr) builtin_newarray_float, "newarray_float"},
48 {(functionptr) builtin_newarray_double, "newarray_double"},
49 {(functionptr) builtin_newarray_byte, "newarray_byte"},
50 {(functionptr) builtin_newarray_short, "newarray_short"},
51 {(functionptr) builtin_newarray_int, "newarray_int"},
52 {(functionptr) builtin_newarray_long, "newarray_long"},
53 {(functionptr) builtin_displaymethodstart, "displaymethodstart"},
54 {(functionptr) builtin_displaymethodstop, "displaymethodstop"},
55 {(functionptr) builtin_monitorenter, "monitorenter"},
56 {(functionptr) asm_builtin_monitorenter, "monitorenter"},
57 {(functionptr) builtin_monitorexit, "monitorexit"},
58 {(functionptr) asm_builtin_monitorexit, "monitorexit"},
59 {(functionptr) builtin_idiv, "idiv"},
60 {(functionptr) asm_builtin_idiv, "idiv"},
61 {(functionptr) builtin_irem, "irem"},
62 {(functionptr) asm_builtin_irem, "irem"},
63 {(functionptr) builtin_ladd, "ladd"},
64 {(functionptr) builtin_lsub, "lsub"},
65 {(functionptr) builtin_lmul, "lmul"},
66 {(functionptr) builtin_ldiv, "ldiv"},
67 {(functionptr) asm_builtin_ldiv, "ldiv"},
68 {(functionptr) builtin_lrem, "lrem"},
69 {(functionptr) asm_builtin_lrem, "lrem"},
70 {(functionptr) builtin_lshl, "lshl"},
71 {(functionptr) builtin_lshr, "lshr"},
72 {(functionptr) builtin_lushr, "lushr"},
73 {(functionptr) builtin_land, "land"},
74 {(functionptr) builtin_lor, "lor"},
75 {(functionptr) builtin_lxor, "lxor"},
76 {(functionptr) builtin_lneg, "lneg"},
77 {(functionptr) builtin_lcmp, "lcmp"},
78 {(functionptr) builtin_fadd, "fadd"},
79 {(functionptr) builtin_fsub, "fsub"},
80 {(functionptr) builtin_fmul, "fmul"},
81 {(functionptr) builtin_fdiv, "fdiv"},
82 {(functionptr) builtin_frem, "frem"},
83 {(functionptr) builtin_fneg, "fneg"},
84 {(functionptr) builtin_fcmpl, "fcmpl"},
85 {(functionptr) builtin_fcmpg, "fcmpg"},
86 {(functionptr) builtin_dadd, "dadd"},
87 {(functionptr) builtin_dsub, "dsub"},
88 {(functionptr) builtin_dmul, "dmul"},
89 {(functionptr) builtin_ddiv, "ddiv"},
90 {(functionptr) builtin_drem, "drem"},
91 {(functionptr) builtin_dneg, "dneg"},
92 {(functionptr) builtin_dcmpl, "dcmpl"},
93 {(functionptr) builtin_dcmpg, "dcmpg"},
94 {(functionptr) builtin_i2l, "i2l"},
95 {(functionptr) builtin_i2f, "i2f"},
96 {(functionptr) builtin_i2d, "i2d"},
97 {(functionptr) builtin_l2i, "l2i"},
98 {(functionptr) builtin_l2f, "l2f"},
99 {(functionptr) builtin_l2d, "l2d"},
100 {(functionptr) builtin_f2i, "f2i"},
101 {(functionptr) builtin_f2l, "f2l"},
102 {(functionptr) builtin_f2d, "f2d"},
103 {(functionptr) builtin_d2i, "d2i"},
104 {(functionptr) builtin_d2l, "d2l"},
105 {(functionptr) builtin_d2f, "d2f"},
106 {(functionptr) NULL, "unknown"}
110 /*****************************************************************************
112 *****************************************************************************/
116 /*************** internal function: builtin_isanysubclass *********************
118 Checks a subclass relation between two classes. Implemented interfaces
119 are interpreted as super classes.
120 Return value: 1 ... sub is subclass of super
123 *****************************************************************************/
125 s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
127 if (super->flags & ACC_INTERFACE)
128 return (sub->vftbl->interfacetablelength > super->index) &&
129 (sub->vftbl->interfacetable[-super->index] != NULL);
141 return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <=
142 (unsigned) (super->vftbl->diffval);
146 /****************** function: builtin_instanceof *****************************
148 Checks if an object is an instance of some given class (or subclass of
149 that class). If class is an interface, checks if the interface is
151 Return value: 1 ... obj is an instance of class or implements the interface
152 0 ... otherwise or if obj == NULL
154 *****************************************************************************/
156 s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
159 log_text ("builtin_instanceof called");
163 return builtin_isanysubclass (obj->vftbl->class, class);
168 /**************** function: builtin_checkcast *******************************
170 The same as builtin_instanceof except that 1 is returned when
173 ****************************************************************************/
175 s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
178 log_text ("builtin_checkcast called");
183 if (builtin_isanysubclass (obj->vftbl->class, class))
187 printf ("#### checkcast failed ");
188 utf_display (obj->vftbl->class->name);
190 utf_display (class->name);
198 /*********** internal function: builtin_descriptorscompatible ******************
200 Checks if two array type descriptors are assignment compatible
201 Return value: 1 ... target = desc is possible
204 ******************************************************************************/
206 static s4 builtin_descriptorscompatible
207 (constant_arraydescriptor *desc, constant_arraydescriptor *target)
209 if (desc==target) return 1;
210 if (desc->arraytype != target->arraytype) return 0;
211 switch (target->arraytype) {
212 case ARRAYTYPE_OBJECT:
213 return builtin_isanysubclass (desc->objectclass, target->objectclass);
214 case ARRAYTYPE_ARRAY:
215 return builtin_descriptorscompatible
216 (desc->elementdescriptor, target->elementdescriptor);
223 /******************** function: builtin_checkarraycast ***********************
225 Checks if an object is really a subtype of the requested array type.
226 The object has to be an array to begin with. For simple arrays (int, short,
227 double, etc.) the types have to match exactly.
228 For arrays of objects, the type of elements in the array has to be a
229 subtype (or the same type) of the requested element type. For arrays of
230 arrays (which in turn can again be arrays of arrays), the types at the
231 lowest level have to satisfy the corresponding sub class relation.
233 Return value: 1 ... cast is possible
236 ATTENTION: a cast with a NULL pointer is always possible.
238 *****************************************************************************/
240 s4 builtin_checkarraycast(java_objectheader *o, constant_arraydescriptor *desc)
242 java_arrayheader *a = (java_arrayheader*) o;
245 if (o->vftbl->class != class_array) {
247 printf ("#### checkarraycast failed 1\n");
252 if (a->arraytype != desc->arraytype) {
254 printf ("#### checkarraycast failed 2\n");
259 switch (a->arraytype) {
260 case ARRAYTYPE_OBJECT: {
261 java_objectarray *oa = (java_objectarray*) o;
262 int result = builtin_isanysubclass (oa->elementtype, desc->objectclass);
266 printf ("#### checkarraycast failed 3\n");
270 case ARRAYTYPE_ARRAY: {
271 java_arrayarray *aa = (java_arrayarray*) o;
272 int result = builtin_descriptorscompatible
273 (aa->elementdescriptor, desc->elementdescriptor);
277 printf ("#### checkarraycast failed 4\n");
287 s4 builtin_arrayinstanceof
288 (java_objectheader *obj, constant_arraydescriptor *desc)
291 return builtin_checkarraycast (obj, desc);
295 /************************** exception functions *******************************
297 ******************************************************************************/
299 java_objectheader *builtin_throw_exception (java_objectheader *local_exceptionptr) {
301 sprintf(logtext, "Builtin exception thrown: ");
302 utf_sprint(logtext + strlen(logtext), local_exceptionptr->vftbl->class->name);
305 exceptionptr = local_exceptionptr;
306 return local_exceptionptr;
310 /******************* function: builtin_canstore *******************************
312 Checks, if an object can be stored in an array.
313 Return value: 1 ... possible
316 ******************************************************************************/
319 s4 builtin_canstore (java_objectarray *a, java_objectheader *o)
323 switch (a->header.arraytype) {
324 case ARRAYTYPE_OBJECT:
325 if ( ! builtin_checkcast (o, a->elementtype) ) {
331 case ARRAYTYPE_ARRAY:
332 if ( ! builtin_checkarraycast
333 (o, ((java_arrayarray*)a)->elementdescriptor) ) {
340 panic ("builtin_canstore called with invalid arraytype");
347 /*****************************************************************************
349 *****************************************************************************/
353 /******************** Funktion: builtin_new **********************************
355 Creates a new instance of class c on the heap.
356 Return value: pointer to the object or NULL if no memory is
359 *****************************************************************************/
362 #define align_size(size) ((size + ((1 << ALIGNMENT) - 1)) & ~((1 << ALIGNMENT) - 1))
364 java_objectheader *builtin_new (classinfo *c)
366 java_objectheader *o;
370 #ifdef SIZE_FROM_CLASSINFO
371 c->alignedsize = align_size(c->instancesize);
372 o = heap_allocate ( c->alignedsize, true, c->finalizer );
374 o = heap_allocate ( c->instancesize, true, c->finalizer );
378 memset (o, 0, c->instancesize);
380 o -> vftbl = c -> vftbl;
386 /******************** function: builtin_anewarray ****************************
388 Creates an array of pointers to objects on the heap.
390 size ......... number of elements
391 elementtype .. pointer to the classinfo structure for the element type
393 Return value: pointer to the array or NULL if no memory is available
395 *****************************************************************************/
398 void* __builtin_newarray(s4 base_size,
405 #ifdef SIZE_FROM_CLASSINFO
406 s4 alignedsize = align_size(base_size + (size-1) * elementsize);
407 a = heap_allocate ( alignedsize, true, NULL );
409 a = heap_allocate ( sizeof(java_objectarray) + (size-1) * elementsize,
415 #ifdef SIZE_FROM_CLASSINFO
416 memset(a, 0, alignedsize);
418 memset(a, 0, base_size + (size-1) * elementsize);
421 a -> objheader.vftbl = class_array -> vftbl;
423 #ifdef SIZE_FROM_CLASSINFO
424 a -> alignedsize = alignedsize;
426 a -> arraytype = arraytype;
432 java_objectarray *builtin_anewarray (s4 size, classinfo *elementtype)
435 a = (java_objectarray*)__builtin_newarray(sizeof(java_objectarray),
442 a -> elementtype = elementtype;
448 /******************** function: builtin_newarray_array ***********************
450 Creates an array of pointers to arrays on the heap.
452 size ......... number of elements
453 elementdesc .. pointer to the array description structure for the
456 Return value: pointer to the array or NULL if no memory is available
458 *****************************************************************************/
460 java_arrayarray *builtin_newarray_array
461 (s4 size, constant_arraydescriptor *elementdesc)
464 a = (java_arrayarray*)__builtin_newarray(sizeof(java_arrayarray),
471 a -> elementdescriptor = elementdesc;
476 /******************** function: builtin_newarray_boolean ************************
478 Creates an array of bytes on the heap. The array is designated as an array
479 of booleans (important for casts)
481 Return value: pointer to the array or NULL if no memory is available
483 *****************************************************************************/
485 java_booleanarray *builtin_newarray_boolean (s4 size)
487 java_booleanarray *a;
488 a = (java_booleanarray*)__builtin_newarray(sizeof(java_booleanarray),
496 /******************** function: builtin_newarray_char ************************
498 Creates an array of characters on the heap.
500 Return value: pointer to the array or NULL if no memory is available
502 *****************************************************************************/
504 java_chararray *builtin_newarray_char (s4 size)
507 a = (java_chararray*)__builtin_newarray(sizeof(java_chararray),
516 /******************** function: builtin_newarray_float ***********************
518 Creates an array of 32 bit IEEE floats on the heap.
520 Return value: pointer to the array or NULL if no memory is available
522 *****************************************************************************/
524 java_floatarray *builtin_newarray_float (s4 size)
527 a = (java_floatarray*)__builtin_newarray(sizeof(java_floatarray),
536 /******************** function: builtin_newarray_double ***********************
538 Creates an array of 64 bit IEEE floats on the heap.
540 Return value: pointer to the array or NULL if no memory is available
542 *****************************************************************************/
544 java_doublearray *builtin_newarray_double (s4 size)
547 a = (java_doublearray*)__builtin_newarray(sizeof(java_doublearray),
558 /******************** function: builtin_newarray_byte ***********************
560 Creates an array of 8 bit Integers on the heap.
562 Return value: pointer to the array or NULL if no memory is available
564 *****************************************************************************/
566 java_bytearray *builtin_newarray_byte (s4 size)
569 a = (java_bytearray*)__builtin_newarray(sizeof(java_bytearray),
578 /******************** function: builtin_newarray_short ***********************
580 Creates an array of 16 bit Integers on the heap.
582 Return value: pointer to the array or NULL if no memory is available
584 *****************************************************************************/
586 java_shortarray *builtin_newarray_short (s4 size)
589 a = (java_shortarray*)__builtin_newarray(sizeof(java_shortarray),
598 /******************** Funktion: builtin_newarray_int ***********************
600 Creates an array of 32 bit Integers on the heap.
602 Return value: pointer to the array or NULL if no memory is available
604 *****************************************************************************/
606 java_intarray *builtin_newarray_int (s4 size)
609 a = (java_intarray*)__builtin_newarray(sizeof(java_intarray),
618 /******************** Funktion: builtin_newarray_long ***********************
620 Creates an array of 64 bit Integers on the heap.
622 Return value: pointer to the array or NULL if no memory is available
624 *****************************************************************************/
626 java_longarray *builtin_newarray_long (s4 size)
629 a = (java_longarray*)__builtin_newarray(sizeof(java_longarray),
639 /***************** function: builtin_multianewarray ***************************
641 Creates a multi-dimensional array on the heap. The dimensions are passed in
642 an array of Integers. The type for the array is passed as a reference to a
643 constant_arraydescriptor structure.
645 Return value: pointer to the array or NULL if no memory is available
647 ******************************************************************************/
649 /* Helper functions */
651 static java_arrayheader *multianewarray_part (java_intarray *dims, int thisdim,
652 constant_arraydescriptor *desc)
657 size = dims -> data[thisdim];
659 if (thisdim == (dims->header.size-1)) {
660 /* last dimension reached */
662 switch (desc -> arraytype) {
663 case ARRAYTYPE_BOOLEAN:
664 return (java_arrayheader*) builtin_newarray_boolean (size);
666 return (java_arrayheader*) builtin_newarray_char (size);
667 case ARRAYTYPE_FLOAT:
668 return (java_arrayheader*) builtin_newarray_float (size);
669 case ARRAYTYPE_DOUBLE:
670 return (java_arrayheader*) builtin_newarray_double (size);
672 return (java_arrayheader*) builtin_newarray_byte (size);
673 case ARRAYTYPE_SHORT:
674 return (java_arrayheader*) builtin_newarray_short (size);
676 return (java_arrayheader*) builtin_newarray_int (size);
678 return (java_arrayheader*) builtin_newarray_long (size);
679 case ARRAYTYPE_OBJECT:
680 return (java_arrayheader*) builtin_anewarray (size, desc->objectclass);
682 case ARRAYTYPE_ARRAY:
683 return (java_arrayheader*) builtin_newarray_array (size, desc->elementdescriptor);
685 default: panic ("Invalid arraytype in multianewarray");
689 /* if the last dimension has not been reached yet */
691 if (desc->arraytype != ARRAYTYPE_ARRAY)
692 panic ("multianewarray with too many dimensions");
694 a = builtin_newarray_array (size, desc->elementdescriptor);
697 for (i=0; i<size; i++) {
698 java_arrayheader *ea =
699 multianewarray_part (dims, thisdim+1, desc->elementdescriptor);
700 if (!ea) return NULL;
705 return (java_arrayheader*) a;
709 java_arrayheader *builtin_multianewarray (java_intarray *dims,
710 constant_arraydescriptor *desc)
712 return multianewarray_part (dims, 0, desc);
716 static java_arrayheader *nmultianewarray_part (int n, long *dims, int thisdim,
717 constant_arraydescriptor *desc)
722 size = (int) dims[thisdim];
724 if (thisdim == (n - 1)) {
725 /* last dimension reached */
727 switch (desc -> arraytype) {
728 case ARRAYTYPE_BOOLEAN:
729 return (java_arrayheader*) builtin_newarray_boolean(size);
731 return (java_arrayheader*) builtin_newarray_char(size);
732 case ARRAYTYPE_FLOAT:
733 return (java_arrayheader*) builtin_newarray_float(size);
734 case ARRAYTYPE_DOUBLE:
735 return (java_arrayheader*) builtin_newarray_double(size);
737 return (java_arrayheader*) builtin_newarray_byte(size);
738 case ARRAYTYPE_SHORT:
739 return (java_arrayheader*) builtin_newarray_short(size);
741 return (java_arrayheader*) builtin_newarray_int(size);
743 return (java_arrayheader*) builtin_newarray_long(size);
744 case ARRAYTYPE_OBJECT:
745 return (java_arrayheader*) builtin_anewarray(size,
747 case ARRAYTYPE_ARRAY:
748 return (java_arrayheader*) builtin_newarray_array(size,
749 desc->elementdescriptor);
751 default: panic ("Invalid arraytype in multianewarray");
755 /* if the last dimension has not been reached yet */
757 if (desc->arraytype != ARRAYTYPE_ARRAY)
758 panic ("multianewarray with too many dimensions");
760 a = builtin_newarray_array(size, desc->elementdescriptor);
763 for (i = 0; i < size; i++) {
764 java_arrayheader *ea =
765 nmultianewarray_part(n, dims, thisdim + 1, desc->elementdescriptor);
766 if (!ea) return NULL;
771 return (java_arrayheader*) a;
775 java_arrayheader *builtin_nmultianewarray (int size,
776 constant_arraydescriptor *desc, long *dims)
778 (void) builtin_newarray_int(size); /* for compatibility with -old */
779 return nmultianewarray_part (size, dims, 0, desc);
785 /************************* function: builtin_aastore *************************
787 Stores a reference to an object into an object array or into an array
788 array. Before any action is performed, the validity of the operation is
791 Return value: 1 ... ok
792 0 ... this object cannot be stored into this array
794 *****************************************************************************/
796 s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o)
798 if (builtin_canstore(a,o)) {
810 /*****************************************************************************
813 Various functions for printing a message at method entry or exit (for
816 *****************************************************************************/
821 java_objectheader *builtin_trace_exception (java_objectheader *exceptionptr,
822 methodinfo *method, int *pos, int noindent) {
826 if (verbose || runverbose) {
827 printf("Exception ");
828 utf_display (exceptionptr->vftbl->class->name);
829 printf(" thrown in ");
831 utf_display (method->class->name);
833 utf_display (method->name);
834 if (method->flags & ACC_SYNCHRONIZED)
838 printf("(%p) at position %p\n", method->entrypoint, pos);
841 printf("call_java_method\n");
848 void builtin_trace_args(long a0, long a1, long a2, long a3, long a4, long a5,
851 sprintf (logtext, " ");
852 sprintf (logtext+methodindent, "called: ");
853 utf_sprint (logtext+strlen(logtext), method->class->name);
854 sprintf (logtext+strlen(logtext), ".");
855 utf_sprint (logtext+strlen(logtext), method->name);
856 utf_sprint (logtext+strlen(logtext), method->descriptor);
857 sprintf (logtext+strlen(logtext), "(");
858 switch (method->paramcount) {
860 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx",
861 a0, a1, a2, a3, a4, a5);
864 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx",
868 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx",
872 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2);
875 sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1);
878 sprintf(logtext+strlen(logtext), "%lx", a0);
881 sprintf (logtext+strlen(logtext), ")");
887 void builtin_displaymethodstart(methodinfo *method)
889 sprintf (logtext, " ");
890 sprintf (logtext+methodindent, "called: ");
891 utf_sprint (logtext+strlen(logtext), method->class->name);
892 sprintf (logtext+strlen(logtext), ".");
893 utf_sprint (logtext+strlen(logtext), method->name);
894 utf_sprint (logtext+strlen(logtext), method->descriptor);
899 void builtin_displaymethodstop(methodinfo *method, long l, double d)
902 sprintf (logtext, " ");
903 sprintf (logtext+methodindent, "finished: ");
904 utf_sprint (logtext+strlen(logtext), method->class->name);
905 sprintf (logtext+strlen(logtext), ".");
906 utf_sprint (logtext+strlen(logtext), method->name);
907 utf_sprint (logtext+strlen(logtext), method->descriptor);
908 switch (method->returntype) {
912 sprintf (logtext+strlen(logtext), "->%ld", l);
916 sprintf (logtext+strlen(logtext), "->%g", d);
922 void builtin_displaymethodexception(methodinfo *method)
924 sprintf (logtext, " ");
925 sprintf (logtext+methodindent, "exception abort: ");
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);
934 /****************************************************************************
935 SYNCHRONIZATION FUNCTIONS
936 *****************************************************************************/
939 * Lock the mutex of an object.
943 internal_lock_mutex_for_object (java_objectheader *object)
945 mutexHashEntry *entry;
950 hashValue = MUTEX_HASH_VALUE(object);
951 entry = &mutexHashTable[hashValue];
953 if (entry->object != 0)
955 if (entry->mutex.count == 0 && entry->conditionCount == 0)
958 entry->mutex.holder = 0;
959 entry->mutex.count = 0;
960 entry->mutex.muxWaiters = 0;
964 while (entry->next != 0 && entry->object != object)
967 if (entry->object != object)
969 entry->next = firstFreeOverflowEntry;
970 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
975 assert(entry->conditionCount == 0);
981 entry->mutex.holder = 0;
982 entry->mutex.count = 0;
983 entry->mutex.muxWaiters = 0;
986 if (entry->object == 0)
987 entry->object = object;
989 internal_lock_mutex(&entry->mutex);
995 * Unlocks the mutex of an object.
999 internal_unlock_mutex_for_object (java_objectheader *object)
1002 mutexHashEntry *entry;
1004 hashValue = MUTEX_HASH_VALUE(object);
1005 entry = &mutexHashTable[hashValue];
1007 if (entry->object == object)
1008 internal_unlock_mutex(&entry->mutex);
1011 while (entry->next != 0 && entry->next->object != object)
1012 entry = entry->next;
1014 assert(entry->next != 0);
1016 internal_unlock_mutex(&entry->next->mutex);
1018 if (entry->next->mutex.count == 0 && entry->conditionCount == 0)
1020 mutexHashEntry *unlinked = entry->next;
1022 entry->next = unlinked->next;
1023 unlinked->next = firstFreeOverflowEntry;
1024 firstFreeOverflowEntry = unlinked;
1031 builtin_monitorenter (java_objectheader *o)
1036 assert(blockInts == 0);
1040 hashValue = MUTEX_HASH_VALUE(o);
1041 if (mutexHashTable[hashValue].object == o
1042 && mutexHashTable[hashValue].mutex.holder == currentThread)
1043 ++mutexHashTable[hashValue].mutex.count;
1045 internal_lock_mutex_for_object(o);
1049 assert(blockInts == 0);
1053 void builtin_monitorexit (java_objectheader *o)
1058 assert(blockInts == 0);
1062 hashValue = MUTEX_HASH_VALUE(o);
1063 if (mutexHashTable[hashValue].object == o)
1065 if (mutexHashTable[hashValue].mutex.count == 1
1066 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1067 internal_unlock_mutex_for_object(o);
1069 --mutexHashTable[hashValue].mutex.count;
1072 internal_unlock_mutex_for_object(o);
1076 assert(blockInts == 0);
1081 /*****************************************************************************
1082 MISCELLANEOUS HELPER FUNCTIONS
1083 *****************************************************************************/
1087 /*********** Functions for integer divisions *****************************
1089 On some systems (eg. DEC ALPHA), integer division is not supported by the
1090 CPU. These helper functions implement the missing functionality.
1092 ******************************************************************************/
1094 s4 builtin_idiv (s4 a, s4 b) { return a/b; }
1095 s4 builtin_irem (s4 a, s4 b) { return a%b; }
1098 /************** Functions for long arithmetics *******************************
1100 On systems where 64 bit Integers are not supported by the CPU, these
1101 functions are needed.
1103 ******************************************************************************/
1106 s8 builtin_ladd (s8 a, s8 b)
1111 return builtin_i2l(0);
1115 s8 builtin_lsub (s8 a, s8 b)
1120 return builtin_i2l(0);
1124 s8 builtin_lmul (s8 a, s8 b)
1129 return builtin_i2l(0);
1133 s8 builtin_ldiv (s8 a, s8 b)
1138 return builtin_i2l(0);
1142 s8 builtin_lrem (s8 a, s8 b)
1147 return builtin_i2l(0);
1151 s8 builtin_lshl (s8 a, s4 b)
1156 return builtin_i2l(0);
1160 s8 builtin_lshr (s8 a, s4 b)
1165 return builtin_i2l(0);
1169 s8 builtin_lushr (s8 a, s4 b)
1172 return ((u8)a)>>(b&63);
1174 return builtin_i2l(0);
1178 s8 builtin_land (s8 a, s8 b)
1183 return builtin_i2l(0);
1187 s8 builtin_lor (s8 a, s8 b)
1192 return builtin_i2l(0);
1196 s8 builtin_lxor (s8 a, s8 b)
1201 return builtin_i2l(0);
1205 s8 builtin_lneg (s8 a)
1210 return builtin_i2l(0);
1214 s4 builtin_lcmp (s8 a, s8 b)
1229 /*********** Functions for floating point operations *************************/
1231 float builtin_fadd (float a, float b)
1233 if (isnanf(a)) return FLT_NAN;
1234 if (isnanf(b)) return FLT_NAN;
1236 if (finitef(b)) return a+b;
1240 if (finitef(b)) return a;
1242 if (copysignf(1.0, a)==copysignf(1.0, b)) return a;
1243 else return FLT_NAN;
1248 float builtin_fsub (float a, float b)
1250 return builtin_fadd (a, builtin_fneg(b));
1253 float builtin_fmul (float a, float b)
1255 if (isnanf(a)) return FLT_NAN;
1256 if (isnanf(b)) return FLT_NAN;
1258 if (finitef(b)) return a*b;
1260 if (a==0) return FLT_NAN;
1261 else return copysignf(b, copysignf(1.0, b)*a);
1266 if (b==0) return FLT_NAN;
1267 else return copysignf(a, copysignf(1.0, a)*b);
1270 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1275 float builtin_fdiv (float a, float b)
1277 if (finitef(a) && finitef(b)) {
1290 float builtin_frem (float a, float b)
1293 /* return (float) builtin_drem((double) a, (double) b); */
1297 if (finite((double) a) && finite((double) b)) {
1299 if (finite((double) f))
1303 if (isnan((double) b))
1305 if (finite((double) a))
1311 if (finitef(a) && finitef(b)) {
1314 return a - floorf(f) * b;
1325 float builtin_fneg (float a)
1327 if (isnanf(a)) return a;
1329 if (finitef(a)) return -a;
1330 else return copysignf(a,-copysignf(1.0, a));
1334 s4 builtin_fcmpl (float a, float b)
1336 if (isnanf(a)) return -1;
1337 if (isnanf(b)) return -1;
1338 if (!finitef(a) || !finitef(b)) {
1339 a = finitef(a) ? 0 : copysignf(1.0, a);
1340 b = finitef(b) ? 0 : copysignf(1.0, b);
1347 s4 builtin_fcmpg (float a, float b)
1349 if (isnanf(a)) return 1;
1350 if (isnanf(b)) return 1;
1351 if (!finitef(a) || !finitef(b)) {
1352 a = finitef(a) ? 0 : copysignf(1.0, a);
1353 b = finitef(b) ? 0 : copysignf(1.0, b);
1362 /************************* Functions for doubles ****************************/
1364 double builtin_dadd (double a, double b)
1366 if (isnan(a)) return DBL_NAN;
1367 if (isnan(b)) return DBL_NAN;
1369 if (finite(b)) return a+b;
1373 if (finite(b)) return a;
1375 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1376 else return DBL_NAN;
1381 double builtin_dsub (double a, double b)
1383 return builtin_dadd (a, builtin_dneg(b));
1386 double builtin_dmul (double a, double b)
1388 if (isnan(a)) return DBL_NAN;
1389 if (isnan(b)) return DBL_NAN;
1391 if (finite(b)) return a*b;
1393 if (a==0) return DBL_NAN;
1394 else return copysign(b, copysign(1.0, b)*a);
1399 if (b==0) return DBL_NAN;
1400 else return copysign(a, copysign(1.0, a)*b);
1403 return copysign(a, copysign(1.0, a)*copysign(1.0, b));
1408 double builtin_ddiv (double a, double b)
1410 if (finite(a) && finite(b)) {
1423 double builtin_drem (double a, double b)
1427 if (finite(a) && finite(b)) {
1430 if ((d < 1.0) && (d > 0.0))
1443 double builtin_dneg (double a)
1445 if (isnan(a)) return a;
1447 if (finite(a)) return -a;
1448 else return copysign(a,-copysign(1.0, a));
1452 s4 builtin_dcmpl (double a, double b)
1454 if (isnan(a)) return -1;
1455 if (isnan(b)) return -1;
1456 if (!finite(a) || !finite(b)) {
1457 a = finite(a) ? 0 : copysign(1.0, a);
1458 b = finite(b) ? 0 : copysign(1.0, b);
1465 s4 builtin_dcmpg (double a, double b)
1467 if (isnan(a)) return 1;
1468 if (isnan(b)) return 1;
1469 if (!finite(a) || !finite(b)) {
1470 a = finite(a) ? 0 : copysign(1.0, a);
1471 b = finite(b) ? 0 : copysign(1.0, b);
1479 /*********************** Conversion operations ****************************/
1481 s8 builtin_i2l (s4 i)
1486 s8 v; v.high = 0; v.low=i; return v;
1490 float builtin_i2f (s4 a)
1492 float f = (float) a;
1496 double builtin_i2d (s4 a)
1498 double d = (double) a;
1503 s4 builtin_l2i (s8 l)
1512 float builtin_l2f (s8 a)
1515 float f = (float) a;
1522 double builtin_l2d (s8 a)
1525 double d = (double) a;
1533 s4 builtin_f2i(float a)
1536 return builtin_d2i((double) a);
1545 if (a < (-2147483648))
1546 return (-2147483648);
1549 f = copysignf((float) 1.0, a);
1552 return (-2147483648); */
1556 s8 builtin_f2l (float a)
1559 return builtin_d2l((double) a);
1564 if (a > 9223372036854775807L)
1565 return 9223372036854775807L;
1566 if (a < (-9223372036854775808L))
1567 return (-9223372036854775808L);
1572 f = copysignf((float) 1.0, a);
1574 return 9223372036854775807L;
1575 return (-9223372036854775808L); */
1579 double builtin_f2d (float a)
1581 if (finitef(a)) return (double) a;
1583 if (isnanf(a)) return DBL_NAN;
1584 else return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1589 s4 builtin_d2i (double a)
1594 if (a >= 2147483647)
1596 if (a <= (-2147483648))
1597 return (-2147483648);
1602 d = copysign(1.0, a);
1605 return (-2147483648);
1609 s8 builtin_d2l (double a)
1614 if (a >= 9223372036854775807L)
1615 return 9223372036854775807L;
1616 if (a <= (-9223372036854775807L-1))
1617 return (-9223372036854775807L-1);
1622 d = copysign(1.0, a);
1624 return 9223372036854775807L;
1625 return (-9223372036854775807L-1);
1629 float builtin_d2f (double a)
1631 if (finite(a)) return (float) a;
1633 if (isnan(a)) return FLT_NAN;
1634 else return copysignf (FLT_POSINF, (float) copysign(1.0, a));
1640 * These are local overrides for various environment variables in Emacs.
1641 * Please do not remove this and leave it at the end of the file, where
1642 * Emacs will automagically detect them.
1643 * ---------------------------------------------------------------------
1646 * indent-tabs-mode: t