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