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

Mon, 02 Aug 2010 12:51:43 -0700

author
johnc
date
Mon, 02 Aug 2010 12:51:43 -0700
changeset 2060
2d160770d2e5
parent 1907
c18cbe5936b8
child 2314
f95d63e2154a
permissions
-rw-r--r--

6814437: G1: remove the _new_refs array
Summary: The per-worker _new_refs array is used to hold references that point into the collection set. It is populated during RSet updating and subsequently processed. In the event of an evacuation failure it processed again to recreate the RSets of regions in the collection set. Remove the per-worker _new_refs array by processing the references directly. Use a DirtyCardQueue to hold the cards containing the references so that the RSets of regions in the collection set can be recreated when handling an evacuation failure.
Reviewed-by: iveresov, jmasa, tonyp

ysr@777 1 /*
trims@1907 2 * Copyright (c) 2001, 2007, 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
ysr@777 25 # include "incls/_precompiled.incl"
ysr@777 26 # include "incls/_satbQueue.cpp.incl"
ysr@777 27
ysr@777 28 void ObjPtrQueue::apply_closure(ObjectClosure* cl) {
ysr@777 29 if (_buf != NULL) {
ysr@777 30 apply_closure_to_buffer(cl, _buf, _index, _sz);
ysr@777 31 _index = _sz;
ysr@777 32 }
ysr@777 33 }
ysr@777 34
ysr@777 35 void ObjPtrQueue::apply_closure_to_buffer(ObjectClosure* cl,
ysr@777 36 void** buf, size_t index, size_t sz) {
ysr@777 37 if (cl == NULL) return;
ysr@777 38 for (size_t i = index; i < sz; i += oopSize) {
ysr@777 39 oop obj = (oop)buf[byte_index_to_index((int)i)];
ysr@777 40 // There can be NULL entries because of destructors.
ysr@777 41 if (obj != NULL) {
ysr@777 42 cl->do_object(obj);
ysr@777 43 }
ysr@777 44 }
ysr@777 45 }
ysr@1280 46
ysr@1280 47 #ifdef ASSERT
ysr@1280 48 void ObjPtrQueue::verify_oops_in_buffer() {
ysr@1280 49 if (_buf == NULL) return;
ysr@1280 50 for (size_t i = _index; i < _sz; i += oopSize) {
ysr@1280 51 oop obj = (oop)_buf[byte_index_to_index((int)i)];
ysr@1280 52 assert(obj != NULL && obj->is_oop(true /* ignore mark word */),
ysr@1280 53 "Not an oop");
ysr@1280 54 }
ysr@1280 55 }
ysr@1280 56 #endif
ysr@1280 57
ysr@777 58 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away
ysr@777 59 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
ysr@777 60 #endif // _MSC_VER
ysr@777 61
ysr@777 62
ysr@777 63 SATBMarkQueueSet::SATBMarkQueueSet() :
ysr@777 64 PtrQueueSet(),
ysr@777 65 _closure(NULL), _par_closures(NULL),
ysr@777 66 _shared_satb_queue(this, true /*perm*/)
ysr@777 67 {}
ysr@777 68
ysr@777 69 void SATBMarkQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
iveresov@1546 70 int process_completed_threshold,
ysr@777 71 Mutex* lock) {
iveresov@1546 72 PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold, -1);
ysr@777 73 _shared_satb_queue.set_lock(lock);
ysr@777 74 if (ParallelGCThreads > 0) {
ysr@777 75 _par_closures = NEW_C_HEAP_ARRAY(ObjectClosure*, ParallelGCThreads);
ysr@777 76 }
ysr@777 77 }
ysr@777 78
ysr@777 79
ysr@777 80 void SATBMarkQueueSet::handle_zero_index_for_thread(JavaThread* t) {
ysr@1280 81 DEBUG_ONLY(t->satb_mark_queue().verify_oops_in_buffer();)
ysr@777 82 t->satb_mark_queue().handle_zero_index();
ysr@777 83 }
ysr@777 84
tonyp@1752 85 #ifdef ASSERT
tonyp@1752 86 void SATBMarkQueueSet::dump_active_values(JavaThread* first,
tonyp@1752 87 bool expected_active) {
tonyp@1752 88 gclog_or_tty->print_cr("SATB queue active values for Java Threads");
tonyp@1752 89 gclog_or_tty->print_cr(" SATB queue set: active is %s",
tonyp@1752 90 (is_active()) ? "TRUE" : "FALSE");
tonyp@1752 91 gclog_or_tty->print_cr(" expected_active is %s",
tonyp@1752 92 (expected_active) ? "TRUE" : "FALSE");
tonyp@1752 93 for (JavaThread* t = first; t; t = t->next()) {
tonyp@1752 94 bool active = t->satb_mark_queue().is_active();
tonyp@1752 95 gclog_or_tty->print_cr(" thread %s, active is %s",
tonyp@1752 96 t->name(), (active) ? "TRUE" : "FALSE");
tonyp@1752 97 }
tonyp@1752 98 }
tonyp@1752 99 #endif // ASSERT
tonyp@1752 100
tonyp@1752 101 void SATBMarkQueueSet::set_active_all_threads(bool b,
tonyp@1752 102 bool expected_active) {
tonyp@1752 103 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
tonyp@1752 104 JavaThread* first = Threads::first();
tonyp@1752 105
tonyp@1752 106 #ifdef ASSERT
tonyp@1752 107 if (_all_active != expected_active) {
tonyp@1752 108 dump_active_values(first, expected_active);
tonyp@1752 109
tonyp@1752 110 // I leave this here as a guarantee, instead of an assert, so
tonyp@1752 111 // that it will still be compiled in if we choose to uncomment
tonyp@1752 112 // the #ifdef ASSERT in a product build. The whole block is
tonyp@1752 113 // within an #ifdef ASSERT so the guarantee will not be compiled
tonyp@1752 114 // in a product build anyway.
tonyp@1752 115 guarantee(false,
tonyp@1752 116 "SATB queue set has an unexpected active value");
tonyp@1752 117 }
tonyp@1752 118 #endif // ASSERT
ysr@777 119 _all_active = b;
tonyp@1752 120
tonyp@1752 121 for (JavaThread* t = first; t; t = t->next()) {
tonyp@1752 122 #ifdef ASSERT
tonyp@1752 123 bool active = t->satb_mark_queue().is_active();
tonyp@1752 124 if (active != expected_active) {
tonyp@1752 125 dump_active_values(first, expected_active);
tonyp@1752 126
tonyp@1752 127 // I leave this here as a guarantee, instead of an assert, so
tonyp@1752 128 // that it will still be compiled in if we choose to uncomment
tonyp@1752 129 // the #ifdef ASSERT in a product build. The whole block is
tonyp@1752 130 // within an #ifdef ASSERT so the guarantee will not be compiled
tonyp@1752 131 // in a product build anyway.
tonyp@1752 132 guarantee(false,
tonyp@1752 133 "thread has an unexpected active value in its SATB queue");
tonyp@1752 134 }
tonyp@1752 135 #endif // ASSERT
ysr@777 136 t->satb_mark_queue().set_active(b);
ysr@777 137 }
ysr@777 138 }
ysr@777 139
ysr@777 140 void SATBMarkQueueSet::set_closure(ObjectClosure* closure) {
ysr@777 141 _closure = closure;
ysr@777 142 }
ysr@777 143
ysr@777 144 void SATBMarkQueueSet::set_par_closure(int i, ObjectClosure* par_closure) {
ysr@777 145 assert(ParallelGCThreads > 0 && _par_closures != NULL, "Precondition");
ysr@777 146 _par_closures[i] = par_closure;
ysr@777 147 }
ysr@777 148
ysr@777 149 void SATBMarkQueueSet::iterate_closure_all_threads() {
ysr@777 150 for(JavaThread* t = Threads::first(); t; t = t->next()) {
ysr@777 151 t->satb_mark_queue().apply_closure(_closure);
ysr@777 152 }
ysr@777 153 shared_satb_queue()->apply_closure(_closure);
ysr@777 154 }
ysr@777 155
ysr@777 156 void SATBMarkQueueSet::par_iterate_closure_all_threads(int worker) {
ysr@777 157 SharedHeap* sh = SharedHeap::heap();
ysr@777 158 int parity = sh->strong_roots_parity();
ysr@777 159
ysr@777 160 for(JavaThread* t = Threads::first(); t; t = t->next()) {
ysr@777 161 if (t->claim_oops_do(true, parity)) {
ysr@777 162 t->satb_mark_queue().apply_closure(_par_closures[worker]);
ysr@777 163 }
ysr@777 164 }
ysr@777 165 // We'll have worker 0 do this one.
ysr@777 166 if (worker == 0) {
ysr@777 167 shared_satb_queue()->apply_closure(_par_closures[0]);
ysr@777 168 }
ysr@777 169 }
ysr@777 170
ysr@777 171 bool SATBMarkQueueSet::apply_closure_to_completed_buffer_work(bool par,
ysr@777 172 int worker) {
iveresov@1546 173 BufferNode* nd = NULL;
ysr@777 174 {
ysr@777 175 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
ysr@777 176 if (_completed_buffers_head != NULL) {
ysr@777 177 nd = _completed_buffers_head;
iveresov@1546 178 _completed_buffers_head = nd->next();
ysr@777 179 if (_completed_buffers_head == NULL) _completed_buffers_tail = NULL;
ysr@777 180 _n_completed_buffers--;
ysr@777 181 if (_n_completed_buffers == 0) _process_completed = false;
ysr@777 182 }
ysr@777 183 }
ysr@777 184 ObjectClosure* cl = (par ? _par_closures[worker] : _closure);
ysr@777 185 if (nd != NULL) {
iveresov@1546 186 void **buf = BufferNode::make_buffer_from_node(nd);
iveresov@1546 187 ObjPtrQueue::apply_closure_to_buffer(cl, buf, 0, _sz);
iveresov@1546 188 deallocate_buffer(buf);
ysr@777 189 return true;
ysr@777 190 } else {
ysr@777 191 return false;
ysr@777 192 }
ysr@777 193 }
ysr@777 194
ysr@777 195 void SATBMarkQueueSet::abandon_partial_marking() {
iveresov@1546 196 BufferNode* buffers_to_delete = NULL;
ysr@777 197 {
ysr@777 198 MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
ysr@777 199 while (_completed_buffers_head != NULL) {
iveresov@1546 200 BufferNode* nd = _completed_buffers_head;
iveresov@1546 201 _completed_buffers_head = nd->next();
iveresov@1546 202 nd->set_next(buffers_to_delete);
ysr@777 203 buffers_to_delete = nd;
ysr@777 204 }
ysr@777 205 _completed_buffers_tail = NULL;
ysr@777 206 _n_completed_buffers = 0;
ysr@1280 207 DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
ysr@777 208 }
ysr@777 209 while (buffers_to_delete != NULL) {
iveresov@1546 210 BufferNode* nd = buffers_to_delete;
iveresov@1546 211 buffers_to_delete = nd->next();
iveresov@1546 212 deallocate_buffer(BufferNode::make_buffer_from_node(nd));
ysr@777 213 }
ysr@777 214 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
ysr@777 215 // So we can safely manipulate these queues.
ysr@777 216 for (JavaThread* t = Threads::first(); t; t = t->next()) {
ysr@777 217 t->satb_mark_queue().reset();
ysr@777 218 }
ysr@777 219 shared_satb_queue()->reset();
ysr@777 220 }

mercurial