From 9cc43a970cf84f2d16f616e7875d480797d3660f Mon Sep 17 00:00:00 2001 From: fleuria Date: Wed, 24 Jul 2013 14:05:49 +0800 Subject: introduce incremental_gc_step() --- src/gc.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/gc.c b/src/gc.c index cfe48df68..1dcaf4dd0 100644 --- a/src/gc.c +++ b/src/gc.c @@ -918,6 +918,20 @@ incremental_gc_until(mrb_state *mrb, enum gc_state to_state) } while (mrb->gc_state != to_state); } +static void +incremental_gc_step(mrb_state *mrb) +{ + size_t limit = 0, result = 0; + limit = (GC_STEP_SIZE/100) * mrb->gc_step_ratio; + while (result < limit) { + result += incremental_gc(mrb, limit); + if (mrb->gc_state == GC_STATE_NONE) + break; + } + + mrb->gc_threshold = mrb->live + GC_STEP_SIZE; +} + static void clear_all_old(mrb_state *mrb) { @@ -947,13 +961,7 @@ mrb_incremental_gc(mrb_state *mrb) incremental_gc_until(mrb, GC_STATE_NONE); } else { - size_t limit = 0, result = 0; - limit = (GC_STEP_SIZE/100) * mrb->gc_step_ratio; - while (result < limit) { - result += incremental_gc(mrb, limit); - if (mrb->gc_state == GC_STATE_NONE) - break; - } + incremental_gc_step(mrb); } if (mrb->gc_state == GC_STATE_NONE) { @@ -962,6 +970,7 @@ mrb_incremental_gc(mrb_state *mrb) if (mrb->gc_threshold < GC_STEP_SIZE) { mrb->gc_threshold = GC_STEP_SIZE; } + if (is_major_gc(mrb)) { mrb->majorgc_old_threshold = mrb->gc_live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO; mrb->gc_full = FALSE; @@ -973,10 +982,6 @@ mrb_incremental_gc(mrb_state *mrb) } } } - else { - mrb->gc_threshold = mrb->live + GC_STEP_SIZE; - } - GC_TIME_STOP_AND_REPORT; } -- cgit v1.2.3 From c852626ea73136aa148f9bca92ecc3babfd28017 Mon Sep 17 00:00:00 2001 From: fleuria Date: Wed, 24 Jul 2013 15:42:56 +0800 Subject: rename mrb_garbage_collect() to mrb_full_gc() --- include/mruby.h | 2 +- src/gc.c | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/include/mruby.h b/include/mruby.h index 85b464b8e..af6901b52 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -272,7 +272,7 @@ mrb_value mrb_Float(mrb_state *mrb, mrb_value val); mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj); mrb_bool mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2); -void mrb_garbage_collect(mrb_state*); +void mrb_full_gc(mrb_state*); void mrb_incremental_gc(mrb_state *); int mrb_gc_arena_save(mrb_state*); void mrb_gc_arena_restore(mrb_state*,int); diff --git a/src/gc.c b/src/gc.c index 1dcaf4dd0..9a8fea791 100644 --- a/src/gc.c +++ b/src/gc.c @@ -175,7 +175,7 @@ mrb_realloc_simple(mrb_state *mrb, void *p, size_t len) p2 = (mrb->allocf)(mrb, p, len, mrb->ud); if (!p2 && len > 0 && mrb->heaps) { - mrb_garbage_collect(mrb); + mrb_full_gc(mrb); p2 = (mrb->allocf)(mrb, p, len, mrb->ud); } @@ -390,7 +390,7 @@ mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls) static const RVALUE RVALUE_zero = { { { MRB_TT_FALSE } } }; #ifdef MRB_GC_STRESS - mrb_garbage_collect(mrb); + mrb_full_gc(mrb); #endif if (mrb->gc_threshold < mrb->live) { mrb_incremental_gc(mrb); @@ -986,11 +986,12 @@ mrb_incremental_gc(mrb_state *mrb) GC_TIME_STOP_AND_REPORT; } +/* Perform a full gc cycle */ void -mrb_garbage_collect(mrb_state *mrb) +mrb_full_gc(mrb_state *mrb) { if (mrb->gc_disabled) return; - GC_INVOKE_TIME_REPORT("mrb_garbage_collect()"); + GC_INVOKE_TIME_REPORT("mrb_full_gc()"); GC_TIME_START; if (mrb->gc_state == GC_STATE_SWEEP) { @@ -1082,7 +1083,7 @@ mrb_write_barrier(mrb_state *mrb, struct RBasic *obj) static mrb_value gc_start(mrb_state *mrb, mrb_value obj) { - mrb_garbage_collect(mrb); + mrb_full_gc(mrb); return mrb_nil_value(); } @@ -1452,8 +1453,8 @@ test_incremental_gc(void) puts("test_incremental_gc"); change_gen_gc_mode(mrb, FALSE); - puts(" in mrb_garbage_collect"); - mrb_garbage_collect(mrb); + puts(" in mrb_full_gc"); + mrb_full_gc(mrb); gc_assert(mrb->gc_state == GC_STATE_NONE); puts(" in GC_STATE_NONE"); -- cgit v1.2.3 From 0c0efc16b08237d30fc30f03033140d2844d6e74 Mon Sep 17 00:00:00 2001 From: fleuria Date: Wed, 24 Jul 2013 16:22:38 +0800 Subject: gc: replace comment "a round of GC" to "a GC cycle" --- src/gc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/gc.c b/src/gc.c index 9a8fea791..72db02f05 100644 --- a/src/gc.c +++ b/src/gc.c @@ -42,18 +42,18 @@ There're two white color types in a flip-flop fassion: White-A and White-B, which respectively represent the Current White color (the newly allocated - objects in the current round of GC) and the Sweep Target White color (the + objects in the current GC cycle) and the Sweep Target White color (the dead objects to be swept). - A and B will be switched just at the beginning of the next round of GC. At + A and B will be switched just at the beginning of the next GC cycle. At that time, all the dead objects have been swept, while the newly created - objects in the current round of GC which finally remains White are now + objects in the current GC cycle which finally remains White are now regarded as dead objects. Instead of traversing all the White-A objects and paint them as White-B, just switch the meaning of White-A and White-B would be much cheaper. - As a result, the objects we sweep in the current round of GC are always - left from the previous round of GC. This allows us to sweep objects + As a result, the objects we sweep in the current GC cycle are always + left from the previous GC cycle. This allows us to sweep objects incrementally, without the disturbance of the newly created objects. == Execution Timing @@ -86,7 +86,7 @@ phase, then only sweep the newly created objects, and leave the Old objects live. - * Major GC - same as a full round of regular GC. + * Major GC - same as a full regular GC cycle. For details, see the comments for each function. -- cgit v1.2.3