1 /* builtin.c - functions for unsupported operations
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5 M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6 P. Tomsich, J. Wenninger
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Reinhard Grafl
31 Contains C functions for JavaVM Instructions that cannot be
32 translated to machine language directly. Consequently, the
33 generated machine code for these instructions contains function
34 calls instead of machine instructions, using the C calling
37 $Id: builtin.c 689 2003-12-05 18:03:47Z stefan $
51 #include "threads/thread.h"
52 #include "threads/locks.h"
53 #include "toolbox/loging.h"
54 #include "toolbox/memory.h"
56 #include "native-math.h"
58 #undef DEBUG /*define DEBUG 1*/
60 builtin_descriptor builtin_desc[] = {
61 {(functionptr) builtin_instanceof, "instanceof"},
62 {(functionptr) builtin_checkcast, "checkcast"},
63 {(functionptr) asm_builtin_checkcast, "checkcast"},
64 {(functionptr) builtin_arrayinstanceof, "arrayinstanceof"},
66 {(functionptr) asm_builtin_arrayinstanceof,"arrayinstanceof"},
68 {(functionptr) builtin_checkarraycast, "checkarraycast"},
69 {(functionptr) asm_builtin_checkarraycast, "checkarraycast"},
70 {(functionptr) asm_builtin_aastore, "aastore"},
71 {(functionptr) builtin_new, "new"},
72 {(functionptr) builtin_newarray, "newarray"},
73 {(functionptr) builtin_anewarray, "anewarray"},
76 * have 2 parameters (needs stack manipulation)
78 {(functionptr) asm_builtin_newarray, "newarray"},
80 {(functionptr) builtin_newarray_boolean, "newarray_boolean"},
81 {(functionptr) builtin_newarray_char, "newarray_char"},
82 {(functionptr) builtin_newarray_float, "newarray_float"},
83 {(functionptr) builtin_newarray_double, "newarray_double"},
84 {(functionptr) builtin_newarray_byte, "newarray_byte"},
85 {(functionptr) builtin_newarray_short, "newarray_short"},
86 {(functionptr) builtin_newarray_int, "newarray_int"},
87 {(functionptr) builtin_newarray_long, "newarray_long"},
88 {(functionptr) builtin_displaymethodstart, "displaymethodstart"},
89 {(functionptr) builtin_displaymethodstop, "displaymethodstop"},
90 {(functionptr) builtin_monitorenter, "monitorenter"},
91 {(functionptr) asm_builtin_monitorenter, "monitorenter"},
92 {(functionptr) builtin_monitorexit, "monitorexit"},
93 {(functionptr) asm_builtin_monitorexit, "monitorexit"},
95 {(functionptr) builtin_idiv, "idiv"},
96 {(functionptr) asm_builtin_idiv, "idiv"},
97 {(functionptr) builtin_irem, "irem"},
98 {(functionptr) asm_builtin_irem, "irem"},
100 {(functionptr) builtin_ladd, "ladd"},
101 {(functionptr) builtin_lsub, "lsub"},
102 {(functionptr) builtin_lmul, "lmul"},
103 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
104 {(functionptr) builtin_ldiv, "ldiv"},
105 {(functionptr) asm_builtin_ldiv, "ldiv"},
106 {(functionptr) builtin_lrem, "lrem"},
107 {(functionptr) asm_builtin_lrem, "lrem"},
109 {(functionptr) builtin_lshl, "lshl"},
110 {(functionptr) builtin_lshr, "lshr"},
111 {(functionptr) builtin_lushr, "lushr"},
112 {(functionptr) builtin_land, "land"},
113 {(functionptr) builtin_lor, "lor"},
114 {(functionptr) builtin_lxor, "lxor"},
115 {(functionptr) builtin_lneg, "lneg"},
116 {(functionptr) builtin_lcmp, "lcmp"},
117 {(functionptr) builtin_fadd, "fadd"},
118 {(functionptr) builtin_fsub, "fsub"},
119 {(functionptr) builtin_fmul, "fmul"},
120 {(functionptr) builtin_fdiv, "fdiv"},
121 {(functionptr) builtin_frem, "frem"},
122 {(functionptr) builtin_fneg, "fneg"},
123 {(functionptr) builtin_fcmpl, "fcmpl"},
124 {(functionptr) builtin_fcmpg, "fcmpg"},
125 {(functionptr) builtin_dadd, "dadd"},
126 {(functionptr) builtin_dsub, "dsub"},
127 {(functionptr) builtin_dmul, "dmul"},
128 {(functionptr) builtin_ddiv, "ddiv"},
129 {(functionptr) builtin_drem, "drem"},
130 {(functionptr) builtin_dneg, "dneg"},
131 {(functionptr) builtin_dcmpl, "dcmpl"},
132 {(functionptr) builtin_dcmpg, "dcmpg"},
133 {(functionptr) builtin_i2l, "i2l"},
134 {(functionptr) builtin_i2f, "i2f"},
135 {(functionptr) builtin_i2d, "i2d"},
136 {(functionptr) builtin_l2i, "l2i"},
137 {(functionptr) builtin_l2f, "l2f"},
138 {(functionptr) builtin_l2d, "l2d"},
139 {(functionptr) builtin_f2i, "f2i"},
140 {(functionptr) builtin_f2l, "f2l"},
141 {(functionptr) builtin_f2d, "f2d"},
142 {(functionptr) builtin_d2i, "d2i"},
143 {(functionptr) builtin_d2l, "d2l"},
144 #if defined(__I386__)
145 {(functionptr) asm_builtin_f2i, "f2i"},
146 {(functionptr) asm_builtin_f2l, "f2l"},
147 {(functionptr) asm_builtin_d2i, "d2i"},
148 {(functionptr) asm_builtin_d2l, "d2l"},
150 {(functionptr) builtin_d2f, "d2f"},
151 {(functionptr) NULL, "unknown"}
155 /*****************************************************************************
157 *****************************************************************************/
161 /*************** internal function: builtin_isanysubclass *********************
163 Checks a subclass relation between two classes. Implemented interfaces
164 are interpreted as super classes.
165 Return value: 1 ... sub is subclass of super
168 *****************************************************************************/
170 s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
173 if (super->flags & ACC_INTERFACE)
174 return (sub->vftbl->interfacetablelength > super->index) &&
175 (sub->vftbl->interfacetable[-super->index] != NULL);
188 for (tmp=sub;tmp!=0;tmp=tmp->super) {
190 utf_display(tmp->name);
194 for (tmp=super;tmp!=0;tmp=tmp->super) {
196 utf_display(tmp->name);
201 printf("sub->vftbl->baseval %d, super->vftbl->baseval %d\n diff %d, super->vftbl->diffval %d\n",
202 sub->vftbl->baseval, super->vftbl->baseval, (unsigned)(sub->vftbl->baseval - super->vftbl->baseval),
203 super->vftbl->diffval); */
205 return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <=
206 (unsigned) (super->vftbl->diffval);
209 /* XXX inline this? */
210 s4 builtin_isanysubclass_vftbl(vftbl *sub,vftbl *super)
214 if ((base = super->baseval) <= 0)
215 /* super is an interface */
216 return (sub->interfacetablelength > -base) &&
217 (sub->interfacetable[base] != NULL);
218 return (unsigned) (sub->baseval - base)
219 <= (unsigned) (super->diffval);
223 /****************** function: builtin_instanceof *****************************
225 Checks if an object is an instance of some given class (or subclass of
226 that class). If class is an interface, checks if the interface is
228 Return value: 1 ... obj is an instance of class or implements the interface
229 0 ... otherwise or if obj == NULL
231 *****************************************************************************/
233 /* XXX should use vftbl */
234 s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
237 log_text ("builtin_instanceof called");
240 return builtin_isanysubclass (obj->vftbl->class, class);
245 /**************** function: builtin_checkcast *******************************
247 The same as builtin_instanceof except that 1 is returned when
250 ****************************************************************************/
252 /* XXX should use vftbl */
253 s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
256 log_text("builtin_checkcast called");
261 if (builtin_isanysubclass(obj->vftbl->class, class))
265 printf("#### checkcast failed ");
266 utf_display(obj->vftbl->class->name);
268 utf_display(class->name);
276 /*********** internal function: builtin_descriptorscompatible ******************
278 Checks if two array type descriptors are assignment compatible
279 Return value: 1 ... target = desc is possible
282 ******************************************************************************/
284 /* XXX inline this? */
285 static s4 builtin_descriptorscompatible(arraydescriptor *desc,arraydescriptor *target)
287 if (desc==target) return 1;
288 if (desc->arraytype != target->arraytype) return 0;
289 if (desc->arraytype != ARRAYTYPE_OBJECT) return 1;
291 /* {both arrays are arrays of references} */
292 if (desc->dimension == target->dimension)
293 return builtin_isanysubclass_vftbl(desc->elementvftbl,target->elementvftbl);
294 if (desc->dimension < target->dimension) return 0;
296 /* {desc has higher dimension than target} */
297 return builtin_isanysubclass_vftbl(pseudo_class_Arraystub_vftbl,target->elementvftbl);
300 /******************** function: builtin_checkarraycast ***********************
302 Checks if an object is really a subtype of the requested array type.
303 The object has to be an array to begin with. For simple arrays (int, short,
304 double, etc.) the types have to match exactly.
305 For arrays of objects, the type of elements in the array has to be a
306 subtype (or the same type) of the requested element type. For arrays of
307 arrays (which in turn can again be arrays of arrays), the types at the
308 lowest level have to satisfy the corresponding sub class relation.
310 Return value: 1 ... cast is possible
313 ATTENTION: a cast with a NULL pointer is always possible.
315 *****************************************************************************/
317 s4 builtin_checkarraycast(java_objectheader *o,arraydescriptor *target)
319 arraydescriptor *desc;
322 if ((desc = o->vftbl->arraydesc) == NULL) return 0;
324 return builtin_descriptorscompatible(desc,target);
327 s4 builtin_arrayinstanceof(java_objectheader *obj,arraydescriptor *desc)
330 return builtin_checkarraycast (obj, desc);
333 /************************** exception functions *******************************
335 ******************************************************************************/
337 java_objectheader *builtin_throw_exception(java_objectheader *local_exceptionptr)
340 char logtext[MAXLOGTEXT];
341 sprintf(logtext, "Builtin exception thrown: ");
342 if (local_exceptionptr)
343 utf_sprint(logtext + strlen(logtext), local_exceptionptr->vftbl->class->name);
345 sprintf(logtext+strlen(logtext),"%s","Error: <Nullpointer instead of exception>");
346 if (!proto_java_lang_ClassCastException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ClassCastException==0");
347 if (!proto_java_lang_NullPointerException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_NullPointerException==0");
348 if (!proto_java_lang_NullPointerException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_NullPointerException==0");
349 if (!proto_java_lang_ArrayIndexOutOfBoundsException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ArrayIndexOutOfBoundsException==0");
350 if (!proto_java_lang_NegativeArraySizeException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_NegativeArraySizeException==0");
351 if (!proto_java_lang_OutOfMemoryError) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_OutOfMemoryError==0");
352 if (!proto_java_lang_ArithmeticException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ArithmeticException==0");
353 if (!proto_java_lang_ArrayStoreException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ArrayStoreException==0");
354 if (!proto_java_lang_ThreadDeath) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ThreadDeath==0");
355 if (!proto_java_lang_ThreadDeath) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ThreadDeath==0");
359 exceptionptr = local_exceptionptr;
360 return local_exceptionptr;
364 /******************* function: builtin_canstore *******************************
366 Checks, if an object can be stored in an array.
367 Return value: 1 ... possible
370 ******************************************************************************/
372 s4 builtin_canstore (java_objectarray *a, java_objectheader *o)
374 arraydescriptor *desc;
375 arraydescriptor *valuedesc;
376 vftbl *componentvftbl;
383 /* The following is guaranteed (by verifier checks):
385 * *) a->...vftbl->arraydesc != NULL
386 * *) a->...vftbl->arraydesc->componentvftbl != NULL
387 * *) o->vftbl is not an interface vftbl
390 desc = a->header.objheader.vftbl->arraydesc;
391 componentvftbl = desc->componentvftbl;
392 valuevftbl = o->vftbl;
394 if ((dim_m1 = desc->dimension - 1) == 0) {
395 /* {a is a one-dimensional array} */
396 /* {a is an array of references} */
398 if (valuevftbl == componentvftbl)
401 if ((base = componentvftbl->baseval) <= 0)
402 /* an array of interface references */
403 return (valuevftbl->interfacetablelength > -base &&
404 valuevftbl->interfacetable[base] != NULL);
406 return (unsigned)(valuevftbl->baseval - base)
407 <= (unsigned)(componentvftbl->diffval);
409 /* {a has dimension > 1} */
410 /* {componentvftbl->arraydesc != NULL} */
412 /* check if o is an array */
413 if ((valuedesc = valuevftbl->arraydesc) == NULL)
415 /* {o is an array} */
417 return builtin_descriptorscompatible(valuedesc,componentvftbl->arraydesc);
420 /* This is an optimized version where a is guaranteed to be one-dimensional */
421 s4 builtin_canstore_onedim (java_objectarray *a, java_objectheader *o)
423 arraydescriptor *desc;
430 /* The following is guaranteed (by verifier checks):
432 * *) a->...vftbl->arraydesc != NULL
433 * *) a->...vftbl->arraydesc->elementvftbl != NULL
434 * *) a->...vftbl->arraydesc->dimension == 1
435 * *) o->vftbl is not an interface vftbl
438 desc = a->header.objheader.vftbl->arraydesc;
439 elementvftbl = desc->elementvftbl;
440 valuevftbl = o->vftbl;
442 /* {a is a one-dimensional array} */
444 if (valuevftbl == elementvftbl)
447 if ((base = elementvftbl->baseval) <= 0)
448 /* an array of interface references */
449 return (valuevftbl->interfacetablelength > -base &&
450 valuevftbl->interfacetable[base] != NULL);
452 return (unsigned)(valuevftbl->baseval - base)
453 <= (unsigned)(elementvftbl->diffval);
456 /* This is an optimized version where a is guaranteed to be a
457 * one-dimensional array of a class type */
458 /* XXX this could be inlined by the code generator */
459 s4 builtin_canstore_onedim_class (java_objectarray *a, java_objectheader *o)
466 /* The following is guaranteed (by verifier checks):
468 * *) a->...vftbl->arraydesc != NULL
469 * *) a->...vftbl->arraydesc->elementvftbl != NULL
470 * *) a->...vftbl->arraydesc->elementvftbl is not an interface vftbl
471 * *) a->...vftbl->arraydesc->dimension == 1
472 * *) o->vftbl is not an interface vftbl
475 elementvftbl = a->header.objheader.vftbl->arraydesc->elementvftbl;
476 valuevftbl = o->vftbl;
478 /* {a is a one-dimensional array} */
480 if (valuevftbl == elementvftbl)
483 return (unsigned)(valuevftbl->baseval - elementvftbl->baseval)
484 <= (unsigned)(elementvftbl->diffval);
488 /******************** Function: builtin_new **********************************
490 Creates a new instance of class c on the heap.
491 Return value: pointer to the object or NULL if no memory is
494 *****************************************************************************/
497 #define align_size(size) ((size + ((1 << ALIGNMENT) - 1)) & ~((1 << ALIGNMENT) - 1))
499 java_objectheader *builtin_new(classinfo *c)
501 java_objectheader *o;
505 #ifdef SIZE_FROM_CLASSINFO
506 c->alignedsize = align_size(c->instancesize);
507 o = heap_allocate(c->alignedsize, true, c->finalizer);
509 o = heap_allocate(c->instancesize, true, c->finalizer);
513 memset(o, 0, c->instancesize);
520 /********************** Function: builtin_newarray **************************
522 Creates an array with the given vftbl on the heap.
524 Return value: pointer to the array or NULL if no memory is available
526 CAUTION: The given vftbl must be the vftbl of the *array* class,
527 not of the element class.
529 *****************************************************************************/
531 java_arrayheader *builtin_newarray(s4 size,vftbl *arrayvftbl)
534 arraydescriptor *desc = arrayvftbl->arraydesc;
535 s4 dataoffset = desc->dataoffset;
536 s4 componentsize = desc->componentsize;
540 exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/NegativeArraySizeException")));
543 #ifdef SIZE_FROM_CLASSINFO
544 actualsize = align_size(dataoffset + size * componentsize);
546 actualsize = dataoffset + size * componentsize;
548 a = (java_arrayheader *)
549 heap_allocate(actualsize,
550 (desc->arraytype == ARRAYTYPE_OBJECT),
554 memset(a,0,actualsize);
557 /*printf("builtin_newarray: Created an array of size : %d\n",size);*/
559 a->objheader.vftbl = arrayvftbl;
561 #ifdef SIZE_FROM_CLASSINFO
562 a->alignedsize = actualsize;
567 /********************** Function: builtin_anewarray *************************
569 Creates an array of references to the given class type on the heap.
571 Return value: pointer to the array or NULL if no memory is available
573 XXX This function does not do The Right Thing, because it uses a
574 classinfo pointer at runtime. builtin_newarray should be used
577 *****************************************************************************/
580 builtin_anewarray(s4 size,classinfo *component)
582 return (java_objectarray*) builtin_newarray(size,class_array_of(component)->vftbl);
585 /******************** Function: builtin_newarray_int ***********************
587 Creates an array of 32 bit Integers on the heap.
589 Return value: pointer to the array or NULL if no memory is available
591 *****************************************************************************/
593 java_intarray *builtin_newarray_int (s4 size)
595 return (java_intarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_INT].arrayvftbl);
598 /******************** Function: builtin_newarray_long ***********************
600 Creates an array of 64 bit Integers on the heap.
602 Return value: pointer to the array or NULL if no memory is available
604 *****************************************************************************/
606 java_longarray *builtin_newarray_long (s4 size)
608 return (java_longarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_LONG].arrayvftbl);
611 /******************** function: builtin_newarray_float ***********************
613 Creates an array of 32 bit IEEE floats on the heap.
615 Return value: pointer to the array or NULL if no memory is available
617 *****************************************************************************/
619 java_floatarray *builtin_newarray_float (s4 size)
621 return (java_floatarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_FLOAT].arrayvftbl);
624 /******************** function: builtin_newarray_double ***********************
626 Creates an array of 64 bit IEEE floats on the heap.
628 Return value: pointer to the array or NULL if no memory is available
630 *****************************************************************************/
632 java_doublearray *builtin_newarray_double (s4 size)
634 return (java_doublearray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_DOUBLE].arrayvftbl);
637 /******************** function: builtin_newarray_byte ***********************
639 Creates an array of 8 bit Integers on the heap.
641 Return value: pointer to the array or NULL if no memory is available
643 *****************************************************************************/
645 java_bytearray *builtin_newarray_byte (s4 size)
647 return (java_bytearray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_BYTE].arrayvftbl);
650 /******************** function: builtin_newarray_char ************************
652 Creates an array of characters on the heap.
654 Return value: pointer to the array or NULL if no memory is available
656 *****************************************************************************/
658 java_chararray *builtin_newarray_char (s4 size)
660 return (java_chararray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl);
663 /******************** function: builtin_newarray_short ***********************
665 Creates an array of 16 bit Integers on the heap.
667 Return value: pointer to the array or NULL if no memory is available
669 *****************************************************************************/
671 java_shortarray *builtin_newarray_short (s4 size)
673 return (java_shortarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_SHORT].arrayvftbl);
676 /******************** function: builtin_newarray_boolean ************************
678 Creates an array of bytes on the heap. The array is designated as an array
679 of booleans (important for casts)
681 Return value: pointer to the array or NULL if no memory is available
683 *****************************************************************************/
685 java_booleanarray *builtin_newarray_boolean (s4 size)
687 return (java_booleanarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_BOOLEAN].arrayvftbl);
690 /**************** function: builtin_nmultianewarray ***************************
692 Creates a multi-dimensional array on the heap. The dimensions are passed in
696 n............number of dimensions to create
697 arrayvftbl...vftbl of the array class
698 dims.........array containing the size of each dimension to create
700 Return value: pointer to the array or NULL if no memory is available
702 ******************************************************************************/
704 java_arrayheader *builtin_nmultianewarray (int n,
705 vftbl *arrayvftbl, long *dims)
709 vftbl *componentvftbl;
711 /* create this dimension */
712 size = (int) dims[0];
713 a = builtin_newarray(size,arrayvftbl);
716 /* if this is the last dimension return */
719 /* get the vftbl of the components to create */
720 componentvftbl = arrayvftbl->arraydesc->componentvftbl;
721 if (!componentvftbl) /* XXX the verifier could check this */
722 panic ("multianewarray with too many dimensions");
724 /* create the component arrays */
725 for (i = 0; i < size; i++) {
726 java_arrayheader *ea =
727 builtin_nmultianewarray(n,componentvftbl,dims+1);
728 if (!ea) return NULL;
729 ((java_objectarray*)a)->data[i] = (java_objectheader *) ea;
735 /*****************************************************************************
738 Various functions for printing a message at method entry or exit (for
741 *****************************************************************************/
746 java_objectheader *builtin_trace_exception(java_objectheader *exceptionptr,
747 methodinfo *method, int *pos,
753 if (verbose || runverbose) {
754 printf("Exception ");
756 utf_display (exceptionptr->vftbl->class->name);
759 printf("Error: <Nullpointer instead of exception>");
760 if (!proto_java_lang_ClassCastException) printf("%s","proto_java_lang_ClassCastException==0");
761 if (!proto_java_lang_NullPointerException) printf("%s","proto_java_lang_NullPointerException==0");
762 if (!proto_java_lang_NullPointerException) printf("%s","proto_java_lang_NullPointerException==0");
763 if (!proto_java_lang_ArrayIndexOutOfBoundsException) printf("%s","proto_java_lang_ArrayIndexOutOfBoundsException==0");
764 if (!proto_java_lang_NegativeArraySizeException) printf("%s","proto_java_lang_NegativeArraySizeException==0");
765 if (!proto_java_lang_OutOfMemoryError) printf("%s","proto_java_lang_OutOfMemoryError==0");
766 if (!proto_java_lang_ArithmeticException) printf("%s","proto_java_lang_ArithmeticException==0");
767 if (!proto_java_lang_ArrayStoreException) printf("%s","proto_java_lang_ArrayStoreException==0");
768 if (!proto_java_lang_ThreadDeath) printf("%s","proto_java_lang_ThreadDeath==0");
769 if (!proto_java_lang_ThreadDeath) printf("%s","proto_java_lang_ThreadDeath==0");
772 printf(" thrown in ");
774 utf_display (method->class->name);
776 utf_display (method->name);
777 if (method->flags & ACC_SYNCHRONIZED)
781 printf("(%p) at position %p\n", method->entrypoint, pos);
784 printf("call_java_method\n");
791 #ifdef TRACE_ARGS_NUM
792 void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5,
793 #if TRACE_ARGS_NUM > 6
800 char logtext[MAXLOGTEXT];
801 for (i = 0; i < methodindent; i++)
803 sprintf(logtext + methodindent, "called: ");
804 utf_sprint(logtext + strlen(logtext), method->class->name);
805 sprintf(logtext + strlen(logtext), ".");
806 utf_sprint(logtext + strlen(logtext), method->name);
807 utf_sprint(logtext + strlen(logtext), method->descriptor);
808 sprintf(logtext + strlen(logtext), "(");
810 switch (method->paramcount) {
814 #if defined(__I386__)
816 sprintf(logtext+strlen(logtext), "%llx", a0);
820 sprintf(logtext+strlen(logtext), "%llx, %llx", a0, a1);
824 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx", a0, a1, a2);
828 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx",
833 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx",
838 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx",
839 a0, a1, a2, a3, a4, a5);
842 #if TRACE_ARGS_NUM > 6
844 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx",
845 a0, a1, a2, a3, a4, a5, a6);
849 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx",
850 a0, a1, a2, a3, a4, a5, a6, a7);
854 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
855 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
859 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
860 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
865 sprintf(logtext+strlen(logtext), "%lx", a0);
869 sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1);
873 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2);
877 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx",
882 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx",
887 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx",
888 a0, a1, a2, a3, a4, a5);
891 #if TRACE_ARGS_NUM > 6
893 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx",
894 a0, a1, a2, a3, a4, a5, a6);
898 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx",
899 a0, a1, a2, a3, a4, a5, a6, a7);
903 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx, ...(%d)",
904 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
908 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, ...(%d)",
909 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
914 sprintf (logtext+strlen(logtext), ")");
922 void builtin_displaymethodstart(methodinfo *method)
924 char logtext[MAXLOGTEXT];
925 sprintf(logtext, " ");
926 sprintf(logtext + methodindent, "called: ");
927 utf_sprint(logtext + strlen(logtext), method->class->name);
928 sprintf(logtext + strlen(logtext), ".");
929 utf_sprint(logtext + strlen(logtext), method->name);
930 utf_sprint(logtext + strlen(logtext), method->descriptor);
936 void builtin_displaymethodstop(methodinfo *method, s8 l, double d, float f)
939 char logtext[MAXLOGTEXT];
940 for (i = 0; i < methodindent; i++)
943 sprintf(logtext + methodindent, "finished: ");
944 utf_sprint(logtext + strlen(logtext), method->class->name);
945 sprintf(logtext + strlen(logtext), ".");
946 utf_sprint(logtext + strlen(logtext), method->name);
947 utf_sprint(logtext + strlen(logtext), method->descriptor);
949 switch (method->returntype) {
951 sprintf(logtext + strlen(logtext), "->%d", (s4) l);
954 #if defined(__I386__)
955 sprintf(logtext + strlen(logtext), "->%lld", (s8) l);
957 sprintf(logtext + strlen(logtext), "->%ld", (s8) l);
961 #if defined(__I386__)
962 sprintf(logtext + strlen(logtext), "->%p", (u1*) ((s4) l));
964 sprintf(logtext + strlen(logtext), "->%p", (u1*) l);
968 sprintf(logtext + strlen(logtext), "->%g", f);
971 sprintf(logtext + strlen(logtext), "->%g", d);
978 void builtin_displaymethodexception(methodinfo *method)
981 char logtext[MAXLOGTEXT];
982 for (i = 0; i < methodindent; i++)
984 sprintf(logtext + methodindent, "exception abort: ");
985 utf_sprint(logtext + strlen(logtext), method->class->name);
986 sprintf(logtext + strlen(logtext), ".");
987 utf_sprint(logtext + strlen(logtext), method->name);
988 utf_sprint(logtext + strlen(logtext), method->descriptor);
993 /****************************************************************************
994 SYNCHRONIZATION FUNCTIONS
995 *****************************************************************************/
998 * Lock the mutex of an object.
1002 internal_lock_mutex_for_object (java_objectheader *object)
1004 mutexHashEntry *entry;
1007 assert(object != 0);
1009 hashValue = MUTEX_HASH_VALUE(object);
1010 entry = &mutexHashTable[hashValue];
1012 if (entry->object != 0) {
1013 if (entry->mutex.count == 0 && entry->conditionCount == 0) {
1015 entry->mutex.holder = 0;
1016 entry->mutex.count = 0;
1017 entry->mutex.muxWaiters = 0;
1020 while (entry->next != 0 && entry->object != object)
1021 entry = entry->next;
1023 if (entry->object != object) {
1024 entry->next = firstFreeOverflowEntry;
1025 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
1027 entry = entry->next;
1030 assert(entry->conditionCount == 0);
1035 entry->mutex.holder = 0;
1036 entry->mutex.count = 0;
1037 entry->mutex.muxWaiters = 0;
1040 if (entry->object == 0)
1041 entry->object = object;
1043 internal_lock_mutex(&entry->mutex);
1049 * Unlocks the mutex of an object.
1053 internal_unlock_mutex_for_object (java_objectheader *object)
1056 mutexHashEntry *entry;
1058 hashValue = MUTEX_HASH_VALUE(object);
1059 entry = &mutexHashTable[hashValue];
1061 if (entry->object == object) {
1062 internal_unlock_mutex(&entry->mutex);
1065 while (entry->next != 0 && entry->next->object != object)
1066 entry = entry->next;
1068 assert(entry->next != 0);
1070 internal_unlock_mutex(&entry->next->mutex);
1072 if (entry->next->mutex.count == 0 && entry->conditionCount == 0) {
1073 mutexHashEntry *unlinked = entry->next;
1075 entry->next = unlinked->next;
1076 unlinked->next = firstFreeOverflowEntry;
1077 firstFreeOverflowEntry = unlinked;
1084 void builtin_monitorenter(java_objectheader *o)
1089 assert(blockInts == 0);
1093 hashValue = MUTEX_HASH_VALUE(o);
1094 if (mutexHashTable[hashValue].object == o
1095 && mutexHashTable[hashValue].mutex.holder == currentThread)
1096 ++mutexHashTable[hashValue].mutex.count;
1098 internal_lock_mutex_for_object(o);
1102 assert(blockInts == 0);
1107 void builtin_monitorexit (java_objectheader *o)
1112 assert(blockInts == 0);
1116 hashValue = MUTEX_HASH_VALUE(o);
1117 if (mutexHashTable[hashValue].object == o) {
1118 if (mutexHashTable[hashValue].mutex.count == 1
1119 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1120 internal_unlock_mutex_for_object(o);
1122 --mutexHashTable[hashValue].mutex.count;
1125 internal_unlock_mutex_for_object(o);
1129 assert(blockInts == 0);
1134 /*****************************************************************************
1135 MISCELLANEOUS HELPER FUNCTIONS
1136 *****************************************************************************/
1140 /*********** Functions for integer divisions *****************************
1142 On some systems (eg. DEC ALPHA), integer division is not supported by the
1143 CPU. These helper functions implement the missing functionality.
1145 ******************************************************************************/
1147 s4 builtin_idiv(s4 a, s4 b) { return a / b; }
1148 s4 builtin_irem(s4 a, s4 b) { return a % b; }
1151 /************** Functions for long arithmetics *******************************
1153 On systems where 64 bit Integers are not supported by the CPU, these
1154 functions are needed.
1156 ******************************************************************************/
1159 s8 builtin_ladd(s8 a, s8 b)
1164 return builtin_i2l(0);
1168 s8 builtin_lsub(s8 a, s8 b)
1173 return builtin_i2l(0);
1177 s8 builtin_lmul(s8 a, s8 b)
1182 return builtin_i2l(0);
1186 s8 builtin_ldiv(s8 a, s8 b)
1191 return builtin_i2l(0);
1195 s8 builtin_lrem(s8 a, s8 b)
1200 return builtin_i2l(0);
1204 s8 builtin_lshl(s8 a, s4 b)
1207 return a << (b & 63);
1209 return builtin_i2l(0);
1213 s8 builtin_lshr(s8 a, s4 b)
1216 return a >> (b & 63);
1218 return builtin_i2l(0);
1222 s8 builtin_lushr(s8 a, s4 b)
1225 return ((u8) a) >> (b & 63);
1227 return builtin_i2l(0);
1231 s8 builtin_land(s8 a, s8 b)
1236 return builtin_i2l(0);
1240 s8 builtin_lor(s8 a, s8 b)
1245 return builtin_i2l(0);
1249 s8 builtin_lxor(s8 a, s8 b)
1254 return builtin_i2l(0);
1258 s8 builtin_lneg(s8 a)
1263 return builtin_i2l(0);
1267 s4 builtin_lcmp(s8 a, s8 b)
1270 if (a < b) return -1;
1271 if (a > b) return 1;
1282 /*********** Functions for floating point operations *************************/
1284 float builtin_fadd(float a, float b)
1286 if (isnanf(a)) return FLT_NAN;
1287 if (isnanf(b)) return FLT_NAN;
1298 if (copysignf(1.0, a) == copysignf(1.0, b))
1307 float builtin_fsub(float a, float b)
1309 return builtin_fadd(a, builtin_fneg(b));
1313 float builtin_fmul(float a, float b)
1315 if (isnanf(a)) return FLT_NAN;
1316 if (isnanf(b)) return FLT_NAN;
1318 if (finitef(b)) return a*b;
1320 if (a == 0) return FLT_NAN;
1321 else return copysignf(b, copysignf(1.0, b)*a);
1326 if (b == 0) return FLT_NAN;
1327 else return copysignf(a, copysignf(1.0, a)*b);
1330 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1336 float builtin_fdiv(float a, float b)
1338 if (finitef(a) && finitef(b)) {
1352 float builtin_frem(float a, float b)
1358 float builtin_fneg(float a)
1360 if (isnanf(a)) return a;
1362 if (finitef(a)) return -a;
1363 else return copysignf(a, -copysignf(1.0, a));
1368 s4 builtin_fcmpl(float a, float b)
1370 if (isnanf(a)) return -1;
1371 if (isnanf(b)) return -1;
1372 if (!finitef(a) || !finitef(b)) {
1373 a = finitef(a) ? 0 : copysignf(1.0, a);
1374 b = finitef(b) ? 0 : copysignf(1.0, b);
1376 if (a > b) return 1;
1377 if (a == b) return 0;
1382 s4 builtin_fcmpg(float a, float b)
1384 if (isnanf(a)) return 1;
1385 if (isnanf(b)) return 1;
1386 if (!finitef(a) || !finitef(b)) {
1387 a = finitef(a) ? 0 : copysignf(1.0, a);
1388 b = finitef(b) ? 0 : copysignf(1.0, b);
1390 if (a > b) return 1;
1391 if (a == b) return 0;
1397 /************************* Functions for doubles ****************************/
1399 double builtin_dadd(double a, double b)
1401 if (isnan(a)) return DBL_NAN;
1402 if (isnan(b)) return DBL_NAN;
1404 if (finite(b)) return a+b;
1408 if (finite(b)) return a;
1410 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1411 else return DBL_NAN;
1417 double builtin_dsub(double a, double b)
1419 return builtin_dadd(a, builtin_dneg(b));
1423 double builtin_dmul(double a, double b)
1425 if (isnan(a)) return DBL_NAN;
1426 if (isnan(b)) return DBL_NAN;
1428 if (finite(b)) return a * b;
1430 if (a == 0) return DBL_NAN;
1431 else return copysign(b, copysign(1.0, b) * a);
1436 if (b == 0) return DBL_NAN;
1437 else return copysign(a, copysign(1.0, a) * b);
1440 return copysign(a, copysign(1.0, a) * copysign(1.0, b));
1446 double builtin_ddiv(double a, double b)
1448 if (finite(a) && finite(b)) {
1462 double builtin_drem(double a, double b)
1468 double builtin_dneg(double a)
1470 if (isnan(a)) return a;
1472 if (finite(a)) return -a;
1473 else return copysign(a, -copysign(1.0, a));
1478 s4 builtin_dcmpl(double a, double b)
1480 if (isnan(a)) return -1;
1481 if (isnan(b)) return -1;
1482 if (!finite(a) || !finite(b)) {
1483 a = finite(a) ? 0 : copysign(1.0, a);
1484 b = finite(b) ? 0 : copysign(1.0, b);
1486 if (a > b) return 1;
1487 if (a == b) return 0;
1492 s4 builtin_dcmpg(double a, double b)
1494 if (isnan(a)) return 1;
1495 if (isnan(b)) return 1;
1496 if (!finite(a) || !finite(b)) {
1497 a = finite(a) ? 0 : copysign(1.0, a);
1498 b = finite(b) ? 0 : copysign(1.0, b);
1500 if (a > b) return 1;
1501 if (a == b) return 0;
1506 /*********************** Conversion operations ****************************/
1508 s8 builtin_i2l(s4 i)
1513 s8 v; v.high = 0; v.low=i; return v;
1518 float builtin_i2f(s4 a)
1520 float f = (float) a;
1525 double builtin_i2d(s4 a)
1527 double d = (double) a;
1532 s4 builtin_l2i(s8 l)
1542 float builtin_l2f(s8 a)
1545 float f = (float) a;
1553 double builtin_l2d(s8 a)
1556 double d = (double) a;
1564 s4 builtin_f2i(float a)
1567 return builtin_d2i((double) a);
1576 if (a < (-2147483648))
1577 return (-2147483648);
1580 f = copysignf((float) 1.0, a);
1583 return (-2147483648); */
1587 s8 builtin_f2l(float a)
1590 return builtin_d2l((double) a);
1595 if (a > 9223372036854775807L)
1596 return 9223372036854775807L;
1597 if (a < (-9223372036854775808L))
1598 return (-9223372036854775808L);
1603 f = copysignf((float) 1.0, a);
1605 return 9223372036854775807L;
1606 return (-9223372036854775808L); */
1610 double builtin_f2d(float a)
1612 if (finitef(a)) return (double) a;
1617 return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1622 s4 builtin_d2i(double a)
1627 if (a >= 2147483647)
1629 if (a <= (-2147483647-1))
1630 return (-2147483647-1);
1635 d = copysign(1.0, a);
1638 return (-2147483647-1);
1642 s8 builtin_d2l(double a)
1647 if (a >= 9223372036854775807LL)
1648 return 9223372036854775807LL;
1649 if (a <= (-9223372036854775807LL-1))
1650 return (-9223372036854775807LL-1);
1655 d = copysign(1.0, a);
1657 return 9223372036854775807LL;
1658 return (-9223372036854775807LL-1);
1662 float builtin_d2f(double a)
1670 return copysignf(FLT_POSINF, (float) copysign(1.0, a));
1675 java_arrayheader *builtin_clone_array(void *env,java_arrayheader *o) {
1676 return Java_java_lang_VMObject_clone ( 0 , 0, o);
1681 * These are local overrides for various environment variables in Emacs.
1682 * Please do not remove this and leave it at the end of the file, where
1683 * Emacs will automagically detect them.
1684 * ---------------------------------------------------------------------
1687 * indent-tabs-mode: t