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();
301 tprintf("FINISH_EXECUTION\n");
304 BAMBOO_EXIT_APP(___status___);
308 #ifdef D___Vector______removeElement_____AR_L___Object____I_I
309 void CALL23(___Vector______removeElement_____AR_L___Object____I_I,
312 struct ArrayObject * ___array___,
315 char* offset=((char *)(&VAR(___array___)->___length___))
316 +sizeof(unsigned int)+sizeof(void *)*___index___;
317 memmove(offset, offset+sizeof(void *),
318 (___size___-___index___-1)*sizeof(void *));
322 #ifdef D___System______printI____I
323 void CALL11(___System______printI____I,
326 BAMBOO_PRINT(0x1111);
327 BAMBOO_PRINT_REG(___status___);
331 #ifdef D___System______currentTimeMillis____
332 long long CALL00(___System______currentTimeMillis____) {
333 //TilePro64 is 700mHz
334 return ((unsigned long long)BAMBOO_GET_EXE_TIME())/700000;
338 #ifdef D___System______setgcprofileflag____
339 void CALL00(___System______setgcprofileflag____) {
342 extern volatile bool gc_profile_flag;
343 gc_profile_flag = true;
349 #ifdef D___System______resetgcprofileflag____
350 void CALL00(___System______resetgcprofileflag____) {
353 extern volatile bool gc_profile_flag;
354 gc_profile_flag = false;
360 #ifdef D___System______gc____
361 void CALL00(___System______gc____) {
363 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
364 if(!gc_status_info.gcprocessing && !gcflag) {
367 for(int i = 0; i < NUMCORESACTIVE; i++) {
368 // reuse the gcnumsendobjs & gcnumreceiveobjs
369 gcnumsendobjs[0][i] = 0;
370 gcnumreceiveobjs[0][i] = 0;
372 for(int i = 0; i < NUMCORES4GC; i++) {
373 if(i != STARTUPCORE) {
374 send_msg_1_I(i,GCSTARTPRE);
379 // send msg to the startup core to start gc
380 send_msg_1(STARTUPCORE, GCINVOKE);
386 #ifdef D___System______printString____L___String___
387 void CALL01(___System______printString____L___String___, struct ___String___ * ___s___) {
388 #if defined(MGC)&&defined(TILERA_BME)
389 struct ArrayObject * chararray=VAR(___s___)->___value___;
391 int offset=VAR(___s___)->___offset___;
393 for(i=0; i<VAR(___s___)->___count___; i++) {
395 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
402 /* Object allocation function */
404 #if defined(MULTICORE_GC)||defined(PMC_GC)
405 void * allocate_new(void * ptr,
407 struct ___Object___ * v=
408 (struct ___Object___*)FREEMALLOC((struct garbagelist*) ptr,classsize[type]);
417 extern unsigned int gc_num_obj;
423 /* Array allocation function */
425 struct ArrayObject * allocate_newarray(void * ptr,
428 struct ArrayObject * v=(struct ArrayObject *)FREEMALLOC(
429 (struct garbagelist*)ptr,
430 sizeof(struct ArrayObject)+length*classsize[type]);
439 v->___length___=length;
440 initlock((struct ___Object___ *)v);
442 extern unsigned int gc_num_obj;
449 void * allocate_new(int type) {
450 struct ___Object___ * v=FREEMALLOC(classsize[type]);
460 /* Array allocation function */
462 struct ArrayObject * allocate_newarray(int type,
464 struct ArrayObject * v=FREEMALLOC(
465 sizeof(struct ArrayObject)+length*classsize[type]);
471 v->___length___=length;
472 initlock((struct ___Object___ *) v);
477 /* Converts C character arrays into Java strings */
478 #if defined(MULTICORE_GC)||defined(PMC_GC)
479 __attribute__((malloc)) struct ___String___ * NewStringShort(void * ptr,
483 __attribute__((malloc)) struct ___String___ * NewStringShort(const short *str,
487 #if defined(MULTICORE_GC)||defined(PMC_GC)
488 struct ArrayObject * chararray=
489 allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
490 INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
491 struct ___String___ * strobj=
492 allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
493 chararray=(struct ArrayObject *) ptrarray[2];
495 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
496 struct ___String___ * strobj=allocate_new(STRINGTYPE);
498 strobj->___value___=chararray;
499 strobj->___count___=length;
500 strobj->___offset___=0;
502 for(i=0; i<length; i++) {
503 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=str[i];
508 /* Converts C character arrays into Java strings */
509 #if defined(MULTICORE_GC)||defined(PMC_GC)
510 struct ___String___ * NewString(void * ptr,
514 struct ___String___ * NewString(const char *str,
518 #if defined(MULTICORE_GC)||defined(PMC_GC)
519 struct ArrayObject * chararray=
520 allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
521 int ptrarray[]={1, (int) ptr, (int) chararray};
522 struct ___String___ * strobj=
523 allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
524 chararray=(struct ArrayObject *) ptrarray[2];
526 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
527 struct ___String___ * strobj=allocate_new(STRINGTYPE);
529 strobj->___value___=chararray;
530 strobj->___count___=length;
531 strobj->___offset___=0;
533 for(i=0; i<length; i++) {
534 ((short*)(((char*)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
539 /* Generated code calls this if we fail a bounds check */
541 void failedboundschk(int num, int index, struct ArrayObject * ao) {
543 printf("Array out of bounds at line %u with index %u of object %x with lengt\
544 h %u\n", num, index, ao, ao->___length___);
554 printf("Array out of bounds\n");
555 longjmp(error_handler,2);
562 /* Generated code calls this if we fail null ptr chk */
563 void failednullptr(void * ptr) {
564 #if defined(MULTICORE_GC)||defined(PMC_GC)
566 //print out current stack
569 struct garbagelist * stackptr = (struct garbagelist *)ptr;
570 while(stackptr!=NULL) {
571 tprintf("Stack %d: \n\t", j);
572 for(i=0; i<stackptr->size; i++) {
573 if(stackptr->array[i] != NULL) {
574 tprintf("%x, ", stackptr->array[i]);
580 stackptr=stackptr->next;
585 printf("NULL ptr\n");
595 printf("NULL ptr\n");
596 longjmp(error_handler,2);
603 /* Abort task call */
607 printf("Aborting\n");
608 longjmp(error_handler,4);
611 printf("Aborting\n");
616 void initruntimedata() {
617 // initialize the arrays
618 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
619 // startup core to initialize corestatus[]
620 for(int i = 0; i < NUMCORESACTIVE; ++i) {
623 numreceiveobjs[i] = 0;
630 self_numsendobjs = 0;
631 self_numreceiveobjs = 0;
633 for(int i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
638 //msglength = BAMBOO_MSG_BUF_LENGTH;
640 for(int i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
646 isMsgHanging = false;
649 bamboo_cur_msp = NULL;
650 bamboo_smem_size = 0;
655 INITMULTICOREGCDATA();
659 bamboo_current_thread = NULL;
665 void disruntimedata() {
666 DISMULTICOREGCDATA();
668 BAMBOO_LOCAL_MEM_CLOSE();
669 BAMBOO_SHARE_MEM_CLOSE();
672 void recordtotalexetime() {
674 totalexetime = BAMBOO_GET_EXE_TIME()-bamboo_start_time;
676 unsigned long long timediff=BAMBOO_GET_EXE_TIME()-bamboo_start_time;
677 BAMBOO_PRINT(timediff);
678 #ifndef BAMBOO_MEMPROF
679 BAMBOO_PRINT(0xbbbbbbbb);
684 void getprofiledata_I() {
685 //profile mode, send msgs to other cores to request pouring out progiling data
687 // use numconfirm to check if all cores have finished output task profiling
688 // information. This is safe as when the execution reaches this phase there
689 // should have no other msgs except the PROFILEFINISH msg, there should be
691 numconfirm=NUMCORESACTIVE-1;
692 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
693 for(i = 1; i < NUMCORESACTIVE; ++i) {
694 // send profile request msg to core i
695 send_msg_2(i, PROFILEOUTPUT, totalexetime);
698 // pour profiling data on startup core
702 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
703 if(numconfirm != 0) {
705 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
709 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
716 void checkCoreStatus() {
720 (waitconfirm && (numconfirm == 0))) {
721 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
722 corestatus[BAMBOO_NUM_OF_CORE] = 0;
723 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
724 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
725 // check the status of all cores
726 for(i = 0; i < NUMCORESACTIVE; ++i) {
727 if(corestatus[i] != 0) {
731 if(i == NUMCORESACTIVE) {
732 // check if the sum of send objs and receive obj are the same
733 // yes->check if the info is the latest; no->go on executing
735 for(i = 0; i < NUMCORESACTIVE; ++i) {
736 sumsendobj += numsendobjs[i];
738 for(i = 0; i < NUMCORESACTIVE; ++i) {
739 sumsendobj -= numreceiveobjs[i];
741 if(0 == sumsendobj) {
743 // the first time found all cores stall
744 // send out status confirm msg to all other cores
745 // reset the corestatus array too
746 corestatus[BAMBOO_NUM_OF_CORE] = 1;
748 numconfirm = NUMCORESACTIVE - 1;
749 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
750 for(i = 1; i < NUMCORESACTIVE; ++i) {
752 // send status confirm msg to core i
753 send_msg_1(i, STATUSCONFIRM);
757 // all the core status info are the latest
758 // terminate; for profiling mode, send request to all
759 // other cores to pour out profiling data
760 recordtotalexetime();
762 CACHEADAPT_DISABLE_TIMER();
763 GC_OUTPUT_PROFILE_DATA();
767 gc_outputProfileDataReadable();
769 tprintf("FINISH_EXECUTION\n");
770 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
771 terminate(); // All done.
774 // still some objects on the fly on the network
775 // reset the waitconfirm and numconfirm
780 // not all cores are stall, keep on waiting
784 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
788 // main function for each core
789 void run(int argc, char** argv) {
790 bool sendStall = false;
792 bool tocontinue = false;
794 corenum = BAMBOO_GET_NUM_OF_CORE();
795 // initialize runtime data structures
802 if (BAMBOO_NUM_OF_CORE==STARTUPCORE)
803 profile_init(_LOCAL_DRD_CNT,_LOCAL_WR_CNT, _REMOTE_DRD_CNT, _REMOTE_WR_CNT);
805 int offcore=4*(BAMBOO_NUM_OF_CORE-1);
806 profile_init(validevents[(offcore)%87], validevents[(offcore+1)%87], validevents[(offcore+2)%87], validevents[(offcore+3)%87]);
809 if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
810 numconfirm=NUMCORES-1;
811 for(int i=0;i<NUMCORES;i++) {
812 if (i!=STARTUPCORE) {
813 send_msg_1(i,REQNOTIFYSTART);
818 tprintf("START_EXECUTION\n");
819 bamboo_start_time = BAMBOO_GET_EXE_TIME();
825 bme_performance_counter_start();
828 CACHEADAPT_ENABLE_TIMER();
830 initializeexithandler();
832 // main process of the execution module
833 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
835 // non-executing cores, only processing communications
841 /* Create queue of active tasks */
842 activetasks= genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
843 (int (*)(void *,void *)) &comparetpd);
845 /* Process task information */
848 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
849 /* Create startup object */
850 createstartupobject(argc, argv);
855 profile_start(APP_REGION);
857 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
859 // run the initStaticAndGlobal method to initialize the static blocks and
861 initStaticAndGlobal();
863 // run the main method in the specified mainclass
864 mgc_main(argc, argv);
871 // check if there are new active tasks can be executed
877 while(receiveObject_I() != -1) {
880 // check if there are some pending objects,
881 // if yes, enqueue them and executetasks again
882 tocontinue = checkObjQueue();
884 tocontinue = trystartthread();
892 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
903 // wait for some time
909 // send StallMsg to startup core
911 send_msg_4(STARTUPCORE,TRANSTALL,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);