aboutsummaryrefslogtreecommitdiffstats
path: root/gc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gc.cpp')
-rw-r--r--gc.cpp59
1 files changed, 42 insertions, 17 deletions
diff --git a/gc.cpp b/gc.cpp
index a321d35..84ebab1 100644
--- a/gc.cpp
+++ b/gc.cpp
@@ -15,6 +15,7 @@
* along with Tuplr. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <cassert>
#include <set>
#include <iostream>
#include "tuplr.hpp"
@@ -22,48 +23,72 @@
using namespace std;
void*
-GC::alloc(size_t size)
+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(CEnv& cenv, const Object* obj)
+mark(const Object* obj)
{
- if (!obj || obj->used)
+ if (!obj || obj->marked())
return;
- obj->used = true;
- const ATuple* tup = dynamic_cast<const ATuple*>(obj);
- if (tup) {
- FOREACH(ATuple::const_iterator, i, *tup)
- mark(cenv, *i);
+ 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) {
+ FOREACH(ATuple::const_iterator, i, *tup)
+ mark(*i);
+ }
}
}
void
-GC::collect(CEnv& cenv, const Roots& roots)
+GC::collect(const Roots& roots)
{
+ //const size_t oldSize = _heap.size();
+
for (Roots::const_iterator i = roots.begin(); i != roots.end(); ++i)
- mark(cenv, *i);
+ 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);
Heap::iterator next = i;
++next;
- if ((*i)->used) {
- (*i)->used = false;
+
+ if ((*i)->marked()) {
+ (*i)->mark(false);
} else {
- AType* t = dynamic_cast<AType*>(*i);
- // Don't delete types that are keys in the current type substitution
- if (!t || cenv.tsubst.find(t) == cenv.tsubst.end()) {
- (*i)->~Object();
- free(*i);
+ AST* ast;
+ switch ((GC::Tag)(*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();
+ free((char*)(*i) - sizeof(Object::Header));
_heap.erase(i);
+ break;
}
}
i = next;
}
+ //std::cerr << "[GC] Collect " << oldSize << " => " << _heap.size() << endl;
}