From fcb069b98bb6a2f59e5ebfd2ad0ab5ee82a1bdb8 Mon Sep 17 00:00:00 2001 From: Teddy Date: Tue, 13 Aug 2013 22:07:31 +0800 Subject: add cycle detect for `Pair`, `ProcObj`, `Envt` and `Cont` --- types.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 10 deletions(-) (limited to 'types.cpp') diff --git a/types.cpp b/types.cpp index edeeb99..8ae25fc 100644 --- a/types.cpp +++ b/types.cpp @@ -28,15 +28,13 @@ Pair::~Pair() { } void Pair::gc_decrement() { - if (car->is_container()) - static_cast(car)->gc_refs--; - if (cdr->is_container()) - static_cast(cdr)->gc_refs--; + GC_CYC_DEC(car); + GC_CYC_DEC(cdr); } -void Pair::gc_trigger(EvalObj ** &tail) { - *tail++ = car; - *tail++ = cdr; +void Pair::gc_trigger(EvalObj ** &tail, EvalObjSet &visited) { + GC_CYC_TRIGGER(car); + GC_CYC_TRIGGER(cdr); } ReprCons *Pair::get_repr_cons() { @@ -59,7 +57,10 @@ SymObj::SymObj(const string &str) : return new ReprStr(val); } -OptObj::OptObj() : EvalObj(CLS_SIM_OBJ | CLS_OPT_OBJ) {} +OptObj::OptObj() : Container(CLS_SIM_OBJ | CLS_OPT_OBJ) {} + +void OptObj::gc_decrement() {} +void OptObj::gc_trigger(EvalObj ** &tail, EvalObjSet &visited) {} ProcObj::ProcObj(Pair *_body, Environment *_envt, EvalObj *_params) : OptObj(), body(_body), params(_params), envt(_envt) { @@ -114,6 +115,18 @@ Pair *ProcObj::call(Pair *_args, Environment * &genvt, return body; // Move pc to the proc entry point } +void ProcObj::gc_decrement() { + GC_CYC_DEC(body); + GC_CYC_DEC(params); + GC_CYC_DEC(envt); +} + +void ProcObj::gc_trigger(EvalObj ** &tail, EvalObjSet &visited) { + GC_CYC_TRIGGER(body); + GC_CYC_TRIGGER(params); + GC_CYC_TRIGGER(envt); +} + ReprCons *ProcObj::get_repr_cons() { return new ReprStr("#"); } @@ -268,7 +281,8 @@ ReprCons *BuiltinProcObj::get_repr_cons() { return new ReprStr("#"); } -Environment::Environment(Environment *_prev_envt) : prev_envt(_prev_envt) { +Environment::Environment(Environment *_prev_envt) : + Container(), prev_envt(_prev_envt) { gc.attach(prev_envt); } @@ -283,6 +297,20 @@ ReprCons *Environment::get_repr_cons() { return new ReprStr("#"); } +void Environment::gc_decrement() { + GC_CYC_DEC(prev_envt); + for (Str2EvalObj::iterator it = binding.begin(); + it != binding.end(); it++) + GC_CYC_DEC(it->second); +} + +void Environment::gc_trigger(EvalObj ** &tail, EvalObjSet &visited) { + GC_CYC_TRIGGER(prev_envt); + for (Str2EvalObj::iterator it = binding.begin(); + it != binding.end(); it++) + GC_CYC_TRIGGER(it->second); +} + bool Environment::add_binding(SymObj *sym_obj, EvalObj *eval_obj, bool def) { bool found = false; string name(sym_obj->val); @@ -337,7 +365,7 @@ EvalObj *Environment::get_obj(EvalObj *obj) { Continuation::Continuation(Environment *_envt, Pair *_pc, Continuation *_prev_cont, Pair *_proc_body) : - prev_cont(_prev_cont), envt(_envt), pc(_pc), proc_body(_proc_body) { + Container(), prev_cont(_prev_cont), envt(_envt), pc(_pc), proc_body(_proc_body) { gc.attach(prev_cont); gc.attach(envt); } @@ -347,6 +375,16 @@ Continuation::~Continuation() { gc.expose(envt); } +void Continuation::gc_decrement() { + GC_CYC_DEC(prev_cont); + GC_CYC_DEC(envt); +} + +void Continuation::gc_trigger(EvalObj ** &tail, EvalObjSet &visited) { + GC_CYC_TRIGGER(prev_cont); + GC_CYC_TRIGGER(envt); +} + ReprCons *Continuation::get_repr_cons() { return new ReprStr("#"); } -- cgit v1.2.3