From 123eeb1c1a904923754ce65148dbef045b56e083 Mon Sep 17 00:00:00 2001 From: ko1 Date: Mon, 8 Sep 2014 04:11:00 +0000 Subject: * gc.c: add incremental GC algorithm. [Feature #10137] Please refer this ticket for details. This change also introduces the following changes. * Remove RGENGC_AGE2_PROMOTION and introduce object age (0 to 3). Age can be count with FL_PROMOTE0 and FL_PROMOTE1 flags in RBasic::flags (2 bit). Age == 3 objects become old objects. * WB_PROTECTED flag in RBasic to WB_UNPROTECTED bitmap. * LONG_LIVED bitmap to represent living objects while minor GCs It specifies (1) Old objects and (2) remembered shady objects. * Introduce rb_objspace_t::marked_objects which counts marked objects in current marking phase. marking count is needed to introduce incremental marking. * rename mark related function and sweep related function to gc_(marks|sweep)_(start|finish|step|rest|continue). * rename rgengc_report() to gc_report(). * Add obj_info() function to get cstr of object details. * Add MEASURE_LINE() macro to measure execution time of specific line. * and many small fixes. * include/ruby/ruby.h: add flag USE_RINCGC. Now USE_RINCGC can be set only with USE_RGENGC. * include/ruby/ruby.h: introduce FL_PROMOTED0 and add FL_PROMOTED1 to count object age. * include/ruby/ruby.h: rewrite write barriers for incremental marking. * debug.c: catch up flag name changes. * internal.h: add rb_gc_writebarrier_remember() instead of rb_gc_writebarrier_remember_promoted(). * array.c (ary_memcpy0): use rb_gc_writebarrier_remember(). * array.c (rb_ary_modify): ditto. * hash.c (rb_hash_keys): ditto. * hash.c (rb_hash_values): ditto. * object.c (init_copy): use rb_copy_wb_protected_attribute() because FL_WB_PROTECTED is moved from RBasic::flags. * test/objspace/test_objspace.rb: catch up ObjectSpace.dump() changes. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47444 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- include/ruby/ruby.h | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) (limited to 'include') diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h index 1f2fbafeb7..ae55b0defa 100644 --- a/include/ruby/ruby.h +++ b/include/ruby/ruby.h @@ -710,6 +710,13 @@ VALUE rb_obj_setup(VALUE obj, VALUE klass, VALUE type); #ifndef USE_RGENGC #define USE_RGENGC 1 +#ifndef USE_RINCGC +#define USE_RINCGC 1 +#endif +#endif + +#if USE_RGENGC == 0 +#define USE_RINCGC 0 #endif #ifndef RGENGC_WB_PROTECTED_ARRAY @@ -1068,7 +1075,8 @@ struct RStruct { #define FL_SINGLETON FL_USER0 #define FL_WB_PROTECTED (((VALUE)1)<<5) -#define FL_PROMOTED (((VALUE)1)<<6) +#define FL_PROMOTED0 (((VALUE)1)<<5) +#define FL_PROMOTED1 (((VALUE)1)<<6) #define FL_FINALIZE (((VALUE)1)<<7) #define FL_TAINT (((VALUE)1)<<8) #define FL_UNTRUSTED FL_TAINT @@ -1122,16 +1130,20 @@ struct RStruct { #define OBJ_FREEZE(x) FL_SET((x), FL_FREEZE) #if USE_RGENGC -#define OBJ_PROMOTED(x) (SPECIAL_CONST_P(x) ? 0 : FL_TEST_RAW((x), FL_PROMOTED)) -#define OBJ_WB_PROTECTED(x) (SPECIAL_CONST_P(x) ? 1 : FL_TEST_RAW((x), FL_WB_PROTECTED)) +#define OBJ_PROMOTED_RAW(x) ((RBASIC(x)->flags & (FL_PROMOTED0|FL_PROMOTED1)) == (FL_PROMOTED0|FL_PROMOTED1)) +#define OBJ_PROMOTED(x) (SPECIAL_CONST_P(x) ? 0 : OBJ_PROMOTED_RAW(x)) #define OBJ_WB_UNPROTECT(x) rb_obj_wb_unprotect(x, __FILE__, __LINE__) -void rb_gc_writebarrier(VALUE a, VALUE b); -void rb_gc_writebarrier_unprotect_promoted(VALUE obj); +#if USE_RINCGC +int rb_gc_writebarrier_incremental(VALUE a, VALUE b); +#else +#define rb_gc_writebarrier_incremental(a, b) 0 +#endif +void rb_gc_writebarrier_generational(VALUE a, VALUE b); +void rb_gc_writebarrier_unprotect(VALUE obj); #else /* USE_RGENGC */ #define OBJ_PROMOTED(x) 0 -#define OBJ_WB_PROTECTED(x) 0 #define OBJ_WB_UNPROTECT(x) rb_obj_wb_unprotect(x, __FILE__, __LINE__) #endif @@ -1164,15 +1176,8 @@ rb_obj_wb_unprotect(VALUE x, RB_UNUSED_VAR(const char *filename), RB_UNUSED_VAR( #ifdef RGENGC_LOGGING_WB_UNPROTECT RGENGC_LOGGING_WB_UNPROTECT((void *)x, filename, line); #endif - #if USE_RGENGC - /* `x' should be an RVALUE object */ - if (FL_TEST_RAW((x), FL_WB_PROTECTED)) { - if (FL_TEST_RAW((x), FL_PROMOTED)) { - rb_gc_writebarrier_unprotect_promoted(x); - } - RBASIC(x)->flags &= ~FL_WB_PROTECTED; - } + rb_gc_writebarrier_unprotect(x); #endif return x; } @@ -1185,9 +1190,12 @@ rb_obj_written(VALUE a, RB_UNUSED_VAR(VALUE oldv), VALUE b, RB_UNUSED_VAR(const #endif #if USE_RGENGC - /* `a' should be an RVALUE object */ - if (FL_TEST_RAW((a), FL_PROMOTED) && !SPECIAL_CONST_P(b)) { - rb_gc_writebarrier(a, b); + if (!SPECIAL_CONST_P(b)) { + if (rb_gc_writebarrier_incremental(a, b) == 0) { + if (OBJ_PROMOTED_RAW(a) && !OBJ_PROMOTED_RAW(b)) { + rb_gc_writebarrier_generational(a, b); + } + } } #endif -- cgit v1.2.1