8048248: G1 Class Unloading after completing a concurrent mark cycle

Reviewed-by: tschatzl, ehelin, brutisso, coleenp, roland, iveresov
This commit is contained in:
Stefan Karlsson 2014-07-07 10:12:40 +02:00
parent b0138be158
commit 8c3aced316
75 changed files with 2169 additions and 874 deletions

View file

@ -331,6 +331,11 @@ void CodeCache::blobs_do(CodeBlobClosure* f) {
// Walk the list of methods which might contain non-perm oops.
void CodeCache::scavenge_root_nmethods_do(CodeBlobClosure* f) {
assert_locked_or_safepoint(CodeCache_lock);
if (UseG1GC) {
return;
}
debug_only(mark_scavenge_root_nmethods());
for (nmethod* cur = scavenge_root_nmethods(); cur != NULL; cur = cur->scavenge_root_link()) {
@ -356,6 +361,11 @@ void CodeCache::scavenge_root_nmethods_do(CodeBlobClosure* f) {
void CodeCache::add_scavenge_root_nmethod(nmethod* nm) {
assert_locked_or_safepoint(CodeCache_lock);
if (UseG1GC) {
return;
}
nm->set_on_scavenge_root_list();
nm->set_scavenge_root_link(_scavenge_root_nmethods);
set_scavenge_root_nmethods(nm);
@ -364,6 +374,11 @@ void CodeCache::add_scavenge_root_nmethod(nmethod* nm) {
void CodeCache::drop_scavenge_root_nmethod(nmethod* nm) {
assert_locked_or_safepoint(CodeCache_lock);
if (UseG1GC) {
return;
}
print_trace("drop_scavenge_root", nm);
nmethod* last = NULL;
nmethod* cur = scavenge_root_nmethods();
@ -385,6 +400,11 @@ void CodeCache::drop_scavenge_root_nmethod(nmethod* nm) {
void CodeCache::prune_scavenge_root_nmethods() {
assert_locked_or_safepoint(CodeCache_lock);
if (UseG1GC) {
return;
}
debug_only(mark_scavenge_root_nmethods());
nmethod* last = NULL;
@ -417,6 +437,10 @@ void CodeCache::prune_scavenge_root_nmethods() {
#ifndef PRODUCT
void CodeCache::asserted_non_scavengable_nmethods_do(CodeBlobClosure* f) {
if (UseG1GC) {
return;
}
// While we are here, verify the integrity of the list.
mark_scavenge_root_nmethods();
for (nmethod* cur = scavenge_root_nmethods(); cur != NULL; cur = cur->scavenge_root_link()) {
@ -457,9 +481,36 @@ void CodeCache::verify_perm_nmethods(CodeBlobClosure* f_or_null) {
}
#endif //PRODUCT
void CodeCache::verify_clean_inline_caches() {
#ifdef ASSERT
FOR_ALL_ALIVE_BLOBS(cb) {
if (cb->is_nmethod()) {
nmethod* nm = (nmethod*)cb;
assert(!nm->is_unloaded(), "Tautology");
nm->verify_clean_inline_caches();
nm->verify();
}
}
#endif
}
void CodeCache::verify_icholder_relocations() {
#ifdef ASSERT
// make sure that we aren't leaking icholders
int count = 0;
FOR_ALL_BLOBS(cb) {
if (cb->is_nmethod()) {
nmethod* nm = (nmethod*)cb;
count += nm->verify_icholder_relocations();
}
}
assert(count + InlineCacheBuffer::pending_icholder_count() + CompiledICHolder::live_not_claimed_count() ==
CompiledICHolder::live_count(), "must agree");
#endif
}
void CodeCache::gc_prologue() {
assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_epilogue must be called");
}
void CodeCache::gc_epilogue() {
@ -472,41 +523,15 @@ void CodeCache::gc_epilogue() {
nm->cleanup_inline_caches();
}
DEBUG_ONLY(nm->verify());
nm->fix_oop_relocations();
DEBUG_ONLY(nm->verify_oop_relocations());
}
}
set_needs_cache_clean(false);
prune_scavenge_root_nmethods();
assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_prologue must be called");
#ifdef ASSERT
// make sure that we aren't leaking icholders
int count = 0;
FOR_ALL_BLOBS(cb) {
if (cb->is_nmethod()) {
RelocIterator iter((nmethod*)cb);
while(iter.next()) {
if (iter.type() == relocInfo::virtual_call_type) {
if (CompiledIC::is_icholder_call_site(iter.virtual_call_reloc())) {
CompiledIC *ic = CompiledIC_at(&iter);
if (TraceCompiledIC) {
tty->print("noticed icholder " INTPTR_FORMAT " ", p2i(ic->cached_icholder()));
ic->print();
}
assert(ic->cached_icholder() != NULL, "must be non-NULL");
count++;
}
}
}
}
}
assert(count + InlineCacheBuffer::pending_icholder_count() + CompiledICHolder::live_not_claimed_count() ==
CompiledICHolder::live_count(), "must agree");
#endif
verify_icholder_relocations();
}
void CodeCache::verify_oops() {
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
VerifyOopClosure voc;