1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Add compaction support to rb_ast_t

This commit adds compaction support to `rb_ast_t`.
This commit is contained in:
Aaron Patterson 2019-09-09 15:46:07 -07:00
parent 37f9213f89
commit 293c6c8cc3
No known key found for this signature in database
GPG key ID: 953170BCB4FFAFC6
4 changed files with 70 additions and 4 deletions

2
gc.c
View file

@ -7918,6 +7918,8 @@ gc_ref_update_imemo(rb_objspace_t *objspace, VALUE obj)
rb_iseq_update_references((rb_iseq_t *)obj); rb_iseq_update_references((rb_iseq_t *)obj);
break; break;
case imemo_ast: case imemo_ast:
rb_ast_update_references((rb_ast_t *)obj);
break;
case imemo_parser_strterm: case imemo_parser_strterm:
case imemo_tmpbuf: case imemo_tmpbuf:
break; break;

57
node.c
View file

@ -1262,20 +1262,20 @@ mark_ast_value(void *ctx, NODE * node)
ID *buf = node->nd_tbl; ID *buf = node->nd_tbl;
if (buf) { if (buf) {
unsigned int size = (unsigned int)*buf; unsigned int size = (unsigned int)*buf;
rb_gc_mark((VALUE)buf[size + 1]); rb_gc_mark_movable((VALUE)buf[size + 1]);
} }
break; break;
} }
case NODE_ARYPTN: case NODE_ARYPTN:
{ {
struct rb_ary_pattern_info *apinfo = node->nd_apinfo; struct rb_ary_pattern_info *apinfo = node->nd_apinfo;
rb_gc_mark(apinfo->imemo); rb_gc_mark_movable(apinfo->imemo);
break; break;
} }
case NODE_ARGS: case NODE_ARGS:
{ {
struct rb_args_info *args = node->nd_ainfo; struct rb_args_info *args = node->nd_ainfo;
rb_gc_mark(args->imemo); rb_gc_mark_movable(args->imemo);
break; break;
} }
case NODE_MATCH: case NODE_MATCH:
@ -1286,13 +1286,62 @@ mark_ast_value(void *ctx, NODE * node)
case NODE_DXSTR: case NODE_DXSTR:
case NODE_DREGX: case NODE_DREGX:
case NODE_DSYM: case NODE_DSYM:
rb_gc_mark(node->nd_lit); rb_gc_mark_movable(node->nd_lit);
break; break;
default: default:
rb_bug("unreachable node %s", ruby_node_name(nd_type(node))); 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 void
rb_ast_mark(rb_ast_t *ast) rb_ast_mark(rb_ast_t *ast)
{ {

1
node.h
View file

@ -405,6 +405,7 @@ typedef struct rb_ast_struct {
} rb_ast_t; } rb_ast_t;
rb_ast_t *rb_ast_new(void); rb_ast_t *rb_ast_new(void);
void rb_ast_mark(rb_ast_t*); 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_dispose(rb_ast_t*);
void rb_ast_free(rb_ast_t*); void rb_ast_free(rb_ast_t*);
size_t rb_ast_memsize(const rb_ast_t*); size_t rb_ast_memsize(const rb_ast_t*);

View file

@ -130,4 +130,18 @@ class TestGCCompact < Test::Unit::TestCase
GC.verify_compaction_references(toward: :empty) GC.verify_compaction_references(toward: :empty)
assert_equal hash, list_of_objects.hash assert_equal hash, list_of_objects.hash
end 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 end