cffd1c375ebe2d377ea290f98008b4a692971db3
[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
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
388 void CALL11(___System______logevent____I,int ___event___, int ___event___) {
389 #ifdef STMLOG
390   event[counter] = ___event___;
391   clkticks[counter] = rdtsc();
392   counter++;
393 #endif
394   return;
395 }
396
397 void CALL00(___System______logevent____) {
398 #ifdef STMLOG
399   beginClock= rdtsc();
400 #endif
401   return;
402 }
403
404 void CALL11(___System______flushToFile____I, int ___threadid___, int ___threadid___) {
405 #ifdef STMLOG
406   FILE *fp;
407   /* Flush to file */
408   char filename[20];
409   memset(filename, 0, 20);
410   sprintf(filename, "%s_%d", FILENAME, ___threadid___);
411   if ((fp = fopen(filename, "w+")) == NULL) {
412     perror("fopen");
413     return;
414   }
415   int i;
416   for (i = 0; i < counter-1; i++) {
417     fprintf(fp, "%d %lld %lld\n", event[i], clkticks[i]-beginClock, clkticks[i+1]-beginClock);
418   }
419   fprintf(fp, "%d %lld\n", event[i], clkticks[i]-beginClock);
420
421   fclose(fp);
422 #endif
423   return;
424 }
425
426 void CALL00(___System______initLog____) {
427 #ifdef STMLOG
428   counter=0;
429   int i;
430   for(i=0; i<ARRAY_LENGTH; i++) {
431     event[i] = 0;
432     clkticks[i] = 0;
433   }
434
435 #endif
436   return;
437 }
438
439 #ifdef D___Vector______removeElement_____AR_L___Object____I_I
440 void CALL23(___Vector______removeElement_____AR_L___Object____I_I, int ___index___, int ___size___, struct ArrayObject * ___array___, int ___index___, int ___size___) {
441   char* offset=((char *)(&VAR(___array___)->___length___))+sizeof(unsigned int)+sizeof(void *)*___index___;
442   memmove(offset, offset+sizeof(void *),(___size___-___index___-1)*sizeof(void *));
443 }
444 #endif
445
446 void CALL11(___System______printI____I,int ___status___, int ___status___) {
447   printf("%d\n",___status___);
448 }
449
450 long long CALL00(___System______currentTimeMillis____) {
451   struct timeval tv; long long retval;
452   gettimeofday(&tv, NULL);
453   retval = tv.tv_sec; /* seconds */
454   retval*=1000; /* milliseconds */
455   retval+= (tv.tv_usec/1000); /* adjust milliseconds & add them in */
456   return retval;
457 }
458
459 #ifdef D___System______gc____
460 void CALL00(___System______gc____) {
461 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
462   while (pthread_mutex_trylock(&gclock)!=0) {
463     stopforgc((struct garbagelist *)___params___);
464     restartaftergc();
465   }
466 #endif
467
468   /* Grow the to heap if necessary */
469   {
470     INTPTR curr_heapsize=curr_heaptop-curr_heapbase;
471     INTPTR to_heapsize=to_heaptop-to_heapbase;
472
473     if (curr_heapsize>to_heapsize) {
474       free(to_heapbase);
475       to_heapbase=malloc(curr_heapsize);
476       if (to_heapbase==NULL) {
477         printf("Error Allocating enough memory\n");
478         exit(-1);
479       }
480       to_heaptop=to_heapbase+curr_heapsize;
481       to_heapptr=to_heapbase;
482     }
483   }
484
485
486   collect((struct garbagelist *)___params___);
487
488   {
489   void * tmp=to_heapbase;
490   to_heapbase=curr_heapbase;
491   curr_heapbase=tmp;
492
493   tmp=to_heaptop;
494   to_heaptop=curr_heaptop;
495   curr_heaptop=tmp;
496
497   tmp=to_heapptr;
498   curr_heapptr=to_heapptr;
499   curr_heapgcpoint=((char *) curr_heapbase)+GCPOINT(curr_heaptop-curr_heapbase);
500   to_heapptr=to_heapbase;
501   bzero(tmp, curr_heaptop-tmp);
502
503   }
504
505 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
506   pthread_mutex_unlock(&gclock);
507 #endif
508 }
509 #endif
510
511 long long CALL00(___System______microTimes____) {
512   struct timeval tv; 
513   long long retval;
514   gettimeofday(&tv, NULL);
515   retval = tv.tv_sec; /* seconds */
516   retval*=1000000; /* microsecs */
517   retval+= (tv.tv_usec); /* adjust microseconds & add them in */
518   return retval;
519 }
520
521 long long CALL00(___System______getticks____) {
522   unsigned a, d;
523   asm("cpuid");
524   asm volatile("rdtsc" : "=a" (a), "=d" (d));
525   return (((ticks)a) | (((ticks)d) << 32));
526 }
527
528 void CALL01(___System______printString____L___String___,struct ___String___ * ___s___) {
529   struct ArrayObject * chararray=VAR(___s___)->___value___;
530   int i;
531   int offset=VAR(___s___)->___offset___;
532   for(i=0; i<VAR(___s___)->___count___; i++) {
533     short sc=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
534     putchar(sc);
535   }
536 #ifdef RECOVERYSTATS
537   fflush(stdout);
538   fflush(stdout);
539 #endif
540 }
541
542 #ifdef D___RecoveryStat______printRecoveryStat____ 
543 #ifdef RECOVERYSTATS
544 void CALL00(___RecoveryStat______printRecoveryStat____) {
545   printRecoveryStat();
546 }
547 #else
548 void CALL00(___RecoveryStat______printRecoveryStat____) {
549   printf("No Stat\n");
550   fflush(stdout);
551 }
552 #endif
553 #endif
554
555 #ifdef DSTM
556 void CALL00(___System______clearPrefetchCache____) {
557   prehashClear();
558 }
559
560 #ifdef RANGEPREFETCH
561 void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) {
562   /* Manual Prefetches to be inserted */
563   //printf("DEBUG-> %s() ___Object___ * ___o___ = %x\n", __func__, VAR(___o___));
564   //printf("DEBUG-> %s() ArrayObject * = %x\n", __func__, VAR(___offsets___));
565   int numoffset=VAR(___offsets___)->___length___;
566   int i;
567   short offArry[numoffset+2];
568   offArry[0] = 0;
569   offArry[1] = 0;
570   for(i = 2; i<(numoffset+2); i++) {
571     offArry[i] = *((short *)(((char *)&VAR(___offsets___)->___length___) + sizeof(int) + (i-2) * sizeof(short)));
572     //printf("DEBUG-> offArry[%d] = %d\n", i, offArry[i]);
573   }
574   unsigned int oid;
575   if(((unsigned int)(VAR(___o___)) & 1) != 0) { //odd
576     oid =  (unsigned int) VAR(___o___); //outside transaction therefore just an oid
577   } else { //even
578     oid = (unsigned int) COMPOID(VAR(___o___)); //inside transaction therefore a pointer to oid
579   }
580   rangePrefetch(oid, (short)(numoffset+2), offArry);
581 }
582 #else
583 void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) {
584   return;
585 }
586 #endif
587
588 #ifdef D___Task______execution____ 
589 extern void* virtualtable[];
590 // associated with Task.execution(). finds proper execute method and call it
591 void CALL01(___Task______execution____,struct ___Task___ * ___this___)
592 {
593   unsigned int oid;
594   oid = (unsigned int) VAR(___this___);   // object id
595   int type = getObjType(oid);             // object type
596
597 #ifdef PRECISE_GC
598   int p[] = {1,0 , oid};
599   ((void(*) (void *))virtualtable[type*MAXCOUNT + EXECUTEMETHOD])(p);
600 #else
601   // call the proper execute method
602   ((void(*) (void *))virtualtable[type*MAXCOUNT + EXECUTEMETHOD])(oid);
603 #endif
604 }
605 #endif
606
607 #endif // DSTM
608
609 /* STM Barrier constructs */
610 #ifdef D___Barrier______setBarrier____I
611 void CALL11(___Barrier______setBarrier____I, int nthreads, int nthreads) {
612   // Barrier initialization
613   int ret;
614   if((ret = pthread_barrier_init(&barrier, NULL, nthreads)) != 0) {
615     printf("%s() Could not create a barrier: numthreads = 0 in %s\n", __func__, __FILE__);
616     exit(-1);
617   }
618 }
619 #endif
620
621 #ifdef D___Barrier______enterBarrier____
622 void CALL00(___Barrier______enterBarrier____) {
623   // Synchronization point
624   int ret;
625 #ifdef EVENTMONITOR
626   EVLOGEVENT(EV_ENTERBARRIER);
627 #endif
628 #ifdef PRECISE_GC
629   stopforgc((struct garbagelist *)___params___);
630 #endif
631   ret = pthread_barrier_wait(&barrier);
632 #ifdef PRECISE_GC
633   restartaftergc();
634 #endif
635   if(ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) {
636     printf("%s() Could not wait on barrier: error %d in %s\n", __func__, errno, __FILE__);
637     exit(-1);
638   }
639 #ifdef EVENTMONITOR
640   EVLOGEVENT(EV_EXITBARRIER);
641 #endif
642 }
643 #endif
644
645 /* Object allocation function */
646
647 #ifdef DSTM
648 __attribute__((malloc)) void * allocate_newglobal(int type) {
649   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(classsize[type]);
650   v->type=type;
651   //printf("DEBUG %s(), type= %x\n", __func__, type);
652 #ifdef THREADS
653   v->tid=0;
654   v->lockentry=0;
655   v->lockcount=0;
656 #endif
657   return v;
658 }
659
660 /* Array allocation function */
661
662 __attribute__((malloc)) struct ArrayObject * allocate_newarrayglobal(int type, int length) {
663   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(sizeof(struct ArrayObject)+length*classsize[type]);
664   if (length<0) {
665     printf("ERROR: negative array\n");
666     return NULL;
667   }
668   v->type=type;
669   v->___length___=length;
670 #ifdef THREADS
671   v->tid=0;
672   v->lockentry=0;
673   v->lockcount=0;
674 #endif
675   return v;
676 }
677 #endif
678
679
680 #ifdef STM
681 // STM Versions of allocation functions
682
683 /* Object allocation function */
684 __attribute__((malloc)) void * allocate_newtrans(void * ptr, int type) {
685 #ifdef STMARRAY
686   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type], 0);
687 #else
688   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type]);
689 #endif
690   ASSIGNUID(v);
691   v->type=type;
692   v->___objlocation___=v;
693   return v;
694 }
695
696 /* Array allocation function */
697 __attribute__((malloc)) struct ArrayObject * allocate_newarraytrans(void * ptr, int type, int length) {
698 #ifdef STMARRAY
699   int basesize=length*classsize[type];
700   //round the base size up
701   basesize=(basesize+LOWMASK)&HIGHMASK;
702   int numlocks=basesize>>INDEXSHIFT;
703   int bookkeepsize=numlocks*2*sizeof(int);
704   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+basesize+bookkeepsize, bookkeepsize);
705   unsigned int *intptr=(unsigned int *)(((char *)v)-sizeof(objheader_t));
706   for(;numlocks>0;numlocks--) {
707     intptr-=2;
708     intptr[0]=1;
709   }
710   v->highindex=-1;
711   v->lowindex=MAXARRAYSIZE;
712 #else
713   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+length*classsize[type]);
714 #endif
715   ASSIGNUID(v);
716   if (length<0) {
717     printf("ERROR: negative array\n");
718     return NULL;
719   }
720   v->___objlocation___=(struct ___Object___*)v;
721   v->type=type;
722   v->___length___=length;
723   return v;
724 }
725
726 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
727   objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, classsize[type]+sizeof(objheader_t));
728   struct ___Object___ * v=(struct ___Object___ *) &tmp[1];
729   ASSIGNUID(v);
730   initdsmlocks(&tmp->lock);
731   tmp->version = 1;
732   v->___objlocation___=v;
733   v->type = type;
734   return v;
735 }
736
737 /* Array allocation function */
738
739 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
740 #ifdef STMARRAY
741   int basesize=length*classsize[type];
742   //round the base size up
743   basesize=(basesize+LOWMASK)&HIGHMASK;
744   int numlocks=basesize>>INDEXSHIFT;
745   int bookkeepsize=(numlocks)*2*sizeof(int);
746   int *tmpint=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+basesize+sizeof(objheader_t)+bookkeepsize);
747   for(;numlocks>0;numlocks--) {
748     tmpint[0]=1;
749     tmpint+=2;
750   }
751   objheader_t *tmp=(objheader_t *)tmpint;
752   struct ArrayObject * v=(struct ArrayObject *) &tmp[1];
753   v->highindex=-1;
754   v->lowindex=MAXARRAYSIZE;
755 #else
756   objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]+sizeof(objheader_t));
757   struct ArrayObject * v=(struct ArrayObject *) &tmp[1];
758 #endif
759 #ifdef DUALVIEW
760   tmp->lock=RW_LOCK_BIAS;
761 #else
762   initdsmlocks(&tmp->lock);
763 #endif
764   tmp->version=1;
765   ASSIGNUID(v);
766   v->type=type;
767   if (length<0) {
768     printf("ERROR: negative array %d\n", length);
769     return NULL;
770   }
771   v->___objlocation___=(struct ___Object___ *)v;
772   v->___length___=length;
773   return v;
774 }
775 #endif
776
777 #ifndef STM
778 #if defined(PRECISE_GC)
779 #ifdef MLP
780 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
781   return allocate_new_mlp(ptr, type, 0, 0);
782 }
783 __attribute__((malloc)) void * allocate_new_mlp(void * ptr, int type, int oid, int allocsite) {
784 #else
785 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
786 #endif
787   struct ___Object___ * v=(struct ___Object___ *) mygcmalloc((struct garbagelist *) ptr, classsize[type]);
788   v->type=type;
789 #ifdef THREADS
790   v->tid=0;
791   v->lockentry=0;
792   v->lockcount=0;
793 #endif
794 #ifdef OPTIONAL
795   v->fses=0;
796 #endif
797 #ifdef MLP
798   v->oid=oid;
799   v->allocsite=allocsite;
800 #endif
801   return v;
802 }
803
804 /* Array allocation function */
805 #ifdef MLP
806 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
807   return allocate_newarray_mlp(ptr, type, length, 0, 0);
808 }
809  __attribute__((malloc)) struct ArrayObject * allocate_newarray_mlp(void * ptr, int type, int length, int oid, int allocsite) {
810 #else
811 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
812 #endif
813   struct ArrayObject * v=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]);
814   v->type=type;
815   if (length<0) {
816     printf("ERROR: negative array\n");
817     return NULL;
818   }
819   v->___length___=length;
820 #ifdef THREADS
821   v->tid=0;
822   v->lockentry=0;
823   v->lockcount=0;
824 #endif
825 #ifdef OPTIONAL
826   v->fses=0;
827 #endif
828 #ifdef MLP
829   v->oid=oid;
830   v->allocsite=allocsite;
831 #endif
832   return v;
833 }
834
835 #else
836 __attribute__((malloc)) void * allocate_new(int type) {
837   struct ___Object___ * v=FREEMALLOC(classsize[type]);
838   v->type=type;
839 #ifdef OPTIONAL
840   v->fses=0;
841 #endif
842   return v;
843 }
844
845 /* Array allocation function */
846
847 __attribute__((malloc)) struct ArrayObject * allocate_newarray(int type, int length) {
848   __attribute__((malloc))  struct ArrayObject * v=FREEMALLOC(sizeof(struct ArrayObject)+length*classsize[type]);
849   v->type=type;
850   v->___length___=length;
851 #ifdef OPTIONAL
852   v->fses=0;
853 #endif
854   return v;
855 }
856 #endif
857 #endif
858
859 /* Converts C character arrays into Java strings */
860 #ifdef PRECISE_GC
861 __attribute__((malloc)) struct ___String___ * NewStringShort(void * ptr, const short *str,int length) {
862 #else
863 __attribute__((malloc)) struct ___String___ * NewStringShort(const short *str,int length) {
864 #endif
865   int i;
866 #ifdef PRECISE_GC
867   struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
868   INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
869   struct ___String___ * strobj=allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
870   chararray=(struct ArrayObject *) ptrarray[2];
871 #else
872   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
873   struct ___String___ * strobj=allocate_new(STRINGTYPE);
874 #endif
875   strobj->___value___=chararray;
876   strobj->___count___=length;
877   strobj->___offset___=0;
878
879   for(i=0; i<length; i++) {
880     ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=str[i];
881   }
882   return strobj;
883 }
884
885 /* Converts C character arrays into Java strings */
886 #ifdef PRECISE_GC
887 __attribute__((malloc)) struct ___String___ * NewString(void * ptr, const char *str,int length) {
888 #else
889 __attribute__((malloc)) struct ___String___ * NewString(const char *str,int length) {
890 #endif
891   int i;
892 #ifdef PRECISE_GC
893   struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
894   INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
895   struct ___String___ * strobj=allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
896   chararray=(struct ArrayObject *) ptrarray[2];
897 #else
898   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
899   struct ___String___ * strobj=allocate_new(STRINGTYPE);
900 #endif
901   strobj->___value___=chararray;
902   strobj->___count___=length;
903   strobj->___offset___=0;
904
905   for(i=0; i<length; i++) {
906     ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
907   }
908   return strobj;
909 }
910
911 /* Generated code calls this if we fail a bounds check */
912
913 void failedboundschk(int num) {
914 #ifndef TASK
915   printf("Array out of bounds\n");
916 #ifdef THREADS
917   threadexit();
918 #else
919   exit(-1);
920 #endif
921 #else
922   longjmp(error_handler,2);
923 #endif
924 }
925
926 /* Abort task call */
927 void abort_task() {
928 #ifdef TASK
929   longjmp(error_handler,4);
930 #else
931   printf("Aborting\n");
932   exit(-1);
933 #endif
934 }
935
936 #ifndef SANDBOX
937 #ifdef D___System______Assert____Z
938  void CALL11(___System______Assert____Z, int ___status___, int ___status___) {
939    if (!___status___) {
940      printf("Assertion violation\n");
941      *((int *)(NULL)); //force stack trace error
942    }
943  }
944 #endif
945 #endif