fixed 10000 factorial bug

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

fixed 10000 factorial bug

Paolo Bonzini-2
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 <[hidden email]>
Date:   Sun Dec 7 14:09:57 2008 -0600

    fix failure when tenuring stressed oldspace allocation heavily
   
    libgst:
    2008-12-07  Paolo Bonzini  <[hidden email]>
   
    * 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  <[hidden email]>
+
+ * 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  <[hidden email]>
 
  * 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;
+    }
 }
 
 

_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk