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