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