help-smalltalk
[Top][All Lists]
Advanced

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

[Help-smalltalk] fixed 10000 factorial bug


From: Paolo Bonzini
Subject: [Help-smalltalk] fixed 10000 factorial bug
Date: Sun, 07 Dec 2008 14:17:12 -0600
User-agent: Thunderbird 2.0.0.18 (Macintosh/20081105)

I fixed the crash when 10000 factorial was implemented in the naive way.
 The problem occurred because so many objects were tenured, that they
filled all of oldspace.

Of course we cannot start a full mark-and-sweep GC during a
newspace-only copying GC, and the old code just, well, crashed.  With
the patch (which I just committed as fc94470c to master, and I also
backported to stable-3.0) instead the objects are placed in oldspace
normally but a full GC is also done as soon as the copying GC ends.
(More easily done than said, actually; the bug was exactly where the
assertion failed, there was no memory corruption of any kind).

Paolo
commit fc94470ca00985c2236fe8a401844ba03189ed83
Author: Paolo Bonzini <address@hidden>
Date:   Sun Dec 7 14:09:57 2008 -0600

    fix failure when tenuring stressed oldspace allocation heavily
    
    libgst:
    2008-12-07  Paolo Bonzini  <address@hidden>
    
        * libgst/oop.c: Resize the oldspace if tenuring needs more space than
        we would have liked to have, but then do a GC if this happens.

diff --git a/libgst/ChangeLog b/libgst/ChangeLog
index 98b119b..1faa321 100644
--- a/libgst/ChangeLog
+++ b/libgst/ChangeLog
@@ -1,3 +1,8 @@
+2008-12-07  Paolo Bonzini  <address@hidden>
+
+       * libgst/oop.c: Resize the oldspace if tenuring needs more space than
+       we would have liked to have, but then do a GC if this happens.
+
 2008-11-18  Paolo Bonzini  <address@hidden>
 
        * libgst/alloc.c: Use fixed values for MMAP_AREA_SIZE and
diff --git a/libgst/oop.c b/libgst/oop.c
index 6df0343..fdfb4d2 100644
--- a/libgst/oop.c
+++ b/libgst/oop.c
@@ -895,12 +895,22 @@ heap_data *
 oldspace_nomemory (heap_data *h, size_t sz)
 {
   if (!_gst_gc_running)
+    _gst_global_gc (sz);
+  else
     {
-      _gst_global_gc (sz);
-      return _gst_mem.old;
+      /* Already garbage collecting, emergency growth just to satisfy
+        tenuring necessities.  */
+      int grow_amount_to_satisfy_rate = _gst_mem.old->heap_limit
+           * (100.0 + _gst_mem.space_grow_rate) / 100;
+      int grow_amount_to_satisfy_threshold = 
+          (sz + _gst_mem.old->heap_total)
+          * 100.0 /_gst_mem.grow_threshold_percent;
+
+      _gst_mem.old->heap_limit = MAX (grow_amount_to_satisfy_rate,
+                                     grow_amount_to_satisfy_threshold);
     }
-  else
-    return NULL;
+
+  return _gst_mem.old;
 }
 
 #ifndef NO_SIGSEGV_HANDLING
@@ -1160,6 +1170,9 @@ _gst_scavenge (void)
 {
   int oldBytes, reclaimedBytes, tenuredBytes, reclaimedPercent;
 
+  /* Check if oldspace had to be grown in emergency.  */
+  size_t prev_heap_limit = _gst_mem.old->heap_limit;
+ 
   /* Force a GC as soon as possible if we're low on OOPs or memory.  */
   if UNCOMMON (_gst_mem.num_free_oops < LOW_WATER_OOP_THRESHOLD
      || _gst_mem.old->heap_total * 100.0 / _gst_mem.old->heap_limit >
@@ -1235,6 +1248,15 @@ _gst_scavenge (void)
 
   _gst_invalidate_croutine_cache ();
   mourn_objects ();
+
+  /* If tenuring had to grow oldspace, do a global garbage collection
+     now.  */
+  if (_gst_mem.old->heap_limit > prev_heap_limit)
+    {
+      _gst_global_gc (0);
+      _gst_incremental_gc_step ();
+      return;
+    }
 }
 
 

reply via email to

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