f2c81b0fb99616f93c0697c34fb32d86638c789c
[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(struct ___Object___ *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 {
192   bool z;
193   char    c;
194   short   s;
195   int     i;
196   long long    j;
197   float   f;
198   double  d;
199 } jvalue;
200
201 long long CALL11(___Double______doubleToRawLongBits____D, double dval, double dval) {
202   jvalue val;
203   val.d = dval;
204
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. */
209
210 #define SWAP_DOUBLE(a)    (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
211
212   val.j = SWAP_DOUBLE(val.j);
213 #endif
214
215   return val.j;
216 }
217 #endif
218
219 #ifdef D___Double______longBitsToDouble____J 
220 double CALL11(___Double______longBitsToDouble____J, long long lval, long long lval) {
221   jvalue val;
222   val.j = lval;
223
224 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
225 #ifndef SWAP_DOUBLE
226 #define SWAP_DOUBLE(a)    (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
227 #endif
228   val.j = SWAP_DOUBLE(val.j);
229 #endif
230
231   return val.d;
232 }
233 #endif
234
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___;
238   char str[length];
239   int i;
240   int num=snprintf(str, length, "%f",___val___);
241   if (num>=length)
242     num=length-1;
243   for(i=0; i<length; i++) {
244     ((short *)(((char *)&VAR(___chararray___)->___length___)+sizeof(int)))[i]=(short)str[i];
245   }
246   return num;
247 }
248 #endif
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];
253 #ifdef STMARRAY
254   src=src->___objlocation___;
255 #endif
256   if (dsttype<NUMCLASSES||srctype<NUMCLASSES||srctype!=dsttype)
257     return;
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)
263     return;
264   unsigned INTPTR *pointer=pointerarray[srctype];
265   if (pointer==0) {
266     int elementsize=classsize[srctype];
267     int size=srclength*elementsize;
268     //primitives
269     memcpy(((char *)&aodst->___length___)+sizeof(int) , ((char *)&aosrc->___length___)+sizeof(int), size);
270   } else {
271     //objects
272     int i;
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);
279       } else {
280         //hit an object
281         ((struct ___Object___ **)(((char*) &aodst->___length___)+sizeof(int)))[i]=ptr;
282       }
283     }
284   }
285 }
286
287 void CALL02(___System______deepArrayCopy____L___Object____L___Object___, struct ___Object___ * ___dst___, struct ___Object___ * ___src___) {
288   deepArrayCopy(VAR(___dst___), VAR(___src___));
289 }
290 #endif
291
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];
296
297   //not an array or type mismatch
298   if (dsttype<NUMCLASSES||srctype<NUMCLASSES)
299     return;
300   if (srctype!=dsttype)
301     printf("Potential type mismatch in arraycopy\n");
302
303   struct ArrayObject *aodst=(struct ArrayObject *)dst;
304   struct ArrayObject *aosrc=(struct ArrayObject *)src;
305   int dstlength=aodst->___length___;
306   int srclength=aosrc->___length___;
307
308   if (length<=0)
309     return;
310   if (srcPos+length>srclength)
311     return;
312   if (destPos+length>dstlength)
313     return;
314
315   unsigned INTPTR *pointer=pointerarray[srctype];
316   if (pointer==0) {
317     int elementsize=classsize[srctype];
318     int size=length*elementsize;
319     //primitives
320     memcpy(((char *)&aodst->___length___)+sizeof(int)+destPos*elementsize, ((char *)&aosrc->___length___)+sizeof(int)+srcPos*elementsize, size);
321   } else {
322     //objects
323     int i;
324     for(i=0;i<length;i++) {
325       struct ___Object___ * ptr=((struct ___Object___**)(((char*) &aosrc->___length___)+sizeof(int)))[i+srcPos];
326       //hit an object
327       ((struct ___Object___ **)(((char*) &aodst->___length___)+sizeof(int)))[i+destPos]=ptr;
328     }
329   }
330 }
331
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___);
334 }
335 #endif
336
337 #ifdef D___Runtime______availableProcessors____
338 int CALL01(___Runtime______availableProcessors____, struct ___Runtime___ * ___this___) {
339   printf("Unimplemented Runtime.availableProcessors\n");
340   return 24;
341 }
342 #endif
343
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;
348 }
349 #endif
350
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;
355 }
356 #endif
357
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;
362 }
363 #endif
364 #ifdef D___System______exit____I
365 void CALL11(___System______exit____I,int ___status___, int ___status___) {
366 #ifdef TRANSSTATS
367 #ifndef RECOVERY
368   printf("numTransCommit = %d\n", numTransCommit);
369   printf("numTransAbort = %d\n", numTransAbort);
370   printf("nSoftAbort = %d\n", nSoftAbort);
371 #endif
372 #ifdef STM
373   printf("nSoftAbortCommit = %d\n", nSoftAbortCommit);
374   printf("nSoftAbortAbort = %d\n", nSoftAbortAbort);
375 #ifdef STMSTATS
376   int i;
377   for(i=0; i<TOTALNUMCLASSANDARRAY; i++) {
378     printf("typesCausingAbort[%2d] numaccess= %5d numabort= %3d\n", i, typesCausingAbort[i].numaccess, typesCausingAbort[i].numabort);
379   }
380 #endif
381 #endif
382 #endif
383 #ifdef EVENTMONITOR
384   dumpdata();
385 #endif
386   exit(___status___);
387 }
388 #endif
389
390 #ifdef D___System______logevent____I
391 void CALL11(___System______logevent____I,int ___event___, int ___event___) {
392 #ifdef STMLOG
393   event[counter] = ___event___;
394   clkticks[counter] = rdtsc();
395   counter++;
396 #endif
397   return;
398 }
399 #endif
400
401 #ifdef ___System______logevent____
402 void CALL00(___System______logevent____) {
403 #ifdef STMLOG
404   beginClock= rdtsc();
405 #endif
406   return;
407 }
408 #endif
409
410 #ifdef ___System______flushToFile____I
411 void CALL11(___System______flushToFile____I, int ___threadid___, int ___threadid___) {
412 #ifdef STMLOG
413   FILE *fp;
414   /* Flush to file */
415   char filename[20];
416   memset(filename, 0, 20);
417   sprintf(filename, "%s_%d", FILENAME, ___threadid___);
418   if ((fp = fopen(filename, "w+")) == NULL) {
419     perror("fopen");
420     return;
421   }
422   int i;
423   for (i = 0; i < counter-1; i++) {
424     fprintf(fp, "%d %lld %lld\n", event[i], clkticks[i]-beginClock, clkticks[i+1]-beginClock);
425   }
426   fprintf(fp, "%d %lld\n", event[i], clkticks[i]-beginClock);
427
428   fclose(fp);
429 #endif
430   return;
431 }
432 #endif
433
434 #ifdef D___System______initLog____
435 void CALL00(___System______initLog____) {
436 #ifdef STMLOG
437   counter=0;
438   int i;
439   for(i=0; i<ARRAY_LENGTH; i++) {
440     event[i] = 0;
441     clkticks[i] = 0;
442   }
443
444 #endif
445   return;
446 }
447 #endif
448
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 *));
453 }
454 #endif
455
456 #ifdef D___System______printI____I
457 void CALL11(___System______printI____I,int ___status___, int ___status___) {
458   printf("%d\n",___status___);
459 }
460 #endif
461
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 */
469   return retval;
470 }
471 #endif
472
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___);
478     restartaftergc();
479   }
480 #endif
481
482   /* Grow the to heap if necessary */
483   {
484     INTPTR curr_heapsize=curr_heaptop-curr_heapbase;
485     INTPTR to_heapsize=to_heaptop-to_heapbase;
486
487     if (curr_heapsize>to_heapsize) {
488       free(to_heapbase);
489       to_heapbase=malloc(curr_heapsize);
490       if (to_heapbase==NULL) {
491         printf("Error Allocating enough memory\n");
492         exit(-1);
493       }
494       to_heaptop=to_heapbase+curr_heapsize;
495       to_heapptr=to_heapbase;
496     }
497   }
498
499
500   collect((struct garbagelist *)___params___);
501
502   {
503   void * tmp=to_heapbase;
504   to_heapbase=curr_heapbase;
505   curr_heapbase=tmp;
506
507   tmp=to_heaptop;
508   to_heaptop=curr_heaptop;
509   curr_heaptop=tmp;
510
511   tmp=to_heapptr;
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);
516
517   }
518
519 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
520   pthread_mutex_unlock(&gclock);
521 #endif
522 }
523 #endif
524
525 #ifdef D___System______microTimes____
526 long long CALL00(___System______microTimes____) {
527   struct timeval tv; 
528   long long retval;
529   gettimeofday(&tv, NULL);
530   retval = tv.tv_sec; /* seconds */
531   retval*=1000000; /* microsecs */
532   retval+= (tv.tv_usec); /* adjust microseconds & add them in */
533   return retval;
534 }
535 #endif
536
537 #ifdef D___System______getticks____
538 long long CALL00(___System______getticks____) {
539   unsigned a, d;
540   asm("cpuid");
541   asm volatile("rdtsc" : "=a" (a), "=d" (d));
542   return (((ticks)a) | (((ticks)d) << 32));
543 }
544 #endif
545
546 #ifdef D___System______printString____L___String___
547 void CALL01(___System______printString____L___String___,struct ___String___ * ___s___) {
548   struct ArrayObject * chararray=VAR(___s___)->___value___;
549   int i;
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];
553     putchar(sc);
554   }
555 #ifdef RECOVERYSTATS
556   fflush(stdout);
557   fflush(stdout);
558 #endif
559 }
560 #endif
561
562 #ifdef D___RecoveryStat______printRecoveryStat____ 
563 #ifdef RECOVERYSTATS
564 void CALL00(___RecoveryStat______printRecoveryStat____) {
565   printRecoveryStat();
566 }
567 #else
568 void CALL00(___RecoveryStat______printRecoveryStat____) {
569   printf("No Stat\n");
570   fflush(stdout);
571 }
572 #endif
573 #endif
574
575 #ifdef DSTM
576 #ifdef D___System______clearPrefetchCache____
577 void CALL00(___System______clearPrefetchCache____) {
578   prehashClear();
579 }
580 #endif
581
582 #ifdef RANGEPREFETCH
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___;
589   int i;
590   short offArry[numoffset+2];
591   offArry[0] = 0;
592   offArry[1] = 0;
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]);
596   }
597   unsigned int oid;
598   if(((unsigned int)(VAR(___o___)) & 1) != 0) { //odd
599     oid =  (unsigned int) VAR(___o___); //outside transaction therefore just an oid
600   } else { //even
601     oid = (unsigned int) COMPOID(VAR(___o___)); //inside transaction therefore a pointer to oid
602   }
603   rangePrefetch(oid, (short)(numoffset+2), offArry);
604 }
605 #else
606 void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) {
607   return;
608 }
609 #endif
610 #endif
611
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___)
616 {
617   unsigned int oid;
618   oid = (unsigned int) VAR(___this___);   // object id
619   int type = getObjType(oid);             // object type
620
621 #ifdef PRECISE_GC
622   int p[] = {1,0 , oid};
623   ((void(*) (void *))virtualtable[type*MAXCOUNT + EXECUTEMETHOD])(p);
624 #else
625   // call the proper execute method
626   ((void(*) (void *))virtualtable[type*MAXCOUNT + EXECUTEMETHOD])(oid);
627 #endif
628 }
629 #endif
630
631 #endif // DSTM
632
633 /* STM Barrier constructs */
634 #ifdef D___Barrier______setBarrier____I
635 void CALL11(___Barrier______setBarrier____I, int nthreads, int nthreads) {
636   // Barrier initialization
637   int ret;
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__);
640     exit(-1);
641   }
642 }
643 #endif
644
645 #ifdef D___Barrier______enterBarrier____
646 void CALL00(___Barrier______enterBarrier____) {
647   // Synchronization point
648   int ret;
649 #ifdef EVENTMONITOR
650   EVLOGEVENT(EV_ENTERBARRIER);
651 #endif
652 #ifdef PRECISE_GC
653   stopforgc((struct garbagelist *)___params___);
654 #endif
655   ret = pthread_barrier_wait(&barrier);
656 #ifdef PRECISE_GC
657   restartaftergc();
658 #endif
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__);
661     exit(-1);
662   }
663 #ifdef EVENTMONITOR
664   EVLOGEVENT(EV_EXITBARRIER);
665 #endif
666 }
667 #endif
668
669 /* Object allocation function */
670
671 #ifdef DSTM
672 __attribute__((malloc)) void * allocate_newglobal(int type) {
673   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(classsize[type]);
674   v->type=type;
675   //printf("DEBUG %s(), type= %x\n", __func__, type);
676 #ifdef THREADS
677   v->tid=0;
678 #endif
679   return v;
680 }
681
682 /* Array allocation function */
683
684 __attribute__((malloc)) struct ArrayObject * allocate_newarrayglobal(int type, int length) {
685   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(sizeof(struct ArrayObject)+length*classsize[type]);
686   if (length<0) {
687     printf("ERROR: negative array\n");
688     return NULL;
689   }
690   v->type=type;
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->___objlocation___=v;
713   return v;
714 }
715
716 /* Array allocation function */
717 __attribute__((malloc)) struct ArrayObject * allocate_newarraytrans(void * ptr, int type, int length) {
718 #ifdef STMARRAY
719   int basesize=length*classsize[type];
720   //round the base size up
721   basesize=(basesize+LOWMASK)&HIGHMASK;
722   int numlocks=basesize>>INDEXSHIFT;
723   int bookkeepsize=numlocks*2*sizeof(int);
724   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+basesize+bookkeepsize, bookkeepsize);
725   unsigned int *intptr=(unsigned int *)(((char *)v)-sizeof(objheader_t));
726   for(;numlocks>0;numlocks--) {
727     intptr-=2;
728     intptr[0]=1;
729   }
730   v->highindex=-1;
731   v->lowindex=MAXARRAYSIZE;
732 #else
733   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+length*classsize[type]);
734 #endif
735   ASSIGNUID(v);
736   if (length<0) {
737     printf("ERROR: negative array\n");
738     return NULL;
739   }
740   v->___objlocation___=(struct ___Object___*)v;
741   v->type=type;
742   v->___length___=length;
743   return v;
744 }
745
746 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
747   objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, classsize[type]+sizeof(objheader_t));
748   struct ___Object___ * v=(struct ___Object___ *) &tmp[1];
749   ASSIGNUID(v);
750   initdsmlocks(&tmp->lock);
751   tmp->version = 1;
752   v->___objlocation___=v;
753   v->type = type;
754   return v;
755 }
756
757 /* Array allocation function */
758
759 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
760 #ifdef STMARRAY
761   int basesize=length*classsize[type];
762   //round the base size up
763   basesize=(basesize+LOWMASK)&HIGHMASK;
764   int numlocks=basesize>>INDEXSHIFT;
765   int bookkeepsize=(numlocks)*2*sizeof(int);
766   int *tmpint=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+basesize+sizeof(objheader_t)+bookkeepsize);
767   for(;numlocks>0;numlocks--) {
768     tmpint[0]=1;
769     tmpint+=2;
770   }
771   objheader_t *tmp=(objheader_t *)tmpint;
772   struct ArrayObject * v=(struct ArrayObject *) &tmp[1];
773   v->highindex=-1;
774   v->lowindex=MAXARRAYSIZE;
775 #else
776   objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]+sizeof(objheader_t));
777   struct ArrayObject * v=(struct ArrayObject *) &tmp[1];
778 #endif
779 #ifdef DUALVIEW
780   tmp->lock=RW_LOCK_BIAS;
781 #else
782   initdsmlocks(&tmp->lock);
783 #endif
784   tmp->version=1;
785   ASSIGNUID(v);
786   v->type=type;
787   if (length<0) {
788     printf("ERROR: negative array %d\n", length);
789     return NULL;
790   }
791   v->___objlocation___=(struct ___Object___ *)v;
792   v->___length___=length;
793   return v;
794 }
795 #endif
796
797 #ifndef STM
798 #if defined(PRECISE_GC)
799 #ifdef MLP
800 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
801   return allocate_new_mlp(ptr, type, 0, 0);
802 }
803 __attribute__((malloc)) void * allocate_new_mlp(void * ptr, int type, int oid, int allocsite) {
804 #else
805 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
806 #endif
807   struct ___Object___ * v=(struct ___Object___ *) mygcmalloc((struct garbagelist *) ptr, classsize[type]);
808   v->type=type;
809 #ifdef THREADS
810   v->tid=0;
811 #endif
812 #ifdef OPTIONAL
813   v->fses=0;
814 #endif
815 #ifdef MLP
816   v->oid=oid;
817   v->allocsite=allocsite;
818 #endif
819   return v;
820 }
821
822 /* Array allocation function */
823 #ifdef MLP
824 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
825   return allocate_newarray_mlp(ptr, type, length, 0, 0);
826 }
827  __attribute__((malloc)) struct ArrayObject * allocate_newarray_mlp(void * ptr, int type, int length, int oid, int allocsite) {
828 #else
829 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
830 #endif
831   struct ArrayObject * v=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]);
832   v->type=type;
833   if (length<0) {
834     printf("ERROR: negative array\n");
835     return NULL;
836   }
837   v->___length___=length;
838 #ifdef THREADS
839   v->tid=0;
840 #endif
841 #ifdef OPTIONAL
842   v->fses=0;
843 #endif
844 #ifdef MLP
845   v->oid=oid;
846   v->allocsite=allocsite;
847 #endif
848   return v;
849 }
850
851 #else
852 __attribute__((malloc)) void * allocate_new(int type) {
853   struct ___Object___ * v=FREEMALLOC(classsize[type]);
854   v->type=type;
855 #ifdef OPTIONAL
856   v->fses=0;
857 #endif
858   return v;
859 }
860
861 /* Array allocation function */
862
863 __attribute__((malloc)) struct ArrayObject * allocate_newarray(int type, int length) {
864   __attribute__((malloc))  struct ArrayObject * v=FREEMALLOC(sizeof(struct ArrayObject)+length*classsize[type]);
865   v->type=type;
866   v->___length___=length;
867 #ifdef OPTIONAL
868   v->fses=0;
869 #endif
870   return v;
871 }
872 #endif
873 #endif
874
875 /* Converts C character arrays into Java strings */
876 #ifdef PRECISE_GC
877 __attribute__((malloc)) struct ___String___ * NewStringShort(void * ptr, const short *str,int length) {
878 #else
879 __attribute__((malloc)) struct ___String___ * NewStringShort(const short *str,int length) {
880 #endif
881   int i;
882 #ifdef PRECISE_GC
883   struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
884   INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
885   struct ___String___ * strobj=allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
886   chararray=(struct ArrayObject *) ptrarray[2];
887 #else
888   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
889   struct ___String___ * strobj=allocate_new(STRINGTYPE);
890 #endif
891   strobj->___value___=chararray;
892   strobj->___count___=length;
893   strobj->___offset___=0;
894
895   for(i=0; i<length; i++) {
896     ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=str[i];
897   }
898   return strobj;
899 }
900
901 /* Converts C character arrays into Java strings */
902 #ifdef PRECISE_GC
903 __attribute__((malloc)) struct ___String___ * NewString(void * ptr, const char *str,int length) {
904 #else
905 __attribute__((malloc)) struct ___String___ * NewString(const char *str,int length) {
906 #endif
907   int i;
908 #ifdef PRECISE_GC
909   struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
910   INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
911   struct ___String___ * strobj=allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
912   chararray=(struct ArrayObject *) ptrarray[2];
913 #else
914   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
915   struct ___String___ * strobj=allocate_new(STRINGTYPE);
916 #endif
917   strobj->___value___=chararray;
918   strobj->___count___=length;
919   strobj->___offset___=0;
920
921   for(i=0; i<length; i++) {
922     ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
923   }
924   return strobj;
925 }
926
927 /* Generated code calls this if we fail a bounds check */
928
929 void failedboundschk(int num) {
930 #ifndef TASK
931   printf("Array out of bounds\n");
932 #ifdef THREADS
933   threadexit();
934 #else
935   exit(-1);
936 #endif
937 #else
938   longjmp(error_handler,2);
939 #endif
940 }
941
942 /* Abort task call */
943 void abort_task() {
944 #ifdef TASK
945   longjmp(error_handler,4);
946 #else
947   printf("Aborting\n");
948   exit(-1);
949 #endif
950 }
951
952 #ifndef SANDBOX
953 #ifdef D___System______Assert____Z
954  void CALL11(___System______Assert____Z, int ___status___, int ___status___) {
955    if (!___status___) {
956      printf("Assertion violation\n");
957      *((int *)(NULL)); //force stack trace error
958    }
959  }
960 #endif
961 #endif