annotate src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp @ 5188:5afc5a089c2c

8014555: G1: Memory ordering problem with Conc refinement and card marking Summary: Add a StoreLoad barrier in the G1 post-barrier to fix a race with concurrent refinement. Reviewed-by: brutisso, tschatzl, roland
author mgerdin
date Tue, 08 Oct 2013 17:35:51 +0200
parents eacc90e71427
children 5d0a13adec23
rev   line source
ysr@345 1 /*
johnc@2488 2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
ysr@345 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ysr@345 4 *
ysr@345 5 * This code is free software; you can redistribute it and/or modify it
ysr@345 6 * under the terms of the GNU General Public License version 2 only, as
ysr@345 7 * published by the Free Software Foundation.
ysr@345 8 *
ysr@345 9 * This code is distributed in the hope that it will be useful, but WITHOUT
ysr@345 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ysr@345 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ysr@345 12 * version 2 for more details (a copy is included in the LICENSE file that
ysr@345 13 * accompanied this code).
ysr@345 14 *
ysr@345 15 * You should have received a copy of the GNU General Public License version
ysr@345 16 * 2 along with this work; if not, write to the Free Software Foundation,
ysr@345 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ysr@345 18 *
trims@1563 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1563 20 * or visit www.oracle.com if you need additional information or have any
trims@1563 21 * questions.
ysr@345 22 *
ysr@345 23 */
ysr@345 24
stefank@1992 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1SATBCARDTABLEMODREFBS_HPP
stefank@1992 26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1SATBCARDTABLEMODREFBS_HPP
stefank@1992 27
stefank@1992 28 #include "memory/cardTableModRefBS.hpp"
stefank@1992 29 #include "memory/memRegion.hpp"
stefank@1992 30 #include "oops/oop.inline.hpp"
stefank@1992 31
ysr@345 32 #ifndef SERIALGC
ysr@345 33
ysr@345 34 class DirtyCardQueueSet;
ysr@345 35
ysr@345 36 // This barrier is specialized to use a logging barrier to support
ysr@345 37 // snapshot-at-the-beginning marking.
ysr@345 38
ysr@345 39 class G1SATBCardTableModRefBS: public CardTableModRefBSForCTRS {
mgerdin@5188 40 protected:
mgerdin@5188 41 enum G1CardValues {
mgerdin@5188 42 g1_young_gen = CT_MR_BS_last_reserved << 1
mgerdin@5188 43 };
mgerdin@5188 44
johnc@2488 45 public:
mgerdin@5188 46 static int g1_young_card_val() { return g1_young_gen; }
mgerdin@5188 47
ysr@345 48 // Add "pre_val" to a set of objects that may have been disconnected from the
ysr@345 49 // pre-marking object graph.
ysr@345 50 static void enqueue(oop pre_val);
ysr@345 51
ysr@345 52 G1SATBCardTableModRefBS(MemRegion whole_heap,
ysr@345 53 int max_covered_regions);
ysr@345 54
ysr@345 55 bool is_a(BarrierSet::Name bsn) {
ysr@345 56 return bsn == BarrierSet::G1SATBCT || CardTableModRefBS::is_a(bsn);
ysr@345 57 }
ysr@345 58
ysr@345 59 virtual bool has_write_ref_pre_barrier() { return true; }
ysr@345 60
ysr@345 61 // This notes that we don't need to access any BarrierSet data
ysr@345 62 // structures, so this can be called from a static context.
ysr@896 63 template <class T> static void write_ref_field_pre_static(T* field, oop newVal) {
ysr@896 64 T heap_oop = oopDesc::load_heap_oop(field);
ysr@896 65 if (!oopDesc::is_null(heap_oop)) {
ysr@896 66 enqueue(oopDesc::decode_heap_oop(heap_oop));
ysr@345 67 }
ysr@345 68 }
ysr@345 69
ysr@345 70 // We export this to make it available in cases where the static
ysr@345 71 // type of the barrier set is known. Note that it is non-virtual.
ysr@896 72 template <class T> inline void inline_write_ref_field_pre(T* field, oop newVal) {
ysr@345 73 write_ref_field_pre_static(field, newVal);
ysr@345 74 }
ysr@345 75
ysr@896 76 // These are the more general virtual versions.
ysr@896 77 virtual void write_ref_field_pre_work(oop* field, oop new_val) {
ysr@345 78 inline_write_ref_field_pre(field, new_val);
ysr@345 79 }
ysr@896 80 virtual void write_ref_field_pre_work(narrowOop* field, oop new_val) {
ysr@896 81 inline_write_ref_field_pre(field, new_val);
ysr@896 82 }
ysr@896 83 virtual void write_ref_field_pre_work(void* field, oop new_val) {
ysr@896 84 guarantee(false, "Not needed");
ysr@896 85 }
ysr@345 86
ysr@896 87 template <class T> void write_ref_array_pre_work(T* dst, int count);
iveresov@2303 88 virtual void write_ref_array_pre(oop* dst, int count, bool dest_uninitialized) {
iveresov@2303 89 if (!dest_uninitialized) {
iveresov@2303 90 write_ref_array_pre_work(dst, count);
iveresov@2303 91 }
ysr@896 92 }
iveresov@2303 93 virtual void write_ref_array_pre(narrowOop* dst, int count, bool dest_uninitialized) {
iveresov@2303 94 if (!dest_uninitialized) {
iveresov@2303 95 write_ref_array_pre_work(dst, count);
iveresov@2303 96 }
ysr@896 97 }
mgerdin@5187 98
mgerdin@5187 99 /*
mgerdin@5187 100 Claimed and deferred bits are used together in G1 during the evacuation
mgerdin@5187 101 pause. These bits can have the following state transitions:
mgerdin@5187 102 1. The claimed bit can be put over any other card state. Except that
mgerdin@5187 103 the "dirty -> dirty and claimed" transition is checked for in
mgerdin@5187 104 G1 code and is not used.
mgerdin@5187 105 2. Deferred bit can be set only if the previous state of the card
mgerdin@5187 106 was either clean or claimed. mark_card_deferred() is wait-free.
mgerdin@5187 107 We do not care if the operation is be successful because if
mgerdin@5187 108 it does not it will only result in duplicate entry in the update
mgerdin@5187 109 buffer because of the "cache-miss". So it's not worth spinning.
mgerdin@5187 110 */
mgerdin@5187 111
mgerdin@5187 112 bool is_card_claimed(size_t card_index) {
mgerdin@5187 113 jbyte val = _byte_map[card_index];
mgerdin@5187 114 return (val & (clean_card_mask_val() | claimed_card_val())) == claimed_card_val();
mgerdin@5187 115 }
mgerdin@5187 116
mgerdin@5187 117 void set_card_claimed(size_t card_index) {
mgerdin@5187 118 jbyte val = _byte_map[card_index];
mgerdin@5187 119 if (val == clean_card_val()) {
mgerdin@5187 120 val = (jbyte)claimed_card_val();
mgerdin@5187 121 } else {
mgerdin@5187 122 val |= (jbyte)claimed_card_val();
mgerdin@5187 123 }
mgerdin@5187 124 _byte_map[card_index] = val;
mgerdin@5187 125 }
mgerdin@5187 126
mgerdin@5188 127 void verify_g1_young_region(MemRegion mr) PRODUCT_RETURN;
mgerdin@5188 128 void g1_mark_as_young(const MemRegion& mr);
mgerdin@5188 129
mgerdin@5187 130 bool mark_card_deferred(size_t card_index);
mgerdin@5187 131
mgerdin@5187 132 bool is_card_deferred(size_t card_index) {
mgerdin@5187 133 jbyte val = _byte_map[card_index];
mgerdin@5187 134 return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val();
mgerdin@5187 135 }
mgerdin@5187 136
ysr@345 137 };
ysr@345 138
ysr@345 139 // Adds card-table logging to the post-barrier.
ysr@345 140 // Usual invariant: all dirty cards are logged in the DirtyCardQueueSet.
ysr@345 141 class G1SATBCardTableLoggingModRefBS: public G1SATBCardTableModRefBS {
ysr@345 142 private:
ysr@345 143 DirtyCardQueueSet& _dcqs;
ysr@345 144 public:
ysr@345 145 G1SATBCardTableLoggingModRefBS(MemRegion whole_heap,
ysr@345 146 int max_covered_regions);
ysr@345 147
ysr@345 148 bool is_a(BarrierSet::Name bsn) {
ysr@345 149 return bsn == BarrierSet::G1SATBCTLogging ||
ysr@345 150 G1SATBCardTableModRefBS::is_a(bsn);
ysr@345 151 }
ysr@345 152
ysr@345 153 void write_ref_field_work(void* field, oop new_val);
ysr@345 154
ysr@345 155 // Can be called from static contexts.
ysr@345 156 static void write_ref_field_static(void* field, oop new_val);
ysr@345 157
ysr@345 158 // NB: if you do a whole-heap invalidation, the "usual invariant" defined
ysr@345 159 // above no longer applies.
ysr@345 160 void invalidate(MemRegion mr, bool whole_heap = false);
ysr@345 161
ysr@345 162 void write_region_work(MemRegion mr) { invalidate(mr); }
ysr@345 163 void write_ref_array_work(MemRegion mr) { invalidate(mr); }
ysr@345 164
ysr@345 165
ysr@345 166 };
ysr@345 167
ysr@345 168
ysr@345 169 #endif // SERIALGC
stefank@1992 170
stefank@1992 171 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1SATBCARDTABLEMODREFBS_HPP