bug fixes
[IRC.git] / Robust / src / Runtime / checkpoint.c
1 #include "checkpoint.h"
2 #include "runtime.h"
3 #include "structdefs.h"
4 #include <string.h>
5 #ifdef DMALLOC
6 #include "dmalloc.h"
7 #endif
8 extern void * curr_heapbase;
9 extern void * curr_heapptr;
10 extern void * curr_heapgcpoint;
11 extern void * curr_heaptop;
12
13 extern void * to_heapbase;
14 extern void * to_heapptr;
15 extern void * to_heaptop;
16
17
18 #define MALLOCSIZE 20*1024
19
20 struct malloclist {
21   struct malloclist *next;
22   int size;
23   char space[];
24 };
25
26 struct malloclist * top=NULL;
27 int offset=0;
28
29 void * cpmalloc(int size) {
30   int endoffset=offset+size;
31   if (top==NULL||endoffset>top->size) {
32     int basesize=MALLOCSIZE;
33     struct malloclist *tmp;
34     if (size>basesize)
35       basesize=size;
36     tmp=RUNMALLOC(sizeof(struct malloclist)+basesize);
37     tmp->next=top;
38     top=tmp;
39     top->size=basesize;
40     offset=0;
41   }
42   int tmpoffset=offset;
43   offset+=size;
44   return &top->space[tmpoffset];
45 }
46
47 void freemalloc() {
48   while(top!=NULL) {
49     struct malloclist *next=top->next;
50     RUNFREE(top);
51     top=next;
52   }
53 }
54
55 void checkvalid(void * ptr) {
56   if (ptr>=curr_heapbase&&ptr<=curr_heaptop) {
57     printf("Valid\n");
58   }
59 }
60
61 void validitycheck(struct RuntimeHash *forward, struct RuntimeHash *reverse)  {
62     struct RuntimeIterator rit;
63     RuntimeHashiterator(forward, &rit);
64     while(RunhasNext(&rit)) {
65       struct ___Object___ * data=(struct ___Object___*) Runnext(&rit);
66       int type=data->type;
67       unsigned int * pointer=pointerarray[type];
68       int size;
69       int i;
70       if (pointer!=0&&((int)pointer)!=1) {
71         size=pointer[0];
72         for(i=1;i<=size;i++) {
73           int offset=pointer[i];
74           void * ptr=*(void **) (((int) data) + offset);
75           if (ptr!=NULL&&!RuntimeHashcontainskey(reverse, (int) ptr)) {
76             printf("Bad\n");
77           }
78           checkvalid(ptr);
79         }
80       }
81     }
82
83     RuntimeHashiterator(reverse, &rit);
84     while(RunhasNext(&rit)) {
85       struct ___Object___ * data=(struct ___Object___*) Runkey(&rit);
86       Runnext(&rit);
87       int type=data->type;
88       unsigned int * pointer=pointerarray[type];
89       int size;
90       int i;
91       if (pointer!=0&&((int)pointer)!=1) {
92         size=pointer[0];
93         for(i=1;i<=size;i++) {
94           int offset=pointer[i];
95           void * ptr=*(void **) (((int) data) + offset);
96           if (ptr!=NULL&&!RuntimeHashcontainskey(reverse, (int) ptr)) {
97             printf("Bad2\n");
98           }
99           checkvalid(ptr);
100         }
101       }
102     }
103   }
104
105
106
107 void ** makecheckpoint(int numparams, void ** srcpointer, struct RuntimeHash * forward, struct RuntimeHash * reverse) {
108 #ifdef PRECISE_GC
109   void **newarray=cpmalloc(sizeof(void *)*numparams);
110 #else
111   void **newarray=RUNMALLOC(sizeof(void *)*numparams);
112 #endif
113   struct RuntimeHash *todo=allocateRuntimeHash(100);
114   int i;
115
116   for(i=0;i<numparams;i++) {
117     void * objptr=srcpointer[i];
118     if (RuntimeHashcontainskey(forward, (int) objptr))
119       RuntimeHashget(forward,(int) objptr,(int *) &newarray[i]);
120     else {
121       void * copy=createcopy(objptr);
122       RuntimeHashadd(forward, (int) objptr, (int)copy);
123       RuntimeHashadd(reverse, (int) copy, (int) objptr);
124       RuntimeHashadd(todo, (int) objptr, (int) objptr);
125       newarray[i]=copy;
126     }
127   }
128   while(RuntimeHashcountset(todo)!=0) {
129     void * ptr=(void *) RuntimeHashfirstkey(todo);
130     int type=((int *)ptr)[0];
131     RuntimeHashremove(todo, (int) ptr, (int) ptr);
132     {
133       void *cpy;
134       RuntimeHashget(forward, (int) ptr, (int *) &cpy);
135
136       unsigned int * pointer=pointerarray[type];
137 #ifdef TASK
138       if (type==TAGTYPE) {
139         void *objptr=((struct ___TagDescriptor___*)ptr)->flagptr;
140         if (objptr!=NULL) {
141           if (!RuntimeHashcontainskey(forward, (int) objptr)) {
142             void *copy=createcopy(objptr);
143             RuntimeHashadd(forward, (int) objptr, (int) copy);
144             RuntimeHashadd(reverse, (int) copy, (int) objptr);
145             RuntimeHashadd(todo, (int) objptr, (int) objptr);
146             ((struct ___TagDescriptor___*)cpy)->flagptr=copy;
147           } else {
148             RuntimeHashget(forward, (int) objptr, (int *) &(((struct ___TagDescriptor___*) cpy)->flagptr));
149           }
150         }
151       } else
152 #endif
153       if (pointer==0) {
154         /* Array of primitives */
155         /* Do nothing */
156       } else if (((int)pointer)==1) {
157         /* Array of pointers */
158         struct ArrayObject *ao=(struct ArrayObject *) ptr;
159         struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
160         int length=ao->___length___;
161         int i;
162         for(i=0;i<length;i++) {
163           void *objptr=((void **)(((char *)& ao->___length___)+sizeof(int)))[i];
164           if (objptr==NULL) {
165             ((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]=NULL;
166           } else if (RuntimeHashcontainskey(forward, (int) objptr))
167             RuntimeHashget(forward,(int) objptr,(int *) &((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]);
168           else {
169             void * copy=createcopy(objptr);
170             RuntimeHashadd(forward, (int) objptr, (int)copy);
171             RuntimeHashadd(reverse, (int) copy, (int) objptr);
172             RuntimeHashadd(todo, (int) objptr, (int) objptr);
173             ((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]=copy;
174           }
175         }
176       } else {
177         int size=pointer[0];
178         int i;
179         for(i=1;i<=size;i++) {
180           int offset=pointer[i];
181           void * objptr=*((void **)(((int)ptr)+offset));
182           if (objptr==NULL) {
183             *((void **) (((int)cpy)+offset))=NULL;
184           } else if (RuntimeHashcontainskey(forward, (int) objptr))
185             RuntimeHashget(forward, (int) objptr, (int *) &(((char *)cpy)[offset]));
186           else {
187             void * copy=createcopy(objptr);
188             RuntimeHashadd(forward, (int) objptr, (int) copy);
189             RuntimeHashadd(reverse, (int) copy, (int) objptr);
190             RuntimeHashadd(todo, (int) objptr, (int) objptr);
191             *((void **) (((int)cpy)+offset))=copy;
192           }
193         }
194       }
195     }
196   }
197   freeRuntimeHash(todo);
198   return newarray;
199 }
200
201 void * createcopy(void * orig) {
202   if (orig==0)
203     return 0;
204   else {
205     int type=((int *)orig)[0];
206     if (type<NUMCLASSES) {
207       /* We have a normal object */
208       int size=classsize[type];
209 #ifdef PRECISE_GC
210       void *newobj=cpmalloc(size);
211 #else
212       void *newobj=RUNMALLOC(size);
213 #endif
214       memcpy(newobj, orig, size);
215       return newobj;
216     } else {
217       /* We have an array */
218       struct ArrayObject *ao=(struct ArrayObject *)orig;
219       int elementsize=classsize[type];
220       int length=ao->___length___;
221       int size=sizeof(struct ArrayObject)+length*elementsize;
222 #ifdef PRECISE_GC
223       void *newobj=cpmalloc(size);
224 #else
225       void *newobj=RUNMALLOC(size);
226 #endif
227       memcpy(newobj, orig, size);
228       return newobj;
229     }
230   }
231 }
232
233 void restorecheckpoint(int numparams, void ** original, void ** checkpoint, struct RuntimeHash *forward, struct RuntimeHash * reverse) {
234   struct RuntimeHash *todo=allocateRuntimeHash(100);
235   struct RuntimeHash *visited=allocateRuntimeHash(100);
236   int i;
237
238   for(i=0;i<numparams;i++) {
239     if (checkpoint[i]!=NULL) {
240       RuntimeHashadd(todo, (int) checkpoint[i], (int) checkpoint[i]);
241       RuntimeHashadd(visited, (int) checkpoint[i], (int) checkpoint[i]);
242     }
243   }
244   
245   while(RuntimeHashcountset(todo)!=0) {
246     void * ptr=(void *) RuntimeHashfirstkey(todo);
247     int type=((int *)ptr)[0];
248     RuntimeHashremove(todo, (int) ptr, (int) ptr);
249
250     {
251       void *cpy;
252       unsigned int *pointer;
253       int size;
254       RuntimeHashget(reverse, (int) ptr, (int *) &cpy);
255       pointer=pointerarray[type];
256       size=classsize[type];
257 #ifdef TASK
258       if (type==TAGTYPE) {
259         void *objptr=((struct ___TagDescriptor___*)ptr)->flagptr;
260         memcpy(cpy, ptr, size);
261         if (objptr!=NULL) {
262           if (!RuntimeHashcontainskey(visited, (int) objptr)) {
263             RuntimeHashadd(visited, (int) objptr, (int) objptr);
264             RuntimeHashadd(todo, (int) objptr, (int) objptr);
265           }
266           RuntimeHashget(reverse, (int) objptr, (int *) & (((struct ___TagDescriptor___ *)cpy)->flagptr));
267         }
268       } else
269 #endif
270       if (pointer==0) {
271         /* Array of primitives */
272         struct ArrayObject *ao=(struct ArrayObject *) ptr;
273         int length=ao->___length___;
274         int cpysize=sizeof(struct ArrayObject)+length*size;
275         memcpy(cpy, ptr, cpysize);
276       } else if ((int)pointer==1) {
277         /* Array of pointers */
278         struct ArrayObject *ao=(struct ArrayObject *) ptr;
279         struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
280         int length=ao->___length___;
281         int i;
282         int cpysize=sizeof(struct ArrayObject)+length*size;
283         memcpy(ao_cpy, ao, cpysize);
284
285         for(i=0;i<length;i++) {
286           void *objptr=((void **)(((char *)& ao->___length___)+sizeof(int)))[i];
287           if (objptr==NULL)
288             ((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]=NULL;
289           else {
290             if (!RuntimeHashcontainskey(visited, (int) objptr)) {
291               RuntimeHashadd(visited, (int) objptr, (int) objptr);
292               RuntimeHashadd(todo, (int) objptr, (int) objptr);
293             }
294             RuntimeHashget(reverse, (int) objptr, (int *) &((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]);
295           }
296         }
297       } else {
298         int numptr=pointer[0];
299         int i;
300         void *flagptr;
301         int oldflag;
302         int currflag;
303         if (hasflags[type]) {
304           flagptr=(void *) (((int *)cpy)[2]);
305           oldflag=(((int *)cpy)[1]);
306           currflag=(((int *)ptr)[1]);
307         }
308         memcpy(cpy, ptr, size);
309         for(i=1;i<=numptr;i++) {
310           int offset=pointer[i];
311           void * objptr=*((void **)(((int)ptr)+offset));
312           if (objptr==NULL)
313             *((void **) (((int)cpy)+offset))=NULL;
314           else {
315             if (!RuntimeHashcontainskey(visited, (int) objptr)) {
316               RuntimeHashadd(visited, (int) objptr, (int) objptr);
317               RuntimeHashadd(todo, (int) objptr, (int) objptr);
318             }
319             RuntimeHashget(reverse, (int) objptr, (int *) &(((char *)cpy)[offset]));
320           }
321         }
322         if (hasflags[type]) {
323           (((void **)cpy)[2])=flagptr;
324           if (currflag!=oldflag)
325             flagorandinit(cpy, 0, 0xFFFFFFFF);
326         }
327       }
328     }
329   }
330   freeRuntimeHash(todo);
331   freeRuntimeHash(visited);
332 }