77 } |
77 } |
78 |
78 |
79 void G1DefaultAllocator::init_gc_alloc_regions(EvacuationInfo& evacuation_info) { |
79 void G1DefaultAllocator::init_gc_alloc_regions(EvacuationInfo& evacuation_info) { |
80 assert_at_safepoint(true /* should_be_vm_thread */); |
80 assert_at_safepoint(true /* should_be_vm_thread */); |
81 |
81 |
|
82 G1Allocator::init_gc_alloc_regions(evacuation_info); |
|
83 |
82 _survivor_gc_alloc_region.init(); |
84 _survivor_gc_alloc_region.init(); |
83 _old_gc_alloc_region.init(); |
85 _old_gc_alloc_region.init(); |
84 reuse_retained_old_region(evacuation_info, |
86 reuse_retained_old_region(evacuation_info, |
85 &_old_gc_alloc_region, |
87 &_old_gc_alloc_region, |
86 &_retained_old_gc_alloc_region); |
88 &_retained_old_gc_alloc_region); |
145 ShouldNotReachHere(); |
147 ShouldNotReachHere(); |
146 return NULL; // Keep some compilers happy |
148 return NULL; // Keep some compilers happy |
147 } |
149 } |
148 } |
150 } |
149 |
151 |
|
152 bool G1Allocator::survivor_is_full(AllocationContext_t context) const { |
|
153 return _survivor_is_full; |
|
154 } |
|
155 |
|
156 bool G1Allocator::old_is_full(AllocationContext_t context) const { |
|
157 return _old_is_full; |
|
158 } |
|
159 |
|
160 void G1Allocator::set_survivor_full(AllocationContext_t context) { |
|
161 _survivor_is_full = true; |
|
162 } |
|
163 |
|
164 void G1Allocator::set_old_full(AllocationContext_t context) { |
|
165 _old_is_full = true; |
|
166 } |
|
167 |
150 HeapWord* G1Allocator::survivor_attempt_allocation(size_t word_size, |
168 HeapWord* G1Allocator::survivor_attempt_allocation(size_t word_size, |
151 AllocationContext_t context) { |
169 AllocationContext_t context) { |
152 assert(!_g1h->is_humongous(word_size), |
170 assert(!_g1h->is_humongous(word_size), |
153 "we should not be seeing humongous-size allocations in this path"); |
171 "we should not be seeing humongous-size allocations in this path"); |
154 |
172 |
155 HeapWord* result = survivor_gc_alloc_region(context)->attempt_allocation(word_size, |
173 HeapWord* result = survivor_gc_alloc_region(context)->attempt_allocation(word_size, |
156 false /* bot_updates */); |
174 false /* bot_updates */); |
157 if (result == NULL) { |
175 if (result == NULL && !survivor_is_full(context)) { |
158 MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag); |
176 MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag); |
159 result = survivor_gc_alloc_region(context)->attempt_allocation_locked(word_size, |
177 result = survivor_gc_alloc_region(context)->attempt_allocation_locked(word_size, |
160 false /* bot_updates */); |
178 false /* bot_updates */); |
|
179 if (result == NULL) { |
|
180 set_survivor_full(context); |
|
181 } |
161 } |
182 } |
162 if (result != NULL) { |
183 if (result != NULL) { |
163 _g1h->dirty_young_block(result, word_size); |
184 _g1h->dirty_young_block(result, word_size); |
164 } |
185 } |
165 return result; |
186 return result; |
170 assert(!_g1h->is_humongous(word_size), |
191 assert(!_g1h->is_humongous(word_size), |
171 "we should not be seeing humongous-size allocations in this path"); |
192 "we should not be seeing humongous-size allocations in this path"); |
172 |
193 |
173 HeapWord* result = old_gc_alloc_region(context)->attempt_allocation(word_size, |
194 HeapWord* result = old_gc_alloc_region(context)->attempt_allocation(word_size, |
174 true /* bot_updates */); |
195 true /* bot_updates */); |
175 if (result == NULL) { |
196 if (result == NULL && !old_is_full(context)) { |
176 MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag); |
197 MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag); |
177 result = old_gc_alloc_region(context)->attempt_allocation_locked(word_size, |
198 result = old_gc_alloc_region(context)->attempt_allocation_locked(word_size, |
178 true /* bot_updates */); |
199 true /* bot_updates */); |
|
200 if (result == NULL) { |
|
201 set_old_full(context); |
|
202 } |
179 } |
203 } |
180 return result; |
204 return result; |
|
205 } |
|
206 |
|
207 void G1Allocator::init_gc_alloc_regions(EvacuationInfo& evacuation_info) { |
|
208 _survivor_is_full = false; |
|
209 _old_is_full = false; |
181 } |
210 } |
182 |
211 |
183 G1PLABAllocator::G1PLABAllocator(G1Allocator* allocator) : |
212 G1PLABAllocator::G1PLABAllocator(G1Allocator* allocator) : |
184 _g1h(G1CollectedHeap::heap()), |
213 _g1h(G1CollectedHeap::heap()), |
185 _allocator(allocator), |
214 _allocator(allocator), |
186 _survivor_alignment_bytes(calc_survivor_alignment_bytes()) { |
215 _survivor_alignment_bytes(calc_survivor_alignment_bytes()) { |
187 } |
216 } |
188 |
217 |
189 HeapWord* G1PLABAllocator::allocate_direct_or_new_plab(InCSetState dest, |
218 HeapWord* G1PLABAllocator::allocate_direct_or_new_plab(InCSetState dest, |
190 size_t word_sz, |
219 size_t word_sz, |
191 AllocationContext_t context) { |
220 AllocationContext_t context, |
|
221 bool* plab_refill_failed) { |
192 size_t gclab_word_size = _g1h->desired_plab_sz(dest); |
222 size_t gclab_word_size = _g1h->desired_plab_sz(dest); |
193 if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) { |
223 if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) { |
194 G1PLAB* alloc_buf = alloc_buffer(dest, context); |
224 G1PLAB* alloc_buf = alloc_buffer(dest, context); |
195 alloc_buf->retire(); |
225 alloc_buf->retire(); |
196 |
226 |
197 HeapWord* buf = _allocator->par_allocate_during_gc(dest, gclab_word_size, context); |
227 HeapWord* buf = _allocator->par_allocate_during_gc(dest, gclab_word_size, context); |
198 if (buf == NULL) { |
228 if (buf != NULL) { |
199 return NULL; // Let caller handle allocation failure. |
229 // Otherwise. |
|
230 alloc_buf->set_word_size(gclab_word_size); |
|
231 alloc_buf->set_buf(buf); |
|
232 |
|
233 HeapWord* const obj = alloc_buf->allocate(word_sz); |
|
234 assert(obj != NULL, "buffer was definitely big enough..."); |
|
235 return obj; |
200 } |
236 } |
201 // Otherwise. |
237 // Otherwise. |
202 alloc_buf->set_word_size(gclab_word_size); |
238 *plab_refill_failed = true; |
203 alloc_buf->set_buf(buf); |
239 } |
204 |
240 // Try inline allocation. |
205 HeapWord* const obj = alloc_buf->allocate(word_sz); |
241 return _allocator->par_allocate_during_gc(dest, word_sz, context); |
206 assert(obj != NULL, "buffer was definitely big enough..."); |
|
207 return obj; |
|
208 } else { |
|
209 return _allocator->par_allocate_during_gc(dest, word_sz, context); |
|
210 } |
|
211 } |
242 } |
212 |
243 |
213 void G1PLABAllocator::undo_allocation(InCSetState dest, HeapWord* obj, size_t word_sz, AllocationContext_t context) { |
244 void G1PLABAllocator::undo_allocation(InCSetState dest, HeapWord* obj, size_t word_sz, AllocationContext_t context) { |
214 alloc_buffer(dest, context)->undo_allocation(obj, word_sz); |
245 alloc_buffer(dest, context)->undo_allocation(obj, word_sz); |
215 } |
246 } |