Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(418)

Side by Side Diff: src/compiler/access-info.cc

Issue 2836913004: [turbofan] General consolidation of element access. (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/access-info.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <ostream> 5 #include <ostream>
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/compilation-dependencies.h" 8 #include "src/compilation-dependencies.h"
9 #include "src/compiler/access-info.h" 9 #include "src/compiler/access-info.h"
10 #include "src/compiler/type-cache.h" 10 #include "src/compiler/type-cache.h"
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 // Check if it is safe to inline element access for the {map}. 199 // Check if it is safe to inline element access for the {map}.
200 if (!CanInlineElementAccess(map)) return false; 200 if (!CanInlineElementAccess(map)) return false;
201 ElementsKind const elements_kind = map->elements_kind(); 201 ElementsKind const elements_kind = map->elements_kind();
202 *access_info = ElementAccessInfo(MapList{map}, elements_kind); 202 *access_info = ElementAccessInfo(MapList{map}, elements_kind);
203 return true; 203 return true;
204 } 204 }
205 205
206 bool AccessInfoFactory::ComputeElementAccessInfos( 206 bool AccessInfoFactory::ComputeElementAccessInfos(
207 MapHandleList const& maps, AccessMode access_mode, 207 MapHandleList const& maps, AccessMode access_mode,
208 ZoneVector<ElementAccessInfo>* access_infos) { 208 ZoneVector<ElementAccessInfo>* access_infos) {
209 if (access_mode == AccessMode::kLoad) { 209 // For polymorphic loads of similar elements kinds (i.e. all tagged or all
210 // For polymorphic loads of similar elements kinds (i.e. all tagged or all 210 // double), always use the "worst case" code without a transition. This is
211 // double), always use the "worst case" code without a transition. This is 211 // much faster than transitioning the elements to the worst case, trading a
212 // much faster than transitioning the elements to the worst case, trading a 212 // TransitionElementsKind for a CheckMaps, avoiding mutation of the array.
213 // TransitionElementsKind for a CheckMaps, avoiding mutation of the array. 213 //
214 ElementAccessInfo access_info; 214 // Similarly, for polymorphic stores of compatible elements kind that
215 if (ConsolidateElementLoad(maps, &access_info)) { 215 // differ only in holeyness, always use the "holey case" code without a
216 access_infos->push_back(access_info); 216 // transition. This is beneficial, because CheckMaps can often be optimized
217 return true; 217 // whereas TransitionElementsKind can block optimizations. And as above, we
218 } 218 // avoid mutation of the array (we still mutate the array contents).
219 ElementAccessInfo access_info;
220 if (ConsolidateElementAccess(maps, access_mode, &access_info)) {
221 access_infos->push_back(access_info);
222 return true;
219 } 223 }
220 224
221 // Collect possible transition targets. 225 // Collect possible transition targets.
222 MapHandleList possible_transition_targets(maps.length()); 226 MapHandleList possible_transition_targets(maps.length());
223 for (Handle<Map> map : maps) { 227 for (Handle<Map> map : maps) {
224 if (Map::TryUpdate(map).ToHandle(&map)) { 228 if (Map::TryUpdate(map).ToHandle(&map)) {
225 if (CanInlineElementAccess(map) && 229 if (CanInlineElementAccess(map) &&
226 IsFastElementsKind(map->elements_kind()) && 230 IsFastElementsKind(map->elements_kind()) &&
227 GetInitialFastElementsKind() != map->elements_kind()) { 231 GetInitialFastElementsKind() != map->elements_kind()) {
228 possible_transition_targets.Add(map); 232 possible_transition_targets.Add(map);
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 merged = true; 472 merged = true;
469 break; 473 break;
470 } 474 }
471 } 475 }
472 if (!merged) access_infos->push_back(access_info); 476 if (!merged) access_infos->push_back(access_info);
473 } 477 }
474 } 478 }
475 return true; 479 return true;
476 } 480 }
477 481
478 namespace { 482 bool AccessInfoFactory::ConsolidateElementAccess(
479 483 MapHandleList const& maps, AccessMode access_mode,
480 Maybe<ElementsKind> GeneralizeElementsKind(ElementsKind this_kind, 484 ElementAccessInfo* access_info) {
481 ElementsKind that_kind) {
482 if (IsHoleyElementsKind(this_kind)) {
483 that_kind = GetHoleyElementsKind(that_kind);
484 } else if (IsHoleyElementsKind(that_kind)) {
485 this_kind = GetHoleyElementsKind(this_kind);
486 }
487 if (this_kind == that_kind) return Just(this_kind);
488 if (IsFastDoubleElementsKind(that_kind) ==
489 IsFastDoubleElementsKind(this_kind)) {
490 if (IsMoreGeneralElementsKindTransition(that_kind, this_kind)) {
491 return Just(this_kind);
492 }
493 if (IsMoreGeneralElementsKindTransition(this_kind, that_kind)) {
494 return Just(that_kind);
495 }
496 }
497 return Nothing<ElementsKind>();
498 }
499
500 } // namespace
501
502 bool AccessInfoFactory::ConsolidateElementLoad(MapHandleList const& maps,
503 ElementAccessInfo* access_info) {
504 if (maps.is_empty()) return false; 485 if (maps.is_empty()) return false;
505 InstanceType instance_type = maps.first()->instance_type(); 486 InstanceType instance_type = maps.first()->instance_type();
506 ElementsKind elements_kind = maps.first()->elements_kind(); 487 ElementsKind elements_kind = maps.first()->elements_kind();
507 MapList receiver_maps(maps.length()); 488 MapList receiver_maps(maps.length());
508 for (int i = 0; i < maps.length(); ++i) { 489 for (int i = 0; i < maps.length(); ++i) {
509 Handle<Map> map = maps[i]; 490 Handle<Map> map = maps[i];
510 if (!CanInlineElementAccess(map) || map->instance_type() != instance_type) { 491 if (!CanInlineElementAccess(map) || map->instance_type() != instance_type) {
511 return false; 492 return false;
512 } 493 }
513 if (!GeneralizeElementsKind(elements_kind, map->elements_kind()) 494 ElementsKind other_kind = map->elements_kind();
514 .To(&elements_kind)) { 495 if (IsHoleyElementsKind(elements_kind)) {
515 return false; 496 other_kind = GetHoleyElementsKind(other_kind);
497 } else if (IsHoleyElementsKind(other_kind)) {
498 elements_kind = GetHoleyElementsKind(elements_kind);
499 }
500 if (elements_kind != other_kind) {
501 if (access_mode != AccessMode::kLoad) return false;
502 if (IsFastDoubleElementsKind(elements_kind) !=
503 IsFastDoubleElementsKind(other_kind)) {
504 return false;
505 }
506 if (IsMoreGeneralElementsKindTransition(elements_kind, other_kind)) {
507 elements_kind = other_kind;
508 } else if (!IsMoreGeneralElementsKindTransition(other_kind,
509 elements_kind)) {
510 return false;
511 }
516 } 512 }
517 receiver_maps[i] = map; 513 receiver_maps[i] = map;
518 } 514 }
519 *access_info = ElementAccessInfo(receiver_maps, elements_kind); 515 *access_info = ElementAccessInfo(receiver_maps, elements_kind);
520 return true; 516 return true;
521 } 517 }
522 518
523 bool AccessInfoFactory::LookupSpecialFieldAccessor( 519 bool AccessInfoFactory::LookupSpecialFieldAccessor(
524 Handle<Map> map, Handle<Name> name, PropertyAccessInfo* access_info) { 520 Handle<Map> map, Handle<Name> name, PropertyAccessInfo* access_info) {
525 // Check for special JSObject field accessors. 521 // Check for special JSObject field accessors.
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 } 613 }
618 return false; 614 return false;
619 } 615 }
620 616
621 617
622 Factory* AccessInfoFactory::factory() const { return isolate()->factory(); } 618 Factory* AccessInfoFactory::factory() const { return isolate()->factory(); }
623 619
624 } // namespace compiler 620 } // namespace compiler
625 } // namespace internal 621 } // namespace internal
626 } // namespace v8 622 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/access-info.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698