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

Unified Diff: src/compiler/js-native-context-specialization.cc

Issue 1448903002: [turbofan] Initial support for keyed access to holey elements. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/js-native-context-specialization.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/js-native-context-specialization.cc
diff --git a/src/compiler/js-native-context-specialization.cc b/src/compiler/js-native-context-specialization.cc
index 608f14445520532499e3300ccbc496c8ddc4defa..d2483c3384e7f7f5dd161baaa11ce23d8dd46ebb 100644
--- a/src/compiler/js-native-context-specialization.cc
+++ b/src/compiler/js-native-context-specialization.cc
@@ -13,6 +13,7 @@
#include "src/compiler/linkage.h"
#include "src/compiler/node-matchers.h"
#include "src/field-index-inl.h"
+#include "src/isolate-inl.h"
#include "src/objects-inl.h" // TODO(mstarzinger): Temporary cycle breaker!
#include "src/type-cache.h"
#include "src/type-feedback-vector.h"
@@ -496,7 +497,8 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreNamed(Node* node) {
Reduction JSNativeContextSpecialization::ReduceElementAccess(
Node* node, Node* index, Node* value, MapHandleList const& receiver_maps,
- AccessMode access_mode, LanguageMode language_mode) {
+ AccessMode access_mode, LanguageMode language_mode,
+ KeyedAccessStoreMode store_mode) {
DCHECK(node->opcode() == IrOpcode::kJSLoadProperty ||
node->opcode() == IrOpcode::kJSStoreProperty);
Node* receiver = NodeProperties::GetValueInput(node, 0);
@@ -508,6 +510,9 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
// Not much we can do if deoptimization support is disabled.
if (!(flags() & kDeoptimizationEnabled)) return NoChange();
+ // TODO(bmeurer): Add support for non-standard stores.
+ if (store_mode != STANDARD_STORE) return NoChange();
+
// Compute element access infos for the receiver maps.
ZoneVector<ElementAccessInfo> access_infos(zone());
if (!access_info_factory().ComputeElementAccessInfos(
@@ -728,10 +733,62 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
element_type, element_machine_type};
// Access the actual element.
+ // TODO(bmeurer): Refactor this into separate methods or even a separate
+ // class that deals with the elements access.
if (access_mode == AccessMode::kLoad) {
+ // Compute the real element access type, which includes the hole in case
+ // of holey backing stores.
+ if (elements_kind == FAST_HOLEY_ELEMENTS ||
+ elements_kind == FAST_HOLEY_SMI_ELEMENTS) {
+ element_access.type = Type::Union(
+ element_type,
+ Type::Constant(factory()->the_hole_value(), graph()->zone()),
+ graph()->zone());
+ }
+ // Perform the actual backing store access.
this_value = this_effect = graph()->NewNode(
simplified()->LoadElement(element_access), this_elements, this_index,
this_effect, this_control);
+ // Handle loading from holey backing stores correctly, by either mapping
+ // the hole to undefined if possible, or deoptimizing otherwise.
+ if (elements_kind == FAST_HOLEY_ELEMENTS ||
+ elements_kind == FAST_HOLEY_SMI_ELEMENTS) {
+ // Perform the hole check on the result.
+ Node* check =
+ graph()->NewNode(simplified()->ReferenceEqual(element_access.type),
+ this_value, jsgraph()->TheHoleConstant());
+ Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse),
+ check, this_control);
+ Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+ // Check if we are allowed to turn the hole into undefined.
+ Type* initial_holey_array_type = Type::Class(
+ handle(isolate()->get_initial_js_array_map(FAST_HOLEY_ELEMENTS)),
+ graph()->zone());
+ if (receiver_type->NowIs(initial_holey_array_type) &&
+ isolate()->IsFastArrayConstructorPrototypeChainIntact()) {
+ // Add a code dependency on the array protector cell.
+ AssumePrototypesStable(receiver_type,
+ isolate()->initial_object_prototype());
+ dependencies()->AssumePropertyCell(factory()->array_protector());
+ // Turn the hole into undefined.
+ this_control =
+ graph()->NewNode(common()->Merge(2), if_true, if_false);
+ this_value = graph()->NewNode(common()->Phi(kMachAnyTagged, 2),
+ jsgraph()->UndefinedConstant(),
+ this_value, this_control);
+ element_type =
+ Type::Union(element_type, Type::Undefined(), graph()->zone());
+ } else {
+ // Deoptimize in case of the hole.
+ exit_controls.push_back(if_true);
+ this_control = if_false;
+ }
+ // Rename the result to represent the actual type (not polluted by the
+ // hole).
+ this_value = graph()->NewNode(common()->Guard(element_type), this_value,
+ this_control);
+ }
} else {
DCHECK_EQ(AccessMode::kStore, access_mode);
if (IsFastSmiElementsKind(elements_kind)) {
@@ -809,7 +866,8 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
Reduction JSNativeContextSpecialization::ReduceKeyedAccess(
Node* node, Node* index, Node* value, FeedbackNexus const& nexus,
- AccessMode access_mode, LanguageMode language_mode) {
+ AccessMode access_mode, LanguageMode language_mode,
+ KeyedAccessStoreMode store_mode) {
DCHECK(node->opcode() == IrOpcode::kJSLoadProperty ||
node->opcode() == IrOpcode::kJSStoreProperty);
@@ -848,7 +906,7 @@ Reduction JSNativeContextSpecialization::ReduceKeyedAccess(
// Try to lower the element access based on the {receiver_maps}.
return ReduceElementAccess(node, index, value, receiver_maps, access_mode,
- language_mode);
+ language_mode, store_mode);
}
@@ -864,7 +922,7 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadProperty(Node* node) {
// Try to lower the keyed access based on the {nexus}.
return ReduceKeyedAccess(node, index, value, nexus, AccessMode::kLoad,
- p.language_mode());
+ p.language_mode(), STANDARD_STORE);
}
@@ -878,9 +936,12 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreProperty(Node* node) {
if (!p.feedback().IsValid()) return NoChange();
KeyedStoreICNexus nexus(p.feedback().vector(), p.feedback().slot());
+ // Extract the keyed access store mode from the KEYED_STORE_IC.
+ KeyedAccessStoreMode store_mode = nexus.GetKeyedAccessStoreMode();
+
// Try to lower the keyed access based on the {nexus}.
return ReduceKeyedAccess(node, index, value, nexus, AccessMode::kStore,
- p.language_mode());
+ p.language_mode(), store_mode);
}
« no previous file with comments | « src/compiler/js-native-context-specialization.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698