diff -BburN svn/interpreter/src/interpreter.cpp vm.new/interpreter/src/interpreter.cpp --- svn/interpreter/src/interpreter.cpp 2007-06-27 09:56:16.000000000 +0800 +++ vm.new/interpreter/src/interpreter.cpp 2007-07-17 10:26:29.000000000 +0800 @@ -3330,6 +3330,7 @@ // Setup locals and stack on C stack. SETUP_LOCALS_AND_STACK(frame, method); + frame.This = *(method->get_class()->get_class_handle()); int args = method->get_num_arg_slots(); for(int i = args-1; i >= 0; --i) { diff -BburN svn/vmcore/include/classloader.h vm.new/vmcore/include/classloader.h --- svn/vmcore/include/classloader.h 2007-07-11 12:11:30.000000000 +0800 +++ vm.new/vmcore/include/classloader.h 2007-07-16 16:39:07.000000000 +0800 @@ -227,9 +227,14 @@ static ClassLoader* FindByObject( ManagedObject* loader ); // ppervov: NOTE: LookupLoader has side effect of adding 'loader' to the collection VMEXPORT static ClassLoader* LookupLoader( ManagedObject* loader ); - static void UnloadClassLoader( ManagedObject* loader ); + static void UnloadClassLoader( ClassLoader* loader); static void gc_enumerate(); static void ClearMarkBits(); + static void StartUnloading(); static unsigned GetClassLoaderNumber() { return m_nextEntry; } static ClassLoader** GetClassLoaderTable() { return m_table; } static void DeleteClassLoaderTable(){ diff -BburN svn/vmcore/include/unloading.h vm.new/vmcore/include/unloading.h --- svn/vmcore/include/unloading.h 2007-07-11 12:11:31.000000000 +0800 +++ vm.new/vmcore/include/unloading.h 2007-07-16 16:17:35.000000000 +0800 @@ -23,5 +23,8 @@ #define __UNLOADING_H__ void class_unloading_clear_mark_bits(); +void class_unloading_start(); #endif diff -BburN svn/vmcore/include/vtable.h vm.new/vmcore/include/vtable.h --- svn/vmcore/include/vtable.h 2007-07-11 12:11:31.000000000 +0800 +++ vm.new/vmcore/include/vtable.h 2007-07-16 11:52:06.000000000 +0800 @@ -55,6 +55,8 @@ typedef struct VTable { Byte _gc_private_information[GC_BYTES_IN_VTABLE]; + ManagedObject* jIC; //for class-unloading, chunrong + unsigned int vtmark; //for class-unloading, chunrong Class* clss; // See the masks in vm_for_gc.h. diff -BburN svn/vmcore/src/class_support/Prepare.cpp vm.new/vmcore/src/class_support/Prepare.cpp --- svn/vmcore/src/class_support/Prepare.cpp 2007-07-11 12:12:04.000000000 +0800 +++ vm.new/vmcore/src/class_support/Prepare.cpp 2007-07-16 17:23:06.000000000 +0800 @@ -905,6 +905,21 @@ { m_is_suitable_for_fast_instanceof = 1; } + + Global_Env* env = VM_Global_State::loader_env; + if (!env->InBootstrap()){ + tmn_suspend_disable(); + vtable->jIC = *get_class_handle(); + tmn_suspend_enable(); + } + else { + // for BootStrap mode jlC is set in create_instance_for_class + // class_handle is NULL in bootstrap mode + assert (!get_class_handle()); + vtable->jIC = NULL; + } m_vtable = vtable; } // Class::create_vtable diff -BburN svn/vmcore/src/class_support/classloader.cpp vm.new/vmcore/src/class_support/classloader.cpp --- svn/vmcore/src/class_support/classloader.cpp 2007-07-11 12:12:04.000000000 +0800 +++ vm.new/vmcore/src/class_support/classloader.cpp 2007-07-17 11:23:29.000000000 +0800 @@ -462,14 +462,18 @@ } -void ClassLoader::UnloadClassLoader( ManagedObject* loader ) +void ClassLoader::UnloadClassLoader( ClassLoader* loader ) { LMAutoUnlock aulock( &(ClassLoader::m_tableLock) ); unsigned i; for(i = 0; i < m_nextEntry; i++) { ClassLoader* cl = m_table[i]; - if( loader == cl->m_loader ) break; + if( loader == cl) break; } if (i == m_nextEntry) return; ClassLoader* cl = m_table[i]; @@ -486,9 +490,25 @@ LMAutoUnlock aulock( &(ClassLoader::m_tableLock) ); for(unsigned int i = 0; i < m_nextEntry; i++) { if(m_table[i]->m_loader != NULL) { vm_enumerate_root_reference((void**)(&(m_table[i]->m_loader)), FALSE); } + **/ + assert (m_table[i]->m_loader); + if (m_table[i]->m_markBit) { + vm_enumerate_root_reference((void**)(&(m_table[i]->m_loader)), FALSE); + } + else { + vm_enumerate_weak_root_reference((void**)(&(m_table[i]->m_loader)), FALSE); + } + // should enumerate errors for classes + //for(fci = m_table[i]->m_failedClasses->begin(); + // fci != m_table[i]->m_failedClasses->end(); fci++) + //{ + // vm_enumerate_root_reference((void**)(&(fci->second.m_exception)), FALSE); + //} } } @@ -503,10 +523,76 @@ << m_table[i] << " (" << m_table[i]->m_loader << " : " << m_table[i]->m_loader->vt_unsafe()->clss->get_name()->bytes << ") and its classes"); m_table[i]->m_markBit = 0; + Class* c; + ReportedClasses::iterator itc; + ReportedClasses* RepClasses = m_table[i]->GetReportedClasses(); + for (itc = RepClasses->begin(); itc != RepClasses->end(); itc++) + { + c = itc->second; + if (c && c->get_vtable()) c->get_vtable()->vtmark = 0; + } + ClassTable* ct = m_table[i]->GetLoadedClasses(); + ClassTable::iterator it; + for (it = ct->begin(); it != ct->end(); it++) + { + c = it->second; + if (c && c->get_vtable()) c->get_vtable()->vtmark = 0; + } } TRACE2("classloader.unloading.clear", "Finished clearing mark bits"); } +void ClassLoader::StartUnloading() +{ + TRACE2("classloader.unloading.marking", "Finished marking loaders"); + TRACE2("classloader.unloading.do", "Start checking loaders ready to be unloaded"); + LMAutoUnlock aulock( &(ClassLoader::m_tableLock) ); + vector unloadinglist; + unsigned i; + for(i = 0; i < m_nextEntry; i++) { + if(m_table[i]->m_loader) { + TRACE2("classloader.unloading.debug", " Skipping live classloader " + << m_table[i] << " (" << m_table[i]->m_loader << " : " + << ((VTable*)(*(unsigned**)(m_table[i]->m_loader)))->clss->get_name()->bytes << ")"); + continue; + } + TRACE2("classloader.unloading.stats", " Unloading classloader " + << m_table[i] << " (" << m_table[i] << ")"); +#ifdef _DEBUG // check that all j.l.Classes inside j.l.ClassLoader are also unloaded + ClassTable* ct = m_table[i]->GetLoadedClasses(); + ClassTable::iterator it; + for (it = ct->begin(); it != ct->end(); it++) + { + Class* c = it->second; + if (*c->get_class_handle()) + { + DIE("FAILED on unloading classloader: \n" << (void*)m_table[i] << + "live j.l.Class of unloaded class is detected: " << c->get_name()->bytes); + assert (false); + } + } +#endif + unloadinglist.push_back(m_table[i]); + } + + // safely remove classloaders from m_table + vector::iterator it; + for (it = unloadinglist.begin(); it != unloadinglist.end(); it++) + { + UnloadClassLoader(*it); + } + + TRACE2("classloader.unloading.do", "Finished checking loaders"); +} ClassLoader* ClassLoader::AddClassLoader( ManagedObject* loader ) { @@ -1029,6 +1115,13 @@ void class_unloading_clear_mark_bits() { ClassLoader::ClearMarkBits(); } + +void class_unloading_start() { + ClassLoader::StartUnloading(); +} + inline void BootstrapClassLoader::SetClasspathFromString(char* bcp, apr_pool_t* tmp_pool) diff -BburN svn/vmcore/src/gc/root_set_enum_common.cpp vm.new/vmcore/src/gc/root_set_enum_common.cpp --- svn/vmcore/src/gc/root_set_enum_common.cpp 2007-07-11 12:12:15.000000000 +0800 +++ vm.new/vmcore/src/gc/root_set_enum_common.cpp 2007-07-17 16:49:41.000000000 +0800 @@ -71,9 +71,17 @@ assert (*c->get_class_handle()); if (!b_weak) { vm_enumerate_root_reference((void**)c->get_class_handle(), FALSE); + if(c->get_vtable()) + vm_enumerate_root_reference((void**)&(c->get_vtable()->jIC), FALSE); } else { vm_enumerate_weak_root_reference((void**)c->get_class_handle(), FALSE); + if(c->get_vtable()) + vm_enumerate_weak_root_reference((void**)&(c->get_vtable()->jIC), FALSE); } } diff -BburN svn/vmcore/src/gc/stop_the_world_root_set_enum.cpp vm.new/vmcore/src/gc/stop_the_world_root_set_enum.cpp --- svn/vmcore/src/gc/stop_the_world_root_set_enum.cpp 2007-07-11 12:12:15.000000000 +0800 +++ vm.new/vmcore/src/gc/stop_the_world_root_set_enum.cpp 2007-07-16 16:24:32.000000000 +0800 @@ -163,6 +163,10 @@ assert(p_the_safepoint_control_thread == p_TLS_vmthread); p_the_safepoint_control_thread = 0; + class_unloading_start(); + jvmti_send_gc_finish_event(); jvmti_clean_reclaimed_object_tags(); diff -BburN svn/vmcore/src/init/vm_init.cpp vm.new/vmcore/src/init/vm_init.cpp --- svn/vmcore/src/init/vm_init.cpp 2007-07-11 12:12:07.000000000 +0800 +++ vm.new/vmcore/src/init/vm_init.cpp 2007-07-17 10:59:58.000000000 +0800 @@ -110,6 +110,15 @@ void create_instance_for_class(Global_Env * vm_env, Class *clss) { clss->get_class_loader()->AllocateAndReportInstance(vm_env, clss); + // set jlC to vtable - for non BS classes jlc is set in create_vtable + if (clss->get_vtable()) // vtable = NULL for interfaces + { + assert (!clss->get_vtable()->jIC); // used for BS classes only + clss->get_vtable()->jIC = *clss->get_class_handle(); + assert (!clss->get_class_loader()->GetLoader()); + } } //create_instance_for_class /**