src/share/vm/memory/threadLocalAllocBuffer.hpp

Wed, 13 Jan 2010 15:26:39 -0800

author
ysr
date
Wed, 13 Jan 2010 15:26:39 -0800
changeset 1601
7b0e9cba0307
parent 435
a61af66fc99e
child 1802
9e321dcfa5b7
permissions
-rw-r--r--

6896647: card marks can be deferred too long
Summary: Deferred card marks are now flushed during the gc prologue. Parallel[Scavege,OldGC] and SerialGC no longer defer card marks generated by COMPILER2 as a result of ReduceInitialCardMarks. For these cases, introduced a diagnostic option to defer the card marks, only for the purposes of testing and diagnostics. CMS and G1 continue to defer card marks. Potential performance concern related to single-threaded flushing of deferred card marks in the gc prologue will be addressed in the future.
Reviewed-by: never, johnc

duke@435 1 /*
duke@435 2 * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
duke@435 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
duke@435 20 * CA 95054 USA or visit www.sun.com if you need additional information or
duke@435 21 * have any questions.
duke@435 22 *
duke@435 23 */
duke@435 24
duke@435 25 class GlobalTLABStats;
duke@435 26
duke@435 27 // ThreadLocalAllocBuffer: a descriptor for thread-local storage used by
duke@435 28 // the threads for allocation.
duke@435 29 // It is thread-private at any time, but maybe multiplexed over
duke@435 30 // time across multiple threads. The park()/unpark() pair is
duke@435 31 // used to make it avaiable for such multiplexing.
duke@435 32 class ThreadLocalAllocBuffer: public CHeapObj {
duke@435 33 friend class VMStructs;
duke@435 34 private:
duke@435 35 HeapWord* _start; // address of TLAB
duke@435 36 HeapWord* _top; // address after last allocation
duke@435 37 HeapWord* _pf_top; // allocation prefetch watermark
duke@435 38 HeapWord* _end; // allocation end (excluding alignment_reserve)
duke@435 39 size_t _desired_size; // desired size (including alignment_reserve)
duke@435 40 size_t _refill_waste_limit; // hold onto tlab if free() is larger than this
duke@435 41
duke@435 42 static unsigned _target_refills; // expected number of refills between GCs
duke@435 43
duke@435 44 unsigned _number_of_refills;
duke@435 45 unsigned _fast_refill_waste;
duke@435 46 unsigned _slow_refill_waste;
duke@435 47 unsigned _gc_waste;
duke@435 48 unsigned _slow_allocations;
duke@435 49
duke@435 50 AdaptiveWeightedAverage _allocation_fraction; // fraction of eden allocated in tlabs
duke@435 51
duke@435 52 void accumulate_statistics();
duke@435 53 void initialize_statistics();
duke@435 54
duke@435 55 void set_start(HeapWord* start) { _start = start; }
duke@435 56 void set_end(HeapWord* end) { _end = end; }
duke@435 57 void set_top(HeapWord* top) { _top = top; }
duke@435 58 void set_pf_top(HeapWord* pf_top) { _pf_top = pf_top; }
duke@435 59 void set_desired_size(size_t desired_size) { _desired_size = desired_size; }
duke@435 60 void set_refill_waste_limit(size_t waste) { _refill_waste_limit = waste; }
duke@435 61
duke@435 62 size_t initial_refill_waste_limit() { return desired_size() / TLABRefillWasteFraction; }
duke@435 63
duke@435 64 static int target_refills() { return _target_refills; }
duke@435 65 size_t initial_desired_size();
duke@435 66
duke@435 67 size_t remaining() const { return end() == NULL ? 0 : pointer_delta(hard_end(), top()); }
duke@435 68
duke@435 69 // Make parsable and release it.
duke@435 70 void reset();
duke@435 71
duke@435 72 // Resize based on amount of allocation, etc.
duke@435 73 void resize();
duke@435 74
duke@435 75 void invariants() const { assert(top() >= start() && top() <= end(), "invalid tlab"); }
duke@435 76
duke@435 77 void initialize(HeapWord* start, HeapWord* top, HeapWord* end);
duke@435 78
duke@435 79 void print_stats(const char* tag);
duke@435 80
duke@435 81 Thread* myThread();
duke@435 82
duke@435 83 // statistics
duke@435 84
duke@435 85 int number_of_refills() const { return _number_of_refills; }
duke@435 86 int fast_refill_waste() const { return _fast_refill_waste; }
duke@435 87 int slow_refill_waste() const { return _slow_refill_waste; }
duke@435 88 int gc_waste() const { return _gc_waste; }
duke@435 89 int slow_allocations() const { return _slow_allocations; }
duke@435 90
duke@435 91 static GlobalTLABStats* _global_stats;
duke@435 92 static GlobalTLABStats* global_stats() { return _global_stats; }
duke@435 93
duke@435 94 public:
duke@435 95 ThreadLocalAllocBuffer() : _allocation_fraction(TLABAllocationWeight) {
duke@435 96 // do nothing. tlabs must be inited by initialize() calls
duke@435 97 }
duke@435 98
duke@435 99 static const size_t min_size() { return align_object_size(MinTLABSize / HeapWordSize); }
duke@435 100 static const size_t max_size();
duke@435 101
duke@435 102 HeapWord* start() const { return _start; }
duke@435 103 HeapWord* end() const { return _end; }
duke@435 104 HeapWord* hard_end() const { return _end + alignment_reserve(); }
duke@435 105 HeapWord* top() const { return _top; }
duke@435 106 HeapWord* pf_top() const { return _pf_top; }
duke@435 107 size_t desired_size() const { return _desired_size; }
duke@435 108 size_t free() const { return pointer_delta(end(), top()); }
duke@435 109 // Don't discard tlab if remaining space is larger than this.
duke@435 110 size_t refill_waste_limit() const { return _refill_waste_limit; }
duke@435 111
duke@435 112 // Allocate size HeapWords. The memory is NOT initialized to zero.
duke@435 113 inline HeapWord* allocate(size_t size);
duke@435 114 static size_t alignment_reserve() { return align_object_size(typeArrayOopDesc::header_size(T_INT)); }
duke@435 115 static size_t alignment_reserve_in_bytes() { return alignment_reserve() * HeapWordSize; }
duke@435 116
duke@435 117 // Return tlab size or remaining space in eden such that the
duke@435 118 // space is large enough to hold obj_size and necessary fill space.
duke@435 119 // Otherwise return 0;
duke@435 120 inline size_t compute_size(size_t obj_size);
duke@435 121
duke@435 122 // Record slow allocation
duke@435 123 inline void record_slow_allocation(size_t obj_size);
duke@435 124
duke@435 125 // Initialization at startup
duke@435 126 static void startup_initialization();
duke@435 127
duke@435 128 // Make an in-use tlab parsable, optionally also retiring it.
duke@435 129 void make_parsable(bool retire);
duke@435 130
duke@435 131 // Retire in-use tlab before allocation of a new tlab
duke@435 132 void clear_before_allocation();
duke@435 133
duke@435 134 // Accumulate statistics across all tlabs before gc
duke@435 135 static void accumulate_statistics_before_gc();
duke@435 136
duke@435 137 // Resize tlabs for all threads
duke@435 138 static void resize_all_tlabs();
duke@435 139
duke@435 140 void fill(HeapWord* start, HeapWord* top, size_t new_size);
duke@435 141 void initialize();
duke@435 142
duke@435 143 static size_t refill_waste_limit_increment() { return TLABWasteIncrement; }
duke@435 144
duke@435 145 // Code generation support
duke@435 146 static ByteSize start_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _start); }
duke@435 147 static ByteSize end_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _end ); }
duke@435 148 static ByteSize top_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _top ); }
duke@435 149 static ByteSize pf_top_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _pf_top ); }
duke@435 150 static ByteSize size_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _desired_size ); }
duke@435 151 static ByteSize refill_waste_limit_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _refill_waste_limit ); }
duke@435 152
duke@435 153 static ByteSize number_of_refills_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _number_of_refills ); }
duke@435 154 static ByteSize fast_refill_waste_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _fast_refill_waste ); }
duke@435 155 static ByteSize slow_allocations_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _slow_allocations ); }
duke@435 156
duke@435 157 void verify();
duke@435 158 };
duke@435 159
duke@435 160 class GlobalTLABStats: public CHeapObj {
duke@435 161 private:
duke@435 162
duke@435 163 // Accumulate perfdata in private variables because
duke@435 164 // PerfData should be write-only for security reasons
duke@435 165 // (see perfData.hpp)
duke@435 166 unsigned _allocating_threads;
duke@435 167 unsigned _total_refills;
duke@435 168 unsigned _max_refills;
duke@435 169 size_t _total_allocation;
duke@435 170 size_t _total_gc_waste;
duke@435 171 size_t _max_gc_waste;
duke@435 172 size_t _total_slow_refill_waste;
duke@435 173 size_t _max_slow_refill_waste;
duke@435 174 size_t _total_fast_refill_waste;
duke@435 175 size_t _max_fast_refill_waste;
duke@435 176 unsigned _total_slow_allocations;
duke@435 177 unsigned _max_slow_allocations;
duke@435 178
duke@435 179 PerfVariable* _perf_allocating_threads;
duke@435 180 PerfVariable* _perf_total_refills;
duke@435 181 PerfVariable* _perf_max_refills;
duke@435 182 PerfVariable* _perf_allocation;
duke@435 183 PerfVariable* _perf_gc_waste;
duke@435 184 PerfVariable* _perf_max_gc_waste;
duke@435 185 PerfVariable* _perf_slow_refill_waste;
duke@435 186 PerfVariable* _perf_max_slow_refill_waste;
duke@435 187 PerfVariable* _perf_fast_refill_waste;
duke@435 188 PerfVariable* _perf_max_fast_refill_waste;
duke@435 189 PerfVariable* _perf_slow_allocations;
duke@435 190 PerfVariable* _perf_max_slow_allocations;
duke@435 191
duke@435 192 AdaptiveWeightedAverage _allocating_threads_avg;
duke@435 193
duke@435 194 public:
duke@435 195 GlobalTLABStats();
duke@435 196
duke@435 197 // Initialize all counters
duke@435 198 void initialize();
duke@435 199
duke@435 200 // Write all perf counters to the perf_counters
duke@435 201 void publish();
duke@435 202
duke@435 203 void print();
duke@435 204
duke@435 205 // Accessors
duke@435 206 unsigned allocating_threads_avg() {
duke@435 207 return MAX2((unsigned)(_allocating_threads_avg.average() + 0.5), 1U);
duke@435 208 }
duke@435 209
duke@435 210 size_t allocation() {
duke@435 211 return _total_allocation;
duke@435 212 }
duke@435 213
duke@435 214 // Update methods
duke@435 215
duke@435 216 void update_allocating_threads() {
duke@435 217 _allocating_threads++;
duke@435 218 }
duke@435 219 void update_number_of_refills(unsigned value) {
duke@435 220 _total_refills += value;
duke@435 221 _max_refills = MAX2(_max_refills, value);
duke@435 222 }
duke@435 223 void update_allocation(size_t value) {
duke@435 224 _total_allocation += value;
duke@435 225 }
duke@435 226 void update_gc_waste(size_t value) {
duke@435 227 _total_gc_waste += value;
duke@435 228 _max_gc_waste = MAX2(_max_gc_waste, value);
duke@435 229 }
duke@435 230 void update_fast_refill_waste(size_t value) {
duke@435 231 _total_fast_refill_waste += value;
duke@435 232 _max_fast_refill_waste = MAX2(_max_fast_refill_waste, value);
duke@435 233 }
duke@435 234 void update_slow_refill_waste(size_t value) {
duke@435 235 _total_slow_refill_waste += value;
duke@435 236 _max_slow_refill_waste = MAX2(_max_slow_refill_waste, value);
duke@435 237 }
duke@435 238 void update_slow_allocations(unsigned value) {
duke@435 239 _total_slow_allocations += value;
duke@435 240 _max_slow_allocations = MAX2(_max_slow_allocations, value);
duke@435 241 }
duke@435 242 };

mercurial