Mon, 15 Apr 2019 16:27:50 +0000
8150013: ParNew: Prune nmethods scavengable list.
Summary: Speed up ParNew collections by pruning the list of scavengable nmethods.
Reviewed-by: jmasa, tonyp, twisti
1.1 --- a/src/share/vm/code/codeCache.cpp Fri Aug 22 09:30:57 2014 -0700 1.2 +++ b/src/share/vm/code/codeCache.cpp Mon Apr 15 16:27:50 2019 +0000 1.3 @@ -336,16 +336,19 @@ 1.4 } 1.5 1.6 // Walk the list of methods which might contain non-perm oops. 1.7 -void CodeCache::scavenge_root_nmethods_do(CodeBlobClosure* f) { 1.8 +void CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure* f) { 1.9 assert_locked_or_safepoint(CodeCache_lock); 1.10 1.11 if (UseG1GC) { 1.12 return; 1.13 } 1.14 1.15 + const bool fix_relocations = f->fix_relocations(); 1.16 debug_only(mark_scavenge_root_nmethods()); 1.17 1.18 - for (nmethod* cur = scavenge_root_nmethods(); cur != NULL; cur = cur->scavenge_root_link()) { 1.19 + nmethod* prev = NULL; 1.20 + nmethod* cur = scavenge_root_nmethods(); 1.21 + while (cur != NULL) { 1.22 debug_only(cur->clear_scavenge_root_marked()); 1.23 assert(cur->scavenge_root_not_marked(), ""); 1.24 assert(cur->on_scavenge_root_list(), "else shouldn't be on this list"); 1.25 @@ -360,6 +363,18 @@ 1.26 // Perform cur->oops_do(f), maybe just once per nmethod. 1.27 f->do_code_blob(cur); 1.28 } 1.29 + nmethod* const next = cur->scavenge_root_link(); 1.30 + // The scavengable nmethod list must contain all methods with scavengable 1.31 + // oops. It is safe to include more nmethod on the list, but we do not 1.32 + // expect any live non-scavengable nmethods on the list. 1.33 + if (fix_relocations) { 1.34 + if (!is_live || !cur->detect_scavenge_root_oops()) { 1.35 + unlink_scavenge_root_nmethod(cur, prev); 1.36 + } else { 1.37 + prev = cur; 1.38 + } 1.39 + } 1.40 + cur = next; 1.41 } 1.42 1.43 // Check for stray marks. 1.44 @@ -379,6 +394,24 @@ 1.45 print_trace("add_scavenge_root", nm); 1.46 } 1.47 1.48 +void CodeCache::unlink_scavenge_root_nmethod(nmethod* nm, nmethod* prev) { 1.49 + assert_locked_or_safepoint(CodeCache_lock); 1.50 + 1.51 + assert((prev == NULL && scavenge_root_nmethods() == nm) || 1.52 + (prev != NULL && prev->scavenge_root_link() == nm), "precondition"); 1.53 + 1.54 + assert(!UseG1GC, "G1 does not use the scavenge_root_nmethods list"); 1.55 + 1.56 + print_trace("unlink_scavenge_root", nm); 1.57 + if (prev == NULL) { 1.58 + set_scavenge_root_nmethods(nm->scavenge_root_link()); 1.59 + } else { 1.60 + prev->set_scavenge_root_link(nm->scavenge_root_link()); 1.61 + } 1.62 + nm->set_scavenge_root_link(NULL); 1.63 + nm->clear_on_scavenge_root_list(); 1.64 +} 1.65 + 1.66 void CodeCache::drop_scavenge_root_nmethod(nmethod* nm) { 1.67 assert_locked_or_safepoint(CodeCache_lock); 1.68 1.69 @@ -387,20 +420,13 @@ 1.70 } 1.71 1.72 print_trace("drop_scavenge_root", nm); 1.73 - nmethod* last = NULL; 1.74 - nmethod* cur = scavenge_root_nmethods(); 1.75 - while (cur != NULL) { 1.76 - nmethod* next = cur->scavenge_root_link(); 1.77 + nmethod* prev = NULL; 1.78 + for (nmethod* cur = scavenge_root_nmethods(); cur != NULL; cur = cur->scavenge_root_link()) { 1.79 if (cur == nm) { 1.80 - if (last != NULL) 1.81 - last->set_scavenge_root_link(next); 1.82 - else set_scavenge_root_nmethods(next); 1.83 - nm->set_scavenge_root_link(NULL); 1.84 - nm->clear_on_scavenge_root_list(); 1.85 + unlink_scavenge_root_nmethod(cur, prev); 1.86 return; 1.87 } 1.88 - last = cur; 1.89 - cur = next; 1.90 + prev = cur; 1.91 } 1.92 assert(false, "should have been on list"); 1.93 } 1.94 @@ -429,11 +455,7 @@ 1.95 } else { 1.96 // Prune it from the list, so we don't have to look at it any more. 1.97 print_trace("prune_scavenge_root", cur); 1.98 - cur->set_scavenge_root_link(NULL); 1.99 - cur->clear_on_scavenge_root_list(); 1.100 - if (last != NULL) 1.101 - last->set_scavenge_root_link(next); 1.102 - else set_scavenge_root_nmethods(next); 1.103 + unlink_scavenge_root_nmethod(cur, last); 1.104 } 1.105 cur = next; 1.106 }
2.1 --- a/src/share/vm/code/codeCache.hpp Fri Aug 22 09:30:57 2014 -0700 2.2 +++ b/src/share/vm/code/codeCache.hpp Mon Apr 15 16:27:50 2019 +0000 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 2.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 * 2.9 * This code is free software; you can redistribute it and/or modify it 2.10 @@ -65,6 +65,10 @@ 2.11 2.12 static int _codemem_full_count; 2.13 2.14 + static void set_scavenge_root_nmethods(nmethod* nm) { _scavenge_root_nmethods = nm; } 2.15 + static void prune_scavenge_root_nmethods(); 2.16 + static void unlink_scavenge_root_nmethod(nmethod* nm, nmethod* prev); 2.17 + 2.18 public: 2.19 2.20 // Initialization 2.21 @@ -135,13 +139,17 @@ 2.22 // to "true" iff some code got unloaded. 2.23 static void do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred); 2.24 static void asserted_non_scavengable_nmethods_do(CodeBlobClosure* f = NULL) PRODUCT_RETURN; 2.25 - static void scavenge_root_nmethods_do(CodeBlobClosure* f); 2.26 + 2.27 + // Apply f to every live code blob in scavengable nmethods. Prune nmethods 2.28 + // from the list of scavengable nmethods if f->fix_relocations() and a nmethod 2.29 + // no longer has scavengable oops. If f->fix_relocations(), then f must copy 2.30 + // objects to their new location immediately to avoid fixing nmethods on the 2.31 + // basis of the old object locations. 2.32 + static void scavenge_root_nmethods_do(CodeBlobToOopClosure* f); 2.33 2.34 static nmethod* scavenge_root_nmethods() { return _scavenge_root_nmethods; } 2.35 - static void set_scavenge_root_nmethods(nmethod* nm) { _scavenge_root_nmethods = nm; } 2.36 static void add_scavenge_root_nmethod(nmethod* nm); 2.37 static void drop_scavenge_root_nmethod(nmethod* nm); 2.38 - static void prune_scavenge_root_nmethods(); 2.39 2.40 // Printing/debugging 2.41 static void print(); // prints summary
3.1 --- a/src/share/vm/code/nmethod.cpp Fri Aug 22 09:30:57 2014 -0700 3.2 +++ b/src/share/vm/code/nmethod.cpp Mon Apr 15 16:27:50 2019 +0000 3.3 @@ -1392,7 +1392,6 @@ 3.4 assert(_method == NULL, "Tautology"); 3.5 3.6 set_osr_link(NULL); 3.7 - //set_scavenge_root_link(NULL); // done by prune_scavenge_root_nmethods 3.8 NMethodSweeper::report_state_change(this); 3.9 } 3.10
4.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Fri Aug 22 09:30:57 2014 -0700 4.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Mon Apr 15 16:27:50 2019 +0000 4.3 @@ -1,5 +1,5 @@ 4.4 /* 4.5 - * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. 4.6 + * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. 4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 * 4.9 * This code is free software; you can redistribute it and/or modify it 4.10 @@ -636,12 +636,6 @@ 4.11 4.12 NOT_PRODUCT(reference_processor()->verify_no_references_recorded()); 4.13 4.14 - { 4.15 - GCTraceTime tm("Prune Scavenge Root Methods", false, false, &_gc_timer, _gc_tracer.gc_id()); 4.16 - 4.17 - CodeCache::prune_scavenge_root_nmethods(); 4.18 - } 4.19 - 4.20 // Re-verify object start arrays 4.21 if (VerifyObjectStartArray && 4.22 VerifyAfterGC) {
5.1 --- a/src/share/vm/memory/genCollectedHeap.cpp Fri Aug 22 09:30:57 2014 -0700 5.2 +++ b/src/share/vm/memory/genCollectedHeap.cpp Mon Apr 15 16:27:50 2019 +0000 5.3 @@ -1,5 +1,5 @@ 5.4 /* 5.5 - * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. 5.6 + * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. 5.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.8 * 5.9 * This code is free software; you can redistribute it and/or modify it 5.10 @@ -619,7 +619,7 @@ 5.11 OopClosure* weak_roots, 5.12 CLDClosure* strong_cld_closure, 5.13 CLDClosure* weak_cld_closure, 5.14 - CodeBlobClosure* code_roots) { 5.15 + CodeBlobToOopClosure* code_roots) { 5.16 StrongRootsScope srs(this, activate_scope); 5.17 5.18 // General roots. 5.19 @@ -638,7 +638,7 @@ 5.20 // Don't process them if they will be processed during the ClassLoaderDataGraph phase. 5.21 CLDClosure* roots_from_clds_p = (strong_cld_closure != weak_cld_closure) ? strong_cld_closure : NULL; 5.22 // Only process code roots from thread stacks if we aren't visiting the entire CodeCache anyway 5.23 - CodeBlobClosure* roots_from_code_p = (so & SO_AllCodeCache) ? NULL : code_roots; 5.24 + CodeBlobToOopClosure* roots_from_code_p = (so & SO_AllCodeCache) ? NULL : code_roots; 5.25 5.26 Threads::possibly_parallel_oops_do(strong_roots, roots_from_clds_p, roots_from_code_p); 5.27
6.1 --- a/src/share/vm/memory/genCollectedHeap.hpp Fri Aug 22 09:30:57 2014 -0700 6.2 +++ b/src/share/vm/memory/genCollectedHeap.hpp Mon Apr 15 16:27:50 2019 +0000 6.3 @@ -1,5 +1,5 @@ 6.4 /* 6.5 - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 6.6 + * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. 6.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.8 * 6.9 * This code is free software; you can redistribute it and/or modify it 6.10 @@ -416,7 +416,7 @@ 6.11 OopClosure* weak_roots, 6.12 CLDClosure* strong_cld_closure, 6.13 CLDClosure* weak_cld_closure, 6.14 - CodeBlobClosure* code_roots); 6.15 + CodeBlobToOopClosure* code_roots); 6.16 6.17 void gen_process_roots(int level, 6.18 bool younger_gens_as_roots,
7.1 --- a/src/share/vm/memory/iterator.hpp Fri Aug 22 09:30:57 2014 -0700 7.2 +++ b/src/share/vm/memory/iterator.hpp Mon Apr 15 16:27:50 2019 +0000 7.3 @@ -1,5 +1,5 @@ 7.4 /* 7.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 7.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 7.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.8 * 7.9 * This code is free software; you can redistribute it and/or modify it 7.10 @@ -291,9 +291,12 @@ 7.11 protected: 7.12 void do_nmethod(nmethod* nm); 7.13 public: 7.14 + // If fix_relocations(), then cl must copy objects to their new location immediately to avoid 7.15 + // patching nmethods with the old locations. 7.16 CodeBlobToOopClosure(OopClosure* cl, bool fix_relocations) : _cl(cl), _fix_relocations(fix_relocations) {} 7.17 virtual void do_code_blob(CodeBlob* cb); 7.18 7.19 + bool fix_relocations() const { return _fix_relocations; } 7.20 const static bool FixRelocations = true; 7.21 }; 7.22