From fa0cdd6234aa73ab0680c37f23664ff8c73cc1cb Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 20 Jun 2009 06:08:23 +0000 Subject: Garbage collection of code-allocated stack frames. git-svn-id: http://svn.drobilla.net/resp/tuplr@130 ad02d1e2-f140-0410-9f75-f8b11f17cedd --- tuplr.hpp | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) (limited to 'tuplr.hpp') diff --git a/tuplr.hpp b/tuplr.hpp index ce0a2f3..48c3fe6 100644 --- a/tuplr.hpp +++ b/tuplr.hpp @@ -142,25 +142,38 @@ struct Object; ///< Object (AST nodes and runtime data) struct CEnv; ///< Compile-Time Environment struct GC { + enum Tag { + TAG_AST = 2, ///< Abstract syntax tree node + TAG_TYPE = 4, ///< Type + TAG_FRAME = 6 ///< Stack frame + }; typedef std::list Roots; typedef std::list Heap; - void* alloc(size_t size); - void collect(CEnv& cenv, const Roots& roots); + void* alloc(size_t size, Tag tag); + void collect(const Roots& roots); void addRoot(const Object* obj) { if (obj) _roots.push_back(obj); } void lock() { _roots.insert(_roots.end(), _heap.begin(), _heap.end()); } const Roots& roots() const { return _roots; } private: - Heap _heap; - Roots _roots; + Heap _heap; + Roots _roots; }; +/// Dynamic (garbage-collected) object struct Object { - Object() : used(false) {} - virtual ~Object() {} + struct Header { + uint8_t mark; + uint8_t tag; + }; - mutable bool used; + /// Always allocated with pool.alloc, so this - sizeof(Header) is a valid Header*. + inline Header* header() const { return (Header*)((char*)this - sizeof(Header)); } - static void* operator new(size_t size) { return pool.alloc(size); } + inline bool marked() const { return header()->mark != 0; } + inline void mark(bool b) const { header()->mark = 1; } + inline GC::Tag tag() const { return (GC::Tag)header()->tag; } + + static void* operator new(size_t size) { return pool.alloc(size, GC::TAG_AST); } static void operator delete(void* ptr) {} static GC pool; }; @@ -181,6 +194,7 @@ extern ostream& operator<<(ostream& out, const AST* ast); /// Base class for all AST nodes struct AST : public Object { AST(Cursor c=Cursor()) : loc(c) {} + virtual ~AST() {} virtual bool operator==(const AST& o) const = 0; virtual bool contains(const AST* child) const { return false; } virtual void constrain(TEnv& tenv, Constraints& c) const {} @@ -233,10 +247,6 @@ struct ATuple : public AST, public vector { push_back(a); va_end(args); } - void free() { - FOREACH(const_iterator, p, *this) - delete *p; - } bool operator==(const AST& rhs) const { const ATuple* rt = rhs.to(); if (!rt || rt->size() != size()) return false; @@ -315,6 +325,7 @@ struct AType : public ATuple { } return false; // never reached } + static void* operator new(size_t size) { return pool.alloc(size, GC::TAG_TYPE); } enum { VAR, PRIM, EXPR } kind; unsigned id; }; -- cgit v1.2.1