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______nanoTime____
342 long long CALL00(___System______nanoTime____) {
343 //TilePro64 is 700mHz
344 return ((unsigned long long)BAMBOO_GET_EXE_TIME())/700;
348 #ifdef D___System______setgcprofileflag____
349 void CALL00(___System______setgcprofileflag____) {
352 extern volatile bool gc_profile_flag;
353 gc_profile_flag = true;
359 #ifdef D___System______resetgcprofileflag____
360 void CALL00(___System______resetgcprofileflag____) {
363 extern volatile bool gc_profile_flag;
364 gc_profile_flag = false;
370 #ifdef D___System______gc____
371 void CALL00(___System______gc____) {
373 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
374 if(!gc_status_info.gcprocessing && !gcflag) {
377 for(int i = 0; i < NUMCORESACTIVE; i++) {
378 // reuse the gcnumsendobjs & gcnumreceiveobjs
379 gcnumsendobjs[0][i] = 0;
380 gcnumreceiveobjs[0][i] = 0;
382 for(int i = 0; i < NUMCORES4GC; i++) {
383 if(i != STARTUPCORE) {
384 send_msg_1(i,GCSTARTPRE);
389 // send msg to the startup core to start gc
390 send_msg_1(STARTUPCORE, GCINVOKE);
396 #ifdef D___System______printString____L___String___
397 void CALL01(___System______printString____L___String___, struct ___String___ * ___s___) {
398 #if defined(MGC)&&defined(TILERA_BME)
399 struct ArrayObject * chararray=VAR(___s___)->___value___;
401 int offset=VAR(___s___)->___offset___;
403 for(i=0; i<VAR(___s___)->___count___; i++) {
405 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
412 /* Object allocation function */
414 #if defined(MULTICORE_GC)||defined(PMC_GC)
415 void * allocate_new(void * ptr,
417 struct ___Object___ * v=
418 (struct ___Object___*)FREEMALLOC((struct garbagelist*) ptr,classsize[type]);
429 /* Array allocation function */
431 struct ArrayObject * allocate_newarray(void * ptr,
434 struct ArrayObject * v=(struct ArrayObject *)FREEMALLOC(
435 (struct garbagelist*)ptr,
436 sizeof(struct ArrayObject)+length*classsize[type]);
445 v->___length___=length;
446 initlock((struct ___Object___ *)v);
451 void * allocate_new(int type) {
452 struct ___Object___ * v=FREEMALLOC(classsize[type]);
462 /* Array allocation function */
464 struct ArrayObject * allocate_newarray(int type,
466 struct ArrayObject * v=FREEMALLOC(
467 sizeof(struct ArrayObject)+length*classsize[type]);
473 v->___length___=length;
474 initlock((struct ___Object___ *) v);
479 /* Converts C character arrays into Java strings */
480 #if defined(MULTICORE_GC)||defined(PMC_GC)
481 __attribute__((malloc)) struct ___String___ * NewStringShort(void * ptr,
485 __attribute__((malloc)) struct ___String___ * NewStringShort(const short *str,
489 #if defined(MULTICORE_GC)||defined(PMC_GC)
490 struct ArrayObject * chararray=
491 allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
492 INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
493 struct ___String___ * strobj=
494 allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
495 chararray=(struct ArrayObject *) ptrarray[2];
497 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
498 struct ___String___ * strobj=allocate_new(STRINGTYPE);
500 strobj->___value___=chararray;
501 strobj->___count___=length;
502 strobj->___offset___=0;
504 for(i=0; i<length; i++) {
505 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=str[i];
510 /* Converts C character arrays into Java strings */
511 #if defined(MULTICORE_GC)||defined(PMC_GC)
512 struct ___String___ * NewString(void * ptr,
516 struct ___String___ * NewString(const char *str,
520 #if defined(MULTICORE_GC)||defined(PMC_GC)
521 struct ArrayObject * chararray=
522 allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
523 int ptrarray[]={1, (int) ptr, (int) chararray};
524 struct ___String___ * strobj=
525 allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
526 chararray=(struct ArrayObject *) ptrarray[2];
528 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
529 struct ___String___ * strobj=allocate_new(STRINGTYPE);
531 strobj->___value___=chararray;
532 strobj->___count___=length;
533 strobj->___offset___=0;
535 for(i=0; i<length; i++) {
536 ((short*)(((char*)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
541 /* Generated code calls this if we fail a bounds check */
543 void failedboundschk(int num, int index, struct ArrayObject * ao) {
545 printf("Array out of bounds at line %u with index %u of object %x with lengt\
546 h %u\n", num, index, ao, ao->___length___);
556 printf("Array out of bounds\n");
557 longjmp(error_handler,2);
564 /* Generated code calls this if we fail null ptr chk */
565 void failednullptr(void * ptr) {
566 #if defined(MULTICORE_GC)||defined(PMC_GC)
568 //print out current stack
571 struct garbagelist * stackptr = (struct garbagelist *)ptr;
572 while(stackptr!=NULL) {
573 tprintf("Stack %d: \n\t", j);
574 for(i=0; i<stackptr->size; i++) {
575 if(stackptr->array[i] != NULL) {
576 tprintf("%x, ", stackptr->array[i]);
582 stackptr=stackptr->next;
587 printf("NULL ptr\n");
597 printf("NULL ptr\n");
598 longjmp(error_handler,2);
605 /* Abort task call */
609 printf("Aborting\n");
610 longjmp(error_handler,4);
613 printf("Aborting\n");
618 void initruntimedata() {
619 // initialize the arrays
620 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
621 // startup core to initialize corestatus[]
622 for(int i = 0; i < NUMCORESACTIVE; ++i) {
625 numreceiveobjs[i] = 0;
632 self_numsendobjs = 0;
633 self_numreceiveobjs = 0;
635 for(int i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
640 //msglength = BAMBOO_MSG_BUF_LENGTH;
642 for(int i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
648 isMsgHanging = false;
651 bamboo_cur_msp = NULL;
652 bamboo_smem_size = 0;
657 INITMULTICOREGCDATA();
661 bamboo_current_thread = NULL;
667 void disruntimedata() {
668 DISMULTICOREGCDATA();
670 BAMBOO_LOCAL_MEM_CLOSE();
671 BAMBOO_SHARE_MEM_CLOSE();
674 void recordtotalexetime() {
676 totalexetime = BAMBOO_GET_EXE_TIME()-bamboo_start_time;
678 unsigned long long timediff=BAMBOO_GET_EXE_TIME()-bamboo_start_time;
679 BAMBOO_PRINT(timediff);
680 #ifndef BAMBOO_MEMPROF
681 BAMBOO_PRINT(0xbbbbbbbb);
686 void getprofiledata_I() {
687 //profile mode, send msgs to other cores to request pouring out progiling data
689 // use numconfirm to check if all cores have finished output task profiling
690 // information. This is safe as when the execution reaches this phase there
691 // should have no other msgs except the PROFILEFINISH msg, there should be
693 numconfirm=NUMCORESACTIVE-1;
694 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
695 for(i = 1; i < NUMCORESACTIVE; ++i) {
696 // send profile request msg to core i
697 send_msg_2(i, PROFILEOUTPUT, totalexetime);
700 // pour profiling data on startup core
704 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
705 if(numconfirm != 0) {
707 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
711 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
718 void checkCoreStatus() {
722 (waitconfirm && (numconfirm == 0))) {
723 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
724 corestatus[BAMBOO_NUM_OF_CORE] = 0;
725 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
726 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
727 // check the status of all cores
728 for(i = 0; i < NUMCORESACTIVE; ++i) {
729 if(corestatus[i] != 0) {
733 if(i == NUMCORESACTIVE) {
734 // check if the sum of send objs and receive obj are the same
735 // yes->check if the info is the latest; no->go on executing
737 for(i = 0; i < NUMCORESACTIVE; ++i) {
738 sumsendobj += numsendobjs[i];
740 for(i = 0; i < NUMCORESACTIVE; ++i) {
741 sumsendobj -= numreceiveobjs[i];
743 if(0 == sumsendobj) {
745 // the first time found all cores stall
746 // send out status confirm msg to all other cores
747 // reset the corestatus array too
748 corestatus[BAMBOO_NUM_OF_CORE] = 1;
750 numconfirm = NUMCORESACTIVE - 1;
751 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
752 for(i = 1; i < NUMCORESACTIVE; ++i) {
754 // send status confirm msg to core i
755 send_msg_1(i, STATUSCONFIRM);
759 // all the core status info are the latest
760 // terminate; for profiling mode, send request to all
761 // other cores to pour out profiling data
762 recordtotalexetime();
764 CACHEADAPT_DISABLE_TIMER();
765 GC_OUTPUT_PROFILE_DATA();
769 gc_outputProfileDataReadable();
771 tprintf("FINISH_EXECUTION\n");
772 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
773 terminate(); // All done.
776 // still some objects on the fly on the network
777 // reset the waitconfirm and numconfirm
782 // not all cores are stall, keep on waiting
786 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
790 // main function for each core
791 void run(int argc, char** argv) {
792 bool sendStall = false;
794 bool tocontinue = false;
796 corenum = BAMBOO_GET_NUM_OF_CORE();
797 // initialize runtime data structures
804 if (BAMBOO_NUM_OF_CORE==STARTUPCORE)
805 profile_init(_LOCAL_DRD_CNT,_LOCAL_WR_CNT, _REMOTE_DRD_CNT, _REMOTE_WR_CNT);
807 int offcore=4*(BAMBOO_NUM_OF_CORE-1);
808 profile_init(validevents[(offcore)%87], validevents[(offcore+1)%87], validevents[(offcore+2)%87], validevents[(offcore+3)%87]);
811 if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
812 numconfirm=NUMCORES-1;
813 for(int i=0;i<NUMCORES;i++) {
814 if (i!=STARTUPCORE) {
815 send_msg_1(i,REQNOTIFYSTART);
820 tprintf("START_EXECUTION\n");
821 bamboo_start_time = BAMBOO_GET_EXE_TIME();
827 bme_performance_counter_start();
830 CACHEADAPT_ENABLE_TIMER();
832 initializeexithandler();
834 // main process of the execution module
835 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
837 // non-executing cores, only processing communications
843 /* Create queue of active tasks */
844 activetasks= genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
845 (int (*)(void *,void *)) &comparetpd);
847 /* Process task information */
850 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
851 /* Create startup object */
852 createstartupobject(argc, argv);
857 profile_start(APP_REGION);
859 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
861 // run the initStaticAndGlobal method to initialize the static blocks and
863 initStaticAndGlobal();
865 // run the main method in the specified mainclass
866 mgc_main(argc, argv);
873 // check if there are new active tasks can be executed
879 while(receiveObject_I() != -1) {
882 // check if there are some pending objects,
883 // if yes, enqueue them and executetasks again
884 tocontinue = checkObjQueue();
886 tocontinue = trystartthread();
894 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
905 // wait for some time
911 // send StallMsg to startup core
913 send_msg_4(STARTUPCORE,TRANSTALL,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);