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"
20 #include "InputFileArrays.h"
24 extern int classsize[];
25 extern int typearray[];
26 extern int typearray2[];
27 extern int* supertypes[];
30 extern struct genhashtable * activetasks;
37 int instanceofif(int otype, int type) {
44 int num = supertypes[otype][0];
45 for(int i = 1; i < num + 1; i++) {
46 int t = supertypes[otype][i];
47 if(instanceofif(t, type) == 1) {
54 int instanceof(struct ___Object___ *ptr, int type) {
59 if(instanceofif(i, type) == 1) {
66 i=typearray2[i-NUMCLASSES];
72 void initializeexithandler() {
75 /* This function inject failures */
76 void injectinstructionfailure() {
77 // not supported in MULTICORE version
81 #ifdef D___Double______nativeparsedouble____L___String___
82 double CALL01(___Double______nativeparsedouble____L___String___,
83 struct ___String___ * ___str___) {
84 int length=VAR(___str___)->___count___;
85 int maxlength=(length>60) ? 60 : length;
86 char str[maxlength+1];
87 struct ArrayObject * chararray=VAR(___str___)->___value___;
89 int offset=VAR(___str___)->___offset___;
90 for(i=0; i<maxlength; i++) {
92 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
95 double d=0.0; //atof(str); TODO Unimplemented nativeparsedoulbe
100 #ifdef D___Double______nativeparsedouble_____AR_B_I_I
101 double CALL23(___Double______nativeparsedouble_____AR_B_I_I,
106 struct ArrayObject * ___str___) {
107 int maxlength=(length>60)?60:length;
108 char str[maxlength+1];
109 struct ArrayObject * bytearray=VAR(___str___);
111 for(i=0; i<maxlength; i++) {
112 str[i]=(((char *)&bytearray->___length___)+sizeof(int))[i+start];
115 double d=0.0; //atof(str); TODO Unimplemented nativeparsedouble
120 typedef union jvalue {
130 #ifdef D___Double______doubleToRawLongBits____D
131 long long CALL11(___Double______doubleToRawLongBits____D,
133 double ___value___) {
137 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
138 /* On little endian ARM processors when using FPA, word order of
139 doubles is still big endian. So take that into account here. When
140 using VFP, word order of doubles follows byte order. */
141 #define SWAP_DOUBLE(a) (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
142 val.j = SWAP_DOUBLE(val.j);
149 #ifdef D___Double______longBitsToDouble____J
150 double CALL11(___Double______longBitsToDouble____J,
151 long long ___bits___,
152 long long ___bits___) {
156 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
158 #define SWAP_DOUBLE(a) (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
160 val.j = SWAP_DOUBLE(val.j);
167 #ifdef D___String______convertdoubletochar____D__AR_C
168 int CALL12(___String______convertdoubletochar____D__AR_C,
171 struct ArrayObject * ___chararray___) {
172 int length=VAR(___chararray___)->___length___;
175 int num=snprintf(str, length, "%f",___val___);
178 for(i=0; i<length; i++) {
179 ((short *)(((char *)&VAR(___chararray___)->___length___)+sizeof(int)))[i]=
186 #ifdef D___System______deepArrayCopy____L___Object____L___Object___
187 void deepArrayCopy(struct ___Object___ * dst,
188 struct ___Object___ * src) {
189 int dsttype=((int *)dst)[0];
190 int srctype=((int *)src)[0];
191 if (dsttype<NUMCLASSES||srctype<NUMCLASSES||srctype!=dsttype)
193 struct ArrayObject *aodst=(struct ArrayObject *)dst;
194 struct ArrayObject *aosrc=(struct ArrayObject *)src;
195 int dstlength=aodst->___length___;
196 int srclength=aosrc->___length___;
197 if (dstlength!=srclength)
199 unsigned INTPTR *pointer=pointerarray[srctype];
201 int elementsize=classsize[srctype];
202 int size=srclength*elementsize;
204 memcpy(((char *)&aodst->___length___)+sizeof(int) ,
205 ((char *)&aosrc->___length___)+sizeof(int), size);
209 for(i=0;i<srclength;i++) {
210 struct ___Object___ * ptr=
211 ((struct ___Object___**)(((char*)&aosrc->___length___)+sizeof(int)))[i];
212 int ptrtype=((int *)ptr)[0];
213 if (ptrtype>=NUMCLASSES) {
214 struct ___Object___ * dstptr=((struct ___Object___**)
215 (((char*)&aodst->___length___)+sizeof(int)))[i];
216 deepArrayCopy(dstptr,ptr);
219 ((struct ___Object___ **)
220 (((char*) &aodst->___length___)+sizeof(int)))[i]=ptr;
226 void CALL02(___System______deepArrayCopy____L___Object____L___Object___,
227 struct ___Object___ * ___dst___,
228 struct ___Object___ * ___src___) {
229 deepArrayCopy(VAR(___dst___), VAR(___src___));
233 #ifdef D___System______arraycopy____L___Object____I_L___Object____I_I
234 void arraycopy(struct ___Object___ *src,
236 struct ___Object___ *dst,
239 int dsttype=((int *)dst)[0];
240 int srctype=((int *)src)[0];
242 //not an array or type mismatch
243 if (dsttype<NUMCLASSES||srctype<NUMCLASSES/*||srctype!=dsttype*/)
246 struct ArrayObject *aodst=(struct ArrayObject *)dst;
247 struct ArrayObject *aosrc=(struct ArrayObject *)src;
248 int dstlength=aodst->___length___;
249 int srclength=aosrc->___length___;
253 if (srcPos+length>srclength)
255 if (destPos+length>dstlength)
258 unsigned INTPTR *pointer=pointerarray[srctype];
260 int elementsize=classsize[srctype];
261 int size=length*elementsize;
263 memcpy(((char *)&aodst->___length___)+sizeof(int)+destPos*elementsize,
264 ((char *)&aosrc->___length___)+sizeof(int)+srcPos*elementsize, size);
268 for(i=0;i<length;i++) {
269 struct ___Object___ * ptr=((struct ___Object___**)
270 (((char*)&aosrc->___length___)+sizeof(int)))[i+srcPos];
271 int ptrtype=((int *)ptr)[0];
273 ((struct ___Object___ **)
274 (((char*) &aodst->___length___)+sizeof(int)))[i+destPos]=ptr;
279 void CALL35(___System______arraycopy____L___Object____I_L___Object____I_I,
283 struct ___Object___ * ___src___,
285 struct ___Object___ * ___dst___,
288 arraycopy(VAR(___src___), ___srcPos___, VAR(___dst___), ___destPos___,
293 #ifdef D___System______exit____I
294 void CALL11(___System______exit____I,
297 // gc_profile mode, output gc prfiling data
298 #if defined(MULTICORE_GC)||defined(PMC_GC)
299 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
300 BAMBOO_PRINT(BAMBOO_GET_EXE_TIME());
301 BAMBOO_PRINT(0xbbbbbbbb);
302 CACHEADAPT_DISABLE_TIMER();
303 GC_OUTPUT_PROFILE_DATA();
307 gc_outputProfileDataReadable();
308 tprintf("FINISH_EXECUTION\n");
311 BAMBOO_EXIT_APP(___status___);
315 #ifdef D___Vector______removeElement_____AR_L___Object____I_I
316 void CALL23(___Vector______removeElement_____AR_L___Object____I_I,
319 struct ArrayObject * ___array___,
322 char* offset=((char *)(&VAR(___array___)->___length___))
323 +sizeof(unsigned int)+sizeof(void *)*___index___;
324 memmove(offset, offset+sizeof(void *),
325 (___size___-___index___-1)*sizeof(void *));
329 #ifdef D___System______printI____I
330 void CALL11(___System______printI____I,
333 BAMBOO_PRINT(0x1111);
334 BAMBOO_PRINT_REG(___status___);
338 #ifdef D___System______currentTimeMillis____
339 long long CALL00(___System______currentTimeMillis____) {
340 //TilePro64 is 700mHz
341 return ((unsigned long long)BAMBOO_GET_EXE_TIME())/700000;
345 #ifdef D___System______numGCs____
346 long long ___System______numGCs____(struct ___System______numGCs_____params * ___params___) {
355 #ifdef D___System______milliGcTime____
356 long long CALL00(___System______milliGcTime____) {
358 return GCtime/700000;
365 #ifdef D___System______nanoTime____
366 long long CALL00(___System______nanoTime____) {
367 //TilePro64 is 700mHz
368 return ((unsigned long long)BAMBOO_GET_EXE_TIME())/700;
372 #ifdef D___System______setgcprofileflag____
373 void CALL00(___System______setgcprofileflag____) {
376 extern volatile bool gc_profile_flag;
377 gc_profile_flag = true;
383 #ifdef D___System______resetgcprofileflag____
384 void CALL00(___System______resetgcprofileflag____) {
387 extern volatile bool gc_profile_flag;
388 gc_profile_flag = false;
394 #ifdef D___System______gc____
395 void CALL00(___System______gc____) {
397 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
398 if(!gc_status_info.gcprocessing && !gcflag) {
401 for(int i = 0; i < NUMCORESACTIVE; i++) {
402 // reuse the gcnumsendobjs & gcnumreceiveobjs
403 gcnumsendobjs[0][i] = 0;
404 gcnumreceiveobjs[0][i] = 0;
406 for(int i = 0; i < NUMCORES4GC; i++) {
407 if(i != STARTUPCORE) {
408 send_msg_1(i,GCSTARTPRE);
413 // send msg to the startup core to start gc
414 send_msg_1(STARTUPCORE, GCINVOKE);
420 #ifdef D___System______printString____L___String___
421 void CALL01(___System______printString____L___String___, struct ___String___ * ___s___) {
422 #if defined(MGC)&&defined(TILERA_BME)
423 struct ArrayObject * chararray=VAR(___s___)->___value___;
425 int offset=VAR(___s___)->___offset___;
427 for(i=0; i<VAR(___s___)->___count___; i++) {
429 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
437 #ifdef D___Scanner______nextInt____
438 int CALL01(___Scanner______nextInt____, struct ___Scanner___ * ___this___) {
439 int pos = VAR(___this___)->___currentpos___;
440 int value = nextInt(VAR(___this___)->___fd___, &pos);
441 VAR(___this___)->___currentpos___ = pos;
446 #ifdef D___Scanner______nextDouble____
447 double CALL01(___Scanner______nextDouble____, struct ___Scanner___ * ___this___) {
448 int pos = VAR(___this___)->___currentpos___;
449 double value = nextDouble(VAR(___this___)->___fd___, &pos);
450 VAR(___this___)->___currentpos___ = pos;
456 /* Object allocation function */
458 #if defined(MULTICORE_GC)||defined(PMC_GC)
459 void * allocate_new(void * ptr,
461 struct ___Object___ * v=
462 (struct ___Object___*)FREEMALLOC((struct garbagelist*) ptr,classsize[type]);
473 /* Array allocation function */
475 struct ArrayObject * allocate_newarray(void * ptr,
478 struct ArrayObject * v=(struct ArrayObject *)FREEMALLOC(
479 (struct garbagelist*)ptr,
480 sizeof(struct ArrayObject)+length*classsize[type]);
489 v->___length___=length;
490 initlock((struct ___Object___ *)v);
495 void * allocate_new(int type) {
496 struct ___Object___ * v=FREEMALLOC(classsize[type]);
506 /* Array allocation function */
508 struct ArrayObject * allocate_newarray(int type,
510 struct ArrayObject * v=FREEMALLOC(
511 sizeof(struct ArrayObject)+length*classsize[type]);
517 v->___length___=length;
518 initlock((struct ___Object___ *) v);
523 /* Converts C character arrays into Java strings */
524 #if defined(MULTICORE_GC)||defined(PMC_GC)
525 __attribute__((malloc)) struct ___String___ * NewStringShort(void * ptr,
529 __attribute__((malloc)) struct ___String___ * NewStringShort(const short *str,
533 #if defined(MULTICORE_GC)||defined(PMC_GC)
534 struct ArrayObject * chararray=
535 allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
536 INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
537 struct ___String___ * strobj=
538 allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
539 chararray=(struct ArrayObject *) ptrarray[2];
541 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
542 struct ___String___ * strobj=allocate_new(STRINGTYPE);
544 strobj->___value___=chararray;
545 strobj->___count___=length;
546 strobj->___offset___=0;
548 for(i=0; i<length; i++) {
549 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=str[i];
554 /* Converts C character arrays into Java strings */
555 #if defined(MULTICORE_GC)||defined(PMC_GC)
556 struct ___String___ * NewString(void * ptr,
560 struct ___String___ * NewString(const char *str,
564 #if defined(MULTICORE_GC)||defined(PMC_GC)
565 struct ArrayObject * chararray=
566 allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
567 int ptrarray[]={1, (int) ptr, (int) chararray};
568 struct ___String___ * strobj=
569 allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
570 chararray=(struct ArrayObject *) ptrarray[2];
572 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
573 struct ___String___ * strobj=allocate_new(STRINGTYPE);
575 strobj->___value___=chararray;
576 strobj->___count___=length;
577 strobj->___offset___=0;
579 for(i=0; i<length; i++) {
580 ((short*)(((char*)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
585 /* Generated code calls this if we fail a bounds check */
587 void failedboundschk(int num, int index, struct ArrayObject * ao) {
589 printf("Array out of bounds at line %u with index %u of object %x with lengt\
590 h %u\n", num, index, ao, ao->___length___);
600 printf("Array out of bounds\n");
601 longjmp(error_handler,2);
608 /* Generated code calls this if we fail null ptr chk */
609 void failednullptr(void * ptr) {
610 #if defined(MULTICORE_GC)||defined(PMC_GC)
612 //print out current stack
615 struct garbagelist * stackptr = (struct garbagelist *)ptr;
616 while(stackptr!=NULL) {
617 tprintf("Stack %d: \n\t", j);
618 for(i=0; i<stackptr->size; i++) {
619 if(stackptr->array[i] != NULL) {
620 tprintf("%x, ", stackptr->array[i]);
626 stackptr=stackptr->next;
631 printf("NULL ptr\n");
641 printf("NULL ptr\n");
642 longjmp(error_handler,2);
649 /* Abort task call */
653 printf("Aborting\n");
654 longjmp(error_handler,4);
657 printf("Aborting\n");
662 void initruntimedata() {
663 // initialize the arrays
664 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
665 // startup core to initialize corestatus[]
666 for(int i = 0; i < NUMCORESACTIVE; ++i) {
669 numreceiveobjs[i] = 0;
676 self_numsendobjs = 0;
677 self_numreceiveobjs = 0;
679 for(int i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
684 //msglength = BAMBOO_MSG_BUF_LENGTH;
686 for(int i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
692 isMsgHanging = false;
695 bamboo_cur_msp = NULL;
696 bamboo_smem_size = 0;
701 INITMULTICOREGCDATA();
705 bamboo_current_thread = NULL;
711 void disruntimedata() {
712 DISMULTICOREGCDATA();
714 BAMBOO_LOCAL_MEM_CLOSE();
715 BAMBOO_SHARE_MEM_CLOSE();
718 void recordtotalexetime() {
720 totalexetime = BAMBOO_GET_EXE_TIME()-bamboo_start_time;
722 unsigned long long timediff=BAMBOO_GET_EXE_TIME()-bamboo_start_time;
723 BAMBOO_PRINT(timediff);
724 #ifndef BAMBOO_MEMPROF
725 BAMBOO_PRINT(0xbbbbbbbb);
730 void getprofiledata_I() {
731 //profile mode, send msgs to other cores to request pouring out progiling data
733 // use numconfirm to check if all cores have finished output task profiling
734 // information. This is safe as when the execution reaches this phase there
735 // should have no other msgs except the PROFILEFINISH msg, there should be
737 numconfirm=NUMCORESACTIVE-1;
738 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
739 for(i = 1; i < NUMCORESACTIVE; ++i) {
740 // send profile request msg to core i
741 send_msg_2(i, PROFILEOUTPUT, totalexetime);
744 // pour profiling data on startup core
748 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
749 if(numconfirm != 0) {
751 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
755 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
762 void checkCoreStatus() {
766 (waitconfirm && (numconfirm == 0))) {
767 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
768 corestatus[BAMBOO_NUM_OF_CORE] = 0;
769 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
770 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
771 // check the status of all cores
772 for(i = 0; i < NUMCORESACTIVE; ++i) {
773 if(corestatus[i] != 0) {
777 if(i == NUMCORESACTIVE) {
778 // check if the sum of send objs and receive obj are the same
779 // yes->check if the info is the latest; no->go on executing
781 for(i = 0; i < NUMCORESACTIVE; ++i) {
782 sumsendobj += numsendobjs[i];
784 for(i = 0; i < NUMCORESACTIVE; ++i) {
785 sumsendobj -= numreceiveobjs[i];
787 if(0 == sumsendobj) {
789 // the first time found all cores stall
790 // send out status confirm msg to all other cores
791 // reset the corestatus array too
792 corestatus[BAMBOO_NUM_OF_CORE] = 1;
794 numconfirm = NUMCORESACTIVE - 1;
795 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
796 for(i = 1; i < NUMCORESACTIVE; ++i) {
798 // send status confirm msg to core i
799 send_msg_1(i, STATUSCONFIRM);
803 // all the core status info are the latest
804 // terminate; for profiling mode, send request to all
805 // other cores to pour out profiling data
806 recordtotalexetime();
808 CACHEADAPT_DISABLE_TIMER();
809 GC_OUTPUT_PROFILE_DATA();
813 gc_outputProfileDataReadable();
815 tprintf("FINISH_EXECUTION\n");
816 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
817 terminate(); // All done.
820 // still some objects on the fly on the network
821 // reset the waitconfirm and numconfirm
826 // not all cores are stall, keep on waiting
830 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
834 // main function for each core
835 void run(int argc, char** argv) {
836 bool sendStall = false;
838 bool tocontinue = false;
840 corenum = BAMBOO_GET_NUM_OF_CORE();
841 // initialize runtime data structures
848 if (BAMBOO_NUM_OF_CORE==STARTUPCORE)
849 profile_init(_LOCAL_DRD_CNT,_LOCAL_WR_CNT, _REMOTE_DRD_CNT, _REMOTE_WR_CNT);
851 int offcore=4*(BAMBOO_NUM_OF_CORE-1);
852 profile_init(validevents[(offcore)%87], validevents[(offcore+1)%87], validevents[(offcore+2)%87], validevents[(offcore+3)%87]);
855 if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
856 numconfirm=NUMCORES-1;
857 for(int i=0;i<NUMCORES;i++) {
858 if (i!=STARTUPCORE) {
859 send_msg_1(i,REQNOTIFYSTART);
864 tprintf("START_EXECUTION\n");
865 bamboo_start_time = BAMBOO_GET_EXE_TIME();
871 bme_performance_counter_start();
874 CACHEADAPT_ENABLE_TIMER();
876 initializeexithandler();
878 // main process of the execution module
879 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
881 // non-executing cores, only processing communications
887 /* Create queue of active tasks */
888 activetasks= genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
889 (int (*)(void *,void *)) &comparetpd);
891 /* Process task information */
894 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
895 /* Create startup object */
896 createstartupobject(argc, argv);
901 profile_start(APP_REGION);
903 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
905 // run the initStaticAndGlobal method to initialize the static blocks and
907 initStaticAndGlobal();
909 // run the main method in the specified mainclass
910 mgc_main(argc, argv);
917 // check if there are new active tasks can be executed
923 while(receiveObject_I() != -1) {
926 // check if there are some pending objects,
927 // if yes, enqueue them and executetasks again
928 tocontinue = checkObjQueue();
930 tocontinue = trystartthread();
938 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
949 // wait for some time
955 // send StallMsg to startup core
957 send_msg_4(STARTUPCORE,TRANSTALL,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);