Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" ]

Expand Down
4 changes: 3 additions & 1 deletion shape.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion yjit/bindgen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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")
Expand Down
7 changes: 6 additions & 1 deletion yjit/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion yjit/src/cruby_bindings.inc.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

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:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy