c2c158afde0a5bc001c27b21800c970c6ef34bc3
[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
27   while(tmpptr<topptr) {
28     unsigned int type;
29     unsigned int size;
30     //tprintf("C:%x\n",tmpptr);
31     gettype_size(tmpptr, &type, &size);
32     if (!type) {
33       tmpptr+=ALIGNMENTSIZE;
34       continue;
35     }
36     size=((size-1)&(~(ALIGNMENTSIZE-1)))+ALIGNMENTSIZE;
37     if (((struct ___Object___ *)tmpptr)->marked) {
38       if (lastunmarked!=NULL) {
39         if (padokay)
40           padspace(lastunmarked, (unsigned INTPTR) (tmpptr-lastunmarked));
41         padokay=false;
42         lastunmarked=NULL;
43       }
44       totalbytes+=size;
45     } else if (lastunmarked!=NULL)
46       lastunmarked=tmpptr;
47     else
48       padokay=true;
49     tmpptr+=size;
50   }
51   unit->numbytes=totalbytes;
52 }
53
54 void pmc_processunits() {
55   unsigned int livebytes=0;
56   for(int i=0;i<NUMPMCUNITS;i++) {
57     livebytes+=pmc_heapptr->units[i].numbytes;
58   }
59   //make sure to round up
60   unsigned int livebytespercore=((livebytes-1)/NUMCORES4GC)+1;
61   unsigned int regionnum=0;
62   int totalbytes=0;
63   int numregions=0;
64
65   pmc_heapptr->regions[0].startptr=gcbaseva;
66   pmc_heapptr->regions[0].lowunit=0;
67
68   for(int i=0;i<NUMPMCUNITS;i++) {
69     if (numregions>0&&(totalbytes+pmc_heapptr->units[i].numbytes)>livebytespercore) {
70       pmc_heapptr->regions[regionnum].highunit=i;
71       pmc_heapptr->regions[regionnum].endptr=pmc_heapptr->units[i-1].endptr;
72
73       if((regionnum+1)<NUMCORES4GC) {
74         pmc_heapptr->regions[regionnum+1].startptr=pmc_heapptr->units[i-1].endptr;
75         pmc_heapptr->regions[regionnum+1].lowunit=i;
76         regionnum++;
77       }
78       totalbytes-=livebytespercore;
79       numregions=0;
80     }
81     numregions++;
82     pmc_heapptr->units[i].regionnum=regionnum;
83     tmc_spin_mutex_init(&pmc_heapptr->units[i].lock);
84     totalbytes+=pmc_heapptr->units[i].numbytes;
85   }
86
87   for(;regionnum<NUMCORES4GC;regionnum++) {
88     pmc_heapptr->regions[regionnum].highunit=NUMPMCUNITS;
89     pmc_heapptr->regions[regionnum].endptr=pmc_heapptr->units[NUMPMCUNITS-1].endptr;
90     if ((regionnum+1)<NUMCORES4GC) {
91       pmc_heapptr->regions[regionnum+1].startptr=pmc_heapptr->units[NUMPMCUNITS-1].endptr;
92       pmc_heapptr->regions[regionnum+1].lowunit=NUMPMCUNITS;
93     }
94   }
95 }
96
97 void pmc_doforward() {
98   int startregion=-1;
99   int endregion=-1;
100   unsigned int totalbytes=0;
101   struct pmc_region * region=&pmc_heapptr->regions[BAMBOO_NUM_OF_CORE];
102   for(int index=region->lowunit; index<region->highunit;index++) {
103     totalbytes+=pmc_heapptr->units[index].numbytes;
104   }
105
106   if (BAMBOO_NUM_OF_CORE&1) {
107     //upward in memory
108     region->lastptr=region->endptr-totalbytes;
109   } else {
110     //downward in memory
111     region->lastptr=region->startptr+totalbytes;
112   }
113   pmc_forward(region, totalbytes, region->startptr, region->endptr, !(BAMBOO_NUM_OF_CORE&1));
114 }
115
116
117 //fwddirection=1 means move things to lower addresses
118 void pmc_forward(struct pmc_region *region, unsigned int totalbytes, void *bottomptr, void *topptr, bool lower) {
119   void *tmpptr=bottomptr;
120   void *forwardptr=lower?bottomptr:(topptr-totalbytes);
121   struct ___Object___ *lastobj=NULL;
122   unsigned int currunit=region->lowunit;
123   void *endunit=pmc_unitend(currunit);
124   bool internal=!(BAMBOO_NUM_OF_CORE&1);
125   int highbound=internal?region->highunit:region->highunit-1;
126
127
128   if (!lower) {
129     //We're resetting the boundaries of units at the low address end of the region...
130     //Be sure not to reset the boundary of our last unit...it is shared with another region
131
132     while(endunit<=region->lastptr&&(currunit<highbound)) {
133       pmc_heapptr->units[currunit].endptr=endunit;
134       //tprintf("Ch2: %u -> %x\n", currunit, endunit);
135       currunit++;
136       endunit=pmc_unitend(currunit);
137     }
138   } else {
139     //We're resetting the boundaries of units at the high address end of the region...
140     //Very top most unit defines boundary of region...we can't move that right now
141     unsigned int lastunit=internal?region->highunit-1:region->highunit-2;
142     void * lastunitend=pmc_unitend(lastunit);
143     //move units that are nominally supposed to be in free area back to the right location
144     while(lastunitend>=region->lastptr&&lastunit>=region->lowunit) {
145       pmc_heapptr->units[lastunit].endptr=lastunitend;
146       //tprintf("Ch3: %u -> %x\n", lastunit, lastunitend);
147       lastunit--;
148       lastunitend=pmc_unitend(lastunit);
149     }
150     //move units that are actually in the free area (but nominaly not supposed to be) to the end pointer
151     while(lastunit>=region->lowunit&&pmc_heapptr->units[lastunit].endptr>region->lastptr) {
152       pmc_heapptr->units[lastunit].endptr=region->lastptr;
153       lastunit--;
154     }
155   }
156
157
158   while(tmpptr<topptr) {
159     unsigned int type;
160     unsigned int size;
161     gettype_size(tmpptr, &type, &size);
162     if (!type) {
163       tmpptr+=ALIGNMENTSIZE;
164       continue;
165     }
166     size=((size-1)&(~(ALIGNMENTSIZE-1)))+ALIGNMENTSIZE;
167
168     if (((struct ___Object___ *)tmpptr)->marked) {
169       ((struct ___Object___ *)tmpptr)->marked=forwardptr;
170       //tprintf("Forwarding %x->%x\n", tmpptr, forwardptr);
171       void *newforwardptr=forwardptr+size;
172       //Need to make sure that unit boundaries do not fall in the middle of an object...
173       //Unless the unit boundary is at the end of the region...then just ignore it.
174       while(newforwardptr>=endunit&&currunit<highbound) {
175         pmc_heapptr->units[currunit].endptr=newforwardptr;
176         //tprintf("Ch4: %u -> %x\n", currunit, newforwardptr);
177         currunit++;
178         endunit=pmc_unitend(currunit);
179       }
180
181       forwardptr=newforwardptr;
182       if (!lower) {
183         ((struct ___Object___ *)tmpptr)->backward=lastobj;
184         lastobj=(struct ___Object___ *)tmpptr;
185       }
186     }
187     tmpptr+=size;
188   }
189   //tprintf("forwardptr=%x\n",forwardptr);
190   region->lastobj=lastobj;
191 }