| 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 20 matching lines...) Expand all Loading... |
| 31 flags_(flags), | 31 flags_(flags), |
| 32 native_context_(native_context), | 32 native_context_(native_context), |
| 33 dependencies_(dependencies), | 33 dependencies_(dependencies), |
| 34 zone_(zone), | 34 zone_(zone), |
| 35 type_cache_(TypeCache::Get()), | 35 type_cache_(TypeCache::Get()), |
| 36 access_info_factory_(dependencies, native_context, graph()->zone()) {} | 36 access_info_factory_(dependencies, native_context, graph()->zone()) {} |
| 37 | 37 |
| 38 | 38 |
| 39 Reduction JSNativeContextSpecialization::Reduce(Node* node) { | 39 Reduction JSNativeContextSpecialization::Reduce(Node* node) { |
| 40 switch (node->opcode()) { | 40 switch (node->opcode()) { |
| 41 case IrOpcode::kJSCallFunction: | |
| 42 return ReduceJSCallFunction(node); | |
| 43 case IrOpcode::kJSLoadNamed: | 41 case IrOpcode::kJSLoadNamed: |
| 44 return ReduceJSLoadNamed(node); | 42 return ReduceJSLoadNamed(node); |
| 45 case IrOpcode::kJSStoreNamed: | 43 case IrOpcode::kJSStoreNamed: |
| 46 return ReduceJSStoreNamed(node); | 44 return ReduceJSStoreNamed(node); |
| 47 case IrOpcode::kJSLoadProperty: | 45 case IrOpcode::kJSLoadProperty: |
| 48 return ReduceJSLoadProperty(node); | 46 return ReduceJSLoadProperty(node); |
| 49 case IrOpcode::kJSStoreProperty: | 47 case IrOpcode::kJSStoreProperty: |
| 50 return ReduceJSStoreProperty(node); | 48 return ReduceJSStoreProperty(node); |
| 51 default: | 49 default: |
| 52 break; | 50 break; |
| 53 } | 51 } |
| 54 return NoChange(); | 52 return NoChange(); |
| 55 } | 53 } |
| 56 | 54 |
| 57 | 55 |
| 58 Reduction JSNativeContextSpecialization::ReduceJSCallFunction(Node* node) { | |
| 59 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); | |
| 60 CallFunctionParameters const& p = CallFunctionParametersOf(node->op()); | |
| 61 Node* target = NodeProperties::GetValueInput(node, 0); | |
| 62 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | |
| 63 Node* control = NodeProperties::GetControlInput(node); | |
| 64 Node* effect = NodeProperties::GetEffectInput(node); | |
| 65 | |
| 66 // Not much we can do if deoptimization support is disabled. | |
| 67 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); | |
| 68 | |
| 69 // Don't mess with JSCallFunction nodes that have a constant {target}. | |
| 70 if (HeapObjectMatcher(target).HasValue()) return NoChange(); | |
| 71 if (!p.feedback().IsValid()) return NoChange(); | |
| 72 CallICNexus nexus(p.feedback().vector(), p.feedback().slot()); | |
| 73 Handle<Object> feedback(nexus.GetFeedback(), isolate()); | |
| 74 if (feedback->IsWeakCell()) { | |
| 75 Handle<WeakCell> cell = Handle<WeakCell>::cast(feedback); | |
| 76 if (cell->value()->IsJSFunction()) { | |
| 77 // Avoid cross-context leaks, meaning don't embed references to functions | |
| 78 // in other native contexts. | |
| 79 Handle<JSFunction> function(JSFunction::cast(cell->value()), isolate()); | |
| 80 if (function->context()->native_context() != *native_context()) { | |
| 81 return NoChange(); | |
| 82 } | |
| 83 | |
| 84 // Check that the {target} is still the {target_function}. | |
| 85 Node* target_function = jsgraph()->HeapConstant(function); | |
| 86 Node* check = graph()->NewNode(simplified()->ReferenceEqual(Type::Any()), | |
| 87 target, target_function); | |
| 88 Node* branch = | |
| 89 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); | |
| 90 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | |
| 91 Node* deoptimize = graph()->NewNode(common()->Deoptimize(), frame_state, | |
| 92 effect, if_false); | |
| 93 // TODO(bmeurer): This should be on the AdvancedReducer somehow. | |
| 94 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); | |
| 95 control = graph()->NewNode(common()->IfTrue(), branch); | |
| 96 | |
| 97 // Specialize the JSCallFunction node to the {target_function}. | |
| 98 NodeProperties::ReplaceValueInput(node, target_function, 0); | |
| 99 NodeProperties::ReplaceControlInput(node, control); | |
| 100 return Changed(node); | |
| 101 } | |
| 102 // TODO(bmeurer): Also support optimizing bound functions and proxies here. | |
| 103 } | |
| 104 return NoChange(); | |
| 105 } | |
| 106 | |
| 107 | |
| 108 Reduction JSNativeContextSpecialization::ReduceNamedAccess( | 56 Reduction JSNativeContextSpecialization::ReduceNamedAccess( |
| 109 Node* node, Node* value, MapHandleList const& receiver_maps, | 57 Node* node, Node* value, MapHandleList const& receiver_maps, |
| 110 Handle<Name> name, AccessMode access_mode, LanguageMode language_mode, | 58 Handle<Name> name, AccessMode access_mode, LanguageMode language_mode, |
| 111 Node* index) { | 59 Node* index) { |
| 112 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed || | 60 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed || |
| 113 node->opcode() == IrOpcode::kJSStoreNamed || | 61 node->opcode() == IrOpcode::kJSStoreNamed || |
| 114 node->opcode() == IrOpcode::kJSLoadProperty || | 62 node->opcode() == IrOpcode::kJSLoadProperty || |
| 115 node->opcode() == IrOpcode::kJSStoreProperty); | 63 node->opcode() == IrOpcode::kJSStoreProperty); |
| 116 Node* receiver = NodeProperties::GetValueInput(node, 0); | 64 Node* receiver = NodeProperties::GetValueInput(node, 0); |
| 117 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 65 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); |
| (...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1013 } | 961 } |
| 1014 | 962 |
| 1015 | 963 |
| 1016 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 964 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
| 1017 return jsgraph()->simplified(); | 965 return jsgraph()->simplified(); |
| 1018 } | 966 } |
| 1019 | 967 |
| 1020 } // namespace compiler | 968 } // namespace compiler |
| 1021 } // namespace internal | 969 } // namespace internal |
| 1022 } // namespace v8 | 970 } // namespace v8 |
| OLD | NEW |