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

     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

mercurial