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"},
43 {(functionptr) builtin_anewarray, "anewarray"},
44 {(functionptr) builtin_newarray_array, "newarray_array"},
47 * have 2 parameters (needs stack manipulation)
49 {(functionptr) asm_builtin_anewarray, "anewarray"},
50 {(functionptr) asm_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(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5,
857 #if TRACE_ARGS_NUM > 6
863 for (i=0; i<methodindent; i++)
865 sprintf (logtext+methodindent, "called: ");
866 utf_sprint (logtext+strlen(logtext), method->class->name);
867 sprintf (logtext+strlen(logtext), ".");
868 utf_sprint (logtext+strlen(logtext), method->name);
869 utf_sprint (logtext+strlen(logtext), method->descriptor);
870 sprintf (logtext+strlen(logtext), "(");
871 switch (method->paramcount) {
872 #if TRACE_ARGS_NUM > 6
874 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx",
875 a0, a1, a2, a3, a4, a5, a6, a7);
878 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx",
879 a0, a1, a2, a3, a4, a5, a6);
883 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx",
884 a0, a1, a2, a3, a4, a5);
887 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx",
891 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx",
895 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx", a0, a1, a2);
898 sprintf(logtext+strlen(logtext), "%llx, %llx", a0, a1);
901 sprintf(logtext+strlen(logtext), "%llx", a0);
904 sprintf (logtext+strlen(logtext), ")");
911 void builtin_displaymethodstart(methodinfo *method)
913 sprintf (logtext, " ");
914 sprintf (logtext+methodindent, "called: ");
915 utf_sprint (logtext+strlen(logtext), method->class->name);
916 sprintf (logtext+strlen(logtext), ".");
917 utf_sprint (logtext+strlen(logtext), method->name);
918 utf_sprint (logtext+strlen(logtext), method->descriptor);
923 void builtin_displaymethodstop(methodinfo *method, s8 l, double d, float f)
926 for (i=0; i<methodindent; i++)
929 sprintf (logtext+methodindent, "finished: ");
930 utf_sprint (logtext+strlen(logtext), method->class->name);
931 sprintf (logtext+strlen(logtext), ".");
932 utf_sprint (logtext+strlen(logtext), method->name);
933 utf_sprint (logtext+strlen(logtext), method->descriptor);
934 switch (method->returntype) {
938 sprintf (logtext+strlen(logtext), "->%ld", l);
941 sprintf (logtext+strlen(logtext), "->%g", f);
944 sprintf (logtext+strlen(logtext), "->%g", d);
950 void builtin_displaymethodexception(methodinfo *method)
953 for (i=0; i<methodindent; i++)
955 sprintf (logtext+methodindent, "exception abort: ");
956 utf_sprint (logtext+strlen(logtext), method->class->name);
957 sprintf (logtext+strlen(logtext), ".");
958 utf_sprint (logtext+strlen(logtext), method->name);
959 utf_sprint (logtext+strlen(logtext), method->descriptor);
964 /****************************************************************************
965 SYNCHRONIZATION FUNCTIONS
966 *****************************************************************************/
969 * Lock the mutex of an object.
973 internal_lock_mutex_for_object (java_objectheader *object)
975 mutexHashEntry *entry;
980 hashValue = MUTEX_HASH_VALUE(object);
981 entry = &mutexHashTable[hashValue];
983 if (entry->object != 0)
985 if (entry->mutex.count == 0 && entry->conditionCount == 0)
988 entry->mutex.holder = 0;
989 entry->mutex.count = 0;
990 entry->mutex.muxWaiters = 0;
994 while (entry->next != 0 && entry->object != object)
997 if (entry->object != object)
999 entry->next = firstFreeOverflowEntry;
1000 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
1002 entry = entry->next;
1005 assert(entry->conditionCount == 0);
1011 entry->mutex.holder = 0;
1012 entry->mutex.count = 0;
1013 entry->mutex.muxWaiters = 0;
1016 if (entry->object == 0)
1017 entry->object = object;
1019 internal_lock_mutex(&entry->mutex);
1025 * Unlocks the mutex of an object.
1029 internal_unlock_mutex_for_object (java_objectheader *object)
1032 mutexHashEntry *entry;
1034 hashValue = MUTEX_HASH_VALUE(object);
1035 entry = &mutexHashTable[hashValue];
1037 if (entry->object == object)
1038 internal_unlock_mutex(&entry->mutex);
1041 while (entry->next != 0 && entry->next->object != object)
1042 entry = entry->next;
1044 assert(entry->next != 0);
1046 internal_unlock_mutex(&entry->next->mutex);
1048 if (entry->next->mutex.count == 0 && entry->conditionCount == 0)
1050 mutexHashEntry *unlinked = entry->next;
1052 entry->next = unlinked->next;
1053 unlinked->next = firstFreeOverflowEntry;
1054 firstFreeOverflowEntry = unlinked;
1061 builtin_monitorenter (java_objectheader *o)
1066 assert(blockInts == 0);
1070 hashValue = MUTEX_HASH_VALUE(o);
1071 if (mutexHashTable[hashValue].object == o
1072 && mutexHashTable[hashValue].mutex.holder == currentThread)
1073 ++mutexHashTable[hashValue].mutex.count;
1075 internal_lock_mutex_for_object(o);
1079 assert(blockInts == 0);
1083 void builtin_monitorexit (java_objectheader *o)
1088 assert(blockInts == 0);
1092 hashValue = MUTEX_HASH_VALUE(o);
1093 if (mutexHashTable[hashValue].object == o)
1095 if (mutexHashTable[hashValue].mutex.count == 1
1096 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1097 internal_unlock_mutex_for_object(o);
1099 --mutexHashTable[hashValue].mutex.count;
1102 internal_unlock_mutex_for_object(o);
1106 assert(blockInts == 0);
1111 /*****************************************************************************
1112 MISCELLANEOUS HELPER FUNCTIONS
1113 *****************************************************************************/
1117 /*********** Functions for integer divisions *****************************
1119 On some systems (eg. DEC ALPHA), integer division is not supported by the
1120 CPU. These helper functions implement the missing functionality.
1122 ******************************************************************************/
1124 s4 builtin_idiv (s4 a, s4 b) { return a/b; }
1125 s4 builtin_irem (s4 a, s4 b) { return a%b; }
1128 /************** Functions for long arithmetics *******************************
1130 On systems where 64 bit Integers are not supported by the CPU, these
1131 functions are needed.
1133 ******************************************************************************/
1136 s8 builtin_ladd (s8 a, s8 b)
1141 return builtin_i2l(0);
1145 s8 builtin_lsub (s8 a, s8 b)
1150 return builtin_i2l(0);
1154 s8 builtin_lmul (s8 a, s8 b)
1159 return builtin_i2l(0);
1163 s8 builtin_ldiv (s8 a, s8 b)
1168 return builtin_i2l(0);
1172 s8 builtin_lrem (s8 a, s8 b)
1177 return builtin_i2l(0);
1181 s8 builtin_lshl (s8 a, s4 b)
1186 return builtin_i2l(0);
1190 s8 builtin_lshr (s8 a, s4 b)
1195 return builtin_i2l(0);
1199 s8 builtin_lushr (s8 a, s4 b)
1202 return ((u8)a)>>(b&63);
1204 return builtin_i2l(0);
1208 s8 builtin_land (s8 a, s8 b)
1213 return builtin_i2l(0);
1217 s8 builtin_lor (s8 a, s8 b)
1222 return builtin_i2l(0);
1226 s8 builtin_lxor (s8 a, s8 b)
1231 return builtin_i2l(0);
1235 s8 builtin_lneg (s8 a)
1240 return builtin_i2l(0);
1244 s4 builtin_lcmp (s8 a, s8 b)
1259 /*********** Functions for floating point operations *************************/
1261 float builtin_fadd (float a, float b)
1263 if (isnanf(a)) return FLT_NAN;
1264 if (isnanf(b)) return FLT_NAN;
1266 if (finitef(b)) return a+b;
1270 if (finitef(b)) return a;
1272 if (copysignf(1.0, a)==copysignf(1.0, b)) return a;
1273 else return FLT_NAN;
1278 float builtin_fsub (float a, float b)
1280 return builtin_fadd (a, builtin_fneg(b));
1283 float builtin_fmul (float a, float b)
1285 if (isnanf(a)) return FLT_NAN;
1286 if (isnanf(b)) return FLT_NAN;
1288 if (finitef(b)) return a*b;
1290 if (a==0) return FLT_NAN;
1291 else return copysignf(b, copysignf(1.0, b)*a);
1296 if (b==0) return FLT_NAN;
1297 else return copysignf(a, copysignf(1.0, a)*b);
1300 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1305 float builtin_fdiv (float a, float b)
1307 if (finitef(a) && finitef(b)) {
1320 float builtin_frem (float a, float b)
1323 /* return (float) builtin_drem((double) a, (double) b); */
1327 if (finite((double) a) && finite((double) b)) {
1329 if (finite((double) f))
1333 if (isnan((double) b))
1335 if (finite((double) a))
1341 if (finitef(a) && finitef(b)) {
1344 return a - floorf(f) * b;
1355 float builtin_fneg (float a)
1357 if (isnanf(a)) return a;
1359 if (finitef(a)) return -a;
1360 else return copysignf(a,-copysignf(1.0, a));
1364 s4 builtin_fcmpl (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);
1377 s4 builtin_fcmpg (float a, float b)
1379 if (isnanf(a)) return 1;
1380 if (isnanf(b)) return 1;
1381 if (!finitef(a) || !finitef(b)) {
1382 a = finitef(a) ? 0 : copysignf(1.0, a);
1383 b = finitef(b) ? 0 : copysignf(1.0, b);
1392 /************************* Functions for doubles ****************************/
1394 double builtin_dadd (double a, double b)
1396 if (isnan(a)) return DBL_NAN;
1397 if (isnan(b)) return DBL_NAN;
1399 if (finite(b)) return a+b;
1403 if (finite(b)) return a;
1405 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1406 else return DBL_NAN;
1411 double builtin_dsub (double a, double b)
1413 return builtin_dadd (a, builtin_dneg(b));
1416 double builtin_dmul (double a, double b)
1418 if (isnan(a)) return DBL_NAN;
1419 if (isnan(b)) return DBL_NAN;
1421 if (finite(b)) return a*b;
1423 if (a==0) return DBL_NAN;
1424 else return copysign(b, copysign(1.0, b)*a);
1429 if (b==0) return DBL_NAN;
1430 else return copysign(a, copysign(1.0, a)*b);
1433 return copysign(a, copysign(1.0, a)*copysign(1.0, b));
1438 double builtin_ddiv (double a, double b)
1440 if (finite(a) && finite(b)) {
1453 double builtin_drem (double a, double b)
1457 if (finite(a) && finite(b)) {
1460 if ((d < 1.0) && (d > 0.0))
1473 double builtin_dneg (double a)
1475 if (isnan(a)) return a;
1477 if (finite(a)) return -a;
1478 else return copysign(a,-copysign(1.0, a));
1482 s4 builtin_dcmpl (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);
1495 s4 builtin_dcmpg (double a, double b)
1497 if (isnan(a)) return 1;
1498 if (isnan(b)) return 1;
1499 if (!finite(a) || !finite(b)) {
1500 a = finite(a) ? 0 : copysign(1.0, a);
1501 b = finite(b) ? 0 : copysign(1.0, b);
1509 /*********************** Conversion operations ****************************/
1511 s8 builtin_i2l (s4 i)
1516 s8 v; v.high = 0; v.low=i; return v;
1520 float builtin_i2f (s4 a)
1522 float f = (float) a;
1526 double builtin_i2d (s4 a)
1528 double d = (double) a;
1533 s4 builtin_l2i (s8 l)
1542 float builtin_l2f (s8 a)
1545 float f = (float) a;
1552 double builtin_l2d (s8 a)
1555 double d = (double) a;
1563 s4 builtin_f2i(float a)
1566 return builtin_d2i((double) a);
1575 if (a < (-2147483648))
1576 return (-2147483648);
1579 f = copysignf((float) 1.0, a);
1582 return (-2147483648); */
1586 s8 builtin_f2l (float a)
1589 return builtin_d2l((double) a);
1594 if (a > 9223372036854775807L)
1595 return 9223372036854775807L;
1596 if (a < (-9223372036854775808L))
1597 return (-9223372036854775808L);
1602 f = copysignf((float) 1.0, a);
1604 return 9223372036854775807L;
1605 return (-9223372036854775808L); */
1609 double builtin_f2d (float a)
1611 if (finitef(a)) return (double) a;
1613 if (isnanf(a)) return DBL_NAN;
1614 else return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1619 s4 builtin_d2i (double a)
1624 if (a >= 2147483647)
1626 if (a <= (-2147483648))
1627 return (-2147483648);
1632 d = copysign(1.0, a);
1635 return (-2147483648);
1639 s8 builtin_d2l (double a)
1644 if (a >= 9223372036854775807L)
1645 return 9223372036854775807L;
1646 if (a <= (-9223372036854775807L-1))
1647 return (-9223372036854775807L-1);
1652 d = copysign(1.0, a);
1654 return 9223372036854775807L;
1655 return (-9223372036854775807L-1);
1659 float builtin_d2f (double a)
1661 if (finite(a)) return (float) a;
1663 if (isnan(a)) return FLT_NAN;
1664 else return copysignf (FLT_POSINF, (float) copysign(1.0, a));
1670 * These are local overrides for various environment variables in Emacs.
1671 * Please do not remove this and leave it at the end of the file, where
1672 * Emacs will automagically detect them.
1673 * ---------------------------------------------------------------------
1676 * indent-tabs-mode: t