Mercurial > hg > truffle
diff 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 |
line wrap: on
line diff
--- a/src/share/vm/memory/threadLocalAllocBuffer.cpp Tue Apr 01 14:09:03 2014 +0200 +++ b/src/share/vm/memory/threadLocalAllocBuffer.cpp Tue Apr 01 13:57:07 2014 +0200 @@ -34,7 +34,6 @@ // Thread-Local Edens support // static member initialization -size_t ThreadLocalAllocBuffer::_max_size = 0; unsigned ThreadLocalAllocBuffer::_target_refills = 0; GlobalTLABStats* ThreadLocalAllocBuffer::_global_stats = NULL; @@ -46,7 +45,7 @@ void ThreadLocalAllocBuffer::accumulate_statistics_before_gc() { global_stats()->initialize(); - for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) { + for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) { thread->tlab().accumulate_statistics(); thread->tlab().initialize_statistics(); } @@ -61,32 +60,28 @@ } void ThreadLocalAllocBuffer::accumulate_statistics() { - Thread* thread = myThread(); - size_t capacity = Universe::heap()->tlab_capacity(thread); - size_t used = Universe::heap()->tlab_used(thread); + size_t capacity = Universe::heap()->tlab_capacity(myThread()) / HeapWordSize; + size_t unused = Universe::heap()->unsafe_max_tlab_alloc(myThread()) / HeapWordSize; + size_t used = capacity - unused; + + // Update allocation history if a reasonable amount of eden was allocated. + bool update_allocation_history = used > 0.5 * capacity; _gc_waste += (unsigned)remaining(); - size_t total_allocated = thread->allocated_bytes(); - size_t allocated_since_last_gc = total_allocated - _allocated_before_last_gc; - _allocated_before_last_gc = total_allocated; if (PrintTLAB && (_number_of_refills > 0 || Verbose)) { print_stats("gc"); } if (_number_of_refills > 0) { - // Update allocation history if a reasonable amount of eden was allocated. - bool update_allocation_history = used > 0.5 * capacity; if (update_allocation_history) { // Average the fraction of eden allocated in a tlab by this // thread for use in the next resize operation. // _gc_waste is not subtracted because it's included in // "used". - // The result can be larger than 1.0 due to direct to old allocations. - // These allocations should ideally not be counted but since it is not possible - // to filter them out here we just cap the fraction to be at most 1.0. - double alloc_frac = MIN2(1.0, (double) allocated_since_last_gc / used); + size_t allocation = _number_of_refills * desired_size(); + double alloc_frac = allocation / (double) used; _allocation_fraction.sample(alloc_frac); } global_stats()->update_allocating_threads(); @@ -132,32 +127,33 @@ } void ThreadLocalAllocBuffer::resize_all_tlabs() { - if (ResizeTLAB) { - for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) { - thread->tlab().resize(); - } + for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) { + thread->tlab().resize(); } } void ThreadLocalAllocBuffer::resize() { - // Compute the next tlab size using expected allocation amount - assert(ResizeTLAB, "Should not call this otherwise"); - size_t alloc = (size_t)(_allocation_fraction.average() * - (Universe::heap()->tlab_capacity(myThread()) / HeapWordSize)); - size_t new_size = alloc / _target_refills; - new_size = MIN2(MAX2(new_size, min_size()), max_size()); + if (ResizeTLAB) { + // Compute the next tlab size using expected allocation amount + size_t alloc = (size_t)(_allocation_fraction.average() * + (Universe::heap()->tlab_capacity(myThread()) / HeapWordSize)); + size_t new_size = alloc / _target_refills; + + new_size = MIN2(MAX2(new_size, min_size()), max_size()); + + size_t aligned_new_size = align_object_size(new_size); - size_t aligned_new_size = align_object_size(new_size); + if (PrintTLAB && Verbose) { + gclog_or_tty->print("TLAB new size: thread: " INTPTR_FORMAT " [id: %2d]" + " refills %d alloc: %8.6f desired_size: " SIZE_FORMAT " -> " SIZE_FORMAT "\n", + myThread(), myThread()->osthread()->thread_id(), + _target_refills, _allocation_fraction.average(), desired_size(), aligned_new_size); + } + set_desired_size(aligned_new_size); - if (PrintTLAB && Verbose) { - gclog_or_tty->print("TLAB new size: thread: " INTPTR_FORMAT " [id: %2d]" - " refills %d alloc: %8.6f desired_size: " SIZE_FORMAT " -> " SIZE_FORMAT "\n", - myThread(), myThread()->osthread()->thread_id(), - _target_refills, _allocation_fraction.average(), desired_size(), aligned_new_size); + set_refill_waste_limit(initial_refill_waste_limit()); } - set_desired_size(aligned_new_size); - set_refill_waste_limit(initial_refill_waste_limit()); } void ThreadLocalAllocBuffer::initialize_statistics() { @@ -253,13 +249,31 @@ return init_sz; } +const size_t ThreadLocalAllocBuffer::max_size() { + + // TLABs can't be bigger than we can fill with a int[Integer.MAX_VALUE]. + // This restriction could be removed by enabling filling with multiple arrays. + // If we compute that the reasonable way as + // header_size + ((sizeof(jint) * max_jint) / HeapWordSize) + // we'll overflow on the multiply, so we do the divide first. + // We actually lose a little by dividing first, + // but that just makes the TLAB somewhat smaller than the biggest array, + // which is fine, since we'll be able to fill that. + + size_t unaligned_max_size = typeArrayOopDesc::header_size(T_INT) + + sizeof(jint) * + ((juint) max_jint / (size_t) HeapWordSize); + return align_size_down(unaligned_max_size, MinObjAlignment); +} + void ThreadLocalAllocBuffer::print_stats(const char* tag) { Thread* thrd = myThread(); size_t waste = _gc_waste + _slow_refill_waste + _fast_refill_waste; size_t alloc = _number_of_refills * _desired_size; double waste_percent = alloc == 0 ? 0.0 : 100.0 * waste / alloc; - size_t tlab_used = Universe::heap()->tlab_used(thrd); + size_t tlab_used = Universe::heap()->tlab_capacity(thrd) - + Universe::heap()->unsafe_max_tlab_alloc(thrd); gclog_or_tty->print("TLAB: %s thread: " INTPTR_FORMAT " [id: %2d]" " desired_size: " SIZE_FORMAT "KB" " slow allocs: %d refill waste: " SIZE_FORMAT "B"