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 {(functionptr) builtin_d2f, "d2f"},
119 {(functionptr) NULL, "unknown"}
123 /*****************************************************************************
125 *****************************************************************************/
129 /*************** internal function: builtin_isanysubclass *********************
131 Checks a subclass relation between two classes. Implemented interfaces
132 are interpreted as super classes.
133 Return value: 1 ... sub is subclass of super
136 *****************************************************************************/
138 s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
140 if (super->flags & ACC_INTERFACE)
141 return (sub->vftbl->interfacetablelength > super->index) &&
142 (sub->vftbl->interfacetable[-super->index] != NULL);
154 return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <=
155 (unsigned) (super->vftbl->diffval);
159 /****************** function: builtin_instanceof *****************************
161 Checks if an object is an instance of some given class (or subclass of
162 that class). If class is an interface, checks if the interface is
164 Return value: 1 ... obj is an instance of class or implements the interface
165 0 ... otherwise or if obj == NULL
167 *****************************************************************************/
169 s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
172 log_text ("builtin_instanceof called");
176 return builtin_isanysubclass (obj->vftbl->class, class);
181 /**************** function: builtin_checkcast *******************************
183 The same as builtin_instanceof except that 1 is returned when
186 ****************************************************************************/
188 s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
191 log_text ("builtin_checkcast called");
196 if (builtin_isanysubclass (obj->vftbl->class, class))
200 printf ("#### checkcast failed ");
201 utf_display (obj->vftbl->class->name);
203 utf_display (class->name);
211 /*********** internal function: builtin_descriptorscompatible ******************
213 Checks if two array type descriptors are assignment compatible
214 Return value: 1 ... target = desc is possible
217 ******************************************************************************/
219 static s4 builtin_descriptorscompatible(constant_arraydescriptor *desc, constant_arraydescriptor *target)
221 if (desc==target) return 1;
222 if (desc->arraytype != target->arraytype) return 0;
223 switch (target->arraytype) {
224 case ARRAYTYPE_OBJECT:
225 return builtin_isanysubclass (desc->objectclass, target->objectclass);
226 case ARRAYTYPE_ARRAY:
227 return builtin_descriptorscompatible
228 (desc->elementdescriptor, target->elementdescriptor);
235 /******************** function: builtin_checkarraycast ***********************
237 Checks if an object is really a subtype of the requested array type.
238 The object has to be an array to begin with. For simple arrays (int, short,
239 double, etc.) the types have to match exactly.
240 For arrays of objects, the type of elements in the array has to be a
241 subtype (or the same type) of the requested element type. For arrays of
242 arrays (which in turn can again be arrays of arrays), the types at the
243 lowest level have to satisfy the corresponding sub class relation.
245 Return value: 1 ... cast is possible
248 ATTENTION: a cast with a NULL pointer is always possible.
250 *****************************************************************************/
252 s4 builtin_checkarraycast(java_objectheader *o, constant_arraydescriptor *desc)
254 java_arrayheader *a = (java_arrayheader*) o;
257 if (o->vftbl->class != class_array) {
259 printf ("#### checkarraycast failed 1\n");
264 if (a->arraytype != desc->arraytype) {
266 printf ("#### checkarraycast failed 2\n");
271 switch (a->arraytype) {
272 case ARRAYTYPE_OBJECT: {
273 java_objectarray *oa = (java_objectarray*) o;
274 int result = builtin_isanysubclass (oa->elementtype, desc->objectclass);
278 printf ("#### checkarraycast failed 3\n");
282 case ARRAYTYPE_ARRAY: {
283 java_arrayarray *aa = (java_arrayarray*) o;
284 int result = builtin_descriptorscompatible
285 (aa->elementdescriptor, desc->elementdescriptor);
289 printf ("#### checkarraycast failed 4\n");
299 s4 builtin_arrayinstanceof(java_objectheader *obj, constant_arraydescriptor *desc)
302 return builtin_checkarraycast (obj, desc);
306 /************************** exception functions *******************************
308 ******************************************************************************/
310 java_objectheader *builtin_throw_exception (java_objectheader *local_exceptionptr) {
312 sprintf(logtext, "Builtin exception thrown: ");
313 utf_sprint(logtext + strlen(logtext), local_exceptionptr->vftbl->class->name);
316 exceptionptr = local_exceptionptr;
317 return local_exceptionptr;
321 /******************* function: builtin_canstore *******************************
323 Checks, if an object can be stored in an array.
324 Return value: 1 ... possible
327 ******************************************************************************/
330 s4 builtin_canstore (java_objectarray *a, java_objectheader *o)
334 switch (a->header.arraytype) {
335 case ARRAYTYPE_OBJECT:
336 if ( ! builtin_checkcast (o, a->elementtype) ) {
342 case ARRAYTYPE_ARRAY:
343 if ( ! builtin_checkarraycast
344 (o, ((java_arrayarray*)a)->elementdescriptor) ) {
351 panic ("builtin_canstore called with invalid arraytype");
358 /*****************************************************************************
360 *****************************************************************************/
364 /******************** Function: builtin_new **********************************
366 Creates a new instance of class c on the heap.
367 Return value: pointer to the object or NULL if no memory is
370 *****************************************************************************/
373 #define align_size(size) ((size + ((1 << ALIGNMENT) - 1)) & ~((1 << ALIGNMENT) - 1))
375 java_objectheader *builtin_new(classinfo *c)
377 java_objectheader *o;
381 #ifdef SIZE_FROM_CLASSINFO
382 c->alignedsize = align_size(c->instancesize);
383 o = heap_allocate(c->alignedsize, true, c->finalizer);
385 o = heap_allocate(c->instancesize, true, c->finalizer);
389 memset(o, 0, c->instancesize);
398 /******************** function: builtin_anewarray ****************************
400 Creates an array of pointers to objects on the heap.
402 size ......... number of elements
403 elementtype .. pointer to the classinfo structure for the element type
405 Return value: pointer to the array or NULL if no memory is available
407 *****************************************************************************/
409 void XXX_copy_vftbl(vftbl **dest, vftbl *src)
411 *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr)*(src->vftbllength-1));
412 memcpy(*dest, src, sizeof(vftbl) - sizeof(methodptr));
413 memcpy(&(*dest)->table, &src->table, src->vftbllength * sizeof(methodptr));
416 void XXX_use_class_as_object(classinfo *c, char *cname)
418 vftbl *vt = class_get(utf_new_char(cname))->vftbl;
420 if (!c->classvftbl) {
421 c->classvftbl = true;
422 XXX_copy_vftbl(&newtbl, vt);
423 newtbl->class = c->header.vftbl->class;
424 newtbl->baseval = c->header.vftbl->baseval;
425 newtbl->diffval = c->header.vftbl->diffval;
426 c->header.vftbl = newtbl;
431 void* __builtin_newarray(s4 base_size,
440 #ifdef SIZE_FROM_CLASSINFO
441 s4 alignedsize = align_size(base_size + (size-1) * elementsize);
442 a = heap_allocate( alignedsize, references, NULL );
444 a = heap_allocate(sizeof(java_objectarray) + (size-1) * elementsize,
450 #ifdef SIZE_FROM_CLASSINFO
451 memset(a, 0, alignedsize);
453 memset(a, 0, base_size + (size-1) * elementsize);
462 c = create_array_class(utf_new_char("[I"));
463 XXX_use_class_as_object(c, "int");
467 c = create_array_class(utf_new_char("[J"));
468 XXX_use_class_as_object(c, "long");
471 case ARRAYTYPE_FLOAT:
472 c = create_array_class(utf_new_char("[F"));
473 XXX_use_class_as_object(c, "float");
476 case ARRAYTYPE_DOUBLE:
477 c = create_array_class(utf_new_char("[D"));
478 XXX_use_class_as_object(c, "double");
482 c = create_array_class(utf_new_char("[B"));
483 XXX_use_class_as_object(c, "byte");
487 c = create_array_class(utf_new_char("[C"));
488 XXX_use_class_as_object(c, "char");
491 case ARRAYTYPE_SHORT:
492 c = create_array_class(utf_new_char("[S"));
493 XXX_use_class_as_object(c, "short");
496 case ARRAYTYPE_BOOLEAN:
497 c = create_array_class(utf_new_char("[Z"));
498 XXX_use_class_as_object(c, "boolean");
501 case ARRAYTYPE_OBJECT:
504 cname = heap_allocate(utf_strlen(el->name), false, NULL);
505 utf_sprint(cname, el->name);
506 buf = heap_allocate(strlen(cname) + 3, false, NULL);
507 /* printf("\n\n[L%s;\n\n", cname); */
508 sprintf(buf, "[L%s;", cname);
509 c = create_array_class(utf_new_char(buf));
510 /* MFREE(buf, char, strlen(cname) + 3); */
511 /* MFREE(cname, char, utf_strlen(el->name)); */
512 XXX_use_class_as_object(c, cname);
516 case ARRAYTYPE_ARRAY:
517 c = create_array_class(utf_new_char("[["));
518 XXX_use_class_as_object(c, "java/lang/Boolean");
522 panic("unknown array type");
525 a->objheader.vftbl = c->vftbl;
528 a->objheader.vftbl = class_array->vftbl;
531 #ifdef SIZE_FROM_CLASSINFO
532 a -> alignedsize = alignedsize;
534 a -> arraytype = arraytype;
540 java_objectarray *builtin_anewarray (s4 size, classinfo *elementtype)
543 a = (java_objectarray*)__builtin_newarray(sizeof(java_objectarray),
551 a -> elementtype = elementtype;
557 /******************** function: builtin_newarray_array ***********************
559 Creates an array of pointers to arrays on the heap.
561 size ......... number of elements
562 elementdesc .. pointer to the array description structure for the
565 Return value: pointer to the array or NULL if no memory is available
567 *****************************************************************************/
569 java_arrayarray *builtin_newarray_array
570 (s4 size, constant_arraydescriptor *elementdesc)
573 a = (java_arrayarray*)__builtin_newarray(sizeof(java_arrayarray),
578 elementdesc->objectclass);
581 a -> elementdescriptor = elementdesc;
586 /******************** function: builtin_newarray_boolean ************************
588 Creates an array of bytes on the heap. The array is designated as an array
589 of booleans (important for casts)
591 Return value: pointer to the array or NULL if no memory is available
593 *****************************************************************************/
595 java_booleanarray *builtin_newarray_boolean (s4 size)
597 java_booleanarray *a;
598 a = (java_booleanarray*)__builtin_newarray(sizeof(java_booleanarray),
607 /******************** function: builtin_newarray_char ************************
609 Creates an array of characters on the heap.
611 Return value: pointer to the array or NULL if no memory is available
613 *****************************************************************************/
615 java_chararray *builtin_newarray_char (s4 size)
618 a = (java_chararray*)__builtin_newarray(sizeof(java_chararray),
628 /******************** function: builtin_newarray_float ***********************
630 Creates an array of 32 bit IEEE floats on the heap.
632 Return value: pointer to the array or NULL if no memory is available
634 *****************************************************************************/
636 java_floatarray *builtin_newarray_float (s4 size)
639 a = (java_floatarray*)__builtin_newarray(sizeof(java_floatarray),
649 /******************** function: builtin_newarray_double ***********************
651 Creates an array of 64 bit IEEE floats on the heap.
653 Return value: pointer to the array or NULL if no memory is available
655 *****************************************************************************/
657 java_doublearray *builtin_newarray_double (s4 size)
660 a = (java_doublearray*)__builtin_newarray(sizeof(java_doublearray),
672 /******************** function: builtin_newarray_byte ***********************
674 Creates an array of 8 bit Integers on the heap.
676 Return value: pointer to the array or NULL if no memory is available
678 *****************************************************************************/
680 java_bytearray *builtin_newarray_byte (s4 size)
683 a = (java_bytearray*)__builtin_newarray(sizeof(java_bytearray),
693 /******************** function: builtin_newarray_short ***********************
695 Creates an array of 16 bit Integers on the heap.
697 Return value: pointer to the array or NULL if no memory is available
699 *****************************************************************************/
701 java_shortarray *builtin_newarray_short (s4 size)
704 a = (java_shortarray*)__builtin_newarray(sizeof(java_shortarray),
714 /******************** Function: builtin_newarray_int ***********************
716 Creates an array of 32 bit Integers on the heap.
718 Return value: pointer to the array or NULL if no memory is available
720 *****************************************************************************/
722 java_intarray *builtin_newarray_int (s4 size)
725 a = (java_intarray*)__builtin_newarray(sizeof(java_intarray),
735 /******************** Function: builtin_newarray_long ***********************
737 Creates an array of 64 bit Integers on the heap.
739 Return value: pointer to the array or NULL if no memory is available
741 *****************************************************************************/
743 java_longarray *builtin_newarray_long (s4 size)
746 a = (java_longarray*)__builtin_newarray(sizeof(java_longarray),
757 /***************** function: builtin_multianewarray ***************************
759 Creates a multi-dimensional array on the heap. The dimensions are passed in
760 an array of Integers. The type for the array is passed as a reference to a
761 constant_arraydescriptor structure.
763 Return value: pointer to the array or NULL if no memory is available
765 ******************************************************************************/
767 /* Helper functions */
769 static java_arrayheader *multianewarray_part (java_intarray *dims, int thisdim,
770 constant_arraydescriptor *desc)
775 size = dims -> data[thisdim];
777 if (thisdim == (dims->header.size-1)) {
778 /* last dimension reached */
780 switch (desc -> arraytype) {
781 case ARRAYTYPE_BOOLEAN:
782 return (java_arrayheader*) builtin_newarray_boolean (size);
784 return (java_arrayheader*) builtin_newarray_char (size);
785 case ARRAYTYPE_FLOAT:
786 return (java_arrayheader*) builtin_newarray_float (size);
787 case ARRAYTYPE_DOUBLE:
788 return (java_arrayheader*) builtin_newarray_double (size);
790 return (java_arrayheader*) builtin_newarray_byte (size);
791 case ARRAYTYPE_SHORT:
792 return (java_arrayheader*) builtin_newarray_short (size);
794 return (java_arrayheader*) builtin_newarray_int (size);
796 return (java_arrayheader*) builtin_newarray_long (size);
797 case ARRAYTYPE_OBJECT:
798 return (java_arrayheader*) builtin_anewarray (size, desc->objectclass);
800 case ARRAYTYPE_ARRAY:
801 return (java_arrayheader*) builtin_newarray_array (size, desc->elementdescriptor);
803 default: panic ("Invalid arraytype in multianewarray");
807 /* if the last dimension has not been reached yet */
809 if (desc->arraytype != ARRAYTYPE_ARRAY)
810 panic ("multianewarray with too many dimensions");
812 a = builtin_newarray_array (size, desc->elementdescriptor);
815 for (i=0; i<size; i++) {
816 java_arrayheader *ea =
817 multianewarray_part (dims, thisdim+1, desc->elementdescriptor);
818 if (!ea) return NULL;
823 return (java_arrayheader*) a;
827 java_arrayheader *builtin_multianewarray (java_intarray *dims,
828 constant_arraydescriptor *desc)
830 return multianewarray_part (dims, 0, desc);
834 static java_arrayheader *nmultianewarray_part (int n, long *dims, int thisdim,
835 constant_arraydescriptor *desc)
840 size = (int) dims[thisdim];
842 if (thisdim == (n - 1)) {
843 /* last dimension reached */
845 switch (desc -> arraytype) {
846 case ARRAYTYPE_BOOLEAN:
847 return (java_arrayheader*) builtin_newarray_boolean(size);
849 return (java_arrayheader*) builtin_newarray_char(size);
850 case ARRAYTYPE_FLOAT:
851 return (java_arrayheader*) builtin_newarray_float(size);
852 case ARRAYTYPE_DOUBLE:
853 return (java_arrayheader*) builtin_newarray_double(size);
855 return (java_arrayheader*) builtin_newarray_byte(size);
856 case ARRAYTYPE_SHORT:
857 return (java_arrayheader*) builtin_newarray_short(size);
859 return (java_arrayheader*) builtin_newarray_int(size);
861 return (java_arrayheader*) builtin_newarray_long(size);
862 case ARRAYTYPE_OBJECT:
863 return (java_arrayheader*) builtin_anewarray(size,
865 case ARRAYTYPE_ARRAY:
866 return (java_arrayheader*) builtin_newarray_array(size,
867 desc->elementdescriptor);
869 default: panic ("Invalid arraytype in multianewarray");
873 /* if the last dimension has not been reached yet */
875 if (desc->arraytype != ARRAYTYPE_ARRAY)
876 panic ("multianewarray with too many dimensions");
878 a = builtin_newarray_array(size, desc->elementdescriptor);
881 for (i = 0; i < size; i++) {
882 java_arrayheader *ea =
883 nmultianewarray_part(n, dims, thisdim + 1, desc->elementdescriptor);
884 if (!ea) return NULL;
889 return (java_arrayheader*) a;
893 java_arrayheader *builtin_nmultianewarray (int size,
894 constant_arraydescriptor *desc, long *dims)
896 (void) builtin_newarray_int(size); /* for compatibility with -old */
897 return nmultianewarray_part (size, dims, 0, desc);
903 /************************* function: builtin_aastore *************************
905 Stores a reference to an object into an object array or into an array
906 array. Before any action is performed, the validity of the operation is
909 Return value: 1 ... ok
910 0 ... this object cannot be stored into this array
912 *****************************************************************************/
914 s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o)
916 if (builtin_canstore(a,o)) {
928 /*****************************************************************************
931 Various functions for printing a message at method entry or exit (for
934 *****************************************************************************/
939 java_objectheader *builtin_trace_exception (java_objectheader *exceptionptr,
940 methodinfo *method, int *pos, int noindent) {
944 if (verbose || runverbose) {
945 printf("Exception ");
946 utf_display (exceptionptr->vftbl->class->name);
947 printf(" thrown in ");
949 utf_display (method->class->name);
951 utf_display (method->name);
952 if (method->flags & ACC_SYNCHRONIZED)
956 printf("(%p) at position %p\n", method->entrypoint, pos);
959 printf("call_java_method\n");
966 #ifdef TRACE_ARGS_NUM
967 void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5,
968 #if TRACE_ARGS_NUM > 6
974 for (i=0; i<methodindent; i++)
976 sprintf (logtext+methodindent, "called: ");
977 utf_sprint (logtext+strlen(logtext), method->class->name);
978 sprintf (logtext+strlen(logtext), ".");
979 utf_sprint (logtext+strlen(logtext), method->name);
980 utf_sprint (logtext+strlen(logtext), method->descriptor);
981 sprintf (logtext+strlen(logtext), "(");
982 switch (method->paramcount) {
987 sprintf(logtext+strlen(logtext), "%llx", a0);
991 sprintf(logtext+strlen(logtext), "%llx, %llx", a0, a1);
995 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx", a0, a1, a2);
999 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx",
1004 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx",
1005 a0, a1, a2, a3, a4);
1009 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx",
1010 a0, a1, a2, a3, a4, a5);
1013 #if TRACE_ARGS_NUM > 6
1015 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx",
1016 a0, a1, a2, a3, a4, a5, a6);
1020 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx",
1021 a0, a1, a2, a3, a4, a5, a6, a7);
1025 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
1026 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
1030 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
1031 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
1035 sprintf (logtext+strlen(logtext), ")");
1042 void builtin_displaymethodstart(methodinfo *method)
1044 sprintf (logtext, " ");
1045 sprintf (logtext+methodindent, "called: ");
1046 utf_sprint (logtext+strlen(logtext), method->class->name);
1047 sprintf (logtext+strlen(logtext), ".");
1048 utf_sprint (logtext+strlen(logtext), method->name);
1049 utf_sprint (logtext+strlen(logtext), method->descriptor);
1054 void builtin_displaymethodstop(methodinfo *method, s8 l, double d, float f)
1057 for (i=0; i<methodindent; i++)
1060 sprintf (logtext+methodindent, "finished: ");
1061 utf_sprint (logtext+strlen(logtext), method->class->name);
1062 sprintf (logtext+strlen(logtext), ".");
1063 utf_sprint (logtext+strlen(logtext), method->name);
1064 utf_sprint (logtext+strlen(logtext), method->descriptor);
1065 switch (method->returntype) {
1067 sprintf (logtext+strlen(logtext), "->%d", (s4) l);
1070 #if defined(__I386__)
1071 sprintf(logtext+strlen(logtext), "->%lld", (s8) l);
1073 sprintf(logtext+strlen(logtext), "->%ld", (s8) l);
1077 #if defined(__I386__)
1078 sprintf(logtext+strlen(logtext), "->%p", (u1*) ((s4) l));
1080 sprintf(logtext+strlen(logtext), "->%p", (u1*) l);
1084 sprintf (logtext+strlen(logtext), "->%g", f);
1087 sprintf (logtext+strlen(logtext), "->%g", d);
1093 void builtin_displaymethodexception(methodinfo *method)
1096 for (i=0; i<methodindent; i++)
1098 sprintf (logtext+methodindent, "exception abort: ");
1099 utf_sprint (logtext+strlen(logtext), method->class->name);
1100 sprintf (logtext+strlen(logtext), ".");
1101 utf_sprint (logtext+strlen(logtext), method->name);
1102 utf_sprint (logtext+strlen(logtext), method->descriptor);
1107 /****************************************************************************
1108 SYNCHRONIZATION FUNCTIONS
1109 *****************************************************************************/
1112 * Lock the mutex of an object.
1116 internal_lock_mutex_for_object (java_objectheader *object)
1118 mutexHashEntry *entry;
1121 assert(object != 0);
1123 hashValue = MUTEX_HASH_VALUE(object);
1124 entry = &mutexHashTable[hashValue];
1126 if (entry->object != 0)
1128 if (entry->mutex.count == 0 && entry->conditionCount == 0)
1131 entry->mutex.holder = 0;
1132 entry->mutex.count = 0;
1133 entry->mutex.muxWaiters = 0;
1137 while (entry->next != 0 && entry->object != object)
1138 entry = entry->next;
1140 if (entry->object != object)
1142 entry->next = firstFreeOverflowEntry;
1143 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
1145 entry = entry->next;
1148 assert(entry->conditionCount == 0);
1154 entry->mutex.holder = 0;
1155 entry->mutex.count = 0;
1156 entry->mutex.muxWaiters = 0;
1159 if (entry->object == 0)
1160 entry->object = object;
1162 internal_lock_mutex(&entry->mutex);
1168 * Unlocks the mutex of an object.
1172 internal_unlock_mutex_for_object (java_objectheader *object)
1175 mutexHashEntry *entry;
1177 hashValue = MUTEX_HASH_VALUE(object);
1178 entry = &mutexHashTable[hashValue];
1180 if (entry->object == object)
1181 internal_unlock_mutex(&entry->mutex);
1184 while (entry->next != 0 && entry->next->object != object)
1185 entry = entry->next;
1187 assert(entry->next != 0);
1189 internal_unlock_mutex(&entry->next->mutex);
1191 if (entry->next->mutex.count == 0 && entry->conditionCount == 0)
1193 mutexHashEntry *unlinked = entry->next;
1195 entry->next = unlinked->next;
1196 unlinked->next = firstFreeOverflowEntry;
1197 firstFreeOverflowEntry = unlinked;
1204 builtin_monitorenter (java_objectheader *o)
1209 assert(blockInts == 0);
1213 hashValue = MUTEX_HASH_VALUE(o);
1214 if (mutexHashTable[hashValue].object == o
1215 && mutexHashTable[hashValue].mutex.holder == currentThread)
1216 ++mutexHashTable[hashValue].mutex.count;
1218 internal_lock_mutex_for_object(o);
1222 assert(blockInts == 0);
1226 void builtin_monitorexit (java_objectheader *o)
1231 assert(blockInts == 0);
1235 hashValue = MUTEX_HASH_VALUE(o);
1236 if (mutexHashTable[hashValue].object == o)
1238 if (mutexHashTable[hashValue].mutex.count == 1
1239 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1240 internal_unlock_mutex_for_object(o);
1242 --mutexHashTable[hashValue].mutex.count;
1245 internal_unlock_mutex_for_object(o);
1249 assert(blockInts == 0);
1254 /*****************************************************************************
1255 MISCELLANEOUS HELPER FUNCTIONS
1256 *****************************************************************************/
1260 /*********** Functions for integer divisions *****************************
1262 On some systems (eg. DEC ALPHA), integer division is not supported by the
1263 CPU. These helper functions implement the missing functionality.
1265 ******************************************************************************/
1267 s4 builtin_idiv (s4 a, s4 b) { return a/b; }
1268 s4 builtin_irem (s4 a, s4 b) { return a%b; }
1271 /************** Functions for long arithmetics *******************************
1273 On systems where 64 bit Integers are not supported by the CPU, these
1274 functions are needed.
1276 ******************************************************************************/
1279 s8 builtin_ladd (s8 a, s8 b)
1284 return builtin_i2l(0);
1288 s8 builtin_lsub (s8 a, s8 b)
1293 return builtin_i2l(0);
1297 s8 builtin_lmul (s8 a, s8 b)
1302 return builtin_i2l(0);
1306 s8 builtin_ldiv (s8 a, s8 b)
1311 return builtin_i2l(0);
1315 s8 builtin_lrem (s8 a, s8 b)
1320 return builtin_i2l(0);
1324 s8 builtin_lshl (s8 a, s4 b)
1329 return builtin_i2l(0);
1333 s8 builtin_lshr (s8 a, s4 b)
1338 return builtin_i2l(0);
1342 s8 builtin_lushr (s8 a, s4 b)
1345 return ((u8)a)>>(b&63);
1347 return builtin_i2l(0);
1351 s8 builtin_land (s8 a, s8 b)
1356 return builtin_i2l(0);
1360 s8 builtin_lor (s8 a, s8 b)
1365 return builtin_i2l(0);
1369 s8 builtin_lxor (s8 a, s8 b)
1374 return builtin_i2l(0);
1378 s8 builtin_lneg (s8 a)
1383 return builtin_i2l(0);
1387 s4 builtin_lcmp (s8 a, s8 b)
1402 /*********** Functions for floating point operations *************************/
1404 float builtin_fadd (float a, float b)
1406 if (isnanf(a)) return FLT_NAN;
1407 if (isnanf(b)) return FLT_NAN;
1409 if (finitef(b)) return a+b;
1413 if (finitef(b)) return a;
1415 if (copysignf(1.0, a)==copysignf(1.0, b)) return a;
1416 else return FLT_NAN;
1421 float builtin_fsub (float a, float b)
1423 return builtin_fadd (a, builtin_fneg(b));
1426 float builtin_fmul (float a, float b)
1428 if (isnanf(a)) return FLT_NAN;
1429 if (isnanf(b)) return FLT_NAN;
1431 if (finitef(b)) return a*b;
1433 if (a==0) return FLT_NAN;
1434 else return copysignf(b, copysignf(1.0, b)*a);
1439 if (b==0) return FLT_NAN;
1440 else return copysignf(a, copysignf(1.0, a)*b);
1443 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1448 float builtin_fdiv (float a, float b)
1450 if (finitef(a) && finitef(b)) {
1463 float builtin_frem (float a, float b)
1469 float builtin_fneg (float a)
1471 if (isnanf(a)) return a;
1473 if (finitef(a)) return -a;
1474 else return copysignf(a,-copysignf(1.0, a));
1478 s4 builtin_fcmpl (float a, float b)
1480 if (isnanf(a)) return -1;
1481 if (isnanf(b)) return -1;
1482 if (!finitef(a) || !finitef(b)) {
1483 a = finitef(a) ? 0 : copysignf(1.0, a);
1484 b = finitef(b) ? 0 : copysignf(1.0, b);
1491 s4 builtin_fcmpg (float a, float b)
1493 if (isnanf(a)) return 1;
1494 if (isnanf(b)) return 1;
1495 if (!finitef(a) || !finitef(b)) {
1496 a = finitef(a) ? 0 : copysignf(1.0, a);
1497 b = finitef(b) ? 0 : copysignf(1.0, b);
1506 /************************* Functions for doubles ****************************/
1508 double builtin_dadd (double a, double b)
1510 if (isnan(a)) return DBL_NAN;
1511 if (isnan(b)) return DBL_NAN;
1513 if (finite(b)) return a+b;
1517 if (finite(b)) return a;
1519 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1520 else return DBL_NAN;
1525 double builtin_dsub (double a, double b)
1527 return builtin_dadd (a, builtin_dneg(b));
1530 double builtin_dmul (double a, double b)
1532 if (isnan(a)) return DBL_NAN;
1533 if (isnan(b)) return DBL_NAN;
1535 if (finite(b)) return a*b;
1537 if (a==0) return DBL_NAN;
1538 else return copysign(b, copysign(1.0, b)*a);
1543 if (b==0) return DBL_NAN;
1544 else return copysign(a, copysign(1.0, a)*b);
1547 return copysign(a, copysign(1.0, a)*copysign(1.0, b));
1552 double builtin_ddiv (double a, double b)
1554 if (finite(a) && finite(b)) {
1567 double builtin_drem (double a, double b)
1572 double builtin_dneg (double a)
1574 if (isnan(a)) return a;
1576 if (finite(a)) return -a;
1577 else return copysign(a,-copysign(1.0, a));
1581 s4 builtin_dcmpl (double a, double b)
1583 if (isnan(a)) return -1;
1584 if (isnan(b)) return -1;
1585 if (!finite(a) || !finite(b)) {
1586 a = finite(a) ? 0 : copysign(1.0, a);
1587 b = finite(b) ? 0 : copysign(1.0, b);
1594 s4 builtin_dcmpg (double a, double b)
1596 if (isnan(a)) return 1;
1597 if (isnan(b)) return 1;
1598 if (!finite(a) || !finite(b)) {
1599 a = finite(a) ? 0 : copysign(1.0, a);
1600 b = finite(b) ? 0 : copysign(1.0, b);
1608 /*********************** Conversion operations ****************************/
1610 s8 builtin_i2l (s4 i)
1615 s8 v; v.high = 0; v.low=i; return v;
1619 float builtin_i2f (s4 a)
1621 float f = (float) a;
1625 double builtin_i2d (s4 a)
1627 double d = (double) a;
1632 s4 builtin_l2i (s8 l)
1641 float builtin_l2f (s8 a)
1644 float f = (float) a;
1651 double builtin_l2d (s8 a)
1654 double d = (double) a;
1662 s4 builtin_f2i(float a)
1665 return builtin_d2i((double) a);
1674 if (a < (-2147483648))
1675 return (-2147483648);
1678 f = copysignf((float) 1.0, a);
1681 return (-2147483648); */
1685 s8 builtin_f2l (float a)
1688 return builtin_d2l((double) a);
1693 if (a > 9223372036854775807L)
1694 return 9223372036854775807L;
1695 if (a < (-9223372036854775808L))
1696 return (-9223372036854775808L);
1701 f = copysignf((float) 1.0, a);
1703 return 9223372036854775807L;
1704 return (-9223372036854775808L); */
1708 double builtin_f2d (float a)
1710 if (finitef(a)) return (double) a;
1712 if (isnanf(a)) return DBL_NAN;
1713 else return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1718 s4 builtin_d2i (double a)
1723 if (a >= 2147483647)
1725 if (a <= (-2147483647-1))
1726 return (-2147483647-1);
1731 d = copysign(1.0, a);
1734 return (-2147483647-1);
1738 s8 builtin_d2l (double a)
1743 if (a >= 9223372036854775807LL)
1744 return 9223372036854775807LL;
1745 if (a <= (-9223372036854775807LL-1))
1746 return (-9223372036854775807LL-1);
1751 d = copysign(1.0, a);
1753 return 9223372036854775807LL;
1754 return (-9223372036854775807LL-1);
1758 float builtin_d2f (double a)
1760 if (finite(a)) return (float) a;
1762 if (isnan(a)) return FLT_NAN;
1763 else return copysignf (FLT_POSINF, (float) copysign(1.0, a));
1769 * These are local overrides for various environment variables in Emacs.
1770 * Please do not remove this and leave it at the end of the file, where
1771 * Emacs will automagically detect them.
1772 * ---------------------------------------------------------------------
1775 * indent-tabs-mode: t