Changes to accommodate the runtime for multicore gc w/o tasks
[IRC.git] / Robust / src / Runtime / bamboo / multicoreruntime.c
1 #ifdef MULTICORE
2
3 #include "runtime.h"
4 #include "multicoreruntime.h"
5 #include "runtime_arch.h"
6 #include "GenericHashtable.h"
7 #include "structdefs.h"
8 #include "mem.h"
9 #ifndef RAW
10 #include <stdio.h>
11 #endif
12 #ifdef MGC
13 #include "thread.h"
14 #endif
15
16 #ifndef INLINE
17 #define INLINE    inline __attribute__((always_inline))
18 #endif // #ifndef INLINE
19
20 extern int classsize[];
21 extern int typearray[];
22 extern int typearray2[];
23
24 #ifdef TASK
25 extern struct genhashtable * activetasks;
26 #endif
27 #ifdef MULTICORE_GC
28 #ifdef SMEMM
29 extern unsigned int gcmem_mixed_threshold;
30 extern unsigned int gcmem_mixed_usedmem;
31 #endif // SMEMM
32 #endif // MULTICORE_GC
33
34 int debugtask=0;
35
36 int instanceof(struct ___Object___ *ptr, int type) {
37   int i=ptr->type;
38   do {
39     if (i==type)
40       return 1;
41     i=typearray[i];
42   } while(i!=-1);
43   i=ptr->type;
44   if (i>NUMCLASSES) {
45     do {
46       if (i==type)
47         return 1;
48       i=typearray2[i-NUMCLASSES];
49     } while(i!=-1);
50   }
51   return 0;
52 }
53
54 void initializeexithandler() {
55 }
56
57 /* This function inject failures */
58
59 void injectinstructionfailure() {
60   // not supported in MULTICORE version
61   return;
62 }
63
64 #ifdef D___Double______nativeparsedouble____L___String___
65 double CALL01(___Double______nativeparsedouble____L___String___,struct ___String___ * ___str___) {
66   int length=VAR(___str___)->___count___;
67   int maxlength=(length>60) ? 60 : length;
68   char str[maxlength+1];
69   struct ArrayObject * chararray=VAR(___str___)->___value___;
70   int i;
71   int offset=VAR(___str___)->___offset___;
72   for(i=0; i<maxlength; i++) {
73     str[i]=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
74   }
75   str[i]=0;
76   double d=atof(str);
77   return d;
78 }
79 #endif
80
81 #ifdef D___String______convertdoubletochar____D__AR_C
82 int CALL12(___String______convertdoubletochar____D__AR_C, double ___val___, double ___val___, struct ArrayObject ___chararray___) {
83   int length=VAR(___chararray___)->___length___;
84   char str[length];
85   int i;
86   int num=snprintf(str, length, "%f",___val___);
87   if (num>=length)
88     num=length-1;
89   for(i=0; i<length; i++) {
90     ((short *)(((char *)&VAR(___chararray___)->___length___)+sizeof(int)))[i]=(short)str[i];
91   }
92   return num;
93 }
94 #else
95 int CALL12(___String______convertdoubletochar____D__AR_C, double ___val___, double ___val___, struct ArrayObject ___chararray___) {
96   return 0;
97 }
98 #endif
99
100 void CALL11(___System______exit____I,int ___status___, int ___status___) {
101   BAMBOO_EXIT(___status___);
102 }
103
104 void CALL23(___Vector______removeElement_____AR_L___Object____I_I, int ___index___, int ___size___, struct ArrayObject * ___array___, int ___index___, int ___size___) {
105   char* offset=((char *)(&VAR(___array___)->___length___))+sizeof(unsigned int)+sizeof(void *)*___index___;
106   memmove(offset, offset+sizeof(void *),(___size___-___index___-1)*sizeof(void *));
107 }
108
109 void CALL11(___System______printI____I,int ___status___, int ___status___) {
110   BAMBOO_DEBUGPRINT(0x1111);
111   BAMBOO_DEBUGPRINT_REG(___status___);
112 }
113
114 long CALL00(___System______currentTimeMillis____) {
115   // not supported in MULTICORE version
116   return -1;
117 }
118
119 void CALL01(___System______printString____L___String___,struct ___String___ * ___s___) {
120 }
121
122 /* Object allocation function */
123
124 #ifdef MULTICORE_GC
125 void * allocate_new(void * ptr, int type) {
126   struct ___Object___ * v=
127         (struct ___Object___*)FREEMALLOC((struct garbagelist*) ptr,classsize[type]);
128   v->type=type;
129   v->version = 0;
130   v->lock = NULL;
131   v->lockcount = 0;
132   initlock(v);
133 #ifdef GC_PROFILE
134   extern unsigned int gc_num_obj;
135   gc_num_obj++;
136 #endif
137   return v;
138 }
139
140 /* Array allocation function */
141
142 struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
143   struct ArrayObject * v=(struct ArrayObject *)
144         FREEMALLOC((struct garbagelist*)ptr,
145                 sizeof(struct ArrayObject)+length*classsize[type]);
146   v->type=type;
147   v->version = 0;
148   v->lock = NULL;
149   if (length<0) {
150     return NULL;
151   }
152   v->___length___=length;
153   initlock(v);
154 #ifdef GC_PROFILE
155   extern unsigned int gc_num_obj;
156   gc_num_obj++;
157 #endif
158   return v;
159 }
160
161 #else
162 void * allocate_new(int type) {
163   struct ___Object___ * v=FREEMALLOC(classsize[type]);
164   v->type=type;
165   v->version = 0;
166   v->lock = NULL;
167   initlock(v);
168   return v;
169 }
170
171 /* Array allocation function */
172
173 struct ArrayObject * allocate_newarray(int type, int length) {
174   struct ArrayObject * v=
175         FREEMALLOC(sizeof(struct ArrayObject)+length*classsize[type]);
176   v->type=type;
177   v->version = 0;
178   v->lock = NULL;
179   v->___length___=length;
180   initlock(v);
181   return v;
182 }
183 #endif
184
185
186 /* Converts C character arrays into Java strings */
187 #ifdef MULTICORE_GC
188 struct ___String___ * NewString(void * ptr, const char *str,int length) {
189 #else
190 struct ___String___ * NewString(const char *str,int length) {
191 #endif
192   int i;
193 #ifdef MULTICORE_GC
194   struct ArrayObject * chararray=
195         allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
196   int ptrarray[]={1, (int) ptr, (int) chararray};
197   struct ___String___ * strobj=
198         allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
199   chararray=(struct ArrayObject *) ptrarray[2];
200 #else
201   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
202   struct ___String___ * strobj=allocate_new(STRINGTYPE);
203 #endif
204   strobj->___value___=chararray;
205   strobj->___count___=length;
206   strobj->___offset___=0;
207
208   for(i=0; i<length; i++) {
209     ((short*)(((char*)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
210   }
211   return strobj;
212 }
213
214 /* Generated code calls this if we fail a bounds check */
215
216 void failedboundschk() {
217 #ifndef TASK
218   printf("Array out of bounds\n");
219 #ifdef THREADS
220   threadexit();
221 #else
222   exit(-1);
223 #endif
224 #else
225 #ifndef MULTICORE
226   printf("Array out of bounds\n");
227   longjmp(error_handler,2);
228 #else
229   BAMBOO_EXIT(0xa002);
230 #endif
231 #endif
232 }
233
234 /* Abort task call */
235 void abort_task() {
236 #ifdef TASK
237 #ifndef MULTICORE
238   printf("Aborting\n");
239   longjmp(error_handler,4);
240 #endif
241 #else
242   printf("Aborting\n");
243   exit(-1);
244 #endif
245 }
246
247 INLINE void initruntimedata() {
248   int i;
249   // initialize the arrays
250   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
251     // startup core to initialize corestatus[]
252     for(i = 0; i < NUMCORESACTIVE; ++i) {
253       corestatus[i] = 1;
254       numsendobjs[i] = 0;
255       numreceiveobjs[i] = 0;
256 #ifdef MULTICORE_GC
257       gccorestatus[i] = 1;
258       gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
259       gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
260 #endif
261     } // for(i = 0; i < NUMCORESACTIVE; ++i)
262 #ifdef MULTICORE_GC
263     for(i = 0; i < NUMCORES4GC; ++i) {
264       gcloads[i] = 0;
265       gcrequiredmems[i] = 0;
266       gcstopblock[i] = 0;
267       gcfilledblocks[i] = 0;
268     } // for(i = 0; i < NUMCORES4GC; ++i)
269 #ifdef GC_PROFILE
270     gc_infoIndex = 0;
271     gc_infoOverflow = false;
272         gc_num_livespace = 0;
273         gc_num_freespace = 0;
274 #endif
275 #endif
276     numconfirm = 0;
277     waitconfirm = false;
278   }
279
280   busystatus = true;
281   self_numsendobjs = 0;
282   self_numreceiveobjs = 0;
283
284   for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
285     msgdata[i] = -1;
286   }
287   msgdataindex = 0;
288   msgdatalast = 0;
289   msglength = BAMBOO_MSG_BUF_LENGTH;
290   msgdatafull = false;
291   for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
292     outmsgdata[i] = -1;
293   }
294   outmsgindex = 0;
295   outmsglast = 0;
296   outmsgleft = 0;
297   isMsgHanging = false;
298
299   smemflag = true;
300   bamboo_cur_msp = NULL;
301   bamboo_smem_size = 0;
302
303 #ifdef MULTICORE_GC
304   bamboo_smem_zero_top = NULL;
305   gcflag = false;
306   gcprocessing = false;
307   gcphase = FINISHPHASE;
308   gcprecheck = true;
309   gccurr_heaptop = 0;
310   gcself_numsendobjs = 0;
311   gcself_numreceiveobjs = 0;
312   gcmarkedptrbound = 0;
313 #ifdef LOCALHASHTBL_TEST
314   gcpointertbl = allocateRuntimeHash_I(20);
315 #else
316   gcpointertbl = mgchashCreate_I(2000, 0.75);
317 #endif
318   gcforwardobjtbl = allocateMGCHash_I(20, 3);
319   gcobj2map = 0;
320   gcmappedobj = 0;
321   gcnumlobjs = 0;
322   gcheaptop = 0;
323   gctopcore = 0;
324   gctopblock = 0;
325   gcmovestartaddr = 0;
326   gctomove = false;
327   gcmovepending = 0;
328   gcblock2fill = 0;
329   gcsbstarttbl = BAMBOO_BASE_VA;
330   bamboo_smemtbl = (void *)gcsbstarttbl
331                + (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE)*sizeof(INTPTR);
332   if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
333         int t_size = ((BAMBOO_RMSP_SIZE)-sizeof(mgcsharedhashtbl_t)*2
334                 -128*sizeof(size_t))/sizeof(mgcsharedhashlistnode_t)-2;
335         int kk = 0;
336         unsigned int tmp_k = 1 << (sizeof(int)*8 -1);
337         while(((t_size & tmp_k) == 0) && (kk < sizeof(int)*8)) {
338           t_size = t_size << 1;
339           kk++;
340         }
341         t_size = tmp_k >> kk;
342         gcsharedptbl = mgcsharedhashCreate_I(t_size,0.30);
343   } else {
344         gcsharedptbl = NULL;
345   }
346   BAMBOO_MEMSET_WH(gcrpointertbls, 0, 
347           sizeof(mgcsharedhashtbl_t *)*NUMCORES4GC);
348 #ifdef SMEMM
349   gcmem_mixed_threshold = (unsigned int)((BAMBOO_SHARED_MEM_SIZE
350                 -bamboo_reserved_smem*BAMBOO_SMEM_SIZE)*0.8);
351   gcmem_mixed_usedmem = 0;
352 #endif
353 #ifdef GC_PROFILE
354   gc_num_obj = 0;
355   gc_num_liveobj = 0;
356   gc_num_forwardobj = 0;
357   gc_num_profiles = NUMCORESACTIVE - 1;
358 #endif
359 #ifdef GC_FLUSH_DTLB
360   gc_num_flush_dtlb = 0;
361 #endif
362   gc_localheap_s = false;
363 #ifdef GC_CACHE_ADAPT
364   gccachestage = false;
365 #endif // GC_CACHE_ADAPT
366 #endif // MULTICORE_GC
367 #ifndef INTERRUPT
368   reside = false;
369 #endif
370
371 #ifdef MGC
372   // TODO
373   threadlocks = 0;
374 #endif
375
376 #ifdef TASK
377   inittaskdata();
378 #endif
379 }
380
381 INLINE void disruntimedata() {
382 #ifdef MULTICORE_GC
383 #ifdef LOCALHASHTBL_TEST
384   freeRuntimeHash(gcpointertbl);
385 #else
386   mgchashDelete(gcpointertbl);
387 #endif
388   freeMGCHash(gcforwardobjtbl);
389 #endif // MULTICORE_GC
390 #ifdef TASK
391   distaskdata()
392 #endif // TASK
393   BAMBOO_LOCAL_MEM_CLOSE();
394   BAMBOO_SHARE_MEM_CLOSE();
395 }
396
397 INLINE void checkCoreStatus() {
398   bool allStall = false;
399   int i = 0;
400   int sumsendobj = 0;
401   if((!waitconfirm) ||
402      (waitconfirm && (numconfirm == 0))) {
403     BAMBOO_DEBUGPRINT(0xee04);
404     BAMBOO_DEBUGPRINT_REG(waitconfirm);
405     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
406     BAMBOO_DEBUGPRINT(0xf001);
407     corestatus[BAMBOO_NUM_OF_CORE] = 0;
408     numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
409     numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
410     // check the status of all cores
411     allStall = true;
412     BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
413     for(i = 0; i < NUMCORESACTIVE; ++i) {
414       BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
415       if(corestatus[i] != 0) {
416                 allStall = false;
417                 break;
418       }
419     }  // for(i = 0; i < NUMCORESACTIVE; ++i)
420     if(allStall) {
421       // check if the sum of send objs and receive obj are the same
422       // yes->check if the info is the latest; no->go on executing
423       sumsendobj = 0;
424       for(i = 0; i < NUMCORESACTIVE; ++i) {
425                 sumsendobj += numsendobjs[i];
426                 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
427       }  // for(i = 0; i < NUMCORESACTIVE; ++i)
428       for(i = 0; i < NUMCORESACTIVE; ++i) {
429                 sumsendobj -= numreceiveobjs[i];
430                 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
431       }  // for(i = 0; i < NUMCORESACTIVE; ++i)
432       if(0 == sumsendobj) {
433                 if(!waitconfirm) {
434                   // the first time found all cores stall
435                   // send out status confirm msg to all other cores
436                   // reset the corestatus array too
437                   BAMBOO_DEBUGPRINT(0xee05);
438                   corestatus[BAMBOO_NUM_OF_CORE] = 1;
439                   waitconfirm = true;
440                   numconfirm = NUMCORESACTIVE - 1;
441                   BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
442                   for(i = 1; i < NUMCORESACTIVE; ++i) {
443                         corestatus[i] = 1;
444                         // send status confirm msg to core i
445                         send_msg_1(i, STATUSCONFIRM, false);
446                   }   // for(i = 1; i < NUMCORESACTIVE; ++i)
447                   return;
448                 } else {
449                   // all the core status info are the latest
450                   // terminate; for profiling mode, send request to all
451                   // other cores to pour out profiling data
452                   BAMBOO_DEBUGPRINT(0xee06);
453
454 #ifdef USEIO
455                   totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
456 #else
457
458                   BAMBOO_PRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
459                   //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
460 #ifdef GC_FLUSH_DTLB
461                   BAMBOO_PRINT_REG(gc_num_flush_dtlb);
462 #endif
463 #ifndef BAMBOO_MEMPROF
464                   BAMBOO_PRINT(0xbbbbbbbb);
465 #endif
466 #endif
467                   // profile mode, send msgs to other cores to request pouring
468                   // out progiling data
469 #ifdef PROFILE
470                   BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
471                   BAMBOO_DEBUGPRINT(0xf000);
472                   for(i = 1; i < NUMCORESACTIVE; ++i) {
473                         // send profile request msg to core i
474                         send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
475                   } // for(i = 1; i < NUMCORESACTIVE; ++i)
476 #ifndef RT_TEST
477                   // pour profiling data on startup core
478                   outputProfileData();
479 #endif
480                   while(true) {
481                         BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
482                         BAMBOO_DEBUGPRINT(0xf001);
483                         profilestatus[BAMBOO_NUM_OF_CORE] = 0;
484                         // check the status of all cores
485                         allStall = true;
486                         BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
487                         for(i = 0; i < NUMCORESACTIVE; ++i) {
488                           BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
489                           if(profilestatus[i] != 0) {
490                                 allStall = false;
491                                 break;
492                           }
493                         }  // for(i = 0; i < NUMCORESACTIVE; ++i)
494                         if(!allStall) {
495                           int halt = 100;
496                           BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
497                           BAMBOO_DEBUGPRINT(0xf000);
498                           while(halt--) {
499                           }
500                         } else {
501                           BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
502                           break;
503                         }  // if(!allStall)
504                   }  // while(true)
505 #endif
506
507                   // gc_profile mode, output gc prfiling data
508 #ifdef MULTICORE_GC
509 #ifdef GC_CACHE_ADAPT
510                   bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
511 #endif // GC_CACHE_ADAPT
512 #ifdef GC_PROFILE
513                   gc_outputProfileData();
514 #endif // #ifdef GC_PROFILE
515 #endif // #ifdef MULTICORE_GC
516                   disruntimedata();
517                   BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
518                   terminate();  // All done.
519                 }  // if(!waitconfirm)
520       } else {
521                 // still some objects on the fly on the network
522                 // reset the waitconfirm and numconfirm
523                 BAMBOO_DEBUGPRINT(0xee07);
524                 waitconfirm = false;
525                 numconfirm = 0;
526           }  //  if(0 == sumsendobj)
527     } else {
528       // not all cores are stall, keep on waiting
529       BAMBOO_DEBUGPRINT(0xee08);
530       waitconfirm = false;
531       numconfirm = 0;
532     }  //  if(allStall)
533     BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
534     BAMBOO_DEBUGPRINT(0xf000);
535   }  // if((!waitconfirm) ||
536 }
537
538 // main function for each core
539 inline void run(void * arg) {
540   int i = 0;
541   int argc = 1;
542   char ** argv = NULL;
543   bool sendStall = false;
544   bool isfirst = true;
545   bool tocontinue = false;
546
547   corenum = BAMBOO_GET_NUM_OF_CORE();
548   BAMBOO_DEBUGPRINT(0xeeee);
549   BAMBOO_DEBUGPRINT_REG(corenum);
550   BAMBOO_DEBUGPRINT(STARTUPCORE);
551
552   // initialize runtime data structures
553   initruntimedata();
554
555   // other architecture related initialization
556   initialization();
557   initCommunication();
558
559 #ifdef GC_CACHE_ADAPT
560 // enable the timer interrupt
561 #ifdef GC_CACHE_SAMPLING
562   bamboo_tile_timer_set_next_event(GC_TILE_TIMER_EVENT_SETTING); // TODO
563   bamboo_unmask_timer_intr();
564   bamboo_dtlb_sampling_process();
565 #endif // GC_CACHE_SAMPLING
566 #endif // GC_CACHE_ADAPT
567
568   initializeexithandler();
569
570   // main process of the execution module
571   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
572 #ifdef TASK
573     // non-executing cores, only processing communications
574     activetasks = NULL;
575 #endif
576     fakeExecution();
577   } else {
578 #ifdef TASK
579     /* Create queue of active tasks */
580     activetasks=
581       genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
582                            (int (*)(void *,void *)) &comparetpd);
583
584     /* Process task information */
585     processtasks();
586
587     if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
588       /* Create startup object */
589       createstartupobject(argc, argv);
590     }
591
592     BAMBOO_DEBUGPRINT(0xee00);
593 #endif
594
595     while(true) {
596
597 #ifdef MULTICORE_GC
598       // check if need to do GC
599       if(gcflag) {
600                 gc(NULL);
601           }
602 #endif // MULTICORE_GC
603
604 #ifdef TASK
605       // check if there are new active tasks can be executed
606       executetasks();
607       if(busystatus) {
608                 sendStall = false;
609       }
610
611 #ifndef INTERRUPT
612       while(receiveObject() != -1) {
613       }
614 #endif
615
616       BAMBOO_DEBUGPRINT(0xee01);
617
618       // check if there are some pending objects,
619       // if yes, enqueue them and executetasks again
620       tocontinue = checkObjQueue();
621 #elif defined MGC
622           // TODO
623 #endif
624
625       if(!tocontinue) {
626                 // check if stop
627                 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
628                   if(isfirst) {
629                         BAMBOO_DEBUGPRINT(0xee03);
630                         isfirst = false;
631                   }
632                   checkCoreStatus();
633                 } else {
634                   if(!sendStall) {
635                         BAMBOO_DEBUGPRINT(0xee09);
636 #ifdef PROFILE
637                         if(!stall) {
638 #endif
639                         if(isfirst) {
640                           // wait for some time
641                           int halt = 10000;
642                           BAMBOO_DEBUGPRINT(0xee0a);
643                           while(halt--) {
644                           }
645                           isfirst = false;
646                         } else {
647                           // send StallMsg to startup core
648                           BAMBOO_DEBUGPRINT(0xee0b);
649                           // send stall msg
650                           send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
651                                                  self_numsendobjs, self_numreceiveobjs, false);
652                           sendStall = true;
653                           isfirst = true;
654                           busystatus = false;
655                         }
656 #ifdef PROFILE
657                   }
658 #endif
659                   } else {
660                         isfirst = true;
661                         busystatus = false;
662                         BAMBOO_DEBUGPRINT(0xee0c);
663                   }   // if(!sendStall)
664                 }   // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
665       }  // if(!tocontinue)
666     }  // while(true)
667   } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
668
669 } // run()
670
671 INLINE int checkMsgLength_I(int size) {
672 #ifndef CLOSE_PRINT
673   BAMBOO_DEBUGPRINT(0xcccc);
674 #endif
675   int type = msgdata[msgdataindex];
676   switch(type) {
677   case STATUSCONFIRM:
678   case TERMINATE:
679 #ifdef MULTICORE_GC
680   case GCSTARTPRE:
681   case GCSTARTINIT:
682   case GCSTART:
683   case GCSTARTMAPINFO:
684   case GCSTARTFLUSH:
685   case GCFINISH:
686   case GCMARKCONFIRM:
687   case GCLOBJREQUEST:
688 #ifdef GC_CACHE_ADAPT
689   case GCSTARTPREF:
690 #endif // GC_CACHE_ADAPT
691 #endif // MULTICORE_GC
692   {
693         msglength = 1;
694         break;
695   }
696
697 #ifdef TASK
698   case PROFILEOUTPUT:
699   case PROFILEFINISH:
700 #endif
701 #ifdef MULTICORE_GC
702   case GCSTARTCOMPACT:
703   case GCMARKEDOBJ:
704   case GCFINISHINIT:
705   case GCFINISHMAPINFO:
706   case GCFINISHFLUSH:
707 #ifdef GC_CACHE_ADAPT
708   case GCFINISHPREF:
709 #endif // GC_CACHE_ADAPT
710 #endif // MULTICORE_GC
711   {
712         msglength = 2;
713         break;
714   }
715
716   case MEMREQUEST:
717   case MEMRESPONSE:
718 #ifdef MULTICORE_GC
719   case GCMAPREQUEST:
720   case GCMAPINFO:
721   case GCMAPTBL:
722   case GCLOBJMAPPING:
723 #endif
724   {
725         msglength = 3;
726         break;
727   }
728
729   case TRANSTALL:
730 #ifdef TASK
731   case LOCKGROUNT:
732   case LOCKDENY:
733   case LOCKRELEASE:
734   case REDIRECTGROUNT:
735   case REDIRECTDENY:
736   case REDIRECTRELEASE:
737 #endif
738 #ifdef MULTICORE_GC
739   case GCFINISHPRE:
740   case GCFINISHMARK:
741   case GCMOVESTART:
742 #ifdef GC_PROFILE
743   case GCPROFILES:
744 #endif
745 #endif
746   {
747         msglength = 4;
748         break;
749   }
750
751 #ifdef TASK
752   case LOCKREQUEST:
753 #endif
754   case STATUSREPORT:
755 #ifdef MULTICORE_GC
756   case GCFINISHCOMPACT:
757   case GCMARKREPORT:
758 #endif
759   {
760         msglength = 5;
761         break;
762   }
763
764 #ifdef TASK
765   case REDIRECTLOCK:
766   {
767     msglength = 6;
768     break;
769   }
770 #endif
771
772 #ifdef TASK
773   case TRANSOBJ:   // nonfixed size
774 #endif
775 #ifdef MULTICORE_GC
776   case GCLOBJINFO:
777 #endif
778   {  // nonfixed size
779         if(size > 1) {
780           msglength = msgdata[(msgdataindex+1)&(BAMBOO_MSG_BUF_MASK)];
781         } else {
782           return -1;
783         }
784         break;
785   }
786
787   default:
788   {
789     BAMBOO_DEBUGPRINT_REG(type);
790         BAMBOO_DEBUGPRINT_REG(size);
791     BAMBOO_DEBUGPRINT_REG(msgdataindex);
792         BAMBOO_DEBUGPRINT_REG(msgdatalast);
793         BAMBOO_DEBUGPRINT_REG(msgdatafull);
794     int i = 6;
795     while(i-- > 0) {
796       BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
797     }
798     BAMBOO_EXIT(0xe004);
799     break;
800   }
801   }
802 #ifndef CLOSE_PRINT
803   BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
804   BAMBOO_DEBUGPRINT(0xffff);
805 #endif
806   return msglength;
807 }
808
809 INLINE void processmsg_transtall_I() {
810   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
811     // non startup core can not receive stall msg
812 #ifndef CLOSE_PRINT
813     BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
814 #endif
815     BAMBOO_EXIT(0xe006);
816   }
817   int num_core = msgdata[msgdataindex]; //[1]
818   MSG_INDEXINC_I();
819   int data2 = msgdata[msgdataindex]; //[2];
820   MSG_INDEXINC_I();
821   int data3 = msgdata[msgdataindex]; //[3];
822   MSG_INDEXINC_I();
823   if(num_core < NUMCORESACTIVE) {
824 #ifndef CLOSE_PRINT
825     BAMBOO_DEBUGPRINT(0xe881);
826 #endif
827     corestatus[num_core] = 0;
828     numsendobjs[num_core] = data2; //[2];
829     numreceiveobjs[num_core] = data3; //[3];
830   }
831 }
832
833 INLINE void processmsg_statusconfirm_I() {
834   if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
835      || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
836     // wrong core to receive such msg
837     BAMBOO_EXIT(0xe011);
838   } else {
839     // send response msg
840 #ifndef CLOSE_PRINT
841     BAMBOO_DEBUGPRINT(0xe887);
842 #endif
843     // cache the msg first
844     if(BAMBOO_CHECK_SEND_MODE()) {
845           cache_msg_5(STARTUPCORE, STATUSREPORT,
846                                   busystatus ? 1 : 0, BAMBOO_NUM_OF_CORE,
847                                   self_numsendobjs, self_numreceiveobjs);
848     } else {
849           send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
850                                  BAMBOO_NUM_OF_CORE, self_numsendobjs,
851                                  self_numreceiveobjs, true);
852     }
853   }
854 }
855
856 INLINE void processmsg_statusreport_I() {
857   int data1 = msgdata[msgdataindex];
858   MSG_INDEXINC_I();
859   int data2 = msgdata[msgdataindex];
860   MSG_INDEXINC_I();
861   int data3 = msgdata[msgdataindex];
862   MSG_INDEXINC_I();
863   int data4 = msgdata[msgdataindex];
864   MSG_INDEXINC_I();
865   // receive a status confirm info
866   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
867     // wrong core to receive such msg
868 #ifndef CLOSE_PRINT
869     BAMBOO_DEBUGPRINT_REG(data2);
870 #endif
871     BAMBOO_EXIT(0xe012);
872   } else {
873 #ifndef CLOSE_PRINT
874     BAMBOO_DEBUGPRINT(0xe888);
875 #endif
876     if(waitconfirm) {
877       numconfirm--;
878     }
879     corestatus[data2] = data1;
880     numsendobjs[data2] = data3;
881     numreceiveobjs[data2] = data4;
882   }
883 }
884
885 INLINE void processmsg_terminate_I() {
886 #ifndef CLOSE_PRINT
887   BAMBOO_DEBUGPRINT(0xe889);
888 #endif
889   disruntimedata();
890 #ifdef MULTICORE_GC
891 #ifdef GC_CACHE_ADAPT
892   bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
893 #endif // GC_CACHE_ADAPT
894 #endif // MULTICORE_GC
895   BAMBOO_EXIT_APP(0);
896 }
897
898 INLINE void processmsg_memrequest_I() {
899   int data1 = msgdata[msgdataindex];
900   MSG_INDEXINC_I();
901   int data2 = msgdata[msgdataindex];
902   MSG_INDEXINC_I();
903   // receive a shared memory request msg
904   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
905     // wrong core to receive such msg
906 #ifndef CLOSE_PRINT
907     BAMBOO_DEBUGPRINT_REG(data2);
908 #endif
909     BAMBOO_EXIT(0xe013);
910   } else {
911 #ifndef CLOSE_PRINT
912     BAMBOO_DEBUGPRINT(0xe88a);
913 #endif
914     int allocsize = 0;
915     void * mem = NULL;
916 #ifdef MULTICORE_GC
917     if(gcprocessing) {
918       // is currently doing gc, dump this msg
919       if(INITPHASE == gcphase) {
920                 // if still in the initphase of gc, send a startinit msg again,
921                 // cache the msg first
922                 if(BAMBOO_CHECK_SEND_MODE()) {
923                   cache_msg_1(data2, GCSTARTINIT);
924                 } else {
925                   send_msg_1(data2, GCSTARTINIT, true);
926                 }
927       }
928     } else {
929 #endif
930     mem = smemalloc_I(data2, data1, &allocsize);
931     if(mem != NULL) {
932       // send the start_va to request core, cache the msg first
933       if(BAMBOO_CHECK_SEND_MODE()) {
934                 cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
935       } else {
936                 send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
937           }
938     } //else 
939           // if mem == NULL, the gcflag of the startup core has been set
940           // and all the other cores have been informed to start gc
941 #ifdef MULTICORE_GC
942   }
943 #endif
944   }
945 }
946
947 INLINE void processmsg_memresponse_I() {
948   int data1 = msgdata[msgdataindex];
949   MSG_INDEXINC_I();
950   int data2 = msgdata[msgdataindex];
951   MSG_INDEXINC_I();
952   // receive a shared memory response msg
953 #ifndef CLOSE_PRINT
954   BAMBOO_DEBUGPRINT(0xe88b);
955 #endif
956 #ifdef MULTICORE_GC
957   // if is currently doing gc, dump this msg
958   if(!gcprocessing) {
959 #endif
960   if(data2 == 0) {
961     bamboo_smem_size = 0;
962     bamboo_cur_msp = 0;
963 #ifdef MULTICORE_GC
964         bamboo_smem_zero_top = 0;
965 #endif
966   } else {
967 #ifdef MULTICORE_GC
968     // fill header to store the size of this mem block
969     BAMBOO_MEMSET_WH(data1, '\0', BAMBOO_CACHE_LINE_SIZE); 
970     (*((int*)data1)) = data2;
971     bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
972     bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
973         bamboo_smem_zero_top = bamboo_cur_msp;
974 #else
975     bamboo_smem_size = data2;
976     bamboo_cur_msp =(void*)(data1);
977 #endif
978   }
979   smemflag = true;
980 #ifdef MULTICORE_GC
981 }
982 #endif
983 }
984
985 #ifdef MULTICORE_GC
986 INLINE void processmsg_gcstartpre_I() {
987   if(gcprocessing) {
988         // already stall for gc
989         // send a update pregc information msg to the master core
990         if(BAMBOO_CHECK_SEND_MODE()) {
991           cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE, 
992                   self_numsendobjs, self_numreceiveobjs);
993         } else {
994           send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE, 
995                   self_numsendobjs, self_numreceiveobjs, true);
996         }
997   } else {
998         // the first time to be informed to start gc
999         gcflag = true;
1000         if(!smemflag) {
1001           // is waiting for response of mem request
1002           // let it return NULL and start gc
1003           bamboo_smem_size = 0;
1004           bamboo_cur_msp = NULL;
1005           smemflag = true;
1006           bamboo_smem_zero_top = NULL;
1007         }
1008   }
1009 }
1010
1011 INLINE void processmsg_gcstartinit_I() {
1012   gcphase = INITPHASE;
1013 }
1014
1015 INLINE void processmsg_gcstart_I() {
1016 #ifndef CLOSE_PRINT
1017   BAMBOO_DEBUGPRINT(0xe88c);
1018 #endif
1019   // set the GC flag
1020   gcphase = MARKPHASE;
1021 }
1022
1023 INLINE void processmsg_gcstartcompact_I() {
1024   gcblock2fill = msgdata[msgdataindex];
1025   MSG_INDEXINC_I();  //msgdata[1];
1026   gcphase = COMPACTPHASE;
1027 }
1028
1029 INLINE void processmsg_gcstartmapinfo_I() {
1030   gcphase = MAPPHASE;
1031 }
1032
1033 INLINE void processmsg_gcstartflush_I() {
1034   gcphase = FLUSHPHASE;
1035 }
1036
1037 INLINE void processmsg_gcfinishpre_I() {
1038   int data1 = msgdata[msgdataindex];
1039   MSG_INDEXINC_I();
1040   int data2 = msgdata[msgdataindex];
1041   MSG_INDEXINC_I();
1042   int data3 = msgdata[msgdataindex];
1043   MSG_INDEXINC_I();
1044   // received a init phase finish msg
1045   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1046     // non startup core can not receive this msg
1047 #ifndef CLOSE_PRINT
1048     BAMBOO_DEBUGPRINT_REG(data1);
1049 #endif
1050     BAMBOO_EXIT(0xe014);
1051   }
1052   // All cores should do init GC
1053   if(!gcprecheck) {
1054         gcprecheck = true;
1055   }
1056   gccorestatus[data1] = 0;
1057   gcnumsendobjs[0][data1] = data2;
1058   gcnumreceiveobjs[0][data1] = data3;
1059 }
1060
1061 INLINE void processmsg_gcfinishinit_I() {
1062   int data1 = msgdata[msgdataindex];
1063   MSG_INDEXINC_I();
1064   // received a init phase finish msg
1065   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1066     // non startup core can not receive this msg
1067 #ifndef CLOSE_PRINT
1068     BAMBOO_DEBUGPRINT_REG(data1);
1069 #endif
1070     BAMBOO_EXIT(0xe015);
1071   }
1072 #ifndef CLOSE_PRINT
1073   BAMBOO_DEBUGPRINT(0xe88c);
1074   BAMBOO_DEBUGPRINT_REG(data1);
1075 #endif
1076   // All cores should do init GC
1077   if(data1 < NUMCORESACTIVE) {
1078     gccorestatus[data1] = 0;
1079   }
1080 }
1081
1082 INLINE void processmsg_gcfinishmark_I() {
1083   int data1 = msgdata[msgdataindex];
1084   MSG_INDEXINC_I();
1085   int data2 = msgdata[msgdataindex];
1086   MSG_INDEXINC_I();
1087   int data3 = msgdata[msgdataindex];
1088   MSG_INDEXINC_I();
1089   // received a mark phase finish msg
1090   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1091     // non startup core can not receive this msg
1092 #ifndef CLOSE_PRINT
1093     BAMBOO_DEBUGPRINT_REG(data1);
1094 #endif
1095     BAMBOO_EXIT(0xe016);
1096   }
1097   // all cores should do mark
1098   if(data1 < NUMCORESACTIVE) {
1099     gccorestatus[data1] = 0;
1100         int entry_index = 0;
1101         if(waitconfirm)  {
1102           // phase 2
1103           entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
1104         } else {
1105           // phase 1
1106           entry_index = gcnumsrobjs_index;
1107         }
1108     gcnumsendobjs[entry_index][data1] = data2;
1109     gcnumreceiveobjs[entry_index][data1] = data3;
1110   }
1111 }
1112
1113 INLINE void processmsg_gcfinishcompact_I() {
1114   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1115     // non startup core can not receive this msg
1116     // return -1
1117 #ifndef CLOSE_PRINT
1118     BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
1119 #endif
1120     BAMBOO_EXIT(0xe017);
1121   }
1122   int cnum = msgdata[msgdataindex];
1123   MSG_INDEXINC_I();       //msgdata[1];
1124   int filledblocks = msgdata[msgdataindex];
1125   MSG_INDEXINC_I();       //msgdata[2];
1126   int heaptop = msgdata[msgdataindex];
1127   MSG_INDEXINC_I();       //msgdata[3];
1128   int data4 = msgdata[msgdataindex];
1129   MSG_INDEXINC_I();       //msgdata[4];
1130   // only gc cores need to do compact
1131   if(cnum < NUMCORES4GC) {
1132     if(COMPACTPHASE == gcphase) {
1133       gcfilledblocks[cnum] = filledblocks;
1134       gcloads[cnum] = heaptop;
1135     }
1136     if(data4 > 0) {
1137       // ask for more mem
1138       int startaddr = 0;
1139       int tomove = 0;
1140       int dstcore = 0;
1141       if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
1142                 // cache the msg first
1143                 if(BAMBOO_CHECK_SEND_MODE()) {
1144                   cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
1145                 } else {
1146                   send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
1147                 }
1148       }
1149     } else {
1150       gccorestatus[cnum] = 0;
1151     }  // if(data4>0)
1152   }  // if(cnum < NUMCORES4GC)
1153 }
1154
1155 INLINE void processmsg_gcfinishmapinfo_I() {
1156   int data1 = msgdata[msgdataindex];
1157   MSG_INDEXINC_I();
1158   // received a map phase finish msg
1159   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1160     // non startup core can not receive this msg
1161 #ifndef CLOSE_PRINT
1162     BAMBOO_DEBUGPRINT_REG(data1);
1163 #endif
1164     BAMBOO_EXIT(0xe018);
1165   }
1166   // all cores should do flush
1167   if(data1 < NUMCORES4GC) {
1168     gccorestatus[data1] = 0;
1169   }
1170 }
1171
1172
1173 INLINE void processmsg_gcfinishflush_I() {
1174   int data1 = msgdata[msgdataindex];
1175   MSG_INDEXINC_I();
1176   // received a flush phase finish msg
1177   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1178     // non startup core can not receive this msg
1179 #ifndef CLOSE_PRINT
1180     BAMBOO_DEBUGPRINT_REG(data1);
1181 #endif
1182     BAMBOO_EXIT(0xe019);
1183   }
1184   // all cores should do flush
1185   if(data1 < NUMCORESACTIVE) {
1186     gccorestatus[data1] = 0;
1187   }
1188 }
1189
1190 INLINE void processmsg_gcmarkconfirm_I() {
1191   if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
1192      || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
1193     // wrong core to receive such msg
1194     BAMBOO_EXIT(0xe01a);
1195   } else {
1196     // send response msg, cahce the msg first
1197     if(BAMBOO_CHECK_SEND_MODE()) {
1198           cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
1199                                   gcbusystatus, gcself_numsendobjs,
1200                                   gcself_numreceiveobjs);
1201     } else {
1202           send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
1203                                  gcbusystatus, gcself_numsendobjs,
1204                                  gcself_numreceiveobjs, true);
1205     }
1206   }
1207 }
1208
1209 INLINE void processmsg_gcmarkreport_I() {
1210   int data1 = msgdata[msgdataindex];
1211   MSG_INDEXINC_I();
1212   int data2 = msgdata[msgdataindex];
1213   MSG_INDEXINC_I();
1214   int data3 = msgdata[msgdataindex];
1215   MSG_INDEXINC_I();
1216   int data4 = msgdata[msgdataindex];
1217   MSG_INDEXINC_I();
1218   // received a marked phase finish confirm response msg
1219   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1220     // wrong core to receive such msg
1221 #ifndef CLOSE_PRINT
1222     BAMBOO_DEBUGPRINT_REG(data2);
1223 #endif
1224     BAMBOO_EXIT(0xe01b);
1225   } else {
1226         int entry_index = 0;
1227     if(waitconfirm) {
1228           // phse 2
1229       numconfirm--;
1230           entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
1231     } else {
1232           // can never reach here
1233           // phase 1
1234           entry_index = gcnumsrobjs_index;
1235         }
1236     gccorestatus[data1] = data2;
1237     gcnumsendobjs[entry_index][data1] = data3;
1238     gcnumreceiveobjs[entry_index][data1] = data4;
1239   }
1240 }
1241
1242 INLINE void processmsg_gcmarkedobj_I() {
1243   int data1 = msgdata[msgdataindex];
1244   MSG_INDEXINC_I();
1245   // received a markedObj msg
1246   if(((int *)data1)[6] == INIT) {
1247     // this is the first time that this object is discovered,
1248     // set the flag as DISCOVERED
1249     ((int *)data1)[6] = DISCOVERED;
1250     gc_enqueue_I(data1);
1251   } 
1252   // set the remote flag
1253   ((int *)data1)[6] |= REMOTEM;
1254   gcself_numreceiveobjs++;
1255   gcbusystatus = true;
1256 }
1257
1258 INLINE void processmsg_gcmovestart_I() {
1259   gctomove = true;
1260   gcdstcore = msgdata[msgdataindex];
1261   MSG_INDEXINC_I();       //msgdata[1];
1262   gcmovestartaddr = msgdata[msgdataindex];
1263   MSG_INDEXINC_I();       //msgdata[2];
1264   gcblock2fill = msgdata[msgdataindex];
1265   MSG_INDEXINC_I();       //msgdata[3];
1266 }
1267
1268 INLINE void processmsg_gcmaprequest_I() {
1269   void * dstptr = NULL;
1270   int data1 = msgdata[msgdataindex];
1271   MSG_INDEXINC_I();
1272   int data2 = msgdata[msgdataindex];
1273   MSG_INDEXINC_I();
1274 #ifdef LOCALHASHTBL_TEST
1275   RuntimeHashget(gcpointertbl, data1, &dstptr);
1276 #else
1277   dstptr = mgchashSearch(gcpointertbl, data1);
1278 #endif
1279   if(NULL == dstptr) {
1280     // no such pointer in this core, something is wrong
1281 #ifndef CLOSE_PRINT
1282     BAMBOO_DEBUGPRINT_REG(data1);
1283     BAMBOO_DEBUGPRINT_REG(data2);
1284 #endif
1285     BAMBOO_EXIT(0xe01c);
1286   } else {
1287     // send back the mapping info, cache the msg first
1288     if(BAMBOO_CHECK_SEND_MODE()) {
1289           cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
1290     } else {
1291           send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
1292     }
1293   }
1294 }
1295
1296 INLINE void processmsg_gcmapinfo_I() {
1297   int data1 = msgdata[msgdataindex];
1298   MSG_INDEXINC_I();
1299   gcmappedobj = msgdata[msgdataindex];  // [2]
1300   MSG_INDEXINC_I();
1301 #ifdef LOCALHASHTBL_TEST
1302   RuntimeHashadd_I(gcpointertbl, data1, gcmappedobj);
1303 #else
1304   mgchashInsert_I(gcpointertbl, data1, gcmappedobj);
1305 #endif
1306   if(data1 == gcobj2map) {
1307         gcismapped = true;
1308   }
1309 }
1310
1311 INLINE void processmsg_gcmaptbl_I() {
1312   int data1 = msgdata[msgdataindex];
1313   MSG_INDEXINC_I();
1314   int data2 = msgdata[msgdataindex];
1315   MSG_INDEXINC_I();
1316   gcrpointertbls[data2] = (mgcsharedhashtbl_t *)data1; 
1317 }
1318
1319 INLINE void processmsg_gclobjinfo_I() {
1320   numconfirm--;
1321
1322   int data1 = msgdata[msgdataindex];
1323   MSG_INDEXINC_I();
1324   int data2 = msgdata[msgdataindex];
1325   MSG_INDEXINC_I();
1326   if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
1327 #ifndef CLOSE_PRINT
1328     BAMBOO_DEBUGPRINT_REG(data2);
1329 #endif
1330     BAMBOO_EXIT(0xe01d);
1331   }
1332   // store the mark result info
1333   int cnum = data2;
1334   gcloads[cnum] = msgdata[msgdataindex];
1335   MSG_INDEXINC_I();       // msgdata[3];
1336   int data4 = msgdata[msgdataindex];
1337   MSG_INDEXINC_I();
1338   if(gcheaptop < data4) {
1339     gcheaptop = data4;
1340   }
1341   // large obj info here
1342   for(int k = 5; k < data1; k+=2) {
1343     int lobj = msgdata[msgdataindex];
1344     MSG_INDEXINC_I();   //msgdata[k++];
1345     int length = msgdata[msgdataindex];
1346     MSG_INDEXINC_I();   //msgdata[k++];
1347     gc_lobjenqueue_I(lobj, length, cnum);
1348     gcnumlobjs++;
1349   }  // for(int k = 5; k < msgdata[1];)
1350 }
1351
1352 INLINE void processmsg_gclobjmapping_I() {
1353   int data1 = msgdata[msgdataindex];
1354   MSG_INDEXINC_I();
1355   int data2 = msgdata[msgdataindex];
1356   MSG_INDEXINC_I();
1357 #ifdef LOCALHASHTBL_TEST
1358   RuntimeHashadd_I(gcpointertbl, data1, data2);
1359 #else
1360   mgchashInsert_I(gcpointertbl, data1, data2);
1361 #endif
1362   mgcsharedhashInsert_I(gcsharedptbl, data1, data2);
1363 }
1364
1365 #ifdef GC_PROFILE
1366 INLINE void processmsg_gcprofiles_I() {
1367   int data1 = msgdata[msgdataindex];
1368   MSG_INDEXINC_I();
1369   int data2 = msgdata[msgdataindex];
1370   MSG_INDEXINC_I();
1371   int data3 = msgdata[msgdataindex];
1372   MSG_INDEXINC_I();
1373   gc_num_obj += data1;
1374   gc_num_liveobj += data2;
1375   gc_num_forwardobj += data3;
1376   gc_num_profiles--;
1377 }
1378 #endif // GC_PROFILE
1379
1380 #ifdef GC_CACHE_ADAPT
1381 INLINE void processmsg_gcstartpref_I() {
1382   gcphase = PREFINISHPHASE;
1383 }
1384
1385 INLINE void processmsg_gcfinishpref_I() {
1386   int data1 = msgdata[msgdataindex];
1387   MSG_INDEXINC_I();
1388   // received a flush phase finish msg
1389   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1390     // non startup core can not receive this msg
1391 #ifndef CLOSE_PRINT
1392     BAMBOO_DEBUGPRINT_REG(data1);
1393 #endif
1394     BAMBOO_EXIT(0xe01e);
1395   }
1396   // all cores should do flush
1397   if(data1 < NUMCORESACTIVE) {
1398     gccorestatus[data1] = 0;
1399   }
1400 }
1401 #endif // GC_CACHE_ADAPT
1402 #endif // #ifdef MULTICORE_GC
1403
1404 // receive object transferred from other cores
1405 // or the terminate message from other cores
1406 // Should be invoked in critical sections!!
1407 // NOTICE: following format is for threadsimulate version only
1408 //         RAW version please see previous description
1409 // format: type + object
1410 // type: -1--stall msg
1411 //      !-1--object
1412 // return value: 0--received an object
1413 //               1--received nothing
1414 //               2--received a Stall Msg
1415 //               3--received a lock Msg
1416 //               RAW version: -1 -- received nothing
1417 //                            otherwise -- received msg type
1418 int receiveObject(int send_port_pending) {
1419 #ifdef TASK
1420 #ifdef PROFILE_INTERRUPT
1421   if(!interruptInfoOverflow) {
1422     InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
1423     interruptInfoArray[interruptInfoIndex] = intInfo;
1424     intInfo->startTime = BAMBOO_GET_EXE_TIME();
1425     intInfo->endTime = -1;
1426   }
1427 #endif // PROFILE_INTERRUPT
1428 #endif // TASK
1429 msg:
1430   // get the incoming msgs
1431   if(receiveMsg(send_port_pending) == -1) {
1432     return -1;
1433   }
1434 processmsg:
1435   // processing received msgs
1436   int size = 0;
1437   MSG_REMAINSIZE_I(&size);
1438   if((size == 0) || (checkMsgLength_I(size) == -1)) {
1439     // not a whole msg
1440     // have new coming msg
1441     if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
1442       goto msg;
1443     } else {
1444       return -1;
1445     }
1446   }
1447
1448   if(msglength <= size) {
1449     // have some whole msg
1450     MSGTYPE type;
1451     type = msgdata[msgdataindex]; //[0]
1452     MSG_INDEXINC_I();
1453     msgdatafull = false;
1454     switch(type) {
1455 #ifdef TASK
1456     case TRANSOBJ: {
1457       // receive a object transfer msg
1458       processmsg_transobj_I();
1459       break;
1460     }   // case TRANSOBJ
1461 #endif // TASK
1462
1463     case TRANSTALL: {
1464       // receive a stall msg
1465       processmsg_transtall_I();
1466       break;
1467     }   // case TRANSTALL
1468
1469 #ifdef TASK
1470 // GC version have no lock msgs
1471 #ifndef MULTICORE_GC
1472     case LOCKREQUEST: {
1473       // receive lock request msg, handle it right now
1474       processmsg_lockrequest_I();
1475       break;
1476     }   // case LOCKREQUEST
1477
1478     case LOCKGROUNT: {
1479       // receive lock grount msg
1480       processmsg_lockgrount_I();
1481       break;
1482     }   // case LOCKGROUNT
1483
1484     case LOCKDENY: {
1485       // receive lock deny msg
1486       processmsg_lockdeny_I();
1487       break;
1488     }   // case LOCKDENY
1489
1490     case LOCKRELEASE: {
1491       processmsg_lockrelease_I();
1492       break;
1493     }   // case LOCKRELEASE
1494 #endif // #ifndef MULTICORE_GC
1495
1496 #ifdef PROFILE
1497     case PROFILEOUTPUT: {
1498       // receive an output profile data request msg
1499       processmsg_profileoutput_I();
1500       break;
1501     }   // case PROFILEOUTPUT
1502
1503     case PROFILEFINISH: {
1504       // receive a profile output finish msg
1505       processmsg_profilefinish_I();
1506       break;
1507     }   // case PROFILEFINISH
1508 #endif // #ifdef PROFILE
1509
1510 // GC version has no lock msgs
1511 #ifndef MULTICORE_GC
1512     case REDIRECTLOCK: {
1513       // receive a redirect lock request msg, handle it right now
1514       processmsg_redirectlock_I();
1515       break;
1516     }   // case REDIRECTLOCK
1517
1518     case REDIRECTGROUNT: {
1519       // receive a lock grant msg with redirect info
1520       processmsg_redirectgrount_I();
1521       break;
1522     }   // case REDIRECTGROUNT
1523
1524     case REDIRECTDENY: {
1525       // receive a lock deny msg with redirect info
1526       processmsg_redirectdeny_I();
1527       break;
1528     }   // case REDIRECTDENY
1529
1530     case REDIRECTRELEASE: {
1531       // receive a lock release msg with redirect info
1532       processmsg_redirectrelease_I();
1533       break;
1534     }   // case REDIRECTRELEASE
1535 #endif // #ifndef MULTICORE_GC
1536 #endif // TASK
1537
1538     case STATUSCONFIRM: {
1539       // receive a status confirm info
1540       processmsg_statusconfirm_I();
1541       break;
1542     }   // case STATUSCONFIRM
1543
1544     case STATUSREPORT: {
1545       processmsg_statusreport_I();
1546       break;
1547     }   // case STATUSREPORT
1548
1549     case TERMINATE: {
1550       // receive a terminate msg
1551       processmsg_terminate_I();
1552       break;
1553     }   // case TERMINATE
1554
1555     case MEMREQUEST: {
1556       processmsg_memrequest_I();
1557       break;
1558     }   // case MEMREQUEST
1559
1560     case MEMRESPONSE: {
1561       processmsg_memresponse_I();
1562       break;
1563     }   // case MEMRESPONSE
1564
1565 #ifdef MULTICORE_GC
1566     // GC msgs
1567     case GCSTARTPRE: {
1568       processmsg_gcstartpre_I();
1569       break;
1570     }   // case GCSTARTPRE
1571         
1572         case GCSTARTINIT: {
1573       processmsg_gcstartinit_I();
1574       break;
1575     }   // case GCSTARTINIT
1576
1577     case GCSTART: {
1578       // receive a start GC msg
1579       processmsg_gcstart_I();
1580       break;
1581     }   // case GCSTART
1582
1583     case GCSTARTCOMPACT: {
1584       // a compact phase start msg
1585       processmsg_gcstartcompact_I();
1586       break;
1587     }   // case GCSTARTCOMPACT
1588
1589         case GCSTARTMAPINFO: {
1590       // received a flush phase start msg
1591       processmsg_gcstartmapinfo_I();
1592       break;
1593     }   // case GCSTARTFLUSH
1594
1595     case GCSTARTFLUSH: {
1596       // received a flush phase start msg
1597       processmsg_gcstartflush_I();
1598       break;
1599     }   // case GCSTARTFLUSH
1600
1601     case GCFINISHPRE: {
1602       processmsg_gcfinishpre_I();
1603       break;
1604     }   // case GCFINISHPRE
1605         
1606         case GCFINISHINIT: {
1607       processmsg_gcfinishinit_I();
1608       break;
1609     }   // case GCFINISHINIT
1610
1611     case GCFINISHMARK: {
1612       processmsg_gcfinishmark_I();
1613       break;
1614     }   // case GCFINISHMARK
1615
1616     case GCFINISHCOMPACT: {
1617       // received a compact phase finish msg
1618       processmsg_gcfinishcompact_I();
1619       break;
1620     }   // case GCFINISHCOMPACT
1621
1622         case GCFINISHMAPINFO: {
1623       processmsg_gcfinishmapinfo_I();
1624       break;
1625     }   // case GCFINISHMAPINFO
1626
1627     case GCFINISHFLUSH: {
1628       processmsg_gcfinishflush_I();
1629       break;
1630     }   // case GCFINISHFLUSH
1631
1632     case GCFINISH: {
1633       // received a GC finish msg
1634       gcphase = FINISHPHASE;
1635       break;
1636     }   // case GCFINISH
1637
1638     case GCMARKCONFIRM: {
1639       // received a marked phase finish confirm request msg
1640       // all cores should do mark
1641       processmsg_gcmarkconfirm_I();
1642       break;
1643     }   // case GCMARKCONFIRM
1644
1645     case GCMARKREPORT: {
1646       processmsg_gcmarkreport_I();
1647       break;
1648     }   // case GCMARKREPORT
1649
1650     case GCMARKEDOBJ: {
1651       processmsg_gcmarkedobj_I();
1652       break;
1653     }   // case GCMARKEDOBJ
1654
1655     case GCMOVESTART: {
1656       // received a start moving objs msg
1657       processmsg_gcmovestart_I();
1658       break;
1659     }   // case GCMOVESTART
1660
1661     case GCMAPREQUEST: {
1662       // received a mapping info request msg
1663       processmsg_gcmaprequest_I();
1664       break;
1665     }   // case GCMAPREQUEST
1666
1667     case GCMAPINFO: {
1668       // received a mapping info response msg
1669       processmsg_gcmapinfo_I();
1670       break;
1671     }   // case GCMAPINFO
1672
1673     case GCMAPTBL: {
1674       // received a mapping tbl response msg
1675       processmsg_gcmaptbl_I();
1676       break;
1677     }   // case GCMAPTBL
1678         
1679         case GCLOBJREQUEST: {
1680       // received a large objs info request msg
1681       transferMarkResults_I();
1682       break;
1683     }   // case GCLOBJREQUEST
1684
1685     case GCLOBJINFO: {
1686       // received a large objs info response msg
1687       processmsg_gclobjinfo_I();
1688       break;
1689     }   // case GCLOBJINFO
1690
1691     case GCLOBJMAPPING: {
1692       // received a large obj mapping info msg
1693       processmsg_gclobjmapping_I();
1694       break;
1695     }  // case GCLOBJMAPPING
1696
1697 #ifdef GC_PROFILE
1698         case GCPROFILES: {
1699       // received a gcprofiles msg
1700       processmsg_gcprofiles_I();
1701       break;
1702     }
1703 #endif // GC_PROFILE
1704
1705 #ifdef GC_CACHE_ADAPT
1706         case GCSTARTPREF: {
1707       // received a gcstartpref msg
1708       processmsg_gcstartpref_I();
1709       break;
1710     }
1711
1712         case GCFINISHPREF: {
1713       // received a gcfinishpref msg
1714       processmsg_gcfinishpref_I();
1715       break;
1716     }
1717 #endif // GC_CACHE_ADAPT
1718 #endif // #ifdef MULTICORE_GC
1719
1720     default:
1721       break;
1722     }  // switch(type)
1723     msglength = BAMBOO_MSG_BUF_LENGTH;
1724
1725     if((msgdataindex != msgdatalast) || (msgdatafull)) {
1726       // still have available msg
1727       goto processmsg;
1728     }
1729 #ifndef CLOSE_PRINT
1730     BAMBOO_DEBUGPRINT(0xe88d);
1731 #endif
1732
1733     // have new coming msg
1734     if(BAMBOO_MSG_AVAIL() != 0) {
1735       goto msg;
1736     } // TODO
1737
1738 #ifdef TASK
1739 #ifdef PROFILE_INTERRUPT
1740   if(!interruptInfoOverflow) {
1741     interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
1742     interruptInfoIndex++;
1743     if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
1744       interruptInfoOverflow = true;
1745     }
1746   }
1747 #endif
1748 #endif // TASK
1749     return (int)type;
1750   } else {
1751     // not a whole msg
1752 #ifndef CLOSE_PRINT
1753     BAMBOO_DEBUGPRINT(0xe88e);
1754 #endif
1755     return -2;
1756   }
1757 }
1758
1759 #endif // MULTICORE