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

Print this page

        

*** 588,602 **** // allocation region, either by picking one or expanding the // heap, and then allocate a block of the given size. The block // may not be a humongous - it must fit into a single heap region. HeapWord* par_allocate_during_gc(GCAllocPurpose purpose, size_t word_size); - HeapWord* allocate_during_gc_slow(GCAllocPurpose purpose, - HeapRegion* alloc_region, - bool par, - size_t word_size); - // Ensure that no further allocations can happen in "r", bearing in mind // that parallel threads might be attempting allocations. void par_allocate_remaining_space(HeapRegion* r); // Allocation attempt during GC for a survivor object / PLAB. --- 588,597 ----
*** 1744,1763 **** _retired = true; } }; class G1ParScanThreadState : public StackObj { protected: G1CollectedHeap* _g1h; RefToScanQueue* _refs; DirtyCardQueue _dcq; CardTableModRefBS* _ct_bs; G1RemSet* _g1_rem; ! G1ParGCAllocBuffer _surviving_alloc_buffer; ! G1ParGCAllocBuffer _tenured_alloc_buffer; ! G1ParGCAllocBuffer* _alloc_buffers[GCAllocPurposeCount]; ageTable _age_table; size_t _alloc_buffer_waste; size_t _undo_waste; --- 1739,1767 ---- _retired = true; } }; class G1ParScanThreadState : public StackObj { + private: + enum GCAllocPriority { + GCAllocPriority1, + GCAllocPriority2, + GCAllocPriorityCount + }; + + int buf_idx(int purpose, int priority) { + return purpose*GCAllocPriorityCount + priority; + } + protected: G1CollectedHeap* _g1h; RefToScanQueue* _refs; DirtyCardQueue _dcq; CardTableModRefBS* _ct_bs; G1RemSet* _g1_rem; ! G1ParGCAllocBuffer* _alloc_buffers[GCAllocPurposeCount*GCAllocPriorityCount]; ageTable _age_table; size_t _alloc_buffer_waste; size_t _undo_waste;
*** 1812,1828 **** public: G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num); ~G1ParScanThreadState() { FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base, mtGC); } RefToScanQueue* refs() { return _refs; } ageTable* age_table() { return &_age_table; } ! G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose) { ! return _alloc_buffers[purpose]; } size_t alloc_buffer_waste() const { return _alloc_buffer_waste; } size_t undo_waste() const { return _undo_waste; } --- 1816,1836 ---- public: G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num); ~G1ParScanThreadState() { FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base, mtGC); + for (int ap = 0; ap < GCAllocPurposeCount; ++ap) + for (int pr = 0; pr < GCAllocPriorityCount; ++pr) { + delete alloc_buffer(GCAllocPurpose(ap), GCAllocPriority(pr)); + } } RefToScanQueue* refs() { return _refs; } ageTable* age_table() { return &_age_table; } ! G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose, GCAllocPriority priority) { ! return _alloc_buffers[buf_idx(purpose, priority)]; } size_t alloc_buffer_waste() const { return _alloc_buffer_waste; } size_t undo_waste() const { return _undo_waste; }
*** 1847,1890 **** HeapWord* allocate_slow(GCAllocPurpose purpose, size_t word_sz) { HeapWord* obj = NULL; size_t gclab_word_size = _g1h->desired_plab_sz(purpose); if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) { ! G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose); ! add_to_alloc_buffer_waste(alloc_buf->words_remaining()); ! alloc_buf->retire(false /* end_of_gc */, false /* retain */); HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size); if (buf == NULL) return NULL; // Let caller handle allocation failure. // Otherwise. ! alloc_buf->set_word_size(gclab_word_size); ! alloc_buf->set_buf(buf); ! obj = alloc_buf->allocate(word_sz); assert(obj != NULL, "buffer was definitely big enough..."); } else { obj = _g1h->par_allocate_during_gc(purpose, word_sz); } return obj; } HeapWord* allocate(GCAllocPurpose purpose, size_t word_sz) { ! HeapWord* obj = alloc_buffer(purpose)->allocate(word_sz); if (obj != NULL) return obj; return allocate_slow(purpose, word_sz); } void undo_allocation(GCAllocPurpose purpose, HeapWord* obj, size_t word_sz) { ! if (alloc_buffer(purpose)->contains(obj)) { ! assert(alloc_buffer(purpose)->contains(obj + word_sz - 1), "should contain whole object"); ! alloc_buffer(purpose)->undo_allocation(obj, word_sz); ! } else { CollectedHeap::fill_with_object(obj, word_sz); add_to_undo_waste(word_sz); } - } void set_evac_failure_closure(OopsInHeapRegionClosure* evac_failure_cl) { _evac_failure_cl = evac_failure_cl; } OopsInHeapRegionClosure* evac_failure_closure() { --- 1855,1911 ---- HeapWord* allocate_slow(GCAllocPurpose purpose, size_t word_sz) { HeapWord* obj = NULL; size_t gclab_word_size = _g1h->desired_plab_sz(purpose); if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) { ! G1ParGCAllocBuffer* alloc_buf1 = alloc_buffer(purpose, GCAllocPriority1); ! G1ParGCAllocBuffer* alloc_buf2 = alloc_buffer(purpose, GCAllocPriority2); ! ! add_to_alloc_buffer_waste(alloc_buf1->words_remaining()); ! alloc_buf1->retire(false /* end_of_gc */, false /* retain */); HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size); if (buf == NULL) return NULL; // Let caller handle allocation failure. // Otherwise. ! alloc_buf1->set_word_size(gclab_word_size); ! alloc_buf1->set_buf(buf); ! obj = alloc_buf1->allocate(word_sz); assert(obj != NULL, "buffer was definitely big enough..."); + + // Swap buffers in order to preserve the priority order + _alloc_buffers[buf_idx(purpose, GCAllocPriority1)] = alloc_buf2; + _alloc_buffers[buf_idx(purpose, GCAllocPriority2)] = alloc_buf1; } else { obj = _g1h->par_allocate_during_gc(purpose, word_sz); } return obj; } HeapWord* allocate(GCAllocPurpose purpose, size_t word_sz) { ! HeapWord* obj; ! for (int pr = 0; pr < GCAllocPriorityCount; ++pr) { ! obj = alloc_buffer(purpose, (GCAllocPriority)pr)->allocate(word_sz); if (obj != NULL) return obj; + } + // Otherwise. return allocate_slow(purpose, word_sz); } void undo_allocation(GCAllocPurpose purpose, HeapWord* obj, size_t word_sz) { ! for (int pr = 0; pr < GCAllocPriorityCount; ++pr) { ! if (alloc_buffer(purpose, (GCAllocPriority)pr)->contains(obj)) { ! assert(alloc_buffer(purpose, pr)->contains(obj + word_sz - 1), "should contain whole object"); ! alloc_buffer(purpose, (GCAllocPriority)pr)->undo_allocation(obj, word_sz); ! return; ! } ! } ! CollectedHeap::fill_with_object(obj, word_sz); add_to_undo_waste(word_sz); } void set_evac_failure_closure(OopsInHeapRegionClosure* evac_failure_cl) { _evac_failure_cl = evac_failure_cl; } OopsInHeapRegionClosure* evac_failure_closure() {
*** 1936,1949 **** // age -1 regions (i.e. non-young ones) return _surviving_young_words; } void retire_alloc_buffers() { ! for (int ap = 0; ap < GCAllocPurposeCount; ++ap) { ! size_t waste = _alloc_buffers[ap]->words_remaining(); add_to_alloc_buffer_waste(waste); ! _alloc_buffers[ap]->flush_stats_and_retire(_g1h->stats_for_purpose((GCAllocPurpose)ap), true /* end_of_gc */, false /* retain */); } } --- 1957,1972 ---- // age -1 regions (i.e. non-young ones) return _surviving_young_words; } void retire_alloc_buffers() { ! for (int ap = 0; ap < GCAllocPurposeCount; ++ap) ! for (int pr = 0; pr < GCAllocPriorityCount; ++pr) { ! G1ParGCAllocBuffer* buffer = alloc_buffer((GCAllocPurpose)ap, (GCAllocPriority)pr); ! size_t waste = buffer->words_remaining(); add_to_alloc_buffer_waste(waste); ! buffer->flush_stats_and_retire(_g1h->stats_for_purpose((GCAllocPurpose)ap), true /* end_of_gc */, false /* retain */); } }
*** 1967,1976 **** } else { deal_with_reference((oop*)ref); } } - public: void trim_queue(); }; #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTEDHEAP_HPP --- 1990,1998 ----