[vm/ffi] Convert Objects to Dart_Handles in FFI calls
This includes support for calling Dart_PropagateError in native code
when doing FFI calls, and catching uncaught exceptions with Dart_IsError
when doing FFI callbacks.
The support for Dart_PropagateError adds a catch entry to the FFI
trampoline, which prevents inlining these trampolines in AOT. This
regresses the FfiCall benchmarks by 1-2% in AOT.
In addition, Dart_PropagateError requires maintaining a bit whether we
entered native/VM code from generated code through FFI or not. That way
we can do the proper transition on the exception path. When entering
generated code, we store this bit on the stack, right after the entry
frame.
Design: http://go/dart-ffi-handles
Issue: https://github.com/dart-lang/sdk/issues/36858
Issue: https://github.com/dart-lang/sdk/issues/41319
Change-Id: Idfd7ff69132fb29cc730931a4113d914d4437396
Cq-Include-Trybots: luci.dart.try:vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64-try,app-kernel-linux-debug-x64-try,vm-kernel-linux-debug-ia32-try,vm-kernel-win-debug-x64-try,vm-kernel-win-debug-ia32-try,vm-kernel-precomp-linux-debug-x64-try,vm-dartkb-linux-release-x64-abi-try,vm-kernel-precomp-android-release-arm64-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-simarm64-try,vm-kernel-precomp-android-release-arm_x64-try,vm-kernel-precomp-obfuscate-linux-release-x64-try,dart-sdk-linux-try,analyzer-analysis-server-linux-try,analyzer-linux-release-try,front-end-linux-release-x64-try,vm-kernel-precomp-win-release-x64-try,vm-kernel-mac-debug-x64-try,vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-nnbd-linux-debug-x64-try,analyzer-nnbd-linux-release-try,front-end-nnbd-linux-release-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/145591
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
2020-06-12 11:14:22 +00:00
|
|
|
// Copyright (c) 2020, 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.
|
|
|
|
//
|
|
|
|
// SharedObjects=ffi_test_functions
|
|
|
|
|
2021-04-26 17:58:57 +00:00
|
|
|
// @dart = 2.9
|
|
|
|
|
[vm/ffi] Convert Objects to Dart_Handles in FFI calls
This includes support for calling Dart_PropagateError in native code
when doing FFI calls, and catching uncaught exceptions with Dart_IsError
when doing FFI callbacks.
The support for Dart_PropagateError adds a catch entry to the FFI
trampoline, which prevents inlining these trampolines in AOT. This
regresses the FfiCall benchmarks by 1-2% in AOT.
In addition, Dart_PropagateError requires maintaining a bit whether we
entered native/VM code from generated code through FFI or not. That way
we can do the proper transition on the exception path. When entering
generated code, we store this bit on the stack, right after the entry
frame.
Design: http://go/dart-ffi-handles
Issue: https://github.com/dart-lang/sdk/issues/36858
Issue: https://github.com/dart-lang/sdk/issues/41319
Change-Id: Idfd7ff69132fb29cc730931a4113d914d4437396
Cq-Include-Trybots: luci.dart.try:vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64-try,app-kernel-linux-debug-x64-try,vm-kernel-linux-debug-ia32-try,vm-kernel-win-debug-x64-try,vm-kernel-win-debug-ia32-try,vm-kernel-precomp-linux-debug-x64-try,vm-dartkb-linux-release-x64-abi-try,vm-kernel-precomp-android-release-arm64-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-simarm64-try,vm-kernel-precomp-android-release-arm_x64-try,vm-kernel-precomp-obfuscate-linux-release-x64-try,dart-sdk-linux-try,analyzer-analysis-server-linux-try,analyzer-linux-release-try,front-end-linux-release-x64-try,vm-kernel-precomp-win-release-x64-try,vm-kernel-mac-debug-x64-try,vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-nnbd-linux-debug-x64-try,analyzer-nnbd-linux-release-try,front-end-nnbd-linux-release-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/145591
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
2020-06-12 11:14:22 +00:00
|
|
|
import 'dart:ffi';
|
|
|
|
|
|
|
|
import 'package:expect/expect.dart';
|
|
|
|
|
|
|
|
import 'dylib_utils.dart';
|
|
|
|
|
|
|
|
void main() {
|
|
|
|
testHandle();
|
|
|
|
testReadField();
|
|
|
|
testTrueHandle();
|
|
|
|
testClosureCallback();
|
|
|
|
testReturnHandleInCallback();
|
|
|
|
testPropagateError();
|
|
|
|
testCallbackReturnException();
|
|
|
|
testDeepException();
|
|
|
|
testDeepException2();
|
|
|
|
testNull();
|
|
|
|
testDeepRecursive();
|
[vm/ffi] Remove try-catch from ffi trampoline if no handle scope
https://dart-review.googlesource.com/c/sdk/+/145591 introduced a try
catch into FFI calls to call ExitHandleScope on the exception path.
However, we only need this try-catch if we actually need to exit the
handle scope on the exception path, which is not the case if we have
no handles in the signature. So this CL makes the try catch optional.
This speeds up ffi calls without handles (tested on JIT x64):
FfiCall.Uint8x01(RunTime): 206.4801280066068 us.
->
FfiCall.Uint8x01(RunTime): 203.7240782236708 us.
Also adds a test that checks that an exception can still be propagated
with Dart_PropagateError from native code when the FFI trampoline has
no try catch.
Change-Id: I9fac7078381c60fb8055b64fff29ea364fbc948f
Cq-Include-Trybots: luci.dart.try:vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64-try,app-kernel-linux-debug-x64-try,vm-kernel-linux-debug-ia32-try,vm-kernel-win-debug-x64-try,vm-kernel-win-debug-ia32-try,vm-kernel-precomp-linux-debug-x64-try,vm-dartkb-linux-release-x64-abi-try,vm-kernel-precomp-android-release-arm64-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-msan-linux-release-x64-try,vm-kernel-precomp-msan-linux-release-x64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-simarm64-try,vm-kernel-precomp-android-release-arm_x64-try,vm-kernel-precomp-obfuscate-linux-release-x64-try,dart-sdk-linux-try,analyzer-analysis-server-linux-try,analyzer-linux-release-try,front-end-linux-release-x64-try,vm-kernel-precomp-win-release-x64-try,vm-kernel-mac-debug-x64-try,vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-nnbd-linux-debug-x64-try,analyzer-nnbd-linux-release-try,front-end-nnbd-linux-release-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151239
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
2020-06-26 12:03:02 +00:00
|
|
|
testNoHandlePropagateError();
|
[vm/ffi] Convert Objects to Dart_Handles in FFI calls
This includes support for calling Dart_PropagateError in native code
when doing FFI calls, and catching uncaught exceptions with Dart_IsError
when doing FFI callbacks.
The support for Dart_PropagateError adds a catch entry to the FFI
trampoline, which prevents inlining these trampolines in AOT. This
regresses the FfiCall benchmarks by 1-2% in AOT.
In addition, Dart_PropagateError requires maintaining a bit whether we
entered native/VM code from generated code through FFI or not. That way
we can do the proper transition on the exception path. When entering
generated code, we store this bit on the stack, right after the entry
frame.
Design: http://go/dart-ffi-handles
Issue: https://github.com/dart-lang/sdk/issues/36858
Issue: https://github.com/dart-lang/sdk/issues/41319
Change-Id: Idfd7ff69132fb29cc730931a4113d914d4437396
Cq-Include-Trybots: luci.dart.try:vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64-try,app-kernel-linux-debug-x64-try,vm-kernel-linux-debug-ia32-try,vm-kernel-win-debug-x64-try,vm-kernel-win-debug-ia32-try,vm-kernel-precomp-linux-debug-x64-try,vm-dartkb-linux-release-x64-abi-try,vm-kernel-precomp-android-release-arm64-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-simarm64-try,vm-kernel-precomp-android-release-arm_x64-try,vm-kernel-precomp-obfuscate-linux-release-x64-try,dart-sdk-linux-try,analyzer-analysis-server-linux-try,analyzer-linux-release-try,front-end-linux-release-x64-try,vm-kernel-precomp-win-release-x64-try,vm-kernel-mac-debug-x64-try,vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-nnbd-linux-debug-x64-try,analyzer-nnbd-linux-release-try,front-end-nnbd-linux-release-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/145591
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
2020-06-12 11:14:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void testHandle() {
|
|
|
|
print("testHandle");
|
|
|
|
final s = SomeClass(123);
|
|
|
|
print("passObjectToC($s)");
|
|
|
|
final result = passObjectToC(s);
|
|
|
|
print("result = $result");
|
|
|
|
Expect.isTrue(identical(s, result));
|
|
|
|
}
|
|
|
|
|
|
|
|
void testReadField() {
|
|
|
|
final s = SomeClass(123);
|
|
|
|
final result = handleReadFieldValue(s);
|
|
|
|
Expect.equals(s.a, result);
|
|
|
|
}
|
|
|
|
|
|
|
|
void testTrueHandle() {
|
|
|
|
final result = trueHandle();
|
|
|
|
Expect.isTrue(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
int globalCounter = 0;
|
|
|
|
|
|
|
|
void increaseCounter() {
|
|
|
|
print("increaseCounter");
|
|
|
|
globalCounter++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void doClosureCallback(Object callback) {
|
|
|
|
print("doClosureCallback");
|
|
|
|
print(callback.runtimeType);
|
|
|
|
print(callback);
|
|
|
|
final callback_as_function = callback as void Function();
|
|
|
|
callback_as_function();
|
|
|
|
}
|
|
|
|
|
|
|
|
final closureCallbackPointer =
|
|
|
|
Pointer.fromFunction<Void Function(Handle)>(doClosureCallback);
|
|
|
|
|
|
|
|
void testClosureCallback() {
|
|
|
|
print("testClosureCallback $closureCallbackPointer");
|
|
|
|
Expect.equals(0, globalCounter);
|
|
|
|
closureCallbackThroughHandle(closureCallbackPointer, increaseCounter);
|
|
|
|
Expect.equals(1, globalCounter);
|
|
|
|
closureCallbackThroughHandle(closureCallbackPointer, increaseCounter);
|
|
|
|
Expect.equals(2, globalCounter);
|
|
|
|
}
|
|
|
|
|
|
|
|
final someObject = SomeClass(12356789);
|
|
|
|
|
|
|
|
Object returnHandleCallback() {
|
|
|
|
print("returnHandleCallback returning $someObject");
|
|
|
|
return someObject;
|
|
|
|
}
|
|
|
|
|
|
|
|
final returnHandleCallbackPointer =
|
|
|
|
Pointer.fromFunction<Handle Function()>(returnHandleCallback);
|
|
|
|
|
|
|
|
void testReturnHandleInCallback() {
|
|
|
|
print("testReturnHandleInCallback");
|
|
|
|
final result = returnHandleInCallback(returnHandleCallbackPointer);
|
|
|
|
Expect.isTrue(identical(someObject, result));
|
|
|
|
}
|
|
|
|
|
|
|
|
class SomeClass {
|
|
|
|
// We use this getter in the native api, don't tree shake it.
|
|
|
|
@pragma("vm:entry-point")
|
|
|
|
final int a;
|
|
|
|
SomeClass(this.a);
|
|
|
|
}
|
|
|
|
|
|
|
|
void testPropagateError() {
|
|
|
|
final s = SomeOtherClass(123);
|
|
|
|
Expect.throws(() => handleReadFieldValue(s));
|
|
|
|
}
|
|
|
|
|
|
|
|
class SomeOtherClass {
|
|
|
|
final int notA;
|
|
|
|
SomeOtherClass(this.notA);
|
|
|
|
}
|
|
|
|
|
|
|
|
final someException = Exception("exceptionHandleCallback exception");
|
|
|
|
|
|
|
|
Object exceptionHandleCallback() {
|
|
|
|
print("exceptionHandleCallback throwing ($someException)");
|
|
|
|
throw someException;
|
|
|
|
}
|
|
|
|
|
|
|
|
final exceptionHandleCallbackPointer =
|
|
|
|
Pointer.fromFunction<Handle Function()>(exceptionHandleCallback);
|
|
|
|
|
|
|
|
void testCallbackReturnException() {
|
|
|
|
print("testCallbackReturnException");
|
|
|
|
bool throws = false;
|
|
|
|
try {
|
|
|
|
final result = returnHandleInCallback(exceptionHandleCallbackPointer);
|
|
|
|
print(result);
|
|
|
|
} catch (e) {
|
|
|
|
throws = true;
|
|
|
|
print("caught ($e)");
|
|
|
|
Expect.isTrue(identical(someException, e));
|
|
|
|
}
|
|
|
|
Expect.isTrue(throws);
|
|
|
|
}
|
|
|
|
|
|
|
|
Object callCAgainFromCallback() {
|
|
|
|
print("callCAgainFromCallback");
|
|
|
|
final s = SomeOtherClass(123);
|
|
|
|
Expect.throws(() => handleReadFieldValue(s));
|
|
|
|
return someObject;
|
|
|
|
}
|
|
|
|
|
|
|
|
final callCAgainFromCallbackPointer =
|
|
|
|
Pointer.fromFunction<Handle Function()>(callCAgainFromCallback);
|
|
|
|
|
|
|
|
void testDeepException() {
|
|
|
|
print("testDeepException");
|
|
|
|
final result = returnHandleInCallback(callCAgainFromCallbackPointer);
|
|
|
|
Expect.isTrue(identical(someObject, result));
|
|
|
|
}
|
|
|
|
|
|
|
|
Object callCAgainFromCallback2() {
|
|
|
|
print("callCAgainFromCallback2");
|
|
|
|
final s = SomeOtherClass(123);
|
|
|
|
handleReadFieldValue(s); // throws.
|
|
|
|
return someObject;
|
|
|
|
}
|
|
|
|
|
|
|
|
final callCAgainFromCallbackPointer2 =
|
|
|
|
Pointer.fromFunction<Handle Function()>(callCAgainFromCallback2);
|
|
|
|
|
|
|
|
void testDeepException2() {
|
|
|
|
print("testDeepException2");
|
|
|
|
Expect.throws(() => returnHandleInCallback(callCAgainFromCallbackPointer2));
|
|
|
|
}
|
|
|
|
|
|
|
|
Object returnNullHandleCallback() {
|
|
|
|
print("returnHandleCallback returning null");
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
final returnNullHandleCallbackPointer =
|
|
|
|
Pointer.fromFunction<Handle Function()>(returnNullHandleCallback);
|
|
|
|
|
|
|
|
void testNull() {
|
|
|
|
print("testNull");
|
|
|
|
final result = passObjectToC(null);
|
|
|
|
Expect.isNull(result);
|
|
|
|
|
|
|
|
final result2 = returnHandleInCallback(returnNullHandleCallbackPointer);
|
|
|
|
Expect.isNull(result2);
|
|
|
|
}
|
|
|
|
|
|
|
|
Object recurseAbove0(int i) {
|
|
|
|
print("recurseAbove0($i)");
|
|
|
|
if (i == 0) {
|
|
|
|
print("throwing");
|
|
|
|
throw someException;
|
|
|
|
}
|
|
|
|
if (i < 0) {
|
|
|
|
print("returning");
|
|
|
|
return someObject;
|
|
|
|
}
|
|
|
|
final result =
|
|
|
|
handleRecursion(SomeClassWithMethod(), recurseAbove0Pointer, i - 1);
|
|
|
|
print("return $i");
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
final recurseAbove0Pointer =
|
|
|
|
Pointer.fromFunction<Handle Function(Int64)>(recurseAbove0);
|
|
|
|
|
|
|
|
class SomeClassWithMethod {
|
|
|
|
// We use this method in the native api, don't tree shake it.
|
|
|
|
@pragma("vm:entry-point")
|
|
|
|
Object a(int i) => recurseAbove0(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
void testDeepRecursive() {
|
|
|
|
// works on arm.
|
|
|
|
Expect.throws(() {
|
|
|
|
handleRecursion(123, recurseAbove0Pointer, 1);
|
|
|
|
});
|
|
|
|
|
|
|
|
Expect.throws(() {
|
|
|
|
handleRecursion(SomeClassWithMethod(), recurseAbove0Pointer, 1);
|
|
|
|
});
|
|
|
|
|
|
|
|
Expect.throws(() {
|
|
|
|
recurseAbove0(100);
|
|
|
|
});
|
|
|
|
|
|
|
|
final result = recurseAbove0(101);
|
|
|
|
Expect.isTrue(identical(someObject, result));
|
|
|
|
}
|
|
|
|
|
[vm/ffi] Remove try-catch from ffi trampoline if no handle scope
https://dart-review.googlesource.com/c/sdk/+/145591 introduced a try
catch into FFI calls to call ExitHandleScope on the exception path.
However, we only need this try-catch if we actually need to exit the
handle scope on the exception path, which is not the case if we have
no handles in the signature. So this CL makes the try catch optional.
This speeds up ffi calls without handles (tested on JIT x64):
FfiCall.Uint8x01(RunTime): 206.4801280066068 us.
->
FfiCall.Uint8x01(RunTime): 203.7240782236708 us.
Also adds a test that checks that an exception can still be propagated
with Dart_PropagateError from native code when the FFI trampoline has
no try catch.
Change-Id: I9fac7078381c60fb8055b64fff29ea364fbc948f
Cq-Include-Trybots: luci.dart.try:vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64-try,app-kernel-linux-debug-x64-try,vm-kernel-linux-debug-ia32-try,vm-kernel-win-debug-x64-try,vm-kernel-win-debug-ia32-try,vm-kernel-precomp-linux-debug-x64-try,vm-dartkb-linux-release-x64-abi-try,vm-kernel-precomp-android-release-arm64-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-msan-linux-release-x64-try,vm-kernel-precomp-msan-linux-release-x64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-simarm64-try,vm-kernel-precomp-android-release-arm_x64-try,vm-kernel-precomp-obfuscate-linux-release-x64-try,dart-sdk-linux-try,analyzer-analysis-server-linux-try,analyzer-linux-release-try,front-end-linux-release-x64-try,vm-kernel-precomp-win-release-x64-try,vm-kernel-mac-debug-x64-try,vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-nnbd-linux-debug-x64-try,analyzer-nnbd-linux-release-try,front-end-nnbd-linux-release-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151239
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
2020-06-26 12:03:02 +00:00
|
|
|
void testNoHandlePropagateError() {
|
|
|
|
bool throws = false;
|
|
|
|
try {
|
|
|
|
final result = propagateErrorWithoutHandle(exceptionHandleCallbackPointer);
|
|
|
|
print(result);
|
|
|
|
} catch (e) {
|
|
|
|
throws = true;
|
|
|
|
print("caught ($e)");
|
|
|
|
Expect.isTrue(identical(someException, e));
|
|
|
|
}
|
|
|
|
Expect.isTrue(throws);
|
|
|
|
}
|
|
|
|
|
[vm/ffi] Convert Objects to Dart_Handles in FFI calls
This includes support for calling Dart_PropagateError in native code
when doing FFI calls, and catching uncaught exceptions with Dart_IsError
when doing FFI callbacks.
The support for Dart_PropagateError adds a catch entry to the FFI
trampoline, which prevents inlining these trampolines in AOT. This
regresses the FfiCall benchmarks by 1-2% in AOT.
In addition, Dart_PropagateError requires maintaining a bit whether we
entered native/VM code from generated code through FFI or not. That way
we can do the proper transition on the exception path. When entering
generated code, we store this bit on the stack, right after the entry
frame.
Design: http://go/dart-ffi-handles
Issue: https://github.com/dart-lang/sdk/issues/36858
Issue: https://github.com/dart-lang/sdk/issues/41319
Change-Id: Idfd7ff69132fb29cc730931a4113d914d4437396
Cq-Include-Trybots: luci.dart.try:vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64-try,app-kernel-linux-debug-x64-try,vm-kernel-linux-debug-ia32-try,vm-kernel-win-debug-x64-try,vm-kernel-win-debug-ia32-try,vm-kernel-precomp-linux-debug-x64-try,vm-dartkb-linux-release-x64-abi-try,vm-kernel-precomp-android-release-arm64-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-simarm64-try,vm-kernel-precomp-android-release-arm_x64-try,vm-kernel-precomp-obfuscate-linux-release-x64-try,dart-sdk-linux-try,analyzer-analysis-server-linux-try,analyzer-linux-release-try,front-end-linux-release-x64-try,vm-kernel-precomp-win-release-x64-try,vm-kernel-mac-debug-x64-try,vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-nnbd-linux-debug-x64-try,analyzer-nnbd-linux-release-try,front-end-nnbd-linux-release-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/145591
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
2020-06-12 11:14:22 +00:00
|
|
|
final testLibrary = dlopenPlatformSpecific("ffi_test_functions");
|
|
|
|
|
|
|
|
final passObjectToC = testLibrary.lookupFunction<Handle Function(Handle),
|
|
|
|
Object Function(Object)>("PassObjectToC");
|
|
|
|
|
|
|
|
final handleReadFieldValue =
|
|
|
|
testLibrary.lookupFunction<Int64 Function(Handle), int Function(Object)>(
|
|
|
|
"HandleReadFieldValue");
|
|
|
|
|
|
|
|
final trueHandle = testLibrary
|
|
|
|
.lookupFunction<Handle Function(), Object Function()>("TrueHandle");
|
|
|
|
|
|
|
|
final closureCallbackThroughHandle = testLibrary.lookupFunction<
|
|
|
|
Void Function(Pointer<NativeFunction<Void Function(Handle)>>, Handle),
|
|
|
|
void Function(Pointer<NativeFunction<Void Function(Handle)>>,
|
|
|
|
Object)>("ClosureCallbackThroughHandle");
|
|
|
|
|
|
|
|
final returnHandleInCallback = testLibrary.lookupFunction<
|
|
|
|
Handle Function(Pointer<NativeFunction<Handle Function()>>),
|
|
|
|
Object Function(
|
|
|
|
Pointer<NativeFunction<Handle Function()>>)>("ReturnHandleInCallback");
|
|
|
|
|
|
|
|
final handleRecursion = testLibrary.lookupFunction<
|
|
|
|
Handle Function(
|
|
|
|
Handle, Pointer<NativeFunction<Handle Function(Int64)>>, Int64),
|
|
|
|
Object Function(Object, Pointer<NativeFunction<Handle Function(Int64)>>,
|
|
|
|
int)>("HandleRecursion");
|
[vm/ffi] Remove try-catch from ffi trampoline if no handle scope
https://dart-review.googlesource.com/c/sdk/+/145591 introduced a try
catch into FFI calls to call ExitHandleScope on the exception path.
However, we only need this try-catch if we actually need to exit the
handle scope on the exception path, which is not the case if we have
no handles in the signature. So this CL makes the try catch optional.
This speeds up ffi calls without handles (tested on JIT x64):
FfiCall.Uint8x01(RunTime): 206.4801280066068 us.
->
FfiCall.Uint8x01(RunTime): 203.7240782236708 us.
Also adds a test that checks that an exception can still be propagated
with Dart_PropagateError from native code when the FFI trampoline has
no try catch.
Change-Id: I9fac7078381c60fb8055b64fff29ea364fbc948f
Cq-Include-Trybots: luci.dart.try:vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64-try,app-kernel-linux-debug-x64-try,vm-kernel-linux-debug-ia32-try,vm-kernel-win-debug-x64-try,vm-kernel-win-debug-ia32-try,vm-kernel-precomp-linux-debug-x64-try,vm-dartkb-linux-release-x64-abi-try,vm-kernel-precomp-android-release-arm64-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-msan-linux-release-x64-try,vm-kernel-precomp-msan-linux-release-x64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-simarm64-try,vm-kernel-precomp-android-release-arm_x64-try,vm-kernel-precomp-obfuscate-linux-release-x64-try,dart-sdk-linux-try,analyzer-analysis-server-linux-try,analyzer-linux-release-try,front-end-linux-release-x64-try,vm-kernel-precomp-win-release-x64-try,vm-kernel-mac-debug-x64-try,vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-nnbd-linux-debug-x64-try,analyzer-nnbd-linux-release-try,front-end-nnbd-linux-release-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151239
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
2020-06-26 12:03:02 +00:00
|
|
|
|
|
|
|
final propagateErrorWithoutHandle = testLibrary.lookupFunction<
|
|
|
|
Int64 Function(Pointer<NativeFunction<Handle Function()>>),
|
|
|
|
int Function(Pointer<NativeFunction<Handle Function()>>)>(
|
|
|
|
"PropagateErrorWithoutHandle");
|