Skip to content

Commit 571a8d2

Browse files
authored
YJIT: Side-exit on String#dup when it's not leaf (ruby#13921)
* YJIT: Side-exit on String#dup when it's not leaf * Use an enum instead of a macro for bindgen
1 parent 15cf72d commit 571a8d2

5 files changed

Lines changed: 13 additions & 6 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ path = "jit.rs"
2222

2323
[features]
2424
disasm = ["yjit?/disasm", "zjit?/disasm"]
25-
# TODO(GH-642) Turning this on trips a btest failure.
26-
runtime_checks = [] # ["yjit?/runtime_checks", "zjit?/runtime_checks"]
25+
runtime_checks = ["yjit?/runtime_checks", "zjit?/runtime_checks"]
2726
yjit = [ "dep:yjit" ]
2827
zjit = [ "dep:zjit" ]
2928

shape.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ enum shape_id_fl_type {
4848

4949
// This masks allows to check if a shape_id contains any ivar.
5050
// It rely on ROOT_SHAPE_WITH_OBJ_ID==1.
51-
#define SHAPE_ID_HAS_IVAR_MASK (SHAPE_ID_FL_TOO_COMPLEX | (SHAPE_ID_OFFSET_MASK - 1))
51+
enum {
52+
SHAPE_ID_HAS_IVAR_MASK = SHAPE_ID_FL_TOO_COMPLEX | (SHAPE_ID_OFFSET_MASK - 1),
53+
};
5254

5355
// The interpreter doesn't care about frozen status or slot size when reading ivars.
5456
// So we normalize shape_id by clearing these bits to improve cache hits.

yjit/bindgen/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ fn main() {
103103
.allowlist_function("rb_yjit_shape_capacity")
104104
.allowlist_function("rb_yjit_shape_index")
105105
.allowlist_var("SHAPE_ID_NUM_BITS")
106+
.allowlist_var("SHAPE_ID_HAS_IVAR_MASK")
106107

107108
// From ruby/internal/intern/object.h
108109
.allowlist_function("rb_obj_is_kind_of")
@@ -228,7 +229,6 @@ fn main() {
228229
.allowlist_function("rb_obj_as_string_result")
229230
.allowlist_function("rb_str_byte_substr")
230231
.allowlist_function("rb_str_substr_two_fixnums")
231-
.allowlist_function("rb_str_dup_m")
232232

233233
// From include/ruby/internal/intern/parse.h
234234
.allowlist_function("rb_backref_get")

yjit/src/codegen.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6278,9 +6278,14 @@ fn jit_rb_str_dup(
62786278
let recv_opnd = asm.stack_pop(1);
62796279
let recv_opnd = asm.load(recv_opnd);
62806280

6281+
let shape_id_offset = unsafe { rb_shape_id_offset() };
6282+
let shape_opnd = Opnd::mem(64, recv_opnd, shape_id_offset);
6283+
asm.test(shape_opnd, Opnd::UImm(SHAPE_ID_HAS_IVAR_MASK as u64));
6284+
asm.jnz(Target::side_exit(Counter::send_str_dup_exivar));
6285+
62816286
// Call rb_str_dup
62826287
let stack_ret = asm.stack_push(Type::CString);
6283-
let ret_opnd = asm.ccall(rb_str_dup_m as *const u8, vec![recv_opnd]);
6288+
let ret_opnd = asm.ccall(rb_str_dup as *const u8, vec![recv_opnd]);
62846289
asm.mov(stack_ret, ret_opnd);
62856290

62866291
true

yjit/src/cruby_bindings.inc.rs

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)