| 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 // Given a context {node} and the {distance} from that context to the target |
| 100 // context (which we want to read from or store to), try to return a |
| 101 // specialization context. If successful, update {distance} to whatever |
| 102 // distance remains from the specialization context. |
| 103 MaybeHandle<Context> GetSpecializationContext(Node* node, size_t* distance, |
| 104 Maybe<OuterContext> maybe_outer) { |
| 105 switch (node->opcode()) { |
| 106 case IrOpcode::kHeapConstant: |
| 107 return Handle<Context>::cast(OpParameter<Handle<HeapObject>>(node)); |
| 108 case IrOpcode::kParameter: { |
| 109 OuterContext outer; |
| 110 if (maybe_outer.To(&outer) && IsContextParameter(node) && |
| 111 *distance >= outer.distance) { |
| 112 *distance -= outer.distance; |
| 113 return outer.context; |
| 114 } |
| 115 break; |
| 116 } |
| 117 default: |
| 118 break; |
| 119 } |
| 120 return MaybeHandle<Context>(); |
| 121 } |
| 122 |
| 123 } // anonymous namespace |
| 124 |
| 86 Reduction JSContextSpecialization::ReduceJSLoadContext(Node* node) { | 125 Reduction JSContextSpecialization::ReduceJSLoadContext(Node* node) { |
| 87 DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode()); | 126 DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode()); |
| 88 | 127 |
| 89 const ContextAccess& access = ContextAccessOf(node->op()); | 128 const ContextAccess& access = ContextAccessOf(node->op()); |
| 90 size_t depth = access.depth(); | 129 size_t depth = access.depth(); |
| 91 | 130 |
| 92 // First walk up the context chain in the graph as far as possible. | 131 // First walk up the context chain in the graph as far as possible. |
| 93 Node* outer = NodeProperties::GetOuterContext(node, &depth); | 132 Node* context = NodeProperties::GetOuterContext(node, &depth); |
| 94 | 133 |
| 95 Handle<Context> concrete; | 134 Handle<Context> concrete; |
| 96 if (!NodeProperties::GetSpecializationContext(outer, context()) | 135 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 | 136 // We do not have a concrete context object, so we can only partially reduce |
| 99 // the load by folding-in the outer context node. | 137 // the load by folding-in the outer context node. |
| 100 return SimplifyJSLoadContext(node, outer, depth); | 138 return SimplifyJSLoadContext(node, context, depth); |
| 101 } | 139 } |
| 102 | 140 |
| 103 // Now walk up the concrete context chain for the remaining depth. | 141 // Now walk up the concrete context chain for the remaining depth. |
| 104 for (; depth > 0; --depth) { | 142 for (; depth > 0; --depth) { |
| 105 concrete = handle(concrete->previous(), isolate()); | 143 concrete = handle(concrete->previous(), isolate()); |
| 106 } | 144 } |
| 107 | 145 |
| 108 if (!access.immutable()) { | 146 if (!access.immutable()) { |
| 109 // We found the requested context object but since the context slot is | 147 // We found the requested context object but since the context slot is |
| 110 // mutable we can only partially reduce the load. | 148 // mutable we can only partially reduce the load. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 132 | 170 |
| 133 | 171 |
| 134 Reduction JSContextSpecialization::ReduceJSStoreContext(Node* node) { | 172 Reduction JSContextSpecialization::ReduceJSStoreContext(Node* node) { |
| 135 DCHECK_EQ(IrOpcode::kJSStoreContext, node->opcode()); | 173 DCHECK_EQ(IrOpcode::kJSStoreContext, node->opcode()); |
| 136 | 174 |
| 137 const ContextAccess& access = ContextAccessOf(node->op()); | 175 const ContextAccess& access = ContextAccessOf(node->op()); |
| 138 size_t depth = access.depth(); | 176 size_t depth = access.depth(); |
| 139 | 177 |
| 140 // First walk up the context chain in the graph until we reduce the depth to 0 | 178 // 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. | 179 // or hit a node that does not have a CreateXYZContext operator. |
| 142 Node* outer = NodeProperties::GetOuterContext(node, &depth); | 180 Node* context = NodeProperties::GetOuterContext(node, &depth); |
| 143 | 181 |
| 144 Handle<Context> concrete; | 182 Handle<Context> concrete; |
| 145 if (!NodeProperties::GetSpecializationContext(outer, context()) | 183 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 | 184 // We do not have a concrete context object, so we can only partially reduce |
| 148 // the load by folding-in the outer context node. | 185 // the load by folding-in the outer context node. |
| 149 return SimplifyJSStoreContext(node, outer, depth); | 186 return SimplifyJSStoreContext(node, context, depth); |
| 150 } | 187 } |
| 151 | 188 |
| 152 // Now walk up the concrete context chain for the remaining depth. | 189 // Now walk up the concrete context chain for the remaining depth. |
| 153 for (; depth > 0; --depth) { | 190 for (; depth > 0; --depth) { |
| 154 concrete = handle(concrete->previous(), isolate()); | 191 concrete = handle(concrete->previous(), isolate()); |
| 155 } | 192 } |
| 156 | 193 |
| 157 return SimplifyJSStoreContext(node, jsgraph()->Constant(concrete), depth); | 194 return SimplifyJSStoreContext(node, jsgraph()->Constant(concrete), depth); |
| 158 } | 195 } |
| 159 | 196 |
| 160 | 197 |
| 161 Isolate* JSContextSpecialization::isolate() const { | 198 Isolate* JSContextSpecialization::isolate() const { |
| 162 return jsgraph()->isolate(); | 199 return jsgraph()->isolate(); |
| 163 } | 200 } |
| 164 | 201 |
| 165 | 202 |
| 166 JSOperatorBuilder* JSContextSpecialization::javascript() const { | 203 JSOperatorBuilder* JSContextSpecialization::javascript() const { |
| 167 return jsgraph()->javascript(); | 204 return jsgraph()->javascript(); |
| 168 } | 205 } |
| 169 | 206 |
| 170 } // namespace compiler | 207 } // namespace compiler |
| 171 } // namespace internal | 208 } // namespace internal |
| 172 } // namespace v8 | 209 } // namespace v8 |
| OLD | NEW |