21 * questions.
22 *
23 */
24
25 #ifndef SHARE_VM_GC_G1_G1ALLOCATOR_HPP
26 #define SHARE_VM_GC_G1_G1ALLOCATOR_HPP
27
28 #include "gc/g1/g1AllocRegion.hpp"
29 #include "gc/g1/g1AllocationContext.hpp"
30 #include "gc/g1/g1InCSetState.hpp"
31 #include "gc/shared/collectedHeap.hpp"
32 #include "gc/shared/plab.hpp"
33
34 class EvacuationInfo;
35
36 // Interface to keep track of which regions G1 is currently allocating into. Provides
37 // some accessors (e.g. allocating into them, or getting their occupancy).
38 // Also keeps track of retained regions across GCs.
39 class G1Allocator : public CHeapObj<mtGC> {
40 friend class VMStructs;
41 protected:
42 G1CollectedHeap* _g1h;
43
44 virtual MutatorAllocRegion* mutator_alloc_region(AllocationContext_t context) = 0;
45
46 // Accessors to the allocation regions.
47 virtual SurvivorGCAllocRegion* survivor_gc_alloc_region(AllocationContext_t context) = 0;
48 virtual OldGCAllocRegion* old_gc_alloc_region(AllocationContext_t context) = 0;
49
50 // Allocation attempt during GC for a survivor object / PLAB.
51 inline HeapWord* survivor_attempt_allocation(size_t word_size,
52 AllocationContext_t context);
53 // Allocation attempt during GC for an old object / PLAB.
54 inline HeapWord* old_attempt_allocation(size_t word_size,
55 AllocationContext_t context);
56 public:
57 G1Allocator(G1CollectedHeap* heap) : _g1h(heap) { }
58 virtual ~G1Allocator() { }
59
60 static G1Allocator* create_allocator(G1CollectedHeap* g1h);
61
62 #ifdef ASSERT
63 // Do we currently have an active mutator region to allocate into?
64 bool has_mutator_alloc_region(AllocationContext_t context) { return mutator_alloc_region(context)->get() != NULL; }
65 #endif
66 virtual void init_mutator_alloc_region() = 0;
67 virtual void release_mutator_alloc_region() = 0;
68
69 virtual void init_gc_alloc_regions(EvacuationInfo& evacuation_info) = 0;
70 virtual void release_gc_alloc_regions(EvacuationInfo& evacuation_info) = 0;
71 virtual void abandon_gc_alloc_regions() = 0;
72
73 // Management of retained regions.
74
75 virtual bool is_retained_old_region(HeapRegion* hr) = 0;
76 void reuse_retained_old_region(EvacuationInfo& evacuation_info,
77 OldGCAllocRegion* old,
78 HeapRegion** retained);
79
80 // Allocate blocks of memory during mutator time.
81
82 inline HeapWord* attempt_allocation(size_t word_size, AllocationContext_t context);
83 inline HeapWord* attempt_allocation_locked(size_t word_size, AllocationContext_t context);
84 inline HeapWord* attempt_allocation_force(size_t word_size, AllocationContext_t context);
85
86 size_t unsafe_max_tlab_alloc(AllocationContext_t context);
87
88 // Allocate blocks of memory during garbage collection. Will ensure an
89 // allocation region, either by picking one or expanding the
206 static uint calc_survivor_alignment_bytes() {
207 assert(SurvivorAlignmentInBytes >= ObjectAlignmentInBytes, "sanity");
208 if (SurvivorAlignmentInBytes == ObjectAlignmentInBytes) {
209 // No need to align objects in the survivors differently, return 0
210 // which means "survivor alignment is not used".
211 return 0;
212 } else {
213 assert(SurvivorAlignmentInBytes > 0, "sanity");
214 return SurvivorAlignmentInBytes;
215 }
216 }
217
218 public:
219 G1PLABAllocator(G1Allocator* allocator);
220 virtual ~G1PLABAllocator() { }
221
222 static G1PLABAllocator* create_allocator(G1Allocator* allocator);
223
224 virtual void waste(size_t& wasted, size_t& undo_wasted) = 0;
225
226 // Allocate word_sz words in dest, either directly into the regions or by
227 // allocating a new PLAB. Returns the address of the allocated memory, NULL if
228 // not successful.
229 HeapWord* allocate_direct_or_new_plab(InCSetState dest,
230 size_t word_sz,
231 AllocationContext_t context);
232
233 // Allocate word_sz words in the PLAB of dest. Returns the address of the
234 // allocated memory, NULL if not successful.
235 HeapWord* plab_allocate(InCSetState dest,
236 size_t word_sz,
237 AllocationContext_t context) {
238 G1PLAB* buffer = alloc_buffer(dest, context);
239 if (_survivor_alignment_bytes == 0 || !dest.is_young()) {
240 return buffer->allocate(word_sz);
241 } else {
242 return buffer->allocate_aligned(word_sz, _survivor_alignment_bytes);
243 }
244 }
245
246 HeapWord* allocate(InCSetState dest, size_t word_sz,
247 AllocationContext_t context) {
248 HeapWord* const obj = plab_allocate(dest, word_sz, context);
249 if (obj != NULL) {
250 return obj;
251 }
252 return allocate_direct_or_new_plab(dest, word_sz, context);
253 }
254
255 void undo_allocation(InCSetState dest, HeapWord* obj, size_t word_sz, AllocationContext_t context);
256 };
257
258 // The default PLAB allocator for G1. Keeps the current (single) PLAB for survivor
259 // and old generation allocation.
260 class G1DefaultPLABAllocator : public G1PLABAllocator {
261 G1PLAB _surviving_alloc_buffer;
262 G1PLAB _tenured_alloc_buffer;
263 G1PLAB* _alloc_buffers[InCSetState::Num];
264
265 public:
266 G1DefaultPLABAllocator(G1Allocator* _allocator);
267
268 virtual G1PLAB* alloc_buffer(InCSetState dest, AllocationContext_t context) {
269 assert(dest.is_valid(),
270 err_msg("Allocation buffer index out-of-bounds: " CSETSTATE_FORMAT, dest.value()));
271 assert(_alloc_buffers[dest.value()] != NULL,
272 err_msg("Allocation buffer is NULL: " CSETSTATE_FORMAT, dest.value()));
|
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_VM_GC_G1_G1ALLOCATOR_HPP
26 #define SHARE_VM_GC_G1_G1ALLOCATOR_HPP
27
28 #include "gc/g1/g1AllocRegion.hpp"
29 #include "gc/g1/g1AllocationContext.hpp"
30 #include "gc/g1/g1InCSetState.hpp"
31 #include "gc/shared/collectedHeap.hpp"
32 #include "gc/shared/plab.hpp"
33
34 class EvacuationInfo;
35
36 // Interface to keep track of which regions G1 is currently allocating into. Provides
37 // some accessors (e.g. allocating into them, or getting their occupancy).
38 // Also keeps track of retained regions across GCs.
39 class G1Allocator : public CHeapObj<mtGC> {
40 friend class VMStructs;
41 private:
42 bool _survivor_is_full;
43 bool _old_is_full;
44 protected:
45 G1CollectedHeap* _g1h;
46
47 virtual MutatorAllocRegion* mutator_alloc_region(AllocationContext_t context) = 0;
48
49 virtual bool survivor_is_full(AllocationContext_t context) const;
50 virtual bool old_is_full(AllocationContext_t context) const;
51
52 virtual void set_survivor_full(AllocationContext_t context);
53 virtual void set_old_full(AllocationContext_t context);
54
55 // Accessors to the allocation regions.
56 virtual SurvivorGCAllocRegion* survivor_gc_alloc_region(AllocationContext_t context) = 0;
57 virtual OldGCAllocRegion* old_gc_alloc_region(AllocationContext_t context) = 0;
58
59 // Allocation attempt during GC for a survivor object / PLAB.
60 inline HeapWord* survivor_attempt_allocation(size_t word_size,
61 AllocationContext_t context);
62 // Allocation attempt during GC for an old object / PLAB.
63 inline HeapWord* old_attempt_allocation(size_t word_size,
64 AllocationContext_t context);
65 public:
66 G1Allocator(G1CollectedHeap* heap) : _g1h(heap), _survivor_is_full(false), _old_is_full(false) { }
67 virtual ~G1Allocator() { }
68
69 static G1Allocator* create_allocator(G1CollectedHeap* g1h);
70
71 #ifdef ASSERT
72 // Do we currently have an active mutator region to allocate into?
73 bool has_mutator_alloc_region(AllocationContext_t context) { return mutator_alloc_region(context)->get() != NULL; }
74 #endif
75 virtual void init_mutator_alloc_region() = 0;
76 virtual void release_mutator_alloc_region() = 0;
77
78 virtual void init_gc_alloc_regions(EvacuationInfo& evacuation_info);
79 virtual void release_gc_alloc_regions(EvacuationInfo& evacuation_info) = 0;
80 virtual void abandon_gc_alloc_regions() = 0;
81
82 // Management of retained regions.
83
84 virtual bool is_retained_old_region(HeapRegion* hr) = 0;
85 void reuse_retained_old_region(EvacuationInfo& evacuation_info,
86 OldGCAllocRegion* old,
87 HeapRegion** retained);
88
89 // Allocate blocks of memory during mutator time.
90
91 inline HeapWord* attempt_allocation(size_t word_size, AllocationContext_t context);
92 inline HeapWord* attempt_allocation_locked(size_t word_size, AllocationContext_t context);
93 inline HeapWord* attempt_allocation_force(size_t word_size, AllocationContext_t context);
94
95 size_t unsafe_max_tlab_alloc(AllocationContext_t context);
96
97 // Allocate blocks of memory during garbage collection. Will ensure an
98 // allocation region, either by picking one or expanding the
215 static uint calc_survivor_alignment_bytes() {
216 assert(SurvivorAlignmentInBytes >= ObjectAlignmentInBytes, "sanity");
217 if (SurvivorAlignmentInBytes == ObjectAlignmentInBytes) {
218 // No need to align objects in the survivors differently, return 0
219 // which means "survivor alignment is not used".
220 return 0;
221 } else {
222 assert(SurvivorAlignmentInBytes > 0, "sanity");
223 return SurvivorAlignmentInBytes;
224 }
225 }
226
227 public:
228 G1PLABAllocator(G1Allocator* allocator);
229 virtual ~G1PLABAllocator() { }
230
231 static G1PLABAllocator* create_allocator(G1Allocator* allocator);
232
233 virtual void waste(size_t& wasted, size_t& undo_wasted) = 0;
234
235 // Allocate word_sz words in dest, either directly into the regions (inline) or by
236 // allocating a new PLAB. Returns the address of the allocated memory, NULL if
237 // not successful. Plab_refill_failed indicates whether an attempt to refill the
238 // PLAB failed or not.
239 HeapWord* allocate_inline_or_new_plab(InCSetState dest,
240 size_t word_sz,
241 AllocationContext_t context,
242 bool* plab_refill_failed);
243
244 // Allocate word_sz words in the PLAB of dest. Returns the address of the
245 // allocated memory, NULL if not successful.
246 HeapWord* plab_allocate(InCSetState dest,
247 size_t word_sz,
248 AllocationContext_t context) {
249 G1PLAB* buffer = alloc_buffer(dest, context);
250 if (_survivor_alignment_bytes == 0 || !dest.is_young()) {
251 return buffer->allocate(word_sz);
252 } else {
253 return buffer->allocate_aligned(word_sz, _survivor_alignment_bytes);
254 }
255 }
256
257 HeapWord* allocate(InCSetState dest,
258 size_t word_sz,
259 AllocationContext_t context,
260 bool* refill_failed) {
261 HeapWord* const obj = plab_allocate(dest, word_sz, context);
262 if (obj != NULL) {
263 return obj;
264 }
265 return allocate_inline_or_new_plab(dest, word_sz, context, refill_failed);
266 }
267
268 void undo_allocation(InCSetState dest, HeapWord* obj, size_t word_sz, AllocationContext_t context);
269 };
270
271 // The default PLAB allocator for G1. Keeps the current (single) PLAB for survivor
272 // and old generation allocation.
273 class G1DefaultPLABAllocator : public G1PLABAllocator {
274 G1PLAB _surviving_alloc_buffer;
275 G1PLAB _tenured_alloc_buffer;
276 G1PLAB* _alloc_buffers[InCSetState::Num];
277
278 public:
279 G1DefaultPLABAllocator(G1Allocator* _allocator);
280
281 virtual G1PLAB* alloc_buffer(InCSetState dest, AllocationContext_t context) {
282 assert(dest.is_valid(),
283 err_msg("Allocation buffer index out-of-bounds: " CSETSTATE_FORMAT, dest.value()));
284 assert(_alloc_buffers[dest.value()] != NULL,
285 err_msg("Allocation buffer is NULL: " CSETSTATE_FORMAT, dest.value()));
|