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) {
986 #if defined(__I386__)
988 sprintf(logtext+strlen(logtext), "%llx", a0);
992 sprintf(logtext+strlen(logtext), "%llx, %llx", a0, a1);
996 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx", a0, a1, a2);
1000 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx",
1005 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx",
1006 a0, a1, a2, a3, a4);
1010 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx",
1011 a0, a1, a2, a3, a4, a5);
1014 #if TRACE_ARGS_NUM > 6
1016 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx",
1017 a0, a1, a2, a3, a4, a5, a6);
1021 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx",
1022 a0, a1, a2, a3, a4, a5, a6, a7);
1026 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
1027 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
1031 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
1032 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
1037 sprintf(logtext+strlen(logtext), "%lx", a0);
1041 sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1);
1045 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2);
1049 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx",
1054 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx",
1055 a0, a1, a2, a3, a4);
1059 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx",
1060 a0, a1, a2, a3, a4, a5);
1063 #if TRACE_ARGS_NUM > 6
1065 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx",
1066 a0, a1, a2, a3, a4, a5, a6);
1070 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx",
1071 a0, a1, a2, a3, a4, a5, a6, a7);
1075 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx, ...(%d)",
1076 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
1080 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, ...(%d)",
1081 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
1086 sprintf (logtext+strlen(logtext), ")");
1093 void builtin_displaymethodstart(methodinfo *method)
1095 sprintf (logtext, " ");
1096 sprintf (logtext+methodindent, "called: ");
1097 utf_sprint (logtext+strlen(logtext), method->class->name);
1098 sprintf (logtext+strlen(logtext), ".");
1099 utf_sprint (logtext+strlen(logtext), method->name);
1100 utf_sprint (logtext+strlen(logtext), method->descriptor);
1105 void builtin_displaymethodstop(methodinfo *method, s8 l, double d, float f)
1108 for (i=0; i<methodindent; i++)
1111 sprintf (logtext+methodindent, "finished: ");
1112 utf_sprint (logtext+strlen(logtext), method->class->name);
1113 sprintf (logtext+strlen(logtext), ".");
1114 utf_sprint (logtext+strlen(logtext), method->name);
1115 utf_sprint (logtext+strlen(logtext), method->descriptor);
1116 switch (method->returntype) {
1118 sprintf (logtext+strlen(logtext), "->%d", (s4) l);
1121 #if defined(__I386__)
1122 sprintf(logtext+strlen(logtext), "->%lld", (s8) l);
1124 sprintf(logtext+strlen(logtext), "->%ld", (s8) l);
1128 #if defined(__I386__)
1129 sprintf(logtext+strlen(logtext), "->%p", (u1*) ((s4) l));
1131 sprintf(logtext+strlen(logtext), "->%p", (u1*) l);
1135 sprintf (logtext+strlen(logtext), "->%g", f);
1138 sprintf (logtext+strlen(logtext), "->%g", d);
1144 void builtin_displaymethodexception(methodinfo *method)
1147 for (i=0; i<methodindent; i++)
1149 sprintf (logtext+methodindent, "exception abort: ");
1150 utf_sprint (logtext+strlen(logtext), method->class->name);
1151 sprintf (logtext+strlen(logtext), ".");
1152 utf_sprint (logtext+strlen(logtext), method->name);
1153 utf_sprint (logtext+strlen(logtext), method->descriptor);
1158 /****************************************************************************
1159 SYNCHRONIZATION FUNCTIONS
1160 *****************************************************************************/
1163 * Lock the mutex of an object.
1167 internal_lock_mutex_for_object (java_objectheader *object)
1169 mutexHashEntry *entry;
1172 assert(object != 0);
1174 hashValue = MUTEX_HASH_VALUE(object);
1175 entry = &mutexHashTable[hashValue];
1177 if (entry->object != 0)
1179 if (entry->mutex.count == 0 && entry->conditionCount == 0)
1182 entry->mutex.holder = 0;
1183 entry->mutex.count = 0;
1184 entry->mutex.muxWaiters = 0;
1188 while (entry->next != 0 && entry->object != object)
1189 entry = entry->next;
1191 if (entry->object != object)
1193 entry->next = firstFreeOverflowEntry;
1194 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
1196 entry = entry->next;
1199 assert(entry->conditionCount == 0);
1205 entry->mutex.holder = 0;
1206 entry->mutex.count = 0;
1207 entry->mutex.muxWaiters = 0;
1210 if (entry->object == 0)
1211 entry->object = object;
1213 internal_lock_mutex(&entry->mutex);
1219 * Unlocks the mutex of an object.
1223 internal_unlock_mutex_for_object (java_objectheader *object)
1226 mutexHashEntry *entry;
1228 hashValue = MUTEX_HASH_VALUE(object);
1229 entry = &mutexHashTable[hashValue];
1231 if (entry->object == object)
1232 internal_unlock_mutex(&entry->mutex);
1235 while (entry->next != 0 && entry->next->object != object)
1236 entry = entry->next;
1238 assert(entry->next != 0);
1240 internal_unlock_mutex(&entry->next->mutex);
1242 if (entry->next->mutex.count == 0 && entry->conditionCount == 0)
1244 mutexHashEntry *unlinked = entry->next;
1246 entry->next = unlinked->next;
1247 unlinked->next = firstFreeOverflowEntry;
1248 firstFreeOverflowEntry = unlinked;
1255 builtin_monitorenter (java_objectheader *o)
1260 assert(blockInts == 0);
1264 hashValue = MUTEX_HASH_VALUE(o);
1265 if (mutexHashTable[hashValue].object == o
1266 && mutexHashTable[hashValue].mutex.holder == currentThread)
1267 ++mutexHashTable[hashValue].mutex.count;
1269 internal_lock_mutex_for_object(o);
1273 assert(blockInts == 0);
1277 void builtin_monitorexit (java_objectheader *o)
1282 assert(blockInts == 0);
1286 hashValue = MUTEX_HASH_VALUE(o);
1287 if (mutexHashTable[hashValue].object == o)
1289 if (mutexHashTable[hashValue].mutex.count == 1
1290 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1291 internal_unlock_mutex_for_object(o);
1293 --mutexHashTable[hashValue].mutex.count;
1296 internal_unlock_mutex_for_object(o);
1300 assert(blockInts == 0);
1305 /*****************************************************************************
1306 MISCELLANEOUS HELPER FUNCTIONS
1307 *****************************************************************************/
1311 /*********** Functions for integer divisions *****************************
1313 On some systems (eg. DEC ALPHA), integer division is not supported by the
1314 CPU. These helper functions implement the missing functionality.
1316 ******************************************************************************/
1318 s4 builtin_idiv (s4 a, s4 b) { return a/b; }
1319 s4 builtin_irem (s4 a, s4 b) { return a%b; }
1322 /************** Functions for long arithmetics *******************************
1324 On systems where 64 bit Integers are not supported by the CPU, these
1325 functions are needed.
1327 ******************************************************************************/
1330 s8 builtin_ladd (s8 a, s8 b)
1335 return builtin_i2l(0);
1339 s8 builtin_lsub (s8 a, s8 b)
1344 return builtin_i2l(0);
1348 s8 builtin_lmul (s8 a, s8 b)
1353 return builtin_i2l(0);
1357 s8 builtin_ldiv (s8 a, s8 b)
1362 return builtin_i2l(0);
1366 s8 builtin_lrem (s8 a, s8 b)
1371 return builtin_i2l(0);
1375 s8 builtin_lshl (s8 a, s4 b)
1380 return builtin_i2l(0);
1384 s8 builtin_lshr (s8 a, s4 b)
1389 return builtin_i2l(0);
1393 s8 builtin_lushr (s8 a, s4 b)
1396 return ((u8)a)>>(b&63);
1398 return builtin_i2l(0);
1402 s8 builtin_land (s8 a, s8 b)
1407 return builtin_i2l(0);
1411 s8 builtin_lor (s8 a, s8 b)
1416 return builtin_i2l(0);
1420 s8 builtin_lxor (s8 a, s8 b)
1425 return builtin_i2l(0);
1429 s8 builtin_lneg (s8 a)
1434 return builtin_i2l(0);
1438 s4 builtin_lcmp (s8 a, s8 b)
1453 /*********** Functions for floating point operations *************************/
1455 float builtin_fadd (float a, float b)
1457 if (isnanf(a)) return FLT_NAN;
1458 if (isnanf(b)) return FLT_NAN;
1460 if (finitef(b)) return a+b;
1464 if (finitef(b)) return a;
1466 if (copysignf(1.0, a)==copysignf(1.0, b)) return a;
1467 else return FLT_NAN;
1472 float builtin_fsub (float a, float b)
1474 return builtin_fadd (a, builtin_fneg(b));
1477 float builtin_fmul (float a, float b)
1479 if (isnanf(a)) return FLT_NAN;
1480 if (isnanf(b)) return FLT_NAN;
1482 if (finitef(b)) return a*b;
1484 if (a==0) return FLT_NAN;
1485 else return copysignf(b, copysignf(1.0, b)*a);
1490 if (b==0) return FLT_NAN;
1491 else return copysignf(a, copysignf(1.0, a)*b);
1494 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1499 float builtin_fdiv (float a, float b)
1501 if (finitef(a) && finitef(b)) {
1514 float builtin_frem (float a, float b)
1520 float builtin_fneg (float a)
1522 if (isnanf(a)) return a;
1524 if (finitef(a)) return -a;
1525 else return copysignf(a,-copysignf(1.0, a));
1529 s4 builtin_fcmpl (float a, float b)
1531 if (isnanf(a)) return -1;
1532 if (isnanf(b)) return -1;
1533 if (!finitef(a) || !finitef(b)) {
1534 a = finitef(a) ? 0 : copysignf(1.0, a);
1535 b = finitef(b) ? 0 : copysignf(1.0, b);
1542 s4 builtin_fcmpg (float a, float b)
1544 if (isnanf(a)) return 1;
1545 if (isnanf(b)) return 1;
1546 if (!finitef(a) || !finitef(b)) {
1547 a = finitef(a) ? 0 : copysignf(1.0, a);
1548 b = finitef(b) ? 0 : copysignf(1.0, b);
1557 /************************* Functions for doubles ****************************/
1559 double builtin_dadd (double a, double b)
1561 if (isnan(a)) return DBL_NAN;
1562 if (isnan(b)) return DBL_NAN;
1564 if (finite(b)) return a+b;
1568 if (finite(b)) return a;
1570 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1571 else return DBL_NAN;
1576 double builtin_dsub (double a, double b)
1578 return builtin_dadd (a, builtin_dneg(b));
1581 double builtin_dmul (double a, double b)
1583 if (isnan(a)) return DBL_NAN;
1584 if (isnan(b)) return DBL_NAN;
1586 if (finite(b)) return a*b;
1588 if (a==0) return DBL_NAN;
1589 else return copysign(b, copysign(1.0, b)*a);
1594 if (b==0) return DBL_NAN;
1595 else return copysign(a, copysign(1.0, a)*b);
1598 return copysign(a, copysign(1.0, a)*copysign(1.0, b));
1603 double builtin_ddiv (double a, double b)
1605 if (finite(a) && finite(b)) {
1618 double builtin_drem (double a, double b)
1623 double builtin_dneg (double a)
1625 if (isnan(a)) return a;
1627 if (finite(a)) return -a;
1628 else return copysign(a,-copysign(1.0, a));
1632 s4 builtin_dcmpl (double a, double b)
1634 if (isnan(a)) return -1;
1635 if (isnan(b)) return -1;
1636 if (!finite(a) || !finite(b)) {
1637 a = finite(a) ? 0 : copysign(1.0, a);
1638 b = finite(b) ? 0 : copysign(1.0, b);
1645 s4 builtin_dcmpg (double a, double b)
1647 if (isnan(a)) return 1;
1648 if (isnan(b)) return 1;
1649 if (!finite(a) || !finite(b)) {
1650 a = finite(a) ? 0 : copysign(1.0, a);
1651 b = finite(b) ? 0 : copysign(1.0, b);
1659 /*********************** Conversion operations ****************************/
1661 s8 builtin_i2l (s4 i)
1666 s8 v; v.high = 0; v.low=i; return v;
1670 float builtin_i2f (s4 a)
1672 float f = (float) a;
1676 double builtin_i2d (s4 a)
1678 double d = (double) a;
1683 s4 builtin_l2i (s8 l)
1692 float builtin_l2f (s8 a)
1695 float f = (float) a;
1702 double builtin_l2d (s8 a)
1705 double d = (double) a;
1713 s4 builtin_f2i(float a)
1716 return builtin_d2i((double) a);
1725 if (a < (-2147483648))
1726 return (-2147483648);
1729 f = copysignf((float) 1.0, a);
1732 return (-2147483648); */
1736 s8 builtin_f2l (float a)
1739 return builtin_d2l((double) a);
1744 if (a > 9223372036854775807L)
1745 return 9223372036854775807L;
1746 if (a < (-9223372036854775808L))
1747 return (-9223372036854775808L);
1752 f = copysignf((float) 1.0, a);
1754 return 9223372036854775807L;
1755 return (-9223372036854775808L); */
1759 double builtin_f2d (float a)
1761 if (finitef(a)) return (double) a;
1763 if (isnanf(a)) return DBL_NAN;
1764 else return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1769 s4 builtin_d2i (double a)
1774 if (a >= 2147483647)
1776 if (a <= (-2147483647-1))
1777 return (-2147483647-1);
1782 d = copysign(1.0, a);
1785 return (-2147483647-1);
1789 s8 builtin_d2l (double a)
1794 if (a >= 9223372036854775807LL)
1795 return 9223372036854775807LL;
1796 if (a <= (-9223372036854775807LL-1))
1797 return (-9223372036854775807LL-1);
1802 d = copysign(1.0, a);
1804 return 9223372036854775807LL;
1805 return (-9223372036854775807LL-1);
1809 float builtin_d2f (double a)
1811 if (finite(a)) return (float) a;
1813 if (isnan(a)) return FLT_NAN;
1814 else return copysignf (FLT_POSINF, (float) copysign(1.0, a));
1820 * These are local overrides for various environment variables in Emacs.
1821 * Please do not remove this and leave it at the end of the file, where
1822 * Emacs will automagically detect them.
1823 * ---------------------------------------------------------------------
1826 * indent-tabs-mode: t