d886b552f13d3a93f03d4f898882f5a3cb60c536
[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       pmc_heapptr->regions[regionnum+1].startptr=pmc_heapptr->units[i-1].endptr;
73       pmc_heapptr->regions[regionnum+1].lowunit=i;
74       regionnum++;
75       totalbytes-=livebytespercore;
76       numregions=0;
77     }
78     numregions++;
79     pmc_heapptr->units[i].regionnum=regionnum;
80     tmc_spin_mutex_init(&pmc_heapptr->units[i].lock);
81     totalbytes+=pmc_heapptr->units[i].numbytes;
82   }
83   pmc_heapptr->regions[regionnum].highunit=NUMPMCUNITS;
84   pmc_heapptr->regions[regionnum].endptr=pmc_heapptr->units[NUMPMCUNITS-1].endptr;
85   regionnum++;
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     pmc_heapptr->regions[regionnum+1].startptr=pmc_heapptr->units[NUMPMCUNITS-1].endptr;
90     pmc_heapptr->regions[regionnum+1].lowunit=NUMPMCUNITS;
91   }
92 }
93
94 void pmc_doforward() {
95   int startregion=-1;
96   int endregion=-1;
97   unsigned int totalbytes=0;
98   struct pmc_region * region=&pmc_heapptr->regions[BAMBOO_NUM_OF_CORE];
99   for(int index=region->lowunit; index<region->highunit;index++) {
100     totalbytes+=pmc_heapptr->units[index].numbytes;
101   }
102
103   if (BAMBOO_NUM_OF_CORE&1) {
104     //upward in memory
105     region->lastptr=region->endptr-totalbytes;
106   } else {
107     //downward in memory
108     region->lastptr=region->startptr+totalbytes;
109   }
110   pmc_forward(region, totalbytes, region->startptr, region->endptr, !(BAMBOO_NUM_OF_CORE&1));
111 }
112
113
114 //fwddirection=1 means move things to lower addresses
115 void pmc_forward(struct pmc_region *region, unsigned int totalbytes, void *bottomptr, void *topptr, bool lower) {
116   void *tmpptr=bottomptr;
117   void *forwardptr=lower?bottomptr:(topptr-totalbytes);
118   struct ___Object___ *lastobj=NULL;
119   unsigned int currunit=region->lowunit;
120   void *endunit=pmc_unitend(currunit);
121   bool internal=!(BAMBOO_NUM_OF_CORE&1);
122   int highbound=internal?region->highunit:region->highunit-1;
123
124
125   if (!lower) {
126     //We're resetting the boundaries of units at the low address end of the region...
127     //Be sure not to reset the boundary of our last unit...it is shared with another region
128
129     while(endunit<=region->lastptr&&(currunit<highbound)) {
130       pmc_heapptr->units[currunit].endptr=endunit;
131       //tprintf("Ch2: %u -> %x\n", currunit, endunit);
132       currunit++;
133       endunit=pmc_unitend(currunit);
134     }
135   } else {
136     //We're resetting the boundaries of units at the high address end of the region...
137     //Very top most unit defines boundary of region...we can't move that right now
138     unsigned int lastunit=internal?region->highunit-1:region->highunit-2;
139     void * lastunitend=pmc_unitend(lastunit);
140     while(lastunitend>=region->lastptr) {
141       pmc_heapptr->units[lastunit].endptr=lastunitend;
142       //tprintf("Ch3: %u -> %x\n", lastunit, lastunitend);
143       lastunit--;
144       lastunitend=pmc_unitend(lastunit);
145     }
146   }
147
148   while(tmpptr<topptr) {
149     unsigned int type;
150     unsigned int size;
151     gettype_size(tmpptr, &type, &size);
152     if (!type) {
153       tmpptr+=ALIGNMENTSIZE;
154       continue;
155     }
156     size=((size-1)&(~(ALIGNMENTSIZE-1)))+ALIGNMENTSIZE;
157
158     if (((struct ___Object___ *)tmpptr)->marked) {
159       ((struct ___Object___ *)tmpptr)->marked=forwardptr;
160       //tprintf("Forwarding %x->%x\n", tmpptr, forwardptr);
161       void *newforwardptr=forwardptr+size;
162       //Need to make sure that unit boundaries do not fall in the middle of an object...
163       //Unless the unit boundary is at the end of the region...then just ignore it.
164       while(newforwardptr>=endunit&&currunit<highbound) {
165         pmc_heapptr->units[currunit].endptr=newforwardptr;
166         //tprintf("Ch4: %u -> %x\n", currunit, newforwardptr);
167         currunit++;
168         endunit=pmc_unitend(currunit);
169       }
170
171       forwardptr=newforwardptr;
172       if (!lower) {
173         ((struct ___Object___ *)tmpptr)->backward=lastobj;
174         lastobj=(struct ___Object___ *)tmpptr;
175       }
176     }
177     tmpptr+=size;
178   }
179   //tprintf("forwardptr=%x\n",forwardptr);
180   region->lastobj=lastobj;
181 }