1 #include "multicoregc.h"
2 #include "multicoreruntime.h"
3 #include "multicoregcprofile.h"
4 #include "pmc_garbage.h"
5 #include "runtime_arch.h"
7 #include "pmc_forward.h"
8 #include "pmc_refupdate.h"
10 #include "bme_perf_counter.h"
13 struct pmc_heap * pmc_heapptr;
14 struct pmc_queue * pmc_localqueue;
17 void incrementthreads() {
18 tmc_spin_mutex_lock(&pmc_heapptr->lock);
19 pmc_heapptr->numthreads++;
20 tmc_spin_mutex_unlock(&pmc_heapptr->lock);
23 void decrementthreads() {
24 tmc_spin_mutex_lock(&pmc_heapptr->lock);
25 pmc_heapptr->numthreads--;
26 tmc_spin_mutex_unlock(&pmc_heapptr->lock);
29 void * pmc_unitend(unsigned int index) {
30 return gcbaseva+(index+1)*UNITSIZE;
34 pmc_localqueue=&pmc_heapptr->regions[BAMBOO_NUM_OF_CORE].markqueue;
35 pmc_queueinit(pmc_localqueue);
36 if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
37 tmc_spin_barrier_init(&pmc_heapptr->barrier, NUMCORES4GC);
38 for(int i=0;i<NUMPMCUNITS;i++) {
39 pmc_heapptr->units[i].endptr=pmc_unitend(i);
40 //tprintf("Ch5: %u-> %x\n", i, pmc_heapptr->units[i].endptr);
43 for(int i=0;i<NUMCORES4GC;i+=2) {
45 pmc_heapptr->regions[i].lastptr=gcbaseva;
47 pmc_heapptr->regions[i].lastptr=pmc_heapptr->units[i*4-1].endptr;
48 pmc_heapptr->regions[i].lowunit=4*i;
49 pmc_heapptr->regions[i].highunit=4*(i+1);
50 if ((i+1)<NUMCORES4GC) {
51 pmc_heapptr->regions[i+1].lastptr=pmc_heapptr->units[(i+1)*4+3].endptr;
52 pmc_heapptr->regions[i+1].lowunit=4*(i+1);
53 pmc_heapptr->regions[i+1].highunit=4*(i+2);
56 //for(int i=0;i<NUMCORES4GC;i++) {
57 //tprintf("%u lastptr=%x\n", i, pmc_heapptr->regions[i].lastptr);
63 if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
64 pmc_heapptr->numthreads=NUMCORES4GC;
65 for(int i=0;i<NUMCORES4GC;i+=2) {
66 void *startptr=pmc_heapptr->regions[i].lastptr;
67 void *finishptr=(i+1)<NUMCORES4GC?pmc_heapptr->regions[i+1].lastptr:pmc_heapptr->regions[i].endptr;
68 struct pmc_region *region=&pmc_heapptr->regions[i];
69 unsigned int startindex=region->lowunit;
70 unsigned int endindex=(i+1)<NUMCORES4GC?pmc_heapptr->regions[i+1].highunit:pmc_heapptr->regions[i].highunit;
71 //tprintf("Free space in partition %u from %x to %x\n", i, startptr, finishptr);
72 for(unsigned int index=startindex;index<endindex;index++) {
73 void *ptr=pmc_heapptr->units[index].endptr;
74 if ((ptr>startptr)&&(ptr<=finishptr)) {
75 padspace(startptr, (unsigned int)(ptr-startptr));
79 padspace(startptr, (unsigned int) (finishptr-startptr));
85 if (bamboo_smem_size) {
86 //tprintf("Left over alloc space from %x to %x\n", bamboo_cur_msp, bamboo_cur_msp+bamboo_smem_size);
87 padspace(bamboo_cur_msp, bamboo_smem_size);
89 tmc_spin_barrier_wait(&pmc_heapptr->barrier);
92 void gc(struct garbagelist *gl) {
94 profile_start(GC_REGION);
96 if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
97 tprintf("start GC\n");
98 GCPROFILE_START_MASTER();
101 if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
102 GCPROFILE_ITEM_MASTER();
107 //count live objects per unit
108 tmc_spin_barrier_wait(&pmc_heapptr->barrier);
109 if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
110 GCPROFILE_ITEM_MASTER();
112 //tprintf("count\n");
114 tmc_spin_barrier_wait(&pmc_heapptr->barrier);
115 if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
116 GCPROFILE_ITEM_MASTER();
119 //tprintf("divide\n");
120 if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
122 GCPROFILE_ITEM_MASTER();
124 tmc_spin_barrier_wait(&pmc_heapptr->barrier);
125 //set up forwarding pointers
126 //tprintf("forward\n");
128 tmc_spin_barrier_wait(&pmc_heapptr->barrier);
129 if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
130 GCPROFILE_ITEM_MASTER();
133 //tprintf("updaterefs\n");
134 pmc_doreferenceupdate(gl);
135 tmc_spin_barrier_wait(&pmc_heapptr->barrier);
136 if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
137 GCPROFILE_ITEM_MASTER();
140 //tprintf("compact\n");
142 //reset memory allocation
147 //if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
148 // for(int i=0;i<NUMCORES4GC;i+=2) {
149 // void *startptr=pmc_heapptr->regions[i].lastptr;
150 // void *finishptr=pmc_heapptr->regions[i+1].lastptr;
151 // tprintf("Partition %u from %x to %x\n", i, startptr, finishptr);
152 // tprintf("%x %x %x %x\n", pmc_heapptr->regions[i].startptr, pmc_heapptr->regions[i].endptr, pmc_heapptr->regions[i+1].startptr, pmc_heapptr->regions[i+1].endptr);
157 tmc_spin_barrier_wait(&pmc_heapptr->barrier);
158 if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
159 GCPROFILE_RECORD_SPACE_MASTER();
160 GCPROFILE_END_MASTER();
164 profile_start(APP_REGION);
166 //tprintf("exit GC\n");
169 void padspace(void *ptr, unsigned int length) {
171 if (length<sizeof(struct ArrayObject)) {
172 BAMBOO_MEMSET_WH(ptr,0,length);
174 //generate fake arrays for big blocks
175 struct ArrayObject *ao=(struct ArrayObject *)ptr;
176 ao->type=BYTEARRAYTYPE;
177 unsigned arraylength=length-sizeof(struct ArrayObject);
178 ao->___length___=arraylength;
183 void gettype_size(void * ptr, unsigned int * ttype, unsigned int * tsize) {
184 int type = ((int *)ptr)[0];
185 // if (type>TOTALNUMCLASSANDARRAY) {
186 // tprintf("ptr=%x type=%u\n", ptr, type);
189 if(type < NUMCLASSES) {
191 *tsize = classsize[type];
195 struct ArrayObject *ao=(struct ArrayObject *)ptr;
196 unsigned int elementsize=classsize[type];
197 unsigned int length=ao->___length___;
198 *tsize = sizeof(struct ArrayObject)+length*elementsize;