src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp

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 1752
d4197f8d516a
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 #include "incls/_precompiled.incl"
ysr@777 26 #include "incls/_g1SATBCardTableModRefBS.cpp.incl"
ysr@777 27
ysr@777 28 G1SATBCardTableModRefBS::G1SATBCardTableModRefBS(MemRegion whole_heap,
ysr@777 29 int max_covered_regions) :
ysr@777 30 CardTableModRefBSForCTRS(whole_heap, max_covered_regions)
ysr@777 31 {
ysr@777 32 _kind = G1SATBCT;
ysr@777 33 }
ysr@777 34
ysr@777 35
ysr@777 36 void G1SATBCardTableModRefBS::enqueue(oop pre_val) {
ysr@1280 37 assert(pre_val->is_oop_or_null(true), "Error");
ysr@777 38 if (!JavaThread::satb_mark_queue_set().active()) return;
ysr@777 39 Thread* thr = Thread::current();
ysr@777 40 if (thr->is_Java_thread()) {
ysr@777 41 JavaThread* jt = (JavaThread*)thr;
ysr@777 42 jt->satb_mark_queue().enqueue(pre_val);
ysr@777 43 } else {
ysr@777 44 MutexLocker x(Shared_SATB_Q_lock);
ysr@777 45 JavaThread::satb_mark_queue_set().shared_satb_queue()->enqueue(pre_val);
ysr@777 46 }
ysr@777 47 }
ysr@777 48
ysr@777 49 // When we know the current java thread:
ysr@1280 50 template <class T> void
ysr@1280 51 G1SATBCardTableModRefBS::write_ref_field_pre_static(T* field,
ysr@1280 52 oop new_val,
ysr@777 53 JavaThread* jt) {
ysr@777 54 if (!JavaThread::satb_mark_queue_set().active()) return;
ysr@1280 55 T heap_oop = oopDesc::load_heap_oop(field);
ysr@1280 56 if (!oopDesc::is_null(heap_oop)) {
ysr@1280 57 oop pre_val = oopDesc::decode_heap_oop_not_null(heap_oop);
ysr@1280 58 assert(pre_val->is_oop(true /* ignore mark word */), "Error");
ysr@1280 59 jt->satb_mark_queue().enqueue(pre_val);
ysr@777 60 }
ysr@777 61 }
ysr@777 62
ysr@1280 63 template <class T> void
ysr@1280 64 G1SATBCardTableModRefBS::write_ref_array_pre_work(T* dst, int count) {
ysr@777 65 if (!JavaThread::satb_mark_queue_set().active()) return;
ysr@1280 66 T* elem_ptr = dst;
ysr@1280 67 for (int i = 0; i < count; i++, elem_ptr++) {
ysr@1280 68 T heap_oop = oopDesc::load_heap_oop(elem_ptr);
ysr@1280 69 if (!oopDesc::is_null(heap_oop)) {
ysr@1280 70 enqueue(oopDesc::decode_heap_oop_not_null(heap_oop));
ysr@1280 71 }
ysr@777 72 }
ysr@777 73 }
ysr@777 74
ysr@777 75 G1SATBCardTableLoggingModRefBS::
ysr@777 76 G1SATBCardTableLoggingModRefBS(MemRegion whole_heap,
ysr@777 77 int max_covered_regions) :
ysr@777 78 G1SATBCardTableModRefBS(whole_heap, max_covered_regions),
ysr@777 79 _dcqs(JavaThread::dirty_card_queue_set())
ysr@777 80 {
ysr@777 81 _kind = G1SATBCTLogging;
ysr@777 82 }
ysr@777 83
ysr@777 84 void
ysr@777 85 G1SATBCardTableLoggingModRefBS::write_ref_field_work(void* field,
ysr@777 86 oop new_val) {
ysr@777 87 jbyte* byte = byte_for(field);
ysr@777 88 if (*byte != dirty_card) {
ysr@777 89 *byte = dirty_card;
ysr@777 90 Thread* thr = Thread::current();
ysr@777 91 if (thr->is_Java_thread()) {
ysr@777 92 JavaThread* jt = (JavaThread*)thr;
ysr@777 93 jt->dirty_card_queue().enqueue(byte);
ysr@777 94 } else {
ysr@777 95 MutexLockerEx x(Shared_DirtyCardQ_lock,
ysr@777 96 Mutex::_no_safepoint_check_flag);
ysr@777 97 _dcqs.shared_dirty_card_queue()->enqueue(byte);
ysr@777 98 }
ysr@777 99 }
ysr@777 100 }
ysr@777 101
ysr@777 102 void
ysr@777 103 G1SATBCardTableLoggingModRefBS::write_ref_field_static(void* field,
ysr@777 104 oop new_val) {
ysr@777 105 uintptr_t field_uint = (uintptr_t)field;
ysr@777 106 uintptr_t new_val_uint = (uintptr_t)new_val;
ysr@777 107 uintptr_t comb = field_uint ^ new_val_uint;
ysr@777 108 comb = comb >> HeapRegion::LogOfHRGrainBytes;
ysr@777 109 if (comb == 0) return;
ysr@777 110 if (new_val == NULL) return;
ysr@777 111 // Otherwise, log it.
ysr@777 112 G1SATBCardTableLoggingModRefBS* g1_bs =
ysr@777 113 (G1SATBCardTableLoggingModRefBS*)Universe::heap()->barrier_set();
ysr@777 114 g1_bs->write_ref_field_work(field, new_val);
ysr@777 115 }
ysr@777 116
ysr@777 117 void
ysr@777 118 G1SATBCardTableLoggingModRefBS::invalidate(MemRegion mr, bool whole_heap) {
ysr@777 119 jbyte* byte = byte_for(mr.start());
ysr@777 120 jbyte* last_byte = byte_for(mr.last());
ysr@777 121 Thread* thr = Thread::current();
ysr@777 122 if (whole_heap) {
ysr@777 123 while (byte <= last_byte) {
ysr@777 124 *byte = dirty_card;
ysr@777 125 byte++;
ysr@777 126 }
ysr@777 127 } else {
ysr@777 128 // Enqueue if necessary.
ysr@777 129 if (thr->is_Java_thread()) {
ysr@777 130 JavaThread* jt = (JavaThread*)thr;
ysr@777 131 while (byte <= last_byte) {
ysr@777 132 if (*byte != dirty_card) {
ysr@777 133 *byte = dirty_card;
ysr@777 134 jt->dirty_card_queue().enqueue(byte);
ysr@777 135 }
ysr@777 136 byte++;
ysr@777 137 }
ysr@777 138 } else {
ysr@777 139 MutexLockerEx x(Shared_DirtyCardQ_lock,
ysr@777 140 Mutex::_no_safepoint_check_flag);
ysr@777 141 while (byte <= last_byte) {
ysr@777 142 if (*byte != dirty_card) {
ysr@777 143 *byte = dirty_card;
ysr@777 144 _dcqs.shared_dirty_card_queue()->enqueue(byte);
ysr@777 145 }
ysr@777 146 byte++;
ysr@777 147 }
ysr@777 148 }
ysr@777 149 }
ysr@777 150 }

mercurial