Index: vm/vmcore/src/gc/root_set_enum_common.cpp =================================================================== --- vm/vmcore/src/gc/root_set_enum_common.cpp (revision 541174) +++ vm/vmcore/src/gc/root_set_enum_common.cpp (working copy) @@ -139,10 +139,9 @@ } //vm_enumerate_static_fields -// This is the main function used to enumerate Java references by the VM and the JITs. -// It is part of the JIT-VM interface. // 20030405 Note: When compressing references, vm_enumerate_root_reference() expects to be called with slots // containing *managed* refs (represented by heap_base if null, not 0/NULL), so those refs must not be NULL. +#if _DEBUG static void check_ref(void** ref) { if (VM_Global_State::loader_env->compress_references) { @@ -156,6 +155,7 @@ } } } +#endif // _DEBUG void vm_enumerate_root_reference(void **ref, Boolean is_pinned) Index: vm/vmcore/src/kernel_classes/javasrc/java/lang/Class.java =================================================================== --- vm/vmcore/src/kernel_classes/javasrc/java/lang/Class.java (revision 541174) +++ vm/vmcore/src/kernel_classes/javasrc/java/lang/Class.java (working copy) @@ -285,7 +285,8 @@ * @com.intel.drl.spec_ref */ public ClassLoader getClassLoader() { - ClassLoader loader = VMClassRegistry.getClassLoader(this); + ClassLoader loader = definingLoader; + assert(loader == VMClassRegistry.getClassLoader(this)); SecurityManager sc = System.getSecurityManager(); if (sc != null) { ClassLoader callerLoader = VMClassRegistry.getClassLoader(VMStack @@ -1160,7 +1161,12 @@ return VMClassRegistry.getSimpleName(this); } - protected ClassLoader definingLoader; + /** + * Provides strong referencing between the classloader + * and it's defined classes. Intended for class unloading implementation. + * @see java.lang.ClassLoader#loadedClasses + */ + ClassLoader definingLoader; private final class ReflectionData { Index: vm/vmcore/src/kernel_classes/javasrc/java/lang/ClassLoader.java =================================================================== --- vm/vmcore/src/kernel_classes/javasrc/java/lang/ClassLoader.java (revision 541174) +++ vm/vmcore/src/kernel_classes/javasrc/java/lang/ClassLoader.java (working copy) @@ -106,11 +106,13 @@ */ private final HashMap definedPackages; - /* - * The following mapping is used , where binaryClassName - class name, - * clazz - corresponding class. - */ - Hashtable loadedClasses = new Hashtable(); + /** + * The class registry, provides strong referencing between the classloader + * and it's defined classes. Intended for class unloading implementation. + * @see java.lang.Class#definingLoader + * @see #registerLoadedClass() + */ + private ArrayList loadedClasses = new ArrayList(); /** * package private to access from the java.lang.Class class. The following @@ -377,12 +379,15 @@ } /** - * @com.intel.drl.spec_ref + * Registers the defined class, invoked by VM. + * Intended for class unloading implementation. */ - public void addToLoadedClasses(String name, Class clazz) { + @SuppressWarnings("unused") + private void registerLoadedClass(Class clazz) { synchronized (loadedClasses){ - loadedClasses.put(name, clazz); + loadedClasses.add(clazz); } + clazz.definingLoader = this; } /** @@ -430,7 +435,6 @@ certs = getCertificates(packageName, domain.getCodeSource()); } Class clazz = defineClass0(name, data, offset, len); - clazz.definingLoader = this; clazz.setProtectionDomain(domain); if (certs != null) { packageCertificates.put(packageName, certs); Index: vm/vmcore/src/class_support/classloader.cpp =================================================================== --- vm/vmcore/src/class_support/classloader.cpp (revision 541174) +++ vm/vmcore/src/class_support/classloader.cpp (working copy) @@ -1595,34 +1595,24 @@ return clss; } // UserDefinedClassLoader::DoLoadClass -bool ClassLoader::InsertClass(Class* clss) { - tmn_suspend_disable(); +static jmethodID getClassRegistryMethod() { + Global_Env* env = VM_Global_State::loader_env; + String* acr_func_name = env->string_pool.lookup("registerLoadedClass"); + String* acr_func_desc = env->string_pool.lookup("(Ljava/lang/Class;)V"); + Class* clss = env->LoadCoreClass("java/lang/ClassLoader"); + Method* m = clss->lookup_method(acr_func_name, acr_func_desc); + assert(m); + return (jmethodID)m; +} + +bool ClassLoader::InsertClass(Class* clss) +{ if (!IsBootstrap()) // skip BS classes { - Global_Env* env = VM_Global_State::loader_env; - jvalue args[3]; - ManagedObject* jstr; + static jmethodID registryMethod = getClassRegistryMethod(); + tmn_suspend_disable(); + jvalue args[2], res; - if (env->compress_references) { - jstr = uncompress_compressed_reference(clss->get_name()->intern.compressed_ref); - } else { - jstr = clss->get_name()->intern.raw_ref; - } - ObjectHandle h = oh_allocate_local_handle(); - if (jstr != NULL) { - h->object = jstr; - } else { - h->object = vm_instantiate_cp_string_resolved((String*)clss->get_name()); - } - args[1].l = h; - - if (exn_raised()) { - TRACE2("classloader", "OutOfMemoryError on class registering " << clss->get_name()->bytes); - assert (false); - tmn_suspend_enable(); - return false; - } - // this parameter ObjectHandle hl = oh_allocate_local_handle(); hl->object = m_loader; @@ -1631,19 +1621,12 @@ // jlc parameter ObjectHandle chl = oh_allocate_local_handle(); chl->object = *clss->get_class_handle(); - args[2].l = chl; + args[1].l = chl; - static String* acr_func_name = env->string_pool.lookup("addToLoadedClasses"); - static String* acr_func_desc = env->string_pool.lookup("(Ljava/lang/String;Ljava/lang/Class;)V"); + vm_execute_java_method_array(registryMethod, &res, args); + tmn_suspend_enable(); - Method* method = class_lookup_method_recursive(m_loader->vt()->clss, acr_func_name, acr_func_desc); - assert(method); - - jvalue res; - vm_execute_java_method_array((jmethodID) method, &res, args); - if(exn_raised()) { - tmn_suspend_enable(); return false; } } @@ -1653,7 +1636,7 @@ if (!IsBootstrap()){ RemoveFromReported(clss->get_name()); } - tmn_suspend_enable(); + m_initiatedClasses->Insert(clss->get_name(), clss); return true; }