kolibrios/programs/develop/tinypy/tinypy/gc.c
jaeger 9fd32b8cdf Uploaded tinypy sources.
git-svn-id: svn://kolibrios.org@1913 a494cfbc-eb01-0410-851d-a64ba20cac60
2011-03-31 09:59:54 +00:00

153 lines
3.5 KiB
C

/* tp_obj tp_track(TP,tp_obj v) { return v; }
void tp_grey(TP,tp_obj v) { }
void tp_full(TP) { }
void tp_gc_init(TP) { }
void tp_gc_deinit(TP) { }
void tp_delete(TP,tp_obj v) { }*/
void tp_grey(TP,tp_obj v) {
if (v.type < TP_STRING || (!v.gci.data) || *v.gci.data) { return; }
*v.gci.data = 1;
if (v.type == TP_STRING || v.type == TP_DATA) {
_tp_list_appendx(tp,tp->black,v);
return;
}
_tp_list_appendx(tp,tp->grey,v);
}
void tp_follow(TP,tp_obj v) {
int type = v.type;
if (type == TP_LIST) {
int n;
for (n=0; n<v.list.val->len; n++) {
tp_grey(tp,v.list.val->items[n]);
}
}
if (type == TP_DICT) {
int i;
for (i=0; i<v.dict.val->len; i++) {
int n = _tp_dict_next(tp,v.dict.val);
tp_grey(tp,v.dict.val->items[n].key);
tp_grey(tp,v.dict.val->items[n].val);
}
}
if (type == TP_FNC) {
tp_grey(tp,v.fnc.info->self);
tp_grey(tp,v.fnc.info->globals);
}
}
void tp_reset(TP) {
int n;
_tp_list *tmp;
for (n=0; n<tp->black->len; n++) {
*tp->black->items[n].gci.data = 0;
}
tmp = tp->white;
tp->white = tp->black;
tp->black = tmp;
}
void tp_gc_init(TP) {
tp->white = _tp_list_new();
tp->strings = _tp_dict_new();
tp->grey = _tp_list_new();
tp->black = _tp_list_new();
tp->steps = 0;
}
void tp_gc_deinit(TP) {
_tp_list_free(tp->white);
_tp_dict_free(tp->strings);
_tp_list_free(tp->grey);
_tp_list_free(tp->black);
}
void tp_delete(TP,tp_obj v) {
int type = v.type;
if (type == TP_LIST) {
_tp_list_free(v.list.val);
return;
} else if (type == TP_DICT) {
_tp_dict_free(v.dict.val);
return;
} else if (type == TP_STRING) {
tp_free(v.string.info);
return;
} else if (type == TP_DATA) {
if (v.data.info->free) {
v.data.info->free(tp,v);
}
tp_free(v.data.info);
return;
} else if (type == TP_FNC) {
tp_free(v.fnc.info);
return;
}
tp_raise(,"tp_delete(%s)",TP_CSTR(v));
}
void tp_collect(TP) {
int n;
for (n=0; n<tp->white->len; n++) {
tp_obj r = tp->white->items[n];
if (*r.gci.data) { continue; }
if (r.type == TP_STRING) {
/*this can't be moved into tp_delete, because tp_delete is
also used by tp_track_s to delete redundant strings*/
_tp_dict_del(tp,tp->strings,r,"tp_collect");
}
tp_delete(tp,r);
}
tp->white->len = 0;
tp_reset(tp);
}
void _tp_gcinc(TP) {
tp_obj v;
if (!tp->grey->len) {
return;
}
v = _tp_list_pop(tp,tp->grey,tp->grey->len-1,"_tp_gcinc");
tp_follow(tp,v);
_tp_list_appendx(tp,tp->black,v);
}
void tp_full(TP) {
while (tp->grey->len) {
_tp_gcinc(tp);
}
tp_collect(tp);
tp_follow(tp,tp->root);
}
void tp_gcinc(TP) {
tp->steps += 1;
if (tp->steps < TP_GCMAX || tp->grey->len > 0) {
_tp_gcinc(tp); _tp_gcinc(tp);
}
if (tp->steps < TP_GCMAX || tp->grey->len > 0) { return; }
tp->steps = 0;
tp_full(tp);
return;
}
tp_obj tp_track(TP,tp_obj v) {
if (v.type == TP_STRING) {
int i = _tp_dict_find(tp,tp->strings,v);
if (i != -1) {
tp_delete(tp,v);
v = tp->strings->items[i].key;
tp_grey(tp,v);
return v;
}
_tp_dict_setx(tp,tp->strings,v,tp_True);
}
tp_gcinc(tp);
tp_grey(tp,v);
return v;
}
/**/