annotate src/share/vm/gc_implementation/g1/satbQueue.cpp @ 452:00b023ae2d78

6722113: CMS: Incorrect overflow handling during precleaning of Reference lists Summary: When we encounter marking stack overflow during precleaning of Reference lists, we were using the overflow list mechanism, which can cause problems on account of mutating the mark word of the header because of conflicts with mutator accesses and updates of that field. Instead we should use the usual mechanism for overflow handling in concurrent phases, namely dirtying of the card on which the overflowed object lies. Since precleaning effectively does a form of discovered list processing, albeit with discovery enabled, we needed to adjust some code to be correct in the face of interleaved processing and discovery. Reviewed-by: apetrusenko, jcoomes
author ysr
date Thu, 20 Nov 2008 12:27:41 -0800
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/_satbQueue.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 void ObjPtrQueue::apply_closure(ObjectClosure* cl) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
29 if (_buf != NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
30 apply_closure_to_buffer(cl, _buf, _index, _sz);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
31 _index = _sz;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
32 }
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 void ObjPtrQueue::apply_closure_to_buffer(ObjectClosure* cl,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
36 void** buf, size_t index, size_t sz) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
37 if (cl == NULL) return;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
38 for (size_t i = index; i < sz; i += oopSize) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
39 oop obj = (oop)buf[byte_index_to_index((int)i)];
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
40 // There can be NULL entries because of destructors.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
41 if (obj != NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
42 cl->do_object(obj);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
43 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
44 }
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 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
47 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
48 #endif // _MSC_VER
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
49
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
50
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
51 SATBMarkQueueSet::SATBMarkQueueSet() :
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
52 PtrQueueSet(),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
53 _closure(NULL), _par_closures(NULL),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
54 _shared_satb_queue(this, true /*perm*/)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
55 {}
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
56
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
57 void SATBMarkQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
58 int max_completed_queue,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
59 Mutex* lock) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
60 PtrQueueSet::initialize(cbl_mon, fl_lock, max_completed_queue);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
61 _shared_satb_queue.set_lock(lock);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
62 if (ParallelGCThreads > 0) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
63 _par_closures = NEW_C_HEAP_ARRAY(ObjectClosure*, ParallelGCThreads);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
64 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
65 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
66
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
67
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
68 void SATBMarkQueueSet::handle_zero_index_for_thread(JavaThread* t) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
69 t->satb_mark_queue().handle_zero_index();
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 void SATBMarkQueueSet::set_active_all_threads(bool b) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
73 _all_active = b;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
74 for(JavaThread* t = Threads::first(); t; t = t->next()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
75 t->satb_mark_queue().set_active(b);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
76 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
77 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
78
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
79 void SATBMarkQueueSet::set_closure(ObjectClosure* closure) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
80 _closure = closure;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
81 }
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 void SATBMarkQueueSet::set_par_closure(int i, ObjectClosure* par_closure) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
84 assert(ParallelGCThreads > 0 && _par_closures != NULL, "Precondition");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
85 _par_closures[i] = par_closure;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
86 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
87
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
88 void SATBMarkQueueSet::iterate_closure_all_threads() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
89 for(JavaThread* t = Threads::first(); t; t = t->next()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
90 t->satb_mark_queue().apply_closure(_closure);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
91 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
92 shared_satb_queue()->apply_closure(_closure);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
93 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
94
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
95 void SATBMarkQueueSet::par_iterate_closure_all_threads(int worker) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
96 SharedHeap* sh = SharedHeap::heap();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
97 int parity = sh->strong_roots_parity();
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 for(JavaThread* t = Threads::first(); t; t = t->next()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
100 if (t->claim_oops_do(true, parity)) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
101 t->satb_mark_queue().apply_closure(_par_closures[worker]);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
102 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
103 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
104 // We'll have worker 0 do this one.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
105 if (worker == 0) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
106 shared_satb_queue()->apply_closure(_par_closures[0]);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
107 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
108 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
109
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
110 bool SATBMarkQueueSet::apply_closure_to_completed_buffer_work(bool par,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
111 int worker) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
112 CompletedBufferNode* nd = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
113 {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
114 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
115 if (_completed_buffers_head != NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
116 nd = _completed_buffers_head;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
117 _completed_buffers_head = nd->next;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
118 if (_completed_buffers_head == NULL) _completed_buffers_tail = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
119 _n_completed_buffers--;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
120 if (_n_completed_buffers == 0) _process_completed = false;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
121 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
122 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
123 ObjectClosure* cl = (par ? _par_closures[worker] : _closure);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
124 if (nd != NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
125 ObjPtrQueue::apply_closure_to_buffer(cl, nd->buf, 0, _sz);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
126 deallocate_buffer(nd->buf);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
127 delete nd;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
128 return true;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
129 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
130 return false;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
131 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
132 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
133
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
134 void SATBMarkQueueSet::abandon_partial_marking() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
135 CompletedBufferNode* buffers_to_delete = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
136 {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
137 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
138 while (_completed_buffers_head != NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
139 CompletedBufferNode* nd = _completed_buffers_head;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
140 _completed_buffers_head = nd->next;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
141 nd->next = buffers_to_delete;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
142 buffers_to_delete = nd;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
143 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
144 _completed_buffers_tail = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
145 _n_completed_buffers = 0;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
146 debug_only(assert_completed_buffer_list_len_correct_locked());
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 while (buffers_to_delete != NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
149 CompletedBufferNode* nd = buffers_to_delete;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
150 buffers_to_delete = nd->next;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
151 deallocate_buffer(nd->buf);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
152 delete nd;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
153 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
154 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
155 // So we can safely manipulate these queues.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
156 for (JavaThread* t = Threads::first(); t; t = t->next()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
157 t->satb_mark_queue().reset();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
158 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
159 shared_satb_queue()->reset();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
160 }