mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-17 17:44:40 +02:00
8220343: Move scavenge_root_nmethods from shared code
Reviewed-by: kvn, eosterlund
This commit is contained in:
parent
3796014d86
commit
2370adc703
32 changed files with 521 additions and 399 deletions
|
@ -145,7 +145,6 @@ class CodeBlob_sizes {
|
|||
address CodeCache::_low_bound = 0;
|
||||
address CodeCache::_high_bound = 0;
|
||||
int CodeCache::_number_of_nmethods_with_dependencies = 0;
|
||||
nmethod* CodeCache::_scavenge_root_nmethods = NULL;
|
||||
ExceptionCache* volatile CodeCache::_exception_cache_purge_list = NULL;
|
||||
|
||||
// Initialize arrays of CodeHeap subsets
|
||||
|
@ -711,167 +710,6 @@ void CodeCache::blobs_do(CodeBlobClosure* f) {
|
|||
}
|
||||
}
|
||||
|
||||
// Walk the list of methods which might contain oops to the java heap.
|
||||
void CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure* f) {
|
||||
assert_locked_or_safepoint(CodeCache_lock);
|
||||
|
||||
const bool fix_relocations = f->fix_relocations();
|
||||
debug_only(mark_scavenge_root_nmethods());
|
||||
|
||||
nmethod* prev = NULL;
|
||||
nmethod* cur = scavenge_root_nmethods();
|
||||
while (cur != NULL) {
|
||||
debug_only(cur->clear_scavenge_root_marked());
|
||||
assert(cur->scavenge_root_not_marked(), "");
|
||||
assert(cur->on_scavenge_root_list(), "else shouldn't be on this list");
|
||||
|
||||
bool is_live = (!cur->is_zombie() && !cur->is_unloaded());
|
||||
LogTarget(Trace, gc, nmethod) lt;
|
||||
if (lt.is_enabled()) {
|
||||
LogStream ls(lt);
|
||||
CompileTask::print(&ls, cur,
|
||||
is_live ? "scavenge root " : "dead scavenge root", /*short_form:*/ true);
|
||||
}
|
||||
if (is_live) {
|
||||
// Perform cur->oops_do(f), maybe just once per nmethod.
|
||||
f->do_code_blob(cur);
|
||||
}
|
||||
nmethod* const next = cur->scavenge_root_link();
|
||||
// The scavengable nmethod list must contain all methods with scavengable
|
||||
// oops. It is safe to include more nmethod on the list, but we do not
|
||||
// expect any live non-scavengable nmethods on the list.
|
||||
if (fix_relocations) {
|
||||
if (!is_live || !cur->detect_scavenge_root_oops()) {
|
||||
unlink_scavenge_root_nmethod(cur, prev);
|
||||
} else {
|
||||
prev = cur;
|
||||
}
|
||||
}
|
||||
cur = next;
|
||||
}
|
||||
|
||||
// Check for stray marks.
|
||||
debug_only(verify_perm_nmethods(NULL));
|
||||
}
|
||||
|
||||
void CodeCache::register_scavenge_root_nmethod(nmethod* nm) {
|
||||
assert_locked_or_safepoint(CodeCache_lock);
|
||||
if (!nm->on_scavenge_root_list() && nm->detect_scavenge_root_oops()) {
|
||||
add_scavenge_root_nmethod(nm);
|
||||
}
|
||||
}
|
||||
|
||||
void CodeCache::verify_scavenge_root_nmethod(nmethod* nm) {
|
||||
nm->verify_scavenge_root_oops();
|
||||
}
|
||||
|
||||
void CodeCache::add_scavenge_root_nmethod(nmethod* nm) {
|
||||
assert_locked_or_safepoint(CodeCache_lock);
|
||||
|
||||
nm->set_on_scavenge_root_list();
|
||||
nm->set_scavenge_root_link(_scavenge_root_nmethods);
|
||||
set_scavenge_root_nmethods(nm);
|
||||
print_trace("add_scavenge_root", nm);
|
||||
}
|
||||
|
||||
void CodeCache::unlink_scavenge_root_nmethod(nmethod* nm, nmethod* prev) {
|
||||
assert_locked_or_safepoint(CodeCache_lock);
|
||||
|
||||
assert((prev == NULL && scavenge_root_nmethods() == nm) ||
|
||||
(prev != NULL && prev->scavenge_root_link() == nm), "precondition");
|
||||
|
||||
print_trace("unlink_scavenge_root", nm);
|
||||
if (prev == NULL) {
|
||||
set_scavenge_root_nmethods(nm->scavenge_root_link());
|
||||
} else {
|
||||
prev->set_scavenge_root_link(nm->scavenge_root_link());
|
||||
}
|
||||
nm->set_scavenge_root_link(NULL);
|
||||
nm->clear_on_scavenge_root_list();
|
||||
}
|
||||
|
||||
void CodeCache::drop_scavenge_root_nmethod(nmethod* nm) {
|
||||
assert_locked_or_safepoint(CodeCache_lock);
|
||||
|
||||
print_trace("drop_scavenge_root", nm);
|
||||
nmethod* prev = NULL;
|
||||
for (nmethod* cur = scavenge_root_nmethods(); cur != NULL; cur = cur->scavenge_root_link()) {
|
||||
if (cur == nm) {
|
||||
unlink_scavenge_root_nmethod(cur, prev);
|
||||
return;
|
||||
}
|
||||
prev = cur;
|
||||
}
|
||||
assert(false, "should have been on list");
|
||||
}
|
||||
|
||||
void CodeCache::prune_scavenge_root_nmethods() {
|
||||
assert_locked_or_safepoint(CodeCache_lock);
|
||||
|
||||
debug_only(mark_scavenge_root_nmethods());
|
||||
|
||||
nmethod* last = NULL;
|
||||
nmethod* cur = scavenge_root_nmethods();
|
||||
while (cur != NULL) {
|
||||
nmethod* next = cur->scavenge_root_link();
|
||||
debug_only(cur->clear_scavenge_root_marked());
|
||||
assert(cur->scavenge_root_not_marked(), "");
|
||||
assert(cur->on_scavenge_root_list(), "else shouldn't be on this list");
|
||||
|
||||
if (!cur->is_zombie() && !cur->is_unloaded()
|
||||
&& cur->detect_scavenge_root_oops()) {
|
||||
// Keep it. Advance 'last' to prevent deletion.
|
||||
last = cur;
|
||||
} else {
|
||||
// Prune it from the list, so we don't have to look at it any more.
|
||||
print_trace("prune_scavenge_root", cur);
|
||||
unlink_scavenge_root_nmethod(cur, last);
|
||||
}
|
||||
cur = next;
|
||||
}
|
||||
|
||||
// Check for stray marks.
|
||||
debug_only(verify_perm_nmethods(NULL));
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
void CodeCache::asserted_non_scavengable_nmethods_do(CodeBlobClosure* f) {
|
||||
// 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()) {
|
||||
assert(cur->on_scavenge_root_list(), "else shouldn't be on this list");
|
||||
cur->clear_scavenge_root_marked();
|
||||
}
|
||||
verify_perm_nmethods(f);
|
||||
}
|
||||
|
||||
// Temporarily mark nmethods that are claimed to be on the scavenge list.
|
||||
void CodeCache::mark_scavenge_root_nmethods() {
|
||||
NMethodIterator iter(NMethodIterator::only_alive);
|
||||
while(iter.next()) {
|
||||
nmethod* nm = iter.method();
|
||||
assert(nm->scavenge_root_not_marked(), "clean state");
|
||||
if (nm->on_scavenge_root_list())
|
||||
nm->set_scavenge_root_marked();
|
||||
}
|
||||
}
|
||||
|
||||
// If the closure is given, run it on the unlisted nmethods.
|
||||
// Also make sure that the effects of mark_scavenge_root_nmethods is gone.
|
||||
void CodeCache::verify_perm_nmethods(CodeBlobClosure* f_or_null) {
|
||||
NMethodIterator iter(NMethodIterator::only_alive);
|
||||
while(iter.next()) {
|
||||
nmethod* nm = iter.method();
|
||||
bool call_f = (f_or_null != NULL);
|
||||
assert(nm->scavenge_root_not_marked(), "must be already processed");
|
||||
if (nm->on_scavenge_root_list())
|
||||
call_f = false; // don't show this one to the client
|
||||
Universe::heap()->verify_nmethod(nm);
|
||||
if (call_f) f_or_null->do_code_blob(nm);
|
||||
}
|
||||
}
|
||||
#endif //PRODUCT
|
||||
|
||||
void CodeCache::verify_clean_inline_caches() {
|
||||
#ifdef ASSERT
|
||||
NMethodIterator iter(NMethodIterator::only_alive_and_not_unloading);
|
||||
|
@ -929,12 +767,6 @@ void CodeCache::purge_exception_caches() {
|
|||
_exception_cache_purge_list = NULL;
|
||||
}
|
||||
|
||||
void CodeCache::gc_prologue() { }
|
||||
|
||||
void CodeCache::gc_epilogue() {
|
||||
prune_scavenge_root_nmethods();
|
||||
}
|
||||
|
||||
uint8_t CodeCache::_unloading_cycle = 1;
|
||||
|
||||
void CodeCache::increment_unloading_cycle() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue