src/share/vm/gc_implementation/shared/markSweep.cpp

Thu, 20 Sep 2012 09:52:56 -0700

author
johnc
date
Thu, 20 Sep 2012 09:52:56 -0700
changeset 4067
b2ef234911c9
parent 4037
da91efe96a93
child 4068
e861d44e0c9c
permissions
-rw-r--r--

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

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

mercurial