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

Thu, 07 Apr 2011 09:53:20 -0700

author
johnc
date
Thu, 07 Apr 2011 09:53:20 -0700
changeset 2781
e1162778c1c8
parent 2606
0ac769a57c64
child 2784
92add02409c9
permissions
-rw-r--r--

7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer.
Reviewed-by: kvn, iveresov, never, tonyp, dholmes

ysr@777 1 /*
johnc@2781 2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. 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 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
ysr@777 22 *
ysr@777 23 */
ysr@777 24
stefank@2314 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1SATBCARDTABLEMODREFBS_HPP
stefank@2314 26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1SATBCARDTABLEMODREFBS_HPP
stefank@2314 27
stefank@2314 28 #include "memory/cardTableModRefBS.hpp"
stefank@2314 29 #include "memory/memRegion.hpp"
stefank@2314 30 #include "oops/oop.inline.hpp"
stefank@2314 31
ysr@777 32 #ifndef SERIALGC
ysr@777 33
ysr@777 34 class DirtyCardQueueSet;
ysr@777 35
ysr@777 36 // This barrier is specialized to use a logging barrier to support
ysr@777 37 // snapshot-at-the-beginning marking.
ysr@777 38
ysr@777 39 class G1SATBCardTableModRefBS: public CardTableModRefBSForCTRS {
johnc@2781 40 public:
ysr@777 41 // Add "pre_val" to a set of objects that may have been disconnected from the
ysr@777 42 // pre-marking object graph.
ysr@777 43 static void enqueue(oop pre_val);
ysr@777 44
ysr@777 45 G1SATBCardTableModRefBS(MemRegion whole_heap,
ysr@777 46 int max_covered_regions);
ysr@777 47
ysr@777 48 bool is_a(BarrierSet::Name bsn) {
ysr@777 49 return bsn == BarrierSet::G1SATBCT || CardTableModRefBS::is_a(bsn);
ysr@777 50 }
ysr@777 51
ysr@777 52 virtual bool has_write_ref_pre_barrier() { return true; }
ysr@777 53
ysr@777 54 // This notes that we don't need to access any BarrierSet data
ysr@777 55 // structures, so this can be called from a static context.
ysr@1280 56 template <class T> static void write_ref_field_pre_static(T* field, oop newVal) {
ysr@1280 57 T heap_oop = oopDesc::load_heap_oop(field);
ysr@1280 58 if (!oopDesc::is_null(heap_oop)) {
ysr@1280 59 enqueue(oopDesc::decode_heap_oop(heap_oop));
ysr@777 60 }
ysr@777 61 }
ysr@777 62
ysr@777 63 // We export this to make it available in cases where the static
ysr@777 64 // type of the barrier set is known. Note that it is non-virtual.
ysr@1280 65 template <class T> inline void inline_write_ref_field_pre(T* field, oop newVal) {
ysr@777 66 write_ref_field_pre_static(field, newVal);
ysr@777 67 }
ysr@777 68
ysr@1280 69 // These are the more general virtual versions.
ysr@1280 70 virtual void write_ref_field_pre_work(oop* field, oop new_val) {
ysr@777 71 inline_write_ref_field_pre(field, new_val);
ysr@777 72 }
ysr@1280 73 virtual void write_ref_field_pre_work(narrowOop* field, oop new_val) {
ysr@1280 74 inline_write_ref_field_pre(field, new_val);
ysr@1280 75 }
ysr@1280 76 virtual void write_ref_field_pre_work(void* field, oop new_val) {
ysr@1280 77 guarantee(false, "Not needed");
ysr@1280 78 }
ysr@777 79
ysr@1280 80 template <class T> void write_ref_array_pre_work(T* dst, int count);
iveresov@2606 81 virtual void write_ref_array_pre(oop* dst, int count, bool dest_uninitialized) {
iveresov@2606 82 if (!dest_uninitialized) {
iveresov@2606 83 write_ref_array_pre_work(dst, count);
iveresov@2606 84 }
ysr@1280 85 }
iveresov@2606 86 virtual void write_ref_array_pre(narrowOop* dst, int count, bool dest_uninitialized) {
iveresov@2606 87 if (!dest_uninitialized) {
iveresov@2606 88 write_ref_array_pre_work(dst, count);
iveresov@2606 89 }
ysr@1280 90 }
ysr@777 91 };
ysr@777 92
ysr@777 93 // Adds card-table logging to the post-barrier.
ysr@777 94 // Usual invariant: all dirty cards are logged in the DirtyCardQueueSet.
ysr@777 95 class G1SATBCardTableLoggingModRefBS: public G1SATBCardTableModRefBS {
ysr@777 96 private:
ysr@777 97 DirtyCardQueueSet& _dcqs;
ysr@777 98 public:
ysr@777 99 G1SATBCardTableLoggingModRefBS(MemRegion whole_heap,
ysr@777 100 int max_covered_regions);
ysr@777 101
ysr@777 102 bool is_a(BarrierSet::Name bsn) {
ysr@777 103 return bsn == BarrierSet::G1SATBCTLogging ||
ysr@777 104 G1SATBCardTableModRefBS::is_a(bsn);
ysr@777 105 }
ysr@777 106
ysr@777 107 void write_ref_field_work(void* field, oop new_val);
ysr@777 108
ysr@777 109 // Can be called from static contexts.
ysr@777 110 static void write_ref_field_static(void* field, oop new_val);
ysr@777 111
ysr@777 112 // NB: if you do a whole-heap invalidation, the "usual invariant" defined
ysr@777 113 // above no longer applies.
ysr@777 114 void invalidate(MemRegion mr, bool whole_heap = false);
ysr@777 115
ysr@777 116 void write_region_work(MemRegion mr) { invalidate(mr); }
ysr@777 117 void write_ref_array_work(MemRegion mr) { invalidate(mr); }
ysr@777 118
ysr@777 119
ysr@777 120 };
ysr@777 121
ysr@777 122
ysr@777 123 #endif // SERIALGC
stefank@2314 124
stefank@2314 125 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1SATBCARDTABLEMODREFBS_HPP

mercurial