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