hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
changeset 6251 90e562b9f1cc
parent 6247 00e5cc407d03
child 6260 fba83fd3adc7
equal deleted inserted replaced
6250:5680f968c721 6251:90e562b9f1cc
    44 class ConcurrentMark;
    44 class ConcurrentMark;
    45 class ConcurrentMarkThread;
    45 class ConcurrentMarkThread;
    46 class ConcurrentG1Refine;
    46 class ConcurrentG1Refine;
    47 class ConcurrentZFThread;
    47 class ConcurrentZFThread;
    48 
    48 
    49 // If want to accumulate detailed statistics on work queues
    49 typedef OverflowTaskQueue<StarTask>         RefToScanQueue;
    50 // turn this on.
       
    51 #define G1_DETAILED_STATS 0
       
    52 
       
    53 #if G1_DETAILED_STATS
       
    54 #  define IF_G1_DETAILED_STATS(code) code
       
    55 #else
       
    56 #  define IF_G1_DETAILED_STATS(code)
       
    57 #endif
       
    58 
       
    59 typedef GenericTaskQueue<StarTask>          RefToScanQueue;
       
    60 typedef GenericTaskQueueSet<RefToScanQueue> RefToScanQueueSet;
    50 typedef GenericTaskQueueSet<RefToScanQueue> RefToScanQueueSet;
    61 
    51 
    62 typedef int RegionIdx_t;   // needs to hold [ 0..max_regions() )
    52 typedef int RegionIdx_t;   // needs to hold [ 0..max_regions() )
    63 typedef int CardIdx_t;     // needs to hold [ 0..CardsPerRegion )
    53 typedef int CardIdx_t;     // needs to hold [ 0..CardsPerRegion )
    64 
    54 
   469   // Shrink the garbage-first heap by at most the given size (in bytes!).
   459   // Shrink the garbage-first heap by at most the given size (in bytes!).
   470   // (Rounds down to a HeapRegion boundary.)
   460   // (Rounds down to a HeapRegion boundary.)
   471   virtual void shrink(size_t expand_bytes);
   461   virtual void shrink(size_t expand_bytes);
   472   void shrink_helper(size_t expand_bytes);
   462   void shrink_helper(size_t expand_bytes);
   473 
   463 
       
   464   #if TASKQUEUE_STATS
       
   465   static void print_taskqueue_stats_hdr(outputStream* const st = gclog_or_tty);
       
   466   void print_taskqueue_stats(outputStream* const st = gclog_or_tty) const;
       
   467   void reset_taskqueue_stats();
       
   468   #endif // TASKQUEUE_STATS
       
   469 
   474   // Do an incremental collection: identify a collection set, and evacuate
   470   // Do an incremental collection: identify a collection set, and evacuate
   475   // its live objects elsewhere.
   471   // its live objects elsewhere.
   476   virtual void do_collection_pause();
   472   virtual void do_collection_pause();
   477 
   473 
   478   // The guts of the incremental collection pause, executed by the vm
   474   // The guts of the incremental collection pause, executed by the vm
   660   bool _unclean_regions_coming;
   656   bool _unclean_regions_coming;
   661 
   657 
   662 public:
   658 public:
   663   void set_refine_cte_cl_concurrency(bool concurrent);
   659   void set_refine_cte_cl_concurrency(bool concurrent);
   664 
   660 
   665   RefToScanQueue *task_queue(int i);
   661   RefToScanQueue *task_queue(int i) const;
   666 
   662 
   667   // A set of cards where updates happened during the GC
   663   // A set of cards where updates happened during the GC
   668   DirtyCardQueueSet& dirty_card_queue_set() { return _dirty_card_queue_set; }
   664   DirtyCardQueueSet& dirty_card_queue_set() { return _dirty_card_queue_set; }
   669 
   665 
   670   // A DirtyCardQueueSet that is used to hold cards that contain
   666   // A DirtyCardQueueSet that is used to hold cards that contain
  1577   RefToScanQueue*  _refs;
  1573   RefToScanQueue*  _refs;
  1578   DirtyCardQueue   _dcq;
  1574   DirtyCardQueue   _dcq;
  1579   CardTableModRefBS* _ct_bs;
  1575   CardTableModRefBS* _ct_bs;
  1580   G1RemSet* _g1_rem;
  1576   G1RemSet* _g1_rem;
  1581 
  1577 
  1582   typedef GrowableArray<StarTask> OverflowQueue;
       
  1583   OverflowQueue* _overflowed_refs;
       
  1584 
       
  1585   G1ParGCAllocBuffer  _surviving_alloc_buffer;
  1578   G1ParGCAllocBuffer  _surviving_alloc_buffer;
  1586   G1ParGCAllocBuffer  _tenured_alloc_buffer;
  1579   G1ParGCAllocBuffer  _tenured_alloc_buffer;
  1587   G1ParGCAllocBuffer* _alloc_buffers[GCAllocPurposeCount];
  1580   G1ParGCAllocBuffer* _alloc_buffers[GCAllocPurposeCount];
  1588   ageTable            _age_table;
  1581   ageTable            _age_table;
  1589 
  1582 
  1596 
  1589 
  1597   int _hash_seed;
  1590   int _hash_seed;
  1598   int _queue_num;
  1591   int _queue_num;
  1599 
  1592 
  1600   size_t _term_attempts;
  1593   size_t _term_attempts;
  1601 #if G1_DETAILED_STATS
       
  1602   int _pushes, _pops, _steals, _steal_attempts;
       
  1603   int _overflow_pushes;
       
  1604 #endif
       
  1605 
  1594 
  1606   double _start;
  1595   double _start;
  1607   double _start_strong_roots;
  1596   double _start_strong_roots;
  1608   double _strong_roots_time;
  1597   double _strong_roots_time;
  1609   double _start_term;
  1598   double _start_term;
  1613   // surviving words. base is what we get back from the malloc call
  1602   // surviving words. base is what we get back from the malloc call
  1614   size_t* _surviving_young_words_base;
  1603   size_t* _surviving_young_words_base;
  1615   // this points into the array, as we use the first few entries for padding
  1604   // this points into the array, as we use the first few entries for padding
  1616   size_t* _surviving_young_words;
  1605   size_t* _surviving_young_words;
  1617 
  1606 
  1618 #define PADDING_ELEM_NUM (64 / sizeof(size_t))
  1607 #define PADDING_ELEM_NUM (DEFAULT_CACHE_LINE_SIZE / sizeof(size_t))
  1619 
  1608 
  1620   void   add_to_alloc_buffer_waste(size_t waste) { _alloc_buffer_waste += waste; }
  1609   void   add_to_alloc_buffer_waste(size_t waste) { _alloc_buffer_waste += waste; }
  1621 
  1610 
  1622   void   add_to_undo_waste(size_t waste)         { _undo_waste += waste; }
  1611   void   add_to_undo_waste(size_t waste)         { _undo_waste += waste; }
  1623 
  1612 
  1648   ~G1ParScanThreadState() {
  1637   ~G1ParScanThreadState() {
  1649     FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base);
  1638     FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base);
  1650   }
  1639   }
  1651 
  1640 
  1652   RefToScanQueue*   refs()            { return _refs;             }
  1641   RefToScanQueue*   refs()            { return _refs;             }
  1653   OverflowQueue*    overflowed_refs() { return _overflowed_refs;  }
       
  1654   ageTable*         age_table()       { return &_age_table;       }
  1642   ageTable*         age_table()       { return &_age_table;       }
  1655 
  1643 
  1656   G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose) {
  1644   G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose) {
  1657     return _alloc_buffers[purpose];
  1645     return _alloc_buffers[purpose];
  1658   }
  1646   }
  1659 
  1647 
  1660   size_t alloc_buffer_waste()                    { return _alloc_buffer_waste; }
  1648   size_t alloc_buffer_waste() const              { return _alloc_buffer_waste; }
  1661   size_t undo_waste()                            { return _undo_waste; }
  1649   size_t undo_waste() const                      { return _undo_waste; }
  1662 
  1650 
  1663   template <class T> void push_on_queue(T* ref) {
  1651   template <class T> void push_on_queue(T* ref) {
  1664     assert(ref != NULL, "invariant");
  1652     assert(ref != NULL, "invariant");
  1665     assert(has_partial_array_mask(ref) ||
  1653     assert(has_partial_array_mask(ref) ||
  1666            _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(ref)), "invariant");
  1654            _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(ref)), "invariant");
  1669       oop p = clear_partial_array_mask(ref);
  1657       oop p = clear_partial_array_mask(ref);
  1670       // Verify that we point into the CS
  1658       // Verify that we point into the CS
  1671       assert(_g1h->obj_in_cs(p), "Should be in CS");
  1659       assert(_g1h->obj_in_cs(p), "Should be in CS");
  1672     }
  1660     }
  1673 #endif
  1661 #endif
  1674     if (!refs()->push(ref)) {
  1662     refs()->push(ref);
  1675       overflowed_refs()->push(ref);
       
  1676       IF_G1_DETAILED_STATS(note_overflow_push());
       
  1677     } else {
       
  1678       IF_G1_DETAILED_STATS(note_push());
       
  1679     }
       
  1680   }
  1663   }
  1681 
  1664 
  1682   void pop_from_queue(StarTask& ref) {
  1665   void pop_from_queue(StarTask& ref) {
  1683     if (refs()->pop_local(ref)) {
  1666     if (refs()->pop_local(ref)) {
  1684       assert((oop*)ref != NULL, "pop_local() returned true");
  1667       assert((oop*)ref != NULL, "pop_local() returned true");
  1685       assert(UseCompressedOops || !ref.is_narrow(), "Error");
  1668       assert(UseCompressedOops || !ref.is_narrow(), "Error");
  1686       assert(has_partial_array_mask((oop*)ref) ||
  1669       assert(has_partial_array_mask((oop*)ref) ||
  1687              _g1h->is_in_g1_reserved(ref.is_narrow() ? oopDesc::load_decode_heap_oop((narrowOop*)ref)
  1670              _g1h->is_in_g1_reserved(ref.is_narrow() ? oopDesc::load_decode_heap_oop((narrowOop*)ref)
  1688                                                      : oopDesc::load_decode_heap_oop((oop*)ref)),
  1671                                                      : oopDesc::load_decode_heap_oop((oop*)ref)),
  1689               "invariant");
  1672               "invariant");
  1690       IF_G1_DETAILED_STATS(note_pop());
       
  1691     } else {
  1673     } else {
  1692       StarTask null_task;
  1674       StarTask null_task;
  1693       ref = null_task;
  1675       ref = null_task;
  1694     }
  1676     }
  1695   }
  1677   }
  1696 
  1678 
  1697   void pop_from_overflow_queue(StarTask& ref) {
  1679   void pop_from_overflow_queue(StarTask& ref) {
  1698     StarTask new_ref = overflowed_refs()->pop();
  1680     StarTask new_ref;
       
  1681     refs()->pop_overflow(new_ref);
  1699     assert((oop*)new_ref != NULL, "pop() from a local non-empty stack");
  1682     assert((oop*)new_ref != NULL, "pop() from a local non-empty stack");
  1700     assert(UseCompressedOops || !new_ref.is_narrow(), "Error");
  1683     assert(UseCompressedOops || !new_ref.is_narrow(), "Error");
  1701     assert(has_partial_array_mask((oop*)new_ref) ||
  1684     assert(has_partial_array_mask((oop*)new_ref) ||
  1702            _g1h->is_in_g1_reserved(new_ref.is_narrow() ? oopDesc::load_decode_heap_oop((narrowOop*)new_ref)
  1685            _g1h->is_in_g1_reserved(new_ref.is_narrow() ? oopDesc::load_decode_heap_oop((narrowOop*)new_ref)
  1703                                                        : oopDesc::load_decode_heap_oop((oop*)new_ref)),
  1686                                                        : oopDesc::load_decode_heap_oop((oop*)new_ref)),
  1704            "invariant");
  1687            "invariant");
  1705     ref = new_ref;
  1688     ref = new_ref;
  1706   }
  1689   }
  1707 
  1690 
  1708   int refs_to_scan()                             { return refs()->size();                 }
  1691   int refs_to_scan()            { return refs()->size(); }
  1709   int overflowed_refs_to_scan()                  { return overflowed_refs()->length();    }
  1692   int overflowed_refs_to_scan() { return refs()->overflow_stack()->length(); }
  1710 
  1693 
  1711   template <class T> void update_rs(HeapRegion* from, T* p, int tid) {
  1694   template <class T> void update_rs(HeapRegion* from, T* p, int tid) {
  1712     if (G1DeferredRSUpdate) {
  1695     if (G1DeferredRSUpdate) {
  1713       deferred_rs_update(from, p, tid);
  1696       deferred_rs_update(from, p, tid);
  1714     } else {
  1697     } else {
  1773   }
  1756   }
  1774 
  1757 
  1775   int* hash_seed() { return &_hash_seed; }
  1758   int* hash_seed() { return &_hash_seed; }
  1776   int  queue_num() { return _queue_num; }
  1759   int  queue_num() { return _queue_num; }
  1777 
  1760 
  1778   size_t term_attempts()   { return _term_attempts; }
  1761   size_t term_attempts() const  { return _term_attempts; }
  1779   void note_term_attempt() { _term_attempts++; }
  1762   void note_term_attempt() { _term_attempts++; }
  1780 
       
  1781 #if G1_DETAILED_STATS
       
  1782   int pushes()          { return _pushes; }
       
  1783   int pops()            { return _pops; }
       
  1784   int steals()          { return _steals; }
       
  1785   int steal_attempts()  { return _steal_attempts; }
       
  1786   int overflow_pushes() { return _overflow_pushes; }
       
  1787 
       
  1788   void note_push()          { _pushes++; }
       
  1789   void note_pop()           { _pops++; }
       
  1790   void note_steal()         { _steals++; }
       
  1791   void note_steal_attempt() { _steal_attempts++; }
       
  1792   void note_overflow_push() { _overflow_pushes++; }
       
  1793 #endif
       
  1794 
  1763 
  1795   void start_strong_roots() {
  1764   void start_strong_roots() {
  1796     _start_strong_roots = os::elapsedTime();
  1765     _start_strong_roots = os::elapsedTime();
  1797   }
  1766   }
  1798   void end_strong_roots() {
  1767   void end_strong_roots() {
  1799     _strong_roots_time += (os::elapsedTime() - _start_strong_roots);
  1768     _strong_roots_time += (os::elapsedTime() - _start_strong_roots);
  1800   }
  1769   }
  1801   double strong_roots_time() { return _strong_roots_time; }
  1770   double strong_roots_time() const { return _strong_roots_time; }
  1802 
  1771 
  1803   void start_term_time() {
  1772   void start_term_time() {
  1804     note_term_attempt();
  1773     note_term_attempt();
  1805     _start_term = os::elapsedTime();
  1774     _start_term = os::elapsedTime();
  1806   }
  1775   }
  1807   void end_term_time() {
  1776   void end_term_time() {
  1808     _term_time += (os::elapsedTime() - _start_term);
  1777     _term_time += (os::elapsedTime() - _start_term);
  1809   }
  1778   }
  1810   double term_time() { return _term_time; }
  1779   double term_time() const { return _term_time; }
  1811 
  1780 
  1812   double elapsed() {
  1781   double elapsed_time() const {
  1813     return os::elapsedTime() - _start;
  1782     return os::elapsedTime() - _start;
  1814   }
  1783   }
       
  1784 
       
  1785   static void
       
  1786     print_termination_stats_hdr(outputStream* const st = gclog_or_tty);
       
  1787   void
       
  1788     print_termination_stats(int i, outputStream* const st = gclog_or_tty) const;
  1815 
  1789 
  1816   size_t* surviving_young_words() {
  1790   size_t* surviving_young_words() {
  1817     // We add on to hide entry 0 which accumulates surviving words for
  1791     // We add on to hide entry 0 which accumulates surviving words for
  1818     // age -1 regions (i.e. non-young ones)
  1792     // age -1 regions (i.e. non-young ones)
  1819     return _surviving_young_words;
  1793     return _surviving_young_words;