diff --git a/Cargo.toml b/Cargo.toml index 6f61e5f95cfd35..3f373fdace9cbf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,8 +22,7 @@ path = "jit.rs" [features] disasm = ["yjit?/disasm", "zjit?/disasm"] -# TODO(GH-642) Turning this on trips a btest failure. -runtime_checks = [] # ["yjit?/runtime_checks", "zjit?/runtime_checks"] +runtime_checks = ["yjit?/runtime_checks", "zjit?/runtime_checks"] yjit = [ "dep:yjit" ] zjit = [ "dep:zjit" ] diff --git a/shape.h b/shape.h index 63d5534d463dce..a418dc78218693 100644 --- a/shape.h +++ b/shape.h @@ -48,7 +48,9 @@ enum shape_id_fl_type { // This masks allows to check if a shape_id contains any ivar. // It rely on ROOT_SHAPE_WITH_OBJ_ID==1. -#define SHAPE_ID_HAS_IVAR_MASK (SHAPE_ID_FL_TOO_COMPLEX | (SHAPE_ID_OFFSET_MASK - 1)) +enum { + SHAPE_ID_HAS_IVAR_MASK = SHAPE_ID_FL_TOO_COMPLEX | (SHAPE_ID_OFFSET_MASK - 1), +}; // The interpreter doesn't care about frozen status or slot size when reading ivars. // So we normalize shape_id by clearing these bits to improve cache hits. diff --git a/yjit/bindgen/src/main.rs b/yjit/bindgen/src/main.rs index a0446ad17b6a91..7c8ce7bce5c69d 100644 --- a/yjit/bindgen/src/main.rs +++ b/yjit/bindgen/src/main.rs @@ -103,6 +103,7 @@ fn main() { .allowlist_function("rb_yjit_shape_capacity") .allowlist_function("rb_yjit_shape_index") .allowlist_var("SHAPE_ID_NUM_BITS") + .allowlist_var("SHAPE_ID_HAS_IVAR_MASK") // From ruby/internal/intern/object.h .allowlist_function("rb_obj_is_kind_of") @@ -228,7 +229,6 @@ fn main() { .allowlist_function("rb_obj_as_string_result") .allowlist_function("rb_str_byte_substr") .allowlist_function("rb_str_substr_two_fixnums") - .allowlist_function("rb_str_dup_m") // From include/ruby/internal/intern/parse.h .allowlist_function("rb_backref_get") diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 66932fd46cc961..b8b15adc8b44a8 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -6278,9 +6278,14 @@ fn jit_rb_str_dup( let recv_opnd = asm.stack_pop(1); let recv_opnd = asm.load(recv_opnd); + let shape_id_offset = unsafe { rb_shape_id_offset() }; + let shape_opnd = Opnd::mem(64, recv_opnd, shape_id_offset); + asm.test(shape_opnd, Opnd::UImm(SHAPE_ID_HAS_IVAR_MASK as u64)); + asm.jnz(Target::side_exit(Counter::send_str_dup_exivar)); + // Call rb_str_dup let stack_ret = asm.stack_push(Type::CString); - let ret_opnd = asm.ccall(rb_str_dup_m as *const u8, vec![recv_opnd]); + let ret_opnd = asm.ccall(rb_str_dup as *const u8, vec![recv_opnd]); asm.mov(stack_ret, ret_opnd); true diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs index e36b6f9f5f73c7..9b871c9e7c88ed 100644 --- a/yjit/src/cruby_bindings.inc.rs +++ b/yjit/src/cruby_bindings.inc.rs @@ -689,6 +689,8 @@ pub const VM_ENV_FLAG_ISOLATED: vm_frame_env_flags = 16; pub type vm_frame_env_flags = u32; pub type attr_index_t = u16; pub type shape_id_t = u32; +pub const SHAPE_ID_HAS_IVAR_MASK: _bindgen_ty_37 = 134742014; +pub type _bindgen_ty_37 = u32; #[repr(C)] pub struct rb_cvar_class_tbl_entry { pub index: u32, @@ -1120,7 +1122,6 @@ extern "C" { pub fn rb_gvar_set(arg1: ID, arg2: VALUE) -> VALUE; pub fn rb_ensure_iv_list_size(obj: VALUE, current_len: u32, newsize: u32); pub fn rb_vm_barrier(); - pub fn rb_str_dup_m(str_: VALUE) -> VALUE; pub fn rb_str_byte_substr(str_: VALUE, beg: VALUE, len: VALUE) -> VALUE; pub fn rb_str_substr_two_fixnums( str_: VALUE,
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: