From 7038690dbd4c0a0d7dd3ec3b7900c0b4159af97a Mon Sep 17 00:00:00 2001 From: Maple Ong Date: Wed, 9 Mar 2022 15:14:50 -0500 Subject: [PATCH 1/6] Rename caller_local_table_size --- compile.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/compile.c b/compile.c index b82a7f4ab7aa50..740731b6ad75e6 100644 --- a/compile.c +++ b/compile.c @@ -746,11 +746,10 @@ rb_vm_insn_null_translator(const void *addr) struct inline_context { rb_iseq_t * iseq; - unsigned int caller_locals; + unsigned int caller_local_table_size; LINK_ANCHOR *code_list_root; unsigned int depth; LABEL * leave_label; - unsigned int caller_local_size; unsigned int local_increase; st_table * labels; }; @@ -13289,15 +13288,14 @@ rb_inline_callee_iseqs(const rb_iseq_t * original_iseq) struct inline_context ctx; ctx.iseq = iseq; // Inlined iseq - // number of locals in the caller - ctx.caller_locals = original_iseq->body->local_table_size; + // Number of locals in the caller + ctx.caller_local_table_size = original_iseq->body->local_table_size; // Linked list for building the inlined method ctx.code_list_root = code_list_root; // depth ctx.depth = 0; - ctx.caller_local_size = original_iseq->body->local_table_size; ctx.labels = st_init_numtable(); const rb_code_location_t *loc = &body->location.code_location; From 25a6bf87ea272bb0a94bb83196f4c3dd43f421b4 Mon Sep 17 00:00:00 2001 From: Maple Ong Date: Wed, 9 Mar 2022 15:18:54 -0500 Subject: [PATCH 2/6] Stop reusing caller's local table --- compile.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/compile.c b/compile.c index 740731b6ad75e6..00cefbe3213c00 100644 --- a/compile.c +++ b/compile.c @@ -747,6 +747,7 @@ rb_vm_insn_null_translator(const void *addr) struct inline_context { rb_iseq_t * iseq; unsigned int caller_local_table_size; + unsigned int callee_local_table_size; LINK_ANCHOR *code_list_root; unsigned int depth; LABEL * leave_label; @@ -13261,7 +13262,7 @@ rb_inline_callee_iseqs(const rb_iseq_t * original_iseq) } struct iseq_inline_expansion_info info; - info.max_locals = original_iseq->body->local_table_size; + info.max_locals = 0; info.inlineable_calls = 0; size = body->iseq_size; @@ -13288,8 +13289,9 @@ rb_inline_callee_iseqs(const rb_iseq_t * original_iseq) struct inline_context ctx; ctx.iseq = iseq; // Inlined iseq - // Number of locals in the caller + // Number of locals in the caller and callee ctx.caller_local_table_size = original_iseq->body->local_table_size; + ctx.callee_local_table_size = info.max_locals; // Linked list for building the inlined method ctx.code_list_root = code_list_root; @@ -13313,7 +13315,6 @@ rb_inline_callee_iseqs(const rb_iseq_t * original_iseq) n += inline_iseqs(code, n, NULL, &ctx, translator); } - fprintf(stderr, "original size: %d new size %d\n", original_iseq->body->local_table_size, info.max_locals); iseq->body->original_iseq = original_iseq; RB_OBJ_WRITTEN(iseq, Qundef, original_iseq); @@ -13322,17 +13323,12 @@ rb_inline_callee_iseqs(const rb_iseq_t * original_iseq) iseq->body->param.size = original_iseq->body->param.size; iseq->body->param.lead_num = original_iseq->body->param.lead_num; - if (info.max_locals > original_iseq->body->local_table_size) { - unsigned int local_size = info.max_locals; - ID *ids = (ID *)ALLOC_N(ID, local_size); - MEMCPY(ids, original_iseq->body->local_table, ID, original_iseq->body->local_table_size); - iseq->body->local_table = ids; - iseq->body->local_table_size = local_size; - } - else { - iseq->body->local_table = original_iseq->body->local_table; - iseq->body->local_table_size = original_iseq->body->local_table_size; - } + unsigned int local_size = ctx.callee_local_table_size + ctx.caller_locals; + fprintf(stderr, "original size: %d new size %d\n", original_iseq->body->local_table_size, local_size); + ID *ids = (ID *)ALLOC_N(ID, local_size); + MEMCPY(ids, original_iseq->body->local_table, ID, original_iseq->body->local_table_size); + iseq->body->local_table = ids; + iseq->body->local_table_size = local_size; st_free_table(ctx.labels); From b07c6e77d243d187e9286f1d53309148ffd160f0 Mon Sep 17 00:00:00 2001 From: Maple Ong Date: Wed, 9 Mar 2022 15:38:15 -0500 Subject: [PATCH 3/6] Fix caller local field name --- compile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compile.c b/compile.c index 00cefbe3213c00..214d936cfac3ba 100644 --- a/compile.c +++ b/compile.c @@ -13323,7 +13323,7 @@ rb_inline_callee_iseqs(const rb_iseq_t * original_iseq) iseq->body->param.size = original_iseq->body->param.size; iseq->body->param.lead_num = original_iseq->body->param.lead_num; - unsigned int local_size = ctx.callee_local_table_size + ctx.caller_locals; + unsigned int local_size = ctx.callee_local_table_size + ctx.caller_local_table_size; fprintf(stderr, "original size: %d new size %d\n", original_iseq->body->local_table_size, local_size); ID *ids = (ID *)ALLOC_N(ID, local_size); MEMCPY(ids, original_iseq->body->local_table, ID, original_iseq->body->local_table_size); From e63dd26c5e0e48a7da22fc9e3c83300e8f81b629 Mon Sep 17 00:00:00 2001 From: Maple Ong Date: Wed, 9 Mar 2022 15:31:15 -0500 Subject: [PATCH 4/6] Store self as a local --- compile.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/compile.c b/compile.c index 214d936cfac3ba..a80784d8d18b60 100644 --- a/compile.c +++ b/compile.c @@ -753,6 +753,7 @@ struct inline_context { LABEL * leave_label; unsigned int local_increase; st_table * labels; + unsigned int self_index; }; static INSN * new_insn_core(rb_iseq_t *iseq, const NODE *line_node, int insn_id, int argc, VALUE *argv); @@ -13103,8 +13104,9 @@ inline_iseqs(VALUE *code, size_t pos, iseq_value_itr_t * func, void *_ctx, rb_vm ADD_INSN2(code_list_root, &dummy_line_node, setlocal, INT2FIX(i + VM_ENV_DATA_SIZE), INT2NUM(0)); } - // Remove the receiver from the stack - ADD_INSN(code_list_root, &dummy_line_node, pop); + // Store self as a local + ADD_INSN2(code_list_root, &dummy_line_node, setlocal, INT2FIX(vm_ci_argc(cd->ci) + VM_ENV_DATA_SIZE), INT2NUM(0)); + ctx->self_index = vm_ci_argc(cd->ci); for (size_t n = 0; n < size;) { n += inline_iseqs(callee_code, n, NULL, _ctx, translator); @@ -13192,6 +13194,13 @@ inline_iseqs(VALUE *code, size_t pos, iseq_value_itr_t * func, void *_ctx, rb_vm if (ctx->depth > 0 && IS_INSN_ID(insn, getlocal)) { insn = new_insn_body(iseq, &dummy_line_node, BIN(getlocal), 2, OPERAND_AT(insn, 0), OPERAND_AT(insn, 1)); } + if (ctx->depth > 0 && IS_INSN_ID(insn, setlocal)) { + insn = new_insn_body(iseq, &dummy_line_node, BIN(getlocal), 2, INT2FIX(ctx->self_index + VM_ENV_DATA_SIZE), INT2NUM(0)); + } + if (ctx->depth == 0 && IS_INSN_ID(insn, getlocal)) { + int idx = NUM2INT(OPERAND_AT(insn, 0)) + ctx->callee_local_table_size; + insn = new_insn_body(iseq, &dummy_line_node, BIN(getlocal), 2, INT2FIX(idx), OPERAND_AT(insn, 1)); + } ADD_ELEM(code_list_root, (LINK_ELEMENT *)insn); } @@ -13230,7 +13239,7 @@ find_max_local_table(VALUE *code, size_t pos, iseq_value_itr_t * func, void *_ct // Callee's iseq body if (cme && cme->def->type == VM_METHOD_TYPE_ISEQ && rb_simple_iseq_p(cme->def->body.iseq.iseqptr)) { const rb_iseq_t * callee_iseq = cme->def->body.iseq.iseqptr; - unsigned int local_table_size = callee_iseq->body->local_table_size; + unsigned int local_table_size = callee_iseq->body->local_table_size + 1; info->inlineable_calls++; if (local_table_size > info->max_locals) { From ba012cb97c02979accc706932b0bd9e554e7f353 Mon Sep 17 00:00:00 2001 From: Maple Ong Date: Wed, 9 Mar 2022 17:28:01 -0500 Subject: [PATCH 5/6] Read putself using getlocal --- compile.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compile.c b/compile.c index a80784d8d18b60..9afaa5d855a680 100644 --- a/compile.c +++ b/compile.c @@ -13201,6 +13201,10 @@ inline_iseqs(VALUE *code, size_t pos, iseq_value_itr_t * func, void *_ctx, rb_vm int idx = NUM2INT(OPERAND_AT(insn, 0)) + ctx->callee_local_table_size; insn = new_insn_body(iseq, &dummy_line_node, BIN(getlocal), 2, INT2FIX(idx), OPERAND_AT(insn, 1)); } + if (ctx->depth > 0 && IS_INSN_ID(insn, putself)) { + insn = new_insn_body(iseq, &dummy_line_node, BIN(getlocal), 2, INT2FIX(ctx->self_index + VM_ENV_DATA_SIZE), INT2NUM(0)); + } + ADD_ELEM(code_list_root, (LINK_ELEMENT *)insn); } From 5fa0f88a0b71094064fb40a25572323f11f6b693 Mon Sep 17 00:00:00 2001 From: Maple Ong Date: Thu, 10 Mar 2022 14:50:26 -0500 Subject: [PATCH 6/6] Remove noops and add comments --- compile.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/compile.c b/compile.c index 9afaa5d855a680..9399b885def351 100644 --- a/compile.c +++ b/compile.c @@ -13187,20 +13187,20 @@ inline_iseqs(VALUE *code, size_t pos, iseq_value_itr_t * func, void *_ctx, rb_vm } INSN * insn = new_insn_core(iseq, &dummy_line_node, insn_id, len - 1, ops); insn = insn_operands_separate(iseq, &dummy_line_node, insn); + + // Translate leave to jump in the callee if (ctx->depth > 0 && IS_INSN_ID(insn, leave)) { insn = new_insn_body(iseq, &dummy_line_node, BIN(jump), 1, ctx->leave_label); LABEL_REF(ctx->leave_label); } - if (ctx->depth > 0 && IS_INSN_ID(insn, getlocal)) { - insn = new_insn_body(iseq, &dummy_line_node, BIN(getlocal), 2, OPERAND_AT(insn, 0), OPERAND_AT(insn, 1)); - } - if (ctx->depth > 0 && IS_INSN_ID(insn, setlocal)) { - insn = new_insn_body(iseq, &dummy_line_node, BIN(getlocal), 2, INT2FIX(ctx->self_index + VM_ENV_DATA_SIZE), INT2NUM(0)); - } + + // Adjust the index of locals in the caller if (ctx->depth == 0 && IS_INSN_ID(insn, getlocal)) { int idx = NUM2INT(OPERAND_AT(insn, 0)) + ctx->callee_local_table_size; insn = new_insn_body(iseq, &dummy_line_node, BIN(getlocal), 2, INT2FIX(idx), OPERAND_AT(insn, 1)); } + + // Convert putself into getlocal in the callee if (ctx->depth > 0 && IS_INSN_ID(insn, putself)) { insn = new_insn_body(iseq, &dummy_line_node, BIN(getlocal), 2, INT2FIX(ctx->self_index + VM_ENV_DATA_SIZE), INT2NUM(0)); }