/[cvs]/stack/gc.c
ViewVC logotype

Contents of /stack/gc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show annotations)
Thu Feb 19 15:35:38 2004 UTC (20 years, 2 months ago) by masse
Branch: MAIN
CVS Tags: HEAD
File MIME type: text/plain
Extracted garbage collector to gc.c

1 /*
2 stack - an interactive interpreter for a stack-based language
3 Copyright (C) 2002 Mats Alritzson and Teddy Hogeborn
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Authors: Mats Alritzson <masse@fukt.bth.se>
20 Teddy Hogeborn <teddy@fukt.bth.se>
21 */
22
23 #include "stack.h"
24
25 /* Mark values recursively.
26 Marked values are not collected by the GC. */
27 inline void gc_mark(value *val)
28 {
29 if(val==NULL || val->gc.flag.mark)
30 return;
31
32 val->gc.flag.mark= 1;
33
34 if(val->type==tcons) {
35 gc_mark(CAR(val));
36 gc_mark(CDR(val));
37 }
38 }
39
40
41 /* Start GC */
42 extern void gc_init(environment *env)
43 {
44 stackitem *new_head= NULL, *titem;
45 symbol *tsymb;
46 int i;
47
48 if(env->interactive)
49 printf("Garbage collecting.");
50
51 /* Mark values on stack */
52 gc_mark(env->head);
53
54 if(env->interactive)
55 printf(".");
56
57 /* Mark values in hashtable */
58 for(i= 0; i<HASHTBLSIZE; i++)
59 for(tsymb= env->symbols[i]; tsymb!=NULL; tsymb= tsymb->next)
60 if (tsymb->val != NULL)
61 gc_mark(tsymb->val);
62
63 if(env->interactive)
64 printf(".");
65
66 env->gc_count= 0;
67
68 while(env->gc_ref!=NULL) { /* Sweep unused values */
69 if(!(env->gc_ref->item->gc.no_gc)){ /* neither mark nor protect */
70
71 /* Remove content */
72 switch(env->gc_ref->item->type){
73 case string:
74 free(env->gc_ref->item->content.string);
75 break;
76 case tcons:
77 free(env->gc_ref->item->content.c);
78 break;
79 case port:
80 case empty:
81 case unknown:
82 case integer:
83 case tfloat:
84 case func:
85 case symb:
86 /* Symbol strings are freed when walking the hash table */
87 break;
88 }
89
90 free(env->gc_ref->item); /* Remove from gc_ref */
91 titem= env->gc_ref->next;
92 free(env->gc_ref); /* Remove value */
93 env->gc_ref= titem;
94 continue;
95 }
96
97 #ifdef DEBUG
98 printf("Kept value (%p)", env->gc_ref->item);
99 if(env->gc_ref->item->gc.flag.mark)
100 printf(" (marked)");
101 if(env->gc_ref->item->gc.flag.protect)
102 printf(" (protected)");
103 switch(env->gc_ref->item->type){
104 case integer:
105 printf(" integer: %d", env->gc_ref->item->content.i);
106 break;
107 case func:
108 printf(" func: %p", env->gc_ref->item->content.func);
109 break;
110 case symb:
111 printf(" symb: %s", env->gc_ref->item->content.sym->id);
112 break;
113 case tcons:
114 printf(" tcons: %p\t%p", CAR(env->gc_ref->item),
115 CDR(env->gc_ref->item));
116 break;
117 default:
118 printf(" <unknown %d>", (env->gc_ref->item->type));
119 }
120 printf("\n");
121 #endif /* DEBUG */
122
123 /* Keep values */
124 env->gc_count += sizeof(value);
125 if(env->gc_ref->item->type==string)
126 env->gc_count += strlen(env->gc_ref->item->content.string)+1;
127
128 titem= env->gc_ref->next;
129 env->gc_ref->next= new_head;
130 new_head= env->gc_ref;
131 new_head->item->gc.flag.mark= 0;
132 env->gc_ref= titem;
133 }
134
135 if (env->gc_limit < env->gc_count*2)
136 env->gc_limit= env->gc_count*2;
137
138 env->gc_ref= new_head;
139
140 if(env->interactive)
141 printf("done (%d bytes still allocated)\n", env->gc_count);
142
143 }
144
145
146 inline void gc_maybe(environment *env)
147 {
148 if(env->gc_count < env->gc_limit)
149 return;
150 else
151 return gc_init(env);
152 }
153
154
155 /* Protect values from GC */
156 void protect(value *val)
157 {
158 if(val==NULL || val->gc.flag.protect)
159 return;
160
161 val->gc.flag.protect= 1;
162
163 if(val->type==tcons) {
164 protect(CAR(val));
165 protect(CDR(val));
166 }
167 }
168
169
170 /* Unprotect values from GC */
171 void unprotect(value *val)
172 {
173 if(val==NULL || !(val->gc.flag.protect))
174 return;
175
176 val->gc.flag.protect= 0;
177
178 if(val->type==tcons) {
179 unprotect(CAR(val));
180 unprotect(CDR(val));
181 }
182 }

root@recompile.se
ViewVC Help
Powered by ViewVC 1.1.26