67 global_stats()->print(); |
67 global_stats()->print(); |
68 } |
68 } |
69 } |
69 } |
70 |
70 |
71 void ThreadLocalAllocBuffer::accumulate_statistics() { |
71 void ThreadLocalAllocBuffer::accumulate_statistics() { |
72 Thread* thread = myThread(); |
72 Thread* thr = thread(); |
73 size_t capacity = Universe::heap()->tlab_capacity(thread); |
73 size_t capacity = Universe::heap()->tlab_capacity(thr); |
74 size_t used = Universe::heap()->tlab_used(thread); |
74 size_t used = Universe::heap()->tlab_used(thr); |
75 |
75 |
76 _gc_waste += (unsigned)remaining(); |
76 _gc_waste += (unsigned)remaining(); |
77 size_t total_allocated = thread->allocated_bytes(); |
77 size_t total_allocated = thr->allocated_bytes(); |
78 size_t allocated_since_last_gc = total_allocated - _allocated_before_last_gc; |
78 size_t allocated_since_last_gc = total_allocated - _allocated_before_last_gc; |
79 _allocated_before_last_gc = total_allocated; |
79 _allocated_before_last_gc = total_allocated; |
80 |
80 |
81 print_stats("gc"); |
81 print_stats("gc"); |
82 |
82 |
117 void ThreadLocalAllocBuffer::make_parsable(bool retire, bool zap) { |
117 void ThreadLocalAllocBuffer::make_parsable(bool retire, bool zap) { |
118 if (end() != NULL) { |
118 if (end() != NULL) { |
119 invariants(); |
119 invariants(); |
120 |
120 |
121 if (retire) { |
121 if (retire) { |
122 myThread()->incr_allocated_bytes(used_bytes()); |
122 thread()->incr_allocated_bytes(used_bytes()); |
123 } |
123 } |
124 |
124 |
125 Universe::heap()->fill_with_dummy_object(top(), hard_end(), retire && zap); |
125 Universe::heap()->fill_with_dummy_object(top(), hard_end(), retire && zap); |
126 |
126 |
127 if (retire || ZeroTLAB) { // "Reset" the TLAB |
127 if (retire || ZeroTLAB) { // "Reset" the TLAB |
148 |
148 |
149 void ThreadLocalAllocBuffer::resize() { |
149 void ThreadLocalAllocBuffer::resize() { |
150 // Compute the next tlab size using expected allocation amount |
150 // Compute the next tlab size using expected allocation amount |
151 assert(ResizeTLAB, "Should not call this otherwise"); |
151 assert(ResizeTLAB, "Should not call this otherwise"); |
152 size_t alloc = (size_t)(_allocation_fraction.average() * |
152 size_t alloc = (size_t)(_allocation_fraction.average() * |
153 (Universe::heap()->tlab_capacity(myThread()) / HeapWordSize)); |
153 (Universe::heap()->tlab_capacity(thread()) / HeapWordSize)); |
154 size_t new_size = alloc / _target_refills; |
154 size_t new_size = alloc / _target_refills; |
155 |
155 |
156 new_size = MIN2(MAX2(new_size, min_size()), max_size()); |
156 new_size = MIN2(MAX2(new_size, min_size()), max_size()); |
157 |
157 |
158 size_t aligned_new_size = align_object_size(new_size); |
158 size_t aligned_new_size = align_object_size(new_size); |
159 |
159 |
160 log_trace(gc, tlab)("TLAB new size: thread: " INTPTR_FORMAT " [id: %2d]" |
160 log_trace(gc, tlab)("TLAB new size: thread: " INTPTR_FORMAT " [id: %2d]" |
161 " refills %d alloc: %8.6f desired_size: " SIZE_FORMAT " -> " SIZE_FORMAT, |
161 " refills %d alloc: %8.6f desired_size: " SIZE_FORMAT " -> " SIZE_FORMAT, |
162 p2i(myThread()), myThread()->osthread()->thread_id(), |
162 p2i(thread()), thread()->osthread()->thread_id(), |
163 _target_refills, _allocation_fraction.average(), desired_size(), aligned_new_size); |
163 _target_refills, _allocation_fraction.average(), desired_size(), aligned_new_size); |
164 |
164 |
165 set_desired_size(aligned_new_size); |
165 set_desired_size(aligned_new_size); |
166 set_refill_waste_limit(initial_refill_waste_limit()); |
166 set_refill_waste_limit(initial_refill_waste_limit()); |
167 } |
167 } |
209 |
209 |
210 // Following check is needed because at startup the main |
210 // Following check is needed because at startup the main |
211 // thread is initialized before the heap is. The initialization for |
211 // thread is initialized before the heap is. The initialization for |
212 // this thread is redone in startup_initialization below. |
212 // this thread is redone in startup_initialization below. |
213 if (Universe::heap() != NULL) { |
213 if (Universe::heap() != NULL) { |
214 size_t capacity = Universe::heap()->tlab_capacity(myThread()) / HeapWordSize; |
214 size_t capacity = Universe::heap()->tlab_capacity(thread()) / HeapWordSize; |
215 double alloc_frac = desired_size() * target_refills() / (double) capacity; |
215 double alloc_frac = desired_size() * target_refills() / (double) capacity; |
216 _allocation_fraction.sample(alloc_frac); |
216 _allocation_fraction.sample(alloc_frac); |
217 } |
217 } |
218 |
218 |
219 set_refill_waste_limit(initial_refill_waste_limit()); |
219 set_refill_waste_limit(initial_refill_waste_limit()); |
272 init_sz = TLABSize / HeapWordSize; |
272 init_sz = TLABSize / HeapWordSize; |
273 } else if (global_stats() != NULL) { |
273 } else if (global_stats() != NULL) { |
274 // Initial size is a function of the average number of allocating threads. |
274 // Initial size is a function of the average number of allocating threads. |
275 unsigned nof_threads = global_stats()->allocating_threads_avg(); |
275 unsigned nof_threads = global_stats()->allocating_threads_avg(); |
276 |
276 |
277 init_sz = (Universe::heap()->tlab_capacity(myThread()) / HeapWordSize) / |
277 init_sz = (Universe::heap()->tlab_capacity(thread()) / HeapWordSize) / |
278 (nof_threads * target_refills()); |
278 (nof_threads * target_refills()); |
279 init_sz = align_object_size(init_sz); |
279 init_sz = align_object_size(init_sz); |
280 } |
280 } |
281 init_sz = MIN2(MAX2(init_sz, min_size()), max_size()); |
281 init_sz = MIN2(MAX2(init_sz, min_size()), max_size()); |
282 return init_sz; |
282 return init_sz; |
286 Log(gc, tlab) log; |
286 Log(gc, tlab) log; |
287 if (!log.is_trace()) { |
287 if (!log.is_trace()) { |
288 return; |
288 return; |
289 } |
289 } |
290 |
290 |
291 Thread* thrd = myThread(); |
291 Thread* thrd = thread(); |
292 size_t waste = _gc_waste + _slow_refill_waste + _fast_refill_waste; |
292 size_t waste = _gc_waste + _slow_refill_waste + _fast_refill_waste; |
293 double waste_percent = percent_of(waste, _allocated_size); |
293 double waste_percent = percent_of(waste, _allocated_size); |
294 size_t tlab_used = Universe::heap()->tlab_used(thrd); |
294 size_t tlab_used = Universe::heap()->tlab_used(thrd); |
295 log.trace("TLAB: %s thread: " INTPTR_FORMAT " [id: %2d]" |
295 log.trace("TLAB: %s thread: " INTPTR_FORMAT " [id: %2d]" |
296 " desired_size: " SIZE_FORMAT "KB" |
296 " desired_size: " SIZE_FORMAT "KB" |
320 guarantee(p == top(), "end of last object must match end of space"); |
320 guarantee(p == top(), "end of last object must match end of space"); |
321 } |
321 } |
322 |
322 |
323 void ThreadLocalAllocBuffer::set_sample_end() { |
323 void ThreadLocalAllocBuffer::set_sample_end() { |
324 size_t heap_words_remaining = pointer_delta(_end, _top); |
324 size_t heap_words_remaining = pointer_delta(_end, _top); |
325 size_t bytes_until_sample = myThread()->heap_sampler().bytes_until_sample(); |
325 size_t bytes_until_sample = thread()->heap_sampler().bytes_until_sample(); |
326 size_t words_until_sample = bytes_until_sample / HeapWordSize; |
326 size_t words_until_sample = bytes_until_sample / HeapWordSize; |
327 |
327 |
328 if (heap_words_remaining > words_until_sample) { |
328 if (heap_words_remaining > words_until_sample) { |
329 HeapWord* new_end = _top + words_until_sample; |
329 HeapWord* new_end = _top + words_until_sample; |
330 set_end(new_end); |
330 set_end(new_end); |
332 } else { |
332 } else { |
333 _bytes_since_last_sample_point = heap_words_remaining * HeapWordSize; |
333 _bytes_since_last_sample_point = heap_words_remaining * HeapWordSize; |
334 } |
334 } |
335 } |
335 } |
336 |
336 |
337 Thread* ThreadLocalAllocBuffer::myThread() { |
337 Thread* ThreadLocalAllocBuffer::thread() { |
338 return (Thread*)(((char *)this) + |
338 return (Thread*)(((char*)this) + in_bytes(start_offset()) - in_bytes(Thread::tlab_start_offset())); |
339 in_bytes(start_offset()) - |
|
340 in_bytes(Thread::tlab_start_offset())); |
|
341 } |
339 } |
342 |
340 |
343 void ThreadLocalAllocBuffer::set_back_allocation_end() { |
341 void ThreadLocalAllocBuffer::set_back_allocation_end() { |
344 _end = _allocation_end; |
342 _end = _allocation_end; |
345 } |
343 } |