diff options
author | Teddy <[email protected]> | 2013-08-12 21:34:55 +0800 |
---|---|---|
committer | Teddy <[email protected]> | 2013-08-12 21:34:55 +0800 |
commit | d4d9eee6bef1bc9169e765c9bf3d2382a70198c2 (patch) | |
tree | 045c3eff6ab6a83554ee2cb46651a19b144ff868 | |
parent | 55d1072441582936d119ed04fd8c532c2760b9d4 (diff) |
...
-rw-r--r-- | eval.cpp | 11 | ||||
-rw-r--r-- | gc.cpp | 30 | ||||
-rw-r--r-- | gc.h | 3 | ||||
-rw-r--r-- | types.cpp | 10 |
4 files changed, 39 insertions, 15 deletions
@@ -110,13 +110,11 @@ inline bool make_exec(Pair *ptr) { } inline void push(Pair * &pc, FrameObj ** &top_ptr, Environment *envt) { - gc.attach(pc); // if (pc->car == NULL) // puts("oops"); if (pc->car->is_simple_obj()) // Not an opt invocation { - *top_ptr = envt->get_obj(pc->car); // Objectify the symbol - top_ptr++; + *top_ptr++ = gc.attach(envt->get_obj(pc->car)); // Objectify the symbol pc = pc->next; // Move to the next instruction // if (pc == empty_list) // puts("oops"); @@ -152,6 +150,7 @@ EvalObj *Evaluator::run_expr(Pair *prog) { Continuation *cont = NULL; // envt is this->envt push(pc, top_ptr, envt); + gc.attach(prog); while((*eval_stack)->is_ret_addr()) { @@ -163,7 +162,11 @@ EvalObj *Evaluator::run_expr(Pair *prog) { { Pair *args = empty_list; while (!(*(--top_ptr))->is_ret_addr()) - args = new Pair(static_cast<EvalObj*>(*top_ptr), args); + { + EvalObj* obj = static_cast<EvalObj*>(*top_ptr); + gc.expose(obj); + args = new Pair(obj, args); + } //< static_cast because the while condition RetAddr *ret_addr = static_cast<RetAddr*>(*top_ptr); if (!ret_addr->addr) @@ -13,39 +13,46 @@ GarbageCollector::GarbageCollector() { mapping.clear(); pend_cnt = 0; pending_list = NULL; + collecting = false; } GarbageCollector::PendingEntry::PendingEntry( EvalObj *_obj, PendingEntry *_next) : obj(_obj), next(_next) {} -void GarbageCollector::expose(EvalObj *ptr, bool delay) { +void GarbageCollector::expose(EvalObj *ptr) { bool flag = mapping.count(ptr); if (flag) { - if (!--mapping[ptr] && !delay) +#ifdef GC_DEBUG + fprintf(stderr, "GC: 0x%llx exposed. count = %lu \"%s\"\n", + (ull)ptr, mapping[ptr], ptr->ext_repr().c_str()); +#endif + if (!--mapping[ptr] && collecting) { #ifdef GC_DEBUG fprintf(stderr, "GC: 0x%llx pending. \n", (ull)ptr); #endif pending_list = new PendingEntry(ptr, pending_list); - if (++pend_cnt == GC_QUEUE_SIZE >> 1) - force(); // the gc queue may overflow - } + } } } void GarbageCollector::force() { EvalObj **l = gcq, **r = l; - for (PendingEntry *p = pending_list, *np; p; p = np) +/* for (PendingEntry *p = pending_list, *np; p; p = np) { np = p->next; *r++ = p->obj; delete p; } // fetch the pending pointers in the list // clear the list - pending_list = NULL; + pending_list = NULL; */ + for (EvalObj2Int::iterator it = mapping.begin(); + it != mapping.end(); it++) + if (it->second == 0) *r++ = it->first; + collecting = true; #ifdef GC_DEBUG size_t cnt = 0; fprintf(stderr, "GC: Forcing the clear process...\n"); @@ -57,6 +64,7 @@ void GarbageCollector::force() { cnt++; #endif delete *l; + mapping.erase(*l); // maybe it's a complex structure, // so that more pointers are reported for (PendingEntry *p = pending_list, *np; p; p = np) @@ -70,8 +78,14 @@ void GarbageCollector::force() { pending_list = NULL; } #ifdef GC_DEBUG - fprintf(stderr, "GC: Forced clear, %lu objects are freed\n", cnt); + fprintf(stderr, "GC: Forced clear, %lu objects are freed, " + "%lu remains\n", cnt, mapping.size()); +/* for (EvalObj2Int::iterator it = mapping.begin(); + it != mapping.end(); it++) + fprintf(stderr, "%llx => %lu\n", (ull)it->first, it->second); + */ #endif + collecting = false; } EvalObj *GarbageCollector::attach(EvalObj *ptr) { @@ -19,11 +19,12 @@ class GarbageCollector { EvalObj2Int mapping; size_t pend_cnt; PendingEntry *pending_list; + bool collecting; public: GarbageCollector(); void force(); - void expose(EvalObj *ptr, bool delay = false); + void expose(EvalObj *ptr); EvalObj *attach(EvalObj *ptr); }; @@ -90,9 +90,13 @@ Pair *ProcObj::call(Pair *args, Environment * &genvt, genvt = _envt; cont = _cont; - *top_ptr++ = new RetAddr(NULL); // Mark the entrance of a cont + + gc.expose(static_cast<EvalObj*>(*(top_ptr + 1))); // release opt obj + delete *top_ptr; // release ret addr + + *top_ptr++ = new RetAddr(NULL); // Mark the entrance of a cont gc.expose(args); - return body; // Move pc to the proc entry point + return body; // Move pc to the proc entry point } ReprCons *ProcObj::get_repr_cons() { @@ -222,6 +226,8 @@ BuiltinProcObj::BuiltinProcObj(BuiltinProc f, string _name) : Continuation * &cont, FrameObj ** &top_ptr) { Pair *ret_addr = static_cast<RetAddr*>(*top_ptr)->addr; + gc.expose(static_cast<EvalObj*>(*(top_ptr + 1))); + delete *top_ptr; *top_ptr++ = handler(TO_PAIR(args->cdr), name); gc.expose(args); return ret_addr->next; // Move to the next instruction |