90 global_stats()->update_allocating_threads();
91 global_stats()->update_number_of_refills(_number_of_refills);
92 global_stats()->update_allocation(_number_of_refills * desired_size());
93 global_stats()->update_gc_waste(_gc_waste);
94 global_stats()->update_slow_refill_waste(_slow_refill_waste);
95 global_stats()->update_fast_refill_waste(_fast_refill_waste);
96
97 } else {
98 assert(_number_of_refills == 0 && _fast_refill_waste == 0 &&
99 _slow_refill_waste == 0 && _gc_waste == 0,
100 "tlab stats == 0");
101 }
102 global_stats()->update_slow_allocations(_slow_allocations);
103 }
104
105 // Fills the current tlab with a dummy filler array to create
106 // an illusion of a contiguous Eden and optionally retires the tlab.
107 // Waste accounting should be done in caller as appropriate; see,
108 // for example, clear_before_allocation().
109 void ThreadLocalAllocBuffer::make_parsable(bool retire, bool zap) {
110 if (end() != NULL) {
111 invariants();
112
113 if (retire) {
114 myThread()->incr_allocated_bytes(used_bytes());
115 }
116
117 CollectedHeap::fill_with_object(top(), hard_end(), retire && zap);
118
119 if (retire || ZeroTLAB) { // "Reset" the TLAB
120 set_start(NULL);
121 set_top(NULL);
122 set_pf_top(NULL);
123 set_end(NULL);
124 }
125 }
126 assert(!(retire || ZeroTLAB) ||
127 (start() == NULL && end() == NULL && top() == NULL),
128 "TLAB must be reset");
129 }
130
131 void ThreadLocalAllocBuffer::resize_all_tlabs() {
132 if (ResizeTLAB) {
133 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
134 thread->tlab().resize();
135 }
136 }
137 }
138
139 void ThreadLocalAllocBuffer::resize() {
140 // Compute the next tlab size using expected allocation amount
141 assert(ResizeTLAB, "Should not call this otherwise");
142 size_t alloc = (size_t)(_allocation_fraction.average() *
143 (Universe::heap()->tlab_capacity(myThread()) / HeapWordSize));
144 size_t new_size = alloc / _target_refills;
145
146 new_size = MIN2(MAX2(new_size, min_size()), max_size());
147
165 }
166
167 void ThreadLocalAllocBuffer::fill(HeapWord* start,
168 HeapWord* top,
169 size_t new_size) {
170 _number_of_refills++;
171 print_stats("fill");
172 assert(top <= start + new_size - alignment_reserve(), "size too small");
173 initialize(start, top, start + new_size - alignment_reserve());
174
175 // Reset amount of internal fragmentation
176 set_refill_waste_limit(initial_refill_waste_limit());
177 }
178
179 void ThreadLocalAllocBuffer::initialize(HeapWord* start,
180 HeapWord* top,
181 HeapWord* end) {
182 set_start(start);
183 set_top(top);
184 set_pf_top(top);
185 set_end(end);
186 invariants();
187 }
188
189 void ThreadLocalAllocBuffer::initialize() {
190 initialize(NULL, // start
191 NULL, // top
192 NULL); // end
193
194 set_desired_size(initial_desired_size());
195
196 // Following check is needed because at startup the main
197 // thread is initialized before the heap is. The initialization for
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());
|
90 global_stats()->update_allocating_threads();
91 global_stats()->update_number_of_refills(_number_of_refills);
92 global_stats()->update_allocation(_number_of_refills * desired_size());
93 global_stats()->update_gc_waste(_gc_waste);
94 global_stats()->update_slow_refill_waste(_slow_refill_waste);
95 global_stats()->update_fast_refill_waste(_fast_refill_waste);
96
97 } else {
98 assert(_number_of_refills == 0 && _fast_refill_waste == 0 &&
99 _slow_refill_waste == 0 && _gc_waste == 0,
100 "tlab stats == 0");
101 }
102 global_stats()->update_slow_allocations(_slow_allocations);
103 }
104
105 // Fills the current tlab with a dummy filler array to create
106 // an illusion of a contiguous Eden and optionally retires the tlab.
107 // Waste accounting should be done in caller as appropriate; see,
108 // for example, clear_before_allocation().
109 void ThreadLocalAllocBuffer::make_parsable(bool retire, bool zap) {
110 if (fast_path_end() != NULL) {
111 invariants();
112
113 if (retire) {
114 myThread()->incr_allocated_bytes(used_bytes());
115 }
116
117 CollectedHeap::fill_with_object(top(), hard_end(), retire && zap);
118
119 if (retire || ZeroTLAB) { // "Reset" the TLAB
120 set_start(NULL);
121 set_top(NULL);
122 set_pf_top(NULL);
123 set_fast_path_end(NULL);
124 }
125 }
126 assert(!(retire || ZeroTLAB) ||
127 (start() == NULL && fast_path_end() == NULL && top() == NULL),
128 "TLAB must be reset");
129 }
130
131 void ThreadLocalAllocBuffer::resize_all_tlabs() {
132 if (ResizeTLAB) {
133 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
134 thread->tlab().resize();
135 }
136 }
137 }
138
139 void ThreadLocalAllocBuffer::resize() {
140 // Compute the next tlab size using expected allocation amount
141 assert(ResizeTLAB, "Should not call this otherwise");
142 size_t alloc = (size_t)(_allocation_fraction.average() *
143 (Universe::heap()->tlab_capacity(myThread()) / HeapWordSize));
144 size_t new_size = alloc / _target_refills;
145
146 new_size = MIN2(MAX2(new_size, min_size()), max_size());
147
165 }
166
167 void ThreadLocalAllocBuffer::fill(HeapWord* start,
168 HeapWord* top,
169 size_t new_size) {
170 _number_of_refills++;
171 print_stats("fill");
172 assert(top <= start + new_size - alignment_reserve(), "size too small");
173 initialize(start, top, start + new_size - alignment_reserve());
174
175 // Reset amount of internal fragmentation
176 set_refill_waste_limit(initial_refill_waste_limit());
177 }
178
179 void ThreadLocalAllocBuffer::initialize(HeapWord* start,
180 HeapWord* top,
181 HeapWord* end) {
182 set_start(start);
183 set_top(top);
184 set_pf_top(top);
185 set_fast_path_end(end);
186 invariants();
187 }
188
189 void ThreadLocalAllocBuffer::initialize() {
190 initialize(NULL, // start
191 NULL, // top
192 NULL); // end
193
194 set_desired_size(initial_desired_size());
195
196 // Following check is needed because at startup the main
197 // thread is initialized before the heap is. The initialization for
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());
|