diff options
| author | Takashi Kokubun <takashikkbn@gmail.com> | 2025-09-02 11:58:42 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-02 18:58:42 +0000 |
| commit | e0a7da93d25cf9a4fced323ce3344fc390b59ad7 (patch) | |
| tree | 491ee9642fde2d960975736998ea597b856fe0ab | |
| parent | bdaff44bae6cd6e5675a37b19341d132b3881bb7 (diff) | |
ZJIT: Rename gen_save_pc to gen_prepare_call_with_gc (#14427)
| -rw-r--r-- | zjit/src/codegen.rs | 27 |
1 files changed, 11 insertions, 16 deletions
diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs index 66ad5ba3a9..de13d306c1 100644 --- a/zjit/src/codegen.rs +++ b/zjit/src/codegen.rs @@ -943,7 +943,7 @@ fn gen_send( gen_incr_counter(asm, Counter::dynamic_send_count); // Save PC and SP - gen_save_pc(asm, state); + gen_prepare_call_with_gc(asm, state); gen_save_sp(asm, state.stack().len()); // Spill locals and stack @@ -979,7 +979,7 @@ fn gen_send_without_block( asm_comment!(asm, "spill frame state"); // Save PC and SP - gen_save_pc(asm, state); + gen_prepare_call_with_gc(asm, state); gen_save_sp(asm, state.stack().len()); // Spill locals and stack @@ -1012,7 +1012,7 @@ fn gen_send_without_block_direct( state: &FrameState, ) -> lir::Opnd { // Save cfp->pc and cfp->sp for the caller frame - gen_save_pc(asm, state); + gen_prepare_call_with_gc(asm, state); gen_save_sp(asm, state.stack().len() - args.len() - 1); // -1 for receiver gen_spill_locals(jit, asm, state); @@ -1363,9 +1363,13 @@ fn gen_incr_counter(asm: &mut Assembler, counter: Counter) { } } -/// Save the incremented PC on the CFP. -/// This is necessary when callees can raise or allocate. -fn gen_save_pc(asm: &mut Assembler, state: &FrameState) { +/// Save the current PC on the CFP as a preparation for calling a C function +/// that may allocate objects and trigger GC. Use gen_prepare_non_leaf_call() +/// if it may raise exceptions or call arbitrary methods. +/// +/// Unlike YJIT, we don't need to save the stack slots to protect them from GC +/// because the backend spills all live registers onto the C stack on CCall. +fn gen_prepare_call_with_gc(asm: &mut Assembler, state: &FrameState) { let opcode: usize = state.get_opcode().try_into().unwrap(); let next_pc: *const VALUE = unsafe { state.pc.offset(insn_len(opcode) as isize) }; @@ -1409,7 +1413,7 @@ fn gen_spill_stack(jit: &JITState, asm: &mut Assembler, state: &FrameState) { fn gen_prepare_non_leaf_call(jit: &JITState, asm: &mut Assembler, state: &FrameState) { // TODO: Lazily materialize caller frames when needed // Save PC for backtraces and allocation tracing - gen_save_pc(asm, state); + gen_prepare_call_with_gc(asm, state); // Save SP and spill the virtual stack in case it raises an exception // and the interpreter uses the stack for handling the exception @@ -1420,15 +1424,6 @@ fn gen_prepare_non_leaf_call(jit: &JITState, asm: &mut Assembler, state: &FrameS gen_spill_locals(jit, asm, state); } -/// Prepare for calling a C function that may allocate objects and trigger GC. -/// Use gen_prepare_non_leaf_call() if it may also call an arbitrary method. -fn gen_prepare_call_with_gc(asm: &mut Assembler, state: &FrameState) { - // Save PC for allocation tracing - gen_save_pc(asm, state); - // Unlike YJIT, we don't need to save the stack to protect them from GC - // because the backend spills all live registers onto the C stack on asm.ccall(). -} - /// Frame metadata written by gen_push_frame() struct ControlFrame { recv: Opnd, |
