55 #include <boost/archive/xml_oarchive.hpp>
56 #include <boost/archive/xml_iarchive.hpp>
57 #include <boost/serialization/access.hpp>
58 #include <boost/serialization/export.hpp>
59 #include <boost/serialization/version.hpp>
79 #define CXXR_NEW(T) CXXR::GCNode::expose(new T)
189 ++GCNode::s_inhibitor_count;
194 --GCNode::s_inhibitor_count;
203 return s_inhibitor_count != 0;
216 m_rcmmu(s_mark | s_moribund_mask | 1)
220 s_moribund->push_back(
this);
242 __attribute__((hot,fastcall))
244 static void*
operator new(
size_t bytes);
248 static void*
operator new(size_t,
void* where)
262 static void operator delete(
void* p,
size_t bytes)
306 alreadyExposedError();
379 return (m_rcmmu & 1) == 0;
395 #ifdef CHECK_EXPOSURE
396 abortIfNotExposed(node);
444 friend class boost::serialization::access;
456 class Marker :
public const_visitor {
462 unsigned int marksApplied()
const
464 return m_marks_applied;
468 void operator()(
const GCNode* node);
470 unsigned int m_marks_applied;
472 std::vector<const GCNode*> m_ariadne;
476 typedef HeterogeneousList<GCNode> List;
481 static std::vector<const GCNode*>* s_moribund;
484 static List* s_reachable;
488 static const size_t s_gclite_margin;
493 static size_t s_gclite_threshold;
496 static unsigned int s_num_nodes;
497 static unsigned int s_inhibitor_count;
505 static unsigned int s_last_id;
510 static const GCNode* s_watch_addr;
511 static unsigned int s_watch_id;
516 static const unsigned char s_decinc_refcount[];
517 static unsigned char s_mark;
525 static const unsigned char s_mark_mask = 0x80;
526 static const unsigned char s_moribund_mask = 0x40;
527 static const unsigned char s_refcount_mask = 0x3e;
528 mutable unsigned char m_rcmmu;
540 GCNode(
const GCNode&);
541 GCNode& operator=(
const GCNode&);
550 static void abortIfNotExposed(
const GCNode* node);
554 static void alreadyExposedError();
557 static void cleanup();
562 static void decRefCount(
const GCNode* node)
565 unsigned char& rcmmu = node->m_rcmmu;
566 rcmmu ^= s_decinc_refcount[rcmmu & s_refcount_mask];
567 if ((rcmmu & (s_refcount_mask | s_moribund_mask)) == 0)
568 node->makeMoribund();
577 __attribute__((cold))
583 static void incRefCount(
const GCNode* node)
586 unsigned char& rcmmu = node->m_rcmmu;
587 rcmmu ^= s_decinc_refcount[(rcmmu & s_refcount_mask) + 1];
600 static void initialize();
602 bool isMarked()
const
604 return (m_rcmmu & s_mark_mask) == s_mark;
609 __attribute__((hot,fastcall))
611 void makeMoribund()
const;
622 template <
class Archive>
623 void serialize(Archive & ar,
const unsigned int version);
634 friend class GCEdgeBase;
635 friend class SchwarzCounter<GCNode>;
639 template <
class Archive>
640 void CXXR::GCNode::serialize(Archive & ar,
const unsigned int version) {
642 std::ostringstream oss;
644 std::string addr = oss.str();
645 ar & BOOST_SERIALIZATION_NVP(addr);
650 ar & BOOST_SERIALIZATION_NVP(
id);