bug fixes checked in
[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
9 #define MALLOCSIZE 20*1024
10
11 struct malloclist {
12   struct malloclist *next;
13   int size;
14   char space[];
15 };
16
17 struct malloclist * top=NULL;
18 int offset=0;
19
20 void * cpmalloc(int size) {
21   int endoffset=offset+size;
22   if (top==NULL||endoffset>top->size) {
23     int basesize=MALLOCSIZE;
24     struct malloclist *tmp;
25     if (size>basesize)
26       basesize=size;
27     tmp=RUNMALLOC(sizeof(struct malloclist)+basesize);
28     tmp->next=top;
29     top=tmp;
30     top->size=basesize;
31     offset=0;
32   }
33   int tmpoffset=offset;
34   offset+=size;
35   return &top->space[tmpoffset];
36 }
37
38 void freemalloc() {
39   while(top!=NULL) {
40     struct malloclist *next=top->next;
41     RUNFREE(top);
42     top=next;
43   }
44 }
45
46
47 void ** makecheckpoint(int numparams, void ** srcpointer, struct RuntimeHash * forward, struct RuntimeHash * reverse) {
48 #ifdef PRECISE_GC
49   void **newarray=cpmalloc(sizeof(void *)*numparams);
50 #else
51   void **newarray=RUNMALLOC(sizeof(void *)*numparams);
52 #endif
53   struct RuntimeHash *todo=allocateRuntimeHash(100);
54   int i;
55   for(i=0;i<numparams;i++) {
56     void * objptr=srcpointer[i];
57     if (RuntimeHashcontainskey(forward, (int) objptr))
58       RuntimeHashget(forward,(int) objptr,(int *) &newarray[i]);
59     else {
60       void * copy=createcopy(objptr);
61       RuntimeHashadd(forward, (int) objptr, (int)copy);
62       RuntimeHashadd(reverse, (int) copy, (int) objptr);
63       RuntimeHashadd(todo, (int) objptr, (int) objptr);
64       newarray[i]=copy;
65     }
66   }
67   while(RuntimeHashcountset(todo)!=0) {
68     void * ptr=(void *) RuntimeHashfirstkey(todo);
69     int type=((int *)ptr)[0];
70     RuntimeHashremove(todo, (int) ptr, (int) ptr);
71     {
72       void *cpy;
73       RuntimeHashget(forward, (int) ptr, (int *) &cpy);
74       unsigned int * pointer=pointerarray[type];
75 #ifdef TASK
76       if (type==TAGTYPE) {
77         void *objptr=((struct ___TagDescriptor___*)ptr)->flagptr;
78         if (objptr!=NULL) {
79           void * copy=createcopy(objptr);
80           RuntimeHashadd(forward, (int) objptr, (int) copy);
81           RuntimeHashadd(reverse, (int) copy, (int) objptr);
82           RuntimeHashadd(todo, (int) objptr, (int) objptr);
83           ((struct ___TagDescriptor___*)cpy)->flagptr=copy;
84         }
85       } else
86 #endif
87       if (pointer==0) {
88         /* Array of primitives */
89         /* Do nothing */
90       } else if (((int)pointer)==1) {
91         /* Array of pointers */
92         struct ArrayObject *ao=(struct ArrayObject *) ptr;
93         struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
94         int length=ao->___length___;
95         int i;
96         for(i=0;i<length;i++) {
97           void *objptr=((void **)(((char *)& ao->___length___)+sizeof(int)))[i];
98           if (objptr==NULL) {
99             ((void **)(((char *)& ao->___length___)+sizeof(int)))[i]=NULL;
100           } else if (RuntimeHashcontainskey(forward, (int) objptr))
101             RuntimeHashget(forward,(int) objptr,(int *) &((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]);
102           else {
103             void * copy=createcopy(objptr);
104             RuntimeHashadd(forward, (int) objptr, (int)copy);
105             RuntimeHashadd(reverse, (int) copy, (int) objptr);
106             RuntimeHashadd(todo, (int) objptr, (int) objptr);
107             ((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]=copy;
108           }
109         }
110       } else {
111         int size=pointer[0];
112         int i;
113         for(i=1;i<=size;i++) {
114           int offset=pointer[i];
115           void * objptr=*((void **)(((int)ptr)+offset));
116           if (objptr==NULL) {
117             *((void **) (((int)cpy)+offset))=NULL;
118           } else if (RuntimeHashcontainskey(forward, (int) objptr))
119             RuntimeHashget(forward, (int) objptr, (int *) &(((char *)cpy)[offset]));
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             *((void **) (((int)cpy)+offset))=copy;
126           }
127         }
128       }
129     }
130   }
131   freeRuntimeHash(todo);
132   return newarray;
133 }
134
135 void * createcopy(void * orig) {
136   if (orig==0)
137     return 0;
138   else {
139     int type=((int *)orig)[0];
140     if (type<NUMCLASSES) {
141       /* We have a normal object */
142       int size=classsize[type];
143 #ifdef PRECISE_GC
144       void *newobj=cpmalloc(size);
145 #else
146       void *newobj=RUNMALLOC(size);
147 #endif
148       memcpy(newobj, orig, size);
149       return newobj;
150     } else {
151       /* We have an array */
152       struct ArrayObject *ao=(struct ArrayObject *)orig;
153       int elementsize=classsize[type];
154       int length=ao->___length___;
155       int size=sizeof(struct ArrayObject)+length*elementsize;
156 #ifdef PRECISE_GC
157       void *newobj=cpmalloc(size);
158 #else
159       void *newobj=RUNMALLOC(size);
160 #endif
161       memcpy(newobj, orig, size);
162       return newobj;
163     }
164   }
165 }
166
167 void restorecheckpoint(int numparams, void ** original, void ** checkpoint, struct RuntimeHash *forward, struct RuntimeHash * reverse) {
168   struct RuntimeHash *todo=allocateRuntimeHash(100);
169   struct RuntimeHash *visited=allocateRuntimeHash(100);
170   int i;
171
172   for(i=0;i<numparams;i++) {
173     if (checkpoint[i]!=NULL) {
174       RuntimeHashadd(todo, (int) checkpoint[i], (int) checkpoint[i]);
175       RuntimeHashadd(visited, (int) checkpoint[i], (int) checkpoint[i]);
176     }
177   }
178   
179   while(RuntimeHashcountset(todo)!=0) {
180     void * ptr=(void *) RuntimeHashfirstkey(todo);
181     int type=((int *)ptr)[0];
182     RuntimeHashremove(todo, (int) ptr, (int) ptr);
183
184     {
185       void *cpy;
186       unsigned int *pointer;
187       int size;
188       RuntimeHashget(reverse, (int) ptr, (int *) &cpy);
189       pointer=pointerarray[type];
190       size=classsize[type];
191 #ifdef TASK
192       if (type==TAGTYPE) {
193         void *objptr=((struct ___TagDescriptor___*)ptr)->flagptr;
194         memcpy(cpy, ptr, size);
195         if (objptr!=NULL) {
196           if (!RuntimeHashcontainskey(visited, (int) objptr)) {
197             RuntimeHashadd(visited, (int) objptr, (int) objptr);
198             RuntimeHashadd(todo, (int) objptr, (int) objptr);
199           }
200           RuntimeHashget(reverse, (int) objptr, (int *) & (((struct ___TagDescriptor___ *)cpy)->flagptr));
201         }
202       } else
203 #endif
204       if (pointer==0) {
205         /* Array of primitives */
206         struct ArrayObject *ao=(struct ArrayObject *) ptr;
207         int length=ao->___length___;
208         int cpysize=sizeof(struct ArrayObject)+length*size;
209         memcpy(cpy, ptr, cpysize);
210
211       } else if ((int)pointer==1) {
212         /* Array of pointers */
213         struct ArrayObject *ao=(struct ArrayObject *) ptr;
214         struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
215         int length=ao->___length___;
216         int i;
217         int cpysize=sizeof(struct ArrayObject)+length*size;
218         memcpy(ao_cpy, ao, cpysize);
219
220         for(i=0;i<length;i++) {
221           void *objptr=((void **)(((char *)& ao->___length___)+sizeof(int)))[i];
222           if (objptr==NULL)
223             ((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]=NULL;
224           else {
225             if (!RuntimeHashcontainskey(visited, (int) objptr)) {
226               RuntimeHashadd(visited, (int) objptr, (int) objptr);
227               RuntimeHashadd(todo, (int) objptr, (int) objptr);
228             }
229             RuntimeHashget(reverse, (int) objptr, (int *) &((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]);
230           }
231         }
232       } else {
233         int numptr=pointer[0];
234         int i;
235         void *flagptr;
236         if (hasflags[type]) {
237           flagptr=(void *) (((int *)cpy)[2]);
238         }
239         memcpy(cpy, ptr, size);
240         for(i=1;i<=numptr;i++) {
241           int offset=pointer[i];
242           void * objptr=*((void **)(((int)ptr)+offset));
243           if (objptr==NULL)
244             *((void **) (((int)cpy)+offset))=NULL;
245           else {
246             if (!RuntimeHashcontainskey(visited, (int) objptr)) {
247               RuntimeHashadd(visited, (int) objptr, (int) objptr);
248               RuntimeHashadd(todo, (int) objptr, (int) objptr);
249             }
250             RuntimeHashget(reverse, (int) objptr, (int *) &(((char *)cpy)[offset]));
251           }
252         }
253         if (hasflags[type]) {
254           (((void **)cpy)[2])=flagptr;
255           flagorandinit(cpy, 0, 0xFFFFFFFF);
256         }
257       }
258     }
259   }
260   freeRuntimeHash(todo);
261   freeRuntimeHash(visited);
262 }