3 #include "multicoreruntime.h"
4 #include "methodheaders.h"
5 #include "multicoregarbage.h"
7 #include "multicoregcprofile.h"
8 #include "multicoregc.h"
9 #include "pmc_garbage.h"
11 #include "multicore_arch.h"
14 #include "bme_perf_counter.h"
17 extern int classsize[];
18 extern int typearray[];
19 extern int typearray2[];
20 extern int* supertypes[];
23 extern struct genhashtable * activetasks;
30 int instanceofif(int otype, int type) {
37 int num = supertypes[otype][0];
38 for(int i = 1; i < num + 1; i++) {
39 int t = supertypes[otype][i];
40 if(instanceofif(t, type) == 1) {
47 int instanceof(struct ___Object___ *ptr, int type) {
52 if(instanceofif(i, type) == 1) {
59 i=typearray2[i-NUMCLASSES];
65 void initializeexithandler() {
68 /* This function inject failures */
69 void injectinstructionfailure() {
70 // not supported in MULTICORE version
74 #ifdef D___Double______nativeparsedouble____L___String___
75 double CALL01(___Double______nativeparsedouble____L___String___,
76 struct ___String___ * ___str___) {
77 int length=VAR(___str___)->___count___;
78 int maxlength=(length>60) ? 60 : length;
79 char str[maxlength+1];
80 struct ArrayObject * chararray=VAR(___str___)->___value___;
82 int offset=VAR(___str___)->___offset___;
83 for(i=0; i<maxlength; i++) {
85 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
88 double d=0.0; //atof(str); TODO Unimplemented nativeparsedoulbe
93 #ifdef D___Double______nativeparsedouble_____AR_B_I_I
94 double CALL23(___Double______nativeparsedouble_____AR_B_I_I,
99 struct ArrayObject * ___str___) {
100 int maxlength=(length>60)?60:length;
101 char str[maxlength+1];
102 struct ArrayObject * bytearray=VAR(___str___);
104 for(i=0; i<maxlength; i++) {
105 str[i]=(((char *)&bytearray->___length___)+sizeof(int))[i+start];
108 double d=0.0; //atof(str); TODO Unimplemented nativeparsedouble
113 typedef union jvalue {
123 #ifdef D___Double______doubleToRawLongBits____D
124 long long CALL11(___Double______doubleToRawLongBits____D,
126 double ___value___) {
130 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
131 /* On little endian ARM processors when using FPA, word order of
132 doubles is still big endian. So take that into account here. When
133 using VFP, word order of doubles follows byte order. */
134 #define SWAP_DOUBLE(a) (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
135 val.j = SWAP_DOUBLE(val.j);
142 #ifdef D___Double______longBitsToDouble____J
143 double CALL11(___Double______longBitsToDouble____J,
144 long long ___bits___,
145 long long ___bits___) {
149 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
151 #define SWAP_DOUBLE(a) (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
153 val.j = SWAP_DOUBLE(val.j);
160 #ifdef D___String______convertdoubletochar____D__AR_C
161 int CALL12(___String______convertdoubletochar____D__AR_C,
164 struct ArrayObject * ___chararray___) {
165 int length=VAR(___chararray___)->___length___;
168 int num=snprintf(str, length, "%f",___val___);
171 for(i=0; i<length; i++) {
172 ((short *)(((char *)&VAR(___chararray___)->___length___)+sizeof(int)))[i]=
179 #ifdef D___System______deepArrayCopy____L___Object____L___Object___
180 void deepArrayCopy(struct ___Object___ * dst,
181 struct ___Object___ * src) {
182 int dsttype=((int *)dst)[0];
183 int srctype=((int *)src)[0];
184 if (dsttype<NUMCLASSES||srctype<NUMCLASSES||srctype!=dsttype)
186 struct ArrayObject *aodst=(struct ArrayObject *)dst;
187 struct ArrayObject *aosrc=(struct ArrayObject *)src;
188 int dstlength=aodst->___length___;
189 int srclength=aosrc->___length___;
190 if (dstlength!=srclength)
192 unsigned INTPTR *pointer=pointerarray[srctype];
194 int elementsize=classsize[srctype];
195 int size=srclength*elementsize;
197 memcpy(((char *)&aodst->___length___)+sizeof(int) ,
198 ((char *)&aosrc->___length___)+sizeof(int), size);
202 for(i=0;i<srclength;i++) {
203 struct ___Object___ * ptr=
204 ((struct ___Object___**)(((char*)&aosrc->___length___)+sizeof(int)))[i];
205 int ptrtype=((int *)ptr)[0];
206 if (ptrtype>=NUMCLASSES) {
207 struct ___Object___ * dstptr=((struct ___Object___**)
208 (((char*)&aodst->___length___)+sizeof(int)))[i];
209 deepArrayCopy(dstptr,ptr);
212 ((struct ___Object___ **)
213 (((char*) &aodst->___length___)+sizeof(int)))[i]=ptr;
219 void CALL02(___System______deepArrayCopy____L___Object____L___Object___,
220 struct ___Object___ * ___dst___,
221 struct ___Object___ * ___src___) {
222 deepArrayCopy(VAR(___dst___), VAR(___src___));
226 #ifdef D___System______arraycopy____L___Object____I_L___Object____I_I
227 void arraycopy(struct ___Object___ *src,
229 struct ___Object___ *dst,
232 int dsttype=((int *)dst)[0];
233 int srctype=((int *)src)[0];
235 //not an array or type mismatch
236 if (dsttype<NUMCLASSES||srctype<NUMCLASSES/*||srctype!=dsttype*/)
239 struct ArrayObject *aodst=(struct ArrayObject *)dst;
240 struct ArrayObject *aosrc=(struct ArrayObject *)src;
241 int dstlength=aodst->___length___;
242 int srclength=aosrc->___length___;
246 if (srcPos+length>srclength)
248 if (destPos+length>dstlength)
251 unsigned INTPTR *pointer=pointerarray[srctype];
253 int elementsize=classsize[srctype];
254 int size=length*elementsize;
256 memcpy(((char *)&aodst->___length___)+sizeof(int)+destPos*elementsize,
257 ((char *)&aosrc->___length___)+sizeof(int)+srcPos*elementsize, size);
261 for(i=0;i<length;i++) {
262 struct ___Object___ * ptr=((struct ___Object___**)
263 (((char*)&aosrc->___length___)+sizeof(int)))[i+srcPos];
264 int ptrtype=((int *)ptr)[0];
266 ((struct ___Object___ **)
267 (((char*) &aodst->___length___)+sizeof(int)))[i+destPos]=ptr;
272 void CALL35(___System______arraycopy____L___Object____I_L___Object____I_I,
276 struct ___Object___ * ___src___,
278 struct ___Object___ * ___dst___,
281 arraycopy(VAR(___src___), ___srcPos___, VAR(___dst___), ___destPos___,
286 #ifdef D___System______exit____I
287 void CALL11(___System______exit____I,
290 // gc_profile mode, output gc prfiling data
291 #if defined(MULTICORE_GC)||defined(PMC_GC)
292 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
293 BAMBOO_PRINT(BAMBOO_GET_EXE_TIME());
294 BAMBOO_PRINT(0xbbbbbbbb);
295 CACHEADAPT_DISABLE_TIMER();
296 GC_OUTPUT_PROFILE_DATA();
300 gc_outputProfileDataReadable();
303 BAMBOO_EXIT_APP(___status___);
307 #ifdef D___Vector______removeElement_____AR_L___Object____I_I
308 void CALL23(___Vector______removeElement_____AR_L___Object____I_I,
311 struct ArrayObject * ___array___,
314 char* offset=((char *)(&VAR(___array___)->___length___))
315 +sizeof(unsigned int)+sizeof(void *)*___index___;
316 memmove(offset, offset+sizeof(void *),
317 (___size___-___index___-1)*sizeof(void *));
321 #ifdef D___System______printI____I
322 void CALL11(___System______printI____I,
325 BAMBOO_PRINT(0x1111);
326 BAMBOO_PRINT_REG(___status___);
330 #ifdef D___System______currentTimeMillis____
331 long long CALL00(___System______currentTimeMillis____) {
332 //TilePro64 is 700mHz
333 return ((unsigned long long)BAMBOO_GET_EXE_TIME())/700000;
337 #ifdef D___System______setgcprofileflag____
338 void CALL00(___System______setgcprofileflag____) {
341 extern volatile bool gc_profile_flag;
342 gc_profile_flag = true;
348 #ifdef D___System______resetgcprofileflag____
349 void CALL00(___System______resetgcprofileflag____) {
352 extern volatile bool gc_profile_flag;
353 gc_profile_flag = false;
359 #ifdef D___System______gc____
360 void CALL00(___System______gc____) {
362 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
363 if(!gc_status_info.gcprocessing && !gcflag) {
366 for(int i = 0; i < NUMCORESACTIVE; i++) {
367 // reuse the gcnumsendobjs & gcnumreceiveobjs
368 gcnumsendobjs[0][i] = 0;
369 gcnumreceiveobjs[0][i] = 0;
371 for(int i = 0; i < NUMCORES4GC; i++) {
372 if(i != STARTUPCORE) {
373 send_msg_1_I(i,GCSTARTPRE);
378 // send msg to the startup core to start gc
379 send_msg_1(STARTUPCORE, GCINVOKE);
385 #ifdef D___System______printString____L___String___
386 void CALL01(___System______printString____L___String___, struct ___String___ * ___s___) {
387 #if defined(MGC)&&defined(TILERA_BME)
388 struct ArrayObject * chararray=VAR(___s___)->___value___;
390 int offset=VAR(___s___)->___offset___;
392 for(i=0; i<VAR(___s___)->___count___; i++) {
394 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
401 /* Object allocation function */
403 #if defined(MULTICORE_GC)||defined(PMC_GC)
404 void * allocate_new(void * ptr,
406 struct ___Object___ * v=
407 (struct ___Object___*)FREEMALLOC((struct garbagelist*) ptr,classsize[type]);
416 extern unsigned int gc_num_obj;
422 /* Array allocation function */
424 struct ArrayObject * allocate_newarray(void * ptr,
427 struct ArrayObject * v=(struct ArrayObject *)FREEMALLOC(
428 (struct garbagelist*)ptr,
429 sizeof(struct ArrayObject)+length*classsize[type]);
438 v->___length___=length;
439 initlock((struct ___Object___ *)v);
441 extern unsigned int gc_num_obj;
448 void * allocate_new(int type) {
449 struct ___Object___ * v=FREEMALLOC(classsize[type]);
459 /* Array allocation function */
461 struct ArrayObject * allocate_newarray(int type,
463 struct ArrayObject * v=FREEMALLOC(
464 sizeof(struct ArrayObject)+length*classsize[type]);
470 v->___length___=length;
471 initlock((struct ___Object___ *) v);
476 /* Converts C character arrays into Java strings */
477 #if defined(MULTICORE_GC)||defined(PMC_GC)
478 __attribute__((malloc)) struct ___String___ * NewStringShort(void * ptr,
482 __attribute__((malloc)) struct ___String___ * NewStringShort(const short *str,
486 #if defined(MULTICORE_GC)||defined(PMC_GC)
487 struct ArrayObject * chararray=
488 allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
489 INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
490 struct ___String___ * strobj=
491 allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
492 chararray=(struct ArrayObject *) ptrarray[2];
494 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
495 struct ___String___ * strobj=allocate_new(STRINGTYPE);
497 strobj->___value___=chararray;
498 strobj->___count___=length;
499 strobj->___offset___=0;
501 for(i=0; i<length; i++) {
502 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=str[i];
507 /* Converts C character arrays into Java strings */
508 #if defined(MULTICORE_GC)||defined(PMC_GC)
509 struct ___String___ * NewString(void * ptr,
513 struct ___String___ * NewString(const char *str,
517 #if defined(MULTICORE_GC)||defined(PMC_GC)
518 struct ArrayObject * chararray=
519 allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
520 int ptrarray[]={1, (int) ptr, (int) chararray};
521 struct ___String___ * strobj=
522 allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
523 chararray=(struct ArrayObject *) ptrarray[2];
525 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
526 struct ___String___ * strobj=allocate_new(STRINGTYPE);
528 strobj->___value___=chararray;
529 strobj->___count___=length;
530 strobj->___offset___=0;
532 for(i=0; i<length; i++) {
533 ((short*)(((char*)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
538 /* Generated code calls this if we fail a bounds check */
540 void failedboundschk(int num, int index, struct ArrayObject * ao) {
542 printf("Array out of bounds at line %u with index %u of object %x with lengt\
543 h %u\n", num, index, ao, ao->___length___);
553 printf("Array out of bounds\n");
554 longjmp(error_handler,2);
561 /* Generated code calls this if we fail null ptr chk */
562 void failednullptr(void * ptr) {
563 #if defined(MULTICORE_GC)||defined(PMC_GC)
565 //print out current stack
568 struct garbagelist * stackptr = (struct garbagelist *)ptr;
569 while(stackptr!=NULL) {
570 tprintf("Stack %d: \n\t", j);
571 for(i=0; i<stackptr->size; i++) {
572 if(stackptr->array[i] != NULL) {
573 tprintf("%x, ", stackptr->array[i]);
579 stackptr=stackptr->next;
584 printf("NULL ptr\n");
594 printf("NULL ptr\n");
595 longjmp(error_handler,2);
602 /* Abort task call */
606 printf("Aborting\n");
607 longjmp(error_handler,4);
610 printf("Aborting\n");
615 void initruntimedata() {
616 // initialize the arrays
617 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
618 // startup core to initialize corestatus[]
619 for(int i = 0; i < NUMCORESACTIVE; ++i) {
622 numreceiveobjs[i] = 0;
629 self_numsendobjs = 0;
630 self_numreceiveobjs = 0;
632 for(int i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
637 //msglength = BAMBOO_MSG_BUF_LENGTH;
639 for(int i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
645 isMsgHanging = false;
648 bamboo_cur_msp = NULL;
649 bamboo_smem_size = 0;
654 INITMULTICOREGCDATA();
658 bamboo_current_thread = NULL;
664 void disruntimedata() {
665 DISMULTICOREGCDATA();
667 BAMBOO_LOCAL_MEM_CLOSE();
668 BAMBOO_SHARE_MEM_CLOSE();
671 void recordtotalexetime() {
673 totalexetime = BAMBOO_GET_EXE_TIME()-bamboo_start_time;
675 unsigned long long timediff=BAMBOO_GET_EXE_TIME()-bamboo_start_time;
676 BAMBOO_PRINT(timediff);
677 #ifndef BAMBOO_MEMPROF
678 BAMBOO_PRINT(0xbbbbbbbb);
683 void getprofiledata_I() {
684 //profile mode, send msgs to other cores to request pouring out progiling data
686 // use numconfirm to check if all cores have finished output task profiling
687 // information. This is safe as when the execution reaches this phase there
688 // should have no other msgs except the PROFILEFINISH msg, there should be
690 numconfirm=NUMCORESACTIVE-1;
691 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
692 for(i = 1; i < NUMCORESACTIVE; ++i) {
693 // send profile request msg to core i
694 send_msg_2(i, PROFILEOUTPUT, totalexetime);
697 // pour profiling data on startup core
701 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
702 if(numconfirm != 0) {
704 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
708 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
715 void checkCoreStatus() {
719 (waitconfirm && (numconfirm == 0))) {
720 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
721 corestatus[BAMBOO_NUM_OF_CORE] = 0;
722 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
723 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
724 // check the status of all cores
725 for(i = 0; i < NUMCORESACTIVE; ++i) {
726 if(corestatus[i] != 0) {
730 if(i == NUMCORESACTIVE) {
731 // check if the sum of send objs and receive obj are the same
732 // yes->check if the info is the latest; no->go on executing
734 for(i = 0; i < NUMCORESACTIVE; ++i) {
735 sumsendobj += numsendobjs[i];
737 for(i = 0; i < NUMCORESACTIVE; ++i) {
738 sumsendobj -= numreceiveobjs[i];
740 if(0 == sumsendobj) {
742 // the first time found all cores stall
743 // send out status confirm msg to all other cores
744 // reset the corestatus array too
745 corestatus[BAMBOO_NUM_OF_CORE] = 1;
747 numconfirm = NUMCORESACTIVE - 1;
748 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
749 for(i = 1; i < NUMCORESACTIVE; ++i) {
751 // send status confirm msg to core i
752 send_msg_1(i, STATUSCONFIRM);
756 // all the core status info are the latest
757 // terminate; for profiling mode, send request to all
758 // other cores to pour out profiling data
759 recordtotalexetime();
761 CACHEADAPT_DISABLE_TIMER();
762 GC_OUTPUT_PROFILE_DATA();
766 gc_outputProfileDataReadable();
768 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
769 terminate(); // All done.
772 // still some objects on the fly on the network
773 // reset the waitconfirm and numconfirm
778 // not all cores are stall, keep on waiting
782 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
786 // main function for each core
787 void run(int argc, char** argv) {
788 bool sendStall = false;
790 bool tocontinue = false;
792 corenum = BAMBOO_GET_NUM_OF_CORE();
793 // initialize runtime data structures
800 if (BAMBOO_NUM_OF_CORE==STARTUPCORE)
801 profile_init(_LOCAL_DRD_CNT,_LOCAL_WR_CNT, _REMOTE_DRD_CNT, _REMOTE_WR_CNT);
803 int offcore=4*(BAMBOO_NUM_OF_CORE-1);
804 profile_init(validevents[(offcore)%87], validevents[(offcore+1)%87], validevents[(offcore+2)%87], validevents[(offcore+3)%87]);
807 if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
808 numconfirm=NUMCORES-1;
809 for(int i=0;i<NUMCORES;i++) {
810 if (i!=STARTUPCORE) {
811 send_msg_1(i,REQNOTIFYSTART);
816 tprintf("START_EXECUTION\n");
817 bamboo_start_time = BAMBOO_GET_EXE_TIME();
823 bme_performance_counter_start();
826 CACHEADAPT_ENABLE_TIMER();
828 initializeexithandler();
830 // main process of the execution module
831 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
833 // non-executing cores, only processing communications
839 /* Create queue of active tasks */
840 activetasks= genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
841 (int (*)(void *,void *)) &comparetpd);
843 /* Process task information */
846 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
847 /* Create startup object */
848 createstartupobject(argc, argv);
853 profile_start(APP_REGION);
855 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
857 // run the initStaticAndGlobal method to initialize the static blocks and
859 initStaticAndGlobal();
861 // run the main method in the specified mainclass
862 mgc_main(argc, argv);
869 // check if there are new active tasks can be executed
875 while(receiveObject_I() != -1) {
878 // check if there are some pending objects,
879 // if yes, enqueue them and executetasks again
880 tocontinue = checkObjQueue();
882 tocontinue = trystartthread();
890 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
901 // wait for some time
907 // send StallMsg to startup core
909 send_msg_4(STARTUPCORE,TRANSTALL,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);