Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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-context-specialization.h" | 5 #include "src/compiler/js-context-specialization.h" |
| 6 | 6 |
| 7 #include "src/compiler/common-operator.h" | 7 #include "src/compiler/common-operator.h" |
| 8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
| 9 #include "src/compiler/js-operator.h" | 9 #include "src/compiler/js-operator.h" |
| 10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 76 return NoChange(); | 76 return NoChange(); |
| 77 } | 77 } |
| 78 | 78 |
| 79 const Operator* op = | 79 const Operator* op = |
| 80 jsgraph_->javascript()->StoreContext(new_depth, access.index()); | 80 jsgraph_->javascript()->StoreContext(new_depth, access.index()); |
| 81 NodeProperties::ReplaceContextInput(node, new_context); | 81 NodeProperties::ReplaceContextInput(node, new_context); |
| 82 NodeProperties::ChangeOp(node, op); | 82 NodeProperties::ChangeOp(node, op); |
| 83 return Changed(node); | 83 return Changed(node); |
| 84 } | 84 } |
| 85 | 85 |
| 86 namespace { | |
| 87 | |
| 88 bool IsContextParameter(Node* node) { | |
| 89 DCHECK_EQ(IrOpcode::kParameter, node->opcode()); | |
| 90 Node* const start = NodeProperties::GetValueInput(node, 0); | |
| 91 DCHECK_EQ(IrOpcode::kStart, start->opcode()); | |
| 92 int const index = ParameterIndexOf(node->op()); | |
| 93 // The context is always the last parameter to a JavaScript function, and | |
| 94 // {Parameter} indices start at -1, so value outputs of {Start} look like | |
| 95 // this: closure, receiver, param0, ..., paramN, context. | |
| 96 return index == start->op()->ValueOutputCount() - 2; | |
| 97 } | |
| 98 | |
| 99 MaybeHandle<Context> GetSpecializationContext(Node* node, | |
|
Michael Starzinger
2017/05/03 17:28:16
nit: Needs a short comment explaining the semantic
neis
2017/05/04 10:36:21
Done.
| |
| 100 size_t* requested_depth, | |
| 101 Maybe<OuterContext> maybe_outer) { | |
| 102 switch (node->opcode()) { | |
| 103 case IrOpcode::kHeapConstant: | |
| 104 return Handle<Context>::cast(OpParameter<Handle<HeapObject>>(node)); | |
| 105 case IrOpcode::kParameter: { | |
| 106 OuterContext outer; | |
| 107 if (maybe_outer.To(&outer) && IsContextParameter(node) && | |
| 108 *requested_depth >= outer.distance) { | |
| 109 *requested_depth -= outer.distance; | |
| 110 return outer.context; | |
| 111 } | |
| 112 break; | |
| 113 } | |
| 114 default: | |
| 115 break; | |
| 116 } | |
| 117 return MaybeHandle<Context>(); | |
| 118 } | |
| 119 | |
| 120 } // anonymous namespace | |
| 121 | |
| 86 Reduction JSContextSpecialization::ReduceJSLoadContext(Node* node) { | 122 Reduction JSContextSpecialization::ReduceJSLoadContext(Node* node) { |
| 87 DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode()); | 123 DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode()); |
| 88 | 124 |
| 89 const ContextAccess& access = ContextAccessOf(node->op()); | 125 const ContextAccess& access = ContextAccessOf(node->op()); |
| 90 size_t depth = access.depth(); | 126 size_t depth = access.depth(); |
| 91 | 127 |
| 92 // First walk up the context chain in the graph as far as possible. | 128 // First walk up the context chain in the graph as far as possible. |
| 93 Node* outer = NodeProperties::GetOuterContext(node, &depth); | 129 Node* context = NodeProperties::GetOuterContext(node, &depth); |
| 94 | 130 |
| 95 Handle<Context> concrete; | 131 Handle<Context> concrete; |
| 96 if (!NodeProperties::GetSpecializationContext(outer, context()) | 132 if (!GetSpecializationContext(context, &depth, outer()).ToHandle(&concrete)) { |
| 97 .ToHandle(&concrete)) { | |
| 98 // We do not have a concrete context object, so we can only partially reduce | 133 // We do not have a concrete context object, so we can only partially reduce |
| 99 // the load by folding-in the outer context node. | 134 // the load by folding-in the outer context node. |
| 100 return SimplifyJSLoadContext(node, outer, depth); | 135 return SimplifyJSLoadContext(node, context, depth); |
| 101 } | 136 } |
| 102 | 137 |
| 103 // Now walk up the concrete context chain for the remaining depth. | 138 // Now walk up the concrete context chain for the remaining depth. |
| 104 for (; depth > 0; --depth) { | 139 for (; depth > 0; --depth) { |
| 105 concrete = handle(concrete->previous(), isolate()); | 140 concrete = handle(concrete->previous(), isolate()); |
| 106 } | 141 } |
| 107 | 142 |
| 108 if (!access.immutable()) { | 143 if (!access.immutable()) { |
| 109 // We found the requested context object but since the context slot is | 144 // We found the requested context object but since the context slot is |
| 110 // mutable we can only partially reduce the load. | 145 // mutable we can only partially reduce the load. |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 132 | 167 |
| 133 | 168 |
| 134 Reduction JSContextSpecialization::ReduceJSStoreContext(Node* node) { | 169 Reduction JSContextSpecialization::ReduceJSStoreContext(Node* node) { |
| 135 DCHECK_EQ(IrOpcode::kJSStoreContext, node->opcode()); | 170 DCHECK_EQ(IrOpcode::kJSStoreContext, node->opcode()); |
| 136 | 171 |
| 137 const ContextAccess& access = ContextAccessOf(node->op()); | 172 const ContextAccess& access = ContextAccessOf(node->op()); |
| 138 size_t depth = access.depth(); | 173 size_t depth = access.depth(); |
| 139 | 174 |
| 140 // First walk up the context chain in the graph until we reduce the depth to 0 | 175 // First walk up the context chain in the graph until we reduce the depth to 0 |
| 141 // or hit a node that does not have a CreateXYZContext operator. | 176 // or hit a node that does not have a CreateXYZContext operator. |
| 142 Node* outer = NodeProperties::GetOuterContext(node, &depth); | 177 Node* context = NodeProperties::GetOuterContext(node, &depth); |
| 143 | 178 |
| 144 Handle<Context> concrete; | 179 Handle<Context> concrete; |
| 145 if (!NodeProperties::GetSpecializationContext(outer, context()) | 180 if (!GetSpecializationContext(context, &depth, outer()).ToHandle(&concrete)) { |
| 146 .ToHandle(&concrete)) { | |
| 147 // We do not have a concrete context object, so we can only partially reduce | 181 // We do not have a concrete context object, so we can only partially reduce |
| 148 // the load by folding-in the outer context node. | 182 // the load by folding-in the outer context node. |
| 149 return SimplifyJSStoreContext(node, outer, depth); | 183 return SimplifyJSStoreContext(node, context, depth); |
| 150 } | 184 } |
| 151 | 185 |
| 152 // Now walk up the concrete context chain for the remaining depth. | 186 // Now walk up the concrete context chain for the remaining depth. |
| 153 for (; depth > 0; --depth) { | 187 for (; depth > 0; --depth) { |
| 154 concrete = handle(concrete->previous(), isolate()); | 188 concrete = handle(concrete->previous(), isolate()); |
| 155 } | 189 } |
| 156 | 190 |
| 157 return SimplifyJSStoreContext(node, jsgraph()->Constant(concrete), depth); | 191 return SimplifyJSStoreContext(node, jsgraph()->Constant(concrete), depth); |
| 158 } | 192 } |
| 159 | 193 |
| 160 | 194 |
| 161 Isolate* JSContextSpecialization::isolate() const { | 195 Isolate* JSContextSpecialization::isolate() const { |
| 162 return jsgraph()->isolate(); | 196 return jsgraph()->isolate(); |
| 163 } | 197 } |
| 164 | 198 |
| 165 | 199 |
| 166 JSOperatorBuilder* JSContextSpecialization::javascript() const { | 200 JSOperatorBuilder* JSContextSpecialization::javascript() const { |
| 167 return jsgraph()->javascript(); | 201 return jsgraph()->javascript(); |
| 168 } | 202 } |
| 169 | 203 |
| 170 } // namespace compiler | 204 } // namespace compiler |
| 171 } // namespace internal | 205 } // namespace internal |
| 172 } // namespace v8 | 206 } // namespace v8 |
| OLD | NEW |