src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
changeset 54045 c97c87e96897
parent 54006 a421bdf22394
child 54046 f02c6b980c04
equal deleted inserted replaced
54044:d9853137aa28 54045:c97c87e96897
    87 #endif
    87 #endif
    88 
    88 
    89 class ShenandoahPretouchTask : public AbstractGangTask {
    89 class ShenandoahPretouchTask : public AbstractGangTask {
    90 private:
    90 private:
    91   ShenandoahRegionIterator _regions;
    91   ShenandoahRegionIterator _regions;
       
    92   char* _bitmap_base;
    92   const size_t _bitmap_size;
    93   const size_t _bitmap_size;
    93   const size_t _page_size;
    94   const size_t _heap_page_size;
    94   char* _bitmap_base;
    95   const size_t _bitmap_page_size;
    95 public:
    96 public:
    96   ShenandoahPretouchTask(char* bitmap_base, size_t bitmap_size, size_t page_size) :
    97   ShenandoahPretouchTask(char* bitmap_base, size_t bitmap_size, size_t heap_page_size, size_t bitmap_page_size) :
    97     AbstractGangTask("Shenandoah PreTouch"),
    98     AbstractGangTask("Shenandoah PreTouch"),
       
    99     _bitmap_base(bitmap_base),
    98     _bitmap_size(bitmap_size),
   100     _bitmap_size(bitmap_size),
    99     _page_size(page_size),
   101     _heap_page_size(heap_page_size),
   100     _bitmap_base(bitmap_base) {
   102     _bitmap_page_size(bitmap_page_size) {}
   101   }
       
   102 
   103 
   103   virtual void work(uint worker_id) {
   104   virtual void work(uint worker_id) {
   104     ShenandoahHeapRegion* r = _regions.next();
   105     ShenandoahHeapRegion* r = _regions.next();
   105     while (r != NULL) {
   106     while (r != NULL) {
   106       os::pretouch_memory(r->bottom(), r->end(), _page_size);
   107       os::pretouch_memory(r->bottom(), r->end(), _heap_page_size);
   107 
   108 
   108       size_t start = r->region_number()       * ShenandoahHeapRegion::region_size_bytes() / MarkBitMap::heap_map_factor();
   109       size_t start = r->region_number()       * ShenandoahHeapRegion::region_size_bytes() / MarkBitMap::heap_map_factor();
   109       size_t end   = (r->region_number() + 1) * ShenandoahHeapRegion::region_size_bytes() / MarkBitMap::heap_map_factor();
   110       size_t end   = (r->region_number() + 1) * ShenandoahHeapRegion::region_size_bytes() / MarkBitMap::heap_map_factor();
   110       assert (end <= _bitmap_size, "end is sane: " SIZE_FORMAT " < " SIZE_FORMAT, end, _bitmap_size);
   111       assert (end <= _bitmap_size, "end is sane: " SIZE_FORMAT " < " SIZE_FORMAT, end, _bitmap_size);
   111 
   112 
   112       os::pretouch_memory(_bitmap_base + start, _bitmap_base + end, _page_size);
   113       os::pretouch_memory(_bitmap_base + start, _bitmap_base + end, _bitmap_page_size);
   113 
   114 
   114       r = _regions.next();
   115       r = _regions.next();
   115     }
   116     }
   116   }
   117   }
   117 };
   118 };
   119 jint ShenandoahHeap::initialize() {
   120 jint ShenandoahHeap::initialize() {
   120   ShenandoahBrooksPointer::initial_checks();
   121   ShenandoahBrooksPointer::initial_checks();
   121 
   122 
   122   initialize_heuristics();
   123   initialize_heuristics();
   123 
   124 
       
   125   //
       
   126   // Figure out heap sizing
       
   127   //
       
   128 
   124   size_t init_byte_size = collector_policy()->initial_heap_byte_size();
   129   size_t init_byte_size = collector_policy()->initial_heap_byte_size();
   125   size_t max_byte_size = collector_policy()->max_heap_byte_size();
   130   size_t max_byte_size  = collector_policy()->max_heap_byte_size();
   126   size_t heap_alignment = collector_policy()->heap_alignment();
   131   size_t heap_alignment = collector_policy()->heap_alignment();
       
   132 
       
   133   size_t reg_size_bytes = ShenandoahHeapRegion::region_size_bytes();
   127 
   134 
   128   if (ShenandoahAlwaysPreTouch) {
   135   if (ShenandoahAlwaysPreTouch) {
   129     // Enabled pre-touch means the entire heap is committed right away.
   136     // Enabled pre-touch means the entire heap is committed right away.
   130     init_byte_size = max_byte_size;
   137     init_byte_size = max_byte_size;
   131   }
   138   }
   132 
   139 
   133   Universe::check_alignment(max_byte_size,
   140   Universe::check_alignment(max_byte_size,  reg_size_bytes, "Shenandoah heap");
   134                             ShenandoahHeapRegion::region_size_bytes(),
   141   Universe::check_alignment(init_byte_size, reg_size_bytes, "Shenandoah heap");
   135                             "shenandoah heap");
       
   136   Universe::check_alignment(init_byte_size,
       
   137                             ShenandoahHeapRegion::region_size_bytes(),
       
   138                             "shenandoah heap");
       
   139 
       
   140   ReservedSpace heap_rs = Universe::reserve_heap(max_byte_size,
       
   141                                                  heap_alignment);
       
   142   initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*) (heap_rs.base() + heap_rs.size()));
       
   143 
       
   144   ReservedSpace pgc_rs = heap_rs.first_part(max_byte_size);
       
   145 
   142 
   146   _num_regions = ShenandoahHeapRegion::region_count();
   143   _num_regions = ShenandoahHeapRegion::region_count();
   147 
   144 
   148   size_t num_committed_regions = init_byte_size / ShenandoahHeapRegion::region_size_bytes();
   145   size_t num_committed_regions = init_byte_size / reg_size_bytes;
   149   num_committed_regions = MIN2(num_committed_regions, _num_regions);
   146   num_committed_regions = MIN2(num_committed_regions, _num_regions);
   150   assert(num_committed_regions <= _num_regions, "sanity");
   147   assert(num_committed_regions <= _num_regions, "sanity");
   151 
   148 
   152   _initial_size = num_committed_regions * ShenandoahHeapRegion::region_size_bytes();
   149   _initial_size = num_committed_regions * reg_size_bytes;
   153   _committed = _initial_size;
   150   _committed = _initial_size;
   154 
   151 
   155   log_info(gc, heap)("Initialize Shenandoah heap with initial size " SIZE_FORMAT "%s",
   152   size_t heap_page_size   = UseLargePages ? (size_t)os::large_page_size() : (size_t)os::vm_page_size();
   156           byte_size_in_proper_unit(_initial_size), proper_unit_for_byte_size(_initial_size));
   153   size_t bitmap_page_size = UseLargePages ? (size_t)os::large_page_size() : (size_t)os::vm_page_size();
   157   if (!os::commit_memory(pgc_rs.base(), _initial_size, false)) {
   154 
   158     vm_exit_out_of_memory(_initial_size, OOM_MMAP_ERROR, "Shenandoah failed to initialize heap");
   155   //
   159   }
   156   // Reserve and commit memory for heap
   160 
   157   //
   161   size_t reg_size_words = ShenandoahHeapRegion::region_size_words();
   158 
   162   size_t reg_size_bytes = ShenandoahHeapRegion::region_size_bytes();
   159   ReservedSpace heap_rs = Universe::reserve_heap(max_byte_size, heap_alignment);
   163 
   160   initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*) (heap_rs.base() + heap_rs.size()));
   164   _regions = NEW_C_HEAP_ARRAY(ShenandoahHeapRegion*, _num_regions, mtGC);
   161   _heap_region = MemRegion((HeapWord*)heap_rs.base(), heap_rs.size() / HeapWordSize);
   165   _free_set = new ShenandoahFreeSet(this, _num_regions);
       
   166 
       
   167   _collection_set = new ShenandoahCollectionSet(this, (HeapWord*)pgc_rs.base());
       
   168 
       
   169   if (ShenandoahPacing) {
       
   170     _pacer = new ShenandoahPacer(this);
       
   171     _pacer->setup_for_idle();
       
   172   } else {
       
   173     _pacer = NULL;
       
   174   }
       
   175 
   162 
   176   assert((((size_t) base()) & ShenandoahHeapRegion::region_size_bytes_mask()) == 0,
   163   assert((((size_t) base()) & ShenandoahHeapRegion::region_size_bytes_mask()) == 0,
   177          "misaligned heap: " PTR_FORMAT, p2i(base()));
   164          "Misaligned heap: " PTR_FORMAT, p2i(base()));
   178 
   165 
   179   // The call below uses stuff (the SATB* things) that are in G1, but probably
   166   ReservedSpace sh_rs = heap_rs.first_part(max_byte_size);
   180   // belong into a shared location.
   167   os::commit_memory_or_exit(sh_rs.base(), _initial_size, false,
   181   ShenandoahBarrierSet::satb_mark_queue_set().initialize(this,
   168                             "Cannot commit heap memory");
   182                                                SATB_Q_CBL_mon,
   169 
   183                                                20 /* G1SATBProcessCompletedThreshold */,
   170   //
   184                                                60 /* G1SATBBufferEnqueueingThresholdPercent */);
   171   // Reserve and commit memory for bitmap(s)
   185 
   172   //
   186   // Reserve space for prev and next bitmap.
   173 
   187   size_t bitmap_page_size = UseLargePages ? (size_t)os::large_page_size() : (size_t)os::vm_page_size();
       
   188   _bitmap_size = MarkBitMap::compute_size(heap_rs.size());
   174   _bitmap_size = MarkBitMap::compute_size(heap_rs.size());
   189   _bitmap_size = align_up(_bitmap_size, bitmap_page_size);
   175   _bitmap_size = align_up(_bitmap_size, bitmap_page_size);
   190   _heap_region = MemRegion((HeapWord*) heap_rs.base(), heap_rs.size() / HeapWordSize);
       
   191 
   176 
   192   size_t bitmap_bytes_per_region = reg_size_bytes / MarkBitMap::heap_map_factor();
   177   size_t bitmap_bytes_per_region = reg_size_bytes / MarkBitMap::heap_map_factor();
   193 
   178 
   194   guarantee(bitmap_bytes_per_region != 0,
   179   guarantee(bitmap_bytes_per_region != 0,
   195             "Bitmap bytes per region should not be zero");
   180             "Bitmap bytes per region should not be zero");
   210 
   195 
   211   guarantee(((_bitmap_bytes_per_slice) % bitmap_page_size) == 0,
   196   guarantee(((_bitmap_bytes_per_slice) % bitmap_page_size) == 0,
   212             "Bitmap slices should be page-granular: bps = " SIZE_FORMAT ", page size = " SIZE_FORMAT,
   197             "Bitmap slices should be page-granular: bps = " SIZE_FORMAT ", page size = " SIZE_FORMAT,
   213             _bitmap_bytes_per_slice, bitmap_page_size);
   198             _bitmap_bytes_per_slice, bitmap_page_size);
   214 
   199 
   215   ReservedSpace bitmap0(_bitmap_size, bitmap_page_size);
   200   ReservedSpace bitmap(_bitmap_size, bitmap_page_size);
   216   MemTracker::record_virtual_memory_type(bitmap0.base(), mtGC);
   201   MemTracker::record_virtual_memory_type(bitmap.base(), mtGC);
   217   _bitmap_region = MemRegion((HeapWord*) bitmap0.base(), bitmap0.size() / HeapWordSize);
   202   _bitmap_region = MemRegion((HeapWord*) bitmap.base(), bitmap.size() / HeapWordSize);
   218 
   203 
   219   size_t bitmap_init_commit = _bitmap_bytes_per_slice *
   204   size_t bitmap_init_commit = _bitmap_bytes_per_slice *
   220                               align_up(num_committed_regions, _bitmap_regions_per_slice) / _bitmap_regions_per_slice;
   205                               align_up(num_committed_regions, _bitmap_regions_per_slice) / _bitmap_regions_per_slice;
   221   bitmap_init_commit = MIN2(_bitmap_size, bitmap_init_commit);
   206   bitmap_init_commit = MIN2(_bitmap_size, bitmap_init_commit);
   222   os::commit_memory_or_exit((char *) (_bitmap_region.start()), bitmap_init_commit, false,
   207   os::commit_memory_or_exit((char *)_bitmap_region.start(), bitmap_init_commit, false,
   223                             "couldn't allocate initial bitmap");
   208                             "Cannot commit bitmap memory");
   224 
   209 
   225   size_t page_size = UseLargePages ? (size_t)os::large_page_size() : (size_t)os::vm_page_size();
   210   _marking_context = new ShenandoahMarkingContext(_heap_region, _bitmap_region, _num_regions);
   226 
   211 
   227   if (ShenandoahVerify) {
   212   if (ShenandoahVerify) {
   228     ReservedSpace verify_bitmap(_bitmap_size, page_size);
   213     ReservedSpace verify_bitmap(_bitmap_size, bitmap_page_size);
   229     os::commit_memory_or_exit(verify_bitmap.base(), verify_bitmap.size(), false,
   214     os::commit_memory_or_exit(verify_bitmap.base(), verify_bitmap.size(), false,
   230                               "couldn't allocate verification bitmap");
   215                               "Cannot commit verification bitmap memory");
   231     MemTracker::record_virtual_memory_type(verify_bitmap.base(), mtGC);
   216     MemTracker::record_virtual_memory_type(verify_bitmap.base(), mtGC);
   232     MemRegion verify_bitmap_region = MemRegion((HeapWord *) verify_bitmap.base(), verify_bitmap.size() / HeapWordSize);
   217     MemRegion verify_bitmap_region = MemRegion((HeapWord *) verify_bitmap.base(), verify_bitmap.size() / HeapWordSize);
   233     _verification_bit_map.initialize(_heap_region, verify_bitmap_region);
   218     _verification_bit_map.initialize(_heap_region, verify_bitmap_region);
   234     _verifier = new ShenandoahVerifier(this, &_verification_bit_map);
   219     _verifier = new ShenandoahVerifier(this, &_verification_bit_map);
   235   }
       
   236 
       
   237   _marking_context = new ShenandoahMarkingContext(_heap_region, _bitmap_region, _num_regions);
       
   238 
       
   239   {
       
   240     ShenandoahHeapLocker locker(lock());
       
   241     for (size_t i = 0; i < _num_regions; i++) {
       
   242       ShenandoahHeapRegion* r = new ShenandoahHeapRegion(this,
       
   243                                                          (HeapWord*) pgc_rs.base() + reg_size_words * i,
       
   244                                                          reg_size_words,
       
   245                                                          i,
       
   246                                                          i < num_committed_regions);
       
   247 
       
   248       _marking_context->initialize_top_at_mark_start(r);
       
   249       _regions[i] = r;
       
   250       assert(!collection_set()->is_in(i), "New region should not be in collection set");
       
   251     }
       
   252 
       
   253     // Initialize to complete
       
   254     _marking_context->mark_complete();
       
   255 
       
   256     _free_set->rebuild();
       
   257   }
       
   258 
       
   259   if (ShenandoahAlwaysPreTouch) {
       
   260     assert (!AlwaysPreTouch, "Should have been overridden");
       
   261 
       
   262     // For NUMA, it is important to pre-touch the storage under bitmaps with worker threads,
       
   263     // before initialize() below zeroes it with initializing thread. For any given region,
       
   264     // we touch the region and the corresponding bitmaps from the same thread.
       
   265     ShenandoahPushWorkerScope scope(workers(), _max_workers, false);
       
   266 
       
   267     log_info(gc, heap)("Parallel pretouch " SIZE_FORMAT " regions with " SIZE_FORMAT " byte pages",
       
   268                        _num_regions, page_size);
       
   269     ShenandoahPretouchTask cl(bitmap0.base(), _bitmap_size, page_size);
       
   270     _workers->run_task(&cl);
       
   271   }
   220   }
   272 
   221 
   273   // Reserve aux bitmap for use in object_iterate(). We don't commit it here.
   222   // Reserve aux bitmap for use in object_iterate(). We don't commit it here.
   274   ReservedSpace aux_bitmap(_bitmap_size, bitmap_page_size);
   223   ReservedSpace aux_bitmap(_bitmap_size, bitmap_page_size);
   275   MemTracker::record_virtual_memory_type(aux_bitmap.base(), mtGC);
   224   MemTracker::record_virtual_memory_type(aux_bitmap.base(), mtGC);
   276   _aux_bitmap_region = MemRegion((HeapWord*) aux_bitmap.base(), aux_bitmap.size() / HeapWordSize);
   225   _aux_bitmap_region = MemRegion((HeapWord*) aux_bitmap.base(), aux_bitmap.size() / HeapWordSize);
   277   _aux_bit_map.initialize(_heap_region, _aux_bitmap_region);
   226   _aux_bit_map.initialize(_heap_region, _aux_bitmap_region);
   278 
   227 
   279   _traversal_gc = heuristics()->can_do_traversal_gc() ?
   228   //
   280                 new ShenandoahTraversalGC(this, _num_regions) :
   229   // Create regions and region sets
   281                 NULL;
   230   //
   282 
   231 
   283   _monitoring_support = new ShenandoahMonitoringSupport(this);
   232   _regions = NEW_C_HEAP_ARRAY(ShenandoahHeapRegion*, _num_regions, mtGC);
   284 
   233   _free_set = new ShenandoahFreeSet(this, _num_regions);
   285   _phase_timings = new ShenandoahPhaseTimings();
   234   _collection_set = new ShenandoahCollectionSet(this, (HeapWord*)sh_rs.base());
   286 
   235 
   287   if (ShenandoahAllocationTrace) {
   236   {
   288     _alloc_tracker = new ShenandoahAllocTracker();
   237     ShenandoahHeapLocker locker(lock());
   289   }
   238 
   290 
   239     size_t size_words = ShenandoahHeapRegion::region_size_words();
   291   ShenandoahStringDedup::initialize();
   240 
   292 
   241     for (size_t i = 0; i < _num_regions; i++) {
   293   _control_thread = new ShenandoahControlThread();
   242       HeapWord* start = (HeapWord*)sh_rs.base() + size_words * i;
   294 
   243       bool is_committed = i < num_committed_regions;
   295   ShenandoahCodeRoots::initialize();
   244       ShenandoahHeapRegion* r = new ShenandoahHeapRegion(this, start, size_words, i, is_committed);
   296 
   245 
   297   log_info(gc, init)("Safepointing mechanism: %s",
   246       _marking_context->initialize_top_at_mark_start(r);
   298                      SafepointMechanism::uses_thread_local_poll() ? "thread-local poll" :
   247       _regions[i] = r;
   299                      (SafepointMechanism::uses_global_page_poll() ? "global-page poll" : "unknown"));
   248       assert(!collection_set()->is_in(i), "New region should not be in collection set");
       
   249     }
       
   250 
       
   251     // Initialize to complete
       
   252     _marking_context->mark_complete();
       
   253 
       
   254     _free_set->rebuild();
       
   255   }
       
   256 
       
   257   if (ShenandoahAlwaysPreTouch) {
       
   258     assert(!AlwaysPreTouch, "Should have been overridden");
       
   259 
       
   260     // For NUMA, it is important to pre-touch the storage under bitmaps with worker threads,
       
   261     // before initialize() below zeroes it with initializing thread. For any given region,
       
   262     // we touch the region and the corresponding bitmaps from the same thread.
       
   263     ShenandoahPushWorkerScope scope(workers(), _max_workers, false);
       
   264 
       
   265     log_info(gc, init)("Pretouch " SIZE_FORMAT " regions; page sizes: " SIZE_FORMAT " heap, " SIZE_FORMAT " bitmap",
       
   266                        _num_regions, heap_page_size, bitmap_page_size);
       
   267     ShenandoahPretouchTask cl(bitmap.base(), _bitmap_size, heap_page_size, bitmap_page_size);
       
   268     _workers->run_task(&cl);
       
   269   }
       
   270 
       
   271   //
       
   272   // Initialize the rest of GC subsystems
       
   273   //
   300 
   274 
   301   _liveness_cache = NEW_C_HEAP_ARRAY(jushort*, _max_workers, mtGC);
   275   _liveness_cache = NEW_C_HEAP_ARRAY(jushort*, _max_workers, mtGC);
   302   for (uint worker = 0; worker < _max_workers; worker++) {
   276   for (uint worker = 0; worker < _max_workers; worker++) {
   303     _liveness_cache[worker] = NEW_C_HEAP_ARRAY(jushort, _num_regions, mtGC);
   277     _liveness_cache[worker] = NEW_C_HEAP_ARRAY(jushort, _num_regions, mtGC);
   304     Copy::fill_to_bytes(_liveness_cache[worker], _num_regions * sizeof(jushort));
   278     Copy::fill_to_bytes(_liveness_cache[worker], _num_regions * sizeof(jushort));
   305   }
   279   }
       
   280 
       
   281   // The call below uses stuff (the SATB* things) that are in G1, but probably
       
   282   // belong into a shared location.
       
   283   ShenandoahBarrierSet::satb_mark_queue_set().initialize(this,
       
   284                                                          SATB_Q_CBL_mon,
       
   285                                                          20 /* G1SATBProcessCompletedThreshold */,
       
   286                                                          60 /* G1SATBBufferEnqueueingThresholdPercent */);
       
   287 
       
   288   _monitoring_support = new ShenandoahMonitoringSupport(this);
       
   289   _phase_timings = new ShenandoahPhaseTimings();
       
   290   ShenandoahStringDedup::initialize();
       
   291   ShenandoahCodeRoots::initialize();
       
   292 
       
   293   if (ShenandoahAllocationTrace) {
       
   294     _alloc_tracker = new ShenandoahAllocTracker();
       
   295   }
       
   296 
       
   297   if (ShenandoahPacing) {
       
   298     _pacer = new ShenandoahPacer(this);
       
   299     _pacer->setup_for_idle();
       
   300   } else {
       
   301     _pacer = NULL;
       
   302   }
       
   303 
       
   304   _traversal_gc = heuristics()->can_do_traversal_gc() ?
       
   305                   new ShenandoahTraversalGC(this, _num_regions) :
       
   306                   NULL;
       
   307 
       
   308   _control_thread = new ShenandoahControlThread();
       
   309 
       
   310   log_info(gc, init)("Initialize Shenandoah heap with initial size " SIZE_FORMAT "%s",
       
   311                      byte_size_in_proper_unit(_initial_size), proper_unit_for_byte_size(_initial_size));
       
   312 
       
   313   log_info(gc, init)("Safepointing mechanism: %s",
       
   314                      SafepointMechanism::uses_thread_local_poll() ? "thread-local poll" :
       
   315                      (SafepointMechanism::uses_global_page_poll() ? "global-page poll" : "unknown"));
   306 
   316 
   307   return JNI_OK;
   317   return JNI_OK;
   308 }
   318 }
   309 
   319 
   310 void ShenandoahHeap::initialize_heuristics() {
   320 void ShenandoahHeap::initialize_heuristics() {
   381   _cycle_memory_manager("Shenandoah Cycles", "end of GC cycle"),
   391   _cycle_memory_manager("Shenandoah Cycles", "end of GC cycle"),
   382   _gc_timer(new (ResourceObj::C_HEAP, mtGC) ConcurrentGCTimer()),
   392   _gc_timer(new (ResourceObj::C_HEAP, mtGC) ConcurrentGCTimer()),
   383   _soft_ref_policy(),
   393   _soft_ref_policy(),
   384   _ref_processor(NULL),
   394   _ref_processor(NULL),
   385   _marking_context(NULL),
   395   _marking_context(NULL),
       
   396   _bitmap_size(0),
       
   397   _bitmap_regions_per_slice(0),
       
   398   _bitmap_bytes_per_slice(0),
       
   399   _liveness_cache(NULL),
   386   _collection_set(NULL)
   400   _collection_set(NULL)
   387 {
   401 {
   388   log_info(gc, init)("GC threads: " UINT32_FORMAT " parallel, " UINT32_FORMAT " concurrent", ParallelGCThreads, ConcGCThreads);
   402   log_info(gc, init)("GC threads: " UINT32_FORMAT " parallel, " UINT32_FORMAT " concurrent", ParallelGCThreads, ConcGCThreads);
   389   log_info(gc, init)("Reference processing: %s", ParallelRefProcEnabled ? "parallel" : "serial");
   403   log_info(gc, init)("Reference processing: %s", ParallelRefProcEnabled ? "parallel" : "serial");
   390 
   404 
  2766   }
  2780   }
  2767 }
  2781 }
  2768 
  2782 
  2769 jushort* ShenandoahHeap::get_liveness_cache(uint worker_id) {
  2783 jushort* ShenandoahHeap::get_liveness_cache(uint worker_id) {
  2770 #ifdef ASSERT
  2784 #ifdef ASSERT
       
  2785   assert(_liveness_cache != NULL, "sanity");
  2771   assert(worker_id < _max_workers, "sanity");
  2786   assert(worker_id < _max_workers, "sanity");
  2772   for (uint i = 0; i < num_regions(); i++) {
  2787   for (uint i = 0; i < num_regions(); i++) {
  2773     assert(_liveness_cache[worker_id][i] == 0, "liveness cache should be empty");
  2788     assert(_liveness_cache[worker_id][i] == 0, "liveness cache should be empty");
  2774   }
  2789   }
  2775 #endif
  2790 #endif
  2776   return _liveness_cache[worker_id];
  2791   return _liveness_cache[worker_id];
  2777 }
  2792 }
  2778 
  2793 
  2779 void ShenandoahHeap::flush_liveness_cache(uint worker_id) {
  2794 void ShenandoahHeap::flush_liveness_cache(uint worker_id) {
  2780   assert(worker_id < _max_workers, "sanity");
  2795   assert(worker_id < _max_workers, "sanity");
       
  2796   assert(_liveness_cache != NULL, "sanity");
  2781   jushort* ld = _liveness_cache[worker_id];
  2797   jushort* ld = _liveness_cache[worker_id];
  2782   for (uint i = 0; i < num_regions(); i++) {
  2798   for (uint i = 0; i < num_regions(); i++) {
  2783     ShenandoahHeapRegion* r = get_region(i);
  2799     ShenandoahHeapRegion* r = get_region(i);
  2784     jushort live = ld[i];
  2800     jushort live = ld[i];
  2785     if (live > 0) {
  2801     if (live > 0) {