166 if (_retired) {
167 return;
168 }
169 PLAB::retire();
170 _retired = true;
171 }
172 };
173
174 class G1ParGCAllocator : public CHeapObj<mtGC> {
175 friend class G1ParScanThreadState;
176 protected:
177 G1CollectedHeap* _g1h;
178
179 // The survivor alignment in effect in bytes.
180 // == 0 : don't align survivors
181 // != 0 : align survivors to that alignment
182 // These values were chosen to favor the non-alignment case since some
183 // architectures have a special compare against zero instructions.
184 const uint _survivor_alignment_bytes;
185
186 size_t _alloc_buffer_waste;
187 size_t _undo_waste;
188
189 void add_to_alloc_buffer_waste(size_t waste) { _alloc_buffer_waste += waste; }
190 void add_to_undo_waste(size_t waste) { _undo_waste += waste; }
191
192 virtual void retire_alloc_buffers() = 0;
193 virtual G1PLAB* alloc_buffer(InCSetState dest, AllocationContext_t context) = 0;
194
195 // Calculate the survivor space object alignment in bytes. Returns that or 0 if
196 // there are no restrictions on survivor alignment.
197 static uint calc_survivor_alignment_bytes() {
198 assert(SurvivorAlignmentInBytes >= ObjectAlignmentInBytes, "sanity");
199 if (SurvivorAlignmentInBytes == ObjectAlignmentInBytes) {
200 // No need to align objects in the survivors differently, return 0
201 // which means "survivor alignment is not used".
202 return 0;
203 } else {
204 assert(SurvivorAlignmentInBytes > 0, "sanity");
205 return SurvivorAlignmentInBytes;
206 }
207 }
208
209 public:
210 G1ParGCAllocator(G1CollectedHeap* g1h) :
211 _g1h(g1h), _survivor_alignment_bytes(calc_survivor_alignment_bytes()),
212 _alloc_buffer_waste(0), _undo_waste(0) {
213 }
214
215 static G1ParGCAllocator* create_allocator(G1CollectedHeap* g1h);
216
217 size_t alloc_buffer_waste() { return _alloc_buffer_waste; }
218 size_t undo_waste() {return _undo_waste; }
219
220 // Allocate word_sz words in dest, either directly into the regions or by
221 // allocating a new PLAB. Returns the address of the allocated memory, NULL if
222 // not successful.
223 HeapWord* allocate_direct_or_new_plab(InCSetState dest,
224 size_t word_sz,
225 AllocationContext_t context);
226
227 // Allocate word_sz words in the PLAB of dest. Returns the address of the
228 // allocated memory, NULL if not successful.
229 HeapWord* plab_allocate(InCSetState dest,
230 size_t word_sz,
231 AllocationContext_t context) {
232 G1PLAB* buffer = alloc_buffer(dest, context);
233 if (_survivor_alignment_bytes == 0) {
234 return buffer->allocate(word_sz);
235 } else {
236 return buffer->allocate_aligned(word_sz, _survivor_alignment_bytes);
237 }
238 }
239
240 HeapWord* allocate(InCSetState dest, size_t word_sz,
241 AllocationContext_t context) {
242 HeapWord* const obj = plab_allocate(dest, word_sz, context);
243 if (obj != NULL) {
244 return obj;
245 }
246 return allocate_direct_or_new_plab(dest, word_sz, context);
247 }
248
249 void undo_allocation(InCSetState dest, HeapWord* obj, size_t word_sz, AllocationContext_t context) {
250 if (alloc_buffer(dest, context)->contains(obj)) {
251 assert(alloc_buffer(dest, context)->contains(obj + word_sz - 1),
252 "should contain whole object");
253 alloc_buffer(dest, context)->undo_allocation(obj, word_sz);
254 } else {
255 CollectedHeap::fill_with_object(obj, word_sz);
256 add_to_undo_waste(word_sz);
257 }
258 }
259 };
260
261 class G1DefaultParGCAllocator : public G1ParGCAllocator {
262 G1PLAB _surviving_alloc_buffer;
263 G1PLAB _tenured_alloc_buffer;
264 G1PLAB* _alloc_buffers[InCSetState::Num];
265
266 public:
267 G1DefaultParGCAllocator(G1CollectedHeap* g1h);
268
269 virtual G1PLAB* alloc_buffer(InCSetState dest, AllocationContext_t context) {
270 assert(dest.is_valid(),
271 err_msg("Allocation buffer index out-of-bounds: " CSETSTATE_FORMAT, dest.value()));
272 assert(_alloc_buffers[dest.value()] != NULL,
273 err_msg("Allocation buffer is NULL: " CSETSTATE_FORMAT, dest.value()));
274 return _alloc_buffers[dest.value()];
275 }
276
277 virtual void retire_alloc_buffers() ;
278 };
279
280 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCATOR_HPP
|
166 if (_retired) {
167 return;
168 }
169 PLAB::retire();
170 _retired = true;
171 }
172 };
173
174 class G1ParGCAllocator : public CHeapObj<mtGC> {
175 friend class G1ParScanThreadState;
176 protected:
177 G1CollectedHeap* _g1h;
178
179 // The survivor alignment in effect in bytes.
180 // == 0 : don't align survivors
181 // != 0 : align survivors to that alignment
182 // These values were chosen to favor the non-alignment case since some
183 // architectures have a special compare against zero instructions.
184 const uint _survivor_alignment_bytes;
185
186 virtual void retire_alloc_buffers() = 0;
187 virtual G1PLAB* alloc_buffer(InCSetState dest, AllocationContext_t context) = 0;
188
189 // Calculate the survivor space object alignment in bytes. Returns that or 0 if
190 // there are no restrictions on survivor alignment.
191 static uint calc_survivor_alignment_bytes() {
192 assert(SurvivorAlignmentInBytes >= ObjectAlignmentInBytes, "sanity");
193 if (SurvivorAlignmentInBytes == ObjectAlignmentInBytes) {
194 // No need to align objects in the survivors differently, return 0
195 // which means "survivor alignment is not used".
196 return 0;
197 } else {
198 assert(SurvivorAlignmentInBytes > 0, "sanity");
199 return SurvivorAlignmentInBytes;
200 }
201 }
202
203 public:
204 G1ParGCAllocator(G1CollectedHeap* g1h) :
205 _g1h(g1h), _survivor_alignment_bytes(calc_survivor_alignment_bytes()) {
206 }
207
208 static G1ParGCAllocator* create_allocator(G1CollectedHeap* g1h);
209
210 virtual void waste(size_t& wasted, size_t& undo_wasted) = 0;
211
212 // Allocate word_sz words in dest, either directly into the regions or by
213 // allocating a new PLAB. Returns the address of the allocated memory, NULL if
214 // not successful.
215 HeapWord* allocate_direct_or_new_plab(InCSetState dest,
216 size_t word_sz,
217 AllocationContext_t context);
218
219 // Allocate word_sz words in the PLAB of dest. Returns the address of the
220 // allocated memory, NULL if not successful.
221 HeapWord* plab_allocate(InCSetState dest,
222 size_t word_sz,
223 AllocationContext_t context) {
224 G1PLAB* buffer = alloc_buffer(dest, context);
225 if (_survivor_alignment_bytes == 0) {
226 return buffer->allocate(word_sz);
227 } else {
228 return buffer->allocate_aligned(word_sz, _survivor_alignment_bytes);
229 }
230 }
231
232 HeapWord* allocate(InCSetState dest, size_t word_sz,
233 AllocationContext_t context) {
234 HeapWord* const obj = plab_allocate(dest, word_sz, context);
235 if (obj != NULL) {
236 return obj;
237 }
238 return allocate_direct_or_new_plab(dest, word_sz, context);
239 }
240
241 void undo_allocation(InCSetState dest, HeapWord* obj, size_t word_sz, AllocationContext_t context) {
242 alloc_buffer(dest, context)->undo_allocation(obj, word_sz);
243 }
244 };
245
246 class G1DefaultParGCAllocator : public G1ParGCAllocator {
247 G1PLAB _surviving_alloc_buffer;
248 G1PLAB _tenured_alloc_buffer;
249 G1PLAB* _alloc_buffers[InCSetState::Num];
250
251 public:
252 G1DefaultParGCAllocator(G1CollectedHeap* g1h);
253
254 virtual G1PLAB* alloc_buffer(InCSetState dest, AllocationContext_t context) {
255 assert(dest.is_valid(),
256 err_msg("Allocation buffer index out-of-bounds: " CSETSTATE_FORMAT, dest.value()));
257 assert(_alloc_buffers[dest.value()] != NULL,
258 err_msg("Allocation buffer is NULL: " CSETSTATE_FORMAT, dest.value()));
259 return _alloc_buffers[dest.value()];
260 }
261
262 virtual void retire_alloc_buffers();
263
264 virtual void waste(size_t& wasted, size_t& undo_wasted);
265 };
266
267 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCATOR_HPP
|