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 CALL00(___System______milliGcTime____) {
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______nextInt____
433 int CALL01(___Scanner______nextInt____, struct ___Scanner___ * ___this___) {
434 int pos = VAR(___this___)->___currentpos___;
436 unsigned char * filearray = (unsigned char *)(VAR(___this___)->___filearray___);
437 while((filearray[pos]==' ')||(filearray[pos]=='\n')){
444 if (filearray[pos]=='-') {
450 unsigned char b=filearray[pos];
454 else if (b>='a'&&b<='z')
456 else if (b>='A'&&b<='Z')
463 printf("Error in Scanner.nextInt(): val >= radix");
464 value=value*radix+val;
471 VAR(___this___)->___currentpos___ = pos;
476 #ifdef D___Scanner______nextDouble____
477 double CALL01(___Scanner______nextDouble____, struct ___Scanner___ * ___this___) {
478 int pos = VAR(___this___)->___currentpos___;
480 unsigned char * filearray = (unsigned char *)(VAR(___this___)->___filearray___);
481 while((filearray[pos]==' ')||(filearray[pos]=='\n')){
488 if (filearray[pos]=='-') {
491 } else if(filearray[pos]=='+') {
497 unsigned char b=filearray[pos];
501 else if (b>='a'&&b<='z')
503 else if (b>='A'&&b<='Z')
511 value=value*radix+val;
518 VAR(___this___)->___currentpos___ = pos;
523 /* Object allocation function */
525 #if defined(MULTICORE_GC)||defined(PMC_GC)
526 void * allocate_new(void * ptr,
528 struct ___Object___ * v=
529 (struct ___Object___*)FREEMALLOC((struct garbagelist*) ptr,classsize[type]);
540 /* Array allocation function */
542 struct ArrayObject * allocate_newarray(void * ptr,
545 struct ArrayObject * v=(struct ArrayObject *)FREEMALLOC(
546 (struct garbagelist*)ptr,
547 sizeof(struct ArrayObject)+length*classsize[type]);
556 v->___length___=length;
557 initlock((struct ___Object___ *)v);
562 void * allocate_new(int type) {
563 struct ___Object___ * v=FREEMALLOC(classsize[type]);
573 /* Array allocation function */
575 struct ArrayObject * allocate_newarray(int type,
577 struct ArrayObject * v=FREEMALLOC(
578 sizeof(struct ArrayObject)+length*classsize[type]);
584 v->___length___=length;
585 initlock((struct ___Object___ *) v);
590 /* Converts C character arrays into Java strings */
591 #if defined(MULTICORE_GC)||defined(PMC_GC)
592 __attribute__((malloc)) struct ___String___ * NewStringShort(void * ptr,
596 __attribute__((malloc)) struct ___String___ * NewStringShort(const short *str,
600 #if defined(MULTICORE_GC)||defined(PMC_GC)
601 struct ArrayObject * chararray=
602 allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
603 INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
604 struct ___String___ * strobj=
605 allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
606 chararray=(struct ArrayObject *) ptrarray[2];
608 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
609 struct ___String___ * strobj=allocate_new(STRINGTYPE);
611 strobj->___value___=chararray;
612 strobj->___count___=length;
613 strobj->___offset___=0;
615 for(i=0; i<length; i++) {
616 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=str[i];
621 /* Converts C character arrays into Java strings */
622 #if defined(MULTICORE_GC)||defined(PMC_GC)
623 struct ___String___ * NewString(void * ptr,
627 struct ___String___ * NewString(const char *str,
631 #if defined(MULTICORE_GC)||defined(PMC_GC)
632 struct ArrayObject * chararray=
633 allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
634 int ptrarray[]={1, (int) ptr, (int) chararray};
635 struct ___String___ * strobj=
636 allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
637 chararray=(struct ArrayObject *) ptrarray[2];
639 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
640 struct ___String___ * strobj=allocate_new(STRINGTYPE);
642 strobj->___value___=chararray;
643 strobj->___count___=length;
644 strobj->___offset___=0;
646 for(i=0; i<length; i++) {
647 ((short*)(((char*)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
652 /* Generated code calls this if we fail a bounds check */
654 void failedboundschk(int num, int index, struct ArrayObject * ao) {
656 printf("Array out of bounds at line %u with index %u of object %x with lengt\
657 h %u\n", num, index, ao, ao->___length___);
667 printf("Array out of bounds\n");
668 longjmp(error_handler,2);
675 /* Generated code calls this if we fail null ptr chk */
676 void failednullptr(void * ptr) {
677 #if defined(MULTICORE_GC)||defined(PMC_GC)
679 //print out current stack
682 struct garbagelist * stackptr = (struct garbagelist *)ptr;
683 while(stackptr!=NULL) {
684 tprintf("Stack %d: \n\t", j);
685 for(i=0; i<stackptr->size; i++) {
686 if(stackptr->array[i] != NULL) {
687 tprintf("%x, ", stackptr->array[i]);
693 stackptr=stackptr->next;
698 printf("NULL ptr\n");
708 printf("NULL ptr\n");
709 longjmp(error_handler,2);
716 /* Abort task call */
720 printf("Aborting\n");
721 longjmp(error_handler,4);
724 printf("Aborting\n");
729 void initruntimedata() {
730 // initialize the arrays
731 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
732 // startup core to initialize corestatus[]
733 for(int i = 0; i < NUMCORESACTIVE; ++i) {
736 numreceiveobjs[i] = 0;
743 self_numsendobjs = 0;
744 self_numreceiveobjs = 0;
746 for(int i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
751 //msglength = BAMBOO_MSG_BUF_LENGTH;
753 for(int i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
759 isMsgHanging = false;
762 bamboo_cur_msp = NULL;
763 bamboo_smem_size = 0;
768 INITMULTICOREGCDATA();
772 bamboo_current_thread = NULL;
778 void disruntimedata() {
779 DISMULTICOREGCDATA();
781 BAMBOO_LOCAL_MEM_CLOSE();
782 BAMBOO_SHARE_MEM_CLOSE();
785 void recordtotalexetime() {
787 totalexetime = BAMBOO_GET_EXE_TIME()-bamboo_start_time;
789 unsigned long long timediff=BAMBOO_GET_EXE_TIME()-bamboo_start_time;
790 BAMBOO_PRINT(timediff);
791 #ifndef BAMBOO_MEMPROF
792 BAMBOO_PRINT(0xbbbbbbbb);
797 void getprofiledata_I() {
798 //profile mode, send msgs to other cores to request pouring out progiling data
800 // use numconfirm to check if all cores have finished output task profiling
801 // information. This is safe as when the execution reaches this phase there
802 // should have no other msgs except the PROFILEFINISH msg, there should be
804 numconfirm=NUMCORESACTIVE-1;
805 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
806 for(i = 1; i < NUMCORESACTIVE; ++i) {
807 // send profile request msg to core i
808 send_msg_2(i, PROFILEOUTPUT, totalexetime);
811 // pour profiling data on startup core
815 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
816 if(numconfirm != 0) {
818 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
822 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
829 void checkCoreStatus() {
833 (waitconfirm && (numconfirm == 0))) {
834 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
835 corestatus[BAMBOO_NUM_OF_CORE] = 0;
836 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
837 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
838 // check the status of all cores
839 for(i = 0; i < NUMCORESACTIVE; ++i) {
840 if(corestatus[i] != 0) {
844 if(i == NUMCORESACTIVE) {
845 // check if the sum of send objs and receive obj are the same
846 // yes->check if the info is the latest; no->go on executing
848 for(i = 0; i < NUMCORESACTIVE; ++i) {
849 sumsendobj += numsendobjs[i];
851 for(i = 0; i < NUMCORESACTIVE; ++i) {
852 sumsendobj -= numreceiveobjs[i];
854 if(0 == sumsendobj) {
856 // the first time found all cores stall
857 // send out status confirm msg to all other cores
858 // reset the corestatus array too
859 corestatus[BAMBOO_NUM_OF_CORE] = 1;
861 numconfirm = NUMCORESACTIVE - 1;
862 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
863 for(i = 1; i < NUMCORESACTIVE; ++i) {
865 // send status confirm msg to core i
866 send_msg_1(i, STATUSCONFIRM);
870 // all the core status info are the latest
871 // terminate; for profiling mode, send request to all
872 // other cores to pour out profiling data
873 recordtotalexetime();
875 CACHEADAPT_DISABLE_TIMER();
876 GC_OUTPUT_PROFILE_DATA();
880 gc_outputProfileDataReadable();
882 tprintf("FINISH_EXECUTION\n");
883 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
884 terminate(); // All done.
887 // still some objects on the fly on the network
888 // reset the waitconfirm and numconfirm
893 // not all cores are stall, keep on waiting
897 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
901 // main function for each core
902 void run(int argc, char** argv) {
903 bool sendStall = false;
905 bool tocontinue = false;
907 corenum = BAMBOO_GET_NUM_OF_CORE();
908 // initialize runtime data structures
915 if (BAMBOO_NUM_OF_CORE==STARTUPCORE)
916 profile_init(_LOCAL_DRD_CNT,_LOCAL_WR_CNT, _REMOTE_DRD_CNT, _REMOTE_WR_CNT);
918 int offcore=4*(BAMBOO_NUM_OF_CORE-1);
919 profile_init(validevents[(offcore)%87], validevents[(offcore+1)%87], validevents[(offcore+2)%87], validevents[(offcore+3)%87]);
922 if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
923 numconfirm=NUMCORES-1;
924 for(int i=0;i<NUMCORES;i++) {
925 if (i!=STARTUPCORE) {
926 send_msg_1(i,REQNOTIFYSTART);
931 tprintf("START_EXECUTION\n");
932 bamboo_start_time = BAMBOO_GET_EXE_TIME();
938 bme_performance_counter_start();
941 CACHEADAPT_ENABLE_TIMER();
943 initializeexithandler();
945 // main process of the execution module
946 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
948 // non-executing cores, only processing communications
954 /* Create queue of active tasks */
955 activetasks= genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
956 (int (*)(void *,void *)) &comparetpd);
958 /* Process task information */
961 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
962 /* Create startup object */
963 createstartupobject(argc, argv);
968 profile_start(APP_REGION);
970 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
972 // run the initStaticAndGlobal method to initialize the static blocks and
974 initStaticAndGlobal();
976 // run the main method in the specified mainclass
977 mgc_main(argc, argv);
984 // check if there are new active tasks can be executed
990 while(receiveObject_I() != -1) {
993 // check if there are some pending objects,
994 // if yes, enqueue them and executetasks again
995 tocontinue = checkObjQueue();
997 tocontinue = trystartthread();
1005 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
1016 // wait for some time
1022 // send StallMsg to startup core
1024 send_msg_4(STARTUPCORE,TRANSTALL,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);