< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp

Print this page
@@ -42,12 +42,38 @@
  #include "utilities/debug.hpp"
  #include "utilities/sizes.hpp"
  
  class ShenandoahThreadLocalData {
  private:
+   // Thread-local mirror for global GC state
    char _gc_state;
  
+   // Quickened version of GC state.
+   // This allows all architectures to quickly check the group of states by using a single byte load.
+   enum FastGCState {
+     FORWARDED               = ShenandoahHeap::HAS_FORWARDED,
+     MARKING                 = ShenandoahHeap::MARKING,
+     WEAK                    = ShenandoahHeap::WEAK_ROOTS,
+     FORWARDED_MARKING       = ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::MARKING,
+     FORWARDED_WEAK          = ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::WEAK_ROOTS,
+     MARKING_WEAK            = ShenandoahHeap::MARKING       | ShenandoahHeap::WEAK_ROOTS,
+     FORWARDED_MARKING_WEAK  = ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::MARKING    | ShenandoahHeap::WEAK_ROOTS
+   };
+ 
+   enum FastGCStatePos {
+     POS_FORWARDED               = 0,
+     POS_MARKING                 = 1,
+     POS_WEAK                    = 2,
+     POS_FORWARDED_MARKING       = 3,
+     POS_FORWARDED_WEAK          = 4,
+     POS_MARKING_WEAK            = 5,
+     POS_FORWARDED_MARKING_WEAK  = 6,
+     POS_MAX
+   };
+ 
+   char _gc_state_fast_array[POS_MAX];
+ 
    SATBMarkQueue           _satb_mark_queue;
  
    // Current active CardTable's byte_map_base for this thread.
    CardTable::CardValue*   _card_table;
  

@@ -90,12 +116,32 @@
  
    static SATBMarkQueue& satb_mark_queue(Thread* thread) {
      return data(thread)->_satb_mark_queue;
    }
  
+   static char gc_state_to_fast_array_index(char gc_state) {
+     if (gc_state == FORWARDED)              return POS_FORWARDED;
+     if (gc_state == MARKING)                return POS_MARKING;
+     if (gc_state == WEAK)                   return POS_WEAK;
+     if (gc_state == FORWARDED_MARKING)      return POS_FORWARDED_MARKING;
+     if (gc_state == FORWARDED_WEAK)         return POS_FORWARDED_WEAK;
+     if (gc_state == MARKING_WEAK)           return POS_MARKING_WEAK;
+     if (gc_state == FORWARDED_MARKING_WEAK) return POS_FORWARDED_MARKING_WEAK;
+     ShouldNotReachHere();
+     return 0;
+   }
+ 
    static void set_gc_state(Thread* thread, char gc_state) {
-     data(thread)->_gc_state = gc_state;
+     ShenandoahThreadLocalData* d = data(thread);
+     d->_gc_state = gc_state;
+     d->_gc_state_fast_array[POS_FORWARDED]              = (gc_state & FORWARDED) > 0;
+     d->_gc_state_fast_array[POS_MARKING]                = (gc_state & MARKING) > 0;
+     d->_gc_state_fast_array[POS_WEAK]                   = (gc_state & WEAK) > 0;
+     d->_gc_state_fast_array[POS_FORWARDED_MARKING]      = (gc_state & FORWARDED_MARKING) > 0;
+     d->_gc_state_fast_array[POS_FORWARDED_WEAK]         = (gc_state & FORWARDED_WEAK) > 0;
+     d->_gc_state_fast_array[POS_MARKING_WEAK]           = (gc_state & MARKING_WEAK) > 0;
+     d->_gc_state_fast_array[POS_FORWARDED_MARKING_WEAK] = (gc_state & FORWARDED_MARKING_WEAK) > 0;
    }
  
    static char gc_state(Thread* thread) {
      return data(thread)->_gc_state;
    }

@@ -168,10 +214,14 @@
  
    static ByteSize gc_state_offset() {
      return Thread::gc_data_offset() + byte_offset_of(ShenandoahThreadLocalData, _gc_state);
    }
  
+   static ByteSize gc_state_fast_array_offset(char gc_state) {
+     return Thread::gc_data_offset() + byte_offset_of(ShenandoahThreadLocalData, _gc_state_fast_array) + in_ByteSize(gc_state_to_fast_array_index(gc_state));
+   }
+ 
    static ByteSize card_table_offset() {
      return Thread::gc_data_offset() + byte_offset_of(ShenandoahThreadLocalData, _card_table);
    }
  
    // invisible root are the partially initialized obj array set by ShenandoahObjArrayAllocator
< prev index next >