89a2dbe21f1adef0963552351ab31ea120447061
[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() {
405 #ifndef TASK
406   printf("Array out of bounds\n");
407 #ifdef THREADS
408   threadexit();
409 #elif defined MGC
410   BAMBOO_EXIT(0xa002);
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(0xa002);
420 #endif
421 #endif
422 }
423
424 /* Abort task call */
425 void abort_task() {
426 #ifdef TASK
427 #ifndef MULTICORE
428   printf("Aborting\n");
429   longjmp(error_handler,4);
430 #endif
431 #else
432   printf("Aborting\n");
433   exit(-1);
434 #endif
435 }
436
437 INLINE void initruntimedata() {
438   int i;
439   // initialize the arrays
440   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
441     // startup core to initialize corestatus[]
442     for(i = 0; i < NUMCORESACTIVE; ++i) {
443       corestatus[i] = 1;
444       numsendobjs[i] = 0;
445       numreceiveobjs[i] = 0;
446 #ifdef MULTICORE_GC
447       gccorestatus[i] = 1;
448       gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
449       gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
450 #endif
451     } // for(i = 0; i < NUMCORESACTIVE; ++i)
452 #ifdef MULTICORE_GC
453     for(i = 0; i < NUMCORES4GC; ++i) {
454       gcloads[i] = 0;
455       gcrequiredmems[i] = 0;
456       gcstopblock[i] = 0;
457       gcfilledblocks[i] = 0;
458     } // for(i = 0; i < NUMCORES4GC; ++i)
459 #ifdef GC_PROFILE
460     gc_infoIndex = 0;
461     gc_infoOverflow = false;
462         gc_num_livespace = 0;
463         gc_num_freespace = 0;
464 #endif
465 #endif
466     numconfirm = 0;
467     waitconfirm = false;
468   }
469
470   busystatus = true;
471   self_numsendobjs = 0;
472   self_numreceiveobjs = 0;
473
474   for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
475     msgdata[i] = -1;
476   }
477   msgdataindex = 0;
478   msgdatalast = 0;
479   msglength = BAMBOO_MSG_BUF_LENGTH;
480   msgdatafull = false;
481   for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
482     outmsgdata[i] = -1;
483   }
484   outmsgindex = 0;
485   outmsglast = 0;
486   outmsgleft = 0;
487   isMsgHanging = false;
488
489   smemflag = true;
490   bamboo_cur_msp = NULL;
491   bamboo_smem_size = 0;
492
493 #ifdef MULTICORE_GC
494   bamboo_smem_zero_top = NULL;
495   gcflag = false;
496   gcprocessing = false;
497   gcphase = FINISHPHASE;
498   gcprecheck = true;
499   gccurr_heaptop = 0;
500   gcself_numsendobjs = 0;
501   gcself_numreceiveobjs = 0;
502   gcmarkedptrbound = 0;
503 #ifdef LOCALHASHTBL_TEST
504   gcpointertbl = allocateRuntimeHash_I(20);
505 #else
506   gcpointertbl = mgchashCreate_I(2000, 0.75);
507 #endif
508   gcforwardobjtbl = allocateMGCHash_I(20, 3);
509   gcobj2map = 0;
510   gcmappedobj = 0;
511   gcnumlobjs = 0;
512   gcheaptop = 0;
513   gctopcore = 0;
514   gctopblock = 0;
515   gcmovestartaddr = 0;
516   gctomove = false;
517   gcmovepending = 0;
518   gcblock2fill = 0;
519   if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
520         int t_size = ((BAMBOO_RMSP_SIZE)-sizeof(mgcsharedhashtbl_t)*2
521                 -128*sizeof(size_t))/sizeof(mgcsharedhashlistnode_t)-2;
522         int kk = 0;
523         unsigned int tmp_k = 1 << (sizeof(int)*8 -1);
524         while(((t_size & tmp_k) == 0) && (kk < sizeof(int)*8)) {
525           t_size = t_size << 1;
526           kk++;
527         }
528         t_size = tmp_k >> kk;
529         gcsharedptbl = mgcsharedhashCreate_I(t_size,0.30);
530   } else {
531         gcsharedptbl = NULL;
532   }
533   BAMBOO_MEMSET_WH(gcrpointertbls, 0, 
534           sizeof(mgcsharedhashtbl_t *)*NUMCORES4GC);
535 #ifdef SMEMM
536   gcmem_mixed_threshold = (unsigned int)((BAMBOO_SHARED_MEM_SIZE
537                 -bamboo_reserved_smem*BAMBOO_SMEM_SIZE)*0.8);
538   gcmem_mixed_usedmem = 0;
539 #endif
540 #ifdef GC_PROFILE
541   gc_num_obj = 0;
542   gc_num_liveobj = 0;
543   gc_num_forwardobj = 0;
544   gc_num_profiles = NUMCORESACTIVE - 1;
545 #endif
546 #ifdef GC_FLUSH_DTLB
547   gc_num_flush_dtlb = 0;
548 #endif
549   gc_localheap_s = false;
550 #ifdef GC_CACHE_ADAPT
551   gccachestage = false;
552 #endif // GC_CACHE_ADAPT
553 #endif // MULTICORE_GC
554 #ifndef INTERRUPT
555   reside = false;
556 #endif
557
558 #ifdef MGC
559   initializethreads();
560   bamboo_current_thread = NULL;
561 #endif // MGC
562
563 #ifdef TASK
564   inittaskdata();
565 #endif
566 }
567
568 INLINE void disruntimedata() {
569 #ifdef MULTICORE_GC
570 #ifdef LOCALHASHTBL_TEST
571   freeRuntimeHash(gcpointertbl);
572 #else
573   mgchashDelete(gcpointertbl);
574 #endif
575   freeMGCHash(gcforwardobjtbl);
576 #endif // MULTICORE_GC
577 #ifdef TASK
578   distaskdata()
579 #endif // TASK
580   BAMBOO_LOCAL_MEM_CLOSE();
581   BAMBOO_SHARE_MEM_CLOSE();
582 }
583
584 INLINE void checkCoreStatus() {
585   bool allStall = false;
586   int i = 0;
587   int sumsendobj = 0;
588   if((!waitconfirm) ||
589      (waitconfirm && (numconfirm == 0))) {
590     BAMBOO_DEBUGPRINT(0xee04);
591     BAMBOO_DEBUGPRINT_REG(waitconfirm);
592     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
593     BAMBOO_DEBUGPRINT(0xf001);
594     corestatus[BAMBOO_NUM_OF_CORE] = 0;
595     numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
596     numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
597     // check the status of all cores
598     allStall = true;
599     BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
600     for(i = 0; i < NUMCORESACTIVE; ++i) {
601       BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
602       if(corestatus[i] != 0) {
603                 allStall = false;
604                 break;
605       }
606     }  // for(i = 0; i < NUMCORESACTIVE; ++i)
607     if(allStall) {
608       // check if the sum of send objs and receive obj are the same
609       // yes->check if the info is the latest; no->go on executing
610       sumsendobj = 0;
611       for(i = 0; i < NUMCORESACTIVE; ++i) {
612                 sumsendobj += numsendobjs[i];
613                 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
614       }  // for(i = 0; i < NUMCORESACTIVE; ++i)
615       for(i = 0; i < NUMCORESACTIVE; ++i) {
616                 sumsendobj -= numreceiveobjs[i];
617                 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
618       }  // for(i = 0; i < NUMCORESACTIVE; ++i)
619       if(0 == sumsendobj) {
620                 if(!waitconfirm) {
621                   // the first time found all cores stall
622                   // send out status confirm msg to all other cores
623                   // reset the corestatus array too
624                   BAMBOO_DEBUGPRINT(0xee05);
625                   corestatus[BAMBOO_NUM_OF_CORE] = 1;
626                   waitconfirm = true;
627                   numconfirm = NUMCORESACTIVE - 1;
628                   BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
629                   for(i = 1; i < NUMCORESACTIVE; ++i) {
630                         corestatus[i] = 1;
631                         // send status confirm msg to core i
632                         send_msg_1(i, STATUSCONFIRM, false);
633                   }   // for(i = 1; i < NUMCORESACTIVE; ++i)
634                   return;
635                 } else {
636                   // all the core status info are the latest
637                   // terminate; for profiling mode, send request to all
638                   // other cores to pour out profiling data
639                   BAMBOO_DEBUGPRINT(0xee06);
640
641 #ifdef USEIO
642                   totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
643 #else
644
645                   BAMBOO_PRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
646                   //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
647 #ifdef GC_FLUSH_DTLB
648                   BAMBOO_PRINT_REG(gc_num_flush_dtlb);
649 #endif
650 #ifndef BAMBOO_MEMPROF
651                   BAMBOO_PRINT(0xbbbbbbbb);
652 #endif
653 #endif
654                   // profile mode, send msgs to other cores to request pouring
655                   // out progiling data
656 #ifdef PROFILE
657                   BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
658                   BAMBOO_DEBUGPRINT(0xf000);
659                   for(i = 1; i < NUMCORESACTIVE; ++i) {
660                         // send profile request msg to core i
661                         send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
662                   } // for(i = 1; i < NUMCORESACTIVE; ++i)
663 #ifndef RT_TEST
664                   // pour profiling data on startup core
665                   outputProfileData();
666 #endif
667                   while(true) {
668                         BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
669                         BAMBOO_DEBUGPRINT(0xf001);
670                         profilestatus[BAMBOO_NUM_OF_CORE] = 0;
671                         // check the status of all cores
672                         allStall = true;
673                         BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
674                         for(i = 0; i < NUMCORESACTIVE; ++i) {
675                           BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
676                           if(profilestatus[i] != 0) {
677                                 allStall = false;
678                                 break;
679                           }
680                         }  // for(i = 0; i < NUMCORESACTIVE; ++i)
681                         if(!allStall) {
682                           int halt = 100;
683                           BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
684                           BAMBOO_DEBUGPRINT(0xf000);
685                           while(halt--) {
686                           }
687                         } else {
688                           BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
689                           break;
690                         }  // if(!allStall)
691                   }  // while(true)
692 #endif
693
694                   // gc_profile mode, output gc prfiling data
695 #ifdef MULTICORE_GC
696 #ifdef GC_CACHE_ADAPT
697                   bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
698 #endif // GC_CACHE_ADAPT
699 #ifdef GC_PROFILE
700                   gc_outputProfileData();
701 #endif // #ifdef GC_PROFILE
702 #endif // #ifdef MULTICORE_GC
703                   disruntimedata();
704                   BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
705                   terminate();  // All done.
706                 }  // if(!waitconfirm)
707       } else {
708                 // still some objects on the fly on the network
709                 // reset the waitconfirm and numconfirm
710                 BAMBOO_DEBUGPRINT(0xee07);
711                 waitconfirm = false;
712                 numconfirm = 0;
713           }  //  if(0 == sumsendobj)
714     } else {
715       // not all cores are stall, keep on waiting
716       BAMBOO_DEBUGPRINT(0xee08);
717       waitconfirm = false;
718       numconfirm = 0;
719     }  //  if(allStall)
720     BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
721     BAMBOO_DEBUGPRINT(0xf000);
722   }  // if((!waitconfirm) ||
723 }
724
725 // main function for each core
726 inline void run(int argc, char** argv) {
727   int i = 0;
728   bool sendStall = false;
729   bool isfirst = true;
730   bool tocontinue = false;
731
732   corenum = BAMBOO_GET_NUM_OF_CORE();
733   BAMBOO_DEBUGPRINT(0xeeee);
734   BAMBOO_DEBUGPRINT_REG(corenum);
735   BAMBOO_DEBUGPRINT(STARTUPCORE);
736
737   // initialize runtime data structures
738   initruntimedata();
739
740   // other architecture related initialization
741   initialization();
742   initCommunication();
743
744 #ifdef GC_CACHE_ADAPT
745 // enable the timer interrupt
746 #ifdef GC_CACHE_SAMPLING
747   bamboo_tile_timer_set_next_event(GC_TILE_TIMER_EVENT_SETTING); // TODO
748   bamboo_unmask_timer_intr();
749   bamboo_dtlb_sampling_process();
750 #endif // GC_CACHE_SAMPLING
751 #endif // GC_CACHE_ADAPT
752
753   initializeexithandler();
754
755   // main process of the execution module
756   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
757 #ifdef TASK
758     // non-executing cores, only processing communications
759     activetasks = NULL;
760 #endif
761     fakeExecution();
762   } else {
763 #ifdef TASK
764     /* Create queue of active tasks */
765     activetasks=
766       genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
767                            (int (*)(void *,void *)) &comparetpd);
768
769     /* Process task information */
770     processtasks();
771
772     if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
773       /* Create startup object */
774       createstartupobject(argc, argv);
775     }
776
777     BAMBOO_DEBUGPRINT(0xee00);
778 #endif
779
780         if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
781 #ifdef TASK
782           // run the initStaticAndGlobal method to initialize the static blocks and
783           // global fields
784           initStaticAndGlobal();
785 #elif defined MGC
786           // run the main method in the specified mainclass
787           mgc_main(argc, argv);
788 #endif // TASK
789         }
790
791     while(true) {
792
793 #ifdef MULTICORE_GC
794       // check if need to do GC
795       if(gcflag) {
796                 gc(NULL);
797           }
798 #endif // MULTICORE_GC
799
800 #ifdef TASK
801       // check if there are new active tasks can be executed
802       executetasks();
803       if(busystatus) {
804                 sendStall = false;
805       }
806
807 #ifndef INTERRUPT
808       while(receiveObject() != -1) {
809       }
810 #endif
811
812       BAMBOO_DEBUGPRINT(0xee01);
813
814       // check if there are some pending objects,
815       // if yes, enqueue them and executetasks again
816       tocontinue = checkObjQueue();
817 #elif defined MGC
818           tocontinue = trystartthread();
819           if(tocontinue) {
820                 sendStall = false;
821           }
822 #endif
823
824       if(!tocontinue) {
825                 // check if stop
826                 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
827                   if(isfirst) {
828                         BAMBOO_DEBUGPRINT(0xee03);
829                         isfirst = false;
830                   }
831                   checkCoreStatus();
832                 } else {
833                   if(!sendStall) {
834                         BAMBOO_DEBUGPRINT(0xee09);
835 #ifdef PROFILE
836                         if(!stall) {
837 #endif
838                         if(isfirst) {
839                           // wait for some time
840                           int halt = 10000;
841                           BAMBOO_DEBUGPRINT(0xee0a);
842                           while(halt--) {
843                           }
844                           isfirst = false;
845                         } else {
846                           // send StallMsg to startup core
847                           BAMBOO_DEBUGPRINT(0xee0b);
848                           // send stall msg
849                           send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
850                                                  self_numsendobjs, self_numreceiveobjs, false);
851                           sendStall = true;
852                           isfirst = true;
853                           busystatus = false;
854                         }
855 #ifdef PROFILE
856                   }
857 #endif
858                   } else {
859                         isfirst = true;
860                         busystatus = false;
861                         BAMBOO_DEBUGPRINT(0xee0c);
862                   }   // if(!sendStall)
863                 }   // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
864       }  // if(!tocontinue)
865     }  // while(true)
866   } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
867
868 } // run()
869
870 INLINE int checkMsgLength_I(int size) {
871 #ifndef CLOSE_PRINT
872   BAMBOO_DEBUGPRINT(0xcccc);
873 #endif
874   int type = msgdata[msgdataindex];
875   switch(type) {
876   case STATUSCONFIRM:
877   case TERMINATE:
878 #ifdef MULTICORE_GC
879   case GCSTARTPRE:
880   case GCSTARTINIT:
881   case GCSTART:
882   case GCSTARTMAPINFO:
883   case GCSTARTFLUSH:
884   case GCFINISH:
885   case GCMARKCONFIRM:
886   case GCLOBJREQUEST:
887 #ifdef GC_CACHE_ADAPT
888   case GCSTARTPREF:
889 #endif // GC_CACHE_ADAPT
890 #endif // MULTICORE_GC
891   {
892         msglength = 1;
893         break;
894   }
895
896 #ifdef TASK
897   case PROFILEOUTPUT:
898   case PROFILEFINISH:
899 #endif
900 #ifdef MULTICORE_GC
901   case GCSTARTCOMPACT:
902   case GCMARKEDOBJ:
903   case GCFINISHINIT:
904   case GCFINISHMAPINFO:
905   case GCFINISHFLUSH:
906 #ifdef GC_CACHE_ADAPT
907   case GCFINISHPREF:
908 #endif // GC_CACHE_ADAPT
909 #endif // MULTICORE_GC
910   {
911         msglength = 2;
912         break;
913   }
914
915   case MEMREQUEST:
916   case MEMRESPONSE:
917 #ifdef MULTICORE_GC
918   case GCMAPREQUEST:
919   case GCMAPINFO:
920   case GCMAPTBL:
921   case GCLOBJMAPPING:
922 #endif
923   {
924         msglength = 3;
925         break;
926   }
927
928   case TRANSTALL:
929 #ifdef TASK
930   case LOCKGROUNT:
931   case LOCKDENY:
932   case LOCKRELEASE:
933   case REDIRECTGROUNT:
934   case REDIRECTDENY:
935   case REDIRECTRELEASE:
936 #endif
937 #ifdef MULTICORE_GC
938   case GCFINISHPRE:
939   case GCFINISHMARK:
940   case GCMOVESTART:
941 #ifdef GC_PROFILE
942   case GCPROFILES:
943 #endif
944 #endif
945   {
946         msglength = 4;
947         break;
948   }
949
950 #ifdef TASK
951   case LOCKREQUEST:
952 #endif
953   case STATUSREPORT:
954 #ifdef MULTICORE_GC
955   case GCFINISHCOMPACT:
956   case GCMARKREPORT:
957 #endif
958   {
959         msglength = 5;
960         break;
961   }
962
963 #ifdef TASK
964   case REDIRECTLOCK:
965   {
966     msglength = 6;
967     break;
968   }
969 #endif
970
971 #ifdef TASK
972   case TRANSOBJ:   // nonfixed size
973 #endif
974 #ifdef MULTICORE_GC
975   case GCLOBJINFO:
976 #endif
977   {  // nonfixed size
978         if(size > 1) {
979           msglength = msgdata[(msgdataindex+1)&(BAMBOO_MSG_BUF_MASK)];
980         } else {
981           return -1;
982         }
983         break;
984   }
985
986   default:
987   {
988     BAMBOO_DEBUGPRINT_REG(type);
989         BAMBOO_DEBUGPRINT_REG(size);
990     BAMBOO_DEBUGPRINT_REG(msgdataindex);
991         BAMBOO_DEBUGPRINT_REG(msgdatalast);
992         BAMBOO_DEBUGPRINT_REG(msgdatafull);
993     int i = 6;
994     while(i-- > 0) {
995       BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
996     }
997     BAMBOO_EXIT(0xe004);
998     break;
999   }
1000   }
1001 #ifndef CLOSE_PRINT
1002   BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
1003   BAMBOO_DEBUGPRINT(0xffff);
1004 #endif
1005   return msglength;
1006 }
1007
1008 INLINE void processmsg_transtall_I() {
1009   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1010     // non startup core can not receive stall msg
1011 #ifndef CLOSE_PRINT
1012     BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
1013 #endif
1014     BAMBOO_EXIT(0xe006);
1015   }
1016   int num_core = msgdata[msgdataindex]; //[1]
1017   MSG_INDEXINC_I();
1018   int data2 = msgdata[msgdataindex]; //[2];
1019   MSG_INDEXINC_I();
1020   int data3 = msgdata[msgdataindex]; //[3];
1021   MSG_INDEXINC_I();
1022   if(num_core < NUMCORESACTIVE) {
1023 #ifndef CLOSE_PRINT
1024     BAMBOO_DEBUGPRINT(0xe881);
1025 #endif
1026     corestatus[num_core] = 0;
1027     numsendobjs[num_core] = data2; //[2];
1028     numreceiveobjs[num_core] = data3; //[3];
1029   }
1030 }
1031
1032 INLINE void processmsg_statusconfirm_I() {
1033   if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
1034      || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
1035     // wrong core to receive such msg
1036     BAMBOO_EXIT(0xe011);
1037   } else {
1038     // send response msg
1039 #ifndef CLOSE_PRINT
1040     BAMBOO_DEBUGPRINT(0xe887);
1041 #endif
1042     // cache the msg first
1043     if(BAMBOO_CHECK_SEND_MODE()) {
1044           cache_msg_5(STARTUPCORE, STATUSREPORT,
1045                                   busystatus ? 1 : 0, BAMBOO_NUM_OF_CORE,
1046                                   self_numsendobjs, self_numreceiveobjs);
1047     } else {
1048           send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
1049                                  BAMBOO_NUM_OF_CORE, self_numsendobjs,
1050                                  self_numreceiveobjs, true);
1051     }
1052   }
1053 }
1054
1055 INLINE void processmsg_statusreport_I() {
1056   int data1 = msgdata[msgdataindex];
1057   MSG_INDEXINC_I();
1058   int data2 = msgdata[msgdataindex];
1059   MSG_INDEXINC_I();
1060   int data3 = msgdata[msgdataindex];
1061   MSG_INDEXINC_I();
1062   int data4 = msgdata[msgdataindex];
1063   MSG_INDEXINC_I();
1064   // receive a status confirm info
1065   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1066     // wrong core to receive such msg
1067 #ifndef CLOSE_PRINT
1068     BAMBOO_DEBUGPRINT_REG(data2);
1069 #endif
1070     BAMBOO_EXIT(0xe012);
1071   } else {
1072 #ifndef CLOSE_PRINT
1073     BAMBOO_DEBUGPRINT(0xe888);
1074 #endif
1075     if(waitconfirm) {
1076       numconfirm--;
1077     }
1078     corestatus[data2] = data1;
1079     numsendobjs[data2] = data3;
1080     numreceiveobjs[data2] = data4;
1081   }
1082 }
1083
1084 INLINE void processmsg_terminate_I() {
1085 #ifndef CLOSE_PRINT
1086   BAMBOO_DEBUGPRINT(0xe889);
1087 #endif
1088   disruntimedata();
1089 #ifdef MULTICORE_GC
1090 #ifdef GC_CACHE_ADAPT
1091   bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
1092 #endif // GC_CACHE_ADAPT
1093 #endif // MULTICORE_GC
1094   BAMBOO_EXIT_APP(0);
1095 }
1096
1097 INLINE void processmsg_memrequest_I() {
1098   int data1 = msgdata[msgdataindex];
1099   MSG_INDEXINC_I();
1100   int data2 = msgdata[msgdataindex];
1101   MSG_INDEXINC_I();
1102   // receive a shared memory request msg
1103   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1104     // wrong core to receive such msg
1105 #ifndef CLOSE_PRINT
1106     BAMBOO_DEBUGPRINT_REG(data2);
1107 #endif
1108     BAMBOO_EXIT(0xe013);
1109   } else {
1110 #ifndef CLOSE_PRINT
1111     BAMBOO_DEBUGPRINT(0xe88a);
1112 #endif
1113     int allocsize = 0;
1114     void * mem = NULL;
1115 #ifdef MULTICORE_GC
1116     if(gcprocessing) {
1117       // is currently doing gc, dump this msg
1118       if(INITPHASE == gcphase) {
1119                 // if still in the initphase of gc, send a startinit msg again,
1120                 // cache the msg first
1121                 if(BAMBOO_CHECK_SEND_MODE()) {
1122                   cache_msg_1(data2, GCSTARTINIT);
1123                 } else {
1124                   send_msg_1(data2, GCSTARTINIT, true);
1125                 }
1126       }
1127     } else {
1128 #endif
1129     mem = smemalloc_I(data2, data1, &allocsize);
1130     if(mem != NULL) {
1131       // send the start_va to request core, cache the msg first
1132       if(BAMBOO_CHECK_SEND_MODE()) {
1133                 cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
1134       } else {
1135                 send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
1136           }
1137     } //else 
1138           // if mem == NULL, the gcflag of the startup core has been set
1139           // and all the other cores have been informed to start gc
1140 #ifdef MULTICORE_GC
1141   }
1142 #endif
1143   }
1144 }
1145
1146 INLINE void processmsg_memresponse_I() {
1147   int data1 = msgdata[msgdataindex];
1148   MSG_INDEXINC_I();
1149   int data2 = msgdata[msgdataindex];
1150   MSG_INDEXINC_I();
1151   // receive a shared memory response msg
1152 #ifndef CLOSE_PRINT
1153   BAMBOO_DEBUGPRINT(0xe88b);
1154 #endif
1155 #ifdef MULTICORE_GC
1156   // if is currently doing gc, dump this msg
1157   if(!gcprocessing) {
1158 #endif
1159   if(data2 == 0) {
1160     bamboo_smem_size = 0;
1161     bamboo_cur_msp = 0;
1162 #ifdef MULTICORE_GC
1163         bamboo_smem_zero_top = 0;
1164 #endif
1165   } else {
1166 #ifdef MULTICORE_GC
1167     // fill header to store the size of this mem block
1168     BAMBOO_MEMSET_WH(data1, '\0', BAMBOO_CACHE_LINE_SIZE); 
1169     (*((int*)data1)) = data2;
1170     bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
1171     bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
1172         bamboo_smem_zero_top = bamboo_cur_msp;
1173 #else
1174     bamboo_smem_size = data2;
1175     bamboo_cur_msp =(void*)(data1);
1176 #endif
1177   }
1178   smemflag = true;
1179 #ifdef MULTICORE_GC
1180 }
1181 #endif
1182 }
1183
1184 #ifdef MULTICORE_GC
1185 INLINE void processmsg_gcstartpre_I() {
1186   if(gcprocessing) {
1187         // already stall for gc
1188         // send a update pregc information msg to the master core
1189         if(BAMBOO_CHECK_SEND_MODE()) {
1190           cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE, 
1191                   self_numsendobjs, self_numreceiveobjs);
1192         } else {
1193           send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE, 
1194                   self_numsendobjs, self_numreceiveobjs, true);
1195         }
1196   } else {
1197         // the first time to be informed to start gc
1198         gcflag = true;
1199         if(!smemflag) {
1200           // is waiting for response of mem request
1201           // let it return NULL and start gc
1202           bamboo_smem_size = 0;
1203           bamboo_cur_msp = NULL;
1204           smemflag = true;
1205           bamboo_smem_zero_top = NULL;
1206         }
1207   }
1208 }
1209
1210 INLINE void processmsg_gcstartinit_I() {
1211   gcphase = INITPHASE;
1212 }
1213
1214 INLINE void processmsg_gcstart_I() {
1215 #ifndef CLOSE_PRINT
1216   BAMBOO_DEBUGPRINT(0xe88c);
1217 #endif
1218   // set the GC flag
1219   gcphase = MARKPHASE;
1220 }
1221
1222 INLINE void processmsg_gcstartcompact_I() {
1223   gcblock2fill = msgdata[msgdataindex];
1224   MSG_INDEXINC_I();  //msgdata[1];
1225   gcphase = COMPACTPHASE;
1226 }
1227
1228 INLINE void processmsg_gcstartmapinfo_I() {
1229   gcphase = MAPPHASE;
1230 }
1231
1232 INLINE void processmsg_gcstartflush_I() {
1233   gcphase = FLUSHPHASE;
1234 }
1235
1236 INLINE void processmsg_gcfinishpre_I() {
1237   int data1 = msgdata[msgdataindex];
1238   MSG_INDEXINC_I();
1239   int data2 = msgdata[msgdataindex];
1240   MSG_INDEXINC_I();
1241   int data3 = msgdata[msgdataindex];
1242   MSG_INDEXINC_I();
1243   // received a init phase finish msg
1244   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1245     // non startup core can not receive this msg
1246 #ifndef CLOSE_PRINT
1247     BAMBOO_DEBUGPRINT_REG(data1);
1248 #endif
1249     BAMBOO_EXIT(0xe014);
1250   }
1251   // All cores should do init GC
1252   if(!gcprecheck) {
1253         gcprecheck = true;
1254   }
1255   gccorestatus[data1] = 0;
1256   gcnumsendobjs[0][data1] = data2;
1257   gcnumreceiveobjs[0][data1] = data3;
1258 }
1259
1260 INLINE void processmsg_gcfinishinit_I() {
1261   int data1 = msgdata[msgdataindex];
1262   MSG_INDEXINC_I();
1263   // received a init phase finish msg
1264   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1265     // non startup core can not receive this msg
1266 #ifndef CLOSE_PRINT
1267     BAMBOO_DEBUGPRINT_REG(data1);
1268 #endif
1269     BAMBOO_EXIT(0xe015);
1270   }
1271 #ifndef CLOSE_PRINT
1272   BAMBOO_DEBUGPRINT(0xe88c);
1273   BAMBOO_DEBUGPRINT_REG(data1);
1274 #endif
1275   // All cores should do init GC
1276   if(data1 < NUMCORESACTIVE) {
1277     gccorestatus[data1] = 0;
1278   }
1279 }
1280
1281 INLINE void processmsg_gcfinishmark_I() {
1282   int data1 = msgdata[msgdataindex];
1283   MSG_INDEXINC_I();
1284   int data2 = msgdata[msgdataindex];
1285   MSG_INDEXINC_I();
1286   int data3 = msgdata[msgdataindex];
1287   MSG_INDEXINC_I();
1288   // received a mark phase finish msg
1289   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1290     // non startup core can not receive this msg
1291 #ifndef CLOSE_PRINT
1292     BAMBOO_DEBUGPRINT_REG(data1);
1293 #endif
1294     BAMBOO_EXIT(0xe016);
1295   }
1296   // all cores should do mark
1297   if(data1 < NUMCORESACTIVE) {
1298     gccorestatus[data1] = 0;
1299         int entry_index = 0;
1300         if(waitconfirm)  {
1301           // phase 2
1302           entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
1303         } else {
1304           // phase 1
1305           entry_index = gcnumsrobjs_index;
1306         }
1307     gcnumsendobjs[entry_index][data1] = data2;
1308     gcnumreceiveobjs[entry_index][data1] = data3;
1309   }
1310 }
1311
1312 INLINE void processmsg_gcfinishcompact_I() {
1313   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1314     // non startup core can not receive this msg
1315     // return -1
1316 #ifndef CLOSE_PRINT
1317     BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
1318 #endif
1319     BAMBOO_EXIT(0xe017);
1320   }
1321   int cnum = msgdata[msgdataindex];
1322   MSG_INDEXINC_I();       //msgdata[1];
1323   int filledblocks = msgdata[msgdataindex];
1324   MSG_INDEXINC_I();       //msgdata[2];
1325   int heaptop = msgdata[msgdataindex];
1326   MSG_INDEXINC_I();       //msgdata[3];
1327   int data4 = msgdata[msgdataindex];
1328   MSG_INDEXINC_I();       //msgdata[4];
1329   // only gc cores need to do compact
1330   if(cnum < NUMCORES4GC) {
1331     if(COMPACTPHASE == gcphase) {
1332       gcfilledblocks[cnum] = filledblocks;
1333       gcloads[cnum] = heaptop;
1334     }
1335     if(data4 > 0) {
1336       // ask for more mem
1337       int startaddr = 0;
1338       int tomove = 0;
1339       int dstcore = 0;
1340       if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
1341                 // cache the msg first
1342                 if(BAMBOO_CHECK_SEND_MODE()) {
1343                   cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
1344                 } else {
1345                   send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
1346                 }
1347       }
1348     } else {
1349       gccorestatus[cnum] = 0;
1350     }  // if(data4>0)
1351   }  // if(cnum < NUMCORES4GC)
1352 }
1353
1354 INLINE void processmsg_gcfinishmapinfo_I() {
1355   int data1 = msgdata[msgdataindex];
1356   MSG_INDEXINC_I();
1357   // received a map phase finish msg
1358   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1359     // non startup core can not receive this msg
1360 #ifndef CLOSE_PRINT
1361     BAMBOO_DEBUGPRINT_REG(data1);
1362 #endif
1363     BAMBOO_EXIT(0xe018);
1364   }
1365   // all cores should do flush
1366   if(data1 < NUMCORES4GC) {
1367     gccorestatus[data1] = 0;
1368   }
1369 }
1370
1371
1372 INLINE void processmsg_gcfinishflush_I() {
1373   int data1 = msgdata[msgdataindex];
1374   MSG_INDEXINC_I();
1375   // received a flush phase finish msg
1376   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1377     // non startup core can not receive this msg
1378 #ifndef CLOSE_PRINT
1379     BAMBOO_DEBUGPRINT_REG(data1);
1380 #endif
1381     BAMBOO_EXIT(0xe019);
1382   }
1383   // all cores should do flush
1384   if(data1 < NUMCORESACTIVE) {
1385     gccorestatus[data1] = 0;
1386   }
1387 }
1388
1389 INLINE void processmsg_gcmarkconfirm_I() {
1390   if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
1391      || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
1392     // wrong core to receive such msg
1393     BAMBOO_EXIT(0xe01a);
1394   } else {
1395     // send response msg, cahce the msg first
1396     if(BAMBOO_CHECK_SEND_MODE()) {
1397           cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
1398                                   gcbusystatus, gcself_numsendobjs,
1399                                   gcself_numreceiveobjs);
1400     } else {
1401           send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
1402                                  gcbusystatus, gcself_numsendobjs,
1403                                  gcself_numreceiveobjs, true);
1404     }
1405   }
1406 }
1407
1408 INLINE void processmsg_gcmarkreport_I() {
1409   int data1 = msgdata[msgdataindex];
1410   MSG_INDEXINC_I();
1411   int data2 = msgdata[msgdataindex];
1412   MSG_INDEXINC_I();
1413   int data3 = msgdata[msgdataindex];
1414   MSG_INDEXINC_I();
1415   int data4 = msgdata[msgdataindex];
1416   MSG_INDEXINC_I();
1417   // received a marked phase finish confirm response msg
1418   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1419     // wrong core to receive such msg
1420 #ifndef CLOSE_PRINT
1421     BAMBOO_DEBUGPRINT_REG(data2);
1422 #endif
1423     BAMBOO_EXIT(0xe01b);
1424   } else {
1425         int entry_index = 0;
1426     if(waitconfirm) {
1427           // phse 2
1428       numconfirm--;
1429           entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
1430     } else {
1431           // can never reach here
1432           // phase 1
1433           entry_index = gcnumsrobjs_index;
1434         }
1435     gccorestatus[data1] = data2;
1436     gcnumsendobjs[entry_index][data1] = data3;
1437     gcnumreceiveobjs[entry_index][data1] = data4;
1438   }
1439 }
1440
1441 INLINE void processmsg_gcmarkedobj_I() {
1442   int data1 = msgdata[msgdataindex];
1443   MSG_INDEXINC_I();
1444   // received a markedObj msg
1445   if(((int *)data1)[BAMBOOMARKBIT] == INIT) {
1446     // this is the first time that this object is discovered,
1447     // set the flag as DISCOVERED
1448     ((int *)data1)[BAMBOOMARKBIT] = DISCOVERED;
1449     gc_enqueue_I(data1);
1450   } 
1451   // set the remote flag
1452   ((int *)data1)[BAMBOOMARKBIT] |= REMOTEM;
1453   gcself_numreceiveobjs++;
1454   gcbusystatus = true;
1455 }
1456
1457 INLINE void processmsg_gcmovestart_I() {
1458   gctomove = true;
1459   gcdstcore = msgdata[msgdataindex];
1460   MSG_INDEXINC_I();       //msgdata[1];
1461   gcmovestartaddr = msgdata[msgdataindex];
1462   MSG_INDEXINC_I();       //msgdata[2];
1463   gcblock2fill = msgdata[msgdataindex];
1464   MSG_INDEXINC_I();       //msgdata[3];
1465 }
1466
1467 INLINE void processmsg_gcmaprequest_I() {
1468   void * dstptr = NULL;
1469   int data1 = msgdata[msgdataindex];
1470   MSG_INDEXINC_I();
1471   int data2 = msgdata[msgdataindex];
1472   MSG_INDEXINC_I();
1473 #ifdef LOCALHASHTBL_TEST
1474   RuntimeHashget(gcpointertbl, data1, &dstptr);
1475 #else
1476   dstptr = mgchashSearch(gcpointertbl, data1);
1477 #endif
1478   if(NULL == dstptr) {
1479     // no such pointer in this core, something is wrong
1480 #ifndef CLOSE_PRINT
1481     BAMBOO_DEBUGPRINT_REG(data1);
1482     BAMBOO_DEBUGPRINT_REG(data2);
1483 #endif
1484     BAMBOO_EXIT(0xe01c);
1485   } else {
1486     // send back the mapping info, cache the msg first
1487     if(BAMBOO_CHECK_SEND_MODE()) {
1488           cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
1489     } else {
1490           send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
1491     }
1492   }
1493 }
1494
1495 INLINE void processmsg_gcmapinfo_I() {
1496   int data1 = msgdata[msgdataindex];
1497   MSG_INDEXINC_I();
1498   gcmappedobj = msgdata[msgdataindex];  // [2]
1499   MSG_INDEXINC_I();
1500 #ifdef LOCALHASHTBL_TEST
1501   RuntimeHashadd_I(gcpointertbl, data1, gcmappedobj);
1502 #else
1503   mgchashInsert_I(gcpointertbl, data1, gcmappedobj);
1504 #endif
1505   if(data1 == gcobj2map) {
1506         gcismapped = true;
1507   }
1508 }
1509
1510 INLINE void processmsg_gcmaptbl_I() {
1511   int data1 = msgdata[msgdataindex];
1512   MSG_INDEXINC_I();
1513   int data2 = msgdata[msgdataindex];
1514   MSG_INDEXINC_I();
1515   gcrpointertbls[data2] = (mgcsharedhashtbl_t *)data1; 
1516 }
1517
1518 INLINE void processmsg_gclobjinfo_I() {
1519   numconfirm--;
1520
1521   int data1 = msgdata[msgdataindex];
1522   MSG_INDEXINC_I();
1523   int data2 = msgdata[msgdataindex];
1524   MSG_INDEXINC_I();
1525   if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
1526 #ifndef CLOSE_PRINT
1527     BAMBOO_DEBUGPRINT_REG(data2);
1528 #endif
1529     BAMBOO_EXIT(0xe01d);
1530   }
1531   // store the mark result info
1532   int cnum = data2;
1533   gcloads[cnum] = msgdata[msgdataindex];
1534   MSG_INDEXINC_I();       // msgdata[3];
1535   int data4 = msgdata[msgdataindex];
1536   MSG_INDEXINC_I();
1537   if(gcheaptop < data4) {
1538     gcheaptop = data4;
1539   }
1540   // large obj info here
1541   for(int k = 5; k < data1; k+=2) {
1542     int lobj = msgdata[msgdataindex];
1543     MSG_INDEXINC_I();   //msgdata[k++];
1544     int length = msgdata[msgdataindex];
1545     MSG_INDEXINC_I();   //msgdata[k++];
1546     gc_lobjenqueue_I(lobj, length, cnum);
1547     gcnumlobjs++;
1548   }  // for(int k = 5; k < msgdata[1];)
1549 }
1550
1551 INLINE void processmsg_gclobjmapping_I() {
1552   int data1 = msgdata[msgdataindex];
1553   MSG_INDEXINC_I();
1554   int data2 = msgdata[msgdataindex];
1555   MSG_INDEXINC_I();
1556 #ifdef LOCALHASHTBL_TEST
1557   RuntimeHashadd_I(gcpointertbl, data1, data2);
1558 #else
1559   mgchashInsert_I(gcpointertbl, data1, data2);
1560 #endif
1561   mgcsharedhashInsert_I(gcsharedptbl, data1, data2);
1562 }
1563
1564 #ifdef GC_PROFILE
1565 INLINE void processmsg_gcprofiles_I() {
1566   int data1 = msgdata[msgdataindex];
1567   MSG_INDEXINC_I();
1568   int data2 = msgdata[msgdataindex];
1569   MSG_INDEXINC_I();
1570   int data3 = msgdata[msgdataindex];
1571   MSG_INDEXINC_I();
1572   gc_num_obj += data1;
1573   gc_num_liveobj += data2;
1574   gc_num_forwardobj += data3;
1575   gc_num_profiles--;
1576 }
1577 #endif // GC_PROFILE
1578
1579 #ifdef GC_CACHE_ADAPT
1580 INLINE void processmsg_gcstartpref_I() {
1581   gcphase = PREFINISHPHASE;
1582 }
1583
1584 INLINE void processmsg_gcfinishpref_I() {
1585   int data1 = msgdata[msgdataindex];
1586   MSG_INDEXINC_I();
1587   // received a flush phase finish msg
1588   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1589     // non startup core can not receive this msg
1590 #ifndef CLOSE_PRINT
1591     BAMBOO_DEBUGPRINT_REG(data1);
1592 #endif
1593     BAMBOO_EXIT(0xe01e);
1594   }
1595   // all cores should do flush
1596   if(data1 < NUMCORESACTIVE) {
1597     gccorestatus[data1] = 0;
1598   }
1599 }
1600 #endif // GC_CACHE_ADAPT
1601 #endif // #ifdef MULTICORE_GC
1602
1603 // receive object transferred from other cores
1604 // or the terminate message from other cores
1605 // Should be invoked in critical sections!!
1606 // NOTICE: following format is for threadsimulate version only
1607 //         RAW version please see previous description
1608 // format: type + object
1609 // type: -1--stall msg
1610 //      !-1--object
1611 // return value: 0--received an object
1612 //               1--received nothing
1613 //               2--received a Stall Msg
1614 //               3--received a lock Msg
1615 //               RAW version: -1 -- received nothing
1616 //                            otherwise -- received msg type
1617 int receiveObject(int send_port_pending) {
1618 #ifdef TASK
1619 #ifdef PROFILE_INTERRUPT
1620   if(!interruptInfoOverflow) {
1621     InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
1622     interruptInfoArray[interruptInfoIndex] = intInfo;
1623     intInfo->startTime = BAMBOO_GET_EXE_TIME();
1624     intInfo->endTime = -1;
1625   }
1626 #endif // PROFILE_INTERRUPT
1627 #endif // TASK
1628 msg:
1629   // get the incoming msgs
1630   if(receiveMsg(send_port_pending) == -1) {
1631     return -1;
1632   }
1633 processmsg:
1634   // processing received msgs
1635   int size = 0;
1636   MSG_REMAINSIZE_I(&size);
1637   if((size == 0) || (checkMsgLength_I(size) == -1)) {
1638     // not a whole msg
1639     // have new coming msg
1640     if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
1641       goto msg;
1642     } else {
1643       return -1;
1644     }
1645   }
1646
1647   if(msglength <= size) {
1648     // have some whole msg
1649     MSGTYPE type;
1650     type = msgdata[msgdataindex]; //[0]
1651     MSG_INDEXINC_I();
1652     msgdatafull = false;
1653     switch(type) {
1654 #ifdef TASK
1655     case TRANSOBJ: {
1656       // receive a object transfer msg
1657       processmsg_transobj_I();
1658       break;
1659     }   // case TRANSOBJ
1660 #endif // TASK
1661
1662     case TRANSTALL: {
1663       // receive a stall msg
1664       processmsg_transtall_I();
1665       break;
1666     }   // case TRANSTALL
1667
1668 #ifdef TASK
1669 // GC version have no lock msgs
1670 #ifndef MULTICORE_GC
1671     case LOCKREQUEST: {
1672       // receive lock request msg, handle it right now
1673       processmsg_lockrequest_I();
1674       break;
1675     }   // case LOCKREQUEST
1676
1677     case LOCKGROUNT: {
1678       // receive lock grount msg
1679       processmsg_lockgrount_I();
1680       break;
1681     }   // case LOCKGROUNT
1682
1683     case LOCKDENY: {
1684       // receive lock deny msg
1685       processmsg_lockdeny_I();
1686       break;
1687     }   // case LOCKDENY
1688
1689     case LOCKRELEASE: {
1690       processmsg_lockrelease_I();
1691       break;
1692     }   // case LOCKRELEASE
1693 #endif // #ifndef MULTICORE_GC
1694
1695 #ifdef PROFILE
1696     case PROFILEOUTPUT: {
1697       // receive an output profile data request msg
1698       processmsg_profileoutput_I();
1699       break;
1700     }   // case PROFILEOUTPUT
1701
1702     case PROFILEFINISH: {
1703       // receive a profile output finish msg
1704       processmsg_profilefinish_I();
1705       break;
1706     }   // case PROFILEFINISH
1707 #endif // #ifdef PROFILE
1708
1709 // GC version has no lock msgs
1710 #ifndef MULTICORE_GC
1711     case REDIRECTLOCK: {
1712       // receive a redirect lock request msg, handle it right now
1713       processmsg_redirectlock_I();
1714       break;
1715     }   // case REDIRECTLOCK
1716
1717     case REDIRECTGROUNT: {
1718       // receive a lock grant msg with redirect info
1719       processmsg_redirectgrount_I();
1720       break;
1721     }   // case REDIRECTGROUNT
1722
1723     case REDIRECTDENY: {
1724       // receive a lock deny msg with redirect info
1725       processmsg_redirectdeny_I();
1726       break;
1727     }   // case REDIRECTDENY
1728
1729     case REDIRECTRELEASE: {
1730       // receive a lock release msg with redirect info
1731       processmsg_redirectrelease_I();
1732       break;
1733     }   // case REDIRECTRELEASE
1734 #endif // #ifndef MULTICORE_GC
1735 #endif // TASK
1736
1737     case STATUSCONFIRM: {
1738       // receive a status confirm info
1739       processmsg_statusconfirm_I();
1740       break;
1741     }   // case STATUSCONFIRM
1742
1743     case STATUSREPORT: {
1744       processmsg_statusreport_I();
1745       break;
1746     }   // case STATUSREPORT
1747
1748     case TERMINATE: {
1749       // receive a terminate msg
1750       processmsg_terminate_I();
1751       break;
1752     }   // case TERMINATE
1753
1754     case MEMREQUEST: {
1755       processmsg_memrequest_I();
1756       break;
1757     }   // case MEMREQUEST
1758
1759     case MEMRESPONSE: {
1760       processmsg_memresponse_I();
1761       break;
1762     }   // case MEMRESPONSE
1763
1764 #ifdef MULTICORE_GC
1765     // GC msgs
1766     case GCSTARTPRE: {
1767       processmsg_gcstartpre_I();
1768       break;
1769     }   // case GCSTARTPRE
1770         
1771         case GCSTARTINIT: {
1772       processmsg_gcstartinit_I();
1773       break;
1774     }   // case GCSTARTINIT
1775
1776     case GCSTART: {
1777       // receive a start GC msg
1778       processmsg_gcstart_I();
1779       break;
1780     }   // case GCSTART
1781
1782     case GCSTARTCOMPACT: {
1783       // a compact phase start msg
1784       processmsg_gcstartcompact_I();
1785       break;
1786     }   // case GCSTARTCOMPACT
1787
1788         case GCSTARTMAPINFO: {
1789       // received a flush phase start msg
1790       processmsg_gcstartmapinfo_I();
1791       break;
1792     }   // case GCSTARTFLUSH
1793
1794     case GCSTARTFLUSH: {
1795       // received a flush phase start msg
1796       processmsg_gcstartflush_I();
1797       break;
1798     }   // case GCSTARTFLUSH
1799
1800     case GCFINISHPRE: {
1801       processmsg_gcfinishpre_I();
1802       break;
1803     }   // case GCFINISHPRE
1804         
1805         case GCFINISHINIT: {
1806       processmsg_gcfinishinit_I();
1807       break;
1808     }   // case GCFINISHINIT
1809
1810     case GCFINISHMARK: {
1811       processmsg_gcfinishmark_I();
1812       break;
1813     }   // case GCFINISHMARK
1814
1815     case GCFINISHCOMPACT: {
1816       // received a compact phase finish msg
1817       processmsg_gcfinishcompact_I();
1818       break;
1819     }   // case GCFINISHCOMPACT
1820
1821         case GCFINISHMAPINFO: {
1822       processmsg_gcfinishmapinfo_I();
1823       break;
1824     }   // case GCFINISHMAPINFO
1825
1826     case GCFINISHFLUSH: {
1827       processmsg_gcfinishflush_I();
1828       break;
1829     }   // case GCFINISHFLUSH
1830
1831     case GCFINISH: {
1832       // received a GC finish msg
1833       gcphase = FINISHPHASE;
1834       break;
1835     }   // case GCFINISH
1836
1837     case GCMARKCONFIRM: {
1838       // received a marked phase finish confirm request msg
1839       // all cores should do mark
1840       processmsg_gcmarkconfirm_I();
1841       break;
1842     }   // case GCMARKCONFIRM
1843
1844     case GCMARKREPORT: {
1845       processmsg_gcmarkreport_I();
1846       break;
1847     }   // case GCMARKREPORT
1848
1849     case GCMARKEDOBJ: {
1850       processmsg_gcmarkedobj_I();
1851       break;
1852     }   // case GCMARKEDOBJ
1853
1854     case GCMOVESTART: {
1855       // received a start moving objs msg
1856       processmsg_gcmovestart_I();
1857       break;
1858     }   // case GCMOVESTART
1859
1860     case GCMAPREQUEST: {
1861       // received a mapping info request msg
1862       processmsg_gcmaprequest_I();
1863       break;
1864     }   // case GCMAPREQUEST
1865
1866     case GCMAPINFO: {
1867       // received a mapping info response msg
1868       processmsg_gcmapinfo_I();
1869       break;
1870     }   // case GCMAPINFO
1871
1872     case GCMAPTBL: {
1873       // received a mapping tbl response msg
1874       processmsg_gcmaptbl_I();
1875       break;
1876     }   // case GCMAPTBL
1877         
1878         case GCLOBJREQUEST: {
1879       // received a large objs info request msg
1880       transferMarkResults_I();
1881       break;
1882     }   // case GCLOBJREQUEST
1883
1884     case GCLOBJINFO: {
1885       // received a large objs info response msg
1886       processmsg_gclobjinfo_I();
1887       break;
1888     }   // case GCLOBJINFO
1889
1890     case GCLOBJMAPPING: {
1891       // received a large obj mapping info msg
1892       processmsg_gclobjmapping_I();
1893       break;
1894     }  // case GCLOBJMAPPING
1895
1896 #ifdef GC_PROFILE
1897         case GCPROFILES: {
1898       // received a gcprofiles msg
1899       processmsg_gcprofiles_I();
1900       break;
1901     }
1902 #endif // GC_PROFILE
1903
1904 #ifdef GC_CACHE_ADAPT
1905         case GCSTARTPREF: {
1906       // received a gcstartpref msg
1907       processmsg_gcstartpref_I();
1908       break;
1909     }
1910
1911         case GCFINISHPREF: {
1912       // received a gcfinishpref msg
1913       processmsg_gcfinishpref_I();
1914       break;
1915     }
1916 #endif // GC_CACHE_ADAPT
1917 #endif // #ifdef MULTICORE_GC
1918
1919     default:
1920       break;
1921     }  // switch(type)
1922     msglength = BAMBOO_MSG_BUF_LENGTH;
1923
1924     if((msgdataindex != msgdatalast) || (msgdatafull)) {
1925       // still have available msg
1926       goto processmsg;
1927     }
1928 #ifndef CLOSE_PRINT
1929     BAMBOO_DEBUGPRINT(0xe88d);
1930 #endif
1931
1932     // have new coming msg
1933     if(BAMBOO_MSG_AVAIL() != 0) {
1934       goto msg;
1935     } // TODO
1936
1937 #ifdef TASK
1938 #ifdef PROFILE_INTERRUPT
1939   if(!interruptInfoOverflow) {
1940     interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
1941     interruptInfoIndex++;
1942     if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
1943       interruptInfoOverflow = true;
1944     }
1945   }
1946 #endif
1947 #endif // TASK
1948     return (int)type;
1949   } else {
1950     // not a whole msg
1951 #ifndef CLOSE_PRINT
1952     BAMBOO_DEBUGPRINT(0xe88e);
1953 #endif
1954     return -2;
1955   }
1956 }
1957
1958 #endif // MULTICORE