X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fbuiltin.c;h=377bad8830fd3370390200d55b26348f91e13fd7;hb=7659949229c634784f7d27aa8b679fdd4c8351ab;hp=598820bf5dcb0f0daf1eed122557f83117756c8e;hpb=58df38eba6741e9805cd55f6ca7b149773ef1c73;p=cacao.git diff --git a/src/vm/builtin.c b/src/vm/builtin.c index 598820bf5..377bad883 100644 --- a/src/vm/builtin.c +++ b/src/vm/builtin.c @@ -1,9 +1,7 @@ /* src/vm/builtin.c - functions for unsupported operations - Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel, - C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring, - E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, - J. Wenninger, Institut f. Computersprachen - TU Wien + Copyright (C) 1996-2005, 2006, 2007, 2008 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -56,7 +54,7 @@ #include "native/llni.h" #include "threads/lock-common.h" -#include "threads/threads-common.h" +#include "threads/thread.h" #include "toolbox/logging.h" #include "toolbox/util.h" @@ -67,7 +65,7 @@ #include "vm/exceptions.h" #include "vm/global.h" #include "vm/initialize.h" -#include "vm/primitive.h" +#include "vm/primitive.hpp" #include "vm/stringlocal.h" #include "vm/jit/asmpart.h" @@ -83,9 +81,6 @@ #include #endif -#if defined(ENABLE_DEBUG_FILTER) -# include "vm/jit/show.h" -#endif /* include builtin tables *****************************************************/ @@ -95,6 +90,11 @@ CYCLES_STATS_DECLARE(builtin_new ,100,5) CYCLES_STATS_DECLARE(builtin_overhead , 80,1) + +/*============================================================================*/ +/* BUILTIN TABLE MANAGEMENT FUNCTIONS */ +/*============================================================================*/ + /* builtintable_init *********************************************************** Parse the descriptors of builtin functions and create the parsed @@ -105,13 +105,13 @@ CYCLES_STATS_DECLARE(builtin_overhead , 80,1) static bool builtintable_init(void) { descriptor_pool *descpool; - s4 dumpsize; builtintable_entry *bte; methodinfo *m; + int32_t dumpmarker; /* mark start of dump memory area */ - dumpsize = dump_size(); + DMARKER; /* create a new descriptor pool */ @@ -134,7 +134,7 @@ static bool builtintable_init(void) if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) { /* release dump area */ - dump_release(dumpsize); + DRELEASE; return false; } @@ -144,7 +144,7 @@ static bool builtintable_init(void) bte->descriptor = utf_new_char(bte->cdescriptor); if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) { - dump_release(dumpsize); + DRELEASE; return false; } } @@ -155,7 +155,7 @@ static bool builtintable_init(void) bte->descriptor = utf_new_char(bte->cdescriptor); if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) { - dump_release(dumpsize); + DRELEASE; return false; } } @@ -215,7 +215,7 @@ static bool builtintable_init(void) /* release dump area */ - dump_release(dumpsize); + DRELEASE; return true; } @@ -266,6 +266,8 @@ static void builtintable_sort_automatic(void) bool builtin_init(void) { + TRACESUBSYSTEMINITIALIZATION("builtin_init"); + /* initialize the builtin tables */ if (!builtintable_init()) @@ -396,9 +398,9 @@ bool builtintable_replace_function(void *iptr_) #endif /* defined(ENABLE_JIT) */ -/***************************************************************************** - TYPE CHECKS -*****************************************************************************/ +/*============================================================================*/ +/* INTERNAL BUILTIN FUNCTIONS */ +/*============================================================================*/ /* builtin_instanceof ********************************************************** @@ -406,42 +408,47 @@ bool builtintable_replace_function(void *iptr_) of that class). If class is an interface, checks if the interface is implemented. - Return value: 1 ... o is an instance of class or implements the interface - 0 ... otherwise or if o == NULL - + RETURN VALUE: + 1......o is an instance of class or implements the interface + 0......otherwise or if o == NULL + + NOTE: This builtin can be called from NATIVE code only. + *******************************************************************************/ -s4 builtin_instanceof(java_handle_t *o, classinfo *class) +bool builtin_instanceof(java_handle_t *o, classinfo *c) { - classinfo *c; + classinfo *oc; if (o == NULL) return 0; - LLNI_class_get(o, c); + LLNI_class_get(o, oc); - return class_isanysubclass(c, class); + return class_isanysubclass(oc, c); } /* builtin_checkcast *********************************************************** - The same as builtin_instanceof except that 1 is returned when o == - NULL. - + The same as builtin_instanceof but with the exception + that 1 is returned when (o == NULL). + + NOTE: This builtin can be called from NATIVE code only. + *******************************************************************************/ -s4 builtin_checkcast(java_handle_t *o, classinfo *class) +bool builtin_checkcast(java_handle_t *o, classinfo *c) { - classinfo *c; + classinfo *oc; if (o == NULL) return 1; - LLNI_class_get(o, c); + LLNI_class_get(o, oc); - if (class_isanysubclass(c, class)) + if (class_isanysubclass(oc, c)) return 1; return 0; @@ -450,15 +457,15 @@ s4 builtin_checkcast(java_handle_t *o, classinfo *class) /* builtin_descriptorscompatible *********************************************** - Checks if two array type descriptors are assignment compatible + Checks if two array type descriptors are assignment compatible. - Return value: 1 ... target = desc is possible - 0 ... otherwise + RETURN VALUE: + 1......target = desc is possible + 0......otherwise *******************************************************************************/ -static s4 builtin_descriptorscompatible(arraydescriptor *desc, - arraydescriptor *target) +static bool builtin_descriptorscompatible(arraydescriptor *desc, arraydescriptor *target) { if (desc == target) return 1; @@ -472,6 +479,8 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc, /* {both arrays are arrays of references} */ if (desc->dimension == target->dimension) { + if (!desc->elementvftbl) + return 0; /* an array which contains elements of interface types is allowed to be casted to Object (JOWENN)*/ @@ -479,8 +488,8 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc, (target->elementvftbl->baseval == 1)) return 1; - return class_isanysubclass(desc->elementvftbl->class, - target->elementvftbl->class); + return class_isanysubclass(desc->elementvftbl->clazz, + target->elementvftbl->clazz); } if (desc->dimension < target->dimension) @@ -489,7 +498,7 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc, /* {desc has higher dimension than target} */ return class_isanysubclass(pseudo_class_Arraystub, - target->elementvftbl->class); + target->elementvftbl->clazz); } @@ -503,17 +512,19 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc, arrays of arrays (which in turn can again be arrays of arrays), the types at the lowest level have to satisfy the corresponding sub class relation. - + + NOTE: This is a FAST builtin and can be called from JIT code only. + *******************************************************************************/ -s4 builtin_arraycheckcast(java_handle_t *o, classinfo *targetclass) +bool builtin_fast_arraycheckcast(java_object_t *o, classinfo *targetclass) { arraydescriptor *desc; if (o == NULL) return 1; - desc = LLNI_vftbl_direct(o)->arraydesc; + desc = o->vftbl->arraydesc; if (desc == NULL) return 0; @@ -522,19 +533,48 @@ s4 builtin_arraycheckcast(java_handle_t *o, classinfo *targetclass) } -s4 builtin_arrayinstanceof(java_handle_t *o, classinfo *targetclass) +/* builtin_fast_arrayinstanceof ************************************************ + + NOTE: This is a FAST builtin and can be called from JIT code only. + +*******************************************************************************/ + +bool builtin_fast_arrayinstanceof(java_object_t *o, classinfo *targetclass) { if (o == NULL) return 0; - return builtin_arraycheckcast(o, targetclass); + return builtin_fast_arraycheckcast(o, targetclass); +} + + +/* builtin_arrayinstanceof ***************************************************** + + NOTE: This builtin can be called from NATIVE code only. + +*******************************************************************************/ + +bool builtin_arrayinstanceof(java_handle_t *h, classinfo *targetclass) +{ + bool result; + + LLNI_CRITICAL_START; + + result = builtin_fast_arrayinstanceof(LLNI_UNWRAP(h), targetclass); + + LLNI_CRITICAL_END; + + return result; } /* builtin_throw_exception ***************************************************** - Sets the exceptionptr with the thrown exception and prints some - debugging information. Called from asm_vm_call_method. + Sets the exception pointer with the thrown exception and prints some + debugging information. + + NOTE: This is a FAST builtin and can be called from JIT code, + or from asm_vm_call_method. *******************************************************************************/ @@ -549,7 +589,7 @@ void *builtin_throw_exception(java_object_t *xptr) /* actually set the exception */ - exceptions_set_exception(xptr); + exceptions_set_exception(LLNI_QUICKWRAP(xptr)); /* Return a NULL pointer. This is required for vm_call_method to check for an exception. This is for convenience. */ @@ -558,18 +598,47 @@ void *builtin_throw_exception(java_object_t *xptr) } +/* builtin_retrieve_exception ************************************************** + + Gets and clears the exception pointer of the current thread. + + RETURN VALUE: + the exception object, or NULL if no exception was thrown. + + NOTE: This is a FAST builtin and can be called from JIT code, + or from the signal handlers. + +*******************************************************************************/ + +java_object_t *builtin_retrieve_exception(void) +{ + java_handle_t *h; + java_object_t *o; + + /* actually get and clear the exception */ + + h = exceptions_get_and_clear_exception(); + o = LLNI_UNWRAP(h); + + return o; +} + + /* builtin_canstore ************************************************************ Checks, if an object can be stored in an array. - Return value: 1 ... possible - 0 ... otherwise (throws an ArrayStoreException) + RETURN VALUE: + 1......possible + 0......otherwise (throws an ArrayStoreException) + + NOTE: This is a SLOW builtin and can be called from JIT & NATIVE code. *******************************************************************************/ -s4 builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o) +bool builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o) { - int result; + bool result; LLNI_CRITICAL_START; @@ -586,7 +655,19 @@ s4 builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o) } -s4 builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o) +/* builtin_fast_canstore ******************************************************* + + Checks, if an object can be stored in an array. + + RETURN VALUE: + 1......possible + 0......otherwise (no exception thrown!) + + NOTE: This is a FAST builtin and can be called from JIT code only. + +*******************************************************************************/ + +bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o) { arraydescriptor *desc; arraydescriptor *valuedesc; @@ -594,7 +675,7 @@ s4 builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o) vftbl_t *valuevftbl; int32_t baseval; uint32_t diffval; - int result; + bool result; if (o == NULL) return 1; @@ -605,7 +686,7 @@ s4 builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o) * *) oa->...vftbl->arraydesc->componentvftbl != NULL * *) o->vftbl is not an interface vftbl */ - + desc = oa->header.objheader.vftbl->arraydesc; componentvftbl = desc->componentvftbl; valuevftbl = o->vftbl; @@ -656,14 +737,14 @@ s4 builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o) /* This is an optimized version where a is guaranteed to be one-dimensional */ -s4 builtin_canstore_onedim (java_objectarray_t *a, java_object_t *o) +bool builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o) { arraydescriptor *desc; vftbl_t *elementvftbl; vftbl_t *valuevftbl; int32_t baseval; uint32_t diffval; - int result; + bool result; if (o == NULL) return 1; @@ -707,12 +788,12 @@ s4 builtin_canstore_onedim (java_objectarray_t *a, java_object_t *o) /* This is an optimized version where a is guaranteed to be a * one-dimensional array of a class type */ -s4 builtin_canstore_onedim_class(java_objectarray_t *a, java_object_t *o) +bool builtin_fast_canstore_onedim_class(java_objectarray_t *a, java_object_t *o) { vftbl_t *elementvftbl; vftbl_t *valuevftbl; uint32_t diffval; - int result; + bool result; if (o == NULL) return 1; @@ -749,14 +830,16 @@ s4 builtin_canstore_onedim_class(java_objectarray_t *a, java_object_t *o) Creates a new instance of class c on the heap. - Return value: pointer to the object or NULL if no memory is - available + RETURN VALUE: + pointer to the object, or NULL if no memory is available + + NOTE: This builtin can be called from NATIVE code only. *******************************************************************************/ java_handle_t *builtin_new(classinfo *c) { - java_object_t *o; + java_handle_t *o; #if defined(ENABLE_RT_TIMING) struct timespec time_start, time_end; #endif @@ -800,19 +883,121 @@ java_handle_t *builtin_new(classinfo *c) if (!o) return NULL; - o->vftbl = c->vftbl; +#if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES) + /* XXX this is only a dirty hack to make Boehm work with handles */ + + o = LLNI_WRAP((java_object_t *) o); +#endif + + LLNI_vftbl_direct(o) = c->vftbl; #if defined(ENABLE_THREADS) - lock_init_object_lock(o); + lock_init_object_lock(LLNI_DIRECT(o)); +#endif + + CYCLES_STATS_GET(cycles_end); + RT_TIMING_GET_TIME(time_end); + + CYCLES_STATS_COUNT(builtin_new,cycles_end - cycles_start); + RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_OBJECT); + + return o; +} + +#if defined(ENABLE_ESCAPE_REASON) +java_handle_t *builtin_escape_reason_new(classinfo *c) { + print_escape_reasons(); + return builtin_java_new(c); +} +#endif + +#if defined(ENABLE_TLH) +java_handle_t *builtin_tlh_new(classinfo *c) +{ + java_handle_t *o; +#if defined(ENABLE_RT_TIMING) + struct timespec time_start, time_end; +#endif +#if defined(ENABLE_CYCLES_STATS) + u8 cycles_start, cycles_end; +#endif + + RT_TIMING_GET_TIME(time_start); + CYCLES_STATS_GET(cycles_start); + + /* is the class loaded */ + + assert(c->state & CLASS_LOADED); + + /* check if we can instantiate this class */ + + if (c->flags & ACC_ABSTRACT) { + exceptions_throw_instantiationerror(c); + return NULL; + } + + /* is the class linked */ + + if (!(c->state & CLASS_LINKED)) + if (!link_class(c)) + return NULL; + + if (!(c->state & CLASS_INITIALIZED)) { +#if !defined(NDEBUG) + if (initverbose) + log_message_class("Initialize class (from builtin_new): ", c); +#endif + + if (!initialize_class(c)) + return NULL; + } + + /* + o = tlh_alloc(&(THREADOBJECT->tlh), c->instancesize); + */ + o = NULL; + + if (o == NULL) { + o = heap_alloc(c->instancesize, c->flags & ACC_CLASS_HAS_POINTERS, + c->finalizer, true); + } + + if (!o) + return NULL; + +#if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES) + /* XXX this is only a dirty hack to make Boehm work with handles */ + + o = LLNI_WRAP((java_object_t *) o); +#endif + + LLNI_vftbl_direct(o) = c->vftbl; + +#if defined(ENABLE_THREADS) + lock_init_object_lock(LLNI_DIRECT(o)); #endif CYCLES_STATS_GET(cycles_end); RT_TIMING_GET_TIME(time_end); +/* CYCLES_STATS_COUNT(builtin_new,cycles_end - cycles_start); RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_OBJECT); +*/ return o; +#endif +} + +/* builtin_java_new ************************************************************ + + NOTE: This is a SLOW builtin and can be called from JIT code only. + +*******************************************************************************/ + +java_handle_t *builtin_java_new(java_handle_t *clazz) +{ + return builtin_new(LLNI_classinfo_unwrap(clazz)); } @@ -820,8 +1005,11 @@ java_handle_t *builtin_new(classinfo *c) Creates a new instance of class c on the heap. - Return value: pointer to the object or NULL if no fast return - is possible for any reason. + RETURN VALUE: + pointer to the object, or NULL if no fast return + is possible for any reason. + + NOTE: This is a FAST builtin and can be called from JIT code only. *******************************************************************************/ @@ -882,17 +1070,20 @@ java_object_t *builtin_fast_new(classinfo *c) Creates an array with the given vftbl on the heap. This function takes as class argument an array class. - Return value: pointer to the array or NULL if no memory is available + RETURN VALUE: + pointer to the array or NULL if no memory is available + + NOTE: This builtin can be called from NATIVE code only. *******************************************************************************/ -java_handle_t *builtin_newarray(s4 size, classinfo *arrayclass) +java_handle_t *builtin_newarray(int32_t size, classinfo *arrayclass) { arraydescriptor *desc; s4 dataoffset; s4 componentsize; s4 actualsize; - java_array_t *a; + java_handle_t *a; #if defined(ENABLE_RT_TIMING) struct timespec time_start, time_end; #endif @@ -922,10 +1113,16 @@ java_handle_t *builtin_newarray(s4 size, classinfo *arrayclass) if (a == NULL) return NULL; - a->objheader.vftbl = arrayclass->vftbl; +#if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES) + /* XXX this is only a dirty hack to make Boehm work with handles */ + + a = LLNI_WRAP((java_object_t *) a); +#endif + + LLNI_vftbl_direct(a) = arrayclass->vftbl; #if defined(ENABLE_THREADS) - lock_init_object_lock(&a->objheader); + lock_init_object_lock(LLNI_DIRECT(a)); #endif LLNI_array_size(a) = size; @@ -937,16 +1134,31 @@ java_handle_t *builtin_newarray(s4 size, classinfo *arrayclass) } +/* builtin_java_newarray ******************************************************* + + NOTE: This is a SLOW builtin and can be called from JIT code only. + +*******************************************************************************/ + +java_handle_t *builtin_java_newarray(int32_t size, java_handle_t *arrayclazz) +{ + return builtin_newarray(size, LLNI_classinfo_unwrap(arrayclazz)); +} + + /* builtin_anewarray *********************************************************** Creates an array of references to the given class type on the heap. - Return value: pointer to the array or NULL if no memory is - available + RETURN VALUE: + pointer to the array or NULL if no memory is + available + + NOTE: This builtin can be called from NATIVE code only. *******************************************************************************/ -java_handle_objectarray_t *builtin_anewarray(s4 size, classinfo *componentclass) +java_handle_objectarray_t *builtin_anewarray(int32_t size, classinfo *componentclass) { classinfo *arrayclass; @@ -969,135 +1181,32 @@ java_handle_objectarray_t *builtin_anewarray(s4 size, classinfo *componentclass) } -/* builtin_newarray_boolean **************************************************** +/* builtin_newarray_type **************************************************** - Creates an array of bytes on the heap. The array is designated as - an array of booleans (important for casts) + Creates an array of [type]s on the heap. - Return value: pointer to the array or NULL if no memory is - available + RETURN VALUE: + pointer to the array or NULL if no memory is available -*******************************************************************************/ - -java_handle_booleanarray_t *builtin_newarray_boolean(s4 size) -{ - return (java_handle_booleanarray_t *) - builtin_newarray(size, - primitivetype_table[ARRAYTYPE_BOOLEAN].arrayclass); -} - - -/* builtin_newarray_byte ******************************************************* - - Creates an array of 8 bit Integers on the heap. - - Return value: pointer to the array or NULL if no memory is - available - -*******************************************************************************/ - -java_handle_bytearray_t *builtin_newarray_byte(s4 size) -{ - return (java_handle_bytearray_t *) - builtin_newarray(size, primitivetype_table[ARRAYTYPE_BYTE].arrayclass); -} - - -/* builtin_newarray_char ******************************************************* - - Creates an array of characters on the heap. - - Return value: pointer to the array or NULL if no memory is - available + NOTE: This is a SLOW builtin and can be called from JIT & NATIVE code. *******************************************************************************/ -java_handle_chararray_t *builtin_newarray_char(s4 size) -{ - return (java_handle_chararray_t *) - builtin_newarray(size, primitivetype_table[ARRAYTYPE_CHAR].arrayclass); +#define BUILTIN_NEWARRAY_TYPE(type, arraytype) \ +java_handle_##type##array_t *builtin_newarray_##type(int32_t size) \ +{ \ + return (java_handle_##type##array_t *) \ + builtin_newarray(size, primitivetype_table[arraytype].arrayclass); \ } - -/* builtin_newarray_short ****************************************************** - - Creates an array of 16 bit Integers on the heap. - - Return value: pointer to the array or NULL if no memory is - available - -*******************************************************************************/ - -java_handle_shortarray_t *builtin_newarray_short(s4 size) -{ - return (java_handle_shortarray_t *) - builtin_newarray(size, primitivetype_table[ARRAYTYPE_SHORT].arrayclass); -} - - -/* builtin_newarray_int ******************************************************** - - Creates an array of 32 bit Integers on the heap. - - Return value: pointer to the array or NULL if no memory is - available - -*******************************************************************************/ - -java_handle_intarray_t *builtin_newarray_int(s4 size) -{ - return (java_handle_intarray_t *) - builtin_newarray(size, primitivetype_table[ARRAYTYPE_INT].arrayclass); -} - - -/* builtin_newarray_long ******************************************************* - - Creates an array of 64 bit Integers on the heap. - - Return value: pointer to the array or NULL if no memory is - available - -*******************************************************************************/ - -java_handle_longarray_t *builtin_newarray_long(s4 size) -{ - return (java_handle_longarray_t *) - builtin_newarray(size, primitivetype_table[ARRAYTYPE_LONG].arrayclass); -} - - -/* builtin_newarray_float ****************************************************** - - Creates an array of 32 bit IEEE floats on the heap. - - Return value: pointer to the array or NULL if no memory is - available - -*******************************************************************************/ - -java_handle_floatarray_t *builtin_newarray_float(s4 size) -{ - return (java_handle_floatarray_t *) - builtin_newarray(size, primitivetype_table[ARRAYTYPE_FLOAT].arrayclass); -} - - -/* builtin_newarray_double ***************************************************** - - Creates an array of 64 bit IEEE floats on the heap. - - Return value: pointer to the array or NULL if no memory is - available - -*******************************************************************************/ - -java_handle_doublearray_t *builtin_newarray_double(s4 size) -{ - return (java_handle_doublearray_t *) - builtin_newarray(size, - primitivetype_table[ARRAYTYPE_DOUBLE].arrayclass); -} +BUILTIN_NEWARRAY_TYPE(boolean, ARRAYTYPE_BOOLEAN) +BUILTIN_NEWARRAY_TYPE(byte, ARRAYTYPE_BYTE) +BUILTIN_NEWARRAY_TYPE(char, ARRAYTYPE_CHAR) +BUILTIN_NEWARRAY_TYPE(short, ARRAYTYPE_SHORT) +BUILTIN_NEWARRAY_TYPE(int, ARRAYTYPE_INT) +BUILTIN_NEWARRAY_TYPE(long, ARRAYTYPE_LONG) +BUILTIN_NEWARRAY_TYPE(float, ARRAYTYPE_FLOAT) +BUILTIN_NEWARRAY_TYPE(double, ARRAYTYPE_DOUBLE) /* builtin_multianewarray_intern *********************************************** @@ -1105,13 +1214,13 @@ java_handle_doublearray_t *builtin_newarray_double(s4 size) Creates a multi-dimensional array on the heap. The dimensions are passed in an array of longs. - Arguments: - n.............number of dimensions to create - arrayclass....the array class - dims..........array containing the size of each dimension to create + ARGUMENTS: + n.............number of dimensions to create + arrayclass....the array class + dims..........array containing the size of each dimension to create - Return value: pointer to the array or NULL if no memory is - available + RETURN VALUE: + pointer to the array or NULL if no memory is available ******************************************************************************/ @@ -1139,7 +1248,7 @@ static java_handle_t *builtin_multianewarray_intern(int n, /* get the class of the components to create */ - componentclass = arrayclass->vftbl->arraydesc->componentvftbl->class; + componentclass = arrayclass->vftbl->arraydesc->componentvftbl->clazz; /* The verifier guarantees that the dimension count is in the range. */ @@ -1158,7 +1267,7 @@ static java_handle_t *builtin_multianewarray_intern(int n, if (!ea) return NULL; - LLNI_objectarray_element_set((java_handle_objectarray_t *) a, i, ea); + array_objectarray_element_set((java_handle_objectarray_t *) a, i, ea); } return a; @@ -1170,13 +1279,17 @@ static java_handle_t *builtin_multianewarray_intern(int n, Wrapper for builtin_multianewarray_intern which checks all dimensions before we start allocating. + NOTE: This is a SLOW builtin and can be called from JIT code only. + ******************************************************************************/ -java_handle_objectarray_t *builtin_multianewarray(int n, classinfo *arrayclass, +java_handle_objectarray_t *builtin_multianewarray(int n, + java_handle_t *arrayclazz, long *dims) { - s4 i; - s4 size; + classinfo *c; + s4 i; + s4 size; /* check all dimensions before doing anything */ @@ -1194,149 +1307,24 @@ java_handle_objectarray_t *builtin_multianewarray(int n, classinfo *arrayclass, } } + c = LLNI_classinfo_unwrap(arrayclazz); + /* now call the real function */ return (java_handle_objectarray_t *) - builtin_multianewarray_intern(n, arrayclass, dims); + builtin_multianewarray_intern(n, c, dims); } -/***************************************************************************** - METHOD LOGGING - - Various functions for printing a message at method entry or exit (for - debugging) - -*****************************************************************************/ - -/* builtin_print_argument ****************************************************** - - Prints arguments and return values for the call trace. - -*******************************************************************************/ - -#if !defined(NDEBUG) -static char *builtin_print_argument(char *logtext, s4 *logtextlen, - typedesc *paramtype, s8 value) -{ - imm_union imu; - java_object_t *o; - classinfo *c; - utf *u; - u4 len; - - switch (paramtype->type) { - case TYPE_INT: - imu.i = (s4) value; - sprintf(logtext + strlen(logtext), "%d (0x%08x)", imu.i, imu.i); - break; - - case TYPE_LNG: - imu.l = value; -#if SIZEOF_VOID_P == 4 - sprintf(logtext + strlen(logtext), "%lld (0x%016llx)", imu.l, imu.l); -#else - sprintf(logtext + strlen(logtext), "%ld (0x%016lx)", imu.l, imu.l); -#endif - break; - - case TYPE_FLT: -#if defined(__S390__) - imu.l = value; - /* The below won't work on S390 */ -#else - imu.i = (s4) value; -#endif - sprintf(logtext + strlen(logtext), "%g (0x%08x)", imu.f, imu.i); - break; - - case TYPE_DBL: - imu.l = value; -#if SIZEOF_VOID_P == 4 - sprintf(logtext + strlen(logtext), "%g (0x%016llx)", imu.d, imu.l); -#else - sprintf(logtext + strlen(logtext), "%g (0x%016lx)", imu.d, imu.l); -#endif - break; - - case TYPE_ADR: -#if SIZEOF_VOID_P == 4 - sprintf(logtext + strlen(logtext), "0x%08x", (ptrint) value); -#else - sprintf(logtext + strlen(logtext), "0x%016lx", (ptrint) value); -#endif - - /* cast to java.lang.Object */ - - o = (java_object_t *) (ptrint) value; - - /* check return argument for java.lang.Class or java.lang.String */ - - if (o != NULL) { - if (o->vftbl->class == class_java_lang_String) { - /* get java.lang.String object and the length of the - string */ - - u = javastring_toutf(o, false); - - len = strlen(" (String = \"") + utf_bytes(u) + strlen("\")"); - - /* realloc memory for string length */ - - logtext = DMREALLOC(logtext, char, *logtextlen, *logtextlen + len); - *logtextlen += len; - - /* convert to utf8 string and strcat it to the logtext */ - - strcat(logtext, " (String = \""); - utf_cat(logtext, u); - strcat(logtext, "\")"); - } - else { - if (o->vftbl->class == class_java_lang_Class) { - /* if the object returned is a java.lang.Class - cast it to classinfo structure and get the name - of the class */ - - c = (classinfo *) o; - - u = c->name; - } - else { - /* if the object returned is not a java.lang.String or - a java.lang.Class just print the name of the class */ - - u = o->vftbl->class->name; - } - - len = strlen(" (Class = \"") + utf_bytes(u) + strlen("\")"); - - /* realloc memory for string length */ - - logtext = DMREALLOC(logtext, char, *logtextlen, *logtextlen + len); - *logtextlen += len; - - /* strcat to the logtext */ - - strcat(logtext, " (Class = \""); - utf_cat_classname(logtext, u); - strcat(logtext, "\")"); - } - } - } - - return logtext; -} -#endif /* !defined(NDEBUG) */ - /* builtin_verbosecall_enter *************************************************** Print method call with arguments for -verbose:call. + XXX: Remove mew once all archs use the new tracer! + *******************************************************************************/ #if !defined(NDEBUG) - #ifdef TRACE_ARGS_NUM void builtin_verbosecall_enter(s8 a0, s8 a1, # if TRACE_ARGS_NUM >= 4 @@ -1350,176 +1338,7 @@ void builtin_verbosecall_enter(s8 a0, s8 a1, # endif methodinfo *m) { - methoddesc *md; - char *logtext; - s4 logtextlen; - s4 dumpsize; - s4 i; - s4 pos; - int methodindent; - int callcount; - -#if defined(ENABLE_DEBUG_FILTER) - if (! show_filters_test_verbosecall_enter(m)) return; -#endif - -#if defined(ENABLE_VMLOG) - vmlog_cacao_enter_method(m); - return; -#endif - - md = m->parseddesc; - - methodindent = TRACEJAVACALLINDENT; - - /* calculate message length */ - - logtextlen = - strlen("4294967295 ") + - strlen("-2147483647-") + /* INT_MAX should be sufficient */ - methodindent + - strlen("called: ") + - utf_bytes(m->class->name) + - strlen(".") + - utf_bytes(m->name) + - utf_bytes(m->descriptor); - - /* Actually it's not possible to have all flags printed, but: - safety first! */ - - logtextlen += - strlen(" PUBLIC") + - strlen(" PRIVATE") + - strlen(" PROTECTED") + - strlen(" STATIC") + - strlen(" FINAL") + - strlen(" SYNCHRONIZED") + - strlen(" VOLATILE") + - strlen(" TRANSIENT") + - strlen(" NATIVE") + - strlen(" INTERFACE") + - strlen(" ABSTRACT"); - - /* add maximal argument length */ - - logtextlen += - strlen("(") + - strlen("-9223372036854775808 (0x123456789abcdef0), ") * TRACE_ARGS_NUM + - strlen("...(255)") + - strlen(")"); - - /* allocate memory */ - - dumpsize = dump_size(); - - logtext = DMNEW(char, logtextlen); - - callcount = ++TRACEJAVACALLCOUNT; - - sprintf(logtext, "%10d ", callcount); - sprintf(logtext + strlen(logtext), "-%d-", methodindent); - - pos = strlen(logtext); - - for (i = 0; i < methodindent; i++) - logtext[pos++] = '\t'; - - strcpy(logtext + pos, "called: "); - - utf_cat_classname(logtext, m->class->name); - strcat(logtext, "."); - utf_cat(logtext, m->name); - utf_cat(logtext, m->descriptor); - - if (m->flags & ACC_PUBLIC) strcat(logtext, " PUBLIC"); - if (m->flags & ACC_PRIVATE) strcat(logtext, " PRIVATE"); - if (m->flags & ACC_PROTECTED) strcat(logtext, " PROTECTED"); - if (m->flags & ACC_STATIC) strcat(logtext, " STATIC"); - if (m->flags & ACC_FINAL) strcat(logtext, " FINAL"); - if (m->flags & ACC_SYNCHRONIZED) strcat(logtext, " SYNCHRONIZED"); - if (m->flags & ACC_VOLATILE) strcat(logtext, " VOLATILE"); - if (m->flags & ACC_TRANSIENT) strcat(logtext, " TRANSIENT"); - if (m->flags & ACC_NATIVE) strcat(logtext, " NATIVE"); - if (m->flags & ACC_INTERFACE) strcat(logtext, " INTERFACE"); - if (m->flags & ACC_ABSTRACT) strcat(logtext, " ABSTRACT"); - - strcat(logtext, "("); - - if (md->paramcount >= 1) { - logtext = builtin_print_argument(logtext, &logtextlen, - &md->paramtypes[0], a0); - } - - if (md->paramcount >= 2) { - strcat(logtext, ", "); - - logtext = builtin_print_argument(logtext, &logtextlen, - &md->paramtypes[1], a1); - } - -#if TRACE_ARGS_NUM >= 4 - if (md->paramcount >= 3) { - strcat(logtext, ", "); - - logtext = builtin_print_argument(logtext, &logtextlen, - &md->paramtypes[2], a2); - } - - if (md->paramcount >= 4) { - strcat(logtext, ", "); - - logtext = builtin_print_argument(logtext, &logtextlen, - &md->paramtypes[3], a3); - } -#endif - -#if TRACE_ARGS_NUM >= 6 - if (md->paramcount >= 5) { - strcat(logtext, ", "); - - logtext = builtin_print_argument(logtext, &logtextlen, - &md->paramtypes[4], a4); - } - - if (md->paramcount >= 6) { - strcat(logtext, ", "); - - logtext = builtin_print_argument(logtext, &logtextlen, - &md->paramtypes[5], a5); - } -#endif - -#if TRACE_ARGS_NUM == 8 - if (md->paramcount >= 7) { - strcat(logtext, ", "); - - logtext = builtin_print_argument(logtext, &logtextlen, - &md->paramtypes[6], a6); - } - - if (md->paramcount >= 8) { - strcat(logtext, ", "); - - logtext = builtin_print_argument(logtext, &logtextlen, - &md->paramtypes[7], a7); - } -#endif - - if (md->paramcount > 8) { - sprintf(logtext + strlen(logtext), ", ...(%d)", - md->paramcount - TRACE_ARGS_NUM); - } - - strcat(logtext, ")"); - - log_text(logtext); - - /* release memory */ - - dump_release(dumpsize); - - TRACEJAVACALLINDENT++; - + log_text("builtin_verbosecall_enter: Do not call me anymore!"); } #endif #endif /* !defined(NDEBUG) */ @@ -1529,130 +1348,21 @@ void builtin_verbosecall_enter(s8 a0, s8 a1, Print method exit for -verbose:call. + XXX: Remove mew once all archs use the new tracer! + *******************************************************************************/ #if !defined(NDEBUG) void builtin_verbosecall_exit(s8 l, double d, float f, methodinfo *m) { - methoddesc *md; - char *logtext; - s4 logtextlen; - s4 dumpsize; - s4 i; - s4 pos; - imm_union val; - int methodindent; - -#if defined(ENABLE_DEBUG_FILTER) - if (! show_filters_test_verbosecall_exit(m)) return; -#endif - -#if defined(ENABLE_VMLOG) - vmlog_cacao_leave_method(m); - return; -#endif - - md = m->parseddesc; - - /* outdent the log message */ - - if (TRACEJAVACALLINDENT) - TRACEJAVACALLINDENT--; - else - log_text("WARNING: unmatched methodindent--"); - - methodindent = TRACEJAVACALLINDENT; - - /* calculate message length */ - - logtextlen = - strlen("4294967295 ") + - strlen("-2147483647-") + /* INT_MAX should be sufficient */ - methodindent + - strlen("finished: ") + - utf_bytes(m->class->name) + - strlen(".") + - utf_bytes(m->name) + - utf_bytes(m->descriptor) + - strlen(" SYNCHRONIZED") + strlen("(") + strlen(")"); - - /* add maximal argument length */ - - logtextlen += strlen("->0.4872328470301428 (0x0123456789abcdef)"); - - /* allocate memory */ - - dumpsize = dump_size(); - - logtext = DMNEW(char, logtextlen); - - /* generate the message */ - - sprintf(logtext, " "); - sprintf(logtext + strlen(logtext), "-%d-", methodindent); - - pos = strlen(logtext); - - for (i = 0; i < methodindent; i++) - logtext[pos++] = '\t'; - - strcpy(logtext + pos, "finished: "); - utf_cat_classname(logtext, m->class->name); - strcat(logtext, "."); - utf_cat(logtext, m->name); - utf_cat(logtext, m->descriptor); - - if (!IS_VOID_TYPE(md->returntype.type)) { - strcat(logtext, "->"); - - switch (md->returntype.type) { - case TYPE_INT: - case TYPE_LNG: - case TYPE_ADR: - val.l = l; - break; - - case TYPE_FLT: - val.f = f; - break; - - case TYPE_DBL: - val.d = d; - break; - } - - logtext = - builtin_print_argument(logtext, &logtextlen, &md->returntype, val.l); - } - - log_text(logtext); - - /* release memory */ - - dump_release(dumpsize); - + log_text("builtin_verbosecall_exit: Do not call me anymore!"); } #endif /* !defined(NDEBUG) */ -#if defined(ENABLE_CYCLES_STATS) -void builtin_print_cycles_stats(FILE *file) -{ - fprintf(file,"builtin cylce count statistics:\n"); - - CYCLES_STATS_PRINT_OVERHEAD(builtin_overhead,file); - CYCLES_STATS_PRINT(builtin_new ,file); - - fprintf(file,"\n"); -} -#endif /* defined(ENABLE_CYCLES_STATS) */ - - -/***************************************************************************** - MISCELLANEOUS HELPER FUNCTIONS -*****************************************************************************/ - - +/*============================================================================*/ +/* MISCELLANEOUS MATHEMATICAL HELPER FUNCTIONS */ +/*============================================================================*/ /*********** Functions for integer divisions ***************************** @@ -2465,25 +2175,28 @@ float builtin_d2f(double a) #endif /* !(SUPPORT_FLOAT && SUPPORT_DOUBLE) */ +/*============================================================================*/ +/* AUTOMATICALLY REPLACED FUNCTIONS */ +/*============================================================================*/ + /* builtin_arraycopy *********************************************************** Builtin for java.lang.System.arraycopy. - ATTENTION: This builtin function returns a boolean value to signal - the ICMD_BUILTIN if there was an exception. + NOTE: This is a SLOW builtin and can be called from JIT & NATIVE code. *******************************************************************************/ -bool builtin_arraycopy(java_handle_t *src, s4 srcStart, +void builtin_arraycopy(java_handle_t *src, s4 srcStart, java_handle_t *dest, s4 destStart, s4 len) { arraydescriptor *sdesc; arraydescriptor *ddesc; s4 i; - if ((src == NULL) || (dest == NULL)) { + if ((src == NULL) || (dest == NULL)) { exceptions_throw_nullpointerexception(); - return false; + return; } sdesc = LLNI_vftbl_direct(src)->arraydesc; @@ -2491,16 +2204,25 @@ bool builtin_arraycopy(java_handle_t *src, s4 srcStart, if (!sdesc || !ddesc || (sdesc->arraytype != ddesc->arraytype)) { exceptions_throw_arraystoreexception(); - return false; + return; } - /* we try to throw exception with the same message as SUN does */ + // Check if offsets and length are positive. + if ((srcStart < 0) || (destStart < 0) || (len < 0)) { + exceptions_throw_arrayindexoutofboundsexception(); + return; + } - if ((len < 0) || (srcStart < 0) || (destStart < 0) || - (srcStart + len < 0) || (srcStart + len > LLNI_array_size(src)) || - (destStart + len < 0) || (destStart + len > LLNI_array_size(dest))) { + // Check if ranges are valid. + if ((((uint32_t) srcStart + (uint32_t) len) > (uint32_t) LLNI_array_size(src)) || + (((uint32_t) destStart + (uint32_t) len) > (uint32_t) LLNI_array_size(dest))) { exceptions_throw_arrayindexoutofboundsexception(); - return false; + return; + } + + // Special case. + if (len == 0) { + return; } if (sdesc->componentvftbl == ddesc->componentvftbl) { @@ -2509,9 +2231,13 @@ bool builtin_arraycopy(java_handle_t *src, s4 srcStart, s4 dataoffset = sdesc->dataoffset; s4 componentsize = sdesc->componentsize; - memmove(((u1 *) dest) + dataoffset + componentsize * destStart, - ((u1 *) src) + dataoffset + componentsize * srcStart, - (size_t) len * componentsize); + LLNI_CRITICAL_START; + + MMOVE(((u1 *) LLNI_DIRECT(dest)) + dataoffset + componentsize * destStart, + ((u1 *) LLNI_DIRECT(src)) + dataoffset + componentsize * srcStart, + u1, (size_t) len * componentsize); + + LLNI_CRITICAL_END; } else { /* We copy references of different type */ @@ -2523,12 +2249,12 @@ bool builtin_arraycopy(java_handle_t *src, s4 srcStart, for (i = 0; i < len; i++) { java_handle_t *o; - LLNI_objectarray_element_get(oas, srcStart + i, o); + o = array_objectarray_element_get(oas, srcStart + i); if (!builtin_canstore(oad, o)) - return false; + return; - LLNI_objectarray_element_set(oad, destStart + i, o); + array_objectarray_element_set(oad, destStart + i, o); } } else { @@ -2541,17 +2267,15 @@ bool builtin_arraycopy(java_handle_t *src, s4 srcStart, for (i = len - 1; i >= 0; i--) { java_handle_t *o; - LLNI_objectarray_element_get(oas, srcStart + i, o); + o = array_objectarray_element_get(oas, srcStart + i); if (!builtin_canstore(oad, o)) - return false; + return; - LLNI_objectarray_element_set(oad, destStart + i, o); + array_objectarray_element_set(oad, destStart + i, o); } } } - - return true; } @@ -2595,12 +2319,13 @@ s8 builtin_currenttimemillis(void) Function for cloning objects or arrays. + NOTE: This is a SLOW builtin and can be called from JIT & NATIVE code. + *******************************************************************************/ java_handle_t *builtin_clone(void *env, java_handle_t *o) { arraydescriptor *ad; - java_handle_t *ah; u4 size; classinfo *c; java_handle_t *co; /* cloned object header */ @@ -2612,25 +2337,33 @@ java_handle_t *builtin_clone(void *env, java_handle_t *o) /* we are cloning an array */ if (ad != NULL) { - ah = (java_handle_t *) o; - - size = ad->dataoffset + ad->componentsize * LLNI_array_size(ah); + size = ad->dataoffset + ad->componentsize * LLNI_array_size(o); co = heap_alloc(size, (ad->arraytype == ARRAYTYPE_OBJECT), NULL, true); if (co == NULL) return NULL; - MCOPY(co, o, u1, size); +#if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES) + /* XXX this is only a dirty hack to make Boehm work with handles */ + + co = LLNI_WRAP((java_object_t *) co); +#endif + + LLNI_CRITICAL_START; + + MCOPY(LLNI_DIRECT(co), LLNI_DIRECT(o), u1, size); #if defined(ENABLE_GC_CACAO) - heap_init_objectheader(co, size); + heap_init_objectheader(LLNI_DIRECT(co), size); #endif #if defined(ENABLE_THREADS) - lock_init_object_lock(co); + lock_init_object_lock(LLNI_DIRECT(co)); #endif + LLNI_CRITICAL_END; + return co; } @@ -2652,19 +2385,37 @@ java_handle_t *builtin_clone(void *env, java_handle_t *o) if (co == NULL) return NULL; - MCOPY(co, o, u1, c->instancesize); + LLNI_CRITICAL_START; + + MCOPY(LLNI_DIRECT(co), LLNI_DIRECT(o), u1, c->instancesize); #if defined(ENABLE_GC_CACAO) - heap_init_objectheader(co, c->instancesize); + heap_init_objectheader(LLNI_DIRECT(co), c->instancesize); #endif #if defined(ENABLE_THREADS) - lock_init_object_lock(co); + lock_init_object_lock(LLNI_DIRECT(co)); #endif + LLNI_CRITICAL_END; + return co; } + +#if defined(ENABLE_CYCLES_STATS) +void builtin_print_cycles_stats(FILE *file) +{ + fprintf(file,"builtin cylce count statistics:\n"); + + CYCLES_STATS_PRINT_OVERHEAD(builtin_overhead,file); + CYCLES_STATS_PRINT(builtin_new ,file); + + fprintf(file,"\n"); +} +#endif /* defined(ENABLE_CYCLES_STATS) */ + + #if defined(ENABLE_VMLOG) #define NDEBUG #include