1 /*
   2  * Copyright 1997-2008 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 GrowableArray<DataLayout*>*  MarkSweep::_revisit_mdo_stack = NULL;
  31 
  32 GrowableArray<oop>*     MarkSweep::_preserved_oop_stack = NULL;
  33 GrowableArray<markOop>* MarkSweep::_preserved_mark_stack= NULL;
  34 size_t                  MarkSweep::_preserved_count = 0;
  35 size_t                  MarkSweep::_preserved_count_max = 0;
  36 PreservedMark*          MarkSweep::_preserved_marks = NULL;
  37 ReferenceProcessor*     MarkSweep::_ref_processor   = NULL;
  38 
  39 #ifdef VALIDATE_MARK_SWEEP
  40 GrowableArray<void*>*   MarkSweep::_root_refs_stack = NULL;
  41 GrowableArray<oop> *    MarkSweep::_live_oops = NULL;
  42 GrowableArray<oop> *    MarkSweep::_live_oops_moved_to = NULL;
  43 GrowableArray<size_t>*  MarkSweep::_live_oops_size = NULL;
  44 size_t                  MarkSweep::_live_oops_index = 0;
  45 size_t                  MarkSweep::_live_oops_index_at_perm = 0;
  46 GrowableArray<void*>*   MarkSweep::_other_refs_stack = NULL;
  47 GrowableArray<void*>*   MarkSweep::_adjusted_pointers = NULL;
  48 bool                         MarkSweep::_pointer_tracking = false;
  49 bool                         MarkSweep::_root_tracking = true;
  50 
  51 GrowableArray<HeapWord*>* MarkSweep::_cur_gc_live_oops = NULL;
  52 GrowableArray<HeapWord*>* MarkSweep::_cur_gc_live_oops_moved_to = NULL;
  53 GrowableArray<size_t>   * MarkSweep::_cur_gc_live_oops_size = NULL;
  54 GrowableArray<HeapWord*>* MarkSweep::_last_gc_live_oops = NULL;
  55 GrowableArray<HeapWord*>* MarkSweep::_last_gc_live_oops_moved_to = NULL;
  56 GrowableArray<size_t>   * MarkSweep::_last_gc_live_oops_size = NULL;
  57 #endif
  58 
  59 void MarkSweep::revisit_weak_klass_link(Klass* k) {
  60   _revisit_klass_stack->push(k);
  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   if (PrintRevisitStats) {
  67     gclog_or_tty->print_cr("#classes in system dictionary = %d", SystemDictionary::number_of_classes());
  68     gclog_or_tty->print_cr("Revisit klass stack length = %d", _revisit_klass_stack->length());
  69   }
  70   for (int i = 0; i < _revisit_klass_stack->length(); i++) {
  71     _revisit_klass_stack->at(i)->follow_weak_klass_links(&is_alive,&keep_alive);
  72   }
  73   follow_stack();
  74 }
  75 
  76 #if ( defined(COMPILER1) || defined(COMPILER2) )
  77 void MarkSweep::revisit_mdo(DataLayout* p) {
  78   _revisit_mdo_stack->push(p);
  79 }
  80 
  81 void MarkSweep::follow_mdo_weak_refs() {
  82   // All strongly reachable oops have been marked at this point;
  83   // we can visit and clear any weak references from MDO's which
  84   // we memoized during the strong marking phase.
  85   assert(_marking_stack->is_empty(), "Marking stack should be empty");
  86   if (PrintRevisitStats) {
  87     gclog_or_tty->print_cr("#classes in system dictionary = %d", SystemDictionary::number_of_classes());
  88     gclog_or_tty->print_cr("Revisit MDO stack length = %d", _revisit_mdo_stack->length());
  89   }
  90   for (int i = 0; i < _revisit_mdo_stack->length(); i++) {
  91     _revisit_mdo_stack->at(i)->follow_weak_refs(&is_alive);
  92   }
  93   follow_stack();
  94 }
  95 #endif //  ( COMPILER1 || COMPILER2 )
  96 
  97 MarkSweep::FollowRootClosure  MarkSweep::follow_root_closure;
  98 
  99 void MarkSweep::FollowRootClosure::do_oop(oop* p)       { follow_root(p); }
 100 void MarkSweep::FollowRootClosure::do_oop(narrowOop* p) { follow_root(p); }
 101 
 102 MarkSweep::MarkAndPushClosure MarkSweep::mark_and_push_closure;
 103 
 104 void MarkSweep::MarkAndPushClosure::do_oop(oop* p)       { mark_and_push(p); }
 105 void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(p); }
 106 
 107 void MarkSweep::follow_stack() {
 108   while (!_marking_stack->is_empty()) {
 109     oop obj = _marking_stack->pop();
 110     assert (obj->is_gc_marked(), "p must be marked");
 111     obj->follow_contents();
 112   }
 113 }
 114 
 115 MarkSweep::FollowStackClosure MarkSweep::follow_stack_closure;
 116 
 117 void MarkSweep::FollowStackClosure::do_void() { follow_stack(); }
 118 
 119 // We preserve the mark which should be replaced at the end and the location that it
 120 // will go.  Note that the object that this markOop belongs to isn't currently at that
 121 // address but it will be after phase4
 122 void MarkSweep::preserve_mark(oop obj, markOop mark) {
 123   // we try to store preserved marks in the to space of the new generation since this
 124   // is storage which should be available.  Most of the time this should be sufficient
 125   // space for the marks we need to preserve but if it isn't we fall back in using
 126   // GrowableArrays to keep track of the overflow.
 127   if (_preserved_count < _preserved_count_max) {
 128     _preserved_marks[_preserved_count++].init(obj, mark);
 129   } else {
 130     if (_preserved_mark_stack == NULL) {
 131       _preserved_mark_stack = new (ResourceObj::C_HEAP) GrowableArray<markOop>(40, true);
 132       _preserved_oop_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(40, true);
 133     }
 134     _preserved_mark_stack->push(mark);
 135     _preserved_oop_stack->push(obj);
 136   }
 137 }
 138 
 139 MarkSweep::AdjustPointerClosure MarkSweep::adjust_root_pointer_closure(true);
 140 MarkSweep::AdjustPointerClosure MarkSweep::adjust_pointer_closure(false);
 141 
 142 void MarkSweep::AdjustPointerClosure::do_oop(oop* p)       { adjust_pointer(p, _is_root); }
 143 void MarkSweep::AdjustPointerClosure::do_oop(narrowOop* p) { adjust_pointer(p, _is_root); }
 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(void* p, 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         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 }
 213 
 214 void MarkSweep::check_adjust_pointer(void* p) {
 215   _adjusted_pointers->push(p);
 216 }
 217 
 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 };
 224 
 225 void MarkSweep::track_interior_pointers(oop obj) {
 226   if (ValidateMarkSweep) {
 227     _adjusted_pointers->clear();
 228     _pointer_tracking = true;
 229 
 230     AdjusterTracker checker;
 231     obj->oop_iterate(&checker);
 232   }
 233 }
 234 
 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 }
 241 
 242 void MarkSweep::reset_live_oop_tracking(bool at_perm) {
 243   if (ValidateMarkSweep) {
 244     guarantee((size_t)_live_oops->length() == _live_oops_index, "should be at end of live oops");
 245     _live_oops_index = at_perm ? _live_oops_index_at_perm : 0;
 246   }
 247 }
 248 
 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 }
 256 
 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 }
 265 
 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 }
 280 
 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;
 286 
 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 }
 295 
 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   }
 301 
 302   if (_last_gc_live_oops == NULL) {
 303     tty->print_cr("No compaction information gathered yet");
 304     return;
 305   }
 306 
 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   }
 319 
 320   tty->print_cr("Address " PTR_FORMAT " not found in live oop information from last GC", q);
 321 }
 322 #endif //VALIDATE_MARK_SWEEP
 323 
 324 MarkSweep::IsAliveClosure   MarkSweep::is_alive;
 325 
 326 void MarkSweep::IsAliveClosure::do_object(oop p)   { ShouldNotReachHere(); }
 327 bool MarkSweep::IsAliveClosure::do_object_b(oop p) { return p->is_gc_marked(); }
 328 
 329 MarkSweep::KeepAliveClosure MarkSweep::keep_alive;
 330 
 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); }
 333 
 334 void marksweep_init() { /* empty */ }
 335 
 336 #ifndef PRODUCT
 337 
 338 void MarkSweep::trace(const char* msg) {
 339   if (TraceMarkSweep)
 340     gclog_or_tty->print("%s", msg);
 341 }
 342 
 343 #endif