提交 a44dcc97 编写于 作者: C cvarming

8150013: ParNew: Prune nmethods scavengable list.

Summary: Speed up ParNew collections by pruning the list of scavengable nmethods.
Reviewed-by: jmasa, tonyp, twisti
上级 5a7794e9
...@@ -336,16 +336,19 @@ void CodeCache::blobs_do(CodeBlobClosure* f) { ...@@ -336,16 +336,19 @@ void CodeCache::blobs_do(CodeBlobClosure* f) {
} }
// Walk the list of methods which might contain non-perm oops. // Walk the list of methods which might contain non-perm oops.
void CodeCache::scavenge_root_nmethods_do(CodeBlobClosure* f) { void CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure* f) {
assert_locked_or_safepoint(CodeCache_lock); assert_locked_or_safepoint(CodeCache_lock);
if (UseG1GC) { if (UseG1GC) {
return; return;
} }
const bool fix_relocations = f->fix_relocations();
debug_only(mark_scavenge_root_nmethods()); debug_only(mark_scavenge_root_nmethods());
for (nmethod* cur = scavenge_root_nmethods(); cur != NULL; cur = cur->scavenge_root_link()) { nmethod* prev = NULL;
nmethod* cur = scavenge_root_nmethods();
while (cur != NULL) {
debug_only(cur->clear_scavenge_root_marked()); debug_only(cur->clear_scavenge_root_marked());
assert(cur->scavenge_root_not_marked(), ""); assert(cur->scavenge_root_not_marked(), "");
assert(cur->on_scavenge_root_list(), "else shouldn't be on this list"); assert(cur->on_scavenge_root_list(), "else shouldn't be on this list");
...@@ -360,6 +363,18 @@ void CodeCache::scavenge_root_nmethods_do(CodeBlobClosure* f) { ...@@ -360,6 +363,18 @@ void CodeCache::scavenge_root_nmethods_do(CodeBlobClosure* f) {
// Perform cur->oops_do(f), maybe just once per nmethod. // Perform cur->oops_do(f), maybe just once per nmethod.
f->do_code_blob(cur); 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. // Check for stray marks.
...@@ -379,6 +394,24 @@ void CodeCache::add_scavenge_root_nmethod(nmethod* nm) { ...@@ -379,6 +394,24 @@ void CodeCache::add_scavenge_root_nmethod(nmethod* nm) {
print_trace("add_scavenge_root", 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");
assert(!UseG1GC, "G1 does not use the scavenge_root_nmethods list");
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) { void CodeCache::drop_scavenge_root_nmethod(nmethod* nm) {
assert_locked_or_safepoint(CodeCache_lock); assert_locked_or_safepoint(CodeCache_lock);
...@@ -387,20 +420,13 @@ void CodeCache::drop_scavenge_root_nmethod(nmethod* nm) { ...@@ -387,20 +420,13 @@ void CodeCache::drop_scavenge_root_nmethod(nmethod* nm) {
} }
print_trace("drop_scavenge_root", nm); print_trace("drop_scavenge_root", nm);
nmethod* last = NULL; nmethod* prev = NULL;
nmethod* cur = scavenge_root_nmethods(); for (nmethod* cur = scavenge_root_nmethods(); cur != NULL; cur = cur->scavenge_root_link()) {
while (cur != NULL) {
nmethod* next = cur->scavenge_root_link();
if (cur == nm) { if (cur == nm) {
if (last != NULL) unlink_scavenge_root_nmethod(cur, prev);
last->set_scavenge_root_link(next);
else set_scavenge_root_nmethods(next);
nm->set_scavenge_root_link(NULL);
nm->clear_on_scavenge_root_list();
return; return;
} }
last = cur; prev = cur;
cur = next;
} }
assert(false, "should have been on list"); assert(false, "should have been on list");
} }
...@@ -429,11 +455,7 @@ void CodeCache::prune_scavenge_root_nmethods() { ...@@ -429,11 +455,7 @@ void CodeCache::prune_scavenge_root_nmethods() {
} else { } else {
// Prune it from the list, so we don't have to look at it any more. // Prune it from the list, so we don't have to look at it any more.
print_trace("prune_scavenge_root", cur); print_trace("prune_scavenge_root", cur);
cur->set_scavenge_root_link(NULL); unlink_scavenge_root_nmethod(cur, last);
cur->clear_on_scavenge_root_list();
if (last != NULL)
last->set_scavenge_root_link(next);
else set_scavenge_root_nmethods(next);
} }
cur = next; cur = next;
} }
......
/* /*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -65,6 +65,10 @@ class CodeCache : AllStatic { ...@@ -65,6 +65,10 @@ class CodeCache : AllStatic {
static int _codemem_full_count; static int _codemem_full_count;
static void set_scavenge_root_nmethods(nmethod* nm) { _scavenge_root_nmethods = nm; }
static void prune_scavenge_root_nmethods();
static void unlink_scavenge_root_nmethod(nmethod* nm, nmethod* prev);
public: public:
// Initialization // Initialization
...@@ -135,13 +139,17 @@ class CodeCache : AllStatic { ...@@ -135,13 +139,17 @@ class CodeCache : AllStatic {
// to "true" iff some code got unloaded. // to "true" iff some code got unloaded.
static void do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred); static void do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred);
static void asserted_non_scavengable_nmethods_do(CodeBlobClosure* f = NULL) PRODUCT_RETURN; static void asserted_non_scavengable_nmethods_do(CodeBlobClosure* f = NULL) PRODUCT_RETURN;
static void scavenge_root_nmethods_do(CodeBlobClosure* f);
// Apply f to every live code blob in scavengable nmethods. Prune nmethods
// from the list of scavengable nmethods if f->fix_relocations() and a nmethod
// no longer has scavengable oops. If f->fix_relocations(), then f must copy
// objects to their new location immediately to avoid fixing nmethods on the
// basis of the old object locations.
static void scavenge_root_nmethods_do(CodeBlobToOopClosure* f);
static nmethod* scavenge_root_nmethods() { return _scavenge_root_nmethods; } static nmethod* scavenge_root_nmethods() { return _scavenge_root_nmethods; }
static void set_scavenge_root_nmethods(nmethod* nm) { _scavenge_root_nmethods = nm; }
static void add_scavenge_root_nmethod(nmethod* nm); static void add_scavenge_root_nmethod(nmethod* nm);
static void drop_scavenge_root_nmethod(nmethod* nm); static void drop_scavenge_root_nmethod(nmethod* nm);
static void prune_scavenge_root_nmethods();
// Printing/debugging // Printing/debugging
static void print(); // prints summary static void print(); // prints summary
......
...@@ -1392,7 +1392,6 @@ void nmethod::make_unloaded(BoolObjectClosure* is_alive, oop cause) { ...@@ -1392,7 +1392,6 @@ void nmethod::make_unloaded(BoolObjectClosure* is_alive, oop cause) {
assert(_method == NULL, "Tautology"); assert(_method == NULL, "Tautology");
set_osr_link(NULL); set_osr_link(NULL);
//set_scavenge_root_link(NULL); // done by prune_scavenge_root_nmethods
NMethodSweeper::report_state_change(this); NMethodSweeper::report_state_change(this);
} }
......
/* /*
* Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -636,12 +636,6 @@ bool PSScavenge::invoke_no_policy() { ...@@ -636,12 +636,6 @@ bool PSScavenge::invoke_no_policy() {
NOT_PRODUCT(reference_processor()->verify_no_references_recorded()); NOT_PRODUCT(reference_processor()->verify_no_references_recorded());
{
GCTraceTime tm("Prune Scavenge Root Methods", false, false, &_gc_timer, _gc_tracer.gc_id());
CodeCache::prune_scavenge_root_nmethods();
}
// Re-verify object start arrays // Re-verify object start arrays
if (VerifyObjectStartArray && if (VerifyObjectStartArray &&
VerifyAfterGC) { VerifyAfterGC) {
......
/* /*
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -619,7 +619,7 @@ void GenCollectedHeap::process_roots(bool activate_scope, ...@@ -619,7 +619,7 @@ void GenCollectedHeap::process_roots(bool activate_scope,
OopClosure* weak_roots, OopClosure* weak_roots,
CLDClosure* strong_cld_closure, CLDClosure* strong_cld_closure,
CLDClosure* weak_cld_closure, CLDClosure* weak_cld_closure,
CodeBlobClosure* code_roots) { CodeBlobToOopClosure* code_roots) {
StrongRootsScope srs(this, activate_scope); StrongRootsScope srs(this, activate_scope);
// General roots. // General roots.
...@@ -638,7 +638,7 @@ void GenCollectedHeap::process_roots(bool activate_scope, ...@@ -638,7 +638,7 @@ void GenCollectedHeap::process_roots(bool activate_scope,
// Don't process them if they will be processed during the ClassLoaderDataGraph phase. // Don't process them if they will be processed during the ClassLoaderDataGraph phase.
CLDClosure* roots_from_clds_p = (strong_cld_closure != weak_cld_closure) ? strong_cld_closure : NULL; CLDClosure* roots_from_clds_p = (strong_cld_closure != weak_cld_closure) ? strong_cld_closure : NULL;
// Only process code roots from thread stacks if we aren't visiting the entire CodeCache anyway // Only process code roots from thread stacks if we aren't visiting the entire CodeCache anyway
CodeBlobClosure* roots_from_code_p = (so & SO_AllCodeCache) ? NULL : code_roots; CodeBlobToOopClosure* roots_from_code_p = (so & SO_AllCodeCache) ? NULL : code_roots;
Threads::possibly_parallel_oops_do(strong_roots, roots_from_clds_p, roots_from_code_p); Threads::possibly_parallel_oops_do(strong_roots, roots_from_clds_p, roots_from_code_p);
......
/* /*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -416,7 +416,7 @@ public: ...@@ -416,7 +416,7 @@ public:
OopClosure* weak_roots, OopClosure* weak_roots,
CLDClosure* strong_cld_closure, CLDClosure* strong_cld_closure,
CLDClosure* weak_cld_closure, CLDClosure* weak_cld_closure,
CodeBlobClosure* code_roots); CodeBlobToOopClosure* code_roots);
void gen_process_roots(int level, void gen_process_roots(int level,
bool younger_gens_as_roots, bool younger_gens_as_roots,
......
/* /*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -291,9 +291,12 @@ class CodeBlobToOopClosure : public CodeBlobClosure { ...@@ -291,9 +291,12 @@ class CodeBlobToOopClosure : public CodeBlobClosure {
protected: protected:
void do_nmethod(nmethod* nm); void do_nmethod(nmethod* nm);
public: public:
// If fix_relocations(), then cl must copy objects to their new location immediately to avoid
// patching nmethods with the old locations.
CodeBlobToOopClosure(OopClosure* cl, bool fix_relocations) : _cl(cl), _fix_relocations(fix_relocations) {} CodeBlobToOopClosure(OopClosure* cl, bool fix_relocations) : _cl(cl), _fix_relocations(fix_relocations) {}
virtual void do_code_blob(CodeBlob* cb); virtual void do_code_blob(CodeBlob* cb);
bool fix_relocations() const { return _fix_relocations; }
const static bool FixRelocations = true; const static bool FixRelocations = true;
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册