src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp

Mon, 03 Aug 2009 12:59:30 -0700

author
johnc
date
Mon, 03 Aug 2009 12:59:30 -0700
changeset 1324
15c5903cf9e1
parent 1280
df6caf649ff7
child 1696
0414c1049f15
permissions
-rw-r--r--

6865703: G1: Parallelize hot card cache cleanup
Summary: Have the GC worker threads clear the hot card cache in parallel by having each worker thread claim a chunk of the card cache and process the cards in that chunk. The size of the chunks that each thread will claim is determined at VM initialization from the size of the card cache and the number of worker threads.
Reviewed-by: jmasa, tonyp

ysr@777 1 /*
ysr@777 2 * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
ysr@777 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ysr@777 4 *
ysr@777 5 * This code is free software; you can redistribute it and/or modify it
ysr@777 6 * under the terms of the GNU General Public License version 2 only, as
ysr@777 7 * published by the Free Software Foundation.
ysr@777 8 *
ysr@777 9 * This code is distributed in the hope that it will be useful, but WITHOUT
ysr@777 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ysr@777 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ysr@777 12 * version 2 for more details (a copy is included in the LICENSE file that
ysr@777 13 * accompanied this code).
ysr@777 14 *
ysr@777 15 * You should have received a copy of the GNU General Public License version
ysr@777 16 * 2 along with this work; if not, write to the Free Software Foundation,
ysr@777 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ysr@777 18 *
ysr@777 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
ysr@777 20 * CA 95054 USA or visit www.sun.com if you need additional information or
ysr@777 21 * have any questions.
ysr@777 22 *
ysr@777 23 */
ysr@777 24
ysr@777 25 /*
ysr@777 26 * This really ought to be an inline function, but apparently the C++
ysr@777 27 * compiler sometimes sees fit to ignore inline declarations. Sigh.
ysr@777 28 */
ysr@777 29
ysr@777 30 // This must a ifdef'ed because the counting it controls is in a
ysr@777 31 // perf-critical inner loop.
ysr@777 32 #define FILTERINTOCSCLOSURE_DOHISTOGRAMCOUNT 0
ysr@777 33
ysr@1280 34 template <class T> inline void FilterIntoCSClosure::do_oop_nv(T* p) {
ysr@1280 35 T heap_oop = oopDesc::load_heap_oop(p);
ysr@1280 36 if (!oopDesc::is_null(heap_oop) &&
ysr@1280 37 _g1->obj_in_cs(oopDesc::decode_heap_oop_not_null(heap_oop))) {
ysr@777 38 _oc->do_oop(p);
ysr@777 39 #if FILTERINTOCSCLOSURE_DOHISTOGRAMCOUNT
ysr@777 40 _dcto_cl->incr_count();
ysr@777 41 #endif
ysr@777 42 }
ysr@777 43 }
ysr@777 44
ysr@777 45 #define FILTEROUTOFREGIONCLOSURE_DOHISTOGRAMCOUNT 0
ysr@777 46
ysr@1280 47 template <class T> inline void FilterOutOfRegionClosure::do_oop_nv(T* p) {
ysr@1280 48 T heap_oop = oopDesc::load_heap_oop(p);
ysr@1280 49 if (!oopDesc::is_null(heap_oop)) {
ysr@1280 50 HeapWord* obj_hw = (HeapWord*)oopDesc::decode_heap_oop_not_null(heap_oop);
ysr@1280 51 if (obj_hw < _r_bottom || obj_hw >= _r_end) {
ysr@1280 52 _oc->do_oop(p);
ysr@777 53 #if FILTEROUTOFREGIONCLOSURE_DOHISTOGRAMCOUNT
ysr@1280 54 _out_of_region++;
ysr@777 55 #endif
ysr@1280 56 }
ysr@777 57 }
ysr@777 58 }
ysr@777 59
ysr@1280 60 template <class T> inline void FilterInHeapRegionAndIntoCSClosure::do_oop_nv(T* p) {
ysr@1280 61 T heap_oop = oopDesc::load_heap_oop(p);
ysr@1280 62 if (!oopDesc::is_null(heap_oop) &&
ysr@1280 63 _g1->obj_in_cs(oopDesc::decode_heap_oop_not_null(heap_oop)))
ysr@777 64 _oc->do_oop(p);
ysr@777 65 }
ysr@777 66
ysr@1280 67 template <class T> inline void FilterAndMarkInHeapRegionAndIntoCSClosure::do_oop_nv(T* p) {
ysr@1280 68 T heap_oop = oopDesc::load_heap_oop(p);
ysr@1280 69 if (!oopDesc::is_null(heap_oop)) {
ysr@1280 70 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
ysr@777 71 HeapRegion* hr = _g1->heap_region_containing((HeapWord*) obj);
ysr@777 72 if (hr != NULL) {
ysr@777 73 if (hr->in_collection_set())
ysr@777 74 _oc->do_oop(p);
ysr@777 75 else if (!hr->is_young())
ysr@777 76 _cm->grayRoot(obj);
ysr@777 77 }
ysr@777 78 }
ysr@777 79 }
ysr@777 80
ysr@1280 81 // This closure is applied to the fields of the objects that have just been copied.
ysr@1280 82 template <class T> inline void G1ParScanClosure::do_oop_nv(T* p) {
ysr@1280 83 T heap_oop = oopDesc::load_heap_oop(p);
ysr@1280 84
ysr@1280 85 if (!oopDesc::is_null(heap_oop)) {
ysr@1280 86 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
ysr@1280 87 if (_g1->in_cset_fast_test(obj)) {
ysr@1280 88 // We're not going to even bother checking whether the object is
ysr@1280 89 // already forwarded or not, as this usually causes an immediate
ysr@1280 90 // stall. We'll try to prefetch the object (for write, given that
ysr@1280 91 // we might need to install the forwarding reference) and we'll
ysr@1280 92 // get back to it when pop it from the queue
ysr@1280 93 Prefetch::write(obj->mark_addr(), 0);
ysr@1280 94 Prefetch::read(obj->mark_addr(), (HeapWordSize*2));
ysr@1280 95
ysr@1280 96 // slightly paranoid test; I'm trying to catch potential
ysr@1280 97 // problems before we go into push_on_queue to know where the
ysr@1280 98 // problem is coming from
ysr@1280 99 assert(obj == oopDesc::load_decode_heap_oop(p),
ysr@1280 100 "p should still be pointing to obj");
ysr@1280 101 _par_scan_state->push_on_queue(p);
ysr@1280 102 } else {
ysr@1280 103 _par_scan_state->update_rs(_from, p, _par_scan_state->queue_num());
ysr@1280 104 }
ysr@1280 105 }
ysr@777 106 }

mercurial