[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>
This commit is contained in:
Stevie Strickland 2019-05-23 13:19:46 +00:00 committed by commit-bot@chromium.org
parent 1993669102
commit cbd4391747
2 changed files with 24 additions and 2 deletions

View file

@ -2778,6 +2778,11 @@ Definition* LoadFieldInstr::Canonicalize(FlowGraph* flow_graph) {
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 @@ Definition* LoadFieldInstr::Canonicalize(FlowGraph* flow_graph) {
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 @@ Definition* LoadFieldInstr::Canonicalize(FlowGraph* flow_graph) {
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 @@ Instruction* GuardFieldLengthInstr::Canonicalize(FlowGraph* flow_graph) {
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) {

View file

@ -42,6 +42,7 @@ namespace dart {
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) \