From 332e0db675cd35b60ea82acbc0710d9062c0c92a Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Mon, 29 Jan 2024 16:31:15 -0800 Subject: Avoid unnecessary array allocation for ARGSCAT with LIST body Previously, this would use newarray followed by concattoarray. This now uses pushtoarray instead, avoiding the unnecessary array allocation. This is implemented by making compile_array take a first_chunk argument, passing in 1 in the normal array case, and 0 in the ARGSCAT with LIST body case. --- compile.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'compile.c') diff --git a/compile.c b/compile.c index 3221c6d981..018a9ff607 100644 --- a/compile.c +++ b/compile.c @@ -4786,7 +4786,7 @@ static_literal_value(const NODE *node, rb_iseq_t *iseq) } static int -compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int popped) +compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int popped, int first_chunk) { const NODE *line_node = node; @@ -4846,7 +4846,6 @@ compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int pop const int max_stack_len = 0x100; const int min_tmp_ary_len = 0x40; int stack_len = 0; - int first_chunk = 1; /* Either create a new array, or push to the existing array */ #define FLUSH_CHUNK \ @@ -10174,7 +10173,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no CHECK(compile_super(iseq, ret, node, popped, type)); break; case NODE_LIST:{ - CHECK(compile_array(iseq, ret, node, popped) >= 0); + CHECK(compile_array(iseq, ret, node, popped, 1) >= 0); break; } case NODE_ZLIST:{ @@ -10427,8 +10426,14 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no } else { CHECK(COMPILE(ret, "argscat head", RNODE_ARGSCAT(node)->nd_head)); - CHECK(COMPILE(ret, "argscat body", RNODE_ARGSCAT(node)->nd_body)); - ADD_INSN(ret, node, concattoarray); + const NODE *body_node = RNODE_ARGSCAT(node)->nd_body; + if (nd_type_p(body_node, NODE_LIST)) { + CHECK(compile_array(iseq, ret, body_node, popped, 0) >= 0); + } + else { + CHECK(COMPILE(ret, "argscat body", body_node)); + ADD_INSN(ret, node, concattoarray); + } } break; } -- cgit v1.2.3