From 76581515c188be686a2d0fbcbca6b6429be3263e Mon Sep 17 00:00:00 2001 From: Vyacheslav Egorov Date: Tue, 8 Apr 2025 03:15:49 -0700 Subject: [PATCH] [vm] Fix JumpToFrame for dynamic modules Change 8085a97a6375ade476bd2c2031e70f74e17751f2 moved commonly invoked StackResource::Unwind(...) from several different code paths (simulators & interpreter) into Exceptions::JumpToFrame. However the change did not account for the order of operations in Exceptions::JumpToFrame which broke interpreter. This CL fixes that by moving Interpreter::JumpToFrame under StackResource::Unwind(...). We also forgot to remove StackResource::Unwind from RISC-V simulator - but that's benign because calling it the second time simply does nothing. TEST=vm-aot-dyn-linux-debug-x64 Change-Id: Ia93fc6997b768180fbbb5e54bb0c0fd5c713a244 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/421060 Commit-Queue: Slava Egorov Auto-Submit: Slava Egorov Reviewed-by: Daco Harkes --- runtime/vm/exceptions.cc | 16 ++++++++-------- runtime/vm/simulator_riscv.cc | 5 ----- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc index eaa6c5dd55f..046c5e35c90 100644 --- a/runtime/vm/exceptions.cc +++ b/runtime/vm/exceptions.cc @@ -607,14 +607,6 @@ NO_SANITIZE_SAFE_STACK // This function manipulates the safestack pointer. bool clear_deopt_at_target) { ASSERT(thread->execution_state() == Thread::kThreadInVM); -#if defined(DART_DYNAMIC_MODULES) - Interpreter* interpreter = thread->interpreter(); - if ((interpreter != nullptr) && interpreter->HasFrame(frame_pointer)) { - interpreter->JumpToFrame(program_counter, stack_pointer, frame_pointer, - thread); - } -#endif // defined(DART_DYNAMIC_MODULES) - const uword fp_for_clearing = (clear_deopt_at_target ? frame_pointer + 1 : frame_pointer); ClearLazyDeopts(thread, fp_for_clearing); @@ -623,6 +615,14 @@ NO_SANITIZE_SAFE_STACK // This function manipulates the safestack pointer. // in the previous frames. StackResource::Unwind(thread); +#if defined(DART_DYNAMIC_MODULES) + Interpreter* interpreter = thread->interpreter(); + if ((interpreter != nullptr) && interpreter->HasFrame(frame_pointer)) { + interpreter->JumpToFrame(program_counter, stack_pointer, frame_pointer, + thread); + } +#endif // defined(DART_DYNAMIC_MODULES) + // If execution exited generated code through FFI then exit the safepoint // and transition back to kThreadInGenerated execution state. JumpToFrame // stub will transfer control directly to the exception handler and bypass diff --git a/runtime/vm/simulator_riscv.cc b/runtime/vm/simulator_riscv.cc index 5526c2040d7..b59e7a8382c 100644 --- a/runtime/vm/simulator_riscv.cc +++ b/runtime/vm/simulator_riscv.cc @@ -439,11 +439,6 @@ void Simulator::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) { } ASSERT(buf != nullptr); - // The C++ caller has not cleaned up the stack memory of C++ frames. - // Prepare for unwinding frames by destroying all the stack resources - // in the previous C++ frames. - StackResource::Unwind(thread); - // Keep the following code in sync with `StubCode::JumpToFrameStub()`. // Unwind the C++ stack and continue simulation in the target frame.