comparison src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp @ 1862:b14ec34b1e07

6989448: G1: refactor and simplify G1ParScanThreadState Reviewed-by: iveresov, tonyp
author jcoomes
date Tue, 12 Oct 2010 11:29:45 -0700
parents 894b1d7c7e01
children 35e4e086d5f5
comparison
equal deleted inserted replaced
1861:c32059ef4dc0 1862:b14ec34b1e07
1649 } 1649 }
1650 1650
1651 size_t alloc_buffer_waste() const { return _alloc_buffer_waste; } 1651 size_t alloc_buffer_waste() const { return _alloc_buffer_waste; }
1652 size_t undo_waste() const { return _undo_waste; } 1652 size_t undo_waste() const { return _undo_waste; }
1653 1653
1654 #ifdef ASSERT
1655 bool verify_ref(narrowOop* ref) const;
1656 bool verify_ref(oop* ref) const;
1657 bool verify_task(StarTask ref) const;
1658 #endif // ASSERT
1659
1654 template <class T> void push_on_queue(T* ref) { 1660 template <class T> void push_on_queue(T* ref) {
1655 assert(ref != NULL, "invariant"); 1661 assert(verify_ref(ref), "sanity");
1656 assert(has_partial_array_mask(ref) ||
1657 _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(ref)), "invariant");
1658 #ifdef ASSERT
1659 if (has_partial_array_mask(ref)) {
1660 oop p = clear_partial_array_mask(ref);
1661 // Verify that we point into the CS
1662 assert(_g1h->obj_in_cs(p), "Should be in CS");
1663 }
1664 #endif
1665 refs()->push(ref); 1662 refs()->push(ref);
1666 } 1663 }
1667
1668 void pop_from_queue(StarTask& ref) {
1669 if (refs()->pop_local(ref)) {
1670 assert((oop*)ref != NULL, "pop_local() returned true");
1671 assert(UseCompressedOops || !ref.is_narrow(), "Error");
1672 assert(has_partial_array_mask((oop*)ref) ||
1673 _g1h->is_in_g1_reserved(ref.is_narrow() ? oopDesc::load_decode_heap_oop((narrowOop*)ref)
1674 : oopDesc::load_decode_heap_oop((oop*)ref)),
1675 "invariant");
1676 } else {
1677 StarTask null_task;
1678 ref = null_task;
1679 }
1680 }
1681
1682 void pop_from_overflow_queue(StarTask& ref) {
1683 StarTask new_ref;
1684 refs()->pop_overflow(new_ref);
1685 assert((oop*)new_ref != NULL, "pop() from a local non-empty stack");
1686 assert(UseCompressedOops || !new_ref.is_narrow(), "Error");
1687 assert(has_partial_array_mask((oop*)new_ref) ||
1688 _g1h->is_in_g1_reserved(new_ref.is_narrow() ? oopDesc::load_decode_heap_oop((narrowOop*)new_ref)
1689 : oopDesc::load_decode_heap_oop((oop*)new_ref)),
1690 "invariant");
1691 ref = new_ref;
1692 }
1693
1694 int refs_to_scan() { return (int)refs()->size(); }
1695 int overflowed_refs_to_scan() { return (int)refs()->overflow_stack()->size(); }
1696 1664
1697 template <class T> void update_rs(HeapRegion* from, T* p, int tid) { 1665 template <class T> void update_rs(HeapRegion* from, T* p, int tid) {
1698 if (G1DeferredRSUpdate) { 1666 if (G1DeferredRSUpdate) {
1699 deferred_rs_update(from, p, tid); 1667 deferred_rs_update(from, p, tid);
1700 } else { 1668 } else {
1816 _evac_cl->set_region(r); 1784 _evac_cl->set_region(r);
1817 _evac_cl->do_oop_nv(ref_to_scan); 1785 _evac_cl->do_oop_nv(ref_to_scan);
1818 } 1786 }
1819 } 1787 }
1820 1788
1789 void deal_with_reference(StarTask ref) {
1790 assert(verify_task(ref), "sanity");
1791 if (ref.is_narrow()) {
1792 deal_with_reference((narrowOop*)ref);
1793 } else {
1794 deal_with_reference((oop*)ref);
1795 }
1796 }
1797
1821 public: 1798 public:
1822 void trim_queue() { 1799 void trim_queue();
1823 // I've replicated the loop twice, first to drain the overflow
1824 // queue, second to drain the task queue. This is better than
1825 // having a single loop, which checks both conditions and, inside
1826 // it, either pops the overflow queue or the task queue, as each
1827 // loop is tighter. Also, the decision to drain the overflow queue
1828 // first is not arbitrary, as the overflow queue is not visible
1829 // to the other workers, whereas the task queue is. So, we want to
1830 // drain the "invisible" entries first, while allowing the other
1831 // workers to potentially steal the "visible" entries.
1832
1833 while (refs_to_scan() > 0 || overflowed_refs_to_scan() > 0) {
1834 while (overflowed_refs_to_scan() > 0) {
1835 StarTask ref_to_scan;
1836 assert((oop*)ref_to_scan == NULL, "Constructed above");
1837 pop_from_overflow_queue(ref_to_scan);
1838 // We shouldn't have pushed it on the queue if it was not
1839 // pointing into the CSet.
1840 assert((oop*)ref_to_scan != NULL, "Follows from inner loop invariant");
1841 if (ref_to_scan.is_narrow()) {
1842 assert(UseCompressedOops, "Error");
1843 narrowOop* p = (narrowOop*)ref_to_scan;
1844 assert(!has_partial_array_mask(p) &&
1845 _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(p)), "sanity");
1846 deal_with_reference(p);
1847 } else {
1848 oop* p = (oop*)ref_to_scan;
1849 assert((has_partial_array_mask(p) && _g1h->is_in_g1_reserved(clear_partial_array_mask(p))) ||
1850 _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(p)), "sanity");
1851 deal_with_reference(p);
1852 }
1853 }
1854
1855 while (refs_to_scan() > 0) {
1856 StarTask ref_to_scan;
1857 assert((oop*)ref_to_scan == NULL, "Constructed above");
1858 pop_from_queue(ref_to_scan);
1859 if ((oop*)ref_to_scan != NULL) {
1860 if (ref_to_scan.is_narrow()) {
1861 assert(UseCompressedOops, "Error");
1862 narrowOop* p = (narrowOop*)ref_to_scan;
1863 assert(!has_partial_array_mask(p) &&
1864 _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(p)), "sanity");
1865 deal_with_reference(p);
1866 } else {
1867 oop* p = (oop*)ref_to_scan;
1868 assert((has_partial_array_mask(p) && _g1h->obj_in_cs(clear_partial_array_mask(p))) ||
1869 _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(p)), "sanity");
1870 deal_with_reference(p);
1871 }
1872 }
1873 }
1874 }
1875 }
1876 }; 1800 };