OLD | NEW |
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 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 control_count + 1, &values.front()); | 454 control_count + 1, &values.front()); |
455 effects.push_back(control); | 455 effects.push_back(control); |
456 effect = graph()->NewNode(common()->EffectPhi(control_count), | 456 effect = graph()->NewNode(common()->EffectPhi(control_count), |
457 control_count + 1, &effects.front()); | 457 control_count + 1, &effects.front()); |
458 } | 458 } |
459 ReplaceWithValue(node, value, effect, control); | 459 ReplaceWithValue(node, value, effect, control); |
460 return Replace(value); | 460 return Replace(value); |
461 } | 461 } |
462 | 462 |
463 | 463 |
| 464 Reduction JSNativeContextSpecialization::ReduceNamedAccess( |
| 465 Node* node, Node* value, FeedbackNexus const& nexus, Handle<Name> name, |
| 466 AccessMode access_mode, LanguageMode language_mode) { |
| 467 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed || |
| 468 node->opcode() == IrOpcode::kJSStoreNamed); |
| 469 |
| 470 // Check if the {nexus} reports type feedback for the IC. |
| 471 if (nexus.IsUninitialized()) { |
| 472 if ((flags() & kDeoptimizationEnabled) && |
| 473 (flags() & kBailoutOnUninitialized)) { |
| 474 // TODO(turbofan): Implement all eager bailout points correctly in |
| 475 // the graph builder. |
| 476 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); |
| 477 if (!OpParameter<FrameStateInfo>(frame_state).bailout_id().IsNone()) { |
| 478 return ReduceSoftDeoptimize(node); |
| 479 } |
| 480 } |
| 481 return NoChange(); |
| 482 } |
| 483 |
| 484 // Extract receiver maps from the IC using the {nexus}. |
| 485 MapHandleList receiver_maps; |
| 486 if (nexus.ExtractMaps(&receiver_maps) == 0) return NoChange(); |
| 487 DCHECK_LT(0, receiver_maps.length()); |
| 488 |
| 489 // Try to lower the named access based on the {receiver_maps}. |
| 490 return ReduceNamedAccess(node, value, receiver_maps, name, access_mode, |
| 491 language_mode); |
| 492 } |
| 493 |
| 494 |
464 Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) { | 495 Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) { |
465 DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode()); | 496 DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode()); |
466 NamedAccess const& p = NamedAccessOf(node->op()); | 497 NamedAccess const& p = NamedAccessOf(node->op()); |
467 Node* const value = jsgraph()->Dead(); | 498 Node* const value = jsgraph()->Dead(); |
468 | 499 |
469 // Extract receiver maps from the LOAD_IC using the LoadICNexus. | 500 // Extract receiver maps from the LOAD_IC using the LoadICNexus. |
470 MapHandleList receiver_maps; | |
471 if (!p.feedback().IsValid()) return NoChange(); | 501 if (!p.feedback().IsValid()) return NoChange(); |
472 LoadICNexus nexus(p.feedback().vector(), p.feedback().slot()); | 502 LoadICNexus nexus(p.feedback().vector(), p.feedback().slot()); |
473 if (nexus.ExtractMaps(&receiver_maps) == 0) return NoChange(); | |
474 DCHECK_LT(0, receiver_maps.length()); | |
475 | 503 |
476 // Try to lower the named access based on the {receiver_maps}. | 504 // Try to lower the named access based on the {receiver_maps}. |
477 return ReduceNamedAccess(node, value, receiver_maps, p.name(), | 505 return ReduceNamedAccess(node, value, nexus, p.name(), AccessMode::kLoad, |
478 AccessMode::kLoad, p.language_mode()); | 506 p.language_mode()); |
479 } | 507 } |
480 | 508 |
481 | 509 |
482 Reduction JSNativeContextSpecialization::ReduceJSStoreNamed(Node* node) { | 510 Reduction JSNativeContextSpecialization::ReduceJSStoreNamed(Node* node) { |
483 DCHECK_EQ(IrOpcode::kJSStoreNamed, node->opcode()); | 511 DCHECK_EQ(IrOpcode::kJSStoreNamed, node->opcode()); |
484 NamedAccess const& p = NamedAccessOf(node->op()); | 512 NamedAccess const& p = NamedAccessOf(node->op()); |
485 Node* const value = NodeProperties::GetValueInput(node, 1); | 513 Node* const value = NodeProperties::GetValueInput(node, 1); |
486 | 514 |
487 // Extract receiver maps from the STORE_IC using the StoreICNexus. | 515 // Extract receiver maps from the STORE_IC using the StoreICNexus. |
488 MapHandleList receiver_maps; | |
489 if (!p.feedback().IsValid()) return NoChange(); | 516 if (!p.feedback().IsValid()) return NoChange(); |
490 StoreICNexus nexus(p.feedback().vector(), p.feedback().slot()); | 517 StoreICNexus nexus(p.feedback().vector(), p.feedback().slot()); |
491 if (nexus.ExtractMaps(&receiver_maps) == 0) return NoChange(); | |
492 DCHECK_LT(0, receiver_maps.length()); | |
493 | 518 |
494 // Try to lower the named access based on the {receiver_maps}. | 519 // Try to lower the named access based on the {receiver_maps}. |
495 return ReduceNamedAccess(node, value, receiver_maps, p.name(), | 520 return ReduceNamedAccess(node, value, nexus, p.name(), AccessMode::kStore, |
496 AccessMode::kStore, p.language_mode()); | 521 p.language_mode()); |
497 } | 522 } |
498 | 523 |
499 | 524 |
500 Reduction JSNativeContextSpecialization::ReduceElementAccess( | 525 Reduction JSNativeContextSpecialization::ReduceElementAccess( |
501 Node* node, Node* index, Node* value, MapHandleList const& receiver_maps, | 526 Node* node, Node* index, Node* value, MapHandleList const& receiver_maps, |
502 AccessMode access_mode, LanguageMode language_mode, | 527 AccessMode access_mode, LanguageMode language_mode, |
503 KeyedAccessStoreMode store_mode) { | 528 KeyedAccessStoreMode store_mode) { |
504 DCHECK(node->opcode() == IrOpcode::kJSLoadProperty || | 529 DCHECK(node->opcode() == IrOpcode::kJSLoadProperty || |
505 node->opcode() == IrOpcode::kJSStoreProperty); | 530 node->opcode() == IrOpcode::kJSStoreProperty); |
506 Node* receiver = NodeProperties::GetValueInput(node, 0); | 531 Node* receiver = NodeProperties::GetValueInput(node, 0); |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
894 } | 919 } |
895 | 920 |
896 | 921 |
897 Reduction JSNativeContextSpecialization::ReduceKeyedAccess( | 922 Reduction JSNativeContextSpecialization::ReduceKeyedAccess( |
898 Node* node, Node* index, Node* value, FeedbackNexus const& nexus, | 923 Node* node, Node* index, Node* value, FeedbackNexus const& nexus, |
899 AccessMode access_mode, LanguageMode language_mode, | 924 AccessMode access_mode, LanguageMode language_mode, |
900 KeyedAccessStoreMode store_mode) { | 925 KeyedAccessStoreMode store_mode) { |
901 DCHECK(node->opcode() == IrOpcode::kJSLoadProperty || | 926 DCHECK(node->opcode() == IrOpcode::kJSLoadProperty || |
902 node->opcode() == IrOpcode::kJSStoreProperty); | 927 node->opcode() == IrOpcode::kJSStoreProperty); |
903 | 928 |
| 929 // Check if the {nexus} reports type feedback for the IC. |
| 930 if (nexus.IsUninitialized()) { |
| 931 if ((flags() & kDeoptimizationEnabled) && |
| 932 (flags() & kBailoutOnUninitialized)) { |
| 933 // TODO(turbofan): Implement all eager bailout points correctly in |
| 934 // the graph builder. |
| 935 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); |
| 936 if (!OpParameter<FrameStateInfo>(frame_state).bailout_id().IsNone()) { |
| 937 return ReduceSoftDeoptimize(node); |
| 938 } |
| 939 } |
| 940 return NoChange(); |
| 941 } |
| 942 |
904 // Extract receiver maps from the {nexus}. | 943 // Extract receiver maps from the {nexus}. |
905 MapHandleList receiver_maps; | 944 MapHandleList receiver_maps; |
906 if (nexus.ExtractMaps(&receiver_maps) == 0) return NoChange(); | 945 if (nexus.ExtractMaps(&receiver_maps) == 0) return NoChange(); |
907 DCHECK_LT(0, receiver_maps.length()); | 946 DCHECK_LT(0, receiver_maps.length()); |
908 | 947 |
909 // Optimize access for constant {index}. | 948 // Optimize access for constant {index}. |
910 HeapObjectMatcher mindex(index); | 949 HeapObjectMatcher mindex(index); |
911 if (mindex.HasValue() && mindex.Value()->IsPrimitive()) { | 950 if (mindex.HasValue() && mindex.Value()->IsPrimitive()) { |
912 // Keyed access requires a ToPropertyKey on the {index} first before | 951 // Keyed access requires a ToPropertyKey on the {index} first before |
913 // looking up the property on the object (see ES6 section 12.3.2.1). | 952 // looking up the property on the object (see ES6 section 12.3.2.1). |
(...skipping 19 matching lines...) Expand all Loading... |
933 handle(name, isolate()), access_mode, | 972 handle(name, isolate()), access_mode, |
934 language_mode, index); | 973 language_mode, index); |
935 } | 974 } |
936 | 975 |
937 // Try to lower the element access based on the {receiver_maps}. | 976 // Try to lower the element access based on the {receiver_maps}. |
938 return ReduceElementAccess(node, index, value, receiver_maps, access_mode, | 977 return ReduceElementAccess(node, index, value, receiver_maps, access_mode, |
939 language_mode, store_mode); | 978 language_mode, store_mode); |
940 } | 979 } |
941 | 980 |
942 | 981 |
| 982 Reduction JSNativeContextSpecialization::ReduceSoftDeoptimize(Node* node) { |
| 983 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); |
| 984 Node* effect = NodeProperties::GetEffectInput(node); |
| 985 Node* control = NodeProperties::GetControlInput(node); |
| 986 Node* deoptimize = |
| 987 graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kSoft), frame_state, |
| 988 effect, control); |
| 989 // TODO(bmeurer): This should be on the AdvancedReducer somehow. |
| 990 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); |
| 991 Revisit(graph()->end()); |
| 992 node->TrimInputCount(0); |
| 993 NodeProperties::ChangeOp(node, common()->Dead()); |
| 994 return Changed(node); |
| 995 } |
| 996 |
| 997 |
943 Reduction JSNativeContextSpecialization::ReduceJSLoadProperty(Node* node) { | 998 Reduction JSNativeContextSpecialization::ReduceJSLoadProperty(Node* node) { |
944 DCHECK_EQ(IrOpcode::kJSLoadProperty, node->opcode()); | 999 DCHECK_EQ(IrOpcode::kJSLoadProperty, node->opcode()); |
945 PropertyAccess const& p = PropertyAccessOf(node->op()); | 1000 PropertyAccess const& p = PropertyAccessOf(node->op()); |
946 Node* const index = NodeProperties::GetValueInput(node, 1); | 1001 Node* const index = NodeProperties::GetValueInput(node, 1); |
947 Node* const value = jsgraph()->Dead(); | 1002 Node* const value = jsgraph()->Dead(); |
948 | 1003 |
949 // Extract receiver maps from the KEYED_LOAD_IC using the KeyedLoadICNexus. | 1004 // Extract receiver maps from the KEYED_LOAD_IC using the KeyedLoadICNexus. |
950 if (!p.feedback().IsValid()) return NoChange(); | 1005 if (!p.feedback().IsValid()) return NoChange(); |
951 KeyedLoadICNexus nexus(p.feedback().vector(), p.feedback().slot()); | 1006 KeyedLoadICNexus nexus(p.feedback().vector(), p.feedback().slot()); |
952 | 1007 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1043 } | 1098 } |
1044 | 1099 |
1045 | 1100 |
1046 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 1101 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
1047 return jsgraph()->simplified(); | 1102 return jsgraph()->simplified(); |
1048 } | 1103 } |
1049 | 1104 |
1050 } // namespace compiler | 1105 } // namespace compiler |
1051 } // namespace internal | 1106 } // namespace internal |
1052 } // namespace v8 | 1107 } // namespace v8 |
OLD | NEW |