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