Merge

Wed, 01 Oct 2008 15:05:06 -0400

author
tonyp
date
Wed, 01 Oct 2008 15:05:06 -0400
changeset 812
ddfad9496151
parent 807
be41fa651400
parent 811
0166ac265d53
child 814
af90fe21c1e3
child 819
b7483806cc49
child 824
ee21eaa8ffe1

Merge

src/share/vm/runtime/globals.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/code/nmethod.cpp	Tue Sep 30 15:53:55 2008 -0700
     1.2 +++ b/src/share/vm/code/nmethod.cpp	Wed Oct 01 15:05:06 2008 -0400
     1.3 @@ -1350,11 +1350,7 @@
     1.4        return false;
     1.5      }
     1.6    }
     1.7 -  if (!UseParallelOldGC || !VerifyParallelOldWithMarkSweep) {
     1.8 -    // Cannot do this test if verification of the UseParallelOldGC
     1.9 -    // code using the PSMarkSweep code is being done.
    1.10 -    assert(unloading_occurred, "Inconsistency in unloading");
    1.11 -  }
    1.12 +  assert(unloading_occurred, "Inconsistency in unloading");
    1.13    make_unloaded(is_alive, obj);
    1.14    return true;
    1.15  }
     2.1 --- a/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Tue Sep 30 15:53:55 2008 -0700
     2.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Wed Oct 01 15:05:06 2008 -0400
     2.3 @@ -210,10 +210,6 @@
     2.4    PSScavenge::initialize();
     2.5    if (UseParallelOldGC) {
     2.6      PSParallelCompact::post_initialize();
     2.7 -    if (VerifyParallelOldWithMarkSweep) {
     2.8 -      // Will be used for verification of par old.
     2.9 -      PSMarkSweep::initialize();
    2.10 -    }
    2.11    } else {
    2.12      PSMarkSweep::initialize();
    2.13    }
    2.14 @@ -402,7 +398,7 @@
    2.15          return result;
    2.16        }
    2.17        if (!is_tlab &&
    2.18 -          size >= (young_gen()->eden_space()->capacity_in_words() / 2)) {
    2.19 +          size >= (young_gen()->eden_space()->capacity_in_words(Thread::current()) / 2)) {
    2.20          result = old_gen()->allocate(size, is_tlab);
    2.21          if (result != NULL) {
    2.22            return result;
     3.1 --- a/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	Tue Sep 30 15:53:55 2008 -0700
     3.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	Wed Oct 01 15:05:06 2008 -0400
     3.3 @@ -146,7 +146,7 @@
     3.4  {
     3.5    ParallelScavengeHeap* heap = PSParallelCompact::gc_heap();
     3.6    uint parallel_gc_threads = heap->gc_task_manager()->workers();
     3.7 -  ChunkTaskQueueSet* qset = ParCompactionManager::chunk_array();
     3.8 +  RegionTaskQueueSet* qset = ParCompactionManager::region_array();
     3.9    ParallelTaskTerminator terminator(parallel_gc_threads, qset);
    3.10    GCTaskQueue* q = GCTaskQueue::create();
    3.11    for(uint i=0; i<parallel_gc_threads; i++) {
    3.12 @@ -205,38 +205,38 @@
    3.13  }
    3.14  
    3.15  //
    3.16 -// StealChunkCompactionTask
    3.17 +// StealRegionCompactionTask
    3.18  //
    3.19  
    3.20  
    3.21 -StealChunkCompactionTask::StealChunkCompactionTask(ParallelTaskTerminator* t) :
    3.22 -  _terminator(t) {};
    3.23 +StealRegionCompactionTask::StealRegionCompactionTask(ParallelTaskTerminator* t):
    3.24 +  _terminator(t) {}
    3.25  
    3.26 -void StealChunkCompactionTask::do_it(GCTaskManager* manager, uint which) {
    3.27 +void StealRegionCompactionTask::do_it(GCTaskManager* manager, uint which) {
    3.28    assert(Universe::heap()->is_gc_active(), "called outside gc");
    3.29  
    3.30 -  NOT_PRODUCT(TraceTime tm("StealChunkCompactionTask",
    3.31 +  NOT_PRODUCT(TraceTime tm("StealRegionCompactionTask",
    3.32      PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
    3.33  
    3.34    ParCompactionManager* cm =
    3.35      ParCompactionManager::gc_thread_compaction_manager(which);
    3.36  
    3.37 -  // Has to drain stacks first because there may be chunks on
    3.38 +  // Has to drain stacks first because there may be regions on
    3.39    // preloaded onto the stack and this thread may never have
    3.40    // done a draining task.  Are the draining tasks needed?
    3.41  
    3.42 -  cm->drain_chunk_stacks();
    3.43 +  cm->drain_region_stacks();
    3.44  
    3.45 -  size_t chunk_index = 0;
    3.46 +  size_t region_index = 0;
    3.47    int random_seed = 17;
    3.48  
    3.49    // If we're the termination task, try 10 rounds of stealing before
    3.50    // setting the termination flag
    3.51  
    3.52    while(true) {
    3.53 -    if (ParCompactionManager::steal(which, &random_seed, chunk_index)) {
    3.54 -      PSParallelCompact::fill_and_update_chunk(cm, chunk_index);
    3.55 -      cm->drain_chunk_stacks();
    3.56 +    if (ParCompactionManager::steal(which, &random_seed, region_index)) {
    3.57 +      PSParallelCompact::fill_and_update_region(cm, region_index);
    3.58 +      cm->drain_region_stacks();
    3.59      } else {
    3.60        if (terminator()->offer_termination()) {
    3.61          break;
    3.62 @@ -249,11 +249,10 @@
    3.63  
    3.64  UpdateDensePrefixTask::UpdateDensePrefixTask(
    3.65                                     PSParallelCompact::SpaceId space_id,
    3.66 -                                   size_t chunk_index_start,
    3.67 -                                   size_t chunk_index_end) :
    3.68 -  _space_id(space_id), _chunk_index_start(chunk_index_start),
    3.69 -  _chunk_index_end(chunk_index_end)
    3.70 -{}
    3.71 +                                   size_t region_index_start,
    3.72 +                                   size_t region_index_end) :
    3.73 +  _space_id(space_id), _region_index_start(region_index_start),
    3.74 +  _region_index_end(region_index_end) {}
    3.75  
    3.76  void UpdateDensePrefixTask::do_it(GCTaskManager* manager, uint which) {
    3.77  
    3.78 @@ -265,8 +264,8 @@
    3.79  
    3.80    PSParallelCompact::update_and_deadwood_in_dense_prefix(cm,
    3.81                                                           _space_id,
    3.82 -                                                         _chunk_index_start,
    3.83 -                                                         _chunk_index_end);
    3.84 +                                                         _region_index_start,
    3.85 +                                                         _region_index_end);
    3.86  }
    3.87  
    3.88  void DrainStacksCompactionTask::do_it(GCTaskManager* manager, uint which) {
    3.89 @@ -278,6 +277,6 @@
    3.90    ParCompactionManager* cm =
    3.91      ParCompactionManager::gc_thread_compaction_manager(which);
    3.92  
    3.93 -  // Process any chunks already in the compaction managers stacks.
    3.94 -  cm->drain_chunk_stacks();
    3.95 +  // Process any regions already in the compaction managers stacks.
    3.96 +  cm->drain_region_stacks();
    3.97  }
     4.1 --- a/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp	Tue Sep 30 15:53:55 2008 -0700
     4.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp	Wed Oct 01 15:05:06 2008 -0400
     4.3 @@ -188,18 +188,18 @@
     4.4  };
     4.5  
     4.6  //
     4.7 -// StealChunkCompactionTask
     4.8 +// StealRegionCompactionTask
     4.9  //
    4.10  // This task is used to distribute work to idle threads.
    4.11  //
    4.12  
    4.13 -class StealChunkCompactionTask : public GCTask {
    4.14 +class StealRegionCompactionTask : public GCTask {
    4.15   private:
    4.16     ParallelTaskTerminator* const _terminator;
    4.17   public:
    4.18 -  StealChunkCompactionTask(ParallelTaskTerminator* t);
    4.19 +  StealRegionCompactionTask(ParallelTaskTerminator* t);
    4.20  
    4.21 -  char* name() { return (char *)"steal-chunk-task"; }
    4.22 +  char* name() { return (char *)"steal-region-task"; }
    4.23    ParallelTaskTerminator* terminator() { return _terminator; }
    4.24  
    4.25    virtual void do_it(GCTaskManager* manager, uint which);
    4.26 @@ -215,15 +215,15 @@
    4.27  class UpdateDensePrefixTask : public GCTask {
    4.28   private:
    4.29    PSParallelCompact::SpaceId _space_id;
    4.30 -  size_t _chunk_index_start;
    4.31 -  size_t _chunk_index_end;
    4.32 +  size_t _region_index_start;
    4.33 +  size_t _region_index_end;
    4.34  
    4.35   public:
    4.36    char* name() { return (char *)"update-dense_prefix-task"; }
    4.37  
    4.38    UpdateDensePrefixTask(PSParallelCompact::SpaceId space_id,
    4.39 -                        size_t chunk_index_start,
    4.40 -                        size_t chunk_index_end);
    4.41 +                        size_t region_index_start,
    4.42 +                        size_t region_index_end);
    4.43  
    4.44    virtual void do_it(GCTaskManager* manager, uint which);
    4.45  };
    4.46 @@ -231,17 +231,17 @@
    4.47  //
    4.48  // DrainStacksCompactionTask
    4.49  //
    4.50 -// This task processes chunks that have been added to the stacks of each
    4.51 +// This task processes regions that have been added to the stacks of each
    4.52  // compaction manager.
    4.53  //
    4.54  // Trying to use one draining thread does not work because there are no
    4.55  // guarantees about which task will be picked up by which thread.  For example,
    4.56 -// if thread A gets all the preloaded chunks, thread A may not get a draining
    4.57 +// if thread A gets all the preloaded regions, thread A may not get a draining
    4.58  // task (they may all be done by other threads).
    4.59  //
    4.60  
    4.61  class DrainStacksCompactionTask : public GCTask {
    4.62   public:
    4.63 -  char* name() { return (char *)"drain-chunk-task"; }
    4.64 +  char* name() { return (char *)"drain-region-task"; }
    4.65    virtual void do_it(GCTaskManager* manager, uint which);
    4.66  };
     5.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp	Tue Sep 30 15:53:55 2008 -0700
     5.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp	Wed Oct 01 15:05:06 2008 -0400
     5.3 @@ -30,7 +30,7 @@
     5.4  OopTaskQueueSet*     ParCompactionManager::_stack_array = NULL;
     5.5  ObjectStartArray*    ParCompactionManager::_start_array = NULL;
     5.6  ParMarkBitMap*       ParCompactionManager::_mark_bitmap = NULL;
     5.7 -ChunkTaskQueueSet*   ParCompactionManager::_chunk_array = NULL;
     5.8 +RegionTaskQueueSet*   ParCompactionManager::_region_array = NULL;
     5.9  
    5.10  ParCompactionManager::ParCompactionManager() :
    5.11      _action(CopyAndUpdate) {
    5.12 @@ -46,13 +46,13 @@
    5.13  
    5.14    // We want the overflow stack to be permanent
    5.15    _overflow_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(10, true);
    5.16 -#ifdef USE_ChunkTaskQueueWithOverflow
    5.17 -  chunk_stack()->initialize();
    5.18 +#ifdef USE_RegionTaskQueueWithOverflow
    5.19 +  region_stack()->initialize();
    5.20  #else
    5.21 -  chunk_stack()->initialize();
    5.22 +  region_stack()->initialize();
    5.23  
    5.24    // We want the overflow stack to be permanent
    5.25 -  _chunk_overflow_stack =
    5.26 +  _region_overflow_stack =
    5.27      new (ResourceObj::C_HEAP) GrowableArray<size_t>(10, true);
    5.28  #endif
    5.29  
    5.30 @@ -86,18 +86,18 @@
    5.31  
    5.32    _stack_array = new OopTaskQueueSet(parallel_gc_threads);
    5.33    guarantee(_stack_array != NULL, "Count not initialize promotion manager");
    5.34 -  _chunk_array = new ChunkTaskQueueSet(parallel_gc_threads);
    5.35 -  guarantee(_chunk_array != NULL, "Count not initialize promotion manager");
    5.36 +  _region_array = new RegionTaskQueueSet(parallel_gc_threads);
    5.37 +  guarantee(_region_array != NULL, "Count not initialize promotion manager");
    5.38  
    5.39    // Create and register the ParCompactionManager(s) for the worker threads.
    5.40    for(uint i=0; i<parallel_gc_threads; i++) {
    5.41      _manager_array[i] = new ParCompactionManager();
    5.42      guarantee(_manager_array[i] != NULL, "Could not create ParCompactionManager");
    5.43      stack_array()->register_queue(i, _manager_array[i]->marking_stack());
    5.44 -#ifdef USE_ChunkTaskQueueWithOverflow
    5.45 -    chunk_array()->register_queue(i, _manager_array[i]->chunk_stack()->task_queue());
    5.46 +#ifdef USE_RegionTaskQueueWithOverflow
    5.47 +    region_array()->register_queue(i, _manager_array[i]->region_stack()->task_queue());
    5.48  #else
    5.49 -    chunk_array()->register_queue(i, _manager_array[i]->chunk_stack());
    5.50 +    region_array()->register_queue(i, _manager_array[i]->region_stack());
    5.51  #endif
    5.52    }
    5.53  
    5.54 @@ -153,31 +153,31 @@
    5.55    return NULL;
    5.56  }
    5.57  
    5.58 -// Save chunk on a stack
    5.59 -void ParCompactionManager::save_for_processing(size_t chunk_index) {
    5.60 +// Save region on a stack
    5.61 +void ParCompactionManager::save_for_processing(size_t region_index) {
    5.62  #ifdef ASSERT
    5.63    const ParallelCompactData& sd = PSParallelCompact::summary_data();
    5.64 -  ParallelCompactData::ChunkData* const chunk_ptr = sd.chunk(chunk_index);
    5.65 -  assert(chunk_ptr->claimed(), "must be claimed");
    5.66 -  assert(chunk_ptr->_pushed++ == 0, "should only be pushed once");
    5.67 +  ParallelCompactData::RegionData* const region_ptr = sd.region(region_index);
    5.68 +  assert(region_ptr->claimed(), "must be claimed");
    5.69 +  assert(region_ptr->_pushed++ == 0, "should only be pushed once");
    5.70  #endif
    5.71 -  chunk_stack_push(chunk_index);
    5.72 +  region_stack_push(region_index);
    5.73  }
    5.74  
    5.75 -void ParCompactionManager::chunk_stack_push(size_t chunk_index) {
    5.76 +void ParCompactionManager::region_stack_push(size_t region_index) {
    5.77  
    5.78 -#ifdef USE_ChunkTaskQueueWithOverflow
    5.79 -  chunk_stack()->save(chunk_index);
    5.80 +#ifdef USE_RegionTaskQueueWithOverflow
    5.81 +  region_stack()->save(region_index);
    5.82  #else
    5.83 -  if(!chunk_stack()->push(chunk_index)) {
    5.84 -    chunk_overflow_stack()->push(chunk_index);
    5.85 +  if(!region_stack()->push(region_index)) {
    5.86 +    region_overflow_stack()->push(region_index);
    5.87    }
    5.88  #endif
    5.89  }
    5.90  
    5.91 -bool ParCompactionManager::retrieve_for_processing(size_t& chunk_index) {
    5.92 -#ifdef USE_ChunkTaskQueueWithOverflow
    5.93 -  return chunk_stack()->retrieve(chunk_index);
    5.94 +bool ParCompactionManager::retrieve_for_processing(size_t& region_index) {
    5.95 +#ifdef USE_RegionTaskQueueWithOverflow
    5.96 +  return region_stack()->retrieve(region_index);
    5.97  #else
    5.98    // Should not be used in the parallel case
    5.99    ShouldNotReachHere();
   5.100 @@ -230,14 +230,14 @@
   5.101    assert(overflow_stack()->length() == 0, "Sanity");
   5.102  }
   5.103  
   5.104 -void ParCompactionManager::drain_chunk_overflow_stack() {
   5.105 -  size_t chunk_index = (size_t) -1;
   5.106 -  while(chunk_stack()->retrieve_from_overflow(chunk_index)) {
   5.107 -    PSParallelCompact::fill_and_update_chunk(this, chunk_index);
   5.108 +void ParCompactionManager::drain_region_overflow_stack() {
   5.109 +  size_t region_index = (size_t) -1;
   5.110 +  while(region_stack()->retrieve_from_overflow(region_index)) {
   5.111 +    PSParallelCompact::fill_and_update_region(this, region_index);
   5.112    }
   5.113  }
   5.114  
   5.115 -void ParCompactionManager::drain_chunk_stacks() {
   5.116 +void ParCompactionManager::drain_region_stacks() {
   5.117  #ifdef ASSERT
   5.118    ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
   5.119    assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
   5.120 @@ -249,42 +249,42 @@
   5.121  #if 1 // def DO_PARALLEL - the serial code hasn't been updated
   5.122    do {
   5.123  
   5.124 -#ifdef USE_ChunkTaskQueueWithOverflow
   5.125 +#ifdef USE_RegionTaskQueueWithOverflow
   5.126      // Drain overflow stack first, so other threads can steal from
   5.127      // claimed stack while we work.
   5.128 -    size_t chunk_index = (size_t) -1;
   5.129 -    while(chunk_stack()->retrieve_from_overflow(chunk_index)) {
   5.130 -      PSParallelCompact::fill_and_update_chunk(this, chunk_index);
   5.131 +    size_t region_index = (size_t) -1;
   5.132 +    while(region_stack()->retrieve_from_overflow(region_index)) {
   5.133 +      PSParallelCompact::fill_and_update_region(this, region_index);
   5.134      }
   5.135  
   5.136 -    while (chunk_stack()->retrieve_from_stealable_queue(chunk_index)) {
   5.137 -      PSParallelCompact::fill_and_update_chunk(this, chunk_index);
   5.138 +    while (region_stack()->retrieve_from_stealable_queue(region_index)) {
   5.139 +      PSParallelCompact::fill_and_update_region(this, region_index);
   5.140      }
   5.141 -  } while (!chunk_stack()->is_empty());
   5.142 +  } while (!region_stack()->is_empty());
   5.143  #else
   5.144      // Drain overflow stack first, so other threads can steal from
   5.145      // claimed stack while we work.
   5.146 -    while(!chunk_overflow_stack()->is_empty()) {
   5.147 -      size_t chunk_index = chunk_overflow_stack()->pop();
   5.148 -      PSParallelCompact::fill_and_update_chunk(this, chunk_index);
   5.149 +    while(!region_overflow_stack()->is_empty()) {
   5.150 +      size_t region_index = region_overflow_stack()->pop();
   5.151 +      PSParallelCompact::fill_and_update_region(this, region_index);
   5.152      }
   5.153  
   5.154 -    size_t chunk_index = -1;
   5.155 +    size_t region_index = -1;
   5.156      // obj is a reference!!!
   5.157 -    while (chunk_stack()->pop_local(chunk_index)) {
   5.158 +    while (region_stack()->pop_local(region_index)) {
   5.159        // It would be nice to assert about the type of objects we might
   5.160        // pop, but they can come from anywhere, unfortunately.
   5.161 -      PSParallelCompact::fill_and_update_chunk(this, chunk_index);
   5.162 +      PSParallelCompact::fill_and_update_region(this, region_index);
   5.163      }
   5.164 -  } while((chunk_stack()->size() != 0) ||
   5.165 -          (chunk_overflow_stack()->length() != 0));
   5.166 +  } while((region_stack()->size() != 0) ||
   5.167 +          (region_overflow_stack()->length() != 0));
   5.168  #endif
   5.169  
   5.170 -#ifdef USE_ChunkTaskQueueWithOverflow
   5.171 -  assert(chunk_stack()->is_empty(), "Sanity");
   5.172 +#ifdef USE_RegionTaskQueueWithOverflow
   5.173 +  assert(region_stack()->is_empty(), "Sanity");
   5.174  #else
   5.175 -  assert(chunk_stack()->size() == 0, "Sanity");
   5.176 -  assert(chunk_overflow_stack()->length() == 0, "Sanity");
   5.177 +  assert(region_stack()->size() == 0, "Sanity");
   5.178 +  assert(region_overflow_stack()->length() == 0, "Sanity");
   5.179  #endif
   5.180  #else
   5.181    oop obj;
     6.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp	Tue Sep 30 15:53:55 2008 -0700
     6.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp	Wed Oct 01 15:05:06 2008 -0400
     6.3 @@ -52,7 +52,7 @@
     6.4    friend class ParallelTaskTerminator;
     6.5    friend class ParMarkBitMap;
     6.6    friend class PSParallelCompact;
     6.7 -  friend class StealChunkCompactionTask;
     6.8 +  friend class StealRegionCompactionTask;
     6.9    friend class UpdateAndFillClosure;
    6.10    friend class RefProcTaskExecutor;
    6.11  
    6.12 @@ -72,27 +72,27 @@
    6.13  // ------------------------  End don't putback if not needed
    6.14  
    6.15   private:
    6.16 -  static ParCompactionManager**  _manager_array;
    6.17 -  static OopTaskQueueSet*      _stack_array;
    6.18 -  static ObjectStartArray*     _start_array;
    6.19 -  static ChunkTaskQueueSet*    _chunk_array;
    6.20 -  static PSOldGen*             _old_gen;
    6.21 +  static ParCompactionManager** _manager_array;
    6.22 +  static OopTaskQueueSet*       _stack_array;
    6.23 +  static ObjectStartArray*      _start_array;
    6.24 +  static RegionTaskQueueSet*    _region_array;
    6.25 +  static PSOldGen*              _old_gen;
    6.26  
    6.27 -  OopTaskQueue                 _marking_stack;
    6.28 -  GrowableArray<oop>*          _overflow_stack;
    6.29 +  OopTaskQueue                  _marking_stack;
    6.30 +  GrowableArray<oop>*           _overflow_stack;
    6.31    // Is there a way to reuse the _marking_stack for the
    6.32 -  // saving empty chunks?  For now just create a different
    6.33 +  // saving empty regions?  For now just create a different
    6.34    // type of TaskQueue.
    6.35  
    6.36 -#ifdef USE_ChunkTaskQueueWithOverflow
    6.37 -  ChunkTaskQueueWithOverflow   _chunk_stack;
    6.38 +#ifdef USE_RegionTaskQueueWithOverflow
    6.39 +  RegionTaskQueueWithOverflow   _region_stack;
    6.40  #else
    6.41 -  ChunkTaskQueue               _chunk_stack;
    6.42 -  GrowableArray<size_t>*       _chunk_overflow_stack;
    6.43 +  RegionTaskQueue               _region_stack;
    6.44 +  GrowableArray<size_t>*        _region_overflow_stack;
    6.45  #endif
    6.46  
    6.47  #if 1  // does this happen enough to need a per thread stack?
    6.48 -  GrowableArray<Klass*>*       _revisit_klass_stack;
    6.49 +  GrowableArray<Klass*>*        _revisit_klass_stack;
    6.50  #endif
    6.51    static ParMarkBitMap* _mark_bitmap;
    6.52  
    6.53 @@ -100,21 +100,22 @@
    6.54  
    6.55    static PSOldGen* old_gen()             { return _old_gen; }
    6.56    static ObjectStartArray* start_array() { return _start_array; }
    6.57 -  static OopTaskQueueSet* stack_array()   { return _stack_array; }
    6.58 +  static OopTaskQueueSet* stack_array()  { return _stack_array; }
    6.59  
    6.60    static void initialize(ParMarkBitMap* mbm);
    6.61  
    6.62   protected:
    6.63    // Array of tasks.  Needed by the ParallelTaskTerminator.
    6.64 -  static ChunkTaskQueueSet* chunk_array()   { return _chunk_array; }
    6.65 -
    6.66 -  OopTaskQueue*  marking_stack()          { return &_marking_stack; }
    6.67 -  GrowableArray<oop>* overflow_stack()    { return _overflow_stack; }
    6.68 -#ifdef USE_ChunkTaskQueueWithOverflow
    6.69 -  ChunkTaskQueueWithOverflow* chunk_stack() { return &_chunk_stack; }
    6.70 +  static RegionTaskQueueSet* region_array()      { return _region_array; }
    6.71 +  OopTaskQueue*  marking_stack()                 { return &_marking_stack; }
    6.72 +  GrowableArray<oop>* overflow_stack()           { return _overflow_stack; }
    6.73 +#ifdef USE_RegionTaskQueueWithOverflow
    6.74 +  RegionTaskQueueWithOverflow* region_stack()    { return &_region_stack; }
    6.75  #else
    6.76 -  ChunkTaskQueue*  chunk_stack()          { return &_chunk_stack; }
    6.77 -  GrowableArray<size_t>* chunk_overflow_stack() { return _chunk_overflow_stack; }
    6.78 +  RegionTaskQueue*  region_stack()               { return &_region_stack; }
    6.79 +  GrowableArray<size_t>* region_overflow_stack() {
    6.80 +    return _region_overflow_stack;
    6.81 +  }
    6.82  #endif
    6.83  
    6.84    // Pushes onto the marking stack.  If the marking stack is full,
    6.85 @@ -123,9 +124,9 @@
    6.86    // Do not implement an equivalent stack_pop.  Deal with the
    6.87    // marking stack and overflow stack directly.
    6.88  
    6.89 -  // Pushes onto the chunk stack.  If the chunk stack is full,
    6.90 -  // pushes onto the chunk overflow stack.
    6.91 -  void chunk_stack_push(size_t chunk_index);
    6.92 +  // Pushes onto the region stack.  If the region stack is full,
    6.93 +  // pushes onto the region overflow stack.
    6.94 +  void region_stack_push(size_t region_index);
    6.95   public:
    6.96  
    6.97    Action action() { return _action; }
    6.98 @@ -160,10 +161,10 @@
    6.99    // Get a oop for scanning.  If returns null, no oop were found.
   6.100    oop retrieve_for_scanning();
   6.101  
   6.102 -  // Save chunk for later processing.  Must not fail.
   6.103 -  void save_for_processing(size_t chunk_index);
   6.104 -  // Get a chunk for processing.  If returns null, no chunk were found.
   6.105 -  bool retrieve_for_processing(size_t& chunk_index);
   6.106 +  // Save region for later processing.  Must not fail.
   6.107 +  void save_for_processing(size_t region_index);
   6.108 +  // Get a region for processing.  If returns null, no region were found.
   6.109 +  bool retrieve_for_processing(size_t& region_index);
   6.110  
   6.111    // Access function for compaction managers
   6.112    static ParCompactionManager* gc_thread_compaction_manager(int index);
   6.113 @@ -172,18 +173,18 @@
   6.114      return stack_array()->steal(queue_num, seed, t);
   6.115    }
   6.116  
   6.117 -  static bool steal(int queue_num, int* seed, ChunkTask& t) {
   6.118 -    return chunk_array()->steal(queue_num, seed, t);
   6.119 +  static bool steal(int queue_num, int* seed, RegionTask& t) {
   6.120 +    return region_array()->steal(queue_num, seed, t);
   6.121    }
   6.122  
   6.123    // Process tasks remaining on any stack
   6.124    void drain_marking_stacks(OopClosure *blk);
   6.125  
   6.126    // Process tasks remaining on any stack
   6.127 -  void drain_chunk_stacks();
   6.128 +  void drain_region_stacks();
   6.129  
   6.130    // Process tasks remaining on any stack
   6.131 -  void drain_chunk_overflow_stack();
   6.132 +  void drain_region_overflow_stack();
   6.133  
   6.134    // Debugging support
   6.135  #ifdef ASSERT
     7.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Tue Sep 30 15:53:55 2008 -0700
     7.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Wed Oct 01 15:05:06 2008 -0400
     7.3 @@ -35,9 +35,7 @@
     7.4    _ref_processor = new ReferenceProcessor(mr,
     7.5                                            true,    // atomic_discovery
     7.6                                            false);  // mt_discovery
     7.7 -  if (!UseParallelOldGC || !VerifyParallelOldWithMarkSweep) {
     7.8 -    _counters = new CollectorCounters("PSMarkSweep", 1);
     7.9 -  }
    7.10 +  _counters = new CollectorCounters("PSMarkSweep", 1);
    7.11  }
    7.12  
    7.13  // This method contains all heap specific policy for invoking mark sweep.
    7.14 @@ -518,9 +516,6 @@
    7.15    follow_stack();
    7.16  
    7.17    // Process reference objects found during marking
    7.18 -
    7.19 -  // Skipping the reference processing for VerifyParallelOldWithMarkSweep
    7.20 -  // affects the marking (makes it different).
    7.21    {
    7.22      ReferencePolicy *soft_ref_policy;
    7.23      if (clear_all_softrefs) {
     8.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp	Tue Sep 30 15:53:55 2008 -0700
     8.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp	Wed Oct 01 15:05:06 2008 -0400
     8.3 @@ -152,20 +152,15 @@
     8.4          oop(q)->forward_to(oop(compact_top));
     8.5          assert(oop(q)->is_gc_marked(), "encoding the pointer should preserve the mark");
     8.6        } else {
     8.7 -        // Don't clear the mark since it's confuses parallel old
     8.8 -        // verification.
     8.9 -        if (!UseParallelOldGC || !VerifyParallelOldWithMarkSweep) {
    8.10 -          // if the object isn't moving we can just set the mark to the default
    8.11 -          // mark and handle it specially later on.
    8.12 -          oop(q)->init_mark();
    8.13 -        }
    8.14 +        // if the object isn't moving we can just set the mark to the default
    8.15 +        // mark and handle it specially later on.
    8.16 +        oop(q)->init_mark();
    8.17          assert(oop(q)->forwardee() == NULL, "should be forwarded to NULL");
    8.18        }
    8.19  
    8.20        // Update object start array
    8.21 -      if (!UseParallelOldGC || !VerifyParallelOldWithMarkSweep) {
    8.22 -        if (start_array)
    8.23 -          start_array->allocate_block(compact_top);
    8.24 +      if (start_array) {
    8.25 +        start_array->allocate_block(compact_top);
    8.26        }
    8.27  
    8.28        VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(oop(q), size));
    8.29 @@ -219,19 +214,14 @@
    8.30              assert(oop(q)->is_gc_marked(), "encoding the pointer should preserve the mark");
    8.31            } else {
    8.32              // if the object isn't moving we can just set the mark to the default
    8.33 -            // Don't clear the mark since it's confuses parallel old
    8.34 -            // verification.
    8.35 -            if (!UseParallelOldGC || !VerifyParallelOldWithMarkSweep) {
    8.36 -              // mark and handle it specially later on.
    8.37 -              oop(q)->init_mark();
    8.38 -            }
    8.39 +            // mark and handle it specially later on.
    8.40 +            oop(q)->init_mark();
    8.41              assert(oop(q)->forwardee() == NULL, "should be forwarded to NULL");
    8.42            }
    8.43  
    8.44 -          if (!UseParallelOldGC || !VerifyParallelOldWithMarkSweep) {
    8.45 -            // Update object start array
    8.46 -            if (start_array)
    8.47 -              start_array->allocate_block(compact_top);
    8.48 +          // Update object start array
    8.49 +          if (start_array) {
    8.50 +            start_array->allocate_block(compact_top);
    8.51            }
    8.52  
    8.53            VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(oop(q), sz));
     9.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp	Tue Sep 30 15:53:55 2008 -0700
     9.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp	Wed Oct 01 15:05:06 2008 -0400
     9.3 @@ -152,9 +152,7 @@
     9.4    assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
     9.5  
     9.6    // Reset start array first.
     9.7 -  debug_only(if (!UseParallelOldGC || !VerifyParallelOldWithMarkSweep) {)
     9.8    start_array()->reset();
     9.9 -  debug_only(})
    9.10  
    9.11    object_mark_sweep()->precompact();
    9.12  
    10.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Tue Sep 30 15:53:55 2008 -0700
    10.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Wed Oct 01 15:05:06 2008 -0400
    10.3 @@ -28,43 +28,31 @@
    10.4  #include <math.h>
    10.5  
    10.6  // All sizes are in HeapWords.
    10.7 -const size_t ParallelCompactData::Log2ChunkSize  = 9; // 512 words
    10.8 -const size_t ParallelCompactData::ChunkSize      = (size_t)1 << Log2ChunkSize;
    10.9 -const size_t ParallelCompactData::ChunkSizeBytes = ChunkSize << LogHeapWordSize;
   10.10 -const size_t ParallelCompactData::ChunkSizeOffsetMask = ChunkSize - 1;
   10.11 -const size_t ParallelCompactData::ChunkAddrOffsetMask = ChunkSizeBytes - 1;
   10.12 -const size_t ParallelCompactData::ChunkAddrMask  = ~ChunkAddrOffsetMask;
   10.13 -
   10.14 -// 32-bit:  128 words covers 4 bitmap words
   10.15 -// 64-bit:  128 words covers 2 bitmap words
   10.16 -const size_t ParallelCompactData::Log2BlockSize   = 7; // 128 words
   10.17 -const size_t ParallelCompactData::BlockSize       = (size_t)1 << Log2BlockSize;
   10.18 -const size_t ParallelCompactData::BlockOffsetMask = BlockSize - 1;
   10.19 -const size_t ParallelCompactData::BlockMask       = ~BlockOffsetMask;
   10.20 -
   10.21 -const size_t ParallelCompactData::BlocksPerChunk = ChunkSize / BlockSize;
   10.22 -
   10.23 -const ParallelCompactData::ChunkData::chunk_sz_t
   10.24 -ParallelCompactData::ChunkData::dc_shift = 27;
   10.25 -
   10.26 -const ParallelCompactData::ChunkData::chunk_sz_t
   10.27 -ParallelCompactData::ChunkData::dc_mask = ~0U << dc_shift;
   10.28 -
   10.29 -const ParallelCompactData::ChunkData::chunk_sz_t
   10.30 -ParallelCompactData::ChunkData::dc_one = 0x1U << dc_shift;
   10.31 -
   10.32 -const ParallelCompactData::ChunkData::chunk_sz_t
   10.33 -ParallelCompactData::ChunkData::los_mask = ~dc_mask;
   10.34 -
   10.35 -const ParallelCompactData::ChunkData::chunk_sz_t
   10.36 -ParallelCompactData::ChunkData::dc_claimed = 0x8U << dc_shift;
   10.37 -
   10.38 -const ParallelCompactData::ChunkData::chunk_sz_t
   10.39 -ParallelCompactData::ChunkData::dc_completed = 0xcU << dc_shift;
   10.40 -
   10.41 -#ifdef ASSERT
   10.42 -short   ParallelCompactData::BlockData::_cur_phase = 0;
   10.43 -#endif
   10.44 +const size_t ParallelCompactData::Log2RegionSize  = 9; // 512 words
   10.45 +const size_t ParallelCompactData::RegionSize      = (size_t)1 << Log2RegionSize;
   10.46 +const size_t ParallelCompactData::RegionSizeBytes =
   10.47 +  RegionSize << LogHeapWordSize;
   10.48 +const size_t ParallelCompactData::RegionSizeOffsetMask = RegionSize - 1;
   10.49 +const size_t ParallelCompactData::RegionAddrOffsetMask = RegionSizeBytes - 1;
   10.50 +const size_t ParallelCompactData::RegionAddrMask  = ~RegionAddrOffsetMask;
   10.51 +
   10.52 +const ParallelCompactData::RegionData::region_sz_t
   10.53 +ParallelCompactData::RegionData::dc_shift = 27;
   10.54 +
   10.55 +const ParallelCompactData::RegionData::region_sz_t
   10.56 +ParallelCompactData::RegionData::dc_mask = ~0U << dc_shift;
   10.57 +
   10.58 +const ParallelCompactData::RegionData::region_sz_t
   10.59 +ParallelCompactData::RegionData::dc_one = 0x1U << dc_shift;
   10.60 +
   10.61 +const ParallelCompactData::RegionData::region_sz_t
   10.62 +ParallelCompactData::RegionData::los_mask = ~dc_mask;
   10.63 +
   10.64 +const ParallelCompactData::RegionData::region_sz_t
   10.65 +ParallelCompactData::RegionData::dc_claimed = 0x8U << dc_shift;
   10.66 +
   10.67 +const ParallelCompactData::RegionData::region_sz_t
   10.68 +ParallelCompactData::RegionData::dc_completed = 0xcU << dc_shift;
   10.69  
   10.70  SpaceInfo PSParallelCompact::_space_info[PSParallelCompact::last_space_id];
   10.71  bool      PSParallelCompact::_print_phases = false;
   10.72 @@ -100,99 +88,12 @@
   10.73  GrowableArray<size_t>   * PSParallelCompact::_last_gc_live_oops_size = NULL;
   10.74  #endif
   10.75  
   10.76 -// XXX beg - verification code; only works while we also mark in object headers
   10.77 -static void
   10.78 -verify_mark_bitmap(ParMarkBitMap& _mark_bitmap)
   10.79 -{
   10.80 -  ParallelScavengeHeap* heap = PSParallelCompact::gc_heap();
   10.81 -
   10.82 -  PSPermGen* perm_gen = heap->perm_gen();
   10.83 -  PSOldGen* old_gen = heap->old_gen();
   10.84 -  PSYoungGen* young_gen = heap->young_gen();
   10.85 -
   10.86 -  MutableSpace* perm_space = perm_gen->object_space();
   10.87 -  MutableSpace* old_space = old_gen->object_space();
   10.88 -  MutableSpace* eden_space = young_gen->eden_space();
   10.89 -  MutableSpace* from_space = young_gen->from_space();
   10.90 -  MutableSpace* to_space = young_gen->to_space();
   10.91 -
   10.92 -  // 'from_space' here is the survivor space at the lower address.
   10.93 -  if (to_space->bottom() < from_space->bottom()) {
   10.94 -    from_space = to_space;
   10.95 -    to_space = young_gen->from_space();
   10.96 -  }
   10.97 -
   10.98 -  HeapWord* boundaries[12];
   10.99 -  unsigned int bidx = 0;
  10.100 -  const unsigned int bidx_max = sizeof(boundaries) / sizeof(boundaries[0]);
  10.101 -
  10.102 -  boundaries[0] = perm_space->bottom();
  10.103 -  boundaries[1] = perm_space->top();
  10.104 -  boundaries[2] = old_space->bottom();
  10.105 -  boundaries[3] = old_space->top();
  10.106 -  boundaries[4] = eden_space->bottom();
  10.107 -  boundaries[5] = eden_space->top();
  10.108 -  boundaries[6] = from_space->bottom();
  10.109 -  boundaries[7] = from_space->top();
  10.110 -  boundaries[8] = to_space->bottom();
  10.111 -  boundaries[9] = to_space->top();
  10.112 -  boundaries[10] = to_space->end();
  10.113 -  boundaries[11] = to_space->end();
  10.114 -
  10.115 -  BitMap::idx_t beg_bit = 0;
  10.116 -  BitMap::idx_t end_bit;
  10.117 -  BitMap::idx_t tmp_bit;
  10.118 -  const BitMap::idx_t last_bit = _mark_bitmap.size();
  10.119 -  do {
  10.120 -    HeapWord* addr = _mark_bitmap.bit_to_addr(beg_bit);
  10.121 -    if (_mark_bitmap.is_marked(beg_bit)) {
  10.122 -      oop obj = (oop)addr;
  10.123 -      assert(obj->is_gc_marked(), "obj header is not marked");
  10.124 -      end_bit = _mark_bitmap.find_obj_end(beg_bit, last_bit);
  10.125 -      const size_t size = _mark_bitmap.obj_size(beg_bit, end_bit);
  10.126 -      assert(size == (size_t)obj->size(), "end bit wrong?");
  10.127 -      beg_bit = _mark_bitmap.find_obj_beg(beg_bit + 1, last_bit);
  10.128 -      assert(beg_bit > end_bit, "bit set in middle of an obj");
  10.129 -    } else {
  10.130 -      if (addr >= boundaries[bidx] && addr < boundaries[bidx + 1]) {
  10.131 -        // a dead object in the current space.
  10.132 -        oop obj = (oop)addr;
  10.133 -        end_bit = _mark_bitmap.addr_to_bit(addr + obj->size());
  10.134 -        assert(!obj->is_gc_marked(), "obj marked in header, not in bitmap");
  10.135 -        tmp_bit = beg_bit + 1;
  10.136 -        beg_bit = _mark_bitmap.find_obj_beg(tmp_bit, end_bit);
  10.137 -        assert(beg_bit == end_bit, "beg bit set in unmarked obj");
  10.138 -        beg_bit = _mark_bitmap.find_obj_end(tmp_bit, end_bit);
  10.139 -        assert(beg_bit == end_bit, "end bit set in unmarked obj");
  10.140 -      } else if (addr < boundaries[bidx + 2]) {
  10.141 -        // addr is between top in the current space and bottom in the next.
  10.142 -        end_bit = beg_bit + pointer_delta(boundaries[bidx + 2], addr);
  10.143 -        tmp_bit = beg_bit;
  10.144 -        beg_bit = _mark_bitmap.find_obj_beg(tmp_bit, end_bit);
  10.145 -        assert(beg_bit == end_bit, "beg bit set above top");
  10.146 -        beg_bit = _mark_bitmap.find_obj_end(tmp_bit, end_bit);
  10.147 -        assert(beg_bit == end_bit, "end bit set above top");
  10.148 -        bidx += 2;
  10.149 -      } else if (bidx < bidx_max - 2) {
  10.150 -        bidx += 2; // ???
  10.151 -      } else {
  10.152 -        tmp_bit = beg_bit;
  10.153 -        beg_bit = _mark_bitmap.find_obj_beg(tmp_bit, last_bit);
  10.154 -        assert(beg_bit == last_bit, "beg bit set outside heap");
  10.155 -        beg_bit = _mark_bitmap.find_obj_end(tmp_bit, last_bit);
  10.156 -        assert(beg_bit == last_bit, "end bit set outside heap");
  10.157 -      }
  10.158 -    }
  10.159 -  } while (beg_bit < last_bit);
  10.160 -}
  10.161 -// XXX end - verification code; only works while we also mark in object headers
  10.162 -
  10.163  #ifndef PRODUCT
  10.164  const char* PSParallelCompact::space_names[] = {
  10.165    "perm", "old ", "eden", "from", "to  "
  10.166  };
  10.167  
  10.168 -void PSParallelCompact::print_chunk_ranges()
  10.169 +void PSParallelCompact::print_region_ranges()
  10.170  {
  10.171    tty->print_cr("space  bottom     top        end        new_top");
  10.172    tty->print_cr("------ ---------- ---------- ---------- ----------");
  10.173 @@ -203,31 +104,31 @@
  10.174                    SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " "
  10.175                    SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " ",
  10.176                    id, space_names[id],
  10.177 -                  summary_data().addr_to_chunk_idx(space->bottom()),
  10.178 -                  summary_data().addr_to_chunk_idx(space->top()),
  10.179 -                  summary_data().addr_to_chunk_idx(space->end()),
  10.180 -                  summary_data().addr_to_chunk_idx(_space_info[id].new_top()));
  10.181 +                  summary_data().addr_to_region_idx(space->bottom()),
  10.182 +                  summary_data().addr_to_region_idx(space->top()),
  10.183 +                  summary_data().addr_to_region_idx(space->end()),
  10.184 +                  summary_data().addr_to_region_idx(_space_info[id].new_top()));
  10.185    }
  10.186  }
  10.187  
  10.188  void
  10.189 -print_generic_summary_chunk(size_t i, const ParallelCompactData::ChunkData* c)
  10.190 +print_generic_summary_region(size_t i, const ParallelCompactData::RegionData* c)
  10.191  {
  10.192 -#define CHUNK_IDX_FORMAT        SIZE_FORMAT_W(7)
  10.193 -#define CHUNK_DATA_FORMAT       SIZE_FORMAT_W(5)
  10.194 +#define REGION_IDX_FORMAT        SIZE_FORMAT_W(7)
  10.195 +#define REGION_DATA_FORMAT       SIZE_FORMAT_W(5)
  10.196  
  10.197    ParallelCompactData& sd = PSParallelCompact::summary_data();
  10.198 -  size_t dci = c->destination() ? sd.addr_to_chunk_idx(c->destination()) : 0;
  10.199 -  tty->print_cr(CHUNK_IDX_FORMAT " " PTR_FORMAT " "
  10.200 -                CHUNK_IDX_FORMAT " " PTR_FORMAT " "
  10.201 -                CHUNK_DATA_FORMAT " " CHUNK_DATA_FORMAT " "
  10.202 -                CHUNK_DATA_FORMAT " " CHUNK_IDX_FORMAT " %d",
  10.203 +  size_t dci = c->destination() ? sd.addr_to_region_idx(c->destination()) : 0;
  10.204 +  tty->print_cr(REGION_IDX_FORMAT " " PTR_FORMAT " "
  10.205 +                REGION_IDX_FORMAT " " PTR_FORMAT " "
  10.206 +                REGION_DATA_FORMAT " " REGION_DATA_FORMAT " "
  10.207 +                REGION_DATA_FORMAT " " REGION_IDX_FORMAT " %d",
  10.208                  i, c->data_location(), dci, c->destination(),
  10.209                  c->partial_obj_size(), c->live_obj_size(),
  10.210 -                c->data_size(), c->source_chunk(), c->destination_count());
  10.211 -
  10.212 -#undef  CHUNK_IDX_FORMAT
  10.213 -#undef  CHUNK_DATA_FORMAT
  10.214 +                c->data_size(), c->source_region(), c->destination_count());
  10.215 +
  10.216 +#undef  REGION_IDX_FORMAT
  10.217 +#undef  REGION_DATA_FORMAT
  10.218  }
  10.219  
  10.220  void
  10.221 @@ -236,14 +137,14 @@
  10.222                             HeapWord* const end_addr)
  10.223  {
  10.224    size_t total_words = 0;
  10.225 -  size_t i = summary_data.addr_to_chunk_idx(beg_addr);
  10.226 -  const size_t last = summary_data.addr_to_chunk_idx(end_addr);
  10.227 +  size_t i = summary_data.addr_to_region_idx(beg_addr);
  10.228 +  const size_t last = summary_data.addr_to_region_idx(end_addr);
  10.229    HeapWord* pdest = 0;
  10.230  
  10.231    while (i <= last) {
  10.232 -    ParallelCompactData::ChunkData* c = summary_data.chunk(i);
  10.233 +    ParallelCompactData::RegionData* c = summary_data.region(i);
  10.234      if (c->data_size() != 0 || c->destination() != pdest) {
  10.235 -      print_generic_summary_chunk(i, c);
  10.236 +      print_generic_summary_region(i, c);
  10.237        total_words += c->data_size();
  10.238        pdest = c->destination();
  10.239      }
  10.240 @@ -265,16 +166,16 @@
  10.241  }
  10.242  
  10.243  void
  10.244 -print_initial_summary_chunk(size_t i,
  10.245 -                            const ParallelCompactData::ChunkData* c,
  10.246 -                            bool newline = true)
  10.247 +print_initial_summary_region(size_t i,
  10.248 +                             const ParallelCompactData::RegionData* c,
  10.249 +                             bool newline = true)
  10.250  {
  10.251    tty->print(SIZE_FORMAT_W(5) " " PTR_FORMAT " "
  10.252               SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " "
  10.253               SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " %d",
  10.254               i, c->destination(),
  10.255               c->partial_obj_size(), c->live_obj_size(),
  10.256 -             c->data_size(), c->source_chunk(), c->destination_count());
  10.257 +             c->data_size(), c->source_region(), c->destination_count());
  10.258    if (newline) tty->cr();
  10.259  }
  10.260  
  10.261 @@ -285,47 +186,48 @@
  10.262      return;
  10.263    }
  10.264  
  10.265 -  const size_t chunk_size = ParallelCompactData::ChunkSize;
  10.266 -  HeapWord* const top_aligned_up = summary_data.chunk_align_up(space->top());
  10.267 -  const size_t end_chunk = summary_data.addr_to_chunk_idx(top_aligned_up);
  10.268 -  const ParallelCompactData::ChunkData* c = summary_data.chunk(end_chunk - 1);
  10.269 +  const size_t region_size = ParallelCompactData::RegionSize;
  10.270 +  typedef ParallelCompactData::RegionData RegionData;
  10.271 +  HeapWord* const top_aligned_up = summary_data.region_align_up(space->top());
  10.272 +  const size_t end_region = summary_data.addr_to_region_idx(top_aligned_up);
  10.273 +  const RegionData* c = summary_data.region(end_region - 1);
  10.274    HeapWord* end_addr = c->destination() + c->data_size();
  10.275    const size_t live_in_space = pointer_delta(end_addr, space->bottom());
  10.276  
  10.277 -  // Print (and count) the full chunks at the beginning of the space.
  10.278 -  size_t full_chunk_count = 0;
  10.279 -  size_t i = summary_data.addr_to_chunk_idx(space->bottom());
  10.280 -  while (i < end_chunk && summary_data.chunk(i)->data_size() == chunk_size) {
  10.281 -    print_initial_summary_chunk(i, summary_data.chunk(i));
  10.282 -    ++full_chunk_count;
  10.283 +  // Print (and count) the full regions at the beginning of the space.
  10.284 +  size_t full_region_count = 0;
  10.285 +  size_t i = summary_data.addr_to_region_idx(space->bottom());
  10.286 +  while (i < end_region && summary_data.region(i)->data_size() == region_size) {
  10.287 +    print_initial_summary_region(i, summary_data.region(i));
  10.288 +    ++full_region_count;
  10.289      ++i;
  10.290    }
  10.291  
  10.292 -  size_t live_to_right = live_in_space - full_chunk_count * chunk_size;
  10.293 +  size_t live_to_right = live_in_space - full_region_count * region_size;
  10.294  
  10.295    double max_reclaimed_ratio = 0.0;
  10.296 -  size_t max_reclaimed_ratio_chunk = 0;
  10.297 +  size_t max_reclaimed_ratio_region = 0;
  10.298    size_t max_dead_to_right = 0;
  10.299    size_t max_live_to_right = 0;
  10.300  
  10.301 -  // Print the 'reclaimed ratio' for chunks while there is something live in the
  10.302 -  // chunk or to the right of it.  The remaining chunks are empty (and
  10.303 +  // Print the 'reclaimed ratio' for regions while there is something live in
  10.304 +  // the region or to the right of it.  The remaining regions are empty (and
  10.305    // uninteresting), and computing the ratio will result in division by 0.
  10.306 -  while (i < end_chunk && live_to_right > 0) {
  10.307 -    c = summary_data.chunk(i);
  10.308 -    HeapWord* const chunk_addr = summary_data.chunk_to_addr(i);
  10.309 -    const size_t used_to_right = pointer_delta(space->top(), chunk_addr);
  10.310 +  while (i < end_region && live_to_right > 0) {
  10.311 +    c = summary_data.region(i);
  10.312 +    HeapWord* const region_addr = summary_data.region_to_addr(i);
  10.313 +    const size_t used_to_right = pointer_delta(space->top(), region_addr);
  10.314      const size_t dead_to_right = used_to_right - live_to_right;
  10.315      const double reclaimed_ratio = double(dead_to_right) / live_to_right;
  10.316  
  10.317      if (reclaimed_ratio > max_reclaimed_ratio) {
  10.318              max_reclaimed_ratio = reclaimed_ratio;
  10.319 -            max_reclaimed_ratio_chunk = i;
  10.320 +            max_reclaimed_ratio_region = i;
  10.321              max_dead_to_right = dead_to_right;
  10.322              max_live_to_right = live_to_right;
  10.323      }
  10.324  
  10.325 -    print_initial_summary_chunk(i, c, false);
  10.326 +    print_initial_summary_region(i, c, false);
  10.327      tty->print_cr(" %12.10f " SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10),
  10.328                    reclaimed_ratio, dead_to_right, live_to_right);
  10.329  
  10.330 @@ -333,14 +235,14 @@
  10.331      ++i;
  10.332    }
  10.333  
  10.334 -  // Any remaining chunks are empty.  Print one more if there is one.
  10.335 -  if (i < end_chunk) {
  10.336 -    print_initial_summary_chunk(i, summary_data.chunk(i));
  10.337 +  // Any remaining regions are empty.  Print one more if there is one.
  10.338 +  if (i < end_region) {
  10.339 +    print_initial_summary_region(i, summary_data.region(i));
  10.340    }
  10.341  
  10.342    tty->print_cr("max:  " SIZE_FORMAT_W(4) " d2r=" SIZE_FORMAT_W(10) " "
  10.343                  "l2r=" SIZE_FORMAT_W(10) " max_ratio=%14.12f",
  10.344 -                max_reclaimed_ratio_chunk, max_dead_to_right,
  10.345 +                max_reclaimed_ratio_region, max_dead_to_right,
  10.346                  max_live_to_right, max_reclaimed_ratio);
  10.347  }
  10.348  
  10.349 @@ -372,13 +274,9 @@
  10.350  {
  10.351    _region_start = 0;
  10.352  
  10.353 -  _chunk_vspace = 0;
  10.354 -  _chunk_data = 0;
  10.355 -  _chunk_count = 0;
  10.356 -
  10.357 -  _block_vspace = 0;
  10.358 -  _block_data = 0;
  10.359 -  _block_count = 0;
  10.360 +  _region_vspace = 0;
  10.361 +  _region_data = 0;
  10.362 +  _region_count = 0;
  10.363  }
  10.364  
  10.365  bool ParallelCompactData::initialize(MemRegion covered_region)
  10.366 @@ -387,18 +285,12 @@
  10.367    const size_t region_size = covered_region.word_size();
  10.368    DEBUG_ONLY(_region_end = _region_start + region_size;)
  10.369  
  10.370 -  assert(chunk_align_down(_region_start) == _region_start,
  10.371 +  assert(region_align_down(_region_start) == _region_start,
  10.372           "region start not aligned");
  10.373 -  assert((region_size & ChunkSizeOffsetMask) == 0,
  10.374 -         "region size not a multiple of ChunkSize");
  10.375 -
  10.376 -  bool result = initialize_chunk_data(region_size);
  10.377 -
  10.378 -  // Initialize the block data if it will be used for updating pointers, or if
  10.379 -  // this is a debug build.
  10.380 -  if (!UseParallelOldGCChunkPointerCalc || trueInDebug) {
  10.381 -    result = result && initialize_block_data(region_size);
  10.382 -  }
  10.383 +  assert((region_size & RegionSizeOffsetMask) == 0,
  10.384 +         "region size not a multiple of RegionSize");
  10.385 +
  10.386 +  bool result = initialize_region_data(region_size);
  10.387  
  10.388    return result;
  10.389  }
  10.390 @@ -429,64 +321,41 @@
  10.391    return 0;
  10.392  }
  10.393  
  10.394 -bool ParallelCompactData::initialize_chunk_data(size_t region_size)
  10.395 +bool ParallelCompactData::initialize_region_data(size_t region_size)
  10.396  {
  10.397 -  const size_t count = (region_size + ChunkSizeOffsetMask) >> Log2ChunkSize;
  10.398 -  _chunk_vspace = create_vspace(count, sizeof(ChunkData));
  10.399 -  if (_chunk_vspace != 0) {
  10.400 -    _chunk_data = (ChunkData*)_chunk_vspace->reserved_low_addr();
  10.401 -    _chunk_count = count;
  10.402 +  const size_t count = (region_size + RegionSizeOffsetMask) >> Log2RegionSize;
  10.403 +  _region_vspace = create_vspace(count, sizeof(RegionData));
  10.404 +  if (_region_vspace != 0) {
  10.405 +    _region_data = (RegionData*)_region_vspace->reserved_low_addr();
  10.406 +    _region_count = count;
  10.407      return true;
  10.408    }
  10.409    return false;
  10.410  }
  10.411  
  10.412 -bool ParallelCompactData::initialize_block_data(size_t region_size)
  10.413 -{
  10.414 -  const size_t count = (region_size + BlockOffsetMask) >> Log2BlockSize;
  10.415 -  _block_vspace = create_vspace(count, sizeof(BlockData));
  10.416 -  if (_block_vspace != 0) {
  10.417 -    _block_data = (BlockData*)_block_vspace->reserved_low_addr();
  10.418 -    _block_count = count;
  10.419 -    return true;
  10.420 -  }
  10.421 -  return false;
  10.422 -}
  10.423 -
  10.424  void ParallelCompactData::clear()
  10.425  {
  10.426 -  if (_block_data) {
  10.427 -    memset(_block_data, 0, _block_vspace->committed_size());
  10.428 -  }
  10.429 -  memset(_chunk_data, 0, _chunk_vspace->committed_size());
  10.430 +  memset(_region_data, 0, _region_vspace->committed_size());
  10.431  }
  10.432  
  10.433 -void ParallelCompactData::clear_range(size_t beg_chunk, size_t end_chunk) {
  10.434 -  assert(beg_chunk <= _chunk_count, "beg_chunk out of range");
  10.435 -  assert(end_chunk <= _chunk_count, "end_chunk out of range");
  10.436 -  assert(ChunkSize % BlockSize == 0, "ChunkSize not a multiple of BlockSize");
  10.437 -
  10.438 -  const size_t chunk_cnt = end_chunk - beg_chunk;
  10.439 -
  10.440 -  if (_block_data) {
  10.441 -    const size_t blocks_per_chunk = ChunkSize / BlockSize;
  10.442 -    const size_t beg_block = beg_chunk * blocks_per_chunk;
  10.443 -    const size_t block_cnt = chunk_cnt * blocks_per_chunk;
  10.444 -    memset(_block_data + beg_block, 0, block_cnt * sizeof(BlockData));
  10.445 -  }
  10.446 -  memset(_chunk_data + beg_chunk, 0, chunk_cnt * sizeof(ChunkData));
  10.447 +void ParallelCompactData::clear_range(size_t beg_region, size_t end_region) {
  10.448 +  assert(beg_region <= _region_count, "beg_region out of range");
  10.449 +  assert(end_region <= _region_count, "end_region out of range");
  10.450 +
  10.451 +  const size_t region_cnt = end_region - beg_region;
  10.452 +  memset(_region_data + beg_region, 0, region_cnt * sizeof(RegionData));
  10.453  }
  10.454  
  10.455 -HeapWord* ParallelCompactData::partial_obj_end(size_t chunk_idx) const
  10.456 +HeapWord* ParallelCompactData::partial_obj_end(size_t region_idx) const
  10.457  {
  10.458 -  const ChunkData* cur_cp = chunk(chunk_idx);
  10.459 -  const ChunkData* const end_cp = chunk(chunk_count() - 1);
  10.460 -
  10.461 -  HeapWord* result = chunk_to_addr(chunk_idx);
  10.462 +  const RegionData* cur_cp = region(region_idx);
  10.463 +  const RegionData* const end_cp = region(region_count() - 1);
  10.464 +
  10.465 +  HeapWord* result = region_to_addr(region_idx);
  10.466    if (cur_cp < end_cp) {
  10.467      do {
  10.468        result += cur_cp->partial_obj_size();
  10.469 -    } while (cur_cp->partial_obj_size() == ChunkSize && ++cur_cp < end_cp);
  10.470 +    } while (cur_cp->partial_obj_size() == RegionSize && ++cur_cp < end_cp);
  10.471    }
  10.472    return result;
  10.473  }
  10.474 @@ -494,56 +363,56 @@
  10.475  void ParallelCompactData::add_obj(HeapWord* addr, size_t len)
  10.476  {
  10.477    const size_t obj_ofs = pointer_delta(addr, _region_start);
  10.478 -  const size_t beg_chunk = obj_ofs >> Log2ChunkSize;
  10.479 -  const size_t end_chunk = (obj_ofs + len - 1) >> Log2ChunkSize;
  10.480 +  const size_t beg_region = obj_ofs >> Log2RegionSize;
  10.481 +  const size_t end_region = (obj_ofs + len - 1) >> Log2RegionSize;
  10.482  
  10.483    DEBUG_ONLY(Atomic::inc_ptr(&add_obj_count);)
  10.484    DEBUG_ONLY(Atomic::add_ptr(len, &add_obj_size);)
  10.485  
  10.486 -  if (beg_chunk == end_chunk) {
  10.487 -    // All in one chunk.
  10.488 -    _chunk_data[beg_chunk].add_live_obj(len);
  10.489 +  if (beg_region == end_region) {
  10.490 +    // All in one region.
  10.491 +    _region_data[beg_region].add_live_obj(len);
  10.492      return;
  10.493    }
  10.494  
  10.495 -  // First chunk.
  10.496 -  const size_t beg_ofs = chunk_offset(addr);
  10.497 -  _chunk_data[beg_chunk].add_live_obj(ChunkSize - beg_ofs);
  10.498 +  // First region.
  10.499 +  const size_t beg_ofs = region_offset(addr);
  10.500 +  _region_data[beg_region].add_live_obj(RegionSize - beg_ofs);
  10.501  
  10.502    klassOop klass = ((oop)addr)->klass();
  10.503 -  // Middle chunks--completely spanned by this object.
  10.504 -  for (size_t chunk = beg_chunk + 1; chunk < end_chunk; ++chunk) {
  10.505 -    _chunk_data[chunk].set_partial_obj_size(ChunkSize);
  10.506 -    _chunk_data[chunk].set_partial_obj_addr(addr);
  10.507 +  // Middle regions--completely spanned by this object.
  10.508 +  for (size_t region = beg_region + 1; region < end_region; ++region) {
  10.509 +    _region_data[region].set_partial_obj_size(RegionSize);
  10.510 +    _region_data[region].set_partial_obj_addr(addr);
  10.511    }
  10.512  
  10.513 -  // Last chunk.
  10.514 -  const size_t end_ofs = chunk_offset(addr + len - 1);
  10.515 -  _chunk_data[end_chunk].set_partial_obj_size(end_ofs + 1);
  10.516 -  _chunk_data[end_chunk].set_partial_obj_addr(addr);
  10.517 +  // Last region.
  10.518 +  const size_t end_ofs = region_offset(addr + len - 1);
  10.519 +  _region_data[end_region].set_partial_obj_size(end_ofs + 1);
  10.520 +  _region_data[end_region].set_partial_obj_addr(addr);
  10.521  }
  10.522  
  10.523  void
  10.524  ParallelCompactData::summarize_dense_prefix(HeapWord* beg, HeapWord* end)
  10.525  {
  10.526 -  assert(chunk_offset(beg) == 0, "not ChunkSize aligned");
  10.527 -  assert(chunk_offset(end) == 0, "not ChunkSize aligned");
  10.528 -
  10.529 -  size_t cur_chunk = addr_to_chunk_idx(beg);
  10.530 -  const size_t end_chunk = addr_to_chunk_idx(end);
  10.531 +  assert(region_offset(beg) == 0, "not RegionSize aligned");
  10.532 +  assert(region_offset(end) == 0, "not RegionSize aligned");
  10.533 +
  10.534 +  size_t cur_region = addr_to_region_idx(beg);
  10.535 +  const size_t end_region = addr_to_region_idx(end);
  10.536    HeapWord* addr = beg;
  10.537 -  while (cur_chunk < end_chunk) {
  10.538 -    _chunk_data[cur_chunk].set_destination(addr);
  10.539 -    _chunk_data[cur_chunk].set_destination_count(0);
  10.540 -    _chunk_data[cur_chunk].set_source_chunk(cur_chunk);
  10.541 -    _chunk_data[cur_chunk].set_data_location(addr);
  10.542 -
  10.543 -    // Update live_obj_size so the chunk appears completely full.
  10.544 -    size_t live_size = ChunkSize - _chunk_data[cur_chunk].partial_obj_size();
  10.545 -    _chunk_data[cur_chunk].set_live_obj_size(live_size);
  10.546 -
  10.547 -    ++cur_chunk;
  10.548 -    addr += ChunkSize;
  10.549 +  while (cur_region < end_region) {
  10.550 +    _region_data[cur_region].set_destination(addr);
  10.551 +    _region_data[cur_region].set_destination_count(0);
  10.552 +    _region_data[cur_region].set_source_region(cur_region);
  10.553 +    _region_data[cur_region].set_data_location(addr);
  10.554 +
  10.555 +    // Update live_obj_size so the region appears completely full.
  10.556 +    size_t live_size = RegionSize - _region_data[cur_region].partial_obj_size();
  10.557 +    _region_data[cur_region].set_live_obj_size(live_size);
  10.558 +
  10.559 +    ++cur_region;
  10.560 +    addr += RegionSize;
  10.561    }
  10.562  }
  10.563  
  10.564 @@ -552,7 +421,7 @@
  10.565                                      HeapWord** target_next,
  10.566                                      HeapWord** source_next) {
  10.567    // This is too strict.
  10.568 -  // assert(chunk_offset(source_beg) == 0, "not ChunkSize aligned");
  10.569 +  // assert(region_offset(source_beg) == 0, "not RegionSize aligned");
  10.570  
  10.571    if (TraceParallelOldGCSummaryPhase) {
  10.572      tty->print_cr("tb=" PTR_FORMAT " te=" PTR_FORMAT " "
  10.573 @@ -564,125 +433,93 @@
  10.574                    source_next != 0 ? *source_next : (HeapWord*) 0);
  10.575    }
  10.576  
  10.577 -  size_t cur_chunk = addr_to_chunk_idx(source_beg);
  10.578 -  const size_t end_chunk = addr_to_chunk_idx(chunk_align_up(source_end));
  10.579 +  size_t cur_region = addr_to_region_idx(source_beg);
  10.580 +  const size_t end_region = addr_to_region_idx(region_align_up(source_end));
  10.581  
  10.582    HeapWord *dest_addr = target_beg;
  10.583 -  while (cur_chunk < end_chunk) {
  10.584 -    size_t words = _chunk_data[cur_chunk].data_size();
  10.585 +  while (cur_region < end_region) {
  10.586 +    size_t words = _region_data[cur_region].data_size();
  10.587  
  10.588  #if     1
  10.589      assert(pointer_delta(target_end, dest_addr) >= words,
  10.590             "source region does not fit into target region");
  10.591  #else
  10.592 -    // XXX - need some work on the corner cases here.  If the chunk does not
  10.593 -    // fit, then must either make sure any partial_obj from the chunk fits, or
  10.594 -    // 'undo' the initial part of the partial_obj that is in the previous chunk.
  10.595 +    // XXX - need some work on the corner cases here.  If the region does not
  10.596 +    // fit, then must either make sure any partial_obj from the region fits, or
  10.597 +    // "undo" the initial part of the partial_obj that is in the previous
  10.598 +    // region.
  10.599      if (dest_addr + words >= target_end) {
  10.600        // Let the caller know where to continue.
  10.601        *target_next = dest_addr;
  10.602 -      *source_next = chunk_to_addr(cur_chunk);
  10.603 +      *source_next = region_to_addr(cur_region);
  10.604        return false;
  10.605      }
  10.606  #endif  // #if 1
  10.607  
  10.608 -    _chunk_data[cur_chunk].set_destination(dest_addr);
  10.609 -
  10.610 -    // Set the destination_count for cur_chunk, and if necessary, update
  10.611 -    // source_chunk for a destination chunk.  The source_chunk field is updated
  10.612 -    // if cur_chunk is the first (left-most) chunk to be copied to a destination
  10.613 -    // chunk.
  10.614 +    _region_data[cur_region].set_destination(dest_addr);
  10.615 +
  10.616 +    // Set the destination_count for cur_region, and if necessary, update
  10.617 +    // source_region for a destination region.  The source_region field is
  10.618 +    // updated if cur_region is the first (left-most) region to be copied to a
  10.619 +    // destination region.
  10.620      //
  10.621 -    // The destination_count calculation is a bit subtle.  A chunk that has data
  10.622 -    // that compacts into itself does not count itself as a destination.  This
  10.623 -    // maintains the invariant that a zero count means the chunk is available
  10.624 -    // and can be claimed and then filled.
  10.625 +    // The destination_count calculation is a bit subtle.  A region that has
  10.626 +    // data that compacts into itself does not count itself as a destination.
  10.627 +    // This maintains the invariant that a zero count means the region is
  10.628 +    // available and can be claimed and then filled.
  10.629      if (words > 0) {
  10.630        HeapWord* const last_addr = dest_addr + words - 1;
  10.631 -      const size_t dest_chunk_1 = addr_to_chunk_idx(dest_addr);
  10.632 -      const size_t dest_chunk_2 = addr_to_chunk_idx(last_addr);
  10.633 +      const size_t dest_region_1 = addr_to_region_idx(dest_addr);
  10.634 +      const size_t dest_region_2 = addr_to_region_idx(last_addr);
  10.635  #if     0
  10.636 -      // Initially assume that the destination chunks will be the same and
  10.637 +      // Initially assume that the destination regions will be the same and
  10.638        // adjust the value below if necessary.  Under this assumption, if
  10.639 -      // cur_chunk == dest_chunk_2, then cur_chunk will be compacted completely
  10.640 -      // into itself.
  10.641 -      uint destination_count = cur_chunk == dest_chunk_2 ? 0 : 1;
  10.642 -      if (dest_chunk_1 != dest_chunk_2) {
  10.643 -        // Destination chunks differ; adjust destination_count.
  10.644 +      // cur_region == dest_region_2, then cur_region will be compacted
  10.645 +      // completely into itself.
  10.646 +      uint destination_count = cur_region == dest_region_2 ? 0 : 1;
  10.647 +      if (dest_region_1 != dest_region_2) {
  10.648 +        // Destination regions differ; adjust destination_count.
  10.649          destination_count += 1;
  10.650 -        // Data from cur_chunk will be copied to the start of dest_chunk_2.
  10.651 -        _chunk_data[dest_chunk_2].set_source_chunk(cur_chunk);
  10.652 -      } else if (chunk_offset(dest_addr) == 0) {
  10.653 -        // Data from cur_chunk will be copied to the start of the destination
  10.654 -        // chunk.
  10.655 -        _chunk_data[dest_chunk_1].set_source_chunk(cur_chunk);
  10.656 +        // Data from cur_region will be copied to the start of dest_region_2.
  10.657 +        _region_data[dest_region_2].set_source_region(cur_region);
  10.658 +      } else if (region_offset(dest_addr) == 0) {
  10.659 +        // Data from cur_region will be copied to the start of the destination
  10.660 +        // region.
  10.661 +        _region_data[dest_region_1].set_source_region(cur_region);
  10.662        }
  10.663  #else
  10.664 -      // Initially assume that the destination chunks will be different and
  10.665 +      // Initially assume that the destination regions will be different and
  10.666        // adjust the value below if necessary.  Under this assumption, if
  10.667 -      // cur_chunk == dest_chunk2, then cur_chunk will be compacted partially
  10.668 -      // into dest_chunk_1 and partially into itself.
  10.669 -      uint destination_count = cur_chunk == dest_chunk_2 ? 1 : 2;
  10.670 -      if (dest_chunk_1 != dest_chunk_2) {
  10.671 -        // Data from cur_chunk will be copied to the start of dest_chunk_2.
  10.672 -        _chunk_data[dest_chunk_2].set_source_chunk(cur_chunk);
  10.673 +      // cur_region == dest_region2, then cur_region will be compacted partially
  10.674 +      // into dest_region_1 and partially into itself.
  10.675 +      uint destination_count = cur_region == dest_region_2 ? 1 : 2;
  10.676 +      if (dest_region_1 != dest_region_2) {
  10.677 +        // Data from cur_region will be copied to the start of dest_region_2.
  10.678 +        _region_data[dest_region_2].set_source_region(cur_region);
  10.679        } else {
  10.680 -        // Destination chunks are the same; adjust destination_count.
  10.681 +        // Destination regions are the same; adjust destination_count.
  10.682          destination_count -= 1;
  10.683 -        if (chunk_offset(dest_addr) == 0) {
  10.684 -          // Data from cur_chunk will be copied to the start of the destination
  10.685 -          // chunk.
  10.686 -          _chunk_data[dest_chunk_1].set_source_chunk(cur_chunk);
  10.687 +        if (region_offset(dest_addr) == 0) {
  10.688 +          // Data from cur_region will be copied to the start of the destination
  10.689 +          // region.
  10.690 +          _region_data[dest_region_1].set_source_region(cur_region);
  10.691          }
  10.692        }
  10.693  #endif  // #if 0
  10.694  
  10.695 -      _chunk_data[cur_chunk].set_destination_count(destination_count);
  10.696 -      _chunk_data[cur_chunk].set_data_location(chunk_to_addr(cur_chunk));
  10.697 +      _region_data[cur_region].set_destination_count(destination_count);
  10.698 +      _region_data[cur_region].set_data_location(region_to_addr(cur_region));
  10.699        dest_addr += words;
  10.700      }
  10.701  
  10.702 -    ++cur_chunk;
  10.703 +    ++cur_region;
  10.704    }
  10.705  
  10.706    *target_next = dest_addr;
  10.707    return true;
  10.708  }
  10.709  
  10.710 -bool ParallelCompactData::partial_obj_ends_in_block(size_t block_index) {
  10.711 -  HeapWord* block_addr = block_to_addr(block_index);
  10.712 -  HeapWord* block_end_addr = block_addr + BlockSize;
  10.713 -  size_t chunk_index = addr_to_chunk_idx(block_addr);
  10.714 -  HeapWord* partial_obj_end_addr = partial_obj_end(chunk_index);
  10.715 -
  10.716 -  // An object that ends at the end of the block, ends
  10.717 -  // in the block (the last word of the object is to
  10.718 -  // the left of the end).
  10.719 -  if ((block_addr < partial_obj_end_addr) &&
  10.720 -      (partial_obj_end_addr <= block_end_addr)) {
  10.721 -    return true;
  10.722 -  }
  10.723 -
  10.724 -  return false;
  10.725 -}
  10.726 -
  10.727  HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr) {
  10.728 -  HeapWord* result = NULL;
  10.729 -  if (UseParallelOldGCChunkPointerCalc) {
  10.730 -    result = chunk_calc_new_pointer(addr);
  10.731 -  } else {
  10.732 -    result = block_calc_new_pointer(addr);
  10.733 -  }
  10.734 -  return result;
  10.735 -}
  10.736 -
  10.737 -// This method is overly complicated (expensive) to be called
  10.738 -// for every reference.
  10.739 -// Try to restructure this so that a NULL is returned if
  10.740 -// the object is dead.  But don't wast the cycles to explicitly check
  10.741 -// that it is dead since only live objects should be passed in.
  10.742 -
  10.743 -HeapWord* ParallelCompactData::chunk_calc_new_pointer(HeapWord* addr) {
  10.744    assert(addr != NULL, "Should detect NULL oop earlier");
  10.745    assert(PSParallelCompact::gc_heap()->is_in(addr), "addr not in heap");
  10.746  #ifdef ASSERT
  10.747 @@ -692,30 +529,30 @@
  10.748  #endif
  10.749    assert(PSParallelCompact::mark_bitmap()->is_marked(addr), "obj not marked");
  10.750  
  10.751 -  // Chunk covering the object.
  10.752 -  size_t chunk_index = addr_to_chunk_idx(addr);
  10.753 -  const ChunkData* const chunk_ptr = chunk(chunk_index);
  10.754 -  HeapWord* const chunk_addr = chunk_align_down(addr);
  10.755 -
  10.756 -  assert(addr < chunk_addr + ChunkSize, "Chunk does not cover object");
  10.757 -  assert(addr_to_chunk_ptr(chunk_addr) == chunk_ptr, "sanity check");
  10.758 -
  10.759 -  HeapWord* result = chunk_ptr->destination();
  10.760 -
  10.761 -  // If all the data in the chunk is live, then the new location of the object
  10.762 -  // can be calculated from the destination of the chunk plus the offset of the
  10.763 -  // object in the chunk.
  10.764 -  if (chunk_ptr->data_size() == ChunkSize) {
  10.765 -    result += pointer_delta(addr, chunk_addr);
  10.766 +  // Region covering the object.
  10.767 +  size_t region_index = addr_to_region_idx(addr);
  10.768 +  const RegionData* const region_ptr = region(region_index);
  10.769 +  HeapWord* const region_addr = region_align_down(addr);
  10.770 +
  10.771 +  assert(addr < region_addr + RegionSize, "Region does not cover object");
  10.772 +  assert(addr_to_region_ptr(region_addr) == region_ptr, "sanity check");
  10.773 +
  10.774 +  HeapWord* result = region_ptr->destination();
  10.775 +
  10.776 +  // If all the data in the region is live, then the new location of the object
  10.777 +  // can be calculated from the destination of the region plus the offset of the
  10.778 +  // object in the region.
  10.779 +  if (region_ptr->data_size() == RegionSize) {
  10.780 +    result += pointer_delta(addr, region_addr);
  10.781      return result;
  10.782    }
  10.783  
  10.784    // The new location of the object is
  10.785 -  //    chunk destination +
  10.786 -  //    size of the partial object extending onto the chunk +
  10.787 -  //    sizes of the live objects in the Chunk that are to the left of addr
  10.788 -  const size_t partial_obj_size = chunk_ptr->partial_obj_size();
  10.789 -  HeapWord* const search_start = chunk_addr + partial_obj_size;
  10.790 +  //    region destination +
  10.791 +  //    size of the partial object extending onto the region +
  10.792 +  //    sizes of the live objects in the Region that are to the left of addr
  10.793 +  const size_t partial_obj_size = region_ptr->partial_obj_size();
  10.794 +  HeapWord* const search_start = region_addr + partial_obj_size;
  10.795  
  10.796    const ParMarkBitMap* bitmap = PSParallelCompact::mark_bitmap();
  10.797    size_t live_to_left = bitmap->live_words_in_range(search_start, oop(addr));
  10.798 @@ -725,50 +562,6 @@
  10.799    return result;
  10.800  }
  10.801  
  10.802 -HeapWord* ParallelCompactData::block_calc_new_pointer(HeapWord* addr) {
  10.803 -  assert(addr != NULL, "Should detect NULL oop earlier");
  10.804 -  assert(PSParallelCompact::gc_heap()->is_in(addr), "addr not in heap");
  10.805 -#ifdef ASSERT
  10.806 -  if (PSParallelCompact::mark_bitmap()->is_unmarked(addr)) {
  10.807 -    gclog_or_tty->print_cr("calc_new_pointer:: addr " PTR_FORMAT, addr);
  10.808 -  }
  10.809 -#endif
  10.810 -  assert(PSParallelCompact::mark_bitmap()->is_marked(addr), "obj not marked");
  10.811 -
  10.812 -  // Chunk covering the object.
  10.813 -  size_t chunk_index = addr_to_chunk_idx(addr);
  10.814 -  const ChunkData* const chunk_ptr = chunk(chunk_index);
  10.815 -  HeapWord* const chunk_addr = chunk_align_down(addr);
  10.816 -
  10.817 -  assert(addr < chunk_addr + ChunkSize, "Chunk does not cover object");
  10.818 -  assert(addr_to_chunk_ptr(chunk_addr) == chunk_ptr, "sanity check");
  10.819 -
  10.820 -  HeapWord* result = chunk_ptr->destination();
  10.821 -
  10.822 -  // If all the data in the chunk is live, then the new location of the object
  10.823 -  // can be calculated from the destination of the chunk plus the offset of the
  10.824 -  // object in the chunk.
  10.825 -  if (chunk_ptr->data_size() == ChunkSize) {
  10.826 -    result += pointer_delta(addr, chunk_addr);
  10.827 -    return result;
  10.828 -  }
  10.829 -
  10.830 -  // The new location of the object is
  10.831 -  //    chunk destination +
  10.832 -  //    block offset +
  10.833 -  //    sizes of the live objects in the Block that are to the left of addr
  10.834 -  const size_t block_offset = addr_to_block_ptr(addr)->offset();
  10.835 -  HeapWord* const search_start = chunk_addr + block_offset;
  10.836 -
  10.837 -  const ParMarkBitMap* bitmap = PSParallelCompact::mark_bitmap();
  10.838 -  size_t live_to_left = bitmap->live_words_in_range(search_start, oop(addr));
  10.839 -
  10.840 -  result += block_offset + live_to_left;
  10.841 -  assert(result <= addr, "object cannot move to the right");
  10.842 -  assert(result == chunk_calc_new_pointer(addr), "Should match");
  10.843 -  return result;
  10.844 -}
  10.845 -
  10.846  klassOop ParallelCompactData::calc_new_klass(klassOop old_klass) {
  10.847    klassOop updated_klass;
  10.848    if (PSParallelCompact::should_update_klass(old_klass)) {
  10.849 @@ -792,15 +585,14 @@
  10.850  
  10.851  void ParallelCompactData::verify_clear()
  10.852  {
  10.853 -  verify_clear(_chunk_vspace);
  10.854 -  verify_clear(_block_vspace);
  10.855 +  verify_clear(_region_vspace);
  10.856  }
  10.857  #endif  // #ifdef ASSERT
  10.858  
  10.859  #ifdef NOT_PRODUCT
  10.860 -ParallelCompactData::ChunkData* debug_chunk(size_t chunk_index) {
  10.861 +ParallelCompactData::RegionData* debug_region(size_t region_index) {
  10.862    ParallelCompactData& sd = PSParallelCompact::summary_data();
  10.863 -  return sd.chunk(chunk_index);
  10.864 +  return sd.region(region_index);
  10.865  }
  10.866  #endif
  10.867  
  10.868 @@ -953,10 +745,10 @@
  10.869    const idx_t end_bit = BitMap::word_align_up(_mark_bitmap.addr_to_bit(top));
  10.870    _mark_bitmap.clear_range(beg_bit, end_bit);
  10.871  
  10.872 -  const size_t beg_chunk = _summary_data.addr_to_chunk_idx(bot);
  10.873 -  const size_t end_chunk =
  10.874 -    _summary_data.addr_to_chunk_idx(_summary_data.chunk_align_up(max_top));
  10.875 -  _summary_data.clear_range(beg_chunk, end_chunk);
  10.876 +  const size_t beg_region = _summary_data.addr_to_region_idx(bot);
  10.877 +  const size_t end_region =
  10.878 +    _summary_data.addr_to_region_idx(_summary_data.region_align_up(max_top));
  10.879 +  _summary_data.clear_range(beg_region, end_region);
  10.880  }
  10.881  
  10.882  void PSParallelCompact::pre_compact(PreGCValues* pre_gc_values)
  10.883 @@ -1072,19 +864,19 @@
  10.884  PSParallelCompact::compute_dense_prefix_via_density(const SpaceId id,
  10.885                                                      bool maximum_compaction)
  10.886  {
  10.887 -  const size_t chunk_size = ParallelCompactData::ChunkSize;
  10.888 +  const size_t region_size = ParallelCompactData::RegionSize;
  10.889    const ParallelCompactData& sd = summary_data();
  10.890  
  10.891    const MutableSpace* const space = _space_info[id].space();
  10.892 -  HeapWord* const top_aligned_up = sd.chunk_align_up(space->top());
  10.893 -  const ChunkData* const beg_cp = sd.addr_to_chunk_ptr(space->bottom());
  10.894 -  const ChunkData* const end_cp = sd.addr_to_chunk_ptr(top_aligned_up);
  10.895 -
  10.896 -  // Skip full chunks at the beginning of the space--they are necessarily part
  10.897 +  HeapWord* const top_aligned_up = sd.region_align_up(space->top());
  10.898 +  const RegionData* const beg_cp = sd.addr_to_region_ptr(space->bottom());
  10.899 +  const RegionData* const end_cp = sd.addr_to_region_ptr(top_aligned_up);
  10.900 +
  10.901 +  // Skip full regions at the beginning of the space--they are necessarily part
  10.902    // of the dense prefix.
  10.903    size_t full_count = 0;
  10.904 -  const ChunkData* cp;
  10.905 -  for (cp = beg_cp; cp < end_cp && cp->data_size() == chunk_size; ++cp) {
  10.906 +  const RegionData* cp;
  10.907 +  for (cp = beg_cp; cp < end_cp && cp->data_size() == region_size; ++cp) {
  10.908      ++full_count;
  10.909    }
  10.910  
  10.911 @@ -1093,7 +885,7 @@
  10.912    const bool interval_ended = gcs_since_max > HeapMaximumCompactionInterval;
  10.913    if (maximum_compaction || cp == end_cp || interval_ended) {
  10.914      _maximum_compaction_gc_num = total_invocations();
  10.915 -    return sd.chunk_to_addr(cp);
  10.916 +    return sd.region_to_addr(cp);
  10.917    }
  10.918  
  10.919    HeapWord* const new_top = _space_info[id].new_top();
  10.920 @@ -1116,52 +908,53 @@
  10.921    }
  10.922  
  10.923    // XXX - Use binary search?
  10.924 -  HeapWord* dense_prefix = sd.chunk_to_addr(cp);
  10.925 -  const ChunkData* full_cp = cp;
  10.926 -  const ChunkData* const top_cp = sd.addr_to_chunk_ptr(space->top() - 1);
  10.927 +  HeapWord* dense_prefix = sd.region_to_addr(cp);
  10.928 +  const RegionData* full_cp = cp;
  10.929 +  const RegionData* const top_cp = sd.addr_to_region_ptr(space->top() - 1);
  10.930    while (cp < end_cp) {
  10.931 -    HeapWord* chunk_destination = cp->destination();
  10.932 -    const size_t cur_deadwood = pointer_delta(dense_prefix, chunk_destination);
  10.933 +    HeapWord* region_destination = cp->destination();
  10.934 +    const size_t cur_deadwood = pointer_delta(dense_prefix, region_destination);
  10.935      if (TraceParallelOldGCDensePrefix && Verbose) {
  10.936        tty->print_cr("c#=" SIZE_FORMAT_W(4) " dst=" PTR_FORMAT " "
  10.937                      "dp=" SIZE_FORMAT_W(8) " " "cdw=" SIZE_FORMAT_W(8),
  10.938 -                    sd.chunk(cp), chunk_destination,
  10.939 +                    sd.region(cp), region_destination,
  10.940                      dense_prefix, cur_deadwood);
  10.941      }
  10.942  
  10.943      if (cur_deadwood >= deadwood_goal) {
  10.944 -      // Found the chunk that has the correct amount of deadwood to the left.
  10.945 -      // This typically occurs after crossing a fairly sparse set of chunks, so
  10.946 -      // iterate backwards over those sparse chunks, looking for the chunk that
  10.947 -      // has the lowest density of live objects 'to the right.'
  10.948 -      size_t space_to_left = sd.chunk(cp) * chunk_size;
  10.949 +      // Found the region that has the correct amount of deadwood to the left.
  10.950 +      // This typically occurs after crossing a fairly sparse set of regions, so
  10.951 +      // iterate backwards over those sparse regions, looking for the region
  10.952 +      // that has the lowest density of live objects 'to the right.'
  10.953 +      size_t space_to_left = sd.region(cp) * region_size;
  10.954        size_t live_to_left = space_to_left - cur_deadwood;
  10.955        size_t space_to_right = space_capacity - space_to_left;
  10.956        size_t live_to_right = space_live - live_to_left;
  10.957        double density_to_right = double(live_to_right) / space_to_right;
  10.958        while (cp > full_cp) {
  10.959          --cp;
  10.960 -        const size_t prev_chunk_live_to_right = live_to_right - cp->data_size();
  10.961 -        const size_t prev_chunk_space_to_right = space_to_right + chunk_size;
  10.962 -        double prev_chunk_density_to_right =
  10.963 -          double(prev_chunk_live_to_right) / prev_chunk_space_to_right;
  10.964 -        if (density_to_right <= prev_chunk_density_to_right) {
  10.965 +        const size_t prev_region_live_to_right = live_to_right -
  10.966 +          cp->data_size();
  10.967 +        const size_t prev_region_space_to_right = space_to_right + region_size;
  10.968 +        double prev_region_density_to_right =
  10.969 +          double(prev_region_live_to_right) / prev_region_space_to_right;
  10.970 +        if (density_to_right <= prev_region_density_to_right) {
  10.971            return dense_prefix;
  10.972          }
  10.973          if (TraceParallelOldGCDensePrefix && Verbose) {
  10.974            tty->print_cr("backing up from c=" SIZE_FORMAT_W(4) " d2r=%10.8f "
  10.975 -                        "pc_d2r=%10.8f", sd.chunk(cp), density_to_right,
  10.976 -                        prev_chunk_density_to_right);
  10.977 +                        "pc_d2r=%10.8f", sd.region(cp), density_to_right,
  10.978 +                        prev_region_density_to_right);
  10.979          }
  10.980 -        dense_prefix -= chunk_size;
  10.981 -        live_to_right = prev_chunk_live_to_right;
  10.982 -        space_to_right = prev_chunk_space_to_right;
  10.983 -        density_to_right = prev_chunk_density_to_right;
  10.984 +        dense_prefix -= region_size;
  10.985 +        live_to_right = prev_region_live_to_right;
  10.986 +        space_to_right = prev_region_space_to_right;
  10.987 +        density_to_right = prev_region_density_to_right;
  10.988        }
  10.989        return dense_prefix;
  10.990      }
  10.991  
  10.992 -    dense_prefix += chunk_size;
  10.993 +    dense_prefix += region_size;
  10.994      ++cp;
  10.995    }
  10.996  
  10.997 @@ -1174,8 +967,8 @@
  10.998                                                   const bool maximum_compaction,
  10.999                                                   HeapWord* const addr)
 10.1000  {
 10.1001 -  const size_t chunk_idx = summary_data().addr_to_chunk_idx(addr);
 10.1002 -  ChunkData* const cp = summary_data().chunk(chunk_idx);
 10.1003 +  const size_t region_idx = summary_data().addr_to_region_idx(addr);
 10.1004 +  RegionData* const cp = summary_data().region(region_idx);
 10.1005    const MutableSpace* const space = _space_info[id].space();
 10.1006    HeapWord* const new_top = _space_info[id].new_top();
 10.1007  
 10.1008 @@ -1191,7 +984,7 @@
 10.1009                  "d2l=" SIZE_FORMAT " d2l%%=%6.4f "
 10.1010                  "d2r=" SIZE_FORMAT " l2r=" SIZE_FORMAT
 10.1011                  " ratio=%10.8f",
 10.1012 -                algorithm, addr, chunk_idx,
 10.1013 +                algorithm, addr, region_idx,
 10.1014                  space_live,
 10.1015                  dead_to_left, dead_to_left_pct,
 10.1016                  dead_to_right, live_to_right,
 10.1017 @@ -1253,52 +1046,52 @@
 10.1018    return MAX2(limit, 0.0);
 10.1019  }
 10.1020  
 10.1021 -ParallelCompactData::ChunkData*
 10.1022 -PSParallelCompact::first_dead_space_chunk(const ChunkData* beg,
 10.1023 -                                          const ChunkData* end)
 10.1024 +ParallelCompactData::RegionData*
 10.1025 +PSParallelCompact::first_dead_space_region(const RegionData* beg,
 10.1026 +                                           const RegionData* end)
 10.1027  {
 10.1028 -  const size_t chunk_size = ParallelCompactData::ChunkSize;
 10.1029 +  const size_t region_size = ParallelCompactData::RegionSize;
 10.1030    ParallelCompactData& sd = summary_data();
 10.1031 -  size_t left = sd.chunk(beg);
 10.1032 -  size_t right = end > beg ? sd.chunk(end) - 1 : left;
 10.1033 +  size_t left = sd.region(beg);
 10.1034 +  size_t right = end > beg ? sd.region(end) - 1 : left;
 10.1035  
 10.1036    // Binary search.
 10.1037    while (left < right) {
 10.1038      // Equivalent to (left + right) / 2, but does not overflow.
 10.1039      const size_t middle = left + (right - left) / 2;
 10.1040 -    ChunkData* const middle_ptr = sd.chunk(middle);
 10.1041 +    RegionData* const middle_ptr = sd.region(middle);
 10.1042      HeapWord* const dest = middle_ptr->destination();
 10.1043 -    HeapWord* const addr = sd.chunk_to_addr(middle);
 10.1044 +    HeapWord* const addr = sd.region_to_addr(middle);
 10.1045      assert(dest != NULL, "sanity");
 10.1046      assert(dest <= addr, "must move left");
 10.1047  
 10.1048      if (middle > left && dest < addr) {
 10.1049        right = middle - 1;
 10.1050 -    } else if (middle < right && middle_ptr->data_size() == chunk_size) {
 10.1051 +    } else if (middle < right && middle_ptr->data_size() == region_size) {
 10.1052        left = middle + 1;
 10.1053      } else {
 10.1054        return middle_ptr;
 10.1055      }
 10.1056    }
 10.1057 -  return sd.chunk(left);
 10.1058 +  return sd.region(left);
 10.1059  }
 10.1060  
 10.1061 -ParallelCompactData::ChunkData*
 10.1062 -PSParallelCompact::dead_wood_limit_chunk(const ChunkData* beg,
 10.1063 -                                         const ChunkData* end,
 10.1064 -                                         size_t dead_words)
 10.1065 +ParallelCompactData::RegionData*
 10.1066 +PSParallelCompact::dead_wood_limit_region(const RegionData* beg,
 10.1067 +                                          const RegionData* end,
 10.1068 +                                          size_t dead_words)
 10.1069  {
 10.1070    ParallelCompactData& sd = summary_data();
 10.1071 -  size_t left = sd.chunk(beg);
 10.1072 -  size_t right = end > beg ? sd.chunk(end) - 1 : left;
 10.1073 +  size_t left = sd.region(beg);
 10.1074 +  size_t right = end > beg ? sd.region(end) - 1 : left;
 10.1075  
 10.1076    // Binary search.
 10.1077    while (left < right) {
 10.1078      // Equivalent to (left + right) / 2, but does not overflow.
 10.1079      const size_t middle = left + (right - left) / 2;
 10.1080 -    ChunkData* const middle_ptr = sd.chunk(middle);
 10.1081 +    RegionData* const middle_ptr = sd.region(middle);
 10.1082      HeapWord* const dest = middle_ptr->destination();
 10.1083 -    HeapWord* const addr = sd.chunk_to_addr(middle);
 10.1084 +    HeapWord* const addr = sd.region_to_addr(middle);
 10.1085      assert(dest != NULL, "sanity");
 10.1086      assert(dest <= addr, "must move left");
 10.1087  
 10.1088 @@ -1311,13 +1104,13 @@
 10.1089        return middle_ptr;
 10.1090      }
 10.1091    }
 10.1092 -  return sd.chunk(left);
 10.1093 +  return sd.region(left);
 10.1094  }
 10.1095  
 10.1096  // The result is valid during the summary phase, after the initial summarization
 10.1097  // of each space into itself, and before final summarization.
 10.1098  inline double
 10.1099 -PSParallelCompact::reclaimed_ratio(const ChunkData* const cp,
 10.1100 +PSParallelCompact::reclaimed_ratio(const RegionData* const cp,
 10.1101                                     HeapWord* const bottom,
 10.1102                                     HeapWord* const top,
 10.1103                                     HeapWord* const new_top)
 10.1104 @@ -1331,12 +1124,13 @@
 10.1105    assert(top >= new_top, "summary data problem?");
 10.1106    assert(new_top > bottom, "space is empty; should not be here");
 10.1107    assert(new_top >= cp->destination(), "sanity");
 10.1108 -  assert(top >= sd.chunk_to_addr(cp), "sanity");
 10.1109 +  assert(top >= sd.region_to_addr(cp), "sanity");
 10.1110  
 10.1111    HeapWord* const destination = cp->destination();
 10.1112    const size_t dense_prefix_live  = pointer_delta(destination, bottom);
 10.1113    const size_t compacted_region_live = pointer_delta(new_top, destination);
 10.1114 -  const size_t compacted_region_used = pointer_delta(top, sd.chunk_to_addr(cp));
 10.1115 +  const size_t compacted_region_used = pointer_delta(top,
 10.1116 +                                                     sd.region_to_addr(cp));
 10.1117    const size_t reclaimable = compacted_region_used - compacted_region_live;
 10.1118  
 10.1119    const double divisor = dense_prefix_live + 1.25 * compacted_region_live;
 10.1120 @@ -1344,39 +1138,40 @@
 10.1121  }
 10.1122  
 10.1123  // Return the address of the end of the dense prefix, a.k.a. the start of the
 10.1124 -// compacted region.  The address is always on a chunk boundary.
 10.1125 +// compacted region.  The address is always on a region boundary.
 10.1126  //
 10.1127 -// Completely full chunks at the left are skipped, since no compaction can occur
 10.1128 -// in those chunks.  Then the maximum amount of dead wood to allow is computed,
 10.1129 -// based on the density (amount live / capacity) of the generation; the chunk
 10.1130 -// with approximately that amount of dead space to the left is identified as the
 10.1131 -// limit chunk.  Chunks between the last completely full chunk and the limit
 10.1132 -// chunk are scanned and the one that has the best (maximum) reclaimed_ratio()
 10.1133 -// is selected.
 10.1134 +// Completely full regions at the left are skipped, since no compaction can
 10.1135 +// occur in those regions.  Then the maximum amount of dead wood to allow is
 10.1136 +// computed, based on the density (amount live / capacity) of the generation;
 10.1137 +// the region with approximately that amount of dead space to the left is
 10.1138 +// identified as the limit region.  Regions between the last completely full
 10.1139 +// region and the limit region are scanned and the one that has the best
 10.1140 +// (maximum) reclaimed_ratio() is selected.
 10.1141  HeapWord*
 10.1142  PSParallelCompact::compute_dense_prefix(const SpaceId id,
 10.1143                                          bool maximum_compaction)
 10.1144  {
 10.1145 -  const size_t chunk_size = ParallelCompactData::ChunkSize;
 10.1146 +  const size_t region_size = ParallelCompactData::RegionSize;
 10.1147    const ParallelCompactData& sd = summary_data();
 10.1148  
 10.1149    const MutableSpace* const space = _space_info[id].space();
 10.1150    HeapWord* const top = space->top();
 10.1151 -  HeapWord* const top_aligned_up = sd.chunk_align_up(top);
 10.1152 +  HeapWord* const top_aligned_up = sd.region_align_up(top);
 10.1153    HeapWord* const new_top = _space_info[id].new_top();
 10.1154 -  HeapWord* const new_top_aligned_up = sd.chunk_align_up(new_top);
 10.1155 +  HeapWord* const new_top_aligned_up = sd.region_align_up(new_top);
 10.1156    HeapWord* const bottom = space->bottom();
 10.1157 -  const ChunkData* const beg_cp = sd.addr_to_chunk_ptr(bottom);
 10.1158 -  const ChunkData* const top_cp = sd.addr_to_chunk_ptr(top_aligned_up);
 10.1159 -  const ChunkData* const new_top_cp = sd.addr_to_chunk_ptr(new_top_aligned_up);
 10.1160 -
 10.1161 -  // Skip full chunks at the beginning of the space--they are necessarily part
 10.1162 +  const RegionData* const beg_cp = sd.addr_to_region_ptr(bottom);
 10.1163 +  const RegionData* const top_cp = sd.addr_to_region_ptr(top_aligned_up);
 10.1164 +  const RegionData* const new_top_cp =
 10.1165 +    sd.addr_to_region_ptr(new_top_aligned_up);
 10.1166 +
 10.1167 +  // Skip full regions at the beginning of the space--they are necessarily part
 10.1168    // of the dense prefix.
 10.1169 -  const ChunkData* const full_cp = first_dead_space_chunk(beg_cp, new_top_cp);
 10.1170 -  assert(full_cp->destination() == sd.chunk_to_addr(full_cp) ||
 10.1171 +  const RegionData* const full_cp = first_dead_space_region(beg_cp, new_top_cp);
 10.1172 +  assert(full_cp->destination() == sd.region_to_addr(full_cp) ||
 10.1173           space->is_empty(), "no dead space allowed to the left");
 10.1174 -  assert(full_cp->data_size() < chunk_size || full_cp == new_top_cp - 1,
 10.1175 -         "chunk must have dead space");
 10.1176 +  assert(full_cp->data_size() < region_size || full_cp == new_top_cp - 1,
 10.1177 +         "region must have dead space");
 10.1178  
 10.1179    // The gc number is saved whenever a maximum compaction is done, and used to
 10.1180    // determine when the maximum compaction interval has expired.  This avoids
 10.1181 @@ -1387,7 +1182,7 @@
 10.1182      total_invocations() == HeapFirstMaximumCompactionCount;
 10.1183    if (maximum_compaction || full_cp == top_cp || interval_ended) {
 10.1184      _maximum_compaction_gc_num = total_invocations();
 10.1185 -    return sd.chunk_to_addr(full_cp);
 10.1186 +    return sd.region_to_addr(full_cp);
 10.1187    }
 10.1188  
 10.1189    const size_t space_live = pointer_delta(new_top, bottom);
 10.1190 @@ -1413,15 +1208,15 @@
 10.1191                    dead_wood_max, dead_wood_limit);
 10.1192    }
 10.1193  
 10.1194 -  // Locate the chunk with the desired amount of dead space to the left.
 10.1195 -  const ChunkData* const limit_cp =
 10.1196 -    dead_wood_limit_chunk(full_cp, top_cp, dead_wood_limit);
 10.1197 -
 10.1198 -  // Scan from the first chunk with dead space to the limit chunk and find the
 10.1199 +  // Locate the region with the desired amount of dead space to the left.
 10.1200 +  const RegionData* const limit_cp =
 10.1201 +    dead_wood_limit_region(full_cp, top_cp, dead_wood_limit);
 10.1202 +
 10.1203 +  // Scan from the first region with dead space to the limit region and find the
 10.1204    // one with the best (largest) reclaimed ratio.
 10.1205    double best_ratio = 0.0;
 10.1206 -  const ChunkData* best_cp = full_cp;
 10.1207 -  for (const ChunkData* cp = full_cp; cp < limit_cp; ++cp) {
 10.1208 +  const RegionData* best_cp = full_cp;
 10.1209 +  for (const RegionData* cp = full_cp; cp < limit_cp; ++cp) {
 10.1210      double tmp_ratio = reclaimed_ratio(cp, bottom, top, new_top);
 10.1211      if (tmp_ratio > best_ratio) {
 10.1212        best_cp = cp;
 10.1213 @@ -1430,18 +1225,18 @@
 10.1214    }
 10.1215  
 10.1216  #if     0
 10.1217 -  // Something to consider:  if the chunk with the best ratio is 'close to' the
 10.1218 -  // first chunk w/free space, choose the first chunk with free space
 10.1219 -  // ("first-free").  The first-free chunk is usually near the start of the
 10.1220 +  // Something to consider:  if the region with the best ratio is 'close to' the
 10.1221 +  // first region w/free space, choose the first region with free space
 10.1222 +  // ("first-free").  The first-free region is usually near the start of the
 10.1223    // heap, which means we are copying most of the heap already, so copy a bit
 10.1224    // more to get complete compaction.
 10.1225 -  if (pointer_delta(best_cp, full_cp, sizeof(ChunkData)) < 4) {
 10.1226 +  if (pointer_delta(best_cp, full_cp, sizeof(RegionData)) < 4) {
 10.1227      _maximum_compaction_gc_num = total_invocations();
 10.1228      best_cp = full_cp;
 10.1229    }
 10.1230  #endif  // #if 0
 10.1231  
 10.1232 -  return sd.chunk_to_addr(best_cp);
 10.1233 +  return sd.region_to_addr(best_cp);
 10.1234  }
 10.1235  
 10.1236  void PSParallelCompact::summarize_spaces_quick()
 10.1237 @@ -1459,9 +1254,9 @@
 10.1238  void PSParallelCompact::fill_dense_prefix_end(SpaceId id)
 10.1239  {
 10.1240    HeapWord* const dense_prefix_end = dense_prefix(id);
 10.1241 -  const ChunkData* chunk = _summary_data.addr_to_chunk_ptr(dense_prefix_end);
 10.1242 +  const RegionData* region = _summary_data.addr_to_region_ptr(dense_prefix_end);
 10.1243    const idx_t dense_prefix_bit = _mark_bitmap.addr_to_bit(dense_prefix_end);
 10.1244 -  if (dead_space_crosses_boundary(chunk, dense_prefix_bit)) {
 10.1245 +  if (dead_space_crosses_boundary(region, dense_prefix_bit)) {
 10.1246      // Only enough dead space is filled so that any remaining dead space to the
 10.1247      // left is larger than the minimum filler object.  (The remainder is filled
 10.1248      // during the copy/update phase.)
 10.1249 @@ -1552,7 +1347,7 @@
 10.1250        fill_dense_prefix_end(id);
 10.1251      }
 10.1252  
 10.1253 -    // Compute the destination of each Chunk, and thus each object.
 10.1254 +    // Compute the destination of each Region, and thus each object.
 10.1255      _summary_data.summarize_dense_prefix(space->bottom(), dense_prefix_end);
 10.1256      _summary_data.summarize(dense_prefix_end, space->end(),
 10.1257                              dense_prefix_end, space->top(),
 10.1258 @@ -1560,19 +1355,19 @@
 10.1259    }
 10.1260  
 10.1261    if (TraceParallelOldGCSummaryPhase) {
 10.1262 -    const size_t chunk_size = ParallelCompactData::ChunkSize;
 10.1263 +    const size_t region_size = ParallelCompactData::RegionSize;
 10.1264      HeapWord* const dense_prefix_end = _space_info[id].dense_prefix();
 10.1265 -    const size_t dp_chunk = _summary_data.addr_to_chunk_idx(dense_prefix_end);
 10.1266 +    const size_t dp_region = _summary_data.addr_to_region_idx(dense_prefix_end);
 10.1267      const size_t dp_words = pointer_delta(dense_prefix_end, space->bottom());
 10.1268      HeapWord* const new_top = _space_info[id].new_top();
 10.1269 -    const HeapWord* nt_aligned_up = _summary_data.chunk_align_up(new_top);
 10.1270 +    const HeapWord* nt_aligned_up = _summary_data.region_align_up(new_top);
 10.1271      const size_t cr_words = pointer_delta(nt_aligned_up, dense_prefix_end);
 10.1272      tty->print_cr("id=%d cap=" SIZE_FORMAT " dp=" PTR_FORMAT " "
 10.1273 -                  "dp_chunk=" SIZE_FORMAT " " "dp_count=" SIZE_FORMAT " "
 10.1274 +                  "dp_region=" SIZE_FORMAT " " "dp_count=" SIZE_FORMAT " "
 10.1275                    "cr_count=" SIZE_FORMAT " " "nt=" PTR_FORMAT,
 10.1276                    id, space->capacity_in_words(), dense_prefix_end,
 10.1277 -                  dp_chunk, dp_words / chunk_size,
 10.1278 -                  cr_words / chunk_size, new_top);
 10.1279 +                  dp_region, dp_words / region_size,
 10.1280 +                  cr_words / region_size, new_top);
 10.1281    }
 10.1282  }
 10.1283  
 10.1284 @@ -1584,11 +1379,6 @@
 10.1285    // trace("2");
 10.1286  
 10.1287  #ifdef  ASSERT
 10.1288 -  if (VerifyParallelOldWithMarkSweep  &&
 10.1289 -      (PSParallelCompact::total_invocations() %
 10.1290 -         VerifyParallelOldWithMarkSweepInterval) == 0) {
 10.1291 -    verify_mark_bitmap(_mark_bitmap);
 10.1292 -  }
 10.1293    if (TraceParallelOldGCMarkingPhase) {
 10.1294      tty->print_cr("add_obj_count=" SIZE_FORMAT " "
 10.1295                    "add_obj_bytes=" SIZE_FORMAT,
 10.1296 @@ -1605,7 +1395,7 @@
 10.1297    if (TraceParallelOldGCSummaryPhase) {
 10.1298      tty->print_cr("summary_phase:  after summarizing each space to self");
 10.1299      Universe::print();
 10.1300 -    NOT_PRODUCT(print_chunk_ranges());
 10.1301 +    NOT_PRODUCT(print_region_ranges());
 10.1302      if (Verbose) {
 10.1303        NOT_PRODUCT(print_initial_summary_data(_summary_data, _space_info));
 10.1304      }
 10.1305 @@ -1651,14 +1441,15 @@
 10.1306                                space->bottom(), space->top(),
 10.1307                                new_top_addr);
 10.1308  
 10.1309 -      // Clear the source_chunk field for each chunk in the space.
 10.1310 +      // Clear the source_region field for each region in the space.
 10.1311        HeapWord* const new_top = _space_info[id].new_top();
 10.1312 -      HeapWord* const clear_end = _summary_data.chunk_align_up(new_top);
 10.1313 -      ChunkData* beg_chunk = _summary_data.addr_to_chunk_ptr(space->bottom());
 10.1314 -      ChunkData* end_chunk = _summary_data.addr_to_chunk_ptr(clear_end);
 10.1315 -      while (beg_chunk < end_chunk) {
 10.1316 -        beg_chunk->set_source_chunk(0);
 10.1317 -        ++beg_chunk;
 10.1318 +      HeapWord* const clear_end = _summary_data.region_align_up(new_top);
 10.1319 +      RegionData* beg_region =
 10.1320 +        _summary_data.addr_to_region_ptr(space->bottom());
 10.1321 +      RegionData* end_region = _summary_data.addr_to_region_ptr(clear_end);
 10.1322 +      while (beg_region < end_region) {
 10.1323 +        beg_region->set_source_region(0);
 10.1324 +        ++beg_region;
 10.1325        }
 10.1326  
 10.1327        // Reset the new_top value for the space.
 10.1328 @@ -1666,243 +1457,16 @@
 10.1329      }
 10.1330    }
 10.1331  
 10.1332 -  // Fill in the block data after any changes to the chunks have
 10.1333 -  // been made.
 10.1334 -#ifdef  ASSERT
 10.1335 -  summarize_blocks(cm, perm_space_id);
 10.1336 -  summarize_blocks(cm, old_space_id);
 10.1337 -#else
 10.1338 -  if (!UseParallelOldGCChunkPointerCalc) {
 10.1339 -    summarize_blocks(cm, perm_space_id);
 10.1340 -    summarize_blocks(cm, old_space_id);
 10.1341 -  }
 10.1342 -#endif
 10.1343 -
 10.1344    if (TraceParallelOldGCSummaryPhase) {
 10.1345      tty->print_cr("summary_phase:  after final summarization");
 10.1346      Universe::print();
 10.1347 -    NOT_PRODUCT(print_chunk_ranges());
 10.1348 +    NOT_PRODUCT(print_region_ranges());
 10.1349      if (Verbose) {
 10.1350        NOT_PRODUCT(print_generic_summary_data(_summary_data, _space_info));
 10.1351      }
 10.1352    }
 10.1353  }
 10.1354  
 10.1355 -// Fill in the BlockData.
 10.1356 -// Iterate over the spaces and within each space iterate over
 10.1357 -// the chunks and fill in the BlockData for each chunk.
 10.1358 -
 10.1359 -void PSParallelCompact::summarize_blocks(ParCompactionManager* cm,
 10.1360 -                                         SpaceId first_compaction_space_id) {
 10.1361 -#if     0
 10.1362 -  DEBUG_ONLY(ParallelCompactData::BlockData::set_cur_phase(1);)
 10.1363 -  for (SpaceId cur_space_id = first_compaction_space_id;
 10.1364 -       cur_space_id != last_space_id;
 10.1365 -       cur_space_id = next_compaction_space_id(cur_space_id)) {
 10.1366 -    // Iterate over the chunks in the space
 10.1367 -    size_t start_chunk_index =
 10.1368 -      _summary_data.addr_to_chunk_idx(space(cur_space_id)->bottom());
 10.1369 -    BitBlockUpdateClosure bbu(mark_bitmap(),
 10.1370 -                              cm,
 10.1371 -                              start_chunk_index);
 10.1372 -    // Iterate over blocks.
 10.1373 -    for (size_t chunk_index =  start_chunk_index;
 10.1374 -         chunk_index < _summary_data.chunk_count() &&
 10.1375 -         _summary_data.chunk_to_addr(chunk_index) < space(cur_space_id)->top();
 10.1376 -         chunk_index++) {
 10.1377 -
 10.1378 -      // Reset the closure for the new chunk.  Note that the closure
 10.1379 -      // maintains some data that does not get reset for each chunk
 10.1380 -      // so a new instance of the closure is no appropriate.
 10.1381 -      bbu.reset_chunk(chunk_index);
 10.1382 -
 10.1383 -      // Start the iteration with the first live object.  This
 10.1384 -      // may return the end of the chunk.  That is acceptable since
 10.1385 -      // it will properly limit the iterations.
 10.1386 -      ParMarkBitMap::idx_t left_offset = mark_bitmap()->addr_to_bit(
 10.1387 -        _summary_data.first_live_or_end_in_chunk(chunk_index));
 10.1388 -
 10.1389 -      // End the iteration at the end of the chunk.
 10.1390 -      HeapWord* chunk_addr = _summary_data.chunk_to_addr(chunk_index);
 10.1391 -      HeapWord* chunk_end = chunk_addr + ParallelCompactData::ChunkSize;
 10.1392 -      ParMarkBitMap::idx_t right_offset =
 10.1393 -        mark_bitmap()->addr_to_bit(chunk_end);
 10.1394 -
 10.1395 -      // Blocks that have not objects starting in them can be
 10.1396 -      // skipped because their data will never be used.
 10.1397 -      if (left_offset < right_offset) {
 10.1398 -
 10.1399 -        // Iterate through the objects in the chunk.
 10.1400 -        ParMarkBitMap::idx_t last_offset =
 10.1401 -          mark_bitmap()->pair_iterate(&bbu, left_offset, right_offset);
 10.1402 -
 10.1403 -        // If last_offset is less than right_offset, then the iterations
 10.1404 -        // terminated while it was looking for an end bit.  "last_offset"
 10.1405 -        // is then the offset for the last start bit.  In this situation
 10.1406 -        // the "offset" field for the next block to the right (_cur_block + 1)
 10.1407 -        // will not have been update although there may be live data
 10.1408 -        // to the left of the chunk.
 10.1409 -
 10.1410 -        size_t cur_block_plus_1 = bbu.cur_block() + 1;
 10.1411 -        HeapWord* cur_block_plus_1_addr =
 10.1412 -        _summary_data.block_to_addr(bbu.cur_block()) +
 10.1413 -        ParallelCompactData::BlockSize;
 10.1414 -        HeapWord* last_offset_addr = mark_bitmap()->bit_to_addr(last_offset);
 10.1415 - #if 1  // This code works.  The else doesn't but should.  Why does it?
 10.1416 -        // The current block (cur_block()) has already been updated.
 10.1417 -        // The last block that may need to be updated is either the
 10.1418 -        // next block (current block + 1) or the block where the
 10.1419 -        // last object starts (which can be greater than the
 10.1420 -        // next block if there were no objects found in intervening
 10.1421 -        // blocks).
 10.1422 -        size_t last_block =
 10.1423 -          MAX2(bbu.cur_block() + 1,
 10.1424 -               _summary_data.addr_to_block_idx(last_offset_addr));
 10.1425 - #else
 10.1426 -        // The current block has already been updated.  The only block
 10.1427 -        // that remains to be updated is the block where the last
 10.1428 -        // object in the chunk starts.
 10.1429 -        size_t last_block = _summary_data.addr_to_block_idx(last_offset_addr);
 10.1430 - #endif
 10.1431 -        assert_bit_is_start(last_offset);
 10.1432 -        assert((last_block == _summary_data.block_count()) ||
 10.1433 -             (_summary_data.block(last_block)->raw_offset() == 0),
 10.1434 -          "Should not have been set");
 10.1435 -        // Is the last block still in the current chunk?  If still
 10.1436 -        // in this chunk, update the last block (the counting that
 10.1437 -        // included the current block is meant for the offset of the last
 10.1438 -        // block).  If not in this chunk, do nothing.  Should not
 10.1439 -        // update a block in the next chunk.
 10.1440 -        if (ParallelCompactData::chunk_contains_block(bbu.chunk_index(),
 10.1441 -                                                      last_block)) {
 10.1442 -          if (last_offset < right_offset) {
 10.1443 -            // The last object started in this chunk but ends beyond
 10.1444 -            // this chunk.  Update the block for this last object.
 10.1445 -            assert(mark_bitmap()->is_marked(last_offset), "Should be marked");
 10.1446 -            // No end bit was found.  The closure takes care of
 10.1447 -            // the cases where
 10.1448 -            //   an objects crosses over into the next block
 10.1449 -            //   an objects starts and ends in the next block
 10.1450 -            // It does not handle the case where an object is
 10.1451 -            // the first object in a later block and extends
 10.1452 -            // past the end of the chunk (i.e., the closure
 10.1453 -            // only handles complete objects that are in the range
 10.1454 -            // it is given).  That object is handed back here
 10.1455 -            // for any special consideration necessary.
 10.1456 -            //
 10.1457 -            // Is the first bit in the last block a start or end bit?
 10.1458 -            //
 10.1459 -            // If the partial object ends in the last block L,
 10.1460 -            // then the 1st bit in L may be an end bit.
 10.1461 -            //
 10.1462 -            // Else does the last object start in a block after the current
 10.1463 -            // block? A block AA will already have been updated if an
 10.1464 -            // object ends in the next block AA+1.  An object found to end in
 10.1465 -            // the AA+1 is the trigger that updates AA.  Objects are being
 10.1466 -            // counted in the current block for updaing a following
 10.1467 -            // block.  An object may start in later block
 10.1468 -            // block but may extend beyond the last block in the chunk.
 10.1469 -            // Updates are only done when the end of an object has been
 10.1470 -            // found. If the last object (covered by block L) starts
 10.1471 -            // beyond the current block, then no object ends in L (otherwise
 10.1472 -            // L would be the current block).  So the first bit in L is
 10.1473 -            // a start bit.
 10.1474 -            //
 10.1475 -            // Else the last objects start in the current block and ends
 10.1476 -            // beyond the chunk.  The current block has already been
 10.1477 -            // updated and there is no later block (with an object
 10.1478 -            // starting in it) that needs to be updated.
 10.1479 -            //
 10.1480 -            if (_summary_data.partial_obj_ends_in_block(last_block)) {
 10.1481 -              _summary_data.block(last_block)->set_end_bit_offset(
 10.1482 -                bbu.live_data_left());
 10.1483 -            } else if (last_offset_addr >= cur_block_plus_1_addr) {
 10.1484 -              //   The start of the object is on a later block
 10.1485 -              // (to the right of the current block and there are no
 10.1486 -              // complete live objects to the left of this last object
 10.1487 -              // within the chunk.
 10.1488 -              //   The first bit in the block is for the start of the
 10.1489 -              // last object.
 10.1490 -              _summary_data.block(last_block)->set_start_bit_offset(
 10.1491 -                bbu.live_data_left());
 10.1492 -            } else {
 10.1493 -              //   The start of the last object was found in
 10.1494 -              // the current chunk (which has already
 10.1495 -              // been updated).
 10.1496 -              assert(bbu.cur_block() ==
 10.1497 -                      _summary_data.addr_to_block_idx(last_offset_addr),
 10.1498 -                "Should be a block already processed");
 10.1499 -            }
 10.1500 -#ifdef ASSERT
 10.1501 -            // Is there enough block information to find this object?
 10.1502 -            // The destination of the chunk has not been set so the
 10.1503 -            // values returned by calc_new_pointer() and
 10.1504 -            // block_calc_new_pointer() will only be
 10.1505 -            // offsets.  But they should agree.
 10.1506 -            HeapWord* moved_obj_with_chunks =
 10.1507 -              _summary_data.chunk_calc_new_pointer(last_offset_addr);
 10.1508 -            HeapWord* moved_obj_with_blocks =
 10.1509 -              _summary_data.calc_new_pointer(last_offset_addr);
 10.1510 -            assert(moved_obj_with_chunks == moved_obj_with_blocks,
 10.1511 -              "Block calculation is wrong");
 10.1512 -#endif
 10.1513 -          } else if (last_block < _summary_data.block_count()) {
 10.1514 -            // Iterations ended looking for a start bit (but
 10.1515 -            // did not run off the end of the block table).
 10.1516 -            _summary_data.block(last_block)->set_start_bit_offset(
 10.1517 -              bbu.live_data_left());
 10.1518 -          }
 10.1519 -        }
 10.1520 -#ifdef ASSERT
 10.1521 -        // Is there enough block information to find this object?
 10.1522 -          HeapWord* left_offset_addr = mark_bitmap()->bit_to_addr(left_offset);
 10.1523 -        HeapWord* moved_obj_with_chunks =
 10.1524 -          _summary_data.calc_new_pointer(left_offset_addr);
 10.1525 -        HeapWord* moved_obj_with_blocks =
 10.1526 -          _summary_data.calc_new_pointer(left_offset_addr);
 10.1527 -          assert(moved_obj_with_chunks == moved_obj_with_blocks,
 10.1528 -          "Block calculation is wrong");
 10.1529 -#endif
 10.1530 -
 10.1531 -        // Is there another block after the end of this chunk?
 10.1532 -#ifdef ASSERT
 10.1533 -        if (last_block < _summary_data.block_count()) {
 10.1534 -        // No object may have been found in a block.  If that
 10.1535 -        // block is at the end of the chunk, the iteration will
 10.1536 -        // terminate without incrementing the current block so
 10.1537 -        // that the current block is not the last block in the
 10.1538 -        // chunk.  That situation precludes asserting that the
 10.1539 -        // current block is the last block in the chunk.  Assert
 10.1540 -        // the lesser condition that the current block does not
 10.1541 -        // exceed the chunk.
 10.1542 -          assert(_summary_data.block_to_addr(last_block) <=
 10.1543 -               (_summary_data.chunk_to_addr(chunk_index) +
 10.1544 -                 ParallelCompactData::ChunkSize),
 10.1545 -              "Chunk and block inconsistency");
 10.1546 -          assert(last_offset <= right_offset, "Iteration over ran end");
 10.1547 -        }
 10.1548 -#endif
 10.1549 -      }
 10.1550 -#ifdef ASSERT
 10.1551 -      if (PrintGCDetails && Verbose) {
 10.1552 -        if (_summary_data.chunk(chunk_index)->partial_obj_size() == 1) {
 10.1553 -          size_t first_block =
 10.1554 -            chunk_index / ParallelCompactData::BlocksPerChunk;
 10.1555 -          gclog_or_tty->print_cr("first_block " PTR_FORMAT
 10.1556 -            " _offset " PTR_FORMAT
 10.1557 -            "_first_is_start_bit %d",
 10.1558 -            first_block,
 10.1559 -            _summary_data.block(first_block)->raw_offset(),
 10.1560 -            _summary_data.block(first_block)->first_is_start_bit());
 10.1561 -        }
 10.1562 -      }
 10.1563 -#endif
 10.1564 -    }
 10.1565 -  }
 10.1566 -  DEBUG_ONLY(ParallelCompactData::BlockData::set_cur_phase(16);)
 10.1567 -#endif  // #if 0
 10.1568 -}
 10.1569 -
 10.1570  // This method should contain all heap-specific policy for invoking a full
 10.1571  // collection.  invoke_no_policy() will only attempt to compact the heap; it
 10.1572  // will do nothing further.  If we need to bail out for policy reasons, scavenge
 10.1573 @@ -1937,18 +1501,9 @@
 10.1574    }
 10.1575  }
 10.1576  
 10.1577 -bool ParallelCompactData::chunk_contains(size_t chunk_index, HeapWord* addr) {
 10.1578 -  size_t addr_chunk_index = addr_to_chunk_idx(addr);
 10.1579 -  return chunk_index == addr_chunk_index;
 10.1580 -}
 10.1581 -
 10.1582 -bool ParallelCompactData::chunk_contains_block(size_t chunk_index,
 10.1583 -                                               size_t block_index) {
 10.1584 -  size_t first_block_in_chunk = chunk_index * BlocksPerChunk;
 10.1585 -  size_t last_block_in_chunk = (chunk_index + 1) * BlocksPerChunk - 1;
 10.1586 -
 10.1587 -  return (first_block_in_chunk <= block_index) &&
 10.1588 -         (block_index <= last_block_in_chunk);
 10.1589 +bool ParallelCompactData::region_contains(size_t region_index, HeapWord* addr) {
 10.1590 +  size_t addr_region_index = addr_to_region_idx(addr);
 10.1591 +  return region_index == addr_region_index;
 10.1592  }
 10.1593  
 10.1594  // This method contains no policy. You should probably
 10.1595 @@ -2038,39 +1593,9 @@
 10.1596      }
 10.1597  #endif  // #ifndef PRODUCT
 10.1598  
 10.1599 -#ifdef ASSERT
 10.1600 -    if (VerifyParallelOldWithMarkSweep &&
 10.1601 -        (PSParallelCompact::total_invocations() %
 10.1602 -           VerifyParallelOldWithMarkSweepInterval) == 0) {
 10.1603 -      gclog_or_tty->print_cr("Verify marking with mark_sweep_phase1()");
 10.1604 -      if (PrintGCDetails && Verbose) {
 10.1605 -        gclog_or_tty->print_cr("mark_sweep_phase1:");
 10.1606 -      }
 10.1607 -      // Clear the discovered lists so that discovered objects
 10.1608 -      // don't look like they have been discovered twice.
 10.1609 -      ref_processor()->clear_discovered_references();
 10.1610 -
 10.1611 -      PSMarkSweep::allocate_stacks();
 10.1612 -      MemRegion mr = Universe::heap()->reserved_region();
 10.1613 -      PSMarkSweep::ref_processor()->enable_discovery();
 10.1614 -      PSMarkSweep::mark_sweep_phase1(maximum_heap_compaction);
 10.1615 -    }
 10.1616 -#endif
 10.1617 -
 10.1618      bool max_on_system_gc = UseMaximumCompactionOnSystemGC && is_system_gc;
 10.1619      summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc);
 10.1620  
 10.1621 -#ifdef ASSERT
 10.1622 -    if (VerifyParallelOldWithMarkSweep &&
 10.1623 -        (PSParallelCompact::total_invocations() %
 10.1624 -           VerifyParallelOldWithMarkSweepInterval) == 0) {
 10.1625 -      if (PrintGCDetails && Verbose) {
 10.1626 -        gclog_or_tty->print_cr("mark_sweep_phase2:");
 10.1627 -      }
 10.1628 -      PSMarkSweep::mark_sweep_phase2();
 10.1629 -    }
 10.1630 -#endif
 10.1631 -
 10.1632      COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity"));
 10.1633      COMPILER2_PRESENT(DerivedPointerTable::set_active(false));
 10.1634  
 10.1635 @@ -2078,28 +1603,6 @@
 10.1636      // needed by the compaction for filling holes in the dense prefix.
 10.1637      adjust_roots();
 10.1638  
 10.1639 -#ifdef ASSERT
 10.1640 -    if (VerifyParallelOldWithMarkSweep &&
 10.1641 -        (PSParallelCompact::total_invocations() %
 10.1642 -           VerifyParallelOldWithMarkSweepInterval) == 0) {
 10.1643 -      // Do a separate verify phase so that the verify
 10.1644 -      // code can use the the forwarding pointers to
 10.1645 -      // check the new pointer calculation.  The restore_marks()
 10.1646 -      // has to be done before the real compact.
 10.1647 -      vmthread_cm->set_action(ParCompactionManager::VerifyUpdate);
 10.1648 -      compact_perm(vmthread_cm);
 10.1649 -      compact_serial(vmthread_cm);
 10.1650 -      vmthread_cm->set_action(ParCompactionManager::ResetObjects);
 10.1651 -      compact_perm(vmthread_cm);
 10.1652 -      compact_serial(vmthread_cm);
 10.1653 -      vmthread_cm->set_action(ParCompactionManager::UpdateAndCopy);
 10.1654 -
 10.1655 -      // For debugging only
 10.1656 -      PSMarkSweep::restore_marks();
 10.1657 -      PSMarkSweep::deallocate_stacks();
 10.1658 -    }
 10.1659 -#endif
 10.1660 -
 10.1661      compaction_start.update();
 10.1662      // Does the perm gen always have to be done serially because
 10.1663      // klasses are used in the update of an object?
 10.1664 @@ -2349,7 +1852,7 @@
 10.1665  
 10.1666    ParallelScavengeHeap* heap = gc_heap();
 10.1667    uint parallel_gc_threads = heap->gc_task_manager()->workers();
 10.1668 -  TaskQueueSetSuper* qset = ParCompactionManager::chunk_array();
 10.1669 +  TaskQueueSetSuper* qset = ParCompactionManager::region_array();
 10.1670    ParallelTaskTerminator terminator(parallel_gc_threads, qset);
 10.1671  
 10.1672    PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
 10.1673 @@ -2487,8 +1990,9 @@
 10.1674    move_and_update(cm, perm_space_id);
 10.1675  }
 10.1676  
 10.1677 -void PSParallelCompact::enqueue_chunk_draining_tasks(GCTaskQueue* q,
 10.1678 -                                                     uint parallel_gc_threads) {
 10.1679 +void PSParallelCompact::enqueue_region_draining_tasks(GCTaskQueue* q,
 10.1680 +                                                      uint parallel_gc_threads)
 10.1681 +{
 10.1682    TraceTime tm("drain task setup", print_phases(), true, gclog_or_tty);
 10.1683  
 10.1684    const unsigned int task_count = MAX2(parallel_gc_threads, 1U);
 10.1685 @@ -2496,13 +2000,13 @@
 10.1686      q->enqueue(new DrainStacksCompactionTask());
 10.1687    }
 10.1688  
 10.1689 -  // Find all chunks that are available (can be filled immediately) and
 10.1690 +  // Find all regions that are available (can be filled immediately) and
 10.1691    // distribute them to the thread stacks.  The iteration is done in reverse
 10.1692 -  // order (high to low) so the chunks will be removed in ascending order.
 10.1693 +  // order (high to low) so the regions will be removed in ascending order.
 10.1694  
 10.1695    const ParallelCompactData& sd = PSParallelCompact::summary_data();
 10.1696  
 10.1697 -  size_t fillable_chunks = 0;   // A count for diagnostic purposes.
 10.1698 +  size_t fillable_regions = 0;   // A count for diagnostic purposes.
 10.1699    unsigned int which = 0;       // The worker thread number.
 10.1700  
 10.1701    for (unsigned int id = to_space_id; id > perm_space_id; --id) {
 10.1702 @@ -2510,25 +2014,26 @@
 10.1703      MutableSpace* const space = space_info->space();
 10.1704      HeapWord* const new_top = space_info->new_top();
 10.1705  
 10.1706 -    const size_t beg_chunk = sd.addr_to_chunk_idx(space_info->dense_prefix());
 10.1707 -    const size_t end_chunk = sd.addr_to_chunk_idx(sd.chunk_align_up(new_top));
 10.1708 -    assert(end_chunk > 0, "perm gen cannot be empty");
 10.1709 -
 10.1710 -    for (size_t cur = end_chunk - 1; cur >= beg_chunk; --cur) {
 10.1711 -      if (sd.chunk(cur)->claim_unsafe()) {
 10.1712 +    const size_t beg_region = sd.addr_to_region_idx(space_info->dense_prefix());
 10.1713 +    const size_t end_region =
 10.1714 +      sd.addr_to_region_idx(sd.region_align_up(new_top));
 10.1715 +    assert(end_region > 0, "perm gen cannot be empty");
 10.1716 +
 10.1717 +    for (size_t cur = end_region - 1; cur >= beg_region; --cur) {
 10.1718 +      if (sd.region(cur)->claim_unsafe()) {
 10.1719          ParCompactionManager* cm = ParCompactionManager::manager_array(which);
 10.1720          cm->save_for_processing(cur);
 10.1721  
 10.1722          if (TraceParallelOldGCCompactionPhase && Verbose) {
 10.1723 -          const size_t count_mod_8 = fillable_chunks & 7;
 10.1724 +          const size_t count_mod_8 = fillable_regions & 7;
 10.1725            if (count_mod_8 == 0) gclog_or_tty->print("fillable: ");
 10.1726            gclog_or_tty->print(" " SIZE_FORMAT_W(7), cur);
 10.1727            if (count_mod_8 == 7) gclog_or_tty->cr();
 10.1728          }
 10.1729  
 10.1730 -        NOT_PRODUCT(++fillable_chunks;)
 10.1731 -
 10.1732 -        // Assign chunks to threads in round-robin fashion.
 10.1733 +        NOT_PRODUCT(++fillable_regions;)
 10.1734 +
 10.1735 +        // Assign regions to threads in round-robin fashion.
 10.1736          if (++which == task_count) {
 10.1737            which = 0;
 10.1738          }
 10.1739 @@ -2537,8 +2042,8 @@
 10.1740    }
 10.1741  
 10.1742    if (TraceParallelOldGCCompactionPhase) {
 10.1743 -    if (Verbose && (fillable_chunks & 7) != 0) gclog_or_tty->cr();
 10.1744 -    gclog_or_tty->print_cr("%u initially fillable chunks", fillable_chunks);
 10.1745 +    if (Verbose && (fillable_regions & 7) != 0) gclog_or_tty->cr();
 10.1746 +    gclog_or_tty->print_cr("%u initially fillable regions", fillable_regions);
 10.1747    }
 10.1748  }
 10.1749  
 10.1750 @@ -2551,7 +2056,7 @@
 10.1751    ParallelCompactData& sd = PSParallelCompact::summary_data();
 10.1752  
 10.1753    // Iterate over all the spaces adding tasks for updating
 10.1754 -  // chunks in the dense prefix.  Assume that 1 gc thread
 10.1755 +  // regions in the dense prefix.  Assume that 1 gc thread
 10.1756    // will work on opening the gaps and the remaining gc threads
 10.1757    // will work on the dense prefix.
 10.1758    SpaceId space_id = old_space_id;
 10.1759 @@ -2565,30 +2070,31 @@
 10.1760        continue;
 10.1761      }
 10.1762  
 10.1763 -    // The dense prefix is before this chunk.
 10.1764 -    size_t chunk_index_end_dense_prefix =
 10.1765 -        sd.addr_to_chunk_idx(dense_prefix_end);
 10.1766 -    ChunkData* const dense_prefix_cp = sd.chunk(chunk_index_end_dense_prefix);
 10.1767 +    // The dense prefix is before this region.
 10.1768 +    size_t region_index_end_dense_prefix =
 10.1769 +        sd.addr_to_region_idx(dense_prefix_end);
 10.1770 +    RegionData* const dense_prefix_cp =
 10.1771 +      sd.region(region_index_end_dense_prefix);
 10.1772      assert(dense_prefix_end == space->end() ||
 10.1773             dense_prefix_cp->available() ||
 10.1774             dense_prefix_cp->claimed(),
 10.1775 -           "The chunk after the dense prefix should always be ready to fill");
 10.1776 -
 10.1777 -    size_t chunk_index_start = sd.addr_to_chunk_idx(space->bottom());
 10.1778 +           "The region after the dense prefix should always be ready to fill");
 10.1779 +
 10.1780 +    size_t region_index_start = sd.addr_to_region_idx(space->bottom());
 10.1781  
 10.1782      // Is there dense prefix work?
 10.1783 -    size_t total_dense_prefix_chunks =
 10.1784 -      chunk_index_end_dense_prefix - chunk_index_start;
 10.1785 -    // How many chunks of the dense prefix should be given to
 10.1786 +    size_t total_dense_prefix_regions =
 10.1787 +      region_index_end_dense_prefix - region_index_start;
 10.1788 +    // How many regions of the dense prefix should be given to
 10.1789      // each thread?
 10.1790 -    if (total_dense_prefix_chunks > 0) {
 10.1791 +    if (total_dense_prefix_regions > 0) {
 10.1792        uint tasks_for_dense_prefix = 1;
 10.1793        if (UseParallelDensePrefixUpdate) {
 10.1794 -        if (total_dense_prefix_chunks <=
 10.1795 +        if (total_dense_prefix_regions <=
 10.1796              (parallel_gc_threads * PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING)) {
 10.1797            // Don't over partition.  This assumes that
 10.1798            // PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING is a small integer value
 10.1799 -          // so there are not many chunks to process.
 10.1800 +          // so there are not many regions to process.
 10.1801            tasks_for_dense_prefix = parallel_gc_threads;
 10.1802          } else {
 10.1803            // Over partition
 10.1804 @@ -2596,50 +2102,50 @@
 10.1805              PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING;
 10.1806          }
 10.1807        }
 10.1808 -      size_t chunks_per_thread = total_dense_prefix_chunks /
 10.1809 +      size_t regions_per_thread = total_dense_prefix_regions /
 10.1810          tasks_for_dense_prefix;
 10.1811 -      // Give each thread at least 1 chunk.
 10.1812 -      if (chunks_per_thread == 0) {
 10.1813 -        chunks_per_thread = 1;
 10.1814 +      // Give each thread at least 1 region.
 10.1815 +      if (regions_per_thread == 0) {
 10.1816 +        regions_per_thread = 1;
 10.1817        }
 10.1818  
 10.1819        for (uint k = 0; k < tasks_for_dense_prefix; k++) {
 10.1820 -        if (chunk_index_start >= chunk_index_end_dense_prefix) {
 10.1821 +        if (region_index_start >= region_index_end_dense_prefix) {
 10.1822            break;
 10.1823          }
 10.1824 -        // chunk_index_end is not processed
 10.1825 -        size_t chunk_index_end = MIN2(chunk_index_start + chunks_per_thread,
 10.1826 -                                      chunk_index_end_dense_prefix);
 10.1827 +        // region_index_end is not processed
 10.1828 +        size_t region_index_end = MIN2(region_index_start + regions_per_thread,
 10.1829 +                                       region_index_end_dense_prefix);
 10.1830          q->enqueue(new UpdateDensePrefixTask(
 10.1831                                   space_id,
 10.1832 -                                 chunk_index_start,
 10.1833 -                                 chunk_index_end));
 10.1834 -        chunk_index_start = chunk_index_end;
 10.1835 +                                 region_index_start,
 10.1836 +                                 region_index_end));
 10.1837 +        region_index_start = region_index_end;
 10.1838        }
 10.1839      }
 10.1840      // This gets any part of the dense prefix that did not
 10.1841      // fit evenly.
 10.1842 -    if (chunk_index_start < chunk_index_end_dense_prefix) {
 10.1843 +    if (region_index_start < region_index_end_dense_prefix) {
 10.1844        q->enqueue(new UpdateDensePrefixTask(
 10.1845                                   space_id,
 10.1846 -                                 chunk_index_start,
 10.1847 -                                 chunk_index_end_dense_prefix));
 10.1848 +                                 region_index_start,
 10.1849 +                                 region_index_end_dense_prefix));
 10.1850      }
 10.1851      space_id = next_compaction_space_id(space_id);
 10.1852    }  // End tasks for dense prefix
 10.1853  }
 10.1854  
 10.1855 -void PSParallelCompact::enqueue_chunk_stealing_tasks(
 10.1856 +void PSParallelCompact::enqueue_region_stealing_tasks(
 10.1857                                       GCTaskQueue* q,
 10.1858                                       ParallelTaskTerminator* terminator_ptr,
 10.1859                                       uint parallel_gc_threads) {
 10.1860    TraceTime tm("steal task setup", print_phases(), true, gclog_or_tty);
 10.1861  
 10.1862 -  // Once a thread has drained it's stack, it should try to steal chunks from
 10.1863 +  // Once a thread has drained it's stack, it should try to steal regions from
 10.1864    // other threads.
 10.1865    if (parallel_gc_threads > 1) {
 10.1866      for (uint j = 0; j < parallel_gc_threads; j++) {
 10.1867 -      q->enqueue(new StealChunkCompactionTask(terminator_ptr));
 10.1868 +      q->enqueue(new StealRegionCompactionTask(terminator_ptr));
 10.1869      }
 10.1870    }
 10.1871  }
 10.1872 @@ -2654,13 +2160,13 @@
 10.1873    PSOldGen* old_gen = heap->old_gen();
 10.1874    old_gen->start_array()->reset();
 10.1875    uint parallel_gc_threads = heap->gc_task_manager()->workers();
 10.1876 -  TaskQueueSetSuper* qset = ParCompactionManager::chunk_array();
 10.1877 +  TaskQueueSetSuper* qset = ParCompactionManager::region_array();
 10.1878    ParallelTaskTerminator terminator(parallel_gc_threads, qset);
 10.1879  
 10.1880    GCTaskQueue* q = GCTaskQueue::create();
 10.1881 -  enqueue_chunk_draining_tasks(q, parallel_gc_threads);
 10.1882 +  enqueue_region_draining_tasks(q, parallel_gc_threads);
 10.1883    enqueue_dense_prefix_tasks(q, parallel_gc_threads);
 10.1884 -  enqueue_chunk_stealing_tasks(q, &terminator, parallel_gc_threads);
 10.1885 +  enqueue_region_stealing_tasks(q, &terminator, parallel_gc_threads);
 10.1886  
 10.1887    {
 10.1888      TraceTime tm_pc("par compact", print_phases(), true, gclog_or_tty);
 10.1889 @@ -2676,9 +2182,9 @@
 10.1890      WaitForBarrierGCTask::destroy(fin);
 10.1891  
 10.1892  #ifdef  ASSERT
 10.1893 -    // Verify that all chunks have been processed before the deferred updates.
 10.1894 +    // Verify that all regions have been processed before the deferred updates.
 10.1895      // Note that perm_space_id is skipped; this type of verification is not
 10.1896 -    // valid until the perm gen is compacted by chunks.
 10.1897 +    // valid until the perm gen is compacted by regions.
 10.1898      for (unsigned int id = old_space_id; id < last_space_id; ++id) {
 10.1899        verify_complete(SpaceId(id));
 10.1900      }
 10.1901 @@ -2697,42 +2203,42 @@
 10.1902  
 10.1903  #ifdef  ASSERT
 10.1904  void PSParallelCompact::verify_complete(SpaceId space_id) {
 10.1905 -  // All Chunks between space bottom() to new_top() should be marked as filled
 10.1906 -  // and all Chunks between new_top() and top() should be available (i.e.,
 10.1907 +  // All Regions between space bottom() to new_top() should be marked as filled
 10.1908 +  // and all Regions between new_top() and top() should be available (i.e.,
 10.1909    // should have been emptied).
 10.1910    ParallelCompactData& sd = summary_data();
 10.1911    SpaceInfo si = _space_info[space_id];
 10.1912 -  HeapWord* new_top_addr = sd.chunk_align_up(si.new_top());
 10.1913 -  HeapWord* old_top_addr = sd.chunk_align_up(si.space()->top());
 10.1914 -  const size_t beg_chunk = sd.addr_to_chunk_idx(si.space()->bottom());
 10.1915 -  const size_t new_top_chunk = sd.addr_to_chunk_idx(new_top_addr);
 10.1916 -  const size_t old_top_chunk = sd.addr_to_chunk_idx(old_top_addr);
 10.1917 +  HeapWord* new_top_addr = sd.region_align_up(si.new_top());
 10.1918 +  HeapWord* old_top_addr = sd.region_align_up(si.space()->top());
 10.1919 +  const size_t beg_region = sd.addr_to_region_idx(si.space()->bottom());
 10.1920 +  const size_t new_top_region = sd.addr_to_region_idx(new_top_addr);
 10.1921 +  const size_t old_top_region = sd.addr_to_region_idx(old_top_addr);
 10.1922  
 10.1923    bool issued_a_warning = false;
 10.1924  
 10.1925 -  size_t cur_chunk;
 10.1926 -  for (cur_chunk = beg_chunk; cur_chunk < new_top_chunk; ++cur_chunk) {
 10.1927 -    const ChunkData* const c = sd.chunk(cur_chunk);
 10.1928 +  size_t cur_region;
 10.1929 +  for (cur_region = beg_region; cur_region < new_top_region; ++cur_region) {
 10.1930 +    const RegionData* const c = sd.region(cur_region);
 10.1931      if (!c->completed()) {
 10.1932 -      warning("chunk " SIZE_FORMAT " not filled:  "
 10.1933 +      warning("region " SIZE_FORMAT " not filled:  "
 10.1934                "destination_count=" SIZE_FORMAT,
 10.1935 -              cur_chunk, c->destination_count());
 10.1936 +              cur_region, c->destination_count());
 10.1937        issued_a_warning = true;
 10.1938      }
 10.1939    }
 10.1940  
 10.1941 -  for (cur_chunk = new_top_chunk; cur_chunk < old_top_chunk; ++cur_chunk) {
 10.1942 -    const ChunkData* const c = sd.chunk(cur_chunk);
 10.1943 +  for (cur_region = new_top_region; cur_region < old_top_region; ++cur_region) {
 10.1944 +    const RegionData* const c = sd.region(cur_region);
 10.1945      if (!c->available()) {
 10.1946 -      warning("chunk " SIZE_FORMAT " not empty:   "
 10.1947 +      warning("region " SIZE_FORMAT " not empty:   "
 10.1948                "destination_count=" SIZE_FORMAT,
 10.1949 -              cur_chunk, c->destination_count());
 10.1950 +              cur_region, c->destination_count());
 10.1951        issued_a_warning = true;
 10.1952      }
 10.1953    }
 10.1954  
 10.1955    if (issued_a_warning) {
 10.1956 -    print_chunk_ranges();
 10.1957 +    print_region_ranges();
 10.1958    }
 10.1959  }
 10.1960  #endif  // #ifdef ASSERT
 10.1961 @@ -2933,46 +2439,47 @@
 10.1962  }
 10.1963  #endif //VALIDATE_MARK_SWEEP
 10.1964  
 10.1965 -// Update interior oops in the ranges of chunks [beg_chunk, end_chunk).
 10.1966 +// Update interior oops in the ranges of regions [beg_region, end_region).
 10.1967  void
 10.1968  PSParallelCompact::update_and_deadwood_in_dense_prefix(ParCompactionManager* cm,
 10.1969                                                         SpaceId space_id,
 10.1970 -                                                       size_t beg_chunk,
 10.1971 -                                                       size_t end_chunk) {
 10.1972 +                                                       size_t beg_region,
 10.1973 +                                                       size_t end_region) {
 10.1974    ParallelCompactData& sd = summary_data();
 10.1975    ParMarkBitMap* const mbm = mark_bitmap();
 10.1976  
 10.1977 -  HeapWord* beg_addr = sd.chunk_to_addr(beg_chunk);
 10.1978 -  HeapWord* const end_addr = sd.chunk_to_addr(end_chunk);
 10.1979 -  assert(beg_chunk <= end_chunk, "bad chunk range");
 10.1980 +  HeapWord* beg_addr = sd.region_to_addr(beg_region);
 10.1981 +  HeapWord* const end_addr = sd.region_to_addr(end_region);
 10.1982 +  assert(beg_region <= end_region, "bad region range");
 10.1983    assert(end_addr <= dense_prefix(space_id), "not in the dense prefix");
 10.1984  
 10.1985  #ifdef  ASSERT
 10.1986 -  // Claim the chunks to avoid triggering an assert when they are marked as
 10.1987 +  // Claim the regions to avoid triggering an assert when they are marked as
 10.1988    // filled.
 10.1989 -  for (size_t claim_chunk = beg_chunk; claim_chunk < end_chunk; ++claim_chunk) {
 10.1990 -    assert(sd.chunk(claim_chunk)->claim_unsafe(), "claim() failed");
 10.1991 +  for (size_t claim_region = beg_region; claim_region < end_region; ++claim_region) {
 10.1992 +    assert(sd.region(claim_region)->claim_unsafe(), "claim() failed");
 10.1993    }
 10.1994  #endif  // #ifdef ASSERT
 10.1995  
 10.1996    if (beg_addr != space(space_id)->bottom()) {
 10.1997      // Find the first live object or block of dead space that *starts* in this
 10.1998 -    // range of chunks.  If a partial object crosses onto the chunk, skip it; it
 10.1999 -    // will be marked for 'deferred update' when the object head is processed.
 10.2000 -    // If dead space crosses onto the chunk, it is also skipped; it will be
 10.2001 -    // filled when the prior chunk is processed.  If neither of those apply, the
 10.2002 -    // first word in the chunk is the start of a live object or dead space.
 10.2003 +    // range of regions.  If a partial object crosses onto the region, skip it;
 10.2004 +    // it will be marked for 'deferred update' when the object head is
 10.2005 +    // processed.  If dead space crosses onto the region, it is also skipped; it
 10.2006 +    // will be filled when the prior region is processed.  If neither of those
 10.2007 +    // apply, the first word in the region is the start of a live object or dead
 10.2008 +    // space.
 10.2009      assert(beg_addr > space(space_id)->bottom(), "sanity");
 10.2010 -    const ChunkData* const cp = sd.chunk(beg_chunk);
 10.2011 +    const RegionData* const cp = sd.region(beg_region);
 10.2012      if (cp->partial_obj_size() != 0) {
 10.2013 -      beg_addr = sd.partial_obj_end(beg_chunk);
 10.2014 +      beg_addr = sd.partial_obj_end(beg_region);
 10.2015      } else if (dead_space_crosses_boundary(cp, mbm->addr_to_bit(beg_addr))) {
 10.2016        beg_addr = mbm->find_obj_beg(beg_addr, end_addr);
 10.2017      }
 10.2018    }
 10.2019  
 10.2020    if (beg_addr < end_addr) {
 10.2021 -    // A live object or block of dead space starts in this range of Chunks.
 10.2022 +    // A live object or block of dead space starts in this range of Regions.
 10.2023       HeapWord* const dense_prefix_end = dense_prefix(space_id);
 10.2024  
 10.2025      // Create closures and iterate.
 10.2026 @@ -2986,10 +2493,10 @@
 10.2027      }
 10.2028    }
 10.2029  
 10.2030 -  // Mark the chunks as filled.
 10.2031 -  ChunkData* const beg_cp = sd.chunk(beg_chunk);
 10.2032 -  ChunkData* const end_cp = sd.chunk(end_chunk);
 10.2033 -  for (ChunkData* cp = beg_cp; cp < end_cp; ++cp) {
 10.2034 +  // Mark the regions as filled.
 10.2035 +  RegionData* const beg_cp = sd.region(beg_region);
 10.2036 +  RegionData* const end_cp = sd.region(end_region);
 10.2037 +  for (RegionData* cp = beg_cp; cp < end_cp; ++cp) {
 10.2038      cp->set_completed();
 10.2039    }
 10.2040  }
 10.2041 @@ -3021,13 +2528,13 @@
 10.2042    const MutableSpace* const space = space_info->space();
 10.2043    assert(space_info->dense_prefix() >= space->bottom(), "dense_prefix not set");
 10.2044    HeapWord* const beg_addr = space_info->dense_prefix();
 10.2045 -  HeapWord* const end_addr = sd.chunk_align_up(space_info->new_top());
 10.2046 -
 10.2047 -  const ChunkData* const beg_chunk = sd.addr_to_chunk_ptr(beg_addr);
 10.2048 -  const ChunkData* const end_chunk = sd.addr_to_chunk_ptr(end_addr);
 10.2049 -  const ChunkData* cur_chunk;
 10.2050 -  for (cur_chunk = beg_chunk; cur_chunk < end_chunk; ++cur_chunk) {
 10.2051 -    HeapWord* const addr = cur_chunk->deferred_obj_addr();
 10.2052 +  HeapWord* const end_addr = sd.region_align_up(space_info->new_top());
 10.2053 +
 10.2054 +  const RegionData* const beg_region = sd.addr_to_region_ptr(beg_addr);
 10.2055 +  const RegionData* const end_region = sd.addr_to_region_ptr(end_addr);
 10.2056 +  const RegionData* cur_region;
 10.2057 +  for (cur_region = beg_region; cur_region < end_region; ++cur_region) {
 10.2058 +    HeapWord* const addr = cur_region->deferred_obj_addr();
 10.2059      if (addr != NULL) {
 10.2060        if (start_array != NULL) {
 10.2061          start_array->allocate_block(addr);
 10.2062 @@ -3073,45 +2580,45 @@
 10.2063  
 10.2064  HeapWord*
 10.2065  PSParallelCompact::first_src_addr(HeapWord* const dest_addr,
 10.2066 -                                 size_t src_chunk_idx)
 10.2067 +                                 size_t src_region_idx)
 10.2068  {
 10.2069    ParMarkBitMap* const bitmap = mark_bitmap();
 10.2070    const ParallelCompactData& sd = summary_data();
 10.2071 -  const size_t ChunkSize = ParallelCompactData::ChunkSize;
 10.2072 -
 10.2073 -  assert(sd.is_chunk_aligned(dest_addr), "not aligned");
 10.2074 -
 10.2075 -  const ChunkData* const src_chunk_ptr = sd.chunk(src_chunk_idx);
 10.2076 -  const size_t partial_obj_size = src_chunk_ptr->partial_obj_size();
 10.2077 -  HeapWord* const src_chunk_destination = src_chunk_ptr->destination();
 10.2078 -
 10.2079 -  assert(dest_addr >= src_chunk_destination, "wrong src chunk");
 10.2080 -  assert(src_chunk_ptr->data_size() > 0, "src chunk cannot be empty");
 10.2081 -
 10.2082 -  HeapWord* const src_chunk_beg = sd.chunk_to_addr(src_chunk_idx);
 10.2083 -  HeapWord* const src_chunk_end = src_chunk_beg + ChunkSize;
 10.2084 -
 10.2085 -  HeapWord* addr = src_chunk_beg;
 10.2086 -  if (dest_addr == src_chunk_destination) {
 10.2087 -    // Return the first live word in the source chunk.
 10.2088 +  const size_t RegionSize = ParallelCompactData::RegionSize;
 10.2089 +
 10.2090 +  assert(sd.is_region_aligned(dest_addr), "not aligned");
 10.2091 +
 10.2092 +  const RegionData* const src_region_ptr = sd.region(src_region_idx);
 10.2093 +  const size_t partial_obj_size = src_region_ptr->partial_obj_size();
 10.2094 +  HeapWord* const src_region_destination = src_region_ptr->destination();
 10.2095 +
 10.2096 +  assert(dest_addr >= src_region_destination, "wrong src region");
 10.2097 +  assert(src_region_ptr->data_size() > 0, "src region cannot be empty");
 10.2098 +
 10.2099 +  HeapWord* const src_region_beg = sd.region_to_addr(src_region_idx);
 10.2100 +  HeapWord* const src_region_end = src_region_beg + RegionSize;
 10.2101 +
 10.2102 +  HeapWord* addr = src_region_beg;
 10.2103 +  if (dest_addr == src_region_destination) {
 10.2104 +    // Return the first live word in the source region.
 10.2105      if (partial_obj_size == 0) {
 10.2106 -      addr = bitmap->find_obj_beg(addr, src_chunk_end);
 10.2107 -      assert(addr < src_chunk_end, "no objects start in src chunk");
 10.2108 +      addr = bitmap->find_obj_beg(addr, src_region_end);
 10.2109 +      assert(addr < src_region_end, "no objects start in src region");
 10.2110      }
 10.2111      return addr;
 10.2112    }
 10.2113  
 10.2114    // Must skip some live data.
 10.2115 -  size_t words_to_skip = dest_addr - src_chunk_destination;
 10.2116 -  assert(src_chunk_ptr->data_size() > words_to_skip, "wrong src chunk");
 10.2117 +  size_t words_to_skip = dest_addr - src_region_destination;
 10.2118 +  assert(src_region_ptr->data_size() > words_to_skip, "wrong src region");
 10.2119  
 10.2120    if (partial_obj_size >= words_to_skip) {
 10.2121      // All the live words to skip are part of the partial object.
 10.2122      addr += words_to_skip;
 10.2123      if (partial_obj_size == words_to_skip) {
 10.2124        // Find the first live word past the partial object.
 10.2125 -      addr = bitmap->find_obj_beg(addr, src_chunk_end);
 10.2126 -      assert(addr < src_chunk_end, "wrong src chunk");
 10.2127 +      addr = bitmap->find_obj_beg(addr, src_region_end);
 10.2128 +      assert(addr < src_region_end, "wrong src region");
 10.2129      }
 10.2130      return addr;
 10.2131    }
 10.2132 @@ -3122,63 +2629,64 @@
 10.2133      addr += partial_obj_size;
 10.2134    }
 10.2135  
 10.2136 -  // Skip over live words due to objects that start in the chunk.
 10.2137 -  addr = skip_live_words(addr, src_chunk_end, words_to_skip);
 10.2138 -  assert(addr < src_chunk_end, "wrong src chunk");
 10.2139 +  // Skip over live words due to objects that start in the region.
 10.2140 +  addr = skip_live_words(addr, src_region_end, words_to_skip);
 10.2141 +  assert(addr < src_region_end, "wrong src region");
 10.2142    return addr;
 10.2143  }
 10.2144  
 10.2145  void PSParallelCompact::decrement_destination_counts(ParCompactionManager* cm,
 10.2146 -                                                     size_t beg_chunk,
 10.2147 +                                                     size_t beg_region,
 10.2148                                                       HeapWord* end_addr)
 10.2149  {
 10.2150    ParallelCompactData& sd = summary_data();
 10.2151 -  ChunkData* const beg = sd.chunk(beg_chunk);
 10.2152 -  HeapWord* const end_addr_aligned_up = sd.chunk_align_up(end_addr);
 10.2153 -  ChunkData* const end = sd.addr_to_chunk_ptr(end_addr_aligned_up);
 10.2154 -  size_t cur_idx = beg_chunk;
 10.2155 -  for (ChunkData* cur = beg; cur < end; ++cur, ++cur_idx) {
 10.2156 -    assert(cur->data_size() > 0, "chunk must have live data");
 10.2157 +  RegionData* const beg = sd.region(beg_region);
 10.2158 +  HeapWord* const end_addr_aligned_up = sd.region_align_up(end_addr);
 10.2159 +  RegionData* const end = sd.addr_to_region_ptr(end_addr_aligned_up);
 10.2160 +  size_t cur_idx = beg_region;
 10.2161 +  for (RegionData* cur = beg; cur < end; ++cur, ++cur_idx) {
 10.2162 +    assert(cur->data_size() > 0, "region must have live data");
 10.2163      cur->decrement_destination_count();
 10.2164 -    if (cur_idx <= cur->source_chunk() && cur->available() && cur->claim()) {
 10.2165 +    if (cur_idx <= cur->source_region() && cur->available() && cur->claim()) {
 10.2166        cm->save_for_processing(cur_idx);
 10.2167      }
 10.2168    }
 10.2169  }
 10.2170  
 10.2171 -size_t PSParallelCompact::next_src_chunk(MoveAndUpdateClosure& closure,
 10.2172 -                                         SpaceId& src_space_id,
 10.2173 -                                         HeapWord*& src_space_top,
 10.2174 -                                         HeapWord* end_addr)
 10.2175 +size_t PSParallelCompact::next_src_region(MoveAndUpdateClosure& closure,
 10.2176 +                                          SpaceId& src_space_id,
 10.2177 +                                          HeapWord*& src_space_top,
 10.2178 +                                          HeapWord* end_addr)
 10.2179  {
 10.2180 -  typedef ParallelCompactData::ChunkData ChunkData;
 10.2181 +  typedef ParallelCompactData::RegionData RegionData;
 10.2182  
 10.2183    ParallelCompactData& sd = PSParallelCompact::summary_data();
 10.2184 -  const size_t chunk_size = ParallelCompactData::ChunkSize;
 10.2185 -
 10.2186 -  size_t src_chunk_idx = 0;
 10.2187 -
 10.2188 -  // Skip empty chunks (if any) up to the top of the space.
 10.2189 -  HeapWord* const src_aligned_up = sd.chunk_align_up(end_addr);
 10.2190 -  ChunkData* src_chunk_ptr = sd.addr_to_chunk_ptr(src_aligned_up);
 10.2191 -  HeapWord* const top_aligned_up = sd.chunk_align_up(src_space_top);
 10.2192 -  const ChunkData* const top_chunk_ptr = sd.addr_to_chunk_ptr(top_aligned_up);
 10.2193 -  while (src_chunk_ptr < top_chunk_ptr && src_chunk_ptr->data_size() == 0) {
 10.2194 -    ++src_chunk_ptr;
 10.2195 +  const size_t region_size = ParallelCompactData::RegionSize;
 10.2196 +
 10.2197 +  size_t src_region_idx = 0;
 10.2198 +
 10.2199 +  // Skip empty regions (if any) up to the top of the space.
 10.2200 +  HeapWord* const src_aligned_up = sd.region_align_up(end_addr);
 10.2201 +  RegionData* src_region_ptr = sd.addr_to_region_ptr(src_aligned_up);
 10.2202 +  HeapWord* const top_aligned_up = sd.region_align_up(src_space_top);
 10.2203 +  const RegionData* const top_region_ptr =
 10.2204 +    sd.addr_to_region_ptr(top_aligned_up);
 10.2205 +  while (src_region_ptr < top_region_ptr && src_region_ptr->data_size() == 0) {
 10.2206 +    ++src_region_ptr;
 10.2207    }
 10.2208  
 10.2209 -  if (src_chunk_ptr < top_chunk_ptr) {
 10.2210 -    // The next source chunk is in the current space.  Update src_chunk_idx and
 10.2211 -    // the source address to match src_chunk_ptr.
 10.2212 -    src_chunk_idx = sd.chunk(src_chunk_ptr);
 10.2213 -    HeapWord* const src_chunk_addr = sd.chunk_to_addr(src_chunk_idx);
 10.2214 -    if (src_chunk_addr > closure.source()) {
 10.2215 -      closure.set_source(src_chunk_addr);
 10.2216 +  if (src_region_ptr < top_region_ptr) {
 10.2217 +    // The next source region is in the current space.  Update src_region_idx
 10.2218 +    // and the source address to match src_region_ptr.
 10.2219 +    src_region_idx = sd.region(src_region_ptr);
 10.2220 +    HeapWord* const src_region_addr = sd.region_to_addr(src_region_idx);
 10.2221 +    if (src_region_addr > closure.source()) {
 10.2222 +      closure.set_source(src_region_addr);
 10.2223      }
 10.2224 -    return src_chunk_idx;
 10.2225 +    return src_region_idx;
 10.2226    }
 10.2227  
 10.2228 -  // Switch to a new source space and find the first non-empty chunk.
 10.2229 +  // Switch to a new source space and find the first non-empty region.
 10.2230    unsigned int space_id = src_space_id + 1;
 10.2231    assert(space_id < last_space_id, "not enough spaces");
 10.2232  
 10.2233 @@ -3187,14 +2695,14 @@
 10.2234    do {
 10.2235      MutableSpace* space = _space_info[space_id].space();
 10.2236      HeapWord* const bottom = space->bottom();
 10.2237 -    const ChunkData* const bottom_cp = sd.addr_to_chunk_ptr(bottom);
 10.2238 +    const RegionData* const bottom_cp = sd.addr_to_region_ptr(bottom);
 10.2239  
 10.2240      // Iterate over the spaces that do not compact into themselves.
 10.2241      if (bottom_cp->destination() != bottom) {
 10.2242 -      HeapWord* const top_aligned_up = sd.chunk_align_up(space->top());
 10.2243 -      const ChunkData* const top_cp = sd.addr_to_chunk_ptr(top_aligned_up);
 10.2244 -
 10.2245 -      for (const ChunkData* src_cp = bottom_cp; src_cp < top_cp; ++src_cp) {
 10.2246 +      HeapWord* const top_aligned_up = sd.region_align_up(space->top());
 10.2247 +      const RegionData* const top_cp = sd.addr_to_region_ptr(top_aligned_up);
 10.2248 +
 10.2249 +      for (const RegionData* src_cp = bottom_cp; src_cp < top_cp; ++src_cp) {
 10.2250          if (src_cp->live_obj_size() > 0) {
 10.2251            // Found it.
 10.2252            assert(src_cp->destination() == destination,
 10.2253 @@ -3204,9 +2712,9 @@
 10.2254  
 10.2255            src_space_id = SpaceId(space_id);
 10.2256            src_space_top = space->top();
 10.2257 -          const size_t src_chunk_idx = sd.chunk(src_cp);
 10.2258 -          closure.set_source(sd.chunk_to_addr(src_chunk_idx));
 10.2259 -          return src_chunk_idx;
 10.2260 +          const size_t src_region_idx = sd.region(src_cp);
 10.2261 +          closure.set_source(sd.region_to_addr(src_region_idx));
 10.2262 +          return src_region_idx;
 10.2263          } else {
 10.2264            assert(src_cp->data_size() == 0, "sanity");
 10.2265          }
 10.2266 @@ -3214,38 +2722,38 @@
 10.2267      }
 10.2268    } while (++space_id < last_space_id);
 10.2269  
 10.2270 -  assert(false, "no source chunk was found");
 10.2271 +  assert(false, "no source region was found");
 10.2272    return 0;
 10.2273  }
 10.2274  
 10.2275 -void PSParallelCompact::fill_chunk(ParCompactionManager* cm, size_t chunk_idx)
 10.2276 +void PSParallelCompact::fill_region(ParCompactionManager* cm, size_t region_idx)
 10.2277  {
 10.2278    typedef ParMarkBitMap::IterationStatus IterationStatus;
 10.2279 -  const size_t ChunkSize = ParallelCompactData::ChunkSize;
 10.2280 +  const size_t RegionSize = ParallelCompactData::RegionSize;
 10.2281    ParMarkBitMap* const bitmap = mark_bitmap();
 10.2282    ParallelCompactData& sd = summary_data();
 10.2283 -  ChunkData* const chunk_ptr = sd.chunk(chunk_idx);
 10.2284 +  RegionData* const region_ptr = sd.region(region_idx);
 10.2285  
 10.2286    // Get the items needed to construct the closure.
 10.2287 -  HeapWord* dest_addr = sd.chunk_to_addr(chunk_idx);
 10.2288 +  HeapWord* dest_addr = sd.region_to_addr(region_idx);
 10.2289    SpaceId dest_space_id = space_id(dest_addr);
 10.2290    ObjectStartArray* start_array = _space_info[dest_space_id].start_array();
 10.2291    HeapWord* new_top = _space_info[dest_space_id].new_top();
 10.2292    assert(dest_addr < new_top, "sanity");
 10.2293 -  const size_t words = MIN2(pointer_delta(new_top, dest_addr), ChunkSize);
 10.2294 -
 10.2295 -  // Get the source chunk and related info.
 10.2296 -  size_t src_chunk_idx = chunk_ptr->source_chunk();
 10.2297 -  SpaceId src_space_id = space_id(sd.chunk_to_addr(src_chunk_idx));
 10.2298 +  const size_t words = MIN2(pointer_delta(new_top, dest_addr), RegionSize);
 10.2299 +
 10.2300 +  // Get the source region and related info.
 10.2301 +  size_t src_region_idx = region_ptr->source_region();
 10.2302 +  SpaceId src_space_id = space_id(sd.region_to_addr(src_region_idx));
 10.2303    HeapWord* src_space_top = _space_info[src_space_id].space()->top();
 10.2304  
 10.2305    MoveAndUpdateClosure closure(bitmap, cm, start_array, dest_addr, words);
 10.2306 -  closure.set_source(first_src_addr(dest_addr, src_chunk_idx));
 10.2307 -
 10.2308 -  // Adjust src_chunk_idx to prepare for decrementing destination counts (the
 10.2309 -  // destination count is not decremented when a chunk is copied to itself).
 10.2310 -  if (src_chunk_idx == chunk_idx) {
 10.2311 -    src_chunk_idx += 1;
 10.2312 +  closure.set_source(first_src_addr(dest_addr, src_region_idx));
 10.2313 +
 10.2314 +  // Adjust src_region_idx to prepare for decrementing destination counts (the
 10.2315 +  // destination count is not decremented when a region is copied to itself).
 10.2316 +  if (src_region_idx == region_idx) {
 10.2317 +    src_region_idx += 1;
 10.2318    }
 10.2319  
 10.2320    if (bitmap->is_unmarked(closure.source())) {
 10.2321 @@ -3255,32 +2763,33 @@
 10.2322      HeapWord* const old_src_addr = closure.source();
 10.2323      closure.copy_partial_obj();
 10.2324      if (closure.is_full()) {
 10.2325 -      decrement_destination_counts(cm, src_chunk_idx, closure.source());
 10.2326 -      chunk_ptr->set_deferred_obj_addr(NULL);
 10.2327 -      chunk_ptr->set_completed();
 10.2328 +      decrement_destination_counts(cm, src_region_idx, closure.source());
 10.2329 +      region_ptr->set_deferred_obj_addr(NULL);
 10.2330 +      region_ptr->set_completed();
 10.2331        return;
 10.2332      }
 10.2333  
 10.2334 -    HeapWord* const end_addr = sd.chunk_align_down(closure.source());
 10.2335 -    if (sd.chunk_align_down(old_src_addr) != end_addr) {
 10.2336 -      // The partial object was copied from more than one source chunk.
 10.2337 -      decrement_destination_counts(cm, src_chunk_idx, end_addr);
 10.2338 -
 10.2339 -      // Move to the next source chunk, possibly switching spaces as well.  All
 10.2340 +    HeapWord* const end_addr = sd.region_align_down(closure.source());
 10.2341 +    if (sd.region_align_down(old_src_addr) != end_addr) {
 10.2342 +      // The partial object was copied from more than one source region.
 10.2343 +      decrement_destination_counts(cm, src_region_idx, end_addr);
 10.2344 +
 10.2345 +      // Move to the next source region, possibly switching spaces as well.  All
 10.2346        // args except end_addr may be modified.
 10.2347 -      src_chunk_idx = next_src_chunk(closure, src_space_id, src_space_top,
 10.2348 -                                     end_addr);
 10.2349 +      src_region_idx = next_src_region(closure, src_space_id, src_space_top,
 10.2350 +                                       end_addr);
 10.2351      }
 10.2352    }
 10.2353  
 10.2354    do {
 10.2355      HeapWord* const cur_addr = closure.source();
 10.2356 -    HeapWord* const end_addr = MIN2(sd.chunk_align_up(cur_addr + 1),
 10.2357 +    HeapWord* const end_addr = MIN2(sd.region_align_up(cur_addr + 1),
 10.2358                                      src_space_top);
 10.2359      IterationStatus status = bitmap->iterate(&closure, cur_addr, end_addr);
 10.2360  
 10.2361      if (status == ParMarkBitMap::incomplete) {
 10.2362 -      // The last obj that starts in the source chunk does not end in the chunk.
 10.2363 +      // The last obj that starts in the source region does not end in the
 10.2364 +      // region.
 10.2365        assert(closure.source() < end_addr, "sanity")
 10.2366        HeapWord* const obj_beg = closure.source();
 10.2367        HeapWord* const range_end = MIN2(obj_beg + closure.words_remaining(),
 10.2368 @@ -3299,28 +2808,28 @@
 10.2369  
 10.2370      if (status == ParMarkBitMap::would_overflow) {
 10.2371        // The last object did not fit.  Note that interior oop updates were
 10.2372 -      // deferred, then copy enough of the object to fill the chunk.
 10.2373 -      chunk_ptr->set_deferred_obj_addr(closure.destination());
 10.2374 +      // deferred, then copy enough of the object to fill the region.
 10.2375 +      region_ptr->set_deferred_obj_addr(closure.destination());
 10.2376        status = closure.copy_until_full(); // copies from closure.source()
 10.2377  
 10.2378 -      decrement_destination_counts(cm, src_chunk_idx, closure.source());
 10.2379 -      chunk_ptr->set_completed();
 10.2380 +      decrement_destination_counts(cm, src_region_idx, closure.source());
 10.2381 +      region_ptr->set_completed();
 10.2382        return;
 10.2383      }
 10.2384  
 10.2385      if (status == ParMarkBitMap::full) {
 10.2386 -      decrement_destination_counts(cm, src_chunk_idx, closure.source());
 10.2387 -      chunk_ptr->set_deferred_obj_addr(NULL);
 10.2388 -      chunk_ptr->set_completed();
 10.2389 +      decrement_destination_counts(cm, src_region_idx, closure.source());
 10.2390 +      region_ptr->set_deferred_obj_addr(NULL);
 10.2391 +      region_ptr->set_completed();
 10.2392        return;
 10.2393      }
 10.2394  
 10.2395 -    decrement_destination_counts(cm, src_chunk_idx, end_addr);
 10.2396 -
 10.2397 -    // Move to the next source chunk, possibly switching spaces as well.  All
 10.2398 +    decrement_destination_counts(cm, src_region_idx, end_addr);
 10.2399 +
 10.2400 +    // Move to the next source region, possibly switching spaces as well.  All
 10.2401      // args except end_addr may be modified.
 10.2402 -    src_chunk_idx = next_src_chunk(closure, src_space_id, src_space_top,
 10.2403 -                                   end_addr);
 10.2404 +    src_region_idx = next_src_region(closure, src_space_id, src_space_top,
 10.2405 +                                     end_addr);
 10.2406    } while (true);
 10.2407  }
 10.2408  
 10.2409 @@ -3352,15 +2861,15 @@
 10.2410    }
 10.2411  #endif
 10.2412  
 10.2413 -  const size_t beg_chunk = sd.addr_to_chunk_idx(beg_addr);
 10.2414 -  const size_t dp_chunk = sd.addr_to_chunk_idx(dp_addr);
 10.2415 -  if (beg_chunk < dp_chunk) {
 10.2416 -    update_and_deadwood_in_dense_prefix(cm, space_id, beg_chunk, dp_chunk);
 10.2417 +  const size_t beg_region = sd.addr_to_region_idx(beg_addr);
 10.2418 +  const size_t dp_region = sd.addr_to_region_idx(dp_addr);
 10.2419 +  if (beg_region < dp_region) {
 10.2420 +    update_and_deadwood_in_dense_prefix(cm, space_id, beg_region, dp_region);
 10.2421    }
 10.2422  
 10.2423 -  // The destination of the first live object that starts in the chunk is one
 10.2424 -  // past the end of the partial object entering the chunk (if any).
 10.2425 -  HeapWord* const dest_addr = sd.partial_obj_end(dp_chunk);
 10.2426 +  // The destination of the first live object that starts in the region is one
 10.2427 +  // past the end of the partial object entering the region (if any).
 10.2428 +  HeapWord* const dest_addr = sd.partial_obj_end(dp_region);
 10.2429    HeapWord* const new_top = _space_info[space_id].new_top();
 10.2430    assert(new_top >= dest_addr, "bad new_top value");
 10.2431    const size_t words = pointer_delta(new_top, dest_addr);
 10.2432 @@ -3469,172 +2978,6 @@
 10.2433    return ParMarkBitMap::incomplete;
 10.2434  }
 10.2435  
 10.2436 -BitBlockUpdateClosure::BitBlockUpdateClosure(ParMarkBitMap* mbm,
 10.2437 -                        ParCompactionManager* cm,
 10.2438 -                        size_t chunk_index) :
 10.2439 -                        ParMarkBitMapClosure(mbm, cm),
 10.2440 -                        _live_data_left(0),
 10.2441 -                        _cur_block(0) {
 10.2442 -  _chunk_start =
 10.2443 -    PSParallelCompact::summary_data().chunk_to_addr(chunk_index);
 10.2444 -  _chunk_end =
 10.2445 -    PSParallelCompact::summary_data().chunk_to_addr(chunk_index) +
 10.2446 -                 ParallelCompactData::ChunkSize;
 10.2447 -  _chunk_index = chunk_index;
 10.2448 -  _cur_block =
 10.2449 -    PSParallelCompact::summary_data().addr_to_block_idx(_chunk_start);
 10.2450 -}
 10.2451 -
 10.2452 -bool BitBlockUpdateClosure::chunk_contains_cur_block() {
 10.2453 -  return ParallelCompactData::chunk_contains_block(_chunk_index, _cur_block);
 10.2454 -}
 10.2455 -
 10.2456 -void BitBlockUpdateClosure::reset_chunk(size_t chunk_index) {
 10.2457 -  DEBUG_ONLY(ParallelCompactData::BlockData::set_cur_phase(7);)
 10.2458 -  ParallelCompactData& sd = PSParallelCompact::summary_data();
 10.2459 -  _chunk_index = chunk_index;
 10.2460 -  _live_data_left = 0;
 10.2461 -  _chunk_start = sd.chunk_to_addr(chunk_index);
 10.2462 -  _chunk_end = sd.chunk_to_addr(chunk_index) + ParallelCompactData::ChunkSize;
 10.2463 -
 10.2464 -  // The first block in this chunk
 10.2465 -  size_t first_block =  sd.addr_to_block_idx(_chunk_start);
 10.2466 -  size_t partial_live_size = sd.chunk(chunk_index)->partial_obj_size();
 10.2467 -
 10.2468 -  // Set the offset to 0. By definition it should have that value
 10.2469 -  // but it may have been written while processing an earlier chunk.
 10.2470 -  if (partial_live_size == 0) {
 10.2471 -    // No live object extends onto the chunk.  The first bit
 10.2472 -    // in the bit map for the first chunk must be a start bit.
 10.2473 -    // Although there may not be any marked bits, it is safe
 10.2474 -    // to set it as a start bit.
 10.2475 -    sd.block(first_block)->set_start_bit_offset(0);
 10.2476 -    sd.block(first_block)->set_first_is_start_bit(true);
 10.2477 -  } else if (sd.partial_obj_ends_in_block(first_block)) {
 10.2478 -    sd.block(first_block)->set_end_bit_offset(0);
 10.2479 -    sd.block(first_block)->set_first_is_start_bit(false);
 10.2480 -  } else {
 10.2481 -    // The partial object extends beyond the first block.
 10.2482 -    // There is no object starting in the first block
 10.2483 -    // so the offset and bit parity are not needed.
 10.2484 -    // Set the the bit parity to start bit so assertions
 10.2485 -    // work when not bit is found.
 10.2486 -    sd.block(first_block)->set_end_bit_offset(0);
 10.2487 -    sd.block(first_block)->set_first_is_start_bit(false);
 10.2488 -  }
 10.2489 -  _cur_block = first_block;
 10.2490 -#ifdef ASSERT
 10.2491 -  if (sd.block(first_block)->first_is_start_bit()) {
 10.2492 -    assert(!sd.partial_obj_ends_in_block(first_block),
 10.2493 -      "Partial object cannot end in first block");
 10.2494 -  }
 10.2495 -
 10.2496 -  if (PrintGCDetails && Verbose) {
 10.2497 -    if (partial_live_size == 1) {
 10.2498 -    gclog_or_tty->print_cr("first_block " PTR_FORMAT
 10.2499 -      " _offset " PTR_FORMAT
 10.2500 -      " _first_is_start_bit %d",
 10.2501 -      first_block,
 10.2502 -      sd.block(first_block)->raw_offset(),
 10.2503 -      sd.block(first_block)->first_is_start_bit());
 10.2504 -    }
 10.2505 -  }
 10.2506 -#endif
 10.2507 -  DEBUG_ONLY(ParallelCompactData::BlockData::set_cur_phase(17);)
 10.2508 -}
 10.2509 -
 10.2510 -// This method is called when a object has been found (both beginning
 10.2511 -// and end of the object) in the range of iteration.  This method is
 10.2512 -// calculating the words of live data to the left of a block.  That live
 10.2513 -// data includes any object starting to the left of the block (i.e.,
 10.2514 -// the live-data-to-the-left of block AAA will include the full size
 10.2515 -// of any object entering AAA).
 10.2516 -
 10.2517 -ParMarkBitMapClosure::IterationStatus
 10.2518 -BitBlockUpdateClosure::do_addr(HeapWord* addr, size_t words) {
 10.2519 -  // add the size to the block data.
 10.2520 -  HeapWord* obj = addr;
 10.2521 -  ParallelCompactData& sd = PSParallelCompact::summary_data();
 10.2522 -
 10.2523 -  assert(bitmap()->obj_size(obj) == words, "bad size");
 10.2524 -  assert(_chunk_start <= obj, "object is not in chunk");
 10.2525 -  assert(obj + words <= _chunk_end, "object is not in chunk");
 10.2526 -
 10.2527 -  // Update the live data to the left
 10.2528 -  size_t prev_live_data_left = _live_data_left;
 10.2529 -  _live_data_left = _live_data_left + words;
 10.2530 -
 10.2531 -  // Is this object in the current block.
 10.2532 -  size_t block_of_obj = sd.addr_to_block_idx(obj);
 10.2533 -  size_t block_of_obj_last = sd.addr_to_block_idx(obj + words - 1);
 10.2534 -  HeapWord* block_of_obj_last_addr = sd.block_to_addr(block_of_obj_last);
 10.2535 -  if (_cur_block < block_of_obj) {
 10.2536 -
 10.2537 -    //
 10.2538 -    // No object crossed the block boundary and this object was found
 10.2539 -    // on the other side of the block boundary.  Update the offset for
 10.2540 -    // the new block with the data size that does not include this object.
 10.2541 -    //
 10.2542 -    // The first bit in block_of_obj is a start bit except in the
 10.2543 -    // case where the partial object for the chunk extends into
 10.2544 -    // this block.
 10.2545 -    if (sd.partial_obj_ends_in_block(block_of_obj)) {
 10.2546 -      sd.block(block_of_obj)->set_end_bit_offset(prev_live_data_left);
 10.2547 -    } else {
 10.2548 -      sd.block(block_of_obj)->set_start_bit_offset(prev_live_data_left);
 10.2549 -    }
 10.2550 -
 10.2551 -    // Does this object pass beyond the its block?
 10.2552 -    if (block_of_obj < block_of_obj_last) {
 10.2553 -      // Object crosses block boundary.  Two blocks need to be udpated:
 10.2554 -      //        the current block where the object started
 10.2555 -      //        the block where the object ends
 10.2556 -      //
 10.2557 -      // The offset for blocks with no objects starting in them
 10.2558 -      // (e.g., blocks between _cur_block and  block_of_obj_last)
 10.2559 -      // should not be needed.
 10.2560 -      // Note that block_of_obj_last may be in another chunk.  If so,
 10.2561 -      // it should be overwritten later.  This is a problem (writting
 10.2562 -      // into a block in a later chunk) for parallel execution.
 10.2563 -      assert(obj < block_of_obj_last_addr,
 10.2564 -        "Object should start in previous block");
 10.2565 -
 10.2566 -      // obj is crossing into block_of_obj_last so the first bit
 10.2567 -      // is and end bit.
 10.2568 -      sd.block(block_of_obj_last)->set_end_bit_offset(_live_data_left);
 10.2569 -
 10.2570 -      _cur_block = block_of_obj_last;
 10.2571 -    } else {
 10.2572 -      // _first_is_start_bit has already been set correctly
 10.2573 -      // in the if-then-else above so don't reset it here.
 10.2574 -      _cur_block = block_of_obj;
 10.2575 -    }
 10.2576 -  } else {
 10.2577 -    // The current block only changes if the object extends beyound
 10.2578 -    // the block it starts in.
 10.2579 -    //
 10.2580 -    // The object starts in the current block.
 10.2581 -    // Does this object pass beyond the end of it?
 10.2582 -    if (block_of_obj < block_of_obj_last) {
 10.2583 -      // Object crosses block boundary.
 10.2584 -      // See note above on possible blocks between block_of_obj and
 10.2585 -      // block_of_obj_last
 10.2586 -      assert(obj < block_of_obj_last_addr,
 10.2587 -        "Object should start in previous block");
 10.2588 -
 10.2589 -      sd.block(block_of_obj_last)->set_end_bit_offset(_live_data_left);
 10.2590 -
 10.2591 -      _cur_block = block_of_obj_last;
 10.2592 -    }
 10.2593 -  }
 10.2594 -
 10.2595 -  // Return incomplete if there are more blocks to be done.
 10.2596 -  if (chunk_contains_cur_block()) {
 10.2597 -    return ParMarkBitMap::incomplete;
 10.2598 -  }
 10.2599 -  return ParMarkBitMap::complete;
 10.2600 -}
 10.2601 -
 10.2602  // Verify the new location using the forwarding pointer
 10.2603  // from MarkSweep::mark_sweep_phase2().  Set the mark_word
 10.2604  // to the initial value.
 10.2605 @@ -3707,12 +3050,3 @@
 10.2606        return last_space_id;
 10.2607    }
 10.2608  }
 10.2609 -
 10.2610 -// Here temporarily for debugging
 10.2611 -#ifdef ASSERT
 10.2612 -  size_t ParallelCompactData::block_idx(BlockData* block) {
 10.2613 -    size_t index = pointer_delta(block,
 10.2614 -      PSParallelCompact::summary_data()._block_data, sizeof(BlockData));
 10.2615 -    return index;
 10.2616 -  }
 10.2617 -#endif
    11.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	Tue Sep 30 15:53:55 2008 -0700
    11.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	Wed Oct 01 15:05:06 2008 -0400
    11.3 @@ -76,87 +76,80 @@
    11.4  {
    11.5  public:
    11.6    // Sizes are in HeapWords, unless indicated otherwise.
    11.7 -  static const size_t Log2ChunkSize;
    11.8 -  static const size_t ChunkSize;
    11.9 -  static const size_t ChunkSizeBytes;
   11.10 +  static const size_t Log2RegionSize;
   11.11 +  static const size_t RegionSize;
   11.12 +  static const size_t RegionSizeBytes;
   11.13  
   11.14 -  // Mask for the bits in a size_t to get an offset within a chunk.
   11.15 -  static const size_t ChunkSizeOffsetMask;
   11.16 -  // Mask for the bits in a pointer to get an offset within a chunk.
   11.17 -  static const size_t ChunkAddrOffsetMask;
   11.18 -  // Mask for the bits in a pointer to get the address of the start of a chunk.
   11.19 -  static const size_t ChunkAddrMask;
   11.20 +  // Mask for the bits in a size_t to get an offset within a region.
   11.21 +  static const size_t RegionSizeOffsetMask;
   11.22 +  // Mask for the bits in a pointer to get an offset within a region.
   11.23 +  static const size_t RegionAddrOffsetMask;
   11.24 +  // Mask for the bits in a pointer to get the address of the start of a region.
   11.25 +  static const size_t RegionAddrMask;
   11.26  
   11.27 -  static const size_t Log2BlockSize;
   11.28 -  static const size_t BlockSize;
   11.29 -  static const size_t BlockOffsetMask;
   11.30 -  static const size_t BlockMask;
   11.31 -
   11.32 -  static const size_t BlocksPerChunk;
   11.33 -
   11.34 -  class ChunkData
   11.35 +  class RegionData
   11.36    {
   11.37    public:
   11.38 -    // Destination address of the chunk.
   11.39 +    // Destination address of the region.
   11.40      HeapWord* destination() const { return _destination; }
   11.41  
   11.42 -    // The first chunk containing data destined for this chunk.
   11.43 -    size_t source_chunk() const { return _source_chunk; }
   11.44 +    // The first region containing data destined for this region.
   11.45 +    size_t source_region() const { return _source_region; }
   11.46  
   11.47 -    // The object (if any) starting in this chunk and ending in a different
   11.48 -    // chunk that could not be updated during the main (parallel) compaction
   11.49 +    // The object (if any) starting in this region and ending in a different
   11.50 +    // region that could not be updated during the main (parallel) compaction
   11.51      // phase.  This is different from _partial_obj_addr, which is an object that
   11.52 -    // extends onto a source chunk.  However, the two uses do not overlap in
   11.53 +    // extends onto a source region.  However, the two uses do not overlap in
   11.54      // time, so the same field is used to save space.
   11.55      HeapWord* deferred_obj_addr() const { return _partial_obj_addr; }
   11.56  
   11.57 -    // The starting address of the partial object extending onto the chunk.
   11.58 +    // The starting address of the partial object extending onto the region.
   11.59      HeapWord* partial_obj_addr() const { return _partial_obj_addr; }
   11.60  
   11.61 -    // Size of the partial object extending onto the chunk (words).
   11.62 +    // Size of the partial object extending onto the region (words).
   11.63      size_t partial_obj_size() const { return _partial_obj_size; }
   11.64  
   11.65 -    // Size of live data that lies within this chunk due to objects that start
   11.66 -    // in this chunk (words).  This does not include the partial object
   11.67 -    // extending onto the chunk (if any), or the part of an object that extends
   11.68 -    // onto the next chunk (if any).
   11.69 +    // Size of live data that lies within this region due to objects that start
   11.70 +    // in this region (words).  This does not include the partial object
   11.71 +    // extending onto the region (if any), or the part of an object that extends
   11.72 +    // onto the next region (if any).
   11.73      size_t live_obj_size() const { return _dc_and_los & los_mask; }
   11.74  
   11.75 -    // Total live data that lies within the chunk (words).
   11.76 +    // Total live data that lies within the region (words).
   11.77      size_t data_size() const { return partial_obj_size() + live_obj_size(); }
   11.78  
   11.79 -    // The destination_count is the number of other chunks to which data from
   11.80 -    // this chunk will be copied.  At the end of the summary phase, the valid
   11.81 +    // The destination_count is the number of other regions to which data from
   11.82 +    // this region will be copied.  At the end of the summary phase, the valid
   11.83      // values of destination_count are
   11.84      //
   11.85 -    // 0 - data from the chunk will be compacted completely into itself, or the
   11.86 -    //     chunk is empty.  The chunk can be claimed and then filled.
   11.87 -    // 1 - data from the chunk will be compacted into 1 other chunk; some
   11.88 -    //     data from the chunk may also be compacted into the chunk itself.
   11.89 -    // 2 - data from the chunk will be copied to 2 other chunks.
   11.90 +    // 0 - data from the region will be compacted completely into itself, or the
   11.91 +    //     region is empty.  The region can be claimed and then filled.
   11.92 +    // 1 - data from the region will be compacted into 1 other region; some
   11.93 +    //     data from the region may also be compacted into the region itself.
   11.94 +    // 2 - data from the region will be copied to 2 other regions.
   11.95      //
   11.96 -    // During compaction as chunks are emptied, the destination_count is
   11.97 +    // During compaction as regions are emptied, the destination_count is
   11.98      // decremented (atomically) and when it reaches 0, it can be claimed and
   11.99      // then filled.
  11.100      //
  11.101 -    // A chunk is claimed for processing by atomically changing the
  11.102 -    // destination_count to the claimed value (dc_claimed).  After a chunk has
  11.103 +    // A region is claimed for processing by atomically changing the
  11.104 +    // destination_count to the claimed value (dc_claimed).  After a region has
  11.105      // been filled, the destination_count should be set to the completed value
  11.106      // (dc_completed).
  11.107      inline uint destination_count() const;
  11.108      inline uint destination_count_raw() const;
  11.109  
  11.110 -    // The location of the java heap data that corresponds to this chunk.
  11.111 +    // The location of the java heap data that corresponds to this region.
  11.112      inline HeapWord* data_location() const;
  11.113  
  11.114 -    // The highest address referenced by objects in this chunk.
  11.115 +    // The highest address referenced by objects in this region.
  11.116      inline HeapWord* highest_ref() const;
  11.117  
  11.118 -    // Whether this chunk is available to be claimed, has been claimed, or has
  11.119 +    // Whether this region is available to be claimed, has been claimed, or has
  11.120      // been completed.
  11.121      //
  11.122 -    // Minor subtlety:  claimed() returns true if the chunk is marked
  11.123 -    // completed(), which is desirable since a chunk must be claimed before it
  11.124 +    // Minor subtlety:  claimed() returns true if the region is marked
  11.125 +    // completed(), which is desirable since a region must be claimed before it
  11.126      // can be completed.
  11.127      bool available() const { return _dc_and_los < dc_one; }
  11.128      bool claimed() const   { return _dc_and_los >= dc_claimed; }
  11.129 @@ -164,11 +157,11 @@
  11.130  
  11.131      // These are not atomic.
  11.132      void set_destination(HeapWord* addr)       { _destination = addr; }
  11.133 -    void set_source_chunk(size_t chunk)        { _source_chunk = chunk; }
  11.134 +    void set_source_region(size_t region)      { _source_region = region; }
  11.135      void set_deferred_obj_addr(HeapWord* addr) { _partial_obj_addr = addr; }
  11.136      void set_partial_obj_addr(HeapWord* addr)  { _partial_obj_addr = addr; }
  11.137      void set_partial_obj_size(size_t words)    {
  11.138 -      _partial_obj_size = (chunk_sz_t) words;
  11.139 +      _partial_obj_size = (region_sz_t) words;
  11.140      }
  11.141  
  11.142      inline void set_destination_count(uint count);
  11.143 @@ -184,129 +177,57 @@
  11.144      inline bool claim();
  11.145  
  11.146    private:
  11.147 -    // The type used to represent object sizes within a chunk.
  11.148 -    typedef uint chunk_sz_t;
  11.149 +    // The type used to represent object sizes within a region.
  11.150 +    typedef uint region_sz_t;
  11.151  
  11.152      // Constants for manipulating the _dc_and_los field, which holds both the
  11.153      // destination count and live obj size.  The live obj size lives at the
  11.154      // least significant end so no masking is necessary when adding.
  11.155 -    static const chunk_sz_t dc_shift;           // Shift amount.
  11.156 -    static const chunk_sz_t dc_mask;            // Mask for destination count.
  11.157 -    static const chunk_sz_t dc_one;             // 1, shifted appropriately.
  11.158 -    static const chunk_sz_t dc_claimed;         // Chunk has been claimed.
  11.159 -    static const chunk_sz_t dc_completed;       // Chunk has been completed.
  11.160 -    static const chunk_sz_t los_mask;           // Mask for live obj size.
  11.161 +    static const region_sz_t dc_shift;           // Shift amount.
  11.162 +    static const region_sz_t dc_mask;            // Mask for destination count.
  11.163 +    static const region_sz_t dc_one;             // 1, shifted appropriately.
  11.164 +    static const region_sz_t dc_claimed;         // Region has been claimed.
  11.165 +    static const region_sz_t dc_completed;       // Region has been completed.
  11.166 +    static const region_sz_t los_mask;           // Mask for live obj size.
  11.167  
  11.168 -    HeapWord*           _destination;
  11.169 -    size_t              _source_chunk;
  11.170 -    HeapWord*           _partial_obj_addr;
  11.171 -    chunk_sz_t          _partial_obj_size;
  11.172 -    chunk_sz_t volatile _dc_and_los;
  11.173 +    HeapWord*            _destination;
  11.174 +    size_t               _source_region;
  11.175 +    HeapWord*            _partial_obj_addr;
  11.176 +    region_sz_t          _partial_obj_size;
  11.177 +    region_sz_t volatile _dc_and_los;
  11.178  #ifdef ASSERT
  11.179      // These enable optimizations that are only partially implemented.  Use
  11.180      // debug builds to prevent the code fragments from breaking.
  11.181 -    HeapWord*           _data_location;
  11.182 -    HeapWord*           _highest_ref;
  11.183 +    HeapWord*            _data_location;
  11.184 +    HeapWord*            _highest_ref;
  11.185  #endif  // #ifdef ASSERT
  11.186  
  11.187  #ifdef ASSERT
  11.188     public:
  11.189 -    uint            _pushed;    // 0 until chunk is pushed onto a worker's stack
  11.190 +    uint            _pushed;   // 0 until region is pushed onto a worker's stack
  11.191     private:
  11.192  #endif
  11.193    };
  11.194  
  11.195 -  // 'Blocks' allow shorter sections of the bitmap to be searched.  Each Block
  11.196 -  // holds an offset, which is the amount of live data in the Chunk to the left
  11.197 -  // of the first live object in the Block.  This amount of live data will
  11.198 -  // include any object extending into the block. The first block in
  11.199 -  // a chunk does not include any partial object extending into the
  11.200 -  // the chunk.
  11.201 -  //
  11.202 -  // The offset also encodes the
  11.203 -  // 'parity' of the first 1 bit in the Block:  a positive offset means the
  11.204 -  // first 1 bit marks the start of an object, a negative offset means the first
  11.205 -  // 1 bit marks the end of an object.
  11.206 -  class BlockData
  11.207 -  {
  11.208 -   public:
  11.209 -    typedef short int blk_ofs_t;
  11.210 -
  11.211 -    blk_ofs_t offset() const { return _offset >= 0 ? _offset : -_offset; }
  11.212 -    blk_ofs_t raw_offset() const { return _offset; }
  11.213 -    void set_first_is_start_bit(bool v) { _first_is_start_bit = v; }
  11.214 -
  11.215 -#if 0
  11.216 -    // The need for this method was anticipated but it is
  11.217 -    // never actually used.  Do not include it for now.  If
  11.218 -    // it is needed, consider the problem of what is passed
  11.219 -    // as "v".  To avoid warning errors the method set_start_bit_offset()
  11.220 -    // was changed to take a size_t as the parameter and to do the
  11.221 -    // check for the possible overflow.  Doing the cast in these
  11.222 -    // methods better limits the potential problems because of
  11.223 -    // the size of the field to this class.
  11.224 -    void set_raw_offset(blk_ofs_t v) { _offset = v; }
  11.225 -#endif
  11.226 -    void set_start_bit_offset(size_t val) {
  11.227 -      assert(val >= 0, "sanity");
  11.228 -      _offset = (blk_ofs_t) val;
  11.229 -      assert(val == (size_t) _offset, "Value is too large");
  11.230 -      _first_is_start_bit = true;
  11.231 -    }
  11.232 -    void set_end_bit_offset(size_t val) {
  11.233 -      assert(val >= 0, "sanity");
  11.234 -      _offset = (blk_ofs_t) val;
  11.235 -      assert(val == (size_t) _offset, "Value is too large");
  11.236 -      _offset = - _offset;
  11.237 -      _first_is_start_bit = false;
  11.238 -    }
  11.239 -    bool first_is_start_bit() {
  11.240 -      assert(_set_phase > 0, "Not initialized");
  11.241 -      return _first_is_start_bit;
  11.242 -    }
  11.243 -    bool first_is_end_bit() {
  11.244 -      assert(_set_phase > 0, "Not initialized");
  11.245 -      return !_first_is_start_bit;
  11.246 -    }
  11.247 -
  11.248 -   private:
  11.249 -    blk_ofs_t _offset;
  11.250 -    // This is temporary until the mark_bitmap is separated into
  11.251 -    // a start bit array and an end bit array.
  11.252 -    bool      _first_is_start_bit;
  11.253 -#ifdef ASSERT
  11.254 -    short     _set_phase;
  11.255 -    static short _cur_phase;
  11.256 -   public:
  11.257 -    static void set_cur_phase(short v) { _cur_phase = v; }
  11.258 -#endif
  11.259 -  };
  11.260 -
  11.261  public:
  11.262    ParallelCompactData();
  11.263    bool initialize(MemRegion covered_region);
  11.264  
  11.265 -  size_t chunk_count() const { return _chunk_count; }
  11.266 +  size_t region_count() const { return _region_count; }
  11.267  
  11.268 -  // Convert chunk indices to/from ChunkData pointers.
  11.269 -  inline ChunkData* chunk(size_t chunk_idx) const;
  11.270 -  inline size_t     chunk(const ChunkData* const chunk_ptr) const;
  11.271 +  // Convert region indices to/from RegionData pointers.
  11.272 +  inline RegionData* region(size_t region_idx) const;
  11.273 +  inline size_t     region(const RegionData* const region_ptr) const;
  11.274  
  11.275 -  // Returns true if the given address is contained within the chunk
  11.276 -  bool chunk_contains(size_t chunk_index, HeapWord* addr);
  11.277 -
  11.278 -  size_t block_count() const { return _block_count; }
  11.279 -  inline BlockData* block(size_t n) const;
  11.280 -
  11.281 -  // Returns true if the given block is in the given chunk.
  11.282 -  static bool chunk_contains_block(size_t chunk_index, size_t block_index);
  11.283 +  // Returns true if the given address is contained within the region
  11.284 +  bool region_contains(size_t region_index, HeapWord* addr);
  11.285  
  11.286    void add_obj(HeapWord* addr, size_t len);
  11.287    void add_obj(oop p, size_t len) { add_obj((HeapWord*)p, len); }
  11.288  
  11.289 -  // Fill in the chunks covering [beg, end) so that no data moves; i.e., the
  11.290 -  // destination of chunk n is simply the start of chunk n.  The argument beg
  11.291 -  // must be chunk-aligned; end need not be.
  11.292 +  // Fill in the regions covering [beg, end) so that no data moves; i.e., the
  11.293 +  // destination of region n is simply the start of region n.  The argument beg
  11.294 +  // must be region-aligned; end need not be.
  11.295    void summarize_dense_prefix(HeapWord* beg, HeapWord* end);
  11.296  
  11.297    bool summarize(HeapWord* target_beg, HeapWord* target_end,
  11.298 @@ -314,48 +235,33 @@
  11.299                   HeapWord** target_next, HeapWord** source_next = 0);
  11.300  
  11.301    void clear();
  11.302 -  void clear_range(size_t beg_chunk, size_t end_chunk);
  11.303 +  void clear_range(size_t beg_region, size_t end_region);
  11.304    void clear_range(HeapWord* beg, HeapWord* end) {
  11.305 -    clear_range(addr_to_chunk_idx(beg), addr_to_chunk_idx(end));
  11.306 +    clear_range(addr_to_region_idx(beg), addr_to_region_idx(end));
  11.307    }
  11.308  
  11.309 -  // Return the number of words between addr and the start of the chunk
  11.310 +  // Return the number of words between addr and the start of the region
  11.311    // containing addr.
  11.312 -  inline size_t     chunk_offset(const HeapWord* addr) const;
  11.313 +  inline size_t     region_offset(const HeapWord* addr) const;
  11.314  
  11.315 -  // Convert addresses to/from a chunk index or chunk pointer.
  11.316 -  inline size_t     addr_to_chunk_idx(const HeapWord* addr) const;
  11.317 -  inline ChunkData* addr_to_chunk_ptr(const HeapWord* addr) const;
  11.318 -  inline HeapWord*  chunk_to_addr(size_t chunk) const;
  11.319 -  inline HeapWord*  chunk_to_addr(size_t chunk, size_t offset) const;
  11.320 -  inline HeapWord*  chunk_to_addr(const ChunkData* chunk) const;
  11.321 +  // Convert addresses to/from a region index or region pointer.
  11.322 +  inline size_t     addr_to_region_idx(const HeapWord* addr) const;
  11.323 +  inline RegionData* addr_to_region_ptr(const HeapWord* addr) const;
  11.324 +  inline HeapWord*  region_to_addr(size_t region) const;
  11.325 +  inline HeapWord*  region_to_addr(size_t region, size_t offset) const;
  11.326 +  inline HeapWord*  region_to_addr(const RegionData* region) const;
  11.327  
  11.328 -  inline HeapWord*  chunk_align_down(HeapWord* addr) const;
  11.329 -  inline HeapWord*  chunk_align_up(HeapWord* addr) const;
  11.330 -  inline bool       is_chunk_aligned(HeapWord* addr) const;
  11.331 -
  11.332 -  // Analogous to chunk_offset() for blocks.
  11.333 -  size_t     block_offset(const HeapWord* addr) const;
  11.334 -  size_t     addr_to_block_idx(const HeapWord* addr) const;
  11.335 -  size_t     addr_to_block_idx(const oop obj) const {
  11.336 -    return addr_to_block_idx((HeapWord*) obj);
  11.337 -  }
  11.338 -  inline BlockData* addr_to_block_ptr(const HeapWord* addr) const;
  11.339 -  inline HeapWord*  block_to_addr(size_t block) const;
  11.340 +  inline HeapWord*  region_align_down(HeapWord* addr) const;
  11.341 +  inline HeapWord*  region_align_up(HeapWord* addr) const;
  11.342 +  inline bool       is_region_aligned(HeapWord* addr) const;
  11.343  
  11.344    // Return the address one past the end of the partial object.
  11.345 -  HeapWord* partial_obj_end(size_t chunk_idx) const;
  11.346 +  HeapWord* partial_obj_end(size_t region_idx) const;
  11.347  
  11.348    // Return the new location of the object p after the
  11.349    // the compaction.
  11.350    HeapWord* calc_new_pointer(HeapWord* addr);
  11.351  
  11.352 -  // Same as calc_new_pointer() using blocks.
  11.353 -  HeapWord* block_calc_new_pointer(HeapWord* addr);
  11.354 -
  11.355 -  // Same as calc_new_pointer() using chunks.
  11.356 -  HeapWord* chunk_calc_new_pointer(HeapWord* addr);
  11.357 -
  11.358    HeapWord* calc_new_pointer(oop p) {
  11.359      return calc_new_pointer((HeapWord*) p);
  11.360    }
  11.361 @@ -363,22 +269,13 @@
  11.362    // Return the updated address for the given klass
  11.363    klassOop calc_new_klass(klassOop);
  11.364  
  11.365 -  // Given a block returns true if the partial object for the
  11.366 -  // corresponding chunk ends in the block.  Returns false, otherwise
  11.367 -  // If there is no partial object, returns false.
  11.368 -  bool partial_obj_ends_in_block(size_t block_index);
  11.369 -
  11.370 -  // Returns the block index for the block
  11.371 -  static size_t block_idx(BlockData* block);
  11.372 -
  11.373  #ifdef  ASSERT
  11.374    void verify_clear(const PSVirtualSpace* vspace);
  11.375    void verify_clear();
  11.376  #endif  // #ifdef ASSERT
  11.377  
  11.378  private:
  11.379 -  bool initialize_block_data(size_t region_size);
  11.380 -  bool initialize_chunk_data(size_t region_size);
  11.381 +  bool initialize_region_data(size_t region_size);
  11.382    PSVirtualSpace* create_vspace(size_t count, size_t element_size);
  11.383  
  11.384  private:
  11.385 @@ -387,74 +284,70 @@
  11.386    HeapWord*       _region_end;
  11.387  #endif  // #ifdef ASSERT
  11.388  
  11.389 -  PSVirtualSpace* _chunk_vspace;
  11.390 -  ChunkData*      _chunk_data;
  11.391 -  size_t          _chunk_count;
  11.392 -
  11.393 -  PSVirtualSpace* _block_vspace;
  11.394 -  BlockData*      _block_data;
  11.395 -  size_t          _block_count;
  11.396 +  PSVirtualSpace* _region_vspace;
  11.397 +  RegionData*     _region_data;
  11.398 +  size_t          _region_count;
  11.399  };
  11.400  
  11.401  inline uint
  11.402 -ParallelCompactData::ChunkData::destination_count_raw() const
  11.403 +ParallelCompactData::RegionData::destination_count_raw() const
  11.404  {
  11.405    return _dc_and_los & dc_mask;
  11.406  }
  11.407  
  11.408  inline uint
  11.409 -ParallelCompactData::ChunkData::destination_count() const
  11.410 +ParallelCompactData::RegionData::destination_count() const
  11.411  {
  11.412    return destination_count_raw() >> dc_shift;
  11.413  }
  11.414  
  11.415  inline void
  11.416 -ParallelCompactData::ChunkData::set_destination_count(uint count)
  11.417 +ParallelCompactData::RegionData::set_destination_count(uint count)
  11.418  {
  11.419    assert(count <= (dc_completed >> dc_shift), "count too large");
  11.420 -  const chunk_sz_t live_sz = (chunk_sz_t) live_obj_size();
  11.421 +  const region_sz_t live_sz = (region_sz_t) live_obj_size();
  11.422    _dc_and_los = (count << dc_shift) | live_sz;
  11.423  }
  11.424  
  11.425 -inline void ParallelCompactData::ChunkData::set_live_obj_size(size_t words)
  11.426 +inline void ParallelCompactData::RegionData::set_live_obj_size(size_t words)
  11.427  {
  11.428    assert(words <= los_mask, "would overflow");
  11.429 -  _dc_and_los = destination_count_raw() | (chunk_sz_t)words;
  11.430 +  _dc_and_los = destination_count_raw() | (region_sz_t)words;
  11.431  }
  11.432  
  11.433 -inline void ParallelCompactData::ChunkData::decrement_destination_count()
  11.434 +inline void ParallelCompactData::RegionData::decrement_destination_count()
  11.435  {
  11.436    assert(_dc_and_los < dc_claimed, "already claimed");
  11.437    assert(_dc_and_los >= dc_one, "count would go negative");
  11.438    Atomic::add((int)dc_mask, (volatile int*)&_dc_and_los);
  11.439  }
  11.440  
  11.441 -inline HeapWord* ParallelCompactData::ChunkData::data_location() const
  11.442 +inline HeapWord* ParallelCompactData::RegionData::data_location() const
  11.443  {
  11.444    DEBUG_ONLY(return _data_location;)
  11.445    NOT_DEBUG(return NULL;)
  11.446  }
  11.447  
  11.448 -inline HeapWord* ParallelCompactData::ChunkData::highest_ref() const
  11.449 +inline HeapWord* ParallelCompactData::RegionData::highest_ref() const
  11.450  {
  11.451    DEBUG_ONLY(return _highest_ref;)
  11.452    NOT_DEBUG(return NULL;)
  11.453  }
  11.454  
  11.455 -inline void ParallelCompactData::ChunkData::set_data_location(HeapWord* addr)
  11.456 +inline void ParallelCompactData::RegionData::set_data_location(HeapWord* addr)
  11.457  {
  11.458    DEBUG_ONLY(_data_location = addr;)
  11.459  }
  11.460  
  11.461 -inline void ParallelCompactData::ChunkData::set_completed()
  11.462 +inline void ParallelCompactData::RegionData::set_completed()
  11.463  {
  11.464    assert(claimed(), "must be claimed first");
  11.465 -  _dc_and_los = dc_completed | (chunk_sz_t) live_obj_size();
  11.466 +  _dc_and_los = dc_completed | (region_sz_t) live_obj_size();
  11.467  }
  11.468  
  11.469 -// MT-unsafe claiming of a chunk.  Should only be used during single threaded
  11.470 +// MT-unsafe claiming of a region.  Should only be used during single threaded
  11.471  // execution.
  11.472 -inline bool ParallelCompactData::ChunkData::claim_unsafe()
  11.473 +inline bool ParallelCompactData::RegionData::claim_unsafe()
  11.474  {
  11.475    if (available()) {
  11.476      _dc_and_los |= dc_claimed;
  11.477 @@ -463,13 +356,13 @@
  11.478    return false;
  11.479  }
  11.480  
  11.481 -inline void ParallelCompactData::ChunkData::add_live_obj(size_t words)
  11.482 +inline void ParallelCompactData::RegionData::add_live_obj(size_t words)
  11.483  {
  11.484    assert(words <= (size_t)los_mask - live_obj_size(), "overflow");
  11.485    Atomic::add((int) words, (volatile int*) &_dc_and_los);
  11.486  }
  11.487  
  11.488 -inline void ParallelCompactData::ChunkData::set_highest_ref(HeapWord* addr)
  11.489 +inline void ParallelCompactData::RegionData::set_highest_ref(HeapWord* addr)
  11.490  {
  11.491  #ifdef ASSERT
  11.492    HeapWord* tmp = _highest_ref;
  11.493 @@ -479,7 +372,7 @@
  11.494  #endif  // #ifdef ASSERT
  11.495  }
  11.496  
  11.497 -inline bool ParallelCompactData::ChunkData::claim()
  11.498 +inline bool ParallelCompactData::RegionData::claim()
  11.499  {
  11.500    const int los = (int) live_obj_size();
  11.501    const int old = Atomic::cmpxchg(dc_claimed | los,
  11.502 @@ -487,119 +380,85 @@
  11.503    return old == los;
  11.504  }
  11.505  
  11.506 -inline ParallelCompactData::ChunkData*
  11.507 -ParallelCompactData::chunk(size_t chunk_idx) const
  11.508 +inline ParallelCompactData::RegionData*
  11.509 +ParallelCompactData::region(size_t region_idx) const
  11.510  {
  11.511 -  assert(chunk_idx <= chunk_count(), "bad arg");
  11.512 -  return _chunk_data + chunk_idx;
  11.513 +  assert(region_idx <= region_count(), "bad arg");
  11.514 +  return _region_data + region_idx;
  11.515  }
  11.516  
  11.517  inline size_t
  11.518 -ParallelCompactData::chunk(const ChunkData* const chunk_ptr) const
  11.519 +ParallelCompactData::region(const RegionData* const region_ptr) const
  11.520  {
  11.521 -  assert(chunk_ptr >= _chunk_data, "bad arg");
  11.522 -  assert(chunk_ptr <= _chunk_data + chunk_count(), "bad arg");
  11.523 -  return pointer_delta(chunk_ptr, _chunk_data, sizeof(ChunkData));
  11.524 -}
  11.525 -
  11.526 -inline ParallelCompactData::BlockData*
  11.527 -ParallelCompactData::block(size_t n) const {
  11.528 -  assert(n < block_count(), "bad arg");
  11.529 -  return _block_data + n;
  11.530 +  assert(region_ptr >= _region_data, "bad arg");
  11.531 +  assert(region_ptr <= _region_data + region_count(), "bad arg");
  11.532 +  return pointer_delta(region_ptr, _region_data, sizeof(RegionData));
  11.533  }
  11.534  
  11.535  inline size_t
  11.536 -ParallelCompactData::chunk_offset(const HeapWord* addr) const
  11.537 +ParallelCompactData::region_offset(const HeapWord* addr) const
  11.538  {
  11.539    assert(addr >= _region_start, "bad addr");
  11.540    assert(addr <= _region_end, "bad addr");
  11.541 -  return (size_t(addr) & ChunkAddrOffsetMask) >> LogHeapWordSize;
  11.542 +  return (size_t(addr) & RegionAddrOffsetMask) >> LogHeapWordSize;
  11.543  }
  11.544  
  11.545  inline size_t
  11.546 -ParallelCompactData::addr_to_chunk_idx(const HeapWord* addr) const
  11.547 +ParallelCompactData::addr_to_region_idx(const HeapWord* addr) const
  11.548  {
  11.549    assert(addr >= _region_start, "bad addr");
  11.550    assert(addr <= _region_end, "bad addr");
  11.551 -  return pointer_delta(addr, _region_start) >> Log2ChunkSize;
  11.552 +  return pointer_delta(addr, _region_start) >> Log2RegionSize;
  11.553  }
  11.554  
  11.555 -inline ParallelCompactData::ChunkData*
  11.556 -ParallelCompactData::addr_to_chunk_ptr(const HeapWord* addr) const
  11.557 +inline ParallelCompactData::RegionData*
  11.558 +ParallelCompactData::addr_to_region_ptr(const HeapWord* addr) const
  11.559  {
  11.560 -  return chunk(addr_to_chunk_idx(addr));
  11.561 +  return region(addr_to_region_idx(addr));
  11.562  }
  11.563  
  11.564  inline HeapWord*
  11.565 -ParallelCompactData::chunk_to_addr(size_t chunk) const
  11.566 +ParallelCompactData::region_to_addr(size_t region) const
  11.567  {
  11.568 -  assert(chunk <= _chunk_count, "chunk out of range");
  11.569 -  return _region_start + (chunk << Log2ChunkSize);
  11.570 +  assert(region <= _region_count, "region out of range");
  11.571 +  return _region_start + (region << Log2RegionSize);
  11.572  }
  11.573  
  11.574  inline HeapWord*
  11.575 -ParallelCompactData::chunk_to_addr(const ChunkData* chunk) const
  11.576 +ParallelCompactData::region_to_addr(const RegionData* region) const
  11.577  {
  11.578 -  return chunk_to_addr(pointer_delta(chunk, _chunk_data, sizeof(ChunkData)));
  11.579 +  return region_to_addr(pointer_delta(region, _region_data,
  11.580 +                                      sizeof(RegionData)));
  11.581  }
  11.582  
  11.583  inline HeapWord*
  11.584 -ParallelCompactData::chunk_to_addr(size_t chunk, size_t offset) const
  11.585 +ParallelCompactData::region_to_addr(size_t region, size_t offset) const
  11.586  {
  11.587 -  assert(chunk <= _chunk_count, "chunk out of range");
  11.588 -  assert(offset < ChunkSize, "offset too big");  // This may be too strict.
  11.589 -  return chunk_to_addr(chunk) + offset;
  11.590 +  assert(region <= _region_count, "region out of range");
  11.591 +  assert(offset < RegionSize, "offset too big");  // This may be too strict.
  11.592 +  return region_to_addr(region) + offset;
  11.593  }
  11.594  
  11.595  inline HeapWord*
  11.596 -ParallelCompactData::chunk_align_down(HeapWord* addr) const
  11.597 +ParallelCompactData::region_align_down(HeapWord* addr) const
  11.598  {
  11.599    assert(addr >= _region_start, "bad addr");
  11.600 -  assert(addr < _region_end + ChunkSize, "bad addr");
  11.601 -  return (HeapWord*)(size_t(addr) & ChunkAddrMask);
  11.602 +  assert(addr < _region_end + RegionSize, "bad addr");
  11.603 +  return (HeapWord*)(size_t(addr) & RegionAddrMask);
  11.604  }
  11.605  
  11.606  inline HeapWord*
  11.607 -ParallelCompactData::chunk_align_up(HeapWord* addr) const
  11.608 +ParallelCompactData::region_align_up(HeapWord* addr) const
  11.609  {
  11.610    assert(addr >= _region_start, "bad addr");
  11.611    assert(addr <= _region_end, "bad addr");
  11.612 -  return chunk_align_down(addr + ChunkSizeOffsetMask);
  11.613 +  return region_align_down(addr + RegionSizeOffsetMask);
  11.614  }
  11.615  
  11.616  inline bool
  11.617 -ParallelCompactData::is_chunk_aligned(HeapWord* addr) const
  11.618 +ParallelCompactData::is_region_aligned(HeapWord* addr) const
  11.619  {
  11.620 -  return chunk_offset(addr) == 0;
  11.621 -}
  11.622 -
  11.623 -inline size_t
  11.624 -ParallelCompactData::block_offset(const HeapWord* addr) const
  11.625 -{
  11.626 -  assert(addr >= _region_start, "bad addr");
  11.627 -  assert(addr <= _region_end, "bad addr");
  11.628 -  return pointer_delta(addr, _region_start) & BlockOffsetMask;
  11.629 -}
  11.630 -
  11.631 -inline size_t
  11.632 -ParallelCompactData::addr_to_block_idx(const HeapWord* addr) const
  11.633 -{
  11.634 -  assert(addr >= _region_start, "bad addr");
  11.635 -  assert(addr <= _region_end, "bad addr");
  11.636 -  return pointer_delta(addr, _region_start) >> Log2BlockSize;
  11.637 -}
  11.638 -
  11.639 -inline ParallelCompactData::BlockData*
  11.640 -ParallelCompactData::addr_to_block_ptr(const HeapWord* addr) const
  11.641 -{
  11.642 -  return block(addr_to_block_idx(addr));
  11.643 -}
  11.644 -
  11.645 -inline HeapWord*
  11.646 -ParallelCompactData::block_to_addr(size_t block) const
  11.647 -{
  11.648 -  assert(block < _block_count, "block out of range");
  11.649 -  return _region_start + (block << Log2BlockSize);
  11.650 +  return region_offset(addr) == 0;
  11.651  }
  11.652  
  11.653  // Abstract closure for use with ParMarkBitMap::iterate(), which will invoke the
  11.654 @@ -687,45 +546,15 @@
  11.655    _words_remaining -= words;
  11.656  }
  11.657  
  11.658 -// Closure for updating the block data during the summary phase.
  11.659 -class BitBlockUpdateClosure: public ParMarkBitMapClosure {
  11.660 -  // ParallelCompactData::BlockData::blk_ofs_t _live_data_left;
  11.661 -  size_t    _live_data_left;
  11.662 -  size_t    _cur_block;
  11.663 -  HeapWord* _chunk_start;
  11.664 -  HeapWord* _chunk_end;
  11.665 -  size_t    _chunk_index;
  11.666 -
  11.667 - public:
  11.668 -  BitBlockUpdateClosure(ParMarkBitMap* mbm,
  11.669 -                        ParCompactionManager* cm,
  11.670 -                        size_t chunk_index);
  11.671 -
  11.672 -  size_t cur_block() { return _cur_block; }
  11.673 -  size_t chunk_index() { return _chunk_index; }
  11.674 -  size_t live_data_left() { return _live_data_left; }
  11.675 -  // Returns true the first bit in the current block (cur_block) is
  11.676 -  // a start bit.
  11.677 -  // Returns true if the current block is within the chunk for the closure;
  11.678 -  bool chunk_contains_cur_block();
  11.679 -
  11.680 -  // Set the chunk index and related chunk values for
  11.681 -  // a new chunk.
  11.682 -  void reset_chunk(size_t chunk_index);
  11.683 -
  11.684 -  virtual IterationStatus do_addr(HeapWord* addr, size_t words);
  11.685 -};
  11.686 -
  11.687 -// The UseParallelOldGC collector is a stop-the-world garbage
  11.688 -// collector that does parts of the collection using parallel threads.
  11.689 -// The collection includes the tenured generation and the young
  11.690 -// generation.  The permanent generation is collected at the same
  11.691 -// time as the other two generations but the permanent generation
  11.692 -// is collect by a single GC thread.  The permanent generation is
  11.693 -// collected serially because of the requirement that during the
  11.694 -// processing of a klass AAA, any objects reference by AAA must
  11.695 -// already have been processed.  This requirement is enforced by
  11.696 -// a left (lower address) to right (higher address) sliding compaction.
  11.697 +// The UseParallelOldGC collector is a stop-the-world garbage collector that
  11.698 +// does parts of the collection using parallel threads.  The collection includes
  11.699 +// the tenured generation and the young generation.  The permanent generation is
  11.700 +// collected at the same time as the other two generations but the permanent
  11.701 +// generation is collect by a single GC thread.  The permanent generation is
  11.702 +// collected serially because of the requirement that during the processing of a
  11.703 +// klass AAA, any objects reference by AAA must already have been processed.
  11.704 +// This requirement is enforced by a left (lower address) to right (higher
  11.705 +// address) sliding compaction.
  11.706  //
  11.707  // There are four phases of the collection.
  11.708  //
  11.709 @@ -740,81 +569,75 @@
  11.710  //      - move the objects to their destination
  11.711  //      - update some references and reinitialize some variables
  11.712  //
  11.713 -// These three phases are invoked in PSParallelCompact::invoke_no_policy().
  11.714 -// The marking phase is implemented in PSParallelCompact::marking_phase()
  11.715 -// and does a complete marking of the heap.
  11.716 -// The summary phase is implemented in PSParallelCompact::summary_phase().
  11.717 -// The move and update phase is implemented in PSParallelCompact::compact().
  11.718 +// These three phases are invoked in PSParallelCompact::invoke_no_policy().  The
  11.719 +// marking phase is implemented in PSParallelCompact::marking_phase() and does a
  11.720 +// complete marking of the heap.  The summary phase is implemented in
  11.721 +// PSParallelCompact::summary_phase().  The move and update phase is implemented
  11.722 +// in PSParallelCompact::compact().
  11.723  //
  11.724 -// A space that is being collected is divided into chunks and with
  11.725 -// each chunk is associated an object of type ParallelCompactData.
  11.726 -// Each chunk is of a fixed size and typically will contain more than
  11.727 -// 1 object and may have parts of objects at the front and back of the
  11.728 -// chunk.
  11.729 +// A space that is being collected is divided into regions and with each region
  11.730 +// is associated an object of type ParallelCompactData.  Each region is of a
  11.731 +// fixed size and typically will contain more than 1 object and may have parts
  11.732 +// of objects at the front and back of the region.
  11.733  //
  11.734 -// chunk            -----+---------------------+----------
  11.735 +// region            -----+---------------------+----------
  11.736  // objects covered   [ AAA  )[ BBB )[ CCC   )[ DDD     )
  11.737  //
  11.738 -// The marking phase does a complete marking of all live objects in the
  11.739 -// heap.  The marking also compiles the size of the data for
  11.740 -// all live objects covered by the chunk.  This size includes the
  11.741 -// part of any live object spanning onto the chunk (part of AAA
  11.742 -// if it is live) from the front, all live objects contained in the chunk
  11.743 -// (BBB and/or CCC if they are live), and the part of any live objects
  11.744 -// covered by the chunk that extends off the chunk (part of DDD if it is
  11.745 -// live).  The marking phase uses multiple GC threads and marking is
  11.746 -// done in a bit array of type ParMarkBitMap.  The marking of the
  11.747 -// bit map is done atomically as is the accumulation of the size of the
  11.748 -// live objects covered by a chunk.
  11.749 +// The marking phase does a complete marking of all live objects in the heap.
  11.750 +// The marking also compiles the size of the data for all live objects covered
  11.751 +// by the region.  This size includes the part of any live object spanning onto
  11.752 +// the region (part of AAA if it is live) from the front, all live objects
  11.753 +// contained in the region (BBB and/or CCC if they are live), and the part of
  11.754 +// any live objects covered by the region that extends off the region (part of
  11.755 +// DDD if it is live).  The marking phase uses multiple GC threads and marking
  11.756 +// is done in a bit array of type ParMarkBitMap.  The marking of the bit map is
  11.757 +// done atomically as is the accumulation of the size of the live objects
  11.758 +// covered by a region.
  11.759  //
  11.760 -// The summary phase calculates the total live data to the left of
  11.761 -// each chunk XXX.  Based on that total and the bottom of the space,
  11.762 -// it can calculate the starting location of the live data in XXX.
  11.763 -// The summary phase calculates for each chunk XXX quantites such as
  11.764 +// The summary phase calculates the total live data to the left of each region
  11.765 +// XXX.  Based on that total and the bottom of the space, it can calculate the
  11.766 +// starting location of the live data in XXX.  The summary phase calculates for
  11.767 +// each region XXX quantites such as
  11.768  //
  11.769 -//      - the amount of live data at the beginning of a chunk from an object
  11.770 -//      entering the chunk.
  11.771 -//      - the location of the first live data on the chunk
  11.772 -//      - a count of the number of chunks receiving live data from XXX.
  11.773 +//      - the amount of live data at the beginning of a region from an object
  11.774 +//        entering the region.
  11.775 +//      - the location of the first live data on the region
  11.776 +//      - a count of the number of regions receiving live data from XXX.
  11.777  //
  11.778  // See ParallelCompactData for precise details.  The summary phase also
  11.779 -// calculates the dense prefix for the compaction.  The dense prefix
  11.780 -// is a portion at the beginning of the space that is not moved.  The
  11.781 -// objects in the dense prefix do need to have their object references
  11.782 -// updated.  See method summarize_dense_prefix().
  11.783 +// calculates the dense prefix for the compaction.  The dense prefix is a
  11.784 +// portion at the beginning of the space that is not moved.  The objects in the
  11.785 +// dense prefix do need to have their object references updated.  See method
  11.786 +// summarize_dense_prefix().
  11.787  //
  11.788  // The summary phase is done using 1 GC thread.
  11.789  //
  11.790 -// The compaction phase moves objects to their new location and updates
  11.791 -// all references in the object.
  11.792 +// The compaction phase moves objects to their new location and updates all
  11.793 +// references in the object.
  11.794  //
  11.795 -// A current exception is that objects that cross a chunk boundary
  11.796 -// are moved but do not have their references updated.  References are
  11.797 -// not updated because it cannot easily be determined if the klass
  11.798 -// pointer KKK for the object AAA has been updated.  KKK likely resides
  11.799 -// in a chunk to the left of the chunk containing AAA.  These AAA's
  11.800 -// have there references updated at the end in a clean up phase.
  11.801 -// See the method PSParallelCompact::update_deferred_objects().  An
  11.802 -// alternate strategy is being investigated for this deferral of updating.
  11.803 +// A current exception is that objects that cross a region boundary are moved
  11.804 +// but do not have their references updated.  References are not updated because
  11.805 +// it cannot easily be determined if the klass pointer KKK for the object AAA
  11.806 +// has been updated.  KKK likely resides in a region to the left of the region
  11.807 +// containing AAA.  These AAA's have there references updated at the end in a
  11.808 +// clean up phase.  See the method PSParallelCompact::update_deferred_objects().
  11.809 +// An alternate strategy is being investigated for this deferral of updating.
  11.810  //
  11.811 -// Compaction is done on a chunk basis.  A chunk that is ready to be
  11.812 -// filled is put on a ready list and GC threads take chunk off the list
  11.813 -// and fill them.  A chunk is ready to be filled if it
  11.814 -// empty of live objects.  Such a chunk may have been initially
  11.815 -// empty (only contained
  11.816 -// dead objects) or may have had all its live objects copied out already.
  11.817 -// A chunk that compacts into itself is also ready for filling.  The
  11.818 -// ready list is initially filled with empty chunks and chunks compacting
  11.819 -// into themselves.  There is always at least 1 chunk that can be put on
  11.820 -// the ready list.  The chunks are atomically added and removed from
  11.821 -// the ready list.
  11.822 -//
  11.823 +// Compaction is done on a region basis.  A region that is ready to be filled is
  11.824 +// put on a ready list and GC threads take region off the list and fill them.  A
  11.825 +// region is ready to be filled if it empty of live objects.  Such a region may
  11.826 +// have been initially empty (only contained dead objects) or may have had all
  11.827 +// its live objects copied out already.  A region that compacts into itself is
  11.828 +// also ready for filling.  The ready list is initially filled with empty
  11.829 +// regions and regions compacting into themselves.  There is always at least 1
  11.830 +// region that can be put on the ready list.  The regions are atomically added
  11.831 +// and removed from the ready list.
  11.832 +
  11.833  class PSParallelCompact : AllStatic {
  11.834   public:
  11.835    // Convenient access to type names.
  11.836    typedef ParMarkBitMap::idx_t idx_t;
  11.837 -  typedef ParallelCompactData::ChunkData ChunkData;
  11.838 -  typedef ParallelCompactData::BlockData BlockData;
  11.839 +  typedef ParallelCompactData::RegionData RegionData;
  11.840  
  11.841    typedef enum {
  11.842      perm_space_id, old_space_id, eden_space_id,
  11.843 @@ -977,26 +800,26 @@
  11.844    // not reclaimed).
  11.845    static double dead_wood_limiter(double density, size_t min_percent);
  11.846  
  11.847 -  // Find the first (left-most) chunk in the range [beg, end) that has at least
  11.848 +  // Find the first (left-most) region in the range [beg, end) that has at least
  11.849    // dead_words of dead space to the left.  The argument beg must be the first
  11.850 -  // chunk in the space that is not completely live.
  11.851 -  static ChunkData* dead_wood_limit_chunk(const ChunkData* beg,
  11.852 -                                          const ChunkData* end,
  11.853 -                                          size_t dead_words);
  11.854 +  // region in the space that is not completely live.
  11.855 +  static RegionData* dead_wood_limit_region(const RegionData* beg,
  11.856 +                                            const RegionData* end,
  11.857 +                                            size_t dead_words);
  11.858  
  11.859 -  // Return a pointer to the first chunk in the range [beg, end) that is not
  11.860 +  // Return a pointer to the first region in the range [beg, end) that is not
  11.861    // completely full.
  11.862 -  static ChunkData* first_dead_space_chunk(const ChunkData* beg,
  11.863 -                                           const ChunkData* end);
  11.864 +  static RegionData* first_dead_space_region(const RegionData* beg,
  11.865 +                                             const RegionData* end);
  11.866  
  11.867    // Return a value indicating the benefit or 'yield' if the compacted region
  11.868    // were to start (or equivalently if the dense prefix were to end) at the
  11.869 -  // candidate chunk.  Higher values are better.
  11.870 +  // candidate region.  Higher values are better.
  11.871    //
  11.872    // The value is based on the amount of space reclaimed vs. the costs of (a)
  11.873    // updating references in the dense prefix plus (b) copying objects and
  11.874    // updating references in the compacted region.
  11.875 -  static inline double reclaimed_ratio(const ChunkData* const candidate,
  11.876 +  static inline double reclaimed_ratio(const RegionData* const candidate,
  11.877                                         HeapWord* const bottom,
  11.878                                         HeapWord* const top,
  11.879                                         HeapWord* const new_top);
  11.880 @@ -1005,9 +828,9 @@
  11.881    static HeapWord* compute_dense_prefix(const SpaceId id,
  11.882                                          bool maximum_compaction);
  11.883  
  11.884 -  // Return true if dead space crosses onto the specified Chunk; bit must be the
  11.885 -  // bit index corresponding to the first word of the Chunk.
  11.886 -  static inline bool dead_space_crosses_boundary(const ChunkData* chunk,
  11.887 +  // Return true if dead space crosses onto the specified Region; bit must be
  11.888 +  // the bit index corresponding to the first word of the Region.
  11.889 +  static inline bool dead_space_crosses_boundary(const RegionData* region,
  11.890                                                   idx_t bit);
  11.891  
  11.892    // Summary phase utility routine to fill dead space (if any) at the dense
  11.893 @@ -1019,12 +842,6 @@
  11.894    static void summarize_space(SpaceId id, bool maximum_compaction);
  11.895    static void summary_phase(ParCompactionManager* cm, bool maximum_compaction);
  11.896  
  11.897 -  static bool block_first_offset(size_t block_index, idx_t* block_offset_ptr);
  11.898 -
  11.899 -  // Fill in the BlockData
  11.900 -  static void summarize_blocks(ParCompactionManager* cm,
  11.901 -                               SpaceId first_compaction_space_id);
  11.902 -
  11.903    // The space that is compacted after space_id.
  11.904    static SpaceId next_compaction_space_id(SpaceId space_id);
  11.905  
  11.906 @@ -1038,16 +855,16 @@
  11.907    static void compact_perm(ParCompactionManager* cm);
  11.908    static void compact();
  11.909  
  11.910 -  // Add available chunks to the stack and draining tasks to the task queue.
  11.911 -  static void enqueue_chunk_draining_tasks(GCTaskQueue* q,
  11.912 -                                           uint parallel_gc_threads);
  11.913 +  // Add available regions to the stack and draining tasks to the task queue.
  11.914 +  static void enqueue_region_draining_tasks(GCTaskQueue* q,
  11.915 +                                            uint parallel_gc_threads);
  11.916  
  11.917    // Add dense prefix update tasks to the task queue.
  11.918    static void enqueue_dense_prefix_tasks(GCTaskQueue* q,
  11.919                                           uint parallel_gc_threads);
  11.920  
  11.921 -  // Add chunk stealing tasks to the task queue.
  11.922 -  static void enqueue_chunk_stealing_tasks(
  11.923 +  // Add region stealing tasks to the task queue.
  11.924 +  static void enqueue_region_stealing_tasks(
  11.925                                         GCTaskQueue* q,
  11.926                                         ParallelTaskTerminator* terminator_ptr,
  11.927                                         uint parallel_gc_threads);
  11.928 @@ -1154,56 +971,56 @@
  11.929    // Move and update the live objects in the specified space.
  11.930    static void move_and_update(ParCompactionManager* cm, SpaceId space_id);
  11.931  
  11.932 -  // Process the end of the given chunk range in the dense prefix.
  11.933 +  // Process the end of the given region range in the dense prefix.
  11.934    // This includes saving any object not updated.
  11.935 -  static void dense_prefix_chunks_epilogue(ParCompactionManager* cm,
  11.936 -                                           size_t chunk_start_index,
  11.937 -                                           size_t chunk_end_index,
  11.938 -                                           idx_t exiting_object_offset,
  11.939 -                                           idx_t chunk_offset_start,
  11.940 -                                           idx_t chunk_offset_end);
  11.941 +  static void dense_prefix_regions_epilogue(ParCompactionManager* cm,
  11.942 +                                            size_t region_start_index,
  11.943 +                                            size_t region_end_index,
  11.944 +                                            idx_t exiting_object_offset,
  11.945 +                                            idx_t region_offset_start,
  11.946 +                                            idx_t region_offset_end);
  11.947  
  11.948 -  // Update a chunk in the dense prefix.  For each live object
  11.949 -  // in the chunk, update it's interior references.  For each
  11.950 +  // Update a region in the dense prefix.  For each live object
  11.951 +  // in the region, update it's interior references.  For each
  11.952    // dead object, fill it with deadwood. Dead space at the end
  11.953 -  // of a chunk range will be filled to the start of the next
  11.954 -  // live object regardless of the chunk_index_end.  None of the
  11.955 +  // of a region range will be filled to the start of the next
  11.956 +  // live object regardless of the region_index_end.  None of the
  11.957    // objects in the dense prefix move and dead space is dead
  11.958    // (holds only dead objects that don't need any processing), so
  11.959    // dead space can be filled in any order.
  11.960    static void update_and_deadwood_in_dense_prefix(ParCompactionManager* cm,
  11.961                                                    SpaceId space_id,
  11.962 -                                                  size_t chunk_index_start,
  11.963 -                                                  size_t chunk_index_end);
  11.964 +                                                  size_t region_index_start,
  11.965 +                                                  size_t region_index_end);
  11.966  
  11.967    // Return the address of the count + 1st live word in the range [beg, end).
  11.968    static HeapWord* skip_live_words(HeapWord* beg, HeapWord* end, size_t count);
  11.969  
  11.970    // Return the address of the word to be copied to dest_addr, which must be
  11.971 -  // aligned to a chunk boundary.
  11.972 +  // aligned to a region boundary.
  11.973    static HeapWord* first_src_addr(HeapWord* const dest_addr,
  11.974 -                                  size_t src_chunk_idx);
  11.975 +                                  size_t src_region_idx);
  11.976  
  11.977 -  // Determine the next source chunk, set closure.source() to the start of the
  11.978 -  // new chunk return the chunk index.  Parameter end_addr is the address one
  11.979 +  // Determine the next source region, set closure.source() to the start of the
  11.980 +  // new region return the region index.  Parameter end_addr is the address one
  11.981    // beyond the end of source range just processed.  If necessary, switch to a
  11.982    // new source space and set src_space_id (in-out parameter) and src_space_top
  11.983    // (out parameter) accordingly.
  11.984 -  static size_t next_src_chunk(MoveAndUpdateClosure& closure,
  11.985 -                               SpaceId& src_space_id,
  11.986 -                               HeapWord*& src_space_top,
  11.987 -                               HeapWord* end_addr);
  11.988 +  static size_t next_src_region(MoveAndUpdateClosure& closure,
  11.989 +                                SpaceId& src_space_id,
  11.990 +                                HeapWord*& src_space_top,
  11.991 +                                HeapWord* end_addr);
  11.992  
  11.993 -  // Decrement the destination count for each non-empty source chunk in the
  11.994 -  // range [beg_chunk, chunk(chunk_align_up(end_addr))).
  11.995 +  // Decrement the destination count for each non-empty source region in the
  11.996 +  // range [beg_region, region(region_align_up(end_addr))).
  11.997    static void decrement_destination_counts(ParCompactionManager* cm,
  11.998 -                                           size_t beg_chunk,
  11.999 +                                           size_t beg_region,
 11.1000                                             HeapWord* end_addr);
 11.1001  
 11.1002 -  // Fill a chunk, copying objects from one or more source chunks.
 11.1003 -  static void fill_chunk(ParCompactionManager* cm, size_t chunk_idx);
 11.1004 -  static void fill_and_update_chunk(ParCompactionManager* cm, size_t chunk) {
 11.1005 -    fill_chunk(cm, chunk);
 11.1006 +  // Fill a region, copying objects from one or more source regions.
 11.1007 +  static void fill_region(ParCompactionManager* cm, size_t region_idx);
 11.1008 +  static void fill_and_update_region(ParCompactionManager* cm, size_t region) {
 11.1009 +    fill_region(cm, region);
 11.1010    }
 11.1011  
 11.1012    // Update the deferred objects in the space.
 11.1013 @@ -1259,7 +1076,7 @@
 11.1014  #ifndef PRODUCT
 11.1015    // Debugging support.
 11.1016    static const char* space_names[last_space_id];
 11.1017 -  static void print_chunk_ranges();
 11.1018 +  static void print_region_ranges();
 11.1019    static void print_dense_prefix_stats(const char* const algorithm,
 11.1020                                         const SpaceId id,
 11.1021                                         const bool maximum_compaction,
 11.1022 @@ -1267,7 +1084,7 @@
 11.1023  #endif  // #ifndef PRODUCT
 11.1024  
 11.1025  #ifdef  ASSERT
 11.1026 -  // Verify that all the chunks have been emptied.
 11.1027 +  // Verify that all the regions have been emptied.
 11.1028    static void verify_complete(SpaceId space_id);
 11.1029  #endif  // #ifdef ASSERT
 11.1030  };
 11.1031 @@ -1376,17 +1193,17 @@
 11.1032  }
 11.1033  
 11.1034  inline bool
 11.1035 -PSParallelCompact::dead_space_crosses_boundary(const ChunkData* chunk,
 11.1036 +PSParallelCompact::dead_space_crosses_boundary(const RegionData* region,
 11.1037                                                 idx_t bit)
 11.1038  {
 11.1039 -  assert(bit > 0, "cannot call this for the first bit/chunk");
 11.1040 -  assert(_summary_data.chunk_to_addr(chunk) == _mark_bitmap.bit_to_addr(bit),
 11.1041 +  assert(bit > 0, "cannot call this for the first bit/region");
 11.1042 +  assert(_summary_data.region_to_addr(region) == _mark_bitmap.bit_to_addr(bit),
 11.1043           "sanity check");
 11.1044  
 11.1045    // Dead space crosses the boundary if (1) a partial object does not extend
 11.1046 -  // onto the chunk, (2) an object does not start at the beginning of the chunk,
 11.1047 -  // and (3) an object does not end at the end of the prior chunk.
 11.1048 -  return chunk->partial_obj_size() == 0 &&
 11.1049 +  // onto the region, (2) an object does not start at the beginning of the
 11.1050 +  // region, and (3) an object does not end at the end of the prior region.
 11.1051 +  return region->partial_obj_size() == 0 &&
 11.1052      !_mark_bitmap.is_obj_beg(bit) &&
 11.1053      !_mark_bitmap.is_obj_end(bit - 1);
 11.1054  }
    12.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psPermGen.cpp	Tue Sep 30 15:53:55 2008 -0700
    12.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psPermGen.cpp	Wed Oct 01 15:05:06 2008 -0400
    12.3 @@ -123,8 +123,6 @@
    12.4  
    12.5  void PSPermGen::precompact() {
    12.6    // Reset start array first.
    12.7 -  debug_only(if (!UseParallelOldGC || !VerifyParallelOldWithMarkSweep) {)
    12.8    _start_array.reset();
    12.9 -  debug_only(})
   12.10    object_mark_sweep()->precompact();
   12.11  }
    13.1 --- a/src/share/vm/gc_implementation/shared/immutableSpace.hpp	Tue Sep 30 15:53:55 2008 -0700
    13.2 +++ b/src/share/vm/gc_implementation/shared/immutableSpace.hpp	Wed Oct 01 15:05:06 2008 -0400
    13.3 @@ -50,7 +50,8 @@
    13.4    size_t capacity_in_bytes() const            { return capacity_in_words() * HeapWordSize; }
    13.5  
    13.6    // Size computations.  Sizes are in heapwords.
    13.7 -  size_t capacity_in_words() const            { return pointer_delta(end(), bottom()); }
    13.8 +  size_t capacity_in_words() const                { return pointer_delta(end(), bottom()); }
    13.9 +  virtual size_t capacity_in_words(Thread*) const { return capacity_in_words(); }
   13.10  
   13.11    // Iteration.
   13.12    virtual void oop_iterate(OopClosure* cl);
    14.1 --- a/src/share/vm/gc_implementation/shared/markSweep.inline.hpp	Tue Sep 30 15:53:55 2008 -0700
    14.2 +++ b/src/share/vm/gc_implementation/shared/markSweep.inline.hpp	Wed Oct 01 15:05:06 2008 -0400
    14.3 @@ -23,13 +23,6 @@
    14.4   */
    14.5  
    14.6  inline void MarkSweep::mark_object(oop obj) {
    14.7 -#ifndef SERIALGC
    14.8 -  if (UseParallelOldGC && VerifyParallelOldWithMarkSweep) {
    14.9 -    assert(PSParallelCompact::mark_bitmap()->is_marked(obj),
   14.10 -           "Should be marked in the marking bitmap");
   14.11 -  }
   14.12 -#endif // SERIALGC
   14.13 -
   14.14    // some marks may contain information we need to preserve so we store them away
   14.15    // and overwrite the mark.  We'll restore it at the end of markSweep.
   14.16    markOop mark = obj->mark();
    15.1 --- a/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp	Tue Sep 30 15:53:55 2008 -0700
    15.2 +++ b/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp	Wed Oct 01 15:05:06 2008 -0400
    15.3 @@ -181,6 +181,25 @@
    15.4    return lgrp_spaces()->at(i)->space()->free_in_bytes();
    15.5  }
    15.6  
    15.7 +
    15.8 +size_t MutableNUMASpace::capacity_in_words(Thread* thr) const {
    15.9 +  guarantee(thr != NULL, "No thread");
   15.10 +  int lgrp_id = thr->lgrp_id();
   15.11 +  if (lgrp_id == -1) {
   15.12 +    if (lgrp_spaces()->length() > 0) {
   15.13 +      return capacity_in_words() / lgrp_spaces()->length();
   15.14 +    } else {
   15.15 +      assert(false, "There should be at least one locality group");
   15.16 +      return 0;
   15.17 +    }
   15.18 +  }
   15.19 +  int i = lgrp_spaces()->find(&lgrp_id, LGRPSpace::equals);
   15.20 +  if (i == -1) {
   15.21 +    return 0;
   15.22 +  }
   15.23 +  return lgrp_spaces()->at(i)->space()->capacity_in_words();
   15.24 +}
   15.25 +
   15.26  // Check if the NUMA topology has changed. Add and remove spaces if needed.
   15.27  // The update can be forced by setting the force parameter equal to true.
   15.28  bool MutableNUMASpace::update_layout(bool force) {
   15.29 @@ -722,7 +741,8 @@
   15.30      i = os::random() % lgrp_spaces()->length();
   15.31    }
   15.32  
   15.33 -  MutableSpace *s = lgrp_spaces()->at(i)->space();
   15.34 +  LGRPSpace* ls = lgrp_spaces()->at(i);
   15.35 +  MutableSpace *s = ls->space();
   15.36    HeapWord *p = s->allocate(size);
   15.37  
   15.38    if (p != NULL) {
   15.39 @@ -743,6 +763,9 @@
   15.40        *(int*)i = 0;
   15.41      }
   15.42    }
   15.43 +  if (p == NULL) {
   15.44 +    ls->set_allocation_failed();
   15.45 +  }
   15.46    return p;
   15.47  }
   15.48  
   15.49 @@ -761,7 +784,8 @@
   15.50    if (i == -1) {
   15.51      i = os::random() % lgrp_spaces()->length();
   15.52    }
   15.53 -  MutableSpace *s = lgrp_spaces()->at(i)->space();
   15.54 +  LGRPSpace *ls = lgrp_spaces()->at(i);
   15.55 +  MutableSpace *s = ls->space();
   15.56    HeapWord *p = s->cas_allocate(size);
   15.57    if (p != NULL) {
   15.58      size_t remainder = pointer_delta(s->end(), p + size);
   15.59 @@ -790,6 +814,9 @@
   15.60        *(int*)i = 0;
   15.61      }
   15.62    }
   15.63 +  if (p == NULL) {
   15.64 +    ls->set_allocation_failed();
   15.65 +  }
   15.66    return p;
   15.67  }
   15.68  
    16.1 --- a/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp	Tue Sep 30 15:53:55 2008 -0700
    16.2 +++ b/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp	Wed Oct 01 15:05:06 2008 -0400
    16.3 @@ -60,6 +60,7 @@
    16.4      MutableSpace* _space;
    16.5      MemRegion _invalid_region;
    16.6      AdaptiveWeightedAverage *_alloc_rate;
    16.7 +    bool _allocation_failed;
    16.8  
    16.9      struct SpaceStats {
   16.10        size_t _local_space, _remote_space, _unbiased_space, _uncommited_space;
   16.11 @@ -81,7 +82,7 @@
   16.12      char* last_page_scanned()            { return _last_page_scanned; }
   16.13      void set_last_page_scanned(char* p)  { _last_page_scanned = p;    }
   16.14     public:
   16.15 -    LGRPSpace(int l) : _lgrp_id(l), _last_page_scanned(NULL) {
   16.16 +    LGRPSpace(int l) : _lgrp_id(l), _last_page_scanned(NULL), _allocation_failed(false) {
   16.17        _space = new MutableSpace();
   16.18        _alloc_rate = new AdaptiveWeightedAverage(NUMAChunkResizeWeight);
   16.19      }
   16.20 @@ -103,8 +104,21 @@
   16.21        return *(int*)lgrp_id_value == p->lgrp_id();
   16.22      }
   16.23  
   16.24 +    // Report a failed allocation.
   16.25 +    void set_allocation_failed() { _allocation_failed = true;  }
   16.26 +
   16.27      void sample() {
   16.28 -      alloc_rate()->sample(space()->used_in_bytes());
   16.29 +      // If there was a failed allocation make allocation rate equal
   16.30 +      // to the size of the whole chunk. This ensures the progress of
   16.31 +      // the adaptation process.
   16.32 +      size_t alloc_rate_sample;
   16.33 +      if (_allocation_failed) {
   16.34 +        alloc_rate_sample = space()->capacity_in_bytes();
   16.35 +        _allocation_failed = false;
   16.36 +      } else {
   16.37 +        alloc_rate_sample = space()->used_in_bytes();
   16.38 +      }
   16.39 +      alloc_rate()->sample(alloc_rate_sample);
   16.40      }
   16.41  
   16.42      MemRegion invalid_region() const                { return _invalid_region;      }
   16.43 @@ -190,6 +204,9 @@
   16.44    virtual void ensure_parsability();
   16.45    virtual size_t used_in_words() const;
   16.46    virtual size_t free_in_words() const;
   16.47 +
   16.48 +  using MutableSpace::capacity_in_words;
   16.49 +  virtual size_t capacity_in_words(Thread* thr) const;
   16.50    virtual size_t tlab_capacity(Thread* thr) const;
   16.51    virtual size_t unsafe_max_tlab_alloc(Thread* thr) const;
   16.52  
    17.1 --- a/src/share/vm/runtime/globals.hpp	Tue Sep 30 15:53:55 2008 -0700
    17.2 +++ b/src/share/vm/runtime/globals.hpp	Wed Oct 01 15:05:06 2008 -0400
    17.3 @@ -1157,10 +1157,6 @@
    17.4            "In the Parallel Old garbage collector use parallel dense"        \
    17.5            " prefix update")                                                 \
    17.6                                                                              \
    17.7 -  develop(bool, UseParallelOldGCChunkPointerCalc, true,                     \
    17.8 -          "In the Parallel Old garbage collector use chucks to calculate"   \
    17.9 -          " new object locations")                                          \
   17.10 -                                                                            \
   17.11    product(uintx, HeapMaximumCompactionInterval, 20,                         \
   17.12            "How often should we maximally compact the heap (not allowing "   \
   17.13            "any dead space)")                                                \
   17.14 @@ -1189,21 +1185,14 @@
   17.15    product(uintx, ParallelCMSThreads, 0,                                     \
   17.16            "Max number of threads CMS will use for concurrent work")         \
   17.17                                                                              \
   17.18 -  develop(bool, VerifyParallelOldWithMarkSweep, false,                      \
   17.19 -          "Use the MarkSweep code to verify phases of Parallel Old")        \
   17.20 -                                                                            \
   17.21 -  develop(uintx, VerifyParallelOldWithMarkSweepInterval, 1,                 \
   17.22 -          "Interval at which the MarkSweep code is used to verify "         \
   17.23 -          "phases of Parallel Old")                                         \
   17.24 -                                                                            \
   17.25    develop(bool, ParallelOldMTUnsafeMarkBitMap, false,                       \
   17.26            "Use the Parallel Old MT unsafe in marking the bitmap")           \
   17.27                                                                              \
   17.28    develop(bool, ParallelOldMTUnsafeUpdateLiveData, false,                   \
   17.29            "Use the Parallel Old MT unsafe in update of live size")          \
   17.30                                                                              \
   17.31 -  develop(bool, TraceChunkTasksQueuing, false,                              \
   17.32 -          "Trace the queuing of the chunk tasks")                           \
   17.33 +  develop(bool, TraceRegionTasksQueuing, false,                             \
   17.34 +          "Trace the queuing of the region tasks")                          \
   17.35                                                                              \
   17.36    product(uintx, ParallelMarkingThreads, 0,                                 \
   17.37            "Number of marking threads concurrent gc will use")               \
    18.1 --- a/src/share/vm/utilities/taskqueue.cpp	Tue Sep 30 15:53:55 2008 -0700
    18.2 +++ b/src/share/vm/utilities/taskqueue.cpp	Wed Oct 01 15:05:06 2008 -0400
    18.3 @@ -109,72 +109,72 @@
    18.4    }
    18.5  }
    18.6  
    18.7 -bool ChunkTaskQueueWithOverflow::is_empty() {
    18.8 -  return (_chunk_queue.size() == 0) &&
    18.9 +bool RegionTaskQueueWithOverflow::is_empty() {
   18.10 +  return (_region_queue.size() == 0) &&
   18.11           (_overflow_stack->length() == 0);
   18.12  }
   18.13  
   18.14 -bool ChunkTaskQueueWithOverflow::stealable_is_empty() {
   18.15 -  return _chunk_queue.size() == 0;
   18.16 +bool RegionTaskQueueWithOverflow::stealable_is_empty() {
   18.17 +  return _region_queue.size() == 0;
   18.18  }
   18.19  
   18.20 -bool ChunkTaskQueueWithOverflow::overflow_is_empty() {
   18.21 +bool RegionTaskQueueWithOverflow::overflow_is_empty() {
   18.22    return _overflow_stack->length() == 0;
   18.23  }
   18.24  
   18.25 -void ChunkTaskQueueWithOverflow::initialize() {
   18.26 -  _chunk_queue.initialize();
   18.27 +void RegionTaskQueueWithOverflow::initialize() {
   18.28 +  _region_queue.initialize();
   18.29    assert(_overflow_stack == 0, "Creating memory leak");
   18.30    _overflow_stack =
   18.31 -    new (ResourceObj::C_HEAP) GrowableArray<ChunkTask>(10, true);
   18.32 +    new (ResourceObj::C_HEAP) GrowableArray<RegionTask>(10, true);
   18.33  }
   18.34  
   18.35 -void ChunkTaskQueueWithOverflow::save(ChunkTask t) {
   18.36 -  if (TraceChunkTasksQueuing && Verbose) {
   18.37 +void RegionTaskQueueWithOverflow::save(RegionTask t) {
   18.38 +  if (TraceRegionTasksQueuing && Verbose) {
   18.39      gclog_or_tty->print_cr("CTQ: save " PTR_FORMAT, t);
   18.40    }
   18.41 -  if(!_chunk_queue.push(t)) {
   18.42 +  if(!_region_queue.push(t)) {
   18.43      _overflow_stack->push(t);
   18.44    }
   18.45  }
   18.46  
   18.47 -// Note that using this method will retrieve all chunks
   18.48 +// Note that using this method will retrieve all regions
   18.49  // that have been saved but that it will always check
   18.50  // the overflow stack.  It may be more efficient to
   18.51  // check the stealable queue and the overflow stack
   18.52  // separately.
   18.53 -bool ChunkTaskQueueWithOverflow::retrieve(ChunkTask& chunk_task) {
   18.54 -  bool result = retrieve_from_overflow(chunk_task);
   18.55 +bool RegionTaskQueueWithOverflow::retrieve(RegionTask& region_task) {
   18.56 +  bool result = retrieve_from_overflow(region_task);
   18.57    if (!result) {
   18.58 -    result = retrieve_from_stealable_queue(chunk_task);
   18.59 +    result = retrieve_from_stealable_queue(region_task);
   18.60    }
   18.61 -  if (TraceChunkTasksQueuing && Verbose && result) {
   18.62 +  if (TraceRegionTasksQueuing && Verbose && result) {
   18.63      gclog_or_tty->print_cr("  CTQ: retrieve " PTR_FORMAT, result);
   18.64    }
   18.65    return result;
   18.66  }
   18.67  
   18.68 -bool ChunkTaskQueueWithOverflow::retrieve_from_stealable_queue(
   18.69 -                                   ChunkTask& chunk_task) {
   18.70 -  bool result = _chunk_queue.pop_local(chunk_task);
   18.71 -  if (TraceChunkTasksQueuing && Verbose) {
   18.72 -    gclog_or_tty->print_cr("CTQ: retrieve_stealable " PTR_FORMAT, chunk_task);
   18.73 +bool RegionTaskQueueWithOverflow::retrieve_from_stealable_queue(
   18.74 +                                   RegionTask& region_task) {
   18.75 +  bool result = _region_queue.pop_local(region_task);
   18.76 +  if (TraceRegionTasksQueuing && Verbose) {
   18.77 +    gclog_or_tty->print_cr("CTQ: retrieve_stealable " PTR_FORMAT, region_task);
   18.78    }
   18.79    return result;
   18.80  }
   18.81  
   18.82 -bool ChunkTaskQueueWithOverflow::retrieve_from_overflow(
   18.83 -                                        ChunkTask& chunk_task) {
   18.84 +bool
   18.85 +RegionTaskQueueWithOverflow::retrieve_from_overflow(RegionTask& region_task) {
   18.86    bool result;
   18.87    if (!_overflow_stack->is_empty()) {
   18.88 -    chunk_task = _overflow_stack->pop();
   18.89 +    region_task = _overflow_stack->pop();
   18.90      result = true;
   18.91    } else {
   18.92 -    chunk_task = (ChunkTask) NULL;
   18.93 +    region_task = (RegionTask) NULL;
   18.94      result = false;
   18.95    }
   18.96 -  if (TraceChunkTasksQueuing && Verbose) {
   18.97 -    gclog_or_tty->print_cr("CTQ: retrieve_stealable " PTR_FORMAT, chunk_task);
   18.98 +  if (TraceRegionTasksQueuing && Verbose) {
   18.99 +    gclog_or_tty->print_cr("CTQ: retrieve_stealable " PTR_FORMAT, region_task);
  18.100    }
  18.101    return result;
  18.102  }
    19.1 --- a/src/share/vm/utilities/taskqueue.hpp	Tue Sep 30 15:53:55 2008 -0700
    19.2 +++ b/src/share/vm/utilities/taskqueue.hpp	Wed Oct 01 15:05:06 2008 -0400
    19.3 @@ -557,32 +557,32 @@
    19.4  typedef GenericTaskQueue<StarTask>     OopStarTaskQueue;
    19.5  typedef GenericTaskQueueSet<StarTask>  OopStarTaskQueueSet;
    19.6  
    19.7 -typedef size_t ChunkTask;  // index for chunk
    19.8 -typedef GenericTaskQueue<ChunkTask>    ChunkTaskQueue;
    19.9 -typedef GenericTaskQueueSet<ChunkTask> ChunkTaskQueueSet;
   19.10 +typedef size_t RegionTask;  // index for region
   19.11 +typedef GenericTaskQueue<RegionTask>    RegionTaskQueue;
   19.12 +typedef GenericTaskQueueSet<RegionTask> RegionTaskQueueSet;
   19.13  
   19.14 -class ChunkTaskQueueWithOverflow: public CHeapObj {
   19.15 +class RegionTaskQueueWithOverflow: public CHeapObj {
   19.16   protected:
   19.17 -  ChunkTaskQueue              _chunk_queue;
   19.18 -  GrowableArray<ChunkTask>*   _overflow_stack;
   19.19 +  RegionTaskQueue              _region_queue;
   19.20 +  GrowableArray<RegionTask>*   _overflow_stack;
   19.21  
   19.22   public:
   19.23 -  ChunkTaskQueueWithOverflow() : _overflow_stack(NULL) {}
   19.24 +  RegionTaskQueueWithOverflow() : _overflow_stack(NULL) {}
   19.25    // Initialize both stealable queue and overflow
   19.26    void initialize();
   19.27    // Save first to stealable queue and then to overflow
   19.28 -  void save(ChunkTask t);
   19.29 +  void save(RegionTask t);
   19.30    // Retrieve first from overflow and then from stealable queue
   19.31 -  bool retrieve(ChunkTask& chunk_index);
   19.32 +  bool retrieve(RegionTask& region_index);
   19.33    // Retrieve from stealable queue
   19.34 -  bool retrieve_from_stealable_queue(ChunkTask& chunk_index);
   19.35 +  bool retrieve_from_stealable_queue(RegionTask& region_index);
   19.36    // Retrieve from overflow
   19.37 -  bool retrieve_from_overflow(ChunkTask& chunk_index);
   19.38 +  bool retrieve_from_overflow(RegionTask& region_index);
   19.39    bool is_empty();
   19.40    bool stealable_is_empty();
   19.41    bool overflow_is_empty();
   19.42 -  juint stealable_size() { return _chunk_queue.size(); }
   19.43 -  ChunkTaskQueue* task_queue() { return &_chunk_queue; }
   19.44 +  juint stealable_size() { return _region_queue.size(); }
   19.45 +  RegionTaskQueue* task_queue() { return &_region_queue; }
   19.46  };
   19.47  
   19.48 -#define USE_ChunkTaskQueueWithOverflow
   19.49 +#define USE_RegionTaskQueueWithOverflow

mercurial