summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Bernstein <ruby@bernsteinbear.com>2025-11-19 20:53:41 -0500
committerMax Bernstein <tekknolagi@gmail.com>2025-11-21 08:49:03 -0800
commit8090988f878c71c2aaefbb3123ac13e3753c93da (patch)
tree85552e23d11348fb9f19e76ba8b7314aecc544c9
parent6cebbf4037376f28d9792cecf38d4f770bcdcaac (diff)
ZJIT: Inline ArrayLength into LIR
-rw-r--r--zjit/src/codegen.rs9
1 files changed, 8 insertions, 1 deletions
diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs
index d00ab500d7..06f991c738 100644
--- a/zjit/src/codegen.rs
+++ b/zjit/src/codegen.rs
@@ -1426,7 +1426,14 @@ fn gen_array_pop(asm: &mut Assembler, array: Opnd, state: &FrameState) -> lir::O
}
fn gen_array_length(asm: &mut Assembler, array: Opnd) -> lir::Opnd {
- asm_ccall!(asm, rb_jit_array_len, array)
+ let array = asm.load(array);
+ let flags = Opnd::mem(VALUE_BITS, array, RUBY_OFFSET_RBASIC_FLAGS);
+ let embedded_len = asm.and(flags, (RARRAY_EMBED_LEN_MASK as u64).into());
+ let embedded_len = asm.rshift(embedded_len, (RARRAY_EMBED_LEN_SHIFT as u64).into());
+ // cmov between the embedded length and heap length depending on the embed flag
+ asm.test(flags, (RARRAY_EMBED_FLAG as u64).into());
+ let heap_len = Opnd::mem(c_long::BITS as u8, array, RUBY_OFFSET_RARRAY_AS_HEAP_LEN);
+ asm.csel_nz(embedded_len, heap_len)
}
/// Compile opt_newarray_hash - create a hash from array elements