ruby-changes:69002
From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:19:39 +0900 (JST)
Subject: [ruby-changes:69002] 6164274c76 (master): Re-enable local type tracking, until first call
https://git.ruby-lang.org/ruby.git/commit/?id=6164274c76 From 6164274c76d31bc447a92c59c8d277670a93f229 Mon Sep 17 00:00:00 2001 From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...> Date: Fri, 9 Apr 2021 11:44:35 -0400 Subject: Re-enable local type tracking, until first call --- yjit_codegen.c | 19 ++++++++++++------- yjit_core.c | 7 +++++++ 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) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L527 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) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L592 // 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 https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L613 { // `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_ https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1398 // 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_ https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1414 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) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1853 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) https://github.com/ruby/ruby/blob/trunk/yjit_core.c#L208 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); https://github.com/ruby/ruby/blob/trunk/yjit_core.h#L240 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); -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/