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

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

Issue 2743253002: [turbofan] Skip JSCallReducer and JSNativeContextSpecialization on asm.js. (Closed)
Patch Set: REBASE Created 3 years, 9 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/js-native-context-specialization.h ('k') | src/compiler/pipeline.cc » ('j') | 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 "src/compiler/js-native-context-specialization.h" 5 #include "src/compiler/js-native-context-specialization.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/compilation-dependencies.h" 9 #include "src/compilation-dependencies.h"
10 #include "src/compiler/access-builder.h" 10 #include "src/compiler/access-builder.h"
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 } 131 }
132 } 132 }
133 return NoChange(); 133 return NoChange();
134 } 134 }
135 135
136 Reduction JSNativeContextSpecialization::ReduceJSGetSuperConstructor( 136 Reduction JSNativeContextSpecialization::ReduceJSGetSuperConstructor(
137 Node* node) { 137 Node* node) {
138 DCHECK_EQ(IrOpcode::kJSGetSuperConstructor, node->opcode()); 138 DCHECK_EQ(IrOpcode::kJSGetSuperConstructor, node->opcode());
139 Node* constructor = NodeProperties::GetValueInput(node, 0); 139 Node* constructor = NodeProperties::GetValueInput(node, 0);
140 140
141 // If deoptimization is disabled, we cannot optimize.
142 if (!(flags() & kDeoptimizationEnabled)) return NoChange();
143
144 // Check if the input is a known JSFunction. 141 // Check if the input is a known JSFunction.
145 HeapObjectMatcher m(constructor); 142 HeapObjectMatcher m(constructor);
146 if (!m.HasValue()) return NoChange(); 143 if (!m.HasValue()) return NoChange();
147 Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value()); 144 Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value());
148 Handle<Map> function_map(function->map(), isolate()); 145 Handle<Map> function_map(function->map(), isolate());
149 Handle<Object> function_prototype(function_map->prototype(), isolate()); 146 Handle<Object> function_prototype(function_map->prototype(), isolate());
150 147
151 // We can constant-fold the super constructor access if the 148 // We can constant-fold the super constructor access if the
152 // {function}s map is stable, i.e. we can use a code dependency 149 // {function}s map is stable, i.e. we can use a code dependency
153 // to guard against [[Prototype]] changes of {function}. 150 // to guard against [[Prototype]] changes of {function}.
(...skipping 15 matching lines...) Expand all
169 } 166 }
170 167
171 Reduction JSNativeContextSpecialization::ReduceJSInstanceOf(Node* node) { 168 Reduction JSNativeContextSpecialization::ReduceJSInstanceOf(Node* node) {
172 DCHECK_EQ(IrOpcode::kJSInstanceOf, node->opcode()); 169 DCHECK_EQ(IrOpcode::kJSInstanceOf, node->opcode());
173 Node* object = NodeProperties::GetValueInput(node, 0); 170 Node* object = NodeProperties::GetValueInput(node, 0);
174 Node* constructor = NodeProperties::GetValueInput(node, 1); 171 Node* constructor = NodeProperties::GetValueInput(node, 1);
175 Node* context = NodeProperties::GetContextInput(node); 172 Node* context = NodeProperties::GetContextInput(node);
176 Node* effect = NodeProperties::GetEffectInput(node); 173 Node* effect = NodeProperties::GetEffectInput(node);
177 Node* control = NodeProperties::GetControlInput(node); 174 Node* control = NodeProperties::GetControlInput(node);
178 175
179 // If deoptimization is disabled, we cannot optimize.
180 if (!(flags() & kDeoptimizationEnabled)) return NoChange();
181
182 // Check if the right hand side is a known {receiver}. 176 // Check if the right hand side is a known {receiver}.
183 HeapObjectMatcher m(constructor); 177 HeapObjectMatcher m(constructor);
184 if (!m.HasValue() || !m.Value()->IsJSObject()) return NoChange(); 178 if (!m.HasValue() || !m.Value()->IsJSObject()) return NoChange();
185 Handle<JSObject> receiver = Handle<JSObject>::cast(m.Value()); 179 Handle<JSObject> receiver = Handle<JSObject>::cast(m.Value());
186 Handle<Map> receiver_map(receiver->map(), isolate()); 180 Handle<Map> receiver_map(receiver->map(), isolate());
187 181
188 // Compute property access info for @@hasInstance on {receiver}. 182 // Compute property access info for @@hasInstance on {receiver}.
189 PropertyAccessInfo access_info; 183 PropertyAccessInfo access_info;
190 AccessInfoFactory access_info_factory(dependencies(), native_context(), 184 AccessInfoFactory access_info_factory(dependencies(), native_context(),
191 graph()->zone()); 185 graph()->zone());
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 if (LookupInScriptContextTable(name, &result)) { 500 if (LookupInScriptContextTable(name, &result)) {
507 if (result.context->is_the_hole(isolate(), result.index)) return NoChange(); 501 if (result.context->is_the_hole(isolate(), result.index)) return NoChange();
508 Node* context = jsgraph()->HeapConstant(result.context); 502 Node* context = jsgraph()->HeapConstant(result.context);
509 Node* value = effect = graph()->NewNode( 503 Node* value = effect = graph()->NewNode(
510 javascript()->LoadContext(0, result.index, result.immutable), context, 504 javascript()->LoadContext(0, result.index, result.immutable), context,
511 effect); 505 effect);
512 ReplaceWithValue(node, value, effect); 506 ReplaceWithValue(node, value, effect);
513 return Replace(value); 507 return Replace(value);
514 } 508 }
515 509
516 // Not much we can do if deoptimization support is disabled.
517 if (!(flags() & kDeoptimizationEnabled)) return NoChange();
518
519 // Lookup the {name} on the global object instead. 510 // Lookup the {name} on the global object instead.
520 return ReduceGlobalAccess(node, nullptr, nullptr, name, AccessMode::kLoad); 511 return ReduceGlobalAccess(node, nullptr, nullptr, name, AccessMode::kLoad);
521 } 512 }
522 513
523 Reduction JSNativeContextSpecialization::ReduceJSStoreGlobal(Node* node) { 514 Reduction JSNativeContextSpecialization::ReduceJSStoreGlobal(Node* node) {
524 DCHECK_EQ(IrOpcode::kJSStoreGlobal, node->opcode()); 515 DCHECK_EQ(IrOpcode::kJSStoreGlobal, node->opcode());
525 Handle<Name> name = StoreGlobalParametersOf(node->op()).name(); 516 Handle<Name> name = StoreGlobalParametersOf(node->op()).name();
526 Node* value = NodeProperties::GetValueInput(node, 0); 517 Node* value = NodeProperties::GetValueInput(node, 0);
527 Node* effect = NodeProperties::GetEffectInput(node); 518 Node* effect = NodeProperties::GetEffectInput(node);
528 Node* control = NodeProperties::GetControlInput(node); 519 Node* control = NodeProperties::GetControlInput(node);
529 520
530 // Try to lookup the name on the script context table first (lexical scoping). 521 // Try to lookup the name on the script context table first (lexical scoping).
531 ScriptContextTableLookupResult result; 522 ScriptContextTableLookupResult result;
532 if (LookupInScriptContextTable(name, &result)) { 523 if (LookupInScriptContextTable(name, &result)) {
533 if (result.context->is_the_hole(isolate(), result.index)) return NoChange(); 524 if (result.context->is_the_hole(isolate(), result.index)) return NoChange();
534 if (result.immutable) return NoChange(); 525 if (result.immutable) return NoChange();
535 Node* context = jsgraph()->HeapConstant(result.context); 526 Node* context = jsgraph()->HeapConstant(result.context);
536 effect = graph()->NewNode(javascript()->StoreContext(0, result.index), 527 effect = graph()->NewNode(javascript()->StoreContext(0, result.index),
537 value, context, effect, control); 528 value, context, effect, control);
538 ReplaceWithValue(node, value, effect, control); 529 ReplaceWithValue(node, value, effect, control);
539 return Replace(value); 530 return Replace(value);
540 } 531 }
541 532
542 // Not much we can do if deoptimization support is disabled.
543 if (!(flags() & kDeoptimizationEnabled)) return NoChange();
544
545 // Lookup the {name} on the global object instead. 533 // Lookup the {name} on the global object instead.
546 return ReduceGlobalAccess(node, nullptr, value, name, AccessMode::kStore); 534 return ReduceGlobalAccess(node, nullptr, value, name, AccessMode::kStore);
547 } 535 }
548 536
549 Reduction JSNativeContextSpecialization::ReduceNamedAccess( 537 Reduction JSNativeContextSpecialization::ReduceNamedAccess(
550 Node* node, Node* value, MapHandleList const& receiver_maps, 538 Node* node, Node* value, MapHandleList const& receiver_maps,
551 Handle<Name> name, AccessMode access_mode, LanguageMode language_mode, 539 Handle<Name> name, AccessMode access_mode, LanguageMode language_mode,
552 Handle<FeedbackVector> vector, FeedbackSlot slot, Node* index) { 540 Handle<FeedbackVector> vector, FeedbackSlot slot, Node* index) {
553 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed || 541 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed ||
554 node->opcode() == IrOpcode::kJSStoreNamed || 542 node->opcode() == IrOpcode::kJSStoreNamed ||
555 node->opcode() == IrOpcode::kJSLoadProperty || 543 node->opcode() == IrOpcode::kJSLoadProperty ||
556 node->opcode() == IrOpcode::kJSStoreProperty || 544 node->opcode() == IrOpcode::kJSStoreProperty ||
557 node->opcode() == IrOpcode::kJSStoreNamedOwn); 545 node->opcode() == IrOpcode::kJSStoreNamedOwn);
558 Node* receiver = NodeProperties::GetValueInput(node, 0); 546 Node* receiver = NodeProperties::GetValueInput(node, 0);
559 Node* context = NodeProperties::GetContextInput(node); 547 Node* context = NodeProperties::GetContextInput(node);
560 Node* frame_state = NodeProperties::GetFrameStateInput(node); 548 Node* frame_state = NodeProperties::GetFrameStateInput(node);
561 Node* effect = NodeProperties::GetEffectInput(node); 549 Node* effect = NodeProperties::GetEffectInput(node);
562 Node* control = NodeProperties::GetControlInput(node); 550 Node* control = NodeProperties::GetControlInput(node);
563 551
564 // Not much we can do if deoptimization support is disabled.
565 if (!(flags() & kDeoptimizationEnabled)) return NoChange();
566
567 // Check if we have an access o.x or o.x=v where o is the current 552 // Check if we have an access o.x or o.x=v where o is the current
568 // native contexts' global proxy, and turn that into a direct access 553 // native contexts' global proxy, and turn that into a direct access
569 // to the current native contexts' global object instead. 554 // to the current native contexts' global object instead.
570 if (receiver_maps.length() == 1) { 555 if (receiver_maps.length() == 1) {
571 Handle<Map> receiver_map = receiver_maps.first(); 556 Handle<Map> receiver_map = receiver_maps.first();
572 if (receiver_map->IsJSGlobalProxyMap()) { 557 if (receiver_map->IsJSGlobalProxyMap()) {
573 Object* maybe_constructor = receiver_map->GetConstructor(); 558 Object* maybe_constructor = receiver_map->GetConstructor();
574 // Detached global proxies have |null| as their constructor. 559 // Detached global proxies have |null| as their constructor.
575 if (maybe_constructor->IsJSFunction() && 560 if (maybe_constructor->IsJSFunction() &&
576 JSFunction::cast(maybe_constructor)->native_context() == 561 JSFunction::cast(maybe_constructor)->native_context() ==
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 768
784 Reduction JSNativeContextSpecialization::ReduceNamedAccessFromNexus( 769 Reduction JSNativeContextSpecialization::ReduceNamedAccessFromNexus(
785 Node* node, Node* value, FeedbackNexus const& nexus, Handle<Name> name, 770 Node* node, Node* value, FeedbackNexus const& nexus, Handle<Name> name,
786 AccessMode access_mode, LanguageMode language_mode) { 771 AccessMode access_mode, LanguageMode language_mode) {
787 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed || 772 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed ||
788 node->opcode() == IrOpcode::kJSStoreNamed || 773 node->opcode() == IrOpcode::kJSStoreNamed ||
789 node->opcode() == IrOpcode::kJSStoreNamedOwn); 774 node->opcode() == IrOpcode::kJSStoreNamedOwn);
790 Node* const receiver = NodeProperties::GetValueInput(node, 0); 775 Node* const receiver = NodeProperties::GetValueInput(node, 0);
791 Node* const effect = NodeProperties::GetEffectInput(node); 776 Node* const effect = NodeProperties::GetEffectInput(node);
792 777
793 if (flags() & kDeoptimizationEnabled) { 778 // Check if we are accessing the current native contexts' global proxy.
794 // Check if we are accessing the current native contexts' global proxy. 779 HeapObjectMatcher m(receiver);
795 HeapObjectMatcher m(receiver); 780 if (m.HasValue() && m.Value().is_identical_to(global_proxy())) {
796 if (m.HasValue() && m.Value().is_identical_to(global_proxy())) { 781 // Optimize accesses to the current native contexts' global proxy.
797 // Optimize accesses to the current native contexts' global proxy. 782 return ReduceGlobalAccess(node, nullptr, value, name, access_mode);
798 return ReduceGlobalAccess(node, nullptr, value, name, access_mode);
799 }
800 } 783 }
801 784
802 // Check if the {nexus} reports type feedback for the IC. 785 // Check if the {nexus} reports type feedback for the IC.
803 if (nexus.IsUninitialized()) { 786 if (nexus.IsUninitialized()) {
804 if ((flags() & kDeoptimizationEnabled) && 787 if (flags() & kBailoutOnUninitialized) {
805 (flags() & kBailoutOnUninitialized)) {
806 return ReduceSoftDeoptimize( 788 return ReduceSoftDeoptimize(
807 node, 789 node,
808 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); 790 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess);
809 } 791 }
810 return NoChange(); 792 return NoChange();
811 } 793 }
812 794
813 // Extract receiver maps from the IC using the {nexus}. 795 // Extract receiver maps from the IC using the {nexus}.
814 MapHandleList receiver_maps; 796 MapHandleList receiver_maps;
815 if (!ExtractReceiverMaps(receiver, effect, nexus, &receiver_maps)) { 797 if (!ExtractReceiverMaps(receiver, effect, nexus, &receiver_maps)) {
816 return NoChange(); 798 return NoChange();
817 } else if (receiver_maps.length() == 0) { 799 } else if (receiver_maps.length() == 0) {
818 if ((flags() & kDeoptimizationEnabled) && 800 if (flags() & kBailoutOnUninitialized) {
819 (flags() & kBailoutOnUninitialized)) {
820 return ReduceSoftDeoptimize( 801 return ReduceSoftDeoptimize(
821 node, 802 node,
822 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); 803 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess);
823 } 804 }
824 return NoChange(); 805 return NoChange();
825 } 806 }
826 807
827 // Try to lower the named access based on the {receiver_maps}. 808 // Try to lower the named access based on the {receiver_maps}.
828 return ReduceNamedAccess(node, value, receiver_maps, name, access_mode, 809 return ReduceNamedAccess(node, value, receiver_maps, name, access_mode,
829 language_mode, nexus.vector_handle(), nexus.slot()); 810 language_mode, nexus.vector_handle(), nexus.slot());
(...skipping 10 matching lines...) Expand all
840 if (m.HasValue()) { 821 if (m.HasValue()) {
841 if (m.Value()->IsJSFunction() && 822 if (m.Value()->IsJSFunction() &&
842 p.name().is_identical_to(factory()->prototype_string())) { 823 p.name().is_identical_to(factory()->prototype_string())) {
843 // Optimize "prototype" property of functions. 824 // Optimize "prototype" property of functions.
844 Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value()); 825 Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value());
845 if (function->has_initial_map()) { 826 if (function->has_initial_map()) {
846 // We need to add a code dependency on the initial map of the 827 // We need to add a code dependency on the initial map of the
847 // {function} in order to be notified about changes to the 828 // {function} in order to be notified about changes to the
848 // "prototype" of {function}, so it doesn't make sense to 829 // "prototype" of {function}, so it doesn't make sense to
849 // continue unless deoptimization is enabled. 830 // continue unless deoptimization is enabled.
850 if (flags() & kDeoptimizationEnabled) { 831 Handle<Map> initial_map(function->initial_map(), isolate());
851 Handle<Map> initial_map(function->initial_map(), isolate()); 832 dependencies()->AssumeInitialMapCantChange(initial_map);
852 dependencies()->AssumeInitialMapCantChange(initial_map); 833 Handle<Object> prototype(initial_map->prototype(), isolate());
853 Handle<Object> prototype(initial_map->prototype(), isolate()); 834 Node* value = jsgraph()->Constant(prototype);
854 Node* value = jsgraph()->Constant(prototype); 835 ReplaceWithValue(node, value);
855 ReplaceWithValue(node, value); 836 return Replace(value);
856 return Replace(value);
857 }
858 } 837 }
859 } else if (m.Value()->IsString() && 838 } else if (m.Value()->IsString() &&
860 p.name().is_identical_to(factory()->length_string())) { 839 p.name().is_identical_to(factory()->length_string())) {
861 // Constant-fold "length" property on constant strings. 840 // Constant-fold "length" property on constant strings.
862 Handle<String> string = Handle<String>::cast(m.Value()); 841 Handle<String> string = Handle<String>::cast(m.Value());
863 Node* value = jsgraph()->Constant(string->length()); 842 Node* value = jsgraph()->Constant(string->length());
864 ReplaceWithValue(node, value); 843 ReplaceWithValue(node, value);
865 return Replace(value); 844 return Replace(value);
866 } 845 }
867 } 846 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 Node* node, Node* index, Node* value, MapHandleList const& receiver_maps, 887 Node* node, Node* index, Node* value, MapHandleList const& receiver_maps,
909 AccessMode access_mode, LanguageMode language_mode, 888 AccessMode access_mode, LanguageMode language_mode,
910 KeyedAccessStoreMode store_mode) { 889 KeyedAccessStoreMode store_mode) {
911 DCHECK(node->opcode() == IrOpcode::kJSLoadProperty || 890 DCHECK(node->opcode() == IrOpcode::kJSLoadProperty ||
912 node->opcode() == IrOpcode::kJSStoreProperty); 891 node->opcode() == IrOpcode::kJSStoreProperty);
913 Node* receiver = NodeProperties::GetValueInput(node, 0); 892 Node* receiver = NodeProperties::GetValueInput(node, 0);
914 Node* effect = NodeProperties::GetEffectInput(node); 893 Node* effect = NodeProperties::GetEffectInput(node);
915 Node* control = NodeProperties::GetControlInput(node); 894 Node* control = NodeProperties::GetControlInput(node);
916 Node* frame_state = NodeProperties::FindFrameStateBefore(node); 895 Node* frame_state = NodeProperties::FindFrameStateBefore(node);
917 896
918 // Not much we can do if deoptimization support is disabled.
919 if (!(flags() & kDeoptimizationEnabled)) return NoChange();
920
921 // Check for keyed access to strings. 897 // Check for keyed access to strings.
922 if (HasOnlyStringMaps(receiver_maps)) { 898 if (HasOnlyStringMaps(receiver_maps)) {
923 // Strings are immutable in JavaScript. 899 // Strings are immutable in JavaScript.
924 if (access_mode == AccessMode::kStore) return NoChange(); 900 if (access_mode == AccessMode::kStore) return NoChange();
925 901
926 // Ensure that the {receiver} is actually a String. 902 // Ensure that the {receiver} is actually a String.
927 receiver = effect = graph()->NewNode(simplified()->CheckString(), receiver, 903 receiver = effect = graph()->NewNode(simplified()->CheckString(), receiver,
928 effect, control); 904 effect, control);
929 905
930 // Determine the {receiver} length. 906 // Determine the {receiver} length.
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
1156 node->opcode() == IrOpcode::kJSStoreProperty); 1132 node->opcode() == IrOpcode::kJSStoreProperty);
1157 Node* receiver = NodeProperties::GetValueInput(node, 0); 1133 Node* receiver = NodeProperties::GetValueInput(node, 0);
1158 Node* effect = NodeProperties::GetEffectInput(node); 1134 Node* effect = NodeProperties::GetEffectInput(node);
1159 Node* control = NodeProperties::GetControlInput(node); 1135 Node* control = NodeProperties::GetControlInput(node);
1160 1136
1161 // Optimize access for constant {receiver}. 1137 // Optimize access for constant {receiver}.
1162 HeapObjectMatcher mreceiver(receiver); 1138 HeapObjectMatcher mreceiver(receiver);
1163 if (mreceiver.HasValue() && mreceiver.Value()->IsString()) { 1139 if (mreceiver.HasValue() && mreceiver.Value()->IsString()) {
1164 Handle<String> string = Handle<String>::cast(mreceiver.Value()); 1140 Handle<String> string = Handle<String>::cast(mreceiver.Value());
1165 1141
1142 // Strings are immutable in JavaScript.
1143 if (access_mode == AccessMode::kStore) return NoChange();
1144
1145 // Properly deal with constant {index}.
1146 NumberMatcher mindex(index);
1147 if (mindex.IsInteger() && mindex.IsInRange(0.0, string->length() - 1)) {
1148 // Constant-fold the {index} access to {string}.
1149 Node* value = jsgraph()->HeapConstant(
1150 factory()->LookupSingleCharacterStringFromCode(
1151 string->Get(static_cast<int>(mindex.Value()))));
1152 ReplaceWithValue(node, value, effect, control);
1153 return Replace(value);
1154 }
1155
1166 // We can only assume that the {index} is a valid array index if the IC 1156 // We can only assume that the {index} is a valid array index if the IC
1167 // is in element access mode and not MEGAMORPHIC, otherwise there's no 1157 // is in element access mode and not MEGAMORPHIC, otherwise there's no
1168 // guard for the bounds check below. 1158 // guard for the bounds check below.
1169 if (nexus.ic_state() != MEGAMORPHIC && nexus.GetKeyType() == ELEMENT) { 1159 if (nexus.ic_state() != MEGAMORPHIC && nexus.GetKeyType() == ELEMENT) {
1170 // Strings are immutable in JavaScript. 1160 // Ensure that {index} is less than {receiver} length.
1171 if (access_mode == AccessMode::kStore) return NoChange(); 1161 Node* length = jsgraph()->Constant(string->length());
1162 index = effect = graph()->NewNode(simplified()->CheckBounds(), index,
1163 length, effect, control);
1172 1164
1173 // Properly deal with constant {index}. 1165 // Return the character from the {receiver} as single character string.
1174 NumberMatcher mindex(index); 1166 value = graph()->NewNode(simplified()->StringCharAt(), receiver, index,
1175 if (mindex.IsInteger() && mindex.IsInRange(0.0, string->length() - 1)) { 1167 control);
1176 // Constant-fold the {index} access to {string}. 1168 ReplaceWithValue(node, value, effect, control);
1177 Node* value = jsgraph()->HeapConstant( 1169 return Replace(value);
1178 factory()->LookupSingleCharacterStringFromCode(
1179 string->Get(static_cast<int>(mindex.Value()))));
1180 ReplaceWithValue(node, value, effect, control);
1181 return Replace(value);
1182 } else if (flags() & kDeoptimizationEnabled) {
1183 // Ensure that {index} is less than {receiver} length.
1184 Node* length = jsgraph()->Constant(string->length());
1185 index = effect = graph()->NewNode(simplified()->CheckBounds(), index,
1186 length, effect, control);
1187
1188 // Return the character from the {receiver} as single character string.
1189 value = graph()->NewNode(simplified()->StringCharAt(), receiver, index,
1190 control);
1191 ReplaceWithValue(node, value, effect, control);
1192 return Replace(value);
1193 }
1194 } 1170 }
1195 } 1171 }
1196 1172
1197 // Check if the {nexus} reports type feedback for the IC. 1173 // Check if the {nexus} reports type feedback for the IC.
1198 if (nexus.IsUninitialized()) { 1174 if (nexus.IsUninitialized()) {
1199 if ((flags() & kDeoptimizationEnabled) && 1175 if (flags() & kBailoutOnUninitialized) {
1200 (flags() & kBailoutOnUninitialized)) {
1201 return ReduceSoftDeoptimize( 1176 return ReduceSoftDeoptimize(
1202 node, 1177 node,
1203 DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess); 1178 DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess);
1204 } 1179 }
1205 return NoChange(); 1180 return NoChange();
1206 } 1181 }
1207 1182
1208 // Extract receiver maps from the {nexus}. 1183 // Extract receiver maps from the {nexus}.
1209 MapHandleList receiver_maps; 1184 MapHandleList receiver_maps;
1210 if (!ExtractReceiverMaps(receiver, effect, nexus, &receiver_maps)) { 1185 if (!ExtractReceiverMaps(receiver, effect, nexus, &receiver_maps)) {
1211 return NoChange(); 1186 return NoChange();
1212 } else if (receiver_maps.length() == 0) { 1187 } else if (receiver_maps.length() == 0) {
1213 if ((flags() & kDeoptimizationEnabled) && 1188 if (flags() & kBailoutOnUninitialized) {
1214 (flags() & kBailoutOnUninitialized)) {
1215 return ReduceSoftDeoptimize( 1189 return ReduceSoftDeoptimize(
1216 node, 1190 node,
1217 DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess); 1191 DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess);
1218 } 1192 }
1219 return NoChange(); 1193 return NoChange();
1220 } 1194 }
1221 1195
1222 // Optimize access for constant {index}. 1196 // Optimize access for constant {index}.
1223 HeapObjectMatcher mindex(index); 1197 HeapObjectMatcher mindex(index);
1224 if (mindex.HasValue() && mindex.Value()->IsPrimitive()) { 1198 if (mindex.HasValue() && mindex.Value()->IsPrimitive()) {
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
1674 control = graph()->NewNode(common()->IfSuccess(), control); 1648 control = graph()->NewNode(common()->IfSuccess(), control);
1675 } 1649 }
1676 1650
1677 return ValueEffectControl(value, effect, control); 1651 return ValueEffectControl(value, effect, control);
1678 } 1652 }
1679 1653
1680 Reduction JSNativeContextSpecialization::ReduceJSStoreDataPropertyInLiteral( 1654 Reduction JSNativeContextSpecialization::ReduceJSStoreDataPropertyInLiteral(
1681 Node* node) { 1655 Node* node) {
1682 DCHECK_EQ(IrOpcode::kJSStoreDataPropertyInLiteral, node->opcode()); 1656 DCHECK_EQ(IrOpcode::kJSStoreDataPropertyInLiteral, node->opcode());
1683 1657
1684 // If deoptimization is disabled, we cannot optimize.
1685 if (!(flags() & kDeoptimizationEnabled)) return NoChange();
1686
1687 FeedbackParameter const& p = FeedbackParameterOf(node->op()); 1658 FeedbackParameter const& p = FeedbackParameterOf(node->op());
1688 1659
1689 if (!p.feedback().IsValid()) return NoChange(); 1660 if (!p.feedback().IsValid()) return NoChange();
1690 1661
1691 StoreDataPropertyInLiteralICNexus nexus(p.feedback().vector(), 1662 StoreDataPropertyInLiteralICNexus nexus(p.feedback().vector(),
1692 p.feedback().slot()); 1663 p.feedback().slot());
1693 if (nexus.IsUninitialized()) { 1664 if (nexus.IsUninitialized()) {
1694 return NoChange(); 1665 return NoChange();
1695 } 1666 }
1696 1667
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after
2330 return jsgraph()->javascript(); 2301 return jsgraph()->javascript();
2331 } 2302 }
2332 2303
2333 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { 2304 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const {
2334 return jsgraph()->simplified(); 2305 return jsgraph()->simplified();
2335 } 2306 }
2336 2307
2337 } // namespace compiler 2308 } // namespace compiler
2338 } // namespace internal 2309 } // namespace internal
2339 } // namespace v8 2310 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-native-context-specialization.h ('k') | src/compiler/pipeline.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698