Print this page
rev 2724 : 6484965: G1: piggy-back liveness accounting phase on marking
Summary: Remove the separate counting phase of concurrent marking by tracking the amount of marked bytes and the cards spanned by marked objects in marking task/worker thread local data structures, which are updated as individual objects are marked.
Reviewed-by:

Split Close
Expand all
Collapse all
          --- old/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
          +++ new/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
↓ open down ↓ 840 lines elided ↑ open up ↑
 841  841    // Do any necessary initialization for evacuation-failure handling.
 842  842    // "cl" is the closure that will be used to process evac-failure
 843  843    // objects.
 844  844    void init_for_evac_failure(OopsInHeapRegionClosure* cl);
 845  845    // Do any necessary cleanup for evacuation-failure handling data
 846  846    // structures.
 847  847    void finalize_for_evac_failure();
 848  848  
 849  849    // An attempt to evacuate "obj" has failed; take necessary steps.
 850  850    oop handle_evacuation_failure_par(OopsInHeapRegionClosure* cl, oop obj,
 851      -                                    bool should_mark_root);
      851 +                                    bool should_mark_root,
      852 +                                    int worker_i);
 852  853    void handle_evacuation_failure_common(oop obj, markOop m);
 853  854  
 854  855    // ("Weak") Reference processing support.
 855  856    //
 856  857    // G1 has 2 instances of the referece processor class. One
 857  858    // (_ref_processor_cm) handles reference object discovery
 858  859    // and subsequent processing during concurrent marking cycles.
 859  860    //
 860  861    // The other (_ref_processor_stw) handles reference object
 861  862    // discovery and processing during full GCs and incremental
↓ open down ↓ 795 lines elided ↑ open up ↑
1657 1658    // this is the actual end of the GCLab
1658 1659    HeapWord* _real_end_word;
1659 1660  
1660 1661    // this is the first word, possibly located before the actual start
1661 1662    // of the GCLab, that corresponds to the first bit of the bitmap
1662 1663    HeapWord* _start_word;
1663 1664  
1664 1665    // size of a GCLab in words
1665 1666    size_t _gclab_word_size;
1666 1667  
     1668 +  // The size of the marked objects in this bitmap
     1669 +  size_t _marked_bytes;
     1670 +
     1671 +  // Card bitmap associated with cards spanned by the live objects.
     1672 +  // It's sized for _gclab_word_size _plus_ 1 additional card
     1673 +  // in case the lab does not start at a card boundary
     1674 +  BitMap _card_bm;
     1675 +
     1676 +  // Card number of the base of the LAB. Used to encode
     1677 +  // indices into the bitmap above.
     1678 +  intptr_t _bottom_card_num;
     1679 +
1667 1680    static int shifter() {
1668 1681      return MinObjAlignment - 1;
1669 1682    }
1670 1683  
1671 1684    // how many heap words does a single bitmap word corresponds to?
1672 1685    static size_t bitmap_word_covers_words() {
1673 1686      return BitsPerWord << shifter();
1674 1687    }
1675 1688  
1676 1689    size_t gclab_word_size() const {
↓ open down ↓ 9 lines elided ↑ open up ↑
1686 1699    static size_t bitmap_size_in_bits(size_t gclab_word_size) {
1687 1700      size_t bits_in_bitmap = gclab_word_size >> shifter();
1688 1701      // We are going to ensure that the beginning of a word in this
1689 1702      // bitmap also corresponds to the beginning of a word in the
1690 1703      // global marking bitmap. To handle the case where a GCLab
1691 1704      // starts from the middle of the bitmap, we need to add enough
1692 1705      // space (i.e. up to a bitmap word) to ensure that we have
1693 1706      // enough bits in the bitmap.
1694 1707      return bits_in_bitmap + BitsPerWord - 1;
1695 1708    }
     1709 +
1696 1710  public:
1697 1711    GCLabBitMap(HeapWord* heap_start, size_t gclab_word_size)
1698 1712      : BitMap(bitmap_size_in_bits(gclab_word_size)),
1699 1713        _cm(G1CollectedHeap::heap()->concurrent_mark()),
1700 1714        _shifter(shifter()),
1701 1715        _bitmap_word_covers_words(bitmap_word_covers_words()),
1702 1716        _heap_start(heap_start),
1703 1717        _gclab_word_size(gclab_word_size),
1704 1718        _real_start_word(NULL),
1705 1719        _real_end_word(NULL),
1706      -      _start_word(NULL)
     1720 +      _start_word(NULL),
     1721 +      _marked_bytes(0),
     1722 +      _card_bm((((gclab_word_size * BytesPerWord) + CardTableModRefBS::card_size - 1) >>
     1723 +               CardTableModRefBS::card_shift) + 1,
     1724 +               false /* in_resource_area*/),
     1725 +      _bottom_card_num(0)
1707 1726    {
1708 1727      guarantee( size_in_words() >= bitmap_size_in_words(),
1709 1728                 "just making sure");
1710 1729    }
1711 1730  
1712 1731    inline unsigned heapWordToOffset(HeapWord* addr) {
1713 1732      unsigned offset = (unsigned) pointer_delta(addr, _start_word) >> _shifter;
1714 1733      assert(offset < size(), "offset should be within bounds");
1715 1734      return offset;
1716 1735    }
↓ open down ↓ 12 lines elided ↑ open up ↑
1729 1748        return true;
1730 1749  
1731 1750      bool ret2 = _real_start_word >= _start_word &&
1732 1751        _start_word < _real_end_word &&
1733 1752        (_real_start_word + _gclab_word_size) == _real_end_word &&
1734 1753        (_start_word + _gclab_word_size + _bitmap_word_covers_words)
1735 1754                                                                > _real_end_word;
1736 1755      return ret2;
1737 1756    }
1738 1757  
1739      -  inline bool mark(HeapWord* addr) {
     1758 +  inline bool mark(HeapWord* addr, size_t obj_size) {
1740 1759      guarantee(use_local_bitmaps, "invariant");
1741 1760      assert(fields_well_formed(), "invariant");
1742 1761  
1743 1762      if (addr >= _real_start_word && addr < _real_end_word) {
1744 1763        assert(!isMarked(addr), "should not have already been marked");
1745 1764  
1746 1765        // first mark it on the bitmap
1747 1766        at_put(heapWordToOffset(addr), true);
1748 1767  
     1768 +      MemRegion mr(addr, obj_size);
     1769 +
     1770 +      // Add to the marked_bytes total
     1771 +      _marked_bytes += mr.byte_size();
     1772 +
     1773 +      // Set the bits associated with the cards spanned by the
     1774 +      // object
     1775 +      intptr_t start_card_num =
     1776 +        intptr_t(uintptr_t(mr.start()) >> CardTableModRefBS::card_shift);
     1777 +      intptr_t last_card_num =
     1778 +        intptr_t(uintptr_t(mr.last()) >> CardTableModRefBS::card_shift);
     1779 +
     1780 +      BitMap::idx_t start_idx = start_card_num - _bottom_card_num;
     1781 +      BitMap::idx_t last_idx = last_card_num - _bottom_card_num;
     1782 +
     1783 +      _card_bm.set_range(start_idx, last_idx);
     1784 +      // set_range is exclusive so set the bit for last_idx
     1785 +      _card_bm.set_bit(last_idx);
     1786 +
1749 1787        return true;
1750 1788      } else {
1751 1789        return false;
1752 1790      }
1753 1791    }
1754 1792  
1755 1793    inline bool isMarked(HeapWord* addr) {
1756 1794      guarantee(use_local_bitmaps, "invariant");
1757 1795      assert(fields_well_formed(), "invariant");
1758 1796  
↓ open down ↓ 5 lines elided ↑ open up ↑
1764 1802      clear();
1765 1803  
1766 1804      assert(start != NULL, "invariant");
1767 1805      _real_start_word = start;
1768 1806      _real_end_word   = start + _gclab_word_size;
1769 1807  
1770 1808      size_t diff =
1771 1809        pointer_delta(start, _heap_start) % _bitmap_word_covers_words;
1772 1810      _start_word = start - diff;
1773 1811  
     1812 +    // Initialize _bottom_card_num for the card bitmap
     1813 +    _bottom_card_num =
     1814 +      intptr_t(uintptr_t(_real_start_word) >> CardTableModRefBS::card_shift);
     1815 +    
     1816 +    _marked_bytes = 0;
     1817 +    _card_bm.clear();
     1818 +
1774 1819      assert(fields_well_formed(), "invariant");
1775 1820    }
1776 1821  
1777 1822  #ifndef PRODUCT
1778 1823    void verify() {
1779 1824      // verify that the marks have been propagated
1780 1825      GCLabBitMapClosure cl(_cm, this);
1781 1826      iterate(&cl);
1782 1827    }
1783 1828  #endif // PRODUCT
1784 1829  
1785      -  void retire() {
     1830 +  void retire(int worker_i) {
1786 1831      guarantee(use_local_bitmaps, "invariant");
1787 1832      assert(fields_well_formed(), "invariant");
1788 1833  
1789 1834      if (_start_word != NULL) {
1790 1835        CMBitMap*       mark_bitmap = _cm->nextMarkBitMap();
1791 1836  
1792 1837        // this means that the bitmap was set up for the GCLab
1793 1838        assert(_real_start_word != NULL && _real_end_word != NULL, "invariant");
1794 1839  
1795 1840        mark_bitmap->mostly_disjoint_range_union(this,
1796 1841                                  0, // always start from the start of the bitmap
1797 1842                                  _start_word,
1798 1843                                  gclab_real_word_size());
1799      -      _cm->grayRegionIfNecessary(MemRegion(_real_start_word, _real_end_word));
     1844 +
     1845 +      // Note that not all objects copied into the LAB will have a bit set
     1846 +      // in the LAB bitmap (the LAB bitmap is used to propagate marks).
     1847 +      // So we can't just add the entire lab and its bitmap to the count
     1848 +      // data. The marking information has been recorded in _marked_bytes
     1849 +      // and _card_bm.
     1850 +      MemRegion lab_region(_real_start_word, _real_end_word);
     1851 +      _cm->add_to_count_data_for_region(lab_region,
     1852 +                                        &_card_bm,
     1853 +                                        _bottom_card_num,
     1854 +                                        _marked_bytes,
     1855 +                                        worker_i);
     1856 +
     1857 +      _cm->grayRegionIfNecessary(lab_region);
1800 1858  
1801 1859  #ifndef PRODUCT
1802 1860        if (use_local_bitmaps && verify_local_bitmaps)
1803 1861          verify();
1804 1862  #endif // PRODUCT
1805 1863      } else {
1806 1864        assert(_real_start_word == NULL && _real_end_word == NULL, "invariant");
1807 1865      }
1808 1866    }
1809 1867  
↓ open down ↓ 1 lines elided ↑ open up ↑
1811 1869      return (bitmap_size_in_bits(gclab_word_size()) + BitsPerWord - 1) / BitsPerWord;
1812 1870    }
1813 1871  
1814 1872  };
1815 1873  
1816 1874  class G1ParGCAllocBuffer: public ParGCAllocBuffer {
1817 1875  private:
1818 1876    bool        _retired;
1819 1877    bool        _should_mark_objects;
1820 1878    GCLabBitMap _bitmap;
     1879 +  int         _worker_i;
1821 1880  
1822 1881  public:
1823      -  G1ParGCAllocBuffer(size_t gclab_word_size);
     1882 +  G1ParGCAllocBuffer(size_t gclab_word_size, int worker_i);
1824 1883  
1825      -  inline bool mark(HeapWord* addr) {
     1884 +  inline bool mark(HeapWord* addr, size_t obj_size) {
1826 1885      guarantee(use_local_bitmaps, "invariant");
1827 1886      assert(_should_mark_objects, "invariant");
1828      -    return _bitmap.mark(addr);
     1887 +    return _bitmap.mark(addr, obj_size);
1829 1888    }
1830 1889  
1831 1890    inline void set_buf(HeapWord* buf) {
1832 1891      if (use_local_bitmaps && _should_mark_objects) {
1833 1892        _bitmap.set_buffer(buf);
1834 1893      }
1835 1894      ParGCAllocBuffer::set_buf(buf);
1836 1895      _retired = false;
1837 1896    }
1838 1897  
1839 1898    inline void retire(bool end_of_gc, bool retain) {
1840 1899      if (_retired)
1841 1900        return;
1842 1901      if (use_local_bitmaps && _should_mark_objects) {
1843      -      _bitmap.retire();
     1902 +      _bitmap.retire(_worker_i);
1844 1903      }
1845 1904      ParGCAllocBuffer::retire(end_of_gc, retain);
1846 1905      _retired = true;
1847 1906    }
1848 1907  };
1849 1908  
1850 1909  class G1ParScanThreadState : public StackObj {
1851 1910  protected:
1852 1911    G1CollectedHeap* _g1h;
1853 1912    RefToScanQueue*  _refs;
↓ open down ↓ 225 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX