annotate src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp @ 364:919e7959392a

6742641: G1: NullPointerException during GCOld Summary: An update buffer is not processed correctly, which causes roots into the collection set not to be scanned and, hence, for the heap to be corrupted. The cause is that an object is accessed after it has been explicitly deleted, which causes a race. Reviewed-by: jcoomes, ysr
author tonyp
date Mon, 22 Sep 2008 09:56:49 -0400
parents 37f87013dfd8
children df6caf649ff7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
1 /*
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
2 * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
4 *
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
7 * published by the Free Software Foundation.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
8 *
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
13 * accompanied this code).
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
14 *
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
18 *
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
21 * have any questions.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
22 *
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
23 */
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
24
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
25 #include "incls/_precompiled.incl"
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
26 #include "incls/_g1SATBCardTableModRefBS.cpp.incl"
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
27
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
28 G1SATBCardTableModRefBS::G1SATBCardTableModRefBS(MemRegion whole_heap,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
29 int max_covered_regions) :
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
30 CardTableModRefBSForCTRS(whole_heap, max_covered_regions)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
31 {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
32 _kind = G1SATBCT;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
33 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
34
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
35
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
36 void G1SATBCardTableModRefBS::enqueue(oop pre_val) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
37 if (!JavaThread::satb_mark_queue_set().active()) return;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
38 Thread* thr = Thread::current();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
39 if (thr->is_Java_thread()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
40 JavaThread* jt = (JavaThread*)thr;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
41 jt->satb_mark_queue().enqueue(pre_val);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
42 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
43 MutexLocker x(Shared_SATB_Q_lock);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
44 JavaThread::satb_mark_queue_set().shared_satb_queue()->enqueue(pre_val);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
45 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
46 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
47
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
48 // When we know the current java thread:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
49 void
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
50 G1SATBCardTableModRefBS::write_ref_field_pre_static(void* field,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
51 oop newVal,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
52 JavaThread* jt) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
53 if (!JavaThread::satb_mark_queue_set().active()) return;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
54 assert(!UseCompressedOops, "Else will need to modify this to deal with narrowOop");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
55 oop preVal = *(oop*)field;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
56 if (preVal != NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
57 jt->satb_mark_queue().enqueue(preVal);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
58 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
59 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
60
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
61 void
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
62 G1SATBCardTableModRefBS::write_ref_array_pre(MemRegion mr) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
63 if (!JavaThread::satb_mark_queue_set().active()) return;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
64 assert(!UseCompressedOops, "Else will need to modify this to deal with narrowOop");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
65 oop* elem_ptr = (oop*)mr.start();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
66 while ((HeapWord*)elem_ptr < mr.end()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
67 oop elem = *elem_ptr;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
68 if (elem != NULL) enqueue(elem);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
69 elem_ptr++;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
70 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
71 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
72
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
73
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
74
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
75 G1SATBCardTableLoggingModRefBS::
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
76 G1SATBCardTableLoggingModRefBS(MemRegion whole_heap,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
77 int max_covered_regions) :
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
78 G1SATBCardTableModRefBS(whole_heap, max_covered_regions),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
79 _dcqs(JavaThread::dirty_card_queue_set())
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
80 {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
81 _kind = G1SATBCTLogging;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
82 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
83
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
84 void
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
85 G1SATBCardTableLoggingModRefBS::write_ref_field_work(void* field,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
86 oop new_val) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
87 jbyte* byte = byte_for(field);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
88 if (*byte != dirty_card) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
89 *byte = dirty_card;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
90 Thread* thr = Thread::current();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
91 if (thr->is_Java_thread()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
92 JavaThread* jt = (JavaThread*)thr;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
93 jt->dirty_card_queue().enqueue(byte);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
94 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
95 MutexLockerEx x(Shared_DirtyCardQ_lock,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
96 Mutex::_no_safepoint_check_flag);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
97 _dcqs.shared_dirty_card_queue()->enqueue(byte);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
98 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
99 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
100 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
101
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
102 void
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
103 G1SATBCardTableLoggingModRefBS::write_ref_field_static(void* field,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
104 oop new_val) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
105 uintptr_t field_uint = (uintptr_t)field;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
106 uintptr_t new_val_uint = (uintptr_t)new_val;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
107 uintptr_t comb = field_uint ^ new_val_uint;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
108 comb = comb >> HeapRegion::LogOfHRGrainBytes;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
109 if (comb == 0) return;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
110 if (new_val == NULL) return;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
111 // Otherwise, log it.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
112 G1SATBCardTableLoggingModRefBS* g1_bs =
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
113 (G1SATBCardTableLoggingModRefBS*)Universe::heap()->barrier_set();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
114 g1_bs->write_ref_field_work(field, new_val);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
115 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
116
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
117 void
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
118 G1SATBCardTableLoggingModRefBS::invalidate(MemRegion mr, bool whole_heap) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
119 jbyte* byte = byte_for(mr.start());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
120 jbyte* last_byte = byte_for(mr.last());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
121 Thread* thr = Thread::current();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
122 if (whole_heap) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
123 while (byte <= last_byte) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
124 *byte = dirty_card;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
125 byte++;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
126 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
127 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
128 // Enqueue if necessary.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
129 if (thr->is_Java_thread()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
130 JavaThread* jt = (JavaThread*)thr;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
131 while (byte <= last_byte) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
132 if (*byte != dirty_card) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
133 *byte = dirty_card;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
134 jt->dirty_card_queue().enqueue(byte);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
135 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
136 byte++;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
137 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
138 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
139 MutexLockerEx x(Shared_DirtyCardQ_lock,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
140 Mutex::_no_safepoint_check_flag);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
141 while (byte <= last_byte) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
142 if (*byte != dirty_card) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
143 *byte = dirty_card;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
144 _dcqs.shared_dirty_card_queue()->enqueue(byte);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
145 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
146 byte++;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
147 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
148 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
149 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
150 }