It appears to work for my test cases so far. The Hans Boehm garbage collector is no longer needed.
/* Generate main method */
outmethod.println("int main(int argc, const char *argv[]) {");
outmethod.println(" int i;");
- outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
+ if (GENERATEPRECISEGC) {
+ outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
+ } else {
+ outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
+ }
outmethod.println(" for(i=1;i<argc;i++) {");
outmethod.println(" int length=strlen(argv[i]);");
- outmethod.println(" struct ___String___ *newstring=NewString(argv[i],length);");
+ if (GENERATEPRECISEGC) {
+ outmethod.println(" struct ___String___ *newstring=NewString(NULL, argv[i], length);");
+ } else {
+ outmethod.println(" struct ___String___ *newstring=NewString(argv[i], length);");
+ }
outmethod.println(" ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
outmethod.println(" }");
generateHeader(md!=null?md:task,output);
+ TempObject objecttemp=(TempObject) tempstable.get(md!=null?md:task);
+
/* Print code */
if (GENERATEPRECISEGC) {
if (md!=null)
- output.println(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+";");
+ output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
else
- output.println(" struct "+task.getSafeSymbol()+"_locals "+localsprefix+";");
+ output.print(" struct "+task.getSafeSymbol()+"_locals "+localsprefix+"={");
+
+ output.print(objecttemp.numPointers()+",");
+ output.print(paramsprefix);
+ for(int j=0;j<objecttemp.numPointers();j++)
+ output.print(", NULL");
+ output.println("};");
}
- TempObject objecttemp=(TempObject) tempstable.get(md!=null?md:task);
+
for(int i=0;i<objecttemp.numPrimitives();i++) {
TempDescriptor td=objecttemp.getPrimitive(i);
TypeDescriptor type=td.getType();
output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
}
- /* Link the local pointers into chain. */
- if (GENERATEPRECISEGC) {
- if (md!=null) {
- output.println(localsprefix+".size="+objecttemp.numPointers()+";");
- output.println(localsprefix+".next="+paramsprefix+";");
- }
- }
-
/* Generate labels first */
HashSet tovisit=new HashSet();
HashSet visited=new HashSet();
String specname=fcn.getSpec();
String varname="repairstate___";
output.println("{");
-
output.println("struct "+specname+"_state * "+varname+"=allocate"+specname+"_state();");
-
TempDescriptor[] temps=fcn.getTemps();
String[] vars=fcn.getVars();
for(int i=0;i<temps.length;i++) {
private void generateFlatNew(FlatMethod fm, FlatNew fn, PrintWriter output) {
if (fn.getType().isArray()) {
int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
- output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize())+");");
- } else
- output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
+ if (GENERATEPRECISEGC) {
+ output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize())+");");
+ } else {
+ output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize())+");");
+ }
+ } else {
+ if (GENERATEPRECISEGC) {
+ output.println(generateTemp(fm,fn.getDst())+"=allocate_new(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
+ } else {
+ output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
+ }
+ }
}
private void generateFlatOpNode(FlatMethod fm, FlatOpNode fon, PrintWriter output) {
private void generateFlatLiteralNode(FlatMethod fm, FlatLiteralNode fln, PrintWriter output) {
if (fln.getValue()==null)
output.println(generateTemp(fm, fln.getDst())+"=0;");
- else if (fln.getType().getSymbol().equals(TypeUtil.StringClass))
- output.println(generateTemp(fm, fln.getDst())+"=NewString(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
- else if (fln.getType().isBoolean()) {
+ else if (fln.getType().getSymbol().equals(TypeUtil.StringClass)) {
+ if (GENERATEPRECISEGC) {
+ output.println(generateTemp(fm, fln.getDst())+"=NewString(&"+localsprefix+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
+ } else {
+ output.println(generateTemp(fm, fln.getDst())+"=NewString(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
+ }
+ } else if (fln.getType().isBoolean()) {
if (((Boolean)fln.getValue()).booleanValue())
output.println(generateTemp(fm, fln.getDst())+"=1;");
else
-III. Using Garbage Collection
+III. Using Garbage Collection
+(DEPRECATED...THIS IS FOR CONSERVATIVE GC ONLY...WE NOW HAVE PRECISE GC.)
+
1) Download the Hans Boehm garbage collector
return ht->counter;
}
+void genrehash(struct genhashtable * ht) {
+ /* Expand hashtable */
+ struct genpointerlist **newbins=(struct genpointerlist **) RUNMALLOC(sizeof (struct genpointerlist *)*ht->currentsize);
+ struct genpointerlist **oldbins=ht->bins;
+ long j,i;
+
+ for(i=0;i<ht->currentsize;i++) {
+ struct genpointerlist * tmpptr=oldbins[i];
+ while(tmpptr!=NULL) {
+ int hashcode=genhashfunction(ht, tmpptr->src);
+ struct genpointerlist *nextptr=tmpptr->next;
+ tmpptr->next=newbins[hashcode];
+ newbins[hashcode]=tmpptr;
+ tmpptr=nextptr;
+ }
+ }
+ ht->bins=newbins;
+ RUNFREE(oldbins);
+}
+
void * gengettable(struct genhashtable *ht, void * key) {
struct genpointerlist * ptr=ht->bins[genhashfunction(ht,key)];
while(ptr!=NULL) {
struct genhashtable * genallocatehashtable(unsigned int (*hash_function)(void *),int (*comp_function)(void *,void *));
void genfreehashtable(struct genhashtable * ht);
-
+void genrehash(struct genhashtable * ht);
void * getnext(struct genhashtable *,void *);
int genputtable(struct genhashtable *, void *, void *);
void * gengettable(struct genhashtable *, void *);
return 0;
}
+void RuntimeHashrehash(struct RuntimeHash * thisvar) {
+ int newsize=thisvar->size;
+ struct RuntimeNode ** newbucket = (struct RuntimeNode **) RUNMALLOC(sizeof(struct RuntimeNode *)*newsize);
+ int i;
+ for(i=thisvar->size-1;i>=0;i--) {
+ struct RuntimeNode *ptr;
+ for(ptr=thisvar->bucket[i];ptr!=NULL;) {
+ struct RuntimeNode * nextptr=ptr->next;
+ unsigned int newhashkey=(unsigned int)ptr->key % newsize;
+ ptr->next=newbucket[newhashkey];
+ newbucket[newhashkey]=ptr;
+ ptr=nextptr;
+ }
+ }
+ thisvar->size=newsize;
+ RUNFREE(thisvar->bucket);
+ thisvar->bucket=newbucket;
+}
+
int RuntimeHashadd(struct RuntimeHash * thisvar,int key, int data) {
/* Rehash code */
unsigned int hashkey;
void RuntimeHashaddChild(struct RuntimeHash *thisvar, struct RuntimeHash * child);
void freeRuntimeHash(struct RuntimeHash *);
-
+void RuntimeHashrehash(struct RuntimeHash * thisvar);
int RuntimeHashadd(struct RuntimeHash *, int key, int data);
int RuntimeHashremove(struct RuntimeHash *,int key, int data);
bool RuntimeHashcontainskey(struct RuntimeHash *,int key);
#include "structdefs.h"
#include <string.h>
+#define MALLOCSIZE 20*1024
+
+struct malloclist {
+ struct malloclist *next;
+ int size;
+ char space[];
+};
+
+struct malloclist * top=NULL;
+int offset=0;
+
+void * cpmalloc(int size) {
+ int endoffset=offset+size;
+ if (top==NULL||endoffset>top->size) {
+ int basesize=MALLOCSIZE;
+ struct malloclist *tmp;
+ if (size>basesize)
+ basesize=size;
+ tmp=RUNMALLOC(sizeof(struct malloclist)+basesize);
+ tmp->next=top;
+ top=tmp;
+ top->size=basesize;
+ offset=0;
+ }
+ int tmpoffset=offset;
+ offset+=size;
+ return &top->space[tmpoffset];
+}
+
+void freemalloc() {
+ while(top!=NULL) {
+ struct malloclist *next=top->next;
+ RUNFREE(top);
+ top=next;
+ }
+}
+
+
void ** makecheckpoint(int numparams, void ** srcpointer, struct RuntimeHash * forward, struct RuntimeHash * reverse) {
+#ifdef PRECISE_GC
+ void **newarray=cpmalloc(sizeof(void *)*numparams);
+#else
void **newarray=RUNMALLOC(sizeof(void *)*numparams);
+#endif
struct RuntimeHash *todo=allocateRuntimeHash(100);
int i;
for(i=0;i<numparams;i++) {
if (type<NUMCLASSES) {
/* We have a normal object */
int size=classsize[type];
+#ifdef PRECISE_GC
+ void *newobj=cpmalloc(size);
+#else
void *newobj=RUNMALLOC(size);
+#endif
memcpy(newobj, orig, size);
return newobj;
} else {
int elementsize=classsize[type];
int length=ao->___length___;
int size=sizeof(struct ArrayObject)+length*elementsize;
+#ifdef PRECISE_GC
+ void *newobj=cpmalloc(size);
+#else
void *newobj=RUNMALLOC(size);
+#endif
memcpy(newobj, orig, size);
return newobj;
}
void restorecheckpoint(int numparams, void ** original, void ** checkpoint, struct RuntimeHash *forward, struct RuntimeHash * reverse);
void * createcopy(void * orig);
-
+void freemalloc();
#endif
--- /dev/null
+#include "garbage.h"
+#include "runtime.h"
+#include "structdefs.h"
+#include "Queue.h"
+#include "SimpleHash.h"
+#include "GenericHashtable.h"
+#include <string.h>
+
+#define NUMPTRS 100
+
+#define INITIALHEAPSIZE 10*1024
+#define GCPOINT(x) ((int)((x)*0.9))
+/* This define takes in how full the heap is initially and returns a new heap size to use */
+#define HEAPSIZE(x,y) (((int)((x)/0.6))+y)
+
+#ifdef TASK
+extern struct Queue * activetasks;
+extern struct parameterwrapper * objectqueues[NUMCLASSES];
+extern struct genhashtable * failedtasks;
+extern struct RuntimeHash *forward;
+extern struct RuntimeHash *reverse;
+extern struct RuntimeHash *fdtoobject;
+#endif
+
+struct pointerblock {
+ void * ptrs[NUMPTRS];
+ struct pointerblock *next;
+};
+
+struct pointerblock *head=NULL;
+int headindex=0;
+struct pointerblock *tail=NULL;
+int tailindex=0;
+struct pointerblock *spare=NULL;
+
+
+void enqueue(void *ptr) {
+ if (headindex==NUMPTRS) {
+ struct pointerblock * tmp;
+ if (spare!=NULL) {
+ tmp=spare;
+ spare=NULL;
+ } else
+ tmp=malloc(sizeof(struct pointerblock));
+ head->next=tmp;
+ head=tmp;
+ headindex=0;
+ }
+ head->ptrs[headindex++]=ptr;
+}
+
+void * dequeue() {
+ if (tailindex==NUMPTRS) {
+ struct pointerblock *tmp=tail;
+ tail=tail->next;
+ tailindex=0;
+ if (spare!=NULL)
+ free(tmp);
+ else
+ spare=tmp;
+ }
+ return tail->ptrs[tailindex++];
+}
+
+int moreItems() {
+ if ((head==tail)&&(tailindex==headindex))
+ return 0;
+ return 1;
+}
+
+void collect(struct garbagelist * stackptr) {
+ if (head==NULL) {
+ headindex=0;
+ tailindex=0;
+ head=tail=malloc(sizeof(struct pointerblock));
+ }
+ /* Check current stack */
+ while(stackptr!=NULL) {
+ int i;
+ for(i=0;i<stackptr->size;i++) {
+ void * orig=stackptr->array[i];
+ void * copy;
+ if (gc_createcopy(orig,©))
+ enqueue(orig);
+ stackptr->array[i]=copy;
+ }
+ stackptr=stackptr->next;
+ }
+
+#ifdef TASK
+ {
+ /* Update objectsets */
+ int i;
+ for(i=0;i<NUMCLASSES;i++) {
+ struct parameterwrapper * p=objectqueues[i];
+ while(p!=NULL) {
+ struct RuntimeHash * set=p->objectset;
+ struct RuntimeNode * ptr=set->listhead;
+ while(ptr!=NULL) {
+ void *orig=(void *)ptr->key;
+ void *copy;
+ if (gc_createcopy(orig, ©))
+ enqueue(orig);
+ ptr->key=(int)copy;
+
+ ptr=ptr->lnext;
+ }
+ RuntimeHashrehash(set); /* Rehash the table */
+ p=p->next;
+ }
+ }
+ }
+
+ if (forward!=NULL) {
+ struct RuntimeNode * ptr=forward->listhead;
+ while(ptr!=NULL) {
+ void * orig=(void *)ptr->key;
+ void *copy;
+ if (gc_createcopy(orig, ©))
+ enqueue(orig);
+ ptr->key=(int)copy;
+
+ ptr=ptr->lnext;
+ }
+ RuntimeHashrehash(forward); /* Rehash the table */
+ }
+
+ if (reverse!=NULL) {
+ struct RuntimeNode * ptr=reverse->listhead;
+ while(ptr!=NULL) {
+ void *orig=(void *)ptr->data;
+ void *copy;
+ if (gc_createcopy(orig, ©))
+ enqueue(orig);
+ ptr->data=(int)copy;
+
+ ptr=ptr->lnext;
+ }
+ }
+
+ {
+ struct RuntimeNode * ptr=fdtoobject->listhead;
+ while(ptr!=NULL) {
+ void *orig=(void *)ptr->data;
+ void *copy;
+ if (gc_createcopy(orig, ©))
+ enqueue(orig);
+ ptr->data=(int)copy;
+
+ ptr=ptr->lnext;
+ }
+ }
+
+
+ {
+ /* Update active tasks */
+ struct QueueItem * ptr=activetasks->head;
+ while (ptr!=NULL) {
+ struct taskparamdescriptor *tpd=ptr->objectptr;
+ int i;
+ for(i=0;i<tpd->numParameters;i++) {
+ void *orig=tpd->parameterArray[i];
+ void *copy;
+ if (gc_createcopy(orig, ©))
+ enqueue(orig);
+ tpd->parameterArray[i]=copy;
+ }
+ ptr=ptr->next;
+ }
+ }
+ /* Update failed tasks */
+ {
+ struct genpointerlist * ptr=failedtasks->list;
+ while(ptr!=NULL) {
+ void *orig=ptr->src;
+ void *copy;
+ if (gc_createcopy(orig, ©))
+ enqueue(orig);
+ ptr->src=copy;
+ ptr->object=copy;
+ ptr=ptr->inext;
+ }
+ genrehash(failedtasks);
+ }
+#endif
+
+ while(moreItems()) {
+ void * ptr=dequeue();
+ void *cpy=((void **)ptr)[1];
+ int type=((int *)cpy)[0];
+ int * pointer=pointerarray[type];
+ if (pointer==0) {
+ /* Array of primitives */
+ /* Do nothing */
+ } else if (((int)pointer)==1) {
+ /* Array of pointers */
+ struct ArrayObject *ao=(struct ArrayObject *) ptr;
+ struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
+ int length=ao->___length___;
+ int i;
+ for(i=0;i<length;i++) {
+ void *objptr=((void **)(((char *)& ao->___length___)+sizeof(int)))[i];
+ void * copy;
+ if (gc_createcopy(objptr, ©))
+ enqueue(objptr);
+ ((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]=copy;
+ }
+ } else {
+ int size=pointer[0];
+ int i;
+ for(i=1;i<=size;i++) {
+ int offset=pointer[i];
+ void * objptr=*((void **)(((int)ptr)+offset));
+ void * copy;
+ if (gc_createcopy(objptr, ©))
+ enqueue(objptr);
+ *((void **) (((int)cpy)+offset))=copy;
+ }
+ }
+ }
+}
+
+void * curr_heapbase=0;
+void * curr_heapptr=0;
+void * curr_heapgcpoint=0;
+void * curr_heaptop=0;
+
+void * to_heapbase=0;
+void * to_heapptr=0;
+void * to_heaptop=0;
+long lastgcsize=0;
+
+void * tomalloc(int size) {
+ void * ptr=to_heapptr;
+ if ((size%4)!=0)
+ size+=(4-(size%4));
+ to_heapptr+=size;
+ return ptr;
+}
+
+void * mygcmalloc(struct garbagelist * stackptr, int size) {
+ void *ptr=curr_heapptr;
+ if ((size%4)!=0)
+ size+=(4-(size%4));
+ curr_heapptr+=size;
+ if (curr_heapptr>curr_heapgcpoint) {
+ if (curr_heapbase==0) {
+ /* Need to allocate base heap */
+ curr_heapbase=malloc(INITIALHEAPSIZE);
+ bzero(curr_heapbase, INITIALHEAPSIZE);
+ curr_heaptop=curr_heapbase+INITIALHEAPSIZE;
+ curr_heapgcpoint=((char *) curr_heapbase)+GCPOINT(INITIALHEAPSIZE);
+ curr_heapptr=curr_heapbase+size;
+
+ to_heapbase=malloc(INITIALHEAPSIZE);
+ to_heaptop=to_heapbase+INITIALHEAPSIZE;
+ to_heapptr=to_heapbase;
+ return curr_heapbase;
+ }
+
+ /* Grow the to heap if necessary */
+ {
+ int curr_heapsize=curr_heaptop-curr_heapbase;
+ int to_heapsize=to_heaptop-to_heapbase;
+ int last_heapsize=0;
+ if (lastgcsize>0) {
+ last_heapsize=HEAPSIZE(lastgcsize, size);
+ if ((last_heapsize%4)!=0)
+ last_heapsize+=(4-(last_heapsize%4));
+ }
+ if (curr_heapsize>last_heapsize)
+ last_heapsize=curr_heapsize;
+ if (last_heapsize>to_heapsize) {
+ free(to_heapbase);
+ to_heapbase=malloc(last_heapsize);
+ to_heaptop=to_heapbase+last_heapsize;
+ to_heapptr=to_heapbase;
+ }
+ }
+
+ /* Do our collection */
+ collect(stackptr);
+
+ /* Update stat on previous gc size */
+ lastgcsize=to_heapptr-to_heapbase;
+
+ /* Flip to/curr heaps */
+ {
+ void * tmp=to_heapbase;
+ to_heapbase=curr_heapbase;
+ curr_heapbase=tmp;
+
+ tmp=to_heaptop;
+ to_heaptop=curr_heaptop;
+ curr_heaptop=tmp;
+
+ tmp=to_heapptr;
+ curr_heapptr=to_heapptr+size;
+ curr_heapgcpoint=((char *) curr_heapbase)+GCPOINT(curr_heaptop-curr_heapbase);
+ to_heapptr=to_heapbase;
+
+ //XXXXX Need check here in case we allocate a really big object
+ bzero(tmp, curr_heaptop-tmp);
+ return tmp;
+ }
+ } else
+ return ptr;
+}
+
+
+int gc_createcopy(void * orig, void ** copy_ptr) {
+ if (orig==0) {
+ *copy_ptr=NULL;
+ return 0;
+ } else {
+ int type=((int *)orig)[0];
+ if (type==-1) {
+ *copy_ptr=((void **)orig)[1];
+ return 0;
+ } if (type<NUMCLASSES) {
+ /* We have a normal object */
+ int size=classsize[type];
+ void *newobj=tomalloc(size);
+ memcpy(newobj, orig, size);
+ ((int *)orig)[0]=-1;
+ ((void **)orig)[1]=newobj;
+ *copy_ptr=newobj;
+ return 1;
+ } else {
+ /* We have an array */
+ struct ArrayObject *ao=(struct ArrayObject *)orig;
+ int elementsize=classsize[type];
+ int length=ao->___length___;
+ int size=sizeof(struct ArrayObject)+length*elementsize;
+ void *newobj=tomalloc(size);
+ memcpy(newobj, orig, size);
+ ((int *)orig)[0]=-1;
+ ((void **)orig)[1]=newobj;
+ *copy_ptr=newobj;
+ return 1;
+ }
+ }
+}
--- /dev/null
+#ifndef GARBAGE_H
+#define GARBAGE_H
+struct garbagelist {
+ int size;
+ struct garbagelist *next;
+ void * array[];
+};
+
+void collect(struct garbagelist *stackptr);
+int gc_createcopy(void * orig, void **);
+void * mygcmalloc(struct garbagelist * ptr, int size);
+#endif
#define RUNMALLOC(x) GC_malloc(x)
#define RUNFREE(x)
#else
+#ifdef PRECISE_GC
+#include "garbage.h"
+#define RUNMALLOC(x) calloc(1,x)
+#define RUNFREE(x) free(x)
+#else
#define FREEMALLOC(x) calloc(1,x)
#define RUNMALLOC(x) calloc(1,x)
#define RUNFREE(x) free(x)
#endif
#endif
+#endif
jmp_buf error_handler;
int instructioncount;
+char *options;
+int injectfailures=0;
+float failurechance=0;
+int debugtask=0;
+int injectinstructionfailures;
+int failurecount;
+float instfailurechance=0;
+int numfailures;
+int instaccum=0;
+
+
+
#ifdef TASK
#include "checkpoint.h"
#include "Queue.h"
struct Queue * activetasks;
struct parameterwrapper * objectqueues[NUMCLASSES];
struct genhashtable * failedtasks;
-char *options;
-int injectfailures=0;
-float failurechance=0;
-int debugtask=0;
-int injectinstructionfailures;
-int failurecount;
-float instfailurechance=0;
-int numfailures;
-int instaccum=0;
+struct RuntimeHash * forward;
+struct RuntimeHash * reverse;
+
int main(int argc, char **argv) {
#ifdef BOEHM_GC
#endif
processOptions();
- {
- int i;
- /* Allocate startup object */
- struct ___StartupObject___ *startupobject=(struct ___StartupObject___*) allocate_new(STARTUPTYPE);
- struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);
+ /* Create table for failed tasks */
failedtasks=genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
(int (*)(void *,void *)) &comparetpd);
+ /* Create queue of active tasks */
activetasks=createQueue();
-
- /* Set flags */
+
+ /* Process task information */
processtasks();
- flagorand(startupobject,1,0xFFFFFFFF);
- /* Build array of strings */
+ /* Create startup object */
+ createstartupobject(argc, argv);
- startupobject->___parameters___=stringarray;
+ /* Start executing the tasks */
+ executetasks();
+}
+void createstartupobject(int argc, char ** argv) {
+ int i;
+
+ /* Allocate startup object */
+#ifdef PRECISE_GC
+ struct ___StartupObject___ *startupobject=(struct ___StartupObject___*) allocate_new(NULL, STARTUPTYPE);
+ struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);
+#else
+ struct ___StartupObject___ *startupobject=(struct ___StartupObject___*) allocate_new(STARTUPTYPE);
+ struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);
+#endif
+ /* Build array of strings */
+ startupobject->___parameters___=stringarray;
for(i=1;i<argc;i++) {
int length=strlen(argv[i]);
+#ifdef PRECISE_GC
+ struct ___String___ *newstring=NewString(NULL, argv[i],length);
+#else
struct ___String___ *newstring=NewString(argv[i],length);
+#endif
((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;
}
- executetasks();
- }
+
+ /* Set initialized flag for startup object */
+ flagorand(startupobject,1,0xFFFFFFFF);
}
int hashCodetpd(struct taskparamdescriptor *ftd) {
}
{
/* Checkpoint the state */
- struct RuntimeHash * forward=allocateRuntimeHash(100);
- struct RuntimeHash * reverse=allocateRuntimeHash(100);
+ forward=allocateRuntimeHash(100);
+ reverse=allocateRuntimeHash(100);
void ** checkpoint=makecheckpoint(tpd->task->numParameters, &taskpointerarray[OFFSET], forward, reverse);
int x;
if (x=setjmp(error_handler)) {
printf("Fatal Error=%d, Recovering!\n",x);
#endif
genputtable(failedtasks,tpd,tpd);
- /* for(i=0;i<tpd->task->numParameters;i++) {
- void *parameter=tpd->parameterArray[i];
- {
- // Create mapping from object -> failed tasks
- struct tpdlist * tpnew=RUNMALLOC(sizeof(struct tpdlist));
- tpnew->task=tpd;
- if (gencontains(failedobjects, parameter)) {
- struct tpdlist * tpdptr=gengettable(failedobjects, parameter);
- tpnew->next=tpdptr->next;
- tpdptr->next=tpnew;
- } else {
- tpnew->next=NULL;
- genputtable(failedobjects, parameter, tpnew);
- }
- }
- } */
restorecheckpoint(tpd->task->numParameters, &taskpointerarray[OFFSET], checkpoint, forward, reverse);
+ freeRuntimeHash(forward);
+ freeRuntimeHash(reverse);
+ freemalloc();
+ forward=NULL;
+ reverse=NULL;
} else {
if (injectfailures) {
if ((((double)random())/RAND_MAX)<failurechance) {
printf("EXIT %s count=%d\n",tpd->task->name, (instaccum-instructioncount));
} else
((void (*) (void **)) tpd->task->taskptr)(taskpointerarray);
+ freeRuntimeHash(forward);
+ freeRuntimeHash(reverse);
+ freemalloc();
+ forward=NULL;
+ reverse=NULL;
}
}
}
/* Object allocation function */
+#ifdef PRECISE_GC
+void * allocate_new(void * ptr, int type) {
+ void * v=mygcmalloc((struct garbagelist *) ptr, classsize[type]);
+ *((int *)v)=type;
+ return v;
+}
+
+/* Array allocation function */
+
+struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
+ struct ArrayObject * v=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]);
+ v->type=type;
+ v->___length___=length;
+ return v;
+}
+
+#else
void * allocate_new(int type) {
void * v=FREEMALLOC(classsize[type]);
*((int *)v)=type;
v->___length___=length;
return v;
}
+#endif
-/* Converts C character arrays into Java strings */
+/* Converts C character arrays into Java strings */
+#ifdef PRECISE_GC
+struct ___String___ * NewString(void * ptr, const char *str,int length) {
+#else
struct ___String___ * NewString(const char *str,int length) {
+#endif
+#ifdef PRECISE_GC
+ struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
+ struct ___String___ * strobj=allocate_new((struct garbagelist *) ptr, STRINGTYPE);
+#else
struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
struct ___String___ * strobj=allocate_new(STRINGTYPE);
+#endif
int i;
strobj->___value___=chararray;
strobj->___count___=length;
extern jmp_buf error_handler;
extern int instructioncount;
-void * allocate_new(int type);
+#ifdef PRECISE_GC
+#include "garbage.h"
+void * allocate_new(void *, int type);
+struct ArrayObject * allocate_newarray(void *, int type, int length);
+struct ___String___ * NewString(void *, const char *str,int length);
+#else
+void * allocate_new(struct int type);
struct ArrayObject * allocate_newarray(int type, int length);
struct ___String___ * NewString(const char *str,int length);
+#endif
void failedboundschk();
void failednullptr();
void abort_task();
void injectinstructionfailure();
+void createstartupobject();
#ifdef PRECISE_GC
#define VAR(name) ___params___->name
MAINFILE=$1
shift
mkdir tmpbuilddirectory
+
java -cp $ROBUSTROOT/../cup/:$ROBUSTROOT Main.Main -classlibrary $ROBUSTROOT/ClassLibrary/ -dir tmpbuilddirectory -precise -mainclass $MAINFILE $@
-gcc -I$ROBUSTROOT/Runtime -Itmpbuilddirectory -DPRECISE_GC -O0 -g tmpbuilddirectory/methods.c $ROBUSTROOT/Runtime/runtime.c $ROBUSTROOT/Runtime/file.c $ROBUSTROOT/Runtime/option.c -o $MAINFILE.bin
\ No newline at end of file
+
+gcc -I$ROBUSTROOT/Runtime -Itmpbuilddirectory -DPRECISE_GC -O0 -g tmpbuilddirectory/methods.c $ROBUSTROOT/Runtime/runtime.c $ROBUSTROOT/Runtime/file.c $ROBUSTROOT/Runtime/garbage.c $ROBUSTROOT/Runtime/option.c -o $MAINFILE.bin
mkdir $BUILDDIR
java -cp $ROBUSTROOT/../cup/:$ROBUSTROOT Main.Main -classlibrary \
-$ROBUSTROOT/ClassLibrary/ -dir $BUILDDIR -struct $MAINFILE -conscheck \
+$ROBUSTROOT/ClassLibrary/ -dir $BUILDDIR -precise -struct $MAINFILE -conscheck \
-struct structfile -task $@
# Build all of the consistency specs
cd $CURDIR
gcc -I$ROBUSTROOT/Runtime -I. -I$BUILDDIR/specdir \
--IRuntime/include -I$BUILDDIR -O0 -DBOEHM_GC -DCONSCHECK \
+-IRuntime/include -I$BUILDDIR -O0 -DPRECISE_GC -DCONSCHECK \
-LRuntime/lib/ -lgc -DTASK -g tmpbuilddirectory/methods.c \
tmpbuilddirectory/taskdefs.c $ROBUSTROOT/Runtime/runtime.c \
$ROBUSTROOT/Runtime/file.c \
$ROBUSTROOT/Runtime/Queue.c $ROBUSTROOT/Runtime/SimpleHash.c \
$ROBUSTROOT/Runtime/checkpoint.c \
$ROBUSTROOT/Runtime/option.c \
+$ROBUSTROOT/Runtime/garbage.c \
$ROBUSTROOT/Runtime/GenericHashtable.c $BUILDDIR/specdir/*.o -o \
$MAINFILE.bin
MAINFILE=$1
shift
mkdir tmpbuilddirectory
+
java -cp $ROBUSTROOT/../cup/:$ROBUSTROOT Main.Main -classlibrary $ROBUSTROOT/ClassLibrary/ -dir tmpbuilddirectory -precise -struct $MAINFILE -task $@
-gcc -DPRECISE_GC -I$ROBUSTROOT/Runtime -I. -IRuntime/include -Itmpbuilddirectory -O0 -DBOEHM_GC -LRuntime/lib/ -lgc -DTASK -DDEBUG -g tmpbuilddirectory/methods.c tmpbuilddirectory/taskdefs.c $ROBUSTROOT/Runtime/runtime.c $ROBUSTROOT/Runtime/file.c $ROBUSTROOT/Runtime/socket.c $ROBUSTROOT/Runtime/Queue.c $ROBUSTROOT/Runtime/SimpleHash.c $ROBUSTROOT/Runtime/checkpoint.c $ROBUSTROOT/Runtime/GenericHashtable.c $ROBUSTROOT/Runtime/option.c -o $MAINFILE.bin
\ No newline at end of file
+
+gcc -DPRECISE_GC -I$ROBUSTROOT/Runtime -I. -IRuntime/include -Itmpbuilddirectory -O0 -LRuntime/lib/ -DTASK -DDEBUG -g tmpbuilddirectory/methods.c tmpbuilddirectory/taskdefs.c $ROBUSTROOT/Runtime/runtime.c $ROBUSTROOT/Runtime/file.c $ROBUSTROOT/Runtime/socket.c $ROBUSTROOT/Runtime/Queue.c $ROBUSTROOT/Runtime/SimpleHash.c $ROBUSTROOT/Runtime/checkpoint.c $ROBUSTROOT/Runtime/GenericHashtable.c $ROBUSTROOT/Runtime/option.c $ROBUSTROOT/Runtime/garbage.c -o $MAINFILE.bin
\ No newline at end of file
shift
mkdir tmpbuilddirectory
java -cp $ROBUSTROOT/../cup/:$ROBUSTROOT Main.Main -classlibrary $ROBUSTROOT/ClassLibrary/ -dir tmpbuilddirectory -struct $MAINFILE -task -instructionfailures $@
-gcc -I$ROBUSTROOT/Runtime -I. -IRuntime/include -Itmpbuilddirectory -O0 -DBOEHM_GC -LRuntime/lib/ -lgc -DTASK -DDEBUG -g tmpbuilddirectory/methods.c tmpbuilddirectory/taskdefs.c $ROBUSTROOT/Runtime/runtime.c $ROBUSTROOT/Runtime/file.c $ROBUSTROOT/Runtime/socket.c $ROBUSTROOT/Runtime/Queue.c $ROBUSTROOT/Runtime/SimpleHash.c $ROBUSTROOT/Runtime/checkpoint.c $ROBUSTROOT/Runtime/GenericHashtable.c $ROBUSTROOT/Runtime/option.c -o $MAINFILE.bin
\ No newline at end of file
+gcc -I$ROBUSTROOT/Runtime -I. -IRuntime/include -Itmpbuilddirectory -O0 -DPRECISE_GC -LRuntime/lib/ -DTASK -DDEBUG -g tmpbuilddirectory/methods.c tmpbuilddirectory/taskdefs.c $ROBUSTROOT/Runtime/runtime.c $ROBUSTROOT/Runtime/file.c $ROBUSTROOT/Runtime/socket.c $ROBUSTROOT/Runtime/Queue.c $ROBUSTROOT/Runtime/SimpleHash.c $ROBUSTROOT/Runtime/checkpoint.c $ROBUSTROOT/Runtime/GenericHashtable.c $ROBUSTROOT/Runtime/option.c $ROBUSTROOT/Runtime/garbage.c -o $MAINFILE.bin
\ No newline at end of file