aboutsummaryrefslogtreecommitdiffstats
path: root/gc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gc.cpp')
-rw-r--r--gc.cpp71
1 files changed, 71 insertions, 0 deletions
diff --git a/gc.cpp b/gc.cpp
new file mode 100644
index 0000000..1cfd087
--- /dev/null
+++ b/gc.cpp
@@ -0,0 +1,71 @@
+/* Tuplr: A programming language
+ * Copyright (C) 2008-2009 David Robillard <dave@drobilla.net>
+ *
+ * Tuplr is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU Affero General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * Tuplr is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Tuplr. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <set>
+#include <iostream>
+#include "tuplr.hpp"
+
+using namespace std;
+
+void*
+GC::alloc(size_t size)
+{
+ void* ret = malloc(size);
+ _heap.push_back((AST*)ret);
+ return ret;
+}
+
+inline void
+mark(CEnv& cenv, const AST* ast)
+{
+ if (!ast || ast->used)
+ return;
+
+ ast->used = true;
+ const ATuple* tup = ast->to<const ATuple*>();
+ if (tup) {
+ FOREACH(ATuple::const_iterator, i, *tup) {
+ mark(cenv, *i);
+ mark(cenv, cenv.type(*i));
+ }
+ }
+}
+
+void
+GC::collect(CEnv& cenv, const Roots& roots)
+{
+ for (Roots::const_iterator i = roots.begin(); i != roots.end(); ++i)
+ mark(cenv, *i);
+
+ for (Heap::iterator i = _heap.begin(); i != _heap.end();) {
+ Heap::iterator next = i;
+ ++next;
+ if ((*i)->used) {
+ (*i)->used = false;
+ } else {
+ AType* t = (*i)->to<AType*>();
+ // Don't delete types that are keys in the current type substitution
+ if (!t || cenv.tsubst.find(t) == cenv.tsubst.end()) {
+ (*i)->~AST();
+ free(*i);
+ _heap.erase(i);
+ }
+ }
+ i = next;
+ }
+}
+