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;
26 while(tmpptr<topptr) {
29 //tprintf("C:%x\n",tmpptr);
30 gettype_size(tmpptr, &type, &size);
32 tmpptr+=ALIGNMENTSIZE;
35 size=((size-1)&(~(ALIGNMENTSIZE-1)))+ALIGNMENTSIZE;
36 if (((struct ___Object___ *)tmpptr)->marked) {
37 if (lastunmarked!=NULL) {
39 padspace(lastunmarked, (unsigned INTPTR) (tmpptr-lastunmarked));
44 } else if (lastunmarked!=NULL)
50 unit->numbytes=totalbytes;
53 void pmc_processunits() {
54 unsigned int livebytes=0;
55 for(int i=0;i<NUMPMCUNITS;i++) {
56 livebytes+=pmc_heapptr->units[i].numbytes;
58 //make sure to round up
59 unsigned int livebytespercore=((livebytes-1)/NUMCORES4GC)+1;
60 unsigned int regionnum=0;
64 pmc_heapptr->regions[0].startptr=gcbaseva;
65 pmc_heapptr->regions[0].lowunit=0;
67 for(int i=0;i<NUMPMCUNITS;i++) {
68 if (numregions>0&&(totalbytes+pmc_heapptr->units[i].numbytes)>livebytespercore) {
69 pmc_heapptr->regions[regionnum].highunit=i;
70 pmc_heapptr->regions[regionnum].endptr=pmc_heapptr->units[i-1].endptr;
72 pmc_heapptr->regions[regionnum+1].startptr=pmc_heapptr->units[i-1].endptr;
73 pmc_heapptr->regions[regionnum+1].lowunit=i;
75 totalbytes-=livebytespercore;
79 pmc_heapptr->units[i].regionnum=regionnum;
80 tmc_spin_mutex_init(&pmc_heapptr->units[i].lock);
81 totalbytes+=pmc_heapptr->units[i].numbytes;
83 pmc_heapptr->regions[regionnum].highunit=NUMPMCUNITS;
84 pmc_heapptr->regions[regionnum].endptr=pmc_heapptr->units[NUMPMCUNITS-1].endptr;
86 for(;regionnum<NUMCORES4GC;regionnum++) {
87 pmc_heapptr->regions[regionnum].highunit=NUMPMCUNITS;
88 pmc_heapptr->regions[regionnum].endptr=pmc_heapptr->units[NUMPMCUNITS-1].endptr;
89 if ((regionnum+1)<NUMCORES4GC) {
90 pmc_heapptr->regions[regionnum+1].startptr=pmc_heapptr->units[NUMPMCUNITS-1].endptr;
91 pmc_heapptr->regions[regionnum+1].lowunit=NUMPMCUNITS;
96 void pmc_doforward() {
99 unsigned int totalbytes=0;
100 struct pmc_region * region=&pmc_heapptr->regions[BAMBOO_NUM_OF_CORE];
101 for(int index=region->lowunit; index<region->highunit;index++) {
102 totalbytes+=pmc_heapptr->units[index].numbytes;
105 if (BAMBOO_NUM_OF_CORE&1) {
107 region->lastptr=region->endptr-totalbytes;
110 region->lastptr=region->startptr+totalbytes;
112 pmc_forward(region, totalbytes, region->startptr, region->endptr, !(BAMBOO_NUM_OF_CORE&1));
116 //fwddirection=1 means move things to lower addresses
117 void pmc_forward(struct pmc_region *region, unsigned int totalbytes, void *bottomptr, void *topptr, bool lower) {
118 void *tmpptr=bottomptr;
119 void *forwardptr=lower?bottomptr:(topptr-totalbytes);
120 struct ___Object___ *lastobj=NULL;
121 unsigned int currunit=region->lowunit;
122 void *endunit=pmc_unitend(currunit);
123 bool internal=!(BAMBOO_NUM_OF_CORE&1);
124 int highbound=internal?region->highunit:region->highunit-1;
128 //We're resetting the boundaries of units at the low address end of the region...
129 //Be sure not to reset the boundary of our last unit...it is shared with another region
131 while(endunit<=region->lastptr&&(currunit<highbound)) {
132 pmc_heapptr->units[currunit].endptr=endunit;
133 //tprintf("Ch2: %u -> %x\n", currunit, endunit);
135 endunit=pmc_unitend(currunit);
138 //We're resetting the boundaries of units at the high address end of the region...
139 //Very top most unit defines boundary of region...we can't move that right now
140 unsigned int lastunit=internal?region->highunit-1:region->highunit-2;
141 void * lastunitend=pmc_unitend(lastunit);
142 while(lastunitend>=region->lastptr) {
143 pmc_heapptr->units[lastunit].endptr=lastunitend;
144 //tprintf("Ch3: %u -> %x\n", lastunit, lastunitend);
146 lastunitend=pmc_unitend(lastunit);
150 while(tmpptr<topptr) {
153 gettype_size(tmpptr, &type, &size);
155 tmpptr+=ALIGNMENTSIZE;
158 size=((size-1)&(~(ALIGNMENTSIZE-1)))+ALIGNMENTSIZE;
160 if (((struct ___Object___ *)tmpptr)->marked) {
161 ((struct ___Object___ *)tmpptr)->marked=forwardptr;
162 //tprintf("Forwarding %x->%x\n", tmpptr, forwardptr);
163 void *newforwardptr=forwardptr+size;
164 //Need to make sure that unit boundaries do not fall in the middle of an object...
165 //Unless the unit boundary is at the end of the region...then just ignore it.
166 while(newforwardptr>=endunit&&currunit<highbound) {
167 pmc_heapptr->units[currunit].endptr=newforwardptr;
168 //tprintf("Ch4: %u -> %x\n", currunit, newforwardptr);
170 endunit=pmc_unitend(currunit);
173 forwardptr=newforwardptr;
175 ((struct ___Object___ *)tmpptr)->backward=lastobj;
176 lastobj=(struct ___Object___ *)tmpptr;
181 //tprintf("forwardptr=%x\n",forwardptr);
182 region->lastobj=lastobj;