X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=cacao.git;a=blobdiff_plain;f=src%2Fvm%2Floader.cpp;h=0dc53d0c0330602339dbad0aae5934ce9589e5a0;hp=4f1d36fff68d90f530ec0ac276fe36fd00431f18;hb=00f70baa559d938988363d68f416f684760d92a2;hpb=0698bb7e6153d5892e5ccdb9d9770999b1e1c217 diff --git a/src/vm/loader.cpp b/src/vm/loader.cpp index 4f1d36fff..0dc53d0c0 100644 --- a/src/vm/loader.cpp +++ b/src/vm/loader.cpp @@ -1,7 +1,8 @@ /* src/vm/loader.cpp - class loader functions - Copyright (C) 1996-2005, 2006, 2007, 2008 + Copyright (C) 1996-2011 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO + Copyright (C) 2009 Theobroma Systems Ltd. This file is part of CACAO. @@ -32,24 +33,27 @@ #include "vm/types.h" #include "mm/dumpmemory.hpp" -#include "mm/memory.h" +#include "mm/memory.hpp" #include "native/llni.h" #include "threads/mutex.hpp" #include "toolbox/hashtable.h" -#include "toolbox/logging.h" +#include "toolbox/list.hpp" +#include "toolbox/logging.hpp" #include "vm/jit/builtin.hpp" -#include "vm/classcache.h" +#include "vm/classcache.hpp" #include "vm/exceptions.hpp" #include "vm/field.hpp" #include "vm/global.h" #include "vm/globals.hpp" -#include "vm/linker.h" +#include "vm/hook.hpp" +#include "vm/javaobjects.hpp" +#include "vm/linker.hpp" #include "vm/loader.hpp" -#include "vm/method.h" +#include "vm/method.hpp" #include "vm/options.h" #include "vm/package.hpp" #include "vm/primitive.hpp" @@ -61,7 +65,7 @@ #if defined(ENABLE_JAVASE) -# include "vm/annotation.h" +# include "vm/annotation.hpp" # include "vm/stackmap.h" #endif @@ -70,15 +74,11 @@ #endif #if defined(ENABLE_ZLIB) -# include "vm/zip.h" +# include "vm/zip.hpp" #endif #include "vm/jit/stubs.hpp" -#if defined(ENABLE_JVMTI) -# include "native/jvmti/cacaodbg.h" -#endif - /* global variables ***********************************************************/ @@ -100,9 +100,12 @@ void loader_preinit(void) TRACESUBSYSTEMINITIALIZATION("loader_preinit"); #if defined(ENABLE_THREADS) + // Get current list of classpath entries. + SuckClasspath& suckclasspath = VM::get_current()->get_suckclasspath(); + /* Initialize the monitor pointer for zip/jar file locking. */ - for (List::iterator it = list_classpath_entries->begin(); it != list_classpath_entries->end(); it++) { + for (SuckClasspath::iterator it = suckclasspath.begin(); it != suckclasspath.end(); it++) { list_classpath_entry* lce = *it; if (lce->type == CLASSPATH_ARCHIVE) @@ -226,8 +229,10 @@ void loader_init(void) class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector); # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) - class_sun_misc_Signal = load_class_bootstrap(utf_new_char("sun/misc/Signal")); - class_sun_reflect_MagicAccessorImpl = load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl")); + class_sun_misc_Signal = load_class_bootstrap(utf_new_char("sun/misc/Signal")); + class_sun_reflect_MagicAccessorImpl = load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl")); + class_sun_reflect_MethodAccessorImpl = load_class_bootstrap(utf_new_char("sun/reflect/MethodAccessorImpl")); + class_sun_reflect_ConstructorAccessorImpl = load_class_bootstrap(utf_new_char("sun/reflect/ConstructorAccessorImpl")); # endif arrayclass_java_lang_Object = @@ -398,7 +403,10 @@ void loader_load_all_classes(void) utf *u; #endif - for (List::iterator it = list_classpath_entries->begin(); it != list_classpath_entries->end(); it++) { + // Get current list of classpath entries. + SuckClasspath& suckclasspath = VM::get_current()->get_suckclasspath(); + + for (SuckClasspath::iterator it = suckclasspath.begin(); it != suckclasspath.end(); it++) { list_classpath_entry* lce = *it; #if defined(ENABLE_ZLIB) @@ -484,58 +492,51 @@ bool loader_skip_attribute_body(classbuffer *cb) *******************************************************************************/ +/* The following structures are used to save information which cannot be + processed during the first pass. After the complete constantpool has + been traversed the references can be resolved (only in specific order). */ + +/* CONSTANT_Class entries */ +typedef struct forward_class { + u2 thisindex; + u2 name_index; +} forward_class; + +/* CONSTANT_String */ +typedef struct forward_string { + u2 thisindex; + u2 string_index; +} forward_string; + +/* CONSTANT_NameAndType */ +typedef struct forward_nameandtype { + u2 thisindex; + u2 name_index; + u2 sig_index; +} forward_nameandtype; + +/* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */ +typedef struct forward_fieldmethint { + u2 thisindex; + u1 tag; + u2 class_index; + u2 nameandtype_index; +} forward_fieldmethint; + static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool) { - - /* The following structures are used to save information which cannot be - processed during the first pass. After the complete constantpool has - been traversed the references can be resolved. - (only in specific order) */ - - /* CONSTANT_Class entries */ - typedef struct forward_class { - struct forward_class *next; - u2 thisindex; - u2 name_index; - } forward_class; - - /* CONSTANT_String */ - typedef struct forward_string { - struct forward_string *next; - u2 thisindex; - u2 string_index; - } forward_string; - - /* CONSTANT_NameAndType */ - typedef struct forward_nameandtype { - struct forward_nameandtype *next; - u2 thisindex; - u2 name_index; - u2 sig_index; - } forward_nameandtype; - - /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */ - typedef struct forward_fieldmethint { - struct forward_fieldmethint *next; - u2 thisindex; - u1 tag; - u2 class_index; - u2 nameandtype_index; - } forward_fieldmethint; - - classinfo *c; u4 idx; - forward_class *forward_classes = NULL; - forward_string *forward_strings = NULL; - forward_nameandtype *forward_nameandtypes = NULL; - forward_fieldmethint *forward_fieldmethints = NULL; + DumpList forward_classes; + DumpList forward_strings; + DumpList forward_nameandtypes; + DumpList forward_fieldmethints; - forward_class *nfc; - forward_string *nfs; - forward_nameandtype *nfn; - forward_fieldmethint *nff; + forward_class nfc; + forward_string nfs; + forward_nameandtype nfn; + forward_fieldmethint nff; u4 cpcount; u1 *cptags; @@ -569,11 +570,11 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool) cpinfos[idx] = NULL; } - + /******* first pass *******/ /* entries which cannot be resolved now are written into temporary structures and traversed again later */ - + idx = 1; while (idx < cpcount) { u4 t; @@ -586,88 +587,73 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool) switch (t) { case CONSTANT_Class: -#warning Use list. - nfc = (forward_class*) DumpMemory::allocate(sizeof(forward_class)); + nfc.thisindex = idx; - nfc->next = forward_classes; - forward_classes = nfc; - - nfc->thisindex = idx; /* reference to CONSTANT_NameAndType */ if (!suck_check_classbuffer_size(cb, 2)) return false; - nfc->name_index = suck_u2(cb); + nfc.name_index = suck_u2(cb); + + forward_classes.push_front(nfc); idx++; break; - + case CONSTANT_String: -#warning Use list. - nfs = (forward_string*) DumpMemory::allocate(sizeof(forward_string)); - - nfs->next = forward_strings; - forward_strings = nfs; - - nfs->thisindex = idx; + nfs.thisindex = idx; /* reference to CONSTANT_Utf8_info with string characters */ if (!suck_check_classbuffer_size(cb, 2)) return false; - nfs->string_index = suck_u2(cb); - + nfs.string_index = suck_u2(cb); + + forward_strings.push_front(nfs); + idx++; break; case CONSTANT_NameAndType: -#warning Use list. - nfn = (forward_nameandtype*) DumpMemory::allocate(sizeof(forward_nameandtype)); - - nfn->next = forward_nameandtypes; - forward_nameandtypes = nfn; - - nfn->thisindex = idx; + nfn.thisindex = idx; if (!suck_check_classbuffer_size(cb, 2 + 2)) return false; /* reference to CONSTANT_Utf8_info containing simple name */ - nfn->name_index = suck_u2(cb); + nfn.name_index = suck_u2(cb); /* reference to CONSTANT_Utf8_info containing field or method descriptor */ - nfn->sig_index = suck_u2(cb); - + nfn.sig_index = suck_u2(cb); + + forward_nameandtypes.push_front(nfn); + idx++; break; case CONSTANT_Fieldref: case CONSTANT_Methodref: case CONSTANT_InterfaceMethodref: -#warning Use list. - nff = (forward_fieldmethint*) DumpMemory::allocate(sizeof(forward_fieldmethint)); - - nff->next = forward_fieldmethints; - forward_fieldmethints = nff; - - nff->thisindex = idx; + nff.thisindex = idx; /* constant type */ - nff->tag = t; + nff.tag = t; if (!suck_check_classbuffer_size(cb, 2 + 2)) return false; /* class or interface type that contains the declaration of the field or method */ - nff->class_index = suck_u2(cb); + nff.class_index = suck_u2(cb); /* name and descriptor of the field or method */ - nff->nameandtype_index = suck_u2(cb); + nff.nameandtype_index = suck_u2(cb); + + forward_fieldmethints.push_front(nff); idx++; break; - + case CONSTANT_Integer: { constant_integer *ci = NEW(constant_integer); @@ -790,8 +776,10 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool) /* resolve entries in temporary structures */ - while (forward_classes) { - utf *name = (utf*) class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8); + for (DumpList::iterator it = forward_classes.begin(); + it != forward_classes.end(); ++it) { + + utf *name = (utf*) class_getconstant(c, it->name_index, CONSTANT_Utf8); if (!name) return false; @@ -807,30 +795,28 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool) if (!descriptor_pool_add_class(descpool, name)) return false; - cptags[forward_classes->thisindex] = CONSTANT_Class; + cptags[it->thisindex] = CONSTANT_Class; /* the classref is created later */ - cpinfos[forward_classes->thisindex] = name; - - nfc = forward_classes; - forward_classes = forward_classes->next; + cpinfos[it->thisindex] = name; } - while (forward_strings) { - utf *text = (utf*) class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8); + for (DumpList::iterator it = forward_strings.begin(); + it != forward_strings.end(); ++it) { + + utf *text = (utf*) class_getconstant(c, it->string_index, CONSTANT_Utf8); if (!text) return false; /* resolve utf-string */ - cptags[forward_strings->thisindex] = CONSTANT_String; - cpinfos[forward_strings->thisindex] = text; - - nfs = forward_strings; - forward_strings = forward_strings->next; + cptags[it->thisindex] = CONSTANT_String; + cpinfos[it->thisindex] = text; } - while (forward_nameandtypes) { + for (DumpList::iterator it = forward_nameandtypes.begin(); + it != forward_nameandtypes.end(); ++it) { + constant_nameandtype *cn = NEW(constant_nameandtype); #if defined(ENABLE_STATISTICS) @@ -840,13 +826,13 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool) /* resolve simple name and descriptor */ cn->name = (utf*) class_getconstant(c, - forward_nameandtypes->name_index, + it->name_index, CONSTANT_Utf8); if (!cn->name) return false; cn->descriptor = (utf*) class_getconstant(c, - forward_nameandtypes->sig_index, + it->sig_index, CONSTANT_Utf8); if (!cn->descriptor) return false; @@ -870,14 +856,13 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool) } #endif /* ENABLE_VERIFIER */ - cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType; - cpinfos[forward_nameandtypes->thisindex] = cn; - - nfn = forward_nameandtypes; - forward_nameandtypes = forward_nameandtypes->next; + cptags[it->thisindex] = CONSTANT_NameAndType; + cpinfos[it->thisindex] = cn; } - while (forward_fieldmethints) { + for (DumpList::iterator it = forward_fieldmethints.begin(); + it != forward_fieldmethints.end(); ++it) { + constant_nameandtype *nat; constant_FMIref *fmi = NEW(constant_FMIref); @@ -888,7 +873,7 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool) /* resolve simple name and descriptor */ nat = (constant_nameandtype*) class_getconstant(c, - forward_fieldmethints->nameandtype_index, + it->nameandtype_index, CONSTANT_NameAndType); if (!nat) @@ -901,15 +886,12 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool) /* the classref is created later */ - fmi->p.index = forward_fieldmethints->class_index; + fmi->p.index = it->class_index; fmi->name = nat->name; fmi->descriptor = nat->descriptor; - cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag; - cpinfos[forward_fieldmethints->thisindex] = fmi; - - nff = forward_fieldmethints; - forward_fieldmethints = forward_fieldmethints->next; + cptags[it->thisindex] = it->tag; + cpinfos[it->thisindex] = fmi; } /* everything was ok */ @@ -985,37 +967,22 @@ bool loader_load_attribute_signature(classbuffer *cb, utf **signature) *******************************************************************************/ +#if defined(ENABLE_JAVASE) classinfo *load_class_from_sysloader(utf *name) { - methodinfo *m; - java_handle_t *clo; classloader_t *cl; classinfo *c; - assert(class_java_lang_Object); - assert(class_java_lang_ClassLoader); - assert(class_java_lang_ClassLoader->state & CLASS_LINKED); - - m = class_resolveclassmethod(class_java_lang_ClassLoader, - utf_getSystemClassLoader, - utf_void__java_lang_ClassLoader, - class_java_lang_Object, - false); + cl = java_lang_ClassLoader::invoke_getSystemClassLoader(); - if (!m) - return false; - - clo = vm_call_method(m, NULL); - - if (!clo) + if (cl == NULL) return false; - cl = loader_hashtable_classloader_add(clo); - c = load_class_from_classloader(name, cl); return c; } +#endif /* defined(ENABLE_JAVASE) */ /* load_class_from_classloader ************************************************* @@ -1182,6 +1149,18 @@ classinfo *load_class_from_classloader(utf *name, classloader_t *cl) c = tmpc; } + else { + // Expected behavior for the classloader is to throw an exception + // and never return NULL. If the classloader shows a different + // behavior, we are correcting it here (see PR126). + if (exceptions_get_exception() == NULL) { +#if !defined(NDEBUG) + if (opt_PrintWarnings) + log_message_utf("load_class_from_classloader: Correcting faulty classloader behavior (PR126) for ", name); +#endif + exceptions_throw_classnotfoundexception(name); + } + } RT_TIMING_GET_TIME(time_cache); @@ -1197,12 +1176,6 @@ classinfo *load_class_from_classloader(utf *name, classloader_t *cl) printf("]\n"); } -#if defined(ENABLE_JVMTI) - /* fire Class Load JVMTI event */ - if (jvmti) jvmti_ClassLoadPrepare(false, c); -#endif - - return c; } @@ -1620,7 +1593,6 @@ static bool load_class_from_classbuffer_intern(classbuffer *cb) /* allocate space for the parsed descriptors */ descriptor_pool_alloc_parsed_descriptors(descpool); - c->parseddescs = (u1*) descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize)); #if defined(ENABLE_STATISTICS) if (opt_stat) { @@ -1992,18 +1964,14 @@ classinfo *load_class_from_classbuffer(classbuffer *cb) c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED; -#if defined(ENABLE_JVMTI) - /* fire Class Prepare JVMTI event */ - - if (jvmti) - jvmti_ClassLoadPrepare(true, c); -#endif - #if !defined(NDEBUG) if (loadverbose) log_message_class("Loading done class: ", c); #endif + // Hook point just after a class was loaded. + Hook::class_loaded(c); + return c; } @@ -2169,8 +2137,7 @@ classinfo *load_newly_created_array(classinfo *c, classloader_t *loader) /* parse the descriptor to get the register allocation */ - if (!descriptor_params_from_paramtypes(clonedesc, clone->flags)) - return false; + descriptor_params_from_paramtypes(clonedesc, clone->flags); clone->code = NativeStub::generate(clone, BUILTIN_clone); @@ -2179,8 +2146,6 @@ classinfo *load_newly_created_array(classinfo *c, classloader_t *loader) /* array classes are not loaded from class files */ c->state |= CLASS_LOADED; - c->parseddescs = (u1 *) clonedesc; - c->parseddescsize = sizeof(methodinfo); c->classrefs = classrefs; c->classrefcount = 1;