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 5f48a14b9e9ccc0e1f8a211570d16abd15d56132..33b76716c018fb936c9ea7d61cfc2c113656c956 100644 |
--- a/src/compiler/js-native-context-specialization.cc |
+++ b/src/compiler/js-native-context-specialization.cc |
@@ -672,8 +672,37 @@ Reduction JSNativeContextSpecialization::ReduceKeyedAccess( |
KeyedAccessStoreMode store_mode) { |
DCHECK(node->opcode() == IrOpcode::kJSLoadProperty || |
node->opcode() == IrOpcode::kJSStoreProperty); |
- Node* const receiver = NodeProperties::GetValueInput(node, 0); |
- Node* const effect = NodeProperties::GetEffectInput(node); |
+ Node* receiver = NodeProperties::GetValueInput(node, 0); |
+ Node* effect = NodeProperties::GetEffectInput(node); |
+ Node* control = NodeProperties::GetControlInput(node); |
+ |
+ // Optimize access for constant {receiver}. |
+ HeapObjectMatcher mreceiver(receiver); |
+ if (mreceiver.HasValue() && mreceiver.Value()->IsString()) { |
+ Handle<String> string = Handle<String>::cast(mreceiver.Value()); |
+ |
+ // We can only assume that the {index} is a valid array index if the IC |
+ // is in element access mode, otherwise there's no guard for the bounds |
+ // check below. |
+ if (nexus.GetKeyType() == ELEMENT) { |
Yang
2016/10/24 06:48:32
So... if the index is also a constant... *wink*
Benedikt Meurer
2016/10/24 07:34:28
Follow-up CL.
|
+ // Strings are immutable in JavaScript. |
+ if (access_mode == AccessMode::kStore) return NoChange(); |
+ |
+ // Ensure that {index} is less than {receiver} length. |
+ Node* length = jsgraph()->Constant(string->length()); |
+ index = effect = graph()->NewNode(simplified()->CheckBounds(), index, |
+ length, effect, control); |
+ |
+ // Load the character from the {receiver}. |
+ value = graph()->NewNode(simplified()->StringCharCodeAt(), receiver, |
+ index, control); |
+ |
+ // Return it as a single character string. |
+ value = graph()->NewNode(simplified()->StringFromCharCode(), value); |
+ ReplaceWithValue(node, value, effect, control); |
+ return Replace(value); |
+ } |
+ } |
// Check if the {nexus} reports type feedback for the IC. |
if (nexus.IsUninitialized()) { |