[VM/FFI] Adds FFI leaf calls.

This CL adds FFI leaf calls by adding `lookupFunction(.., isLeaf)`
and `_asFunctionInternal(.., isLeaf)`, which generate FFI leaf calls.
These calls skip a lot of the usual frame building and generated <->
native transition overhead.

`benchmark/FfiCall/` shows a 1.1x - 4.3x speed-up between the regular
FFI calls and their leaf call counterparts (JIT, x64, release).

TEST=Adds `tests/ffi{,_2}/vmspecific_leaf_call_test.dart`. Tested FFI tests.

Closes: https://github.com/dart-lang/sdk/issues/36707
Cq-Include-Trybots: luci.dart.try:vm-precomp-ffi-qemu-linux-release-arm-try,vm-ffi-android-release-arm64-try,vm-ffi-android-release-arm-try,vm-ffi-android-product-arm64-try,vm-ffi-android-product-arm-try,vm-ffi-android-debug-arm64-try,vm-ffi-android-debug-arm-try,vm-kernel-linux-debug-ia32-try,vm-kernel-win-debug-ia32-try,vm-kernel-win-debug-x64-try,vm-kernel-win-release-x64-try,vm-kernel-mac-debug-x64-try,vm-kernel-precomp-nnbd-mac-release-simarm64-try,vm-kernel-precomp-android-release-arm64-try,vm-kernel-precomp-asan-linux-release-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try,vm-kernel-precomp-obfuscate-linux-release-x64-try,vm-kernel-precomp-ubsan-linux-release-x64-try,vm-kernel-precomp-tsan-linux-release-x64-try,vm-kernel-precomp-win-release-x64-try,vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-reload-rollback-linux-debug-x64-try,vm-kernel-reload-linux-debug-x64-try
Bug: https://github.com/dart-lang/sdk/issues/36707
Change-Id: Id8824f36b0006bf09951207bd004356fe6e9f46e
Cq-Do-Not-Cancel-Tryjobs: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/179768
Commit-Queue: Clement Skau <cskau@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
This commit is contained in:
Clement Skau
2021-05-21 11:12:02 +00:00
committed by commit-bot@chromium.org
parent f364c8bf7b
commit 4d5055805f
55 changed files with 17073 additions and 612 deletions
+14 -9
View File
@@ -21,18 +21,21 @@ import 'very_large_struct.dart';
typedef NativeCoordinateOp = Pointer<Coordinate> Function(Pointer<Coordinate>);
void main() {
testFunctionWithStruct();
testFunctionWithStructArray();
testFunctionWithVeryLargeStruct();
for (final isLeaf in [false, true]) {
testFunctionWithStruct(isLeaf: isLeaf);
testFunctionWithStructArray(isLeaf: isLeaf);
testFunctionWithVeryLargeStruct(isLeaf: isLeaf);
}
}
DynamicLibrary ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
/// pass a struct to a c function and get a struct as return value
void testFunctionWithStruct() {
void testFunctionWithStruct({bool isLeaf: false}) {
Pointer<NativeFunction<NativeCoordinateOp>> p1 =
ffiTestFunctions.lookup("TransposeCoordinate");
NativeCoordinateOp f1 = p1.asFunction();
NativeCoordinateOp f1 =
(isLeaf ? p1.asFunction(isLeaf: true) : p1.asFunction(isLeaf: false));
final c1 = calloc<Coordinate>()
..ref.x = 10.0
@@ -56,10 +59,11 @@ void testFunctionWithStruct() {
}
/// pass an array of structs to a c funtion
void testFunctionWithStructArray() {
void testFunctionWithStructArray({bool isLeaf: false}) {
Pointer<NativeFunction<NativeCoordinateOp>> p1 =
ffiTestFunctions.lookup("CoordinateElemAt1");
NativeCoordinateOp f1 = p1.asFunction();
NativeCoordinateOp f1 =
(isLeaf ? p1.asFunction(isLeaf: true) : p1.asFunction(isLeaf: false));
final coordinateArray = calloc<Coordinate>(3);
Coordinate c1 = coordinateArray[0];
@@ -85,10 +89,11 @@ void testFunctionWithStructArray() {
typedef VeryLargeStructSum = int Function(Pointer<VeryLargeStruct>);
typedef NativeVeryLargeStructSum = Int64 Function(Pointer<VeryLargeStruct>);
void testFunctionWithVeryLargeStruct() {
void testFunctionWithVeryLargeStruct({bool isLeaf: false}) {
Pointer<NativeFunction<NativeVeryLargeStructSum>> p1 =
ffiTestFunctions.lookup("SumVeryLargeStruct");
VeryLargeStructSum f = p1.asFunction();
VeryLargeStructSum f =
(isLeaf ? p1.asFunction(isLeaf: true) : p1.asFunction(isLeaf: false));
final vlsArray = calloc<VeryLargeStruct>(2);
VeryLargeStruct vls1 = vlsArray[0];