Skip to content

Commit 50e0e0d

Browse files
aamCommit Queue
authored and
Commit Queue
committed
[vm/shared] Introduce NativeCallable.isolateGroupShared
This method allows for synchronous execution of dart callbacks from native code. The execution happens on dart mutator thread, from which dart code can only access isolate-group variables - those which are tagged with . Bug: #54530 Bug: #56841 Change-Id: Ia1a6b01327be493f003f1eea82e558bb6b147dd3 CoreLibraryReviewExempt: only internal library change TEST=isolate_group_shared_callback_test Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/422920 Reviewed-by: Slava Egorov <[email protected]> Commit-Queue: Alexander Aprelev <[email protected]>
1 parent 7431e88 commit 50e0e0d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1224
-120
lines changed

BUILD.gn

+2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ group("runtime") {
4949
"runtime/vm:kernel_platform_files($host_toolchain)",
5050
"samples/embedder:kernel",
5151
"samples/ffi/http:fake_http",
52+
"samples/ffi/httpIG:fake_httpIG",
5253
"utils/dartdev:dartdev",
5354
"utils/kernel-service:kernel-service",
5455
]
@@ -308,6 +309,7 @@ if (is_fuchsia) {
308309
"tests/ffi/inline_array_test.dart",
309310
"tests/ffi/inline_array_variable_length_test.dart",
310311
"tests/ffi/invoke_callback_after_suspension_test.dart",
312+
"tests/ffi/isolate_group_shared_callback_test.dart",
311313
"tests/ffi/isolate_local_function_callbacks_test.dart",
312314
"tests/ffi/msan_test.dart",
313315
"tests/ffi/native_assets/asset_absolute_test.dart",

pkg/vm/lib/modular/transformations/ffi/common.dart

+30
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,10 @@ class FfiTransformer extends Transformer {
313313
final Procedure nativeCallbackFunctionProcedure;
314314
final Procedure nativeAsyncCallbackFunctionProcedure;
315315
final Procedure createNativeCallableIsolateLocalProcedure;
316+
final Procedure createNativeCallableIsolateGroupSharedProcedure;
316317
final Procedure nativeIsolateLocalCallbackFunctionProcedure;
318+
final Procedure nativeIsolateGroupSharedCallbackFunctionProcedure;
319+
final Procedure nativeIsolateGroupSharedClosureFunctionProcedure;
317320
final Map<NativeType, Procedure> loadMethods;
318321
final Map<NativeType, Procedure> loadUnalignedMethods;
319322
final Map<NativeType, Procedure> storeMethods;
@@ -337,7 +340,9 @@ class FfiTransformer extends Transformer {
337340
final Class rawRecvPortClass;
338341
final Class nativeCallableClass;
339342
final Procedure nativeCallableIsolateLocalConstructor;
343+
final Procedure nativeCallableIsolateGroupSharedConstructor;
340344
final Constructor nativeCallablePrivateIsolateLocalConstructor;
345+
final Constructor nativeCallablePrivateIsolateGroupSharedConstructor;
341346
final Procedure nativeCallableListenerConstructor;
342347
final Constructor nativeCallablePrivateListenerConstructor;
343348
final Field nativeCallablePortField;
@@ -821,6 +826,11 @@ class FfiTransformer extends Transformer {
821826
'dart:ffi',
822827
'_createNativeCallableIsolateLocal',
823828
),
829+
createNativeCallableIsolateGroupSharedProcedure = index
830+
.getTopLevelProcedure(
831+
'dart:ffi',
832+
'_createNativeCallableIsolateGroupShared',
833+
),
824834
nativeCallbackFunctionProcedure = index.getTopLevelProcedure(
825835
'dart:ffi',
826836
'_nativeCallbackFunction',
@@ -833,6 +843,16 @@ class FfiTransformer extends Transformer {
833843
'dart:ffi',
834844
'_nativeIsolateLocalCallbackFunction',
835845
),
846+
nativeIsolateGroupSharedCallbackFunctionProcedure = index
847+
.getTopLevelProcedure(
848+
'dart:ffi',
849+
'_nativeIsolateGroupSharedCallbackFunction',
850+
),
851+
nativeIsolateGroupSharedClosureFunctionProcedure = index
852+
.getTopLevelProcedure(
853+
'dart:ffi',
854+
'_nativeIsolateGroupSharedClosureFunction',
855+
),
836856
nativeTypesClasses = nativeTypeClassNames.map(
837857
(nativeType, name) =>
838858
MapEntry(nativeType, index.getClass('dart:ffi', name)),
@@ -937,6 +957,11 @@ class FfiTransformer extends Transformer {
937957
'NativeCallable',
938958
'isolateLocal',
939959
),
960+
nativeCallableIsolateGroupSharedConstructor = index.getProcedure(
961+
'dart:ffi',
962+
'NativeCallable',
963+
'isolateGroupShared',
964+
),
940965
nativeCallablePrivateIsolateLocalConstructor = index.getConstructor(
941966
'dart:ffi',
942967
'_NativeCallableIsolateLocal',
@@ -952,6 +977,11 @@ class FfiTransformer extends Transformer {
952977
'_NativeCallableListener',
953978
'',
954979
),
980+
nativeCallablePrivateIsolateGroupSharedConstructor = index.getConstructor(
981+
'dart:ffi',
982+
'_NativeCallableIsolateGroupShared',
983+
'',
984+
),
955985
nativeCallablePortField = index.getField(
956986
'dart:ffi',
957987
'_NativeCallableListener',

pkg/vm/lib/modular/transformations/ffi/use_sites.dart

+97-19
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,11 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
570570
);
571571
} else if (target == nativeCallableIsolateLocalConstructor) {
572572
return _verifyAndReplaceNativeCallableIsolateLocal(node);
573+
} else if (target == nativeCallableIsolateGroupSharedConstructor) {
574+
return _verifyAndReplaceNativeCallable(
575+
node,
576+
replacement: _replaceNativeCallableIsolateGroupSharedConstructor,
577+
);
573578
} else if (target == nativeCallableListenerConstructor) {
574579
final DartType nativeType = InterfaceType(
575580
nativeFunctionClass,
@@ -881,18 +886,18 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
881886
}
882887

883888
// NativeCallable<T>.isolateLocal(target, exceptionalReturn) calls become:
884-
// isStaticFunction is false:
885-
// _NativeCallableIsolateLocal<T>(
886-
// _createNativeCallableIsolateLocal<NativeFunction<T>>(
887-
// _nativeIsolateLocalCallbackFunction<T>(exceptionalReturn),
888-
// target,
889-
// true));
890889
// isStaticFunction is true:
891890
// _NativeCallableIsolateLocal<T>(
892891
// _createNativeCallableIsolateLocal<NativeFunction<T>>(
893892
// _nativeCallbackFunction<T>(target, exceptionalReturn),
894893
// null,
895894
// true);
895+
// isStaticFunction is false:
896+
// _NativeCallableIsolateLocal<T>(
897+
// _createNativeCallableIsolateLocal<NativeFunction<T>>(
898+
// _nativeIsolateLocalCallbackFunction<T>(exceptionalReturn),
899+
// target,
900+
// true));
896901
Expression _replaceNativeCallableIsolateLocalConstructor(
897902
StaticInvocation node,
898903
Expression exceptionalReturn,
@@ -949,7 +954,7 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
949954
// void _handler(List args) => target(args[0], args[1], ...)
950955
// final _callback = _NativeCallableListener<T>(_handler, debugName);
951956
// _callback._pointer = _createNativeCallableListener<NativeFunction<T>>(
952-
// _nativeAsyncCallbackFunction<T>(), _callback._rawPort);
957+
// _nativeAsyncCallbackFunction<T>(), _callback._port);
953958
// expression result: _callback;
954959
Expression _replaceNativeCallableListenerConstructor(StaticInvocation node) {
955960
final nativeFunctionType = InterfaceType(
@@ -1017,7 +1022,7 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
10171022
)..fileOffset = node.fileOffset;
10181023

10191024
// _callback._pointer = _createNativeCallableListener<NativeFunction<T>>(
1020-
// _nativeAsyncCallbackFunction<T>(), _callback._rawPort);
1025+
// _nativeAsyncCallbackFunction<T>(), _callback._port);
10211026
final pointerValue = StaticInvocation(
10221027
createNativeCallableListenerProcedure,
10231028
Arguments(
@@ -1054,9 +1059,73 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
10541059
);
10551060
}
10561061

1057-
Expression _verifyAndReplaceNativeCallableIsolateLocal(
1062+
// NativeCallable<T>.isolateGroupShared(target, exceptionalReturn) calls become:
1063+
// isStaticFunction is true:
1064+
// _NativeCallableIsolateGroupShared<T>(
1065+
// _createNativeCallableIsolateGroupShared<NativeFunction<T>>(
1066+
// _nativeIsolateGroupSharedCallbackFunction<T>(target, exceptionalReturn),
1067+
// null);
1068+
// isStaticFunction is false:
1069+
// _NativeCallableIsolateGroupShared<T>(
1070+
// _createNativeCallableIsolateGroupShared<NativeFunction<T>>(
1071+
// _nativeIsolateGroupSharedClosureFunction<T>(exceptionalReturn),
1072+
// target));
1073+
Expression _replaceNativeCallableIsolateGroupSharedConstructor(
1074+
StaticInvocation node,
1075+
Expression exceptionalReturn,
1076+
bool isStaticFunction,
1077+
) {
1078+
final nativeFunctionType = InterfaceType(
1079+
nativeFunctionClass,
1080+
currentLibrary.nonNullable,
1081+
node.arguments.types,
1082+
);
1083+
final target = node.arguments.positional[0];
1084+
late StaticInvocation pointerValue;
1085+
if (isStaticFunction) {
1086+
pointerValue = StaticInvocation(
1087+
createNativeCallableIsolateGroupSharedProcedure,
1088+
Arguments(
1089+
[
1090+
StaticInvocation(
1091+
nativeIsolateGroupSharedCallbackFunctionProcedure,
1092+
Arguments([
1093+
target,
1094+
exceptionalReturn,
1095+
], types: node.arguments.types),
1096+
),
1097+
NullLiteral(),
1098+
],
1099+
types: [nativeFunctionType],
1100+
),
1101+
);
1102+
} else {
1103+
pointerValue = StaticInvocation(
1104+
createNativeCallableIsolateGroupSharedProcedure,
1105+
Arguments(
1106+
[
1107+
StaticInvocation(
1108+
nativeIsolateGroupSharedClosureFunctionProcedure,
1109+
Arguments([exceptionalReturn], types: node.arguments.types),
1110+
),
1111+
target,
1112+
],
1113+
types: [nativeFunctionType],
1114+
),
1115+
);
1116+
}
1117+
1118+
return ConstructorInvocation(
1119+
nativeCallablePrivateIsolateGroupSharedConstructor,
1120+
Arguments([pointerValue], types: node.arguments.types),
1121+
);
1122+
}
1123+
1124+
Expression _verifyAndReplaceNativeCallable(
10581125
StaticInvocation node, {
10591126
bool fromFunction = false,
1127+
required Expression Function(StaticInvocation, Expression, bool)
1128+
replacement,
10601129
}) {
10611130
final DartType nativeType = InterfaceType(
10621131
nativeFunctionClass,
@@ -1188,15 +1257,6 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
11881257
}
11891258
}
11901259

1191-
final replacement =
1192-
fromFunction
1193-
? _replaceFromFunction(node, exceptionalReturn)
1194-
: _replaceNativeCallableIsolateLocalConstructor(
1195-
node,
1196-
exceptionalReturn,
1197-
isStaticFunction,
1198-
);
1199-
12001260
final compoundClasses =
12011261
funcType.positionalParameters
12021262
.whereType<InterfaceType>()
@@ -1205,7 +1265,25 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
12051265
(c) => c.superclass == structClass || c.superclass == unionClass,
12061266
)
12071267
.toList();
1208-
return invokeCompoundConstructors(replacement, compoundClasses);
1268+
return invokeCompoundConstructors(
1269+
replacement(node, exceptionalReturn, isStaticFunction),
1270+
compoundClasses,
1271+
);
1272+
}
1273+
1274+
Expression _verifyAndReplaceNativeCallableIsolateLocal(
1275+
StaticInvocation node, {
1276+
bool fromFunction = false,
1277+
}) {
1278+
return _verifyAndReplaceNativeCallable(
1279+
node,
1280+
fromFunction: fromFunction,
1281+
replacement:
1282+
fromFunction
1283+
? (node, exceptionalReturn, _) =>
1284+
_replaceFromFunction(node, exceptionalReturn)
1285+
: _replaceNativeCallableIsolateLocalConstructor,
1286+
);
12091287
}
12101288

12111289
Expression _replaceGetRef(StaticInvocation node) {

pubspec.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ workspace:
7878
- pkg/wasm_builder
7979
- runtime/tools/profiling
8080
- samples/ffi/http
81+
- samples/ffi/httpIG
8182
# dap and language_server_protocol are checked in to and
8283
# developed in the SDK repo, though they are located in `third_party/`.
8384
- third_party/pkg/dap

runtime/bin/ffi_test/ffi_test_functions.cc

+6
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ DART_EXPORT Coord GetGlobalStruct() {
6666
return globalStruct;
6767
}
6868

69+
DART_EXPORT void SleepFor(int32_t ms) {
70+
std::cout << "Sleeping for " << ms << " milliseconds...\n";
71+
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
72+
std::cout << "done\n";
73+
}
74+
6975
// Sums two ints and adds 42.
7076
// Simple function to test trampolines.
7177
// Also used for testing argument exception on passing null instead of a Dart

runtime/lib/ffi.cc

+8
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ DEFINE_NATIVE_ENTRY(Ffi_createNativeCallableIsolateLocal, 1, 3) {
4646
zone, trampoline, target, keep_isolate_alive));
4747
}
4848

49+
DEFINE_NATIVE_ENTRY(Ffi_createNativeCallableIsolateGroupShared, 1, 2) {
50+
const auto& trampoline =
51+
Function::CheckedHandle(zone, arguments->NativeArg0());
52+
const auto& target = Closure::CheckedHandle(zone, arguments->NativeArgAt(1));
53+
return Pointer::New(
54+
isolate->CreateIsolateGroupSharedFfiCallback(zone, trampoline, target));
55+
}
56+
4957
DEFINE_NATIVE_ENTRY(Ffi_deleteNativeCallable, 1, 1) {
5058
const auto& pointer = Pointer::CheckedHandle(zone, arguments->NativeArg0());
5159
isolate->DeleteFfiCallback(pointer.NativeAddress());

runtime/vm/bootstrap_natives.h

+1
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ namespace dart {
300300
V(VMService_RemoveUserTagsFromStreamableSampleList, 1) \
301301
V(Ffi_createNativeCallableListener, 2) \
302302
V(Ffi_createNativeCallableIsolateLocal, 3) \
303+
V(Ffi_createNativeCallableIsolateGroupShared, 2) \
303304
V(Ffi_deleteNativeCallable, 1) \
304305
V(Ffi_updateNativeCallableKeepIsolateAliveCounter, 1) \
305306
V(Ffi_dl_open, 1) \

runtime/vm/bss_relocs.cc

+3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ void BSS::Initialize(Thread* current, uword* bss_start, bool vm) {
3535
InitializeBSSEntry(Relocation::DLRT_ExitTemporaryIsolate,
3636
reinterpret_cast<uword>(DLRT_ExitTemporaryIsolate),
3737
bss_start);
38+
InitializeBSSEntry(
39+
Relocation::DLRT_ExitIsolateGroupSharedIsolate,
40+
reinterpret_cast<uword>(DLRT_ExitIsolateGroupSharedIsolate), bss_start);
3841
}
3942

4043
} // namespace dart

runtime/vm/bss_relocs.h

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class BSS : public AllStatic {
1818
enum class Relocation : intptr_t {
1919
DLRT_GetFfiCallbackMetadata, // TODO(https://dartbug.com/52579): Remove.
2020
DLRT_ExitTemporaryIsolate, // TODO(https://dartbug.com/52579): Remove.
21+
DLRT_ExitIsolateGroupSharedIsolate, // TODO(https://dartbug.com/52579)
2122
EndOfVmEntries,
2223

2324
// We don't have any isolate group specific entries at the moment.

runtime/vm/compiler/ffi/callback.cc

+6
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ const String& NativeCallbackFunctionName(Thread* thread,
2828
return String::Handle(
2929
zone, Symbols::FromConcat(thread, Symbols::FfiCallback(),
3030
String::Handle(zone, dart_target.name())));
31+
case FfiCallbackKind::kIsolateGroupSharedClosureCallback:
32+
return Symbols::FfiIsolateGroupSharedCallback();
33+
case FfiCallbackKind::kIsolateGroupSharedStaticCallback:
34+
return String::Handle(
35+
zone, Symbols::FromConcat(thread, Symbols::FfiCallback(),
36+
String::Handle(zone, dart_target.name())));
3137
default:
3238
UNREACHABLE();
3339
}

runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc

+16-1
Original file line numberDiff line numberDiff line change
@@ -3390,6 +3390,12 @@ Fragment StreamingFlowGraphBuilder::BuildStaticInvocation(TokenPosition* p) {
33903390
case MethodRecognizer::kFfiNativeIsolateLocalCallbackFunction:
33913391
return BuildFfiNativeCallbackFunction(
33923392
FfiCallbackKind::kIsolateLocalClosureCallback);
3393+
case MethodRecognizer::kFfiNativeIsolateGroupSharedCallbackFunction:
3394+
return BuildFfiNativeCallbackFunction(
3395+
FfiCallbackKind::kIsolateGroupSharedStaticCallback);
3396+
case MethodRecognizer::kFfiNativeIsolateGroupSharedClosureFunction:
3397+
return BuildFfiNativeCallbackFunction(
3398+
FfiCallbackKind::kIsolateGroupSharedClosureCallback);
33933399
case MethodRecognizer::kFfiNativeAsyncCallbackFunction:
33943400
return BuildFfiNativeCallbackFunction(FfiCallbackKind::kAsyncCallback);
33953401
case MethodRecognizer::kFfiLoadAbiSpecificInt:
@@ -6210,16 +6216,25 @@ Fragment StreamingFlowGraphBuilder::BuildFfiNativeCallbackFunction(
62106216
// FfiCallbackKind::kIsolateLocalStaticCallback:
62116217
// _nativeCallbackFunction<NativeSignatureType>(target, exceptionalReturn)
62126218
//
6219+
// FfiCallbackKind::kIsolateGroupSharedStaticCallback:
6220+
// _nativeCallbackFunction<NativeSignatureType>(target, exceptionalReturn)
6221+
//
62136222
// FfiCallbackKind::kAsyncCallback:
62146223
// _nativeAsyncCallbackFunction<NativeSignatureType>()
62156224
//
62166225
// FfiCallbackKind::kIsolateLocalClosureCallback:
62176226
// _nativeIsolateLocalCallbackFunction<NativeSignatureType>(
62186227
// exceptionalReturn)
62196228
//
6229+
// FfiCallbackKind::kIsolateGroupSharedClosureCallback:
6230+
// _nativeIsolateGroupSharedCallbackFunction<NativeSignatureType>(
6231+
// exceptionalReturn)
6232+
//
62206233
// The FE also guarantees that the arguments are constants.
62216234

6222-
const bool has_target = kind == FfiCallbackKind::kIsolateLocalStaticCallback;
6235+
const bool has_target =
6236+
kind == FfiCallbackKind::kIsolateLocalStaticCallback ||
6237+
kind == FfiCallbackKind::kIsolateGroupSharedStaticCallback;
62236238
const bool has_exceptional_return = kind != FfiCallbackKind::kAsyncCallback;
62246239
const intptr_t expected_argc =
62256240
static_cast<int>(has_target) + static_cast<int>(has_exceptional_return);

0 commit comments

Comments
 (0)