Skip to content

Commit

Permalink
[vm/compiler] Avoid speculative conversion in ffi Pointer.asTypedList
Browse files Browse the repository at this point in the history
On 32-bit ARM in AOT mode Pointer.asTypedList is generated so that
there is a LoadField from Pointer.data_field which has kUnboxedFfiIntPtr
representation (uint32) and then the value is passed to a
StoreInstanceField for TypedDataBase.data_field which has kUnboxedIntPtr
representation (int32). As a result, a speculative uint32->int32
IntConverter instruction is inserted by SelectRepresentations pass.
AOT doesn't support deoptimization so code generation crashes after
retrying without speculative inlining.

This change fixes the type incompatibility by loading value with
LoadUntagged and then converting it with ConvertUntaggedToUnboxed(kUnboxedIntPtr).

TEST=ffi/regress_flutter97301_test
Fixes flutter/flutter#97301

Change-Id: I4a00d4ac7978b4775add0ddae510841a2b4cbae0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/230956
Reviewed-by: Daco Harkes <[email protected]>
Reviewed-by: Martin Kustermann <[email protected]>
Commit-Queue: Alexander Markov <[email protected]>
  • Loading branch information
alexmarkov authored and Commit Bot committed Feb 1, 2022
1 parent 4104427 commit e4942db
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 1 deletion.
3 changes: 2 additions & 1 deletion runtime/vm/compiler/frontend/kernel_to_il.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1582,7 +1582,8 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfRecognizedMethod(
// Initialize the result's data pointer field.
body += LoadLocal(typed_data_object);
body += LoadLocal(arg_pointer);
body += LoadNativeField(Slot::Pointer_data_field());
body += LoadUntagged(compiler::target::Pointer::data_field_offset());
body += ConvertUntaggedToUnboxed(kUnboxedIntPtr);
body += StoreNativeField(Slot::TypedDataBase_data_field(),
StoreInstanceFieldInstr::Kind::kInitializing,
kNoStoreBarrier);
Expand Down
21 changes: 21 additions & 0 deletions tests/ffi/regress_flutter97301_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) 2022, 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.
//
// Verifies that there are no deoptimizing IntConverter instructions
// used when converting Pointer to TypedData.
// Regression test for https://github.com/flutter/flutter/issues/97301.

import "dart:ffi";
import "package:ffi/ffi.dart";

@pragma("vm:never-inline")
Pointer<Uint32> foo() => calloc(4);

main() {
final Pointer<Uint32> offsetsPtr = foo();

for (var i = 0; i < 2; i++) {
print(offsetsPtr.asTypedList(1));
}
}
23 changes: 23 additions & 0 deletions tests/ffi_2/regress_flutter97301_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) 2022, 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.
//
// Verifies that there are no deoptimizing IntConverter instructions
// used when converting Pointer to TypedData.
// Regression test for https://github.com/flutter/flutter/issues/97301.

// @dart = 2.9

import "dart:ffi";
import "package:ffi/ffi.dart";

@pragma("vm:never-inline")
Pointer<Uint32> foo() => calloc(4);

main() {
final Pointer<Uint32> offsetsPtr = foo();

for (var i = 0; i < 2; i++) {
print(offsetsPtr.asTypedList(1));
}
}

0 comments on commit e4942db

Please sign in to comment.