summaryrefslogtreecommitdiff
path: root/zjit/src/codegen.rs
diff options
context:
space:
mode:
Diffstat (limited to 'zjit/src/codegen.rs')
-rw-r--r--zjit/src/codegen.rs53
1 files changed, 27 insertions, 26 deletions
diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs
index 7c893a72fe..d5d381acfa 100644
--- a/zjit/src/codegen.rs
+++ b/zjit/src/codegen.rs
@@ -2551,25 +2551,6 @@ fn gen_guard_type(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, guard
asm.cmp(klass, Opnd::Value(expected_class));
asm.jne(jit, side_exit);
- } else if guard_type.is_subtype(types::TData) {
- let side = side_exit(jit, state, GuardType(guard_type));
-
- // Check special constant
- asm.test(val, Opnd::UImm(RUBY_IMMEDIATE_MASK as u64));
- asm.jnz(jit, side.clone());
-
- // Check false
- asm.cmp(val, Qfalse.into());
- asm.je(jit, side.clone());
-
- // Check the T_DATA builtin type.
- let val = asm.load_mem(val);
- let flags = asm.load(Opnd::mem(VALUE_BITS, val, RUBY_OFFSET_RBASIC_FLAGS));
- let mask = RUBY_T_MASK.to_usize();
- let expected = RUBY_T_DATA.to_usize();
- let masked = asm.and(flags, mask.into());
- asm.cmp(masked, expected.into());
- asm.jne(jit, side);
} else if let Some(builtin_type) = guard_type.builtin_type_equivalent() {
let side = side_exit(jit, state, GuardType(guard_type));
@@ -3098,7 +3079,7 @@ c_callable! {
// If we side-exit from function_stub_hit (before JIT code runs), we need to set them here.
fn prepare_for_exit(iseq: IseqPtr, cfp: CfpPtr, sp: *mut VALUE, argc: u16, num_opts_filled: u16, compile_error: &CompileError) {
unsafe {
- // Caller frames are materialized by jit_exec() after the entry trampoline returns.
+ // Caller frames are materialized by the materialize_exit trampoline before unwinding native frames.
// The current frame's pc and iseq are already set by function_stub_hit before this point.
// Set SP which gen_push_frame() doesn't set
@@ -3186,7 +3167,7 @@ c_callable! {
unsafe { Rc::increment_strong_count(iseq_call_ptr as *const IseqCall); }
prepare_for_exit(iseq, cfp, sp, argc, num_opts_filled, compile_error);
- return ZJITState::get_exit_trampoline_with_counter().raw_ptr(cb);
+ return ZJITState::get_materialize_exit_trampoline_with_counter().raw_ptr(cb);
}
// Otherwise, attempt to compile the ISEQ. We have to mark_all_executable() beyond this point.
@@ -3201,7 +3182,7 @@ c_callable! {
unsafe { Rc::increment_strong_count(iseq_call_ptr as *const IseqCall); }
prepare_for_exit(iseq, cfp, sp, argc, num_opts_filled, &compile_error);
- ZJITState::get_exit_trampoline_with_counter()
+ ZJITState::get_materialize_exit_trampoline_with_counter()
});
cb.mark_all_executable();
code_ptr.raw_ptr(cb)
@@ -3332,14 +3313,34 @@ pub fn gen_exit_trampoline(cb: &mut CodeBlock) -> Result<CodePtr, CompileError>
})
}
-/// Generate a trampoline that increments exit_compilation_failure and jumps to exit_trampoline.
-pub fn gen_exit_trampoline_with_counter(cb: &mut CodeBlock, exit_trampoline: CodePtr) -> Result<CodePtr, CompileError> {
+/// Generate a trampoline that materializes ZJIT frames before unwinding native frames.
+pub fn gen_materialize_exit_trampoline(cb: &mut CodeBlock, exit_trampoline: CodePtr) -> Result<CodePtr, CompileError> {
+ unsafe extern "C" {
+ fn rb_zjit_materialize_frames(ec: EcPtr, cfp: CfpPtr);
+ }
+
let mut asm = Assembler::new();
- asm.new_block_without_id("exit_trampoline_with_counter");
+ asm.new_block_without_id("materialize_exit_trampoline");
+
+ asm_comment!(asm, "materialize ZJIT frames");
+ asm.store(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_JIT_RETURN), 0.into());
+ asm_ccall!(asm, rb_zjit_materialize_frames, EC, CFP);
+ asm.jmp(Target::CodePtr(exit_trampoline));
+
+ asm.compile(cb).map(|(code_ptr, gc_offsets)| {
+ assert_eq!(gc_offsets.len(), 0);
+ code_ptr
+ })
+}
+
+/// Generate a trampoline that increments exit_compilation_failure and jumps to materialize_exit_trampoline.
+pub fn gen_materialize_exit_trampoline_with_counter(cb: &mut CodeBlock, materialize_exit_trampoline: CodePtr) -> Result<CodePtr, CompileError> {
+ let mut asm = Assembler::new();
+ asm.new_block_without_id("materialize_exit_trampoline_with_counter");
asm_comment!(asm, "function stub exit trampoline");
gen_incr_counter(&mut asm, exit_compile_error);
- asm.jmp(Target::CodePtr(exit_trampoline));
+ asm.jmp(Target::CodePtr(materialize_exit_trampoline));
asm.compile(cb).map(|(code_ptr, gc_offsets)| {
assert_eq!(gc_offsets.len(), 0);