comparison src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp @ 10374:87c64c0438fb

6976350: G1: deal with fragmentation while copying objects during GC Summary: Create G1ParGCAllocBufferContainer to contain two buffers instead of previously using one buffer, in order to hold the first priority buffer longer. Thus, when some large objects hits the value of free space left in the first priority buffer it has an alternative to fit in the second priority buffer while the first priority buffer is given more chances to try allocating smaller objects. Overall, it will improve heap space efficiency. Reviewed-by: johnc, jmasa, brutisso Contributed-by: tamao <tao.mao@oracle.com>
author tamao
date Mon, 03 Jun 2013 14:37:13 -0700
parents 001ec9515f84
children f2110083203d
comparison
equal deleted inserted replaced
10372:e72f7eecc96d 10374:87c64c0438fb
590 // Allocate blocks during garbage collection. Will ensure an 590 // Allocate blocks during garbage collection. Will ensure an
591 // allocation region, either by picking one or expanding the 591 // allocation region, either by picking one or expanding the
592 // heap, and then allocate a block of the given size. The block 592 // heap, and then allocate a block of the given size. The block
593 // may not be a humongous - it must fit into a single heap region. 593 // may not be a humongous - it must fit into a single heap region.
594 HeapWord* par_allocate_during_gc(GCAllocPurpose purpose, size_t word_size); 594 HeapWord* par_allocate_during_gc(GCAllocPurpose purpose, size_t word_size);
595
596 HeapWord* allocate_during_gc_slow(GCAllocPurpose purpose,
597 HeapRegion* alloc_region,
598 bool par,
599 size_t word_size);
600 595
601 // Ensure that no further allocations can happen in "r", bearing in mind 596 // Ensure that no further allocations can happen in "r", bearing in mind
602 // that parallel threads might be attempting allocations. 597 // that parallel threads might be attempting allocations.
603 void par_allocate_remaining_space(HeapRegion* r); 598 void par_allocate_remaining_space(HeapRegion* r);
604 599
1731 if (_retired) 1726 if (_retired)
1732 return; 1727 return;
1733 ParGCAllocBuffer::retire(end_of_gc, retain); 1728 ParGCAllocBuffer::retire(end_of_gc, retain);
1734 _retired = true; 1729 _retired = true;
1735 } 1730 }
1731
1732 bool is_retired() {
1733 return _retired;
1734 }
1735 };
1736
1737 class G1ParGCAllocBufferContainer {
1738 protected:
1739 static int const _priority_max = 2;
1740 G1ParGCAllocBuffer* _priority_buffer[_priority_max];
1741
1742 public:
1743 G1ParGCAllocBufferContainer(size_t gclab_word_size) {
1744 for (int pr = 0; pr < _priority_max; ++pr) {
1745 _priority_buffer[pr] = new G1ParGCAllocBuffer(gclab_word_size);
1746 }
1747 }
1748
1749 ~G1ParGCAllocBufferContainer() {
1750 for (int pr = 0; pr < _priority_max; ++pr) {
1751 assert(_priority_buffer[pr]->is_retired(), "alloc buffers should all retire at this point.");
1752 delete _priority_buffer[pr];
1753 }
1754 }
1755
1756 HeapWord* allocate(size_t word_sz) {
1757 HeapWord* obj;
1758 for (int pr = 0; pr < _priority_max; ++pr) {
1759 obj = _priority_buffer[pr]->allocate(word_sz);
1760 if (obj != NULL) return obj;
1761 }
1762 return obj;
1763 }
1764
1765 bool contains(void* addr) {
1766 for (int pr = 0; pr < _priority_max; ++pr) {
1767 if (_priority_buffer[pr]->contains(addr)) return true;
1768 }
1769 return false;
1770 }
1771
1772 void undo_allocation(HeapWord* obj, size_t word_sz) {
1773 bool finish_undo;
1774 for (int pr = 0; pr < _priority_max; ++pr) {
1775 if (_priority_buffer[pr]->contains(obj)) {
1776 _priority_buffer[pr]->undo_allocation(obj, word_sz);
1777 finish_undo = true;
1778 }
1779 }
1780 if (!finish_undo) ShouldNotReachHere();
1781 }
1782
1783 size_t words_remaining() {
1784 size_t result = 0;
1785 for (int pr = 0; pr < _priority_max; ++pr) {
1786 result += _priority_buffer[pr]->words_remaining();
1787 }
1788 return result;
1789 }
1790
1791 size_t words_remaining_in_retired_buffer() {
1792 G1ParGCAllocBuffer* retired = _priority_buffer[0];
1793 return retired->words_remaining();
1794 }
1795
1796 void flush_stats_and_retire(PLABStats* stats, bool end_of_gc, bool retain) {
1797 for (int pr = 0; pr < _priority_max; ++pr) {
1798 _priority_buffer[pr]->flush_stats_and_retire(stats, end_of_gc, retain);
1799 }
1800 }
1801
1802 void update(bool end_of_gc, bool retain, HeapWord* buf, size_t word_sz) {
1803 G1ParGCAllocBuffer* retired_and_set = _priority_buffer[0];
1804 retired_and_set->retire(end_of_gc, retain);
1805 retired_and_set->set_buf(buf);
1806 retired_and_set->set_word_size(word_sz);
1807 adjust_priority_order();
1808 }
1809
1810 private:
1811 void adjust_priority_order() {
1812 G1ParGCAllocBuffer* retired_and_set = _priority_buffer[0];
1813
1814 int last = _priority_max - 1;
1815 for (int pr = 0; pr < last; ++pr) {
1816 _priority_buffer[pr] = _priority_buffer[pr + 1];
1817 }
1818 _priority_buffer[last] = retired_and_set;
1819 }
1736 }; 1820 };
1737 1821
1738 class G1ParScanThreadState : public StackObj { 1822 class G1ParScanThreadState : public StackObj {
1739 protected: 1823 protected:
1740 G1CollectedHeap* _g1h; 1824 G1CollectedHeap* _g1h;
1741 RefToScanQueue* _refs; 1825 RefToScanQueue* _refs;
1742 DirtyCardQueue _dcq; 1826 DirtyCardQueue _dcq;
1743 CardTableModRefBS* _ct_bs; 1827 CardTableModRefBS* _ct_bs;
1744 G1RemSet* _g1_rem; 1828 G1RemSet* _g1_rem;
1745 1829
1746 G1ParGCAllocBuffer _surviving_alloc_buffer; 1830 G1ParGCAllocBufferContainer _surviving_alloc_buffer;
1747 G1ParGCAllocBuffer _tenured_alloc_buffer; 1831 G1ParGCAllocBufferContainer _tenured_alloc_buffer;
1748 G1ParGCAllocBuffer* _alloc_buffers[GCAllocPurposeCount]; 1832 G1ParGCAllocBufferContainer* _alloc_buffers[GCAllocPurposeCount];
1749 ageTable _age_table; 1833 ageTable _age_table;
1750 1834
1751 size_t _alloc_buffer_waste; 1835 size_t _alloc_buffer_waste;
1752 size_t _undo_waste; 1836 size_t _undo_waste;
1753 1837
1807 } 1891 }
1808 1892
1809 RefToScanQueue* refs() { return _refs; } 1893 RefToScanQueue* refs() { return _refs; }
1810 ageTable* age_table() { return &_age_table; } 1894 ageTable* age_table() { return &_age_table; }
1811 1895
1812 G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose) { 1896 G1ParGCAllocBufferContainer* alloc_buffer(GCAllocPurpose purpose) {
1813 return _alloc_buffers[purpose]; 1897 return _alloc_buffers[purpose];
1814 } 1898 }
1815 1899
1816 size_t alloc_buffer_waste() const { return _alloc_buffer_waste; } 1900 size_t alloc_buffer_waste() const { return _alloc_buffer_waste; }
1817 size_t undo_waste() const { return _undo_waste; } 1901 size_t undo_waste() const { return _undo_waste; }
1837 1921
1838 HeapWord* allocate_slow(GCAllocPurpose purpose, size_t word_sz) { 1922 HeapWord* allocate_slow(GCAllocPurpose purpose, size_t word_sz) {
1839 HeapWord* obj = NULL; 1923 HeapWord* obj = NULL;
1840 size_t gclab_word_size = _g1h->desired_plab_sz(purpose); 1924 size_t gclab_word_size = _g1h->desired_plab_sz(purpose);
1841 if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) { 1925 if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
1842 G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose); 1926 G1ParGCAllocBufferContainer* alloc_buf = alloc_buffer(purpose);
1843 add_to_alloc_buffer_waste(alloc_buf->words_remaining());
1844 alloc_buf->retire(false /* end_of_gc */, false /* retain */);
1845 1927
1846 HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size); 1928 HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size);
1847 if (buf == NULL) return NULL; // Let caller handle allocation failure. 1929 if (buf == NULL) return NULL; // Let caller handle allocation failure.
1848 // Otherwise. 1930
1849 alloc_buf->set_word_size(gclab_word_size); 1931 add_to_alloc_buffer_waste(alloc_buf->words_remaining_in_retired_buffer());
1850 alloc_buf->set_buf(buf); 1932 alloc_buf->update(false /* end_of_gc */, false /* retain */, buf, gclab_word_size);
1851 1933
1852 obj = alloc_buf->allocate(word_sz); 1934 obj = alloc_buf->allocate(word_sz);
1853 assert(obj != NULL, "buffer was definitely big enough..."); 1935 assert(obj != NULL, "buffer was definitely big enough...");
1854 } else { 1936 } else {
1855 obj = _g1h->par_allocate_during_gc(purpose, word_sz); 1937 obj = _g1h->par_allocate_during_gc(purpose, word_sz);
1957 } else { 2039 } else {
1958 deal_with_reference((oop*)ref); 2040 deal_with_reference((oop*)ref);
1959 } 2041 }
1960 } 2042 }
1961 2043
1962 public:
1963 void trim_queue(); 2044 void trim_queue();
1964 }; 2045 };
1965 2046
1966 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTEDHEAP_HPP 2047 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTEDHEAP_HPP