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