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 |
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); |