diff options
-rw-r--r-- | yjit_codegen.c | 19 | ||||
-rw-r--r-- | yjit_core.c | 7 | ||||
-rw-r--r-- | yjit_core.h | 1 |
3 files changed, 20 insertions, 7 deletions
diff --git a/yjit_codegen.c b/yjit_codegen.c index 0d90cdeb43..b91af9bba7 100644 --- a/yjit_codegen.c +++ b/yjit_codegen.c @@ -527,8 +527,8 @@ gen_getlocal_wc0(jitstate_t* jit, ctx_t* ctx) mov(cb, REG0, mem_opnd(64, REG0, offs)); // Write the local at SP - //x86opnd_t stack_top = ctx_stack_push_local(ctx, local_idx); - x86opnd_t stack_top = ctx_stack_push(ctx, TYPE_UNKNOWN); + x86opnd_t stack_top = ctx_stack_push_local(ctx, local_idx); + //x86opnd_t stack_top = ctx_stack_push(ctx, TYPE_UNKNOWN); mov(cb, stack_top, REG0); return YJIT_KEEP_COMPILING; @@ -592,12 +592,9 @@ gen_setlocal_wc0(jitstate_t* jit, ctx_t* ctx) // if (flags & VM_ENV_FLAG_WB_REQUIRED) != 0 jnz_ptr(cb, side_exit); - // NOTE: disabled for now since we don't have a good strategy - // for dealing with how blocks/closures can affect local types - // // Set the type of the local variable in the context - //val_type_t temp_type = ctx_get_opnd_type(ctx, OPND_STACK(0)); - //ctx_set_local_type(ctx, local_idx, temp_type); + val_type_t temp_type = ctx_get_opnd_type(ctx, OPND_STACK(0)); + ctx_set_local_type(ctx, local_idx, temp_type); // Pop the value to write from the stack x86opnd_t stack_top = ctx_stack_pop(ctx, 1); @@ -616,6 +613,8 @@ guard_self_is_heap(codeblock_t *cb, x86opnd_t self_opnd, uint8_t *side_exit, ctx { // `self` is constant throughout the entire region, so we only need to do this check once. if (!ctx->self_type.is_heap) { + // FIXME: use two-comparison test + ADD_COMMENT(cb, "guard self is heap"); test(cb, self_opnd, imm_opnd(RUBY_IMMEDIATE_MASK)); jnz_ptr(cb, side_exit); cmp(cb, self_opnd, imm_opnd(Qfalse)); @@ -1399,6 +1398,8 @@ jit_guard_known_klass(jitstate_t *jit, ctx_t* ctx, VALUE known_klass, insn_opnd_ // Check that the receiver is a heap object if (!val_type.is_heap) { + // FIXME: use two comparisons instead of 3 here + ADD_COMMENT(cb, "guard not immediate"); test(cb, REG0, imm_opnd(RUBY_IMMEDIATE_MASK)); jnz_ptr(cb, side_exit); cmp(cb, REG0, imm_opnd(Qfalse)); @@ -1413,6 +1414,7 @@ jit_guard_known_klass(jitstate_t *jit, ctx_t* ctx, VALUE known_klass, insn_opnd_ x86opnd_t klass_opnd = mem_opnd(64, REG0, offsetof(struct RBasic, klass)); // Bail if receiver class is different from compile-time call cache class + ADD_COMMENT(cb, "guard known class"); jit_mov_gc_ptr(jit, cb, REG1, known_klass); cmp(cb, klass_opnd, REG1); jit_chain_guard(JCC_JNE, jit, ctx, max_chain_depth, side_exit); @@ -1851,6 +1853,9 @@ gen_opt_send_without_block(jitstate_t* jit, ctx_t* ctx) RUBY_ASSERT(cme->called_id == mid); assume_method_lookup_stable(comptime_recv_klass, cme, jit->block); + // Method calls may corrupt types + ctx_clear_local_types(ctx); + switch (cme->def->type) { case VM_METHOD_TYPE_ISEQ: return gen_oswb_iseq(jit, ctx, ci, cme, argc); diff --git a/yjit_core.c b/yjit_core.c index 64a87b5d8a..9469616947 100644 --- a/yjit_core.c +++ b/yjit_core.c @@ -208,6 +208,13 @@ void ctx_set_local_type(ctx_t* ctx, size_t idx, val_type_t type) ctx->local_types[idx] = type; } +// Erase local variable type information +// eg: because of a call we can't track +void ctx_clear_local_types(ctx_t* ctx) +{ + memset(&ctx->local_types, 0, sizeof(ctx->local_types)); +} + /* Compute a difference between two value types Returns 0 if the two are the same diff --git a/yjit_core.h b/yjit_core.h index ab849b9414..2297caebcd 100644 --- a/yjit_core.h +++ b/yjit_core.h @@ -240,6 +240,7 @@ x86opnd_t ctx_stack_opnd(ctx_t* ctx, int32_t idx); val_type_t ctx_get_opnd_type(const ctx_t* ctx, insn_opnd_t opnd); void ctx_set_opnd_type(ctx_t* ctx, insn_opnd_t opnd, val_type_t type); void ctx_set_local_type(ctx_t* ctx, size_t idx, val_type_t type); +void ctx_clear_local_types(ctx_t* ctx); int ctx_diff(const ctx_t* src, const ctx_t* dst); block_t* find_block_version(blockid_t blockid, const ctx_t* ctx); |