help-smalltalk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Help-smalltalk] Re: v 2.3


From: Paolo Bonzini
Subject: [Help-smalltalk] Re: v 2.3
Date: Tue, 12 Dec 2006 10:07:15 +0100
User-agent: Thunderbird 1.5.0.8 (Macintosh/20061025)


st> address@hidden:~/src/smalltalk$ cd
address@hidden:~$ gst
gst: Aborted
(ip 4)HomedAssociation(Association)>>#hash

I got another report privately about this, and I could reproduce it if I ran "Finish.st" manually instead of letting make install run it. (The other report was slightly different, but both involve a bug in the handling of weak objects). The attached patch should fix it.

I'll release 2.3.1 some time after I get confirmation that the fix works.

Paolo
2006-12-12  Paolo Bonzini  <address@hidden>

        * libgst/oop.c (_gst_check_oop_table): New.
        (_gst_global_gc): Call it.
        (mark_ephemeron_oops): Proceed recursively if marking of the
        ephemerons' slots finds more ephemerons.

--- orig/libgst/oop.c
+++ mod/libgst/oop.c
@@ -541,6 +548,44 @@ _gst_dump_oop_table()
           _gst_display_oop_short (oop);
       }
 }
+
+void
+_gst_check_oop_table ()
+{
+  OOP oop, lastOOP;
+
+  for (oop = _gst_mem.ot_base, lastOOP = &_gst_mem.ot[_gst_mem.ot_size];
+       oop < lastOOP; oop++)
+    {
+      gst_object object;
+      OOP *scanPtr;
+      int n;
+
+      if (!IS_OOP_VALID_GC (oop))
+       continue;
+
+      object = OOP_TO_OBJ (oop);
+      scanPtr = &object->objClass;
+      if (oop->flags & F_CONTEXT)
+        {
+          gst_method_context ctx;
+          intptr_t methodSP;
+          ctx = (gst_method_context) object;
+          methodSP = TO_INT (ctx->spOffset);
+          n = ctx->contextStack + methodSP + 1 - object->data;
+        }
+      else
+        n = NUM_OOPS (object) + 1;
+
+      while (n--)
+        {
+         OOP pointedOOP = *scanPtr++;
+         if (IS_OOP (pointedOOP)
+             && (!IS_OOP_ADDR (pointedOOP) || !IS_OOP_VALID_GC (pointedOOP)))
+            abort ();
+       }
+    }
+}
 
 
 void
@@ -1063,6 +1119,7 @@ _gst_global_gc (int next_allocation)
   _gst_mem.live_flags |= F_REACHABLE;
   check_weak_refs ();
   _gst_restore_object_pointers ();
+  _gst_check_oop_table ();
   reset_incremental_gc (_gst_mem.ot);
 
   update_stats (&stats.timeOfLastGlobalGC,
@@ -1985,7 +2042,7 @@ mark_oops (void)
 void
 mark_ephemeron_oops (void)
 {
-  OOP *pOOP, *base;
+  OOP *pOOP, *pDeadOOP, *base;
   int i, size;
 
   /* Make a local copy of the buffer */
@@ -2009,9 +2066,9 @@ mark_ephemeron_oops (void)
       key->flags |= F_REACHABLE;
     }
 
-  for (pOOP = base, i = size; i--; pOOP++)
+  for (pOOP = pDeadOOP = base, i = size; i--; )
     {
-      OOP oop = *pOOP;
+      OOP oop = *pOOP++;
       gst_object obj = OOP_TO_OBJ(oop);
       OOP key = obj->data[0];
       int num = NUM_OOPS(obj);
@@ -2024,10 +2081,10 @@ mark_ephemeron_oops (void)
       for (j = 1; j < num; j++)
         MAYBE_MARK_OOP (obj->data[j]);
 
-      /* Remember that above we cleared F_EPHEMERON is the key
+      /* Remember that above we cleared F_EPHEMERON if the key
          is alive.  */
       if (!IS_OOP_MARKED (key) && (oop->flags & F_EPHEMERON))
-        _gst_add_buf_pointer (oop);
+        *pDeadOOP++ = oop;
 
       /* Ok, now mark the key.  */
       MAYBE_MARK_OOP (key);
@@ -2035,6 +2092,12 @@ mark_ephemeron_oops (void)
       /* Restore the flag in case it was cleared.  */
       oop->flags |= F_EPHEMERON;
     }
+
+  /* If more ephemerons were reachable from the object, go on...  */
+  if (_gst_buffer_size ())
+    mark_ephemeron_oops ();
+
+  _gst_add_buf_data (base, (char *) pDeadOOP - (char *) base);
 }
 
 #define TAIL_MARK_OOP(newOOP) BEGIN_MACRO { \

reply via email to

[Prev in Thread] Current Thread [Next in Thread]