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