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