--- old/src/share/vm/gc/shared/threadLocalAllocBuffer.hpp 2017-06-12 10:25:12.666255648 -0700 +++ new/src/share/vm/gc/shared/threadLocalAllocBuffer.hpp 2017-06-12 10:25:12.590255944 -0700 @@ -45,6 +45,7 @@ HeapWord* _top; // address after last allocation HeapWord* _pf_top; // allocation prefetch watermark HeapWord* _end; // allocation end (excluding alignment_reserve) + HeapWord* _actual_end; // allocation actual_end (excluding alignment_reserve) size_t _desired_size; // desired size (including alignment_reserve) size_t _refill_waste_limit; // hold onto tlab if free() is larger than this size_t _allocated_before_last_gc; // total bytes allocated up until the last gc @@ -52,6 +53,8 @@ static size_t _max_size; // maximum size of any TLAB static int _reserve_for_allocation_prefetch; // Reserve at the end of the TLAB static unsigned _target_refills; // expected number of refills between GCs + size_t _bytes_until_sample; // bytes until sample. + size_t _extra_space; // extra space due to sampling logic. unsigned _number_of_refills; unsigned _fast_refill_waste; @@ -66,10 +69,12 @@ void set_start(HeapWord* start) { _start = start; } void set_end(HeapWord* end) { _end = end; } + void set_actual_end(HeapWord* actual_end) { _actual_end = actual_end; } void set_top(HeapWord* top) { _top = top; } void set_pf_top(HeapWord* pf_top) { _pf_top = pf_top; } void set_desired_size(size_t desired_size) { _desired_size = desired_size; } void set_refill_waste_limit(size_t waste) { _refill_waste_limit = waste; } + void set_bytes_until_sample(size_t bytes) { _bytes_until_sample = bytes; } size_t initial_refill_waste_limit() { return desired_size() / TLABRefillWasteFraction; } @@ -115,13 +120,14 @@ HeapWord* start() const { return _start; } HeapWord* end() const { return _end; } - HeapWord* hard_end() const { return _end + alignment_reserve(); } + HeapWord* hard_end() const { return _actual_end + alignment_reserve(); } HeapWord* top() const { return _top; } HeapWord* pf_top() const { return _pf_top; } size_t desired_size() const { return _desired_size; } size_t used() const { return pointer_delta(top(), start()); } size_t used_bytes() const { return pointer_delta(top(), start(), 1); } size_t free() const { return pointer_delta(end(), top()); } + // Don't discard tlab if remaining space is larger than this. size_t refill_waste_limit() const { return _refill_waste_limit; } @@ -159,14 +165,22 @@ // Resize tlabs for all threads static void resize_all_tlabs(); + void set_back_actual_end() { _end = _actual_end; } void fill(HeapWord* start, HeapWord* top, size_t new_size); void initialize(); + void pick_next_sample(); + void handle_sample(Thread* thread, HeapWord* result, size_t size); + size_t bytes_until_sample() { return _bytes_until_sample; } + size_t *bytes_until_sample_addr() { return &_bytes_until_sample; } + bool should_sample() { return bytes_until_sample() == 0; } + static size_t refill_waste_limit_increment() { return TLABWasteIncrement; } // Code generation support static ByteSize start_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _start); } static ByteSize end_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _end ); } + static ByteSize actual_end_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _actual_end ); } static ByteSize top_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _top ); } static ByteSize pf_top_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _pf_top ); } static ByteSize size_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _desired_size ); }