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

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

Issue 2809923002: Unify implementations of Map handles vectors and lists (Closed)
Patch Set: Review feedback 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/js-native-context-specialization.h ('k') | src/crankshaft/hydrogen.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"
11 #include "src/compiler/access-info.h" 11 #include "src/compiler/access-info.h"
12 #include "src/compiler/js-graph.h" 12 #include "src/compiler/js-graph.h"
13 #include "src/compiler/js-operator.h" 13 #include "src/compiler/js-operator.h"
14 #include "src/compiler/linkage.h" 14 #include "src/compiler/linkage.h"
15 #include "src/compiler/node-matchers.h" 15 #include "src/compiler/node-matchers.h"
16 #include "src/compiler/type-cache.h" 16 #include "src/compiler/type-cache.h"
17 #include "src/feedback-vector.h" 17 #include "src/feedback-vector.h"
18 #include "src/field-index-inl.h" 18 #include "src/field-index-inl.h"
19 #include "src/isolate-inl.h" 19 #include "src/isolate-inl.h"
20 20
21 namespace v8 { 21 namespace v8 {
22 namespace internal { 22 namespace internal {
23 namespace compiler { 23 namespace compiler {
24 24
25 namespace { 25 namespace {
26 26
27 bool HasNumberMaps(MapList const& maps) { 27 bool HasNumberMaps(MapHandles const& maps) {
28 for (auto map : maps) { 28 for (auto map : maps) {
29 if (map->instance_type() == HEAP_NUMBER_TYPE) return true; 29 if (map->instance_type() == HEAP_NUMBER_TYPE) return true;
30 } 30 }
31 return false; 31 return false;
32 } 32 }
33 33
34 bool HasOnlyJSArrayMaps(MapList const& maps) { 34 bool HasOnlyJSArrayMaps(MapHandles const& maps) {
35 for (auto map : maps) { 35 for (auto map : maps) {
36 if (!map->IsJSArrayMap()) return false; 36 if (!map->IsJSArrayMap()) return false;
37 } 37 }
38 return true; 38 return true;
39 } 39 }
40 40
41 bool HasOnlyNumberMaps(MapList const& maps) { 41 bool HasOnlyNumberMaps(MapHandles const& maps) {
42 for (auto map : maps) { 42 for (auto map : maps) {
43 if (map->instance_type() != HEAP_NUMBER_TYPE) return false; 43 if (map->instance_type() != HEAP_NUMBER_TYPE) return false;
44 } 44 }
45 return true; 45 return true;
46 } 46 }
47 47
48 template <typename T> 48 template <typename T>
49 bool HasOnlyStringMaps(T const& maps) { 49 bool HasOnlyStringMaps(T const& maps) {
50 for (auto map : maps) { 50 for (auto map : maps) {
51 if (!map->IsStringMap()) return false; 51 if (!map->IsStringMap()) return false;
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 value, context, effect, control); 699 value, context, effect, control);
700 ReplaceWithValue(node, value, effect, control); 700 ReplaceWithValue(node, value, effect, control);
701 return Replace(value); 701 return Replace(value);
702 } 702 }
703 703
704 // Lookup the {name} on the global object instead. 704 // Lookup the {name} on the global object instead.
705 return ReduceGlobalAccess(node, nullptr, value, name, AccessMode::kStore); 705 return ReduceGlobalAccess(node, nullptr, value, name, AccessMode::kStore);
706 } 706 }
707 707
708 Reduction JSNativeContextSpecialization::ReduceNamedAccess( 708 Reduction JSNativeContextSpecialization::ReduceNamedAccess(
709 Node* node, Node* value, MapHandleList const& receiver_maps, 709 Node* node, Node* value, MapHandles const& receiver_maps, Handle<Name> name,
710 Handle<Name> name, AccessMode access_mode, LanguageMode language_mode, 710 AccessMode access_mode, LanguageMode language_mode, Node* index) {
711 Node* index) {
712 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed || 711 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed ||
713 node->opcode() == IrOpcode::kJSStoreNamed || 712 node->opcode() == IrOpcode::kJSStoreNamed ||
714 node->opcode() == IrOpcode::kJSLoadProperty || 713 node->opcode() == IrOpcode::kJSLoadProperty ||
715 node->opcode() == IrOpcode::kJSStoreProperty || 714 node->opcode() == IrOpcode::kJSStoreProperty ||
716 node->opcode() == IrOpcode::kJSStoreNamedOwn); 715 node->opcode() == IrOpcode::kJSStoreNamedOwn);
717 Node* receiver = NodeProperties::GetValueInput(node, 0); 716 Node* receiver = NodeProperties::GetValueInput(node, 0);
718 Node* context = NodeProperties::GetContextInput(node); 717 Node* context = NodeProperties::GetContextInput(node);
719 Node* frame_state = NodeProperties::GetFrameStateInput(node); 718 Node* frame_state = NodeProperties::GetFrameStateInput(node);
720 Node* effect = NodeProperties::GetEffectInput(node); 719 Node* effect = NodeProperties::GetEffectInput(node);
721 Node* control = NodeProperties::GetControlInput(node); 720 Node* control = NodeProperties::GetControlInput(node);
722 721
723 // Check if we have an access o.x or o.x=v where o is the current 722 // Check if we have an access o.x or o.x=v where o is the current
724 // native contexts' global proxy, and turn that into a direct access 723 // native contexts' global proxy, and turn that into a direct access
725 // to the current native contexts' global object instead. 724 // to the current native contexts' global object instead.
726 if (receiver_maps.length() == 1) { 725 if (receiver_maps.size() == 1) {
727 Handle<Map> receiver_map = receiver_maps.first(); 726 Handle<Map> receiver_map = receiver_maps.front();
728 if (receiver_map->IsJSGlobalProxyMap()) { 727 if (receiver_map->IsJSGlobalProxyMap()) {
729 Object* maybe_constructor = receiver_map->GetConstructor(); 728 Object* maybe_constructor = receiver_map->GetConstructor();
730 // Detached global proxies have |null| as their constructor. 729 // Detached global proxies have |null| as their constructor.
731 if (maybe_constructor->IsJSFunction() && 730 if (maybe_constructor->IsJSFunction() &&
732 JSFunction::cast(maybe_constructor)->native_context() == 731 JSFunction::cast(maybe_constructor)->native_context() ==
733 *native_context()) { 732 *native_context()) {
734 return ReduceGlobalAccess(node, receiver, value, name, access_mode, 733 return ReduceGlobalAccess(node, receiver, value, name, access_mode,
735 index); 734 index);
736 } 735 }
737 } 736 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
834 // Generate code for the various different property access patterns. 833 // Generate code for the various different property access patterns.
835 Node* fallthrough_control = control; 834 Node* fallthrough_control = control;
836 for (size_t j = 0; j < access_infos.size(); ++j) { 835 for (size_t j = 0; j < access_infos.size(); ++j) {
837 PropertyAccessInfo const& access_info = access_infos[j]; 836 PropertyAccessInfo const& access_info = access_infos[j];
838 Node* this_value = value; 837 Node* this_value = value;
839 Node* this_receiver = receiver; 838 Node* this_receiver = receiver;
840 Node* this_effect = effect; 839 Node* this_effect = effect;
841 Node* this_control = fallthrough_control; 840 Node* this_control = fallthrough_control;
842 841
843 // Perform map check on {receiver}. 842 // Perform map check on {receiver}.
844 MapList const& receiver_maps = access_info.receiver_maps(); 843 MapHandles const& receiver_maps = access_info.receiver_maps();
845 { 844 {
846 // Emit a (sequence of) map checks for other {receiver}s. 845 // Emit a (sequence of) map checks for other {receiver}s.
847 ZoneVector<Node*> this_controls(zone()); 846 ZoneVector<Node*> this_controls(zone());
848 ZoneVector<Node*> this_effects(zone()); 847 ZoneVector<Node*> this_effects(zone());
849 if (j == access_infos.size() - 1) { 848 if (j == access_infos.size() - 1) {
850 // Last map check on the fallthrough control path, do a 849 // Last map check on the fallthrough control path, do a
851 // conditional eager deoptimization exit here. 850 // conditional eager deoptimization exit here.
852 this_effect = BuildCheckMaps(receiver, this_effect, this_control, 851 this_effect = BuildCheckMaps(receiver, this_effect, this_control,
853 receiver_maps); 852 receiver_maps);
854 this_effects.push_back(this_effect); 853 this_effects.push_back(this_effect);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
949 if (nexus.IsUninitialized()) { 948 if (nexus.IsUninitialized()) {
950 if (flags() & kBailoutOnUninitialized) { 949 if (flags() & kBailoutOnUninitialized) {
951 return ReduceSoftDeoptimize( 950 return ReduceSoftDeoptimize(
952 node, 951 node,
953 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); 952 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess);
954 } 953 }
955 return NoChange(); 954 return NoChange();
956 } 955 }
957 956
958 // Extract receiver maps from the IC using the {nexus}. 957 // Extract receiver maps from the IC using the {nexus}.
959 MapHandleList receiver_maps; 958 MapHandles receiver_maps;
960 if (!ExtractReceiverMaps(receiver, effect, nexus, &receiver_maps)) { 959 if (!ExtractReceiverMaps(receiver, effect, nexus, &receiver_maps)) {
961 return NoChange(); 960 return NoChange();
962 } else if (receiver_maps.length() == 0) { 961 } else if (receiver_maps.empty()) {
963 if (flags() & kBailoutOnUninitialized) { 962 if (flags() & kBailoutOnUninitialized) {
964 return ReduceSoftDeoptimize( 963 return ReduceSoftDeoptimize(
965 node, 964 node,
966 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); 965 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess);
967 } 966 }
968 return NoChange(); 967 return NoChange();
969 } 968 }
970 969
971 // Try to lower the named access based on the {receiver_maps}. 970 // Try to lower the named access based on the {receiver_maps}.
972 return ReduceNamedAccess(node, value, receiver_maps, name, access_mode, 971 return ReduceNamedAccess(node, value, receiver_maps, name, access_mode,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1040 // Extract receiver maps from the IC using the StoreOwnICNexus. 1039 // Extract receiver maps from the IC using the StoreOwnICNexus.
1041 if (!p.feedback().IsValid()) return NoChange(); 1040 if (!p.feedback().IsValid()) return NoChange();
1042 StoreOwnICNexus nexus(p.feedback().vector(), p.feedback().slot()); 1041 StoreOwnICNexus nexus(p.feedback().vector(), p.feedback().slot());
1043 1042
1044 // Try to lower the creation of a named property based on the {receiver_maps}. 1043 // Try to lower the creation of a named property based on the {receiver_maps}.
1045 return ReduceNamedAccessFromNexus(node, value, nexus, p.name(), 1044 return ReduceNamedAccessFromNexus(node, value, nexus, p.name(),
1046 AccessMode::kStoreInLiteral, STRICT); 1045 AccessMode::kStoreInLiteral, STRICT);
1047 } 1046 }
1048 1047
1049 Reduction JSNativeContextSpecialization::ReduceElementAccess( 1048 Reduction JSNativeContextSpecialization::ReduceElementAccess(
1050 Node* node, Node* index, Node* value, MapHandleList const& receiver_maps, 1049 Node* node, Node* index, Node* value, MapHandles const& receiver_maps,
1051 AccessMode access_mode, LanguageMode language_mode, 1050 AccessMode access_mode, LanguageMode language_mode,
1052 KeyedAccessStoreMode store_mode) { 1051 KeyedAccessStoreMode store_mode) {
1053 DCHECK(node->opcode() == IrOpcode::kJSLoadProperty || 1052 DCHECK(node->opcode() == IrOpcode::kJSLoadProperty ||
1054 node->opcode() == IrOpcode::kJSStoreProperty); 1053 node->opcode() == IrOpcode::kJSStoreProperty);
1055 Node* receiver = NodeProperties::GetValueInput(node, 0); 1054 Node* receiver = NodeProperties::GetValueInput(node, 0);
1056 Node* effect = NodeProperties::GetEffectInput(node); 1055 Node* effect = NodeProperties::GetEffectInput(node);
1057 Node* control = NodeProperties::GetControlInput(node); 1056 Node* control = NodeProperties::GetControlInput(node);
1058 Node* frame_state = NodeProperties::FindFrameStateBefore(node); 1057 Node* frame_state = NodeProperties::FindFrameStateBefore(node);
1059 1058
1060 // Check for keyed access to strings. 1059 // Check for keyed access to strings.
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1204 transition_source, transition_target)), 1203 transition_source, transition_target)),
1205 receiver, this_effect, this_control); 1204 receiver, this_effect, this_control);
1206 } 1205 }
1207 1206
1208 // Load the {receiver} map. 1207 // Load the {receiver} map.
1209 Node* receiver_map = this_effect = 1208 Node* receiver_map = this_effect =
1210 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), 1209 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
1211 receiver, this_effect, this_control); 1210 receiver, this_effect, this_control);
1212 1211
1213 // Perform map check(s) on {receiver}. 1212 // Perform map check(s) on {receiver}.
1214 MapList const& receiver_maps = access_info.receiver_maps(); 1213 MapHandles const& receiver_maps = access_info.receiver_maps();
1215 if (j == access_infos.size() - 1) { 1214 if (j == access_infos.size() - 1) {
1216 // Last map check on the fallthrough control path, do a 1215 // Last map check on the fallthrough control path, do a
1217 // conditional eager deoptimization exit here. 1216 // conditional eager deoptimization exit here.
1218 this_effect = BuildCheckMaps(receiver, this_effect, this_control, 1217 this_effect = BuildCheckMaps(receiver, this_effect, this_control,
1219 receiver_maps); 1218 receiver_maps);
1220 fallthrough_control = nullptr; 1219 fallthrough_control = nullptr;
1221 } else { 1220 } else {
1222 ZoneVector<Node*> this_controls(zone()); 1221 ZoneVector<Node*> this_controls(zone());
1223 ZoneVector<Node*> this_effects(zone()); 1222 ZoneVector<Node*> this_effects(zone());
1224 for (Handle<Map> map : receiver_maps) { 1223 for (Handle<Map> map : receiver_maps) {
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 if (nexus.IsUninitialized()) { 1336 if (nexus.IsUninitialized()) {
1338 if (flags() & kBailoutOnUninitialized) { 1337 if (flags() & kBailoutOnUninitialized) {
1339 return ReduceSoftDeoptimize( 1338 return ReduceSoftDeoptimize(
1340 node, 1339 node,
1341 DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess); 1340 DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess);
1342 } 1341 }
1343 return NoChange(); 1342 return NoChange();
1344 } 1343 }
1345 1344
1346 // Extract receiver maps from the {nexus}. 1345 // Extract receiver maps from the {nexus}.
1347 MapHandleList receiver_maps; 1346 MapHandles receiver_maps;
1348 if (!ExtractReceiverMaps(receiver, effect, nexus, &receiver_maps)) { 1347 if (!ExtractReceiverMaps(receiver, effect, nexus, &receiver_maps)) {
1349 return NoChange(); 1348 return NoChange();
1350 } else if (receiver_maps.length() == 0) { 1349 } else if (receiver_maps.empty()) {
1351 if (flags() & kBailoutOnUninitialized) { 1350 if (flags() & kBailoutOnUninitialized) {
1352 return ReduceSoftDeoptimize( 1351 return ReduceSoftDeoptimize(
1353 node, 1352 node,
1354 DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess); 1353 DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess);
1355 } 1354 }
1356 return NoChange(); 1355 return NoChange();
1357 } 1356 }
1358 1357
1359 // Optimize access for constant {index}. 1358 // Optimize access for constant {index}.
1360 HeapObjectMatcher mindex(index); 1359 HeapObjectMatcher mindex(index);
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
1904 JSNativeContextSpecialization::ValueEffectControl 1903 JSNativeContextSpecialization::ValueEffectControl
1905 JSNativeContextSpecialization::BuildElementAccess( 1904 JSNativeContextSpecialization::BuildElementAccess(
1906 Node* receiver, Node* index, Node* value, Node* effect, Node* control, 1905 Node* receiver, Node* index, Node* value, Node* effect, Node* control,
1907 ElementAccessInfo const& access_info, AccessMode access_mode, 1906 ElementAccessInfo const& access_info, AccessMode access_mode,
1908 KeyedAccessStoreMode store_mode) { 1907 KeyedAccessStoreMode store_mode) {
1909 DCHECK_NE(AccessMode::kStoreInLiteral, access_mode); 1908 DCHECK_NE(AccessMode::kStoreInLiteral, access_mode);
1910 1909
1911 // TODO(bmeurer): We currently specialize based on elements kind. We should 1910 // TODO(bmeurer): We currently specialize based on elements kind. We should
1912 // also be able to properly support strings and other JSObjects here. 1911 // also be able to properly support strings and other JSObjects here.
1913 ElementsKind elements_kind = access_info.elements_kind(); 1912 ElementsKind elements_kind = access_info.elements_kind();
1914 MapList const& receiver_maps = access_info.receiver_maps(); 1913 MapHandles const& receiver_maps = access_info.receiver_maps();
1915 1914
1916 if (IsFixedTypedArrayElementsKind(elements_kind)) { 1915 if (IsFixedTypedArrayElementsKind(elements_kind)) {
1917 Node* buffer; 1916 Node* buffer;
1918 Node* length; 1917 Node* length;
1919 Node* base_pointer; 1918 Node* base_pointer;
1920 Node* external_pointer; 1919 Node* external_pointer;
1921 1920
1922 // Check if we can constant-fold information about the {receiver} (i.e. 1921 // Check if we can constant-fold information about the {receiver} (i.e.
1923 // for asm.js-like code patterns). 1922 // for asm.js-like code patterns).
1924 HeapObjectMatcher m(receiver); 1923 HeapObjectMatcher m(receiver);
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
2275 } 2274 }
2276 default: { 2275 default: {
2277 return *effect = graph()->NewNode(simplified()->CheckHeapObject(), 2276 return *effect = graph()->NewNode(simplified()->CheckHeapObject(),
2278 receiver, *effect, control); 2277 receiver, *effect, control);
2279 } 2278 }
2280 } 2279 }
2281 } 2280 }
2282 2281
2283 Node* JSNativeContextSpecialization::BuildCheckMaps( 2282 Node* JSNativeContextSpecialization::BuildCheckMaps(
2284 Node* receiver, Node* effect, Node* control, 2283 Node* receiver, Node* effect, Node* control,
2285 std::vector<Handle<Map>> const& receiver_maps) { 2284 MapHandles const& receiver_maps) {
2286 HeapObjectMatcher m(receiver); 2285 HeapObjectMatcher m(receiver);
2287 if (m.HasValue()) { 2286 if (m.HasValue()) {
2288 Handle<Map> receiver_map(m.Value()->map(), isolate()); 2287 Handle<Map> receiver_map(m.Value()->map(), isolate());
2289 if (receiver_map->is_stable()) { 2288 if (receiver_map->is_stable()) {
2290 for (Handle<Map> map : receiver_maps) { 2289 for (Handle<Map> map : receiver_maps) {
2291 if (map.is_identical_to(receiver_map)) { 2290 if (map.is_identical_to(receiver_map)) {
2292 dependencies()->AssumeMapStable(receiver_map); 2291 dependencies()->AssumeMapStable(receiver_map);
2293 return effect; 2292 return effect;
2294 } 2293 }
2295 } 2294 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2349 new_properties, jsgraph()->Constant(new_length), effect, control); 2348 new_properties, jsgraph()->Constant(new_length), effect, control);
2350 for (int i = 0; i < new_length; ++i) { 2349 for (int i = 0; i < new_length; ++i) {
2351 effect = graph()->NewNode( 2350 effect = graph()->NewNode(
2352 simplified()->StoreField(AccessBuilder::ForFixedArraySlot(i)), 2351 simplified()->StoreField(AccessBuilder::ForFixedArraySlot(i)),
2353 new_properties, values[i], effect, control); 2352 new_properties, values[i], effect, control);
2354 } 2353 }
2355 return graph()->NewNode(common()->FinishRegion(), new_properties, effect); 2354 return graph()->NewNode(common()->FinishRegion(), new_properties, effect);
2356 } 2355 }
2357 2356
2358 void JSNativeContextSpecialization::AssumePrototypesStable( 2357 void JSNativeContextSpecialization::AssumePrototypesStable(
2359 std::vector<Handle<Map>> const& receiver_maps, Handle<JSObject> holder) { 2358 MapHandles const& receiver_maps, Handle<JSObject> holder) {
2360 // Determine actual holder and perform prototype chain checks. 2359 // Determine actual holder and perform prototype chain checks.
2361 for (auto map : receiver_maps) { 2360 for (auto map : receiver_maps) {
2362 // Perform the implicit ToObject for primitives here. 2361 // Perform the implicit ToObject for primitives here.
2363 // Implemented according to ES6 section 7.3.2 GetV (V, P). 2362 // Implemented according to ES6 section 7.3.2 GetV (V, P).
2364 Handle<JSFunction> constructor; 2363 Handle<JSFunction> constructor;
2365 if (Map::GetConstructorFunction(map, native_context()) 2364 if (Map::GetConstructorFunction(map, native_context())
2366 .ToHandle(&constructor)) { 2365 .ToHandle(&constructor)) {
2367 map = handle(constructor->initial_map(), isolate()); 2366 map = handle(constructor->initial_map(), isolate());
2368 } 2367 }
2369 dependencies()->AssumePrototypeMapsStable(map, holder); 2368 dependencies()->AssumePrototypeMapsStable(map, holder);
2370 } 2369 }
2371 } 2370 }
2372 2371
2373 bool JSNativeContextSpecialization::CanTreatHoleAsUndefined( 2372 bool JSNativeContextSpecialization::CanTreatHoleAsUndefined(
2374 std::vector<Handle<Map>> const& receiver_maps) { 2373 MapHandles const& receiver_maps) {
2375 // Check if the array prototype chain is intact. 2374 // Check if the array prototype chain is intact.
2376 if (!isolate()->IsFastArrayConstructorPrototypeChainIntact()) return false; 2375 if (!isolate()->IsFastArrayConstructorPrototypeChainIntact()) return false;
2377 2376
2378 // Make sure both the initial Array and Object prototypes are stable. 2377 // Make sure both the initial Array and Object prototypes are stable.
2379 Handle<JSObject> initial_array_prototype( 2378 Handle<JSObject> initial_array_prototype(
2380 native_context()->initial_array_prototype(), isolate()); 2379 native_context()->initial_array_prototype(), isolate());
2381 Handle<JSObject> initial_object_prototype( 2380 Handle<JSObject> initial_object_prototype(
2382 native_context()->initial_object_prototype(), isolate()); 2381 native_context()->initial_object_prototype(), isolate());
2383 if (!initial_array_prototype->map()->is_stable() || 2382 if (!initial_array_prototype->map()->is_stable() ||
2384 !initial_object_prototype->map()->is_stable()) { 2383 !initial_object_prototype->map()->is_stable()) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
2451 DCHECK_IMPLIES(all, !none); 2450 DCHECK_IMPLIES(all, !none);
2452 DCHECK_IMPLIES(none, !all); 2451 DCHECK_IMPLIES(none, !all);
2453 2452
2454 if (all) return kIsInPrototypeChain; 2453 if (all) return kIsInPrototypeChain;
2455 if (none) return kIsNotInPrototypeChain; 2454 if (none) return kIsNotInPrototypeChain;
2456 return kMayBeInPrototypeChain; 2455 return kMayBeInPrototypeChain;
2457 } 2456 }
2458 2457
2459 bool JSNativeContextSpecialization::ExtractReceiverMaps( 2458 bool JSNativeContextSpecialization::ExtractReceiverMaps(
2460 Node* receiver, Node* effect, FeedbackNexus const& nexus, 2459 Node* receiver, Node* effect, FeedbackNexus const& nexus,
2461 MapHandleList* receiver_maps) { 2460 MapHandles* receiver_maps) {
2462 DCHECK_EQ(0, receiver_maps->length()); 2461 DCHECK_EQ(0, receiver_maps->size());
2463 // See if we can infer a concrete type for the {receiver}. 2462 // See if we can infer a concrete type for the {receiver}.
2464 if (InferReceiverMaps(receiver, effect, receiver_maps)) { 2463 if (InferReceiverMaps(receiver, effect, receiver_maps)) {
2465 // We can assume that the {receiver} still has the infered {receiver_maps}. 2464 // We can assume that the {receiver} still has the infered {receiver_maps}.
2466 return true; 2465 return true;
2467 } 2466 }
2468 // Try to extract some maps from the {nexus}. 2467 // Try to extract some maps from the {nexus}.
2469 if (nexus.ExtractMaps(receiver_maps) != 0) { 2468 if (nexus.ExtractMaps(receiver_maps) != 0) {
2470 // Try to filter impossible candidates based on infered root map. 2469 // Try to filter impossible candidates based on infered root map.
2471 Handle<Map> receiver_map; 2470 Handle<Map> receiver_map;
2472 if (InferReceiverRootMap(receiver).ToHandle(&receiver_map)) { 2471 if (InferReceiverRootMap(receiver).ToHandle(&receiver_map)) {
2473 for (int i = receiver_maps->length(); --i >= 0;) { 2472 receiver_maps->erase(
2474 if (receiver_maps->at(i)->FindRootMap() != *receiver_map) { 2473 std::remove_if(receiver_maps->begin(), receiver_maps->end(),
2475 receiver_maps->Remove(i); 2474 [receiver_map](const Handle<Map>& map) {
2476 } 2475 return map->FindRootMap() != *receiver_map;
2477 } 2476 }),
2477 receiver_maps->end());
2478 } 2478 }
2479 return true; 2479 return true;
2480 } 2480 }
2481 return false; 2481 return false;
2482 } 2482 }
2483 2483
2484 bool JSNativeContextSpecialization::InferReceiverMaps( 2484 bool JSNativeContextSpecialization::InferReceiverMaps(
2485 Node* receiver, Node* effect, MapHandleList* receiver_maps) { 2485 Node* receiver, Node* effect, MapHandles* receiver_maps) {
2486 ZoneHandleSet<Map> maps; 2486 ZoneHandleSet<Map> maps;
2487 NodeProperties::InferReceiverMapsResult result = 2487 NodeProperties::InferReceiverMapsResult result =
2488 NodeProperties::InferReceiverMaps(receiver, effect, &maps); 2488 NodeProperties::InferReceiverMaps(receiver, effect, &maps);
2489 if (result == NodeProperties::kReliableReceiverMaps) { 2489 if (result == NodeProperties::kReliableReceiverMaps) {
2490 for (size_t i = 0; i < maps.size(); ++i) { 2490 for (size_t i = 0; i < maps.size(); ++i) {
2491 receiver_maps->Add(maps[i]); 2491 receiver_maps->push_back(maps[i]);
2492 } 2492 }
2493 return true; 2493 return true;
2494 } else if (result == NodeProperties::kUnreliableReceiverMaps) { 2494 } else if (result == NodeProperties::kUnreliableReceiverMaps) {
2495 // For untrusted receiver maps, we can still use the information 2495 // For untrusted receiver maps, we can still use the information
2496 // if the maps are stable. 2496 // if the maps are stable.
2497 for (size_t i = 0; i < maps.size(); ++i) { 2497 for (size_t i = 0; i < maps.size(); ++i) {
2498 if (!maps[i]->is_stable()) return false; 2498 if (!maps[i]->is_stable()) return false;
2499 } 2499 }
2500 for (size_t i = 0; i < maps.size(); ++i) { 2500 for (size_t i = 0; i < maps.size(); ++i) {
2501 receiver_maps->Add(maps[i]); 2501 receiver_maps->push_back(maps[i]);
2502 } 2502 }
2503 return true; 2503 return true;
2504 } 2504 }
2505 return false; 2505 return false;
2506 } 2506 }
2507 2507
2508 MaybeHandle<Map> JSNativeContextSpecialization::InferReceiverRootMap( 2508 MaybeHandle<Map> JSNativeContextSpecialization::InferReceiverRootMap(
2509 Node* receiver) { 2509 Node* receiver) {
2510 HeapObjectMatcher m(receiver); 2510 HeapObjectMatcher m(receiver);
2511 if (m.HasValue()) { 2511 if (m.HasValue()) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2570 return jsgraph()->javascript(); 2570 return jsgraph()->javascript();
2571 } 2571 }
2572 2572
2573 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { 2573 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const {
2574 return jsgraph()->simplified(); 2574 return jsgraph()->simplified();
2575 } 2575 }
2576 2576
2577 } // namespace compiler 2577 } // namespace compiler
2578 } // namespace internal 2578 } // namespace internal
2579 } // namespace v8 2579 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-native-context-specialization.h ('k') | src/crankshaft/hydrogen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698