X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Flinker.cpp;h=b1bd60a427ca66815990cf6269939f03395e75be;hb=8c6bb03b79a31fcdb02e2331a91a928d558c2845;hp=84672cfb16cbf46a3587656e5ff220fe453dd858;hpb=4cce6a2426d398775d952d1726a28cf3da8fe990;p=cacao.git diff --git a/src/vm/linker.cpp b/src/vm/linker.cpp index 84672cfb1..b1bd60a42 100644 --- a/src/vm/linker.cpp +++ b/src/vm/linker.cpp @@ -94,7 +94,9 @@ classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool c static s4 interfaceindex; /* sequential numbering of interfaces */ static s4 classvalue; -Mutex *linker_classrenumber_mutex; +#if !USES_NEW_SUBTYPE +Mutex *linker_classrenumber_lock; +#endif #if defined(__cplusplus) extern "C" { @@ -125,10 +127,10 @@ void linker_preinit(void) interfaceindex = 0; -#if defined(ENABLE_THREADS) +#if defined(ENABLE_THREADS) && !USES_NEW_SUBTYPE /* create the global mutex */ - linker_classrenumber_mutex = new Mutex(); + linker_classrenumber_lock = new Mutex(); #endif /* Link the most basic classes. */ @@ -519,6 +521,77 @@ static bool linker_overwrite_method(methodinfo *mg, } +#if USES_NEW_SUBTYPE +/* build_display *************************************************************** + + Builds the entire display for a class. This entails filling the fixed part + as well as allocating and initializing the overflow part. + + See Cliff Click and John Rose: Fast subtype checking in the Hotspot JVM. + +*******************************************************************************/ + +static classinfo *build_display(classinfo *c) +{ + int depth, i; + int depth_fixed; + classinfo *super; + + do { + /* Handle arrays. */ + if (c->vftbl->arraydesc) { + arraydescriptor *a = c->vftbl->arraydesc; + if (a->elementvftbl && a->elementvftbl->clazz->super) { + classinfo *cls = a->elementvftbl->clazz->super; + int n; + for (n=0; ndimension; n++) + cls = class_array_of(cls, true); + super = cls; + break; + } + if (a->componentvftbl && a->elementvftbl) { + super = a->componentvftbl->clazz; + break; + } + } + /* Normal classes. */ + super = c->super; + } while (false); + if (super) { + if (!link_class(super)) + return NULL; + depth = super->vftbl->subtype_depth + 1; + } else + /* java.lang.Object doesn't have a super class. */ + depth = 0; + + /* Now copy super's display, append c->vftbl and initialize the remaining fields. */ + if (depth >= DISPLAY_SIZE) { + c->vftbl->subtype_overflow = MNEW(vftbl_t *, depth - DISPLAY_SIZE + 1); +#if defined(ENABLE_STATISTICS) + if (opt_stat) + count_vftbl_len += sizeof(vftbl_t*) * (depth - DISPLAY_SIZE + 1); +#endif + memcpy(c->vftbl->subtype_overflow, super->vftbl->subtype_overflow, sizeof(vftbl_t*) * (depth - DISPLAY_SIZE)); + c->vftbl->subtype_overflow[depth - DISPLAY_SIZE] = c->vftbl; + depth_fixed = DISPLAY_SIZE; + } + else { + depth_fixed = depth; + c->vftbl->subtype_display[depth] = c->vftbl; + } + + if (super) + memcpy(c->vftbl->subtype_display, super->vftbl->subtype_display, sizeof(vftbl_t*) * depth_fixed); + for (i=depth_fixed+1; i<=DISPLAY_SIZE; i++) + c->vftbl->subtype_display[i] = NULL; + c->vftbl->subtype_offset = OFFSET(vftbl_t, subtype_display[0]) + sizeof(vftbl_t*) * depth_fixed; + c->vftbl->subtype_depth = depth; + + return c; +} +#endif + /* link_class_intern *********************************************************** Tries to link a class. The function calculates the length in bytes @@ -921,8 +994,14 @@ static classinfo *link_class_intern(classinfo *c) linker_compute_subclasses(c); + /* FIXME: this is completely useless now */ RT_TIMING_GET_TIME(time_subclasses); +#if USES_NEW_SUBTYPE + if (!build_display(c)) + return NULL; +#endif + /* revert the linking state and class is linked */ c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED; @@ -1122,11 +1201,15 @@ static arraydescriptor *link_array(classinfo *c) static void linker_compute_subclasses(classinfo *c) { - linker_classrenumber_mutex->lock(); + + LOCK_CLASSRENUMBER_LOCK; if (!(c->flags & ACC_INTERFACE)) { c->nextsub = NULL; c->sub = NULL; +#if USES_NEW_SUBTYPE + c->vftbl->baseval = 1; /* so it does not look like an interface */ +#endif } if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) { @@ -1136,11 +1219,14 @@ static void linker_compute_subclasses(classinfo *c) classvalue = 0; +#if !USES_NEW_SUBTYPE /* compute class values */ linker_compute_class_values(class_java_lang_Object); +#endif + + UNLOCK_CLASSRENUMBER_LOCK; - linker_classrenumber_mutex->unlock(); }