I have found and (I believe) fixed a nasty bug in
storage.c:dropScriptsFrom().  Basically, the problem is with the
following code fragment:

        for (i=INSTMIN; i<instHw; i++) {
            List ds = inst(i).dicts;
            List dn = NIL;

            while (nonNull(ds)) {
                List temp = tl(ds);
                if (hd(ds)<nameHw) {
                    tl(ds) = dn;
                    dn     = ds;
                }
                ds = temp;
            }
            inst(i).dicts = rev(dn);
        }

In the above fragment, hd(ds) is a Cell representing a heap-allocated
dictionary object (i.e., a negative number); nameHw is a "name" (a
positive number).  Thus, the test always succeeds, and dictionaries
are always kept in these lists.

My first attempt at a fix was to merely discard all dictionaries from
the instances, under the assumption that this was merely a cache, and
that the dictionaries would get regenerated as needed (with some loss
of sharing); however, this failed miserably.  Evidently this data
structure is what holds on to the dictionaries for garbage collection;
when I discarded all dictionaries, they got garbage collected out from
under the code.

Thus, I needed a way to discard only "new" dictionaries.  I couldn't
see any way to tell the age of a dictionary in the current
implementation, so I added one; now there is a counter which counts
the dictionaries as they are allocated, and the current value of the
counter is stored in the dictionary (at the end).

I've appended my patch.

Carl Witty
[EMAIL PROTECTED]

diff -x *.o -x *~ -ur hugs-orig/src/storage.c hugs/src/storage.c
--- hugs-orig/src/storage.c     Tue Oct 28 04:39:12 1997
+++ hugs/src/storage.c  Tue Oct 28 05:18:11 1997
@@ -773,10 +773,20 @@
 static Class classHw;                  /* next unused class                */
 static List  classes;                  /* list of classes in current scope */
 static Inst  instHw;                   /* next unused instance record      */
+static Int   dictHw;                   /* next unused dictionary number    */
 
 struct strClass DEFTABLE(tabClass,NUM_CLASSES); /* table of class records  */
 struct strInst far *tabInst;           /* (pointer to) table of instances  */
 
+Cell newDict(len)                     /* create a new dictionary          */
+Int len; {
+    Cell dict = flatAlloc(DICTCELL, len+1);
+
+    flatSet(dict, len+1, mkInt(dictHw++));
+
+    return dict;
+}
+
 Class newClass(t)                      /* add new class to class table     */
 Text t; {
     if (classHw-CLASSMIN >= NUM_CLASSES) {
@@ -1051,6 +1061,7 @@
     Name  nameHw;
     Class classHw;
     Inst  instHw;
+    Int   dictHw;
 #if TREX
     Ext   extHw;
 #endif
@@ -1102,6 +1113,7 @@
     scripts[scriptHw].nameHw       = nameHw;
     scripts[scriptHw].classHw      = classHw;
     scripts[scriptHw].instHw       = instHw;
+    scripts[scriptHw].dictHw       = dictHw;
 #if TREX
     scripts[scriptHw].extHw       = extHw;
 #endif
@@ -1189,6 +1201,7 @@
        nameHw       = scripts[sno].nameHw;
        classHw      = scripts[sno].classHw;
        instHw       = scripts[sno].instHw;
+       dictHw       = scripts[sno].dictHw;
 #if TREX
        extHw        = scripts[sno].extHw;
 #endif
@@ -1247,7 +1260,8 @@
 
            while (nonNull(ds)) {
                List temp = tl(ds);
-               if (hd(ds)<nameHw) {
+               Cell d = hd(ds);
+               if (intOf(dictGet(d,flatLen(d)))<dictHw) {
                    tl(ds) = dn;
                     dn     = ds;
                }
@@ -2771,6 +2785,8 @@
                       classHw  = CLASSMIN;
 
                       instHw   = INSTMIN;
+
+                      dictHw   = 0;
 
                       tabInst  = (struct strInst far *)
                                    farCalloc(NUM_INSTS,sizeof(struct strInst));
diff -x *.o -x *~ -ur hugs-orig/src/storage.h hugs/src/storage.h
--- hugs-orig/src/storage.h     Thu Jul 17 13:52:59 1997
+++ hugs/src/storage.h  Tue Oct 28 05:04:18 1997
@@ -616,7 +616,7 @@
 #define dictOf(c)              flatOf(c)
 #define dictGet(d,i)           flatGet(d,i)
 #define dictSet(d,i,e)         flatSet(d,i,e)
-#define newDict(l)                     flatAlloc(DICTCELL,l)
+extern Cell newDict        Args((Int));
 
 #define dictMembersStart(cl)   (1)
 #define dictSupersStart(cl)    (dictMembersStart(cl) + cclass(cl).numMembers)

Reply via email to