From 254168883050be511b924f200399785d258cab74 Mon Sep 17 00:00:00 2001
From: David Robillard <d@drobilla.net>
Date: Sat, 20 Jun 2009 08:00:45 +0000
Subject: Accurate garbage collection of types without special (kludge) tag.

git-svn-id: http://svn.drobilla.net/resp/tuplr@131 ad02d1e2-f140-0410-9f75-f8b11f17cedd
---
 gc.cpp    | 24 ++++++++++--------------
 llvm.cpp  |  6 ++++++
 tuplr.hpp |  4 +---
 3 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/gc.cpp b/gc.cpp
index 84ebab1..6311058 100644
--- a/gc.cpp
+++ b/gc.cpp
@@ -42,13 +42,15 @@ mark(const Object* obj)
 		return;
 
 	obj->mark(true);
-	if (obj->tag() == GC::TAG_AST) {
-		const AST* ast = static_cast<const AST*>(obj);
-		const ATuple* tup = dynamic_cast<const ATuple*>(ast);
-		if (tup) {
+	switch (obj->tag()) {
+	case GC::TAG_FRAME:
+		break;
+	case GC::TAG_AST:
+		const ATuple* tup = dynamic_cast<const ATuple*>((AST*)obj);
+		if (tup)
 			FOREACH(ATuple::const_iterator, i, *tup)
 				mark(*i);
-		}
+		break;
 	}
 }
 
@@ -61,26 +63,20 @@ GC::collect(const Roots& roots)
 		mark(*i);
 
 	for (Heap::iterator i = _heap.begin(); i != _heap.end();) {
-		assert((*i)->tag() == GC::TAG_AST || (*i)->tag() == GC::TAG_FRAME
-				||(*i)->tag() == GC::TAG_TYPE);
+		assert((*i)->tag() == GC::TAG_AST || (*i)->tag() == GC::TAG_FRAME);
 		Heap::iterator next = i;
 		++next;
 
 		if ((*i)->marked()) {
 			(*i)->mark(false);
 		} else {
-			AST* ast;
-			switch ((GC::Tag)(*i)->tag()) {
+			switch ((*i)->tag()) {
 			case GC::TAG_FRAME:
 				free((char*)(*i) - sizeof(Object::Header));
 				_heap.erase(i);
 				break;
-			case GC::TAG_TYPE:
-				// Don't delete types that are keys in the current type substitution
-				break;
 			case GC::TAG_AST:
-				ast = (AST*)*i;
-				assert(!ast->to<AType*>());
+				AST* ast = (AST*)*i;
 				(ast)->~AST();
 				free((char*)(*i) - sizeof(Object::Header));
 				_heap.erase(i);
diff --git a/llvm.cpp b/llvm.cpp
index 80aaafb..baa7ed3 100644
--- a/llvm.cpp
+++ b/llvm.cpp
@@ -540,6 +540,12 @@ eval(CEnv& cenv, const string& name, istream& is)
 			// Add definitions as GC roots
 			if (result->to<ADefinition*>())
 				cenv.lock(result);
+
+			// Add types in type substition as GC roots
+			for (Subst::iterator i = cenv.tsubst.begin(); i != cenv.tsubst.end(); ++i) {
+				Object::pool.addRoot(i->first);
+				Object::pool.addRoot(i->second);
+			}
 		}
 
 		const Type* ctype = lltype(resultType);
diff --git a/tuplr.hpp b/tuplr.hpp
index 48c3fe6..f70fc9c 100644
--- a/tuplr.hpp
+++ b/tuplr.hpp
@@ -144,8 +144,7 @@ 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
+		TAG_FRAME = 4  ///< Stack frame
 	};
 	typedef std::list<const Object*> Roots;
 	typedef std::list<Object*>       Heap;
@@ -325,7 +324,6 @@ 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