diff options
author | John Hawthorn <john@hawthorn.email> | 2022-07-20 09:31:40 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-20 12:31:40 -0400 |
commit | 660b1e973c8d9ea09667a853a2777a1b8b5a2a58 (patch) | |
tree | 1da08cfde8b62f50bb912036b1c701f5ebd06350 /yjit | |
parent | 6140edb5df29bc9362ded379d6e2e72e4584d07a (diff) |
YJIT: Skip setlocal WB check for immediate values (#6122)
Write barriers may be required when VM_ENV_FLAG_WB_REQUIRED is set,
however write barriers only affect heap objects being written. If we
know an immediate value is being written we can skip this check.
Notes
Notes:
Merged-By: maximecb <maximecb@ruby-lang.org>
Diffstat (limited to 'yjit')
-rw-r--r-- | yjit/src/codegen.rs | 60 |
1 files changed, 36 insertions, 24 deletions
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 9cd69cd340..af501158ff 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -1565,27 +1565,32 @@ fn gen_setlocal_wc0( let slot_idx = jit_get_arg(jit, 0).as_i32(); let local_idx = slot_to_local_idx(jit.get_iseq(), slot_idx).as_usize(); + let value_type = ctx.get_opnd_type(StackOpnd(0)); // Load environment pointer EP (level 0) from CFP gen_get_ep(cb, REG0, 0); - // flags & VM_ENV_FLAG_WB_REQUIRED - let flags_opnd = mem_opnd( - 64, - REG0, - SIZEOF_VALUE as i32 * VM_ENV_DATA_INDEX_FLAGS as i32, - ); - test(cb, flags_opnd, imm_opnd(VM_ENV_FLAG_WB_REQUIRED as i64)); + // Write barriers may be required when VM_ENV_FLAG_WB_REQUIRED is set, however write barriers + // only affect heap objects being written. If we know an immediate value is being written we + // can skip this check. + if !value_type.is_imm() { + // flags & VM_ENV_FLAG_WB_REQUIRED + let flags_opnd = mem_opnd( + 64, + REG0, + SIZEOF_VALUE as i32 * VM_ENV_DATA_INDEX_FLAGS as i32, + ); + test(cb, flags_opnd, imm_opnd(VM_ENV_FLAG_WB_REQUIRED as i64)); - // Create a side-exit to fall back to the interpreter - let side_exit = get_side_exit(jit, ocb, ctx); + // Create a side-exit to fall back to the interpreter + let side_exit = get_side_exit(jit, ocb, ctx); - // if (flags & VM_ENV_FLAG_WB_REQUIRED) != 0 - jnz_ptr(cb, side_exit); + // if (flags & VM_ENV_FLAG_WB_REQUIRED) != 0 + jnz_ptr(cb, side_exit); + } // Set the type of the local variable in the context - let temp_type = ctx.get_opnd_type(StackOpnd(0)); - ctx.set_local_type(local_idx, temp_type); + ctx.set_local_type(local_idx, value_type); // Pop the value to write from the stack let stack_top = ctx.stack_pop(1); @@ -1606,22 +1611,29 @@ fn gen_setlocal_generic( local_idx: i32, level: u32, ) -> CodegenStatus { + let value_type = ctx.get_opnd_type(StackOpnd(0)); + // Load environment pointer EP at level gen_get_ep(cb, REG0, level); - // flags & VM_ENV_FLAG_WB_REQUIRED - let flags_opnd = mem_opnd( - 64, - REG0, - SIZEOF_VALUE as i32 * VM_ENV_DATA_INDEX_FLAGS as i32, - ); - test(cb, flags_opnd, uimm_opnd(VM_ENV_FLAG_WB_REQUIRED.into())); + // Write barriers may be required when VM_ENV_FLAG_WB_REQUIRED is set, however write barriers + // only affect heap objects being written. If we know an immediate value is being written we + // can skip this check. + if !value_type.is_imm() { + // flags & VM_ENV_FLAG_WB_REQUIRED + let flags_opnd = mem_opnd( + 64, + REG0, + SIZEOF_VALUE as i32 * VM_ENV_DATA_INDEX_FLAGS as i32, + ); + test(cb, flags_opnd, uimm_opnd(VM_ENV_FLAG_WB_REQUIRED.into())); - // Create a side-exit to fall back to the interpreter - let side_exit = get_side_exit(jit, ocb, ctx); + // Create a side-exit to fall back to the interpreter + let side_exit = get_side_exit(jit, ocb, ctx); - // if (flags & VM_ENV_FLAG_WB_REQUIRED) != 0 - jnz_ptr(cb, side_exit); + // if (flags & VM_ENV_FLAG_WB_REQUIRED) != 0 + jnz_ptr(cb, side_exit); + } // Pop the value to write from the stack let stack_top = ctx.stack_pop(1); |