26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCATOR_HPP |
26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCATOR_HPP |
27 |
27 |
28 #include "gc_implementation/g1/g1AllocationContext.hpp" |
28 #include "gc_implementation/g1/g1AllocationContext.hpp" |
29 #include "gc_implementation/g1/g1AllocRegion.hpp" |
29 #include "gc_implementation/g1/g1AllocRegion.hpp" |
30 #include "gc_implementation/g1/g1InCSetState.hpp" |
30 #include "gc_implementation/g1/g1InCSetState.hpp" |
31 #include "gc_implementation/shared/parGCAllocBuffer.hpp" |
31 #include "gc_implementation/shared/plab.hpp" |
32 #include "gc_interface/collectedHeap.hpp" |
32 #include "gc_interface/collectedHeap.hpp" |
33 |
33 |
34 class EvacuationInfo; |
34 class EvacuationInfo; |
35 |
35 |
36 // Base class for G1 allocators. |
36 // Base class for G1 allocators. |
145 } |
145 } |
146 return result; |
146 return result; |
147 } |
147 } |
148 }; |
148 }; |
149 |
149 |
150 class G1ParGCAllocBuffer: public ParGCAllocBuffer { |
150 class G1PLAB: public PLAB { |
151 private: |
151 private: |
152 bool _retired; |
152 bool _retired; |
153 |
153 |
154 public: |
154 public: |
155 G1ParGCAllocBuffer(size_t gclab_word_size); |
155 G1PLAB(size_t gclab_word_size); |
156 virtual ~G1ParGCAllocBuffer() { |
156 virtual ~G1PLAB() { |
157 guarantee(_retired, "Allocation buffer has not been retired"); |
157 guarantee(_retired, "Allocation buffer has not been retired"); |
158 } |
158 } |
159 |
159 |
160 virtual void set_buf(HeapWord* buf) { |
160 virtual void set_buf(HeapWord* buf) { |
161 ParGCAllocBuffer::set_buf(buf); |
161 PLAB::set_buf(buf); |
162 _retired = false; |
162 _retired = false; |
163 } |
163 } |
164 |
164 |
165 virtual void retire() { |
165 virtual void retire() { |
166 if (_retired) { |
166 if (_retired) { |
167 return; |
167 return; |
168 } |
168 } |
169 ParGCAllocBuffer::retire(); |
169 PLAB::retire(); |
170 _retired = true; |
170 _retired = true; |
171 } |
171 } |
172 }; |
172 }; |
173 |
173 |
174 class G1ParGCAllocator : public CHeapObj<mtGC> { |
174 class G1ParGCAllocator : public CHeapObj<mtGC> { |
188 |
188 |
189 void add_to_alloc_buffer_waste(size_t waste) { _alloc_buffer_waste += waste; } |
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; } |
190 void add_to_undo_waste(size_t waste) { _undo_waste += waste; } |
191 |
191 |
192 virtual void retire_alloc_buffers() = 0; |
192 virtual void retire_alloc_buffers() = 0; |
193 virtual G1ParGCAllocBuffer* alloc_buffer(InCSetState dest, AllocationContext_t context) = 0; |
193 virtual G1PLAB* alloc_buffer(InCSetState dest, AllocationContext_t context) = 0; |
194 |
194 |
195 // Calculate the survivor space object alignment in bytes. Returns that or 0 if |
195 // Calculate the survivor space object alignment in bytes. Returns that or 0 if |
196 // there are no restrictions on survivor alignment. |
196 // there are no restrictions on survivor alignment. |
197 static uint calc_survivor_alignment_bytes() { |
197 static uint calc_survivor_alignment_bytes() { |
198 assert(SurvivorAlignmentInBytes >= ObjectAlignmentInBytes, "sanity"); |
198 assert(SurvivorAlignmentInBytes >= ObjectAlignmentInBytes, "sanity"); |
227 // Allocate word_sz words in the PLAB of dest. Returns the address of the |
227 // Allocate word_sz words in the PLAB of dest. Returns the address of the |
228 // allocated memory, NULL if not successful. |
228 // allocated memory, NULL if not successful. |
229 HeapWord* plab_allocate(InCSetState dest, |
229 HeapWord* plab_allocate(InCSetState dest, |
230 size_t word_sz, |
230 size_t word_sz, |
231 AllocationContext_t context) { |
231 AllocationContext_t context) { |
232 G1ParGCAllocBuffer* buffer = alloc_buffer(dest, context); |
232 G1PLAB* buffer = alloc_buffer(dest, context); |
233 if (_survivor_alignment_bytes == 0) { |
233 if (_survivor_alignment_bytes == 0) { |
234 return buffer->allocate(word_sz); |
234 return buffer->allocate(word_sz); |
235 } else { |
235 } else { |
236 return buffer->allocate_aligned(word_sz, _survivor_alignment_bytes); |
236 return buffer->allocate_aligned(word_sz, _survivor_alignment_bytes); |
237 } |
237 } |
257 } |
257 } |
258 } |
258 } |
259 }; |
259 }; |
260 |
260 |
261 class G1DefaultParGCAllocator : public G1ParGCAllocator { |
261 class G1DefaultParGCAllocator : public G1ParGCAllocator { |
262 G1ParGCAllocBuffer _surviving_alloc_buffer; |
262 G1PLAB _surviving_alloc_buffer; |
263 G1ParGCAllocBuffer _tenured_alloc_buffer; |
263 G1PLAB _tenured_alloc_buffer; |
264 G1ParGCAllocBuffer* _alloc_buffers[InCSetState::Num]; |
264 G1PLAB* _alloc_buffers[InCSetState::Num]; |
265 |
265 |
266 public: |
266 public: |
267 G1DefaultParGCAllocator(G1CollectedHeap* g1h); |
267 G1DefaultParGCAllocator(G1CollectedHeap* g1h); |
268 |
268 |
269 virtual G1ParGCAllocBuffer* alloc_buffer(InCSetState dest, AllocationContext_t context) { |
269 virtual G1PLAB* alloc_buffer(InCSetState dest, AllocationContext_t context) { |
270 assert(dest.is_valid(), |
270 assert(dest.is_valid(), |
271 err_msg("Allocation buffer index out-of-bounds: " CSETSTATE_FORMAT, dest.value())); |
271 err_msg("Allocation buffer index out-of-bounds: " CSETSTATE_FORMAT, dest.value())); |
272 assert(_alloc_buffers[dest.value()] != NULL, |
272 assert(_alloc_buffers[dest.value()] != NULL, |
273 err_msg("Allocation buffer is NULL: " CSETSTATE_FORMAT, dest.value())); |
273 err_msg("Allocation buffer is NULL: " CSETSTATE_FORMAT, dest.value())); |
274 return _alloc_buffers[dest.value()]; |
274 return _alloc_buffers[dest.value()]; |