summaryrefslogtreecommitdiff
path: root/yjit_codegen.c
diff options
context:
space:
mode:
authorMaxime Chevalier-Boisvert <[email protected]>2021-04-15 14:16:55 -0400
committerAlan Wu <[email protected]>2021-10-20 18:19:33 -0400
commitedaf12def626a2b06fc2cf9bf53db9b0f45b88ac (patch)
tree0bce49352b5975958fb1b96d4d1f7e889765b275 /yjit_codegen.c
parent791f20af6e9a5db37e69ed33c6b91fc15d9fe824 (diff)
Fix local type tracking in getlocal, setlocal. Add test.
Diffstat (limited to 'yjit_codegen.c')
-rw-r--r--yjit_codegen.c59
1 files changed, 21 insertions, 38 deletions
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)
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)
);
}
-
// 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)
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)
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)
}
*/
- 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)
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
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);