help-smalltalk
[Top][All Lists]
Advanced

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

Re: [Help-smalltalk] Bug with long recursion


From: Paolo Bonzini
Subject: Re: [Help-smalltalk] Bug with long recursion
Date: Wed, 27 Jul 2011 12:44:42 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:5.0) Gecko/20110707 Thunderbird/5.0

On 07/27/2011 11:42 AM, Paolo Bonzini wrote:

I've investigate a bit the long recursion bug, to debug I've choose a
simple recursive code:

ObjectMemory growTo: 100 * 1024 * 1024. " This is not needed "
Object compile: 'foo: i [ i > 1 ifTrue: [ self foo: i - 1 ] ifFalse: [
#ici printNl ] ]'.
Object new foo: 1000000

3.2 works:

It's actually latent there. Like all GC bugs, it's of the "how the heck can it work at all" kind.

The OOP that is being freed incorrectly is the Smalltalk dictionary, nothing less. The incorrect free is due to the OOP being swept twice, the first time during the search for the first unallocated OOP, the second while searching for the last allocated OOP. I haven't really analyzed how it happens (no time; bisection points at an unrelated commit), but the fix is "obvious": just use IS_OOP_VALID rather than IS_OOP_VALID_GC in reset_incremental_gc.

Gwen suggested offlist assigning _gst_mem.next_oop_to_sweep outside the #ifdef. That is not enough, but it put me on the right track. Thanks!

Here is the patch:

diff --git a/libgst/oop.c b/libgst/oop.c
index baa92e6..567cdb1 100644
--- a/libgst/oop.c
+++ b/libgst/oop.c
@@ -1402,19 +1402,21 @@ reset_incremental_gc (OOP firstOOP)

   _gst_mem.first_allocated_oop = oop;

-#ifdef NO_INCREMENTAL_GC
   _gst_mem.next_oop_to_sweep = _gst_mem.last_allocated_oop;
+  _gst_mem.last_swept_oop = oop - 1;
+
+#ifdef NO_INCREMENTAL_GC
   _gst_finish_incremental_gc ();
 #else
   /* Skip high OOPs that are unallocated.  */
-  for (oop = _gst_mem.last_allocated_oop; !IS_OOP_VALID_GC (oop); oop--)
+  for (oop = _gst_mem.last_allocated_oop; !IS_OOP_VALID (oop); oop--)
     _gst_sweep_oop (oop);

   _gst_mem.last_allocated_oop = oop;
   _gst_mem.next_oop_to_sweep = oop;
 #endif

-  _gst_mem.last_swept_oop = _gst_mem.first_allocated_oop - 1;
   _gst_mem.num_free_oops = _gst_mem.ot_size -
     (_gst_mem.last_allocated_oop - _gst_mem.ot);

Paolo



reply via email to

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