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