mirror of
https://github.com/dart-lang/sdk
synced 2024-11-05 18:22:09 +00:00
4be2981c2d
Right each `Pointer.fromFunction()` invocation will lead to creation of a new ffi trampoline function & it's following JITed code. In AOT we have exactly one ffi trampoline per target/native-signature/exceptional-return combination. => This CL ensures we have only one such function. Furthermore each `Pointer.fromFunction()` will currently perform 2 runtime calls in JIT: One to create a `Function` object, the other to JIT that function & register callback metadata. => This CL ensures we won't do a runtime call to get a function, instead do it at compile-time (as in AOT) Furthermore we eagerly assign a callback-id to the unique/deduped ffi trampoline callbacks. Only when the application requests a pointer, do we populate metadata on the `Thread` object. This CL doesn't (yet) change the fact that in JIT mode we have isolate-specific jit trampolines (that will call now shared ffi trampoline functions). We also avoid baking in C++ runtime function pointers in generated code. As a result we can now preserve ffi trampolines across AppJIT serialization. As a nice side-effect, we remove 100 lines of code. TEST=ffi{,_2}/ffi_callback_unique_test Issue https://github.com/dart-lang/sdk/issues/50611 Change-Id: I458831a47b041a088086f28f825de2a3849f6adc Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/273420 Reviewed-by: Daco Harkes <dacoharkes@google.com> Commit-Queue: Martin Kustermann <kustermann@google.com>
38 lines
1.2 KiB
Dart
38 lines
1.2 KiB
Dart
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
import 'dart:ffi';
|
|
|
|
import 'package:expect/expect.dart';
|
|
|
|
void main() {
|
|
final a = <int>[];
|
|
final b = <int>[];
|
|
for (int i = 0; i < 10; ++i) {
|
|
// Several pointers for same call site.
|
|
a.add(
|
|
Pointer.fromFunction<Int Function()>(nativeToDartCallback, 0).address);
|
|
b.add(
|
|
Pointer.fromFunction<Int Function()>(nativeToDartCallback, 1).address);
|
|
}
|
|
// Another pointer from a different call site.
|
|
a.add(Pointer.fromFunction<Int Function()>(nativeToDartCallback, 0).address);
|
|
b.add(Pointer.fromFunction<Int Function()>(nativeToDartCallback, 1).address);
|
|
|
|
ensureEqualEntries(a);
|
|
ensureEqualEntries(b);
|
|
|
|
// The two functions have different exceptional return and should have
|
|
// therefore a different ffi trampoline.
|
|
Expect.notEquals(a.first, b.first);
|
|
}
|
|
|
|
void ensureEqualEntries(List<int> entries) {
|
|
final first = entries.first;
|
|
for (int i = 1; i < entries.length; ++i) {
|
|
Expect.equals(first, entries[i]);
|
|
}
|
|
}
|
|
|
|
int nativeToDartCallback() => 42;
|