2 #include "structdefs.h"
9 #include "methodheaders.h"
12 #include "DSTM/interface_recovery/dstm.h"
13 #include "DSTM/interface_recovery/altprelookup.h"
16 extern int numRecovery;
17 extern unsigned int deadMachine[8];
18 extern unsigned int sizeOfRedupedData[8];
19 extern double elapsedTime[8];
23 #include "DSTM/interface/dstm.h"
24 #include "DSTM/interface/altprelookup.h"
25 #include "DSTM/interface/prefetch.h"
33 #define ARRAY_LENGTH 700003
35 __thread int event[ARRAY_LENGTH];
36 __thread unsigned long long clkticks[ARRAY_LENGTH];
37 unsigned long long beginClock=0;
38 #define FILENAME "log"
42 __thread int objcount=0;
43 #define ASSIGNUID(x) { \
44 int number=((objcount++)<<EVTHREADSHIFT)|threadnum; \
51 #if defined(THREADS)||defined(STM)
52 /* Global barrier for STM */
53 pthread_barrier_t barrier;
54 pthread_barrierattr_t attr;
63 extern int classsize[];
64 extern int typearray[];
65 extern int typearray2[];
66 jmp_buf error_handler;
71 float failurechance=0;
74 int injectinstructionfailures;
76 float instfailurechance=0;
79 typedef unsigned long long ticks;
84 int instanceof(struct ___Object___ *ptr, int type) {
96 i=typearray2[i-NUMCLASSES];
102 void exithandler(int sig, siginfo_t *info, void * uap) {
106 void initializeexithandler() {
107 struct sigaction sig;
108 sig.sa_sigaction=&exithandler;
109 sig.sa_flags=SA_SIGINFO;
110 sigemptyset(&sig.sa_mask);
111 sigaction(SIGUSR2, &sig, 0);
115 /* This function inject failures */
117 void injectinstructionfailure() {
119 if (injectinstructionfailures) {
122 instructioncount=failurecount;
123 instaccum+=failurecount;
124 if ((((double)random())/RAND_MAX)<instfailurechance) {
127 printf("FAILURE!!! %d\n",numfailures);
128 longjmp(error_handler,11);
133 if (injectinstructionfailures) {
136 instaccum+=failurecount;
137 if ((((double)random())/RAND_MAX)<instfailurechance) {
140 printf("FAILURE!!! %d\n",numfailures);
148 #ifdef D___Double______nativeparsedouble____L___String___
149 double CALL01(___Double______nativeparsedouble____L___String___,struct ___String___ * ___str___) {
150 int length=VAR(___str___)->___count___;
151 int maxlength=(length>60)?60:length;
152 char str[maxlength+1];
153 struct ArrayObject * chararray=VAR(___str___)->___value___;
155 int offset=VAR(___str___)->___offset___;
156 for(i=0; i<maxlength; i++) {
157 str[i]=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
165 #ifdef D___Double______nativeparsedouble_____AR_B_I_I
166 double CALL23(___Double______nativeparsedouble_____AR_B_I_I, int start, int length,int start,int length,struct ArrayObject * ___str___) {
167 int maxlength=(length>60)?60:length;
168 char str[maxlength+1];
169 struct ArrayObject * bytearray=VAR(___str___);
171 for(i=0; i<maxlength; i++) {
172 str[i]=(((char *)&bytearray->___length___)+sizeof(int))[i+start];
180 #ifdef D___Double______doubleToRawLongBits____D
192 long long CALL11(___Double______doubleToRawLongBits____D, double dval, double dval) {
196 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
197 /* On little endian ARM processors when using FPA, word order of
198 doubles is still big endian. So take that into account here. When
199 using VFP, word order of doubles follows byte order. */
201 #define SWAP_DOUBLE(a) (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
203 val.j = SWAP_DOUBLE(val.j);
210 #ifdef D___Double______longBitsToDouble____J
211 double CALL11(___Double______longBitsToDouble____J, long long lval, long long lval) {
215 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
217 #define SWAP_DOUBLE(a) (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
219 val.j = SWAP_DOUBLE(val.j);
226 #ifdef D___String______convertdoubletochar____D__AR_C
227 int CALL12(___String______convertdoubletochar____D__AR_C, double ___val___, double ___val___, struct ArrayObject ___chararray___) {
228 int length=VAR(___chararray___)->___length___;
231 int num=snprintf(str, length, "%f",___val___);
234 for(i=0; i<length; i++) {
235 ((short *)(((char *)&VAR(___chararray___)->___length___)+sizeof(int)))[i]=(short)str[i];
240 #ifdef D___System______deepArrayCopy____L___Object____L___Object___
241 void deepArrayCopy(struct ___Object___ * dst, struct ___Object___ * src) {
242 int dsttype=((int *)dst)[0];
243 int srctype=((int *)src)[0];
245 src=src->___objlocation___;
247 if (dsttype<NUMCLASSES||srctype<NUMCLASSES||srctype!=dsttype)
249 struct ArrayObject *aodst=(struct ArrayObject *)dst;
250 struct ArrayObject *aosrc=(struct ArrayObject *)src;
251 int dstlength=aodst->___length___;
252 int srclength=aosrc->___length___;
253 if (dstlength!=srclength)
255 unsigned INTPTR *pointer=pointerarray[srctype];
257 int elementsize=classsize[srctype];
258 int size=srclength*elementsize;
260 memcpy(((char *)&aodst->___length___)+sizeof(int) , ((char *)&aosrc->___length___)+sizeof(int), size);
264 for(i=0;i<srclength;i++) {
265 struct ___Object___ * ptr=((struct ___Object___**)(((char*) &aosrc->___length___)+sizeof(int)))[i];
266 int ptrtype=((int *)ptr)[0];
267 if (ptrtype>=NUMCLASSES) {
268 struct ___Object___ * dstptr=((struct ___Object___**)(((char*) &aodst->___length___)+sizeof(int)))[i];
269 deepArrayCopy(dstptr,ptr);
272 ((struct ___Object___ **)(((char*) &aodst->___length___)+sizeof(int)))[i]=ptr;
278 void CALL02(___System______deepArrayCopy____L___Object____L___Object___, struct ___Object___ * ___dst___, struct ___Object___ * ___src___) {
279 deepArrayCopy(VAR(___dst___), VAR(___src___));
283 #ifdef D___System______arraycopy____L___Object____I_L___Object____I_I
284 void arraycopy(struct ___Object___ *src, int srcPos, struct ___Object___ *dst, int destPos, int length) {
285 int dsttype=((int *)dst)[0];
286 int srctype=((int *)src)[0];
288 //not an array or type mismatch
289 if (dsttype<NUMCLASSES||srctype<NUMCLASSES||srctype!=dsttype)
292 struct ArrayObject *aodst=(struct ArrayObject *)dst;
293 struct ArrayObject *aosrc=(struct ArrayObject *)src;
294 int dstlength=aodst->___length___;
295 int srclength=aosrc->___length___;
299 if (srcPos+length>srclength)
301 if (destPos+length>dstlength)
304 unsigned INTPTR *pointer=pointerarray[srctype];
306 int elementsize=classsize[srctype];
307 int size=length*elementsize;
309 memcpy(((char *)&aodst->___length___)+sizeof(int)+destPos*elementsize, ((char *)&aosrc->___length___)+sizeof(int)+srcPos*elementsize, size);
313 for(i=0;i<length;i++) {
314 struct ___Object___ * ptr=((struct ___Object___**)(((char*) &aosrc->___length___)+sizeof(int)))[i+srcPos];
315 int ptrtype=((int *)ptr)[0];
317 ((struct ___Object___ **)(((char*) &aodst->___length___)+sizeof(int)))[i+destPos]=ptr;
322 void CALL35(___System______arraycopy____L___Object____I_L___Object____I_I, int ___srcPos___, int ___destPos___, int ___length___, struct ___Object___ * ___src___, int ___srcPos___, struct ___Object___ * ___dst___, int ___destPos___, int ___length___) {
323 arraycopy(VAR(___src___), ___srcPos___, VAR(___dst___), ___destPos___, ___length___);
327 void CALL11(___System______exit____I,int ___status___, int ___status___) {
330 printf("numTransCommit = %d\n", numTransCommit);
331 printf("numTransAbort = %d\n", numTransAbort);
332 printf("nSoftAbort = %d\n", nSoftAbort);
335 printf("nSoftAbortCommit = %d\n", nSoftAbortCommit);
336 printf("nSoftAbortAbort = %d\n", nSoftAbortAbort);
339 for(i=0; i<TOTALNUMCLASSANDARRAY; i++) {
340 printf("typesCausingAbort[%2d] numaccess= %5d numabort= %3d\n", i, typesCausingAbort[i].numaccess, typesCausingAbort[i].numabort);
351 void CALL11(___System______logevent____I,int ___event___, int ___event___) {
353 event[counter] = ___event___;
354 clkticks[counter] = rdtsc();
360 void CALL00(___System______logevent____) {
367 void CALL11(___System______flushToFile____I, int ___threadid___, int ___threadid___) {
372 memset(filename, 0, 20);
373 sprintf(filename, "%s_%d", FILENAME, ___threadid___);
374 if ((fp = fopen(filename, "w+")) == NULL) {
379 for (i = 0; i < counter-1; i++) {
380 fprintf(fp, "%d %lld %lld\n", event[i], clkticks[i]-beginClock, clkticks[i+1]-beginClock);
382 fprintf(fp, "%d %lld\n", event[i], clkticks[i]-beginClock);
389 void CALL00(___System______initLog____) {
393 for(i=0; i<ARRAY_LENGTH; i++) {
402 #ifdef D___Vector______removeElement_____AR_L___Object____I_I
403 void CALL23(___Vector______removeElement_____AR_L___Object____I_I, int ___index___, int ___size___, struct ArrayObject * ___array___, int ___index___, int ___size___) {
404 char* offset=((char *)(&VAR(___array___)->___length___))+sizeof(unsigned int)+sizeof(void *)*___index___;
405 memmove(offset, offset+sizeof(void *),(___size___-___index___-1)*sizeof(void *));
409 void CALL11(___System______printI____I,int ___status___, int ___status___) {
410 printf("%d\n",___status___);
413 long long CALL00(___System______currentTimeMillis____) {
414 struct timeval tv; long long retval;
415 gettimeofday(&tv, NULL);
416 retval = tv.tv_sec; /* seconds */
417 retval*=1000; /* milliseconds */
418 retval+= (tv.tv_usec/1000); /* adjust milliseconds & add them in */
422 long long CALL00(___System______microTimes____) {
425 gettimeofday(&tv, NULL);
426 retval = tv.tv_sec; /* seconds */
427 retval*=1000000; /* microsecs */
428 retval+= (tv.tv_usec); /* adjust microseconds & add them in */
432 long long CALL00(___System______getticks____) {
435 asm volatile("rdtsc" : "=a" (a), "=d" (d));
436 return (((ticks)a) | (((ticks)d) << 32));
439 void CALL01(___System______printString____L___String___,struct ___String___ * ___s___) {
440 struct ArrayObject * chararray=VAR(___s___)->___value___;
442 int offset=VAR(___s___)->___offset___;
443 for(i=0; i<VAR(___s___)->___count___; i++) {
444 short sc=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
453 #ifdef D___RecoveryStat______printRecoveryStat____
455 void CALL00(___RecoveryStat______printRecoveryStat____) {
459 void CALL00(___RecoveryStat______printRecoveryStat____) {
467 void CALL00(___System______clearPrefetchCache____) {
472 void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) {
473 /* Manual Prefetches to be inserted */
474 //printf("DEBUG-> %s() ___Object___ * ___o___ = %x\n", __func__, VAR(___o___));
475 //printf("DEBUG-> %s() ArrayObject * = %x\n", __func__, VAR(___offsets___));
476 int numoffset=VAR(___offsets___)->___length___;
478 short offArry[numoffset+2];
481 for(i = 2; i<(numoffset+2); i++) {
482 offArry[i] = *((short *)(((char *)&VAR(___offsets___)->___length___) + sizeof(int) + (i-2) * sizeof(short)));
483 //printf("DEBUG-> offArry[%d] = %d\n", i, offArry[i]);
486 if(((unsigned int)(VAR(___o___)) & 1) != 0) { //odd
487 oid = (unsigned int) VAR(___o___); //outside transaction therefore just an oid
489 oid = (unsigned int) COMPOID(VAR(___o___)); //inside transaction therefore a pointer to oid
491 rangePrefetch(oid, (short)(numoffset+2), offArry);
494 void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) {
499 #ifdef D___Task______execution____
500 extern void* virtualtable[];
501 // associated with Task.execution(). finds proper execute method and call it
502 void CALL01(___Task______execution____,struct ___Task___ * ___this___)
505 oid = (unsigned int) VAR(___this___); // object id
506 int type = getObjType(oid); // object type
509 int p[] = {1,0 , oid};
510 ((void(*) (void *))virtualtable[type*MAXCOUNT + EXECUTEMETHOD])(p);
512 // call the proper execute method
513 ((void(*) (void *))virtualtable[type*MAXCOUNT + EXECUTEMETHOD])(oid);
520 /* STM Barrier constructs */
521 #ifdef D___Barrier______setBarrier____I
522 void CALL11(___Barrier______setBarrier____I, int nthreads, int nthreads) {
523 // Barrier initialization
525 if((ret = pthread_barrier_init(&barrier, NULL, nthreads)) != 0) {
526 printf("%s() Could not create a barrier: numthreads = 0 in %s\n", __func__, __FILE__);
532 #ifdef D___Barrier______enterBarrier____
533 void CALL00(___Barrier______enterBarrier____) {
534 // Synchronization point
537 EVLOGEVENT(EV_ENTERBARRIER);
540 stopforgc((struct garbagelist *)___params___);
542 ret = pthread_barrier_wait(&barrier);
546 if(ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) {
547 printf("%s() Could not wait on barrier: error %d in %s\n", __func__, errno, __FILE__);
551 EVLOGEVENT(EV_EXITBARRIER);
556 /* Object allocation function */
559 __attribute__((malloc)) void * allocate_newglobal(int type) {
560 struct ___Object___ * v=(struct ___Object___ *) transCreateObj(classsize[type]);
562 //printf("DEBUG %s(), type= %x\n", __func__, type);
571 /* Array allocation function */
573 __attribute__((malloc)) struct ArrayObject * allocate_newarrayglobal(int type, int length) {
574 struct ArrayObject * v=(struct ArrayObject *)transCreateObj(sizeof(struct ArrayObject)+length*classsize[type]);
576 printf("ERROR: negative array\n");
580 v->___length___=length;
592 // STM Versions of allocation functions
594 /* Object allocation function */
595 __attribute__((malloc)) void * allocate_newtrans(void * ptr, int type) {
597 struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type], 0);
599 struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type]);
603 v->___objlocation___=v;
607 /* Array allocation function */
608 __attribute__((malloc)) struct ArrayObject * allocate_newarraytrans(void * ptr, int type, int length) {
610 int basesize=length*classsize[type];
611 //round the base size up
612 basesize=(basesize+LOWMASK)&HIGHMASK;
613 int numlocks=basesize>>INDEXSHIFT;
614 int bookkeepsize=numlocks*2*sizeof(int);
615 struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+basesize+bookkeepsize, bookkeepsize);
616 unsigned int *intptr=(unsigned int *)(((char *)v)-sizeof(objheader_t));
617 for(;numlocks>0;numlocks--) {
622 v->lowindex=MAXARRAYSIZE;
624 struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+length*classsize[type]);
628 printf("ERROR: negative array\n");
631 v->___objlocation___=(struct ___Object___*)v;
633 v->___length___=length;
637 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
638 objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, classsize[type]+sizeof(objheader_t));
639 struct ___Object___ * v=(struct ___Object___ *) &tmp[1];
641 initdsmlocks(&tmp->lock);
643 v->___objlocation___=v;
648 /* Array allocation function */
650 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
652 int basesize=length*classsize[type];
653 //round the base size up
654 basesize=(basesize+LOWMASK)&HIGHMASK;
655 int numlocks=basesize>>INDEXSHIFT;
656 int bookkeepsize=(numlocks)*2*sizeof(int);
657 int *tmpint=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+basesize+sizeof(objheader_t)+bookkeepsize);
658 for(;numlocks>0;numlocks--) {
662 objheader_t *tmp=(objheader_t *)tmpint;
663 struct ArrayObject * v=(struct ArrayObject *) &tmp[1];
665 v->lowindex=MAXARRAYSIZE;
667 objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]+sizeof(objheader_t));
668 struct ArrayObject * v=(struct ArrayObject *) &tmp[1];
671 tmp->lock=RW_LOCK_BIAS;
673 initdsmlocks(&tmp->lock);
679 printf("ERROR: negative array %d\n", length);
682 v->___objlocation___=(struct ___Object___ *)v;
683 v->___length___=length;
689 #if defined(PRECISE_GC)
691 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
692 return allocate_new_mlp(ptr, type, 0, 0);
694 __attribute__((malloc)) void * allocate_new_mlp(void * ptr, int type, int oid, int allocsite) {
696 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
698 struct ___Object___ * v=(struct ___Object___ *) mygcmalloc((struct garbagelist *) ptr, classsize[type]);
710 v->allocsite=allocsite;
715 /* Array allocation function */
717 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
718 return allocate_newarray_mlp(ptr, type, length, 0, 0);
720 __attribute__((malloc)) struct ArrayObject * allocate_newarray_mlp(void * ptr, int type, int length, int oid, int allocsite) {
722 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
724 struct ArrayObject * v=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]);
727 printf("ERROR: negative array\n");
730 v->___length___=length;
741 v->allocsite=allocsite;
747 __attribute__((malloc)) void * allocate_new(int type) {
748 struct ___Object___ * v=FREEMALLOC(classsize[type]);
756 /* Array allocation function */
758 __attribute__((malloc)) struct ArrayObject * allocate_newarray(int type, int length) {
759 __attribute__((malloc)) struct ArrayObject * v=FREEMALLOC(sizeof(struct ArrayObject)+length*classsize[type]);
761 v->___length___=length;
770 /* Converts C character arrays into Java strings */
772 __attribute__((malloc)) struct ___String___ * NewString(void * ptr, const char *str,int length) {
774 __attribute__((malloc)) struct ___String___ * NewString(const char *str,int length) {
778 struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
779 INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
780 struct ___String___ * strobj=allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
781 chararray=(struct ArrayObject *) ptrarray[2];
783 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
784 struct ___String___ * strobj=allocate_new(STRINGTYPE);
786 strobj->___value___=chararray;
787 strobj->___count___=length;
788 strobj->___offset___=0;
790 for(i=0; i<length; i++) {
791 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
796 /* Generated code calls this if we fail a bounds check */
798 void failedboundschk() {
800 printf("Array out of bounds\n");
807 longjmp(error_handler,2);
811 /* Abort task call */
814 longjmp(error_handler,4);
816 printf("Aborting\n");
822 #ifdef D___System______Assert____Z
823 void CALL11(___System______Assert____Z, int ___status___, int ___status___) {
825 printf("Assertion violation\n");
826 *((int *)(NULL)); //force stack trace error