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