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