Changes to support garbage collection with tags...
authorbdemsky <bdemsky>
Thu, 10 May 2007 09:36:27 +0000 (09:36 +0000)
committerbdemsky <bdemsky>
Thu, 10 May 2007 09:36:27 +0000 (09:36 +0000)
This change ensures that tags don't keep objects alive.

Robust/src/ClassLibrary/TagDescriptor.java
Robust/src/Runtime/garbage.c
Robust/src/Runtime/garbage.h
Robust/src/Runtime/runtime.c
Robust/src/Runtime/runtime.h

index a17c3c527d30d6397a77eb28f3e478f97adf7d37..be067fa7554da62ae75d494e13c9522ddfb1290b 100644 (file)
@@ -2,5 +2,4 @@
  * internal use to keep track of tags. */
 
 private class TagDescriptor {
-    Object tagset;
 }
index 8dc7d5feeb7c989d6602a533f2e1a9dcbdd4e791..a0184390081c503b5a27c4a075c917440d2d730c 100644 (file)
@@ -81,6 +81,22 @@ int moreItems() {
   return 1;
 }
 
+#ifdef TASK
+struct pointerblock *taghead=NULL;
+int tagindex=0;
+
+void enqueuetag(struct ___TagDescriptor___ *ptr) {
+  if (tagindex==NUMPTRS) {
+    struct pointerblock * tmp=malloc(sizeof(struct pointerblock));
+    tmp->next=taghead;
+    taghead=tmp;
+    tagindex=0;
+  }
+  taghead->ptrs[tagindex++]=ptr;
+}
+#endif
+
+
 void collect(struct garbagelist * stackptr) {
 #ifdef THREADS
   needtocollect=1;
@@ -98,11 +114,20 @@ void collect(struct garbagelist * stackptr) {
     tailindex=0;
     head=tail=malloc(sizeof(struct pointerblock));
   }
+
+#ifdef TASK
+  if (taghead==NULL) {
+    tagindex=0;
+    taghead=malloc(sizeof(struct pointerblock));
+    taghead->next=NULL;
+  }
+#endif
+
   /* Check current stack */
 #ifdef THREADS
  {
    struct listitem *listptr=list;
-   while(stackptr!=NULL) {
+   while(1) {
 #endif
      
   while(stackptr!=NULL) {
@@ -126,7 +151,8 @@ void collect(struct garbagelist * stackptr) {
     listptr->locklist=copy;
     stackptr=listptr->stackptr;
     listptr=listptr->next;
-  }
+  } else
+    break;
    }
  }
 #endif
@@ -249,7 +275,16 @@ void collect(struct garbagelist * stackptr) {
     void * ptr=dequeue();
     void *cpy=((void **)ptr)[1];
     int type=((int *)cpy)[0];
-    int * pointer=pointerarray[type];
+    int * pointer;
+#ifdef TASK
+    if(type==TAGTYPE) {
+      /* Enqueue Tag */
+      /* Nothing is inside */
+      enqueuetag(ptr);
+      continue;
+    }
+#endif
+    pointer=pointerarray[type];
     if (pointer==0) {
       /* Array of primitives */
       /* Do nothing */
@@ -279,12 +314,69 @@ void collect(struct garbagelist * stackptr) {
       }
     }
   }
+#ifdef TASK
+  fixtags();
+#endif
+
 #ifdef THREADS
   needtocollect=0;
   pthread_mutex_unlock(&gclistlock);
 #endif
 }
 
+#ifdef TASK
+void fixtags() {
+  while(taghead!=NULL) {
+    int i;
+    struct pointerblock *tmp=taghead->next;
+    for(i=0;i<tagindex;i++) {
+      struct ___TagDescriptor___ *tagd=taghead->ptrs[i];
+      struct ___Object___ *obj=tagd->flagptr;
+      struct ___TagDescriptor___ *copy=((struct ___TagDescriptor___**)tagd)[1];
+      if (obj->type==-1) {
+       /* Single object case */
+       copy->flagptr=((struct ___Object___**)obj)[1];
+      } else if (obj->type==OBJECTARRAYTYPE) {
+       /* Array case */
+       struct ArrayObject *ao=(struct ArrayObject *) obj;
+       int livecount=0;
+       int j;
+       int k=0;
+       struct ArrayObject *aonew;
+       
+       /* Count live objects */
+       for(j=0;j<ao->___cachedCode___;j++) {
+         struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, j);
+         if (tobj->type==-1)
+           livecount++;
+       }
+       
+       livecount=((livecount-1)/OBJECTARRAYINTERVAL+1)*OBJECTARRAYINTERVAL;
+       aonew=(struct ArrayObject *) tomalloc(sizeof(struct ArrayObject)+sizeof(struct ___Object___*)*livecount);
+       aonew->type=OBJECTARRAYTYPE;
+       aonew->___length___=livecount;
+       copy->flagptr=aonew;
+       for(j=0;j<ao->___cachedCode___;j++) {
+         struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, j);
+         if (tobj->type==-1) {
+           struct ___Object___ * tobjcpy=((struct ___Object___**)tobj)[1];
+           ARRAYSET(aonew, struct ___Object___*, k++,tobjcpy);
+         }
+       }
+       aonew->___cachedCode___=k;
+       
+      } else {
+       /* No object live anymore */
+       copy->flagptr=NULL;
+      }
+    }
+    free(taghead);
+    taghead=tmp;
+    tagindex=NUMPTRS;
+  }
+}
+#endif
+
 void * curr_heapbase=0;
 void * curr_heapptr=0;
 void * curr_heapgcpoint=0;
index ee5b79ec80fc1677f9e004eef11adf561a7a708e..c021ac6415bd0db3b9575c8e03a5c3020784bcf6 100644 (file)
@@ -13,11 +13,16 @@ struct listitem {
   struct ___Object___ * locklist;
 };
 
+#ifdef TASK
+void fixtags();
+#endif
+
 #ifdef THREADS
 void checkcollect(void * ptr);
 struct listitem * stopforgc(struct garbagelist * ptr);
 void restartaftergc(struct listitem * litem);
 #endif
+void * tomalloc(int size);
 void collect(struct garbagelist *stackptr);
 int gc_createcopy(void * orig, void **);
 void * mygcmalloc(struct garbagelist * ptr, int size);
index 0c5b4c5c394378ca07454c7f0bc817baab4a4bd9..e9fff728dccc1b62359991fe8cabeddaa7076edb 100644 (file)
 #include<stdio.h>
 #include "option.h"
 
-#define ARRAYSET(array, type, index, value) \
-((type *)(&(& array->___length___)[1]))[index]=value
-
-#define ARRAYGET(array, type, index) \
-((type *)(&(& array->___length___)[1]))[index]
-
 extern int classsize[];
 jmp_buf error_handler;
 int instructioncount;
@@ -127,8 +121,6 @@ int comparetpd(struct taskparamdescriptor *ftd1, struct taskparamdescriptor *ftd
   return 1;
 }
 
-#define TAGARRAYINTERVAL 10
-#define OBJECTARRAYINTERVAL 10
 
 /* This function sets a tag. */
 #ifdef PRECISE_GC
@@ -190,10 +182,10 @@ void tagset(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
   }
 
   {
-    struct ___Object___ * tagset=tagd->___tagset___;
+    struct ___Object___ * tagset=tagd->flagptr;
     
     if(tagset==NULL) {
-      tagd->___tagset___=obj;
+      tagd->flagptr=obj;
     } else if (tagset->type!=OBJECTARRAYTYPE) {
 #ifdef PRECISE_GC
       int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
@@ -203,10 +195,10 @@ void tagset(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
 #else
       struct ArrayObject * ao=allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
 #endif
-      ARRAYSET(ao, struct ___Object___ *, 0, tagd->___tagset___);
+      ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
       ARRAYSET(ao, struct ___Object___ *, 1, obj);
       ao->___cachedCode___=2;
-      tagd->___tagset___=(struct ___Object___ *)ao;
+      tagd->flagptr=(struct ___Object___ *)ao;
     } else {
       struct ArrayObject *ao=(struct ArrayObject *) tagset;
       if (ao->___cachedCode___<ao->___length___) {
@@ -218,7 +210,7 @@ void tagset(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
        struct ArrayObject * aonew=allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
        obj=(struct ___Object___ *)ptrarray[2];
        tagd=(struct ___TagDescriptor___ *)ptrarray[3];
-       ao=(struct ArrayObject *)tagd->___tagset___;
+       ao=(struct ArrayObject *)tagd->flagptr;
 #else
        struct ArrayObject * aonew=allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
 #endif
@@ -227,7 +219,7 @@ void tagset(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
          ARRAYSET(aonew, struct ___Object___*, i, ARRAYGET(ao, struct ___Object___*, i));
        }
        ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
-       tagd->___tagset___=(struct ___Object___ *) ao;
+       tagd->flagptr=(struct ___Object___ *) ao;
       }
     }
   }
@@ -267,10 +259,10 @@ void tagclear(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
   }
  PROCESSCLEAR:
   {
-    struct ___Object___ *tagset=tagd->___tagset___;
+    struct ___Object___ *tagset=tagd->flagptr;
     if (tagset->type!=OBJECTARRAYTYPE) {
       if (tagset==obj)
-       tagd->___tagset___=NULL;
+       tagd->flagptr=NULL;
       else
        printf("ERROR 3 in tagclear\n");
     } else {
@@ -284,7 +276,7 @@ void tagclear(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
            ARRAYSET(ao, struct ___Object___ *, i, ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
          ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
          if (ao->___cachedCode___==0)
-           tagd->___tagset___=NULL;
+           tagd->flagptr=NULL;
          goto ENDCLEAR;
        }
       }
@@ -838,7 +830,7 @@ int toiHasNext(struct tagobjectiterator *it, void ** objectarray) {
   } else if (it->numtags>0) {
     /* Use tags to locate appropriate objects */
     struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
-    struct ___Object___ *objptr=tag->___tagset___;
+    struct ___Object___ *objptr=tag->flagptr;
     int i;
     if (objptr->type!=OBJECTARRAYTYPE) {
       if (it->tagobjindex>0)
@@ -878,7 +870,7 @@ int toiHasNext(struct tagobjectiterator *it, void ** objectarray) {
 
 int containstag(struct ___Object___ *ptr, struct ___TagDescriptor___ *tag) {
   int j;
-  struct ___Object___ * objptr=tag->___tagset___;
+  struct ___Object___ * objptr=tag->flagptr;
   if (objptr->type==OBJECTARRAYTYPE) {
     struct ArrayObject *ao=(struct ArrayObject *)objptr;
     for(j=0;j<ao->___cachedCode___;j++) {
@@ -907,7 +899,7 @@ void toiNext(struct tagobjectiterator *it , void ** objectarray) {
   } else if (it->numtags>0) {
     /* Use tags to locate appropriate objects */
     struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
-    struct ___Object___ *objptr=tag->___tagset___;
+    struct ___Object___ *objptr=tag->flagptr;
     if (objptr->type!=OBJECTARRAYTYPE) {
       it->tagobjindex++;
       objectarray[it->slot]=objptr;
index 844039e642734afce41f58288c4d48ab5130c33c..19990a009952588187ded7843907017b22303204 100644 (file)
@@ -5,6 +5,15 @@ extern jmp_buf error_handler;
 extern int instructioncount;
 extern int failurecount;
 
+#define TAGARRAYINTERVAL 10
+#define OBJECTARRAYINTERVAL 10
+
+#define ARRAYSET(array, type, index, value) \
+((type *)(&(& array->___length___)[1]))[index]=value
+
+#define ARRAYGET(array, type, index) \
+((type *)(&(& array->___length___)[1]))[index]
+
 #ifdef PRECISE_GC
 #include "garbage.h"
 void * allocate_new(void *, int type);