c6fd9a9be288496784f80d68f4d5c8329e27a0bc
[IRC.git] / Robust / src / Runtime / runtime.c
1 #include "runtime.h"
2 #include "structdefs.h"
3 #include <signal.h>
4 #include "mem.h"
5 #include <fcntl.h>
6 #include <errno.h>
7 #include <stdio.h>
8 #include "option.h"
9 #include "methodheaders.h"
10 #ifdef DSTM
11 #ifdef RECOVERY
12 #include "DSTM/interface_recovery/dstm.h"
13 #include "DSTM/interface_recovery/altprelookup.h"
14
15 #ifdef RECOVERYSTATS
16   extern int numRecovery;
17   extern unsigned int deadMachine[8];
18   extern unsigned int sizeOfRedupedData[8];
19   extern double elapsedTime[8];
20 #endif
21   
22 #else
23 #include "DSTM/interface/dstm.h"
24 #include "DSTM/interface/altprelookup.h"
25 #include "DSTM/interface/prefetch.h"
26 #endif
27 #endif
28 #ifdef STM
29 #include "tm.h"
30 #include <pthread.h>
31 #endif
32 #ifdef STMLOG
33 #define ARRAY_LENGTH 700003
34 __thread int counter;
35 __thread int event[ARRAY_LENGTH];
36 __thread unsigned long long clkticks[ARRAY_LENGTH];
37 unsigned long long beginClock=0;
38 #define FILENAME  "log"
39 #endif
40 #ifdef EVENTMONITOR
41 #include "monitor.h"
42 __thread int objcount=0;
43 #define ASSIGNUID(x) {                                  \
44     int number=((objcount++)<<EVTHREADSHIFT)|threadnum; \
45     x->objuid=number;                                   \
46   }
47 #else
48 #define ASSIGNUID(x)
49 #endif
50
51 #if defined(THREADS)||defined(STM)
52 /* Global barrier for STM */
53 pthread_barrier_t barrier;
54 pthread_barrierattr_t attr;
55 #endif
56
57 #include <string.h>
58
59 #ifndef bool
60 #define bool int
61 #endif
62
63 extern int classsize[];
64 extern int typearray[];
65 extern int typearray2[];
66 jmp_buf error_handler;
67 int instructioncount;
68
69 char *options;
70 int injectfailures=0;
71 float failurechance=0;
72 int errors=0;
73 int debugtask=0;
74 int injectinstructionfailures;
75 int failurecount;
76 float instfailurechance=0;
77 int numfailures;
78 int instaccum=0;
79 typedef unsigned long long ticks;
80 #ifdef DMALLOC
81 #include "dmalloc.h"
82 #endif
83
84 int instanceof(struct ___Object___ *ptr, int type) {
85   int i=ptr->type;
86   do {
87     if (i==type)
88       return 1;
89     i=typearray[i];
90   } while(i!=-1);
91   i=ptr->type;
92   if (i>NUMCLASSES) {
93     do {
94       if (i==type)
95         return 1;
96       i=typearray2[i-NUMCLASSES];
97     } while(i!=-1);
98   }
99   return 0;
100 }
101
102 void exithandler(int sig, siginfo_t *info, void * uap) {
103   exit(0);
104 }
105
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);
112 }
113
114
115 /* This function inject failures */
116
117 void injectinstructionfailure() {
118 #ifdef TASK
119   if (injectinstructionfailures) {
120     if (numfailures==0)
121       return;
122     instructioncount=failurecount;
123     instaccum+=failurecount;
124     if ((((double)random())/RAND_MAX)<instfailurechance) {
125       if (numfailures>0)
126         numfailures--;
127       printf("FAILURE!!! %d\n",numfailures);
128       longjmp(error_handler,11);
129     }
130   }
131 #else
132 #ifdef THREADS
133   if (injectinstructionfailures) {
134     if (numfailures==0)
135       return;
136     instaccum+=failurecount;
137     if ((((double)random())/RAND_MAX)<instfailurechance) {
138       if (numfailures>0)
139         numfailures--;
140       printf("FAILURE!!! %d\n",numfailures);
141       threadexit();
142     }
143   }
144 #endif
145 #endif
146 }
147
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___;
154   int i;
155   int offset=VAR(___str___)->___offset___;
156   for(i=0; i<maxlength; i++) {
157     str[i]=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
158   }
159   str[i]=0;
160   double d=atof(str);
161   return d;
162 }
163 #endif
164
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___);
170   int i;
171   for(i=0; i<maxlength; i++) {
172     str[i]=(((char *)&bytearray->___length___)+sizeof(int))[i+start];
173   }
174   str[i]=0;
175   double d=atof(str);
176   return d;
177 }
178 #endif
179
180 #ifdef D___Double______doubleToRawLongBits____D 
181 typedef union jvalue
182 {
183   bool z;
184   char    c;
185   short   s;
186   int     i;
187   long long    j;
188   float   f;
189   double  d;
190 } jvalue;
191
192 long long CALL11(___Double______doubleToRawLongBits____D, double dval, double dval) {
193   jvalue val;
194   val.d = dval;
195
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. */
200
201 #define SWAP_DOUBLE(a)    (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
202
203   val.j = SWAP_DOUBLE(val.j);
204 #endif
205
206   return val.j;
207 }
208 #endif
209
210 #ifdef D___Double______longBitsToDouble____J 
211 double CALL11(___Double______longBitsToDouble____J, long long lval, long long lval) {
212   jvalue val;
213   val.j = lval;
214
215 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
216 #ifndef SWAP_DOUBLE
217 #define SWAP_DOUBLE(a)    (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
218 #endif
219   val.j = SWAP_DOUBLE(val.j);
220 #endif
221
222   return val.d;
223 }
224 #endif
225
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___;
229   char str[length];
230   int i;
231   int num=snprintf(str, length, "%f",___val___);
232   if (num>=length)
233     num=length-1;
234   for(i=0; i<length; i++) {
235     ((short *)(((char *)&VAR(___chararray___)->___length___)+sizeof(int)))[i]=(short)str[i];
236   }
237   return num;
238 }
239 #endif
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];
244 #ifdef STMARRAY
245   src=src->___objlocation___;
246 #endif
247   if (dsttype<NUMCLASSES||srctype<NUMCLASSES||srctype!=dsttype)
248     return;
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)
254     return;
255   unsigned INTPTR *pointer=pointerarray[srctype];
256   if (pointer==0) {
257     int elementsize=classsize[srctype];
258     int size=srclength*elementsize;
259     //primitives
260     memcpy(((char *)&aodst->___length___)+sizeof(int) , ((char *)&aosrc->___length___)+sizeof(int), size);
261   } else {
262     //objects
263     int i;
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);
270       } else {
271         //hit an object
272         ((struct ___Object___ **)(((char*) &aodst->___length___)+sizeof(int)))[i]=ptr;
273       }
274     }
275   }
276 }
277
278 void CALL02(___System______deepArrayCopy____L___Object____L___Object___, struct ___Object___ * ___dst___, struct ___Object___ * ___src___) {
279   deepArrayCopy(VAR(___dst___), VAR(___src___));
280 }
281 #endif
282
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];
287
288   //not an array or type mismatch
289   if (dsttype<NUMCLASSES||srctype<NUMCLASSES||srctype!=dsttype)
290     return;
291
292   struct ArrayObject *aodst=(struct ArrayObject *)dst;
293   struct ArrayObject *aosrc=(struct ArrayObject *)src;
294   int dstlength=aodst->___length___;
295   int srclength=aosrc->___length___;
296
297   if (length<=0)
298     return;
299   if (srcPos+length>srclength)
300     return;
301   if (destPos+length>dstlength)
302     return;
303
304   unsigned INTPTR *pointer=pointerarray[srctype];
305   if (pointer==0) {
306     int elementsize=classsize[srctype];
307     int size=length*elementsize;
308     //primitives
309     memcpy(((char *)&aodst->___length___)+sizeof(int)+destPos*elementsize, ((char *)&aosrc->___length___)+sizeof(int)+srcPos*elementsize, size);
310   } else {
311     //objects
312     int i;
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];
316       //hit an object
317       ((struct ___Object___ **)(((char*) &aodst->___length___)+sizeof(int)))[i+destPos]=ptr;
318     }
319   }
320 }
321
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___);
324 }
325 #endif
326
327 void CALL11(___System______exit____I,int ___status___, int ___status___) {
328 #ifdef TRANSSTATS
329 #ifndef RECOVERY
330   printf("numTransCommit = %d\n", numTransCommit);
331   printf("numTransAbort = %d\n", numTransAbort);
332   printf("nSoftAbort = %d\n", nSoftAbort);
333 #endif
334 #ifdef STM
335   printf("nSoftAbortCommit = %d\n", nSoftAbortCommit);
336   printf("nSoftAbortAbort = %d\n", nSoftAbortAbort);
337 #ifdef STMSTATS
338   int i;
339   for(i=0; i<TOTALNUMCLASSANDARRAY; i++) {
340     printf("typesCausingAbort[%2d] numaccess= %5d numabort= %3d\n", i, typesCausingAbort[i].numaccess, typesCausingAbort[i].numabort);
341   }
342 #endif
343 #endif
344 #endif
345 #ifdef EVENTMONITOR
346   dumpdata();
347 #endif
348   exit(___status___);
349 }
350
351 void CALL11(___System______logevent____I,int ___event___, int ___event___) {
352 #ifdef STMLOG
353   event[counter] = ___event___;
354   clkticks[counter] = rdtsc();
355   counter++;
356 #endif
357   return;
358 }
359
360 void CALL00(___System______logevent____) {
361 #ifdef STMLOG
362   beginClock= rdtsc();
363 #endif
364   return;
365 }
366
367 void CALL11(___System______flushToFile____I, int ___threadid___, int ___threadid___) {
368 #ifdef STMLOG
369   FILE *fp;
370   /* Flush to file */
371   char filename[20];
372   memset(filename, 0, 20);
373   sprintf(filename, "%s_%d", FILENAME, ___threadid___);
374   if ((fp = fopen(filename, "w+")) == NULL) {
375     perror("fopen");
376     return;
377   }
378   int i;
379   for (i = 0; i < counter-1; i++) {
380     fprintf(fp, "%d %lld %lld\n", event[i], clkticks[i]-beginClock, clkticks[i+1]-beginClock);
381   }
382   fprintf(fp, "%d %lld\n", event[i], clkticks[i]-beginClock);
383
384   fclose(fp);
385 #endif
386   return;
387 }
388
389 void CALL00(___System______initLog____) {
390 #ifdef STMLOG
391   counter=0;
392   int i;
393   for(i=0; i<ARRAY_LENGTH; i++) {
394     event[i] = 0;
395     clkticks[i] = 0;
396   }
397
398 #endif
399   return;
400 }
401
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 *));
406 }
407 #endif
408
409 void CALL11(___System______printI____I,int ___status___, int ___status___) {
410   printf("%d\n",___status___);
411 }
412
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 */
419   return retval;
420 }
421
422 long long CALL00(___System______microTimes____) {
423   struct timeval tv; 
424   long long retval;
425   gettimeofday(&tv, NULL);
426   retval = tv.tv_sec; /* seconds */
427   retval*=1000000; /* microsecs */
428   retval+= (tv.tv_usec); /* adjust microseconds & add them in */
429   return retval;
430 }
431
432 long long CALL00(___System______getticks____) {
433   unsigned a, d;
434   asm("cpuid");
435   asm volatile("rdtsc" : "=a" (a), "=d" (d));
436   return (((ticks)a) | (((ticks)d) << 32));
437 }
438
439 void CALL01(___System______printString____L___String___,struct ___String___ * ___s___) {
440   struct ArrayObject * chararray=VAR(___s___)->___value___;
441   int i;
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];
445     putchar(sc);
446   }
447 #ifdef RECOVERYSTATS
448   fflush(stdout);
449   fflush(stdout);
450 #endif
451 }
452
453 #ifdef D___RecoveryStat______printRecoveryStat____ 
454 #ifdef RECOVERYSTATS
455 void CALL00(___RecoveryStat______printRecoveryStat____) {
456   printRecoveryStat();
457 }
458 #else
459 void CALL00(___RecoveryStat______printRecoveryStat____) {
460   printf("No Stat\n");
461   fflush(stdout);
462 }
463 #endif
464 #endif
465
466 #ifdef DSTM
467 void CALL00(___System______clearPrefetchCache____) {
468   prehashClear();
469 }
470
471 #ifdef RANGEPREFETCH
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___;
477   int i;
478   short offArry[numoffset+2];
479   offArry[0] = 0;
480   offArry[1] = 0;
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]);
484   }
485   unsigned int oid;
486   if(((unsigned int)(VAR(___o___)) & 1) != 0) { //odd
487     oid =  (unsigned int) VAR(___o___); //outside transaction therefore just an oid
488   } else { //even
489     oid = (unsigned int) COMPOID(VAR(___o___)); //inside transaction therefore a pointer to oid
490   }
491   rangePrefetch(oid, (short)(numoffset+2), offArry);
492 }
493 #else
494 void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) {
495   return;
496 }
497 #endif
498
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___)
503 {
504   unsigned int oid;
505   oid = (unsigned int) VAR(___this___);   // object id
506   int type = getObjType(oid);             // object type
507
508 #ifdef PRECISE_GC
509   int p[] = {1,0 , oid};
510   ((void(*) (void *))virtualtable[type*MAXCOUNT + EXECUTEMETHOD])(p);
511 #else
512   // call the proper execute method
513   ((void(*) (void *))virtualtable[type*MAXCOUNT + EXECUTEMETHOD])(oid);
514 #endif
515 }
516 #endif
517
518 #endif // DSTM
519
520 /* STM Barrier constructs */
521 #ifdef D___Barrier______setBarrier____I
522 void CALL11(___Barrier______setBarrier____I, int nthreads, int nthreads) {
523   // Barrier initialization
524   int ret;
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__);
527     exit(-1);
528   }
529 }
530 #endif
531
532 #ifdef D___Barrier______enterBarrier____
533 void CALL00(___Barrier______enterBarrier____) {
534   // Synchronization point
535   int ret;
536 #ifdef EVENTMONITOR
537   EVLOGEVENT(EV_ENTERBARRIER);
538 #endif
539 #ifdef PRECISE_GC
540   stopforgc((struct garbagelist *)___params___);
541 #endif
542   ret = pthread_barrier_wait(&barrier);
543 #ifdef PRECISE_GC
544   restartaftergc();
545 #endif
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__);
548     exit(-1);
549   }
550 #ifdef EVENTMONITOR
551   EVLOGEVENT(EV_EXITBARRIER);
552 #endif
553 }
554 #endif
555
556 /* Object allocation function */
557
558 #ifdef DSTM
559 __attribute__((malloc)) void * allocate_newglobal(int type) {
560   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(classsize[type]);
561   v->type=type;
562   //printf("DEBUG %s(), type= %x\n", __func__, type);
563 #ifdef THREADS
564   v->tid=0;
565   v->lockentry=0;
566   v->lockcount=0;
567 #endif
568   return v;
569 }
570
571 /* Array allocation function */
572
573 __attribute__((malloc)) struct ArrayObject * allocate_newarrayglobal(int type, int length) {
574   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(sizeof(struct ArrayObject)+length*classsize[type]);
575   if (length<0) {
576     printf("ERROR: negative array\n");
577     return NULL;
578   }
579   v->type=type;
580   v->___length___=length;
581 #ifdef THREADS
582   v->tid=0;
583   v->lockentry=0;
584   v->lockcount=0;
585 #endif
586   return v;
587 }
588 #endif
589
590
591 #ifdef STM
592 // STM Versions of allocation functions
593
594 /* Object allocation function */
595 __attribute__((malloc)) void * allocate_newtrans(void * ptr, int type) {
596 #ifdef STMARRAY
597   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type], 0);
598 #else
599   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type]);
600 #endif
601   ASSIGNUID(v);
602   v->type=type;
603   v->___objlocation___=v;
604   return v;
605 }
606
607 /* Array allocation function */
608 __attribute__((malloc)) struct ArrayObject * allocate_newarraytrans(void * ptr, int type, int length) {
609 #ifdef STMARRAY
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--) {
618     intptr-=2;
619     intptr[0]=1;
620   }
621   v->highindex=-1;
622   v->lowindex=MAXARRAYSIZE;
623 #else
624   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+length*classsize[type]);
625 #endif
626   ASSIGNUID(v);
627   if (length<0) {
628     printf("ERROR: negative array\n");
629     return NULL;
630   }
631   v->___objlocation___=(struct ___Object___*)v;
632   v->type=type;
633   v->___length___=length;
634   return v;
635 }
636
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];
640   ASSIGNUID(v);
641   initdsmlocks(&tmp->lock);
642   tmp->version = 1;
643   v->___objlocation___=v;
644   v->type = type;
645   return v;
646 }
647
648 /* Array allocation function */
649
650 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
651 #ifdef STMARRAY
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--) {
659     tmpint[0]=1;
660     tmpint+=2;
661   }
662   objheader_t *tmp=(objheader_t *)tmpint;
663   struct ArrayObject * v=(struct ArrayObject *) &tmp[1];
664   v->highindex=-1;
665   v->lowindex=MAXARRAYSIZE;
666 #else
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];
669 #endif
670 #ifdef DUALVIEW
671   tmp->lock=RW_LOCK_BIAS;
672 #else
673   initdsmlocks(&tmp->lock);
674 #endif
675   tmp->version=1;
676   ASSIGNUID(v);
677   v->type=type;
678   if (length<0) {
679     printf("ERROR: negative array %d\n", length);
680     return NULL;
681   }
682   v->___objlocation___=(struct ___Object___ *)v;
683   v->___length___=length;
684   return v;
685 }
686 #endif
687
688 #ifndef STM
689 #if defined(PRECISE_GC)
690 #ifdef MLP
691 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
692   return allocate_new_mlp(ptr, type, 0, 0);
693 }
694 __attribute__((malloc)) void * allocate_new_mlp(void * ptr, int type, int oid, int allocsite) {
695 #else
696 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
697 #endif
698   struct ___Object___ * v=(struct ___Object___ *) mygcmalloc((struct garbagelist *) ptr, classsize[type]);
699   v->type=type;
700 #ifdef THREADS
701   v->tid=0;
702   v->lockentry=0;
703   v->lockcount=0;
704 #endif
705 #ifdef OPTIONAL
706   v->fses=0;
707 #endif
708 #ifdef MLP
709   v->oid=oid;
710   v->allocsite=allocsite;
711 #endif
712   return v;
713 }
714
715 /* Array allocation function */
716 #ifdef MLP
717 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
718   return allocate_newarray_mlp(ptr, type, length, 0, 0);
719 }
720  __attribute__((malloc)) struct ArrayObject * allocate_newarray_mlp(void * ptr, int type, int length, int oid, int allocsite) {
721 #else
722 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
723 #endif
724   struct ArrayObject * v=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]);
725   v->type=type;
726   if (length<0) {
727     printf("ERROR: negative array\n");
728     return NULL;
729   }
730   v->___length___=length;
731 #ifdef THREADS
732   v->tid=0;
733   v->lockentry=0;
734   v->lockcount=0;
735 #endif
736 #ifdef OPTIONAL
737   v->fses=0;
738 #endif
739 #ifdef MLP
740   v->oid=oid;
741   v->allocsite=allocsite;
742 #endif
743   return v;
744 }
745
746 #else
747 __attribute__((malloc)) void * allocate_new(int type) {
748   struct ___Object___ * v=FREEMALLOC(classsize[type]);
749   v->type=type;
750 #ifdef OPTIONAL
751   v->fses=0;
752 #endif
753   return v;
754 }
755
756 /* Array allocation function */
757
758 __attribute__((malloc)) struct ArrayObject * allocate_newarray(int type, int length) {
759   __attribute__((malloc))  struct ArrayObject * v=FREEMALLOC(sizeof(struct ArrayObject)+length*classsize[type]);
760   v->type=type;
761   v->___length___=length;
762 #ifdef OPTIONAL
763   v->fses=0;
764 #endif
765   return v;
766 }
767 #endif
768 #endif
769
770 /* Converts C character arrays into Java strings */
771 #ifdef PRECISE_GC
772 __attribute__((malloc)) struct ___String___ * NewString(void * ptr, const char *str,int length) {
773 #else
774 __attribute__((malloc)) struct ___String___ * NewString(const char *str,int length) {
775 #endif
776   int i;
777 #ifdef PRECISE_GC
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];
782 #else
783   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
784   struct ___String___ * strobj=allocate_new(STRINGTYPE);
785 #endif
786   strobj->___value___=chararray;
787   strobj->___count___=length;
788   strobj->___offset___=0;
789
790   for(i=0; i<length; i++) {
791     ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
792   }
793   return strobj;
794 }
795
796 /* Generated code calls this if we fail a bounds check */
797
798 void failedboundschk() {
799 #ifndef TASK
800   printf("Array out of bounds\n");
801 #ifdef THREADS
802   threadexit();
803 #else
804   exit(-1);
805 #endif
806 #else
807   longjmp(error_handler,2);
808 #endif
809 }
810
811 /* Abort task call */
812 void abort_task() {
813 #ifdef TASK
814   longjmp(error_handler,4);
815 #else
816   printf("Aborting\n");
817   exit(-1);
818 #endif
819 }
820
821 #ifndef SANDBOX
822 #ifdef D___System______Assert____Z
823  void CALL11(___System______Assert____Z, int ___status___, int ___status___) {
824    if (!___status___) {
825      printf("Assertion violation\n");
826      *((int *)(NULL)); //force stack trace error
827    }
828  }
829 #endif
830 #endif