X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Flinker.cpp;h=aa6cc39bc98a4799ed92bd710e4db67a09628b43;hb=4a6cefba48d8720b9e33f2e89823b8ed7fa0b78d;hp=f0acadb17b6a50c26f409a632b33f5c093396acc;hpb=c26d9e9fce45ecbce36f6fbddc099e4e6e3acaa8;p=cacao.git diff --git a/src/vm/linker.cpp b/src/vm/linker.cpp index f0acadb17..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. @@ -30,14 +30,14 @@ #include "vm/types.h" -#include "mm/memory.h" +#include "mm/memory.hpp" #include "native/native.hpp" #include "threads/lock.hpp" #include "threads/mutex.hpp" -#include "toolbox/logging.h" +#include "toolbox/logging.hpp" #include "vm/access.hpp" #include "vm/array.hpp" @@ -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 ***********************************************************/ @@ -112,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 @@ -291,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)) @@ -376,7 +389,7 @@ classinfo *link_class(classinfo *c) if (c == NULL) { exceptions_throw_nullpointerexception(); - return NULL; + return 0; } LOCK_MONITOR_ENTER(c); @@ -425,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; } @@ -521,78 +538,85 @@ static bool linker_overwrite_method(methodinfo *mg, } -/* link_class_intern *********************************************************** +#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. - Tries to link a class. The function calculates the length in bytes - that an instance of this class requires as well as the VTBL for - methods and interface methods. - *******************************************************************************/ -#if USES_NEW_SUBTYPE -static int build_display_inner(classinfo *topc, classinfo *c, int i) +static classinfo *build_display(classinfo *c) { - int depth; - if (!c) - return 0; + int depth, i; + int depth_fixed; + classinfo *super; + do { - if (c->vftbl->arraydesc) - { + /* Handle arrays. */ + if (c->vftbl->arraydesc) { arraydescriptor *a = c->vftbl->arraydesc; - if (a->elementvftbl && a->elementvftbl->clazz->super) - { + 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); - depth = build_display_inner(topc, cls, i+1); + super = cls; break; } - if (a->componentvftbl && a->elementvftbl) - { - depth = build_display_inner(topc, a->componentvftbl->clazz, i+1); + if (a->componentvftbl && a->elementvftbl) { + super = a->componentvftbl->clazz; break; } } - depth = build_display_inner(topc, c->super, i+1); + /* Normal classes. */ + super = c->super; } while (false); - if (depth >= DISPLAY_SIZE) - { - if (depth == DISPLAY_SIZE) - { - topc->vftbl->subtype_overflow = MNEW(vftbl_t *, i+1); + 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(void*) * (i+1); + if (opt_stat) + count_vftbl_len += sizeof(vftbl_t*) * (depth - DISPLAY_SIZE + 1); #endif - } - topc->vftbl->subtype_overflow[depth - DISPLAY_SIZE] = c->vftbl; - return depth + 1; + 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; } - topc->vftbl->subtype_display[depth] = c->vftbl; - return depth + 1; -} - -static void build_display(classinfo *c) -{ - int depth; - int i; - depth = build_display_inner(c, c, 0) - 1; + 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; - if (depth >= DISPLAY_SIZE) - { - c->vftbl->subtype_offset = OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]); - } - else - { - c->vftbl->subtype_offset = OFFSET(vftbl_t, subtype_display[0]) + sizeof(void*) * depth; - for (i=depth+1; i<=DISPLAY_SIZE; i++) - c->vftbl->subtype_display[i] = NULL; - } + + return c; } #endif +/* link_class_intern *********************************************************** + + Tries to link a class. The function calculates the length in bytes + that an instance of this class requires as well as the VTBL for + methods and interface methods. + +*******************************************************************************/ + static classinfo *link_class_intern(classinfo *c) { classinfo *super; /* super class */ @@ -991,7 +1015,8 @@ static classinfo *link_class_intern(classinfo *c) RT_TIMING_GET_TIME(time_subclasses); #if USES_NEW_SUBTYPE - build_display(c); + if (!build_display(c)) + return NULL; #endif /* revert the linking state and class is linked */ @@ -1100,8 +1125,8 @@ static arraydescriptor *link_array(classinfo *c) desc->elementvftbl = compvftbl->arraydesc->elementvftbl; if (compvftbl->arraydesc->dimension >= 255) { - log_text("Creating array of dimension >255"); - assert(0); + exceptions_throw_illegalargumentexception(); + return NULL; } desc->dimension = compvftbl->arraydesc->dimension + 1; @@ -1178,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 *************************************************** @@ -1395,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