1 #include "multicoregc.h"
2 #include "pmc_forward.h"
3 #include "runtime_arch.h"
4 #include "bambooalign.h"
5 #include "pmc_garbage.h"
9 for(int i=0;i<NUMPMCUNITS;i++) {
10 if (!tmc_spin_mutex_trylock(&pmc_heapptr->units[i].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);
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;
27 while(tmpptr<topptr) {
30 //tprintf("C:%x\n",tmpptr);
31 gettype_size(tmpptr, &type, &size);
33 tmpptr+=ALIGNMENTSIZE;
36 size=((size-1)&(~(ALIGNMENTSIZE-1)))+ALIGNMENTSIZE;
37 if (((struct ___Object___ *)tmpptr)->marked) {
38 if (lastunmarked!=NULL) {
40 padspace(lastunmarked, (unsigned INTPTR) (tmpptr-lastunmarked));
45 } else if (lastunmarked!=NULL)
51 unit->numbytes=totalbytes;
54 void pmc_processunits() {
55 unsigned int livebytes=0;
56 for(int i=0;i<NUMPMCUNITS;i++) {
57 livebytes+=pmc_heapptr->units[i].numbytes;
59 //make sure to round up
60 unsigned int livebytespercore=((livebytes-1)/NUMCORES4GC)+1;
61 unsigned int regionnum=0;
65 pmc_heapptr->regions[0].startptr=gcbaseva;
66 pmc_heapptr->regions[0].lowunit=0;
68 for(int i=0;i<NUMPMCUNITS;i++) {
69 if (numregions>0&&(totalbytes+pmc_heapptr->units[i].numbytes)>livebytespercore) {
70 pmc_heapptr->regions[regionnum].highunit=i;
71 pmc_heapptr->regions[regionnum].endptr=pmc_heapptr->units[i-1].endptr;
73 if((regionnum+1)<NUMCORES4GC) {
74 pmc_heapptr->regions[regionnum+1].startptr=pmc_heapptr->units[i-1].endptr;
75 pmc_heapptr->regions[regionnum+1].lowunit=i;
78 totalbytes-=livebytespercore;
82 pmc_heapptr->units[i].regionnum=regionnum;
83 tmc_spin_mutex_init(&pmc_heapptr->units[i].lock);
84 totalbytes+=pmc_heapptr->units[i].numbytes;
87 for(;regionnum<NUMCORES4GC;regionnum++) {
88 pmc_heapptr->regions[regionnum].highunit=NUMPMCUNITS;
89 pmc_heapptr->regions[regionnum].endptr=pmc_heapptr->units[NUMPMCUNITS-1].endptr;
90 if ((regionnum+1)<NUMCORES4GC) {
91 pmc_heapptr->regions[regionnum+1].startptr=pmc_heapptr->units[NUMPMCUNITS-1].endptr;
92 pmc_heapptr->regions[regionnum+1].lowunit=NUMPMCUNITS;
97 void pmc_doforward() {
100 unsigned int totalbytes=0;
101 struct pmc_region * region=&pmc_heapptr->regions[BAMBOO_NUM_OF_CORE];
102 for(int index=region->lowunit; index<region->highunit;index++) {
103 totalbytes+=pmc_heapptr->units[index].numbytes;
106 if (BAMBOO_NUM_OF_CORE&1) {
108 region->lastptr=region->endptr-totalbytes;
111 region->lastptr=region->startptr+totalbytes;
113 pmc_forward(region, totalbytes, region->startptr, region->endptr, !(BAMBOO_NUM_OF_CORE&1));
117 //fwddirection=1 means move things to lower addresses
118 void pmc_forward(struct pmc_region *region, unsigned int totalbytes, void *bottomptr, void *topptr, bool lower) {
119 void *tmpptr=bottomptr;
120 void *forwardptr=lower?bottomptr:(topptr-totalbytes);
121 struct ___Object___ *lastobj=NULL;
122 unsigned int currunit=region->lowunit;
123 void *endunit=pmc_unitend(currunit);
124 bool internal=!(BAMBOO_NUM_OF_CORE&1);
125 int highbound=internal?region->highunit:region->highunit-1;
129 //We're resetting the boundaries of units at the low address end of the region...
130 //Be sure not to reset the boundary of our last unit...it is shared with another region
132 while(endunit<=region->lastptr&&(currunit<highbound)) {
133 pmc_heapptr->units[currunit].endptr=endunit;
134 //tprintf("Ch2: %u -> %x\n", currunit, endunit);
136 endunit=pmc_unitend(currunit);
139 //We're resetting the boundaries of units at the high address end of the region...
140 //Very top most unit defines boundary of region...we can't move that right now
141 unsigned int lastunit=internal?region->highunit-1:region->highunit-2;
142 void * lastunitend=pmc_unitend(lastunit);
143 //move units that are nominally supposed to be in free area back to the right location
144 while(lastunitend>=region->lastptr&&lastunit>=region->lowunit) {
145 pmc_heapptr->units[lastunit].endptr=lastunitend;
146 //tprintf("Ch3: %u -> %x\n", lastunit, lastunitend);
148 lastunitend=pmc_unitend(lastunit);
150 //move units that are actually in the free area (but nominaly not supposed to be) to the end pointer
151 while(lastunit>=region->lowunit&&pmc_heapptr->units[lastunit].endptr>region->lastptr) {
152 pmc_heapptr->units[lastunit].endptr=region->lastptr;
158 while(tmpptr<topptr) {
161 gettype_size(tmpptr, &type, &size);
163 tmpptr+=ALIGNMENTSIZE;
166 size=((size-1)&(~(ALIGNMENTSIZE-1)))+ALIGNMENTSIZE;
168 if (((struct ___Object___ *)tmpptr)->marked) {
169 ((struct ___Object___ *)tmpptr)->marked=forwardptr;
170 //tprintf("Forwarding %x->%x\n", tmpptr, forwardptr);
171 void *newforwardptr=forwardptr+size;
172 //Need to make sure that unit boundaries do not fall in the middle of an object...
173 //Unless the unit boundary is at the end of the region...then just ignore it.
174 while(newforwardptr>=endunit&&currunit<highbound) {
175 pmc_heapptr->units[currunit].endptr=newforwardptr;
176 //tprintf("Ch4: %u -> %x\n", currunit, newforwardptr);
178 endunit=pmc_unitend(currunit);
181 forwardptr=newforwardptr;
183 ((struct ___Object___ *)tmpptr)->backward=lastobj;
184 lastobj=(struct ___Object___ *)tmpptr;
189 //tprintf("forwardptr=%x\n",forwardptr);
190 region->lastobj=lastobj;