aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeddy <[email protected]>2013-08-13 23:47:38 +0800
committerTeddy <[email protected]>2013-08-13 23:47:38 +0800
commitfaab1d57661e4d68823723a8270205c3a3c6e148 (patch)
tree0117a8d3a07f4d3be91eee01475787d2eb47a5fc
parentfcb069b98bb6a2f59e5ebfd2ad0ab5ee82a1bdb8 (diff)
add gc in `PromObj` and `Continuation`
-rw-r--r--Makefile1
-rw-r--r--gc.cpp4
-rw-r--r--main.cpp1
-rw-r--r--model.cpp4
-rw-r--r--model.h2
-rw-r--r--test/q.scm6
-rw-r--r--types.cpp30
-rw-r--r--types.h12
8 files changed, 48 insertions, 12 deletions
diff --git a/Makefile b/Makefile
index 1f44815..2558d7b 100644
--- a/Makefile
+++ b/Makefile
@@ -4,6 +4,7 @@ BUILD_DIR = build
all: gc_debug
debug: CXX += -DGC_INFO -g -pg
gc_debug: CXX += -DGC_INFO -DGC_DEBUG -g -pg
+release: CXX += -O2
release: $(BUILD_DIR) $(BUILD_DIR)/sonsi
debug: $(BUILD_DIR) $(BUILD_DIR)/sonsi
diff --git a/gc.cpp b/gc.cpp
index e6937c2..85486b6 100644
--- a/gc.cpp
+++ b/gc.cpp
@@ -65,7 +65,7 @@ void GarbageCollector::force() {
for (; l != r; l++)
{
#ifdef GC_DEBUG
- fprintf(stderr, "GC: !!! destroying space 0x%llx. \n", (ull)*l);
+ fprintf(stderr, "GC: !!! destroying space 0x%llx: %s. \n", (ull)*l, (*l)->ext_repr().c_str());
#endif
#ifdef GC_INFO
cnt++;
@@ -114,7 +114,7 @@ EvalObj *GarbageCollector::attach(EvalObj *ptr) {
void GarbageCollector::cycle_resolve() {
if (mapping.size() < GC_CYC_THRESHOLD)
- return;
+ return;
EvalObjSet visited;
Container **clptr = cyc_list;
for (EvalObj2Int::iterator it = mapping.begin();
diff --git a/main.cpp b/main.cpp
index 54fa7d2..42c89b2 100644
--- a/main.cpp
+++ b/main.cpp
@@ -109,5 +109,6 @@ int main(int argc, char **argv) {
fprintf(stderr, "An error occured: %s\n", e.get_msg().c_str());
}
gc.force();
+ gc.cycle_resolve();
}
}
diff --git a/model.cpp b/model.cpp
index 416c583..f802c60 100644
--- a/model.cpp
+++ b/model.cpp
@@ -137,5 +137,5 @@ string EvalObj::ext_repr() {
RetAddr::RetAddr(Pair *_addr, Pair *_state) :
FrameObj(CLS_RET_ADDR), addr(_addr), state(_state) {}
-Container::Container(int otype) : EvalObj(otype | CLS_CONTAINER) {
-}
+Container::Container(int otype, bool override) :
+ EvalObj(otype | (override ? 0 : CLS_CONTAINER)) {}
diff --git a/model.h b/model.h
index 3260fe7..7bfe3c4 100644
--- a/model.h
+++ b/model.h
@@ -109,7 +109,7 @@ class Container: public EvalObj {
public:
bool keep;
size_t gc_refs;
- Container(int otype = 0);
+ Container(int otype = 0, bool override = false);
virtual void gc_decrement() = 0;
virtual void gc_trigger(EvalObj ** &tail, EvalObjSet &visited) = 0;
};
diff --git a/test/q.scm b/test/q.scm
index 498cfad..36adcf8 100644
--- a/test/q.scm
+++ b/test/q.scm
@@ -67,3 +67,9 @@
res)
(display (queen 8))
+
+(define shl '())
+(define shr '())
+(define empty-bits '())
+(define res '())
+(define queen '())
diff --git a/types.cpp b/types.cpp
index 8ae25fc..3e5fd07 100644
--- a/types.cpp
+++ b/types.cpp
@@ -57,13 +57,13 @@ SymObj::SymObj(const string &str) :
return new ReprStr(val);
}
-OptObj::OptObj() : Container(CLS_SIM_OBJ | CLS_OPT_OBJ) {}
+OptObj::OptObj(int otype) : Container(otype | CLS_SIM_OBJ | CLS_OPT_OBJ, true) {}
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) {
+ OptObj(CLS_CONTAINER), body(_body), params(_params), envt(_envt) {
gc.attach(body);
gc.attach(params);
gc.attach(envt);
@@ -187,7 +187,7 @@ ReprCons *CharObj::get_repr_cons() {
}
VecObj::VecObj(size_t size, EvalObj *fill) :
- EvalObj(CLS_SIM_OBJ | CLS_VECT_OBJ) {
+ Container(CLS_SIM_OBJ | CLS_VECT_OBJ) {
vec.resize(size);
for (size_t i = 0; i < size; i++)
{
@@ -237,6 +237,18 @@ ReprCons *VecObj::get_repr_cons() {
return new VectReprCons(this, this);
}
+void VecObj::gc_decrement() {
+ for (EvalObjVec::iterator it = vec.begin();
+ it != vec.end(); it++)
+ GC_CYC_DEC(*it);
+}
+
+void VecObj::gc_trigger(EvalObj ** &tail, EvalObjSet &visited) {
+ for (EvalObjVec::iterator it = vec.begin();
+ it != vec.end(); it++)
+ GC_CYC_TRIGGER(*it);
+}
+
StrObj *StrObj::from_string(string repr) {
size_t len = repr.length();
if (repr[0] == '\"' && repr[len - 1] == '\"')
@@ -453,7 +465,7 @@ VectReprCons::VectReprCons(VecObj *_ptr, EvalObj *_ori) :
}
PromObj::PromObj(EvalObj *exp) :
- EvalObj(CLS_SIM_OBJ | CLS_PROM_OBJ),
+ Container(CLS_SIM_OBJ | CLS_PROM_OBJ),
entry(new Pair(exp, empty_list)), mem(NULL) {
gc.attach(entry);
entry->next = NULL;
@@ -464,6 +476,16 @@ PromObj::~PromObj() {
gc.expose(mem);
}
+void PromObj::gc_decrement() {
+ GC_CYC_DEC(entry);
+ GC_CYC_DEC(mem);
+}
+
+void PromObj::gc_trigger(EvalObj ** &tail, EvalObjSet &visited) {
+ GC_CYC_TRIGGER(entry);
+ GC_CYC_TRIGGER(mem);
+}
+
Pair *PromObj::get_entry() { return entry; }
ReprCons *PromObj::get_repr_cons() { return new ReprStr("#<Promise>"); }
diff --git a/types.h b/types.h
index 0633da1..7db90f5 100644
--- a/types.h
+++ b/types.h
@@ -139,7 +139,7 @@ class Continuation;
*/
class OptObj: public Container {/*{{{*/
public:
- OptObj();
+ OptObj(int otype = 0);
/**
* The function is called when an operation is needed.
* @param args The argument list (the first one is the opt itself)
@@ -300,7 +300,7 @@ class CharObj: public EvalObj {/*{{{*/
* @class VecObj
* Vector support (currently a wrapper of STL vector)
*/
-class VecObj: public EvalObj {/*{{{*/
+class VecObj: public Container {/*{{{*/
public:
EvalObjVec vec;
/** Construct a vector object */
@@ -315,13 +315,16 @@ class VecObj: public EvalObj {/*{{{*/
void set(size_t idx, EvalObj *obj);
EvalObj *get(size_t idx);
ReprCons *get_repr_cons();
+
+ void gc_decrement();
+ void gc_trigger(EvalObj ** &tail, EvalObjSet &visited);
};/*}}}*/
/**
* @class PromObj
* Promise support (partial)
*/
-class PromObj: public EvalObj {/*{{{*/
+class PromObj: public Container {/*{{{*/
private:
Pair *entry;
EvalObj *mem;
@@ -332,6 +335,9 @@ class PromObj: public EvalObj {/*{{{*/
EvalObj *get_mem();
void feed_mem(EvalObj *res);
ReprCons *get_repr_cons();
+
+ void gc_decrement();
+ void gc_trigger(EvalObj ** &tail, EvalObjSet &visited);
};/*}}}*/
/** @class Environment