checkin to only generate C for callable methods...
[IRC.git] / Robust / src / Runtime / runtime.c
1
2 #include "runtime.h"
3 #include "structdefs.h"
4 #include <signal.h>
5 #include "mem.h"
6 #include <fcntl.h>
7 #include <errno.h>
8 #include <stdio.h>
9 #include "option.h"
10 #include "methodheaders.h"
11
12 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
13 #include "thread.h"
14 #endif
15
16 #ifdef DSTM
17 #ifdef RECOVERY
18 #include "DSTM/interface_recovery/dstm.h"
19 #include "DSTM/interface_recovery/altprelookup.h"
20
21 #ifdef RECOVERYSTATS
22   extern int numRecovery;
23   extern unsigned int deadMachine[8];
24   extern unsigned int sizeOfRedupedData[8];
25   extern double elapsedTime[8];
26 #endif
27   
28 #else
29 #include "DSTM/interface/dstm.h"
30 #include "DSTM/interface/altprelookup.h"
31 #include "DSTM/interface/prefetch.h"
32 #endif
33 #endif
34 #ifdef STM
35 #include "tm.h"
36 #include <pthread.h>
37 #endif
38 #ifdef STMLOG
39 #define ARRAY_LENGTH 700003
40 __thread int counter;
41 __thread int event[ARRAY_LENGTH];
42 __thread unsigned long long clkticks[ARRAY_LENGTH];
43 unsigned long long beginClock=0;
44 #define FILENAME  "log"
45 #endif
46 #ifdef EVENTMONITOR
47 #include "monitor.h"
48 __thread int objcount=0;
49 #define ASSIGNUID(x) {                                  \
50     int number=((objcount++)<<EVTHREADSHIFT)|threadnum; \
51     x->objuid=number;                                   \
52   }
53 #else
54 #define ASSIGNUID(x)
55 #endif
56
57 #if defined(THREADS)||defined(STM)
58 /* Global barrier for STM */
59 pthread_barrier_t barrier;
60 pthread_barrierattr_t attr;
61 #endif
62
63 #include <string.h>
64
65 #ifndef bool
66 #define bool int
67 #endif
68 #define GCPOINT(x) ((INTPTR)((x)*0.99))
69
70
71 extern int classsize[];
72 extern int typearray[];
73 extern int typearray2[];
74 jmp_buf error_handler;
75 int instructioncount;
76
77 char *options;
78 int injectfailures=0;
79 float failurechance=0;
80 int errors=0;
81 int debugtask=0;
82 int injectinstructionfailures;
83 int failurecount;
84 float instfailurechance=0;
85 int numfailures;
86 int instaccum=0;
87 typedef unsigned long long ticks;
88 #ifdef DMALLOC
89 #include "dmalloc.h"
90 #endif
91
92 int instanceof(struct ___Object___ *ptr, int type) {
93   int i=ptr->type;
94   do {
95     if (i==type)
96       return 1;
97     i=typearray[i];
98   } while(i!=-1);
99   i=ptr->type;
100   if (i>NUMCLASSES) {
101     do {
102       if (i==type)
103         return 1;
104       i=typearray2[i-NUMCLASSES];
105     } while(i!=-1);
106   }
107   return 0;
108 }
109
110 void exithandler(int sig, siginfo_t *info, void * uap) {
111   exit(0);
112 }
113
114 void initializeexithandler() {
115   struct sigaction sig;
116   sig.sa_sigaction=&exithandler;
117   sig.sa_flags=SA_SIGINFO;
118   sigemptyset(&sig.sa_mask);
119   sigaction(SIGUSR2, &sig, 0);
120 }
121
122
123 /* This function inject failures */
124
125 void injectinstructionfailure() {
126 #ifdef TASK
127   if (injectinstructionfailures) {
128     if (numfailures==0)
129       return;
130     instructioncount=failurecount;
131     instaccum+=failurecount;
132     if ((((double)random())/RAND_MAX)<instfailurechance) {
133       if (numfailures>0)
134         numfailures--;
135       printf("FAILURE!!! %d\n",numfailures);
136       longjmp(error_handler,11);
137     }
138   }
139 #else
140 #ifdef THREADS
141   if (injectinstructionfailures) {
142     if (numfailures==0)
143       return;
144     instaccum+=failurecount;
145     if ((((double)random())/RAND_MAX)<instfailurechance) {
146       if (numfailures>0)
147         numfailures--;
148       printf("FAILURE!!! %d\n",numfailures);
149       threadexit();
150     }
151   }
152 #endif
153 #endif
154 }
155
156 #ifdef D___Double______nativeparsedouble____L___String___
157 double CALL01(___Double______nativeparsedouble____L___String___,struct ___String___ * ___str___) {
158   int length=VAR(___str___)->___count___;
159   int maxlength=(length>60)?60:length;
160   char str[maxlength+1];
161   struct ArrayObject * chararray=VAR(___str___)->___value___;
162   int i;
163   int offset=VAR(___str___)->___offset___;
164   for(i=0; i<maxlength; i++) {
165     str[i]=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
166   }
167   str[i]=0;
168   double d=atof(str);
169   return d;
170 }
171 #endif
172
173 #ifdef D___Double______nativeparsedouble_____AR_B_I_I 
174 double CALL23(___Double______nativeparsedouble_____AR_B_I_I, int start, int length,int start,int length,struct ArrayObject * ___str___) {
175   int maxlength=(length>60)?60:length;
176   char str[maxlength+1];
177   struct ArrayObject * bytearray=VAR(___str___);
178   int i;
179   for(i=0; i<maxlength; i++) {
180     str[i]=(((char *)&bytearray->___length___)+sizeof(int))[i+start];
181   }
182   str[i]=0;
183   double d=atof(str);
184   return d;
185 }
186 #endif
187
188 #ifdef D___Double______doubleToRawLongBits____D 
189 typedef union jvalue
190 {
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 {
616   unsigned int oid;
617   oid = (unsigned int) VAR(___this___);   // object id
618   int type = getObjType(oid);             // object type
619
620 #ifdef PRECISE_GC
621   int p[] = {1,0 , oid};
622   ((void(*) (void *))virtualtable[type*MAXCOUNT + EXECUTEMETHOD])(p);
623 #else
624   // call the proper execute method
625   ((void(*) (void *))virtualtable[type*MAXCOUNT + EXECUTEMETHOD])(oid);
626 #endif
627 }
628 #endif
629
630 #endif // DSTM
631
632 /* STM Barrier constructs */
633 #ifdef D___Barrier______setBarrier____I
634 void CALL11(___Barrier______setBarrier____I, int nthreads, int nthreads) {
635   // Barrier initialization
636   int ret;
637   if((ret = pthread_barrier_init(&barrier, NULL, nthreads)) != 0) {
638     printf("%s() Could not create a barrier: numthreads = 0 in %s\n", __func__, __FILE__);
639     exit(-1);
640   }
641 }
642 #endif
643
644 #ifdef D___Barrier______enterBarrier____
645 void CALL00(___Barrier______enterBarrier____) {
646   // Synchronization point
647   int ret;
648 #ifdef EVENTMONITOR
649   EVLOGEVENT(EV_ENTERBARRIER);
650 #endif
651 #ifdef PRECISE_GC
652   stopforgc((struct garbagelist *)___params___);
653 #endif
654   ret = pthread_barrier_wait(&barrier);
655 #ifdef PRECISE_GC
656   restartaftergc();
657 #endif
658   if(ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) {
659     printf("%s() Could not wait on barrier: error %d in %s\n", __func__, errno, __FILE__);
660     exit(-1);
661   }
662 #ifdef EVENTMONITOR
663   EVLOGEVENT(EV_EXITBARRIER);
664 #endif
665 }
666 #endif
667
668 /* Object allocation function */
669
670 #ifdef DSTM
671 __attribute__((malloc)) void * allocate_newglobal(int type) {
672   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(classsize[type]);
673   v->type=type;
674   //printf("DEBUG %s(), type= %x\n", __func__, type);
675 #ifdef THREADS
676   v->tid=0;
677   v->lockentry=0;
678   v->lockcount=0;
679 #endif
680   return v;
681 }
682
683 /* Array allocation function */
684
685 __attribute__((malloc)) struct ArrayObject * allocate_newarrayglobal(int type, int length) {
686   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(sizeof(struct ArrayObject)+length*classsize[type]);
687   if (length<0) {
688     printf("ERROR: negative array\n");
689     return NULL;
690   }
691   v->type=type;
692   v->___length___=length;
693 #ifdef THREADS
694   v->tid=0;
695   v->lockentry=0;
696   v->lockcount=0;
697 #endif
698   return v;
699 }
700 #endif
701
702
703 #ifdef STM
704 // STM Versions of allocation functions
705
706 /* Object allocation function */
707 __attribute__((malloc)) void * allocate_newtrans(void * ptr, int type) {
708 #ifdef STMARRAY
709   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type], 0);
710 #else
711   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type]);
712 #endif
713   ASSIGNUID(v);
714   v->type=type;
715   v->___objlocation___=v;
716   return v;
717 }
718
719 /* Array allocation function */
720 __attribute__((malloc)) struct ArrayObject * allocate_newarraytrans(void * ptr, int type, int length) {
721 #ifdef STMARRAY
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--) {
730     intptr-=2;
731     intptr[0]=1;
732   }
733   v->highindex=-1;
734   v->lowindex=MAXARRAYSIZE;
735 #else
736   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+length*classsize[type]);
737 #endif
738   ASSIGNUID(v);
739   if (length<0) {
740     printf("ERROR: negative array\n");
741     return NULL;
742   }
743   v->___objlocation___=(struct ___Object___*)v;
744   v->type=type;
745   v->___length___=length;
746   return v;
747 }
748
749 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
750   objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, classsize[type]+sizeof(objheader_t));
751   struct ___Object___ * v=(struct ___Object___ *) &tmp[1];
752   ASSIGNUID(v);
753   initdsmlocks(&tmp->lock);
754   tmp->version = 1;
755   v->___objlocation___=v;
756   v->type = type;
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   if (length<0) {
791     printf("ERROR: negative array %d\n", length);
792     return NULL;
793   }
794   v->___objlocation___=(struct ___Object___ *)v;
795   v->___length___=length;
796   return v;
797 }
798 #endif
799
800 #ifndef STM
801 #if defined(PRECISE_GC)
802 #ifdef MLP
803 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
804   return allocate_new_mlp(ptr, type, 0, 0);
805 }
806 __attribute__((malloc)) void * allocate_new_mlp(void * ptr, int type, int oid, int allocsite) {
807 #else
808 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
809 #endif
810   struct ___Object___ * v=(struct ___Object___ *) mygcmalloc((struct garbagelist *) ptr, classsize[type]);
811   v->type=type;
812 #ifdef THREADS
813   v->tid=0;
814   v->lockentry=0;
815   v->lockcount=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   if (length<0) {
839     printf("ERROR: negative array\n");
840     return NULL;
841   }
842   v->___length___=length;
843 #ifdef THREADS
844   v->tid=0;
845   v->lockentry=0;
846   v->lockcount=0;
847 #endif
848 #ifdef OPTIONAL
849   v->fses=0;
850 #endif
851 #ifdef MLP
852   v->oid=oid;
853   v->allocsite=allocsite;
854 #endif
855   return v;
856 }
857
858 #else
859 __attribute__((malloc)) void * allocate_new(int type) {
860   struct ___Object___ * v=FREEMALLOC(classsize[type]);
861   v->type=type;
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->___length___=length;
874 #ifdef OPTIONAL
875   v->fses=0;
876 #endif
877   return v;
878 }
879 #endif
880 #endif
881
882 /* Converts C character arrays into Java strings */
883 #ifdef PRECISE_GC
884 __attribute__((malloc)) struct ___String___ * NewStringShort(void * ptr, const short *str,int length) {
885 #else
886 __attribute__((malloc)) struct ___String___ * NewStringShort(const short *str,int length) {
887 #endif
888   int i;
889 #ifdef PRECISE_GC
890   struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
891   INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
892   struct ___String___ * strobj=allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
893   chararray=(struct ArrayObject *) ptrarray[2];
894 #else
895   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
896   struct ___String___ * strobj=allocate_new(STRINGTYPE);
897 #endif
898   strobj->___value___=chararray;
899   strobj->___count___=length;
900   strobj->___offset___=0;
901
902   for(i=0; i<length; i++) {
903     ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=str[i];
904   }
905   return strobj;
906 }
907
908 /* Converts C character arrays into Java strings */
909 #ifdef PRECISE_GC
910 __attribute__((malloc)) struct ___String___ * NewString(void * ptr, const char *str,int length) {
911 #else
912 __attribute__((malloc)) struct ___String___ * NewString(const char *str,int length) {
913 #endif
914   int i;
915 #ifdef PRECISE_GC
916   struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
917   INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
918   struct ___String___ * strobj=allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
919   chararray=(struct ArrayObject *) ptrarray[2];
920 #else
921   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
922   struct ___String___ * strobj=allocate_new(STRINGTYPE);
923 #endif
924   strobj->___value___=chararray;
925   strobj->___count___=length;
926   strobj->___offset___=0;
927
928   for(i=0; i<length; i++) {
929     ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
930   }
931   return strobj;
932 }
933
934 /* Generated code calls this if we fail a bounds check */
935
936 void failedboundschk(int num) {
937 #ifndef TASK
938   printf("Array out of bounds\n");
939 #ifdef THREADS
940   threadexit();
941 #else
942   exit(-1);
943 #endif
944 #else
945   longjmp(error_handler,2);
946 #endif
947 }
948
949 /* Abort task call */
950 void abort_task() {
951 #ifdef TASK
952   longjmp(error_handler,4);
953 #else
954   printf("Aborting\n");
955   exit(-1);
956 #endif
957 }
958
959 #ifndef SANDBOX
960 #ifdef D___System______Assert____Z
961  void CALL11(___System______Assert____Z, int ___status___, int ___status___) {
962    if (!___status___) {
963      printf("Assertion violation\n");
964      *((int *)(NULL)); //force stack trace error
965    }
966  }
967 #endif
968 #endif