memory leak
[IRC.git] / Robust / src / Runtime / checkpoint.c
1 #include "checkpoint.h"
2 #include "runtime.h"
3 #include "structdefs.h"
4 #include <string.h>
5
6 #define MALLOCSIZE 20*1024
7
8 struct malloclist {
9   struct malloclist *next;
10   int size;
11   char space[];
12 };
13
14 struct malloclist * top=NULL;
15 int offset=0;
16
17 void * cpmalloc(int size) {
18   int endoffset=offset+size;
19   if (top==NULL||endoffset>top->size) {
20     int basesize=MALLOCSIZE;
21     struct malloclist *tmp;
22     if (size>basesize)
23       basesize=size;
24     tmp=RUNMALLOC(sizeof(struct malloclist)+basesize);
25     tmp->next=top;
26     top=tmp;
27     top->size=basesize;
28     offset=0;
29   }
30   int tmpoffset=offset;
31   offset+=size;
32   return &top->space[tmpoffset];
33 }
34
35 void freemalloc() {
36   while(top!=NULL) {
37     struct malloclist *next=top->next;
38     RUNFREE(top);
39     top=next;
40   }
41 }
42
43
44 void ** makecheckpoint(int numparams, void ** srcpointer, struct RuntimeHash * forward, struct RuntimeHash * reverse) {
45 #ifdef PRECISE_GC
46   void **newarray=cpmalloc(sizeof(void *)*numparams);
47 #else
48   void **newarray=RUNMALLOC(sizeof(void *)*numparams);
49 #endif
50   struct RuntimeHash *todo=allocateRuntimeHash(100);
51   int i;
52   for(i=0;i<numparams;i++) {
53     void * objptr=srcpointer[i];
54     if (RuntimeHashcontainskey(forward, (int) objptr))
55       RuntimeHashget(forward,(int) objptr,(int *) &newarray[i]);
56     else {
57       void * copy=createcopy(objptr);
58       RuntimeHashadd(forward, (int) objptr, (int)copy);
59       RuntimeHashadd(reverse, (int) copy, (int) objptr);
60       RuntimeHashadd(todo, (int) objptr, (int) objptr);
61       newarray[i]=copy;
62     }
63   }
64   while(RuntimeHashcountset(todo)!=0) {
65     void * ptr=(void *) RuntimeHashfirstkey(todo);
66     int type=((int *)ptr)[0];
67     RuntimeHashremove(todo, (int) ptr, (int) ptr);
68     {
69       void *cpy;
70       RuntimeHashget(forward, (int) ptr, (int *) &cpy);
71       int * pointer=pointerarray[type];
72       if (pointer==0) {
73         /* Array of primitives */
74         /* Do nothing */
75       } else if (((int)pointer)==1) {
76         /* Array of pointers */
77         struct ArrayObject *ao=(struct ArrayObject *) ptr;
78         struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
79         int length=ao->___length___;
80         int i;
81         for(i=0;i<length;i++) {
82           void *objptr=((void **)(((char *)& ao->___length___)+sizeof(int)))[i];
83           if (objptr==NULL) {
84             ((void **)(((char *)& ao->___length___)+sizeof(int)))[i]=NULL;
85           } else if (RuntimeHashcontainskey(forward, (int) objptr))
86             RuntimeHashget(forward,(int) objptr,(int *) &((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]);
87           else {
88             void * copy=createcopy(objptr);
89             RuntimeHashadd(forward, (int) objptr, (int)copy);
90             RuntimeHashadd(reverse, (int) copy, (int) objptr);
91             RuntimeHashadd(todo, (int) objptr, (int) objptr);
92             ((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]=copy;
93           }
94         }
95       } else {
96         int size=pointer[0];
97         int i;
98         for(i=1;i<=size;i++) {
99           int offset=pointer[i];
100           void * objptr=*((void **)(((int)ptr)+offset));
101           if (objptr==NULL) {
102             *((void **) (((int)cpy)+offset))=NULL;
103           } else if (RuntimeHashcontainskey(forward, (int) objptr))
104             RuntimeHashget(forward, (int) objptr, (int *) &(((char *)cpy)[offset]));
105           else {
106             void * copy=createcopy(objptr);
107             RuntimeHashadd(forward, (int) objptr, (int) copy);
108             RuntimeHashadd(reverse, (int) copy, (int) objptr);
109             RuntimeHashadd(todo, (int) objptr, (int) objptr);
110             *((void **) (((int)cpy)+offset))=copy;
111           }
112         }
113       }
114     }
115   }
116   freeRuntimeHash(todo);
117   return newarray;
118 }
119
120 void * createcopy(void * orig) {
121   if (orig==0)
122     return 0;
123   else {
124     int type=((int *)orig)[0];
125     if (type<NUMCLASSES) {
126       /* We have a normal object */
127       int size=classsize[type];
128 #ifdef PRECISE_GC
129       void *newobj=cpmalloc(size);
130 #else
131       void *newobj=RUNMALLOC(size);
132 #endif
133       memcpy(newobj, orig, size);
134       return newobj;
135     } else {
136       /* We have an array */
137       struct ArrayObject *ao=(struct ArrayObject *)orig;
138       int elementsize=classsize[type];
139       int length=ao->___length___;
140       int size=sizeof(struct ArrayObject)+length*elementsize;
141 #ifdef PRECISE_GC
142       void *newobj=cpmalloc(size);
143 #else
144       void *newobj=RUNMALLOC(size);
145 #endif
146       memcpy(newobj, orig, size);
147       return newobj;
148     }
149   }
150 }
151
152 void restorecheckpoint(int numparams, void ** original, void ** checkpoint, struct RuntimeHash *forward, struct RuntimeHash * reverse) {
153   struct RuntimeHash *todo=allocateRuntimeHash(100);
154   int i;
155
156   for(i=0;i<numparams;i++) {
157     RuntimeHashadd(todo, (int) checkpoint[i], (int) checkpoint[i]);
158   }
159
160   while(RuntimeHashcountset(todo)!=0) {
161     void * ptr=(void *) RuntimeHashfirstkey(todo);
162     int type=((int *)ptr)[0];
163     RuntimeHashremove(todo, (int) ptr, (int) ptr);
164     {
165       void *cpy;
166       int *pointer;
167       int size;
168       RuntimeHashget(reverse, (int) ptr, (int *) &cpy);
169       pointer=pointerarray[type];
170       size=classsize[type];
171
172       if (pointer==0) {
173         /* Array of primitives */
174         struct ArrayObject *ao=(struct ArrayObject *) ptr;
175         int length=ao->___length___;
176         int cpysize=sizeof(struct ArrayObject)+length*size;
177         memcpy(cpy, ptr, cpysize);
178
179       } else if ((int)pointer==1) {
180         /* Array of pointers */
181         struct ArrayObject *ao=(struct ArrayObject *) ptr;
182         struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
183         int length=ao->___length___;
184         int i;
185         int cpysize=sizeof(struct ArrayObject)+length*size;
186         memcpy(ao_cpy, ao, cpysize);
187
188         for(i=0;i<length;i++) {
189           void *objptr=((void **)(((char *)& ao->___length___)+sizeof(int)))[i];
190           if (objptr==NULL)
191             ((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]=NULL;
192           else
193             RuntimeHashget(reverse, (int) objptr, (int *) &((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]);
194         }
195       } else {
196         int numptr=pointer[0];
197         int i;
198         void *flagptr;
199         if (hasflags[type]) {
200           flagptr=(void *) (((int *)cpy)[2]);
201         }
202         memcpy(cpy, ptr, size);
203         for(i=1;i<=numptr;i++) {
204           int offset=pointer[i];
205           void * objptr=*((void **)(((int)ptr)+offset));
206           if (objptr==NULL)
207             *((void **) (((int)cpy)+offset))=NULL;
208           else
209             RuntimeHashget(reverse, (int) objptr, (int *) &(((char *)cpy)[offset]));
210         }
211         if (hasflags[type]) {
212           (((void **)cpy)[2])=flagptr;
213           flagorand(cpy, 1, 0xFFFFFFFF);
214         }
215       }
216     }
217   }
218   freeRuntimeHash(todo);
219 }