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();
291 BAMBOO_EXIT_APP(___status___);
295 #ifdef D___Vector______removeElement_____AR_L___Object____I_I
296 void CALL23(___Vector______removeElement_____AR_L___Object____I_I,
299 struct ArrayObject * ___array___,
302 char* offset=((char *)(&VAR(___array___)->___length___))
303 +sizeof(unsigned int)+sizeof(void *)*___index___;
304 memmove(offset, offset+sizeof(void *),
305 (___size___-___index___-1)*sizeof(void *));
309 #ifdef D___System______printI____I
310 void CALL11(___System______printI____I,
313 BAMBOO_PRINT(0x1111);
314 BAMBOO_PRINT_REG(___status___);
318 #ifdef D___System______currentTimeMillis____
319 long long CALL00(___System______currentTimeMillis____) {
320 //TilePro64 is 700mHz
321 return ((unsigned long long)BAMBOO_GET_EXE_TIME())/700000;
325 #ifdef D___System______setgcprofileflag____
326 void CALL00(___System______setgcprofileflag____) {
329 extern volatile bool gc_profile_flag;
330 gc_profile_flag = true;
336 #ifdef D___System______resetgcprofileflag____
337 void CALL00(___System______resetgcprofileflag____) {
340 extern volatile bool gc_profile_flag;
341 gc_profile_flag = false;
347 void CALL00(___System______gc____) {
349 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
350 if(!gc_status_info.gcprocessing && !gcflag) {
353 for(int i = 0; i < NUMCORESACTIVE; i++) {
354 // reuse the gcnumsendobjs & gcnumreceiveobjs
355 gcnumsendobjs[0][i] = 0;
356 gcnumreceiveobjs[0][i] = 0;
358 for(int i = 0; i < NUMCORES4GC; i++) {
359 if(i != STARTUPCORE) {
360 send_msg_1_I(i,GCSTARTPRE);
365 // send msg to the startup core to start gc
366 send_msg_1(STARTUPCORE, GCINVOKE);
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(i,GCSTARTPRE);
389 // send msg to the startup core to start gc
390 send_msg_1(STARTUPCORE, GCINVOKE);
395 #ifdef D___System______printString____L___String___
396 void CALL01(___System______printString____L___String___, struct ___String___ * ___s___) {
397 #if defined(MGC)&&defined(TILERA_BME)
398 struct ArrayObject * chararray=VAR(___s___)->___value___;
400 int offset=VAR(___s___)->___offset___;
402 for(i=0; i<VAR(___s___)->___count___; i++) {
404 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
411 /* Object allocation function */
414 void * allocate_new(void * ptr,
416 struct ___Object___ * v=
417 (struct ___Object___*)FREEMALLOC((struct garbagelist*) ptr,classsize[type]);
426 extern unsigned int gc_num_obj;
432 /* Array allocation function */
434 struct ArrayObject * allocate_newarray(void * ptr,
437 struct ArrayObject * v=(struct ArrayObject *)FREEMALLOC(
438 (struct garbagelist*)ptr,
439 sizeof(struct ArrayObject)+length*classsize[type]);
448 v->___length___=length;
449 initlock((struct ___Object___ *)v);
451 extern unsigned int gc_num_obj;
458 void * allocate_new(int type) {
459 struct ___Object___ * v=FREEMALLOC(classsize[type]);
469 /* Array allocation function */
471 struct ArrayObject * allocate_newarray(int type,
473 struct ArrayObject * v=FREEMALLOC(
474 sizeof(struct ArrayObject)+length*classsize[type]);
480 v->___length___=length;
481 initlock((struct ___Object___ *) v);
486 /* Converts C character arrays into Java strings */
488 __attribute__((malloc)) struct ___String___ * NewStringShort(void * ptr,
492 __attribute__((malloc)) struct ___String___ * NewStringShort(const short *str,
497 struct ArrayObject * chararray=
498 allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
499 INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
500 struct ___String___ * strobj=
501 allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
502 chararray=(struct ArrayObject *) ptrarray[2];
504 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
505 struct ___String___ * strobj=allocate_new(STRINGTYPE);
507 strobj->___value___=chararray;
508 strobj->___count___=length;
509 strobj->___offset___=0;
511 for(i=0; i<length; i++) {
512 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=str[i];
517 /* Converts C character arrays into Java strings */
519 struct ___String___ * NewString(void * ptr,
523 struct ___String___ * NewString(const char *str,
528 struct ArrayObject * chararray=
529 allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
530 int ptrarray[]={1, (int) ptr, (int) chararray};
531 struct ___String___ * strobj=
532 allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
533 chararray=(struct ArrayObject *) ptrarray[2];
535 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
536 struct ___String___ * strobj=allocate_new(STRINGTYPE);
538 strobj->___value___=chararray;
539 strobj->___count___=length;
540 strobj->___offset___=0;
542 for(i=0; i<length; i++) {
543 ((short*)(((char*)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
548 /* Generated code calls this if we fail a bounds check */
550 void failedboundschk(int num, int index, struct ArrayObject * ao) {
552 printf("Array out of bounds at line %u with index %u of object %x with lengt\
553 h %u\n", num, index, ao, ao->___length___);
563 printf("Array out of bounds\n");
564 longjmp(error_handler,2);
571 /* Generated code calls this if we fail null ptr chk */
572 void failednullptr(void * ptr) {
575 //print out current stack
578 struct garbagelist * stackptr = (struct garbagelist *)ptr;
579 while(stackptr!=NULL) {
580 tprintf("Stack %d: \n\t", j);
581 for(i=0; i<stackptr->size; i++) {
582 if(stackptr->array[i] != NULL) {
583 tprintf("%x, ", stackptr->array[i]);
589 stackptr=stackptr->next;
594 printf("NULL ptr\n");
604 printf("NULL ptr\n");
605 longjmp(error_handler,2);
612 /* Abort task call */
616 printf("Aborting\n");
617 longjmp(error_handler,4);
620 printf("Aborting\n");
625 void initruntimedata() {
626 // initialize the arrays
627 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
628 // startup core to initialize corestatus[]
629 for(int i = 0; i < NUMCORESACTIVE; ++i) {
632 numreceiveobjs[i] = 0;
639 self_numsendobjs = 0;
640 self_numreceiveobjs = 0;
642 for(int i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
647 //msglength = BAMBOO_MSG_BUF_LENGTH;
649 for(int i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
655 isMsgHanging = false;
661 bamboo_cur_msp = NULL;
662 bamboo_smem_size = 0;
667 INITMULTICOREGCDATA();
671 bamboo_current_thread = NULL;
677 void disruntimedata() {
678 DISMULTICOREGCDATA();
680 BAMBOO_LOCAL_MEM_CLOSE();
681 BAMBOO_SHARE_MEM_CLOSE();
684 void recordtotalexetime() {
686 totalexetime = BAMBOO_GET_EXE_TIME()-bamboo_start_time;
688 unsigned long long timediff=BAMBOO_GET_EXE_TIME()-bamboo_start_time;
689 BAMBOO_PRINT(timediff);
690 #ifndef BAMBOO_MEMPROF
691 BAMBOO_PRINT(0xbbbbbbbb);
696 void getprofiledata_I() {
697 //profile mode, send msgs to other cores to request pouring out progiling data
699 // use numconfirm to check if all cores have finished output task profiling
700 // information. This is safe as when the execution reaches this phase there
701 // should have no other msgs except the PROFILEFINISH msg, there should be
703 numconfirm=NUMCORESACTIVE-1;
704 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
705 for(i = 1; i < NUMCORESACTIVE; ++i) {
706 // send profile request msg to core i
707 send_msg_2(i, PROFILEOUTPUT, totalexetime);
710 // pour profiling data on startup core
714 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
715 if(numconfirm != 0) {
717 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
721 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
728 void checkCoreStatus() {
732 (waitconfirm && (numconfirm == 0))) {
733 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
734 corestatus[BAMBOO_NUM_OF_CORE] = 0;
735 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
736 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
737 // check the status of all cores
738 for(i = 0; i < NUMCORESACTIVE; ++i) {
739 if(corestatus[i] != 0) {
743 if(i == NUMCORESACTIVE) {
744 // check if the sum of send objs and receive obj are the same
745 // yes->check if the info is the latest; no->go on executing
747 for(i = 0; i < NUMCORESACTIVE; ++i) {
748 sumsendobj += numsendobjs[i];
750 for(i = 0; i < NUMCORESACTIVE; ++i) {
751 sumsendobj -= numreceiveobjs[i];
753 if(0 == sumsendobj) {
755 // the first time found all cores stall
756 // send out status confirm msg to all other cores
757 // reset the corestatus array too
758 corestatus[BAMBOO_NUM_OF_CORE] = 1;
760 numconfirm = NUMCORESACTIVE - 1;
761 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
762 for(i = 1; i < NUMCORESACTIVE; ++i) {
764 // send status confirm msg to core i
765 send_msg_1(i, STATUSCONFIRM);
769 // all the core status info are the latest
770 // terminate; for profiling mode, send request to all
771 // other cores to pour out profiling data
772 recordtotalexetime();
774 CACHEADAPT_DISABLE_TIMER();
775 GC_OUTPUT_PROFILE_DATA();
777 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
778 terminate(); // All done.
781 // still some objects on the fly on the network
782 // reset the waitconfirm and numconfirm
787 // not all cores are stall, keep on waiting
791 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
795 // main function for each core
796 void run(int argc, char** argv) {
797 bool sendStall = false;
799 bool tocontinue = false;
801 corenum = BAMBOO_GET_NUM_OF_CORE();
802 // initialize runtime data structures
805 if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
806 numconfirm=NUMCORES-1;
807 for(int i=0;i<NUMCORES;i++) {
808 if (i!=STARTUPCORE) {
809 send_msg_1(i,REQNOTIFYSTART);
814 tprintf("start! \n");
815 bamboo_start_time = BAMBOO_GET_EXE_TIME();
821 CACHEADAPT_ENABLE_TIMER();
823 initializeexithandler();
825 // main process of the execution module
826 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
828 // non-executing cores, only processing communications
834 /* Create queue of active tasks */
835 activetasks= genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
836 (int (*)(void *,void *)) &comparetpd);
838 /* Process task information */
841 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
842 /* Create startup object */
843 createstartupobject(argc, argv);
847 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
849 // run the initStaticAndGlobal method to initialize the static blocks and
851 initStaticAndGlobal();
853 // run the main method in the specified mainclass
854 mgc_main(argc, argv);
861 // check if there are new active tasks can be executed
867 while(receiveObject_I() != -1) {
870 // check if there are some pending objects,
871 // if yes, enqueue them and executetasks again
872 tocontinue = checkObjQueue();
874 tocontinue = trystartthread();
882 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
893 // wait for some time
899 // send StallMsg to startup core
901 send_msg_4(STARTUPCORE,TRANSTALL,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);