hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp

Print this page
rev 611 : Merge
   1 #ifdef USE_PRAGMA_IDENT_SRC
   2 #pragma ident "@(#)psMarkSweepDecorator.cpp     1.26 07/05/17 15:52:53 JVM"
   3 #endif
   4 /*
   5  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
   6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   7  *
   8  * This code is free software; you can redistribute it and/or modify it
   9  * under the terms of the GNU General Public License version 2 only, as
  10  * published by the Free Software Foundation.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  23  * CA 95054 USA or visit www.sun.com if you need additional information or
  24  * have any questions.
  25  *  


  76 
  77 // FIX ME FIX ME FIX ME FIX ME!!!!!!!!!
  78 // The object forwarding code is duplicated. Factor this out!!!!!
  79 //
  80 // This method "precompacts" objects inside its space to dest. It places forwarding
  81 // pointers into markOops for use by adjust_pointers. If "dest" should overflow, we
  82 // finish by compacting into our own space.
  83 
  84 void PSMarkSweepDecorator::precompact() {
  85   // Reset our own compact top.
  86   set_compaction_top(space()->bottom());
  87 
  88   /* We allow some amount of garbage towards the bottom of the space, so
  89    * we don't start compacting before there is a significant gain to be made.
  90    * Occasionally, we want to ensure a full compaction, which is determined
  91    * by the MarkSweepAlwaysCompactCount parameter. This is a significant
  92    * performance improvement!
  93    */
  94   bool skip_dead = ((PSMarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0);
  95 
  96   ssize_t allowed_deadspace = 0;
  97   if (skip_dead) {
  98     int ratio = allowed_dead_ratio();
  99     allowed_deadspace = (space()->capacity_in_bytes() * ratio / 100) / HeapWordSize;
 100   }
 101 
 102   // Fetch the current destination decorator
 103   PSMarkSweepDecorator* dest = destination_decorator();
 104   ObjectStartArray* start_array = dest->start_array();
 105 
 106   HeapWord* compact_top = dest->compaction_top();
 107   HeapWord* compact_end = dest->space()->end();
 108                                            
 109   HeapWord* q = space()->bottom();                                                    
 110   HeapWord* t = space()->top();                                                
 111   
 112   HeapWord*  end_of_live= q;    /* One byte beyond the last byte of the last 
 113                                    live object. */                           
 114   HeapWord*  first_dead = space()->end(); /* The first dead object. */                 
 115   LiveRange* liveRange  = NULL; /* The current live range, recorded in the   
 116                                    first header of preceding free area. */   
 117   _first_dead = first_dead;                                                  
 118 
 119   const intx interval = PrefetchScanIntervalInBytes;


 138 
 139         // Advance to the next compaction decorator
 140         advance_destination_decorator();
 141         dest = destination_decorator();
 142 
 143         // Update compaction info
 144         start_array = dest->start_array();
 145         compact_top = dest->compaction_top();
 146         compact_end = dest->space()->end();
 147         assert(compact_top == dest->space()->bottom(), "Advanced to space already in use");
 148         assert(compact_end > compact_top, "Must always be space remaining");
 149         compaction_max_size = 
 150           pointer_delta(compact_end, compact_top);
 151       }
 152 
 153       // store the forwarding pointer into the mark word
 154       if (q != compact_top) {
 155         oop(q)->forward_to(oop(compact_top));
 156         assert(oop(q)->is_gc_marked(), "encoding the pointer should preserve the mark");
 157       } else {
 158         // Don't clear the mark since it's confuses parallel old
 159         // verification.
 160         if (!UseParallelOldGC || !VerifyParallelOldWithMarkSweep) {
 161           // if the object isn't moving we can just set the mark to the default
 162           // mark and handle it specially later on.  
 163           oop(q)->init_mark();
 164         }
 165         assert(oop(q)->forwardee() == NULL, "should be forwarded to NULL");
 166       }
 167 
 168       // Update object start array
 169       if (!UseParallelOldGC || !VerifyParallelOldWithMarkSweep) {
 170         if (start_array)
 171           start_array->allocate_block(compact_top);
 172       }
 173 
 174       debug_only(MarkSweep::register_live_oop(oop(q), size));
 175       compact_top += size;
 176       assert(compact_top <= dest->space()->end(), 
 177         "Exceeding space in destination");
 178 
 179       q += size;                                                             
 180       end_of_live = q;                                                       
 181     } else {                                                                 
 182       /* run over all the contiguous dead objects */                         
 183       HeapWord* end = q;                                                     
 184       do {                                                                   
 185         /* prefetch beyond end */                                            
 186         Prefetch::write(end, interval);                            
 187         end += oop(end)->size();
 188       } while (end < t && (!oop(end)->is_gc_marked()));
 189 
 190       /* see if we might want to pretend this object is alive so that
 191        * we don't have to compact quite as often.
 192        */
 193       if (allowed_deadspace > 0 && q == compact_top) {
 194         size_t sz = pointer_delta(end, q);


 205             // Advance to the next compaction decorator
 206             advance_destination_decorator();
 207             dest = destination_decorator();
 208             
 209             // Update compaction info
 210             start_array = dest->start_array();
 211             compact_top = dest->compaction_top();
 212             compact_end = dest->space()->end();
 213             assert(compact_top == dest->space()->bottom(), "Advanced to space already in use");
 214             assert(compact_end > compact_top, "Must always be space remaining");
 215             compaction_max_size = 
 216               pointer_delta(compact_end, compact_top);
 217           }
 218 
 219           // store the forwarding pointer into the mark word
 220           if (q != compact_top) {
 221             oop(q)->forward_to(oop(compact_top));
 222             assert(oop(q)->is_gc_marked(), "encoding the pointer should preserve the mark");
 223           } else {
 224             // if the object isn't moving we can just set the mark to the default
 225             // Don't clear the mark since it's confuses parallel old
 226             // verification.
 227             if (!UseParallelOldGC || !VerifyParallelOldWithMarkSweep) {
 228               // mark and handle it specially later on.  
 229               oop(q)->init_mark();
 230             }
 231             assert(oop(q)->forwardee() == NULL, "should be forwarded to NULL");
 232           }
 233 
 234           if (!UseParallelOldGC || !VerifyParallelOldWithMarkSweep) {
 235             // Update object start array
 236             if (start_array)
 237               start_array->allocate_block(compact_top);
 238           }
 239 
 240           debug_only(MarkSweep::register_live_oop(oop(q), sz));
 241           compact_top += sz;
 242           assert(compact_top <= dest->space()->end(), 
 243             "Exceeding space in destination");
 244 
 245           q = end;
 246           end_of_live = end;
 247           continue;
 248         }
 249       }
 250 
 251       /* for the previous LiveRange, record the end of the live objects. */  
 252       if (liveRange) {                                                       
 253         liveRange->set_end(q);                                               
 254       }                                                                      
 255                                                                              
 256       /* record the current LiveRange object.                                
 257        * liveRange->start() is overlaid on the mark word.                    
 258        */                                                                    
 259       liveRange = (LiveRange*)q;                                             
 260       liveRange->set_start(end);                                             


 267                                                                              
 268       /* move on to the next object */                                       
 269       q = end;                                                               
 270     }                                                                        
 271   }                                                                          
 272                                                                              
 273   assert(q == t, "just checking");                                           
 274   if (liveRange != NULL) {                                                   
 275     liveRange->set_end(q);                                                   
 276   }                                                                          
 277   _end_of_live = end_of_live;                                                
 278   if (end_of_live < first_dead) {                                            
 279     first_dead = end_of_live;                                                
 280   }                                                                          
 281   _first_dead = first_dead;                                                  
 282         
 283   // Update compaction top
 284   dest->set_compaction_top(compact_top);
 285 }
 286 
 287 bool PSMarkSweepDecorator::insert_deadspace(ssize_t& allowed_deadspace_words, 
 288                                        HeapWord* q, size_t deadlength) {

 289   allowed_deadspace_words -= deadlength;
 290   if (allowed_deadspace_words >= 0) {
 291     oop(q)->set_mark(markOopDesc::prototype()->set_marked());
 292     const size_t aligned_min_int_array_size =
 293       align_object_size(typeArrayOopDesc::header_size(T_INT));
 294     if (deadlength >= aligned_min_int_array_size) {
 295       oop(q)->set_klass(Universe::intArrayKlassObj());
 296       assert(((deadlength - aligned_min_int_array_size) * (HeapWordSize/sizeof(jint))) < (size_t)max_jint,
 297                 "deadspace too big for Arrayoop");
 298       typeArrayOop(q)->set_length((int)((deadlength - aligned_min_int_array_size)
 299                                             * (HeapWordSize/sizeof(jint))));
 300     } else {
 301       assert((int) deadlength == instanceOopDesc::header_size(),
 302              "size for smallest fake dead object doesn't match");
 303       oop(q)->set_klass(SystemDictionary::object_klass());
 304     }
 305     assert((int) deadlength == oop(q)->size(),
 306            "make sure size for fake dead object match");
 307     // Recall that we required "q == compaction_top".
 308     return true;
 309   } else {
 310     allowed_deadspace_words = 0;
 311     return false;
 312   }
 313 }
 314 
 315 void PSMarkSweepDecorator::adjust_pointers() {
 316   // adjust all the interior pointers to point at the new locations of objects
 317   // Used by MarkSweep::mark_sweep_phase3()
 318 
 319   HeapWord* q = space()->bottom();
 320   HeapWord* t = _end_of_live;  // Established by "prepare_for_compaction".
 321 
 322   assert(_first_dead <= _end_of_live, "Stands to reason, no?");
 323 
 324   if (q < t && _first_dead > q &&
 325       !oop(q)->is_gc_marked()) {
 326     // we have a chunk of the space which hasn't moved and we've
 327     // reinitialized the mark word during the previous pass, so we can't
 328     // use is_gc_marked for the traversal.
 329     HeapWord* end = _first_dead;
 330 
 331     while (q < end) {
 332       debug_only(MarkSweep::track_interior_pointers(oop(q)));
 333 
 334       // point all the oops to the new location
 335       size_t size = oop(q)->adjust_pointers();
 336         
 337       debug_only(MarkSweep::check_interior_pointers());
 338       
 339       debug_only(MarkSweep::validate_live_oop(oop(q), size));
 340       
 341       q += size;
 342     }
 343 
 344     if (_first_dead == t) {
 345       q = t;
 346     } else {
 347       // $$$ This is funky.  Using this to read the previously written
 348       // LiveRange.  See also use below.
 349       q = (HeapWord*)oop(_first_dead)->mark()->decode_pointer();
 350     }
 351   }
 352   const intx interval = PrefetchScanIntervalInBytes;
 353 
 354   debug_only(HeapWord* prev_q = NULL);
 355   while (q < t) {
 356     // prefetch beyond q
 357     Prefetch::write(q, interval);
 358     if (oop(q)->is_gc_marked()) {
 359       // q is alive
 360       debug_only(MarkSweep::track_interior_pointers(oop(q)));
 361       // point all the oops to the new location
 362       size_t size = oop(q)->adjust_pointers();
 363       debug_only(MarkSweep::check_interior_pointers());
 364       debug_only(MarkSweep::validate_live_oop(oop(q), size));
 365       debug_only(prev_q = q);
 366       q += size;
 367     } else {
 368       // q is not a live object, so its mark should point at the next
 369       // live object
 370       debug_only(prev_q = q);
 371       q = (HeapWord*) oop(q)->mark()->decode_pointer();
 372       assert(q > prev_q, "we should be moving forward through memory");
 373     }
 374   }
 375 
 376   assert(q == t, "just checking");
 377 }
 378 
 379 void PSMarkSweepDecorator::compact(bool mangle_free_space ) {
 380   // Copy all live objects to their new location
 381   // Used by MarkSweep::mark_sweep_phase4()
 382 
 383   HeapWord*       q = space()->bottom();
 384   HeapWord* const t = _end_of_live;
 385   debug_only(HeapWord* prev_q = NULL);
 386 
 387   if (q < t && _first_dead > q &&
 388       !oop(q)->is_gc_marked()) {
 389 #ifdef ASSERT
 390     // we have a chunk of the space which hasn't moved and we've reinitialized the
 391     // mark word during the previous pass, so we can't use is_gc_marked for the
 392     // traversal.
 393     HeapWord* const end = _first_dead;
 394       
 395     while (q < end) {
 396       size_t size = oop(q)->size();
 397       assert(!oop(q)->is_gc_marked(), "should be unmarked (special dense prefix handling)");
 398       debug_only(MarkSweep::live_oop_moved_to(q, size, q));
 399       debug_only(prev_q = q);
 400       q += size;
 401     }
 402 #endif
 403       
 404     if (_first_dead == t) {
 405       q = t;
 406     } else {
 407       // $$$ Funky
 408       q = (HeapWord*) oop(_first_dead)->mark()->decode_pointer();
 409     }
 410   }
 411 
 412   const intx scan_interval = PrefetchScanIntervalInBytes;
 413   const intx copy_interval = PrefetchCopyIntervalInBytes;
 414 
 415   while (q < t) {
 416     if (!oop(q)->is_gc_marked()) {
 417       // mark is pointer to next marked oop
 418       debug_only(prev_q = q);
 419       q = (HeapWord*) oop(q)->mark()->decode_pointer();
 420       assert(q > prev_q, "we should be moving forward through memory");
 421     } else {
 422       // prefetch beyond q
 423       Prefetch::read(q, scan_interval);
 424 
 425       // size and destination
 426       size_t size = oop(q)->size();
 427       HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee();
 428 
 429       // prefetch beyond compaction_top
 430       Prefetch::write(compaction_top, copy_interval);
 431 
 432       // copy object and reinit its mark
 433       debug_only(MarkSweep::live_oop_moved_to(q, size, compaction_top));
 434       assert(q != compaction_top, "everything in this pass should be moving");
 435       Copy::aligned_conjoint_words(q, compaction_top, size);
 436       oop(compaction_top)->init_mark();
 437       assert(oop(compaction_top)->klass() != NULL, "should have a class");
 438 
 439       debug_only(prev_q = q);
 440       q += size;
 441     }
 442   }
 443 
 444   assert(compaction_top() >= space()->bottom() && compaction_top() <= space()->end(),
 445          "should point inside space");
 446   space()->set_top(compaction_top());
 447 
 448   if (mangle_free_space) space()->mangle_unused_area();


 449 }
   1 #ifdef USE_PRAGMA_IDENT_SRC
   2 #pragma ident "@(#)psMarkSweepDecorator.cpp     1.26 07/05/17 15:52:53 JVM"
   3 #endif
   4 /*
   5  * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
   6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   7  *
   8  * This code is free software; you can redistribute it and/or modify it
   9  * under the terms of the GNU General Public License version 2 only, as
  10  * published by the Free Software Foundation.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  23  * CA 95054 USA or visit www.sun.com if you need additional information or
  24  * have any questions.
  25  *  


  76 
  77 // FIX ME FIX ME FIX ME FIX ME!!!!!!!!!
  78 // The object forwarding code is duplicated. Factor this out!!!!!
  79 //
  80 // This method "precompacts" objects inside its space to dest. It places forwarding
  81 // pointers into markOops for use by adjust_pointers. If "dest" should overflow, we
  82 // finish by compacting into our own space.
  83 
  84 void PSMarkSweepDecorator::precompact() {
  85   // Reset our own compact top.
  86   set_compaction_top(space()->bottom());
  87 
  88   /* We allow some amount of garbage towards the bottom of the space, so
  89    * we don't start compacting before there is a significant gain to be made.
  90    * Occasionally, we want to ensure a full compaction, which is determined
  91    * by the MarkSweepAlwaysCompactCount parameter. This is a significant
  92    * performance improvement!
  93    */
  94   bool skip_dead = ((PSMarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0);
  95 
  96   size_t allowed_deadspace = 0;
  97   if (skip_dead) {
  98     const size_t ratio = allowed_dead_ratio();
  99     allowed_deadspace = space()->capacity_in_words() * ratio / 100;
 100   }
 101 
 102   // Fetch the current destination decorator
 103   PSMarkSweepDecorator* dest = destination_decorator();
 104   ObjectStartArray* start_array = dest->start_array();
 105 
 106   HeapWord* compact_top = dest->compaction_top();
 107   HeapWord* compact_end = dest->space()->end();
 108                                            
 109   HeapWord* q = space()->bottom();                                                    
 110   HeapWord* t = space()->top();                                                
 111   
 112   HeapWord*  end_of_live= q;    /* One byte beyond the last byte of the last 
 113                                    live object. */                           
 114   HeapWord*  first_dead = space()->end(); /* The first dead object. */                 
 115   LiveRange* liveRange  = NULL; /* The current live range, recorded in the   
 116                                    first header of preceding free area. */   
 117   _first_dead = first_dead;                                                  
 118 
 119   const intx interval = PrefetchScanIntervalInBytes;


 138 
 139         // Advance to the next compaction decorator
 140         advance_destination_decorator();
 141         dest = destination_decorator();
 142 
 143         // Update compaction info
 144         start_array = dest->start_array();
 145         compact_top = dest->compaction_top();
 146         compact_end = dest->space()->end();
 147         assert(compact_top == dest->space()->bottom(), "Advanced to space already in use");
 148         assert(compact_end > compact_top, "Must always be space remaining");
 149         compaction_max_size = 
 150           pointer_delta(compact_end, compact_top);
 151       }
 152 
 153       // store the forwarding pointer into the mark word
 154       if (q != compact_top) {
 155         oop(q)->forward_to(oop(compact_top));
 156         assert(oop(q)->is_gc_marked(), "encoding the pointer should preserve the mark");
 157       } else {



 158         // if the object isn't moving we can just set the mark to the default
 159         // mark and handle it specially later on.
 160         oop(q)->init_mark();

 161         assert(oop(q)->forwardee() == NULL, "should be forwarded to NULL");
 162       }
 163 
 164       // Update object start array
 165       if (start_array) {

 166         start_array->allocate_block(compact_top);
 167       }
 168 
 169       VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(oop(q), size));
 170       compact_top += size;
 171       assert(compact_top <= dest->space()->end(), 
 172         "Exceeding space in destination");
 173 
 174       q += size;                                                             
 175       end_of_live = q;                                                       
 176     } else {                                                                 
 177       /* run over all the contiguous dead objects */                         
 178       HeapWord* end = q;                                                     
 179       do {                                                                   
 180         /* prefetch beyond end */                                            
 181         Prefetch::write(end, interval);                            
 182         end += oop(end)->size();
 183       } while (end < t && (!oop(end)->is_gc_marked()));
 184 
 185       /* see if we might want to pretend this object is alive so that
 186        * we don't have to compact quite as often.
 187        */
 188       if (allowed_deadspace > 0 && q == compact_top) {
 189         size_t sz = pointer_delta(end, q);


 200             // Advance to the next compaction decorator
 201             advance_destination_decorator();
 202             dest = destination_decorator();
 203             
 204             // Update compaction info
 205             start_array = dest->start_array();
 206             compact_top = dest->compaction_top();
 207             compact_end = dest->space()->end();
 208             assert(compact_top == dest->space()->bottom(), "Advanced to space already in use");
 209             assert(compact_end > compact_top, "Must always be space remaining");
 210             compaction_max_size = 
 211               pointer_delta(compact_end, compact_top);
 212           }
 213 
 214           // store the forwarding pointer into the mark word
 215           if (q != compact_top) {
 216             oop(q)->forward_to(oop(compact_top));
 217             assert(oop(q)->is_gc_marked(), "encoding the pointer should preserve the mark");
 218           } else {
 219             // if the object isn't moving we can just set the mark to the default



 220             // mark and handle it specially later on.
 221             oop(q)->init_mark();

 222             assert(oop(q)->forwardee() == NULL, "should be forwarded to NULL");
 223           }
 224 

 225           // Update object start array
 226           if (start_array) {
 227             start_array->allocate_block(compact_top);
 228           }
 229 
 230           VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(oop(q), sz));
 231           compact_top += sz;
 232           assert(compact_top <= dest->space()->end(), 
 233             "Exceeding space in destination");
 234 
 235           q = end;
 236           end_of_live = end;
 237           continue;
 238         }
 239       }
 240 
 241       /* for the previous LiveRange, record the end of the live objects. */  
 242       if (liveRange) {                                                       
 243         liveRange->set_end(q);                                               
 244       }                                                                      
 245                                                                              
 246       /* record the current LiveRange object.                                
 247        * liveRange->start() is overlaid on the mark word.                    
 248        */                                                                    
 249       liveRange = (LiveRange*)q;                                             
 250       liveRange->set_start(end);                                             


 257                                                                              
 258       /* move on to the next object */                                       
 259       q = end;                                                               
 260     }                                                                        
 261   }                                                                          
 262                                                                              
 263   assert(q == t, "just checking");                                           
 264   if (liveRange != NULL) {                                                   
 265     liveRange->set_end(q);                                                   
 266   }                                                                          
 267   _end_of_live = end_of_live;                                                
 268   if (end_of_live < first_dead) {                                            
 269     first_dead = end_of_live;                                                
 270   }                                                                          
 271   _first_dead = first_dead;                                                  
 272         
 273   // Update compaction top
 274   dest->set_compaction_top(compact_top);
 275 }
 276 
 277 bool PSMarkSweepDecorator::insert_deadspace(size_t& allowed_deadspace_words,
 278                                             HeapWord* q, size_t deadlength) {
 279   if (allowed_deadspace_words >= deadlength) {
 280     allowed_deadspace_words -= deadlength;
 281     CollectedHeap::fill_with_object(q, deadlength);
 282     oop(q)->set_mark(oop(q)->mark()->set_marked());
 283     assert((int) deadlength == oop(q)->size(), "bad filler object size");














 284     // Recall that we required "q == compaction_top".
 285     return true;
 286   } else {
 287     allowed_deadspace_words = 0;
 288     return false;
 289   }
 290 }
 291 
 292 void PSMarkSweepDecorator::adjust_pointers() {
 293   // adjust all the interior pointers to point at the new locations of objects
 294   // Used by MarkSweep::mark_sweep_phase3()
 295 
 296   HeapWord* q = space()->bottom();
 297   HeapWord* t = _end_of_live;  // Established by "prepare_for_compaction".
 298 
 299   assert(_first_dead <= _end_of_live, "Stands to reason, no?");
 300 
 301   if (q < t && _first_dead > q &&
 302       !oop(q)->is_gc_marked()) {
 303     // we have a chunk of the space which hasn't moved and we've
 304     // reinitialized the mark word during the previous pass, so we can't
 305     // use is_gc_marked for the traversal.
 306     HeapWord* end = _first_dead;
 307 
 308     while (q < end) {
 309       VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q)));

 310       // point all the oops to the new location
 311       size_t size = oop(q)->adjust_pointers();
 312       VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers());
 313       VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size));



 314       q += size;
 315     }
 316 
 317     if (_first_dead == t) {
 318       q = t;
 319     } else {
 320       // $$$ This is funky.  Using this to read the previously written
 321       // LiveRange.  See also use below.
 322       q = (HeapWord*)oop(_first_dead)->mark()->decode_pointer();
 323     }
 324   }
 325   const intx interval = PrefetchScanIntervalInBytes;
 326 
 327   debug_only(HeapWord* prev_q = NULL);
 328   while (q < t) {
 329     // prefetch beyond q
 330     Prefetch::write(q, interval);
 331     if (oop(q)->is_gc_marked()) {
 332       // q is alive
 333       VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q)));
 334       // point all the oops to the new location
 335       size_t size = oop(q)->adjust_pointers();
 336       VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers());
 337       VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size));
 338       debug_only(prev_q = q);
 339       q += size;
 340     } else {
 341       // q is not a live object, so its mark should point at the next
 342       // live object
 343       debug_only(prev_q = q);
 344       q = (HeapWord*) oop(q)->mark()->decode_pointer();
 345       assert(q > prev_q, "we should be moving forward through memory");
 346     }
 347   }
 348 
 349   assert(q == t, "just checking");
 350 }
 351 
 352 void PSMarkSweepDecorator::compact(bool mangle_free_space ) {
 353   // Copy all live objects to their new location
 354   // Used by MarkSweep::mark_sweep_phase4()
 355 
 356   HeapWord*       q = space()->bottom();
 357   HeapWord* const t = _end_of_live;
 358   debug_only(HeapWord* prev_q = NULL);
 359 
 360   if (q < t && _first_dead > q &&
 361       !oop(q)->is_gc_marked()) {
 362 #ifdef ASSERT
 363     // we have a chunk of the space which hasn't moved and we've reinitialized the
 364     // mark word during the previous pass, so we can't use is_gc_marked for the
 365     // traversal.
 366     HeapWord* const end = _first_dead;
 367       
 368     while (q < end) {
 369       size_t size = oop(q)->size();
 370       assert(!oop(q)->is_gc_marked(), "should be unmarked (special dense prefix handling)");
 371       VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size, q));
 372       debug_only(prev_q = q);
 373       q += size;
 374     }
 375 #endif
 376       
 377     if (_first_dead == t) {
 378       q = t;
 379     } else {
 380       // $$$ Funky
 381       q = (HeapWord*) oop(_first_dead)->mark()->decode_pointer();
 382     }
 383   }
 384 
 385   const intx scan_interval = PrefetchScanIntervalInBytes;
 386   const intx copy_interval = PrefetchCopyIntervalInBytes;
 387 
 388   while (q < t) {
 389     if (!oop(q)->is_gc_marked()) {
 390       // mark is pointer to next marked oop
 391       debug_only(prev_q = q);
 392       q = (HeapWord*) oop(q)->mark()->decode_pointer();
 393       assert(q > prev_q, "we should be moving forward through memory");
 394     } else {
 395       // prefetch beyond q
 396       Prefetch::read(q, scan_interval);
 397 
 398       // size and destination
 399       size_t size = oop(q)->size();
 400       HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee();
 401 
 402       // prefetch beyond compaction_top
 403       Prefetch::write(compaction_top, copy_interval);
 404 
 405       // copy object and reinit its mark
 406       VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size, compaction_top));
 407       assert(q != compaction_top, "everything in this pass should be moving");
 408       Copy::aligned_conjoint_words(q, compaction_top, size);
 409       oop(compaction_top)->init_mark();
 410       assert(oop(compaction_top)->klass() != NULL, "should have a class");
 411 
 412       debug_only(prev_q = q);
 413       q += size;
 414     }
 415   }
 416 
 417   assert(compaction_top() >= space()->bottom() && compaction_top() <= space()->end(),
 418          "should point inside space");
 419   space()->set_top(compaction_top());
 420 
 421   if (mangle_free_space) {
 422     space()->mangle_unused_area();
 423   }
 424 }