aboutsummaryrefslogtreecommitdiffstats
path: root/src/gc.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-06-28 23:29:27 +0000
committerDavid Robillard <d@drobilla.net>2009-06-28 23:29:27 +0000
commit2d925912c38c2557ac853fb1b6de5fd6e5d4c5b5 (patch)
tree2cba1e1d747218b1e9b1c55926e135cf21c8e586 /src/gc.cpp
parent84274ac380968df9fb49bcbf6f3d494536d7a548 (diff)
downloadresp-2d925912c38c2557ac853fb1b6de5fd6e5d4c5b5.tar.gz
resp-2d925912c38c2557ac853fb1b6de5fd6e5d4c5b5.tar.bz2
resp-2d925912c38c2557ac853fb1b6de5fd6e5d4c5b5.zip
Move code into src directory.
git-svn-id: http://svn.drobilla.net/resp/tuplr@160 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src/gc.cpp')
-rw-r--r--src/gc.cpp92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/gc.cpp b/src/gc.cpp
new file mode 100644
index 0000000..3964324
--- /dev/null
+++ b/src/gc.cpp
@@ -0,0 +1,92 @@
+/* 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 <cassert>
+#include <set>
+#include <iostream>
+#include "tuplr.hpp"
+
+using namespace std;
+
+void*
+GC::alloc(size_t size, GC::Tag tag)
+{
+ size += (4 - (size % 4)); // Align to 32-bits
+ size += sizeof(Object::Header);
+ void* ret = malloc(size);
+ ((Object::Header*)ret)->mark = 0;
+ ((Object::Header*)ret)->tag = tag;
+ ret = (char*)ret + sizeof(Object::Header);
+ _heap.push_back((Object*)ret);
+ return ret;
+}
+
+inline void
+mark(const Object* obj)
+{
+ if (!obj || obj->marked())
+ return;
+
+ obj->mark(true);
+ 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;
+ }
+}
+
+void
+GC::collect(const Roots& roots)
+{
+ //const size_t oldSize = _heap.size();
+
+ for (Roots::const_iterator i = roots.begin(); i != roots.end(); ++i)
+ mark(*i);
+
+ for (Heap::iterator i = _heap.begin(); i != _heap.end();) {
+ assert((*i)->tag() == GC::TAG_AST || (*i)->tag() == GC::TAG_FRAME);
+ Heap::iterator next = i;
+ ++next;
+
+ if ((*i)->marked()) {
+ (*i)->mark(false);
+ } else {
+ switch ((*i)->tag()) {
+ case GC::TAG_FRAME:
+ free((char*)(*i) - sizeof(Object::Header));
+ _heap.erase(i);
+ break;
+ case GC::TAG_AST:
+ AST* ast = (AST*)*i;
+ if (!ast->to<AType*>()) { // FIXME
+ (ast)->~AST();
+ free((char*)(*i) - sizeof(Object::Header));
+ _heap.erase(i);
+ }
+ break;
+ }
+ }
+ i = next;
+ }
+ //std::cerr << "[GC] Collect " << oldSize << " => " << _heap.size() << endl;
+}
+