[vm/aot] Fix retaining of targets of FFI callbacks in precompiler Account for the fact that a Function could be only reachable via FfiTrampolineData in the FFI trampoline function. TEST=ffi_2/function_callbacks_test Fixes https://github.com/dart-lang/sdk/issues/45510 Change-Id: I2db81c7730ae48d1f1355aa236339e54562ee6c4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193893 Commit-Queue: Alexander Markov <alexmarkov@google.com> Reviewed-by: Daco Harkes <dacoharkes@google.com> Reviewed-by: Tess Strickland <sstrickl@google.com>
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc index e84949f..4eddc2e 100644 --- a/runtime/vm/compiler/aot/precompiler.cc +++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -144,6 +144,8 @@ static constexpr const char* kLocalParent = "parent of a local function"; // The object has an entry point pragma that requires it be retained. static constexpr const char* kEntryPointPragma = "entry point pragma"; + // The function is a target of FFI callback. + static constexpr const char* kFfiCallbackTarget = "ffi callback target"; }; class RetainedReasonsWriter : public ValueObject { @@ -935,6 +937,13 @@ // Local closure function. const auto& target = Function::Cast(entry); AddFunction(target, RetainReasons::kLocalClosure); + if (target.IsFfiTrampoline()) { + const auto& callback_target = + Function::Handle(Z, target.FfiCallbackTarget()); + if (!callback_target.IsNull()) { + AddFunction(callback_target, RetainReasons::kFfiCallbackTarget); + } + } } else if (entry.IsCode()) { const auto& target_code = Code::Cast(entry); if (target_code.IsAllocationStubCode()) {
diff --git a/tests/ffi/function_callbacks_test.dart b/tests/ffi/function_callbacks_test.dart index 11baff6..e9a853c 100644 --- a/tests/ffi/function_callbacks_test.dart +++ b/tests/ffi/function_callbacks_test.dart
@@ -13,6 +13,7 @@ // VMOptions=--use-slow-path --enable-testing-pragmas --write-protect-code --no-dual-map-code // VMOptions=--use-slow-path --enable-testing-pragmas --write-protect-code --no-dual-map-code --stacktrace-every=100 // VMOptions=--use-bare-instructions=false +// VMOptions=--enable-testing-pragmas --dwarf_stack_traces --no-retain_function_objects --no-retain_code_objects // SharedObjects=ffi_test_functions import 'dart:ffi';
diff --git a/tests/ffi_2/function_callbacks_test.dart b/tests/ffi_2/function_callbacks_test.dart index 11baff6..e9a853c 100644 --- a/tests/ffi_2/function_callbacks_test.dart +++ b/tests/ffi_2/function_callbacks_test.dart
@@ -13,6 +13,7 @@ // VMOptions=--use-slow-path --enable-testing-pragmas --write-protect-code --no-dual-map-code // VMOptions=--use-slow-path --enable-testing-pragmas --write-protect-code --no-dual-map-code --stacktrace-every=100 // VMOptions=--use-bare-instructions=false +// VMOptions=--enable-testing-pragmas --dwarf_stack_traces --no-retain_function_objects --no-retain_code_objects // SharedObjects=ffi_test_functions import 'dart:ffi';