Fix: need to keep the number of allocation site for the heap examiner. Somehow the...
[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
11 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
12 #include "thread.h"
13 #endif
14
15 #ifdef DSTM
16 #ifdef RECOVERY
17 #include "DSTM/interface_recovery/dstm.h"
18 #include "DSTM/interface_recovery/altprelookup.h"
19
20 #ifdef RECOVERYSTATS
21 extern int numRecovery;
22 extern unsigned int deadMachine[8];
23 extern unsigned int sizeOfRedupedData[8];
24 extern double elapsedTime[8];
25 #endif
26
27 #else
28 #include "DSTM/interface/dstm.h"
29 #include "DSTM/interface/altprelookup.h"
30 #include "DSTM/interface/prefetch.h"
31 #endif
32 #endif
33 #ifdef STM
34 #include "tm.h"
35 #include <pthread.h>
36 #endif
37 #ifdef STMLOG
38 #define ARRAY_LENGTH 700003
39 __thread int counter;
40 __thread int event[ARRAY_LENGTH];
41 __thread unsigned long long clkticks[ARRAY_LENGTH];
42 unsigned long long beginClock=0;
43 #define FILENAME  "log"
44 #endif
45 #ifdef EVENTMONITOR
46 #include "monitor.h"
47 __thread int objcount=0;
48 #define ASSIGNUID(x) {                                  \
49     int number=((objcount++)<<EVTHREADSHIFT)|threadnum; \
50     x->objuid=number;                                   \
51 }
52 #else
53 #define ASSIGNUID(x)
54 #endif
55
56 #if defined(THREADS)||defined(STM)
57 #ifndef MAC
58 /* Global barrier for STM */
59 pthread_barrier_t barrier;
60 pthread_barrierattr_t attr;
61 #endif
62 #endif
63
64 #include <string.h>
65
66 #ifndef bool
67 #define bool int
68 #endif
69 #define GCPOINT(x) ((INTPTR)((x)*0.99))
70
71
72 extern int classsize[];
73 extern int typearray[];
74 extern int typearray2[];
75 jmp_buf error_handler;
76 int instructioncount;
77
78 char *options;
79 int injectfailures=0;
80 float failurechance=0;
81 int errors=0;
82 int debugtask=0;
83 int injectinstructionfailures;
84 int failurecount;
85 float instfailurechance=0;
86 int numfailures;
87 int instaccum=0;
88 typedef unsigned long long ticks;
89 #ifdef DMALLOC
90 #include "dmalloc.h"
91 #endif
92
93 int instanceof(ObjectPtr ptr, int type) {
94   int i=ptr->type;
95   do {
96     if (i==type)
97       return 1;
98     i=typearray[i];
99   } while(i!=-1);
100   i=ptr->type;
101   if (i>NUMCLASSES) {
102     do {
103       if (i==type)
104         return 1;
105       i=typearray2[i-NUMCLASSES];
106     } while(i!=-1);
107   }
108   return 0;
109 }
110
111 void exithandler(int sig, siginfo_t *info, void * uap) {
112   exit(0);
113 }
114
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);
121 }
122
123
124 /* This function inject failures */
125
126 void injectinstructionfailure() {
127 #ifdef TASK
128   if (injectinstructionfailures) {
129     if (numfailures==0)
130       return;
131     instructioncount=failurecount;
132     instaccum+=failurecount;
133     if ((((double)random())/RAND_MAX)<instfailurechance) {
134       if (numfailures>0)
135         numfailures--;
136       printf("FAILURE!!! %d\n",numfailures);
137       longjmp(error_handler,11);
138     }
139   }
140 #else
141 #ifdef THREADS
142   if (injectinstructionfailures) {
143     if (numfailures==0)
144       return;
145     instaccum+=failurecount;
146     if ((((double)random())/RAND_MAX)<instfailurechance) {
147       if (numfailures>0)
148         numfailures--;
149       printf("FAILURE!!! %d\n",numfailures);
150       threadexit();
151     }
152   }
153 #endif
154 #endif
155 }
156
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___;
163   int i;
164   int offset=VAR(___str___)->___offset___;
165   for(i=0; i<maxlength; i++) {
166     str[i]=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
167   }
168   str[i]=0;
169   double d=atof(str);
170   return d;
171 }
172 #endif
173
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___);
179   int i;
180   for(i=0; i<maxlength; i++) {
181     str[i]=(((char *)&bytearray->___length___)+sizeof(int))[i+start];
182   }
183   str[i]=0;
184   double d=atof(str);
185   return d;
186 }
187 #endif
188
189 #ifdef D___Double______doubleToRawLongBits____D
190 typedef union jvalue {
191   bool z;
192   char c;
193   short s;
194   int i;
195   long long j;
196   float f;
197   double d;
198 } jvalue;
199
200 long long CALL11(___Double______doubleToRawLongBits____D, double dval, double dval) {
201   jvalue val;
202   val.d = dval;
203
204 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
205   /* On little endian ARM processors when using FPA, word order of
206      doubles is still big endian. So take that into account here. When
207      using VFP, word order of doubles follows byte order. */
208
209 #define SWAP_DOUBLE(a)    (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
210
211   val.j = SWAP_DOUBLE(val.j);
212 #endif
213
214   return val.j;
215 }
216 #endif
217
218 #ifdef D___Double______longBitsToDouble____J
219 double CALL11(___Double______longBitsToDouble____J, long long lval, long long lval) {
220   jvalue val;
221   val.j = lval;
222
223 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
224 #ifndef SWAP_DOUBLE
225 #define SWAP_DOUBLE(a)    (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
226 #endif
227   val.j = SWAP_DOUBLE(val.j);
228 #endif
229
230   return val.d;
231 }
232 #endif
233
234 #ifdef D___String______convertdoubletochar____D__AR_C
235 int CALL12(___String______convertdoubletochar____D__AR_C, double ___val___, double ___val___, struct ArrayObject ___chararray___) {
236   int length=VAR(___chararray___)->___length___;
237   char str[length];
238   int i;
239   int num=snprintf(str, length, "%f",___val___);
240   if (num>=length)
241     num=length-1;
242   for(i=0; i<length; i++) {
243     ((short *)(((char *)&VAR(___chararray___)->___length___)+sizeof(int)))[i]=(short)str[i];
244   }
245   return num;
246 }
247 #endif
248 #ifdef D___System______deepArrayCopy____L___Object____L___Object___
249 void deepArrayCopy(struct ___Object___ * dst, struct ___Object___ * src) {
250   int dsttype=((int *)dst)[0];
251   int srctype=((int *)src)[0];
252 #ifdef STMARRAY
253   src=src->___objlocation___;
254 #endif
255   if (dsttype<NUMCLASSES||srctype<NUMCLASSES||srctype!=dsttype)
256     return;
257   struct ArrayObject *aodst=(struct ArrayObject *)dst;
258   struct ArrayObject *aosrc=(struct ArrayObject *)src;
259   int dstlength=aodst->___length___;
260   int srclength=aosrc->___length___;
261   if (dstlength!=srclength)
262     return;
263   unsigned INTPTR *pointer=pointerarray[srctype];
264   if (pointer==0) {
265     int elementsize=classsize[srctype];
266     int size=srclength*elementsize;
267     //primitives
268     memcpy(((char *)&aodst->___length___)+sizeof(int), ((char *)&aosrc->___length___)+sizeof(int), size);
269   } else {
270     //objects
271     int i;
272     for(i=0; i<srclength; i++) {
273       struct ___Object___ * ptr=((struct ___Object___**)(((char*) &aosrc->___length___)+sizeof(int)))[i];
274       int ptrtype=((int *)ptr)[0];
275       if (ptrtype>=NUMCLASSES) {
276         struct ___Object___ * dstptr=((struct ___Object___**)(((char*) &aodst->___length___)+sizeof(int)))[i];
277         deepArrayCopy(dstptr,ptr);
278       } else {
279         //hit an object
280         ((struct ___Object___ **)(((char*) &aodst->___length___)+sizeof(int)))[i]=ptr;
281       }
282     }
283   }
284 }
285
286 void CALL02(___System______deepArrayCopy____L___Object____L___Object___, struct ___Object___ * ___dst___, struct ___Object___ * ___src___) {
287   deepArrayCopy(VAR(___dst___), VAR(___src___));
288 }
289 #endif
290
291 #ifdef D___System______arraycopy____L___Object____I_L___Object____I_I
292 void arraycopy(struct ___Object___ *src, int srcPos, struct ___Object___ *dst, int destPos, int length) {
293   int dsttype=((int *)dst)[0];
294   int srctype=((int *)src)[0];
295
296   //not an array or type mismatch
297   if (dsttype<NUMCLASSES||srctype<NUMCLASSES)
298     return;
299   if (srctype!=dsttype)
300     printf("Potential type mismatch in arraycopy\n");
301
302   struct ArrayObject *aodst=(struct ArrayObject *)dst;
303   struct ArrayObject *aosrc=(struct ArrayObject *)src;
304   int dstlength=aodst->___length___;
305   int srclength=aosrc->___length___;
306
307   if (length<=0)
308     return;
309   if (srcPos+length>srclength)
310     return;
311   if (destPos+length>dstlength)
312     return;
313
314   unsigned INTPTR *pointer=pointerarray[srctype];
315   if (pointer==0) {
316     int elementsize=classsize[srctype];
317     int size=length*elementsize;
318     //primitives
319     memcpy(((char *)&aodst->___length___)+sizeof(int)+destPos*elementsize, ((char *)&aosrc->___length___)+sizeof(int)+srcPos*elementsize, size);
320   } else {
321     //objects
322     int i;
323     for(i=0; i<length; i++) {
324       struct ___Object___ * ptr=((struct ___Object___**)(((char*) &aosrc->___length___)+sizeof(int)))[i+srcPos];
325       //hit an object
326       ((struct ___Object___ **)(((char*) &aodst->___length___)+sizeof(int)))[i+destPos]=ptr;
327     }
328   }
329 }
330
331 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___) {
332   arraycopy(VAR(___src___), ___srcPos___, VAR(___dst___), ___destPos___, ___length___);
333 }
334 #endif
335
336 #ifdef D___Runtime______availableProcessors____
337 int CALL01(___Runtime______availableProcessors____, struct ___Runtime___ * ___this___) {
338   printf("Unimplemented Runtime.availableProcessors\n");
339   return 24;
340 }
341 #endif
342
343 #ifdef D___Runtime______freeMemory____
344 long long CALL01(___Runtime______freeMemory____, struct ___Runtime___ * ___this___) {
345   printf("Unimplemented Runtime.freeMemory\n");
346   return 1024*1024*1024;
347 }
348 #endif
349
350 #ifdef D___Runtime______totalMemory____
351 long long CALL01(___Runtime______totalMemory____, struct ___Runtime___ * ___this___) {
352   printf("Unimplemented Runtime.totalMemory\n");
353   return 1024*1024*1024;
354 }
355 #endif
356
357 #ifdef D___Runtime______maxMemory____
358 long long CALL01(___Runtime______maxMemory____, struct ___Runtime___ * ___this___) {
359   printf("Unimplemented Runtime.maxMemory\n");
360   return 1024*1024*1024;
361 }
362 #endif
363 #ifdef D___System______exit____I
364 void CALL11(___System______exit____I,int ___status___, int ___status___) {
365 #ifdef TRANSSTATS
366 #ifndef RECOVERY
367   printf("numTransCommit = %d\n", numTransCommit);
368   printf("numTransAbort = %d\n", numTransAbort);
369   printf("nSoftAbort = %d\n", nSoftAbort);
370 #endif
371 #ifdef STM
372   printf("nSoftAbortCommit = %d\n", nSoftAbortCommit);
373   printf("nSoftAbortAbort = %d\n", nSoftAbortAbort);
374 #ifdef STMSTATS
375   int i;
376   for(i=0; i<TOTALNUMCLASSANDARRAY; i++) {
377     printf("typesCausingAbort[%2d] numaccess= %5d numabort= %3d\n", i, typesCausingAbort[i].numaccess, typesCausingAbort[i].numabort);
378   }
379 #endif
380 #endif
381 #endif
382 #ifdef EVENTMONITOR
383   dumpdata();
384 #endif
385   exit(___status___);
386 }
387 #endif
388
389 #ifdef D___System______logevent____I
390 void CALL11(___System______logevent____I,int ___event___, int ___event___) {
391 #ifdef STMLOG
392   event[counter] = ___event___;
393   clkticks[counter] = rdtsc();
394   counter++;
395 #endif
396   return;
397 }
398 #endif
399
400 #ifdef ___System______logevent____
401 void CALL00(___System______logevent____) {
402 #ifdef STMLOG
403   beginClock= rdtsc();
404 #endif
405   return;
406 }
407 #endif
408
409 #ifdef ___System______flushToFile____I
410 void CALL11(___System______flushToFile____I, int ___threadid___, int ___threadid___) {
411 #ifdef STMLOG
412   FILE *fp;
413   /* Flush to file */
414   char filename[20];
415   memset(filename, 0, 20);
416   sprintf(filename, "%s_%d", FILENAME, ___threadid___);
417   if ((fp = fopen(filename, "w+")) == NULL) {
418     perror("fopen");
419     return;
420   }
421   int i;
422   for (i = 0; i < counter-1; i++) {
423     fprintf(fp, "%d %lld %lld\n", event[i], clkticks[i]-beginClock, clkticks[i+1]-beginClock);
424   }
425   fprintf(fp, "%d %lld\n", event[i], clkticks[i]-beginClock);
426
427   fclose(fp);
428 #endif
429   return;
430 }
431 #endif
432
433 #ifdef D___System______initLog____
434 void CALL00(___System______initLog____) {
435 #ifdef STMLOG
436   counter=0;
437   int i;
438   for(i=0; i<ARRAY_LENGTH; i++) {
439     event[i] = 0;
440     clkticks[i] = 0;
441   }
442
443 #endif
444   return;
445 }
446 #endif
447
448 #ifdef D___Vector______removeElement_____AR_L___Object____I_I
449 void CALL23(___Vector______removeElement_____AR_L___Object____I_I, int ___index___, int ___size___, struct ArrayObject * ___array___, int ___index___, int ___size___) {
450   char* offset=((char *)(&VAR(___array___)->___length___))+sizeof(unsigned int)+sizeof(void *)*___index___;
451   memmove(offset, offset+sizeof(void *),(___size___-___index___-1)*sizeof(void *));
452 }
453 #endif
454
455 #ifdef D___System______printI____I
456 void CALL11(___System______printI____I,int ___status___, int ___status___) {
457   printf("%d\n",___status___);
458 }
459 #endif
460
461 #ifdef D___System______currentTimeMillis____
462 long long CALL00(___System______currentTimeMillis____) {
463   struct timeval tv; long long retval;
464   gettimeofday(&tv, NULL);
465   retval = tv.tv_sec; /* seconds */
466   retval*=1000; /* milliseconds */
467   retval+= (tv.tv_usec/1000); /* adjust milliseconds & add them in */
468   return retval;
469 }
470 #endif
471
472 #ifdef D___System______gc____
473 void CALL00(___System______gc____) {
474 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
475   while (pthread_mutex_trylock(&gclock)!=0) {
476     stopforgc((struct garbagelist *)___params___);
477     restartaftergc();
478   }
479 #endif
480
481   /* Grow the to heap if necessary */
482   {
483     INTPTR curr_heapsize=curr_heaptop-curr_heapbase;
484     INTPTR to_heapsize=to_heaptop-to_heapbase;
485
486     if (curr_heapsize>to_heapsize) {
487       free(to_heapbase);
488       to_heapbase=malloc(curr_heapsize);
489       if (to_heapbase==NULL) {
490         printf("Error Allocating enough memory\n");
491         exit(-1);
492       }
493       to_heaptop=to_heapbase+curr_heapsize;
494       to_heapptr=to_heapbase;
495     }
496   }
497
498
499   collect((struct garbagelist *)___params___);
500
501   {
502     void * tmp=to_heapbase;
503     to_heapbase=curr_heapbase;
504     curr_heapbase=tmp;
505
506     tmp=to_heaptop;
507     to_heaptop=curr_heaptop;
508     curr_heaptop=tmp;
509
510     tmp=to_heapptr;
511     curr_heapptr=to_heapptr;
512     curr_heapgcpoint=((char *) curr_heapbase)+GCPOINT(curr_heaptop-curr_heapbase);
513     to_heapptr=to_heapbase;
514     bzero(tmp, curr_heaptop-tmp);
515
516   }
517
518 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
519   pthread_mutex_unlock(&gclock);
520 #endif
521 }
522 #endif
523
524 #ifdef D___System______microTimes____
525 long long CALL00(___System______microTimes____) {
526   struct timeval tv;
527   long long retval;
528   gettimeofday(&tv, NULL);
529   retval = tv.tv_sec; /* seconds */
530   retval*=1000000; /* microsecs */
531   retval+= (tv.tv_usec); /* adjust microseconds & add them in */
532   return retval;
533 }
534 #endif
535
536 #ifdef D___System______getticks____
537 long long CALL00(___System______getticks____) {
538   unsigned a, d;
539   asm ("cpuid");
540   asm volatile ("rdtsc" : "=a" (a), "=d" (d));
541   return (((ticks)a) | (((ticks)d) << 32));
542 }
543 #endif
544
545 #ifdef D___System______printString____L___String___
546 void CALL01(___System______printString____L___String___,struct ___String___ * ___s___) {
547   struct ArrayObject * chararray=VAR(___s___)->___value___;
548   int i;
549   int offset=VAR(___s___)->___offset___;
550   for(i=0; i<VAR(___s___)->___count___; i++) {
551     short sc=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
552     putchar(sc);
553   }
554 #ifdef RECOVERYSTATS
555   fflush(stdout);
556   fflush(stdout);
557 #endif
558 }
559 #endif
560
561 #ifdef D___RecoveryStat______printRecoveryStat____
562 #ifdef RECOVERYSTATS
563 void CALL00(___RecoveryStat______printRecoveryStat____) {
564   printRecoveryStat();
565 }
566 #else
567 void CALL00(___RecoveryStat______printRecoveryStat____) {
568   printf("No Stat\n");
569   fflush(stdout);
570 }
571 #endif
572 #endif
573
574 #ifdef DSTM
575 #ifdef D___System______clearPrefetchCache____
576 void CALL00(___System______clearPrefetchCache____) {
577   prehashClear();
578 }
579 #endif
580
581 #ifdef RANGEPREFETCH
582 #ifdef D___System______rangePrefetch____L___Object_____AR_S
583 void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) {
584   /* Manual Prefetches to be inserted */
585   //printf("DEBUG-> %s() ___Object___ * ___o___ = %x\n", __func__, VAR(___o___));
586   //printf("DEBUG-> %s() ArrayObject * = %x\n", __func__, VAR(___offsets___));
587   int numoffset=VAR(___offsets___)->___length___;
588   int i;
589   short offArry[numoffset+2];
590   offArry[0] = 0;
591   offArry[1] = 0;
592   for(i = 2; i<(numoffset+2); i++) {
593     offArry[i] = *((short *)(((char *)&VAR(___offsets___)->___length___) + sizeof(int) + (i-2) * sizeof(short)));
594     //printf("DEBUG-> offArry[%d] = %d\n", i, offArry[i]);
595   }
596   unsigned int oid;
597   if(((unsigned int)(VAR(___o___)) & 1) != 0) { //odd
598     oid =  (unsigned int) VAR(___o___); //outside transaction therefore just an oid
599   } else { //even
600     oid = (unsigned int) COMPOID(VAR(___o___)); //inside transaction therefore a pointer to oid
601   }
602   rangePrefetch(oid, (short)(numoffset+2), offArry);
603 }
604 #else
605 void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) {
606   return;
607 }
608 #endif
609 #endif
610
611 #ifdef D___Task______execution____
612 extern void* virtualtable[];
613 // associated with Task.execution(). finds proper execute method and call it
614 void CALL01(___Task______execution____,struct ___Task___ * ___this___) {
615   unsigned int oid;
616   oid = (unsigned int) VAR(___this___);   // object id
617   int type = getObjType(oid);             // object type
618
619 #ifdef PRECISE_GC
620   int p[] = {1,0, oid};
621   ((void (*)(void *))virtualtable[type*MAXCOUNT + EXECUTEMETHOD])(p);
622 #else
623   // call the proper execute method
624   ((void (*)(void *))virtualtable[type*MAXCOUNT + EXECUTEMETHOD])(oid);
625 #endif
626 }
627 #endif
628
629 #endif // DSTM
630
631 /* STM Barrier constructs */
632 #ifdef D___Barrier______setBarrier____I
633 void CALL11(___Barrier______setBarrier____I, int nthreads, int nthreads) {
634   // Barrier initialization
635   int ret;
636   if((ret = pthread_barrier_init(&barrier, NULL, nthreads)) != 0) {
637     printf("%s() Could not create a barrier: numthreads = 0 in %s\n", __func__, __FILE__);
638     exit(-1);
639   }
640 }
641 #endif
642
643 #ifdef D___Barrier______enterBarrier____
644 void CALL00(___Barrier______enterBarrier____) {
645   // Synchronization point
646   int ret;
647 #ifdef EVENTMONITOR
648   EVLOGEVENT(EV_ENTERBARRIER);
649 #endif
650 #ifdef PRECISE_GC
651   stopforgc((struct garbagelist *)___params___);
652 #endif
653   ret = pthread_barrier_wait(&barrier);
654 #ifdef PRECISE_GC
655   restartaftergc();
656 #endif
657   if(ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) {
658     printf("%s() Could not wait on barrier: error %d in %s\n", __func__, errno, __FILE__);
659     exit(-1);
660   }
661 #ifdef EVENTMONITOR
662   EVLOGEVENT(EV_EXITBARRIER);
663 #endif
664 }
665 #endif
666
667 /* Object allocation function */
668
669 #ifdef DSTM
670 __attribute__((malloc)) void * allocate_newglobal(int type) {
671   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(classsize[type]);
672   v->type=type;
673   v->hashcode=(int)(INTPTR)v;
674   //printf("DEBUG %s(), type= %x\n", __func__, type);
675 #ifdef THREADS
676   v->tid=0;
677 #endif
678   return v;
679 }
680
681 /* Array allocation function */
682
683 __attribute__((malloc)) struct ArrayObject * allocate_newarrayglobal(int type, int length) {
684   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(sizeof(struct ArrayObject)+length*classsize[type]);
685   if (length<0) {
686     printf("ERROR: negative array\n");
687     return NULL;
688   }
689   v->type=type;
690   v->hashcode=(int)(INTPTR)v;
691   v->___length___=length;
692 #ifdef THREADS
693   v->tid=0;
694 #endif
695   return v;
696 }
697 #endif
698
699
700 #ifdef STM
701 // STM Versions of allocation functions
702
703 /* Object allocation function */
704 __attribute__((malloc)) void * allocate_newtrans(void * ptr, int type) {
705 #ifdef STMARRAY
706   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type], 0);
707 #else
708   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type]);
709 #endif
710   ASSIGNUID(v);
711   v->type=type;
712   v->hashcode=(int)(INTPTR)v;
713   v->___objlocation___=v;
714   return v;
715 }
716
717 /* Array allocation function */
718 __attribute__((malloc)) struct ArrayObject * allocate_newarraytrans(void * ptr, int type, int length) {
719 #ifdef STMARRAY
720   int basesize=length*classsize[type];
721   //round the base size up
722   basesize=(basesize+LOWMASK)&HIGHMASK;
723   int numlocks=basesize>>INDEXSHIFT;
724   int bookkeepsize=numlocks*2*sizeof(int);
725   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+basesize+bookkeepsize, bookkeepsize);
726   unsigned int *intptr=(unsigned int *)(((char *)v)-sizeof(objheader_t));
727   for(; numlocks>0; numlocks--) {
728     intptr-=2;
729     intptr[0]=1;
730   }
731   v->highindex=-1;
732   v->lowindex=MAXARRAYSIZE;
733 #else
734   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+length*classsize[type]);
735 #endif
736   ASSIGNUID(v);
737   if (length<0) {
738     printf("ERROR: negative array\n");
739     return NULL;
740   }
741   v->___objlocation___=(struct ___Object___*)v;
742   v->type=type;
743   v->hashcode=(int)(INTPTR)v;
744   v->___length___=length;
745   return v;
746 }
747
748 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
749   objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, classsize[type]+sizeof(objheader_t));
750   struct ___Object___ * v=(struct ___Object___ *) &tmp[1];
751   ASSIGNUID(v);
752   initdsmlocks(&tmp->lock);
753   tmp->version = 1;
754   v->___objlocation___=v;
755   v->type = type;
756   v->hashcode=(int)(INTPTR)v;
757   return v;
758 }
759
760 /* Array allocation function */
761
762 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
763 #ifdef STMARRAY
764   int basesize=length*classsize[type];
765   //round the base size up
766   basesize=(basesize+LOWMASK)&HIGHMASK;
767   int numlocks=basesize>>INDEXSHIFT;
768   int bookkeepsize=(numlocks)*2*sizeof(int);
769   int *tmpint=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+basesize+sizeof(objheader_t)+bookkeepsize);
770   for(; numlocks>0; numlocks--) {
771     tmpint[0]=1;
772     tmpint+=2;
773   }
774   objheader_t *tmp=(objheader_t *)tmpint;
775   struct ArrayObject * v=(struct ArrayObject *) &tmp[1];
776   v->highindex=-1;
777   v->lowindex=MAXARRAYSIZE;
778 #else
779   objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]+sizeof(objheader_t));
780   struct ArrayObject * v=(struct ArrayObject *) &tmp[1];
781 #endif
782 #ifdef DUALVIEW
783   tmp->lock=RW_LOCK_BIAS;
784 #else
785   initdsmlocks(&tmp->lock);
786 #endif
787   tmp->version=1;
788   ASSIGNUID(v);
789   v->type=type;
790   v->hashcode=(int)(INTPTR)v;
791   if (length<0) {
792     printf("ERROR: negative array %d\n", length);
793     return NULL;
794   }
795   v->___objlocation___=(struct ___Object___ *)v;
796   v->___length___=length;
797   return v;
798 }
799 #endif
800
801 #ifndef STM
802 #if defined(PRECISE_GC)
803 #ifdef MLP
804 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
805   return allocate_new_mlp(ptr, type, 0, 0);
806 }
807 __attribute__((malloc)) void * allocate_new_mlp(void * ptr, int type, int oid, int allocsite) {
808 #else
809 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
810 #endif
811   ObjectPtr v=(ObjectPtr) mygcmalloc((struct garbagelist *) ptr, classsize[type]);
812   v->type=type;
813   v->hashcode=(int)(INTPTR)v;
814 #ifdef THREADS
815   v->tid=0;
816 #endif
817 #ifdef OPTIONAL
818   v->fses=0;
819 #endif
820 #ifdef MLP
821   v->oid=oid;
822   v->allocsite=allocsite;
823 #endif
824   return v;
825 }
826
827 /* Array allocation function */
828 #ifdef MLP
829 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
830   return allocate_newarray_mlp(ptr, type, length, 0, 0);
831 }
832 __attribute__((malloc)) struct ArrayObject * allocate_newarray_mlp(void * ptr, int type, int length, int oid, int allocsite) {
833 #else
834 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
835 #endif
836   struct ArrayObject * v=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]);
837   v->type=type;
838   v->hashcode=(int)(INTPTR)v;
839   if (length<0) {
840     printf("ERROR: negative array\n");
841     return NULL;
842   }
843   v->___length___=length;
844 #ifdef THREADS
845   v->tid=0;
846 #endif
847 #ifdef OPTIONAL
848   v->fses=0;
849 #endif
850 #ifdef MLP
851   v->oid=oid;
852   v->allocsite=allocsite;
853 #endif
854   return v;
855 }
856
857 #else
858 __attribute__((malloc)) void * allocate_new(int type) {
859   ObjectPtr v=FREEMALLOC(classsize[type]);
860   v->type=type;
861   v->hashcode=(int)(INTPTR)v;
862 #ifdef OPTIONAL
863   v->fses=0;
864 #endif
865   return v;
866 }
867
868 /* Array allocation function */
869
870 __attribute__((malloc)) struct ArrayObject * allocate_newarray(int type, int length) {
871   __attribute__((malloc))  struct ArrayObject * v=FREEMALLOC(sizeof(struct ArrayObject)+length*classsize[type]);
872   v->type=type;
873   v->hashcode=(int)(INTPTR)v;
874   v->___length___=length;
875 #ifdef OPTIONAL
876   v->fses=0;
877 #endif
878   return v;
879 }
880 #endif
881 #endif
882
883 /* Converts C character arrays into Java strings */
884 #ifdef PRECISE_GC
885 __attribute__((malloc)) StringPtr NewStringShort(void * ptr, const short *str,int length) {
886 #else
887 __attribute__((malloc)) StringPtr NewStringShort(const short *str,int length) {
888 #endif
889   int i;
890 #ifdef PRECISE_GC
891   struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
892   INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
893   StringPtr strobj=allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
894   chararray=(struct ArrayObject *) ptrarray[2];
895 #else
896   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
897   StringPtr strobj=allocate_new(STRINGTYPE);
898 #endif
899   strobj->___value___=chararray;
900   strobj->___count___=length;
901   strobj->___offset___=0;
902
903   for(i=0; i<length; i++) {
904     ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=str[i];
905   }
906   return strobj;
907 }
908
909 /* Converts C character arrays into Java strings */
910 #ifdef PRECISE_GC
911 __attribute__((malloc)) StringPtr NewString(void * ptr, const char *str,int length) {
912 #else
913 __attribute__((malloc)) StringPtr NewString(const char *str,int length) {
914 #endif
915   int i;
916 #ifdef PRECISE_GC
917   struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
918   INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
919   StringPtr strobj=allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
920   chararray=(struct ArrayObject *) ptrarray[2];
921 #else
922   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
923   StringPtr strobj=allocate_new(STRINGTYPE);
924 #endif
925   strobj->___value___=chararray;
926   strobj->___count___=length;
927   strobj->___offset___=0;
928
929   for(i=0; i<length; i++) {
930     ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
931   }
932   return strobj;
933 }
934
935 /* Generated code calls this if we fail a bounds check */
936
937  void failedboundschk(int num, int index, struct ArrayObject * ao ) {
938 #ifndef TASK
939    printf("Array out of bounds at line %u with index %u of object %x with length %u\n", num, index, ao, ao->___length___);
940 #ifdef THREADS
941   threadexit();
942 #else
943   exit(-1);
944 #endif
945 #else
946   longjmp(error_handler,2);
947 #endif
948 }
949
950 /* Abort task call */
951 void abort_task() {
952 #ifdef TASK
953   longjmp(error_handler,4);
954 #else
955   printf("Aborting\n");
956   exit(-1);
957 #endif
958 }
959
960 #ifndef SANDBOX
961 #ifdef D___System______Assert____Z
962 void CALL11(___System______Assert____Z, int ___status___, int ___status___) {
963   if (!___status___) {
964     printf("Assertion violation\n");
965     *((int *)(NULL));  //force stack trace error
966   }
967 }
968 #endif
969 #endif