e073b3651214e81f2af84d178d6b356a378ccbe1
[IRC.git] / Robust / src / Runtime / bamboo / pmc_forward.c
1 #include "pmc_forward.h"
2
3 void pmc_count() {
4   for(int i=0;i<NUMPMCUNITS;i++) {
5     if (!tmc_spin_mutex_trylock(&pmc_heapptr->units[i].lock)) {
6       //got lock
7       void *unitbase=(i==0)?gcbaseva:pmc_heapptr->unit[i-1]->endptr;
8       void *unittop=pmc_heapptr->unit[i]->endptr;
9       pmc_countbytes(&pmc_heapptr->unit[i], unitbase, unittop);
10     }
11   }
12 }
13
14 //Comment: should build dummy byte arrays to allow skipping data...
15 void pmc_countbytes(struct pmc_unit * unit, void *bottomptr, void *topptr) {
16   void *tmpptr=bottomptr;
17   unsigned int totalbytes=0;
18   while(tmpptr<topptr) {
19     unsigned int type;
20     unsigned int size;
21     gettype_size(tmpptr, &type, &size);
22     if (!type) {
23       tmpptr+=ALIGNMENTSIZE;
24       continue;
25     }
26     size=((size-1)&(~(ALIGNMENTSIZE-1)))+ALIGNMENTSIZE;
27     if (((struct ___Object___ *)tmpptr)->marked)
28       totalbytes+=size;
29     tmpptr+=size;
30   }
31   unit->numbytes=totalbytes;
32 }
33
34 void pmc_processunits() {
35   unsigned int livebytes=0;
36   for(int i=0;i<NUMPMCUNITS;i++) {
37     livebytes+=pmc_heapptr->units[i].numbytes;
38   }
39   //make sure to round up
40   unsigned int livebytespercore=((livebytes-1)/NUMCORES4GC)+1;
41   unsigned int regionnum=0;
42   int totalbytes=0;
43   int numregions=0;
44
45   for(int i=0;i<NUMPMCUNITS;i++) {
46     if (numregions>0&&(totalbytes+pmc_heapptr->units[i].numbytes)>livebytespercore) {
47       regionnum++;
48       totalbytes-=livebytespercore;
49       numregions=0;
50     }
51     numregions++;
52     pmc_heapptr->units[i].regionnum=regionnum;
53     tmc_spin_mutex_init(&pmc_heapptr->units[i].lock);
54     totalbytes+=pmc_heapptr->units[i].numbytes;
55   }
56 }
57
58 void pmc_doforward() {
59   int startregion=-1;
60   int endregion=-1;
61   unsigned int totalbytes=0;
62   struct pmc_region * region=&pmc_heapptr->regions[BAMBOO_NUM_OF_CORE];
63   for(int i=0;i<NUMPMCUNITS;i++) {
64     if (startregion==-1&&BAMBOO_NUM_OF_CORE==pmc_heapptr->units[i].regionnum) {
65       startregion=i;
66     }
67     if (BAMBOO_NUM_OF_CORE<pmc_heapptr->units[i].regionnum) {
68       endregion=i;
69       break;
70     }
71     if (startregion!=-1) {
72       totalbytes+=pmc_heapptr->units[i].numbytes;
73     }
74   }
75   if (startregion==-1) 
76     return;
77   if (endregion==-1)
78     endregion=NUMPMCUNITS;
79   region->lowunit=startregion;
80   region->highunit=endregion;
81   region->startptr=(startregion==0)?gcbaseva:pmc_heapptr->units[startregion-1].endptr;
82   region->endptr=pmc_heapptr->units[endregion].endptr;
83
84   if (BAMBOO_NUM_OF_CORE&1) {
85     //backward direction
86     region->lastptr=region->endptr-totalbytes;
87   } else {
88     //forward direction
89     region->lastptr=region->startptr+totalbytes;
90   }
91
92   pmc_forward(region, totalbytes, region->startptr, region->endptr, !(BAMBOO_NUM_OF_CORE&1));
93 }
94
95
96 void pmc_forward(struct pmc_region *region, unsigned int totalbytes, void *bottomptr, void *topptr, bool fwddirection) {
97   void *tmpptr=bottomptr;
98   void *forwardptr=fwddirection?bottomptr:(topptr-totalbytes);
99   struct ___Object___ *lastobj=NULL;
100   unsigned int currunit=region->lowunit;
101   void *endunit=pmc_unitend(currunit);
102
103   if (!fwddirection) {
104     //reset boundaries of beginning units
105     while(endunit<forwardptr) {
106       pmc_heapptr->units[currunit].endptr=endunit;
107       currunit++;
108       endunit=pmc_unitend(currunit);
109     }
110   } else {
111     //reset boundaries of end units
112     unsigned int lastunit=region->highunit-1;
113     void * lastunitend=pmc_unitend(lastunit);
114     while(lastunitend>forwardptr) {
115       pmc_heapptr->units[currunit].endptr=lastunitend;
116       lastunit--;
117       lastunitend=pmc_unitend(lastunit);
118     }
119   }
120
121   while(tmpptr>topptr) {
122     unsigned int type;
123     unsigned int size;
124     gettype_size(tmpptr, &type, &size);
125     if (!type) {
126       tmpptr+=ALIGNMENTSIZE;
127       continue;
128     }
129     size=((size-1)&(~(ALIGNMENTSIZE-1)))+ALIGNMENTSIZE;
130
131     if (((struct ___Object___ *)tmpptr)->marked) {
132       ((struct ___Object___ *)tmpptr)->marked=forwardptr;
133       void *newforwardptr=forwardptr+size;
134       while(newforwardptr>endunit) {
135         pmc_heapptr->region[currunit].endptr=newforwardptr;
136         currunit++;
137         endunit=pmc_unitend(currunit);
138       }
139
140       forwardptr=newforwardptr;
141       if (lastobj&&!fwddirection) {
142         tmpptr->backward=lastobj;
143         lastobj=(struct ___Object___ *)tmpptr;
144       }
145     }
146     tmpptr+=size;
147   }
148   region->lastobj=lastobj;
149 }