YJIT: Side-exit on String#dup when it's not leaf (#13921)

* YJIT: Side-exit on String#dup when it's not leaf

* Use an enum instead of a macro for bindgen
This commit is contained in:
Takashi Kokubun 2025-07-16 15:59:32 -07:00 committed by GitHub
parent 15cf72dade
commit 571a8d2753
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 13 additions and 6 deletions

View file

@ -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")

View file

@ -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

View file

@ -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,