[vm] Fix JumpToFrame execution state transition
Instead of handling FFI related execution state and safepoint in assembly handle it in runtime code. The transition needs to be done before JumpToFrame unwinds stack because unwinding destroys exit frame and this can't be done at safepoint as GC might be traversing the stack. An incorrect order of operation was manifesting as crashes in GC when one isolate in a group was encountering a lot of exceptions thrown from an FFI call and another isolate is triggering GCs. To catch this in the future added a bit of validation to ExitSafepoint runtime call which triggers when --use-slow-path is enabled. Though after refactoring this code does not trigger this code path anymore because it was completely removed - but it is better than nothing. This CL also removes a lot of unnecessary complexity which was associated with handling this transition in the stub itself. TEST=ffi/vmspecific_handle_test Bug: b/408377905 Cq-Include-Trybots: dart/try:vm-aot-android-release-arm64c-try,vm-aot-android-release-arm_x64-try,vm-aot-asan-linux-release-x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try,vm-aot-mac-release-arm64-try,vm-aot-msan-linux-release-x64-try,vm-aot-obfuscate-linux-release-x64-try,vm-aot-optimization-level-linux-release-x64-try,vm-aot-tsan-linux-release-x64-try,vm-aot-ubsan-linux-release-x64-try,vm-aot-win-debug-x64-try,vm-aot-win-debug-x64c-try,vm-appjit-linux-debug-x64-try,vm-asan-linux-release-arm64-try,vm-asan-linux-release-x64-try,vm-checked-mac-release-arm64-try,vm-eager-optimization-linux-release-ia32-try,vm-eager-optimization-linux-release-x64-try,vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64c-try,vm-ffi-mac-debug-simarm64_arm64-try,vm-ffi-qemu-linux-release-arm-try,vm-ffi-qemu-linux-release-riscv64-try,vm-fuchsia-release-x64-try,vm-linux-debug-ia32-try,vm-linux-debug-x64-try,vm-linux-debug-x64c-try,vm-mac-debug-arm64-try,vm-mac-debug-x64-try,vm-msan-linux-release-arm64-try,vm-msan-linux-release-x64-try,vm-reload-linux-debug-x64-try,vm-reload-rollback-linux-debug-x64-try,vm-tsan-linux-release-arm64-try,vm-tsan-linux-release-x64-try,vm-ubsan-linux-release-arm64-try,vm-ubsan-linux-release-x64-try,vm-win-debug-x64-try,vm-win-debug-x64c-try,vm-win-release-ia32-try Change-Id: Ia073cb6bb9e1b5a0ea8514c7e048cee6019b84d6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/420324 Commit-Queue: Slava Egorov <vegorov@google.com> Reviewed-by: Daco Harkes <dacoharkes@google.com>
This commit is contained in:
committed by
Commit Queue
parent
d33c6c3ef1
commit
8085a97a63
@@ -1381,6 +1381,61 @@ void Thread::HandleStolen() {
|
||||
/*was_stolen=*/true);
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
namespace {
|
||||
|
||||
// This visitor simply dereferences every non-Smi |ObjectPtr| it visits and
|
||||
// checks that its class id is valid.
|
||||
//
|
||||
// It is used for fast validation of pointers on the stack: if a pointer is
|
||||
// invalid it is likely to either cause a crash when dereferenced or have
|
||||
// a garbage class id.
|
||||
class FastPointerValidator : public ObjectPointerVisitor {
|
||||
public:
|
||||
explicit FastPointerValidator(IsolateGroup* isolate_group)
|
||||
: ObjectPointerVisitor(isolate_group) {}
|
||||
|
||||
void VisitPointers(ObjectPtr* from, ObjectPtr* to) override {
|
||||
for (ObjectPtr* ptr = from; ptr <= to; ptr++) {
|
||||
const auto cid = (*ptr)->GetClassId();
|
||||
RELEASE_ASSERT(class_table()->IsValidIndex(cid));
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(DART_COMPRESSED_POINTERS)
|
||||
void VisitCompressedPointers(uword heap_base,
|
||||
CompressedObjectPtr* first,
|
||||
CompressedObjectPtr* last) override {
|
||||
// We are not expecting compressed pointers on the stack.
|
||||
UNREACHABLE();
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(FastPointerValidator);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
void Thread::ValidateExitFrameState() {
|
||||
if (top_exit_frame_info() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
FastPointerValidator fast_pointers_validator(isolate_group());
|
||||
|
||||
StackFrameIterator frames_iterator(
|
||||
top_exit_frame_info(), ValidationPolicy::kValidateFrames, this,
|
||||
StackFrameIterator::kNoCrossThreadIteration);
|
||||
|
||||
StackFrame* frame = frames_iterator.NextFrame();
|
||||
while (frame != nullptr) {
|
||||
frame->VisitObjectPointers(&fast_pointers_validator);
|
||||
frame = frames_iterator.NextFrame();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void Thread::EnterSafepointUsingLock() {
|
||||
isolate_group()->safepoint_handler()->EnterSafepointUsingLock(this);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user