< prev index next >

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

Print this page




  58     _destination_decorator = second;
  59   } else if ( _destination_decorator == second ) {
  60     _destination_decorator = third;
  61   } else if ( _destination_decorator == third ) {
  62     _destination_decorator = fourth;
  63   } else {
  64     fatal("PSMarkSweep attempting to advance past last compaction area");
  65   }
  66 }
  67 
  68 PSMarkSweepDecorator* PSMarkSweepDecorator::destination_decorator() {
  69   assert(_destination_decorator != NULL, "Sanity");
  70 
  71   return _destination_decorator;
  72 }
  73 
  74 // FIX ME FIX ME FIX ME FIX ME!!!!!!!!!
  75 // The object forwarding code is duplicated. Factor this out!!!!!
  76 //
  77 // This method "precompacts" objects inside its space to dest. It places forwarding
  78 // pointers into markWords for use by adjust_pointers. If "dest" should overflow, we
  79 // finish by compacting into our own space.
  80 
  81 void PSMarkSweepDecorator::precompact() {
  82   // Reset our own compact top.
  83   set_compaction_top(space()->bottom());
  84 
  85   /* We allow some amount of garbage towards the bottom of the space, so
  86    * we don't start compacting before there is a significant gain to be made.
  87    * Occasionally, we want to ensure a full compaction, which is determined
  88    * by the MarkSweepAlwaysCompactCount parameter. This is a significant
  89    * performance improvement!
  90    */
  91   bool skip_dead = ((PSMarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0);
  92 
  93   size_t allowed_deadspace = 0;
  94   if (skip_dead) {
  95     const size_t ratio = allowed_dead_ratio();
  96     allowed_deadspace = space()->capacity_in_words() * ratio / 100;
  97   }
  98 
  99   // Fetch the current destination decorator
 100   PSMarkSweepDecorator* dest = destination_decorator();
 101   ObjectStartArray* start_array = dest->start_array();
 102 
 103   HeapWord* compact_top = dest->compaction_top();
 104   HeapWord* compact_end = dest->space()->end();
 105 
 106   HeapWord* q = space()->bottom();
 107   HeapWord* t = space()->top();
 108 
 109   HeapWord*  end_of_live= q;    /* One byte beyond the last byte of the last
 110                                    live object. */
 111   HeapWord*  first_dead = space()->end(); /* The first dead object. */
 112 
 113   const intx interval = PrefetchScanIntervalInBytes;
 114 
 115   while (q < t) {
 116     assert(oop(q)->mark_raw().is_marked() || oop(q)->mark_raw().is_unlocked() ||
 117            oop(q)->mark_raw().has_bias_pattern(),
 118            "these are the only valid states during a mark sweep");
 119     if (oop(q)->is_gc_marked()) {
 120       /* prefetch beyond q */
 121       Prefetch::write(q, interval);
 122       size_t size = oop(q)->size();
 123 
 124       size_t compaction_max_size = pointer_delta(compact_end, compact_top);
 125 
 126       // This should only happen if a space in the young gen overflows the
 127       // old gen. If that should happen, we null out the start_array, because
 128       // the young spaces are not covered by one.
 129       while(size > compaction_max_size) {
 130         // First record the last compact_top
 131         dest->set_compaction_top(compact_top);
 132 
 133         // Advance to the next compaction decorator
 134         advance_destination_decorator();
 135         dest = destination_decorator();
 136 
 137         // Update compaction info


 242       q = end;
 243     }
 244   }
 245 
 246   assert(q == t, "just checking");
 247   _end_of_live = end_of_live;
 248   if (end_of_live < first_dead) {
 249     first_dead = end_of_live;
 250   }
 251   _first_dead = first_dead;
 252 
 253   // Update compaction top
 254   dest->set_compaction_top(compact_top);
 255 }
 256 
 257 bool PSMarkSweepDecorator::insert_deadspace(size_t& allowed_deadspace_words,
 258                                             HeapWord* q, size_t deadlength) {
 259   if (allowed_deadspace_words >= deadlength) {
 260     allowed_deadspace_words -= deadlength;
 261     CollectedHeap::fill_with_object(q, deadlength);
 262     oop(q)->set_mark_raw(oop(q)->mark_raw().set_marked());
 263     assert((int) deadlength == oop(q)->size(), "bad filler object size");
 264     // Recall that we required "q == compaction_top".
 265     return true;
 266   } else {
 267     allowed_deadspace_words = 0;
 268     return false;
 269   }
 270 }
 271 
 272 void PSMarkSweepDecorator::adjust_pointers() {
 273   // adjust all the interior pointers to point at the new locations of objects
 274   // Used by MarkSweep::mark_sweep_phase3()
 275 
 276   HeapWord* q = space()->bottom();
 277   HeapWord* t = _end_of_live;  // Established by "prepare_for_compaction".
 278 
 279   assert(_first_dead <= _end_of_live, "Stands to reason, no?");
 280 
 281   if (q < t && _first_dead > q &&
 282       !oop(q)->is_gc_marked()) {


 333   if (q < t && _first_dead > q &&
 334       !oop(q)->is_gc_marked()) {
 335 #ifdef ASSERT
 336     // we have a chunk of the space which hasn't moved and we've reinitialized the
 337     // mark word during the previous pass, so we can't use is_gc_marked for the
 338     // traversal.
 339     HeapWord* const end = _first_dead;
 340 
 341     while (q < end) {
 342       size_t size = oop(q)->size();
 343       assert(!oop(q)->is_gc_marked(), "should be unmarked (special dense prefix handling)");
 344       debug_only(prev_q = q);
 345       q += size;
 346     }
 347 #endif
 348 
 349     if (_first_dead == t) {
 350       q = t;
 351     } else {
 352       // $$$ Funky
 353       q = (HeapWord*) oop(_first_dead)->mark_raw().decode_pointer();
 354     }
 355   }
 356 
 357   const intx scan_interval = PrefetchScanIntervalInBytes;
 358   const intx copy_interval = PrefetchCopyIntervalInBytes;
 359 
 360   while (q < t) {
 361     if (!oop(q)->is_gc_marked()) {
 362       // mark is pointer to next marked oop
 363       debug_only(prev_q = q);
 364       q = (HeapWord*) oop(q)->mark_raw().decode_pointer();
 365       assert(q > prev_q, "we should be moving forward through memory");
 366     } else {
 367       // prefetch beyond q
 368       Prefetch::read(q, scan_interval);
 369 
 370       // size and destination
 371       size_t size = oop(q)->size();
 372       HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee();
 373 
 374       // prefetch beyond compaction_top
 375       Prefetch::write(compaction_top, copy_interval);
 376 
 377       // copy object and reinit its mark
 378       assert(q != compaction_top, "everything in this pass should be moving");
 379       Copy::aligned_conjoint_words(q, compaction_top, size);
 380       oop(compaction_top)->init_mark_raw();
 381       assert(oop(compaction_top)->klass() != NULL, "should have a class");
 382 
 383       debug_only(prev_q = q);
 384       q += size;


  58     _destination_decorator = second;
  59   } else if ( _destination_decorator == second ) {
  60     _destination_decorator = third;
  61   } else if ( _destination_decorator == third ) {
  62     _destination_decorator = fourth;
  63   } else {
  64     fatal("PSMarkSweep attempting to advance past last compaction area");
  65   }
  66 }
  67 
  68 PSMarkSweepDecorator* PSMarkSweepDecorator::destination_decorator() {
  69   assert(_destination_decorator != NULL, "Sanity");
  70 
  71   return _destination_decorator;
  72 }
  73 
  74 // FIX ME FIX ME FIX ME FIX ME!!!!!!!!!
  75 // The object forwarding code is duplicated. Factor this out!!!!!
  76 //
  77 // This method "precompacts" objects inside its space to dest. It places forwarding
  78 // pointers into markOops for use by adjust_pointers. If "dest" should overflow, we
  79 // finish by compacting into our own space.
  80 
  81 void PSMarkSweepDecorator::precompact() {
  82   // Reset our own compact top.
  83   set_compaction_top(space()->bottom());
  84 
  85   /* We allow some amount of garbage towards the bottom of the space, so
  86    * we don't start compacting before there is a significant gain to be made.
  87    * Occasionally, we want to ensure a full compaction, which is determined
  88    * by the MarkSweepAlwaysCompactCount parameter. This is a significant
  89    * performance improvement!
  90    */
  91   bool skip_dead = ((PSMarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0);
  92 
  93   size_t allowed_deadspace = 0;
  94   if (skip_dead) {
  95     const size_t ratio = allowed_dead_ratio();
  96     allowed_deadspace = space()->capacity_in_words() * ratio / 100;
  97   }
  98 
  99   // Fetch the current destination decorator
 100   PSMarkSweepDecorator* dest = destination_decorator();
 101   ObjectStartArray* start_array = dest->start_array();
 102 
 103   HeapWord* compact_top = dest->compaction_top();
 104   HeapWord* compact_end = dest->space()->end();
 105 
 106   HeapWord* q = space()->bottom();
 107   HeapWord* t = space()->top();
 108 
 109   HeapWord*  end_of_live= q;    /* One byte beyond the last byte of the last
 110                                    live object. */
 111   HeapWord*  first_dead = space()->end(); /* The first dead object. */
 112 
 113   const intx interval = PrefetchScanIntervalInBytes;
 114 
 115   while (q < t) {
 116     assert(oop(q)->mark_raw()->is_marked() || oop(q)->mark_raw()->is_unlocked() ||
 117            oop(q)->mark_raw()->has_bias_pattern(),
 118            "these are the only valid states during a mark sweep");
 119     if (oop(q)->is_gc_marked()) {
 120       /* prefetch beyond q */
 121       Prefetch::write(q, interval);
 122       size_t size = oop(q)->size();
 123 
 124       size_t compaction_max_size = pointer_delta(compact_end, compact_top);
 125 
 126       // This should only happen if a space in the young gen overflows the
 127       // old gen. If that should happen, we null out the start_array, because
 128       // the young spaces are not covered by one.
 129       while(size > compaction_max_size) {
 130         // First record the last compact_top
 131         dest->set_compaction_top(compact_top);
 132 
 133         // Advance to the next compaction decorator
 134         advance_destination_decorator();
 135         dest = destination_decorator();
 136 
 137         // Update compaction info


 242       q = end;
 243     }
 244   }
 245 
 246   assert(q == t, "just checking");
 247   _end_of_live = end_of_live;
 248   if (end_of_live < first_dead) {
 249     first_dead = end_of_live;
 250   }
 251   _first_dead = first_dead;
 252 
 253   // Update compaction top
 254   dest->set_compaction_top(compact_top);
 255 }
 256 
 257 bool PSMarkSweepDecorator::insert_deadspace(size_t& allowed_deadspace_words,
 258                                             HeapWord* q, size_t deadlength) {
 259   if (allowed_deadspace_words >= deadlength) {
 260     allowed_deadspace_words -= deadlength;
 261     CollectedHeap::fill_with_object(q, deadlength);
 262     oop(q)->set_mark_raw(oop(q)->mark_raw()->set_marked());
 263     assert((int) deadlength == oop(q)->size(), "bad filler object size");
 264     // Recall that we required "q == compaction_top".
 265     return true;
 266   } else {
 267     allowed_deadspace_words = 0;
 268     return false;
 269   }
 270 }
 271 
 272 void PSMarkSweepDecorator::adjust_pointers() {
 273   // adjust all the interior pointers to point at the new locations of objects
 274   // Used by MarkSweep::mark_sweep_phase3()
 275 
 276   HeapWord* q = space()->bottom();
 277   HeapWord* t = _end_of_live;  // Established by "prepare_for_compaction".
 278 
 279   assert(_first_dead <= _end_of_live, "Stands to reason, no?");
 280 
 281   if (q < t && _first_dead > q &&
 282       !oop(q)->is_gc_marked()) {


 333   if (q < t && _first_dead > q &&
 334       !oop(q)->is_gc_marked()) {
 335 #ifdef ASSERT
 336     // we have a chunk of the space which hasn't moved and we've reinitialized the
 337     // mark word during the previous pass, so we can't use is_gc_marked for the
 338     // traversal.
 339     HeapWord* const end = _first_dead;
 340 
 341     while (q < end) {
 342       size_t size = oop(q)->size();
 343       assert(!oop(q)->is_gc_marked(), "should be unmarked (special dense prefix handling)");
 344       debug_only(prev_q = q);
 345       q += size;
 346     }
 347 #endif
 348 
 349     if (_first_dead == t) {
 350       q = t;
 351     } else {
 352       // $$$ Funky
 353       q = (HeapWord*) oop(_first_dead)->mark_raw()->decode_pointer();
 354     }
 355   }
 356 
 357   const intx scan_interval = PrefetchScanIntervalInBytes;
 358   const intx copy_interval = PrefetchCopyIntervalInBytes;
 359 
 360   while (q < t) {
 361     if (!oop(q)->is_gc_marked()) {
 362       // mark is pointer to next marked oop
 363       debug_only(prev_q = q);
 364       q = (HeapWord*) oop(q)->mark_raw()->decode_pointer();
 365       assert(q > prev_q, "we should be moving forward through memory");
 366     } else {
 367       // prefetch beyond q
 368       Prefetch::read(q, scan_interval);
 369 
 370       // size and destination
 371       size_t size = oop(q)->size();
 372       HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee();
 373 
 374       // prefetch beyond compaction_top
 375       Prefetch::write(compaction_top, copy_interval);
 376 
 377       // copy object and reinit its mark
 378       assert(q != compaction_top, "everything in this pass should be moving");
 379       Copy::aligned_conjoint_words(q, compaction_top, size);
 380       oop(compaction_top)->init_mark_raw();
 381       assert(oop(compaction_top)->klass() != NULL, "should have a class");
 382 
 383       debug_only(prev_q = q);
 384       q += size;
< prev index next >