[Top][All Lists]
[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 { \