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 /******************** Function: 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 /******************** Function: 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 /******************** Function: 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 #ifdef TRACE_ARGS_NUM
849 void builtin_trace_args(long a0, long a1, long a2, long a3, long a4, long a5,
850 #if TRACE_ARGS_NUM > 6
855 sprintf (logtext, " ");
856 sprintf (logtext+methodindent, "called: ");
857 utf_sprint (logtext+strlen(logtext), method->class->name);
858 sprintf (logtext+strlen(logtext), ".");
859 utf_sprint (logtext+strlen(logtext), method->name);
860 utf_sprint (logtext+strlen(logtext), method->descriptor);
861 sprintf (logtext+strlen(logtext), "(");
862 switch (method->paramcount) {
863 #if TRACE_ARGS_NUM > 6
865 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx",
866 a0, a1, a2, a3, a4, a5, a6, a7);
869 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx",
870 a0, a1, a2, a3, a4, a5, a6);
874 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx",
875 a0, a1, a2, a3, a4, a5);
878 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx",
882 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx",
886 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2);
889 sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1);
892 sprintf(logtext+strlen(logtext), "%lx", a0);
895 sprintf (logtext+strlen(logtext), ")");
902 void builtin_displaymethodstart(methodinfo *method)
904 sprintf (logtext, " ");
905 sprintf (logtext+methodindent, "called: ");
906 utf_sprint (logtext+strlen(logtext), method->class->name);
907 sprintf (logtext+strlen(logtext), ".");
908 utf_sprint (logtext+strlen(logtext), method->name);
909 utf_sprint (logtext+strlen(logtext), method->descriptor);
914 void builtin_displaymethodstop(methodinfo *method, long l, double d, float f)
917 sprintf (logtext, " ");
918 sprintf (logtext+methodindent, "finished: ");
919 utf_sprint (logtext+strlen(logtext), method->class->name);
920 sprintf (logtext+strlen(logtext), ".");
921 utf_sprint (logtext+strlen(logtext), method->name);
922 utf_sprint (logtext+strlen(logtext), method->descriptor);
923 switch (method->returntype) {
927 sprintf (logtext+strlen(logtext), "->%ld", l);
930 sprintf (logtext+strlen(logtext), "->%g", f);
933 sprintf (logtext+strlen(logtext), "->%g", d);
939 void builtin_displaymethodexception(methodinfo *method)
941 sprintf (logtext, " ");
942 sprintf (logtext+methodindent, "exception abort: ");
943 utf_sprint (logtext+strlen(logtext), method->class->name);
944 sprintf (logtext+strlen(logtext), ".");
945 utf_sprint (logtext+strlen(logtext), method->name);
946 utf_sprint (logtext+strlen(logtext), method->descriptor);
951 /****************************************************************************
952 SYNCHRONIZATION FUNCTIONS
953 *****************************************************************************/
956 * Lock the mutex of an object.
960 internal_lock_mutex_for_object (java_objectheader *object)
962 mutexHashEntry *entry;
967 hashValue = MUTEX_HASH_VALUE(object);
968 entry = &mutexHashTable[hashValue];
970 if (entry->object != 0)
972 if (entry->mutex.count == 0 && entry->conditionCount == 0)
975 entry->mutex.holder = 0;
976 entry->mutex.count = 0;
977 entry->mutex.muxWaiters = 0;
981 while (entry->next != 0 && entry->object != object)
984 if (entry->object != object)
986 entry->next = firstFreeOverflowEntry;
987 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
992 assert(entry->conditionCount == 0);
998 entry->mutex.holder = 0;
999 entry->mutex.count = 0;
1000 entry->mutex.muxWaiters = 0;
1003 if (entry->object == 0)
1004 entry->object = object;
1006 internal_lock_mutex(&entry->mutex);
1012 * Unlocks the mutex of an object.
1016 internal_unlock_mutex_for_object (java_objectheader *object)
1019 mutexHashEntry *entry;
1021 hashValue = MUTEX_HASH_VALUE(object);
1022 entry = &mutexHashTable[hashValue];
1024 if (entry->object == object)
1025 internal_unlock_mutex(&entry->mutex);
1028 while (entry->next != 0 && entry->next->object != object)
1029 entry = entry->next;
1031 assert(entry->next != 0);
1033 internal_unlock_mutex(&entry->next->mutex);
1035 if (entry->next->mutex.count == 0 && entry->conditionCount == 0)
1037 mutexHashEntry *unlinked = entry->next;
1039 entry->next = unlinked->next;
1040 unlinked->next = firstFreeOverflowEntry;
1041 firstFreeOverflowEntry = unlinked;
1048 builtin_monitorenter (java_objectheader *o)
1053 assert(blockInts == 0);
1057 hashValue = MUTEX_HASH_VALUE(o);
1058 if (mutexHashTable[hashValue].object == o
1059 && mutexHashTable[hashValue].mutex.holder == currentThread)
1060 ++mutexHashTable[hashValue].mutex.count;
1062 internal_lock_mutex_for_object(o);
1066 assert(blockInts == 0);
1070 void builtin_monitorexit (java_objectheader *o)
1075 assert(blockInts == 0);
1079 hashValue = MUTEX_HASH_VALUE(o);
1080 if (mutexHashTable[hashValue].object == o)
1082 if (mutexHashTable[hashValue].mutex.count == 1
1083 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1084 internal_unlock_mutex_for_object(o);
1086 --mutexHashTable[hashValue].mutex.count;
1089 internal_unlock_mutex_for_object(o);
1093 assert(blockInts == 0);
1098 /*****************************************************************************
1099 MISCELLANEOUS HELPER FUNCTIONS
1100 *****************************************************************************/
1104 /*********** Functions for integer divisions *****************************
1106 On some systems (eg. DEC ALPHA), integer division is not supported by the
1107 CPU. These helper functions implement the missing functionality.
1109 ******************************************************************************/
1111 s4 builtin_idiv (s4 a, s4 b) { return a/b; }
1112 s4 builtin_irem (s4 a, s4 b) { return a%b; }
1115 /************** Functions for long arithmetics *******************************
1117 On systems where 64 bit Integers are not supported by the CPU, these
1118 functions are needed.
1120 ******************************************************************************/
1123 s8 builtin_ladd (s8 a, s8 b)
1128 return builtin_i2l(0);
1132 s8 builtin_lsub (s8 a, s8 b)
1137 return builtin_i2l(0);
1141 s8 builtin_lmul (s8 a, s8 b)
1146 return builtin_i2l(0);
1150 s8 builtin_ldiv (s8 a, s8 b)
1155 return builtin_i2l(0);
1159 s8 builtin_lrem (s8 a, s8 b)
1164 return builtin_i2l(0);
1168 s8 builtin_lshl (s8 a, s4 b)
1173 return builtin_i2l(0);
1177 s8 builtin_lshr (s8 a, s4 b)
1182 return builtin_i2l(0);
1186 s8 builtin_lushr (s8 a, s4 b)
1189 return ((u8)a)>>(b&63);
1191 return builtin_i2l(0);
1195 s8 builtin_land (s8 a, s8 b)
1200 return builtin_i2l(0);
1204 s8 builtin_lor (s8 a, s8 b)
1209 return builtin_i2l(0);
1213 s8 builtin_lxor (s8 a, s8 b)
1218 return builtin_i2l(0);
1222 s8 builtin_lneg (s8 a)
1227 return builtin_i2l(0);
1231 s4 builtin_lcmp (s8 a, s8 b)
1246 /*********** Functions for floating point operations *************************/
1248 float builtin_fadd (float a, float b)
1250 if (isnanf(a)) return FLT_NAN;
1251 if (isnanf(b)) return FLT_NAN;
1253 if (finitef(b)) return a+b;
1257 if (finitef(b)) return a;
1259 if (copysignf(1.0, a)==copysignf(1.0, b)) return a;
1260 else return FLT_NAN;
1265 float builtin_fsub (float a, float b)
1267 return builtin_fadd (a, builtin_fneg(b));
1270 float builtin_fmul (float a, float b)
1272 if (isnanf(a)) return FLT_NAN;
1273 if (isnanf(b)) return FLT_NAN;
1275 if (finitef(b)) return a*b;
1277 if (a==0) return FLT_NAN;
1278 else return copysignf(b, copysignf(1.0, b)*a);
1283 if (b==0) return FLT_NAN;
1284 else return copysignf(a, copysignf(1.0, a)*b);
1287 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1292 float builtin_fdiv (float a, float b)
1294 if (finitef(a) && finitef(b)) {
1307 float builtin_frem (float a, float b)
1310 /* return (float) builtin_drem((double) a, (double) b); */
1314 if (finite((double) a) && finite((double) b)) {
1316 if (finite((double) f))
1320 if (isnan((double) b))
1322 if (finite((double) a))
1328 if (finitef(a) && finitef(b)) {
1331 return a - floorf(f) * b;
1342 float builtin_fneg (float a)
1344 if (isnanf(a)) return a;
1346 if (finitef(a)) return -a;
1347 else return copysignf(a,-copysignf(1.0, a));
1351 s4 builtin_fcmpl (float a, float b)
1353 if (isnanf(a)) return -1;
1354 if (isnanf(b)) return -1;
1355 if (!finitef(a) || !finitef(b)) {
1356 a = finitef(a) ? 0 : copysignf(1.0, a);
1357 b = finitef(b) ? 0 : copysignf(1.0, b);
1364 s4 builtin_fcmpg (float a, float b)
1366 if (isnanf(a)) return 1;
1367 if (isnanf(b)) return 1;
1368 if (!finitef(a) || !finitef(b)) {
1369 a = finitef(a) ? 0 : copysignf(1.0, a);
1370 b = finitef(b) ? 0 : copysignf(1.0, b);
1379 /************************* Functions for doubles ****************************/
1381 double builtin_dadd (double a, double b)
1383 if (isnan(a)) return DBL_NAN;
1384 if (isnan(b)) return DBL_NAN;
1386 if (finite(b)) return a+b;
1390 if (finite(b)) return a;
1392 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1393 else return DBL_NAN;
1398 double builtin_dsub (double a, double b)
1400 return builtin_dadd (a, builtin_dneg(b));
1403 double builtin_dmul (double a, double b)
1405 if (isnan(a)) return DBL_NAN;
1406 if (isnan(b)) return DBL_NAN;
1408 if (finite(b)) return a*b;
1410 if (a==0) return DBL_NAN;
1411 else return copysign(b, copysign(1.0, b)*a);
1416 if (b==0) return DBL_NAN;
1417 else return copysign(a, copysign(1.0, a)*b);
1420 return copysign(a, copysign(1.0, a)*copysign(1.0, b));
1425 double builtin_ddiv (double a, double b)
1427 if (finite(a) && finite(b)) {
1440 double builtin_drem (double a, double b)
1444 if (finite(a) && finite(b)) {
1447 if ((d < 1.0) && (d > 0.0))
1460 double builtin_dneg (double a)
1462 if (isnan(a)) return a;
1464 if (finite(a)) return -a;
1465 else return copysign(a,-copysign(1.0, a));
1469 s4 builtin_dcmpl (double a, double b)
1471 if (isnan(a)) return -1;
1472 if (isnan(b)) return -1;
1473 if (!finite(a) || !finite(b)) {
1474 a = finite(a) ? 0 : copysign(1.0, a);
1475 b = finite(b) ? 0 : copysign(1.0, b);
1482 s4 builtin_dcmpg (double a, double b)
1484 if (isnan(a)) return 1;
1485 if (isnan(b)) return 1;
1486 if (!finite(a) || !finite(b)) {
1487 a = finite(a) ? 0 : copysign(1.0, a);
1488 b = finite(b) ? 0 : copysign(1.0, b);
1496 /*********************** Conversion operations ****************************/
1498 s8 builtin_i2l (s4 i)
1503 s8 v; v.high = 0; v.low=i; return v;
1507 float builtin_i2f (s4 a)
1509 float f = (float) a;
1513 double builtin_i2d (s4 a)
1515 double d = (double) a;
1520 s4 builtin_l2i (s8 l)
1529 float builtin_l2f (s8 a)
1532 float f = (float) a;
1539 double builtin_l2d (s8 a)
1542 double d = (double) a;
1550 s4 builtin_f2i(float a)
1553 return builtin_d2i((double) a);
1562 if (a < (-2147483648))
1563 return (-2147483648);
1566 f = copysignf((float) 1.0, a);
1569 return (-2147483648); */
1573 s8 builtin_f2l (float a)
1576 return builtin_d2l((double) a);
1581 if (a > 9223372036854775807L)
1582 return 9223372036854775807L;
1583 if (a < (-9223372036854775808L))
1584 return (-9223372036854775808L);
1589 f = copysignf((float) 1.0, a);
1591 return 9223372036854775807L;
1592 return (-9223372036854775808L); */
1596 double builtin_f2d (float a)
1598 if (finitef(a)) return (double) a;
1600 if (isnanf(a)) return DBL_NAN;
1601 else return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1606 s4 builtin_d2i (double a)
1611 if (a >= 2147483647)
1613 if (a <= (-2147483648))
1614 return (-2147483648);
1619 d = copysign(1.0, a);
1622 return (-2147483648);
1626 s8 builtin_d2l (double a)
1631 if (a >= 9223372036854775807L)
1632 return 9223372036854775807L;
1633 if (a <= (-9223372036854775807L-1))
1634 return (-9223372036854775807L-1);
1639 d = copysign(1.0, a);
1641 return 9223372036854775807L;
1642 return (-9223372036854775807L-1);
1646 float builtin_d2f (double a)
1648 if (finite(a)) return (float) a;
1650 if (isnan(a)) return FLT_NAN;
1651 else return copysignf (FLT_POSINF, (float) copysign(1.0, a));
1657 * These are local overrides for various environment variables in Emacs.
1658 * Please do not remove this and leave it at the end of the file, where
1659 * Emacs will automagically detect them.
1660 * ---------------------------------------------------------------------
1663 * indent-tabs-mode: t