From cbd43917477000213785dc1ce1f43b51dd23eb29 Mon Sep 17 00:00:00 2001 From: Stevie Strickland Date: Thu, 23 May 2019 13:19:46 +0000 Subject: [PATCH] [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 Commit-Queue: Teagan Strickland --- runtime/vm/compiler/backend/il.cc | 25 +++++++++++++++++-- runtime/vm/compiler/recognized_methods_list.h | 1 + 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc index 7edc129d2df..c554d5ab319 100644 --- a/runtime/vm/compiler/backend/il.cc +++ b/runtime/vm/compiler/backend/il.cc @@ -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) { diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h index 6fc48f4c68a..ffd72557149 100644 --- a/runtime/vm/compiler/recognized_methods_list.h +++ b/runtime/vm/compiler/recognized_methods_list.h @@ -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) \