< prev index next >

src/share/vm/gc/parallel/psMarkSweepDecorator.cpp

Print this page




  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  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/systemDictionary.hpp"
  27 #include "gc/parallel/objectStartArray.hpp"
  28 #include "gc/parallel/parallelScavengeHeap.hpp"
  29 #include "gc/parallel/psMarkSweep.hpp"
  30 #include "gc/parallel/psMarkSweepDecorator.hpp"
  31 #include "gc/serial/markSweep.inline.hpp"
  32 #include "gc/shared/liveRange.hpp"
  33 #include "gc/shared/spaceDecorator.hpp"
  34 #include "oops/oop.inline.hpp"
  35 #include "runtime/prefetch.inline.hpp"
  36 
  37 PSMarkSweepDecorator* PSMarkSweepDecorator::_destination_decorator = NULL;
  38 
  39 
  40 void PSMarkSweepDecorator::set_destination_decorator_tenured() {
  41   ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
  42   _destination_decorator = heap->old_gen()->object_mark_sweep();
  43 }
  44 
  45 void PSMarkSweepDecorator::advance_destination_decorator() {
  46   ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
  47 
  48   assert(_destination_decorator != NULL, "Sanity");
  49 
  50   PSMarkSweepDecorator* first = heap->old_gen()->object_mark_sweep();
  51   PSMarkSweepDecorator* second = heap->young_gen()->eden_mark_sweep();
  52   PSMarkSweepDecorator* third = heap->young_gen()->from_mark_sweep();


  90 
  91   size_t allowed_deadspace = 0;
  92   if (skip_dead) {
  93     const size_t ratio = allowed_dead_ratio();
  94     allowed_deadspace = space()->capacity_in_words() * ratio / 100;
  95   }
  96 
  97   // Fetch the current destination decorator
  98   PSMarkSweepDecorator* dest = destination_decorator();
  99   ObjectStartArray* start_array = dest->start_array();
 100 
 101   HeapWord* compact_top = dest->compaction_top();
 102   HeapWord* compact_end = dest->space()->end();
 103 
 104   HeapWord* q = space()->bottom();
 105   HeapWord* t = space()->top();
 106 
 107   HeapWord*  end_of_live= q;    /* One byte beyond the last byte of the last
 108                                    live object. */
 109   HeapWord*  first_dead = space()->end(); /* The first dead object. */
 110   LiveRange* liveRange  = NULL; /* The current live range, recorded in the
 111                                    first header of preceding free area. */
 112   _first_dead = first_dead;
 113 
 114   const intx interval = PrefetchScanIntervalInBytes;
 115 
 116   while (q < t) {
 117     assert(oop(q)->mark()->is_marked() || oop(q)->mark()->is_unlocked() ||
 118            oop(q)->mark()->has_bias_pattern(),
 119            "these are the only valid states during a mark sweep");
 120     if (oop(q)->is_gc_marked()) {
 121       /* prefetch beyond q */
 122       Prefetch::write(q, interval);
 123       size_t size = oop(q)->size();
 124 
 125       size_t compaction_max_size = pointer_delta(compact_end, compact_top);
 126 
 127       // This should only happen if a space in the young gen overflows the
 128       // old gen. If that should happen, we null out the start_array, because
 129       // the young spaces are not covered by one.
 130       while(size > compaction_max_size) {
 131         // First record the last compact_top
 132         dest->set_compaction_top(compact_top);


 214             // mark and handle it specially later on.
 215             oop(q)->init_mark();
 216             assert(oop(q)->forwardee() == NULL, "should be forwarded to NULL");
 217           }
 218 
 219           // Update object start array
 220           if (start_array) {
 221             start_array->allocate_block(compact_top);
 222           }
 223 
 224           compact_top += sz;
 225           assert(compact_top <= dest->space()->end(),
 226             "Exceeding space in destination");
 227 
 228           q = end;
 229           end_of_live = end;
 230           continue;
 231         }
 232       }
 233 
 234       /* for the previous LiveRange, record the end of the live objects. */
 235       if (liveRange) {
 236         liveRange->set_end(q);
 237       }
 238 
 239       /* record the current LiveRange object.
 240        * liveRange->start() is overlaid on the mark word.
 241        */
 242       liveRange = (LiveRange*)q;
 243       liveRange->set_start(end);
 244       liveRange->set_end(end);
 245 
 246       /* see if this is the first dead region. */
 247       if (q < first_dead) {
 248         first_dead = q;
 249       }
 250 
 251       /* move on to the next object */
 252       q = end;
 253     }
 254   }
 255 
 256   assert(q == t, "just checking");
 257   if (liveRange != NULL) {
 258     liveRange->set_end(q);
 259   }
 260   _end_of_live = end_of_live;
 261   if (end_of_live < first_dead) {
 262     first_dead = end_of_live;
 263   }
 264   _first_dead = first_dead;
 265 
 266   // Update compaction top
 267   dest->set_compaction_top(compact_top);
 268 }
 269 
 270 bool PSMarkSweepDecorator::insert_deadspace(size_t& allowed_deadspace_words,
 271                                             HeapWord* q, size_t deadlength) {
 272   if (allowed_deadspace_words >= deadlength) {
 273     allowed_deadspace_words -= deadlength;
 274     CollectedHeap::fill_with_object(q, deadlength);
 275     oop(q)->set_mark(oop(q)->mark()->set_marked());
 276     assert((int) deadlength == oop(q)->size(), "bad filler object size");
 277     // Recall that we required "q == compaction_top".
 278     return true;
 279   } else {


 290   HeapWord* t = _end_of_live;  // Established by "prepare_for_compaction".
 291 
 292   assert(_first_dead <= _end_of_live, "Stands to reason, no?");
 293 
 294   if (q < t && _first_dead > q &&
 295       !oop(q)->is_gc_marked()) {
 296     // we have a chunk of the space which hasn't moved and we've
 297     // reinitialized the mark word during the previous pass, so we can't
 298     // use is_gc_marked for the traversal.
 299     HeapWord* end = _first_dead;
 300 
 301     while (q < end) {
 302       // point all the oops to the new location
 303       size_t size = MarkSweep::adjust_pointers(oop(q));
 304       q += size;
 305     }
 306 
 307     if (_first_dead == t) {
 308       q = t;
 309     } else {
 310       // $$$ This is funky.  Using this to read the previously written
 311       // LiveRange.  See also use below.
 312       q = (HeapWord*)oop(_first_dead)->mark()->decode_pointer();
 313     }
 314   }
 315   const intx interval = PrefetchScanIntervalInBytes;
 316 
 317   debug_only(HeapWord* prev_q = NULL);
 318   while (q < t) {
 319     // prefetch beyond q
 320     Prefetch::write(q, interval);
 321     if (oop(q)->is_gc_marked()) {
 322       // q is alive
 323       // point all the oops to the new location
 324       size_t size = MarkSweep::adjust_pointers(oop(q));
 325       debug_only(prev_q = q);
 326       q += size;
 327     } else {
 328       // q is not a live object, so its mark should point at the next
 329       // live object
 330       debug_only(prev_q = q);
 331       q = (HeapWord*) oop(q)->mark()->decode_pointer();
 332       assert(q > prev_q, "we should be moving forward through memory");

 333     }
 334   }
 335 
 336   assert(q == t, "just checking");
 337 }
 338 
 339 void PSMarkSweepDecorator::compact(bool mangle_free_space ) {
 340   // Copy all live objects to their new location
 341   // Used by MarkSweep::mark_sweep_phase4()
 342 
 343   HeapWord*       q = space()->bottom();
 344   HeapWord* const t = _end_of_live;
 345   debug_only(HeapWord* prev_q = NULL);
 346 
 347   if (q < t && _first_dead > q &&
 348       !oop(q)->is_gc_marked()) {
 349 #ifdef ASSERT
 350     // we have a chunk of the space which hasn't moved and we've reinitialized the
 351     // mark word during the previous pass, so we can't use is_gc_marked for the
 352     // traversal.




  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  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/systemDictionary.hpp"
  27 #include "gc/parallel/objectStartArray.hpp"
  28 #include "gc/parallel/parallelScavengeHeap.hpp"
  29 #include "gc/parallel/psMarkSweep.hpp"
  30 #include "gc/parallel/psMarkSweepDecorator.hpp"
  31 #include "gc/serial/markSweep.inline.hpp"

  32 #include "gc/shared/spaceDecorator.hpp"
  33 #include "oops/oop.inline.hpp"
  34 #include "runtime/prefetch.inline.hpp"
  35 
  36 PSMarkSweepDecorator* PSMarkSweepDecorator::_destination_decorator = NULL;
  37 
  38 
  39 void PSMarkSweepDecorator::set_destination_decorator_tenured() {
  40   ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
  41   _destination_decorator = heap->old_gen()->object_mark_sweep();
  42 }
  43 
  44 void PSMarkSweepDecorator::advance_destination_decorator() {
  45   ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
  46 
  47   assert(_destination_decorator != NULL, "Sanity");
  48 
  49   PSMarkSweepDecorator* first = heap->old_gen()->object_mark_sweep();
  50   PSMarkSweepDecorator* second = heap->young_gen()->eden_mark_sweep();
  51   PSMarkSweepDecorator* third = heap->young_gen()->from_mark_sweep();


  89 
  90   size_t allowed_deadspace = 0;
  91   if (skip_dead) {
  92     const size_t ratio = allowed_dead_ratio();
  93     allowed_deadspace = space()->capacity_in_words() * ratio / 100;
  94   }
  95 
  96   // Fetch the current destination decorator
  97   PSMarkSweepDecorator* dest = destination_decorator();
  98   ObjectStartArray* start_array = dest->start_array();
  99 
 100   HeapWord* compact_top = dest->compaction_top();
 101   HeapWord* compact_end = dest->space()->end();
 102 
 103   HeapWord* q = space()->bottom();
 104   HeapWord* t = space()->top();
 105 
 106   HeapWord*  end_of_live= q;    /* One byte beyond the last byte of the last
 107                                    live object. */
 108   HeapWord*  first_dead = space()->end(); /* The first dead object. */



 109 
 110   const intx interval = PrefetchScanIntervalInBytes;
 111 
 112   while (q < t) {
 113     assert(oop(q)->mark()->is_marked() || oop(q)->mark()->is_unlocked() ||
 114            oop(q)->mark()->has_bias_pattern(),
 115            "these are the only valid states during a mark sweep");
 116     if (oop(q)->is_gc_marked()) {
 117       /* prefetch beyond q */
 118       Prefetch::write(q, interval);
 119       size_t size = oop(q)->size();
 120 
 121       size_t compaction_max_size = pointer_delta(compact_end, compact_top);
 122 
 123       // This should only happen if a space in the young gen overflows the
 124       // old gen. If that should happen, we null out the start_array, because
 125       // the young spaces are not covered by one.
 126       while(size > compaction_max_size) {
 127         // First record the last compact_top
 128         dest->set_compaction_top(compact_top);


 210             // mark and handle it specially later on.
 211             oop(q)->init_mark();
 212             assert(oop(q)->forwardee() == NULL, "should be forwarded to NULL");
 213           }
 214 
 215           // Update object start array
 216           if (start_array) {
 217             start_array->allocate_block(compact_top);
 218           }
 219 
 220           compact_top += sz;
 221           assert(compact_top <= dest->space()->end(),
 222             "Exceeding space in destination");
 223 
 224           q = end;
 225           end_of_live = end;
 226           continue;
 227         }
 228       }
 229 
 230       // q is a pointer to a dead object. Use this dead memory to store a pointer to the next live object.
 231       (*(HeapWord**)q) = end;









 232 
 233       /* see if this is the first dead region. */
 234       if (q < first_dead) {
 235         first_dead = q;
 236       }
 237 
 238       /* move on to the next object */
 239       q = end;
 240     }
 241   }
 242 
 243   assert(q == t, "just checking");



 244   _end_of_live = end_of_live;
 245   if (end_of_live < first_dead) {
 246     first_dead = end_of_live;
 247   }
 248   _first_dead = first_dead;
 249 
 250   // Update compaction top
 251   dest->set_compaction_top(compact_top);
 252 }
 253 
 254 bool PSMarkSweepDecorator::insert_deadspace(size_t& allowed_deadspace_words,
 255                                             HeapWord* q, size_t deadlength) {
 256   if (allowed_deadspace_words >= deadlength) {
 257     allowed_deadspace_words -= deadlength;
 258     CollectedHeap::fill_with_object(q, deadlength);
 259     oop(q)->set_mark(oop(q)->mark()->set_marked());
 260     assert((int) deadlength == oop(q)->size(), "bad filler object size");
 261     // Recall that we required "q == compaction_top".
 262     return true;
 263   } else {


 274   HeapWord* t = _end_of_live;  // Established by "prepare_for_compaction".
 275 
 276   assert(_first_dead <= _end_of_live, "Stands to reason, no?");
 277 
 278   if (q < t && _first_dead > q &&
 279       !oop(q)->is_gc_marked()) {
 280     // we have a chunk of the space which hasn't moved and we've
 281     // reinitialized the mark word during the previous pass, so we can't
 282     // use is_gc_marked for the traversal.
 283     HeapWord* end = _first_dead;
 284 
 285     while (q < end) {
 286       // point all the oops to the new location
 287       size_t size = MarkSweep::adjust_pointers(oop(q));
 288       q += size;
 289     }
 290 
 291     if (_first_dead == t) {
 292       q = t;
 293     } else {
 294       // The first dead object should contain a pointer to the first live object
 295       q = *(HeapWord**)_first_dead;

 296     }
 297   }
 298   const intx interval = PrefetchScanIntervalInBytes;
 299 
 300   debug_only(HeapWord* prev_q = NULL);
 301   while (q < t) {
 302     // prefetch beyond q
 303     Prefetch::write(q, interval);
 304     if (oop(q)->is_gc_marked()) {
 305       // q is alive
 306       // point all the oops to the new location
 307       size_t size = MarkSweep::adjust_pointers(oop(q));
 308       debug_only(prev_q = q);
 309       q += size;
 310     } else {


 311       debug_only(prev_q = q);
 312       // q is not a live object, instead it points at the next live object
 313       q = *(HeapWord**)q;
 314       assert(q > prev_q, "we should be moving forward through memory, q: " PTR_FORMAT ", prev_q: " PTR_FORMAT, p2i(q), p2i(prev_q));
 315     }
 316   }
 317 
 318   assert(q == t, "just checking");
 319 }
 320 
 321 void PSMarkSweepDecorator::compact(bool mangle_free_space ) {
 322   // Copy all live objects to their new location
 323   // Used by MarkSweep::mark_sweep_phase4()
 324 
 325   HeapWord*       q = space()->bottom();
 326   HeapWord* const t = _end_of_live;
 327   debug_only(HeapWord* prev_q = NULL);
 328 
 329   if (q < t && _first_dead > q &&
 330       !oop(q)->is_gc_marked()) {
 331 #ifdef ASSERT
 332     // we have a chunk of the space which hasn't moved and we've reinitialized the
 333     // mark word during the previous pass, so we can't use is_gc_marked for the
 334     // traversal.


< prev index next >