Skip to content

Commit dc70785

Browse files
alexmarkovsortie
authored andcommitted
[vm/compiler] Avoid speculative conversion in ffi Pointer.asTypedList
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]>
1 parent 547d54e commit dc70785

File tree

3 files changed

+46
-1
lines changed

3 files changed

+46
-1
lines changed

runtime/vm/compiler/frontend/kernel_to_il.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1585,7 +1585,8 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfRecognizedMethod(
15851585
// Initialize the result's data pointer field.
15861586
body += LoadLocal(typed_data_object);
15871587
body += LoadLocal(arg_pointer);
1588-
body += LoadNativeField(Slot::Pointer_data_field());
1588+
body += LoadUntagged(compiler::target::Pointer::data_field_offset());
1589+
body += ConvertUntaggedToUnboxed(kUnboxedIntPtr);
15891590
body += StoreNativeField(Slot::TypedDataBase_data_field(),
15901591
StoreInstanceFieldInstr::Kind::kInitializing,
15911592
kNoStoreBarrier);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
//
5+
// Verifies that there are no deoptimizing IntConverter instructions
6+
// used when converting Pointer to TypedData.
7+
// Regression test for https://github.com/flutter/flutter/issues/97301.
8+
9+
import "dart:ffi";
10+
import "package:ffi/ffi.dart";
11+
12+
@pragma("vm:never-inline")
13+
Pointer<Uint32> foo() => calloc(4);
14+
15+
main() {
16+
final Pointer<Uint32> offsetsPtr = foo();
17+
18+
for (var i = 0; i < 2; i++) {
19+
print(offsetsPtr.asTypedList(1));
20+
}
21+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
//
5+
// Verifies that there are no deoptimizing IntConverter instructions
6+
// used when converting Pointer to TypedData.
7+
// Regression test for https://github.com/flutter/flutter/issues/97301.
8+
9+
// @dart = 2.9
10+
11+
import "dart:ffi";
12+
import "package:ffi/ffi.dart";
13+
14+
@pragma("vm:never-inline")
15+
Pointer<Uint32> foo() => calloc(4);
16+
17+
main() {
18+
final Pointer<Uint32> offsetsPtr = foo();
19+
20+
for (var i = 0; i < 2; i++) {
21+
print(offsetsPtr.asTypedList(1));
22+
}
23+
}

0 commit comments

Comments
 (0)