48 |
{ |
{ |
49 |
int i; |
int i; |
50 |
|
|
51 |
env->gc_limit= 200; |
env->gc_limit= 400000; |
52 |
env->gc_count= 0; |
env->gc_count= 0; |
53 |
env->gc_ref= NULL; |
env->gc_ref= NULL; |
54 |
|
|
80 |
|
|
81 |
env->head= env->head->next; /* Remove the top stack item */ |
env->head= env->head->next; /* Remove the top stack item */ |
82 |
free(temp); /* Free the old top stack item */ |
free(temp); /* Free the old top stack item */ |
|
|
|
|
env->gc_limit--; |
|
83 |
} |
} |
84 |
|
|
85 |
/* Returns a pointer to a pointer to an element in the hash table. */ |
/* Returns a pointer to a pointer to an element in the hash table. */ |
123 |
nitem->next= env->gc_ref; |
nitem->next= env->gc_ref; |
124 |
env->gc_ref= nitem; |
env->gc_ref= nitem; |
125 |
|
|
126 |
env->gc_count++; |
env->gc_count += sizeof(value); |
127 |
nval->gc_garb= 1; |
nval->gc.flag.mark= 0; |
128 |
|
nval->gc.flag.protect= 0; |
129 |
|
|
130 |
return nval; |
return nval; |
131 |
} |
} |
136 |
{ |
{ |
137 |
stackitem *iterator; |
stackitem *iterator; |
138 |
|
|
139 |
if(val->gc_garb==0) |
if(val->gc.flag.mark) |
140 |
return; |
return; |
141 |
|
|
142 |
val->gc_garb= 0; |
val->gc.flag.mark= 1; |
143 |
|
|
144 |
if(val->type==list) { |
if(val->type==list) { |
145 |
iterator= val->content.ptr; |
iterator= val->content.ptr; |
166 |
symbol *tsymb; |
symbol *tsymb; |
167 |
int i; |
int i; |
168 |
|
|
169 |
|
if(env->interactive){ |
170 |
|
printf("Garbage collecting."); |
171 |
|
} |
172 |
|
|
173 |
/* Mark values on stack */ |
/* Mark values on stack */ |
174 |
iterator= env->head; |
iterator= env->head; |
175 |
while(iterator!=NULL) { |
while(iterator!=NULL) { |
177 |
iterator= iterator->next; |
iterator= iterator->next; |
178 |
} |
} |
179 |
|
|
180 |
|
if(env->interactive){ |
181 |
|
printf("."); |
182 |
|
} |
183 |
|
|
184 |
/* Mark values in hashtable */ |
/* Mark values in hashtable */ |
185 |
for(i= 0; i<HASHTBLSIZE; i++) { |
for(i= 0; i<HASHTBLSIZE; i++) { |
186 |
tsymb= env->symbols[i]; |
tsymb= env->symbols[i]; |
191 |
} |
} |
192 |
} |
} |
193 |
|
|
194 |
|
if(env->interactive){ |
195 |
|
printf("."); |
196 |
|
} |
197 |
|
|
198 |
env->gc_count= 0; |
env->gc_count= 0; |
199 |
|
|
200 |
while(env->gc_ref!=NULL) { /* Sweep unused values */ |
while(env->gc_ref!=NULL) { /* Sweep unused values */ |
201 |
|
|
202 |
if(env->gc_ref->item->gc_garb |
if(!(env->gc_ref->item->gc.no_gc)){ /* neither mark nor protect */ |
|
&& !(env->gc_ref->item->gc_protect)) { |
|
203 |
|
|
204 |
switch(env->gc_ref->item->type) { /* Remove content */ |
switch(env->gc_ref->item->type) { /* Remove content */ |
205 |
case string: |
case string: |
218 |
free(env->gc_ref); /* Remove value */ |
free(env->gc_ref); /* Remove value */ |
219 |
env->gc_ref= titem; |
env->gc_ref= titem; |
220 |
continue; |
continue; |
221 |
|
} else { |
222 |
|
env->gc_count += sizeof(value); |
223 |
|
if(env->gc_ref->item->type == string) |
224 |
|
env->gc_count += strlen(env->gc_ref->item->content.ptr); |
225 |
} |
} |
226 |
|
|
227 |
/* Keep values */ |
/* Keep values */ |
228 |
titem= env->gc_ref->next; |
titem= env->gc_ref->next; |
229 |
env->gc_ref->next= new_head; |
env->gc_ref->next= new_head; |
230 |
new_head= env->gc_ref; |
new_head= env->gc_ref; |
231 |
new_head->item->gc_garb= 1; |
new_head->item->gc.flag.mark= 0; |
232 |
env->gc_ref= titem; |
env->gc_ref= titem; |
|
env->gc_count++; |
|
233 |
} |
} |
234 |
|
|
235 |
env->gc_limit= env->gc_count*2; |
if (env->gc_limit < env->gc_count*2) |
236 |
|
env->gc_limit= env->gc_count*2; |
237 |
|
|
238 |
env->gc_ref= new_head; |
env->gc_ref= new_head; |
239 |
|
|
240 |
|
if(env->interactive){ |
241 |
|
printf("done\n"); |
242 |
|
} |
243 |
|
|
244 |
} |
} |
245 |
|
|
246 |
/* Protect values from GC */ |
/* Protect values from GC */ |
248 |
{ |
{ |
249 |
stackitem *iterator; |
stackitem *iterator; |
250 |
|
|
251 |
if(val->gc_protect) |
if(val->gc.flag.protect) |
252 |
return; |
return; |
253 |
|
|
254 |
val->gc_protect= 1; |
val->gc.flag.protect= 1; |
255 |
|
|
256 |
if(val->type==list) { |
if(val->type==list) { |
257 |
iterator= val->content.ptr; |
iterator= val->content.ptr; |
268 |
{ |
{ |
269 |
stackitem *iterator; |
stackitem *iterator; |
270 |
|
|
271 |
if(!(val->gc_protect)) |
if(!(val->gc.flag.protect)) |
272 |
return; |
return; |
273 |
|
|
274 |
val->gc_protect= 0; |
val->gc.flag.protect= 0; |
275 |
|
|
276 |
if(val->type==list) { |
if(val->type==list) { |
277 |
iterator= val->content.ptr; |
iterator= val->content.ptr; |
318 |
void push_cstring(environment *env, const char *in_string) |
void push_cstring(environment *env, const char *in_string) |
319 |
{ |
{ |
320 |
value *new_value= new_val(env); |
value *new_value= new_val(env); |
321 |
|
int length= strlen(in_string)+1; |
322 |
|
|
323 |
new_value->content.ptr= malloc(strlen(in_string)+1); |
new_value->content.ptr= malloc(length); |
324 |
|
env->gc_count += length; |
325 |
strcpy(new_value->content.ptr, in_string); |
strcpy(new_value->content.ptr, in_string); |
326 |
new_value->type= string; |
new_value->type= string; |
327 |
|
|
684 |
push_val(env, iterator->item); |
push_val(env, iterator->item); |
685 |
|
|
686 |
if(env->head->item->type==symb |
if(env->head->item->type==symb |
687 |
&& strcmp(";", ((symbol*)(env->head->item->content.ptr))->id)==0) { |
&& (((symbol*)(env->head->item->content.ptr))->id[0] == ';')) { |
688 |
toss(env); |
toss(env); |
689 |
if(env->err) return; |
if(env->err) return; |
690 |
|
|