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

Print this page
rev 6290 : imported patch 8035400-move-g1parscanthreadstate-into-own-files


  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTEDHEAP_HPP
  26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTEDHEAP_HPP
  27 
  28 #include "gc_implementation/g1/concurrentMark.hpp"
  29 #include "gc_implementation/g1/evacuationInfo.hpp"
  30 #include "gc_implementation/g1/g1AllocRegion.hpp"
  31 #include "gc_implementation/g1/g1BiasedArray.hpp"
  32 #include "gc_implementation/g1/g1HRPrinter.hpp"
  33 #include "gc_implementation/g1/g1MonitoringSupport.hpp"
  34 #include "gc_implementation/g1/g1RemSet.hpp"
  35 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
  36 #include "gc_implementation/g1/g1YCTypes.hpp"
  37 #include "gc_implementation/g1/heapRegionSeq.hpp"
  38 #include "gc_implementation/g1/heapRegionSet.hpp"
  39 #include "gc_implementation/shared/hSpaceCounters.hpp"
  40 #include "gc_implementation/shared/parGCAllocBuffer.hpp"
  41 #include "memory/barrierSet.hpp"
  42 #include "memory/memRegion.hpp"
  43 #include "memory/sharedHeap.hpp"
  44 #include "utilities/stack.hpp"
  45 
  46 // A "G1CollectedHeap" is an implementation of a java heap for HotSpot.
  47 // It uses the "Garbage First" heap organization and algorithm, which
  48 // may combine concurrent marking with parallel, incremental compaction of
  49 // heap subsets that will yield large amounts of garbage.
  50 
  51 // Forward declarations
  52 class HeapRegion;
  53 class HRRSCleanupTask;
  54 class GenerationSpec;


1683   bool        _retired;
1684 
1685 public:
1686   G1ParGCAllocBuffer(size_t gclab_word_size);
1687   virtual ~G1ParGCAllocBuffer() {
1688     guarantee(_retired, "Allocation buffer has not been retired");
1689   }
1690 
1691   virtual void set_buf(HeapWord* buf) {
1692     ParGCAllocBuffer::set_buf(buf);
1693     _retired = false;
1694   }
1695 
1696   virtual void retire(bool end_of_gc, bool retain) {
1697     if (_retired) {
1698       return;
1699     }
1700     ParGCAllocBuffer::retire(end_of_gc, retain);
1701     _retired = true;
1702   }
1703 };
1704 
1705 class G1ParScanThreadState : public StackObj {
1706 protected:
1707   G1CollectedHeap* _g1h;
1708   RefToScanQueue*  _refs;
1709   DirtyCardQueue   _dcq;
1710   G1SATBCardTableModRefBS* _ct_bs;
1711   G1RemSet* _g1_rem;
1712 
1713   G1ParGCAllocBuffer  _surviving_alloc_buffer;
1714   G1ParGCAllocBuffer  _tenured_alloc_buffer;
1715   G1ParGCAllocBuffer* _alloc_buffers[GCAllocPurposeCount];
1716   ageTable            _age_table;
1717 
1718   G1ParScanClosure    _scanner;
1719 
1720   size_t           _alloc_buffer_waste;
1721   size_t           _undo_waste;
1722 
1723   OopsInHeapRegionClosure*      _evac_failure_cl;
1724 
1725   int  _hash_seed;
1726   uint _queue_num;
1727 
1728   size_t _term_attempts;
1729 
1730   double _start;
1731   double _start_strong_roots;
1732   double _strong_roots_time;
1733   double _start_term;
1734   double _term_time;
1735 
1736   // Map from young-age-index (0 == not young, 1 is youngest) to
1737   // surviving words. base is what we get back from the malloc call
1738   size_t* _surviving_young_words_base;
1739   // this points into the array, as we use the first few entries for padding
1740   size_t* _surviving_young_words;
1741 
1742 #define PADDING_ELEM_NUM (DEFAULT_CACHE_LINE_SIZE / sizeof(size_t))
1743 
1744   void   add_to_alloc_buffer_waste(size_t waste) { _alloc_buffer_waste += waste; }
1745 
1746   void   add_to_undo_waste(size_t waste)         { _undo_waste += waste; }
1747 
1748   DirtyCardQueue& dirty_card_queue()             { return _dcq;  }
1749   G1SATBCardTableModRefBS* ctbs()                { return _ct_bs; }
1750 
1751   template <class T> inline void immediate_rs_update(HeapRegion* from, T* p, int tid);
1752 
1753   template <class T> void deferred_rs_update(HeapRegion* from, T* p, int tid) {
1754     // If the new value of the field points to the same region or
1755     // is the to-space, we don't need to include it in the Rset updates.
1756     if (!from->is_in_reserved(oopDesc::load_decode_heap_oop(p)) && !from->is_survivor()) {
1757       size_t card_index = ctbs()->index_for(p);
1758       // If the card hasn't been added to the buffer, do it.
1759       if (ctbs()->mark_card_deferred(card_index)) {
1760         dirty_card_queue().enqueue((jbyte*)ctbs()->byte_for_index(card_index));
1761       }
1762     }
1763   }
1764 
1765 public:
1766   G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, ReferenceProcessor* rp);
1767 
1768   ~G1ParScanThreadState() {
1769     retire_alloc_buffers();
1770     FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base, mtGC);
1771   }
1772 
1773   RefToScanQueue*   refs()            { return _refs;             }
1774   ageTable*         age_table()       { return &_age_table;       }
1775 
1776   G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose) {
1777     return _alloc_buffers[purpose];
1778   }
1779 
1780   size_t alloc_buffer_waste() const              { return _alloc_buffer_waste; }
1781   size_t undo_waste() const                      { return _undo_waste; }
1782 
1783 #ifdef ASSERT
1784   bool verify_ref(narrowOop* ref) const;
1785   bool verify_ref(oop* ref) const;
1786   bool verify_task(StarTask ref) const;
1787 #endif // ASSERT
1788 
1789   template <class T> void push_on_queue(T* ref) {
1790     assert(verify_ref(ref), "sanity");
1791     refs()->push(ref);
1792   }
1793 
1794   template <class T> inline void update_rs(HeapRegion* from, T* p, int tid);
1795 
1796   HeapWord* allocate_slow(GCAllocPurpose purpose, size_t word_sz) {
1797     HeapWord* obj = NULL;
1798     size_t gclab_word_size = _g1h->desired_plab_sz(purpose);
1799     if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
1800       G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose);
1801       add_to_alloc_buffer_waste(alloc_buf->words_remaining());
1802       alloc_buf->retire(false /* end_of_gc */, false /* retain */);
1803 
1804       HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size);
1805       if (buf == NULL) return NULL; // Let caller handle allocation failure.
1806       // Otherwise.
1807       alloc_buf->set_word_size(gclab_word_size);
1808       alloc_buf->set_buf(buf);
1809 
1810       obj = alloc_buf->allocate(word_sz);
1811       assert(obj != NULL, "buffer was definitely big enough...");
1812     } else {
1813       obj = _g1h->par_allocate_during_gc(purpose, word_sz);
1814     }
1815     return obj;
1816   }
1817 
1818   HeapWord* allocate(GCAllocPurpose purpose, size_t word_sz) {
1819     HeapWord* obj = alloc_buffer(purpose)->allocate(word_sz);
1820     if (obj != NULL) return obj;
1821     return allocate_slow(purpose, word_sz);
1822   }
1823 
1824   void undo_allocation(GCAllocPurpose purpose, HeapWord* obj, size_t word_sz) {
1825     if (alloc_buffer(purpose)->contains(obj)) {
1826       assert(alloc_buffer(purpose)->contains(obj + word_sz - 1),
1827              "should contain whole object");
1828       alloc_buffer(purpose)->undo_allocation(obj, word_sz);
1829     } else {
1830       CollectedHeap::fill_with_object(obj, word_sz);
1831       add_to_undo_waste(word_sz);
1832     }
1833   }
1834 
1835   void set_evac_failure_closure(OopsInHeapRegionClosure* evac_failure_cl) {
1836     _evac_failure_cl = evac_failure_cl;
1837   }
1838   OopsInHeapRegionClosure* evac_failure_closure() {
1839     return _evac_failure_cl;
1840   }
1841 
1842   int* hash_seed() { return &_hash_seed; }
1843   uint queue_num() { return _queue_num; }
1844 
1845   size_t term_attempts() const  { return _term_attempts; }
1846   void note_term_attempt() { _term_attempts++; }
1847 
1848   void start_strong_roots() {
1849     _start_strong_roots = os::elapsedTime();
1850   }
1851   void end_strong_roots() {
1852     _strong_roots_time += (os::elapsedTime() - _start_strong_roots);
1853   }
1854   double strong_roots_time() const { return _strong_roots_time; }
1855 
1856   void start_term_time() {
1857     note_term_attempt();
1858     _start_term = os::elapsedTime();
1859   }
1860   void end_term_time() {
1861     _term_time += (os::elapsedTime() - _start_term);
1862   }
1863   double term_time() const { return _term_time; }
1864 
1865   double elapsed_time() const {
1866     return os::elapsedTime() - _start;
1867   }
1868 
1869   static void
1870     print_termination_stats_hdr(outputStream* const st = gclog_or_tty);
1871   void
1872     print_termination_stats(int i, outputStream* const st = gclog_or_tty) const;
1873 
1874   size_t* surviving_young_words() {
1875     // We add on to hide entry 0 which accumulates surviving words for
1876     // age -1 regions (i.e. non-young ones)
1877     return _surviving_young_words;
1878   }
1879 
1880 private:
1881   void retire_alloc_buffers() {
1882     for (int ap = 0; ap < GCAllocPurposeCount; ++ap) {
1883       size_t waste = _alloc_buffers[ap]->words_remaining();
1884       add_to_alloc_buffer_waste(waste);
1885       _alloc_buffers[ap]->flush_stats_and_retire(_g1h->stats_for_purpose((GCAllocPurpose)ap),
1886                                                  true /* end_of_gc */,
1887                                                  false /* retain */);
1888     }
1889   }
1890 
1891 #define G1_PARTIAL_ARRAY_MASK 0x2
1892 
1893   inline bool has_partial_array_mask(oop* ref) const {
1894     return ((uintptr_t)ref & G1_PARTIAL_ARRAY_MASK) == G1_PARTIAL_ARRAY_MASK;
1895   }
1896 
1897   // We never encode partial array oops as narrowOop*, so return false immediately.
1898   // This allows the compiler to create optimized code when popping references from
1899   // the work queue.
1900   inline bool has_partial_array_mask(narrowOop* ref) const {
1901     assert(((uintptr_t)ref & G1_PARTIAL_ARRAY_MASK) != G1_PARTIAL_ARRAY_MASK, "Partial array oop reference encoded as narrowOop*");
1902     return false;
1903   }
1904 
1905   // Only implement set_partial_array_mask() for regular oops, not for narrowOops.
1906   // We always encode partial arrays as regular oop, to allow the
1907   // specialization for has_partial_array_mask() for narrowOops above.
1908   // This means that unintentional use of this method with narrowOops are caught
1909   // by the compiler.
1910   inline oop* set_partial_array_mask(oop obj) const {
1911     assert(((uintptr_t)(void *)obj & G1_PARTIAL_ARRAY_MASK) == 0, "Information loss!");
1912     return (oop*) ((uintptr_t)(void *)obj | G1_PARTIAL_ARRAY_MASK);
1913   }
1914 
1915   inline oop clear_partial_array_mask(oop* ref) const {
1916     return cast_to_oop((intptr_t)ref & ~G1_PARTIAL_ARRAY_MASK);
1917   }
1918 
1919   inline void do_oop_partial_array(oop* p);
1920 
1921   // This method is applied to the fields of the objects that have just been copied.
1922   template <class T> void do_oop_evac(T* p, HeapRegion* from) {
1923     assert(!oopDesc::is_null(oopDesc::load_decode_heap_oop(p)),
1924            "Reference should not be NULL here as such are never pushed to the task queue.");
1925     oop obj = oopDesc::load_decode_heap_oop_not_null(p);
1926 
1927     // Although we never intentionally push references outside of the collection
1928     // set, due to (benign) races in the claim mechanism during RSet scanning more
1929     // than one thread might claim the same card. So the same card may be
1930     // processed multiple times. So redo this check.
1931     if (_g1h->in_cset_fast_test(obj)) {
1932       oop forwardee;
1933       if (obj->is_forwarded()) {
1934         forwardee = obj->forwardee();
1935       } else {
1936         forwardee = copy_to_survivor_space(obj);
1937       }
1938       assert(forwardee != NULL, "forwardee should not be NULL");
1939       oopDesc::encode_store_heap_oop(p, forwardee);
1940     }
1941 
1942     assert(obj != NULL, "Must be");
1943     update_rs(from, p, queue_num());
1944   }
1945 public:
1946 
1947   oop copy_to_survivor_space(oop const obj);
1948 
1949   template <class T> inline void deal_with_reference(T* ref_to_scan);
1950 
1951   inline void deal_with_reference(StarTask ref);
1952 
1953 public:
1954   void trim_queue();
1955 };
1956 
1957 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTEDHEAP_HPP


  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTEDHEAP_HPP
  26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTEDHEAP_HPP
  27 
  28 #include "gc_implementation/g1/concurrentMark.hpp"
  29 #include "gc_implementation/g1/evacuationInfo.hpp"
  30 #include "gc_implementation/g1/g1AllocRegion.hpp"
  31 #include "gc_implementation/g1/g1BiasedArray.hpp"
  32 #include "gc_implementation/g1/g1HRPrinter.hpp"
  33 #include "gc_implementation/g1/g1MonitoringSupport.hpp"

  34 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
  35 #include "gc_implementation/g1/g1YCTypes.hpp"
  36 #include "gc_implementation/g1/heapRegionSeq.hpp"
  37 #include "gc_implementation/g1/heapRegionSet.hpp"
  38 #include "gc_implementation/shared/hSpaceCounters.hpp"
  39 #include "gc_implementation/shared/parGCAllocBuffer.hpp"
  40 #include "memory/barrierSet.hpp"
  41 #include "memory/memRegion.hpp"
  42 #include "memory/sharedHeap.hpp"
  43 #include "utilities/stack.hpp"
  44 
  45 // A "G1CollectedHeap" is an implementation of a java heap for HotSpot.
  46 // It uses the "Garbage First" heap organization and algorithm, which
  47 // may combine concurrent marking with parallel, incremental compaction of
  48 // heap subsets that will yield large amounts of garbage.
  49 
  50 // Forward declarations
  51 class HeapRegion;
  52 class HRRSCleanupTask;
  53 class GenerationSpec;


1682   bool        _retired;
1683 
1684 public:
1685   G1ParGCAllocBuffer(size_t gclab_word_size);
1686   virtual ~G1ParGCAllocBuffer() {
1687     guarantee(_retired, "Allocation buffer has not been retired");
1688   }
1689 
1690   virtual void set_buf(HeapWord* buf) {
1691     ParGCAllocBuffer::set_buf(buf);
1692     _retired = false;
1693   }
1694 
1695   virtual void retire(bool end_of_gc, bool retain) {
1696     if (_retired) {
1697       return;
1698     }
1699     ParGCAllocBuffer::retire(end_of_gc, retain);
1700     _retired = true;
1701   }




























































































































































































































































1702 };
1703 
1704 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTEDHEAP_HPP