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