Index: vm/vmcore/include/classloader.h =================================================================== --- vm/vmcore/include/classloader.h (revision 526669) +++ vm/vmcore/include/classloader.h (working copy) @@ -155,7 +155,7 @@ public: ClassLoader() : m_loader(NULL), m_parent(NULL), m_name(NULL), m_package_table(NULL), m_loadedClasses(NULL), m_loadingClasses(NULL), m_reportedClasses(NULL), - m_javaTypes(NULL), m_nativeLibraries(NULL), m_verifyData(NULL) + m_javaTypes(NULL), m_nativeLibraries(NULL), m_verifyData(NULL), m_markBit(false) { apr_pool_create(&pool, 0); } @@ -208,6 +208,8 @@ public: bool IsBootstrap() { return m_loader == NULL; } + void Mark() { m_markBit = true; } + bool isMarked() { return m_markBit; } ManagedObject* GetLoader() { return m_loader; } const String* GetName() { return m_name; } ClassLoader* GetParent() { return m_parent; } @@ -225,6 +227,7 @@ VMEXPORT static ClassLoader* LookupLoader( ManagedObject* loader ); static void UnloadClassLoader( ManagedObject* loader ); static void gc_enumerate(); + static void ClearMarkBits(); static unsigned GetClassLoaderNumber() { return m_nextEntry; } static ClassLoader** GetClassLoaderTable() { return m_table; } static void DeleteClassLoaderTable(){ @@ -273,6 +276,7 @@ NativeLibraryList m_nativeLibraries; Lock_Manager m_lock; Lock_Manager m_types_cache_lock; + bool m_markBit; void* m_verifyData; apr_pool_t* pool; PoolManager *CodeMemoryManager; Index: vm/vmcore/include/unloading.h =================================================================== --- vm/vmcore/include/unloading.h (revision 526669) +++ vm/vmcore/include/unloading.h (working copy) @@ -22,5 +22,6 @@ #ifndef __UNLOADING_H__ #define __UNLOADING_H__ +void class_unloading_clear_mark_bits(); #endif Index: vm/vmcore/src/gc/stop_the_world_root_set_enum.cpp =================================================================== --- vm/vmcore/src/gc/stop_the_world_root_set_enum.cpp (revision 526669) +++ vm/vmcore/src/gc/stop_the_world_root_set_enum.cpp (working copy) @@ -98,6 +98,8 @@ jvmti_send_gc_start_event(); + class_unloading_clear_mark_bits(); + current_vm_thread = p_TLS_vmthread; // Run through list of active threads and enumerate each one of them. hythread_t tm_thread = hythread_iterator_next(&iterator); Index: vm/vmcore/src/gc/root_set_enum_common.cpp =================================================================== --- vm/vmcore/src/gc/root_set_enum_common.cpp (revision 526669) +++ vm/vmcore/src/gc/root_set_enum_common.cpp (working copy) @@ -255,6 +255,24 @@ << "." << method_get_name(cci->get_method()) << method_get_descriptor(cci->get_method())); cci->get_jit()->get_root_set_from_stack_frame(cci->get_method(), 0, si_get_jit_context(si)); + ClassLoader* cl = cci->get_method()->get_class()->get_class_loader(); + assert (cl); + // force cl classloader to be enumerated as strong reference + cl->Mark(); + if (cci->has_inline_info()) { + JIT *jit = cci->get_jit(); + NativeCodePtr ip = si_get_ip(si); + uint32 inlined_depth = si_get_inline_depth(si); + uint32 offset = (POINTER_SIZE_INT)ip - (POINTER_SIZE_INT)cci->get_code_block_addr(); + for (uint32 i = 0; i < inlined_depth; i++) { + Method* m = jit->get_inlined_method(cci->get_inline_info(), offset, i); + assert (m); + cl = m->get_class()->get_class_loader(); + assert (cl); + // force cl classloader to be enumerated as strong reference + cl->Mark(); + } + } TRACE2("enumeration", "enumerated eip=" << (void *) si_get_ip(si) << " is_first=" << !si_get_jit_context(si)->is_ip_past << " " << class_get_name(method_get_class(cci->get_method())) @@ -268,6 +286,13 @@ << (m2n_get_method(si_get_m2n(si)) ? method_get_name(m2n_get_method(si_get_m2n(si))) : "") << (m2n_get_method(si_get_m2n(si)) ? method_get_descriptor(m2n_get_method(si_get_m2n(si))) : "")); oh_enumerate_handles(m2n_get_local_handles(si_get_m2n(si))); + Method* m = m2n_get_method(si_get_m2n(si)); + if (m) { + ClassLoader* cl = m->get_class()->get_class_loader(); + assert (cl); + // force cl classloader to be enumerated as strong reference + cl->Mark(); + } } si_goto_previous(si, false); } Index: vm/vmcore/src/class_support/classloader.cpp =================================================================== --- vm/vmcore/src/class_support/classloader.cpp (revision 526669) +++ vm/vmcore/src/class_support/classloader.cpp (working copy) @@ -488,6 +488,21 @@ } +void ClassLoader::ClearMarkBits() +{ + TRACE2("classloader.unloading.clear", "Clearing mark bits"); + LMAutoUnlock aulock( &(ClassLoader::m_tableLock) ); + ClassTable::iterator cti; + for(unsigned i = 0; i < m_nextEntry; i++) { + TRACE2("classloader.unloading.debug", " Clearing mark bits in classloader " + << 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; + } + TRACE2("classloader.unloading.clear", "Finished clearing mark bits"); +} + + ClassLoader* ClassLoader::AddClassLoader( ManagedObject* loader ) { SuspendDisabledChecker sdc; @@ -1001,6 +1016,9 @@ return NULL; } +void class_unloading_clear_mark_bits() { + ClassLoader::ClearMarkBits(); +} inline void BootstrapClassLoader::SetClasspathFromString(char* bcp, apr_pool_t* tmp_pool)