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 pmc_heapptr->regions[regionnum+1].startptr=pmc_heapptr->units[NUMPMCUNITS-1].endptr;
90 pmc_heapptr->regions[regionnum+1].lowunit=NUMPMCUNITS;
94 void pmc_doforward() {
97 unsigned int totalbytes=0;
98 struct pmc_region * region=&pmc_heapptr->regions[BAMBOO_NUM_OF_CORE];
99 for(int index=region->lowunit; index<region->highunit;index++) {
100 totalbytes+=pmc_heapptr->units[index].numbytes;
103 if (BAMBOO_NUM_OF_CORE&1) {
105 region->lastptr=region->endptr-totalbytes;
108 region->lastptr=region->startptr+totalbytes;
110 pmc_forward(region, totalbytes, region->startptr, region->endptr, !(BAMBOO_NUM_OF_CORE&1));
114 //fwddirection=1 means move things to lower addresses
115 void pmc_forward(struct pmc_region *region, unsigned int totalbytes, void *bottomptr, void *topptr, bool lower) {
116 void *tmpptr=bottomptr;
117 void *forwardptr=lower?bottomptr:(topptr-totalbytes);
118 struct ___Object___ *lastobj=NULL;
119 unsigned int currunit=region->lowunit;
120 void *endunit=pmc_unitend(currunit);
121 bool internal=!(BAMBOO_NUM_OF_CORE&1);
122 int highbound=internal?region->highunit:region->highunit-1;
126 //We're resetting the boundaries of units at the low address end of the region...
127 //Be sure not to reset the boundary of our last unit...it is shared with another region
129 while(endunit<=region->lastptr&&(currunit<highbound)) {
130 pmc_heapptr->units[currunit].endptr=endunit;
131 //tprintf("Ch2: %u -> %x\n", currunit, endunit);
133 endunit=pmc_unitend(currunit);
136 //We're resetting the boundaries of units at the high address end of the region...
137 //Very top most unit defines boundary of region...we can't move that right now
138 unsigned int lastunit=internal?region->highunit-1:region->highunit-2;
139 void * lastunitend=pmc_unitend(lastunit);
140 while(lastunitend>=region->lastptr) {
141 pmc_heapptr->units[lastunit].endptr=lastunitend;
142 //tprintf("Ch3: %u -> %x\n", lastunit, lastunitend);
144 lastunitend=pmc_unitend(lastunit);
148 while(tmpptr<topptr) {
151 gettype_size(tmpptr, &type, &size);
153 tmpptr+=ALIGNMENTSIZE;
156 size=((size-1)&(~(ALIGNMENTSIZE-1)))+ALIGNMENTSIZE;
158 if (((struct ___Object___ *)tmpptr)->marked) {
159 ((struct ___Object___ *)tmpptr)->marked=forwardptr;
160 //tprintf("Forwarding %x->%x\n", tmpptr, forwardptr);
161 void *newforwardptr=forwardptr+size;
162 //Need to make sure that unit boundaries do not fall in the middle of an object...
163 //Unless the unit boundary is at the end of the region...then just ignore it.
164 while(newforwardptr>=endunit&&currunit<highbound) {
165 pmc_heapptr->units[currunit].endptr=newforwardptr;
166 //tprintf("Ch4: %u -> %x\n", currunit, newforwardptr);
168 endunit=pmc_unitend(currunit);
171 forwardptr=newforwardptr;
173 ((struct ___Object___ *)tmpptr)->backward=lastobj;
174 lastobj=(struct ___Object___ *)tmpptr;
179 //tprintf("forwardptr=%x\n",forwardptr);
180 region->lastobj=lastobj;