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 "utilities/copy.hpp"
34
35 // Thread-Local Edens support
36
37 // static member initialization
38 size_t ThreadLocalAllocBuffer::_max_size = 0;
39 unsigned ThreadLocalAllocBuffer::_target_refills = 0;
40 GlobalTLABStats* ThreadLocalAllocBuffer::_global_stats = NULL;
41
42 void ThreadLocalAllocBuffer::clear_before_allocation() {
43 _slow_refill_waste += (unsigned)remaining();
44 make_parsable(true); // also retire the TLAB
45 }
46
47 void ThreadLocalAllocBuffer::accumulate_statistics_before_gc() {
48 global_stats()->initialize();
49
50 for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) {
51 thread->tlab().accumulate_statistics();
52 thread->tlab().initialize_statistics();
53 }
54
55 // Publish new stats if some allocation occurred.
56 if (global_stats()->allocation() != 0) {
57 global_stats()->publish();
58 global_stats()->print();
197 // this thread is redone in startup_initialization below.
198 if (Universe::heap() != NULL) {
199 size_t capacity = Universe::heap()->tlab_capacity(myThread()) / HeapWordSize;
200 double alloc_frac = desired_size() * target_refills() / (double) capacity;
201 _allocation_fraction.sample(alloc_frac);
202 }
203
204 set_refill_waste_limit(initial_refill_waste_limit());
205
206 initialize_statistics();
207 }
208
209 void ThreadLocalAllocBuffer::startup_initialization() {
210
211 // Assuming each thread's active tlab is, on average,
212 // 1/2 full at a GC
213 _target_refills = 100 / (2 * TLABWasteTargetPercent);
214 _target_refills = MAX2(_target_refills, (unsigned)1U);
215
216 _global_stats = new GlobalTLABStats();
217
218 // During jvm startup, the main (primordial) thread is initialized
219 // before the heap is initialized. So reinitialize it now.
220 guarantee(Thread::current()->is_Java_thread(), "tlab initialization thread not Java thread");
221 Thread::current()->tlab().initialize();
222
223 log_develop_trace(gc, tlab)("TLAB min: " SIZE_FORMAT " initial: " SIZE_FORMAT " max: " SIZE_FORMAT,
224 min_size(), Thread::current()->tlab().initial_desired_size(), max_size());
225 }
226
227 size_t ThreadLocalAllocBuffer::initial_desired_size() {
228 size_t init_sz = 0;
229
230 if (TLABSize > 0) {
231 init_sz = TLABSize / HeapWordSize;
232 } else if (global_stats() != NULL) {
233 // Initial size is a function of the average number of allocating threads.
234 unsigned nof_threads = global_stats()->allocating_threads_avg();
235
236 init_sz = (Universe::heap()->tlab_capacity(myThread()) / HeapWordSize) /
|
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 "utilities/copy.hpp"
34
35 // Thread-Local Edens support
36
37 // static member initialization
38 size_t ThreadLocalAllocBuffer::_max_size = 0;
39 int ThreadLocalAllocBuffer::_reserve_for_allocation_prefetch = 0;
40 unsigned ThreadLocalAllocBuffer::_target_refills = 0;
41 GlobalTLABStats* ThreadLocalAllocBuffer::_global_stats = NULL;
42
43 void ThreadLocalAllocBuffer::clear_before_allocation() {
44 _slow_refill_waste += (unsigned)remaining();
45 make_parsable(true); // also retire the TLAB
46 }
47
48 void ThreadLocalAllocBuffer::accumulate_statistics_before_gc() {
49 global_stats()->initialize();
50
51 for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) {
52 thread->tlab().accumulate_statistics();
53 thread->tlab().initialize_statistics();
54 }
55
56 // Publish new stats if some allocation occurred.
57 if (global_stats()->allocation() != 0) {
58 global_stats()->publish();
59 global_stats()->print();
198 // this thread is redone in startup_initialization below.
199 if (Universe::heap() != NULL) {
200 size_t capacity = Universe::heap()->tlab_capacity(myThread()) / HeapWordSize;
201 double alloc_frac = desired_size() * target_refills() / (double) capacity;
202 _allocation_fraction.sample(alloc_frac);
203 }
204
205 set_refill_waste_limit(initial_refill_waste_limit());
206
207 initialize_statistics();
208 }
209
210 void ThreadLocalAllocBuffer::startup_initialization() {
211
212 // Assuming each thread's active tlab is, on average,
213 // 1/2 full at a GC
214 _target_refills = 100 / (2 * TLABWasteTargetPercent);
215 _target_refills = MAX2(_target_refills, (unsigned)1U);
216
217 _global_stats = new GlobalTLABStats();
218
219 // Need extra space at the end of TLAB, otherwise prefetching
220 // instructions will fault (due to accessing memory outside of heap).
221 // The amount of space is the max of the number of lines to
222 // prefetch for array and for instance allocations. (Extra space must be
223 // reserved to accommodate both types of allocations.)
224 //
225 // Only SPARC-specific BIS instructions are known to fault. (Those
226 // instructions are generated if AllocatePrefetchStyle==3 and
227 // AllocatePrefetchInstr==1). To be on the safe side, however,
228 // extra space is reserved for all combinations of
229 // AllocatePrefetchStyle and AllocatePrefetchInstr.
230
231 // +1 for rounding up to next cache line, +1 to be safe
232 int lines = MAX2(AllocatePrefetchLines, AllocateInstancePrefetchLines) + 2;
233 _reserve_for_allocation_prefetch = (AllocatePrefetchDistance + AllocatePrefetchStepSize * lines) /
234 (int)HeapWordSize;
235
236 // During jvm startup, the main (primordial) thread is initialized
237 // before the heap is initialized. So reinitialize it now.
238 guarantee(Thread::current()->is_Java_thread(), "tlab initialization thread not Java thread");
239 Thread::current()->tlab().initialize();
240
241 log_develop_trace(gc, tlab)("TLAB min: " SIZE_FORMAT " initial: " SIZE_FORMAT " max: " SIZE_FORMAT,
242 min_size(), Thread::current()->tlab().initial_desired_size(), max_size());
243 }
244
245 size_t ThreadLocalAllocBuffer::initial_desired_size() {
246 size_t init_sz = 0;
247
248 if (TLABSize > 0) {
249 init_sz = TLABSize / HeapWordSize;
250 } else if (global_stats() != NULL) {
251 // Initial size is a function of the average number of allocating threads.
252 unsigned nof_threads = global_stats()->allocating_threads_avg();
253
254 init_sz = (Universe::heap()->tlab_capacity(myThread()) / HeapWordSize) /
|