From b8a1d727ae655940eeeacccac568c1445ff76bcd Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Mon, 3 Aug 2026 23:12:42 +0900 Subject: [PATCH] Use datastack path for __init__ dispatch in CallAllocAndEnterInit specialization_run_init used prepare_exact_args_frame which heap-allocates a FrameObject with 4-5 atomic refcount bumps per call. Switch to invoke_prepared_exact_args which uses InterpreterFrame::new_on_datastack with zero refcount bumps. CallAllocAndEnterInit already guards against tracing (eval_frame_active) and recursion limits before reaching this path. Assisted-by: Claude --- crates/vm/src/builtins/function.rs | 2 +- crates/vm/src/frame.rs | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/crates/vm/src/builtins/function.rs b/crates/vm/src/builtins/function.rs index 39195202af7..89fab4db188 100644 --- a/crates/vm/src/builtins/function.rs +++ b/crates/vm/src/builtins/function.rs @@ -791,7 +791,7 @@ impl Py { frame } - fn invoke_prepared_exact_args( + pub(crate) fn invoke_prepared_exact_args( &self, args: impl ExactSizeIterator, vm: &VirtualMachine, diff --git a/crates/vm/src/frame.rs b/crates/vm/src/frame.rs index bf276ec45e0..bd5b66f8a19 100644 --- a/crates/vm/src/frame.rs +++ b/crates/vm/src/frame.rs @@ -2673,10 +2673,7 @@ impl ExecutingFrame<'_> { .iter_mut() .map(|slot| slot.take().expect("arg slot must be filled")); - let init_frame = init_func.prepare_exact_args_frame(taken, vm); - let init_result = vm.run_frame(init_frame.clone()); - release_datastack_frame(&init_frame, vm); - let init_result = init_result?; + let init_result = init_func.invoke_prepared_exact_args(taken, vm)?; if !vm.is_none(&init_result) { return Err(vm.new_type_error(format!(