diff options
author | Aaron Patterson <[email protected]> | 2019-09-09 15:46:07 -0700 |
---|---|---|
committer | Aaron Patterson <[email protected]> | 2019-09-26 15:41:46 -0700 |
commit | 293c6c8cc3cd9a9cb2910672589ee3631e1f1653 (patch) | |
tree | ba7330ecfac15e4a60c88db7994a6a38d36da2c2 /node.c | |
parent | 37f9213f8957e0c6dffee7d8803890907f97bdbb (diff) |
Add compaction support to `rb_ast_t`
This commit adds compaction support to `rb_ast_t`.
Diffstat (limited to 'node.c')
-rw-r--r-- | node.c | 57 |
1 files changed, 53 insertions, 4 deletions
@@ -1262,20 +1262,20 @@ mark_ast_value(void *ctx, NODE * node) 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) 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) { |