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 |