bug fixes...runs at least one benchmark now....
[IRC.git] / Robust / src / Runtime / bamboo / pmc_mark.c
1 #include "pmc_mark.h"
2 #include "pmc_garbage.h"
3 #include "multicoremgc.h"
4 #include <stdlib.h>
5 #include "runtime.h"
6 #include "thread.h"
7
8 #define PMC_MARKOBJ(objptr) {void * marktmpptr=objptr; if (marktmpptr!=NULL) {pmc_markObj(marktmpptr);}}
9
10 #define PMC_MARKOBJNONNULL(objptr) {pmc_markObj(objptr);}
11
12 void pmc_markObj(struct ___Object___ *ptr) {
13   if (!ptr->marked) {
14     ptr->marked=1;
15     pmc_enqueue(pmc_localqueue, ptr);
16   }
17 }
18
19 void pmc_scanPtrsInObj(void * ptr, int type) {
20   // scan all pointers in ptr
21   unsigned int * pointer = pointerarray[type];
22   if (pointer==0) {
23     /* Array of primitives */
24   } else if (((unsigned int)pointer)==1) {
25     /* Array of pointers */
26     struct ArrayObject *ao=(struct ArrayObject *) ptr;
27     int length=ao->___length___;
28     for(int i=0; i<length; i++) {
29       void *objptr=((void **)(((char *)&ao->___length___)+sizeof(int)))[i];
30       //tprintf("%x marks %x\n", ptr, objptr);
31       PMC_MARKOBJ(objptr);
32     }
33   } else {
34     /* Normal Object */
35     int size=pointer[0];
36     for(int i=1; i<=size; i++) {
37       unsigned int offset=pointer[i];
38       void * objptr=*((void **)(((char *)ptr)+offset));
39       //tprintf("%x marks %x\n", ptr, objptr);
40       PMC_MARKOBJ(objptr);
41     }
42   }
43 }
44
45 void pmc_markgarbagelist(struct garbagelist * listptr) {
46   for(;listptr!=NULL;listptr=listptr->next) {
47     int size=listptr->size;
48     for(int i=0; i<size; i++) {
49       //tprintf("gl marks %x\n", listptr->array[i]);
50       PMC_MARKOBJ(listptr->array[i]);
51     }
52   }
53 }
54
55 void pmc_mark(struct garbagelist *stackptr) {
56   pmc_tomark(stackptr);
57   while(true) {
58     //scan everything in our local queue
59     pmc_marklocal();
60     if (pmc_trysteal())
61       break;
62   }
63 }
64
65 bool pmc_trysteal() {
66   decrementthreads();
67   while(pmc_heapptr->numthreads) {
68     for(int i=0;i<NUMCORES4GC;i++) {
69       struct pmc_queue *queue=&pmc_heapptr->regions[i].markqueue;
70       if (!pmc_isEmpty(queue)) {
71         incrementthreads();
72         void *objptr=pmc_dequeue(queue);
73         if (objptr!=NULL) {
74           unsigned int type=((struct ___Object___*)objptr)->type;
75           pmc_scanPtrsInObj(objptr, type);
76         }
77         return false;
78       }
79     }
80   }
81   return true;
82 }
83
84 void pmc_marklocal() {
85   void *objptr;
86   while(objptr=pmc_dequeue(pmc_localqueue)) {
87     unsigned int type=((struct ___Object___*)objptr)->type;
88     pmc_scanPtrsInObj(objptr, type);
89   }
90 }
91
92 void pmc_tomark(struct garbagelist * stackptr) {
93   // enqueue current stack
94   pmc_markgarbagelist(stackptr);
95   
96   // enqueue static pointers global_defs_p
97   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
98     pmc_markgarbagelist((struct garbagelist *)global_defs_p);
99   }
100 #ifdef TASK
101   // enqueue objectsets
102   if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
103     for(int i=0; i<NUMCLASSES; i++) {
104       struct parameterwrapper ** queues = objectqueues[BAMBOO_NUM_OF_CORE][i];
105       int length = numqueues[BAMBOO_NUM_OF_CORE][i];
106       for(int j = 0; j < length; ++j) {
107         struct parameterwrapper * parameter = queues[j];
108         struct ObjectHash * set=parameter->objectset;
109         struct ObjectNode * ptr=set->listhead;
110         for(;ptr!=NULL;ptr=ptr->lnext) {
111           PMC_MARKOBJNONNULL((void *)ptr->key);
112         }
113       }
114     }
115   }
116   
117   // enqueue current task descriptor
118   if(currtpd != NULL) {
119     for(int i=0; i<currtpd->numParameters; i++) {
120       // currtpd->parameterArray[i] can not be NULL
121       PMC_MARKOBJNONNULL(currtpd->parameterArray[i]);
122     }
123   }
124
125   // enqueue active tasks
126   if(activetasks != NULL) {
127     struct genpointerlist * ptr=activetasks->list;
128     for(;ptr!=NULL;ptr=ptr->inext) {
129       struct taskparamdescriptor *tpd=ptr->src;
130       for(int i=0; i<tpd->numParameters; i++) {
131         // the tpd->parameterArray[i] can not be NULL
132         PMC_MARKOBJNONNULL(tpd->parameterArray[i]);
133       }
134     }
135   }
136
137   // enqueue cached transferred obj
138   struct QueueItem * tmpobjptr =  getHead(&objqueue);
139   for(;tmpobjptr != NULL;tmpobjptr=getNextQueueItem(tmpobjptr)) {
140     struct transObjInfo * objInfo=(struct transObjInfo *)(tmpobjptr->objectptr);
141     // the objptr can not be NULL
142     PMC_MARKOBJNONNULL(objInfo->objptr);
143   }
144
145   // enqueue cached objs to be transferred
146   struct QueueItem * item = getHead(totransobjqueue);
147   for(;item != NULL;item=getNextQueueItem(item)) {
148     struct transObjInfo * totransobj=(struct transObjInfo *)(item->objectptr);
149     // the objptr can not be NULL
150     PMC_MARKOBJNONNULL(totransobj->objptr);
151   }
152
153   // enqueue lock related info
154   for(int i = 0; i < runtime_locklen; i++) {
155     PMC_MARKOBJ((void *)(runtime_locks[i].redirectlock));
156     PMC_MARKOBJ((void *)(runtime_locks[i].value));
157   }
158 #endif 
159
160 #ifdef MGC
161   // enqueue global thread queue
162   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
163     lockthreadqueue();
164     unsigned int thread_counter = *((unsigned int*)(bamboo_thread_queue+1));
165     if(thread_counter > 0) {
166       unsigned int start = *((unsigned int*)(bamboo_thread_queue+2));
167       for(int i = thread_counter; i > 0; i--) {
168         // the thread obj can not be NULL
169         //tprintf("mgc marks %x\n", (void *)bamboo_thread_queue[4+start]);
170         PMC_MARKOBJNONNULL((void *)bamboo_thread_queue[4+start]);
171         start = (start+1)&bamboo_max_thread_num_mask;
172       }
173     }
174   }
175   // enqueue the bamboo_threadlocks
176   for(int i = 0; i < bamboo_threadlocks.index; i++) {
177     // the locks can not be NULL
178     //tprintf("mgc2 marks %x\n", (void *)bamboo_threadlocks.locks[i].object);
179     PMC_MARKOBJNONNULL((void *)(bamboo_threadlocks.locks[i].object));
180   }
181   // enqueue the bamboo_current_thread
182   //tprintf("mgc3 marks %x\n", bamboo_current_thread);
183   PMC_MARKOBJ(bamboo_current_thread);
184 #endif
185 }