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

Thu, 04 Oct 2012 10:40:23 -0700

author
jmasa
date
Thu, 04 Oct 2012 10:40:23 -0700
changeset 4131
097d78aaf2b5
parent 4068
e861d44e0c9c
child 4142
d8ce2825b193
permissions
-rw-r--r--

7198873: NPG: VM Does not unload classes with UseConcMarkSweepGC
Reviewed-by: johnc, mgerdin, jwilhelm

     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   // The actual processing of the klass is done when we
    88   // traverse the list of Klasses in the class loader data.
    89   MarkSweep::follow_class_loader(cld);
    90 }
    92 void MarkSweep::adjust_klass(Klass* klass) {
    93   ClassLoaderData* cld = klass->class_loader_data();
    94   // The actual processing of the klass is done when we
    95   // traverse the list of Klasses in the class loader data.
    96   MarkSweep::adjust_class_loader(cld);
    97 }
    99 void MarkSweep::follow_class_loader(ClassLoaderData* cld) {
   100   cld->oops_do(&MarkSweep::mark_and_push_closure, &MarkSweep::follow_klass_closure, true);
   101 }
   103 void MarkSweep::adjust_class_loader(ClassLoaderData* cld) {
   104   cld->oops_do(&MarkSweep::adjust_root_pointer_closure, &MarkSweep::adjust_klass_closure, true);
   105 }
   108 void MarkSweep::follow_stack() {
   109   do {
   110     while (!_marking_stack.is_empty()) {
   111       oop obj = _marking_stack.pop();
   112       assert (obj->is_gc_marked(), "p must be marked");
   113       obj->follow_contents();
   114     }
   115     // Process ObjArrays one at a time to avoid marking stack bloat.
   116     if (!_objarray_stack.is_empty()) {
   117       ObjArrayTask task = _objarray_stack.pop();
   118       objArrayKlass* const k = (objArrayKlass*)task.obj()->klass();
   119       k->oop_follow_contents(task.obj(), task.index());
   120     }
   121   } while (!_marking_stack.is_empty() || !_objarray_stack.is_empty());
   122 }
   124 MarkSweep::FollowStackClosure MarkSweep::follow_stack_closure;
   126 void MarkSweep::FollowStackClosure::do_void() { follow_stack(); }
   128 // We preserve the mark which should be replaced at the end and the location
   129 // that it will go.  Note that the object that this markOop belongs to isn't
   130 // currently at that address but it will be after phase4
   131 void MarkSweep::preserve_mark(oop obj, markOop mark) {
   132   // We try to store preserved marks in the to space of the new generation since
   133   // this is storage which should be available.  Most of the time this should be
   134   // sufficient space for the marks we need to preserve but if it isn't we fall
   135   // back to using Stacks to keep track of the overflow.
   136   if (_preserved_count < _preserved_count_max) {
   137     _preserved_marks[_preserved_count++].init(obj, mark);
   138   } else {
   139     _preserved_mark_stack.push(mark);
   140     _preserved_oop_stack.push(obj);
   141   }
   142 }
   144 MarkSweep::AdjustPointerClosure MarkSweep::adjust_root_pointer_closure(true);
   145 MarkSweep::AdjustPointerClosure MarkSweep::adjust_pointer_closure(false);
   147 void MarkSweep::AdjustPointerClosure::do_oop(oop* p)       { adjust_pointer(p, _is_root); }
   148 void MarkSweep::AdjustPointerClosure::do_oop(narrowOop* p) { adjust_pointer(p, _is_root); }
   150 void MarkSweep::adjust_marks() {
   151   assert( _preserved_oop_stack.size() == _preserved_mark_stack.size(),
   152          "inconsistent preserved oop stacks");
   154   // adjust the oops we saved earlier
   155   for (size_t i = 0; i < _preserved_count; i++) {
   156     _preserved_marks[i].adjust_pointer();
   157   }
   159   // deal with the overflow stack
   160   StackIterator<oop, mtGC> iter(_preserved_oop_stack);
   161   while (!iter.is_empty()) {
   162     oop* p = iter.next_addr();
   163     adjust_pointer(p);
   164   }
   165 }
   167 void MarkSweep::restore_marks() {
   168   assert(_preserved_oop_stack.size() == _preserved_mark_stack.size(),
   169          "inconsistent preserved oop stacks");
   170   if (PrintGC && Verbose) {
   171     gclog_or_tty->print_cr("Restoring %d marks",
   172                            _preserved_count + _preserved_oop_stack.size());
   173   }
   175   // restore the marks we saved earlier
   176   for (size_t i = 0; i < _preserved_count; i++) {
   177     _preserved_marks[i].restore();
   178   }
   180   // deal with the overflow
   181   while (!_preserved_oop_stack.is_empty()) {
   182     oop obj       = _preserved_oop_stack.pop();
   183     markOop mark  = _preserved_mark_stack.pop();
   184     obj->set_mark(mark);
   185   }
   186 }
   188 #ifdef VALIDATE_MARK_SWEEP
   190 void MarkSweep::track_adjusted_pointer(void* p, bool isroot) {
   191   if (!ValidateMarkSweep)
   192     return;
   194   if (!isroot) {
   195     if (_pointer_tracking) {
   196       guarantee(_adjusted_pointers->contains(p), "should have seen this pointer");
   197       _adjusted_pointers->remove(p);
   198     }
   199   } else {
   200     ptrdiff_t index = _root_refs_stack->find(p);
   201     if (index != -1) {
   202       int l = _root_refs_stack->length();
   203       if (l > 0 && l - 1 != index) {
   204         void* last = _root_refs_stack->pop();
   205         assert(last != p, "should be different");
   206         _root_refs_stack->at_put(index, last);
   207       } else {
   208         _root_refs_stack->remove(p);
   209       }
   210     }
   211   }
   212 }
   214 void MarkSweep::check_adjust_pointer(void* p) {
   215   _adjusted_pointers->push(p);
   216 }
   218 class AdjusterTracker: public OopClosure {
   219  public:
   220   AdjusterTracker() {}
   221   void do_oop(oop* o)       { MarkSweep::check_adjust_pointer(o); }
   222   void do_oop(narrowOop* o) { MarkSweep::check_adjust_pointer(o); }
   223 };
   225 void MarkSweep::track_interior_pointers(oop obj) {
   226   if (ValidateMarkSweep) {
   227     _adjusted_pointers->clear();
   228     _pointer_tracking = true;
   230     AdjusterTracker checker;
   231     obj->oop_iterate_no_header(&checker);
   232   }
   233 }
   235 void MarkSweep::check_interior_pointers() {
   236   if (ValidateMarkSweep) {
   237     _pointer_tracking = false;
   238     guarantee(_adjusted_pointers->length() == 0, "should have processed the same pointers");
   239   }
   240 }
   242 void MarkSweep::reset_live_oop_tracking() {
   243   if (ValidateMarkSweep) {
   244     guarantee((size_t)_live_oops->length() == _live_oops_index, "should be at end of live oops");
   245     _live_oops_index = 0;
   246   }
   247 }
   249 void MarkSweep::register_live_oop(oop p, size_t size) {
   250   if (ValidateMarkSweep) {
   251     _live_oops->push(p);
   252     _live_oops_size->push(size);
   253     _live_oops_index++;
   254   }
   255 }
   257 void MarkSweep::validate_live_oop(oop p, size_t size) {
   258   if (ValidateMarkSweep) {
   259     oop obj = _live_oops->at((int)_live_oops_index);
   260     guarantee(obj == p, "should be the same object");
   261     guarantee(_live_oops_size->at((int)_live_oops_index) == size, "should be the same size");
   262     _live_oops_index++;
   263   }
   264 }
   266 void MarkSweep::live_oop_moved_to(HeapWord* q, size_t size,
   267                                   HeapWord* compaction_top) {
   268   assert(oop(q)->forwardee() == NULL || oop(q)->forwardee() == oop(compaction_top),
   269          "should be moved to forwarded location");
   270   if (ValidateMarkSweep) {
   271     MarkSweep::validate_live_oop(oop(q), size);
   272     _live_oops_moved_to->push(oop(compaction_top));
   273   }
   274   if (RecordMarkSweepCompaction) {
   275     _cur_gc_live_oops->push(q);
   276     _cur_gc_live_oops_moved_to->push(compaction_top);
   277     _cur_gc_live_oops_size->push(size);
   278   }
   279 }
   281 void MarkSweep::compaction_complete() {
   282   if (RecordMarkSweepCompaction) {
   283     GrowableArray<HeapWord*>* _tmp_live_oops          = _cur_gc_live_oops;
   284     GrowableArray<HeapWord*>* _tmp_live_oops_moved_to = _cur_gc_live_oops_moved_to;
   285     GrowableArray<size_t>   * _tmp_live_oops_size     = _cur_gc_live_oops_size;
   287     _cur_gc_live_oops           = _last_gc_live_oops;
   288     _cur_gc_live_oops_moved_to  = _last_gc_live_oops_moved_to;
   289     _cur_gc_live_oops_size      = _last_gc_live_oops_size;
   290     _last_gc_live_oops          = _tmp_live_oops;
   291     _last_gc_live_oops_moved_to = _tmp_live_oops_moved_to;
   292     _last_gc_live_oops_size     = _tmp_live_oops_size;
   293   }
   294 }
   296 void MarkSweep::print_new_location_of_heap_address(HeapWord* q) {
   297   if (!RecordMarkSweepCompaction) {
   298     tty->print_cr("Requires RecordMarkSweepCompaction to be enabled");
   299     return;
   300   }
   302   if (_last_gc_live_oops == NULL) {
   303     tty->print_cr("No compaction information gathered yet");
   304     return;
   305   }
   307   for (int i = 0; i < _last_gc_live_oops->length(); i++) {
   308     HeapWord* old_oop = _last_gc_live_oops->at(i);
   309     size_t    sz      = _last_gc_live_oops_size->at(i);
   310     if (old_oop <= q && q < (old_oop + sz)) {
   311       HeapWord* new_oop = _last_gc_live_oops_moved_to->at(i);
   312       size_t offset = (q - old_oop);
   313       tty->print_cr("Address " PTR_FORMAT, q);
   314       tty->print_cr(" Was in oop " PTR_FORMAT ", size " SIZE_FORMAT ", at offset " SIZE_FORMAT, old_oop, sz, offset);
   315       tty->print_cr(" Now in oop " PTR_FORMAT ", actual address " PTR_FORMAT, new_oop, new_oop + offset);
   316       return;
   317     }
   318   }
   320   tty->print_cr("Address " PTR_FORMAT " not found in live oop information from last GC", q);
   321 }
   322 #endif //VALIDATE_MARK_SWEEP
   324 MarkSweep::IsAliveClosure   MarkSweep::is_alive;
   326 void MarkSweep::IsAliveClosure::do_object(oop p)   { ShouldNotReachHere(); }
   327 bool MarkSweep::IsAliveClosure::do_object_b(oop p) { return p->is_gc_marked(); }
   329 MarkSweep::KeepAliveClosure MarkSweep::keep_alive;
   331 void MarkSweep::KeepAliveClosure::do_oop(oop* p)       { MarkSweep::KeepAliveClosure::do_oop_work(p); }
   332 void MarkSweep::KeepAliveClosure::do_oop(narrowOop* p) { MarkSweep::KeepAliveClosure::do_oop_work(p); }
   334 void marksweep_init() { /* empty */ }
   336 #ifndef PRODUCT
   338 void MarkSweep::trace(const char* msg) {
   339   if (TraceMarkSweep)
   340     gclog_or_tty->print("%s", msg);
   341 }
   343 #endif

mercurial