@@ -1215,15 +1215,17 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfRecognizedMethod(
1215
1215
LocalVariable* arg_pointer = parsed_function_->RawParameterVariable (0 );
1216
1216
LocalVariable* arg_offset = parsed_function_->RawParameterVariable (1 );
1217
1217
1218
- body += LoadLocal (arg_pointer );
1218
+ body += LoadLocal (arg_offset );
1219
1219
body += CheckNullOptimized (TokenPosition::kNoSource ,
1220
1220
String::ZoneHandle (Z, function.name ()));
1221
- body += LoadNativeField (Slot::Pointer_c_memory_address ());
1222
- body += UnboxTruncate (kUnboxedFfiIntPtr );
1223
- body += ConvertUnboxedToUntagged (kUnboxedFfiIntPtr );
1224
- body += LoadLocal (arg_offset);
1221
+ LocalVariable* arg_offset_not_null = MakeTemporary ();
1222
+
1223
+ body += LoadLocal (arg_pointer);
1225
1224
body += CheckNullOptimized (TokenPosition::kNoSource ,
1226
1225
String::ZoneHandle (Z, function.name ()));
1226
+ // No GC from here til LoadIndexed.
1227
+ body += LoadUntagged (compiler::target::Pointer::data_offset ());
1228
+ body += LoadLocal (arg_offset_not_null);
1227
1229
body += UnboxTruncate (kUnboxedFfiIntPtr );
1228
1230
body += LoadIndexedTypedData (typed_data_cid, /* index_scale=*/ 1 ,
1229
1231
/* index_unboxed=*/ true );
@@ -1263,11 +1265,13 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfRecognizedMethod(
1263
1265
LocalVariable* pointer = MakeTemporary ();
1264
1266
body += LoadLocal (pointer);
1265
1267
body += LoadLocal (address);
1266
- body += StoreInstanceField (TokenPosition::kNoSource ,
1267
- Slot::Pointer_c_memory_address ());
1268
+ body += UnboxTruncate (kUnboxedFfiIntPtr );
1269
+ body += ConvertUnboxedToUntagged (kUnboxedFfiIntPtr );
1270
+ body += StoreUntagged (compiler::target::Pointer::data_offset ());
1268
1271
body += DropTempsPreserveTop (1 ); // Drop [address] keep [pointer].
1269
1272
}
1270
1273
}
1274
+ body += DropTempsPreserveTop (1 ); // Drop [arg_offset].
1271
1275
} break ;
1272
1276
case MethodRecognizer::kFfiStoreInt8 :
1273
1277
case MethodRecognizer::kFfiStoreInt16 :
@@ -1327,21 +1331,27 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfRecognizedMethod(
1327
1331
}
1328
1332
1329
1333
ASSERT (function.NumParameters () == 3 );
1330
- body += LoadLocal (arg_pointer); // Pointer.
1334
+ body += LoadLocal (arg_offset);
1331
1335
body += CheckNullOptimized (TokenPosition::kNoSource ,
1332
1336
String::ZoneHandle (Z, function.name ()));
1333
- body += LoadNativeField (Slot::Pointer_c_memory_address ());
1334
- body += UnboxTruncate (kUnboxedFfiIntPtr );
1335
- body += ConvertUnboxedToUntagged (kUnboxedFfiIntPtr );
1336
- body += LoadLocal (arg_offset); // Offset.
1337
+ LocalVariable* arg_offset_not_null = MakeTemporary ();
1338
+ body += LoadLocal (arg_value);
1337
1339
body += CheckNullOptimized (TokenPosition::kNoSource ,
1338
1340
String::ZoneHandle (Z, function.name ()));
1339
- body += UnboxTruncate (kUnboxedFfiIntPtr );
1340
- body += LoadLocal (arg_value); // Value.
1341
+ LocalVariable* arg_value_not_null = MakeTemporary ();
1342
+
1343
+ body += LoadLocal (arg_pointer); // Pointer.
1341
1344
body += CheckNullOptimized (TokenPosition::kNoSource ,
1342
1345
String::ZoneHandle (Z, function.name ()));
1346
+ // No GC from here til StoreIndexed.
1347
+ body += LoadUntagged (compiler::target::Pointer::data_offset ());
1348
+ body += LoadLocal (arg_offset_not_null);
1349
+ body += UnboxTruncate (kUnboxedFfiIntPtr );
1350
+ body += LoadLocal (arg_value_not_null);
1343
1351
if (kind == MethodRecognizer::kFfiStorePointer ) {
1344
- body += LoadNativeField (Slot::Pointer_c_memory_address ());
1352
+ // This can only be Pointer, so it is always safe to LoadUntagged.
1353
+ body += LoadUntagged (compiler::target::Pointer::data_offset ());
1354
+ body += ConvertUntaggedToUnboxed (kUnboxedFfiIntPtr );
1345
1355
} else if (kind == MethodRecognizer::kFfiStoreFloat ||
1346
1356
kind == MethodRecognizer::kFfiStoreDouble ) {
1347
1357
body += UnboxTruncate (kUnboxedDouble );
@@ -1353,6 +1363,8 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfRecognizedMethod(
1353
1363
}
1354
1364
body += StoreIndexedTypedData (typed_data_cid, /* index_scale=*/ 1 ,
1355
1365
/* index_unboxed=*/ true );
1366
+ body += Drop (); // Drop [arg_value].
1367
+ body += Drop (); // Drop [arg_offset].
1356
1368
body += NullConstant ();
1357
1369
} break ;
1358
1370
case MethodRecognizer::kFfiFromAddress : {
@@ -1369,21 +1381,19 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfRecognizedMethod(
1369
1381
body += LoadLocal (parsed_function_->RawParameterVariable (0 )); // Address.
1370
1382
body += CheckNullOptimized (TokenPosition::kNoSource ,
1371
1383
String::ZoneHandle (Z, function.name ()));
1372
- #if defined(TARGET_ARCH_IS_32_BIT)
1373
- // Truncate to 32 bits on 32 bit architecture.
1374
1384
body += UnboxTruncate (kUnboxedFfiIntPtr );
1375
- body += Box (kUnboxedFfiIntPtr );
1376
- #endif // defined(TARGET_ARCH_IS_32_BIT)
1377
- body += StoreInstanceField (TokenPosition::kNoSource ,
1378
- Slot::Pointer_c_memory_address (),
1379
- StoreInstanceFieldInstr::Kind::kInitializing );
1385
+ body += ConvertUnboxedToUntagged (kUnboxedFfiIntPtr );
1386
+ body += StoreUntagged (compiler::target::Pointer::data_offset ());
1380
1387
} break ;
1381
1388
case MethodRecognizer::kFfiGetAddress : {
1382
1389
ASSERT (function.NumParameters () == 1 );
1383
1390
body += LoadLocal (parsed_function_->RawParameterVariable (0 )); // Pointer.
1384
1391
body += CheckNullOptimized (TokenPosition::kNoSource ,
1385
1392
String::ZoneHandle (Z, function.name ()));
1386
- body += LoadNativeField (Slot::Pointer_c_memory_address ());
1393
+ // This can only be Pointer, so it is always safe to LoadUntagged.
1394
+ body += LoadUntagged (compiler::target::Pointer::data_offset ());
1395
+ body += ConvertUntaggedToUnboxed (kUnboxedFfiIntPtr );
1396
+ body += Box (kUnboxedFfiIntPtr );
1387
1397
} break ;
1388
1398
default : {
1389
1399
UNREACHABLE ();
@@ -2752,12 +2762,6 @@ Fragment FlowGraphBuilder::UnboxTruncate(Representation to) {
2752
2762
return Fragment (unbox);
2753
2763
}
2754
2764
2755
- Fragment FlowGraphBuilder::Box (Representation from) {
2756
- BoxInstr* box = BoxInstr::Create (from, Pop ());
2757
- Push (box);
2758
- return Fragment (box);
2759
- }
2760
-
2761
2765
Fragment FlowGraphBuilder::NativeReturn (
2762
2766
const compiler::ffi::CallbackMarshaller& marshaller) {
2763
2767
auto * instr = new (Z) NativeReturnInstr (TokenPosition::kNoSource , Pop (),
@@ -2787,9 +2791,9 @@ Fragment FlowGraphBuilder::FfiPointerFromAddress(const Type& result_type) {
2787
2791
LocalVariable* pointer = MakeTemporary ();
2788
2792
code += LoadLocal (pointer);
2789
2793
code += LoadLocal (address);
2790
- code += StoreInstanceField (TokenPosition:: kNoSource ,
2791
- Slot::Pointer_c_memory_address (),
2792
- StoreInstanceFieldInstr::Kind:: kInitializing );
2794
+ code += UnboxTruncate ( kUnboxedFfiIntPtr );
2795
+ code += ConvertUnboxedToUntagged ( kUnboxedFfiIntPtr );
2796
+ code += StoreUntagged ( compiler::target::Pointer::data_offset () );
2793
2797
code += StoreLocal (TokenPosition::kNoSource , result);
2794
2798
code += Drop (); // StoreLocal^
2795
2799
code += Drop (); // address
@@ -2837,11 +2841,13 @@ Fragment FlowGraphBuilder::FfiConvertArgumentToNative(
2837
2841
String::ZoneHandle (Z, marshaller.function_name ()));
2838
2842
2839
2843
if (marshaller.IsPointer (arg_index)) {
2840
- body += LoadNativeField (Slot::Pointer_c_memory_address ());
2844
+ // This can only be Pointer, so it is always safe to LoadUntagged.
2845
+ body += LoadUntagged (compiler::target::Pointer::data_offset ());
2846
+ body += ConvertUntaggedToUnboxed (kUnboxedFfiIntPtr );
2847
+ } else {
2848
+ body += UnboxTruncate (marshaller.RepInDart (arg_index));
2841
2849
}
2842
2850
2843
- body += UnboxTruncate (marshaller.RepInDart (arg_index));
2844
-
2845
2851
if (marshaller.RequiresBitCast (arg_index)) {
2846
2852
body += BitCast (marshaller.RepInDart (arg_index),
2847
2853
marshaller.RepInFfiCall (arg_index));
@@ -2885,15 +2891,18 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfFfiNative(const Function& function) {
2885
2891
body += FfiConvertArgumentToNative (marshaller, i);
2886
2892
}
2887
2893
2888
- // Push the function pointer, which is stored (boxed) in the first slot of the
2889
- // context.
2894
+ // Push the function pointer, which is stored (as Pointer object) in the
2895
+ // first slot of the context.
2890
2896
body += LoadLocal (parsed_function_->ParameterVariable (0 ));
2891
2897
body += LoadNativeField (Slot::Closure_context ());
2892
2898
body += LoadNativeField (Slot::GetContextVariableSlotFor (
2893
2899
thread_, *MakeImplicitClosureScope (
2894
2900
Z, Class::Handle (I->object_store ()->ffi_pointer_class ()))
2895
2901
->context_variables ()[0 ]));
2896
- body += UnboxTruncate (kUnboxedFfiIntPtr );
2902
+
2903
+ // This can only be Pointer, so it is always safe to LoadUntagged.
2904
+ body += LoadUntagged (compiler::target::Pointer::data_offset ());
2905
+ body += ConvertUntaggedToUnboxed (kUnboxedFfiIntPtr );
2897
2906
body += FfiCall (marshaller);
2898
2907
2899
2908
body += FfiConvertArgumentToDart (marshaller, compiler::ffi::kResultIndex );
0 commit comments