df66337d84b27190db2bf7fef8adef0b44511186
[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       int * pointer=pointerarray[type];
75       if (pointer==0) {
76         /* Array of primitives */
77         /* Do nothing */
78       } else if (((int)pointer)==1) {
79         /* Array of pointers */
80         struct ArrayObject *ao=(struct ArrayObject *) ptr;
81         struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
82         int length=ao->___length___;
83         int i;
84         for(i=0;i<length;i++) {
85           void *objptr=((void **)(((char *)& ao->___length___)+sizeof(int)))[i];
86           if (objptr==NULL) {
87             ((void **)(((char *)& ao->___length___)+sizeof(int)))[i]=NULL;
88           } else if (RuntimeHashcontainskey(forward, (int) objptr))
89             RuntimeHashget(forward,(int) objptr,(int *) &((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]);
90           else {
91             void * copy=createcopy(objptr);
92             RuntimeHashadd(forward, (int) objptr, (int)copy);
93             RuntimeHashadd(reverse, (int) copy, (int) objptr);
94             RuntimeHashadd(todo, (int) objptr, (int) objptr);
95             ((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]=copy;
96           }
97         }
98       } else {
99         int size=pointer[0];
100         int i;
101         for(i=1;i<=size;i++) {
102           int offset=pointer[i];
103           void * objptr=*((void **)(((int)ptr)+offset));
104           if (objptr==NULL) {
105             *((void **) (((int)cpy)+offset))=NULL;
106           } else if (RuntimeHashcontainskey(forward, (int) objptr))
107             RuntimeHashget(forward, (int) objptr, (int *) &(((char *)cpy)[offset]));
108           else {
109             void * copy=createcopy(objptr);
110             RuntimeHashadd(forward, (int) objptr, (int) copy);
111             RuntimeHashadd(reverse, (int) copy, (int) objptr);
112             RuntimeHashadd(todo, (int) objptr, (int) objptr);
113             *((void **) (((int)cpy)+offset))=copy;
114           }
115         }
116       }
117     }
118   }
119   freeRuntimeHash(todo);
120   return newarray;
121 }
122
123 void * createcopy(void * orig) {
124   if (orig==0)
125     return 0;
126   else {
127     int type=((int *)orig)[0];
128     if (type<NUMCLASSES) {
129       /* We have a normal object */
130       int size=classsize[type];
131 #ifdef PRECISE_GC
132       void *newobj=cpmalloc(size);
133 #else
134       void *newobj=RUNMALLOC(size);
135 #endif
136       memcpy(newobj, orig, size);
137       return newobj;
138     } else {
139       /* We have an array */
140       struct ArrayObject *ao=(struct ArrayObject *)orig;
141       int elementsize=classsize[type];
142       int length=ao->___length___;
143       int size=sizeof(struct ArrayObject)+length*elementsize;
144 #ifdef PRECISE_GC
145       void *newobj=cpmalloc(size);
146 #else
147       void *newobj=RUNMALLOC(size);
148 #endif
149       memcpy(newobj, orig, size);
150       return newobj;
151     }
152   }
153 }
154
155 void restorecheckpoint(int numparams, void ** original, void ** checkpoint, struct RuntimeHash *forward, struct RuntimeHash * reverse) {
156   struct RuntimeHash *todo=allocateRuntimeHash(100);
157   int i;
158
159   for(i=0;i<numparams;i++) {
160     RuntimeHashadd(todo, (int) checkpoint[i], (int) checkpoint[i]);
161   }
162
163   while(RuntimeHashcountset(todo)!=0) {
164     void * ptr=(void *) RuntimeHashfirstkey(todo);
165     int type=((int *)ptr)[0];
166     RuntimeHashremove(todo, (int) ptr, (int) ptr);
167     {
168       void *cpy;
169       int *pointer;
170       int size;
171       RuntimeHashget(reverse, (int) ptr, (int *) &cpy);
172       pointer=pointerarray[type];
173       size=classsize[type];
174
175       if (pointer==0) {
176         /* Array of primitives */
177         struct ArrayObject *ao=(struct ArrayObject *) ptr;
178         int length=ao->___length___;
179         int cpysize=sizeof(struct ArrayObject)+length*size;
180         memcpy(cpy, ptr, cpysize);
181
182       } else if ((int)pointer==1) {
183         /* Array of pointers */
184         struct ArrayObject *ao=(struct ArrayObject *) ptr;
185         struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
186         int length=ao->___length___;
187         int i;
188         int cpysize=sizeof(struct ArrayObject)+length*size;
189         memcpy(ao_cpy, ao, cpysize);
190
191         for(i=0;i<length;i++) {
192           void *objptr=((void **)(((char *)& ao->___length___)+sizeof(int)))[i];
193           if (objptr==NULL)
194             ((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]=NULL;
195           else
196             RuntimeHashget(reverse, (int) objptr, (int *) &((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]);
197         }
198       } else {
199         int numptr=pointer[0];
200         int i;
201         void *flagptr;
202         if (hasflags[type]) {
203           flagptr=(void *) (((int *)cpy)[2]);
204         }
205         memcpy(cpy, ptr, size);
206         for(i=1;i<=numptr;i++) {
207           int offset=pointer[i];
208           void * objptr=*((void **)(((int)ptr)+offset));
209           if (objptr==NULL)
210             *((void **) (((int)cpy)+offset))=NULL;
211           else
212             RuntimeHashget(reverse, (int) objptr, (int *) &(((char *)cpy)[offset]));
213         }
214         if (hasflags[type]) {
215           (((void **)cpy)[2])=flagptr;
216           flagorand(cpy, 1, 0xFFFFFFFF);
217         }
218       }
219     }
220   }
221   freeRuntimeHash(todo);
222 }