24
25 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHTHREADLOCALDATA_HPP
26 #define SHARE_GC_SHENANDOAH_SHENANDOAHTHREADLOCALDATA_HPP
27
28 #include "gc/shared/plab.hpp"
29 #include "gc/shared/gcThreadLocalData.hpp"
30 #include "gc/shared/gc_globals.hpp"
31 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
32 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
33 #include "gc/shenandoah/shenandoahSATBMarkQueueSet.hpp"
34 #include "runtime/thread.hpp"
35 #include "utilities/debug.hpp"
36 #include "utilities/sizes.hpp"
37
38 class ShenandoahThreadLocalData {
39 private:
40 char _gc_state;
41 // Evacuation OOM state
42 uint8_t _oom_scope_nesting_level;
43 bool _oom_during_evac;
44 SATBMarkQueue _satb_mark_queue;
45 PLAB* _gclab;
46 size_t _gclab_size;
47 int _disarmed_value;
48 double _paced_time;
49
50 ShenandoahThreadLocalData() :
51 _gc_state(0),
52 _oom_scope_nesting_level(0),
53 _oom_during_evac(false),
54 _satb_mark_queue(&ShenandoahBarrierSet::satb_mark_queue_set()),
55 _gclab(NULL),
56 _gclab_size(0),
57 _disarmed_value(0),
58 _paced_time(0) {
59
60 // At least on x86_64, nmethod entry barrier encodes _disarmed_value offset
61 // in instruction as disp8 immed
62 assert(in_bytes(disarmed_value_offset()) < 128, "Offset range check");
63 }
64
65 ~ShenandoahThreadLocalData() {
66 if (_gclab != NULL) {
67 delete _gclab;
68 }
69 }
70
71 static ShenandoahThreadLocalData* data(Thread* thread) {
72 assert(UseShenandoahGC, "Sanity");
73 return thread->gc_data<ShenandoahThreadLocalData>();
74 }
75
76 static ByteSize satb_mark_queue_offset() {
77 return Thread::gc_data_offset() + byte_offset_of(ShenandoahThreadLocalData, _satb_mark_queue);
78 }
79
80 public:
81 static void create(Thread* thread) {
82 new (data(thread)) ShenandoahThreadLocalData();
83 }
84
85 static void destroy(Thread* thread) {
86 data(thread)->~ShenandoahThreadLocalData();
87 }
88
89 static SATBMarkQueue& satb_mark_queue(Thread* thread) {
90 return data(thread)->_satb_mark_queue;
91 }
92
93 static void set_gc_state(Thread* thread, char gc_state) {
94 data(thread)->_gc_state = gc_state;
95 }
96
97 static char gc_state(Thread* thread) {
98 return data(thread)->_gc_state;
99 }
100
101 static void initialize_gclab(Thread* thread) {
102 assert (thread->is_Java_thread() || thread->is_Worker_thread(), "Only Java and GC worker threads are allowed to get GCLABs");
103 assert(data(thread)->_gclab == NULL, "Only initialize once");
104 data(thread)->_gclab = new PLAB(PLAB::min_size());
105 data(thread)->_gclab_size = 0;
106 }
107
108 static PLAB* gclab(Thread* thread) {
109 return data(thread)->_gclab;
110 }
111
112 static size_t gclab_size(Thread* thread) {
113 return data(thread)->_gclab_size;
114 }
115
116 static void set_gclab_size(Thread* thread, size_t v) {
117 data(thread)->_gclab_size = v;
118 }
119
120 static void add_paced_time(Thread* thread, double v) {
121 data(thread)->_paced_time += v;
122 }
123
124 static double paced_time(Thread* thread) {
125 return data(thread)->_paced_time;
126 }
127
128 static void reset_paced_time(Thread* thread) {
129 data(thread)->_paced_time = 0;
130 }
131
132 static void set_disarmed_value(Thread* thread, int value) {
133 data(thread)->_disarmed_value = value;
134 }
135
136 // Evacuation OOM handling
137 static bool is_oom_during_evac(Thread* thread) {
138 return data(thread)->_oom_during_evac;
139 }
|
24
25 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHTHREADLOCALDATA_HPP
26 #define SHARE_GC_SHENANDOAH_SHENANDOAHTHREADLOCALDATA_HPP
27
28 #include "gc/shared/plab.hpp"
29 #include "gc/shared/gcThreadLocalData.hpp"
30 #include "gc/shared/gc_globals.hpp"
31 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
32 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
33 #include "gc/shenandoah/shenandoahSATBMarkQueueSet.hpp"
34 #include "runtime/thread.hpp"
35 #include "utilities/debug.hpp"
36 #include "utilities/sizes.hpp"
37
38 class ShenandoahThreadLocalData {
39 private:
40 char _gc_state;
41 // Evacuation OOM state
42 uint8_t _oom_scope_nesting_level;
43 bool _oom_during_evac;
44 bool _plab_allows_promotion; // If false, no more promotion by this thread during this evacuation phase.
45 SATBMarkQueue _satb_mark_queue;
46
47 // Thread-local allocation buffer for object evacuations.
48 // In generational mode, it is exclusive to the young generation.
49 PLAB* _gclab;
50 size_t _gclab_size;
51
52 // Thread-local allocation buffer only used in generational mode.
53 // Used both by mutator threads and by GC worker threads
54 // for evacuations within the old generation and
55 // for promotions from the young generation into the old generation.
56 PLAB* _plab;
57 size_t _plab_size;
58
59 size_t _plab_evacuated;
60 size_t _plab_promoted;
61
62 uint _worker_id;
63 int _disarmed_value;
64 double _paced_time;
65
66 ShenandoahThreadLocalData() :
67 _gc_state(0),
68 _oom_scope_nesting_level(0),
69 _oom_during_evac(false),
70 _satb_mark_queue(&ShenandoahBarrierSet::satb_mark_queue_set()),
71 _gclab(NULL),
72 _gclab_size(0),
73 _plab(NULL),
74 _plab_size(0),
75 _plab_evacuated(0),
76 _plab_promoted(0),
77 _disarmed_value(0),
78 _paced_time(0) {
79
80 // At least on x86_64, nmethod entry barrier encodes _disarmed_value offset
81 // in instruction as disp8 immed
82 assert(in_bytes(disarmed_value_offset()) < 128, "Offset range check");
83 }
84
85 ~ShenandoahThreadLocalData() {
86 if (_gclab != NULL) {
87 delete _gclab;
88 }
89 if (_plab != NULL) {
90 ShenandoahHeap::heap()->retire_plab(_plab);
91 delete _plab;
92 }
93 }
94
95 static ShenandoahThreadLocalData* data(Thread* thread) {
96 assert(UseShenandoahGC, "Sanity");
97 return thread->gc_data<ShenandoahThreadLocalData>();
98 }
99
100 static ByteSize satb_mark_queue_offset() {
101 return Thread::gc_data_offset() + byte_offset_of(ShenandoahThreadLocalData, _satb_mark_queue);
102 }
103
104 public:
105 static void create(Thread* thread) {
106 new (data(thread)) ShenandoahThreadLocalData();
107 }
108
109 static void destroy(Thread* thread) {
110 data(thread)->~ShenandoahThreadLocalData();
111 }
112
113 static SATBMarkQueue& satb_mark_queue(Thread* thread) {
114 return data(thread)->_satb_mark_queue;
115 }
116
117 static void set_gc_state(Thread* thread, char gc_state) {
118 data(thread)->_gc_state = gc_state;
119 }
120
121 static char gc_state(Thread* thread) {
122 return data(thread)->_gc_state;
123 }
124
125 static void initialize_gclab(Thread* thread) {
126 assert (thread->is_Java_thread() || thread->is_Worker_thread(), "Only Java and GC worker threads are allowed to get GCLABs");
127 assert(data(thread)->_gclab == NULL, "Only initialize once");
128 data(thread)->_gclab = new PLAB(PLAB::min_size());
129 data(thread)->_gclab_size = 0;
130 data(thread)->_plab = new PLAB(PLAB::min_size());
131 data(thread)->_plab_size = 0;
132 }
133
134 static PLAB* gclab(Thread* thread) {
135 return data(thread)->_gclab;
136 }
137
138 static size_t gclab_size(Thread* thread) {
139 return data(thread)->_gclab_size;
140 }
141
142 static void set_gclab_size(Thread* thread, size_t v) {
143 data(thread)->_gclab_size = v;
144 }
145
146 static PLAB* plab(Thread* thread) {
147 return data(thread)->_plab;
148 }
149
150 static size_t plab_size(Thread* thread) {
151 return data(thread)->_plab_size;
152 }
153
154 static void set_plab_size(Thread* thread, size_t v) {
155 data(thread)->_plab_size = v;
156 }
157
158 static void enable_plab_promotions(Thread* thread) {
159 data(thread)->_plab_allows_promotion = true;
160 }
161
162 static void disable_plab_promotions(Thread* thread) {
163 data(thread)->_plab_allows_promotion = false;
164 }
165
166 static bool allow_plab_promotions(Thread* thread) {
167 return data(thread)->_plab_allows_promotion;
168 }
169
170 static void reset_plab_evacuated(Thread* thread) {
171 data(thread)->_plab_evacuated = 0;
172 }
173
174 static void add_to_plab_evacuated(Thread* thread, size_t increment) {
175 data(thread)->_plab_evacuated += increment;
176 }
177
178 static void subtract_from_plab_evacuated(Thread* thread, size_t increment) {
179 data(thread)->_plab_evacuated -= increment;
180 }
181
182 static size_t get_plab_evacuated(Thread* thread) {
183 return data(thread)->_plab_evacuated;
184 }
185
186 static void reset_plab_promoted(Thread* thread) {
187 data(thread)->_plab_promoted = 0;
188 }
189
190 static void add_to_plab_promoted(Thread* thread, size_t increment) {
191 data(thread)->_plab_promoted += increment;
192 }
193
194 static void subtract_from_plab_promoted(Thread* thread, size_t increment) {
195 data(thread)->_plab_promoted -= increment;
196 }
197
198 static size_t get_plab_promoted(Thread* thread) {
199 return data(thread)->_plab_promoted;
200 }
201
202 static void add_paced_time(Thread* thread, double v) {
203 data(thread)->_paced_time += v;
204 }
205
206 static double paced_time(Thread* thread) {
207 return data(thread)->_paced_time;
208 }
209
210 static void reset_paced_time(Thread* thread) {
211 data(thread)->_paced_time = 0;
212 }
213
214 static void set_disarmed_value(Thread* thread, int value) {
215 data(thread)->_disarmed_value = value;
216 }
217
218 // Evacuation OOM handling
219 static bool is_oom_during_evac(Thread* thread) {
220 return data(thread)->_oom_during_evac;
221 }
|