Skip to content
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
6 changes: 6 additions & 0 deletions jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,12 @@ rb_yarv_ary_entry_internal(VALUE ary, long offset)
return rb_ary_entry_internal(ary, offset);
}

long
rb_jit_array_len(VALUE a)
{
return rb_array_len(a);
}

void
rb_set_cfp_pc(struct rb_control_frame_struct *cfp, const VALUE *pc)
{
Expand Down
30 changes: 30 additions & 0 deletions test/ruby/test_zjit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1714,6 +1714,36 @@ def test = RUBY_COPYRIGHT
}, call_threshold: 1, insns: [:opt_getconstant_path]
end

def test_expandarray_no_splat
assert_compiles '[3, 4]', %q{
def test(o)
a, b = o
[a, b]
end
test [3, 4]
}, call_threshold: 1, insns: [:expandarray]
end

def test_expandarray_splat
assert_compiles '[3, [4]]', %q{
def test(o)
a, *b = o
[a, b]
end
test [3, 4]
}, call_threshold: 1, insns: [:expandarray]
end

def test_expandarray_splat_post
assert_compiles '[3, [4], 5]', %q{
def test(o)
a, *b, c = o
[a, b, c]
end
test [3, 4, 5]
}, call_threshold: 1, insns: [:expandarray]
end

def test_getconstant_path_autoload
# A constant-referencing expression can run arbitrary code through Kernel#autoload.
Dir.mktmpdir('autoload') do |tmpdir|
Expand Down
6 changes: 0 additions & 6 deletions yjit.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,6 @@ STATIC_ASSERT(pointer_tagging_scheme, USE_FLONUM);
// The "_yjit_" part is for trying to be informative. We might want different
// suffixes for symbols meant for Rust and symbols meant for broader CRuby.

long
rb_yjit_array_len(VALUE a)
{
return rb_array_len(a);
}

# define PTR2NUM(x) (rb_int2inum((intptr_t)(void *)(x)))

// For a given raw_sample (frame), set the hash with the caller's
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 @@ -381,7 +381,7 @@ fn main() {
.allowlist_function("rb_METHOD_ENTRY_VISI")
.allowlist_function("rb_RCLASS_ORIGIN")
.allowlist_function("rb_method_basic_definition_p")
.allowlist_function("rb_yjit_array_len")
.allowlist_function("rb_jit_array_len")
.allowlist_function("rb_obj_class")
.allowlist_function("rb_obj_is_proc")
.allowlist_function("rb_vm_base_ptr")
Expand Down
4 changes: 2 additions & 2 deletions yjit/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2305,7 +2305,7 @@ fn gen_expandarray(
}

// Get the compile-time array length
let comptime_len = unsafe { rb_yjit_array_len(comptime_recv) as u32 };
let comptime_len = unsafe { rb_jit_array_len(comptime_recv) as u32 };

// Move the array from the stack and check that it's an array.
guard_object_is_array(
Expand Down Expand Up @@ -7603,7 +7603,7 @@ fn gen_send_iseq(
gen_counter_incr(jit, asm, Counter::send_iseq_splat_not_array);
return None;
} else {
unsafe { rb_yjit_array_len(array) as u32}
unsafe { rb_jit_array_len(array) as u32}
};

// Arity check accounting for size of the splat. When callee has rest parameters, we insert
Expand Down
2 changes: 1 addition & 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.

1 change: 1 addition & 0 deletions zjit/bindgen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ fn main() {
.allowlist_function("rb_jit_mark_executable")
.allowlist_function("rb_jit_mark_unused")
.allowlist_function("rb_jit_get_page_size")
.allowlist_function("rb_jit_array_len")
.allowlist_function("rb_zjit_iseq_builtin_attrs")
.allowlist_function("rb_zjit_iseq_inspect")
.allowlist_function("rb_zjit_iseq_insn_set")
Expand Down
20 changes: 15 additions & 5 deletions zjit/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,9 @@ fn gen_function(cb: &mut CodeBlock, iseq: IseqPtr, function: &Function) -> Resul
asm.write_label(label);

// Compile all parameters
for &insn_id in block.params() {
for (idx, &insn_id) in block.params().enumerate() {
match function.find(insn_id) {
Insn::Param { idx } => {
Insn::Param => {
jit.opnds[insn_id.0] = Some(gen_param(&mut asm, idx));
},
insn => unreachable!("Non-param insn found in block.params: {insn:?}"),
Expand Down Expand Up @@ -356,6 +356,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
Insn::NewRangeFixnum { low, high, flag, state } => gen_new_range_fixnum(asm, opnd!(low), opnd!(high), *flag, &function.frame_state(*state)),
Insn::ArrayDup { val, state } => gen_array_dup(asm, opnd!(val), &function.frame_state(*state)),
Insn::ArrayArefFixnum { array, index, .. } => gen_aref_fixnum(asm, opnd!(array), opnd!(index)),
Insn::ArrayLength { array } => gen_array_length(asm, opnd!(array)),
Insn::ObjectAlloc { val, state } => gen_object_alloc(jit, asm, opnd!(val), &function.frame_state(*state)),
&Insn::ObjectAllocClass { class, state } => gen_object_alloc_class(asm, class, &function.frame_state(state)),
Insn::StringCopy { val, chilled, state } => gen_string_copy(asm, opnd!(val), *chilled, &function.frame_state(*state)),
Expand All @@ -366,7 +367,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
&Insn::StringGetbyteFixnum { string, index } => gen_string_getbyte_fixnum(asm, opnd!(string), opnd!(index)),
Insn::StringIntern { val, state } => gen_intern(asm, opnd!(val), &function.frame_state(*state)),
Insn::ToRegexp { opt, values, state } => gen_toregexp(jit, asm, *opt, opnds!(values), &function.frame_state(*state)),
Insn::Param { idx } => unreachable!("block.insns should not have Insn::Param({idx})"),
Insn::Param => unreachable!("block.insns should not have Insn::Param"),
Insn::Snapshot { .. } => return Ok(()), // we don't need to do anything for this instruction at the moment
Insn::Jump(branch) => no_output!(gen_jump(jit, asm, branch)),
Insn::IfTrue { val, target } => no_output!(gen_if_true(jit, asm, opnd!(val), target)),
Expand Down Expand Up @@ -1258,6 +1259,10 @@ fn gen_aref_fixnum(
asm_ccall!(asm, rb_ary_entry, array, unboxed_idx)
}

fn gen_array_length(asm: &mut Assembler, array: Opnd) -> lir::Opnd {
asm_ccall!(asm, rb_jit_array_len, array)
}

/// Compile a new hash instruction
fn gen_new_hash(
jit: &mut JITState,
Expand Down Expand Up @@ -1589,8 +1594,13 @@ fn gen_guard_type_not(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, g
}

/// Compile an identity check with a side exit
fn gen_guard_bit_equals(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, expected: VALUE, state: &FrameState) -> lir::Opnd {
asm.cmp(val, Opnd::Value(expected));
fn gen_guard_bit_equals(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, expected: crate::hir::Const, state: &FrameState) -> lir::Opnd {
let expected_opnd: Opnd = match expected {
crate::hir::Const::Value(v) => { Opnd::Value(v) }
crate::hir::Const::CInt64(v) => { v.into() }
_ => panic!("gen_guard_bit_equals: unexpected hir::Const {:?}", expected),
};
asm.cmp(val, expected_opnd);
asm.jnz(side_exit(jit, state, GuardBitEquals(expected)));
val
}
Expand Down
1 change: 1 addition & 0 deletions zjit/src/cruby_bindings.inc.rs

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

Loading