[vm/compiler] Forward the ByteData constructor length argument.
In addition, if a _ByteDataView came from a use of the ByteData
constructor, its offset is always 0.
Also add appropriate canonicalization for the following instructions for
typed data views coming from a known factory call:
* LoadField getting type arguments
* GuardFieldLength
This closes https://github.com/dart-lang/sdk/issues/36570.
Change-Id: I1c045edb2d928c3bb3340d9d12009c2afa66febb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/102362
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Commit-Queue: Teagan Strickland <sstrickl@google.com>
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 7edc129..c554d5a 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -2778,6 +2778,11 @@
if (call->is_known_list_constructor() &&
IsFixedLengthArrayCid(call->Type()->ToCid())) {
return call->ArgumentAt(1);
+ } else if (call->function().recognized_kind() ==
+ MethodRecognizer::kByteDataFactory) {
+ // Similarly, we check for the ByteData constructor and forward its
+ // explicit length argument appropriately.
+ return call->ArgumentAt(1);
} else if (IsTypedDataViewFactory(call->function())) {
// Typed data view factories all take three arguments (after
// the implicit type arguments parameter):
@@ -2820,6 +2825,11 @@
if (StaticCallInstr* call = array->AsStaticCall()) {
if (IsTypedDataViewFactory(call->function())) {
return call->ArgumentAt(2);
+ } else if (call->function().recognized_kind() ==
+ MethodRecognizer::kByteDataFactory) {
+ // A _ByteDataView returned from the ByteData constructor always
+ // has an offset of 0.
+ return flow_graph->GetConstant(Smi::Handle(Smi::New(0)));
}
}
} else if (slot().IsTypeArguments()) {
@@ -2827,10 +2837,16 @@
if (StaticCallInstr* call = array->AsStaticCall()) {
if (call->is_known_list_constructor()) {
return call->ArgumentAt(0);
- } else if (call->function().recognized_kind() ==
- MethodRecognizer::kLinkedHashMap_getData) {
+ } else if (IsTypedDataViewFactory(call->function())) {
return flow_graph->constant_null();
}
+ switch (call->function().recognized_kind()) {
+ case MethodRecognizer::kByteDataFactory:
+ case MethodRecognizer::kLinkedHashMap_getData:
+ return flow_graph->constant_null();
+ default:
+ break;
+ }
} else if (CreateArrayInstr* create_array = array->AsCreateArray()) {
return create_array->element_type()->definition();
} else if (LoadFieldInstr* load_array = array->AsLoadField()) {
@@ -3573,6 +3589,11 @@
if (call->is_known_list_constructor() &&
LoadFieldInstr::IsFixedLengthArrayCid(call->Type()->ToCid())) {
length = call->ArgumentAt(1)->AsConstant();
+ } else if (call->function().recognized_kind() ==
+ MethodRecognizer::kByteDataFactory) {
+ length = call->ArgumentAt(1)->AsConstant();
+ } else if (LoadFieldInstr::IsTypedDataViewFactory(call->function())) {
+ length = call->ArgumentAt(3)->AsConstant();
}
if ((length != NULL) && length->value().IsSmi() &&
Smi::Cast(length->value()).Value() == expected_length) {
diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h
index 6fc48f4..ffd7255 100644
--- a/runtime/vm/compiler/recognized_methods_list.h
+++ b/runtime/vm/compiler/recognized_methods_list.h
@@ -42,6 +42,7 @@
V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 0x38a80b0d) \
V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 0x40052c4e) \
V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 0x07b89f54) \
+ V(ByteData, ., ByteDataFactory, 0x0) \
V(_ByteDataView, get:offsetInBytes, ByteDataViewOffsetInBytes, 0x0) \
V(_ByteDataView, get:_typedData, ByteDataViewTypedData, 0x0) \
V(_TypedListView, get:offsetInBytes, TypedDataViewOffsetInBytes, 0x0) \