hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp
changeset 1 489c9b5090e2
child 360 21d113ecbf6a
equal deleted inserted replaced
0:fd16c54261b3 1:489c9b5090e2
       
     1 /*
       
     2  * Copyright 1997-2005 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    21  * have any questions.
       
    22  *
       
    23  */
       
    24 
       
    25 #include "incls/_precompiled.incl"
       
    26 #include "incls/_markSweep.cpp.incl"
       
    27 
       
    28 GrowableArray<oop>*     MarkSweep::_marking_stack       = NULL;
       
    29 GrowableArray<Klass*>*  MarkSweep::_revisit_klass_stack = NULL;
       
    30 
       
    31 GrowableArray<oop>*     MarkSweep::_preserved_oop_stack = NULL;
       
    32 GrowableArray<markOop>* MarkSweep::_preserved_mark_stack= NULL;
       
    33 size_t                  MarkSweep::_preserved_count = 0;
       
    34 size_t                  MarkSweep::_preserved_count_max = 0;
       
    35 PreservedMark*          MarkSweep::_preserved_marks = NULL;
       
    36 ReferenceProcessor*     MarkSweep::_ref_processor   = NULL;
       
    37 
       
    38 #ifdef VALIDATE_MARK_SWEEP
       
    39 GrowableArray<oop*>*    MarkSweep::_root_refs_stack = NULL;
       
    40 GrowableArray<oop> *    MarkSweep::_live_oops = NULL;
       
    41 GrowableArray<oop> *    MarkSweep::_live_oops_moved_to = NULL;
       
    42 GrowableArray<size_t>*  MarkSweep::_live_oops_size = NULL;
       
    43 size_t                  MarkSweep::_live_oops_index = 0;
       
    44 size_t                  MarkSweep::_live_oops_index_at_perm = 0;
       
    45 GrowableArray<oop*>*    MarkSweep::_other_refs_stack = NULL;
       
    46 GrowableArray<oop*>*    MarkSweep::_adjusted_pointers = NULL;
       
    47 bool                    MarkSweep::_pointer_tracking = false;
       
    48 bool                    MarkSweep::_root_tracking = true;
       
    49 
       
    50 GrowableArray<HeapWord*>* MarkSweep::_cur_gc_live_oops = NULL;
       
    51 GrowableArray<HeapWord*>* MarkSweep::_cur_gc_live_oops_moved_to = NULL;
       
    52 GrowableArray<size_t>   * MarkSweep::_cur_gc_live_oops_size = NULL;
       
    53 GrowableArray<HeapWord*>* MarkSweep::_last_gc_live_oops = NULL;
       
    54 GrowableArray<HeapWord*>* MarkSweep::_last_gc_live_oops_moved_to = NULL;
       
    55 GrowableArray<size_t>   * MarkSweep::_last_gc_live_oops_size = NULL;
       
    56 #endif
       
    57 
       
    58 void MarkSweep::revisit_weak_klass_link(Klass* k) {
       
    59   _revisit_klass_stack->push(k);
       
    60 }
       
    61 
       
    62 
       
    63 void MarkSweep::follow_weak_klass_links() {
       
    64   // All klasses on the revisit stack are marked at this point.
       
    65   // Update and follow all subklass, sibling and implementor links.
       
    66   for (int i = 0; i < _revisit_klass_stack->length(); i++) {
       
    67     _revisit_klass_stack->at(i)->follow_weak_klass_links(&is_alive,&keep_alive);
       
    68   }
       
    69   follow_stack();
       
    70 }
       
    71 
       
    72 
       
    73 void MarkSweep::mark_and_follow(oop* p) {
       
    74   assert(Universe::heap()->is_in_reserved(p),
       
    75          "we should only be traversing objects here");
       
    76   oop m = *p;
       
    77   if (m != NULL && !m->mark()->is_marked()) {
       
    78     mark_object(m);
       
    79     m->follow_contents();  // Follow contents of the marked object
       
    80   }
       
    81 }
       
    82 
       
    83 void MarkSweep::_mark_and_push(oop* p) {
       
    84   // Push marked object, contents will be followed later
       
    85   oop m = *p;
       
    86   mark_object(m);
       
    87   _marking_stack->push(m);
       
    88 }
       
    89 
       
    90 MarkSweep::MarkAndPushClosure MarkSweep::mark_and_push_closure;
       
    91 
       
    92 void MarkSweep::follow_root(oop* p) {
       
    93   assert(!Universe::heap()->is_in_reserved(p),
       
    94          "roots shouldn't be things within the heap");
       
    95 #ifdef VALIDATE_MARK_SWEEP
       
    96   if (ValidateMarkSweep) {
       
    97     guarantee(!_root_refs_stack->contains(p), "should only be in here once");
       
    98     _root_refs_stack->push(p);
       
    99   }
       
   100 #endif
       
   101   oop m = *p;
       
   102   if (m != NULL && !m->mark()->is_marked()) {
       
   103     mark_object(m);
       
   104     m->follow_contents();  // Follow contents of the marked object
       
   105   }
       
   106   follow_stack();
       
   107 }
       
   108 
       
   109 MarkSweep::FollowRootClosure MarkSweep::follow_root_closure;
       
   110 
       
   111 void MarkSweep::follow_stack() {
       
   112   while (!_marking_stack->is_empty()) {
       
   113     oop obj = _marking_stack->pop();
       
   114     assert (obj->is_gc_marked(), "p must be marked");
       
   115     obj->follow_contents();
       
   116   }
       
   117 }
       
   118 
       
   119 MarkSweep::FollowStackClosure MarkSweep::follow_stack_closure;
       
   120 
       
   121 
       
   122 // We preserve the mark which should be replaced at the end and the location that it
       
   123 // will go.  Note that the object that this markOop belongs to isn't currently at that
       
   124 // address but it will be after phase4
       
   125 void MarkSweep::preserve_mark(oop obj, markOop mark) {
       
   126   // we try to store preserved marks in the to space of the new generation since this
       
   127   // is storage which should be available.  Most of the time this should be sufficient
       
   128   // space for the marks we need to preserve but if it isn't we fall back in using
       
   129   // GrowableArrays to keep track of the overflow.
       
   130   if (_preserved_count < _preserved_count_max) {
       
   131     _preserved_marks[_preserved_count++].init(obj, mark);
       
   132   } else {
       
   133     if (_preserved_mark_stack == NULL) {
       
   134       _preserved_mark_stack = new (ResourceObj::C_HEAP) GrowableArray<markOop>(40, true);
       
   135       _preserved_oop_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(40, true);
       
   136     }
       
   137     _preserved_mark_stack->push(mark);
       
   138     _preserved_oop_stack->push(obj);
       
   139   }
       
   140 }
       
   141 
       
   142 MarkSweep::AdjustPointerClosure MarkSweep::adjust_root_pointer_closure(true);
       
   143 MarkSweep::AdjustPointerClosure MarkSweep::adjust_pointer_closure(false);
       
   144 
       
   145 void MarkSweep::adjust_marks() {
       
   146   assert(_preserved_oop_stack == NULL ||
       
   147          _preserved_oop_stack->length() == _preserved_mark_stack->length(),
       
   148          "inconsistent preserved oop stacks");
       
   149 
       
   150   // adjust the oops we saved earlier
       
   151   for (size_t i = 0; i < _preserved_count; i++) {
       
   152     _preserved_marks[i].adjust_pointer();
       
   153   }
       
   154 
       
   155   // deal with the overflow stack
       
   156   if (_preserved_oop_stack) {
       
   157     for (int i = 0; i < _preserved_oop_stack->length(); i++) {
       
   158       oop* p = _preserved_oop_stack->adr_at(i);
       
   159       adjust_pointer(p);
       
   160     }
       
   161   }
       
   162 }
       
   163 
       
   164 void MarkSweep::restore_marks() {
       
   165   assert(_preserved_oop_stack == NULL ||
       
   166          _preserved_oop_stack->length() == _preserved_mark_stack->length(),
       
   167          "inconsistent preserved oop stacks");
       
   168   if (PrintGC && Verbose) {
       
   169     gclog_or_tty->print_cr("Restoring %d marks", _preserved_count +
       
   170                   (_preserved_oop_stack ? _preserved_oop_stack->length() : 0));
       
   171   }
       
   172 
       
   173   // restore the marks we saved earlier
       
   174   for (size_t i = 0; i < _preserved_count; i++) {
       
   175     _preserved_marks[i].restore();
       
   176   }
       
   177 
       
   178   // deal with the overflow
       
   179   if (_preserved_oop_stack) {
       
   180     for (int i = 0; i < _preserved_oop_stack->length(); i++) {
       
   181       oop obj       = _preserved_oop_stack->at(i);
       
   182       markOop mark  = _preserved_mark_stack->at(i);
       
   183       obj->set_mark(mark);
       
   184     }
       
   185   }
       
   186 }
       
   187 
       
   188 #ifdef VALIDATE_MARK_SWEEP
       
   189 
       
   190 void MarkSweep::track_adjusted_pointer(oop* p, oop newobj, bool isroot) {
       
   191   if (!ValidateMarkSweep)
       
   192     return;
       
   193 
       
   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         oop* 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 }
       
   213 
       
   214 
       
   215 void MarkSweep::check_adjust_pointer(oop* p) {
       
   216   _adjusted_pointers->push(p);
       
   217 }
       
   218 
       
   219 
       
   220 class AdjusterTracker: public OopClosure {
       
   221  public:
       
   222   AdjusterTracker() {};
       
   223   void do_oop(oop* o)   { MarkSweep::check_adjust_pointer(o); }
       
   224 };
       
   225 
       
   226 
       
   227 void MarkSweep::track_interior_pointers(oop obj) {
       
   228   if (ValidateMarkSweep) {
       
   229     _adjusted_pointers->clear();
       
   230     _pointer_tracking = true;
       
   231 
       
   232     AdjusterTracker checker;
       
   233     obj->oop_iterate(&checker);
       
   234   }
       
   235 }
       
   236 
       
   237 
       
   238 void MarkSweep::check_interior_pointers() {
       
   239   if (ValidateMarkSweep) {
       
   240     _pointer_tracking = false;
       
   241     guarantee(_adjusted_pointers->length() == 0, "should have processed the same pointers");
       
   242   }
       
   243 }
       
   244 
       
   245 
       
   246 void MarkSweep::reset_live_oop_tracking(bool at_perm) {
       
   247   if (ValidateMarkSweep) {
       
   248     guarantee((size_t)_live_oops->length() == _live_oops_index, "should be at end of live oops");
       
   249     _live_oops_index = at_perm ? _live_oops_index_at_perm : 0;
       
   250   }
       
   251 }
       
   252 
       
   253 
       
   254 void MarkSweep::register_live_oop(oop p, size_t size) {
       
   255   if (ValidateMarkSweep) {
       
   256     _live_oops->push(p);
       
   257     _live_oops_size->push(size);
       
   258     _live_oops_index++;
       
   259   }
       
   260 }
       
   261 
       
   262 void MarkSweep::validate_live_oop(oop p, size_t size) {
       
   263   if (ValidateMarkSweep) {
       
   264     oop obj = _live_oops->at((int)_live_oops_index);
       
   265     guarantee(obj == p, "should be the same object");
       
   266     guarantee(_live_oops_size->at((int)_live_oops_index) == size, "should be the same size");
       
   267     _live_oops_index++;
       
   268   }
       
   269 }
       
   270 
       
   271 void MarkSweep::live_oop_moved_to(HeapWord* q, size_t size,
       
   272                                   HeapWord* compaction_top) {
       
   273   assert(oop(q)->forwardee() == NULL || oop(q)->forwardee() == oop(compaction_top),
       
   274          "should be moved to forwarded location");
       
   275   if (ValidateMarkSweep) {
       
   276     MarkSweep::validate_live_oop(oop(q), size);
       
   277     _live_oops_moved_to->push(oop(compaction_top));
       
   278   }
       
   279   if (RecordMarkSweepCompaction) {
       
   280     _cur_gc_live_oops->push(q);
       
   281     _cur_gc_live_oops_moved_to->push(compaction_top);
       
   282     _cur_gc_live_oops_size->push(size);
       
   283   }
       
   284 }
       
   285 
       
   286 
       
   287 void MarkSweep::compaction_complete() {
       
   288   if (RecordMarkSweepCompaction) {
       
   289     GrowableArray<HeapWord*>* _tmp_live_oops          = _cur_gc_live_oops;
       
   290     GrowableArray<HeapWord*>* _tmp_live_oops_moved_to = _cur_gc_live_oops_moved_to;
       
   291     GrowableArray<size_t>   * _tmp_live_oops_size     = _cur_gc_live_oops_size;
       
   292 
       
   293     _cur_gc_live_oops           = _last_gc_live_oops;
       
   294     _cur_gc_live_oops_moved_to  = _last_gc_live_oops_moved_to;
       
   295     _cur_gc_live_oops_size      = _last_gc_live_oops_size;
       
   296     _last_gc_live_oops          = _tmp_live_oops;
       
   297     _last_gc_live_oops_moved_to = _tmp_live_oops_moved_to;
       
   298     _last_gc_live_oops_size     = _tmp_live_oops_size;
       
   299   }
       
   300 }
       
   301 
       
   302 
       
   303 void MarkSweep::print_new_location_of_heap_address(HeapWord* q) {
       
   304   if (!RecordMarkSweepCompaction) {
       
   305     tty->print_cr("Requires RecordMarkSweepCompaction to be enabled");
       
   306     return;
       
   307   }
       
   308 
       
   309   if (_last_gc_live_oops == NULL) {
       
   310     tty->print_cr("No compaction information gathered yet");
       
   311     return;
       
   312   }
       
   313 
       
   314   for (int i = 0; i < _last_gc_live_oops->length(); i++) {
       
   315     HeapWord* old_oop = _last_gc_live_oops->at(i);
       
   316     size_t    sz      = _last_gc_live_oops_size->at(i);
       
   317     if (old_oop <= q && q < (old_oop + sz)) {
       
   318       HeapWord* new_oop = _last_gc_live_oops_moved_to->at(i);
       
   319       size_t offset = (q - old_oop);
       
   320       tty->print_cr("Address " PTR_FORMAT, q);
       
   321       tty->print_cr(" Was in oop " PTR_FORMAT ", size %d, at offset %d", old_oop, sz, offset);
       
   322       tty->print_cr(" Now in oop " PTR_FORMAT ", actual address " PTR_FORMAT, new_oop, new_oop + offset);
       
   323       return;
       
   324     }
       
   325   }
       
   326 
       
   327   tty->print_cr("Address " PTR_FORMAT " not found in live oop information from last GC", q);
       
   328 }
       
   329 #endif //VALIDATE_MARK_SWEEP
       
   330 
       
   331 MarkSweep::IsAliveClosure MarkSweep::is_alive;
       
   332 
       
   333 void MarkSweep::KeepAliveClosure::do_oop(oop* p) {
       
   334 #ifdef VALIDATE_MARK_SWEEP
       
   335   if (ValidateMarkSweep) {
       
   336     if (!Universe::heap()->is_in_reserved(p)) {
       
   337       _root_refs_stack->push(p);
       
   338     } else {
       
   339       _other_refs_stack->push(p);
       
   340     }
       
   341   }
       
   342 #endif
       
   343   mark_and_push(p);
       
   344 }
       
   345 
       
   346 MarkSweep::KeepAliveClosure MarkSweep::keep_alive;
       
   347 
       
   348 void marksweep_init() { /* empty */ }
       
   349 
       
   350 #ifndef PRODUCT
       
   351 
       
   352 void MarkSweep::trace(const char* msg) {
       
   353   if (TraceMarkSweep)
       
   354     gclog_or_tty->print("%s", msg);
       
   355 }
       
   356 
       
   357 #endif