3 #include "multicoreruntime.h"
4 #include "methodheaders.h"
5 #include "multicoregarbage.h"
7 #include "multicoregcprofile.h"
9 #include "multicore_arch.h"
12 extern int classsize[];
13 extern int typearray[];
14 extern int typearray2[];
15 extern int* supertypes[];
18 extern struct genhashtable * activetasks;
25 int instanceofif(int otype, int type) {
32 int num = supertypes[otype][0];
33 for(int i = 1; i < num + 1; i++) {
34 int t = supertypes[otype][i];
35 if(instanceofif(t, type) == 1) {
42 int instanceof(struct ___Object___ *ptr, int type) {
47 if(instanceofif(i, type) == 1) {
54 i=typearray2[i-NUMCLASSES];
60 void initializeexithandler() {
63 /* This function inject failures */
64 void injectinstructionfailure() {
65 // not supported in MULTICORE version
69 #ifdef D___Double______nativeparsedouble____L___String___
70 double CALL01(___Double______nativeparsedouble____L___String___,
71 struct ___String___ * ___str___) {
72 int length=VAR(___str___)->___count___;
73 int maxlength=(length>60) ? 60 : length;
74 char str[maxlength+1];
75 struct ArrayObject * chararray=VAR(___str___)->___value___;
77 int offset=VAR(___str___)->___offset___;
78 for(i=0; i<maxlength; i++) {
80 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
83 double d=0.0; //atof(str); TODO Unimplemented nativeparsedoulbe
88 #ifdef D___Double______nativeparsedouble_____AR_B_I_I
89 double CALL23(___Double______nativeparsedouble_____AR_B_I_I,
94 struct ArrayObject * ___str___) {
95 int maxlength=(length>60)?60:length;
96 char str[maxlength+1];
97 struct ArrayObject * bytearray=VAR(___str___);
99 for(i=0; i<maxlength; i++) {
100 str[i]=(((char *)&bytearray->___length___)+sizeof(int))[i+start];
103 double d=0.0; //atof(str); TODO Unimplemented nativeparsedouble
108 typedef union jvalue {
118 #ifdef D___Double______doubleToRawLongBits____D
119 long long CALL11(___Double______doubleToRawLongBits____D,
121 double ___value___) {
125 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
126 /* On little endian ARM processors when using FPA, word order of
127 doubles is still big endian. So take that into account here. When
128 using VFP, word order of doubles follows byte order. */
129 #define SWAP_DOUBLE(a) (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
130 val.j = SWAP_DOUBLE(val.j);
137 #ifdef D___Double______longBitsToDouble____J
138 double CALL11(___Double______longBitsToDouble____J,
139 long long ___bits___,
140 long long ___bits___) {
144 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
146 #define SWAP_DOUBLE(a) (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
148 val.j = SWAP_DOUBLE(val.j);
155 #ifdef D___String______convertdoubletochar____D__AR_C
156 int CALL12(___String______convertdoubletochar____D__AR_C,
159 struct ArrayObject * ___chararray___) {
160 int length=VAR(___chararray___)->___length___;
163 int num=snprintf(str, length, "%f",___val___);
166 for(i=0; i<length; i++) {
167 ((short *)(((char *)&VAR(___chararray___)->___length___)+sizeof(int)))[i]=
174 #ifdef D___System______deepArrayCopy____L___Object____L___Object___
175 void deepArrayCopy(struct ___Object___ * dst,
176 struct ___Object___ * src) {
177 int dsttype=((int *)dst)[0];
178 int srctype=((int *)src)[0];
179 if (dsttype<NUMCLASSES||srctype<NUMCLASSES||srctype!=dsttype)
181 struct ArrayObject *aodst=(struct ArrayObject *)dst;
182 struct ArrayObject *aosrc=(struct ArrayObject *)src;
183 int dstlength=aodst->___length___;
184 int srclength=aosrc->___length___;
185 if (dstlength!=srclength)
187 unsigned INTPTR *pointer=pointerarray[srctype];
189 int elementsize=classsize[srctype];
190 int size=srclength*elementsize;
192 memcpy(((char *)&aodst->___length___)+sizeof(int) ,
193 ((char *)&aosrc->___length___)+sizeof(int), size);
197 for(i=0;i<srclength;i++) {
198 struct ___Object___ * ptr=
199 ((struct ___Object___**)(((char*)&aosrc->___length___)+sizeof(int)))[i];
200 int ptrtype=((int *)ptr)[0];
201 if (ptrtype>=NUMCLASSES) {
202 struct ___Object___ * dstptr=((struct ___Object___**)
203 (((char*)&aodst->___length___)+sizeof(int)))[i];
204 deepArrayCopy(dstptr,ptr);
207 ((struct ___Object___ **)
208 (((char*) &aodst->___length___)+sizeof(int)))[i]=ptr;
214 void CALL02(___System______deepArrayCopy____L___Object____L___Object___,
215 struct ___Object___ * ___dst___,
216 struct ___Object___ * ___src___) {
217 deepArrayCopy(VAR(___dst___), VAR(___src___));
221 #ifdef D___System______arraycopy____L___Object____I_L___Object____I_I
222 void arraycopy(struct ___Object___ *src,
224 struct ___Object___ *dst,
227 int dsttype=((int *)dst)[0];
228 int srctype=((int *)src)[0];
230 //not an array or type mismatch
231 if (dsttype<NUMCLASSES||srctype<NUMCLASSES/*||srctype!=dsttype*/)
234 struct ArrayObject *aodst=(struct ArrayObject *)dst;
235 struct ArrayObject *aosrc=(struct ArrayObject *)src;
236 int dstlength=aodst->___length___;
237 int srclength=aosrc->___length___;
241 if (srcPos+length>srclength)
243 if (destPos+length>dstlength)
246 unsigned INTPTR *pointer=pointerarray[srctype];
248 int elementsize=classsize[srctype];
249 int size=length*elementsize;
251 memcpy(((char *)&aodst->___length___)+sizeof(int)+destPos*elementsize,
252 ((char *)&aosrc->___length___)+sizeof(int)+srcPos*elementsize, size);
256 for(i=0;i<length;i++) {
257 struct ___Object___ * ptr=((struct ___Object___**)
258 (((char*)&aosrc->___length___)+sizeof(int)))[i+srcPos];
259 int ptrtype=((int *)ptr)[0];
261 ((struct ___Object___ **)
262 (((char*) &aodst->___length___)+sizeof(int)))[i+destPos]=ptr;
267 void CALL35(___System______arraycopy____L___Object____I_L___Object____I_I,
271 struct ___Object___ * ___src___,
273 struct ___Object___ * ___dst___,
276 arraycopy(VAR(___src___), ___srcPos___, VAR(___dst___), ___destPos___,
281 #ifdef D___System______exit____I
282 void CALL11(___System______exit____I,
285 // gc_profile mode, output gc prfiling data
286 #if defined(MULTICORE_GC)||defined(PMC_GC)
287 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
288 BAMBOO_PRINT(BAMBOO_GET_EXE_TIME());
289 BAMBOO_PRINT(0xbbbbbbbb);
290 CACHEADAPT_DISABLE_TIMER();
291 GC_OUTPUT_PROFILE_DATA();
292 gc_outputProfileDataReadable();
295 BAMBOO_EXIT_APP(___status___);
299 #ifdef D___Vector______removeElement_____AR_L___Object____I_I
300 void CALL23(___Vector______removeElement_____AR_L___Object____I_I,
303 struct ArrayObject * ___array___,
306 char* offset=((char *)(&VAR(___array___)->___length___))
307 +sizeof(unsigned int)+sizeof(void *)*___index___;
308 memmove(offset, offset+sizeof(void *),
309 (___size___-___index___-1)*sizeof(void *));
313 #ifdef D___System______printI____I
314 void CALL11(___System______printI____I,
317 BAMBOO_PRINT(0x1111);
318 BAMBOO_PRINT_REG(___status___);
322 #ifdef D___System______currentTimeMillis____
323 long long CALL00(___System______currentTimeMillis____) {
324 //TilePro64 is 700mHz
325 return ((unsigned long long)BAMBOO_GET_EXE_TIME())/700000;
329 #ifdef D___System______setgcprofileflag____
330 void CALL00(___System______setgcprofileflag____) {
333 extern volatile bool gc_profile_flag;
334 gc_profile_flag = true;
340 #ifdef D___System______resetgcprofileflag____
341 void CALL00(___System______resetgcprofileflag____) {
344 extern volatile bool gc_profile_flag;
345 gc_profile_flag = false;
351 #ifdef D___System______gc____
352 void CALL00(___System______gc____) {
354 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
355 if(!gc_status_info.gcprocessing && !gcflag) {
358 for(int i = 0; i < NUMCORESACTIVE; i++) {
359 // reuse the gcnumsendobjs & gcnumreceiveobjs
360 gcnumsendobjs[0][i] = 0;
361 gcnumreceiveobjs[0][i] = 0;
363 for(int i = 0; i < NUMCORES4GC; i++) {
364 if(i != STARTUPCORE) {
365 send_msg_1_I(i,GCSTARTPRE);
370 // send msg to the startup core to start gc
371 send_msg_1(STARTUPCORE, GCINVOKE);
377 #ifdef D___System______printString____L___String___
378 void CALL01(___System______printString____L___String___, struct ___String___ * ___s___) {
379 #if defined(MGC)&&defined(TILERA_BME)
380 struct ArrayObject * chararray=VAR(___s___)->___value___;
382 int offset=VAR(___s___)->___offset___;
384 for(i=0; i<VAR(___s___)->___count___; i++) {
386 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
393 /* Object allocation function */
395 #if defined(MULTICORE_GC)||defined(PMC_GC)
396 void * allocate_new(void * ptr,
398 struct ___Object___ * v=
399 (struct ___Object___*)FREEMALLOC((struct garbagelist*) ptr,classsize[type]);
408 extern unsigned int gc_num_obj;
414 /* Array allocation function */
416 struct ArrayObject * allocate_newarray(void * ptr,
419 struct ArrayObject * v=(struct ArrayObject *)FREEMALLOC(
420 (struct garbagelist*)ptr,
421 sizeof(struct ArrayObject)+length*classsize[type]);
430 v->___length___=length;
431 initlock((struct ___Object___ *)v);
433 extern unsigned int gc_num_obj;
440 void * allocate_new(int type) {
441 struct ___Object___ * v=FREEMALLOC(classsize[type]);
451 /* Array allocation function */
453 struct ArrayObject * allocate_newarray(int type,
455 struct ArrayObject * v=FREEMALLOC(
456 sizeof(struct ArrayObject)+length*classsize[type]);
462 v->___length___=length;
463 initlock((struct ___Object___ *) v);
468 /* Converts C character arrays into Java strings */
469 #if defined(MULTICORE_GC)||defined(PMC_GC)
470 __attribute__((malloc)) struct ___String___ * NewStringShort(void * ptr,
474 __attribute__((malloc)) struct ___String___ * NewStringShort(const short *str,
478 #if defined(MULTICORE_GC)||defined(PMC_GC)
479 struct ArrayObject * chararray=
480 allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
481 INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
482 struct ___String___ * strobj=
483 allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
484 chararray=(struct ArrayObject *) ptrarray[2];
486 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
487 struct ___String___ * strobj=allocate_new(STRINGTYPE);
489 strobj->___value___=chararray;
490 strobj->___count___=length;
491 strobj->___offset___=0;
493 for(i=0; i<length; i++) {
494 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=str[i];
499 /* Converts C character arrays into Java strings */
500 #if defined(MULTICORE_GC)||defined(PMC_GC)
501 struct ___String___ * NewString(void * ptr,
505 struct ___String___ * NewString(const char *str,
509 #if defined(MULTICORE_GC)||defined(PMC_GC)
510 struct ArrayObject * chararray=
511 allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
512 int ptrarray[]={1, (int) ptr, (int) chararray};
513 struct ___String___ * strobj=
514 allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
515 chararray=(struct ArrayObject *) ptrarray[2];
517 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
518 struct ___String___ * strobj=allocate_new(STRINGTYPE);
520 strobj->___value___=chararray;
521 strobj->___count___=length;
522 strobj->___offset___=0;
524 for(i=0; i<length; i++) {
525 ((short*)(((char*)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
530 /* Generated code calls this if we fail a bounds check */
532 void failedboundschk(int num, int index, struct ArrayObject * ao) {
534 printf("Array out of bounds at line %u with index %u of object %x with lengt\
535 h %u\n", num, index, ao, ao->___length___);
545 printf("Array out of bounds\n");
546 longjmp(error_handler,2);
553 /* Generated code calls this if we fail null ptr chk */
554 void failednullptr(void * ptr) {
555 #if defined(MULTICORE_GC)||defined(PMC_GC)
557 //print out current stack
560 struct garbagelist * stackptr = (struct garbagelist *)ptr;
561 while(stackptr!=NULL) {
562 tprintf("Stack %d: \n\t", j);
563 for(i=0; i<stackptr->size; i++) {
564 if(stackptr->array[i] != NULL) {
565 tprintf("%x, ", stackptr->array[i]);
571 stackptr=stackptr->next;
576 printf("NULL ptr\n");
586 printf("NULL ptr\n");
587 longjmp(error_handler,2);
594 /* Abort task call */
598 printf("Aborting\n");
599 longjmp(error_handler,4);
602 printf("Aborting\n");
607 void initruntimedata() {
608 // initialize the arrays
609 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
610 // startup core to initialize corestatus[]
611 for(int i = 0; i < NUMCORESACTIVE; ++i) {
614 numreceiveobjs[i] = 0;
621 self_numsendobjs = 0;
622 self_numreceiveobjs = 0;
624 for(int i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
629 //msglength = BAMBOO_MSG_BUF_LENGTH;
631 for(int i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
637 isMsgHanging = false;
643 bamboo_cur_msp = NULL;
644 bamboo_smem_size = 0;
649 INITMULTICOREGCDATA();
653 bamboo_current_thread = NULL;
659 void disruntimedata() {
660 DISMULTICOREGCDATA();
662 BAMBOO_LOCAL_MEM_CLOSE();
663 BAMBOO_SHARE_MEM_CLOSE();
666 void recordtotalexetime() {
668 totalexetime = BAMBOO_GET_EXE_TIME()-bamboo_start_time;
670 unsigned long long timediff=BAMBOO_GET_EXE_TIME()-bamboo_start_time;
671 BAMBOO_PRINT(timediff);
672 #ifndef BAMBOO_MEMPROF
673 BAMBOO_PRINT(0xbbbbbbbb);
678 void getprofiledata_I() {
679 //profile mode, send msgs to other cores to request pouring out progiling data
681 // use numconfirm to check if all cores have finished output task profiling
682 // information. This is safe as when the execution reaches this phase there
683 // should have no other msgs except the PROFILEFINISH msg, there should be
685 numconfirm=NUMCORESACTIVE-1;
686 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
687 for(i = 1; i < NUMCORESACTIVE; ++i) {
688 // send profile request msg to core i
689 send_msg_2(i, PROFILEOUTPUT, totalexetime);
692 // pour profiling data on startup core
696 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
697 if(numconfirm != 0) {
699 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
703 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
710 void checkCoreStatus() {
714 (waitconfirm && (numconfirm == 0))) {
715 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
716 corestatus[BAMBOO_NUM_OF_CORE] = 0;
717 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
718 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
719 // check the status of all cores
720 for(i = 0; i < NUMCORESACTIVE; ++i) {
721 if(corestatus[i] != 0) {
725 if(i == NUMCORESACTIVE) {
726 // check if the sum of send objs and receive obj are the same
727 // yes->check if the info is the latest; no->go on executing
729 for(i = 0; i < NUMCORESACTIVE; ++i) {
730 sumsendobj += numsendobjs[i];
732 for(i = 0; i < NUMCORESACTIVE; ++i) {
733 sumsendobj -= numreceiveobjs[i];
735 if(0 == sumsendobj) {
737 // the first time found all cores stall
738 // send out status confirm msg to all other cores
739 // reset the corestatus array too
740 corestatus[BAMBOO_NUM_OF_CORE] = 1;
742 numconfirm = NUMCORESACTIVE - 1;
743 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
744 for(i = 1; i < NUMCORESACTIVE; ++i) {
746 // send status confirm msg to core i
747 send_msg_1(i, STATUSCONFIRM);
751 // all the core status info are the latest
752 // terminate; for profiling mode, send request to all
753 // other cores to pour out profiling data
754 recordtotalexetime();
756 CACHEADAPT_DISABLE_TIMER();
757 GC_OUTPUT_PROFILE_DATA();
758 gc_outputProfileDataReadable();
760 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
761 terminate(); // All done.
764 // still some objects on the fly on the network
765 // reset the waitconfirm and numconfirm
770 // not all cores are stall, keep on waiting
774 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
778 // main function for each core
779 void run(int argc, char** argv) {
780 bool sendStall = false;
782 bool tocontinue = false;
784 corenum = BAMBOO_GET_NUM_OF_CORE();
785 // initialize runtime data structures
788 if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
789 numconfirm=NUMCORES-1;
790 for(int i=0;i<NUMCORES;i++) {
791 if (i!=STARTUPCORE) {
792 send_msg_1(i,REQNOTIFYSTART);
797 tprintf("start! \n");
798 bamboo_start_time = BAMBOO_GET_EXE_TIME();
804 CACHEADAPT_ENABLE_TIMER();
806 initializeexithandler();
808 // main process of the execution module
809 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
811 // non-executing cores, only processing communications
817 /* Create queue of active tasks */
818 activetasks= genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
819 (int (*)(void *,void *)) &comparetpd);
821 /* Process task information */
824 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
825 /* Create startup object */
826 createstartupobject(argc, argv);
830 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
832 // run the initStaticAndGlobal method to initialize the static blocks and
834 initStaticAndGlobal();
836 // run the main method in the specified mainclass
837 mgc_main(argc, argv);
844 // check if there are new active tasks can be executed
850 while(receiveObject_I() != -1) {
853 // check if there are some pending objects,
854 // if yes, enqueue them and executetasks again
855 tocontinue = checkObjQueue();
857 tocontinue = trystartthread();
865 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
876 // wait for some time
882 // send StallMsg to startup core
884 send_msg_4(STARTUPCORE,TRANSTALL,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);