Skip to content

Commit b496066

Browse files
committed
[vm/ffi] Use LoadNativeField for FFI pointers
This allows the VM to elide FFI Pointer allocations during pointer arithmetic. Bug: dart-lang#42793
1 parent 214a98e commit b496066

File tree

3 files changed

+28
-24
lines changed

3 files changed

+28
-24
lines changed

runtime/vm/compiler/backend/inliner.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -969,15 +969,17 @@ static void ReplaceParameterStubs(Zone* zone,
969969
for (intptr_t i = 0; i < defns->length(); ++i) {
970970
ConstantInstr* constant = (*defns)[i]->AsConstant();
971971
if (constant != nullptr && constant->HasUses()) {
972-
constant->ReplaceUsesWith(caller_graph->GetConstant(constant->value()));
972+
constant->ReplaceUsesWith(caller_graph->GetConstant(
973+
constant->value(), constant->representation()));
973974
}
974975
}
975976

976977
defns = callee_graph->graph_entry()->normal_entry()->initial_definitions();
977978
for (intptr_t i = 0; i < defns->length(); ++i) {
978979
ConstantInstr* constant = (*defns)[i]->AsConstant();
979980
if (constant != nullptr && constant->HasUses()) {
980-
constant->ReplaceUsesWith(caller_graph->GetConstant(constant->value()));
981+
constant->ReplaceUsesWith(caller_graph->GetConstant(
982+
constant->value(), constant->representation()));
981983
}
982984

983985
SpecialParameterInstr* param = (*defns)[i]->AsSpecialParameter();

runtime/vm/compiler/backend/redundancy_elimination.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2187,6 +2187,12 @@ class LoadOptimizer : public ValueObject {
21872187
if (auto* const load = use->instruction()->AsLoadField()) {
21882188
place_id = GetPlaceId(load);
21892189
slot = &load->slot();
2190+
if (alloc->IsAllocateTypedData() &&
2191+
slot == &Slot::PointerBase_data()) {
2192+
// Typed data payload elements are unboxed and initialized to
2193+
// zero, so don't forward a tagged null value.
2194+
continue;
2195+
}
21902196
} else if (auto* const store = use->instruction()->AsStoreField()) {
21912197
ASSERT(!alloc->IsArrayAllocation());
21922198
place_id = GetPlaceId(store);

runtime/vm/compiler/frontend/kernel_to_il.cc

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,7 +1305,8 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfRecognizedMethod(
13051305
body += LoadLocal(arg_pointer);
13061306
body += CheckNullOptimized(String::ZoneHandle(Z, function.name()));
13071307
// No GC from here til LoadIndexed.
1308-
body += LoadUntagged(compiler::target::PointerBase::data_offset());
1308+
body += LoadNativeField(Slot::PointerBase_data());
1309+
body += ConvertUnboxedToUntagged(kUnboxedIntPtr);
13091310
body += LoadLocal(arg_offset_not_null);
13101311
body += UnboxTruncate(kUnboxedFfiIntPtr);
13111312
body += LoadIndexed(typed_data_cid, /*index_scale=*/1,
@@ -1373,14 +1374,13 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfRecognizedMethod(
13731374
body += LoadLocal(arg_pointer); // Pointer.
13741375
body += CheckNullOptimized(String::ZoneHandle(Z, function.name()));
13751376
// No GC from here til StoreIndexed.
1376-
body += LoadUntagged(compiler::target::PointerBase::data_offset());
1377+
body += LoadNativeField(Slot::PointerBase_data());
1378+
body += ConvertUnboxedToUntagged(kUnboxedIntPtr);
13771379
body += LoadLocal(arg_offset_not_null);
13781380
body += UnboxTruncate(kUnboxedFfiIntPtr);
13791381
body += LoadLocal(arg_value_not_null);
13801382
if (kind == MethodRecognizer::kFfiStorePointer) {
1381-
// This can only be Pointer, so it is always safe to LoadUntagged.
1382-
body += LoadUntagged(compiler::target::PointerBase::data_offset());
1383-
body += ConvertUntaggedToUnboxed(kUnboxedFfiIntPtr);
1383+
body += LoadNativeField(Slot::PointerBase_data());
13841384
} else {
13851385
// Avoid any unnecessary (and potentially deoptimizing) int
13861386
// conversions by using the representation consumed by StoreIndexed.
@@ -1417,9 +1417,7 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfRecognizedMethod(
14171417
ASSERT_EQUAL(function.NumParameters(), 1);
14181418
body += LoadLocal(parsed_function_->RawParameterVariable(0)); // Pointer.
14191419
body += CheckNullOptimized(String::ZoneHandle(Z, function.name()));
1420-
// This can only be Pointer, so it is always safe to LoadUntagged.
1421-
body += LoadUntagged(compiler::target::PointerBase::data_offset());
1422-
body += ConvertUntaggedToUnboxed(kUnboxedFfiIntPtr);
1420+
body += LoadNativeField(Slot::PointerBase_data());
14231421
body += Box(kUnboxedFfiIntPtr);
14241422
} break;
14251423
case MethodRecognizer::kHas63BitSmis: {
@@ -1501,8 +1499,7 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfRecognizedMethod(
15011499
// Initialize the result's data pointer field.
15021500
body += LoadLocal(typed_data_object);
15031501
body += LoadLocal(arg_pointer);
1504-
body += LoadUntagged(compiler::target::PointerBase::data_offset());
1505-
body += ConvertUntaggedToUnboxed(kUnboxedIntPtr);
1502+
body += LoadNativeField(Slot::PointerBase_data());
15061503
body += StoreNativeField(Slot::PointerBase_data(),
15071504
StoreFieldInstr::Kind::kInitializing,
15081505
kNoStoreBarrier);
@@ -1716,8 +1713,7 @@ Fragment FlowGraphBuilder::BuildTypedDataViewFactoryConstructor(
17161713
// instructions!
17171714
body += LoadLocal(view_object);
17181715
body += LoadLocal(typed_data);
1719-
body += LoadUntagged(compiler::target::PointerBase::data_offset());
1720-
body += ConvertUntaggedToUnboxed(kUnboxedIntPtr);
1716+
body += LoadNativeField(Slot::PointerBase_data());
17211717
body += LoadLocal(offset_in_bytes);
17221718
body += UnboxSmiToIntptr();
17231719
body += AddIntptrIntegers();
@@ -4401,7 +4397,8 @@ Fragment FlowGraphBuilder::CopyFromCompoundToStack(
44014397
for (intptr_t i = 0; i < num_defs; i++) {
44024398
body += LoadLocal(variable);
44034399
body += LoadTypedDataBaseFromCompound();
4404-
body += LoadUntagged(compiler::target::PointerBase::data_offset());
4400+
body += LoadNativeField(Slot::PointerBase_data());
4401+
body += ConvertUnboxedToUntagged(kUnboxedIntPtr);
44054402
body += IntConstant(offset_in_bytes);
44064403
const Representation representation = representations[i];
44074404
offset_in_bytes += RepresentationUtils::ValueSize(representation);
@@ -4423,7 +4420,8 @@ Fragment FlowGraphBuilder::PopFromStackToTypedDataBase(
44234420
for (intptr_t i = 0; i < num_defs; i++) {
44244421
const Representation representation = representations[i];
44254422
body += LoadLocal(uint8_list);
4426-
body += LoadUntagged(compiler::target::PointerBase::data_offset());
4423+
body += LoadNativeField(Slot::PointerBase_data());
4424+
body += ConvertUnboxedToUntagged(kUnboxedIntPtr);
44274425
body += IntConstant(offset_in_bytes);
44284426
body += LoadLocal(definitions->At(i));
44294427
body += StoreIndexedTypedDataUnboxed(representation, /*index_scale=*/1,
@@ -4477,7 +4475,8 @@ Fragment FlowGraphBuilder::CopyFromTypedDataBaseToUnboxedAddress(
44774475
const classid_t typed_data_cidd = typed_data_cid(chunk_sizee);
44784476

44794477
body += LoadLocal(typed_data_base);
4480-
body += LoadUntagged(compiler::target::PointerBase::data_offset());
4478+
body += LoadNativeField(Slot::PointerBase_data());
4479+
body += ConvertUnboxedToUntagged(kUnboxedIntPtr);
44814480
body += IntConstant(offset_in_bytes);
44824481
body += LoadIndexed(typed_data_cidd, /*index_scale=*/1,
44834482
/*index_unboxed=*/false);
@@ -4522,7 +4521,8 @@ Fragment FlowGraphBuilder::CopyFromUnboxedAddressToTypedDataBase(
45224521
LocalVariable* chunk_value = MakeTemporary("chunk_value");
45234522

45244523
body += LoadLocal(typed_data_base);
4525-
body += LoadUntagged(compiler::target::PointerBase::data_offset());
4524+
body += LoadNativeField(Slot::PointerBase_data());
4525+
body += ConvertUnboxedToUntagged(kUnboxedIntPtr);
45264526
body += IntConstant(offset_in_bytes);
45274527
body += LoadLocal(chunk_value);
45284528
body += StoreIndexedTypedData(typed_data_cidd, /*index_scale=*/1,
@@ -4678,9 +4678,7 @@ Fragment FlowGraphBuilder::FfiConvertPrimitiveToNative(
46784678

46794679
Fragment body;
46804680
if (marshaller.IsPointer(arg_index)) {
4681-
// This can only be Pointer, so it is always safe to LoadUntagged.
4682-
body += LoadUntagged(compiler::target::PointerBase::data_offset());
4683-
body += ConvertUntaggedToUnboxed(kUnboxedFfiIntPtr);
4681+
body += LoadNativeField(Slot::PointerBase_data());
46844682
} else if (marshaller.IsHandle(arg_index)) {
46854683
body += WrapHandle();
46864684
} else {
@@ -4816,9 +4814,7 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfFfiNative(const Function& function) {
48164814
Z, Class::Handle(IG->object_store()->ffi_pointer_class()))
48174815
->context_variables()[0]));
48184816

4819-
// This can only be Pointer, so it is always safe to LoadUntagged.
4820-
body += LoadUntagged(compiler::target::PointerBase::data_offset());
4821-
body += ConvertUntaggedToUnboxed(kUnboxedFfiIntPtr);
4817+
body += LoadNativeField(Slot::PointerBase_data());
48224818

48234819
if (marshaller.PassTypedData()) {
48244820
body += LoadLocal(typed_data);

0 commit comments

Comments
 (0)