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