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 *******************************************************************************/
28 #include "threads/thread.h"
29 #include "threads/locks.h" /* schani */
31 #include "native-math.h"
33 builtin_descriptor builtin_desc[] = {
34 {(functionptr) builtin_instanceof, "instanceof"},
35 {(functionptr) builtin_checkcast, "checkcast"},
36 {(functionptr) asm_builtin_checkcast, "checkcast"},
37 {(functionptr) builtin_arrayinstanceof, "arrayinstanceof"},
39 {(functionptr) asm_builtin_arrayinstanceof,"arrayinstanceof"},
41 {(functionptr) builtin_checkarraycast, "checkarraycast"},
42 {(functionptr) asm_builtin_checkarraycast, "checkarraycast"},
43 {(functionptr) asm_builtin_aastore, "aastore"},
44 {(functionptr) builtin_new, "new"},
45 {(functionptr) builtin_anewarray, "anewarray"},
46 {(functionptr) builtin_newarray_array, "newarray_array"},
49 * have 2 parameters (needs stack manipulation)
51 {(functionptr) asm_builtin_anewarray, "anewarray"},
52 {(functionptr) asm_builtin_newarray_array, "newarray_array"},
54 {(functionptr) builtin_newarray_boolean, "newarray_boolean"},
55 {(functionptr) builtin_newarray_char, "newarray_char"},
56 {(functionptr) builtin_newarray_float, "newarray_float"},
57 {(functionptr) builtin_newarray_double, "newarray_double"},
58 {(functionptr) builtin_newarray_byte, "newarray_byte"},
59 {(functionptr) builtin_newarray_short, "newarray_short"},
60 {(functionptr) builtin_newarray_int, "newarray_int"},
61 {(functionptr) builtin_newarray_long, "newarray_long"},
62 {(functionptr) builtin_displaymethodstart, "displaymethodstart"},
63 {(functionptr) builtin_displaymethodstop, "displaymethodstop"},
64 {(functionptr) builtin_monitorenter, "monitorenter"},
65 {(functionptr) asm_builtin_monitorenter, "monitorenter"},
66 {(functionptr) builtin_monitorexit, "monitorexit"},
67 {(functionptr) asm_builtin_monitorexit, "monitorexit"},
69 {(functionptr) builtin_idiv, "idiv"},
70 {(functionptr) asm_builtin_idiv, "idiv"},
71 {(functionptr) builtin_irem, "irem"},
72 {(functionptr) asm_builtin_irem, "irem"},
74 {(functionptr) builtin_ladd, "ladd"},
75 {(functionptr) builtin_lsub, "lsub"},
76 {(functionptr) builtin_lmul, "lmul"},
77 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_MULDIV)
78 {(functionptr) builtin_ldiv, "ldiv"},
79 {(functionptr) asm_builtin_ldiv, "ldiv"},
80 {(functionptr) builtin_lrem, "lrem"},
81 {(functionptr) asm_builtin_lrem, "lrem"},
83 {(functionptr) builtin_lshl, "lshl"},
84 {(functionptr) builtin_lshr, "lshr"},
85 {(functionptr) builtin_lushr, "lushr"},
86 {(functionptr) builtin_land, "land"},
87 {(functionptr) builtin_lor, "lor"},
88 {(functionptr) builtin_lxor, "lxor"},
89 {(functionptr) builtin_lneg, "lneg"},
90 {(functionptr) builtin_lcmp, "lcmp"},
91 {(functionptr) builtin_fadd, "fadd"},
92 {(functionptr) builtin_fsub, "fsub"},
93 {(functionptr) builtin_fmul, "fmul"},
94 {(functionptr) builtin_fdiv, "fdiv"},
95 {(functionptr) builtin_frem, "frem"},
96 {(functionptr) builtin_fneg, "fneg"},
97 {(functionptr) builtin_fcmpl, "fcmpl"},
98 {(functionptr) builtin_fcmpg, "fcmpg"},
99 {(functionptr) builtin_dadd, "dadd"},
100 {(functionptr) builtin_dsub, "dsub"},
101 {(functionptr) builtin_dmul, "dmul"},
102 {(functionptr) builtin_ddiv, "ddiv"},
103 {(functionptr) builtin_drem, "drem"},
104 {(functionptr) builtin_dneg, "dneg"},
105 {(functionptr) builtin_dcmpl, "dcmpl"},
106 {(functionptr) builtin_dcmpg, "dcmpg"},
107 {(functionptr) builtin_i2l, "i2l"},
108 {(functionptr) builtin_i2f, "i2f"},
109 {(functionptr) builtin_i2d, "i2d"},
110 {(functionptr) builtin_l2i, "l2i"},
111 {(functionptr) builtin_l2f, "l2f"},
112 {(functionptr) builtin_l2d, "l2d"},
113 {(functionptr) builtin_f2i, "f2i"},
114 {(functionptr) builtin_f2l, "f2l"},
115 {(functionptr) builtin_f2d, "f2d"},
116 {(functionptr) builtin_d2i, "d2i"},
117 {(functionptr) builtin_d2l, "d2l"},
118 #if defined(__I386__)
119 {(functionptr) asm_builtin_f2i, "f2i"},
120 {(functionptr) asm_builtin_f2l, "f2l"},
121 {(functionptr) asm_builtin_d2i, "d2i"},
122 {(functionptr) asm_builtin_d2l, "d2l"},
124 {(functionptr) builtin_d2f, "d2f"},
125 {(functionptr) NULL, "unknown"}
129 /*****************************************************************************
131 *****************************************************************************/
135 /*************** internal function: builtin_isanysubclass *********************
137 Checks a subclass relation between two classes. Implemented interfaces
138 are interpreted as super classes.
139 Return value: 1 ... sub is subclass of super
142 *****************************************************************************/
144 s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
146 if (super->flags & ACC_INTERFACE)
147 return (sub->vftbl->interfacetablelength > super->index) &&
148 (sub->vftbl->interfacetable[-super->index] != NULL);
160 return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <=
161 (unsigned) (super->vftbl->diffval);
165 /****************** function: builtin_instanceof *****************************
167 Checks if an object is an instance of some given class (or subclass of
168 that class). If class is an interface, checks if the interface is
170 Return value: 1 ... obj is an instance of class or implements the interface
171 0 ... otherwise or if obj == NULL
173 *****************************************************************************/
175 s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
178 log_text ("builtin_instanceof called");
182 return builtin_isanysubclass (obj->vftbl->class, class);
187 /**************** function: builtin_checkcast *******************************
189 The same as builtin_instanceof except that 1 is returned when
192 ****************************************************************************/
194 s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
197 log_text ("builtin_checkcast called");
202 if (builtin_isanysubclass (obj->vftbl->class, class))
206 printf ("#### checkcast failed ");
207 utf_display (obj->vftbl->class->name);
209 utf_display (class->name);
217 /*********** internal function: builtin_descriptorscompatible ******************
219 Checks if two array type descriptors are assignment compatible
220 Return value: 1 ... target = desc is possible
223 ******************************************************************************/
225 static s4 builtin_descriptorscompatible(constant_arraydescriptor *desc, constant_arraydescriptor *target)
227 if (desc==target) return 1;
228 if (desc->arraytype != target->arraytype) return 0;
229 switch (target->arraytype) {
230 case ARRAYTYPE_OBJECT:
231 return builtin_isanysubclass (desc->objectclass, target->objectclass);
232 case ARRAYTYPE_ARRAY:
233 return builtin_descriptorscompatible
234 (desc->elementdescriptor, target->elementdescriptor);
241 /******************** function: builtin_checkarraycast ***********************
243 Checks if an object is really a subtype of the requested array type.
244 The object has to be an array to begin with. For simple arrays (int, short,
245 double, etc.) the types have to match exactly.
246 For arrays of objects, the type of elements in the array has to be a
247 subtype (or the same type) of the requested element type. For arrays of
248 arrays (which in turn can again be arrays of arrays), the types at the
249 lowest level have to satisfy the corresponding sub class relation.
251 Return value: 1 ... cast is possible
254 ATTENTION: a cast with a NULL pointer is always possible.
256 *****************************************************************************/
258 s4 builtin_checkarraycast(java_objectheader *o, constant_arraydescriptor *desc)
260 java_arrayheader *a = (java_arrayheader*) o;
263 if (o->vftbl->class != class_array) {
265 printf ("#### checkarraycast failed 1\n");
270 if (a->arraytype != desc->arraytype) {
272 printf ("#### checkarraycast failed 2\n");
277 switch (a->arraytype) {
278 case ARRAYTYPE_OBJECT: {
279 java_objectarray *oa = (java_objectarray*) o;
280 int result = builtin_isanysubclass (oa->elementtype, desc->objectclass);
284 printf ("#### checkarraycast failed 3\n");
288 case ARRAYTYPE_ARRAY: {
289 java_arrayarray *aa = (java_arrayarray*) o;
290 int result = builtin_descriptorscompatible
291 (aa->elementdescriptor, desc->elementdescriptor);
295 printf ("#### checkarraycast failed 4\n");
305 s4 builtin_arrayinstanceof(java_objectheader *obj, constant_arraydescriptor *desc)
308 return builtin_checkarraycast (obj, desc);
312 /************************** exception functions *******************************
314 ******************************************************************************/
316 java_objectheader *builtin_throw_exception (java_objectheader *local_exceptionptr) {
318 sprintf(logtext, "Builtin exception thrown: ");
319 utf_sprint(logtext + strlen(logtext), local_exceptionptr->vftbl->class->name);
322 exceptionptr = local_exceptionptr;
323 return local_exceptionptr;
327 /******************* function: builtin_canstore *******************************
329 Checks, if an object can be stored in an array.
330 Return value: 1 ... possible
333 ******************************************************************************/
336 s4 builtin_canstore (java_objectarray *a, java_objectheader *o)
340 switch (a->header.arraytype) {
341 case ARRAYTYPE_OBJECT:
342 if ( ! builtin_checkcast (o, a->elementtype) ) {
348 case ARRAYTYPE_ARRAY:
349 if ( ! builtin_checkarraycast
350 (o, ((java_arrayarray*)a)->elementdescriptor) ) {
357 panic ("builtin_canstore called with invalid arraytype");
364 /*****************************************************************************
366 *****************************************************************************/
370 /******************** Function: builtin_new **********************************
372 Creates a new instance of class c on the heap.
373 Return value: pointer to the object or NULL if no memory is
376 *****************************************************************************/
379 #define align_size(size) ((size + ((1 << ALIGNMENT) - 1)) & ~((1 << ALIGNMENT) - 1))
381 java_objectheader *builtin_new(classinfo *c)
383 java_objectheader *o;
387 #ifdef SIZE_FROM_CLASSINFO
388 c->alignedsize = align_size(c->instancesize);
389 o = heap_allocate(c->alignedsize, true, c->finalizer);
391 o = heap_allocate(c->instancesize, true, c->finalizer);
395 memset(o, 0, c->instancesize);
404 /******************** function: builtin_anewarray ****************************
406 Creates an array of pointers to objects on the heap.
408 size ......... number of elements
409 elementtype .. pointer to the classinfo structure for the element type
411 Return value: pointer to the array or NULL if no memory is available
413 *****************************************************************************/
415 void XXX_copy_vftbl(vftbl **dest, vftbl *src)
417 *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr)*(src->vftbllength-1));
418 memcpy(*dest, src, sizeof(vftbl) - sizeof(methodptr));
419 memcpy(&(*dest)->table, &src->table, src->vftbllength * sizeof(methodptr));
422 void XXX_use_class_as_object(classinfo *c, char *cname)
424 vftbl *vt = class_get(utf_new_char(cname))->vftbl;
426 if (!c->classvftbl) {
427 c->classvftbl = true;
428 XXX_copy_vftbl(&newtbl, vt);
429 newtbl->class = c->header.vftbl->class;
430 newtbl->baseval = c->header.vftbl->baseval;
431 newtbl->diffval = c->header.vftbl->diffval;
432 c->header.vftbl = newtbl;
437 void* __builtin_newarray(s4 base_size,
446 #ifdef SIZE_FROM_CLASSINFO
447 s4 alignedsize = align_size(base_size + (size-1) * elementsize);
448 a = heap_allocate( alignedsize, references, NULL );
450 a = heap_allocate(sizeof(java_objectarray) + (size-1) * elementsize,
456 #ifdef SIZE_FROM_CLASSINFO
457 memset(a, 0, alignedsize);
459 memset(a, 0, base_size + (size-1) * elementsize);
468 c = create_array_class(utf_new_char("[I"));
469 XXX_use_class_as_object(c, "int");
473 c = create_array_class(utf_new_char("[J"));
474 XXX_use_class_as_object(c, "long");
477 case ARRAYTYPE_FLOAT:
478 c = create_array_class(utf_new_char("[F"));
479 XXX_use_class_as_object(c, "float");
482 case ARRAYTYPE_DOUBLE:
483 c = create_array_class(utf_new_char("[D"));
484 XXX_use_class_as_object(c, "double");
488 c = create_array_class(utf_new_char("[B"));
489 XXX_use_class_as_object(c, "byte");
493 c = create_array_class(utf_new_char("[C"));
494 XXX_use_class_as_object(c, "char");
497 case ARRAYTYPE_SHORT:
498 c = create_array_class(utf_new_char("[S"));
499 XXX_use_class_as_object(c, "short");
502 case ARRAYTYPE_BOOLEAN:
503 c = create_array_class(utf_new_char("[Z"));
504 XXX_use_class_as_object(c, "boolean");
507 case ARRAYTYPE_OBJECT:
510 cname = heap_allocate(utf_strlen(el->name), false, NULL);
511 utf_sprint(cname, el->name);
512 buf = heap_allocate(strlen(cname) + 3, false, NULL);
513 /* printf("\n\n[L%s;\n\n", cname); */
514 sprintf(buf, "[L%s;", cname);
515 c = create_array_class(utf_new_char(buf));
516 /* MFREE(buf, char, strlen(cname) + 3); */
517 /* MFREE(cname, char, utf_strlen(el->name)); */
518 XXX_use_class_as_object(c, cname);
522 case ARRAYTYPE_ARRAY:
523 c = create_array_class(utf_new_char("[["));
524 XXX_use_class_as_object(c, "java/lang/Boolean");
528 panic("unknown array type");
531 a->objheader.vftbl = c->vftbl;
534 a->objheader.vftbl = class_array->vftbl;
537 #ifdef SIZE_FROM_CLASSINFO
538 a -> alignedsize = alignedsize;
540 a -> arraytype = arraytype;
546 java_objectarray *builtin_anewarray (s4 size, classinfo *elementtype)
549 a = (java_objectarray*)__builtin_newarray(sizeof(java_objectarray),
557 a -> elementtype = elementtype;
563 /******************** function: builtin_newarray_array ***********************
565 Creates an array of pointers to arrays on the heap.
567 size ......... number of elements
568 elementdesc .. pointer to the array description structure for the
571 Return value: pointer to the array or NULL if no memory is available
573 *****************************************************************************/
575 java_arrayarray *builtin_newarray_array
576 (s4 size, constant_arraydescriptor *elementdesc)
579 a = (java_arrayarray*)__builtin_newarray(sizeof(java_arrayarray),
584 elementdesc->objectclass);
587 a -> elementdescriptor = elementdesc;
592 /******************** function: builtin_newarray_boolean ************************
594 Creates an array of bytes on the heap. The array is designated as an array
595 of booleans (important for casts)
597 Return value: pointer to the array or NULL if no memory is available
599 *****************************************************************************/
601 java_booleanarray *builtin_newarray_boolean (s4 size)
603 java_booleanarray *a;
604 a = (java_booleanarray*)__builtin_newarray(sizeof(java_booleanarray),
613 /******************** function: builtin_newarray_char ************************
615 Creates an array of characters on the heap.
617 Return value: pointer to the array or NULL if no memory is available
619 *****************************************************************************/
621 java_chararray *builtin_newarray_char (s4 size)
624 a = (java_chararray*)__builtin_newarray(sizeof(java_chararray),
634 /******************** function: builtin_newarray_float ***********************
636 Creates an array of 32 bit IEEE floats on the heap.
638 Return value: pointer to the array or NULL if no memory is available
640 *****************************************************************************/
642 java_floatarray *builtin_newarray_float (s4 size)
645 a = (java_floatarray*)__builtin_newarray(sizeof(java_floatarray),
655 /******************** function: builtin_newarray_double ***********************
657 Creates an array of 64 bit IEEE floats on the heap.
659 Return value: pointer to the array or NULL if no memory is available
661 *****************************************************************************/
663 java_doublearray *builtin_newarray_double (s4 size)
666 a = (java_doublearray*)__builtin_newarray(sizeof(java_doublearray),
678 /******************** function: builtin_newarray_byte ***********************
680 Creates an array of 8 bit Integers on the heap.
682 Return value: pointer to the array or NULL if no memory is available
684 *****************************************************************************/
686 java_bytearray *builtin_newarray_byte (s4 size)
689 a = (java_bytearray*)__builtin_newarray(sizeof(java_bytearray),
699 /******************** function: builtin_newarray_short ***********************
701 Creates an array of 16 bit Integers on the heap.
703 Return value: pointer to the array or NULL if no memory is available
705 *****************************************************************************/
707 java_shortarray *builtin_newarray_short (s4 size)
710 a = (java_shortarray*)__builtin_newarray(sizeof(java_shortarray),
720 /******************** Function: builtin_newarray_int ***********************
722 Creates an array of 32 bit Integers on the heap.
724 Return value: pointer to the array or NULL if no memory is available
726 *****************************************************************************/
728 java_intarray *builtin_newarray_int (s4 size)
731 a = (java_intarray*)__builtin_newarray(sizeof(java_intarray),
741 /******************** Function: builtin_newarray_long ***********************
743 Creates an array of 64 bit Integers on the heap.
745 Return value: pointer to the array or NULL if no memory is available
747 *****************************************************************************/
749 java_longarray *builtin_newarray_long (s4 size)
752 a = (java_longarray*)__builtin_newarray(sizeof(java_longarray),
763 /***************** function: builtin_multianewarray ***************************
765 Creates a multi-dimensional array on the heap. The dimensions are passed in
766 an array of Integers. The type for the array is passed as a reference to a
767 constant_arraydescriptor structure.
769 Return value: pointer to the array or NULL if no memory is available
771 ******************************************************************************/
773 /* Helper functions */
775 static java_arrayheader *multianewarray_part (java_intarray *dims, int thisdim,
776 constant_arraydescriptor *desc)
781 size = dims -> data[thisdim];
783 if (thisdim == (dims->header.size-1)) {
784 /* last dimension reached */
786 switch (desc -> arraytype) {
787 case ARRAYTYPE_BOOLEAN:
788 return (java_arrayheader*) builtin_newarray_boolean (size);
790 return (java_arrayheader*) builtin_newarray_char (size);
791 case ARRAYTYPE_FLOAT:
792 return (java_arrayheader*) builtin_newarray_float (size);
793 case ARRAYTYPE_DOUBLE:
794 return (java_arrayheader*) builtin_newarray_double (size);
796 return (java_arrayheader*) builtin_newarray_byte (size);
797 case ARRAYTYPE_SHORT:
798 return (java_arrayheader*) builtin_newarray_short (size);
800 return (java_arrayheader*) builtin_newarray_int (size);
802 return (java_arrayheader*) builtin_newarray_long (size);
803 case ARRAYTYPE_OBJECT:
804 return (java_arrayheader*) builtin_anewarray (size, desc->objectclass);
806 case ARRAYTYPE_ARRAY:
807 return (java_arrayheader*) builtin_newarray_array (size, desc->elementdescriptor);
809 default: panic ("Invalid arraytype in multianewarray");
813 /* if the last dimension has not been reached yet */
815 if (desc->arraytype != ARRAYTYPE_ARRAY)
816 panic ("multianewarray with too many dimensions");
818 a = builtin_newarray_array (size, desc->elementdescriptor);
821 for (i=0; i<size; i++) {
822 java_arrayheader *ea =
823 multianewarray_part (dims, thisdim+1, desc->elementdescriptor);
824 if (!ea) return NULL;
829 return (java_arrayheader*) a;
833 java_arrayheader *builtin_multianewarray (java_intarray *dims,
834 constant_arraydescriptor *desc)
836 return multianewarray_part (dims, 0, desc);
840 static java_arrayheader *nmultianewarray_part (int n, long *dims, int thisdim,
841 constant_arraydescriptor *desc)
846 size = (int) dims[thisdim];
848 if (thisdim == (n - 1)) {
849 /* last dimension reached */
851 switch (desc -> arraytype) {
852 case ARRAYTYPE_BOOLEAN:
853 return (java_arrayheader*) builtin_newarray_boolean(size);
855 return (java_arrayheader*) builtin_newarray_char(size);
856 case ARRAYTYPE_FLOAT:
857 return (java_arrayheader*) builtin_newarray_float(size);
858 case ARRAYTYPE_DOUBLE:
859 return (java_arrayheader*) builtin_newarray_double(size);
861 return (java_arrayheader*) builtin_newarray_byte(size);
862 case ARRAYTYPE_SHORT:
863 return (java_arrayheader*) builtin_newarray_short(size);
865 return (java_arrayheader*) builtin_newarray_int(size);
867 return (java_arrayheader*) builtin_newarray_long(size);
868 case ARRAYTYPE_OBJECT:
869 return (java_arrayheader*) builtin_anewarray(size,
871 case ARRAYTYPE_ARRAY:
872 return (java_arrayheader*) builtin_newarray_array(size,
873 desc->elementdescriptor);
875 default: panic ("Invalid arraytype in multianewarray");
879 /* if the last dimension has not been reached yet */
881 if (desc->arraytype != ARRAYTYPE_ARRAY)
882 panic ("multianewarray with too many dimensions");
884 a = builtin_newarray_array(size, desc->elementdescriptor);
887 for (i = 0; i < size; i++) {
888 java_arrayheader *ea =
889 nmultianewarray_part(n, dims, thisdim + 1, desc->elementdescriptor);
890 if (!ea) return NULL;
895 return (java_arrayheader*) a;
899 java_arrayheader *builtin_nmultianewarray (int size,
900 constant_arraydescriptor *desc, long *dims)
902 (void) builtin_newarray_int(size); /* for compatibility with -old */
903 return nmultianewarray_part (size, dims, 0, desc);
909 /************************* function: builtin_aastore *************************
911 Stores a reference to an object into an object array or into an array
912 array. Before any action is performed, the validity of the operation is
915 Return value: 1 ... ok
916 0 ... this object cannot be stored into this array
918 *****************************************************************************/
920 s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o)
922 if (builtin_canstore(a,o)) {
934 /*****************************************************************************
937 Various functions for printing a message at method entry or exit (for
940 *****************************************************************************/
945 java_objectheader *builtin_trace_exception (java_objectheader *exceptionptr,
946 methodinfo *method, int *pos, int noindent) {
950 if (verbose || runverbose) {
951 printf("Exception ");
952 utf_display (exceptionptr->vftbl->class->name);
953 printf(" thrown in ");
955 utf_display (method->class->name);
957 utf_display (method->name);
958 if (method->flags & ACC_SYNCHRONIZED)
962 printf("(%p) at position %p\n", method->entrypoint, pos);
965 printf("call_java_method\n");
972 #ifdef TRACE_ARGS_NUM
973 void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5,
974 #if TRACE_ARGS_NUM > 6
980 for (i=0; i<methodindent; i++)
982 sprintf (logtext+methodindent, "called: ");
983 utf_sprint (logtext+strlen(logtext), method->class->name);
984 sprintf (logtext+strlen(logtext), ".");
985 utf_sprint (logtext+strlen(logtext), method->name);
986 utf_sprint (logtext+strlen(logtext), method->descriptor);
987 sprintf (logtext+strlen(logtext), "(");
988 switch (method->paramcount) {
992 #if defined(__I386__)
994 sprintf(logtext+strlen(logtext), "%llx", a0);
998 sprintf(logtext+strlen(logtext), "%llx, %llx", a0, a1);
1002 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx", a0, a1, a2);
1006 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx",
1011 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx",
1012 a0, a1, a2, a3, a4);
1016 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx",
1017 a0, a1, a2, a3, a4, a5);
1020 #if TRACE_ARGS_NUM > 6
1022 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx",
1023 a0, a1, a2, a3, a4, a5, a6);
1027 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx",
1028 a0, a1, a2, a3, a4, a5, a6, a7);
1032 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
1033 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
1037 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
1038 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
1043 sprintf(logtext+strlen(logtext), "%lx", a0);
1047 sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1);
1051 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2);
1055 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx",
1060 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx",
1061 a0, a1, a2, a3, a4);
1065 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx",
1066 a0, a1, a2, a3, a4, a5);
1069 #if TRACE_ARGS_NUM > 6
1071 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx",
1072 a0, a1, a2, a3, a4, a5, a6);
1076 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx",
1077 a0, a1, a2, a3, a4, a5, a6, a7);
1081 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx, ...(%d)",
1082 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
1086 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, ...(%d)",
1087 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
1092 sprintf (logtext+strlen(logtext), ")");
1099 void builtin_displaymethodstart(methodinfo *method)
1101 sprintf (logtext, " ");
1102 sprintf (logtext+methodindent, "called: ");
1103 utf_sprint (logtext+strlen(logtext), method->class->name);
1104 sprintf (logtext+strlen(logtext), ".");
1105 utf_sprint (logtext+strlen(logtext), method->name);
1106 utf_sprint (logtext+strlen(logtext), method->descriptor);
1111 void builtin_displaymethodstop(methodinfo *method, s8 l, double d, float f)
1114 for (i=0; i<methodindent; i++)
1117 sprintf (logtext+methodindent, "finished: ");
1118 utf_sprint (logtext+strlen(logtext), method->class->name);
1119 sprintf (logtext+strlen(logtext), ".");
1120 utf_sprint (logtext+strlen(logtext), method->name);
1121 utf_sprint (logtext+strlen(logtext), method->descriptor);
1122 switch (method->returntype) {
1124 sprintf (logtext+strlen(logtext), "->%d", (s4) l);
1127 #if defined(__I386__)
1128 sprintf(logtext+strlen(logtext), "->%lld", (s8) l);
1130 sprintf(logtext+strlen(logtext), "->%ld", (s8) l);
1134 #if defined(__I386__)
1135 sprintf(logtext+strlen(logtext), "->%p", (u1*) ((s4) l));
1137 sprintf(logtext+strlen(logtext), "->%p", (u1*) l);
1141 sprintf (logtext+strlen(logtext), "->%g", f);
1144 sprintf (logtext+strlen(logtext), "->%g", d);
1150 void builtin_displaymethodexception(methodinfo *method)
1153 for (i=0; i<methodindent; i++)
1155 sprintf (logtext+methodindent, "exception abort: ");
1156 utf_sprint (logtext+strlen(logtext), method->class->name);
1157 sprintf (logtext+strlen(logtext), ".");
1158 utf_sprint (logtext+strlen(logtext), method->name);
1159 utf_sprint (logtext+strlen(logtext), method->descriptor);
1164 /****************************************************************************
1165 SYNCHRONIZATION FUNCTIONS
1166 *****************************************************************************/
1169 * Lock the mutex of an object.
1173 internal_lock_mutex_for_object (java_objectheader *object)
1175 mutexHashEntry *entry;
1178 assert(object != 0);
1180 hashValue = MUTEX_HASH_VALUE(object);
1181 entry = &mutexHashTable[hashValue];
1183 if (entry->object != 0)
1185 if (entry->mutex.count == 0 && entry->conditionCount == 0)
1188 entry->mutex.holder = 0;
1189 entry->mutex.count = 0;
1190 entry->mutex.muxWaiters = 0;
1194 while (entry->next != 0 && entry->object != object)
1195 entry = entry->next;
1197 if (entry->object != object)
1199 entry->next = firstFreeOverflowEntry;
1200 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
1202 entry = entry->next;
1205 assert(entry->conditionCount == 0);
1211 entry->mutex.holder = 0;
1212 entry->mutex.count = 0;
1213 entry->mutex.muxWaiters = 0;
1216 if (entry->object == 0)
1217 entry->object = object;
1219 internal_lock_mutex(&entry->mutex);
1225 * Unlocks the mutex of an object.
1229 internal_unlock_mutex_for_object (java_objectheader *object)
1232 mutexHashEntry *entry;
1234 hashValue = MUTEX_HASH_VALUE(object);
1235 entry = &mutexHashTable[hashValue];
1237 if (entry->object == object)
1238 internal_unlock_mutex(&entry->mutex);
1241 while (entry->next != 0 && entry->next->object != object)
1242 entry = entry->next;
1244 assert(entry->next != 0);
1246 internal_unlock_mutex(&entry->next->mutex);
1248 if (entry->next->mutex.count == 0 && entry->conditionCount == 0)
1250 mutexHashEntry *unlinked = entry->next;
1252 entry->next = unlinked->next;
1253 unlinked->next = firstFreeOverflowEntry;
1254 firstFreeOverflowEntry = unlinked;
1261 builtin_monitorenter (java_objectheader *o)
1266 assert(blockInts == 0);
1270 hashValue = MUTEX_HASH_VALUE(o);
1271 if (mutexHashTable[hashValue].object == o
1272 && mutexHashTable[hashValue].mutex.holder == currentThread)
1273 ++mutexHashTable[hashValue].mutex.count;
1275 internal_lock_mutex_for_object(o);
1279 assert(blockInts == 0);
1283 void builtin_monitorexit (java_objectheader *o)
1288 assert(blockInts == 0);
1292 hashValue = MUTEX_HASH_VALUE(o);
1293 if (mutexHashTable[hashValue].object == o)
1295 if (mutexHashTable[hashValue].mutex.count == 1
1296 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1297 internal_unlock_mutex_for_object(o);
1299 --mutexHashTable[hashValue].mutex.count;
1302 internal_unlock_mutex_for_object(o);
1306 assert(blockInts == 0);
1311 /*****************************************************************************
1312 MISCELLANEOUS HELPER FUNCTIONS
1313 *****************************************************************************/
1317 /*********** Functions for integer divisions *****************************
1319 On some systems (eg. DEC ALPHA), integer division is not supported by the
1320 CPU. These helper functions implement the missing functionality.
1322 ******************************************************************************/
1324 s4 builtin_idiv (s4 a, s4 b) { return a/b; }
1325 s4 builtin_irem (s4 a, s4 b) { return a%b; }
1328 /************** Functions for long arithmetics *******************************
1330 On systems where 64 bit Integers are not supported by the CPU, these
1331 functions are needed.
1333 ******************************************************************************/
1336 s8 builtin_ladd (s8 a, s8 b)
1341 return builtin_i2l(0);
1345 s8 builtin_lsub (s8 a, s8 b)
1350 return builtin_i2l(0);
1354 s8 builtin_lmul (s8 a, s8 b)
1359 return builtin_i2l(0);
1363 s8 builtin_ldiv (s8 a, s8 b)
1368 return builtin_i2l(0);
1372 s8 builtin_lrem (s8 a, s8 b)
1377 return builtin_i2l(0);
1381 s8 builtin_lshl (s8 a, s4 b)
1386 return builtin_i2l(0);
1390 s8 builtin_lshr (s8 a, s4 b)
1395 return builtin_i2l(0);
1399 s8 builtin_lushr (s8 a, s4 b)
1402 return ((u8)a)>>(b&63);
1404 return builtin_i2l(0);
1408 s8 builtin_land (s8 a, s8 b)
1413 return builtin_i2l(0);
1417 s8 builtin_lor (s8 a, s8 b)
1422 return builtin_i2l(0);
1426 s8 builtin_lxor (s8 a, s8 b)
1431 return builtin_i2l(0);
1435 s8 builtin_lneg (s8 a)
1440 return builtin_i2l(0);
1444 s4 builtin_lcmp (s8 a, s8 b)
1459 /*********** Functions for floating point operations *************************/
1461 float builtin_fadd (float a, float b)
1463 if (isnanf(a)) return FLT_NAN;
1464 if (isnanf(b)) return FLT_NAN;
1466 if (finitef(b)) return a+b;
1470 if (finitef(b)) return a;
1472 if (copysignf(1.0, a)==copysignf(1.0, b)) return a;
1473 else return FLT_NAN;
1478 float builtin_fsub (float a, float b)
1480 return builtin_fadd (a, builtin_fneg(b));
1483 float builtin_fmul (float a, float b)
1485 if (isnanf(a)) return FLT_NAN;
1486 if (isnanf(b)) return FLT_NAN;
1488 if (finitef(b)) return a*b;
1490 if (a==0) return FLT_NAN;
1491 else return copysignf(b, copysignf(1.0, b)*a);
1496 if (b==0) return FLT_NAN;
1497 else return copysignf(a, copysignf(1.0, a)*b);
1500 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1505 float builtin_fdiv (float a, float b)
1507 if (finitef(a) && finitef(b)) {
1520 float builtin_frem (float a, float b)
1526 float builtin_fneg (float a)
1528 if (isnanf(a)) return a;
1530 if (finitef(a)) return -a;
1531 else return copysignf(a,-copysignf(1.0, a));
1535 s4 builtin_fcmpl (float a, float b)
1537 if (isnanf(a)) return -1;
1538 if (isnanf(b)) return -1;
1539 if (!finitef(a) || !finitef(b)) {
1540 a = finitef(a) ? 0 : copysignf(1.0, a);
1541 b = finitef(b) ? 0 : copysignf(1.0, b);
1548 s4 builtin_fcmpg (float a, float b)
1550 if (isnanf(a)) return 1;
1551 if (isnanf(b)) return 1;
1552 if (!finitef(a) || !finitef(b)) {
1553 a = finitef(a) ? 0 : copysignf(1.0, a);
1554 b = finitef(b) ? 0 : copysignf(1.0, b);
1563 /************************* Functions for doubles ****************************/
1565 double builtin_dadd (double a, double b)
1567 if (isnan(a)) return DBL_NAN;
1568 if (isnan(b)) return DBL_NAN;
1570 if (finite(b)) return a+b;
1574 if (finite(b)) return a;
1576 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1577 else return DBL_NAN;
1582 double builtin_dsub (double a, double b)
1584 return builtin_dadd (a, builtin_dneg(b));
1587 double builtin_dmul (double a, double b)
1589 if (isnan(a)) return DBL_NAN;
1590 if (isnan(b)) return DBL_NAN;
1592 if (finite(b)) return a*b;
1594 if (a==0) return DBL_NAN;
1595 else return copysign(b, copysign(1.0, b)*a);
1600 if (b==0) return DBL_NAN;
1601 else return copysign(a, copysign(1.0, a)*b);
1604 return copysign(a, copysign(1.0, a)*copysign(1.0, b));
1609 double builtin_ddiv (double a, double b)
1611 if (finite(a) && finite(b)) {
1624 double builtin_drem (double a, double b)
1629 double builtin_dneg (double a)
1631 if (isnan(a)) return a;
1633 if (finite(a)) return -a;
1634 else return copysign(a,-copysign(1.0, a));
1638 s4 builtin_dcmpl (double a, double b)
1640 if (isnan(a)) return -1;
1641 if (isnan(b)) return -1;
1642 if (!finite(a) || !finite(b)) {
1643 a = finite(a) ? 0 : copysign(1.0, a);
1644 b = finite(b) ? 0 : copysign(1.0, b);
1651 s4 builtin_dcmpg (double a, double b)
1653 if (isnan(a)) return 1;
1654 if (isnan(b)) return 1;
1655 if (!finite(a) || !finite(b)) {
1656 a = finite(a) ? 0 : copysign(1.0, a);
1657 b = finite(b) ? 0 : copysign(1.0, b);
1665 /*********************** Conversion operations ****************************/
1667 s8 builtin_i2l (s4 i)
1672 s8 v; v.high = 0; v.low=i; return v;
1676 float builtin_i2f (s4 a)
1678 float f = (float) a;
1682 double builtin_i2d (s4 a)
1684 double d = (double) a;
1689 s4 builtin_l2i (s8 l)
1698 float builtin_l2f (s8 a)
1701 float f = (float) a;
1708 double builtin_l2d (s8 a)
1711 double d = (double) a;
1719 s4 builtin_f2i(float a)
1722 return builtin_d2i((double) a);
1731 if (a < (-2147483648))
1732 return (-2147483648);
1735 f = copysignf((float) 1.0, a);
1738 return (-2147483648); */
1742 s8 builtin_f2l (float a)
1745 return builtin_d2l((double) a);
1750 if (a > 9223372036854775807L)
1751 return 9223372036854775807L;
1752 if (a < (-9223372036854775808L))
1753 return (-9223372036854775808L);
1758 f = copysignf((float) 1.0, a);
1760 return 9223372036854775807L;
1761 return (-9223372036854775808L); */
1765 double builtin_f2d (float a)
1767 if (finitef(a)) return (double) a;
1769 if (isnanf(a)) return DBL_NAN;
1770 else return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1775 s4 builtin_d2i (double a)
1780 if (a >= 2147483647)
1782 if (a <= (-2147483647-1))
1783 return (-2147483647-1);
1788 d = copysign(1.0, a);
1791 return (-2147483647-1);
1795 s8 builtin_d2l (double a)
1800 if (a >= 9223372036854775807LL)
1801 return 9223372036854775807LL;
1802 if (a <= (-9223372036854775807LL-1))
1803 return (-9223372036854775807LL-1);
1808 d = copysign(1.0, a);
1810 return 9223372036854775807LL;
1811 return (-9223372036854775807LL-1);
1815 float builtin_d2f (double a)
1817 if (finite(a)) return (float) a;
1819 if (isnan(a)) return FLT_NAN;
1820 else return copysignf (FLT_POSINF, (float) copysign(1.0, a));
1826 * These are local overrides for various environment variables in Emacs.
1827 * Please do not remove this and leave it at the end of the file, where
1828 * Emacs will automagically detect them.
1829 * ---------------------------------------------------------------------
1832 * indent-tabs-mode: t