changeset 60822:9e3539baac38

8242365: Shenandoah: use uint16_t instead of jushort for liveness cache Reviewed-by: rkennke
author shade
date Wed, 08 Apr 2020 13:44:58 +0200
parents f275c9540215
children 13e20575efe1
files src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.hpp src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
diffstat 5 files changed, 28 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp	Wed Apr 08 13:44:57 2020 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp	Wed Apr 08 13:44:58 2020 +0200
@@ -817,7 +817,7 @@
                                                  bool strdedup) {
   ShenandoahObjToScanQueue* q = get_queue(w);
 
-  jushort* ld = _heap->get_liveness_cache(w);
+  ShenandoahLiveData* ld = _heap->get_liveness_cache(w);
 
   // TODO: We can clean up this if we figure out how to do templated oop closures that
   // play nice with specialized_oop_iterators.
@@ -863,7 +863,7 @@
 }
 
 template <class T, bool CANCELLABLE>
-void ShenandoahConcurrentMark::mark_loop_work(T* cl, jushort* live_data, uint worker_id, TaskTerminator *terminator) {
+void ShenandoahConcurrentMark::mark_loop_work(T* cl, ShenandoahLiveData* live_data, uint worker_id, TaskTerminator *terminator) {
   uintx stride = ShenandoahMarkLoopStride;
 
   ShenandoahHeap* heap = ShenandoahHeap::heap();
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.hpp	Wed Apr 08 13:44:57 2020 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.hpp	Wed Apr 08 13:44:58 2020 +0200
@@ -46,7 +46,7 @@
 //
 private:
   template <class T>
-  inline void do_task(ShenandoahObjToScanQueue* q, T* cl, jushort* live_data, ShenandoahMarkTask* task);
+  inline void do_task(ShenandoahObjToScanQueue* q, T* cl, ShenandoahLiveData* live_data, ShenandoahMarkTask* task);
 
   template <class T>
   inline void do_chunked_array_start(ShenandoahObjToScanQueue* q, T* cl, oop array);
@@ -54,10 +54,10 @@
   template <class T>
   inline void do_chunked_array(ShenandoahObjToScanQueue* q, T* cl, oop array, int chunk, int pow);
 
-  inline void count_liveness(jushort* live_data, oop obj);
+  inline void count_liveness(ShenandoahLiveData* live_data, oop obj);
 
   template <class T, bool CANCELLABLE>
-  void mark_loop_work(T* cl, jushort* live_data, uint worker_id, TaskTerminator *t);
+  void mark_loop_work(T* cl, ShenandoahLiveData* live_data, uint worker_id, TaskTerminator *t);
 
   template <bool CANCELLABLE>
   void mark_loop_prework(uint worker_id, TaskTerminator *terminator, ReferenceProcessor *rp, bool strdedup);
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp	Wed Apr 08 13:44:57 2020 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp	Wed Apr 08 13:44:58 2020 +0200
@@ -37,7 +37,7 @@
 #include "runtime/prefetch.inline.hpp"
 
 template <class T>
-void ShenandoahConcurrentMark::do_task(ShenandoahObjToScanQueue* q, T* cl, jushort* live_data, ShenandoahMarkTask* task) {
+void ShenandoahConcurrentMark::do_task(ShenandoahObjToScanQueue* q, T* cl, ShenandoahLiveData* live_data, ShenandoahMarkTask* task) {
   oop obj = task->obj();
 
   shenandoah_assert_not_forwarded(NULL, obj);
@@ -67,23 +67,22 @@
   }
 }
 
-inline void ShenandoahConcurrentMark::count_liveness(jushort* live_data, oop obj) {
+inline void ShenandoahConcurrentMark::count_liveness(ShenandoahLiveData* live_data, oop obj) {
   size_t region_idx = _heap->heap_region_index_containing(obj);
   ShenandoahHeapRegion* region = _heap->get_region(region_idx);
   size_t size = obj->size();
 
   if (!region->is_humongous_start()) {
     assert(!region->is_humongous(), "Cannot have continuations here");
-    size_t max = (1 << (sizeof(jushort) * 8)) - 1;
-    jushort cur = live_data[region_idx];
+    ShenandoahLiveData cur = live_data[region_idx];
     size_t new_val = size + cur;
-    if (new_val >= max) {
+    if (new_val >= SHENANDOAH_LIVEDATA_MAX) {
       // overflow, flush to region data
       region->increase_live_data_gc_words(new_val);
       live_data[region_idx] = 0;
     } else {
       // still good, remember in locals
-      live_data[region_idx] = (jushort) new_val;
+      live_data[region_idx] = (ShenandoahLiveData) new_val;
     }
   } else {
     shenandoah_assert_in_correct_region(NULL, obj);
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Wed Apr 08 13:44:57 2020 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Wed Apr 08 13:44:58 2020 +0200
@@ -357,10 +357,10 @@
   // Initialize the rest of GC subsystems
   //
 
-  _liveness_cache = NEW_C_HEAP_ARRAY(jushort*, _max_workers, mtGC);
+  _liveness_cache = NEW_C_HEAP_ARRAY(ShenandoahLiveData*, _max_workers, mtGC);
   for (uint worker = 0; worker < _max_workers; worker++) {
-    _liveness_cache[worker] = NEW_C_HEAP_ARRAY(jushort, _num_regions, mtGC);
-    Copy::fill_to_bytes(_liveness_cache[worker], _num_regions * sizeof(jushort));
+    _liveness_cache[worker] = NEW_C_HEAP_ARRAY(ShenandoahLiveData, _num_regions, mtGC);
+    Copy::fill_to_bytes(_liveness_cache[worker], _num_regions * sizeof(ShenandoahLiveData));
   }
 
   // There should probably be Shenandoah-specific options for these,
@@ -3008,7 +3008,7 @@
   }
 }
 
-jushort* ShenandoahHeap::get_liveness_cache(uint worker_id) {
+ShenandoahLiveData* ShenandoahHeap::get_liveness_cache(uint worker_id) {
 #ifdef ASSERT
   assert(_liveness_cache != NULL, "sanity");
   assert(worker_id < _max_workers, "sanity");
@@ -3022,9 +3022,9 @@
 void ShenandoahHeap::flush_liveness_cache(uint worker_id) {
   assert(worker_id < _max_workers, "sanity");
   assert(_liveness_cache != NULL, "sanity");
-  jushort* ld = _liveness_cache[worker_id];
+  ShenandoahLiveData* ld = _liveness_cache[worker_id];
   for (uint i = 0; i < num_regions(); i++) {
-    jushort live = ld[i];
+    ShenandoahLiveData live = ld[i];
     if (live > 0) {
       ShenandoahHeapRegion* r = get_region(i);
       r->increase_live_data_gc_words(live);
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp	Wed Apr 08 13:44:57 2020 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp	Wed Apr 08 13:44:58 2020 +0200
@@ -62,6 +62,16 @@
 class ShenandoahWorkGang;
 class VMStructs;
 
+// Used for buffering per-region liveness data.
+// Needed since ShenandoahHeapRegion uses atomics to update liveness.
+// The ShenandoahHeap array has max-workers elements, each of which is an array of
+// uint16_t * max_regions. The choice of uint16_t is not accidental:
+// there is a tradeoff between static/dynamic footprint that translates
+// into cache pressure (which is already high during marking), and
+// too many atomic updates. uint32_t is too large, uint8_t is too small.
+typedef uint16_t ShenandoahLiveData;
+#define SHENANDOAH_LIVEDATA_MAX ((ShenandoahLiveData)-1)
+
 class ShenandoahRegionIterator : public StackObj {
 private:
   ShenandoahHeap* _heap;
@@ -613,15 +623,7 @@
   bool _bitmap_region_special;
   bool _aux_bitmap_region_special;
 
-  // Used for buffering per-region liveness data.
-  // Needed since ShenandoahHeapRegion uses atomics to update liveness.
-  //
-  // The array has max-workers elements, each of which is an array of
-  // jushort * max_regions. The choice of jushort is not accidental:
-  // there is a tradeoff between static/dynamic footprint that translates
-  // into cache pressure (which is already high during marking), and
-  // too many atomic updates. size_t/jint is too large, jbyte is too small.
-  jushort** _liveness_cache;
+  ShenandoahLiveData** _liveness_cache;
 
 public:
   inline ShenandoahMarkingContext* complete_marking_context() const;
@@ -651,7 +653,7 @@
   bool is_bitmap_slice_committed(ShenandoahHeapRegion* r, bool skip_self = false);
 
   // Liveness caching support
-  jushort* get_liveness_cache(uint worker_id);
+  ShenandoahLiveData* get_liveness_cache(uint worker_id);
   void flush_liveness_cache(uint worker_id);
 
 // ---------- Evacuation support