X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fbuiltin.cpp;h=146e64dffdb87a8fbbc3820076088d0d08cb02ab;hb=fa8651a5a680d2f25e03d6df5fd275e70d5cc696;hp=1b9ccb99c0eb23d4fc18d6df2d62d6d88b848c41;hpb=0f3fd6afc8ee66f4a8be9de0adf2f28a336fd7a3;p=cacao.git diff --git a/src/vm/jit/builtin.cpp b/src/vm/jit/builtin.cpp index 1b9ccb99c..146e64dff 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,7 +56,7 @@ #include "threads/mutex.hpp" #include "threads/thread.hpp" -#include "toolbox/logging.h" +#include "toolbox/logging.hpp" #include "toolbox/util.h" #include "vm/array.hpp" @@ -67,7 +67,7 @@ #include "vm/global.h" #include "vm/globals.hpp" #include "vm/initialize.hpp" -#include "vm/linker.h" +#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" @@ -441,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 @@ -515,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); } @@ -628,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; @@ -640,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 ******************************************************* @@ -653,15 +629,6 @@ bool builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o) *******************************************************************************/ -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; -} - bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o) { arraydescriptor *desc; @@ -669,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) @@ -694,6 +660,8 @@ bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o) if (valuevftbl == componentvftbl) return 1; + LOCK_CLASSRENUMBER_LOCK; + baseval = componentvftbl->baseval; if (baseval <= 0) { @@ -703,8 +671,15 @@ bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o) (valuevftbl->interfacetable[baseval] != NULL)); } else { +#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 } + + UNLOCK_CLASSRENUMBER_LOCK; } else if (valuedesc == NULL) { /* {oa has dimension > 1} */ @@ -717,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 */ @@ -733,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) @@ -756,6 +730,8 @@ bool builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o) if (valuevftbl == elementvftbl) return 1; + LOCK_CLASSRENUMBER_LOCK; + baseval = elementvftbl->baseval; if (baseval <= 0) { @@ -764,9 +740,16 @@ bool builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o) (valuevftbl->interfacetable[baseval] != NULL)); } else { +#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 } + UNLOCK_CLASSRENUMBER_LOCK; + return result; } @@ -775,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; @@ -800,7 +782,16 @@ bool builtin_fast_canstore_onedim_class(java_objectarray_t *a, java_object_t *o) if (valuevftbl == elementvftbl) return 1; + LOCK_CLASSRENUMBER_LOCK; + +#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 + + UNLOCK_CLASSRENUMBER_LOCK; return result; } @@ -872,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); @@ -954,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); @@ -1033,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); @@ -1046,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. @@ -1054,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; + classinfo* arrayclass = LLNI_classinfo_unwrap(arrayclazz); - 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; - } - - 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(); } @@ -1173,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 *********************************************** @@ -1205,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 */ @@ -1248,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(); } @@ -2096,6 +2002,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; @@ -2111,8 +2020,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; } @@ -2139,19 +2048,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; + 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); } } else { @@ -2162,14 +2069,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; - - 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); } } } @@ -2234,7 +2139,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); @@ -2256,7 +2163,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; @@ -2291,7 +2198,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;