ruby-changes:69441
From: Yusuke <ko1@a...>
Date: Tue, 26 Oct 2021 01:58:15 +0900 (JST)
Subject: [ruby-changes:69441] 09fa773e04 (master): ast.c: Use kept script_lines data instead of re-opening the source file (#5019)
https://git.ruby-lang.org/ruby.git/commit/?id=09fa773e04 From 09fa773e04f183e5eb685f07e174efa2cf77f9dc Mon Sep 17 00:00:00 2001 From: Yusuke Endoh <mame@r...> Date: Tue, 26 Oct 2021 01:58:01 +0900 Subject: ast.c: Use kept script_lines data instead of re-opening the source file (#5019) ast.c: Use kept script_lines data instead of re-open the source file --- ast.c | 9 +++++---- internal/vm.h | 2 +- parse.y | 1 + vm_backtrace.c | 22 +++++++++++----------- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/ast.c b/ast.c index 84e5fdcecc8..96116d43eba 100644 --- a/ast.c +++ b/ast.c @@ -195,12 +195,12 @@ script_lines(VALUE path) https://github.com/ruby/ruby/blob/trunk/ast.c#L195 static VALUE ast_s_of(rb_execution_context_t *ec, VALUE module, VALUE body, VALUE keep_script_lines) { - VALUE path, node, lines; + VALUE path, node, lines = Qnil; int node_id; if (rb_frame_info_p(body)) { - rb_frame_info_get(body, &path, &node_id); - if (NIL_P(path)) return Qnil; + rb_frame_info_get(body, &path, &lines, &node_id); + if (NIL_P(path) && NIL_P(lines)) return Qnil; } else { const rb_iseq_t *iseq = NULL; @@ -220,10 +220,11 @@ ast_s_of(rb_execution_context_t *ec, VALUE module, VALUE body, VALUE keep_script https://github.com/ruby/ruby/blob/trunk/ast.c#L220 rb_raise(rb_eArgError, "cannot get AST for method defined in eval"); } path = rb_iseq_path(iseq); + lines = iseq->body->variable.script_lines; node_id = iseq->body->location.node_id; } - if (!NIL_P(lines = script_lines(path))) { + if (!NIL_P(lines) || !NIL_P(lines = script_lines(path))) { node = rb_ast_parse_array(lines, keep_script_lines); } else if (RSTRING_LEN(path) == 2 && memcmp(RSTRING_PTR(path), "-e", 2) == 0) { diff --git a/internal/vm.h b/internal/vm.h index 8893d70cd48..e902a814114 100644 --- a/internal/vm.h +++ b/internal/vm.h @@ -111,7 +111,7 @@ VALUE rb_backtrace_to_str_ary(VALUE obj); https://github.com/ruby/ruby/blob/trunk/internal/vm.h#L111 VALUE rb_backtrace_to_location_ary(VALUE obj); void rb_backtrace_each(VALUE (*iter)(VALUE recv, VALUE str), VALUE output); int rb_frame_info_p(VALUE obj); -void rb_frame_info_get(VALUE obj, VALUE *path, int *node_id); +void rb_frame_info_get(VALUE obj, VALUE *path, VALUE *script_lines, int *node_id); MJIT_SYMBOL_EXPORT_BEGIN VALUE rb_ec_backtrace_object(const struct rb_execution_context_struct *ec); diff --git a/parse.y b/parse.y index 2ec9d7770cb..5948f6e2f63 100644 --- a/parse.y +++ b/parse.y @@ -6414,6 +6414,7 @@ lex_getline(struct parser_params *p) https://github.com/ruby/ruby/blob/trunk/parse.y#L6414 VALUE line = (*p->lex.gets)(p, p->lex.input); if (NIL_P(line)) return line; must_be_ascii_compatible(line); + if (RB_OBJ_FROZEN(line)) line = rb_str_dup(line); // needed for RubyVM::AST.of because script_lines in iseq is deep-frozen #ifndef RIPPER if (p->debug_lines) { rb_enc_associate(line, p->enc); diff --git a/vm_backtrace.c b/vm_backtrace.c index 8294d218a4a..f2e9bed6bac 100644 --- a/vm_backtrace.c +++ b/vm_backtrace.c @@ -283,19 +283,16 @@ location_base_label_m(VALUE self) https://github.com/ruby/ruby/blob/trunk/vm_backtrace.c#L283 return location_base_label(location_ptr(self)); } -static VALUE -location_path(rb_backtrace_location_t *loc) +static const rb_iseq_t * +location_iseq(rb_backtrace_location_t *loc) { switch (loc->type) { case LOCATION_TYPE_ISEQ: - return rb_iseq_path(loc->iseq); + return loc->iseq; case LOCATION_TYPE_CFUNC: - if (loc->iseq) { - return rb_iseq_path(loc->iseq); - } - return Qnil; + return loc->iseq; default: - rb_bug("location_path: unreachable"); + rb_bug("location_iseq: unreachable"); UNREACHABLE; } } @@ -313,7 +310,8 @@ location_path(rb_backtrace_location_t *loc) https://github.com/ruby/ruby/blob/trunk/vm_backtrace.c#L310 static VALUE location_path_m(VALUE self) { - return location_path(location_ptr(self)); + const rb_iseq_t *iseq = location_iseq(location_ptr(self)); + return iseq ? rb_iseq_path(iseq) : Qnil; } #ifdef USE_ISEQ_NODE_ID @@ -336,11 +334,13 @@ location_node_id(rb_backtrace_location_t *loc) https://github.com/ruby/ruby/blob/trunk/vm_backtrace.c#L334 #endif void -rb_frame_info_get(VALUE obj, VALUE *path, int *node_id) +rb_frame_info_get(VALUE obj, VALUE *path, VALUE *script_lines, int *node_id) { #ifdef USE_ISEQ_NODE_ID rb_backtrace_location_t *loc = location_ptr(obj); - *path = location_path(loc); + const rb_iseq_t *iseq = location_iseq(loc); + *path = iseq ? rb_iseq_path(iseq) : Qnil; + *script_lines = iseq ? iseq->body->variable.script_lines : Qnil; *node_id = location_node_id(loc); #else *path = Qnil; -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/