gets rid of crashes...
[IRC.git] / Robust / src / Runtime / bamboo / pmc_forward.c
1 #include "multicoregc.h"
2 #include "pmc_forward.h"
3 #include "runtime_arch.h"
4 #include "bambooalign.h"
5 #include "pmc_garbage.h"
6
7
8 void pmc_count() {
9   for(int i=0;i<NUMPMCUNITS;i++) {
10     if (!tmc_spin_mutex_trylock(&pmc_heapptr->units[i].lock)) {
11       //got lock
12       void *unitbase=(i==0)?gcbaseva:pmc_heapptr->units[i-1].endptr;
13       void *unittop=pmc_heapptr->units[i].endptr;
14       //tprintf("Cnt: %x - %x\n", unitbase, unittop);
15       pmc_countbytes(&pmc_heapptr->units[i], unitbase, unittop);
16     }
17   }
18 }
19
20 //Comment: should build dummy byte arrays to allow skipping data...
21 void pmc_countbytes(struct pmc_unit * unit, void *bottomptr, void *topptr) {
22   void *tmpptr=bottomptr;
23   unsigned int totalbytes=0;
24   void * lastunmarked=NULL;
25   bool padokay=false;
26   while(tmpptr<topptr) {
27     unsigned int type;
28     unsigned int size;
29     //tprintf("C:%x\n",tmpptr);
30     gettype_size(tmpptr, &type, &size);
31     if (!type) {
32       tmpptr+=ALIGNMENTSIZE;
33       continue;
34     }
35     size=((size-1)&(~(ALIGNMENTSIZE-1)))+ALIGNMENTSIZE;
36     if (((struct ___Object___ *)tmpptr)->marked) {
37       if (lastunmarked!=NULL) {
38         if (padokay)
39           padspace(lastunmarked, (unsigned INTPTR) (tmpptr-lastunmarked));
40         padokay=false;
41         lastunmarked=NULL;
42       }
43       totalbytes+=size;
44     } else if (lastunmarked!=NULL)
45       lastunmarked=tmpptr;
46     else
47       padokay=true;
48     tmpptr+=size;
49   }
50   unit->numbytes=totalbytes;
51 }
52
53 void pmc_processunits() {
54   unsigned int livebytes=0;
55   for(int i=0;i<NUMPMCUNITS;i++) {
56     livebytes+=pmc_heapptr->units[i].numbytes;
57   }
58   //make sure to round up
59   unsigned int livebytespercore=((livebytes-1)/NUMCORES4GC)+1;
60   unsigned int regionnum=0;
61   int totalbytes=0;
62   int numregions=0;
63
64   pmc_heapptr->regions[0].startptr=gcbaseva;
65   pmc_heapptr->regions[0].lowunit=0;
66
67   for(int i=0;i<NUMPMCUNITS;i++) {
68     if (numregions>0&&(totalbytes+pmc_heapptr->units[i].numbytes)>livebytespercore) {
69       pmc_heapptr->regions[regionnum].highunit=i;
70       pmc_heapptr->regions[regionnum].endptr=pmc_heapptr->units[i-1].endptr;
71
72       if((regionnum+1)<NUMCORES4GC) {
73         pmc_heapptr->regions[regionnum+1].startptr=pmc_heapptr->units[i-1].endptr;
74         pmc_heapptr->regions[regionnum+1].lowunit=i;
75         regionnum++;
76       }
77       totalbytes-=livebytespercore;
78       numregions=0;
79     }
80     numregions++;
81     pmc_heapptr->units[i].regionnum=regionnum;
82     tmc_spin_mutex_init(&pmc_heapptr->units[i].lock);
83     totalbytes+=pmc_heapptr->units[i].numbytes;
84   }
85
86   for(;regionnum<NUMCORES4GC;regionnum++) {
87     pmc_heapptr->regions[regionnum].highunit=NUMPMCUNITS;
88     pmc_heapptr->regions[regionnum].endptr=pmc_heapptr->units[NUMPMCUNITS-1].endptr;
89     if ((regionnum+1)<NUMCORES4GC) {
90       pmc_heapptr->regions[regionnum+1].startptr=pmc_heapptr->units[NUMPMCUNITS-1].endptr;
91       pmc_heapptr->regions[regionnum+1].lowunit=NUMPMCUNITS;
92     }
93   }
94 }
95
96 void pmc_doforward() {
97   int startregion=-1;
98   int endregion=-1;
99   unsigned int totalbytes=0;
100   struct pmc_region * region=&pmc_heapptr->regions[BAMBOO_NUM_OF_CORE];
101   for(int index=region->lowunit; index<region->highunit;index++) {
102     totalbytes+=pmc_heapptr->units[index].numbytes;
103   }
104
105   if (BAMBOO_NUM_OF_CORE&1) {
106     //upward in memory
107     region->lastptr=region->endptr-totalbytes;
108   } else {
109     //downward in memory
110     region->lastptr=region->startptr+totalbytes;
111   }
112   pmc_forward(region, totalbytes, region->startptr, region->endptr, !(BAMBOO_NUM_OF_CORE&1));
113 }
114
115
116 //fwddirection=1 means move things to lower addresses
117 void pmc_forward(struct pmc_region *region, unsigned int totalbytes, void *bottomptr, void *topptr, bool lower) {
118   void *tmpptr=bottomptr;
119   void *forwardptr=lower?bottomptr:(topptr-totalbytes);
120   struct ___Object___ *lastobj=NULL;
121   unsigned int currunit=region->lowunit;
122   void *endunit=pmc_unitend(currunit);
123   bool internal=!(BAMBOO_NUM_OF_CORE&1);
124   int highbound=internal?region->highunit:region->highunit-1;
125
126
127   if (!lower) {
128     //We're resetting the boundaries of units at the low address end of the region...
129     //Be sure not to reset the boundary of our last unit...it is shared with another region
130
131     while(endunit<=region->lastptr&&(currunit<highbound)) {
132       pmc_heapptr->units[currunit].endptr=endunit;
133       //tprintf("Ch2: %u -> %x\n", currunit, endunit);
134       currunit++;
135       endunit=pmc_unitend(currunit);
136     }
137   } else {
138     //We're resetting the boundaries of units at the high address end of the region...
139     //Very top most unit defines boundary of region...we can't move that right now
140     unsigned int lastunit=internal?region->highunit-1:region->highunit-2;
141     void * lastunitend=pmc_unitend(lastunit);
142     while(lastunitend>=region->lastptr) {
143       pmc_heapptr->units[lastunit].endptr=lastunitend;
144       //tprintf("Ch3: %u -> %x\n", lastunit, lastunitend);
145       lastunit--;
146       lastunitend=pmc_unitend(lastunit);
147     }
148   }
149
150   while(tmpptr<topptr) {
151     unsigned int type;
152     unsigned int size;
153     gettype_size(tmpptr, &type, &size);
154     if (!type) {
155       tmpptr+=ALIGNMENTSIZE;
156       continue;
157     }
158     size=((size-1)&(~(ALIGNMENTSIZE-1)))+ALIGNMENTSIZE;
159
160     if (((struct ___Object___ *)tmpptr)->marked) {
161       ((struct ___Object___ *)tmpptr)->marked=forwardptr;
162       //tprintf("Forwarding %x->%x\n", tmpptr, forwardptr);
163       void *newforwardptr=forwardptr+size;
164       //Need to make sure that unit boundaries do not fall in the middle of an object...
165       //Unless the unit boundary is at the end of the region...then just ignore it.
166       while(newforwardptr>=endunit&&currunit<highbound) {
167         pmc_heapptr->units[currunit].endptr=newforwardptr;
168         //tprintf("Ch4: %u -> %x\n", currunit, newforwardptr);
169         currunit++;
170         endunit=pmc_unitend(currunit);
171       }
172
173       forwardptr=newforwardptr;
174       if (!lower) {
175         ((struct ___Object___ *)tmpptr)->backward=lastobj;
176         lastobj=(struct ___Object___ *)tmpptr;
177       }
178     }
179     tmpptr+=size;
180   }
181   //tprintf("forwardptr=%x\n",forwardptr);
182   region->lastobj=lastobj;
183 }