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

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

Issue 2210883002: [turbofan] Add support for "ignore OOB stores" to typed arrays. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 4 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 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 c122634cbb5e82038f7ce6f81a1ae3dc9dc1feea..44521793a035676f137d366a43428e652b1e9c54 100644
--- a/src/compiler/js-native-context-specialization.cc
+++ b/src/compiler/js-native-context-specialization.cc
@@ -427,7 +427,10 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
if (!(flags() & kDeoptimizationEnabled)) return NoChange();
// TODO(bmeurer): Add support for non-standard stores.
- if (store_mode != STANDARD_STORE) return NoChange();
+ if (store_mode != STANDARD_STORE &&
+ store_mode != STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
+ return NoChange();
+ }
// Retrieve the native context from the given {node}.
Handle<Context> native_context;
@@ -482,9 +485,9 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
BuildCheckMaps(receiver, effect, control, access_info.receiver_maps());
// Access the actual element.
- ValueEffectControl continuation =
- BuildElementAccess(receiver, index, value, effect, control,
- native_context, access_info, access_mode);
+ ValueEffectControl continuation = BuildElementAccess(
+ receiver, index, value, effect, control, native_context, access_info,
+ access_mode, store_mode);
value = continuation.value();
effect = continuation.effect();
control = continuation.control();
@@ -589,7 +592,7 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
// Access the actual element.
ValueEffectControl continuation = BuildElementAccess(
this_receiver, this_index, this_value, this_effect, this_control,
- native_context, access_info, access_mode);
+ native_context, access_info, access_mode, store_mode);
values.push_back(continuation.value());
effects.push_back(continuation.effect());
controls.push_back(continuation.control());
@@ -952,7 +955,7 @@ JSNativeContextSpecialization::ValueEffectControl
JSNativeContextSpecialization::BuildElementAccess(
Node* receiver, Node* index, Node* value, Node* effect, Node* control,
Handle<Context> native_context, ElementAccessInfo const& access_info,
- AccessMode access_mode) {
+ AccessMode access_mode, KeyedAccessStoreMode store_mode) {
// Determine actual holder and perform prototype chain checks.
Handle<JSObject> holder;
if (access_info.holder().ToHandle(&holder)) {
@@ -1002,9 +1005,19 @@ JSNativeContextSpecialization::BuildElementAccess(
common()->Select(MachineRepresentation::kTagged, BranchHint::kTrue),
check, length, jsgraph()->ZeroConstant());
- // Check that the {index} is in the valid range for the {receiver}.
- index = effect = graph()->NewNode(simplified()->CheckBounds(), index,
- length, effect, control);
+ if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
+ // Check that the {index} is a valid array index, we do the actual
+ // bounds check below and just skip the store below if it's out of
+ // bounds for the {receiver}.
+ index = effect = graph()->NewNode(simplified()->CheckBounds(), index,
+ jsgraph()->Constant(Smi::kMaxValue),
+ effect, control);
+ } else {
+ // Check that the {index} is in the valid range for the {receiver}.
+ DCHECK_EQ(STANDARD_STORE, store_mode);
+ index = effect = graph()->NewNode(simplified()->CheckBounds(), index,
+ length, effect, control);
+ }
// Load the base and external pointer for the {receiver}.
Node* base_pointer = effect = graph()->NewNode(
@@ -1030,13 +1043,46 @@ JSNativeContextSpecialization::BuildElementAccess(
// Ensure that the {value} is actually a Number.
value = effect = graph()->NewNode(simplified()->CheckNumber(), value,
effect, control);
- effect = graph()->NewNode(
- simplified()->StoreTypedElement(external_array_type), buffer,
- base_pointer, external_pointer, index, value, effect, control);
+
+ // Check if we can skip the out-of-bounds store.
+ if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
+ Node* check =
+ graph()->NewNode(simplified()->NumberLessThan(), index, length);
+ Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue),
+ check, control);
+
+ Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* etrue = effect;
+ {
+ // Perform the actual store.
+ etrue = graph()->NewNode(
+ simplified()->StoreTypedElement(external_array_type), buffer,
+ base_pointer, external_pointer, index, value, etrue, if_true);
+ }
+
+ Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+ Node* efalse = effect;
+ {
+ // Just ignore the out-of-bounds write.
+ }
+
+ control = graph()->NewNode(common()->Merge(2), if_true, if_false);
+ effect =
+ graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
+ } else {
+ // Perform the actual store
+ DCHECK_EQ(STANDARD_STORE, store_mode);
+ effect = graph()->NewNode(
+ simplified()->StoreTypedElement(external_array_type), buffer,
+ base_pointer, external_pointer, index, value, effect, control);
+ }
break;
}
}
} else {
+ // TODO(turbofan): Add support for additional store modes.
+ DCHECK_EQ(STANDARD_STORE, store_mode);
+
// Load the length of the {receiver}.
Node* length = effect =
HasOnlyJSArrayMaps(receiver_maps)
@@ -1066,8 +1112,6 @@ JSNativeContextSpecialization::BuildElementAccess(
kFullWriteBarrier};
// 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.
« 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