X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Flinker.cpp;h=aa6cc39bc98a4799ed92bd710e4db67a09628b43;hb=4a6cefba48d8720b9e33f2e89823b8ed7fa0b78d;hp=84672cfb16cbf46a3587656e5ff220fe453dd858;hpb=c378b6dabad51760ac3d9fae8ca8bcab7cca1364;p=cacao.git diff --git a/src/vm/linker.cpp b/src/vm/linker.cpp index 84672cfb1..aa6cc39bc 100644 --- a/src/vm/linker.cpp +++ b/src/vm/linker.cpp @@ -1,6 +1,6 @@ -/* src/vm/linker.c - class linker functions +/* src/vm/linker.cpp - class linker functions - Copyright (C) 1996-2005, 2006, 2007, 2008 + Copyright (C) 1996, 2011 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -45,6 +45,7 @@ #include "vm/classcache.hpp" #include "vm/exceptions.hpp" #include "vm/globals.hpp" +#include "vm/hook.hpp" #include "vm/loader.hpp" #include "vm/options.h" #include "vm/primitive.hpp" @@ -55,6 +56,9 @@ #include "vm/jit/asmpart.h" #include "vm/jit/stubs.hpp" +#include +#include + /* debugging macros ***********************************************************/ @@ -94,7 +98,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" { @@ -110,6 +116,9 @@ static bool linker_addinterface(classinfo *c, classinfo *ic); static s4 class_highestinterface(classinfo *c); +typedef std::vector > deferred_strings_vec_t; +static deferred_strings_vec_t deferred_strings; + /* linker_init ***************************************************************** Initializes the linker subsystem and links classes required for the @@ -125,10 +134,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. */ @@ -289,6 +298,12 @@ void linker_init(void) if (!link_class(class_sun_reflect_MagicAccessorImpl)) vm_abort("linker_init: linking failed"); + + if (!link_class(class_sun_reflect_MethodAccessorImpl)) + vm_abort("linker_init: linking failed"); + + if (!link_class(class_sun_reflect_ConstructorAccessorImpl)) + vm_abort("linker_init: linking failed"); # endif if (!link_class(arrayclass_java_lang_Object)) @@ -374,7 +389,7 @@ classinfo *link_class(classinfo *c) if (c == NULL) { exceptions_throw_nullpointerexception(); - return NULL; + return 0; } LOCK_MONITOR_ENTER(c); @@ -423,6 +438,10 @@ classinfo *link_class(classinfo *c) RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL); + // Hook point just after a class was linked. + if (!Hook::class_linked(r)) + return 0; + return r; } @@ -519,6 +538,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 +1011,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; @@ -1107,6 +1203,24 @@ static arraydescriptor *link_array(classinfo *c) return desc; } +/* linker_create_string_later ************************************************** + + A hack so we can initialize java.lang.String objects during initialization. + +*******************************************************************************/ +void linker_create_string_later(java_object_t **a, utf *u) +{ + deferred_strings.push_back(std::make_pair(a, u)); +} + +void linker_initialize_deferred_strings() +{ + deferred_strings_vec_t::const_iterator it = deferred_strings.begin(); + for (; it != deferred_strings.end(); ++it) + *it->first = literalstring_new(it->second); + deferred_strings.clear(); +} + /* linker_compute_subclasses *************************************************** @@ -1122,11 +1236,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 +1254,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(); } @@ -1317,7 +1438,7 @@ static s4 class_highestinterface(classinfo *c) * Emacs will automagically detect them. * --------------------------------------------------------------------- * Local variables: - * mode: c + * mode: c++ * indent-tabs-mode: t * c-basic-offset: 4 * tab-width: 4