src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp

Print this page
rev 5917 : 8027559: Decrease code size and templatizing in G1ParCopyClosure::do_oop_work
Summary: Move methods that are not dependent on any of G1ParCopyClosure's template parameters into G1ParCopyHelper. Further remove unused methods and members of the class hierarchy.
Reviewed-by:
rev 5918 : 8035326: Assume non-NULL references in G1CollectedHeap::in_cset_fast_test
Summary: Remove the assumption that G1CollectedHeap::in_cset_fast_test needs to check for NULL references. Most of the time this is not required, making the code doing this check multiple times.
Reviewed-by:
rev 5919 : 8035329: Move G1ParCopyClosure::copy_to_survivor_space into G1ParScanThreadState
Summary: Move G1ParCopyClosure::copy_to_survivor_space to decrease code size.

*** 4532,4552 **** } G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) : ParGCAllocBuffer(gclab_word_size), _retired(false) { } ! G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num) : _g1h(g1h), _refs(g1h->task_queue(queue_num)), _dcq(&g1h->dirty_card_queue_set()), _ct_bs(g1h->g1_barrier_set()), _g1_rem(g1h->g1_rem_set()), _hash_seed(17), _queue_num(queue_num), _term_attempts(0), _surviving_alloc_buffer(g1h->desired_plab_sz(GCAllocForSurvived)), _tenured_alloc_buffer(g1h->desired_plab_sz(GCAllocForTenured)), ! _age_table(false), _strong_roots_time(0), _term_time(0), _alloc_buffer_waste(0), _undo_waste(0) { // we allocate G1YoungSurvRateNumRegions plus one entries, since // we "sacrifice" entry 0 to keep track of surviving bytes for // non-young regions (where the age is -1) --- 4532,4552 ---- } G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) : ParGCAllocBuffer(gclab_word_size), _retired(false) { } ! G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, ReferenceProcessor* rp) : _g1h(g1h), _refs(g1h->task_queue(queue_num)), _dcq(&g1h->dirty_card_queue_set()), _ct_bs(g1h->g1_barrier_set()), _g1_rem(g1h->g1_rem_set()), _hash_seed(17), _queue_num(queue_num), _term_attempts(0), _surviving_alloc_buffer(g1h->desired_plab_sz(GCAllocForSurvived)), _tenured_alloc_buffer(g1h->desired_plab_sz(GCAllocForTenured)), ! _age_table(false), _scanner(g1h, this, rp), _strong_roots_time(0), _term_time(0), _alloc_buffer_waste(0), _undo_waste(0) { // we allocate G1YoungSurvRateNumRegions plus one entries, since // we "sacrifice" entry 0 to keep track of surviving bytes for // non-young regions (where the age is -1)
*** 4687,4726 **** // well-formed. So we have to read its size from its from-space // image which we know should not be changing. _cm->grayRoot(to_obj, (size_t) from_obj->size(), _worker_id); } ! template <G1Barrier barrier, bool do_mark_object> ! oop G1ParCopyClosure<barrier, do_mark_object> ! ::copy_to_survivor_space(oop old) { size_t word_sz = old->size(); ! HeapRegion* from_region = _g1->heap_region_containing_raw(old); // +1 to make the -1 indexes valid... int young_index = from_region->young_index_in_cset()+1; assert( (from_region->is_young() && young_index > 0) || (!from_region->is_young() && young_index == 0), "invariant" ); ! G1CollectorPolicy* g1p = _g1->g1_policy(); markOop m = old->mark(); int age = m->has_displaced_mark_helper() ? m->displaced_mark_helper()->age() : m->age(); GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age, word_sz); ! HeapWord* obj_ptr = _par_scan_state->allocate(alloc_purpose, word_sz); #ifndef PRODUCT // Should this evacuation fail? ! if (_g1->evacuation_should_fail()) { if (obj_ptr != NULL) { ! _par_scan_state->undo_allocation(alloc_purpose, obj_ptr, word_sz); obj_ptr = NULL; } } #endif // !PRODUCT if (obj_ptr == NULL) { // This will either forward-to-self, or detect that someone else has // installed a forwarding pointer. ! return _g1->handle_evacuation_failure_par(_par_scan_state, old); } oop obj = oop(obj_ptr); // We're going to allocate linearly, so might as well prefetch ahead. --- 4687,4724 ---- // well-formed. So we have to read its size from its from-space // image which we know should not be changing. _cm->grayRoot(to_obj, (size_t) from_obj->size(), _worker_id); } ! oop G1ParScanThreadState::copy_to_survivor_space(oop const old) { size_t word_sz = old->size(); ! HeapRegion* from_region = _g1h->heap_region_containing_raw(old); // +1 to make the -1 indexes valid... int young_index = from_region->young_index_in_cset()+1; assert( (from_region->is_young() && young_index > 0) || (!from_region->is_young() && young_index == 0), "invariant" ); ! G1CollectorPolicy* g1p = _g1h->g1_policy(); markOop m = old->mark(); int age = m->has_displaced_mark_helper() ? m->displaced_mark_helper()->age() : m->age(); GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age, word_sz); ! HeapWord* obj_ptr = allocate(alloc_purpose, word_sz); #ifndef PRODUCT // Should this evacuation fail? ! if (_g1h->evacuation_should_fail()) { if (obj_ptr != NULL) { ! undo_allocation(alloc_purpose, obj_ptr, word_sz); obj_ptr = NULL; } } #endif // !PRODUCT if (obj_ptr == NULL) { // This will either forward-to-self, or detect that someone else has // installed a forwarding pointer. ! return _g1h->handle_evacuation_failure_par(this, old); } oop obj = oop(obj_ptr); // We're going to allocate linearly, so might as well prefetch ahead.
*** 4749,4781 **** obj->incr_age(); } else { m = m->incr_age(); obj->set_mark(m); } ! _par_scan_state->age_table()->add(obj, word_sz); } else { obj->set_mark(m); } ! size_t* surv_young_words = _par_scan_state->surviving_young_words(); surv_young_words[young_index] += word_sz; if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) { // We keep track of the next start index in the length field of // the to-space object. The actual length can be found in the // length field of the from-space object. arrayOop(obj)->set_length(0); oop* old_p = set_partial_array_mask(old); ! _par_scan_state->push_on_queue(old_p); } else { // No point in using the slower heap_region_containing() method, // given that we know obj is in the heap. ! _scanner.set_region(_g1->heap_region_containing_raw(obj)); obj->oop_iterate_backwards(&_scanner); } } else { ! _par_scan_state->undo_allocation(alloc_purpose, obj_ptr, word_sz); obj = forward_ptr; } return obj; } --- 4747,4779 ---- obj->incr_age(); } else { m = m->incr_age(); obj->set_mark(m); } ! age_table()->add(obj, word_sz); } else { obj->set_mark(m); } ! size_t* surv_young_words = surviving_young_words(); surv_young_words[young_index] += word_sz; if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) { // We keep track of the next start index in the length field of // the to-space object. The actual length can be found in the // length field of the from-space object. arrayOop(obj)->set_length(0); oop* old_p = set_partial_array_mask(old); ! push_on_queue(old_p); } else { // No point in using the slower heap_region_containing() method, // given that we know obj is in the heap. ! _scanner.set_region(_g1h->heap_region_containing_raw(obj)); obj->oop_iterate_backwards(&_scanner); } } else { ! undo_allocation(alloc_purpose, obj_ptr, word_sz); obj = forward_ptr; } return obj; }
*** 4799,4809 **** if (_g1->in_cset_fast_test(obj)) { oop forwardee; if (obj->is_forwarded()) { forwardee = obj->forwardee(); } else { ! forwardee = copy_to_survivor_space(obj); } assert(forwardee != NULL, "forwardee should not be NULL"); oopDesc::encode_store_heap_oop(p, forwardee); if (do_mark_object && forwardee != obj) { // If the object is self-forwarded we don't need to explicitly --- 4797,4807 ---- if (_g1->in_cset_fast_test(obj)) { oop forwardee; if (obj->is_forwarded()) { forwardee = obj->forwardee(); } else { ! forwardee = _par_scan_state->copy_to_survivor_space(obj); } assert(forwardee != NULL, "forwardee should not be NULL"); oopDesc::encode_store_heap_oop(p, forwardee); if (do_mark_object && forwardee != obj) { // If the object is self-forwarded we don't need to explicitly
*** 5021,5031 **** ResourceMark rm; HandleMark hm; ReferenceProcessor* rp = _g1h->ref_processor_stw(); ! G1ParScanThreadState pss(_g1h, worker_id); G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, rp); G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, rp); G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, rp); pss.set_evac_closure(&scan_evac_cl); --- 5019,5029 ---- ResourceMark rm; HandleMark hm; ReferenceProcessor* rp = _g1h->ref_processor_stw(); ! G1ParScanThreadState pss(_g1h, worker_id, rp); G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, rp); G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, rp); G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, rp); pss.set_evac_closure(&scan_evac_cl);
*** 5452,5462 **** ResourceMark rm; HandleMark hm; G1STWIsAliveClosure is_alive(_g1h); ! G1ParScanThreadState pss(_g1h, worker_id); G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, NULL); G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, NULL); G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, NULL); --- 5450,5460 ---- ResourceMark rm; HandleMark hm; G1STWIsAliveClosure is_alive(_g1h); ! G1ParScanThreadState pss(_g1h, worker_id, NULL); G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, NULL); G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, NULL); G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, NULL);
*** 5564,5574 **** void work(uint worker_id) { ResourceMark rm; HandleMark hm; ! G1ParScanThreadState pss(_g1h, worker_id); G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, NULL); G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, NULL); G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, NULL); pss.set_evac_closure(&scan_evac_cl); --- 5562,5572 ---- void work(uint worker_id) { ResourceMark rm; HandleMark hm; ! G1ParScanThreadState pss(_g1h, worker_id, NULL); G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, NULL); G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, NULL); G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, NULL); pss.set_evac_closure(&scan_evac_cl);
*** 5690,5700 **** // of JNI refs is serial and performed serially by the current thread // rather than by a worker. The following PSS will be used for processing // JNI refs. // Use only a single queue for this PSS. ! G1ParScanThreadState pss(this, 0); // We do not embed a reference processor in the copying/scanning // closures while we're actually processing the discovered // reference objects. G1ParScanHeapEvacClosure scan_evac_cl(this, &pss, NULL); --- 5688,5698 ---- // of JNI refs is serial and performed serially by the current thread // rather than by a worker. The following PSS will be used for processing // JNI refs. // Use only a single queue for this PSS. ! G1ParScanThreadState pss(this, 0, NULL); // We do not embed a reference processor in the copying/scanning // closures while we're actually processing the discovered // reference objects. G1ParScanHeapEvacClosure scan_evac_cl(this, &pss, NULL);