summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYusuke Endoh <mame@ruby-lang.org>2021-06-18 01:31:50 +0900
committerYusuke Endoh <mame@ruby-lang.org>2021-06-18 02:34:27 +0900
commitfb01411ae842dbcc16d18dec2216fa2719649dff (patch)
treee8dcf2550a7aa8c5579a86b2623b00b96d6f8f8c
parentacae5f363dfaedd9c2873cee68c9498da3c072f5 (diff)
node.h: Reduce struct size to fit with Ruby object size (five VALUEs)
by merging `rb_ast_body_t#line_count` and `#script_lines`. Fortunately `line_count == RARRAY_LEN(script_lines)` was always satisfied. When script_lines is saved, it has an array of lines, and when not saved, it has a Fixnum that represents the old line_count.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/4581
-rw-r--r--ast.c2
-rw-r--r--compile.c3
-rw-r--r--iseq.c14
-rw-r--r--node.h4
-rw-r--r--parse.y2
-rw-r--r--vm.c2
6 files changed, 19 insertions, 8 deletions
diff --git a/ast.c b/ast.c
index 3fec251bcc..78de316c61 100644
--- a/ast.c
+++ b/ast.c
@@ -710,7 +710,7 @@ ast_node_script_lines(rb_execution_context_t *ec, VALUE self)
struct ASTNodeData *data;
TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data);
VALUE ret = data->ast->body.script_lines;
- if (!ret) ret = Qnil;
+ if (!RB_TYPE_P(ret, T_ARRAY)) return Qnil;
return ret;
}
diff --git a/compile.c b/compile.c
index 30c75119b2..4b967a87a0 100644
--- a/compile.c
+++ b/compile.c
@@ -1328,8 +1328,7 @@ new_child_iseq(rb_iseq_t *iseq, const NODE *const node,
ast.root = node;
ast.compile_option = 0;
- ast.line_count = -1;
- ast.script_lines = Qfalse;
+ ast.script_lines = INT2FIX(-1);
debugs("[new_child_iseq]> ---------------------------------------\n");
int isolated_depth = ISEQ_COMPILE_DATA(iseq)->isolated_depth;
diff --git a/iseq.c b/iseq.c
index 4ad1fc23be..1609432770 100644
--- a/iseq.c
+++ b/iseq.c
@@ -813,13 +813,23 @@ rb_iseq_new(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath,
0, type, &COMPILE_OPTION_DEFAULT);
}
+static int
+ast_line_count(const rb_ast_body_t *ast)
+{
+ if (RB_TYPE_P(ast->script_lines, T_ARRAY)){
+ return (int)RARRAY_LEN(ast->script_lines);
+ }
+ return FIX2INT(ast->script_lines);
+}
+
rb_iseq_t *
rb_iseq_new_top(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, const rb_iseq_t *parent)
{
VALUE coverages = rb_get_coverages();
if (RTEST(coverages)) {
- if (ast->line_count >= 0) {
- int len = (rb_get_coverage_mode() & COVERAGE_TARGET_ONESHOT_LINES) ? 0 : ast->line_count;
+ int line_count = ast_line_count(ast);
+ if (line_count >= 0) {
+ int len = (rb_get_coverage_mode() & COVERAGE_TARGET_ONESHOT_LINES) ? 0 : line_count;
VALUE coverage = rb_default_coverage(len);
rb_hash_aset(coverages, path, coverage);
}
diff --git a/node.h b/node.h
index 592b285b83..8b09e81a8c 100644
--- a/node.h
+++ b/node.h
@@ -398,8 +398,10 @@ typedef struct node_buffer_struct node_buffer_t;
typedef struct rb_ast_body_struct {
const NODE *root;
VALUE compile_option;
- int line_count;
VALUE script_lines;
+ // script_lines is either:
+ // - a Fixnum that represents the line count of the original source, or
+ // - an Array that contains the lines of the original source
} rb_ast_body_t;
typedef struct rb_ast_struct {
VALUE flags;
diff --git a/parse.y b/parse.y
index 47b63e810d..df16cf6236 100644
--- a/parse.y
+++ b/parse.y
@@ -6286,7 +6286,7 @@ yycompile0(VALUE arg)
RB_OBJ_WRITE(p->ast, &p->ast->body.compile_option, opt);
}
p->ast->body.root = tree;
- p->ast->body.line_count = p->line_count;
+ if (!p->ast->body.script_lines) p->ast->body.script_lines = INT2FIX(p->line_count);
return TRUE;
}
diff --git a/vm.c b/vm.c
index 01afea9d4d..6140bcf861 100644
--- a/vm.c
+++ b/vm.c
@@ -1223,7 +1223,7 @@ rb_binding_add_dynavars(VALUE bindval, rb_binding_t *bind, int dyncount, const I
rb_node_init(&tmp_node, NODE_SCOPE, (VALUE)dyns, 0, 0);
ast.root = &tmp_node;
ast.compile_option = 0;
- ast.line_count = -1;
+ ast.script_lines = INT2FIX(-1);
if (base_iseq) {
iseq = rb_iseq_new(&ast, base_iseq->body->location.label, path, realpath, base_iseq, ISEQ_TYPE_EVAL);