< 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 >