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 682 2003-12-01 15:33:30Z jowenn $
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 sprintf(logtext, "Builtin exception thrown: ");
341 if (local_exceptionptr)
342 utf_sprint(logtext + strlen(logtext), local_exceptionptr->vftbl->class->name);
344 sprintf(logtext+strlen(logtext),"%s","Error: <Nullpointer instead of exception>");
345 if (!proto_java_lang_ClassCastException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ClassCastException==0");
346 if (!proto_java_lang_NullPointerException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_NullPointerException==0");
347 if (!proto_java_lang_NullPointerException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_NullPointerException==0");
348 if (!proto_java_lang_ArrayIndexOutOfBoundsException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ArrayIndexOutOfBoundsException==0");
349 if (!proto_java_lang_NegativeArraySizeException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_NegativeArraySizeException==0");
350 if (!proto_java_lang_OutOfMemoryError) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_OutOfMemoryError==0");
351 if (!proto_java_lang_ArithmeticException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ArithmeticException==0");
352 if (!proto_java_lang_ArrayStoreException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ArrayStoreException==0");
353 if (!proto_java_lang_ThreadDeath) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ThreadDeath==0");
354 if (!proto_java_lang_ThreadDeath) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ThreadDeath==0");
358 exceptionptr = local_exceptionptr;
359 return local_exceptionptr;
363 /******************* function: builtin_canstore *******************************
365 Checks, if an object can be stored in an array.
366 Return value: 1 ... possible
369 ******************************************************************************/
371 s4 builtin_canstore (java_objectarray *a, java_objectheader *o)
373 arraydescriptor *desc;
374 arraydescriptor *valuedesc;
375 vftbl *componentvftbl;
382 /* The following is guaranteed (by verifier checks):
384 * *) a->...vftbl->arraydesc != NULL
385 * *) a->...vftbl->arraydesc->componentvftbl != NULL
386 * *) o->vftbl is not an interface vftbl
389 desc = a->header.objheader.vftbl->arraydesc;
390 componentvftbl = desc->componentvftbl;
391 valuevftbl = o->vftbl;
393 if ((dim_m1 = desc->dimension - 1) == 0) {
394 /* {a is a one-dimensional array} */
395 /* {a is an array of references} */
397 if (valuevftbl == componentvftbl)
400 if ((base = componentvftbl->baseval) <= 0)
401 /* an array of interface references */
402 return (valuevftbl->interfacetablelength > -base &&
403 valuevftbl->interfacetable[base] != NULL);
405 return (unsigned)(valuevftbl->baseval - base)
406 <= (unsigned)(componentvftbl->diffval);
408 /* {a has dimension > 1} */
409 /* {componentvftbl->arraydesc != NULL} */
411 /* check if o is an array */
412 if ((valuedesc = valuevftbl->arraydesc) == NULL)
414 /* {o is an array} */
416 return builtin_descriptorscompatible(valuedesc,componentvftbl->arraydesc);
419 /* This is an optimized version where a is guaranteed to be one-dimensional */
420 s4 builtin_canstore_onedim (java_objectarray *a, java_objectheader *o)
422 arraydescriptor *desc;
429 /* The following is guaranteed (by verifier checks):
431 * *) a->...vftbl->arraydesc != NULL
432 * *) a->...vftbl->arraydesc->elementvftbl != NULL
433 * *) a->...vftbl->arraydesc->dimension == 1
434 * *) o->vftbl is not an interface vftbl
437 desc = a->header.objheader.vftbl->arraydesc;
438 elementvftbl = desc->elementvftbl;
439 valuevftbl = o->vftbl;
441 /* {a is a one-dimensional array} */
443 if (valuevftbl == elementvftbl)
446 if ((base = elementvftbl->baseval) <= 0)
447 /* an array of interface references */
448 return (valuevftbl->interfacetablelength > -base &&
449 valuevftbl->interfacetable[base] != NULL);
451 return (unsigned)(valuevftbl->baseval - base)
452 <= (unsigned)(elementvftbl->diffval);
455 /* This is an optimized version where a is guaranteed to be a
456 * one-dimensional array of a class type */
457 /* XXX this could be inlined by the code generator */
458 s4 builtin_canstore_onedim_class (java_objectarray *a, java_objectheader *o)
465 /* The following is guaranteed (by verifier checks):
467 * *) a->...vftbl->arraydesc != NULL
468 * *) a->...vftbl->arraydesc->elementvftbl != NULL
469 * *) a->...vftbl->arraydesc->elementvftbl is not an interface vftbl
470 * *) a->...vftbl->arraydesc->dimension == 1
471 * *) o->vftbl is not an interface vftbl
474 elementvftbl = a->header.objheader.vftbl->arraydesc->elementvftbl;
475 valuevftbl = o->vftbl;
477 /* {a is a one-dimensional array} */
479 if (valuevftbl == elementvftbl)
482 return (unsigned)(valuevftbl->baseval - elementvftbl->baseval)
483 <= (unsigned)(elementvftbl->diffval);
487 /******************** Function: builtin_new **********************************
489 Creates a new instance of class c on the heap.
490 Return value: pointer to the object or NULL if no memory is
493 *****************************************************************************/
496 #define align_size(size) ((size + ((1 << ALIGNMENT) - 1)) & ~((1 << ALIGNMENT) - 1))
498 java_objectheader *builtin_new(classinfo *c)
500 java_objectheader *o;
504 #ifdef SIZE_FROM_CLASSINFO
505 c->alignedsize = align_size(c->instancesize);
506 o = heap_allocate(c->alignedsize, true, c->finalizer);
508 o = heap_allocate(c->instancesize, true, c->finalizer);
512 memset(o, 0, c->instancesize);
519 /********************** Function: builtin_newarray **************************
521 Creates an array with the given vftbl on the heap.
523 Return value: pointer to the array or NULL if no memory is available
525 CAUTION: The given vftbl must be the vftbl of the *array* class,
526 not of the element class.
528 *****************************************************************************/
530 java_arrayheader *builtin_newarray(s4 size,vftbl *arrayvftbl)
533 arraydescriptor *desc = arrayvftbl->arraydesc;
534 s4 dataoffset = desc->dataoffset;
535 s4 componentsize = desc->componentsize;
538 exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/NegativeArraySizeException")));
541 #ifdef SIZE_FROM_CLASSINFO
542 s4 actualsize = align_size(dataoffset + size * componentsize);
544 s4 actualsize = dataoffset + size * componentsize;
546 a = (java_arrayheader *)
547 heap_allocate(actualsize,
548 (desc->arraytype == ARRAYTYPE_OBJECT),
552 memset(a,0,actualsize);
554 a->objheader.vftbl = arrayvftbl;
556 #ifdef SIZE_FROM_CLASSINFO
557 a->alignedsize = actualsize;
562 /********************** Function: builtin_anewarray *************************
564 Creates an array of references to the given class type on the heap.
566 Return value: pointer to the array or NULL if no memory is available
568 XXX This function does not do The Right Thing, because it uses a
569 classinfo pointer at runtime. builtin_newarray should be used
572 *****************************************************************************/
575 builtin_anewarray(s4 size,classinfo *component)
577 return (java_objectarray*) builtin_newarray(size,class_array_of(component)->vftbl);
580 /******************** Function: builtin_newarray_int ***********************
582 Creates an array of 32 bit Integers on the heap.
584 Return value: pointer to the array or NULL if no memory is available
586 *****************************************************************************/
588 java_intarray *builtin_newarray_int (s4 size)
590 return (java_intarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_INT].arrayvftbl);
593 /******************** Function: builtin_newarray_long ***********************
595 Creates an array of 64 bit Integers on the heap.
597 Return value: pointer to the array or NULL if no memory is available
599 *****************************************************************************/
601 java_longarray *builtin_newarray_long (s4 size)
603 return (java_longarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_LONG].arrayvftbl);
606 /******************** function: builtin_newarray_float ***********************
608 Creates an array of 32 bit IEEE floats on the heap.
610 Return value: pointer to the array or NULL if no memory is available
612 *****************************************************************************/
614 java_floatarray *builtin_newarray_float (s4 size)
616 return (java_floatarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_FLOAT].arrayvftbl);
619 /******************** function: builtin_newarray_double ***********************
621 Creates an array of 64 bit IEEE floats on the heap.
623 Return value: pointer to the array or NULL if no memory is available
625 *****************************************************************************/
627 java_doublearray *builtin_newarray_double (s4 size)
629 return (java_doublearray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_DOUBLE].arrayvftbl);
632 /******************** function: builtin_newarray_byte ***********************
634 Creates an array of 8 bit Integers on the heap.
636 Return value: pointer to the array or NULL if no memory is available
638 *****************************************************************************/
640 java_bytearray *builtin_newarray_byte (s4 size)
642 return (java_bytearray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_BYTE].arrayvftbl);
645 /******************** function: builtin_newarray_char ************************
647 Creates an array of characters on the heap.
649 Return value: pointer to the array or NULL if no memory is available
651 *****************************************************************************/
653 java_chararray *builtin_newarray_char (s4 size)
655 return (java_chararray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl);
658 /******************** function: builtin_newarray_short ***********************
660 Creates an array of 16 bit Integers on the heap.
662 Return value: pointer to the array or NULL if no memory is available
664 *****************************************************************************/
666 java_shortarray *builtin_newarray_short (s4 size)
668 return (java_shortarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_SHORT].arrayvftbl);
671 /******************** function: builtin_newarray_boolean ************************
673 Creates an array of bytes on the heap. The array is designated as an array
674 of booleans (important for casts)
676 Return value: pointer to the array or NULL if no memory is available
678 *****************************************************************************/
680 java_booleanarray *builtin_newarray_boolean (s4 size)
682 return (java_booleanarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_BOOLEAN].arrayvftbl);
685 /**************** function: builtin_nmultianewarray ***************************
687 Creates a multi-dimensional array on the heap. The dimensions are passed in
691 n............number of dimensions to create
692 arrayvftbl...vftbl of the array class
693 dims.........array containing the size of each dimension to create
695 Return value: pointer to the array or NULL if no memory is available
697 ******************************************************************************/
699 java_arrayheader *builtin_nmultianewarray (int n,
700 vftbl *arrayvftbl, long *dims)
704 vftbl *componentvftbl;
706 /* create this dimension */
707 size = (int) dims[0];
708 a = builtin_newarray(size,arrayvftbl);
711 /* if this is the last dimension return */
714 /* get the vftbl of the components to create */
715 componentvftbl = arrayvftbl->arraydesc->componentvftbl;
716 if (!componentvftbl) /* XXX the verifier could check this */
717 panic ("multianewarray with too many dimensions");
719 /* create the component arrays */
720 for (i = 0; i < size; i++) {
721 java_arrayheader *ea =
722 builtin_nmultianewarray(n,componentvftbl,dims+1);
723 if (!ea) return NULL;
724 ((java_objectarray*)a)->data[i] = (java_objectheader *) ea;
730 /*****************************************************************************
733 Various functions for printing a message at method entry or exit (for
736 *****************************************************************************/
741 java_objectheader *builtin_trace_exception(java_objectheader *exceptionptr,
742 methodinfo *method, int *pos,
748 if (verbose || runverbose) {
749 printf("Exception ");
751 utf_display (exceptionptr->vftbl->class->name);
754 printf("Error: <Nullpointer instead of exception>");
755 if (!proto_java_lang_ClassCastException) printf("%s","proto_java_lang_ClassCastException==0");
756 if (!proto_java_lang_NullPointerException) printf("%s","proto_java_lang_NullPointerException==0");
757 if (!proto_java_lang_NullPointerException) printf("%s","proto_java_lang_NullPointerException==0");
758 if (!proto_java_lang_ArrayIndexOutOfBoundsException) printf("%s","proto_java_lang_ArrayIndexOutOfBoundsException==0");
759 if (!proto_java_lang_NegativeArraySizeException) printf("%s","proto_java_lang_NegativeArraySizeException==0");
760 if (!proto_java_lang_OutOfMemoryError) printf("%s","proto_java_lang_OutOfMemoryError==0");
761 if (!proto_java_lang_ArithmeticException) printf("%s","proto_java_lang_ArithmeticException==0");
762 if (!proto_java_lang_ArrayStoreException) printf("%s","proto_java_lang_ArrayStoreException==0");
763 if (!proto_java_lang_ThreadDeath) printf("%s","proto_java_lang_ThreadDeath==0");
764 if (!proto_java_lang_ThreadDeath) printf("%s","proto_java_lang_ThreadDeath==0");
767 printf(" thrown in ");
769 utf_display (method->class->name);
771 utf_display (method->name);
772 if (method->flags & ACC_SYNCHRONIZED)
776 printf("(%p) at position %p\n", method->entrypoint, pos);
779 printf("call_java_method\n");
786 #ifdef TRACE_ARGS_NUM
787 void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5,
788 #if TRACE_ARGS_NUM > 6
795 for (i = 0; i < methodindent; i++)
797 sprintf(logtext + methodindent, "called: ");
798 utf_sprint(logtext + strlen(logtext), method->class->name);
799 sprintf(logtext + strlen(logtext), ".");
800 utf_sprint(logtext + strlen(logtext), method->name);
801 utf_sprint(logtext + strlen(logtext), method->descriptor);
802 sprintf(logtext + strlen(logtext), "(");
804 switch (method->paramcount) {
808 #if defined(__I386__)
810 sprintf(logtext+strlen(logtext), "%llx", a0);
814 sprintf(logtext+strlen(logtext), "%llx, %llx", a0, a1);
818 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx", a0, a1, a2);
822 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx",
827 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx",
832 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx",
833 a0, a1, a2, a3, a4, a5);
836 #if TRACE_ARGS_NUM > 6
838 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx",
839 a0, a1, a2, a3, a4, a5, a6);
843 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx",
844 a0, a1, a2, a3, a4, a5, a6, a7);
848 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
849 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
853 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
854 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
859 sprintf(logtext+strlen(logtext), "%lx", a0);
863 sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1);
867 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2);
871 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx",
876 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx",
881 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx",
882 a0, a1, a2, a3, a4, a5);
885 #if TRACE_ARGS_NUM > 6
887 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx",
888 a0, a1, a2, a3, a4, a5, a6);
892 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx",
893 a0, a1, a2, a3, a4, a5, a6, a7);
897 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx, ...(%d)",
898 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
902 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, ...(%d)",
903 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
908 sprintf (logtext+strlen(logtext), ")");
916 void builtin_displaymethodstart(methodinfo *method)
918 sprintf(logtext, " ");
919 sprintf(logtext + methodindent, "called: ");
920 utf_sprint(logtext + strlen(logtext), method->class->name);
921 sprintf(logtext + strlen(logtext), ".");
922 utf_sprint(logtext + strlen(logtext), method->name);
923 utf_sprint(logtext + strlen(logtext), method->descriptor);
929 void builtin_displaymethodstop(methodinfo *method, s8 l, double d, float f)
932 for (i = 0; i < methodindent; i++)
935 sprintf(logtext + methodindent, "finished: ");
936 utf_sprint(logtext + strlen(logtext), method->class->name);
937 sprintf(logtext + strlen(logtext), ".");
938 utf_sprint(logtext + strlen(logtext), method->name);
939 utf_sprint(logtext + strlen(logtext), method->descriptor);
941 switch (method->returntype) {
943 sprintf(logtext + strlen(logtext), "->%d", (s4) l);
946 #if defined(__I386__)
947 sprintf(logtext + strlen(logtext), "->%lld", (s8) l);
949 sprintf(logtext + strlen(logtext), "->%ld", (s8) l);
953 #if defined(__I386__)
954 sprintf(logtext + strlen(logtext), "->%p", (u1*) ((s4) l));
956 sprintf(logtext + strlen(logtext), "->%p", (u1*) l);
960 sprintf(logtext + strlen(logtext), "->%g", f);
963 sprintf(logtext + strlen(logtext), "->%g", d);
970 void builtin_displaymethodexception(methodinfo *method)
973 for (i = 0; i < methodindent; i++)
975 sprintf(logtext + methodindent, "exception abort: ");
976 utf_sprint(logtext + strlen(logtext), method->class->name);
977 sprintf(logtext + strlen(logtext), ".");
978 utf_sprint(logtext + strlen(logtext), method->name);
979 utf_sprint(logtext + strlen(logtext), method->descriptor);
984 /****************************************************************************
985 SYNCHRONIZATION FUNCTIONS
986 *****************************************************************************/
989 * Lock the mutex of an object.
993 internal_lock_mutex_for_object (java_objectheader *object)
995 mutexHashEntry *entry;
1000 hashValue = MUTEX_HASH_VALUE(object);
1001 entry = &mutexHashTable[hashValue];
1003 if (entry->object != 0) {
1004 if (entry->mutex.count == 0 && entry->conditionCount == 0) {
1006 entry->mutex.holder = 0;
1007 entry->mutex.count = 0;
1008 entry->mutex.muxWaiters = 0;
1011 while (entry->next != 0 && entry->object != object)
1012 entry = entry->next;
1014 if (entry->object != object) {
1015 entry->next = firstFreeOverflowEntry;
1016 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
1018 entry = entry->next;
1021 assert(entry->conditionCount == 0);
1026 entry->mutex.holder = 0;
1027 entry->mutex.count = 0;
1028 entry->mutex.muxWaiters = 0;
1031 if (entry->object == 0)
1032 entry->object = object;
1034 internal_lock_mutex(&entry->mutex);
1040 * Unlocks the mutex of an object.
1044 internal_unlock_mutex_for_object (java_objectheader *object)
1047 mutexHashEntry *entry;
1049 hashValue = MUTEX_HASH_VALUE(object);
1050 entry = &mutexHashTable[hashValue];
1052 if (entry->object == object) {
1053 internal_unlock_mutex(&entry->mutex);
1056 while (entry->next != 0 && entry->next->object != object)
1057 entry = entry->next;
1059 assert(entry->next != 0);
1061 internal_unlock_mutex(&entry->next->mutex);
1063 if (entry->next->mutex.count == 0 && entry->conditionCount == 0) {
1064 mutexHashEntry *unlinked = entry->next;
1066 entry->next = unlinked->next;
1067 unlinked->next = firstFreeOverflowEntry;
1068 firstFreeOverflowEntry = unlinked;
1075 void builtin_monitorenter(java_objectheader *o)
1080 assert(blockInts == 0);
1084 hashValue = MUTEX_HASH_VALUE(o);
1085 if (mutexHashTable[hashValue].object == o
1086 && mutexHashTable[hashValue].mutex.holder == currentThread)
1087 ++mutexHashTable[hashValue].mutex.count;
1089 internal_lock_mutex_for_object(o);
1093 assert(blockInts == 0);
1098 void builtin_monitorexit (java_objectheader *o)
1103 assert(blockInts == 0);
1107 hashValue = MUTEX_HASH_VALUE(o);
1108 if (mutexHashTable[hashValue].object == o) {
1109 if (mutexHashTable[hashValue].mutex.count == 1
1110 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1111 internal_unlock_mutex_for_object(o);
1113 --mutexHashTable[hashValue].mutex.count;
1116 internal_unlock_mutex_for_object(o);
1120 assert(blockInts == 0);
1125 /*****************************************************************************
1126 MISCELLANEOUS HELPER FUNCTIONS
1127 *****************************************************************************/
1131 /*********** Functions for integer divisions *****************************
1133 On some systems (eg. DEC ALPHA), integer division is not supported by the
1134 CPU. These helper functions implement the missing functionality.
1136 ******************************************************************************/
1138 s4 builtin_idiv(s4 a, s4 b) { return a / b; }
1139 s4 builtin_irem(s4 a, s4 b) { return a % b; }
1142 /************** Functions for long arithmetics *******************************
1144 On systems where 64 bit Integers are not supported by the CPU, these
1145 functions are needed.
1147 ******************************************************************************/
1150 s8 builtin_ladd(s8 a, s8 b)
1155 return builtin_i2l(0);
1159 s8 builtin_lsub(s8 a, s8 b)
1164 return builtin_i2l(0);
1168 s8 builtin_lmul(s8 a, s8 b)
1173 return builtin_i2l(0);
1177 s8 builtin_ldiv(s8 a, s8 b)
1182 return builtin_i2l(0);
1186 s8 builtin_lrem(s8 a, s8 b)
1191 return builtin_i2l(0);
1195 s8 builtin_lshl(s8 a, s4 b)
1198 return a << (b & 63);
1200 return builtin_i2l(0);
1204 s8 builtin_lshr(s8 a, s4 b)
1207 return a >> (b & 63);
1209 return builtin_i2l(0);
1213 s8 builtin_lushr(s8 a, s4 b)
1216 return ((u8) a) >> (b & 63);
1218 return builtin_i2l(0);
1222 s8 builtin_land(s8 a, s8 b)
1227 return builtin_i2l(0);
1231 s8 builtin_lor(s8 a, s8 b)
1236 return builtin_i2l(0);
1240 s8 builtin_lxor(s8 a, s8 b)
1245 return builtin_i2l(0);
1249 s8 builtin_lneg(s8 a)
1254 return builtin_i2l(0);
1258 s4 builtin_lcmp(s8 a, s8 b)
1261 if (a < b) return -1;
1262 if (a > b) return 1;
1273 /*********** Functions for floating point operations *************************/
1275 float builtin_fadd(float a, float b)
1277 if (isnanf(a)) return FLT_NAN;
1278 if (isnanf(b)) return FLT_NAN;
1289 if (copysignf(1.0, a) == copysignf(1.0, b))
1298 float builtin_fsub(float a, float b)
1300 return builtin_fadd(a, builtin_fneg(b));
1304 float builtin_fmul(float a, float b)
1306 if (isnanf(a)) return FLT_NAN;
1307 if (isnanf(b)) return FLT_NAN;
1309 if (finitef(b)) return a*b;
1311 if (a == 0) return FLT_NAN;
1312 else return copysignf(b, copysignf(1.0, b)*a);
1317 if (b == 0) return FLT_NAN;
1318 else return copysignf(a, copysignf(1.0, a)*b);
1321 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1327 float builtin_fdiv(float a, float b)
1329 if (finitef(a) && finitef(b)) {
1343 float builtin_frem(float a, float b)
1349 float builtin_fneg(float a)
1351 if (isnanf(a)) return a;
1353 if (finitef(a)) return -a;
1354 else return copysignf(a, -copysignf(1.0, a));
1359 s4 builtin_fcmpl(float a, float b)
1361 if (isnanf(a)) return -1;
1362 if (isnanf(b)) return -1;
1363 if (!finitef(a) || !finitef(b)) {
1364 a = finitef(a) ? 0 : copysignf(1.0, a);
1365 b = finitef(b) ? 0 : copysignf(1.0, b);
1367 if (a > b) return 1;
1368 if (a == b) return 0;
1373 s4 builtin_fcmpg(float a, float b)
1375 if (isnanf(a)) return 1;
1376 if (isnanf(b)) return 1;
1377 if (!finitef(a) || !finitef(b)) {
1378 a = finitef(a) ? 0 : copysignf(1.0, a);
1379 b = finitef(b) ? 0 : copysignf(1.0, b);
1381 if (a > b) return 1;
1382 if (a == b) return 0;
1388 /************************* Functions for doubles ****************************/
1390 double builtin_dadd(double a, double b)
1392 if (isnan(a)) return DBL_NAN;
1393 if (isnan(b)) return DBL_NAN;
1395 if (finite(b)) return a+b;
1399 if (finite(b)) return a;
1401 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1402 else return DBL_NAN;
1408 double builtin_dsub(double a, double b)
1410 return builtin_dadd(a, builtin_dneg(b));
1414 double builtin_dmul(double a, double b)
1416 if (isnan(a)) return DBL_NAN;
1417 if (isnan(b)) return DBL_NAN;
1419 if (finite(b)) return a * b;
1421 if (a == 0) return DBL_NAN;
1422 else return copysign(b, copysign(1.0, b) * a);
1427 if (b == 0) return DBL_NAN;
1428 else return copysign(a, copysign(1.0, a) * b);
1431 return copysign(a, copysign(1.0, a) * copysign(1.0, b));
1437 double builtin_ddiv(double a, double b)
1439 if (finite(a) && finite(b)) {
1453 double builtin_drem(double a, double b)
1459 double builtin_dneg(double a)
1461 if (isnan(a)) return a;
1463 if (finite(a)) return -a;
1464 else return copysign(a, -copysign(1.0, a));
1469 s4 builtin_dcmpl(double a, double b)
1471 if (isnan(a)) return -1;
1472 if (isnan(b)) return -1;
1473 if (!finite(a) || !finite(b)) {
1474 a = finite(a) ? 0 : copysign(1.0, a);
1475 b = finite(b) ? 0 : copysign(1.0, b);
1477 if (a > b) return 1;
1478 if (a == b) return 0;
1483 s4 builtin_dcmpg(double a, double b)
1485 if (isnan(a)) return 1;
1486 if (isnan(b)) return 1;
1487 if (!finite(a) || !finite(b)) {
1488 a = finite(a) ? 0 : copysign(1.0, a);
1489 b = finite(b) ? 0 : copysign(1.0, b);
1491 if (a > b) return 1;
1492 if (a == b) return 0;
1497 /*********************** Conversion operations ****************************/
1499 s8 builtin_i2l(s4 i)
1504 s8 v; v.high = 0; v.low=i; return v;
1509 float builtin_i2f(s4 a)
1511 float f = (float) a;
1516 double builtin_i2d(s4 a)
1518 double d = (double) a;
1523 s4 builtin_l2i(s8 l)
1533 float builtin_l2f(s8 a)
1536 float f = (float) a;
1544 double builtin_l2d(s8 a)
1547 double d = (double) a;
1555 s4 builtin_f2i(float a)
1558 return builtin_d2i((double) a);
1567 if (a < (-2147483648))
1568 return (-2147483648);
1571 f = copysignf((float) 1.0, a);
1574 return (-2147483648); */
1578 s8 builtin_f2l(float a)
1581 return builtin_d2l((double) a);
1586 if (a > 9223372036854775807L)
1587 return 9223372036854775807L;
1588 if (a < (-9223372036854775808L))
1589 return (-9223372036854775808L);
1594 f = copysignf((float) 1.0, a);
1596 return 9223372036854775807L;
1597 return (-9223372036854775808L); */
1601 double builtin_f2d(float a)
1603 if (finitef(a)) return (double) a;
1608 return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1613 s4 builtin_d2i(double a)
1618 if (a >= 2147483647)
1620 if (a <= (-2147483647-1))
1621 return (-2147483647-1);
1626 d = copysign(1.0, a);
1629 return (-2147483647-1);
1633 s8 builtin_d2l(double a)
1638 if (a >= 9223372036854775807LL)
1639 return 9223372036854775807LL;
1640 if (a <= (-9223372036854775807LL-1))
1641 return (-9223372036854775807LL-1);
1646 d = copysign(1.0, a);
1648 return 9223372036854775807LL;
1649 return (-9223372036854775807LL-1);
1653 float builtin_d2f(double a)
1661 return copysignf(FLT_POSINF, (float) copysign(1.0, a));
1666 java_arrayheader *builtin_clone_array(void *env,java_arrayheader *o) {
1667 return Java_java_lang_VMObject_clone ( 0 , 0, o);
1672 * These are local overrides for various environment variables in Emacs.
1673 * Please do not remove this and leave it at the end of the file, where
1674 * Emacs will automagically detect them.
1675 * ---------------------------------------------------------------------
1678 * indent-tabs-mode: t