ruby-changes:68964
From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:19:29 +0900 (JST)
Subject: [ruby-changes:68964] edaf12def6 (master): Fix local type tracking in getlocal, setlocal. Add test.
https://git.ruby-lang.org/ruby.git/commit/?id=edaf12def6 From edaf12def626a2b06fc2cf9bf53db9b0f45b88ac Mon Sep 17 00:00:00 2001 From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...> Date: Thu, 15 Apr 2021 14:16:55 -0400 Subject: Fix local type tracking in getlocal, setlocal. Add test. --- bootstraptest/test_yjit.rb | 14 +++++++++++ yjit_codegen.c | 59 +++++++++++++++++----------------------------- 2 files changed, 35 insertions(+), 38 deletions(-) diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb index fcda5476ea..2da9086a60 100644 --- a/bootstraptest/test_yjit.rb +++ b/bootstraptest/test_yjit.rb @@ -89,6 +89,20 @@ assert_equal '0', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_yjit.rb#L89 retval = foo() } +# Passing argument types to callees +assert_equal '8.5', %q{ + def foo(x, y) + x + y + end + + def bar + foo(7, 1.5) + end + + bar + bar +} + # Recursive Ruby-to-Ruby calls assert_equal '21', %q{ def fib(n) diff --git a/yjit_codegen.c b/yjit_codegen.c index 7e98e21a55..201e2c5fae 100644 --- a/yjit_codegen.c +++ b/yjit_codegen.c @@ -257,13 +257,13 @@ yjit_entry_prologue(void) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L257 return code_ptr; } - // Generate code to check for interrupts and take a side-exit static void yjit_check_ints(codeblock_t* cb, uint8_t* side_exit) { // Check for interrupts // see RUBY_VM_CHECK_INTS(ec) macro + ADD_COMMENT(cb, "RUBY_VM_CHECK_INTS(ec)"); mov(cb, REG0_32, member_opnd(REG_EC, rb_execution_context_t, interrupt_mask)); not(cb, REG0_32); test(cb, member_opnd(REG_EC, rb_execution_context_t, interrupt_flag), REG0_32); @@ -289,7 +289,6 @@ jit_jump_to_next_insn(jitstate_t *jit, const ctx_t *current_context) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L289 ); } - // Compile a sequence of bytecode instructions for a given basic block version void yjit_gen_block(ctx_t *ctx, block_t *block, rb_execution_context_t *ec) @@ -350,9 +349,9 @@ yjit_gen_block(ctx_t *ctx, block_t *block, rb_execution_context_t *ec) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L349 break; } - if (1) { + if (0) { fprintf(stderr, "compiling %d: %s\n", insn_idx, insn_name(opcode)); - //print_str(cb, insn_name(opcode)); + print_str(cb, insn_name(opcode)); } // :count-placement: @@ -518,41 +517,24 @@ gen_putself(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L517 return YJIT_KEEP_COMPILING; } +// Compute the index of a local variable from its slot index +uint32_t slot_to_local_idx(const rb_iseq_t *iseq, int32_t slot_idx) +{ + // Convoluted rules from local_var_name() in iseq.c + int32_t local_table_size = iseq->body->local_table_size; + int32_t op = slot_idx - VM_ENV_DATA_SIZE; + int32_t local_idx = local_idx = local_table_size - op - 1; + RUBY_ASSERT(local_idx >= 0 && local_idx < local_table_size); + return (uint32_t)local_idx; +} + static codegen_status_t gen_getlocal_wc0(jitstate_t* jit, ctx_t* ctx) { // Compute the offset from BP to the local - int32_t local_idx = (int32_t)jit_get_arg(jit, 0); - const int32_t offs = -(SIZEOF_VALUE * local_idx); - - - - /* - if (local_idx < 8) - { - val_type_t local_type = ctx->local_types[local_idx]; - - if (local_type.type == ETYPE_FIXNUM) { - fprintf(stderr, "local_idx=%d is fixnum\n", local_idx); - ADD_COMMENT(cb, "local is fixnum"); - } - else { - fprintf(stderr, "local_idx=%d not fixnum\n", local_idx); - ADD_COMMENT(cb, "local not fixnum"); - } - } - else - { - fprintf(stderr, "local_idx=%d\n", local_idx); - } - */ - - - fprintf(stderr, "local_idx=%d\n", local_idx); - - - - + int32_t slot_idx = (int32_t)jit_get_arg(jit, 0); + const int32_t offs = -(SIZEOF_VALUE * slot_idx); + uint32_t local_idx = slot_to_local_idx(jit->iseq, slot_idx); // Load environment pointer EP from CFP mov(cb, REG0, member_opnd(REG_CFP, rb_control_frame_t, ep)); @@ -610,7 +592,8 @@ gen_setlocal_wc0(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L592 } */ - int32_t local_idx = (int32_t)jit_get_arg(jit, 0); + int32_t slot_idx = (int32_t)jit_get_arg(jit, 0); + uint32_t local_idx = slot_to_local_idx(jit->iseq, slot_idx); // Load environment pointer EP from CFP mov(cb, REG0, member_opnd(REG_CFP, rb_control_frame_t, ep)); @@ -634,7 +617,7 @@ gen_setlocal_wc0(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L617 mov(cb, REG1, stack_top); // Write the value at the environment pointer - const int32_t offs = -8 * local_idx; + const int32_t offs = -8 * slot_idx; mov(cb, mem_opnd(64, REG0, offs), REG1); return YJIT_KEEP_COMPILING; @@ -1728,7 +1711,7 @@ gen_oswb_iseq(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const r https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1711 lea(cb, REG0, ctx_sp_opnd(ctx, sizeof(VALUE) * -(argc + 1))); mov(cb, member_opnd(REG_CFP, rb_control_frame_t, sp), REG0); - // Store the next PC i the current frame + // Store the next PC in the current frame mov(cb, REG0, const_ptr_opnd(jit->pc + insn_len(BIN(opt_send_without_block)))); mov(cb, mem_opnd(64, REG_CFP, offsetof(rb_control_frame_t, pc)), REG0); -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/