3 #include "multicoreruntime.h"
4 #include "methodheaders.h"
5 #include "multicoregarbage.h"
6 #include "multicore_arch.h"
9 extern int classsize[];
10 extern int typearray[];
11 extern int typearray2[];
12 extern int* supertypes[];
15 extern struct genhashtable * activetasks;
22 int instanceofif(int otype, int type) {
29 int num = supertypes[otype][0];
30 for(int i = 1; i < num + 1; i++) {
31 int t = supertypes[otype][i];
32 if(instanceofif(t, type) == 1) {
39 int instanceof(struct ___Object___ *ptr, int type) {
44 if(instanceofif(i, type) == 1) {
51 i=typearray2[i-NUMCLASSES];
57 void initializeexithandler() {
60 /* This function inject failures */
61 void injectinstructionfailure() {
62 // not supported in MULTICORE version
66 #ifdef D___Double______nativeparsedouble____L___String___
67 double CALL01(___Double______nativeparsedouble____L___String___,
68 struct ___String___ * ___str___) {
69 int length=VAR(___str___)->___count___;
70 int maxlength=(length>60) ? 60 : length;
71 char str[maxlength+1];
72 struct ArrayObject * chararray=VAR(___str___)->___value___;
74 int offset=VAR(___str___)->___offset___;
75 for(i=0; i<maxlength; i++) {
77 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
80 double d=0.0; //atof(str); TODO Unimplemented nativeparsedoulbe
85 #ifdef D___Double______nativeparsedouble_____AR_B_I_I
86 double CALL23(___Double______nativeparsedouble_____AR_B_I_I,
91 struct ArrayObject * ___str___) {
92 int maxlength=(length>60)?60:length;
93 char str[maxlength+1];
94 struct ArrayObject * bytearray=VAR(___str___);
96 for(i=0; i<maxlength; i++) {
97 str[i]=(((char *)&bytearray->___length___)+sizeof(int))[i+start];
100 double d=0.0; //atof(str); TODO Unimplemented nativeparsedouble
105 typedef union jvalue {
115 #ifdef D___Double______doubleToRawLongBits____D
116 long long CALL11(___Double______doubleToRawLongBits____D,
118 double ___value___) {
122 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
123 /* On little endian ARM processors when using FPA, word order of
124 doubles is still big endian. So take that into account here. When
125 using VFP, word order of doubles follows byte order. */
126 #define SWAP_DOUBLE(a) (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
127 val.j = SWAP_DOUBLE(val.j);
134 #ifdef D___Double______longBitsToDouble____J
135 double CALL11(___Double______longBitsToDouble____J,
136 long long ___bits___,
137 long long ___bits___) {
141 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
143 #define SWAP_DOUBLE(a) (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
145 val.j = SWAP_DOUBLE(val.j);
152 #ifdef D___String______convertdoubletochar____D__AR_C
153 int CALL12(___String______convertdoubletochar____D__AR_C,
156 struct ArrayObject * ___chararray___) {
157 int length=VAR(___chararray___)->___length___;
160 int num=snprintf(str, length, "%f",___val___);
163 for(i=0; i<length; i++) {
164 ((short *)(((char *)&VAR(___chararray___)->___length___)+sizeof(int)))[i]=
171 #ifdef D___System______deepArrayCopy____L___Object____L___Object___
172 void deepArrayCopy(struct ___Object___ * dst,
173 struct ___Object___ * src) {
174 int dsttype=((int *)dst)[0];
175 int srctype=((int *)src)[0];
176 if (dsttype<NUMCLASSES||srctype<NUMCLASSES||srctype!=dsttype)
178 struct ArrayObject *aodst=(struct ArrayObject *)dst;
179 struct ArrayObject *aosrc=(struct ArrayObject *)src;
180 int dstlength=aodst->___length___;
181 int srclength=aosrc->___length___;
182 if (dstlength!=srclength)
184 unsigned INTPTR *pointer=pointerarray[srctype];
186 int elementsize=classsize[srctype];
187 int size=srclength*elementsize;
189 memcpy(((char *)&aodst->___length___)+sizeof(int) ,
190 ((char *)&aosrc->___length___)+sizeof(int), size);
194 for(i=0;i<srclength;i++) {
195 struct ___Object___ * ptr=
196 ((struct ___Object___**)(((char*)&aosrc->___length___)+sizeof(int)))[i];
197 int ptrtype=((int *)ptr)[0];
198 if (ptrtype>=NUMCLASSES) {
199 struct ___Object___ * dstptr=((struct ___Object___**)
200 (((char*)&aodst->___length___)+sizeof(int)))[i];
201 deepArrayCopy(dstptr,ptr);
204 ((struct ___Object___ **)
205 (((char*) &aodst->___length___)+sizeof(int)))[i]=ptr;
211 void CALL02(___System______deepArrayCopy____L___Object____L___Object___,
212 struct ___Object___ * ___dst___,
213 struct ___Object___ * ___src___) {
214 deepArrayCopy(VAR(___dst___), VAR(___src___));
218 #ifdef D___System______arraycopy____L___Object____I_L___Object____I_I
219 void arraycopy(struct ___Object___ *src,
221 struct ___Object___ *dst,
224 int dsttype=((int *)dst)[0];
225 int srctype=((int *)src)[0];
227 //not an array or type mismatch
228 if (dsttype<NUMCLASSES||srctype<NUMCLASSES/*||srctype!=dsttype*/)
231 struct ArrayObject *aodst=(struct ArrayObject *)dst;
232 struct ArrayObject *aosrc=(struct ArrayObject *)src;
233 int dstlength=aodst->___length___;
234 int srclength=aosrc->___length___;
238 if (srcPos+length>srclength)
240 if (destPos+length>dstlength)
243 unsigned INTPTR *pointer=pointerarray[srctype];
245 int elementsize=classsize[srctype];
246 int size=length*elementsize;
248 memcpy(((char *)&aodst->___length___)+sizeof(int)+destPos*elementsize,
249 ((char *)&aosrc->___length___)+sizeof(int)+srcPos*elementsize, size);
253 for(i=0;i<length;i++) {
254 struct ___Object___ * ptr=((struct ___Object___**)
255 (((char*)&aosrc->___length___)+sizeof(int)))[i+srcPos];
256 int ptrtype=((int *)ptr)[0];
258 ((struct ___Object___ **)
259 (((char*) &aodst->___length___)+sizeof(int)))[i+destPos]=ptr;
264 void CALL35(___System______arraycopy____L___Object____I_L___Object____I_I,
268 struct ___Object___ * ___src___,
270 struct ___Object___ * ___dst___,
273 arraycopy(VAR(___src___), ___srcPos___, VAR(___dst___), ___destPos___,
278 #ifdef D___System______exit____I
279 void CALL11(___System______exit____I,
282 // gc_profile mode, output gc prfiling data
284 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
285 BAMBOO_PRINT(BAMBOO_GET_EXE_TIME());
286 BAMBOO_PRINT(0xbbbbbbbb);
287 CACHEADAPT_DISABLE_TIMER();
288 GC_OUTPUT_PROFILE_DATA();
289 gc_outputProfileDataReadable();
292 BAMBOO_EXIT_APP(___status___);
296 #ifdef D___Vector______removeElement_____AR_L___Object____I_I
297 void CALL23(___Vector______removeElement_____AR_L___Object____I_I,
300 struct ArrayObject * ___array___,
303 char* offset=((char *)(&VAR(___array___)->___length___))
304 +sizeof(unsigned int)+sizeof(void *)*___index___;
305 memmove(offset, offset+sizeof(void *),
306 (___size___-___index___-1)*sizeof(void *));
310 #ifdef D___System______printI____I
311 void CALL11(___System______printI____I,
314 BAMBOO_PRINT(0x1111);
315 BAMBOO_PRINT_REG(___status___);
319 #ifdef D___System______currentTimeMillis____
320 long long CALL00(___System______currentTimeMillis____) {
321 //TilePro64 is 700mHz
322 return ((unsigned long long)BAMBOO_GET_EXE_TIME())/700000;
326 #ifdef D___System______setgcprofileflag____
327 void CALL00(___System______setgcprofileflag____) {
330 extern volatile bool gc_profile_flag;
331 gc_profile_flag = true;
337 #ifdef D___System______resetgcprofileflag____
338 void CALL00(___System______resetgcprofileflag____) {
341 extern volatile bool gc_profile_flag;
342 gc_profile_flag = false;
348 #ifdef D___System______gc____
349 void CALL00(___System______gc____) {
351 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
352 if(!gc_status_info.gcprocessing && !gcflag) {
355 for(int i = 0; i < NUMCORESACTIVE; i++) {
356 // reuse the gcnumsendobjs & gcnumreceiveobjs
357 gcnumsendobjs[0][i] = 0;
358 gcnumreceiveobjs[0][i] = 0;
360 for(int i = 0; i < NUMCORES4GC; i++) {
361 if(i != STARTUPCORE) {
362 send_msg_1_I(i,GCSTARTPRE);
367 // send msg to the startup core to start gc
368 send_msg_1(STARTUPCORE, GCINVOKE);
374 #ifdef D___System______printString____L___String___
375 void CALL01(___System______printString____L___String___, struct ___String___ * ___s___) {
376 #if defined(MGC)&&defined(TILERA_BME)
377 struct ArrayObject * chararray=VAR(___s___)->___value___;
379 int offset=VAR(___s___)->___offset___;
381 for(i=0; i<VAR(___s___)->___count___; i++) {
383 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
390 /* Object allocation function */
393 void * allocate_new(void * ptr,
395 struct ___Object___ * v=
396 (struct ___Object___*)FREEMALLOC((struct garbagelist*) ptr,classsize[type]);
405 extern unsigned int gc_num_obj;
411 /* Array allocation function */
413 struct ArrayObject * allocate_newarray(void * ptr,
416 struct ArrayObject * v=(struct ArrayObject *)FREEMALLOC(
417 (struct garbagelist*)ptr,
418 sizeof(struct ArrayObject)+length*classsize[type]);
427 v->___length___=length;
428 initlock((struct ___Object___ *)v);
430 extern unsigned int gc_num_obj;
437 void * allocate_new(int type) {
438 struct ___Object___ * v=FREEMALLOC(classsize[type]);
448 /* Array allocation function */
450 struct ArrayObject * allocate_newarray(int type,
452 struct ArrayObject * v=FREEMALLOC(
453 sizeof(struct ArrayObject)+length*classsize[type]);
459 v->___length___=length;
460 initlock((struct ___Object___ *) v);
465 /* Converts C character arrays into Java strings */
467 __attribute__((malloc)) struct ___String___ * NewStringShort(void * ptr,
471 __attribute__((malloc)) struct ___String___ * NewStringShort(const short *str,
476 struct ArrayObject * chararray=
477 allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
478 INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
479 struct ___String___ * strobj=
480 allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
481 chararray=(struct ArrayObject *) ptrarray[2];
483 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
484 struct ___String___ * strobj=allocate_new(STRINGTYPE);
486 strobj->___value___=chararray;
487 strobj->___count___=length;
488 strobj->___offset___=0;
490 for(i=0; i<length; i++) {
491 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=str[i];
496 /* Converts C character arrays into Java strings */
498 struct ___String___ * NewString(void * ptr,
502 struct ___String___ * NewString(const char *str,
507 struct ArrayObject * chararray=
508 allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
509 int ptrarray[]={1, (int) ptr, (int) chararray};
510 struct ___String___ * strobj=
511 allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
512 chararray=(struct ArrayObject *) ptrarray[2];
514 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
515 struct ___String___ * strobj=allocate_new(STRINGTYPE);
517 strobj->___value___=chararray;
518 strobj->___count___=length;
519 strobj->___offset___=0;
521 for(i=0; i<length; i++) {
522 ((short*)(((char*)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
527 /* Generated code calls this if we fail a bounds check */
529 void failedboundschk(int num, int index, struct ArrayObject * ao) {
531 printf("Array out of bounds at line %u with index %u of object %x with lengt\
532 h %u\n", num, index, ao, ao->___length___);
542 printf("Array out of bounds\n");
543 longjmp(error_handler,2);
550 /* Generated code calls this if we fail null ptr chk */
551 void failednullptr(void * ptr) {
554 //print out current stack
557 struct garbagelist * stackptr = (struct garbagelist *)ptr;
558 while(stackptr!=NULL) {
559 tprintf("Stack %d: \n\t", j);
560 for(i=0; i<stackptr->size; i++) {
561 if(stackptr->array[i] != NULL) {
562 tprintf("%x, ", stackptr->array[i]);
568 stackptr=stackptr->next;
573 printf("NULL ptr\n");
583 printf("NULL ptr\n");
584 longjmp(error_handler,2);
591 /* Abort task call */
595 printf("Aborting\n");
596 longjmp(error_handler,4);
599 printf("Aborting\n");
604 void initruntimedata() {
605 // initialize the arrays
606 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
607 // startup core to initialize corestatus[]
608 for(int i = 0; i < NUMCORESACTIVE; ++i) {
611 numreceiveobjs[i] = 0;
618 self_numsendobjs = 0;
619 self_numreceiveobjs = 0;
621 for(int i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
626 //msglength = BAMBOO_MSG_BUF_LENGTH;
628 for(int i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
634 isMsgHanging = false;
640 bamboo_cur_msp = NULL;
641 bamboo_smem_size = 0;
646 INITMULTICOREGCDATA();
650 bamboo_current_thread = NULL;
656 void disruntimedata() {
657 DISMULTICOREGCDATA();
659 BAMBOO_LOCAL_MEM_CLOSE();
660 BAMBOO_SHARE_MEM_CLOSE();
663 void recordtotalexetime() {
665 totalexetime = BAMBOO_GET_EXE_TIME()-bamboo_start_time;
667 unsigned long long timediff=BAMBOO_GET_EXE_TIME()-bamboo_start_time;
668 BAMBOO_PRINT(timediff);
669 #ifndef BAMBOO_MEMPROF
670 BAMBOO_PRINT(0xbbbbbbbb);
675 void getprofiledata_I() {
676 //profile mode, send msgs to other cores to request pouring out progiling data
678 // use numconfirm to check if all cores have finished output task profiling
679 // information. This is safe as when the execution reaches this phase there
680 // should have no other msgs except the PROFILEFINISH msg, there should be
682 numconfirm=NUMCORESACTIVE-1;
683 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
684 for(i = 1; i < NUMCORESACTIVE; ++i) {
685 // send profile request msg to core i
686 send_msg_2(i, PROFILEOUTPUT, totalexetime);
689 // pour profiling data on startup core
693 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
694 if(numconfirm != 0) {
696 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
700 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
707 void checkCoreStatus() {
711 (waitconfirm && (numconfirm == 0))) {
712 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
713 corestatus[BAMBOO_NUM_OF_CORE] = 0;
714 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
715 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
716 // check the status of all cores
717 for(i = 0; i < NUMCORESACTIVE; ++i) {
718 if(corestatus[i] != 0) {
722 if(i == NUMCORESACTIVE) {
723 // check if the sum of send objs and receive obj are the same
724 // yes->check if the info is the latest; no->go on executing
726 for(i = 0; i < NUMCORESACTIVE; ++i) {
727 sumsendobj += numsendobjs[i];
729 for(i = 0; i < NUMCORESACTIVE; ++i) {
730 sumsendobj -= numreceiveobjs[i];
732 if(0 == sumsendobj) {
734 // the first time found all cores stall
735 // send out status confirm msg to all other cores
736 // reset the corestatus array too
737 corestatus[BAMBOO_NUM_OF_CORE] = 1;
739 numconfirm = NUMCORESACTIVE - 1;
740 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
741 for(i = 1; i < NUMCORESACTIVE; ++i) {
743 // send status confirm msg to core i
744 send_msg_1(i, STATUSCONFIRM);
748 // all the core status info are the latest
749 // terminate; for profiling mode, send request to all
750 // other cores to pour out profiling data
751 recordtotalexetime();
753 CACHEADAPT_DISABLE_TIMER();
754 GC_OUTPUT_PROFILE_DATA();
755 gc_outputProfileDataReadable();
757 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
758 terminate(); // All done.
761 // still some objects on the fly on the network
762 // reset the waitconfirm and numconfirm
767 // not all cores are stall, keep on waiting
771 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
775 // main function for each core
776 void run(int argc, char** argv) {
777 bool sendStall = false;
779 bool tocontinue = false;
781 corenum = BAMBOO_GET_NUM_OF_CORE();
782 // initialize runtime data structures
785 if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
786 numconfirm=NUMCORES-1;
787 for(int i=0;i<NUMCORES;i++) {
788 if (i!=STARTUPCORE) {
789 send_msg_1(i,REQNOTIFYSTART);
794 tprintf("start! \n");
795 bamboo_start_time = BAMBOO_GET_EXE_TIME();
801 CACHEADAPT_ENABLE_TIMER();
803 initializeexithandler();
805 // main process of the execution module
806 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
808 // non-executing cores, only processing communications
814 /* Create queue of active tasks */
815 activetasks= genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
816 (int (*)(void *,void *)) &comparetpd);
818 /* Process task information */
821 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
822 /* Create startup object */
823 createstartupobject(argc, argv);
827 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
829 // run the initStaticAndGlobal method to initialize the static blocks and
831 initStaticAndGlobal();
833 // run the main method in the specified mainclass
834 mgc_main(argc, argv);
841 // check if there are new active tasks can be executed
847 while(receiveObject_I() != -1) {
850 // check if there are some pending objects,
851 // if yes, enqueue them and executetasks again
852 tocontinue = checkObjQueue();
854 tocontinue = trystartthread();
862 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
873 // wait for some time
879 // send StallMsg to startup core
881 send_msg_4(STARTUPCORE,TRANSTALL,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);