| Index: src/compiler/access-info.cc
|
| diff --git a/src/compiler/access-info.cc b/src/compiler/access-info.cc
|
| index bbbf726773d052e0e77ce2716baebca2b871deb1..3862d86421bd8c622b939ddb1fe1e1a4e1391a6b 100644
|
| --- a/src/compiler/access-info.cc
|
| +++ b/src/compiler/access-info.cc
|
| @@ -206,16 +206,20 @@ bool AccessInfoFactory::ComputeElementAccessInfo(
|
| bool AccessInfoFactory::ComputeElementAccessInfos(
|
| MapHandleList const& maps, AccessMode access_mode,
|
| ZoneVector<ElementAccessInfo>* access_infos) {
|
| - if (access_mode == AccessMode::kLoad) {
|
| - // For polymorphic loads of similar elements kinds (i.e. all tagged or all
|
| - // double), always use the "worst case" code without a transition. This is
|
| - // much faster than transitioning the elements to the worst case, trading a
|
| - // TransitionElementsKind for a CheckMaps, avoiding mutation of the array.
|
| - ElementAccessInfo access_info;
|
| - if (ConsolidateElementLoad(maps, &access_info)) {
|
| - access_infos->push_back(access_info);
|
| - return true;
|
| - }
|
| + // For polymorphic loads of similar elements kinds (i.e. all tagged or all
|
| + // double), always use the "worst case" code without a transition. This is
|
| + // much faster than transitioning the elements to the worst case, trading a
|
| + // TransitionElementsKind for a CheckMaps, avoiding mutation of the array.
|
| + //
|
| + // Similarly, for polymorphic stores of compatible elements kind that
|
| + // differ only in holeyness, always use the "holey case" code without a
|
| + // transition. This is beneficial, because CheckMaps can often be optimized
|
| + // whereas TransitionElementsKind can block optimizations. And as above, we
|
| + // avoid mutation of the array (we still mutate the array contents).
|
| + ElementAccessInfo access_info;
|
| + if (ConsolidateElementAccess(maps, access_mode, &access_info)) {
|
| + access_infos->push_back(access_info);
|
| + return true;
|
| }
|
|
|
| // Collect possible transition targets.
|
| @@ -475,32 +479,9 @@ bool AccessInfoFactory::ComputePropertyAccessInfos(
|
| return true;
|
| }
|
|
|
| -namespace {
|
| -
|
| -Maybe<ElementsKind> GeneralizeElementsKind(ElementsKind this_kind,
|
| - ElementsKind that_kind) {
|
| - if (IsHoleyElementsKind(this_kind)) {
|
| - that_kind = GetHoleyElementsKind(that_kind);
|
| - } else if (IsHoleyElementsKind(that_kind)) {
|
| - this_kind = GetHoleyElementsKind(this_kind);
|
| - }
|
| - if (this_kind == that_kind) return Just(this_kind);
|
| - if (IsFastDoubleElementsKind(that_kind) ==
|
| - IsFastDoubleElementsKind(this_kind)) {
|
| - if (IsMoreGeneralElementsKindTransition(that_kind, this_kind)) {
|
| - return Just(this_kind);
|
| - }
|
| - if (IsMoreGeneralElementsKindTransition(this_kind, that_kind)) {
|
| - return Just(that_kind);
|
| - }
|
| - }
|
| - return Nothing<ElementsKind>();
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -bool AccessInfoFactory::ConsolidateElementLoad(MapHandleList const& maps,
|
| - ElementAccessInfo* access_info) {
|
| +bool AccessInfoFactory::ConsolidateElementAccess(
|
| + MapHandleList const& maps, AccessMode access_mode,
|
| + ElementAccessInfo* access_info) {
|
| if (maps.is_empty()) return false;
|
| InstanceType instance_type = maps.first()->instance_type();
|
| ElementsKind elements_kind = maps.first()->elements_kind();
|
| @@ -510,9 +491,24 @@ bool AccessInfoFactory::ConsolidateElementLoad(MapHandleList const& maps,
|
| if (!CanInlineElementAccess(map) || map->instance_type() != instance_type) {
|
| return false;
|
| }
|
| - if (!GeneralizeElementsKind(elements_kind, map->elements_kind())
|
| - .To(&elements_kind)) {
|
| - return false;
|
| + ElementsKind other_kind = map->elements_kind();
|
| + if (IsHoleyElementsKind(elements_kind)) {
|
| + other_kind = GetHoleyElementsKind(other_kind);
|
| + } else if (IsHoleyElementsKind(other_kind)) {
|
| + elements_kind = GetHoleyElementsKind(elements_kind);
|
| + }
|
| + if (elements_kind != other_kind) {
|
| + if (access_mode != AccessMode::kLoad) return false;
|
| + if (IsFastDoubleElementsKind(elements_kind) !=
|
| + IsFastDoubleElementsKind(other_kind)) {
|
| + return false;
|
| + }
|
| + if (IsMoreGeneralElementsKindTransition(elements_kind, other_kind)) {
|
| + elements_kind = other_kind;
|
| + } else if (!IsMoreGeneralElementsKindTransition(other_kind,
|
| + elements_kind)) {
|
| + return false;
|
| + }
|
| }
|
| receiver_maps[i] = map;
|
| }
|
|
|