4 #include "multicoreruntime.h"
5 #include "methodheaders.h"
6 #include "multicoregarbage.h"
8 extern int classsize[];
9 extern int typearray[];
10 extern int typearray2[];
11 extern int* supertypes[];
14 extern struct genhashtable * activetasks;
21 int instanceofif(int otype, int type) {
28 int num = supertypes[otype][0];
29 for(int i = 1; i < num + 1; i++) {
30 int t = supertypes[otype][i];
31 if(instanceofif(t, type) == 1) {
38 int instanceof(struct ___Object___ *ptr, int type) {
43 if(instanceofif(i, type) == 1) {
50 i=typearray2[i-NUMCLASSES];
56 void initializeexithandler() {
59 /* This function inject failures */
60 void injectinstructionfailure() {
61 // not supported in MULTICORE version
65 #ifdef D___Double______nativeparsedouble____L___String___
66 double CALL01(___Double______nativeparsedouble____L___String___,
67 struct ___String___ * ___str___) {
68 int length=VAR(___str___)->___count___;
69 int maxlength=(length>60) ? 60 : length;
70 char str[maxlength+1];
71 struct ArrayObject * chararray=VAR(___str___)->___value___;
73 int offset=VAR(___str___)->___offset___;
74 for(i=0; i<maxlength; i++) {
76 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
79 double d=0.0; //atof(str); TODO Unimplemented nativeparsedoulbe
84 #ifdef D___Double______nativeparsedouble_____AR_B_I_I
85 double CALL23(___Double______nativeparsedouble_____AR_B_I_I,
90 struct ArrayObject * ___str___) {
91 int maxlength=(length>60)?60:length;
92 char str[maxlength+1];
93 struct ArrayObject * bytearray=VAR(___str___);
95 for(i=0; i<maxlength; i++) {
96 str[i]=(((char *)&bytearray->___length___)+sizeof(int))[i+start];
99 double d=0.0; //atof(str); TODO Unimplemented nativeparsedouble
104 typedef union jvalue {
114 #ifdef D___Double______doubleToRawLongBits____D
115 long long CALL11(___Double______doubleToRawLongBits____D,
117 double ___value___) {
121 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
122 /* On little endian ARM processors when using FPA, word order of
123 doubles is still big endian. So take that into account here. When
124 using VFP, word order of doubles follows byte order. */
125 #define SWAP_DOUBLE(a) (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
126 val.j = SWAP_DOUBLE(val.j);
133 #ifdef D___Double______longBitsToDouble____J
134 double CALL11(___Double______longBitsToDouble____J,
135 long long ___bits___,
136 long long ___bits___) {
140 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
142 #define SWAP_DOUBLE(a) (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
144 val.j = SWAP_DOUBLE(val.j);
151 #ifdef D___String______convertdoubletochar____D__AR_C
152 int CALL12(___String______convertdoubletochar____D__AR_C,
155 struct ArrayObject * ___chararray___) {
156 int length=VAR(___chararray___)->___length___;
159 int num=snprintf(str, length, "%f",___val___);
162 for(i=0; i<length; i++) {
163 ((short *)(((char *)&VAR(___chararray___)->___length___)+sizeof(int)))[i]=
169 int CALL12(___String______convertdoubletochar____D__AR_C,
172 struct ArrayObject ___chararray___) {
177 #ifdef D___System______deepArrayCopy____L___Object____L___Object___
178 void deepArrayCopy(struct ___Object___ * dst,
179 struct ___Object___ * src) {
180 int dsttype=((int *)dst)[0];
181 int srctype=((int *)src)[0];
182 if (dsttype<NUMCLASSES||srctype<NUMCLASSES||srctype!=dsttype)
184 struct ArrayObject *aodst=(struct ArrayObject *)dst;
185 struct ArrayObject *aosrc=(struct ArrayObject *)src;
186 int dstlength=aodst->___length___;
187 int srclength=aosrc->___length___;
188 if (dstlength!=srclength)
190 unsigned INTPTR *pointer=pointerarray[srctype];
192 int elementsize=classsize[srctype];
193 int size=srclength*elementsize;
195 memcpy(((char *)&aodst->___length___)+sizeof(int) ,
196 ((char *)&aosrc->___length___)+sizeof(int), size);
200 for(i=0;i<srclength;i++) {
201 struct ___Object___ * ptr=
202 ((struct ___Object___**)(((char*)&aosrc->___length___)+sizeof(int)))[i];
203 int ptrtype=((int *)ptr)[0];
204 if (ptrtype>=NUMCLASSES) {
205 struct ___Object___ * dstptr=((struct ___Object___**)
206 (((char*)&aodst->___length___)+sizeof(int)))[i];
207 deepArrayCopy(dstptr,ptr);
210 ((struct ___Object___ **)
211 (((char*) &aodst->___length___)+sizeof(int)))[i]=ptr;
217 void CALL02(___System______deepArrayCopy____L___Object____L___Object___,
218 struct ___Object___ * ___dst___,
219 struct ___Object___ * ___src___) {
220 deepArrayCopy(VAR(___dst___), VAR(___src___));
224 #ifdef D___System______arraycopy____L___Object____I_L___Object____I_I
225 void arraycopy(struct ___Object___ *src,
227 struct ___Object___ *dst,
230 int dsttype=((int *)dst)[0];
231 int srctype=((int *)src)[0];
233 //not an array or type mismatch
234 if (dsttype<NUMCLASSES||srctype<NUMCLASSES/*||srctype!=dsttype*/)
237 struct ArrayObject *aodst=(struct ArrayObject *)dst;
238 struct ArrayObject *aosrc=(struct ArrayObject *)src;
239 int dstlength=aodst->___length___;
240 int srclength=aosrc->___length___;
244 if (srcPos+length>srclength)
246 if (destPos+length>dstlength)
249 unsigned INTPTR *pointer=pointerarray[srctype];
251 int elementsize=classsize[srctype];
252 int size=length*elementsize;
254 memcpy(((char *)&aodst->___length___)+sizeof(int)+destPos*elementsize,
255 ((char *)&aosrc->___length___)+sizeof(int)+srcPos*elementsize, size);
259 for(i=0;i<length;i++) {
260 struct ___Object___ * ptr=((struct ___Object___**)
261 (((char*)&aosrc->___length___)+sizeof(int)))[i+srcPos];
262 int ptrtype=((int *)ptr)[0];
264 ((struct ___Object___ **)
265 (((char*) &aodst->___length___)+sizeof(int)))[i+destPos]=ptr;
270 void CALL35(___System______arraycopy____L___Object____I_L___Object____I_I,
274 struct ___Object___ * ___src___,
276 struct ___Object___ * ___dst___,
279 arraycopy(VAR(___src___), ___srcPos___, VAR(___dst___), ___destPos___,
284 #ifdef D___System______exit____I
285 void CALL11(___System______exit____I,
288 // gc_profile mode, output gc prfiling data
290 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
291 BAMBOO_PRINT(BAMBOO_GET_EXE_TIME());
292 BAMBOO_PRINT(0xbbbbbbbb);
293 CACHEADAPT_DISABLE_TIMER();
294 GC_OUTPUT_PROFILE_DATA();
297 BAMBOO_EXIT_APP(___status___);
301 #ifdef D___Vector______removeElement_____AR_L___Object____I_I
302 void CALL23(___Vector______removeElement_____AR_L___Object____I_I,
305 struct ArrayObject * ___array___,
308 char* offset=((char *)(&VAR(___array___)->___length___))
309 +sizeof(unsigned int)+sizeof(void *)*___index___;
310 memmove(offset, offset+sizeof(void *),
311 (___size___-___index___-1)*sizeof(void *));
315 #ifdef D___System______printI____I
316 void CALL11(___System______printI____I,
319 BAMBOO_PRINT(0x1111);
320 BAMBOO_PRINT_REG(___status___);
324 #ifdef D___System______currentTimeMillis____
325 long long CALL00(___System______currentTimeMillis____) {
326 //TilePro64 is 700mHz
327 return ((unsigned long long)BAMBOO_GET_EXE_TIME())/700000;
331 void CALL00(___System______setgcprofileflag____) {
334 extern volatile bool gc_profile_flag;
335 gc_profile_flag = true;
340 void CALL00(___System______resetgcprofileflag____) {
343 extern volatile bool gc_profile_flag;
344 gc_profile_flag = false;
349 #ifdef D___System______printString____L___String___
350 void CALL01(___System______printString____L___String___,
351 struct ___String___ * ___s___) {
354 struct ArrayObject * chararray=VAR(___s___)->___value___;
356 int offset=VAR(___s___)->___offset___;
358 for(i=0; i<VAR(___s___)->___count___; i++) {
360 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
368 /* Object allocation function */
371 void * allocate_new(void * ptr,
373 struct ___Object___ * v=
374 (struct ___Object___*)FREEMALLOC((struct garbagelist*) ptr,classsize[type]);
383 extern unsigned int gc_num_obj;
389 /* Array allocation function */
391 struct ArrayObject * allocate_newarray(void * ptr,
394 struct ArrayObject * v=(struct ArrayObject *)FREEMALLOC(
395 (struct garbagelist*)ptr,
396 sizeof(struct ArrayObject)+length*classsize[type]);
405 v->___length___=length;
408 extern unsigned int gc_num_obj;
415 void * allocate_new(int type) {
416 struct ___Object___ * v=FREEMALLOC(classsize[type]);
426 /* Array allocation function */
428 struct ArrayObject * allocate_newarray(int type,
430 struct ArrayObject * v=FREEMALLOC(
431 sizeof(struct ArrayObject)+length*classsize[type]);
437 v->___length___=length;
443 /* Converts C character arrays into Java strings */
445 __attribute__((malloc)) struct ___String___ * NewStringShort(void * ptr,
449 __attribute__((malloc)) struct ___String___ * NewStringShort(const short *str,
454 struct ArrayObject * chararray=
455 allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
456 INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
457 struct ___String___ * strobj=
458 allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
459 chararray=(struct ArrayObject *) ptrarray[2];
461 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
462 struct ___String___ * strobj=allocate_new(STRINGTYPE);
464 strobj->___value___=chararray;
465 strobj->___count___=length;
466 strobj->___offset___=0;
468 for(i=0; i<length; i++) {
469 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=str[i];
474 /* Converts C character arrays into Java strings */
476 struct ___String___ * NewString(void * ptr,
480 struct ___String___ * NewString(const char *str,
485 struct ArrayObject * chararray=
486 allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
487 int ptrarray[]={1, (int) ptr, (int) chararray};
488 struct ___String___ * strobj=
489 allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
490 chararray=(struct ArrayObject *) ptrarray[2];
492 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
493 struct ___String___ * strobj=allocate_new(STRINGTYPE);
495 strobj->___value___=chararray;
496 strobj->___count___=length;
497 strobj->___offset___=0;
499 for(i=0; i<length; i++) {
500 ((short*)(((char*)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
505 /* Generated code calls this if we fail a bounds check */
507 void failedboundschk(int num, int index, struct ArrayObject * ao) {
509 printf("Array out of bounds at line %u with index %u of object %x with lengt\
510 h %u\n", num, index, ao, ao->___length___);
520 printf("Array out of bounds\n");
521 longjmp(error_handler,2);
528 /* Generated code calls this if we fail null ptr chk */
529 void failednullptr(void * ptr) {
532 //print out current stack
535 struct garbagelist * stackptr = (struct garbagelist *)ptr;
536 while(stackptr!=NULL) {
537 tprintf("Stack %d: \n\t", j);
538 for(i=0; i<stackptr->size; i++) {
539 if(stackptr->array[i] != NULL) {
540 tprintf("%x, ", stackptr->array[i]);
546 stackptr=stackptr->next;
551 printf("NULL ptr\n");
561 printf("NULL ptr\n");
562 longjmp(error_handler,2);
569 /* Abort task call */
573 printf("Aborting\n");
574 longjmp(error_handler,4);
577 printf("Aborting\n");
582 INLINE void initruntimedata() {
583 // initialize the arrays
584 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
585 // startup core to initialize corestatus[]
586 for(int i = 0; i < NUMCORESACTIVE; ++i) {
589 numreceiveobjs[i] = 0;
596 self_numsendobjs = 0;
597 self_numreceiveobjs = 0;
599 for(int i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
604 //msglength = BAMBOO_MSG_BUF_LENGTH;
606 for(int i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
612 isMsgHanging = false;
618 bamboo_cur_msp = NULL;
619 bamboo_smem_size = 0;
624 INITMULTICOREGCDATA();
628 bamboo_current_thread = NULL;
634 INLINE void disruntimedata() {
635 DISMULTICOREGCDATA();
637 BAMBOO_LOCAL_MEM_CLOSE();
638 BAMBOO_SHARE_MEM_CLOSE();
641 INLINE void recordtotalexetime() {
643 totalexetime = BAMBOO_GET_EXE_TIME()-bamboo_start_time;
645 BAMBOO_PRINT(BAMBOO_GET_EXE_TIME()-bamboo_start_time);
646 #ifndef BAMBOO_MEMPROF
647 BAMBOO_PRINT(0xbbbbbbbb);
652 INLINE void getprofiledata_I() {
653 //profile mode, send msgs to other cores to request pouring out progiling data
655 // use numconfirm to check if all cores have finished output task profiling
656 // information. This is safe as when the execution reaches this phase there
657 // should have no other msgs except the PROFILEFINISH msg, there should be
659 numconfirm=NUMCORESACTIVE-1;
660 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
661 for(i = 1; i < NUMCORESACTIVE; ++i) {
662 // send profile request msg to core i
663 send_msg_2(i, PROFILEOUTPUT, totalexetime);
666 // pour profiling data on startup core
670 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
671 if(numconfirm != 0) {
673 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
677 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
684 INLINE void checkCoreStatus() {
688 (waitconfirm && (numconfirm == 0))) {
689 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
690 corestatus[BAMBOO_NUM_OF_CORE] = 0;
691 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
692 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
693 // check the status of all cores
694 for(i = 0; i < NUMCORESACTIVE; ++i) {
695 if(corestatus[i] != 0) {
699 if(i == NUMCORESACTIVE) {
700 // check if the sum of send objs and receive obj are the same
701 // yes->check if the info is the latest; no->go on executing
703 for(i = 0; i < NUMCORESACTIVE; ++i) {
704 sumsendobj += numsendobjs[i];
706 for(i = 0; i < NUMCORESACTIVE; ++i) {
707 sumsendobj -= numreceiveobjs[i];
709 if(0 == sumsendobj) {
711 // the first time found all cores stall
712 // send out status confirm msg to all other cores
713 // reset the corestatus array too
714 corestatus[BAMBOO_NUM_OF_CORE] = 1;
716 numconfirm = NUMCORESACTIVE - 1;
717 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
718 for(i = 1; i < NUMCORESACTIVE; ++i) {
720 // send status confirm msg to core i
721 send_msg_1(i, STATUSCONFIRM);
725 // all the core status info are the latest
726 // terminate; for profiling mode, send request to all
727 // other cores to pour out profiling data
728 recordtotalexetime();
730 CACHEADAPT_DISABLE_TIMER();
731 GC_OUTPUT_PROFILE_DATA();
733 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
734 terminate(); // All done.
737 // still some objects on the fly on the network
738 // reset the waitconfirm and numconfirm
743 // not all cores are stall, keep on waiting
747 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
751 // main function for each core
752 inline void run(int argc, char** argv) {
753 bool sendStall = false;
755 bool tocontinue = false;
757 corenum = BAMBOO_GET_NUM_OF_CORE();
759 // initialize runtime data structures
763 CACHEADAPT_ENABLE_TIMER();
765 initializeexithandler();
767 // main process of the execution module
768 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
770 // non-executing cores, only processing communications
776 /* Create queue of active tasks */
777 activetasks= genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
778 (int (*)(void *,void *)) &comparetpd);
780 /* Process task information */
783 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
784 /* Create startup object */
785 createstartupobject(argc, argv);
789 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
791 // run the initStaticAndGlobal method to initialize the static blocks and
793 initStaticAndGlobal();
795 // run the main method in the specified mainclass
796 mgc_main(argc, argv);
803 // check if there are new active tasks can be executed
809 while(receiveObject_I() != -1) {
812 // check if there are some pending objects,
813 // if yes, enqueue them and executetasks again
814 tocontinue = checkObjQueue();
816 tocontinue = trystartthread();
824 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
835 // wait for some time
841 // send StallMsg to startup core
843 send_msg_4(STARTUPCORE,TRANSTALL,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);