1626 // An ObjectClosure used to restore the mark bits of an object |
1626 // An ObjectClosure used to restore the mark bits of an object |
1627 class RestoreMarksClosure : public ObjectClosure { |
1627 class RestoreMarksClosure : public ObjectClosure { |
1628 public: |
1628 public: |
1629 void do_object(oop o) { |
1629 void do_object(oop o) { |
1630 if (o != NULL) { |
1630 if (o != NULL) { |
1631 markOop mark = o->mark(); |
1631 markWord mark = o->mark(); |
1632 if (mark->is_marked()) { |
1632 if (mark.is_marked()) { |
1633 o->init_mark(); |
1633 o->init_mark(); |
1634 } |
1634 } |
1635 } |
1635 } |
1636 } |
1636 } |
1637 }; |
1637 }; |
1639 // ObjectMarker provides the mark and visited functions |
1639 // ObjectMarker provides the mark and visited functions |
1640 class ObjectMarker : AllStatic { |
1640 class ObjectMarker : AllStatic { |
1641 private: |
1641 private: |
1642 // saved headers |
1642 // saved headers |
1643 static GrowableArray<oop>* _saved_oop_stack; |
1643 static GrowableArray<oop>* _saved_oop_stack; |
1644 static GrowableArray<markOop>* _saved_mark_stack; |
1644 static GrowableArray<markWord>* _saved_mark_stack; |
1645 static bool _needs_reset; // do we need to reset mark bits? |
1645 static bool _needs_reset; // do we need to reset mark bits? |
1646 |
1646 |
1647 public: |
1647 public: |
1648 static void init(); // initialize |
1648 static void init(); // initialize |
1649 static void done(); // clean-up |
1649 static void done(); // clean-up |
1654 static inline bool needs_reset() { return _needs_reset; } |
1654 static inline bool needs_reset() { return _needs_reset; } |
1655 static inline void set_needs_reset(bool v) { _needs_reset = v; } |
1655 static inline void set_needs_reset(bool v) { _needs_reset = v; } |
1656 }; |
1656 }; |
1657 |
1657 |
1658 GrowableArray<oop>* ObjectMarker::_saved_oop_stack = NULL; |
1658 GrowableArray<oop>* ObjectMarker::_saved_oop_stack = NULL; |
1659 GrowableArray<markOop>* ObjectMarker::_saved_mark_stack = NULL; |
1659 GrowableArray<markWord>* ObjectMarker::_saved_mark_stack = NULL; |
1660 bool ObjectMarker::_needs_reset = true; // need to reset mark bits by default |
1660 bool ObjectMarker::_needs_reset = true; // need to reset mark bits by default |
1661 |
1661 |
1662 // initialize ObjectMarker - prepares for object marking |
1662 // initialize ObjectMarker - prepares for object marking |
1663 void ObjectMarker::init() { |
1663 void ObjectMarker::init() { |
1664 assert(Thread::current()->is_VM_thread(), "must be VMThread"); |
1664 assert(Thread::current()->is_VM_thread(), "must be VMThread"); |
1665 |
1665 |
1666 // prepare heap for iteration |
1666 // prepare heap for iteration |
1667 Universe::heap()->ensure_parsability(false); // no need to retire TLABs |
1667 Universe::heap()->ensure_parsability(false); // no need to retire TLABs |
1668 |
1668 |
1669 // create stacks for interesting headers |
1669 // create stacks for interesting headers |
1670 _saved_mark_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<markOop>(4000, true); |
1670 _saved_mark_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<markWord>(4000, true); |
1671 _saved_oop_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(4000, true); |
1671 _saved_oop_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(4000, true); |
1672 |
1672 |
1673 if (UseBiasedLocking) { |
1673 if (UseBiasedLocking) { |
1674 BiasedLocking::preserve_marks(); |
1674 BiasedLocking::preserve_marks(); |
1675 } |
1675 } |
1689 } |
1689 } |
1690 |
1690 |
1691 // now restore the interesting headers |
1691 // now restore the interesting headers |
1692 for (int i = 0; i < _saved_oop_stack->length(); i++) { |
1692 for (int i = 0; i < _saved_oop_stack->length(); i++) { |
1693 oop o = _saved_oop_stack->at(i); |
1693 oop o = _saved_oop_stack->at(i); |
1694 markOop mark = _saved_mark_stack->at(i); |
1694 markWord mark = _saved_mark_stack->at(i); |
1695 o->set_mark(mark); |
1695 o->set_mark(mark); |
1696 } |
1696 } |
1697 |
1697 |
1698 if (UseBiasedLocking) { |
1698 if (UseBiasedLocking) { |
1699 BiasedLocking::restore_marks(); |
1699 BiasedLocking::restore_marks(); |
1705 } |
1705 } |
1706 |
1706 |
1707 // mark an object |
1707 // mark an object |
1708 inline void ObjectMarker::mark(oop o) { |
1708 inline void ObjectMarker::mark(oop o) { |
1709 assert(Universe::heap()->is_in(o), "sanity check"); |
1709 assert(Universe::heap()->is_in(o), "sanity check"); |
1710 assert(!o->mark()->is_marked(), "should only mark an object once"); |
1710 assert(!o->mark().is_marked(), "should only mark an object once"); |
1711 |
1711 |
1712 // object's mark word |
1712 // object's mark word |
1713 markOop mark = o->mark(); |
1713 markWord mark = o->mark(); |
1714 |
1714 |
1715 if (mark->must_be_preserved(o)) { |
1715 if (mark.must_be_preserved(o)) { |
1716 _saved_mark_stack->push(mark); |
1716 _saved_mark_stack->push(mark); |
1717 _saved_oop_stack->push(o); |
1717 _saved_oop_stack->push(o); |
1718 } |
1718 } |
1719 |
1719 |
1720 // mark the object |
1720 // mark the object |
1721 o->set_mark(markOopDesc::prototype()->set_marked()); |
1721 o->set_mark(markWord::prototype().set_marked()); |
1722 } |
1722 } |
1723 |
1723 |
1724 // return true if object is marked |
1724 // return true if object is marked |
1725 inline bool ObjectMarker::visited(oop o) { |
1725 inline bool ObjectMarker::visited(oop o) { |
1726 return o->mark()->is_marked(); |
1726 return o->mark().is_marked(); |
1727 } |
1727 } |
1728 |
1728 |
1729 // Stack allocated class to help ensure that ObjectMarker is used |
1729 // Stack allocated class to help ensure that ObjectMarker is used |
1730 // correctly. Constructor initializes ObjectMarker, destructor calls |
1730 // correctly. Constructor initializes ObjectMarker, destructor calls |
1731 // ObjectMarker's done() function to restore object headers. |
1731 // ObjectMarker's done() function to restore object headers. |