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
6 void ** makecheckpoint(int numparams, void ** srcpointer, struct RuntimeHash * forward, struct RuntimeHash * reverse) {
7   void **newarray=RUNMALLOC(sizeof(void *)*numparams);
8   struct RuntimeHash *todo=allocateRuntimeHash(100);
9   int i;
10   for(i=0;i<numparams;i++) {
11     void * objptr=srcpointer[i];
12     if (RuntimeHashcontainskey(forward, (int) objptr))
13       RuntimeHashget(forward,(int) objptr,(int *) &newarray[i]);
14     else {
15       void * copy=createcopy(objptr);
16       RuntimeHashadd(forward, (int) objptr, (int)copy);
17       RuntimeHashadd(reverse, (int) copy, (int) objptr);
18       RuntimeHashadd(todo, (int) objptr, (int) objptr);
19       newarray[i]=copy;
20     }
21   }
22   while(RuntimeHashcountset(todo)!=0) {
23     void * ptr=(void *) RuntimeHashfirstkey(todo);
24     int type=((int *)ptr)[0];
25     RuntimeHashremove(todo, (int) ptr, (int) ptr);
26     {
27       void *cpy;
28       RuntimeHashget(forward, (int) ptr, (int *) &cpy);
29       int * pointer=pointerarray[type];
30       if (pointer==0) {
31         /* Array of primitives */
32         /* Do nothing */
33       } else if (((int)pointer)==1) {
34         /* Array of pointers */
35         struct ArrayObject *ao=(struct ArrayObject *) ptr;
36         struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
37         int length=ao->___length___;
38         int i;
39         for(i=0;i<length;i++) {
40           void *objptr=((void **)(((char *)& ao->___length___)+sizeof(int)))[i];
41           if (objptr==NULL) {
42             ((void **)(((char *)& ao->___length___)+sizeof(int)))[i]=NULL;
43           } else if (RuntimeHashcontainskey(forward, (int) objptr))
44             RuntimeHashget(forward,(int) objptr,(int *) &((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]);
45           else {
46             void * copy=createcopy(objptr);
47             RuntimeHashadd(forward, (int) objptr, (int)copy);
48             RuntimeHashadd(reverse, (int) copy, (int) objptr);
49             RuntimeHashadd(todo, (int) objptr, (int) objptr);
50             ((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]=copy;
51           }
52         }
53       } else {
54         int size=pointer[0];
55         int i;
56         for(i=1;i<=size;i++) {
57           int offset=pointer[i];
58           void * objptr=*((void **)(((int)ptr)+offset));
59           if (objptr==NULL) {
60             *((void **) (((int)cpy)+offset))=NULL;
61           } else if (RuntimeHashcontainskey(forward, (int) objptr))
62             RuntimeHashget(forward, (int) objptr, (int *) &(((char *)cpy)[offset]));
63           else {
64             void * copy=createcopy(objptr);
65             RuntimeHashadd(forward, (int) objptr, (int) copy);
66             RuntimeHashadd(reverse, (int) copy, (int) objptr);
67             RuntimeHashadd(todo, (int) objptr, (int) objptr);
68             *((void **) (((int)cpy)+offset))=copy;
69           }
70         }
71       }
72     }
73   }
74   return newarray;
75 }
76
77 void * createcopy(void * orig) {
78   if (orig==0)
79     return 0;
80   else {
81     int type=((int *)orig)[0];
82     if (type<NUMCLASSES) {
83       /* We have a normal object */
84       int size=classsize[type];
85       void *newobj=RUNMALLOC(size);
86       memcpy(newobj, orig, size);
87       return newobj;
88     } else {
89       /* We have an array */
90       struct ArrayObject *ao=(struct ArrayObject *)orig;
91       int elementsize=classsize[type];
92       int length=ao->___length___;
93       int size=sizeof(struct ArrayObject)+length*elementsize;
94       void *newobj=RUNMALLOC(size);
95       memcpy(newobj, orig, size);
96       return newobj;
97     }
98   }
99 }
100
101 void restorecheckpoint(int numparams, void ** original, void ** checkpoint, struct RuntimeHash *forward, struct RuntimeHash * reverse) {
102   struct RuntimeHash *todo=allocateRuntimeHash(100);
103   int i;
104
105   for(i=0;i<numparams;i++) {
106     RuntimeHashadd(todo, (int) checkpoint[i], (int) checkpoint[i]);
107   }
108
109   while(RuntimeHashcountset(todo)!=0) {
110     void * ptr=(void *) RuntimeHashfirstkey(todo);
111     int type=((int *)ptr)[0];
112     RuntimeHashremove(todo, (int) ptr, (int) ptr);
113     {
114       void *cpy;
115       int *pointer;
116       int size;
117       RuntimeHashget(reverse, (int) ptr, (int *) &cpy);
118       pointer=pointerarray[type];
119       size=classsize[type];
120
121       if (pointer==0) {
122         /* Array of primitives */
123         struct ArrayObject *ao=(struct ArrayObject *) ptr;
124         int length=ao->___length___;
125         int cpysize=sizeof(struct ArrayObject)+length*size;
126         memcpy(cpy, ptr, cpysize);
127
128       } else if ((int)pointer==1) {
129         /* Array of pointers */
130         struct ArrayObject *ao=(struct ArrayObject *) ptr;
131         struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
132         int length=ao->___length___;
133         int i;
134         int cpysize=sizeof(struct ArrayObject)+length*size;
135         memcpy(ao_cpy, ao, cpysize);
136
137         for(i=0;i<length;i++) {
138           void *objptr=((void **)(((char *)& ao->___length___)+sizeof(int)))[i];
139           if (objptr==NULL)
140             ((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]=NULL;
141           else
142             RuntimeHashget(reverse, (int) objptr, (int *) &((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]);
143         }
144       } else {
145         int numptr=pointer[0];
146         int i;
147         void *flagptr;
148         if (hasflags[type]) {
149           flagptr=(void *) (((int *)cpy)[2]);
150         }
151         memcpy(cpy, ptr, size);
152         for(i=1;i<=numptr;i++) {
153           int offset=pointer[i];
154           void * objptr=*((void **)(((int)ptr)+offset));
155           if (objptr==NULL)
156             *((void **) (((int)cpy)+offset))=NULL;
157           else
158             RuntimeHashget(reverse, (int) objptr, (int *) &(((char *)cpy)[offset]));
159         }
160         if (hasflags[type]) {
161           (((void **)cpy)[2])=flagptr;
162           flagorand(cpy, 1, 0xFFFFFFFF);
163         }
164       }
165     }
166   }
167 }