Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1913 | jaeger | 1 | /* tp_obj tp_track(TP,tp_obj v) { return v; } |
2 | void tp_grey(TP,tp_obj v) { } |
||
3 | void tp_full(TP) { } |
||
4 | void tp_gc_init(TP) { } |
||
5 | void tp_gc_deinit(TP) { } |
||
6 | void tp_delete(TP,tp_obj v) { }*/ |
||
7 | |||
8 | void tp_grey(TP,tp_obj v) { |
||
9 | if (v.type < TP_STRING || (!v.gci.data) || *v.gci.data) { return; } |
||
10 | *v.gci.data = 1; |
||
11 | if (v.type == TP_STRING || v.type == TP_DATA) { |
||
12 | _tp_list_appendx(tp,tp->black,v); |
||
13 | return; |
||
14 | } |
||
15 | _tp_list_appendx(tp,tp->grey,v); |
||
16 | } |
||
17 | |||
18 | void tp_follow(TP,tp_obj v) { |
||
19 | int type = v.type; |
||
20 | if (type == TP_LIST) { |
||
21 | int n; |
||
22 | for (n=0; n |
||
23 | tp_grey(tp,v.list.val->items[n]); |
||
24 | } |
||
25 | } |
||
26 | if (type == TP_DICT) { |
||
27 | int i; |
||
28 | for (i=0; i |
||
29 | int n = _tp_dict_next(tp,v.dict.val); |
||
30 | tp_grey(tp,v.dict.val->items[n].key); |
||
31 | tp_grey(tp,v.dict.val->items[n].val); |
||
32 | } |
||
33 | } |
||
34 | if (type == TP_FNC) { |
||
35 | tp_grey(tp,v.fnc.info->self); |
||
36 | tp_grey(tp,v.fnc.info->globals); |
||
37 | } |
||
38 | } |
||
39 | |||
40 | void tp_reset(TP) { |
||
41 | int n; |
||
42 | _tp_list *tmp; |
||
43 | for (n=0; n |
||
44 | *tp->black->items[n].gci.data = 0; |
||
45 | } |
||
46 | tmp = tp->white; |
||
47 | tp->white = tp->black; |
||
48 | tp->black = tmp; |
||
49 | } |
||
50 | |||
51 | void tp_gc_init(TP) { |
||
52 | tp->white = _tp_list_new(); |
||
53 | tp->strings = _tp_dict_new(); |
||
54 | tp->grey = _tp_list_new(); |
||
55 | tp->black = _tp_list_new(); |
||
56 | tp->steps = 0; |
||
57 | } |
||
58 | |||
59 | void tp_gc_deinit(TP) { |
||
60 | _tp_list_free(tp->white); |
||
61 | _tp_dict_free(tp->strings); |
||
62 | _tp_list_free(tp->grey); |
||
63 | _tp_list_free(tp->black); |
||
64 | } |
||
65 | |||
66 | void tp_delete(TP,tp_obj v) { |
||
67 | int type = v.type; |
||
68 | if (type == TP_LIST) { |
||
69 | _tp_list_free(v.list.val); |
||
70 | return; |
||
71 | } else if (type == TP_DICT) { |
||
72 | _tp_dict_free(v.dict.val); |
||
73 | return; |
||
74 | } else if (type == TP_STRING) { |
||
75 | tp_free(v.string.info); |
||
76 | return; |
||
77 | } else if (type == TP_DATA) { |
||
78 | if (v.data.info->free) { |
||
79 | v.data.info->free(tp,v); |
||
80 | } |
||
81 | tp_free(v.data.info); |
||
82 | return; |
||
83 | } else if (type == TP_FNC) { |
||
84 | tp_free(v.fnc.info); |
||
85 | return; |
||
86 | } |
||
87 | tp_raise(,"tp_delete(%s)",TP_CSTR(v)); |
||
88 | } |
||
89 | |||
90 | void tp_collect(TP) { |
||
91 | int n; |
||
92 | for (n=0; n |
||
93 | tp_obj r = tp->white->items[n]; |
||
94 | if (*r.gci.data) { continue; } |
||
95 | if (r.type == TP_STRING) { |
||
96 | /*this can't be moved into tp_delete, because tp_delete is |
||
97 | also used by tp_track_s to delete redundant strings*/ |
||
98 | _tp_dict_del(tp,tp->strings,r,"tp_collect"); |
||
99 | } |
||
100 | tp_delete(tp,r); |
||
101 | } |
||
102 | tp->white->len = 0; |
||
103 | tp_reset(tp); |
||
104 | } |
||
105 | |||
106 | void _tp_gcinc(TP) { |
||
107 | tp_obj v; |
||
108 | if (!tp->grey->len) { |
||
109 | return; |
||
110 | } |
||
111 | v = _tp_list_pop(tp,tp->grey,tp->grey->len-1,"_tp_gcinc"); |
||
112 | tp_follow(tp,v); |
||
113 | _tp_list_appendx(tp,tp->black,v); |
||
114 | } |
||
115 | |||
116 | void tp_full(TP) { |
||
117 | while (tp->grey->len) { |
||
118 | _tp_gcinc(tp); |
||
119 | } |
||
120 | tp_collect(tp); |
||
121 | tp_follow(tp,tp->root); |
||
122 | } |
||
123 | |||
124 | void tp_gcinc(TP) { |
||
125 | tp->steps += 1; |
||
126 | if (tp->steps < TP_GCMAX || tp->grey->len > 0) { |
||
127 | _tp_gcinc(tp); _tp_gcinc(tp); |
||
128 | } |
||
129 | if (tp->steps < TP_GCMAX || tp->grey->len > 0) { return; } |
||
130 | tp->steps = 0; |
||
131 | tp_full(tp); |
||
132 | return; |
||
133 | } |
||
134 | |||
135 | tp_obj tp_track(TP,tp_obj v) { |
||
136 | if (v.type == TP_STRING) { |
||
137 | int i = _tp_dict_find(tp,tp->strings,v); |
||
138 | if (i != -1) { |
||
139 | tp_delete(tp,v); |
||
140 | v = tp->strings->items[i].key; |
||
141 | tp_grey(tp,v); |
||
142 | return v; |
||
143 | } |
||
144 | _tp_dict_setx(tp,tp->strings,v,tp_True); |
||
145 | } |
||
146 | tp_gcinc(tp); |
||
147 | tp_grey(tp,v); |
||
148 | return v; |
||
149 | } |
||
150 | |||
151 | /**/>>> |
||
152 |