Thu, 20 Sep 2012 09:52:56 -0700
7190666: G1: assert(_unused == 0) failed: Inconsistency in PLAB stats
Summary: Reset the fields in ParGCAllocBuffer, that are used for accumulating values for the ResizePLAB sensors in PLABStats, to zero after flushing the values to the PLABStats fields. Flush PLABStats values only when retiring the final allocation buffers prior to disposing of a G1ParScanThreadState object, rather than when retiring every allocation buffer.
Reviewed-by: jwilhelm, jmasa, ysr
1 /*
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
25 #include "precompiled.hpp"
26 #include "compiler/compileBroker.hpp"
27 #include "gc_implementation/shared/markSweep.inline.hpp"
28 #include "gc_interface/collectedHeap.inline.hpp"
29 #include "oops/methodData.hpp"
30 #include "oops/objArrayKlass.inline.hpp"
31 #include "oops/oop.inline.hpp"
33 unsigned int MarkSweep::_total_invocations = 0;
35 Stack<oop, mtGC> MarkSweep::_marking_stack;
36 Stack<ObjArrayTask, mtGC> MarkSweep::_objarray_stack;
38 Stack<oop, mtGC> MarkSweep::_preserved_oop_stack;
39 Stack<markOop, mtGC> MarkSweep::_preserved_mark_stack;
40 size_t MarkSweep::_preserved_count = 0;
41 size_t MarkSweep::_preserved_count_max = 0;
42 PreservedMark* MarkSweep::_preserved_marks = NULL;
43 ReferenceProcessor* MarkSweep::_ref_processor = NULL;
45 #ifdef VALIDATE_MARK_SWEEP
46 GrowableArray<void*>* MarkSweep::_root_refs_stack = NULL;
47 GrowableArray<oop> * MarkSweep::_live_oops = NULL;
48 GrowableArray<oop> * MarkSweep::_live_oops_moved_to = NULL;
49 GrowableArray<size_t>* MarkSweep::_live_oops_size = NULL;
50 size_t MarkSweep::_live_oops_index = 0;
51 size_t MarkSweep::_live_oops_index_at_perm = 0;
52 GrowableArray<void*>* MarkSweep::_other_refs_stack = NULL;
53 GrowableArray<void*>* MarkSweep::_adjusted_pointers = NULL;
54 bool MarkSweep::_pointer_tracking = false;
55 bool MarkSweep::_root_tracking = true;
57 GrowableArray<HeapWord*>* MarkSweep::_cur_gc_live_oops = NULL;
58 GrowableArray<HeapWord*>* MarkSweep::_cur_gc_live_oops_moved_to = NULL;
59 GrowableArray<size_t> * MarkSweep::_cur_gc_live_oops_size = NULL;
60 GrowableArray<HeapWord*>* MarkSweep::_last_gc_live_oops = NULL;
61 GrowableArray<HeapWord*>* MarkSweep::_last_gc_live_oops_moved_to = NULL;
62 GrowableArray<size_t> * MarkSweep::_last_gc_live_oops_size = NULL;
63 #endif
65 MarkSweep::FollowRootClosure MarkSweep::follow_root_closure;
66 CodeBlobToOopClosure MarkSweep::follow_code_root_closure(&MarkSweep::follow_root_closure, /*do_marking=*/ true);
68 void MarkSweep::FollowRootClosure::do_oop(oop* p) { follow_root(p); }
69 void MarkSweep::FollowRootClosure::do_oop(narrowOop* p) { follow_root(p); }
71 MarkSweep::MarkAndPushClosure MarkSweep::mark_and_push_closure;
72 MarkSweep::FollowKlassClosure MarkSweep::follow_klass_closure;
73 MarkSweep::AdjustKlassClosure MarkSweep::adjust_klass_closure;
75 void MarkSweep::MarkAndPushClosure::do_oop(oop* p) { mark_and_push(p); }
76 void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(p); }
78 void MarkSweep::FollowKlassClosure::do_klass(Klass* klass) {
79 klass->oops_do(&MarkSweep::mark_and_push_closure);
80 }
81 void MarkSweep::AdjustKlassClosure::do_klass(Klass* klass) {
82 klass->oops_do(&MarkSweep::adjust_pointer_closure);
83 }
85 void MarkSweep::follow_klass(Klass* klass) {
86 ClassLoaderData* cld = klass->class_loader_data();
87 assert(cld->has_defined(klass), "inconsistency!");
89 // The actual processing of the klass is done when we
90 // traverse the list of Klasses in the class loader data.
91 MarkSweep::follow_class_loader(cld);
92 }
94 void MarkSweep::adjust_klass(Klass* klass) {
95 ClassLoaderData* cld = klass->class_loader_data();
96 assert(cld->has_defined(klass), "inconsistency!");
98 // The actual processing of the klass is done when we
99 // traverse the list of Klasses in the class loader data.
100 MarkSweep::adjust_class_loader(cld);
101 }
103 void MarkSweep::follow_class_loader(ClassLoaderData* cld) {
104 cld->oops_do(&MarkSweep::mark_and_push_closure, &MarkSweep::follow_klass_closure, true);
105 }
107 void MarkSweep::adjust_class_loader(ClassLoaderData* cld) {
108 cld->oops_do(&MarkSweep::adjust_root_pointer_closure, &MarkSweep::adjust_klass_closure, true);
109 }
112 void MarkSweep::follow_stack() {
113 do {
114 while (!_marking_stack.is_empty()) {
115 oop obj = _marking_stack.pop();
116 assert (obj->is_gc_marked(), "p must be marked");
117 obj->follow_contents();
118 }
119 // Process ObjArrays one at a time to avoid marking stack bloat.
120 if (!_objarray_stack.is_empty()) {
121 ObjArrayTask task = _objarray_stack.pop();
122 objArrayKlass* const k = (objArrayKlass*)task.obj()->klass();
123 k->oop_follow_contents(task.obj(), task.index());
124 }
125 } while (!_marking_stack.is_empty() || !_objarray_stack.is_empty());
126 }
128 MarkSweep::FollowStackClosure MarkSweep::follow_stack_closure;
130 void MarkSweep::FollowStackClosure::do_void() { follow_stack(); }
132 // We preserve the mark which should be replaced at the end and the location
133 // that it will go. Note that the object that this markOop belongs to isn't
134 // currently at that address but it will be after phase4
135 void MarkSweep::preserve_mark(oop obj, markOop mark) {
136 // We try to store preserved marks in the to space of the new generation since
137 // this is storage which should be available. Most of the time this should be
138 // sufficient space for the marks we need to preserve but if it isn't we fall
139 // back to using Stacks to keep track of the overflow.
140 if (_preserved_count < _preserved_count_max) {
141 _preserved_marks[_preserved_count++].init(obj, mark);
142 } else {
143 _preserved_mark_stack.push(mark);
144 _preserved_oop_stack.push(obj);
145 }
146 }
148 MarkSweep::AdjustPointerClosure MarkSweep::adjust_root_pointer_closure(true);
149 MarkSweep::AdjustPointerClosure MarkSweep::adjust_pointer_closure(false);
151 void MarkSweep::AdjustPointerClosure::do_oop(oop* p) { adjust_pointer(p, _is_root); }
152 void MarkSweep::AdjustPointerClosure::do_oop(narrowOop* p) { adjust_pointer(p, _is_root); }
154 void MarkSweep::adjust_marks() {
155 assert( _preserved_oop_stack.size() == _preserved_mark_stack.size(),
156 "inconsistent preserved oop stacks");
158 // adjust the oops we saved earlier
159 for (size_t i = 0; i < _preserved_count; i++) {
160 _preserved_marks[i].adjust_pointer();
161 }
163 // deal with the overflow stack
164 StackIterator<oop, mtGC> iter(_preserved_oop_stack);
165 while (!iter.is_empty()) {
166 oop* p = iter.next_addr();
167 adjust_pointer(p);
168 }
169 }
171 void MarkSweep::restore_marks() {
172 assert(_preserved_oop_stack.size() == _preserved_mark_stack.size(),
173 "inconsistent preserved oop stacks");
174 if (PrintGC && Verbose) {
175 gclog_or_tty->print_cr("Restoring %d marks",
176 _preserved_count + _preserved_oop_stack.size());
177 }
179 // restore the marks we saved earlier
180 for (size_t i = 0; i < _preserved_count; i++) {
181 _preserved_marks[i].restore();
182 }
184 // deal with the overflow
185 while (!_preserved_oop_stack.is_empty()) {
186 oop obj = _preserved_oop_stack.pop();
187 markOop mark = _preserved_mark_stack.pop();
188 obj->set_mark(mark);
189 }
190 }
192 #ifdef VALIDATE_MARK_SWEEP
194 void MarkSweep::track_adjusted_pointer(void* p, bool isroot) {
195 if (!ValidateMarkSweep)
196 return;
198 if (!isroot) {
199 if (_pointer_tracking) {
200 guarantee(_adjusted_pointers->contains(p), "should have seen this pointer");
201 _adjusted_pointers->remove(p);
202 }
203 } else {
204 ptrdiff_t index = _root_refs_stack->find(p);
205 if (index != -1) {
206 int l = _root_refs_stack->length();
207 if (l > 0 && l - 1 != index) {
208 void* last = _root_refs_stack->pop();
209 assert(last != p, "should be different");
210 _root_refs_stack->at_put(index, last);
211 } else {
212 _root_refs_stack->remove(p);
213 }
214 }
215 }
216 }
218 void MarkSweep::check_adjust_pointer(void* p) {
219 _adjusted_pointers->push(p);
220 }
222 class AdjusterTracker: public OopClosure {
223 public:
224 AdjusterTracker() {}
225 void do_oop(oop* o) { MarkSweep::check_adjust_pointer(o); }
226 void do_oop(narrowOop* o) { MarkSweep::check_adjust_pointer(o); }
227 };
229 void MarkSweep::track_interior_pointers(oop obj) {
230 if (ValidateMarkSweep) {
231 _adjusted_pointers->clear();
232 _pointer_tracking = true;
234 AdjusterTracker checker;
235 obj->oop_iterate_no_header(&checker);
236 }
237 }
239 void MarkSweep::check_interior_pointers() {
240 if (ValidateMarkSweep) {
241 _pointer_tracking = false;
242 guarantee(_adjusted_pointers->length() == 0, "should have processed the same pointers");
243 }
244 }
246 void MarkSweep::reset_live_oop_tracking() {
247 if (ValidateMarkSweep) {
248 guarantee((size_t)_live_oops->length() == _live_oops_index, "should be at end of live oops");
249 _live_oops_index = 0;
250 }
251 }
253 void MarkSweep::register_live_oop(oop p, size_t size) {
254 if (ValidateMarkSweep) {
255 _live_oops->push(p);
256 _live_oops_size->push(size);
257 _live_oops_index++;
258 }
259 }
261 void MarkSweep::validate_live_oop(oop p, size_t size) {
262 if (ValidateMarkSweep) {
263 oop obj = _live_oops->at((int)_live_oops_index);
264 guarantee(obj == p, "should be the same object");
265 guarantee(_live_oops_size->at((int)_live_oops_index) == size, "should be the same size");
266 _live_oops_index++;
267 }
268 }
270 void MarkSweep::live_oop_moved_to(HeapWord* q, size_t size,
271 HeapWord* compaction_top) {
272 assert(oop(q)->forwardee() == NULL || oop(q)->forwardee() == oop(compaction_top),
273 "should be moved to forwarded location");
274 if (ValidateMarkSweep) {
275 MarkSweep::validate_live_oop(oop(q), size);
276 _live_oops_moved_to->push(oop(compaction_top));
277 }
278 if (RecordMarkSweepCompaction) {
279 _cur_gc_live_oops->push(q);
280 _cur_gc_live_oops_moved_to->push(compaction_top);
281 _cur_gc_live_oops_size->push(size);
282 }
283 }
285 void MarkSweep::compaction_complete() {
286 if (RecordMarkSweepCompaction) {
287 GrowableArray<HeapWord*>* _tmp_live_oops = _cur_gc_live_oops;
288 GrowableArray<HeapWord*>* _tmp_live_oops_moved_to = _cur_gc_live_oops_moved_to;
289 GrowableArray<size_t> * _tmp_live_oops_size = _cur_gc_live_oops_size;
291 _cur_gc_live_oops = _last_gc_live_oops;
292 _cur_gc_live_oops_moved_to = _last_gc_live_oops_moved_to;
293 _cur_gc_live_oops_size = _last_gc_live_oops_size;
294 _last_gc_live_oops = _tmp_live_oops;
295 _last_gc_live_oops_moved_to = _tmp_live_oops_moved_to;
296 _last_gc_live_oops_size = _tmp_live_oops_size;
297 }
298 }
300 void MarkSweep::print_new_location_of_heap_address(HeapWord* q) {
301 if (!RecordMarkSweepCompaction) {
302 tty->print_cr("Requires RecordMarkSweepCompaction to be enabled");
303 return;
304 }
306 if (_last_gc_live_oops == NULL) {
307 tty->print_cr("No compaction information gathered yet");
308 return;
309 }
311 for (int i = 0; i < _last_gc_live_oops->length(); i++) {
312 HeapWord* old_oop = _last_gc_live_oops->at(i);
313 size_t sz = _last_gc_live_oops_size->at(i);
314 if (old_oop <= q && q < (old_oop + sz)) {
315 HeapWord* new_oop = _last_gc_live_oops_moved_to->at(i);
316 size_t offset = (q - old_oop);
317 tty->print_cr("Address " PTR_FORMAT, q);
318 tty->print_cr(" Was in oop " PTR_FORMAT ", size " SIZE_FORMAT ", at offset " SIZE_FORMAT, old_oop, sz, offset);
319 tty->print_cr(" Now in oop " PTR_FORMAT ", actual address " PTR_FORMAT, new_oop, new_oop + offset);
320 return;
321 }
322 }
324 tty->print_cr("Address " PTR_FORMAT " not found in live oop information from last GC", q);
325 }
326 #endif //VALIDATE_MARK_SWEEP
328 MarkSweep::IsAliveClosure MarkSweep::is_alive;
330 void MarkSweep::IsAliveClosure::do_object(oop p) { ShouldNotReachHere(); }
331 bool MarkSweep::IsAliveClosure::do_object_b(oop p) { return p->is_gc_marked(); }
333 MarkSweep::KeepAliveClosure MarkSweep::keep_alive;
335 void MarkSweep::KeepAliveClosure::do_oop(oop* p) { MarkSweep::KeepAliveClosure::do_oop_work(p); }
336 void MarkSweep::KeepAliveClosure::do_oop(narrowOop* p) { MarkSweep::KeepAliveClosure::do_oop_work(p); }
338 void marksweep_init() { /* empty */ }
340 #ifndef PRODUCT
342 void MarkSweep::trace(const char* msg) {
343 if (TraceMarkSweep)
344 gclog_or_tty->print("%s", msg);
345 }
347 #endif