comparison src/share/vm/memory/threadLocalAllocBuffer.cpp @ 14909:4ca6dc0799b6

Backout jdk9 merge
author Gilles Duboscq <duboscq@ssw.jku.at>
date Tue, 01 Apr 2014 13:57:07 +0200
parents d8041d695d19
children a29e6e7b7a86
comparison
equal deleted inserted replaced
14908:8db6e76cb658 14909:4ca6dc0799b6
32 #include "utilities/copy.hpp" 32 #include "utilities/copy.hpp"
33 33
34 // Thread-Local Edens support 34 // Thread-Local Edens support
35 35
36 // static member initialization 36 // static member initialization
37 size_t ThreadLocalAllocBuffer::_max_size = 0;
38 unsigned ThreadLocalAllocBuffer::_target_refills = 0; 37 unsigned ThreadLocalAllocBuffer::_target_refills = 0;
39 GlobalTLABStats* ThreadLocalAllocBuffer::_global_stats = NULL; 38 GlobalTLABStats* ThreadLocalAllocBuffer::_global_stats = NULL;
40 39
41 void ThreadLocalAllocBuffer::clear_before_allocation() { 40 void ThreadLocalAllocBuffer::clear_before_allocation() {
42 _slow_refill_waste += (unsigned)remaining(); 41 _slow_refill_waste += (unsigned)remaining();
44 } 43 }
45 44
46 void ThreadLocalAllocBuffer::accumulate_statistics_before_gc() { 45 void ThreadLocalAllocBuffer::accumulate_statistics_before_gc() {
47 global_stats()->initialize(); 46 global_stats()->initialize();
48 47
49 for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) { 48 for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
50 thread->tlab().accumulate_statistics(); 49 thread->tlab().accumulate_statistics();
51 thread->tlab().initialize_statistics(); 50 thread->tlab().initialize_statistics();
52 } 51 }
53 52
54 // Publish new stats if some allocation occurred. 53 // Publish new stats if some allocation occurred.
59 } 58 }
60 } 59 }
61 } 60 }
62 61
63 void ThreadLocalAllocBuffer::accumulate_statistics() { 62 void ThreadLocalAllocBuffer::accumulate_statistics() {
64 Thread* thread = myThread(); 63 size_t capacity = Universe::heap()->tlab_capacity(myThread()) / HeapWordSize;
65 size_t capacity = Universe::heap()->tlab_capacity(thread); 64 size_t unused = Universe::heap()->unsafe_max_tlab_alloc(myThread()) / HeapWordSize;
66 size_t used = Universe::heap()->tlab_used(thread); 65 size_t used = capacity - unused;
66
67 // Update allocation history if a reasonable amount of eden was allocated.
68 bool update_allocation_history = used > 0.5 * capacity;
67 69
68 _gc_waste += (unsigned)remaining(); 70 _gc_waste += (unsigned)remaining();
69 size_t total_allocated = thread->allocated_bytes();
70 size_t allocated_since_last_gc = total_allocated - _allocated_before_last_gc;
71 _allocated_before_last_gc = total_allocated;
72 71
73 if (PrintTLAB && (_number_of_refills > 0 || Verbose)) { 72 if (PrintTLAB && (_number_of_refills > 0 || Verbose)) {
74 print_stats("gc"); 73 print_stats("gc");
75 } 74 }
76 75
77 if (_number_of_refills > 0) { 76 if (_number_of_refills > 0) {
78 // Update allocation history if a reasonable amount of eden was allocated.
79 bool update_allocation_history = used > 0.5 * capacity;
80 77
81 if (update_allocation_history) { 78 if (update_allocation_history) {
82 // Average the fraction of eden allocated in a tlab by this 79 // Average the fraction of eden allocated in a tlab by this
83 // thread for use in the next resize operation. 80 // thread for use in the next resize operation.
84 // _gc_waste is not subtracted because it's included in 81 // _gc_waste is not subtracted because it's included in
85 // "used". 82 // "used".
86 // The result can be larger than 1.0 due to direct to old allocations. 83 size_t allocation = _number_of_refills * desired_size();
87 // These allocations should ideally not be counted but since it is not possible 84 double alloc_frac = allocation / (double) used;
88 // to filter them out here we just cap the fraction to be at most 1.0.
89 double alloc_frac = MIN2(1.0, (double) allocated_since_last_gc / used);
90 _allocation_fraction.sample(alloc_frac); 85 _allocation_fraction.sample(alloc_frac);
91 } 86 }
92 global_stats()->update_allocating_threads(); 87 global_stats()->update_allocating_threads();
93 global_stats()->update_number_of_refills(_number_of_refills); 88 global_stats()->update_number_of_refills(_number_of_refills);
94 global_stats()->update_allocation(_number_of_refills * desired_size()); 89 global_stats()->update_allocation(_number_of_refills * desired_size());
130 (start() == NULL && end() == NULL && top() == NULL), 125 (start() == NULL && end() == NULL && top() == NULL),
131 "TLAB must be reset"); 126 "TLAB must be reset");
132 } 127 }
133 128
134 void ThreadLocalAllocBuffer::resize_all_tlabs() { 129 void ThreadLocalAllocBuffer::resize_all_tlabs() {
130 for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
131 thread->tlab().resize();
132 }
133 }
134
135 void ThreadLocalAllocBuffer::resize() {
136
135 if (ResizeTLAB) { 137 if (ResizeTLAB) {
136 for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) { 138 // Compute the next tlab size using expected allocation amount
137 thread->tlab().resize(); 139 size_t alloc = (size_t)(_allocation_fraction.average() *
140 (Universe::heap()->tlab_capacity(myThread()) / HeapWordSize));
141 size_t new_size = alloc / _target_refills;
142
143 new_size = MIN2(MAX2(new_size, min_size()), max_size());
144
145 size_t aligned_new_size = align_object_size(new_size);
146
147 if (PrintTLAB && Verbose) {
148 gclog_or_tty->print("TLAB new size: thread: " INTPTR_FORMAT " [id: %2d]"
149 " refills %d alloc: %8.6f desired_size: " SIZE_FORMAT " -> " SIZE_FORMAT "\n",
150 myThread(), myThread()->osthread()->thread_id(),
151 _target_refills, _allocation_fraction.average(), desired_size(), aligned_new_size);
138 } 152 }
139 } 153 set_desired_size(aligned_new_size);
140 } 154
141 155 set_refill_waste_limit(initial_refill_waste_limit());
142 void ThreadLocalAllocBuffer::resize() { 156 }
143 // Compute the next tlab size using expected allocation amount
144 assert(ResizeTLAB, "Should not call this otherwise");
145 size_t alloc = (size_t)(_allocation_fraction.average() *
146 (Universe::heap()->tlab_capacity(myThread()) / HeapWordSize));
147 size_t new_size = alloc / _target_refills;
148
149 new_size = MIN2(MAX2(new_size, min_size()), max_size());
150
151 size_t aligned_new_size = align_object_size(new_size);
152
153 if (PrintTLAB && Verbose) {
154 gclog_or_tty->print("TLAB new size: thread: " INTPTR_FORMAT " [id: %2d]"
155 " refills %d alloc: %8.6f desired_size: " SIZE_FORMAT " -> " SIZE_FORMAT "\n",
156 myThread(), myThread()->osthread()->thread_id(),
157 _target_refills, _allocation_fraction.average(), desired_size(), aligned_new_size);
158 }
159 set_desired_size(aligned_new_size);
160 set_refill_waste_limit(initial_refill_waste_limit());
161 } 157 }
162 158
163 void ThreadLocalAllocBuffer::initialize_statistics() { 159 void ThreadLocalAllocBuffer::initialize_statistics() {
164 _number_of_refills = 0; 160 _number_of_refills = 0;
165 _fast_refill_waste = 0; 161 _fast_refill_waste = 0;
251 init_sz = MIN2(MAX2(init_sz, min_size()), max_size()); 247 init_sz = MIN2(MAX2(init_sz, min_size()), max_size());
252 } 248 }
253 return init_sz; 249 return init_sz;
254 } 250 }
255 251
252 const size_t ThreadLocalAllocBuffer::max_size() {
253
254 // TLABs can't be bigger than we can fill with a int[Integer.MAX_VALUE].
255 // This restriction could be removed by enabling filling with multiple arrays.
256 // If we compute that the reasonable way as
257 // header_size + ((sizeof(jint) * max_jint) / HeapWordSize)
258 // we'll overflow on the multiply, so we do the divide first.
259 // We actually lose a little by dividing first,
260 // but that just makes the TLAB somewhat smaller than the biggest array,
261 // which is fine, since we'll be able to fill that.
262
263 size_t unaligned_max_size = typeArrayOopDesc::header_size(T_INT) +
264 sizeof(jint) *
265 ((juint) max_jint / (size_t) HeapWordSize);
266 return align_size_down(unaligned_max_size, MinObjAlignment);
267 }
268
256 void ThreadLocalAllocBuffer::print_stats(const char* tag) { 269 void ThreadLocalAllocBuffer::print_stats(const char* tag) {
257 Thread* thrd = myThread(); 270 Thread* thrd = myThread();
258 size_t waste = _gc_waste + _slow_refill_waste + _fast_refill_waste; 271 size_t waste = _gc_waste + _slow_refill_waste + _fast_refill_waste;
259 size_t alloc = _number_of_refills * _desired_size; 272 size_t alloc = _number_of_refills * _desired_size;
260 double waste_percent = alloc == 0 ? 0.0 : 273 double waste_percent = alloc == 0 ? 0.0 :
261 100.0 * waste / alloc; 274 100.0 * waste / alloc;
262 size_t tlab_used = Universe::heap()->tlab_used(thrd); 275 size_t tlab_used = Universe::heap()->tlab_capacity(thrd) -
276 Universe::heap()->unsafe_max_tlab_alloc(thrd);
263 gclog_or_tty->print("TLAB: %s thread: " INTPTR_FORMAT " [id: %2d]" 277 gclog_or_tty->print("TLAB: %s thread: " INTPTR_FORMAT " [id: %2d]"
264 " desired_size: " SIZE_FORMAT "KB" 278 " desired_size: " SIZE_FORMAT "KB"
265 " slow allocs: %d refill waste: " SIZE_FORMAT "B" 279 " slow allocs: %d refill waste: " SIZE_FORMAT "B"
266 " alloc:%8.5f %8.0fKB refills: %d waste %4.1f%% gc: %dB" 280 " alloc:%8.5f %8.0fKB refills: %d waste %4.1f%% gc: %dB"
267 " slow: %dB fast: %dB\n", 281 " slow: %dB fast: %dB\n",