57 _stack_trim_lower_threshold(GCDrainStackTargetSize), |
57 _stack_trim_lower_threshold(GCDrainStackTargetSize), |
58 _trim_ticks(), |
58 _trim_ticks(), |
59 _old_gen_is_full(false), |
59 _old_gen_is_full(false), |
60 _num_optional_regions(optional_cset_length) |
60 _num_optional_regions(optional_cset_length) |
61 { |
61 { |
62 // we allocate G1YoungSurvRateNumRegions plus one entries, since |
62 // We allocate number of young gen regions in the collection set plus one |
63 // we "sacrifice" entry 0 to keep track of surviving bytes for |
63 // entries, since entry 0 keeps track of surviving bytes for non-young regions. |
64 // non-young regions (where the age is -1) |
|
65 // We also add a few elements at the beginning and at the end in |
64 // We also add a few elements at the beginning and at the end in |
66 // an attempt to eliminate cache contention |
65 // an attempt to eliminate cache contention |
67 size_t real_length = 1 + young_cset_length; |
66 size_t real_length = young_cset_length + 1; |
68 size_t array_length = PADDING_ELEM_NUM + |
67 size_t array_length = PADDING_ELEM_NUM + real_length + PADDING_ELEM_NUM; |
69 real_length + |
|
70 PADDING_ELEM_NUM; |
|
71 _surviving_young_words_base = NEW_C_HEAP_ARRAY(size_t, array_length, mtGC); |
68 _surviving_young_words_base = NEW_C_HEAP_ARRAY(size_t, array_length, mtGC); |
72 if (_surviving_young_words_base == NULL) |
|
73 vm_exit_out_of_memory(array_length * sizeof(size_t), OOM_MALLOC_ERROR, |
|
74 "Not enough space for young surv histo."); |
|
75 _surviving_young_words = _surviving_young_words_base + PADDING_ELEM_NUM; |
69 _surviving_young_words = _surviving_young_words_base + PADDING_ELEM_NUM; |
76 memset(_surviving_young_words, 0, real_length * sizeof(size_t)); |
70 memset(_surviving_young_words, 0, real_length * sizeof(size_t)); |
77 |
71 |
78 _plab_allocator = new G1PLABAllocator(_g1h->allocator()); |
72 _plab_allocator = new G1PLABAllocator(_g1h->allocator()); |
79 |
73 |
92 _rdcq.flush(); |
86 _rdcq.flush(); |
93 // Update allocation statistics. |
87 // Update allocation statistics. |
94 _plab_allocator->flush_and_retire_stats(); |
88 _plab_allocator->flush_and_retire_stats(); |
95 _g1h->policy()->record_age_table(&_age_table); |
89 _g1h->policy()->record_age_table(&_age_table); |
96 |
90 |
97 uint length = _g1h->collection_set()->young_region_length(); |
91 uint length = _g1h->collection_set()->young_region_length() + 1; |
98 for (uint region_index = 0; region_index < length; region_index++) { |
92 for (uint i = 0; i < length; i++) { |
99 surviving_young_words[region_index] += _surviving_young_words[region_index]; |
93 surviving_young_words[i] += _surviving_young_words[i]; |
100 } |
94 } |
101 } |
95 } |
102 |
96 |
103 G1ParScanThreadState::~G1ParScanThreadState() { |
97 G1ParScanThreadState::~G1ParScanThreadState() { |
104 delete _plab_allocator; |
98 delete _plab_allocator; |
224 |
218 |
225 oop G1ParScanThreadState::copy_to_survivor_space(G1HeapRegionAttr const region_attr, |
219 oop G1ParScanThreadState::copy_to_survivor_space(G1HeapRegionAttr const region_attr, |
226 oop const old, |
220 oop const old, |
227 markWord const old_mark) { |
221 markWord const old_mark) { |
228 const size_t word_sz = old->size(); |
222 const size_t word_sz = old->size(); |
229 HeapRegion* const from_region = _g1h->heap_region_containing(old); |
|
230 // +1 to make the -1 indexes valid... |
|
231 const int young_index = from_region->young_index_in_cset()+1; |
|
232 assert( (from_region->is_young() && young_index > 0) || |
|
233 (!from_region->is_young() && young_index == 0), "invariant" ); |
|
234 |
223 |
235 uint age = 0; |
224 uint age = 0; |
236 G1HeapRegionAttr dest_attr = next_region_attr(region_attr, old_mark, age); |
225 G1HeapRegionAttr dest_attr = next_region_attr(region_attr, old_mark, age); |
237 // The second clause is to prevent premature evacuation failure in case there |
226 // The second clause is to prevent premature evacuation failure in case there |
238 // is still space in survivor, but old gen is full. |
227 // is still space in survivor, but old gen is full. |
278 |
267 |
279 const oop obj = oop(obj_ptr); |
268 const oop obj = oop(obj_ptr); |
280 const oop forward_ptr = old->forward_to_atomic(obj, old_mark, memory_order_relaxed); |
269 const oop forward_ptr = old->forward_to_atomic(obj, old_mark, memory_order_relaxed); |
281 if (forward_ptr == NULL) { |
270 if (forward_ptr == NULL) { |
282 Copy::aligned_disjoint_words((HeapWord*) old, obj_ptr, word_sz); |
271 Copy::aligned_disjoint_words((HeapWord*) old, obj_ptr, word_sz); |
|
272 |
|
273 HeapRegion* const from_region = _g1h->heap_region_containing(old); |
|
274 const uint young_index = from_region->young_index_in_cset(); |
|
275 |
|
276 assert((from_region->is_young() && young_index > 0) || |
|
277 (!from_region->is_young() && young_index == 0), "invariant" ); |
283 |
278 |
284 if (dest_attr.is_young()) { |
279 if (dest_attr.is_young()) { |
285 if (age < markWord::max_age) { |
280 if (age < markWord::max_age) { |
286 age++; |
281 age++; |
287 } |
282 } |
301 } |
296 } |
302 |
297 |
303 if (G1StringDedup::is_enabled()) { |
298 if (G1StringDedup::is_enabled()) { |
304 const bool is_from_young = region_attr.is_young(); |
299 const bool is_from_young = region_attr.is_young(); |
305 const bool is_to_young = dest_attr.is_young(); |
300 const bool is_to_young = dest_attr.is_young(); |
306 assert(is_from_young == _g1h->heap_region_containing(old)->is_young(), |
301 assert(is_from_young == from_region->is_young(), |
307 "sanity"); |
302 "sanity"); |
308 assert(is_to_young == _g1h->heap_region_containing(obj)->is_young(), |
303 assert(is_to_young == _g1h->heap_region_containing(obj)->is_young(), |
309 "sanity"); |
304 "sanity"); |
310 G1StringDedup::enqueue_from_evacuation(is_from_young, |
305 G1StringDedup::enqueue_from_evacuation(is_from_young, |
311 is_to_young, |
306 is_to_young, |
413 size_t young_cset_length, |
408 size_t young_cset_length, |
414 size_t optional_cset_length) : |
409 size_t optional_cset_length) : |
415 _g1h(g1h), |
410 _g1h(g1h), |
416 _rdcqs(rdcqs), |
411 _rdcqs(rdcqs), |
417 _states(NEW_C_HEAP_ARRAY(G1ParScanThreadState*, n_workers, mtGC)), |
412 _states(NEW_C_HEAP_ARRAY(G1ParScanThreadState*, n_workers, mtGC)), |
418 _surviving_young_words_total(NEW_C_HEAP_ARRAY(size_t, young_cset_length, mtGC)), |
413 _surviving_young_words_total(NEW_C_HEAP_ARRAY(size_t, young_cset_length + 1, mtGC)), |
419 _young_cset_length(young_cset_length), |
414 _young_cset_length(young_cset_length), |
420 _optional_cset_length(optional_cset_length), |
415 _optional_cset_length(optional_cset_length), |
421 _n_workers(n_workers), |
416 _n_workers(n_workers), |
422 _flushed(false) { |
417 _flushed(false) { |
423 for (uint i = 0; i < n_workers; ++i) { |
418 for (uint i = 0; i < n_workers; ++i) { |
424 _states[i] = NULL; |
419 _states[i] = NULL; |
425 } |
420 } |
426 memset(_surviving_young_words_total, 0, young_cset_length * sizeof(size_t)); |
421 memset(_surviving_young_words_total, 0, (young_cset_length + 1) * sizeof(size_t)); |
427 } |
422 } |
428 |
423 |
429 G1ParScanThreadStateSet::~G1ParScanThreadStateSet() { |
424 G1ParScanThreadStateSet::~G1ParScanThreadStateSet() { |
430 assert(_flushed, "thread local state from the per thread states should have been flushed"); |
425 assert(_flushed, "thread local state from the per thread states should have been flushed"); |
431 FREE_C_HEAP_ARRAY(G1ParScanThreadState*, _states); |
426 FREE_C_HEAP_ARRAY(G1ParScanThreadState*, _states); |