X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fbuiltin.cpp;h=615f4b8dc2d51175a66a0b748c3d64c2d14de337;hb=278063eaf49b3b3fc68b40cc7fc4172a065f4e99;hp=f4d23e8eb90c3fd8bceab46c14a26f230851ec21;hpb=f24e856e3c43a10dcc8581fd5ddbdda200d63aba;p=cacao.git diff --git a/src/vm/jit/builtin.cpp b/src/vm/jit/builtin.cpp index f4d23e8eb..615f4b8dc 100644 --- a/src/vm/jit/builtin.cpp +++ b/src/vm/jit/builtin.cpp @@ -1,6 +1,6 @@ /* src/vm/jit/builtin.cpp - functions for unsupported operations - Copyright (C) 1996-2005, 2006, 2007, 2008 + Copyright (C) 1996-2005, 2006, 2007, 2008, 2010 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -48,7 +48,7 @@ #endif #include "mm/gc.hpp" -#include "mm/memory.h" +#include "mm/memory.hpp" #include "native/llni.h" @@ -56,18 +56,18 @@ #include "threads/mutex.hpp" #include "threads/thread.hpp" -#include "toolbox/logging.h" +#include "toolbox/logging.hpp" #include "toolbox/util.h" #include "vm/array.hpp" #include "vm/jit/builtin.hpp" -#include "vm/class.h" +#include "vm/class.hpp" #include "vm/cycles-stats.h" #include "vm/exceptions.hpp" #include "vm/global.h" #include "vm/globals.hpp" -#include "vm/initialize.h" -#include "vm/linker.h" +#include "vm/initialize.hpp" +#include "vm/linker.hpp" #include "vm/loader.hpp" #include "vm/options.h" #include "vm/primitive.hpp" @@ -75,6 +75,7 @@ #include "vm/string.hpp" #include "vm/jit/asmpart.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/stubs.hpp" #include "vm/jit/trace.hpp" @@ -267,81 +268,6 @@ bool builtin_init(void) } -/* builtintable_get_by_key ***************************************************** - - Returns a key for the given builtintable_entry object which is suitable - for retrieving the instance again by calling builtintable_get_by_key. - - The key can be regarded fixed between multiple runs of the JVM. - -*******************************************************************************/ - -s4 builtintable_get_key(builtintable_entry *bte) -{ - s4 entries; -/* - int i; - entries = sizeof(builtintable_internal) / sizeof(builtintable_entry) - 1; - for (i = 0; i < entries; i++) - if (&builtintable_internal[i] == bte) - return i + 1; - - entries = sizeof(builtintable_automatic) / sizeof(builtintable_entry) - 1; - for (i = 0; i < entries; i++) - if (&builtintable_automatic[i] == bte) - return -i; - - entries = sizeof(builtintable_function) / sizeof(builtintable_entry) - 1; - for (i = 0; i < entries; i++) - if (&builtintable_function[i] == bte) - return -1000 - i; -*/ - - entries = sizeof(builtintable_internal) / sizeof(builtintable_entry) - 1; - if (&builtintable_internal[0] <= bte - && &builtintable_internal[entries - 1] >= bte) - { - return (s4) (bte - &builtintable_internal[0]) + 1; - } - - entries = sizeof(builtintable_automatic) / sizeof(builtintable_entry) - 1; - if (&builtintable_automatic[0] <= bte - && &builtintable_automatic[entries - 1] >= bte) - { - return -(s4) (bte - &builtintable_automatic[0]); - } - - entries = sizeof(builtintable_function) / sizeof(builtintable_entry) - 1; - if (&builtintable_function[0] <= bte - && &builtintable_function[entries - 1] >= bte) - { - return -1000 - (s4) (bte - &builtintable_function[0]); - } - - /* builtintable_entry is not in our tables. */ - assert (0); - - return 0; -} - -/* builtintable_get_by_key ***************************************************** - - Retrieves an entry in the internal and automatic builtin functions tables - using a key that was retrived previously with builtintable_get_key() - -*******************************************************************************/ - -builtintable_entry *builtintable_get_by_key(s4 key) -{ - /* If key is positive it is the index into builtintable_internal. If it is - * negative it is the index into builtintable_automatic. If it is <= -1000 - * it is the index into builtintable_function. - */ - return (key > 0) - ? &builtintable_internal[key - 1] - : (key > -1000 ? &builtintable_automatic[-key] : &builtintable_function[-(1000 + key)]); -} - /* builtintable_get_internal *************************************************** Finds an entry in the builtintable for internal functions and @@ -516,53 +442,6 @@ bool builtin_checkcast(java_handle_t *o, classinfo *c) } -/* builtin_descriptorscompatible *********************************************** - - Checks if two array type descriptors are assignment compatible. - - RETURN VALUE: - 1......target = desc is possible - 0......otherwise - -*******************************************************************************/ - -static bool builtin_descriptorscompatible(arraydescriptor *desc, arraydescriptor *target) -{ - if (desc == target) - return 1; - - if (desc->arraytype != target->arraytype) - return 0; - - if (desc->arraytype != ARRAYTYPE_OBJECT) - return 1; - - /* {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)*/ - - if ((desc->elementvftbl->baseval < 0) && - (target->elementvftbl->baseval == 1)) - return 1; - - return class_isanysubclass(desc->elementvftbl->clazz, - target->elementvftbl->clazz); - } - - if (desc->dimension < target->dimension) - return 0; - - /* {desc has higher dimension than target} */ - - return class_isanysubclass(pseudo_class_Arraystub, - target->elementvftbl->clazz); -} - - /* builtin_arraycheckcast ****************************************************** Checks if an object is really a subtype of the requested array @@ -590,7 +469,7 @@ bool builtin_fast_arraycheckcast(java_object_t *o, classinfo *targetclass) if (desc == NULL) return 0; - return builtin_descriptorscompatible(desc, targetclass->vftbl->arraydesc); + return class_is_arraycompatible(desc, targetclass->vftbl->arraydesc); } @@ -703,7 +582,7 @@ bool builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o) LLNI_CRITICAL_START; - result = builtin_fast_canstore(LLNI_DIRECT(oa), LLNI_UNWRAP(o)); + result = builtin_fast_canstore((java_objectarray_t*) LLNI_DIRECT(oa), LLNI_UNWRAP(o)); LLNI_CRITICAL_END; @@ -715,6 +594,28 @@ bool builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o) return result; } +#if USES_NEW_SUBTYPE +/* fast_subtype_check ********************************************************** + + Checks if s is a subtype of t, using both the restricted subtype relation + and the overflow array (see Cliff Click and John Rose: Fast subtype checking + in the Hotspot JVM.) + + RETURN VALUE: + 1......s is a subtype of t. + 0......otherwise + +*******************************************************************************/ + +bool fast_subtype_check(struct _vftbl *s, struct _vftbl *t) +{ + if (s->subtype_display[t->subtype_depth] == t) + return true; + if (t->subtype_offset != OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE])) + return false; + return s->subtype_depth >= t->subtype_depth && s->subtype_overflow[t->subtype_depth - DISPLAY_SIZE] == t; +} +#endif /* builtin_fast_canstore ******************************************************* @@ -735,7 +636,6 @@ bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o) vftbl_t *componentvftbl; vftbl_t *valuevftbl; int32_t baseval; - uint32_t diffval; bool result; if (o == NULL) @@ -760,7 +660,7 @@ bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o) if (valuevftbl == componentvftbl) return 1; - linker_classrenumber_mutex->lock(); + LOCK_CLASSRENUMBER_LOCK; baseval = componentvftbl->baseval; @@ -771,11 +671,15 @@ bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o) (valuevftbl->interfacetable[baseval] != NULL)); } else { - diffval = valuevftbl->baseval - componentvftbl->baseval; - result = diffval <= (uint32_t) componentvftbl->diffval; +#if USES_NEW_SUBTYPE + result = fast_subtype_check(valuevftbl, componentvftbl); +#else + uint32_t diffval = valuevftbl->baseval - componentvftbl->baseval; + result = diffval <= (uint32_t) componentvftbl->diffval; +#endif } - linker_classrenumber_mutex->unlock(); + UNLOCK_CLASSRENUMBER_LOCK; } else if (valuedesc == NULL) { /* {oa has dimension > 1} */ @@ -788,7 +692,7 @@ bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o) else { /* {o is an array} */ - result = builtin_descriptorscompatible(valuedesc, componentvftbl->arraydesc); + result = class_is_arraycompatible(valuedesc, componentvftbl->arraydesc); } /* return result */ @@ -804,7 +708,6 @@ bool builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o) vftbl_t *elementvftbl; vftbl_t *valuevftbl; int32_t baseval; - uint32_t diffval; bool result; if (o == NULL) @@ -827,7 +730,7 @@ bool builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o) if (valuevftbl == elementvftbl) return 1; - linker_classrenumber_mutex->lock(); + LOCK_CLASSRENUMBER_LOCK; baseval = elementvftbl->baseval; @@ -837,11 +740,15 @@ bool builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o) (valuevftbl->interfacetable[baseval] != NULL)); } else { - diffval = valuevftbl->baseval - elementvftbl->baseval; - result = diffval <= (uint32_t) elementvftbl->diffval; +#if USES_NEW_SUBTYPE + result = fast_subtype_check(valuevftbl, elementvftbl); +#else + uint32_t diffval = valuevftbl->baseval - elementvftbl->baseval; + result = diffval <= (uint32_t) elementvftbl->diffval; +#endif } - linker_classrenumber_mutex->unlock(); + UNLOCK_CLASSRENUMBER_LOCK; return result; } @@ -851,10 +758,9 @@ bool builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o) * one-dimensional array of a class type */ bool builtin_fast_canstore_onedim_class(java_objectarray_t *a, java_object_t *o) { - vftbl_t *elementvftbl; - vftbl_t *valuevftbl; - uint32_t diffval; - bool result; + vftbl_t *elementvftbl; + vftbl_t *valuevftbl; + bool result; if (o == NULL) return 1; @@ -876,12 +782,16 @@ bool builtin_fast_canstore_onedim_class(java_objectarray_t *a, java_object_t *o) if (valuevftbl == elementvftbl) return 1; - linker_classrenumber_mutex->lock(); + LOCK_CLASSRENUMBER_LOCK; - diffval = valuevftbl->baseval - elementvftbl->baseval; - result = diffval <= (uint32_t) elementvftbl->diffval; +#if USES_NEW_SUBTYPE + result = fast_subtype_check(valuevftbl, elementvftbl); +#else + uint32_t diffval = valuevftbl->baseval - elementvftbl->baseval; + result = diffval <= (uint32_t) elementvftbl->diffval; +#endif - linker_classrenumber_mutex->unlock(); + UNLOCK_CLASSRENUMBER_LOCK; return result; } @@ -953,7 +863,7 @@ java_handle_t *builtin_new(classinfo *c) LLNI_vftbl_direct(o) = c->vftbl; #if defined(ENABLE_THREADS) - LLNI_DIRECT(o)->lockword.init(); + Lockword(LLNI_DIRECT(o)->lockword).init(); #endif CYCLES_STATS_GET(cycles_end); @@ -1035,7 +945,7 @@ java_handle_t *builtin_tlh_new(classinfo *c) LLNI_vftbl_direct(o) = c->vftbl; # if defined(ENABLE_THREADS) - LLNI_DIRECT(o)->lockword.init(); + Lockword(LLNI_DIRECT(o)->lockword).init(); # endif CYCLES_STATS_GET(cycles_end); @@ -1114,7 +1024,7 @@ java_object_t *builtin_fast_new(classinfo *c) o->vftbl = c->vftbl; #if defined(ENABLE_THREADS) - LLNI_DIRECT(o)->lockword.init(); + Lockword(LLNI_DIRECT(o)->lockword).init(); #endif CYCLES_STATS_GET(cycles_end); @@ -1127,7 +1037,7 @@ java_object_t *builtin_fast_new(classinfo *c) } -/* builtin_newarray ************************************************************ +/* builtin_java_newarray ******************************************************* Creates an array with the given vftbl on the heap. This function takes as class argument an array class. @@ -1135,111 +1045,27 @@ java_object_t *builtin_fast_new(classinfo *c) RETURN VALUE: pointer to the array or NULL if no memory is available - NOTE: This builtin can be called from NATIVE code only. + NOTE: This is a SLOW builtin and can be called from JIT code only. *******************************************************************************/ -java_handle_t *builtin_newarray(int32_t size, classinfo *arrayclass) +java_handle_array_t *builtin_java_newarray(int32_t size, java_handle_t *arrayclazz) { - arraydescriptor *desc; - s4 dataoffset; - s4 componentsize; - s4 actualsize; - java_handle_t *a; #if defined(ENABLE_RT_TIMING) struct timespec time_start, time_end; #endif RT_TIMING_GET_TIME(time_start); - desc = arrayclass->vftbl->arraydesc; - dataoffset = desc->dataoffset; - componentsize = desc->componentsize; - - if (size < 0) { - exceptions_throw_negativearraysizeexception(); - return NULL; - } - - actualsize = dataoffset + size * componentsize; - - /* check for overflow */ - - if (((u4) actualsize) < ((u4) size)) { - exceptions_throw_outofmemoryerror(); - return NULL; - } + classinfo* arrayclass = LLNI_classinfo_unwrap(arrayclazz); - a = (java_handle_t*) heap_alloc(actualsize, (desc->arraytype == ARRAYTYPE_OBJECT), NULL, true); - - if (a == NULL) - return NULL; - -#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) - LLNI_DIRECT(a)->lockword.init(); -#endif - - LLNI_array_size(a) = size; + // Allocate a new array with given size and class on the heap + Array a(size, arrayclass); RT_TIMING_GET_TIME(time_end); RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_ARRAY); - return a; -} - - -/* 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 - - NOTE: This builtin can be called from NATIVE code only. - -*******************************************************************************/ - -java_handle_objectarray_t *builtin_anewarray(int32_t size, classinfo *componentclass) -{ - classinfo *arrayclass; - - /* is class loaded */ - - assert(componentclass->state & CLASS_LOADED); - - /* is class linked */ - - if (!(componentclass->state & CLASS_LINKED)) - if (!link_class(componentclass)) - return NULL; - - arrayclass = class_array_of(componentclass, true); - - if (!arrayclass) - return NULL; - - return (java_handle_objectarray_t *) builtin_newarray(size, arrayclass); + return a.get_handle(); } @@ -1254,21 +1080,21 @@ java_handle_objectarray_t *builtin_anewarray(int32_t size, classinfo *componentc *******************************************************************************/ -#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); \ +#define BUILTIN_NEWARRAY_TYPE(type, name) \ +java_handle_##type##array_t *builtin_newarray_##type(int32_t size) \ +{ \ + name##Array a(size); \ + return a.get_handle(); \ } -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_NEWARRAY_TYPE(boolean, Boolean) +BUILTIN_NEWARRAY_TYPE(byte, Byte) +BUILTIN_NEWARRAY_TYPE(char, Char) +BUILTIN_NEWARRAY_TYPE(short, Short) +BUILTIN_NEWARRAY_TYPE(int, Int) +BUILTIN_NEWARRAY_TYPE(long, Long) +BUILTIN_NEWARRAY_TYPE(float, Float) +BUILTIN_NEWARRAY_TYPE(double, Double) /* builtin_multianewarray_intern *********************************************** @@ -1286,38 +1112,37 @@ BUILTIN_NEWARRAY_TYPE(double, ARRAYTYPE_DOUBLE) ******************************************************************************/ -static java_handle_t *builtin_multianewarray_intern(int n, +static java_handle_array_t *builtin_multianewarray_intern(int n, classinfo *arrayclass, long *dims) { - s4 size; - java_handle_t *a; - classinfo *componentclass; - s4 i; + int32_t i; /* create this dimension */ - size = (s4) dims[0]; - a = builtin_newarray(size, arrayclass); + int32_t size = (int32_t) dims[0]; + Array a(size, arrayclass); - if (!a) + if (a.is_null()) return NULL; /* if this is the last dimension return */ if (!--n) - return a; + return a.get_handle(); /* get the class of the components to create */ - componentclass = arrayclass->vftbl->arraydesc->componentvftbl->clazz; + classinfo* componentclass = arrayclass->vftbl->arraydesc->componentvftbl->clazz; /* The verifier guarantees that the dimension count is in the range. */ /* create the component arrays */ + ObjectArray oa(a.get_handle()); + for (i = 0; i < size; i++) { - java_handle_t *ea = + java_handle_array_t *ea = #if defined(__MIPS__) && (SIZEOF_VOID_P == 4) /* we save an s4 to a s8 slot, 8-byte aligned */ @@ -1329,10 +1154,10 @@ static java_handle_t *builtin_multianewarray_intern(int n, if (!ea) return NULL; - array_objectarray_element_set((java_handle_objectarray_t *) a, i, ea); + oa.set_element(i, (java_handle_t*) ea); } - return a; + return a.get_handle(); } @@ -1584,7 +1409,6 @@ s8 builtin_lxor(s8 a, s8 b) #endif /* !(SUPPORT_LONG && SUPPORT_LONG_LOGICAL) */ -#if !(SUPPORT_LONG && SUPPORT_LONG_CMP) s4 builtin_lcmp(s8 a, s8 b) { if (a < b) @@ -1595,7 +1419,6 @@ s4 builtin_lcmp(s8 a, s8 b) return 0; } -#endif /* !(SUPPORT_LONG && SUPPORT_LONG_CMP) */ /* functions for unsupported floating instructions ****************************/ @@ -2177,6 +2000,9 @@ void builtin_arraycopy(java_handle_t *src, s4 srcStart, return; } + Array sa(src); + Array da(dest); + sdesc = LLNI_vftbl_direct(src)->arraydesc; ddesc = LLNI_vftbl_direct(dest)->arraydesc; @@ -2192,8 +2018,8 @@ void builtin_arraycopy(java_handle_t *src, s4 srcStart, } // 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))) { + if ((((uint32_t) srcStart + (uint32_t) len) > (uint32_t) sa.get_length()) || + (((uint32_t) destStart + (uint32_t) len) > (uint32_t) da.get_length())) { exceptions_throw_arrayindexoutofboundsexception(); return; } @@ -2220,19 +2046,17 @@ void builtin_arraycopy(java_handle_t *src, s4 srcStart, else { /* We copy references of different type */ - java_handle_objectarray_t *oas = (java_handle_objectarray_t *) src; - java_handle_objectarray_t *oad = (java_handle_objectarray_t *) dest; + ObjectArray oas((java_handle_objectarray_t*) src); + ObjectArray oad((java_handle_objectarray_t*) dest); if (destStart <= srcStart) { for (i = 0; i < len; i++) { - java_handle_t *o; - - o = array_objectarray_element_get(oas, srcStart + i); + java_handle_t* o = oas.get_element(srcStart + i); - if (!builtin_canstore(oad, o)) + if (!builtin_canstore(oad.get_handle(), o)) return; - array_objectarray_element_set(oad, destStart + i, o); + oad.set_element(destStart + i, o); } } else { @@ -2243,14 +2067,12 @@ void builtin_arraycopy(java_handle_t *src, s4 srcStart, index have been copied before the throw. */ for (i = len - 1; i >= 0; i--) { - java_handle_t *o; + java_handle_t* o = oas.get_element(srcStart + i); - o = array_objectarray_element_get(oas, srcStart + i); - - if (!builtin_canstore(oad, o)) + if (!builtin_canstore(oad.get_handle(), o)) return; - array_objectarray_element_set(oad, destStart + i, o); + oad.set_element(destStart + i, o); } } } @@ -2315,7 +2137,9 @@ java_handle_t *builtin_clone(void *env, java_handle_t *o) /* we are cloning an array */ if (ad != NULL) { - size = ad->dataoffset + ad->componentsize * LLNI_array_size(o); + Array a(o); + + size = ad->dataoffset + ad->componentsize * a.get_length(); co = (java_handle_t*) heap_alloc(size, (ad->arraytype == ARRAYTYPE_OBJECT), NULL, true); @@ -2337,7 +2161,7 @@ java_handle_t *builtin_clone(void *env, java_handle_t *o) #endif #if defined(ENABLE_THREADS) - LLNI_DIRECT(co)->lockword.init(); + Lockword(LLNI_DIRECT(co)->lockword).init(); #endif LLNI_CRITICAL_END; @@ -2372,7 +2196,7 @@ java_handle_t *builtin_clone(void *env, java_handle_t *o) #endif #if defined(ENABLE_THREADS) - LLNI_DIRECT(co)->lockword.init(); + Lockword(LLNI_DIRECT(co)->lockword).init(); #endif LLNI_CRITICAL_END;