summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/ruby/test_zjit.rb28
-rw-r--r--zjit/src/hir.rs348
2 files changed, 376 insertions, 0 deletions
@@ -295,6 +295,34 @@ class TestZJIT < Test::Unit::TestCase
}, insns: [:opt_ge], call_threshold: 2
end
def test_new_array_empty
assert_compiles '[]', %q{
def test = []
@@ -185,7 +185,9 @@ impl<'a> std::fmt::Display for InvariantPrinter<'a> {
write!(f, "BOPRedefined(")?;
match klass {
INTEGER_REDEFINED_OP_FLAG => write!(f, "INTEGER_REDEFINED_OP_FLAG")?,
ARRAY_REDEFINED_OP_FLAG => write!(f, "ARRAY_REDEFINED_OP_FLAG")?,
_ => write!(f, "{klass}")?,
}
write!(f, ", ")?;
@@ -201,6 +203,8 @@ impl<'a> std::fmt::Display for InvariantPrinter<'a> {
BOP_LE => write!(f, "BOP_LE")?,
BOP_GT => write!(f, "BOP_GT")?,
BOP_GE => write!(f, "BOP_GE")?,
BOP_MAX => write!(f, "BOP_MAX")?,
_ => write!(f, "{bop}")?,
}
@@ -1250,6 +1254,38 @@ impl Function {
}
}
/// Rewrite SendWithoutBlock opcodes into SendWithoutBlockDirect opcodes if we know the target
/// ISEQ statically. This removes run-time method lookups and opens the door for inlining.
fn optimize_direct_sends(&mut self) {
@@ -1280,6 +1316,10 @@ impl Function {
self.try_rewrite_fixnum_op(block, insn_id, &|left, right| Insn::FixnumGt { left, right }, BOP_GT, self_val, args[0], state),
Insn::SendWithoutBlock { self_val, call_info: CallInfo { method_name }, args, state, .. } if method_name == ">=" && args.len() == 1 =>
self.try_rewrite_fixnum_op(block, insn_id, &|left, right| Insn::FixnumGe { left, right }, BOP_GE, self_val, args[0], state),
Insn::SendWithoutBlock { mut self_val, call_info, cd, args, state } => {
let frame_state = self.frame_state(state);
let (klass, guard_equal_to) = if let Some(klass) = self.type_of(self_val).runtime_exact_ruby_class() {
@@ -2421,6 +2461,34 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
let send = fun.push_insn(block, Insn::SendWithoutBlock { self_val: recv, call_info: CallInfo { method_name }, cd, args, state: exit_id });
state.stack_push(send);
}
YARVINSN_leave => {
fun.push_insn(block, Insn::Return { val: state.stack_pop()? });
@@ -3099,6 +3167,62 @@ mod tests {
}
#[test]
fn test_setlocal_getlocal() {
eval("
def test
@@ -5385,4 +5509,228 @@ mod opt_tests {
Return v2
"#]]);
}
}