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