2 #include "structdefs.h"
9 #include "methodheaders.h"
11 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
17 #include "DSTM/interface_recovery/dstm.h"
18 #include "DSTM/interface_recovery/altprelookup.h"
21 extern int numRecovery;
22 extern unsigned int deadMachine[8];
23 extern unsigned int sizeOfRedupedData[8];
24 extern double elapsedTime[8];
28 #include "DSTM/interface/dstm.h"
29 #include "DSTM/interface/altprelookup.h"
30 #include "DSTM/interface/prefetch.h"
38 #define ARRAY_LENGTH 700003
40 __thread int event[ARRAY_LENGTH];
41 __thread unsigned long long clkticks[ARRAY_LENGTH];
42 unsigned long long beginClock=0;
43 #define FILENAME "log"
47 __thread int objcount=0;
48 #define ASSIGNUID(x) { \
49 int number=((objcount++)<<EVTHREADSHIFT)|threadnum; \
56 #if defined(THREADS)||defined(STM)
58 /* Global barrier for STM */
59 pthread_barrier_t barrier;
60 pthread_barrierattr_t attr;
69 #define GCPOINT(x) ((INTPTR)((x)*0.99))
72 extern int classsize[];
73 extern int typearray[];
74 extern int typearray2[];
75 jmp_buf error_handler;
80 float failurechance=0;
83 int injectinstructionfailures;
85 float instfailurechance=0;
88 typedef unsigned long long ticks;
93 int instanceof(struct ___Object___ *ptr, int type) {
105 i=typearray2[i-NUMCLASSES];
111 void exithandler(int sig, siginfo_t *info, void * uap) {
115 void initializeexithandler() {
116 struct sigaction sig;
117 sig.sa_sigaction=&exithandler;
118 sig.sa_flags=SA_SIGINFO;
119 sigemptyset(&sig.sa_mask);
120 sigaction(SIGUSR2, &sig, 0);
124 /* This function inject failures */
126 void injectinstructionfailure() {
128 if (injectinstructionfailures) {
131 instructioncount=failurecount;
132 instaccum+=failurecount;
133 if ((((double)random())/RAND_MAX)<instfailurechance) {
136 printf("FAILURE!!! %d\n",numfailures);
137 longjmp(error_handler,11);
142 if (injectinstructionfailures) {
145 instaccum+=failurecount;
146 if ((((double)random())/RAND_MAX)<instfailurechance) {
149 printf("FAILURE!!! %d\n",numfailures);
157 #ifdef D___Double______nativeparsedouble____L___String___
158 double CALL01(___Double______nativeparsedouble____L___String___,struct ___String___ * ___str___) {
159 int length=VAR(___str___)->___count___;
160 int maxlength=(length>60)?60:length;
161 char str[maxlength+1];
162 struct ArrayObject * chararray=VAR(___str___)->___value___;
164 int offset=VAR(___str___)->___offset___;
165 for(i=0; i<maxlength; i++) {
166 str[i]=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
174 #ifdef D___Double______nativeparsedouble_____AR_B_I_I
175 double CALL23(___Double______nativeparsedouble_____AR_B_I_I, int start, int length,int start,int length,struct ArrayObject * ___str___) {
176 int maxlength=(length>60)?60:length;
177 char str[maxlength+1];
178 struct ArrayObject * bytearray=VAR(___str___);
180 for(i=0; i<maxlength; i++) {
181 str[i]=(((char *)&bytearray->___length___)+sizeof(int))[i+start];
189 #ifdef D___Double______doubleToRawLongBits____D
201 long long CALL11(___Double______doubleToRawLongBits____D, double dval, double dval) {
205 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
206 /* On little endian ARM processors when using FPA, word order of
207 doubles is still big endian. So take that into account here. When
208 using VFP, word order of doubles follows byte order. */
210 #define SWAP_DOUBLE(a) (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
212 val.j = SWAP_DOUBLE(val.j);
219 #ifdef D___Double______longBitsToDouble____J
220 double CALL11(___Double______longBitsToDouble____J, long long lval, long long lval) {
224 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
226 #define SWAP_DOUBLE(a) (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
228 val.j = SWAP_DOUBLE(val.j);
235 #ifdef D___String______convertdoubletochar____D__AR_C
236 int CALL12(___String______convertdoubletochar____D__AR_C, double ___val___, double ___val___, struct ArrayObject ___chararray___) {
237 int length=VAR(___chararray___)->___length___;
240 int num=snprintf(str, length, "%f",___val___);
243 for(i=0; i<length; i++) {
244 ((short *)(((char *)&VAR(___chararray___)->___length___)+sizeof(int)))[i]=(short)str[i];
249 #ifdef D___System______deepArrayCopy____L___Object____L___Object___
250 void deepArrayCopy(struct ___Object___ * dst, struct ___Object___ * src) {
251 int dsttype=((int *)dst)[0];
252 int srctype=((int *)src)[0];
254 src=src->___objlocation___;
256 if (dsttype<NUMCLASSES||srctype<NUMCLASSES||srctype!=dsttype)
258 struct ArrayObject *aodst=(struct ArrayObject *)dst;
259 struct ArrayObject *aosrc=(struct ArrayObject *)src;
260 int dstlength=aodst->___length___;
261 int srclength=aosrc->___length___;
262 if (dstlength!=srclength)
264 unsigned INTPTR *pointer=pointerarray[srctype];
266 int elementsize=classsize[srctype];
267 int size=srclength*elementsize;
269 memcpy(((char *)&aodst->___length___)+sizeof(int) , ((char *)&aosrc->___length___)+sizeof(int), size);
273 for(i=0;i<srclength;i++) {
274 struct ___Object___ * ptr=((struct ___Object___**)(((char*) &aosrc->___length___)+sizeof(int)))[i];
275 int ptrtype=((int *)ptr)[0];
276 if (ptrtype>=NUMCLASSES) {
277 struct ___Object___ * dstptr=((struct ___Object___**)(((char*) &aodst->___length___)+sizeof(int)))[i];
278 deepArrayCopy(dstptr,ptr);
281 ((struct ___Object___ **)(((char*) &aodst->___length___)+sizeof(int)))[i]=ptr;
287 void CALL02(___System______deepArrayCopy____L___Object____L___Object___, struct ___Object___ * ___dst___, struct ___Object___ * ___src___) {
288 deepArrayCopy(VAR(___dst___), VAR(___src___));
292 #ifdef D___System______arraycopy____L___Object____I_L___Object____I_I
293 void arraycopy(struct ___Object___ *src, int srcPos, struct ___Object___ *dst, int destPos, int length) {
294 int dsttype=((int *)dst)[0];
295 int srctype=((int *)src)[0];
297 //not an array or type mismatch
298 if (dsttype<NUMCLASSES||srctype<NUMCLASSES)
300 if (srctype!=dsttype)
301 printf("Potential type mismatch in arraycopy\n");
303 struct ArrayObject *aodst=(struct ArrayObject *)dst;
304 struct ArrayObject *aosrc=(struct ArrayObject *)src;
305 int dstlength=aodst->___length___;
306 int srclength=aosrc->___length___;
310 if (srcPos+length>srclength)
312 if (destPos+length>dstlength)
315 unsigned INTPTR *pointer=pointerarray[srctype];
317 int elementsize=classsize[srctype];
318 int size=length*elementsize;
320 memcpy(((char *)&aodst->___length___)+sizeof(int)+destPos*elementsize, ((char *)&aosrc->___length___)+sizeof(int)+srcPos*elementsize, size);
324 for(i=0;i<length;i++) {
325 struct ___Object___ * ptr=((struct ___Object___**)(((char*) &aosrc->___length___)+sizeof(int)))[i+srcPos];
327 ((struct ___Object___ **)(((char*) &aodst->___length___)+sizeof(int)))[i+destPos]=ptr;
332 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___) {
333 arraycopy(VAR(___src___), ___srcPos___, VAR(___dst___), ___destPos___, ___length___);
337 #ifdef D___Runtime______availableProcessors____
338 int CALL01(___Runtime______availableProcessors____, struct ___Runtime___ * ___this___) {
339 printf("Unimplemented Runtime.availableProcessors\n");
344 #ifdef D___Runtime______freeMemory____
345 long long CALL01(___Runtime______freeMemory____, struct ___Runtime___ * ___this___) {
346 printf("Unimplemented Runtime.freeMemory\n");
347 return 1024*1024*1024;
351 #ifdef D___Runtime______totalMemory____
352 long long CALL01(___Runtime______totalMemory____, struct ___Runtime___ * ___this___) {
353 printf("Unimplemented Runtime.totalMemory\n");
354 return 1024*1024*1024;
358 #ifdef D___Runtime______maxMemory____
359 long long CALL01(___Runtime______maxMemory____, struct ___Runtime___ * ___this___) {
360 printf("Unimplemented Runtime.maxMemory\n");
361 return 1024*1024*1024;
364 #ifdef D___System______exit____I
365 void CALL11(___System______exit____I,int ___status___, int ___status___) {
368 printf("numTransCommit = %d\n", numTransCommit);
369 printf("numTransAbort = %d\n", numTransAbort);
370 printf("nSoftAbort = %d\n", nSoftAbort);
373 printf("nSoftAbortCommit = %d\n", nSoftAbortCommit);
374 printf("nSoftAbortAbort = %d\n", nSoftAbortAbort);
377 for(i=0; i<TOTALNUMCLASSANDARRAY; i++) {
378 printf("typesCausingAbort[%2d] numaccess= %5d numabort= %3d\n", i, typesCausingAbort[i].numaccess, typesCausingAbort[i].numabort);
390 #ifdef D___System______logevent____I
391 void CALL11(___System______logevent____I,int ___event___, int ___event___) {
393 event[counter] = ___event___;
394 clkticks[counter] = rdtsc();
401 #ifdef ___System______logevent____
402 void CALL00(___System______logevent____) {
410 #ifdef ___System______flushToFile____I
411 void CALL11(___System______flushToFile____I, int ___threadid___, int ___threadid___) {
416 memset(filename, 0, 20);
417 sprintf(filename, "%s_%d", FILENAME, ___threadid___);
418 if ((fp = fopen(filename, "w+")) == NULL) {
423 for (i = 0; i < counter-1; i++) {
424 fprintf(fp, "%d %lld %lld\n", event[i], clkticks[i]-beginClock, clkticks[i+1]-beginClock);
426 fprintf(fp, "%d %lld\n", event[i], clkticks[i]-beginClock);
434 #ifdef D___System______initLog____
435 void CALL00(___System______initLog____) {
439 for(i=0; i<ARRAY_LENGTH; i++) {
449 #ifdef D___Vector______removeElement_____AR_L___Object____I_I
450 void CALL23(___Vector______removeElement_____AR_L___Object____I_I, int ___index___, int ___size___, struct ArrayObject * ___array___, int ___index___, int ___size___) {
451 char* offset=((char *)(&VAR(___array___)->___length___))+sizeof(unsigned int)+sizeof(void *)*___index___;
452 memmove(offset, offset+sizeof(void *),(___size___-___index___-1)*sizeof(void *));
456 #ifdef D___System______printI____I
457 void CALL11(___System______printI____I,int ___status___, int ___status___) {
458 printf("%d\n",___status___);
462 #ifdef D___System______currentTimeMillis____
463 long long CALL00(___System______currentTimeMillis____) {
464 struct timeval tv; long long retval;
465 gettimeofday(&tv, NULL);
466 retval = tv.tv_sec; /* seconds */
467 retval*=1000; /* milliseconds */
468 retval+= (tv.tv_usec/1000); /* adjust milliseconds & add them in */
473 #ifdef D___System______gc____
474 void CALL00(___System______gc____) {
475 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
476 while (pthread_mutex_trylock(&gclock)!=0) {
477 stopforgc((struct garbagelist *)___params___);
482 /* Grow the to heap if necessary */
484 INTPTR curr_heapsize=curr_heaptop-curr_heapbase;
485 INTPTR to_heapsize=to_heaptop-to_heapbase;
487 if (curr_heapsize>to_heapsize) {
489 to_heapbase=malloc(curr_heapsize);
490 if (to_heapbase==NULL) {
491 printf("Error Allocating enough memory\n");
494 to_heaptop=to_heapbase+curr_heapsize;
495 to_heapptr=to_heapbase;
500 collect((struct garbagelist *)___params___);
503 void * tmp=to_heapbase;
504 to_heapbase=curr_heapbase;
508 to_heaptop=curr_heaptop;
512 curr_heapptr=to_heapptr;
513 curr_heapgcpoint=((char *) curr_heapbase)+GCPOINT(curr_heaptop-curr_heapbase);
514 to_heapptr=to_heapbase;
515 bzero(tmp, curr_heaptop-tmp);
519 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
520 pthread_mutex_unlock(&gclock);
525 #ifdef D___System______microTimes____
526 long long CALL00(___System______microTimes____) {
529 gettimeofday(&tv, NULL);
530 retval = tv.tv_sec; /* seconds */
531 retval*=1000000; /* microsecs */
532 retval+= (tv.tv_usec); /* adjust microseconds & add them in */
537 #ifdef D___System______getticks____
538 long long CALL00(___System______getticks____) {
541 asm volatile("rdtsc" : "=a" (a), "=d" (d));
542 return (((ticks)a) | (((ticks)d) << 32));
546 #ifdef D___System______printString____L___String___
547 void CALL01(___System______printString____L___String___,struct ___String___ * ___s___) {
548 struct ArrayObject * chararray=VAR(___s___)->___value___;
550 int offset=VAR(___s___)->___offset___;
551 for(i=0; i<VAR(___s___)->___count___; i++) {
552 short sc=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
562 #ifdef D___RecoveryStat______printRecoveryStat____
564 void CALL00(___RecoveryStat______printRecoveryStat____) {
568 void CALL00(___RecoveryStat______printRecoveryStat____) {
576 #ifdef D___System______clearPrefetchCache____
577 void CALL00(___System______clearPrefetchCache____) {
583 #ifdef D___System______rangePrefetch____L___Object_____AR_S
584 void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) {
585 /* Manual Prefetches to be inserted */
586 //printf("DEBUG-> %s() ___Object___ * ___o___ = %x\n", __func__, VAR(___o___));
587 //printf("DEBUG-> %s() ArrayObject * = %x\n", __func__, VAR(___offsets___));
588 int numoffset=VAR(___offsets___)->___length___;
590 short offArry[numoffset+2];
593 for(i = 2; i<(numoffset+2); i++) {
594 offArry[i] = *((short *)(((char *)&VAR(___offsets___)->___length___) + sizeof(int) + (i-2) * sizeof(short)));
595 //printf("DEBUG-> offArry[%d] = %d\n", i, offArry[i]);
598 if(((unsigned int)(VAR(___o___)) & 1) != 0) { //odd
599 oid = (unsigned int) VAR(___o___); //outside transaction therefore just an oid
601 oid = (unsigned int) COMPOID(VAR(___o___)); //inside transaction therefore a pointer to oid
603 rangePrefetch(oid, (short)(numoffset+2), offArry);
606 void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) {
612 #ifdef D___Task______execution____
613 extern void* virtualtable[];
614 // associated with Task.execution(). finds proper execute method and call it
615 void CALL01(___Task______execution____,struct ___Task___ * ___this___)
618 oid = (unsigned int) VAR(___this___); // object id
619 int type = getObjType(oid); // object type
622 int p[] = {1,0 , oid};
623 ((void(*) (void *))virtualtable[type*MAXCOUNT + EXECUTEMETHOD])(p);
625 // call the proper execute method
626 ((void(*) (void *))virtualtable[type*MAXCOUNT + EXECUTEMETHOD])(oid);
633 /* STM Barrier constructs */
634 #ifdef D___Barrier______setBarrier____I
635 void CALL11(___Barrier______setBarrier____I, int nthreads, int nthreads) {
636 // Barrier initialization
638 if((ret = pthread_barrier_init(&barrier, NULL, nthreads)) != 0) {
639 printf("%s() Could not create a barrier: numthreads = 0 in %s\n", __func__, __FILE__);
645 #ifdef D___Barrier______enterBarrier____
646 void CALL00(___Barrier______enterBarrier____) {
647 // Synchronization point
650 EVLOGEVENT(EV_ENTERBARRIER);
653 stopforgc((struct garbagelist *)___params___);
655 ret = pthread_barrier_wait(&barrier);
659 if(ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) {
660 printf("%s() Could not wait on barrier: error %d in %s\n", __func__, errno, __FILE__);
664 EVLOGEVENT(EV_EXITBARRIER);
669 /* Object allocation function */
672 __attribute__((malloc)) void * allocate_newglobal(int type) {
673 struct ___Object___ * v=(struct ___Object___ *) transCreateObj(classsize[type]);
675 v->hashcode=(int)(INTPTR)v;
676 //printf("DEBUG %s(), type= %x\n", __func__, type);
683 /* Array allocation function */
685 __attribute__((malloc)) struct ArrayObject * allocate_newarrayglobal(int type, int length) {
686 struct ArrayObject * v=(struct ArrayObject *)transCreateObj(sizeof(struct ArrayObject)+length*classsize[type]);
688 printf("ERROR: negative array\n");
692 v->hashcode=(int)(INTPTR)v;
693 v->___length___=length;
703 // STM Versions of allocation functions
705 /* Object allocation function */
706 __attribute__((malloc)) void * allocate_newtrans(void * ptr, int type) {
708 struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type], 0);
710 struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type]);
714 v->hashcode=(int)(INTPTR)v;
715 v->___objlocation___=v;
719 /* Array allocation function */
720 __attribute__((malloc)) struct ArrayObject * allocate_newarraytrans(void * ptr, int type, int length) {
722 int basesize=length*classsize[type];
723 //round the base size up
724 basesize=(basesize+LOWMASK)&HIGHMASK;
725 int numlocks=basesize>>INDEXSHIFT;
726 int bookkeepsize=numlocks*2*sizeof(int);
727 struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+basesize+bookkeepsize, bookkeepsize);
728 unsigned int *intptr=(unsigned int *)(((char *)v)-sizeof(objheader_t));
729 for(;numlocks>0;numlocks--) {
734 v->lowindex=MAXARRAYSIZE;
736 struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+length*classsize[type]);
740 printf("ERROR: negative array\n");
743 v->___objlocation___=(struct ___Object___*)v;
745 v->hashcode=(int)(INTPTR)v;
746 v->___length___=length;
750 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
751 objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, classsize[type]+sizeof(objheader_t));
752 struct ___Object___ * v=(struct ___Object___ *) &tmp[1];
754 initdsmlocks(&tmp->lock);
756 v->___objlocation___=v;
758 v->hashcode=(int)(INTPTR)v;
762 /* Array allocation function */
764 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
766 int basesize=length*classsize[type];
767 //round the base size up
768 basesize=(basesize+LOWMASK)&HIGHMASK;
769 int numlocks=basesize>>INDEXSHIFT;
770 int bookkeepsize=(numlocks)*2*sizeof(int);
771 int *tmpint=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+basesize+sizeof(objheader_t)+bookkeepsize);
772 for(;numlocks>0;numlocks--) {
776 objheader_t *tmp=(objheader_t *)tmpint;
777 struct ArrayObject * v=(struct ArrayObject *) &tmp[1];
779 v->lowindex=MAXARRAYSIZE;
781 objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]+sizeof(objheader_t));
782 struct ArrayObject * v=(struct ArrayObject *) &tmp[1];
785 tmp->lock=RW_LOCK_BIAS;
787 initdsmlocks(&tmp->lock);
792 v->hashcode=(int)(INTPTR)v;
794 printf("ERROR: negative array %d\n", length);
797 v->___objlocation___=(struct ___Object___ *)v;
798 v->___length___=length;
804 #if defined(PRECISE_GC)
806 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
807 return allocate_new_mlp(ptr, type, 0, 0);
809 __attribute__((malloc)) void * allocate_new_mlp(void * ptr, int type, int oid, int allocsite) {
811 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
813 struct ___Object___ * v=(struct ___Object___ *) mygcmalloc((struct garbagelist *) ptr, classsize[type]);
815 v->hashcode=(int)(INTPTR)v;
824 v->allocsite=allocsite;
829 /* Array allocation function */
831 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
832 return allocate_newarray_mlp(ptr, type, length, 0, 0);
834 __attribute__((malloc)) struct ArrayObject * allocate_newarray_mlp(void * ptr, int type, int length, int oid, int allocsite) {
836 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
838 struct ArrayObject * v=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]);
840 v->hashcode=(int)(INTPTR)v;
842 printf("ERROR: negative array\n");
845 v->___length___=length;
854 v->allocsite=allocsite;
860 __attribute__((malloc)) void * allocate_new(int type) {
861 struct ___Object___ * v=FREEMALLOC(classsize[type]);
863 v->hashcode=(int)(INTPTR)v;
870 /* Array allocation function */
872 __attribute__((malloc)) struct ArrayObject * allocate_newarray(int type, int length) {
873 __attribute__((malloc)) struct ArrayObject * v=FREEMALLOC(sizeof(struct ArrayObject)+length*classsize[type]);
875 v->hashcode=(int)(INTPTR)v;
876 v->___length___=length;
885 /* Converts C character arrays into Java strings */
887 __attribute__((malloc)) struct ___String___ * NewStringShort(void * ptr, const short *str,int length) {
889 __attribute__((malloc)) struct ___String___ * NewStringShort(const short *str,int length) {
893 struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
894 INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
895 struct ___String___ * strobj=allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
896 chararray=(struct ArrayObject *) ptrarray[2];
898 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
899 struct ___String___ * strobj=allocate_new(STRINGTYPE);
901 strobj->___value___=chararray;
902 strobj->___count___=length;
903 strobj->___offset___=0;
905 for(i=0; i<length; i++) {
906 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=str[i];
911 /* Converts C character arrays into Java strings */
913 __attribute__((malloc)) struct ___String___ * NewString(void * ptr, const char *str,int length) {
915 __attribute__((malloc)) struct ___String___ * NewString(const char *str,int length) {
919 struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
920 INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
921 struct ___String___ * strobj=allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
922 chararray=(struct ArrayObject *) ptrarray[2];
924 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
925 struct ___String___ * strobj=allocate_new(STRINGTYPE);
927 strobj->___value___=chararray;
928 strobj->___count___=length;
929 strobj->___offset___=0;
931 for(i=0; i<length; i++) {
932 ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
937 /* Generated code calls this if we fail a bounds check */
939 void failedboundschk(int num) {
941 printf("Array out of bounds\n");
948 longjmp(error_handler,2);
952 /* Abort task call */
955 longjmp(error_handler,4);
957 printf("Aborting\n");
963 #ifdef D___System______Assert____Z
964 void CALL11(___System______Assert____Z, int ___status___, int ___status___) {
966 printf("Assertion violation\n");
967 *((int *)(NULL)); //force stack trace error