12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/shared/genCollectedHeap.hpp"
27 #include "gc/shared/threadLocalAllocBuffer.inline.hpp"
28 #include "logging/log.hpp"
29 #include "memory/resourceArea.hpp"
30 #include "memory/universe.inline.hpp"
31 #include "oops/oop.inline.hpp"
32 #include "runtime/thread.inline.hpp"
33 #include "runtime/threadSMR.hpp"
34 #include "utilities/copy.hpp"
35
36 // Thread-Local Edens support
37
38 // static member initialization
39 size_t ThreadLocalAllocBuffer::_max_size = 0;
40 int ThreadLocalAllocBuffer::_reserve_for_allocation_prefetch = 0;
41 unsigned ThreadLocalAllocBuffer::_target_refills = 0;
42 GlobalTLABStats* ThreadLocalAllocBuffer::_global_stats = NULL;
43
44 void ThreadLocalAllocBuffer::clear_before_allocation() {
45 _slow_refill_waste += (unsigned)remaining();
46 make_parsable(true); // also retire the TLAB
47 }
48
49 void ThreadLocalAllocBuffer::accumulate_statistics_before_gc() {
50 global_stats()->initialize();
51
52 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
53 thread->tlab().accumulate_statistics();
54 thread->tlab().initialize_statistics();
55 }
56
57 // Publish new stats if some allocation occurred.
58 if (global_stats()->allocation() != 0) {
59 global_stats()->publish();
60 global_stats()->print();
61 }
62 }
63
64 void ThreadLocalAllocBuffer::accumulate_statistics() {
65 Thread* thread = myThread();
66 size_t capacity = Universe::heap()->tlab_capacity(thread);
67 size_t used = Universe::heap()->tlab_used(thread);
68
91 global_stats()->update_allocating_threads();
92 global_stats()->update_number_of_refills(_number_of_refills);
93 global_stats()->update_allocation(_number_of_refills * desired_size());
94 global_stats()->update_gc_waste(_gc_waste);
95 global_stats()->update_slow_refill_waste(_slow_refill_waste);
96 global_stats()->update_fast_refill_waste(_fast_refill_waste);
97
98 } else {
99 assert(_number_of_refills == 0 && _fast_refill_waste == 0 &&
100 _slow_refill_waste == 0 && _gc_waste == 0,
101 "tlab stats == 0");
102 }
103 global_stats()->update_slow_allocations(_slow_allocations);
104 }
105
106 // Fills the current tlab with a dummy filler array to create
107 // an illusion of a contiguous Eden and optionally retires the tlab.
108 // Waste accounting should be done in caller as appropriate; see,
109 // for example, clear_before_allocation().
110 void ThreadLocalAllocBuffer::make_parsable(bool retire, bool zap) {
111 if (end() != NULL) {
112 invariants();
113
114 if (retire) {
115 myThread()->incr_allocated_bytes(used_bytes());
116 }
117
118 CollectedHeap::fill_with_object(top(), hard_end(), retire && zap);
119
120 if (retire || ZeroTLAB) { // "Reset" the TLAB
121 set_start(NULL);
122 set_top(NULL);
123 set_pf_top(NULL);
124 set_end(NULL);
125 }
126 }
127 assert(!(retire || ZeroTLAB) ||
128 (start() == NULL && end() == NULL && top() == NULL),
129 "TLAB must be reset");
130 }
131
132 void ThreadLocalAllocBuffer::resize_all_tlabs() {
133 if (ResizeTLAB) {
134 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
135 thread->tlab().resize();
136 }
137 }
138 }
139
140 void ThreadLocalAllocBuffer::resize() {
141 // Compute the next tlab size using expected allocation amount
142 assert(ResizeTLAB, "Should not call this otherwise");
143 size_t alloc = (size_t)(_allocation_fraction.average() *
144 (Universe::heap()->tlab_capacity(myThread()) / HeapWordSize));
145 size_t new_size = alloc / _target_refills;
146
147 new_size = MIN2(MAX2(new_size, min_size()), max_size());
148
154 _target_refills, _allocation_fraction.average(), desired_size(), aligned_new_size);
155
156 set_desired_size(aligned_new_size);
157 set_refill_waste_limit(initial_refill_waste_limit());
158 }
159
160 void ThreadLocalAllocBuffer::initialize_statistics() {
161 _number_of_refills = 0;
162 _fast_refill_waste = 0;
163 _slow_refill_waste = 0;
164 _gc_waste = 0;
165 _slow_allocations = 0;
166 }
167
168 void ThreadLocalAllocBuffer::fill(HeapWord* start,
169 HeapWord* top,
170 size_t new_size) {
171 _number_of_refills++;
172 print_stats("fill");
173 assert(top <= start + new_size - alignment_reserve(), "size too small");
174 initialize(start, top, start + new_size - alignment_reserve());
175
176 // Reset amount of internal fragmentation
177 set_refill_waste_limit(initial_refill_waste_limit());
178 }
179
180 void ThreadLocalAllocBuffer::initialize(HeapWord* start,
181 HeapWord* top,
182 HeapWord* end) {
183 set_start(start);
184 set_top(top);
185 set_pf_top(top);
186 set_end(end);
187 invariants();
188 }
189
190 void ThreadLocalAllocBuffer::initialize() {
191 initialize(NULL, // start
192 NULL, // top
193 NULL); // end
194
195 set_desired_size(initial_desired_size());
196
197 // Following check is needed because at startup the main
198 // thread is initialized before the heap is. The initialization for
199 // this thread is redone in startup_initialization below.
200 if (Universe::heap() != NULL) {
201 size_t capacity = Universe::heap()->tlab_capacity(myThread()) / HeapWordSize;
202 double alloc_frac = desired_size() * target_refills() / (double) capacity;
203 _allocation_fraction.sample(alloc_frac);
204 }
205
206 set_refill_waste_limit(initial_refill_waste_limit());
207
289 _allocation_fraction.average(),
290 _allocation_fraction.average() * tlab_used / K,
291 _number_of_refills, waste_percent,
292 _gc_waste * HeapWordSize,
293 _slow_refill_waste * HeapWordSize,
294 _fast_refill_waste * HeapWordSize);
295 }
296
297 void ThreadLocalAllocBuffer::verify() {
298 HeapWord* p = start();
299 HeapWord* t = top();
300 HeapWord* prev_p = NULL;
301 while (p < t) {
302 oop(p)->verify();
303 prev_p = p;
304 p += oop(p)->size();
305 }
306 guarantee(p == top(), "end of last object must match end of space");
307 }
308
309 Thread* ThreadLocalAllocBuffer::myThread() {
310 return (Thread*)(((char *)this) +
311 in_bytes(start_offset()) -
312 in_bytes(Thread::tlab_start_offset()));
313 }
314
315
316 GlobalTLABStats::GlobalTLABStats() :
317 _allocating_threads_avg(TLABAllocationWeight) {
318
319 initialize();
320
321 _allocating_threads_avg.sample(1); // One allocating thread at startup
322
323 if (UsePerfData) {
324
325 EXCEPTION_MARK;
326 ResourceMark rm;
327
328 char* cname = PerfDataManager::counter_name("tlab", "allocThreads");
329 _perf_allocating_threads =
330 PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_None, CHECK);
331
332 cname = PerfDataManager::counter_name("tlab", "fills");
333 _perf_total_refills =
334 PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_None, CHECK);
|
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/shared/genCollectedHeap.hpp"
27 #include "gc/shared/threadLocalAllocBuffer.inline.hpp"
28 #include "logging/log.hpp"
29 #include "memory/resourceArea.hpp"
30 #include "memory/universe.inline.hpp"
31 #include "oops/oop.inline.hpp"
32 #include "runtime/heapMonitoring.hpp"
33 #include "runtime/thread.inline.hpp"
34 #include "runtime/threadSMR.hpp"
35 #include "utilities/copy.hpp"
36
37 // Thread-Local Edens support
38
39 // static member initialization
40 size_t ThreadLocalAllocBuffer::_max_size = 0;
41 int ThreadLocalAllocBuffer::_reserve_for_allocation_prefetch = 0;
42 unsigned ThreadLocalAllocBuffer::_target_refills = 0;
43 GlobalTLABStats* ThreadLocalAllocBuffer::_global_stats = NULL;
44
45 void ThreadLocalAllocBuffer::clear_before_allocation() {
46 _slow_refill_waste += (unsigned)remaining();
47 make_parsable(true); // also retire the TLAB
48 }
49
50 size_t ThreadLocalAllocBuffer::remaining() {
51 if (current_end() == NULL) {
52 return 0;
53 }
54
55 // TODO: To be deprecated when FastTLABRefill is deprecated.
56 update_end_pointers();
57 return pointer_delta(reserved_end(), top());
58 }
59
60 void ThreadLocalAllocBuffer::accumulate_statistics_before_gc() {
61 global_stats()->initialize();
62
63 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
64 thread->tlab().accumulate_statistics();
65 thread->tlab().initialize_statistics();
66 }
67
68 // Publish new stats if some allocation occurred.
69 if (global_stats()->allocation() != 0) {
70 global_stats()->publish();
71 global_stats()->print();
72 }
73 }
74
75 void ThreadLocalAllocBuffer::accumulate_statistics() {
76 Thread* thread = myThread();
77 size_t capacity = Universe::heap()->tlab_capacity(thread);
78 size_t used = Universe::heap()->tlab_used(thread);
79
102 global_stats()->update_allocating_threads();
103 global_stats()->update_number_of_refills(_number_of_refills);
104 global_stats()->update_allocation(_number_of_refills * desired_size());
105 global_stats()->update_gc_waste(_gc_waste);
106 global_stats()->update_slow_refill_waste(_slow_refill_waste);
107 global_stats()->update_fast_refill_waste(_fast_refill_waste);
108
109 } else {
110 assert(_number_of_refills == 0 && _fast_refill_waste == 0 &&
111 _slow_refill_waste == 0 && _gc_waste == 0,
112 "tlab stats == 0");
113 }
114 global_stats()->update_slow_allocations(_slow_allocations);
115 }
116
117 // Fills the current tlab with a dummy filler array to create
118 // an illusion of a contiguous Eden and optionally retires the tlab.
119 // Waste accounting should be done in caller as appropriate; see,
120 // for example, clear_before_allocation().
121 void ThreadLocalAllocBuffer::make_parsable(bool retire, bool zap) {
122 if (current_end() != NULL) {
123 invariants();
124
125 if (retire) {
126 myThread()->incr_allocated_bytes(used_bytes());
127 }
128
129 // TODO: To be deprecated when FastTLABRefill is deprecated.
130 update_end_pointers();
131 CollectedHeap::fill_with_object(top(), reserved_end(), retire && zap);
132
133 if (retire || ZeroTLAB) { // "Reset" the TLAB
134 set_start(NULL);
135 set_top(NULL);
136 set_pf_top(NULL);
137 set_current_end(NULL);
138 set_allocation_end(NULL);
139 set_last_slow_path_end(NULL);
140 }
141 }
142 assert(!(retire || ZeroTLAB) ||
143 (start() == NULL && current_end() == NULL && top() == NULL &&
144 _allocation_end == NULL && _last_slow_path_end == NULL),
145 "TLAB must be reset");
146 }
147
148 void ThreadLocalAllocBuffer::resize_all_tlabs() {
149 if (ResizeTLAB) {
150 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
151 thread->tlab().resize();
152 }
153 }
154 }
155
156 void ThreadLocalAllocBuffer::resize() {
157 // Compute the next tlab size using expected allocation amount
158 assert(ResizeTLAB, "Should not call this otherwise");
159 size_t alloc = (size_t)(_allocation_fraction.average() *
160 (Universe::heap()->tlab_capacity(myThread()) / HeapWordSize));
161 size_t new_size = alloc / _target_refills;
162
163 new_size = MIN2(MAX2(new_size, min_size()), max_size());
164
170 _target_refills, _allocation_fraction.average(), desired_size(), aligned_new_size);
171
172 set_desired_size(aligned_new_size);
173 set_refill_waste_limit(initial_refill_waste_limit());
174 }
175
176 void ThreadLocalAllocBuffer::initialize_statistics() {
177 _number_of_refills = 0;
178 _fast_refill_waste = 0;
179 _slow_refill_waste = 0;
180 _gc_waste = 0;
181 _slow_allocations = 0;
182 }
183
184 void ThreadLocalAllocBuffer::fill(HeapWord* start,
185 HeapWord* top,
186 size_t new_size) {
187 _number_of_refills++;
188 print_stats("fill");
189 assert(top <= start + new_size - alignment_reserve(), "size too small");
190
191 // Remember old bytes until sample for the next tlab only if this is our first
192 // actual refill.
193 size_t old_bytes_until_sample = 0;
194 if (_number_of_refills > 1) {
195 old_bytes_until_sample = _bytes_until_sample;
196 }
197
198 initialize(start, top, start + new_size - alignment_reserve());
199
200 if (old_bytes_until_sample > 0) {
201 set_bytes_until_sample(old_bytes_until_sample);
202 set_sample_end();
203 }
204
205 // Reset amount of internal fragmentation
206 set_refill_waste_limit(initial_refill_waste_limit());
207 }
208
209 void ThreadLocalAllocBuffer::initialize(HeapWord* start,
210 HeapWord* top,
211 HeapWord* end) {
212 set_start(start);
213 set_top(top);
214 set_pf_top(top);
215 set_current_end(end);
216 set_allocation_end(end);
217 set_last_slow_path_end(end);
218 invariants();
219 _bytes_until_sample = 0;
220 }
221
222 void ThreadLocalAllocBuffer::initialize() {
223 initialize(NULL, // start
224 NULL, // top
225 NULL); // end
226
227 set_desired_size(initial_desired_size());
228
229 // Following check is needed because at startup the main
230 // thread is initialized before the heap is. The initialization for
231 // this thread is redone in startup_initialization below.
232 if (Universe::heap() != NULL) {
233 size_t capacity = Universe::heap()->tlab_capacity(myThread()) / HeapWordSize;
234 double alloc_frac = desired_size() * target_refills() / (double) capacity;
235 _allocation_fraction.sample(alloc_frac);
236 }
237
238 set_refill_waste_limit(initial_refill_waste_limit());
239
321 _allocation_fraction.average(),
322 _allocation_fraction.average() * tlab_used / K,
323 _number_of_refills, waste_percent,
324 _gc_waste * HeapWordSize,
325 _slow_refill_waste * HeapWordSize,
326 _fast_refill_waste * HeapWordSize);
327 }
328
329 void ThreadLocalAllocBuffer::verify() {
330 HeapWord* p = start();
331 HeapWord* t = top();
332 HeapWord* prev_p = NULL;
333 while (p < t) {
334 oop(p)->verify();
335 prev_p = p;
336 p += oop(p)->size();
337 }
338 guarantee(p == top(), "end of last object must match end of space");
339 }
340
341 void ThreadLocalAllocBuffer::set_sample_end() {
342 size_t heap_words_remaining = pointer_delta(_current_end, _top);
343 size_t bytes_left = _bytes_until_sample;
344 size_t words_until_sample = bytes_left / HeapWordSize;
345
346 if (heap_words_remaining > words_until_sample) {
347 HeapWord* new_end = _top + words_until_sample;
348 set_current_end(new_end);
349 set_last_slow_path_end(new_end);
350 set_bytes_until_sample(0);
351 } else {
352 bytes_left -= heap_words_remaining * HeapWordSize;
353 set_bytes_until_sample(bytes_left);
354 }
355 }
356
357 void ThreadLocalAllocBuffer::pick_next_sample(size_t overflowed_words) {
358 if (!HeapMonitoring::enabled()) {
359 return;
360 }
361
362 if (_bytes_until_sample == 0) {
363 HeapMonitoring::pick_next_sample(&_bytes_until_sample);
364 }
365
366 if (overflowed_words > 0) {
367 // Try to correct sample size by removing extra space from last allocation.
368 if (_bytes_until_sample > overflowed_words * HeapWordSize) {
369 set_bytes_until_sample(_bytes_until_sample - overflowed_words * HeapWordSize);
370 }
371 }
372
373 set_sample_end();
374
375 log_trace(gc, tlab)("TLAB picked next sample: thread: " INTPTR_FORMAT " [id: %2d]"
376 " start: " INTPTR_FORMAT " top: " INTPTR_FORMAT " end: "
377 INTPTR_FORMAT " allocation_end:"
378 INTPTR_FORMAT " last_slow_path_end: " INTPTR_FORMAT,
379 p2i(myThread()), myThread()->osthread()->thread_id(),
380 p2i(start()), p2i(top()), p2i(current_end()),
381 p2i(_allocation_end), p2i(_last_slow_path_end));
382 }
383
384 Thread* ThreadLocalAllocBuffer::myThread() {
385 return (Thread*)(((char *)this) +
386 in_bytes(start_offset()) -
387 in_bytes(Thread::tlab_start_offset()));
388 }
389
390 void ThreadLocalAllocBuffer::set_back_allocation_end() {
391 // Did a fast TLAB refill occur?
392 if (_last_slow_path_end != _current_end) {
393 // Fix up the actual end to be now the end of this TLAB.
394 _last_slow_path_end = _current_end;
395 _allocation_end = _current_end;
396 } else {
397 _current_end = _allocation_end;
398 }
399 }
400
401 void ThreadLocalAllocBuffer::handle_sample(Thread* thread, HeapWord* result,
402 size_t size_in_bytes) {
403 if (!HeapMonitoring::enabled()) {
404 return;
405 }
406
407 if (_bytes_until_sample < size_in_bytes) {
408 HeapMonitoring::object_alloc_do_sample(thread,
409 reinterpret_cast<oopDesc*>(result),
410 size_in_bytes);
411 }
412
413 update_tlab_sample_point(size_in_bytes);
414 }
415
416 void ThreadLocalAllocBuffer::update_tlab_sample_point(size_t size_in_bytes) {
417 if (_bytes_until_sample > size_in_bytes) {
418 _bytes_until_sample -= size_in_bytes;
419 return;
420 }
421
422 // We sampled here, so reset it all and start a new sample point.
423 set_bytes_until_sample(0);
424 set_back_allocation_end();
425 pick_next_sample();
426 }
427
428 void ThreadLocalAllocBuffer::update_end_pointers() {
429 // Did a fast TLAB refill occur? (This will be deprecated when fast TLAB
430 // refill disappears).
431 if (_last_slow_path_end != _current_end) {
432 // Fix up the last slow path end to be now the end of this TLAB.
433 _last_slow_path_end = _current_end;
434 _allocation_end = _current_end;
435 }
436 }
437
438 HeapWord* ThreadLocalAllocBuffer::reserved_end() {
439 assert (_last_slow_path_end == _current_end,
440 "Have to call update_end_pointers before reserved_end.");
441 return _allocation_end + alignment_reserve();
442 }
443
444 GlobalTLABStats::GlobalTLABStats() :
445 _allocating_threads_avg(TLABAllocationWeight) {
446
447 initialize();
448
449 _allocating_threads_avg.sample(1); // One allocating thread at startup
450
451 if (UsePerfData) {
452
453 EXCEPTION_MARK;
454 ResourceMark rm;
455
456 char* cname = PerfDataManager::counter_name("tlab", "allocThreads");
457 _perf_allocating_threads =
458 PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_None, CHECK);
459
460 cname = PerfDataManager::counter_name("tlab", "fills");
461 _perf_total_refills =
462 PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_None, CHECK);
|