ruby-changes:57969
From: Aaron <ko1@a...>
Date: Fri, 27 Sep 2019 07:42:08 +0900 (JST)
Subject: [ruby-changes:57969] 293c6c8cc3 (master): Add compaction support to `rb_ast_t`
https://git.ruby-lang.org/ruby.git/commit/?id=293c6c8cc3 From 293c6c8cc3cd9a9cb2910672589ee3631e1f1653 Mon Sep 17 00:00:00 2001 From: Aaron Patterson <tenderlove@r...> Date: Mon, 9 Sep 2019 15:46:07 -0700 Subject: Add compaction support to `rb_ast_t` This commit adds compaction support to `rb_ast_t`. diff --git a/gc.c b/gc.c index c083fbb..adb86b1 100644 --- a/gc.c +++ b/gc.c @@ -7918,6 +7918,8 @@ gc_ref_update_imemo(rb_objspace_t *objspace, VALUE obj) https://github.com/ruby/ruby/blob/trunk/gc.c#L7918 rb_iseq_update_references((rb_iseq_t *)obj); break; case imemo_ast: + rb_ast_update_references((rb_ast_t *)obj); + break; case imemo_parser_strterm: case imemo_tmpbuf: break; diff --git a/node.c b/node.c index 4a265c3..ee6a356 100644 --- a/node.c +++ b/node.c @@ -1262,20 +1262,20 @@ mark_ast_value(void *ctx, NODE * node) https://github.com/ruby/ruby/blob/trunk/node.c#L1262 ID *buf = node->nd_tbl; if (buf) { unsigned int size = (unsigned int)*buf; - rb_gc_mark((VALUE)buf[size + 1]); + rb_gc_mark_movable((VALUE)buf[size + 1]); } break; } case NODE_ARYPTN: { struct rb_ary_pattern_info *apinfo = node->nd_apinfo; - rb_gc_mark(apinfo->imemo); + rb_gc_mark_movable(apinfo->imemo); break; } case NODE_ARGS: { struct rb_args_info *args = node->nd_ainfo; - rb_gc_mark(args->imemo); + rb_gc_mark_movable(args->imemo); break; } case NODE_MATCH: @@ -1286,13 +1286,62 @@ mark_ast_value(void *ctx, NODE * node) https://github.com/ruby/ruby/blob/trunk/node.c#L1286 case NODE_DXSTR: case NODE_DREGX: case NODE_DSYM: - rb_gc_mark(node->nd_lit); + rb_gc_mark_movable(node->nd_lit); break; default: rb_bug("unreachable node %s", ruby_node_name(nd_type(node))); } } +static void +update_ast_value(void *ctx, NODE * node) +{ + switch (nd_type(node)) { + case NODE_SCOPE: + { + ID *buf = node->nd_tbl; + if (buf) { + unsigned int size = (unsigned int)*buf; + buf[size + 1] = rb_gc_location((VALUE)buf[size + 1]); + } + break; + } + case NODE_ARYPTN: + { + struct rb_ary_pattern_info *apinfo = node->nd_apinfo; + apinfo->imemo = rb_gc_location(apinfo->imemo); + break; + } + case NODE_ARGS: + { + struct rb_args_info *args = node->nd_ainfo; + args->imemo = rb_gc_location(args->imemo); + break; + } + case NODE_LIT: + case NODE_STR: + case NODE_XSTR: + case NODE_DSTR: + case NODE_DXSTR: + case NODE_DREGX: + case NODE_DSYM: + node->nd_lit = rb_gc_location(node->nd_lit); + break; + default: + rb_bug("unreachable"); + } +} + +void +rb_ast_update_references(rb_ast_t *ast) +{ + if (ast->node_buffer) { + node_buffer_t *nb = ast->node_buffer; + + iterate_node_values(&nb->markable, update_ast_value, NULL); + } +} + void rb_ast_mark(rb_ast_t *ast) { diff --git a/node.h b/node.h index 276b4d4..55c2984 100644 --- a/node.h +++ b/node.h @@ -405,6 +405,7 @@ typedef struct rb_ast_struct { https://github.com/ruby/ruby/blob/trunk/node.h#L405 } rb_ast_t; rb_ast_t *rb_ast_new(void); void rb_ast_mark(rb_ast_t*); +void rb_ast_update_references(rb_ast_t*); void rb_ast_dispose(rb_ast_t*); void rb_ast_free(rb_ast_t*); size_t rb_ast_memsize(const rb_ast_t*); diff --git a/test/ruby/test_gc_compact.rb b/test/ruby/test_gc_compact.rb index ca4a285..eaffccd 100644 --- a/test/ruby/test_gc_compact.rb +++ b/test/ruby/test_gc_compact.rb @@ -130,4 +130,18 @@ class TestGCCompact < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_gc_compact.rb#L130 GC.verify_compaction_references(toward: :empty) assert_equal hash, list_of_objects.hash end + + def walk_ast ast + children = ast.children.grep(RubyVM::AbstractSyntaxTree::Node) + children.each do |child| + assert child.type + walk_ast child + end + end + + def test_ast_compacts + ast = RubyVM::AbstractSyntaxTree.parse_file __FILE__ + assert GC.compact + walk_ast ast + end end -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/