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 extern int classsize[];
21 extern int typearray[];
22 extern int typearray2[];
23 extern int* supertypes[];
26 extern struct genhashtable * activetasks;
33 int instanceofif(int otype, int type) {
40 int num = supertypes[otype][0];
41 for(int i = 1; i < num + 1; i++) {
42 int t = supertypes[otype][i];
43 if(instanceofif(t, type) == 1) {
50 int instanceof(struct ___Object___ *ptr, int type) {
55 if(instanceofif(i, type) == 1) {
62 i=typearray2[i-NUMCLASSES];
68 void initializeexithandler() {
71 /* This function inject failures */
72 void injectinstructionfailure() {
73 // not supported in MULTICORE version
77 #ifdef D___Double______nativeparsedouble____L___String___
78 double CALL01(___Double______nativeparsedouble____L___String___,
79 struct ___String___ * ___str___) {
80 int length=VAR(___str___)->___count___;
81 int maxlength=(length>60) ? 60 : length;
82 char str[maxlength+1];
83 struct ArrayObject * chararray=VAR(___str___)->___value___;
85 int offset=VAR(___str___)->___offset___;
86 for(i=0; i<maxlength; i++) {
88 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
91 double d=0.0; //atof(str); TODO Unimplemented nativeparsedoulbe
96 #ifdef D___Double______nativeparsedouble_____AR_B_I_I
97 double CALL23(___Double______nativeparsedouble_____AR_B_I_I,
102 struct ArrayObject * ___str___) {
103 int maxlength=(length>60)?60:length;
104 char str[maxlength+1];
105 struct ArrayObject * bytearray=VAR(___str___);
107 for(i=0; i<maxlength; i++) {
108 str[i]=(((char *)&bytearray->___length___)+sizeof(int))[i+start];
111 double d=0.0; //atof(str); TODO Unimplemented nativeparsedouble
116 typedef union jvalue {
126 #ifdef D___Double______doubleToRawLongBits____D
127 long long CALL11(___Double______doubleToRawLongBits____D,
129 double ___value___) {
133 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
134 /* On little endian ARM processors when using FPA, word order of
135 doubles is still big endian. So take that into account here. When
136 using VFP, word order of doubles follows byte order. */
137 #define SWAP_DOUBLE(a) (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
138 val.j = SWAP_DOUBLE(val.j);
145 #ifdef D___Double______longBitsToDouble____J
146 double CALL11(___Double______longBitsToDouble____J,
147 long long ___bits___,
148 long long ___bits___) {
152 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
154 #define SWAP_DOUBLE(a) (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
156 val.j = SWAP_DOUBLE(val.j);
163 #ifdef D___String______convertdoubletochar____D__AR_C
164 int CALL12(___String______convertdoubletochar____D__AR_C,
167 struct ArrayObject * ___chararray___) {
168 int length=VAR(___chararray___)->___length___;
171 int num=snprintf(str, length, "%f",___val___);
174 for(i=0; i<length; i++) {
175 ((short *)(((char *)&VAR(___chararray___)->___length___)+sizeof(int)))[i]=
182 #ifdef D___System______deepArrayCopy____L___Object____L___Object___
183 void deepArrayCopy(struct ___Object___ * dst,
184 struct ___Object___ * src) {
185 int dsttype=((int *)dst)[0];
186 int srctype=((int *)src)[0];
187 if (dsttype<NUMCLASSES||srctype<NUMCLASSES||srctype!=dsttype)
189 struct ArrayObject *aodst=(struct ArrayObject *)dst;
190 struct ArrayObject *aosrc=(struct ArrayObject *)src;
191 int dstlength=aodst->___length___;
192 int srclength=aosrc->___length___;
193 if (dstlength!=srclength)
195 unsigned INTPTR *pointer=pointerarray[srctype];
197 int elementsize=classsize[srctype];
198 int size=srclength*elementsize;
200 memcpy(((char *)&aodst->___length___)+sizeof(int) ,
201 ((char *)&aosrc->___length___)+sizeof(int), size);
205 for(i=0;i<srclength;i++) {
206 struct ___Object___ * ptr=
207 ((struct ___Object___**)(((char*)&aosrc->___length___)+sizeof(int)))[i];
208 int ptrtype=((int *)ptr)[0];
209 if (ptrtype>=NUMCLASSES) {
210 struct ___Object___ * dstptr=((struct ___Object___**)
211 (((char*)&aodst->___length___)+sizeof(int)))[i];
212 deepArrayCopy(dstptr,ptr);
215 ((struct ___Object___ **)
216 (((char*) &aodst->___length___)+sizeof(int)))[i]=ptr;
222 void CALL02(___System______deepArrayCopy____L___Object____L___Object___,
223 struct ___Object___ * ___dst___,
224 struct ___Object___ * ___src___) {
225 deepArrayCopy(VAR(___dst___), VAR(___src___));
229 #ifdef D___System______arraycopy____L___Object____I_L___Object____I_I
230 void arraycopy(struct ___Object___ *src,
232 struct ___Object___ *dst,
235 int dsttype=((int *)dst)[0];
236 int srctype=((int *)src)[0];
238 //not an array or type mismatch
239 if (dsttype<NUMCLASSES||srctype<NUMCLASSES/*||srctype!=dsttype*/)
242 struct ArrayObject *aodst=(struct ArrayObject *)dst;
243 struct ArrayObject *aosrc=(struct ArrayObject *)src;
244 int dstlength=aodst->___length___;
245 int srclength=aosrc->___length___;
249 if (srcPos+length>srclength)
251 if (destPos+length>dstlength)
254 unsigned INTPTR *pointer=pointerarray[srctype];
256 int elementsize=classsize[srctype];
257 int size=length*elementsize;
259 memcpy(((char *)&aodst->___length___)+sizeof(int)+destPos*elementsize,
260 ((char *)&aosrc->___length___)+sizeof(int)+srcPos*elementsize, size);
264 for(i=0;i<length;i++) {
265 struct ___Object___ * ptr=((struct ___Object___**)
266 (((char*)&aosrc->___length___)+sizeof(int)))[i+srcPos];
267 int ptrtype=((int *)ptr)[0];
269 ((struct ___Object___ **)
270 (((char*) &aodst->___length___)+sizeof(int)))[i+destPos]=ptr;
275 void CALL35(___System______arraycopy____L___Object____I_L___Object____I_I,
279 struct ___Object___ * ___src___,
281 struct ___Object___ * ___dst___,
284 arraycopy(VAR(___src___), ___srcPos___, VAR(___dst___), ___destPos___,
289 #ifdef D___System______exit____I
290 void CALL11(___System______exit____I,
293 // gc_profile mode, output gc prfiling data
294 #if defined(MULTICORE_GC)||defined(PMC_GC)
295 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
296 BAMBOO_PRINT(BAMBOO_GET_EXE_TIME());
297 BAMBOO_PRINT(0xbbbbbbbb);
298 CACHEADAPT_DISABLE_TIMER();
299 GC_OUTPUT_PROFILE_DATA();
303 gc_outputProfileDataReadable();
304 tprintf("FINISH_EXECUTION\n");
307 BAMBOO_EXIT_APP(___status___);
311 #ifdef D___Vector______removeElement_____AR_L___Object____I_I
312 void CALL23(___Vector______removeElement_____AR_L___Object____I_I,
315 struct ArrayObject * ___array___,
318 char* offset=((char *)(&VAR(___array___)->___length___))
319 +sizeof(unsigned int)+sizeof(void *)*___index___;
320 memmove(offset, offset+sizeof(void *),
321 (___size___-___index___-1)*sizeof(void *));
325 #ifdef D___System______printI____I
326 void CALL11(___System______printI____I,
329 BAMBOO_PRINT(0x1111);
330 BAMBOO_PRINT_REG(___status___);
334 #ifdef D___System______currentTimeMillis____
335 long long CALL00(___System______currentTimeMillis____) {
336 //TilePro64 is 700mHz
337 return ((unsigned long long)BAMBOO_GET_EXE_TIME())/700000;
341 #ifdef D___System______numGCs____
342 long long ___System______numGCs____(struct ___System______numGCs_____params * ___params___) {
351 #ifdef D___System______milliGcTime____
352 long long ___System______milliGcTime____(struct ___System______milliGcTime_____params * ___params___) {
354 return GCtime/700000;
361 #ifdef D___System______nanoTime____
362 long long CALL00(___System______nanoTime____) {
363 //TilePro64 is 700mHz
364 return ((unsigned long long)BAMBOO_GET_EXE_TIME())/700;
368 #ifdef D___System______setgcprofileflag____
369 void CALL00(___System______setgcprofileflag____) {
372 extern volatile bool gc_profile_flag;
373 gc_profile_flag = true;
379 #ifdef D___System______resetgcprofileflag____
380 void CALL00(___System______resetgcprofileflag____) {
383 extern volatile bool gc_profile_flag;
384 gc_profile_flag = false;
390 #ifdef D___System______gc____
391 void CALL00(___System______gc____) {
393 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
394 if(!gc_status_info.gcprocessing && !gcflag) {
397 for(int i = 0; i < NUMCORESACTIVE; i++) {
398 // reuse the gcnumsendobjs & gcnumreceiveobjs
399 gcnumsendobjs[0][i] = 0;
400 gcnumreceiveobjs[0][i] = 0;
402 for(int i = 0; i < NUMCORES4GC; i++) {
403 if(i != STARTUPCORE) {
404 send_msg_1(i,GCSTARTPRE);
409 // send msg to the startup core to start gc
410 send_msg_1(STARTUPCORE, GCINVOKE);
416 #ifdef D___System______printString____L___String___
417 void CALL01(___System______printString____L___String___, struct ___String___ * ___s___) {
418 #if defined(MGC)&&defined(TILERA_BME)
419 struct ArrayObject * chararray=VAR(___s___)->___value___;
421 int offset=VAR(___s___)->___offset___;
423 for(i=0; i<VAR(___s___)->___count___; i++) {
425 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
432 #ifdef D___Scanner______nextDouble____
433 double ___Scanner______nextDouble____(struct ___Scanner______nextDouble_____params * ___params___) {
439 #ifdef D___Scanner______nextInt____
440 int ___Scanner______nextInt____(struct ___Scanner______nextInt_____params * ___params___) {
446 /* Object allocation function */
448 #if defined(MULTICORE_GC)||defined(PMC_GC)
449 void * allocate_new(void * ptr,
451 struct ___Object___ * v=
452 (struct ___Object___*)FREEMALLOC((struct garbagelist*) ptr,classsize[type]);
463 /* Array allocation function */
465 struct ArrayObject * allocate_newarray(void * ptr,
468 struct ArrayObject * v=(struct ArrayObject *)FREEMALLOC(
469 (struct garbagelist*)ptr,
470 sizeof(struct ArrayObject)+length*classsize[type]);
479 v->___length___=length;
480 initlock((struct ___Object___ *)v);
485 void * allocate_new(int type) {
486 struct ___Object___ * v=FREEMALLOC(classsize[type]);
496 /* Array allocation function */
498 struct ArrayObject * allocate_newarray(int type,
500 struct ArrayObject * v=FREEMALLOC(
501 sizeof(struct ArrayObject)+length*classsize[type]);
507 v->___length___=length;
508 initlock((struct ___Object___ *) v);
513 /* Converts C character arrays into Java strings */
514 #if defined(MULTICORE_GC)||defined(PMC_GC)
515 __attribute__((malloc)) struct ___String___ * NewStringShort(void * ptr,
519 __attribute__((malloc)) struct ___String___ * NewStringShort(const short *str,
523 #if defined(MULTICORE_GC)||defined(PMC_GC)
524 struct ArrayObject * chararray=
525 allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
526 INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
527 struct ___String___ * strobj=
528 allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
529 chararray=(struct ArrayObject *) ptrarray[2];
531 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
532 struct ___String___ * strobj=allocate_new(STRINGTYPE);
534 strobj->___value___=chararray;
535 strobj->___count___=length;
536 strobj->___offset___=0;
538 for(i=0; i<length; i++) {
539 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=str[i];
544 /* Converts C character arrays into Java strings */
545 #if defined(MULTICORE_GC)||defined(PMC_GC)
546 struct ___String___ * NewString(void * ptr,
550 struct ___String___ * NewString(const char *str,
554 #if defined(MULTICORE_GC)||defined(PMC_GC)
555 struct ArrayObject * chararray=
556 allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
557 int ptrarray[]={1, (int) ptr, (int) chararray};
558 struct ___String___ * strobj=
559 allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
560 chararray=(struct ArrayObject *) ptrarray[2];
562 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
563 struct ___String___ * strobj=allocate_new(STRINGTYPE);
565 strobj->___value___=chararray;
566 strobj->___count___=length;
567 strobj->___offset___=0;
569 for(i=0; i<length; i++) {
570 ((short*)(((char*)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
575 /* Generated code calls this if we fail a bounds check */
577 void failedboundschk(int num, int index, struct ArrayObject * ao) {
579 printf("Array out of bounds at line %u with index %u of object %x with lengt\
580 h %u\n", num, index, ao, ao->___length___);
590 printf("Array out of bounds\n");
591 longjmp(error_handler,2);
598 /* Generated code calls this if we fail null ptr chk */
599 void failednullptr(void * ptr) {
600 #if defined(MULTICORE_GC)||defined(PMC_GC)
602 //print out current stack
605 struct garbagelist * stackptr = (struct garbagelist *)ptr;
606 while(stackptr!=NULL) {
607 tprintf("Stack %d: \n\t", j);
608 for(i=0; i<stackptr->size; i++) {
609 if(stackptr->array[i] != NULL) {
610 tprintf("%x, ", stackptr->array[i]);
616 stackptr=stackptr->next;
621 printf("NULL ptr\n");
631 printf("NULL ptr\n");
632 longjmp(error_handler,2);
639 /* Abort task call */
643 printf("Aborting\n");
644 longjmp(error_handler,4);
647 printf("Aborting\n");
652 void initruntimedata() {
653 // initialize the arrays
654 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
655 // startup core to initialize corestatus[]
656 for(int i = 0; i < NUMCORESACTIVE; ++i) {
659 numreceiveobjs[i] = 0;
666 self_numsendobjs = 0;
667 self_numreceiveobjs = 0;
669 for(int i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
674 //msglength = BAMBOO_MSG_BUF_LENGTH;
676 for(int i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
682 isMsgHanging = false;
685 bamboo_cur_msp = NULL;
686 bamboo_smem_size = 0;
691 INITMULTICOREGCDATA();
695 bamboo_current_thread = NULL;
701 void disruntimedata() {
702 DISMULTICOREGCDATA();
704 BAMBOO_LOCAL_MEM_CLOSE();
705 BAMBOO_SHARE_MEM_CLOSE();
708 void recordtotalexetime() {
710 totalexetime = BAMBOO_GET_EXE_TIME()-bamboo_start_time;
712 unsigned long long timediff=BAMBOO_GET_EXE_TIME()-bamboo_start_time;
713 BAMBOO_PRINT(timediff);
714 #ifndef BAMBOO_MEMPROF
715 BAMBOO_PRINT(0xbbbbbbbb);
720 void getprofiledata_I() {
721 //profile mode, send msgs to other cores to request pouring out progiling data
723 // use numconfirm to check if all cores have finished output task profiling
724 // information. This is safe as when the execution reaches this phase there
725 // should have no other msgs except the PROFILEFINISH msg, there should be
727 numconfirm=NUMCORESACTIVE-1;
728 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
729 for(i = 1; i < NUMCORESACTIVE; ++i) {
730 // send profile request msg to core i
731 send_msg_2(i, PROFILEOUTPUT, totalexetime);
734 // pour profiling data on startup core
738 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
739 if(numconfirm != 0) {
741 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
745 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
752 void checkCoreStatus() {
756 (waitconfirm && (numconfirm == 0))) {
757 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
758 corestatus[BAMBOO_NUM_OF_CORE] = 0;
759 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
760 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
761 // check the status of all cores
762 for(i = 0; i < NUMCORESACTIVE; ++i) {
763 if(corestatus[i] != 0) {
767 if(i == NUMCORESACTIVE) {
768 // check if the sum of send objs and receive obj are the same
769 // yes->check if the info is the latest; no->go on executing
771 for(i = 0; i < NUMCORESACTIVE; ++i) {
772 sumsendobj += numsendobjs[i];
774 for(i = 0; i < NUMCORESACTIVE; ++i) {
775 sumsendobj -= numreceiveobjs[i];
777 if(0 == sumsendobj) {
779 // the first time found all cores stall
780 // send out status confirm msg to all other cores
781 // reset the corestatus array too
782 corestatus[BAMBOO_NUM_OF_CORE] = 1;
784 numconfirm = NUMCORESACTIVE - 1;
785 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
786 for(i = 1; i < NUMCORESACTIVE; ++i) {
788 // send status confirm msg to core i
789 send_msg_1(i, STATUSCONFIRM);
793 // all the core status info are the latest
794 // terminate; for profiling mode, send request to all
795 // other cores to pour out profiling data
796 recordtotalexetime();
798 CACHEADAPT_DISABLE_TIMER();
799 GC_OUTPUT_PROFILE_DATA();
803 gc_outputProfileDataReadable();
805 tprintf("FINISH_EXECUTION\n");
806 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
807 terminate(); // All done.
810 // still some objects on the fly on the network
811 // reset the waitconfirm and numconfirm
816 // not all cores are stall, keep on waiting
820 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
824 // main function for each core
825 void run(int argc, char** argv) {
826 bool sendStall = false;
828 bool tocontinue = false;
830 corenum = BAMBOO_GET_NUM_OF_CORE();
831 // initialize runtime data structures
838 if (BAMBOO_NUM_OF_CORE==STARTUPCORE)
839 profile_init(_LOCAL_DRD_CNT,_LOCAL_WR_CNT, _REMOTE_DRD_CNT, _REMOTE_WR_CNT);
841 int offcore=4*(BAMBOO_NUM_OF_CORE-1);
842 profile_init(validevents[(offcore)%87], validevents[(offcore+1)%87], validevents[(offcore+2)%87], validevents[(offcore+3)%87]);
845 if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
846 numconfirm=NUMCORES-1;
847 for(int i=0;i<NUMCORES;i++) {
848 if (i!=STARTUPCORE) {
849 send_msg_1(i,REQNOTIFYSTART);
854 tprintf("START_EXECUTION\n");
855 bamboo_start_time = BAMBOO_GET_EXE_TIME();
861 bme_performance_counter_start();
864 CACHEADAPT_ENABLE_TIMER();
866 initializeexithandler();
868 // main process of the execution module
869 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
871 // non-executing cores, only processing communications
877 /* Create queue of active tasks */
878 activetasks= genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
879 (int (*)(void *,void *)) &comparetpd);
881 /* Process task information */
884 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
885 /* Create startup object */
886 createstartupobject(argc, argv);
891 profile_start(APP_REGION);
893 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
895 // run the initStaticAndGlobal method to initialize the static blocks and
897 initStaticAndGlobal();
899 // run the main method in the specified mainclass
900 mgc_main(argc, argv);
907 // check if there are new active tasks can be executed
913 while(receiveObject_I() != -1) {
916 // check if there are some pending objects,
917 // if yes, enqueue them and executetasks again
918 tocontinue = checkObjQueue();
920 tocontinue = trystartthread();
928 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
939 // wait for some time
945 // send StallMsg to startup core
947 send_msg_4(STARTUPCORE,TRANSTALL,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);