Skip to content

Commit 9692947

Browse files
committed
PoC1: Move materialize_frames from side exits to jit_exec/JIT_EXEC
Instead of calling rb_zjit_materialize_frames in every side exit's generated code, call zjit_materialize_frames once in jit_exec() and JIT_EXEC() after the ZJIT entry trampoline returns. This reduces generated code size by removing a C function call from each unique side exit.
1 parent 62c6d03 commit 9692947

4 files changed

Lines changed: 13 additions & 11 deletions

File tree

vm.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,8 @@ zjit_compile(rb_execution_context_t *ec)
559559
# define zjit_compile(ec) ((rb_jit_func_t)0)
560560
#endif
561561

562+
static inline void zjit_materialize_frames(rb_control_frame_t *cfp);
563+
562564
// Execute JIT code compiled by yjit_compile() or zjit_compile()
563565
static inline VALUE
564566
jit_exec(rb_execution_context_t *ec)
@@ -578,7 +580,14 @@ jit_exec(rb_execution_context_t *ec)
578580
if (zjit_entry) {
579581
rb_jit_func_t func = zjit_compile(ec);
580582
if (func) {
581-
return ((rb_zjit_func_t)zjit_entry)(ec, ec->cfp, func);
583+
VALUE result = ((rb_zjit_func_t)zjit_entry)(ec, ec->cfp, func);
584+
// Materialize any remaining lightweight ZJIT frames on side exit.
585+
// This is done here (once per JIT entry) instead of in each side exit
586+
// to reduce generated code size.
587+
if (UNDEF_P(result)) {
588+
zjit_materialize_frames(ec->cfp);
589+
}
590+
return result;
582591
}
583592
}
584593
#endif

vm_exec.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ default: \
189189
rb_jit_func_t func = zjit_compile(ec); \
190190
if (func) { \
191191
val = zjit_entry(ec, ec->cfp, func); \
192+
if (UNDEF_P(val)) zjit_materialize_frames(ec->cfp); \
192193
} \
193194
} \
194195
} \

zjit/src/backend/lir.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2641,12 +2641,6 @@ impl Assembler
26412641

26422642
asm_comment!(asm, "save cfp->jit_return");
26432643
asm.store(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_JIT_RETURN), 0.into());
2644-
2645-
asm_comment!(asm, "materialize caller frames");
2646-
unsafe extern "C" {
2647-
fn rb_zjit_materialize_frames(cfp: CfpPtr);
2648-
}
2649-
asm_ccall!(asm, rb_zjit_materialize_frames, CFP);
26502644
}
26512645

26522646
/// Tear down the JIT frame and return to the interpreter.

zjit/src/codegen.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2911,10 +2911,8 @@ c_callable! {
29112911
// If we side-exit from function_stub_hit (before JIT code runs), we need to set them here.
29122912
fn prepare_for_exit(iseq: IseqPtr, cfp: CfpPtr, sp: *mut VALUE, compile_error: &CompileError) {
29132913
unsafe {
2914-
unsafe extern "C" {
2915-
fn rb_zjit_materialize_frames(cfp: CfpPtr);
2916-
}
2917-
rb_zjit_materialize_frames(cfp);
2914+
// Caller frames are materialized by jit_exec() after the entry trampoline returns.
2915+
// The current frame's pc and iseq are already set by function_stub_hit before this point.
29182916

29192917
// Set SP which gen_push_frame() doesn't set
29202918
rb_set_cfp_sp(cfp, sp);

0 commit comments

Comments
 (0)