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

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

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

Powered by Google App Engine
This is Rietveld 408576698