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 |
Free forum by Nabble | Edit this page |