< prev index next >

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

Print this page
rev 59333 : 8245240: Shenandoah: support nesting evacuation OOM scope

*** 31,63 **** #include "gc/shenandoah/shenandoahSATBMarkQueueSet.hpp" #include "runtime/thread.hpp" #include "utilities/debug.hpp" #include "utilities/sizes.hpp" class ShenandoahThreadLocalData { public: static const uint INVALID_WORKER_ID = uint(-1); private: char _gc_state; ! char _oom_during_evac; ShenandoahSATBMarkQueue _satb_mark_queue; PLAB* _gclab; size_t _gclab_size; uint _worker_id; bool _force_satb_flush; int _disarmed_value; ShenandoahThreadLocalData() : _gc_state(0), - _oom_during_evac(0), _satb_mark_queue(&ShenandoahBarrierSet::satb_mark_queue_set()), _gclab(NULL), _gclab_size(0), _worker_id(INVALID_WORKER_ID), _force_satb_flush(false), _disarmed_value(0) { // At least on x86_64, nmethod entry barrier encodes _disarmed_value offset // in instruction as disp8 immed assert(in_bytes(disarmed_value_offset()) < 128, "Offset range check"); } --- 31,74 ---- #include "gc/shenandoah/shenandoahSATBMarkQueueSet.hpp" #include "runtime/thread.hpp" #include "utilities/debug.hpp" #include "utilities/sizes.hpp" + /* Highest bit indicates if current thread encountered OOM + * Remaining bits represent evacuation scope nesting level + */ + typedef struct { + uint8_t _nesting_level : 7; + uint8_t _is_evac_oom : 1; + } ShenandoahEvacOOMState; + + STATIC_ASSERT(sizeof(ShenandoahEvacOOMState) == sizeof(char)); + class ShenandoahThreadLocalData { public: static const uint INVALID_WORKER_ID = uint(-1); private: char _gc_state; ! ShenandoahEvacOOMState _oom_during_evac; ShenandoahSATBMarkQueue _satb_mark_queue; PLAB* _gclab; size_t _gclab_size; uint _worker_id; bool _force_satb_flush; int _disarmed_value; ShenandoahThreadLocalData() : _gc_state(0), _satb_mark_queue(&ShenandoahBarrierSet::satb_mark_queue_set()), _gclab(NULL), _gclab_size(0), _worker_id(INVALID_WORKER_ID), _force_satb_flush(false), _disarmed_value(0) { + _oom_during_evac._nesting_level = 0; + _oom_during_evac._is_evac_oom = 0; // At least on x86_64, nmethod entry barrier encodes _disarmed_value offset // in instruction as disp8 immed assert(in_bytes(disarmed_value_offset()) < 128, "Offset range check"); }
*** 88,109 **** static SATBMarkQueue& satb_mark_queue(Thread* thread) { return data(thread)->_satb_mark_queue; } - static bool is_oom_during_evac(Thread* thread) { - return (data(thread)->_oom_during_evac & 1) == 1; - } - - static void set_oom_during_evac(Thread* thread, bool oom) { - if (oom) { - data(thread)->_oom_during_evac |= 1; - } else { - data(thread)->_oom_during_evac &= ~1; - } - } - static void set_gc_state(Thread* thread, char gc_state) { data(thread)->_gc_state = gc_state; } static char gc_state(Thread* thread) { --- 99,108 ----
*** 149,171 **** static void set_disarmed_value(Thread* thread, int value) { data(thread)->_disarmed_value = value; } ! #ifdef ASSERT ! static void set_evac_allowed(Thread* thread, bool evac_allowed) { ! if (evac_allowed) { ! data(thread)->_oom_during_evac |= 2; } else { ! data(thread)->_oom_during_evac &= ~2; } } static bool is_evac_allowed(Thread* thread) { ! return (data(thread)->_oom_during_evac & 2) == 2; } - #endif // Offsets static ByteSize satb_mark_queue_active_offset() { return satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active(); } --- 148,193 ---- static void set_disarmed_value(Thread* thread, int value) { data(thread)->_disarmed_value = value; } ! // Evacuation OOM handling ! static bool is_oom_during_evac(Thread* thread) { ! return data(thread)->_oom_during_evac._is_evac_oom == 1; ! } ! ! static void set_oom_during_evac(Thread* thread, bool oom) { ! if (oom) { ! data(thread)->_oom_during_evac._is_evac_oom = 1; } else { ! data(thread)->_oom_during_evac._is_evac_oom = 0; ! } } + + static uint8_t evac_oom_scope_level(Thread* thread) { + return data(thread)->_oom_during_evac._nesting_level; + } + + // Push the scope one level deeper, return previous level + static uint8_t push_evac_oom_scope(Thread* thread) { + uint8_t level = evac_oom_scope_level(thread); + assert(level < 127, "Overflow nesting level"); + data(thread)->_oom_during_evac._nesting_level = level + 1; + return level; + } + + // Pop the scope by one level, return previous level + static uint8_t pop_evac_oom_scope(Thread* thread) { + uint8_t level = evac_oom_scope_level(thread); + assert(level > 0, "Underflow nesting level"); + data(thread)->_oom_during_evac._nesting_level = level - 1; + return level; } static bool is_evac_allowed(Thread* thread) { ! return evac_oom_scope_level(thread) > 0; } // Offsets static ByteSize satb_mark_queue_active_offset() { return satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active(); }
< prev index next >