src/share/vm/oops/instanceKlass.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Cdiff src/share/vm/oops/instanceKlass.cpp

src/share/vm/oops/instanceKlass.cpp

Print this page

        

*** 201,211 **** bool is_anonymous) { No_Safepoint_Verifier no_safepoint; // until k becomes parsable int iksize = InstanceKlass::size(vtable_len, itable_len, nonstatic_oop_map_size, access_flags.is_interface(), is_anonymous); - set_vtable_length(vtable_len); set_itable_length(itable_len); set_static_field_size(static_field_size); set_nonstatic_oop_map_size(nonstatic_oop_map_size); set_access_flags(access_flags); --- 201,210 ----
*** 230,240 **** set_array_name(NULL); set_inner_classes(NULL); set_static_oop_field_count(0); set_nonstatic_field_size(0); set_is_marked_dependent(false); ! set_has_unloaded_dependent(false); set_init_state(InstanceKlass::allocated); set_init_thread(NULL); set_reference_type(rt); set_oop_map_cache(NULL); set_jni_ids(NULL); --- 229,239 ---- set_array_name(NULL); set_inner_classes(NULL); set_static_oop_field_count(0); set_nonstatic_field_size(0); set_is_marked_dependent(false); ! _dep_context = DependencyContext::EMPTY; set_init_state(InstanceKlass::allocated); set_init_thread(NULL); set_reference_type(rt); set_oop_map_cache(NULL); set_jni_ids(NULL);
*** 244,254 **** set_generic_signature_index(0); release_set_methods_jmethod_ids(NULL); set_annotations(NULL); set_jvmti_cached_class_field_map(NULL); set_initial_method_idnum(0); - _dependencies = NULL; set_jvmti_cached_class_field_map(NULL); set_cached_class_file(NULL); set_initial_method_idnum(0); set_minor_version(0); set_major_version(0); --- 243,252 ----
*** 1862,1875 **** // // Walk the list of dependent nmethods searching for nmethods which // are dependent on the changes that were passed in and mark them for // deoptimization. Returns the number of nmethods found. // ! int nmethodBucket::mark_dependent_nmethods(nmethodBucket* deps, DepChange& changes) { ! assert_locked_or_safepoint(CodeCache_lock); int found = 0; ! for (nmethodBucket* b = deps; b != NULL; b = b->next()) { nmethod* nm = b->get_nmethod(); // since dependencies aren't removed until an nmethod becomes a zombie, // the dependency list may contain nmethods which aren't alive. if (b->count() > 0 && nm->is_alive() && !nm->is_marked_for_deoptimization() && nm->check_dependency_on(changes)) { if (TraceDependencies) { --- 1860,1872 ---- // // Walk the list of dependent nmethods searching for nmethods which // are dependent on the changes that were passed in and mark them for // deoptimization. Returns the number of nmethods found. // ! int DependencyContext::mark_dependent_nmethods(DepChange& changes) { int found = 0; ! for (nmethodBucket* b = dependencies(); b != NULL; b = b->next()) { nmethod* nm = b->get_nmethod(); // since dependencies aren't removed until an nmethod becomes a zombie, // the dependency list may contain nmethods which aren't alive. if (b->count() > 0 && nm->is_alive() && !nm->is_marked_for_deoptimization() && nm->check_dependency_on(changes)) { if (TraceDependencies) {
*** 1885,1964 **** } return found; } // ! // Add an nmethodBucket to the list of dependencies for this nmethod. // It's possible that an nmethod has multiple dependencies on this klass // so a count is kept for each bucket to guarantee that creation and // deletion of dependencies is consistent. Returns new head of the list. // ! nmethodBucket* nmethodBucket::add_dependent_nmethod(nmethodBucket* deps, nmethod* nm) { ! assert_locked_or_safepoint(CodeCache_lock); ! for (nmethodBucket* b = deps; b != NULL; b = b->next()) { if (nm == b->get_nmethod()) { b->increment(); ! return deps; } } ! return new nmethodBucket(nm, deps); } // ! // Decrement count of the nmethod in the dependency list and remove ! // the bucket completely when the count goes to 0. This method must ! // find a corresponding bucket otherwise there's a bug in the ! // recording of dependencies. Returns true if the bucket was deleted, ! // or marked ready for reclaimation. ! bool nmethodBucket::remove_dependent_nmethod(nmethodBucket** deps, nmethod* nm, bool delete_immediately) { assert_locked_or_safepoint(CodeCache_lock); ! ! nmethodBucket* first = *deps; nmethodBucket* last = NULL; - for (nmethodBucket* b = first; b != NULL; b = b->next()) { if (nm == b->get_nmethod()) { int val = b->decrement(); guarantee(val >= 0, "Underflow: %d", val); if (val == 0) { ! if (delete_immediately) { if (last == NULL) { ! *deps = b->next(); } else { last->set_next(b->next()); } delete b; } } ! return true; } last = b; } - #ifdef ASSERT tty->print_raw_cr("### can't find dependent nmethod"); nm->print(); #endif // ASSERT ShouldNotReachHere(); - return false; - } - - // Convenience overload, for callers that don't want to delete the nmethodBucket entry. - bool nmethodBucket::remove_dependent_nmethod(nmethodBucket* deps, nmethod* nm) { - nmethodBucket** deps_addr = &deps; - return remove_dependent_nmethod(deps_addr, nm, false /* Don't delete */); } // ! // Reclaim all unused buckets. Returns new head of the list. // ! nmethodBucket* nmethodBucket::clean_dependent_nmethods(nmethodBucket* deps) { ! nmethodBucket* first = deps; nmethodBucket* last = NULL; ! nmethodBucket* b = first; ! ! while (b != NULL) { assert(b->count() >= 0, "bucket count: %d", b->count()); nmethodBucket* next = b->next(); if (b->count() == 0) { if (last == NULL) { first = next; --- 1882,1963 ---- } return found; } // ! // Add an nmethod to the dependency context. // It's possible that an nmethod has multiple dependencies on this klass // so a count is kept for each bucket to guarantee that creation and // deletion of dependencies is consistent. Returns new head of the list. // ! void DependencyContext::add_dependent_nmethod(nmethod* nm, bool expunge) { ! assert_lock_strong(CodeCache_lock); ! for (nmethodBucket* b = dependencies(); b != NULL; b = b->next()) { if (nm == b->get_nmethod()) { b->increment(); ! return; } } ! set_dependencies(new nmethodBucket(nm, dependencies())); ! ! if (expunge) { ! // Remove stale entries from the list. ! expunge_stale_entries(); ! } } // ! // Decrement count of the nmethod in the dependency list and, optionally, remove ! // the bucket completely when the count goes to 0. This method must find ! // a corresponding bucket otherwise there's a bug in the recording of dependencies. ! void DependencyContext::remove_dependent_nmethod(nmethod* nm, bool expunge) { assert_locked_or_safepoint(CodeCache_lock); ! nmethodBucket* first = dependencies(); nmethodBucket* last = NULL; for (nmethodBucket* b = first; b != NULL; b = b->next()) { if (nm == b->get_nmethod()) { int val = b->decrement(); guarantee(val >= 0, "Underflow: %d", val); if (val == 0) { ! if (expunge) { if (last == NULL) { ! set_dependencies(b->next()); } else { last->set_next(b->next()); } delete b; + } else { + set_has_stale_entries(true); } } ! if (expunge) { ! // Remove stale entries from the list. ! expunge_stale_entries(); ! } ! return; } last = b; } #ifdef ASSERT tty->print_raw_cr("### can't find dependent nmethod"); nm->print(); #endif // ASSERT ShouldNotReachHere(); } // ! // Reclaim all unused buckets. // ! void DependencyContext::expunge_stale_entries() { ! assert_locked_or_safepoint(CodeCache_lock); ! if (!has_stale_entries()) { ! assert(!find_stale_entries(), "inconsistent info"); ! return; ! } ! nmethodBucket* first = dependencies(); nmethodBucket* last = NULL; ! for (nmethodBucket* b = first; b != NULL;) { assert(b->count() >= 0, "bucket count: %d", b->count()); nmethodBucket* next = b->next(); if (b->count() == 0) { if (last == NULL) { first = next;
*** 1970,1986 **** } else { last = b; } b = next; } ! return first; } #ifndef PRODUCT ! void nmethodBucket::print_dependent_nmethods(nmethodBucket* deps, bool verbose) { int idx = 0; ! for (nmethodBucket* b = deps; b != NULL; b = b->next()) { nmethod* nm = b->get_nmethod(); tty->print("[%d] count=%d { ", idx++, b->count()); if (!verbose) { nm->print_on(tty, "nmethod"); tty->print_cr(" } "); --- 1969,2005 ---- } else { last = b; } b = next; } ! set_dependencies(first); ! set_has_stale_entries(false); ! } ! ! int DependencyContext::remove_all_dependents() { ! //assert_lock_strong(CodeCache_lock); // called from InstanceKlass::release_C_heap_structures() ! nmethodBucket* b = dependencies(); ! set_dependencies(NULL); ! int marked = 0; ! while (b != NULL) { ! nmethod* nm = b->get_nmethod(); ! if (b->count() > 0 && nm->is_alive() && !nm->is_marked_for_deoptimization()) { ! nm->mark_for_deoptimization(); ! marked++; ! } ! nmethodBucket* next = b->next(); ! delete b; ! b = next; ! } ! set_has_stale_entries(false); ! return marked; } #ifndef PRODUCT ! void DependencyContext::print_dependent_nmethods(bool verbose) { int idx = 0; ! for (nmethodBucket* b = dependencies(); b != NULL; b = b->next()) { nmethod* nm = b->get_nmethod(); tty->print("[%d] count=%d { ", idx++, b->count()); if (!verbose) { nm->print_on(tty, "nmethod"); tty->print_cr(" } ");
*** 1990,2064 **** tty->print_cr("--- } "); } } } ! bool nmethodBucket::is_dependent_nmethod(nmethodBucket* deps, nmethod* nm) { ! for (nmethodBucket* b = deps; b != NULL; b = b->next()) { if (nm == b->get_nmethod()) { #ifdef ASSERT int count = b->count(); assert(count >= 0, "count shouldn't be negative: %d", count); #endif return true; } } return false; } - #endif //PRODUCT ! int InstanceKlass::mark_dependent_nmethods(DepChange& changes) { ! assert_locked_or_safepoint(CodeCache_lock); ! return nmethodBucket::mark_dependent_nmethods(_dependencies, changes); } ! void InstanceKlass::clean_dependent_nmethods() { ! assert_locked_or_safepoint(CodeCache_lock); ! if (has_unloaded_dependent()) { ! _dependencies = nmethodBucket::clean_dependent_nmethods(_dependencies); ! set_has_unloaded_dependent(false); ! } ! #ifdef ASSERT ! else { ! // Verification ! for (nmethodBucket* b = _dependencies; b != NULL; b = b->next()) { ! assert(b->count() >= 0, "bucket count: %d", b->count()); ! assert(b->count() != 0, "empty buckets need to be cleaned"); ! } ! } ! #endif } void InstanceKlass::add_dependent_nmethod(nmethod* nm) { ! assert_locked_or_safepoint(CodeCache_lock); ! _dependencies = nmethodBucket::add_dependent_nmethod(_dependencies, nm); } void InstanceKlass::remove_dependent_nmethod(nmethod* nm, bool delete_immediately) { ! assert_locked_or_safepoint(CodeCache_lock); ! ! if (nmethodBucket::remove_dependent_nmethod(&_dependencies, nm, delete_immediately)) { ! set_has_unloaded_dependent(true); ! } } #ifndef PRODUCT void InstanceKlass::print_dependent_nmethods(bool verbose) { ! nmethodBucket::print_dependent_nmethods(_dependencies, verbose); } bool InstanceKlass::is_dependent_nmethod(nmethod* nm) { ! return nmethodBucket::is_dependent_nmethod(_dependencies, nm); } #endif //PRODUCT void InstanceKlass::clean_weak_instanceklass_links(BoolObjectClosure* is_alive) { clean_implementors_list(is_alive); clean_method_data(is_alive); ! clean_dependent_nmethods(); } void InstanceKlass::clean_implementors_list(BoolObjectClosure* is_alive) { assert(class_loader_data()->is_alive(is_alive), "this klass should be live"); if (is_interface()) { --- 2009,2074 ---- tty->print_cr("--- } "); } } } ! bool DependencyContext::is_dependent_nmethod(nmethod* nm) { ! for (nmethodBucket* b = dependencies(); b != NULL; b = b->next()) { if (nm == b->get_nmethod()) { #ifdef ASSERT int count = b->count(); assert(count >= 0, "count shouldn't be negative: %d", count); #endif return true; } } return false; } ! bool DependencyContext::find_stale_entries() { ! for (nmethodBucket* b = dependencies(); b != NULL; b = b->next()) { ! if (b->count() == 0) return true; ! } ! return false; } ! #endif //PRODUCT ! int InstanceKlass::mark_dependent_nmethods(DepChange& changes) { ! DependencyContext dep_context(&_dep_context); ! return dep_context.mark_dependent_nmethods(changes); } void InstanceKlass::add_dependent_nmethod(nmethod* nm) { ! DependencyContext dep_context(&_dep_context); ! dep_context.add_dependent_nmethod(nm); } void InstanceKlass::remove_dependent_nmethod(nmethod* nm, bool delete_immediately) { ! DependencyContext dep_context(&_dep_context); ! dep_context.remove_dependent_nmethod(nm, delete_immediately); } #ifndef PRODUCT void InstanceKlass::print_dependent_nmethods(bool verbose) { ! DependencyContext dep_context(&_dep_context); ! dep_context.print_dependent_nmethods(verbose); } bool InstanceKlass::is_dependent_nmethod(nmethod* nm) { ! DependencyContext dep_context(&_dep_context); ! return dep_context.is_dependent_nmethod(nm); } #endif //PRODUCT void InstanceKlass::clean_weak_instanceklass_links(BoolObjectClosure* is_alive) { clean_implementors_list(is_alive); clean_method_data(is_alive); ! // Since GC iterates InstanceKlasses sequentially, it is safe to remove stale entries here. ! DependencyContext dep_context(&_dep_context); ! dep_context.expunge_stale_entries(); } void InstanceKlass::clean_implementors_list(BoolObjectClosure* is_alive) { assert(class_loader_data()->is_alive(is_alive), "this klass should be live"); if (is_interface()) {
*** 2101,2110 **** --- 2111,2122 ---- } init_implementor(); constants()->remove_unshareable_info(); + assert(_dep_context == DependencyContext::EMPTY, "dependency context is not shareable"); + for (int i = 0; i < methods()->length(); i++) { Method* m = methods()->at(i); m->remove_unshareable_info(); }
*** 2230,2245 **** set_member_names(NULL); } } // release dependencies ! nmethodBucket* b = _dependencies; ! _dependencies = NULL; ! while (b != NULL) { ! nmethodBucket* next = b->next(); ! delete b; ! b = next; } // Deallocate breakpoint records if (breakpoints() != 0x0) { methods_do(clear_all_breakpoints); --- 2242,2255 ---- set_member_names(NULL); } } // release dependencies ! { ! DependencyContext ctx(&_dep_context); ! int marked = ctx.remove_all_dependents(); ! assert(marked == 0, "all dependencies should be already invalidated"); } // Deallocate breakpoint records if (breakpoints() != 0x0) { methods_do(clear_all_breakpoints);
*** 3578,3772 **** /////////////// Unit tests /////////////// #ifndef PRODUCT ! class TestNmethodBucketContext { public: ! nmethod* _nmethodLast; ! nmethod* _nmethodMiddle; ! nmethod* _nmethodFirst; ! ! nmethodBucket* _bucketLast; ! nmethodBucket* _bucketMiddle; ! nmethodBucket* _bucketFirst; ! nmethodBucket* _bucketList; ! TestNmethodBucketContext() { CodeCache_lock->lock_without_safepoint_check(); ! _nmethodLast = reinterpret_cast<nmethod*>(0x8 * 0); ! _nmethodMiddle = reinterpret_cast<nmethod*>(0x8 * 1); ! _nmethodFirst = reinterpret_cast<nmethod*>(0x8 * 2); ! _bucketLast = new nmethodBucket(_nmethodLast, NULL); ! _bucketMiddle = new nmethodBucket(_nmethodMiddle, _bucketLast); ! _bucketFirst = new nmethodBucket(_nmethodFirst, _bucketMiddle); ! _bucketList = _bucketFirst; } ! ~TestNmethodBucketContext() { ! delete _bucketLast; ! delete _bucketMiddle; ! delete _bucketFirst; ! CodeCache_lock->unlock(); } - }; - - class TestNmethodBucket { - public: - static void testRemoveDependentNmethodFirstDeleteImmediately() { - TestNmethodBucketContext c; - - nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodFirst, true /* delete */); ! assert(c._bucketList == c._bucketMiddle, "check"); ! assert(c._bucketList->next() == c._bucketLast, "check"); ! assert(c._bucketList->next()->next() == NULL, "check"); ! ! // Cleanup before context is deleted. ! c._bucketFirst = NULL; } ! static void testRemoveDependentNmethodMiddleDeleteImmediately() { ! TestNmethodBucketContext c; ! ! nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodMiddle, true /* delete */); ! ! assert(c._bucketList == c._bucketFirst, "check"); ! assert(c._bucketList->next() == c._bucketLast, "check"); ! assert(c._bucketList->next()->next() == NULL, "check"); ! ! // Cleanup before context is deleted. ! c._bucketMiddle = NULL; } ! static void testRemoveDependentNmethodLastDeleteImmediately() { ! TestNmethodBucketContext c; ! ! nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodLast, true /* delete */); ! ! assert(c._bucketList == c._bucketFirst, "check"); ! assert(c._bucketList->next() == c._bucketMiddle, "check"); ! assert(c._bucketList->next()->next() == NULL, "check"); ! ! // Cleanup before context is deleted. ! c._bucketLast = NULL; ! } ! ! static void testRemoveDependentNmethodFirstDeleteDeferred() { ! TestNmethodBucketContext c; ! ! nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodFirst, false /* delete */); ! ! assert(c._bucketList == c._bucketFirst, "check"); ! assert(c._bucketList->next() == c._bucketMiddle, "check"); ! assert(c._bucketList->next()->next() == c._bucketLast, "check"); ! assert(c._bucketList->next()->next()->next() == NULL, "check"); ! ! assert(c._bucketFirst->count() == 0, "check"); ! assert(c._bucketMiddle->count() == 1, "check"); ! assert(c._bucketLast->count() == 1, "check"); ! } ! ! static void testRemoveDependentNmethodMiddleDeleteDeferred() { ! TestNmethodBucketContext c; ! ! nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodMiddle, false /* delete */); ! ! assert(c._bucketList == c._bucketFirst, "check"); ! assert(c._bucketList->next() == c._bucketMiddle, "check"); ! assert(c._bucketList->next()->next() == c._bucketLast, "check"); ! assert(c._bucketList->next()->next()->next() == NULL, "check"); ! ! assert(c._bucketFirst->count() == 1, "check"); ! assert(c._bucketMiddle->count() == 0, "check"); ! assert(c._bucketLast->count() == 1, "check"); ! } ! ! static void testRemoveDependentNmethodLastDeleteDeferred() { ! TestNmethodBucketContext c; ! ! nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodLast, false /* delete */); ! ! assert(c._bucketList == c._bucketFirst, "check"); ! assert(c._bucketList->next() == c._bucketMiddle, "check"); ! assert(c._bucketList->next()->next() == c._bucketLast, "check"); ! assert(c._bucketList->next()->next()->next() == NULL, "check"); ! ! assert(c._bucketFirst->count() == 1, "check"); ! assert(c._bucketMiddle->count() == 1, "check"); ! assert(c._bucketLast->count() == 0, "check"); ! } ! ! static void testRemoveDependentNmethodConvenienceFirst() { ! TestNmethodBucketContext c; ! ! nmethodBucket::remove_dependent_nmethod(c._bucketList, c._nmethodFirst); ! ! assert(c._bucketList == c._bucketFirst, "check"); ! assert(c._bucketList->next() == c._bucketMiddle, "check"); ! assert(c._bucketList->next()->next() == c._bucketLast, "check"); ! assert(c._bucketList->next()->next()->next() == NULL, "check"); ! ! assert(c._bucketFirst->count() == 0, "check"); ! assert(c._bucketMiddle->count() == 1, "check"); ! assert(c._bucketLast->count() == 1, "check"); } ! static void testRemoveDependentNmethodConvenienceMiddle() { ! TestNmethodBucketContext c; ! ! nmethodBucket::remove_dependent_nmethod(c._bucketList, c._nmethodMiddle); ! ! assert(c._bucketList == c._bucketFirst, "check"); ! assert(c._bucketList->next() == c._bucketMiddle, "check"); ! assert(c._bucketList->next()->next() == c._bucketLast, "check"); ! assert(c._bucketList->next()->next()->next() == NULL, "check"); ! ! assert(c._bucketFirst->count() == 1, "check"); ! assert(c._bucketMiddle->count() == 0, "check"); ! assert(c._bucketLast->count() == 1, "check"); } ! static void testRemoveDependentNmethodConvenienceLast() { ! TestNmethodBucketContext c; ! ! nmethodBucket::remove_dependent_nmethod(c._bucketList, c._nmethodLast); ! ! assert(c._bucketList == c._bucketFirst, "check"); ! assert(c._bucketList->next() == c._bucketMiddle, "check"); ! assert(c._bucketList->next()->next() == c._bucketLast, "check"); ! assert(c._bucketList->next()->next()->next() == NULL, "check"); ! ! assert(c._bucketFirst->count() == 1, "check"); ! assert(c._bucketMiddle->count() == 1, "check"); ! assert(c._bucketLast->count() == 0, "check"); } ! static void testRemoveDependentNmethod() { ! testRemoveDependentNmethodFirstDeleteImmediately(); ! testRemoveDependentNmethodMiddleDeleteImmediately(); ! testRemoveDependentNmethodLastDeleteImmediately(); ! ! testRemoveDependentNmethodFirstDeleteDeferred(); ! testRemoveDependentNmethodMiddleDeleteDeferred(); ! testRemoveDependentNmethodLastDeleteDeferred(); ! ! testRemoveDependentNmethodConvenienceFirst(); ! testRemoveDependentNmethodConvenienceMiddle(); ! testRemoveDependentNmethodConvenienceLast(); } - - static void test() { - testRemoveDependentNmethod(); } }; ! void TestNmethodBucket_test() { ! TestNmethodBucket::test(); } #endif --- 3588,3672 ---- /////////////// Unit tests /////////////// #ifndef PRODUCT ! class TestDependencyContext { public: ! nmethod* _nmethods[3]; ! intptr_t _dependency_context; ! TestDependencyContext() : _dependency_context(DependencyContext::EMPTY) { CodeCache_lock->lock_without_safepoint_check(); ! DependencyContext depContext(&_dependency_context); ! _nmethods[0] = reinterpret_cast<nmethod*>(0x8 * 0); ! _nmethods[1] = reinterpret_cast<nmethod*>(0x8 * 1); ! _nmethods[2] = reinterpret_cast<nmethod*>(0x8 * 2); ! depContext.add_dependent_nmethod(_nmethods[2]); ! depContext.add_dependent_nmethod(_nmethods[1]); ! depContext.add_dependent_nmethod(_nmethods[0]); } ! ~TestDependencyContext() { ! wipe(); CodeCache_lock->unlock(); } ! static void testRemoveDependentNmethod(int id, bool delete_immediately) { ! TestDependencyContext c; ! DependencyContext depContext(&c._dependency_context); ! assert(!has_stale_entries(depContext), "check"); ! ! nmethod* nm = c._nmethods[id]; ! depContext.remove_dependent_nmethod(nm, delete_immediately); ! ! if (!delete_immediately) { ! assert(has_stale_entries(depContext), "check"); ! assert(depContext.is_dependent_nmethod(nm), "check"); ! depContext.expunge_stale_entries(); } ! assert(!has_stale_entries(depContext), "check"); ! assert(!depContext.is_dependent_nmethod(nm), "check"); } ! static void testRemoveDependentNmethod() { ! testRemoveDependentNmethod(0, false); ! testRemoveDependentNmethod(1, false); ! testRemoveDependentNmethod(2, false); ! ! testRemoveDependentNmethod(0, true); ! testRemoveDependentNmethod(1, true); ! testRemoveDependentNmethod(2, true); } ! static void test() { ! testRemoveDependentNmethod(); } ! static bool has_stale_entries(DependencyContext ctx) { ! assert(ctx.has_stale_entries() == ctx.find_stale_entries(), "check"); ! return ctx.has_stale_entries(); } ! void wipe() { ! DependencyContext ctx(&_dependency_context); ! nmethodBucket* b = ctx.dependencies(); ! ctx.set_dependencies(NULL); ! ctx.set_has_stale_entries(false); ! while (b != NULL) { ! nmethodBucket* next = b->next(); ! delete b; ! b = next; } } }; ! void TestDependencyContext_test() { ! TestDependencyContext::test(); } #endif
src/share/vm/oops/instanceKlass.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File