move hashcode into header...part of prep to switch class libraries
[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   v->hashcode=(int)(INTPTR)v;
676   //printf("DEBUG %s(), type= %x\n", __func__, type);
677 #ifdef THREADS
678   v->tid=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->hashcode=(int)(INTPTR)v;
693   v->___length___=length;
694 #ifdef THREADS
695   v->tid=0;
696 #endif
697   return v;
698 }
699 #endif
700
701
702 #ifdef STM
703 // STM Versions of allocation functions
704
705 /* Object allocation function */
706 __attribute__((malloc)) void * allocate_newtrans(void * ptr, int type) {
707 #ifdef STMARRAY
708   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type], 0);
709 #else
710   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type]);
711 #endif
712   ASSIGNUID(v);
713   v->type=type;
714   v->hashcode=(int)(INTPTR)v;
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->hashcode=(int)(INTPTR)v;
746   v->___length___=length;
747   return v;
748 }
749
750 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
751   objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, classsize[type]+sizeof(objheader_t));
752   struct ___Object___ * v=(struct ___Object___ *) &tmp[1];
753   ASSIGNUID(v);
754   initdsmlocks(&tmp->lock);
755   tmp->version = 1;
756   v->___objlocation___=v;
757   v->type = type;
758   v->hashcode=(int)(INTPTR)v;
759   return v;
760 }
761
762 /* Array allocation function */
763
764 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
765 #ifdef STMARRAY
766   int basesize=length*classsize[type];
767   //round the base size up
768   basesize=(basesize+LOWMASK)&HIGHMASK;
769   int numlocks=basesize>>INDEXSHIFT;
770   int bookkeepsize=(numlocks)*2*sizeof(int);
771   int *tmpint=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+basesize+sizeof(objheader_t)+bookkeepsize);
772   for(;numlocks>0;numlocks--) {
773     tmpint[0]=1;
774     tmpint+=2;
775   }
776   objheader_t *tmp=(objheader_t *)tmpint;
777   struct ArrayObject * v=(struct ArrayObject *) &tmp[1];
778   v->highindex=-1;
779   v->lowindex=MAXARRAYSIZE;
780 #else
781   objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]+sizeof(objheader_t));
782   struct ArrayObject * v=(struct ArrayObject *) &tmp[1];
783 #endif
784 #ifdef DUALVIEW
785   tmp->lock=RW_LOCK_BIAS;
786 #else
787   initdsmlocks(&tmp->lock);
788 #endif
789   tmp->version=1;
790   ASSIGNUID(v);
791   v->type=type;
792   v->hashcode=(int)(INTPTR)v;
793   if (length<0) {
794     printf("ERROR: negative array %d\n", length);
795     return NULL;
796   }
797   v->___objlocation___=(struct ___Object___ *)v;
798   v->___length___=length;
799   return v;
800 }
801 #endif
802
803 #ifndef STM
804 #if defined(PRECISE_GC)
805 #ifdef MLP
806 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
807   return allocate_new_mlp(ptr, type, 0, 0);
808 }
809 __attribute__((malloc)) void * allocate_new_mlp(void * ptr, int type, int oid, int allocsite) {
810 #else
811 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
812 #endif
813   struct ___Object___ * v=(struct ___Object___ *) mygcmalloc((struct garbagelist *) ptr, classsize[type]);
814   v->type=type;
815   v->hashcode=(int)(INTPTR)v;
816 #ifdef THREADS
817   v->tid=0;
818 #endif
819 #ifdef OPTIONAL
820   v->fses=0;
821 #endif
822 #ifdef MLP
823   v->oid=oid;
824   v->allocsite=allocsite;
825 #endif
826   return v;
827 }
828
829 /* Array allocation function */
830 #ifdef MLP
831 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
832   return allocate_newarray_mlp(ptr, type, length, 0, 0);
833 }
834  __attribute__((malloc)) struct ArrayObject * allocate_newarray_mlp(void * ptr, int type, int length, int oid, int allocsite) {
835 #else
836 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
837 #endif
838   struct ArrayObject * v=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]);
839   v->type=type;
840   v->hashcode=(int)(INTPTR)v;
841   if (length<0) {
842     printf("ERROR: negative array\n");
843     return NULL;
844   }
845   v->___length___=length;
846 #ifdef THREADS
847   v->tid=0;
848 #endif
849 #ifdef OPTIONAL
850   v->fses=0;
851 #endif
852 #ifdef MLP
853   v->oid=oid;
854   v->allocsite=allocsite;
855 #endif
856   return v;
857 }
858
859 #else
860 __attribute__((malloc)) void * allocate_new(int type) {
861   struct ___Object___ * v=FREEMALLOC(classsize[type]);
862   v->type=type;
863   v->hashcode=(int)(INTPTR)v;
864 #ifdef OPTIONAL
865   v->fses=0;
866 #endif
867   return v;
868 }
869
870 /* Array allocation function */
871
872 __attribute__((malloc)) struct ArrayObject * allocate_newarray(int type, int length) {
873   __attribute__((malloc))  struct ArrayObject * v=FREEMALLOC(sizeof(struct ArrayObject)+length*classsize[type]);
874   v->type=type;
875   v->hashcode=(int)(INTPTR)v;
876   v->___length___=length;
877 #ifdef OPTIONAL
878   v->fses=0;
879 #endif
880   return v;
881 }
882 #endif
883 #endif
884
885 /* Converts C character arrays into Java strings */
886 #ifdef PRECISE_GC
887 __attribute__((malloc)) struct ___String___ * NewStringShort(void * ptr, const short *str,int length) {
888 #else
889 __attribute__((malloc)) struct ___String___ * NewStringShort(const short *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]=str[i];
907   }
908   return strobj;
909 }
910
911 /* Converts C character arrays into Java strings */
912 #ifdef PRECISE_GC
913 __attribute__((malloc)) struct ___String___ * NewString(void * ptr, const char *str,int length) {
914 #else
915 __attribute__((malloc)) struct ___String___ * NewString(const char *str,int length) {
916 #endif
917   int i;
918 #ifdef PRECISE_GC
919   struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
920   INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
921   struct ___String___ * strobj=allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
922   chararray=(struct ArrayObject *) ptrarray[2];
923 #else
924   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
925   struct ___String___ * strobj=allocate_new(STRINGTYPE);
926 #endif
927   strobj->___value___=chararray;
928   strobj->___count___=length;
929   strobj->___offset___=0;
930
931   for(i=0; i<length; i++) {
932     ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
933   }
934   return strobj;
935 }
936
937 /* Generated code calls this if we fail a bounds check */
938
939 void failedboundschk(int num) {
940 #ifndef TASK
941   printf("Array out of bounds\n");
942 #ifdef THREADS
943   threadexit();
944 #else
945   exit(-1);
946 #endif
947 #else
948   longjmp(error_handler,2);
949 #endif
950 }
951
952 /* Abort task call */
953 void abort_task() {
954 #ifdef TASK
955   longjmp(error_handler,4);
956 #else
957   printf("Aborting\n");
958   exit(-1);
959 #endif
960 }
961
962 #ifndef SANDBOX
963 #ifdef D___System______Assert____Z
964  void CALL11(___System______Assert____Z, int ___status___, int ___status___) {
965    if (!___status___) {
966      printf("Assertion violation\n");
967      *((int *)(NULL)); //force stack trace error
968    }
969  }
970 #endif
971 #endif