# HG changeset patch # User mgerdin # Date 1441352855 -7200 # Node ID ceb9d9044fc8c778d7095758a35148a2bb726101 # Parent 1fb9e9f01532feffcec0e4779a289c22ffb9b5c8 8135012: Don't use G1RootProcessor when scanning remembered sets Reviewed-by: jmasa, ecaspole diff -r 1fb9e9f01532 -r ceb9d9044fc8 src/share/vm/gc/g1/g1CodeBlobClosure.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/gc/g1/g1CodeBlobClosure.cpp Fri Sep 04 09:47:35 2015 +0200 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "code/nmethod.hpp" +#include "gc/g1/g1CodeBlobClosure.hpp" +#include "gc/g1/g1CollectedHeap.inline.hpp" +#include "gc/g1/heapRegion.hpp" +#include "gc/g1/heapRegionRemSet.hpp" +#include "oops/oop.inline.hpp" + +template +void G1CodeBlobClosure::HeapRegionGatheringOopClosure::do_oop_work(T* p) { + _work->do_oop(p); + T oop_or_narrowoop = oopDesc::load_heap_oop(p); + if (!oopDesc::is_null(oop_or_narrowoop)) { + oop o = oopDesc::decode_heap_oop_not_null(oop_or_narrowoop); + HeapRegion* hr = _g1h->heap_region_containing_raw(o); + assert(!_g1h->obj_in_cs(o) || hr->rem_set()->strong_code_roots_list_contains(_nm), "if o still in collection set then evacuation failed and nm must already be in the remset"); + hr->add_strong_code_root(_nm); + } +} + +void G1CodeBlobClosure::HeapRegionGatheringOopClosure::do_oop(oop* o) { + do_oop_work(o); +} + +void G1CodeBlobClosure::HeapRegionGatheringOopClosure::do_oop(narrowOop* o) { + do_oop_work(o); +} + +void G1CodeBlobClosure::do_code_blob(CodeBlob* cb) { + nmethod* nm = cb->as_nmethod_or_null(); + if (nm != NULL) { + if (!nm->test_set_oops_do_mark()) { + _oc.set_nm(nm); + nm->oops_do(&_oc); + nm->fix_oop_relocations(); + } + } +} + diff -r 1fb9e9f01532 -r ceb9d9044fc8 src/share/vm/gc/g1/g1CodeBlobClosure.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/gc/g1/g1CodeBlobClosure.hpp Fri Sep 04 09:47:35 2015 +0200 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "gc/g1/g1CollectedHeap.hpp" +#include "memory/iterator.hpp" + +class nmethod; + +class G1CodeBlobClosure : public CodeBlobClosure { + class HeapRegionGatheringOopClosure : public OopClosure { + G1CollectedHeap* _g1h; + OopClosure* _work; + nmethod* _nm; + + template + void do_oop_work(T* p); + + public: + HeapRegionGatheringOopClosure(OopClosure* oc) : _g1h(G1CollectedHeap::heap()), _work(oc), _nm(NULL) {} + + void do_oop(oop* o); + void do_oop(narrowOop* o); + + void set_nm(nmethod* nm) { + _nm = nm; + } + }; + + HeapRegionGatheringOopClosure _oc; +public: + G1CodeBlobClosure(OopClosure* oc) : _oc(oc) {} + + void do_code_blob(CodeBlob* cb); +}; diff -r 1fb9e9f01532 -r ceb9d9044fc8 src/share/vm/gc/g1/g1CollectedHeap.cpp --- a/src/share/vm/gc/g1/g1CollectedHeap.cpp Fri Sep 04 08:36:13 2015 +0200 +++ b/src/share/vm/gc/g1/g1CollectedHeap.cpp Fri Sep 04 09:47:35 2015 +0200 @@ -4664,9 +4664,9 @@ worker_id); G1ParPushHeapRSClosure push_heap_rs_cl(_g1h, pss); - _root_processor->scan_remembered_sets(&push_heap_rs_cl, - weak_root_cl, - worker_id); + _g1h->g1_rem_set()->oops_into_collection_set_do(&push_heap_rs_cl, + weak_root_cl, + worker_id); double strong_roots_sec = os::elapsedTime() - start_strong_roots_sec; double term_sec = 0.0; diff -r 1fb9e9f01532 -r ceb9d9044fc8 src/share/vm/gc/g1/g1RemSet.cpp --- a/src/share/vm/gc/g1/g1RemSet.cpp Fri Sep 04 08:36:13 2015 +0200 +++ b/src/share/vm/gc/g1/g1RemSet.cpp Fri Sep 04 09:47:35 2015 +0200 @@ -26,6 +26,7 @@ #include "gc/g1/concurrentG1Refine.hpp" #include "gc/g1/concurrentG1RefineThread.hpp" #include "gc/g1/g1BlockOffsetTable.inline.hpp" +#include "gc/g1/g1CodeBlobClosure.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectorPolicy.hpp" #include "gc/g1/g1GCPhaseTimes.hpp" @@ -228,12 +229,15 @@ }; void G1RemSet::scanRS(G1ParPushHeapRSClosure* oc, - CodeBlobClosure* code_root_cl, + OopClosure* non_heap_roots, uint worker_i) { double rs_time_start = os::elapsedTime(); + + G1CodeBlobClosure code_root_cl(non_heap_roots); + HeapRegion *startRegion = _g1->start_cset_region_for_worker(worker_i); - ScanRSClosure scanRScl(oc, code_root_cl, worker_i); + ScanRSClosure scanRScl(oc, &code_root_cl, worker_i); _g1->collection_set_iterate_from(startRegion, &scanRScl); scanRScl.set_try_claimed(); @@ -295,7 +299,7 @@ } void G1RemSet::oops_into_collection_set_do(G1ParPushHeapRSClosure* oc, - CodeBlobClosure* code_root_cl, + OopClosure* non_heap_roots, uint worker_i) { #if CARD_REPEAT_HISTO ct_freq_update_histo_and_reset(); @@ -318,7 +322,7 @@ DirtyCardQueue into_cset_dcq(&_g1->into_cset_dirty_card_queue_set()); updateRS(&into_cset_dcq, worker_i); - scanRS(oc, code_root_cl, worker_i); + scanRS(oc, non_heap_roots, worker_i); // We now clear the cached values of _cset_rs_update_cl for this worker _cset_rs_update_cl[worker_i] = NULL; diff -r 1fb9e9f01532 -r ceb9d9044fc8 src/share/vm/gc/g1/g1RemSet.hpp --- a/src/share/vm/gc/g1/g1RemSet.hpp Fri Sep 04 08:36:13 2015 +0200 +++ b/src/share/vm/gc/g1/g1RemSet.hpp Fri Sep 04 09:47:35 2015 +0200 @@ -85,7 +85,7 @@ // invoked "blk->set_region" to set the "from" region correctly // beforehand.) // - // Invoke code_root_cl->do_code_blob on the unmarked nmethods + // Apply non_heap_roots on the oops of the unmarked nmethods // on the strong code roots list for each region in the // collection set. // @@ -95,7 +95,7 @@ // the "i" passed to the calling thread's work(i) function. // In the sequential case this param will be ignored. void oops_into_collection_set_do(G1ParPushHeapRSClosure* blk, - CodeBlobClosure* code_root_cl, + OopClosure* non_heap_roots, uint worker_i); // Prepare for and cleanup after an oops_into_collection_set_do @@ -107,7 +107,7 @@ void cleanup_after_oops_into_collection_set_do(); void scanRS(G1ParPushHeapRSClosure* oc, - CodeBlobClosure* code_root_cl, + OopClosure* non_heap_roots, uint worker_i); void updateRS(DirtyCardQueue* into_cset_dcq, uint worker_i); diff -r 1fb9e9f01532 -r ceb9d9044fc8 src/share/vm/gc/g1/g1RootProcessor.cpp --- a/src/share/vm/gc/g1/g1RootProcessor.cpp Fri Sep 04 08:36:13 2015 +0200 +++ b/src/share/vm/gc/g1/g1RootProcessor.cpp Fri Sep 04 09:47:35 2015 +0200 @@ -28,6 +28,7 @@ #include "classfile/systemDictionary.hpp" #include "code/codeCache.hpp" #include "gc/g1/bufferingOopClosure.hpp" +#include "gc/g1/g1CodeBlobClosure.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectorPolicy.hpp" #include "gc/g1/g1CollectorState.hpp" @@ -40,57 +41,6 @@ #include "runtime/mutex.hpp" #include "services/management.hpp" -class G1CodeBlobClosure : public CodeBlobClosure { - class HeapRegionGatheringOopClosure : public OopClosure { - G1CollectedHeap* _g1h; - OopClosure* _work; - nmethod* _nm; - - template - void do_oop_work(T* p) { - _work->do_oop(p); - T oop_or_narrowoop = oopDesc::load_heap_oop(p); - if (!oopDesc::is_null(oop_or_narrowoop)) { - oop o = oopDesc::decode_heap_oop_not_null(oop_or_narrowoop); - HeapRegion* hr = _g1h->heap_region_containing_raw(o); - assert(!_g1h->obj_in_cs(o) || hr->rem_set()->strong_code_roots_list_contains(_nm), "if o still in CS then evacuation failed and nm must already be in the remset"); - hr->add_strong_code_root(_nm); - } - } - - public: - HeapRegionGatheringOopClosure(OopClosure* oc) : _g1h(G1CollectedHeap::heap()), _work(oc), _nm(NULL) {} - - void do_oop(oop* o) { - do_oop_work(o); - } - - void do_oop(narrowOop* o) { - do_oop_work(o); - } - - void set_nm(nmethod* nm) { - _nm = nm; - } - }; - - HeapRegionGatheringOopClosure _oc; -public: - G1CodeBlobClosure(OopClosure* oc) : _oc(oc) {} - - void do_code_blob(CodeBlob* cb) { - nmethod* nm = cb->as_nmethod_or_null(); - if (nm != NULL) { - if (!nm->test_set_oops_do_mark()) { - _oc.set_nm(nm); - nm->oops_do(&_oc); - nm->fix_oop_relocations(); - } - } - } -}; - - void G1RootProcessor::worker_has_discovered_all_strong_classes() { assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading"); @@ -321,14 +271,6 @@ } } -void G1RootProcessor::scan_remembered_sets(G1ParPushHeapRSClosure* scan_rs, - OopClosure* scan_non_heap_weak_roots, - uint worker_i) { - G1CodeBlobClosure scavenge_cs_nmethods(scan_non_heap_weak_roots); - - _g1h->g1_rem_set()->oops_into_collection_set_do(scan_rs, &scavenge_cs_nmethods, worker_i); -} - uint G1RootProcessor::n_workers() const { return _srs.n_threads(); } diff -r 1fb9e9f01532 -r ceb9d9044fc8 src/share/vm/gc/g1/g1RootProcessor.hpp --- a/src/share/vm/gc/g1/g1RootProcessor.hpp Fri Sep 04 08:36:13 2015 +0200 +++ b/src/share/vm/gc/g1/g1RootProcessor.hpp Fri Sep 04 09:47:35 2015 +0200 @@ -107,13 +107,6 @@ CLDClosure* clds, CodeBlobClosure* blobs); - // Apply scan_rs to all locations in the union of the remembered sets for all - // regions in the collection set - // (having done "set_region" to indicate the region in which the root resides), - void scan_remembered_sets(G1ParPushHeapRSClosure* scan_rs, - OopClosure* scan_non_heap_weak_roots, - uint worker_i); - // Number of worker threads used by the root processor. uint n_workers() const; };