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 686 2003-12-04 11:35:11Z 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 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;
539 exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/NegativeArraySizeException")));
542 #ifdef SIZE_FROM_CLASSINFO
543 actualsize = align_size(dataoffset + size * componentsize);
545 actualsize = dataoffset + size * componentsize;
547 a = (java_arrayheader *)
548 heap_allocate(actualsize,
549 (desc->arraytype == ARRAYTYPE_OBJECT),
553 memset(a,0,actualsize);
556 /*printf("builtin_newarray: Created an array of size : %d\n",size);*/
558 a->objheader.vftbl = arrayvftbl;
560 #ifdef SIZE_FROM_CLASSINFO
561 a->alignedsize = actualsize;
566 /********************** Function: builtin_anewarray *************************
568 Creates an array of references to the given class type on the heap.
570 Return value: pointer to the array or NULL if no memory is available
572 XXX This function does not do The Right Thing, because it uses a
573 classinfo pointer at runtime. builtin_newarray should be used
576 *****************************************************************************/
579 builtin_anewarray(s4 size,classinfo *component)
581 return (java_objectarray*) builtin_newarray(size,class_array_of(component)->vftbl);
584 /******************** Function: builtin_newarray_int ***********************
586 Creates an array of 32 bit Integers on the heap.
588 Return value: pointer to the array or NULL if no memory is available
590 *****************************************************************************/
592 java_intarray *builtin_newarray_int (s4 size)
594 return (java_intarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_INT].arrayvftbl);
597 /******************** Function: builtin_newarray_long ***********************
599 Creates an array of 64 bit Integers on the heap.
601 Return value: pointer to the array or NULL if no memory is available
603 *****************************************************************************/
605 java_longarray *builtin_newarray_long (s4 size)
607 return (java_longarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_LONG].arrayvftbl);
610 /******************** function: builtin_newarray_float ***********************
612 Creates an array of 32 bit IEEE floats on the heap.
614 Return value: pointer to the array or NULL if no memory is available
616 *****************************************************************************/
618 java_floatarray *builtin_newarray_float (s4 size)
620 return (java_floatarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_FLOAT].arrayvftbl);
623 /******************** function: builtin_newarray_double ***********************
625 Creates an array of 64 bit IEEE floats on the heap.
627 Return value: pointer to the array or NULL if no memory is available
629 *****************************************************************************/
631 java_doublearray *builtin_newarray_double (s4 size)
633 return (java_doublearray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_DOUBLE].arrayvftbl);
636 /******************** function: builtin_newarray_byte ***********************
638 Creates an array of 8 bit Integers on the heap.
640 Return value: pointer to the array or NULL if no memory is available
642 *****************************************************************************/
644 java_bytearray *builtin_newarray_byte (s4 size)
646 return (java_bytearray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_BYTE].arrayvftbl);
649 /******************** function: builtin_newarray_char ************************
651 Creates an array of characters on the heap.
653 Return value: pointer to the array or NULL if no memory is available
655 *****************************************************************************/
657 java_chararray *builtin_newarray_char (s4 size)
659 return (java_chararray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl);
662 /******************** function: builtin_newarray_short ***********************
664 Creates an array of 16 bit Integers on the heap.
666 Return value: pointer to the array or NULL if no memory is available
668 *****************************************************************************/
670 java_shortarray *builtin_newarray_short (s4 size)
672 return (java_shortarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_SHORT].arrayvftbl);
675 /******************** function: builtin_newarray_boolean ************************
677 Creates an array of bytes on the heap. The array is designated as an array
678 of booleans (important for casts)
680 Return value: pointer to the array or NULL if no memory is available
682 *****************************************************************************/
684 java_booleanarray *builtin_newarray_boolean (s4 size)
686 return (java_booleanarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_BOOLEAN].arrayvftbl);
689 /**************** function: builtin_nmultianewarray ***************************
691 Creates a multi-dimensional array on the heap. The dimensions are passed in
695 n............number of dimensions to create
696 arrayvftbl...vftbl of the array class
697 dims.........array containing the size of each dimension to create
699 Return value: pointer to the array or NULL if no memory is available
701 ******************************************************************************/
703 java_arrayheader *builtin_nmultianewarray (int n,
704 vftbl *arrayvftbl, long *dims)
708 vftbl *componentvftbl;
710 /* create this dimension */
711 size = (int) dims[0];
712 a = builtin_newarray(size,arrayvftbl);
715 /* if this is the last dimension return */
718 /* get the vftbl of the components to create */
719 componentvftbl = arrayvftbl->arraydesc->componentvftbl;
720 if (!componentvftbl) /* XXX the verifier could check this */
721 panic ("multianewarray with too many dimensions");
723 /* create the component arrays */
724 for (i = 0; i < size; i++) {
725 java_arrayheader *ea =
726 builtin_nmultianewarray(n,componentvftbl,dims+1);
727 if (!ea) return NULL;
728 ((java_objectarray*)a)->data[i] = (java_objectheader *) ea;
734 /*****************************************************************************
737 Various functions for printing a message at method entry or exit (for
740 *****************************************************************************/
745 java_objectheader *builtin_trace_exception(java_objectheader *exceptionptr,
746 methodinfo *method, int *pos,
752 if (verbose || runverbose) {
753 printf("Exception ");
755 utf_display (exceptionptr->vftbl->class->name);
758 printf("Error: <Nullpointer instead of exception>");
759 if (!proto_java_lang_ClassCastException) printf("%s","proto_java_lang_ClassCastException==0");
760 if (!proto_java_lang_NullPointerException) printf("%s","proto_java_lang_NullPointerException==0");
761 if (!proto_java_lang_NullPointerException) printf("%s","proto_java_lang_NullPointerException==0");
762 if (!proto_java_lang_ArrayIndexOutOfBoundsException) printf("%s","proto_java_lang_ArrayIndexOutOfBoundsException==0");
763 if (!proto_java_lang_NegativeArraySizeException) printf("%s","proto_java_lang_NegativeArraySizeException==0");
764 if (!proto_java_lang_OutOfMemoryError) printf("%s","proto_java_lang_OutOfMemoryError==0");
765 if (!proto_java_lang_ArithmeticException) printf("%s","proto_java_lang_ArithmeticException==0");
766 if (!proto_java_lang_ArrayStoreException) printf("%s","proto_java_lang_ArrayStoreException==0");
767 if (!proto_java_lang_ThreadDeath) printf("%s","proto_java_lang_ThreadDeath==0");
768 if (!proto_java_lang_ThreadDeath) printf("%s","proto_java_lang_ThreadDeath==0");
771 printf(" thrown in ");
773 utf_display (method->class->name);
775 utf_display (method->name);
776 if (method->flags & ACC_SYNCHRONIZED)
780 printf("(%p) at position %p\n", method->entrypoint, pos);
783 printf("call_java_method\n");
790 #ifdef TRACE_ARGS_NUM
791 void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5,
792 #if TRACE_ARGS_NUM > 6
799 for (i = 0; i < methodindent; i++)
801 sprintf(logtext + methodindent, "called: ");
802 utf_sprint(logtext + strlen(logtext), method->class->name);
803 sprintf(logtext + strlen(logtext), ".");
804 utf_sprint(logtext + strlen(logtext), method->name);
805 utf_sprint(logtext + strlen(logtext), method->descriptor);
806 sprintf(logtext + strlen(logtext), "(");
808 switch (method->paramcount) {
812 #if defined(__I386__)
814 sprintf(logtext+strlen(logtext), "%llx", a0);
818 sprintf(logtext+strlen(logtext), "%llx, %llx", a0, a1);
822 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx", a0, a1, a2);
826 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx",
831 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx",
836 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx",
837 a0, a1, a2, a3, a4, a5);
840 #if TRACE_ARGS_NUM > 6
842 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx",
843 a0, a1, a2, a3, a4, a5, a6);
847 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx",
848 a0, a1, a2, a3, a4, a5, a6, a7);
852 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
853 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
857 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
858 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
863 sprintf(logtext+strlen(logtext), "%lx", a0);
867 sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1);
871 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2);
875 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx",
880 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx",
885 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx",
886 a0, a1, a2, a3, a4, a5);
889 #if TRACE_ARGS_NUM > 6
891 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx",
892 a0, a1, a2, a3, a4, a5, a6);
896 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx",
897 a0, a1, a2, a3, a4, a5, a6, a7);
901 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx, ...(%d)",
902 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
906 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, ...(%d)",
907 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
912 sprintf (logtext+strlen(logtext), ")");
920 void builtin_displaymethodstart(methodinfo *method)
922 sprintf(logtext, " ");
923 sprintf(logtext + methodindent, "called: ");
924 utf_sprint(logtext + strlen(logtext), method->class->name);
925 sprintf(logtext + strlen(logtext), ".");
926 utf_sprint(logtext + strlen(logtext), method->name);
927 utf_sprint(logtext + strlen(logtext), method->descriptor);
933 void builtin_displaymethodstop(methodinfo *method, s8 l, double d, float f)
936 for (i = 0; i < methodindent; i++)
939 sprintf(logtext + methodindent, "finished: ");
940 utf_sprint(logtext + strlen(logtext), method->class->name);
941 sprintf(logtext + strlen(logtext), ".");
942 utf_sprint(logtext + strlen(logtext), method->name);
943 utf_sprint(logtext + strlen(logtext), method->descriptor);
945 switch (method->returntype) {
947 sprintf(logtext + strlen(logtext), "->%d", (s4) l);
950 #if defined(__I386__)
951 sprintf(logtext + strlen(logtext), "->%lld", (s8) l);
953 sprintf(logtext + strlen(logtext), "->%ld", (s8) l);
957 #if defined(__I386__)
958 sprintf(logtext + strlen(logtext), "->%p", (u1*) ((s4) l));
960 sprintf(logtext + strlen(logtext), "->%p", (u1*) l);
964 sprintf(logtext + strlen(logtext), "->%g", f);
967 sprintf(logtext + strlen(logtext), "->%g", d);
974 void builtin_displaymethodexception(methodinfo *method)
977 for (i = 0; i < methodindent; i++)
979 sprintf(logtext + methodindent, "exception abort: ");
980 utf_sprint(logtext + strlen(logtext), method->class->name);
981 sprintf(logtext + strlen(logtext), ".");
982 utf_sprint(logtext + strlen(logtext), method->name);
983 utf_sprint(logtext + strlen(logtext), method->descriptor);
988 /****************************************************************************
989 SYNCHRONIZATION FUNCTIONS
990 *****************************************************************************/
993 * Lock the mutex of an object.
997 internal_lock_mutex_for_object (java_objectheader *object)
999 mutexHashEntry *entry;
1002 assert(object != 0);
1004 hashValue = MUTEX_HASH_VALUE(object);
1005 entry = &mutexHashTable[hashValue];
1007 if (entry->object != 0) {
1008 if (entry->mutex.count == 0 && entry->conditionCount == 0) {
1010 entry->mutex.holder = 0;
1011 entry->mutex.count = 0;
1012 entry->mutex.muxWaiters = 0;
1015 while (entry->next != 0 && entry->object != object)
1016 entry = entry->next;
1018 if (entry->object != object) {
1019 entry->next = firstFreeOverflowEntry;
1020 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
1022 entry = entry->next;
1025 assert(entry->conditionCount == 0);
1030 entry->mutex.holder = 0;
1031 entry->mutex.count = 0;
1032 entry->mutex.muxWaiters = 0;
1035 if (entry->object == 0)
1036 entry->object = object;
1038 internal_lock_mutex(&entry->mutex);
1044 * Unlocks the mutex of an object.
1048 internal_unlock_mutex_for_object (java_objectheader *object)
1051 mutexHashEntry *entry;
1053 hashValue = MUTEX_HASH_VALUE(object);
1054 entry = &mutexHashTable[hashValue];
1056 if (entry->object == object) {
1057 internal_unlock_mutex(&entry->mutex);
1060 while (entry->next != 0 && entry->next->object != object)
1061 entry = entry->next;
1063 assert(entry->next != 0);
1065 internal_unlock_mutex(&entry->next->mutex);
1067 if (entry->next->mutex.count == 0 && entry->conditionCount == 0) {
1068 mutexHashEntry *unlinked = entry->next;
1070 entry->next = unlinked->next;
1071 unlinked->next = firstFreeOverflowEntry;
1072 firstFreeOverflowEntry = unlinked;
1079 void builtin_monitorenter(java_objectheader *o)
1084 assert(blockInts == 0);
1088 hashValue = MUTEX_HASH_VALUE(o);
1089 if (mutexHashTable[hashValue].object == o
1090 && mutexHashTable[hashValue].mutex.holder == currentThread)
1091 ++mutexHashTable[hashValue].mutex.count;
1093 internal_lock_mutex_for_object(o);
1097 assert(blockInts == 0);
1102 void builtin_monitorexit (java_objectheader *o)
1107 assert(blockInts == 0);
1111 hashValue = MUTEX_HASH_VALUE(o);
1112 if (mutexHashTable[hashValue].object == o) {
1113 if (mutexHashTable[hashValue].mutex.count == 1
1114 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1115 internal_unlock_mutex_for_object(o);
1117 --mutexHashTable[hashValue].mutex.count;
1120 internal_unlock_mutex_for_object(o);
1124 assert(blockInts == 0);
1129 /*****************************************************************************
1130 MISCELLANEOUS HELPER FUNCTIONS
1131 *****************************************************************************/
1135 /*********** Functions for integer divisions *****************************
1137 On some systems (eg. DEC ALPHA), integer division is not supported by the
1138 CPU. These helper functions implement the missing functionality.
1140 ******************************************************************************/
1142 s4 builtin_idiv(s4 a, s4 b) { return a / b; }
1143 s4 builtin_irem(s4 a, s4 b) { return a % b; }
1146 /************** Functions for long arithmetics *******************************
1148 On systems where 64 bit Integers are not supported by the CPU, these
1149 functions are needed.
1151 ******************************************************************************/
1154 s8 builtin_ladd(s8 a, s8 b)
1159 return builtin_i2l(0);
1163 s8 builtin_lsub(s8 a, s8 b)
1168 return builtin_i2l(0);
1172 s8 builtin_lmul(s8 a, s8 b)
1177 return builtin_i2l(0);
1181 s8 builtin_ldiv(s8 a, s8 b)
1186 return builtin_i2l(0);
1190 s8 builtin_lrem(s8 a, s8 b)
1195 return builtin_i2l(0);
1199 s8 builtin_lshl(s8 a, s4 b)
1202 return a << (b & 63);
1204 return builtin_i2l(0);
1208 s8 builtin_lshr(s8 a, s4 b)
1211 return a >> (b & 63);
1213 return builtin_i2l(0);
1217 s8 builtin_lushr(s8 a, s4 b)
1220 return ((u8) a) >> (b & 63);
1222 return builtin_i2l(0);
1226 s8 builtin_land(s8 a, s8 b)
1231 return builtin_i2l(0);
1235 s8 builtin_lor(s8 a, s8 b)
1240 return builtin_i2l(0);
1244 s8 builtin_lxor(s8 a, s8 b)
1249 return builtin_i2l(0);
1253 s8 builtin_lneg(s8 a)
1258 return builtin_i2l(0);
1262 s4 builtin_lcmp(s8 a, s8 b)
1265 if (a < b) return -1;
1266 if (a > b) return 1;
1277 /*********** Functions for floating point operations *************************/
1279 float builtin_fadd(float a, float b)
1281 if (isnanf(a)) return FLT_NAN;
1282 if (isnanf(b)) return FLT_NAN;
1293 if (copysignf(1.0, a) == copysignf(1.0, b))
1302 float builtin_fsub(float a, float b)
1304 return builtin_fadd(a, builtin_fneg(b));
1308 float builtin_fmul(float a, float b)
1310 if (isnanf(a)) return FLT_NAN;
1311 if (isnanf(b)) return FLT_NAN;
1313 if (finitef(b)) return a*b;
1315 if (a == 0) return FLT_NAN;
1316 else return copysignf(b, copysignf(1.0, b)*a);
1321 if (b == 0) return FLT_NAN;
1322 else return copysignf(a, copysignf(1.0, a)*b);
1325 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1331 float builtin_fdiv(float a, float b)
1333 if (finitef(a) && finitef(b)) {
1347 float builtin_frem(float a, float b)
1353 float builtin_fneg(float a)
1355 if (isnanf(a)) return a;
1357 if (finitef(a)) return -a;
1358 else return copysignf(a, -copysignf(1.0, a));
1363 s4 builtin_fcmpl(float a, float b)
1365 if (isnanf(a)) return -1;
1366 if (isnanf(b)) return -1;
1367 if (!finitef(a) || !finitef(b)) {
1368 a = finitef(a) ? 0 : copysignf(1.0, a);
1369 b = finitef(b) ? 0 : copysignf(1.0, b);
1371 if (a > b) return 1;
1372 if (a == b) return 0;
1377 s4 builtin_fcmpg(float a, float b)
1379 if (isnanf(a)) return 1;
1380 if (isnanf(b)) return 1;
1381 if (!finitef(a) || !finitef(b)) {
1382 a = finitef(a) ? 0 : copysignf(1.0, a);
1383 b = finitef(b) ? 0 : copysignf(1.0, b);
1385 if (a > b) return 1;
1386 if (a == b) return 0;
1392 /************************* Functions for doubles ****************************/
1394 double builtin_dadd(double a, double b)
1396 if (isnan(a)) return DBL_NAN;
1397 if (isnan(b)) return DBL_NAN;
1399 if (finite(b)) return a+b;
1403 if (finite(b)) return a;
1405 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1406 else return DBL_NAN;
1412 double builtin_dsub(double a, double b)
1414 return builtin_dadd(a, builtin_dneg(b));
1418 double builtin_dmul(double a, double b)
1420 if (isnan(a)) return DBL_NAN;
1421 if (isnan(b)) return DBL_NAN;
1423 if (finite(b)) return a * b;
1425 if (a == 0) return DBL_NAN;
1426 else return copysign(b, copysign(1.0, b) * a);
1431 if (b == 0) return DBL_NAN;
1432 else return copysign(a, copysign(1.0, a) * b);
1435 return copysign(a, copysign(1.0, a) * copysign(1.0, b));
1441 double builtin_ddiv(double a, double b)
1443 if (finite(a) && finite(b)) {
1457 double builtin_drem(double a, double b)
1463 double builtin_dneg(double a)
1465 if (isnan(a)) return a;
1467 if (finite(a)) return -a;
1468 else return copysign(a, -copysign(1.0, a));
1473 s4 builtin_dcmpl(double a, double b)
1475 if (isnan(a)) return -1;
1476 if (isnan(b)) return -1;
1477 if (!finite(a) || !finite(b)) {
1478 a = finite(a) ? 0 : copysign(1.0, a);
1479 b = finite(b) ? 0 : copysign(1.0, b);
1481 if (a > b) return 1;
1482 if (a == b) return 0;
1487 s4 builtin_dcmpg(double a, double b)
1489 if (isnan(a)) return 1;
1490 if (isnan(b)) return 1;
1491 if (!finite(a) || !finite(b)) {
1492 a = finite(a) ? 0 : copysign(1.0, a);
1493 b = finite(b) ? 0 : copysign(1.0, b);
1495 if (a > b) return 1;
1496 if (a == b) return 0;
1501 /*********************** Conversion operations ****************************/
1503 s8 builtin_i2l(s4 i)
1508 s8 v; v.high = 0; v.low=i; return v;
1513 float builtin_i2f(s4 a)
1515 float f = (float) a;
1520 double builtin_i2d(s4 a)
1522 double d = (double) a;
1527 s4 builtin_l2i(s8 l)
1537 float builtin_l2f(s8 a)
1540 float f = (float) a;
1548 double builtin_l2d(s8 a)
1551 double d = (double) a;
1559 s4 builtin_f2i(float a)
1562 return builtin_d2i((double) a);
1571 if (a < (-2147483648))
1572 return (-2147483648);
1575 f = copysignf((float) 1.0, a);
1578 return (-2147483648); */
1582 s8 builtin_f2l(float a)
1585 return builtin_d2l((double) a);
1590 if (a > 9223372036854775807L)
1591 return 9223372036854775807L;
1592 if (a < (-9223372036854775808L))
1593 return (-9223372036854775808L);
1598 f = copysignf((float) 1.0, a);
1600 return 9223372036854775807L;
1601 return (-9223372036854775808L); */
1605 double builtin_f2d(float a)
1607 if (finitef(a)) return (double) a;
1612 return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1617 s4 builtin_d2i(double a)
1622 if (a >= 2147483647)
1624 if (a <= (-2147483647-1))
1625 return (-2147483647-1);
1630 d = copysign(1.0, a);
1633 return (-2147483647-1);
1637 s8 builtin_d2l(double a)
1642 if (a >= 9223372036854775807LL)
1643 return 9223372036854775807LL;
1644 if (a <= (-9223372036854775807LL-1))
1645 return (-9223372036854775807LL-1);
1650 d = copysign(1.0, a);
1652 return 9223372036854775807LL;
1653 return (-9223372036854775807LL-1);
1657 float builtin_d2f(double a)
1665 return copysignf(FLT_POSINF, (float) copysign(1.0, a));
1670 java_arrayheader *builtin_clone_array(void *env,java_arrayheader *o) {
1671 return Java_java_lang_VMObject_clone ( 0 , 0, o);
1676 * These are local overrides for various environment variables in Emacs.
1677 * Please do not remove this and leave it at the end of the file, where
1678 * Emacs will automagically detect them.
1679 * ---------------------------------------------------------------------
1682 * indent-tabs-mode: t