This update adds precise garbage collection to the compiler and the runtime.
authorbdemsky <bdemsky>
Tue, 21 Nov 2006 02:58:19 +0000 (02:58 +0000)
committerbdemsky <bdemsky>
Tue, 21 Nov 2006 02:58:19 +0000 (02:58 +0000)
It appears to work for my test cases so far.  The Hans Boehm garbage collector is no longer needed.

17 files changed:
Robust/src/IR/Flat/BuildCode.java
Robust/src/README
Robust/src/Runtime/GenericHashtable.c
Robust/src/Runtime/GenericHashtable.h
Robust/src/Runtime/SimpleHash.c
Robust/src/Runtime/SimpleHash.h
Robust/src/Runtime/checkpoint.c
Robust/src/Runtime/checkpoint.h
Robust/src/Runtime/garbage.c [new file with mode: 0644]
Robust/src/Runtime/garbage.h [new file with mode: 0644]
Robust/src/Runtime/mem.h
Robust/src/Runtime/runtime.c
Robust/src/Runtime/runtime.h
Robust/src/buildscript
Robust/src/buildscriptrepair
Robust/src/buildscripttask
Robust/src/buildscripttaskerror

index bbddb9871a2c51fbb73306451776b5d33a745f23..62233c567754e211daddaceed7e2d1f5fd312c19 100644 (file)
@@ -229,10 +229,18 @@ public class BuildCode {
            /* 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("  }");
 
@@ -814,14 +822,22 @@ public class BuildCode {
 
        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();
@@ -833,14 +849,6 @@ public class BuildCode {
                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();
@@ -991,10 +999,8 @@ public class BuildCode {
            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++) {
@@ -1177,9 +1183,18 @@ public class BuildCode {
     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) {
@@ -1211,9 +1226,13 @@ public class BuildCode {
     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
index 38c877fd555c652f0ad177016a55fb029e57eb49..8b709157b57ee00d7515b2151a28b47b442d8c34 100644 (file)
@@ -26,7 +26,9 @@ java -cp ../cup:. Main.Main -help
 
 
 
-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
 
index 86f40e58acc92c319934f3de1b56d79062cf334e..24d9d70cb3eddc620d027679f5712f2690f3f2fd 100755 (executable)
@@ -58,6 +58,26 @@ int hashsize(struct genhashtable *ht) {
   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) {
index eb7d9846bc884d9bacf9a5ac715bd5f16bef693c..3a65a4c48fa1c6d3cf3a71e245598e9eb6e7ac1e 100755 (executable)
@@ -33,7 +33,7 @@ struct geniterator {
 
 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 *);
index 4d744238c58232de761a590189eb2051af2c6d3d..772ff0bb40aa9e77af238eac829050d78543d947 100755 (executable)
@@ -80,6 +80,25 @@ int RuntimeHashremove(struct RuntimeHash *thisvar, int key, int data) {
     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;
index ed0c0625886a454aff3c3cef5f4d33c56eb7d050..3d89d6e2d5f1f2fa1d893f386d8d145581dd28c7 100755 (executable)
@@ -22,7 +22,7 @@ struct RuntimeHash * allocateRuntimeHash(int size);
 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);
index f47488d658c831d79f0c5c744d51cb1e386e7793..e1ceaa6b94a8fd964e3cbf99bca5e7380031dda0 100644 (file)
@@ -3,8 +3,50 @@
 #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++) {
@@ -82,7 +124,11 @@ void * createcopy(void * orig) {
     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 {
@@ -91,7 +137,11 @@ void * createcopy(void * orig) {
       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;
     }
index b2c1de08e4aa93413bd5812744741549b92cb8af..9f600953500cfa39332715e0112031875266b118 100644 (file)
@@ -7,5 +7,5 @@ void ** makecheckpoint(int numparams, void ** pointerarray, struct RuntimeHash *
 void restorecheckpoint(int numparams, void ** original, void ** checkpoint, struct RuntimeHash *forward, struct RuntimeHash * reverse);
 
 void * createcopy(void * orig);
-
+void freemalloc();
 #endif
diff --git a/Robust/src/Runtime/garbage.c b/Robust/src/Runtime/garbage.c
new file mode 100644 (file)
index 0000000..c4ab01c
--- /dev/null
@@ -0,0 +1,343 @@
+#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,&copy))
+       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, &copy))
+           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, &copy))
+       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, &copy))
+       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, &copy))
+       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, &copy))
+         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, &copy))
+       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, &copy))
+         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, &copy))
+         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;
+    }
+  }
+}
diff --git a/Robust/src/Runtime/garbage.h b/Robust/src/Runtime/garbage.h
new file mode 100644 (file)
index 0000000..bf998fb
--- /dev/null
@@ -0,0 +1,12 @@
+#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
index a2212eddaf107f299273255dcd76910cb8d163b0..ed9270996522fa8b3547c600b525ce46624a2ca6 100644 (file)
@@ -9,8 +9,14 @@
 #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
index 4da7565e1a27a11f268d281d9ad212d7dbf6be41..23a43fd3bcfd66320245e99fc85ed81082117fb5 100644 (file)
@@ -15,6 +15,18 @@ extern int classsize[];
 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"
@@ -29,15 +41,9 @@ int instructioncount;
 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
@@ -48,30 +54,47 @@ int main(int argc, char **argv) {
 #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) {
@@ -295,8 +318,8 @@ void executetasks() {
       }
       {
        /* 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)) {
@@ -306,23 +329,12 @@ void executetasks() {
          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) {
@@ -342,6 +354,11 @@ void executetasks() {
            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;
        }
       }
     }
@@ -417,6 +434,23 @@ void CALL01(___System______printString____L___String___,struct ___String___ * __
 
 /* 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;
@@ -431,12 +465,22 @@ struct ArrayObject * allocate_newarray(int type, int length) {
   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;
index de2c87157382ae31a830440e5b1c331cf14b0ac1..13b2f3df90e7edd9c473209f871eb5b439ff5e9c 100644 (file)
@@ -4,14 +4,22 @@
 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
index 973219b9cd55aaaa832cb4fb997940fc3cbb4eb2..9a20f7db31d860a31a896e358b5b6d876db1aa3c 100755 (executable)
@@ -3,5 +3,7 @@ ROBUSTROOT=~/research/Robust/src
 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
index bcdf48ce9b8f7ab91dffcf97bbd0b07057cd97d0..6cb321d9b6ac9b32a8296a35908030906a5ed738 100755 (executable)
@@ -18,7 +18,7 @@ shift
 
 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
@@ -59,7 +59,7 @@ done
 
 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 \
@@ -67,5 +67,6 @@ $ROBUSTROOT/Runtime/socket.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
index 93edffbca4396867702dd0e9b502b626c5f1735c..85dcbb4462f8aa1c45d20aa54a9c13e03d1cba75 100755 (executable)
@@ -3,5 +3,7 @@ ROBUSTROOT=~/research/Robust/src
 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
index 8b4be7cd61bdd395c7ae37a0b381de22f6cc8530..9686c25168ae8365c097e2ca0602a5cecb125e9c 100755 (executable)
@@ -4,4 +4,4 @@ MAINFILE=$1
 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