X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Floader.cpp;h=391fb71b5c7ace540084bbd44e66185e4939d760;hb=4e25f6be9878154a9a7ae28917ed34427cb8ca6a;hp=2dd8dac9feeabf7c6ced20ea9e317c696b8fc6ce;hpb=63aa269f8f97ed853c98af7b0ae3da84a1c23422;p=cacao.git diff --git a/src/vm/loader.cpp b/src/vm/loader.cpp index 2dd8dac9f..391fb71b5 100644 --- a/src/vm/loader.cpp +++ b/src/vm/loader.cpp @@ -1,6 +1,6 @@ /* 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. @@ -40,6 +40,7 @@ #include "threads/mutex.hpp" #include "toolbox/hashtable.h" +#include "toolbox/list.hpp" #include "toolbox/logging.hpp" #include "vm/jit/builtin.hpp" @@ -48,6 +49,8 @@ #include "vm/field.hpp" #include "vm/global.h" #include "vm/globals.hpp" +#include "vm/hook.hpp" +#include "vm/javaobjects.hpp" #include "vm/linker.hpp" #include "vm/loader.hpp" #include "vm/method.hpp" @@ -76,10 +79,6 @@ #include "vm/jit/stubs.hpp" -#if defined(ENABLE_JVMTI) -# include "native/jvmti/cacaodbg.h" -#endif - /* global variables ***********************************************************/ @@ -230,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 = @@ -491,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; @@ -576,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; @@ -593,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->next = forward_classes; - forward_classes = nfc; + nfc.thisindex = idx; - 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); @@ -797,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; @@ -814,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) @@ -847,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; @@ -877,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); @@ -895,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) @@ -908,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 */ @@ -992,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 ************************************************* @@ -1216,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; } @@ -1639,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) { @@ -2011,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; } @@ -2170,6 +2119,7 @@ classinfo *load_newly_created_array(classinfo *c, classloader_t *loader) clonedesc->paramslots = 0; clonedesc->paramtypes[0].classref = classrefs + 0; clonedesc->params = NULL; + clonedesc->pool_lock = NULL; /* create methodinfo */ @@ -2188,8 +2138,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); @@ -2198,8 +2147,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;