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-global-object-specialization.h" | 5 #include "src/compiler/js-global-object-specialization.h" |
6 | 6 |
7 #include "src/compilation-dependencies.h" | 7 #include "src/compilation-dependencies.h" |
8 #include "src/compiler/access-builder.h" | 8 #include "src/compiler/access-builder.h" |
9 #include "src/compiler/common-operator.h" | 9 #include "src/compiler/common-operator.h" |
10 #include "src/compiler/js-graph.h" | 10 #include "src/compiler/js-graph.h" |
11 #include "src/compiler/js-operator.h" | 11 #include "src/compiler/js-operator.h" |
12 #include "src/compiler/node-properties.h" | 12 #include "src/compiler/node-properties.h" |
13 #include "src/compiler/simplified-operator.h" | 13 #include "src/compiler/simplified-operator.h" |
14 #include "src/compiler/type-cache.h" | 14 #include "src/compiler/type-cache.h" |
15 #include "src/lookup.h" | 15 #include "src/lookup.h" |
16 #include "src/objects-inl.h" | 16 #include "src/objects-inl.h" |
17 | 17 |
18 namespace v8 { | 18 namespace v8 { |
19 namespace internal { | 19 namespace internal { |
20 namespace compiler { | 20 namespace compiler { |
21 | 21 |
22 struct JSGlobalObjectSpecialization::ScriptContextTableLookupResult { | 22 struct JSGlobalObjectSpecialization::ScriptContextTableLookupResult { |
23 Handle<Context> context; | 23 Handle<Context> context; |
24 bool immutable; | 24 bool immutable; |
25 int index; | 25 int index; |
26 }; | 26 }; |
27 | 27 |
28 | |
29 JSGlobalObjectSpecialization::JSGlobalObjectSpecialization( | 28 JSGlobalObjectSpecialization::JSGlobalObjectSpecialization( |
30 Editor* editor, JSGraph* jsgraph, | 29 Editor* editor, JSGraph* jsgraph, Handle<JSGlobalObject> global_object, |
31 MaybeHandle<Context> native_context, CompilationDependencies* dependencies) | 30 CompilationDependencies* dependencies) |
32 : AdvancedReducer(editor), | 31 : AdvancedReducer(editor), |
33 jsgraph_(jsgraph), | 32 jsgraph_(jsgraph), |
34 native_context_(native_context), | 33 global_object_(global_object), |
35 dependencies_(dependencies), | 34 dependencies_(dependencies), |
36 type_cache_(TypeCache::Get()) {} | 35 type_cache_(TypeCache::Get()) {} |
37 | 36 |
38 | |
39 Reduction JSGlobalObjectSpecialization::Reduce(Node* node) { | 37 Reduction JSGlobalObjectSpecialization::Reduce(Node* node) { |
40 switch (node->opcode()) { | 38 switch (node->opcode()) { |
41 case IrOpcode::kJSLoadGlobal: | 39 case IrOpcode::kJSLoadGlobal: |
42 return ReduceJSLoadGlobal(node); | 40 return ReduceJSLoadGlobal(node); |
43 case IrOpcode::kJSStoreGlobal: | 41 case IrOpcode::kJSStoreGlobal: |
44 return ReduceJSStoreGlobal(node); | 42 return ReduceJSStoreGlobal(node); |
45 default: | 43 default: |
46 break; | 44 break; |
47 } | 45 } |
48 return NoChange(); | 46 return NoChange(); |
(...skipping 15 matching lines...) Expand all Loading... |
64 return access; | 62 return access; |
65 } | 63 } |
66 } // namespace | 64 } // namespace |
67 | 65 |
68 Reduction JSGlobalObjectSpecialization::ReduceJSLoadGlobal(Node* node) { | 66 Reduction JSGlobalObjectSpecialization::ReduceJSLoadGlobal(Node* node) { |
69 DCHECK_EQ(IrOpcode::kJSLoadGlobal, node->opcode()); | 67 DCHECK_EQ(IrOpcode::kJSLoadGlobal, node->opcode()); |
70 Handle<Name> name = LoadGlobalParametersOf(node->op()).name(); | 68 Handle<Name> name = LoadGlobalParametersOf(node->op()).name(); |
71 Node* effect = NodeProperties::GetEffectInput(node); | 69 Node* effect = NodeProperties::GetEffectInput(node); |
72 Node* control = NodeProperties::GetControlInput(node); | 70 Node* control = NodeProperties::GetControlInput(node); |
73 | 71 |
74 // Retrieve the global object from the given {node}. | |
75 Handle<JSGlobalObject> global_object; | |
76 if (!GetGlobalObject(node).ToHandle(&global_object)) return NoChange(); | |
77 | |
78 // Try to lookup the name on the script context table first (lexical scoping). | 72 // Try to lookup the name on the script context table first (lexical scoping). |
79 ScriptContextTableLookupResult result; | 73 ScriptContextTableLookupResult result; |
80 if (LookupInScriptContextTable(global_object, name, &result)) { | 74 if (LookupInScriptContextTable(name, &result)) { |
81 if (result.context->is_the_hole(result.index)) return NoChange(); | 75 if (result.context->is_the_hole(result.index)) return NoChange(); |
82 Node* context = jsgraph()->HeapConstant(result.context); | 76 Node* context = jsgraph()->HeapConstant(result.context); |
83 Node* value = effect = graph()->NewNode( | 77 Node* value = effect = graph()->NewNode( |
84 javascript()->LoadContext(0, result.index, result.immutable), context, | 78 javascript()->LoadContext(0, result.index, result.immutable), context, |
85 context, effect); | 79 context, effect); |
86 ReplaceWithValue(node, value, effect); | 80 ReplaceWithValue(node, value, effect); |
87 return Replace(value); | 81 return Replace(value); |
88 } | 82 } |
89 | 83 |
90 // Lookup on the global object instead. We only deal with own data | 84 // Lookup on the global object instead. We only deal with own data |
91 // properties of the global object here (represented as PropertyCell). | 85 // properties of the global object here (represented as PropertyCell). |
92 LookupIterator it(global_object, name, LookupIterator::OWN); | 86 LookupIterator it(global_object(), name, LookupIterator::OWN); |
93 if (it.state() != LookupIterator::DATA) return NoChange(); | 87 if (it.state() != LookupIterator::DATA) return NoChange(); |
94 if (!it.GetHolder<JSObject>()->IsJSGlobalObject()) return NoChange(); | 88 if (!it.GetHolder<JSObject>()->IsJSGlobalObject()) return NoChange(); |
95 Handle<PropertyCell> property_cell = it.GetPropertyCell(); | 89 Handle<PropertyCell> property_cell = it.GetPropertyCell(); |
96 PropertyDetails property_details = property_cell->property_details(); | 90 PropertyDetails property_details = property_cell->property_details(); |
97 Handle<Object> property_cell_value(property_cell->value(), isolate()); | 91 Handle<Object> property_cell_value(property_cell->value(), isolate()); |
98 | 92 |
99 // Load from non-configurable, read-only data property on the global | 93 // Load from non-configurable, read-only data property on the global |
100 // object can be constant-folded, even without deoptimization support. | 94 // object can be constant-folded, even without deoptimization support. |
101 if (!property_details.IsConfigurable() && property_details.IsReadOnly()) { | 95 if (!property_details.IsConfigurable() && property_details.IsReadOnly()) { |
102 Node* value = jsgraph()->Constant(property_cell_value); | 96 Node* value = jsgraph()->Constant(property_cell_value); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 } | 145 } |
152 | 146 |
153 | 147 |
154 Reduction JSGlobalObjectSpecialization::ReduceJSStoreGlobal(Node* node) { | 148 Reduction JSGlobalObjectSpecialization::ReduceJSStoreGlobal(Node* node) { |
155 DCHECK_EQ(IrOpcode::kJSStoreGlobal, node->opcode()); | 149 DCHECK_EQ(IrOpcode::kJSStoreGlobal, node->opcode()); |
156 Handle<Name> name = StoreGlobalParametersOf(node->op()).name(); | 150 Handle<Name> name = StoreGlobalParametersOf(node->op()).name(); |
157 Node* value = NodeProperties::GetValueInput(node, 0); | 151 Node* value = NodeProperties::GetValueInput(node, 0); |
158 Node* effect = NodeProperties::GetEffectInput(node); | 152 Node* effect = NodeProperties::GetEffectInput(node); |
159 Node* control = NodeProperties::GetControlInput(node); | 153 Node* control = NodeProperties::GetControlInput(node); |
160 | 154 |
161 // Retrieve the global object from the given {node}. | |
162 Handle<JSGlobalObject> global_object; | |
163 if (!GetGlobalObject(node).ToHandle(&global_object)) return NoChange(); | |
164 | |
165 // Try to lookup the name on the script context table first (lexical scoping). | 155 // Try to lookup the name on the script context table first (lexical scoping). |
166 ScriptContextTableLookupResult result; | 156 ScriptContextTableLookupResult result; |
167 if (LookupInScriptContextTable(global_object, name, &result)) { | 157 if (LookupInScriptContextTable(name, &result)) { |
168 if (result.context->is_the_hole(result.index)) return NoChange(); | 158 if (result.context->is_the_hole(result.index)) return NoChange(); |
169 if (result.immutable) return NoChange(); | 159 if (result.immutable) return NoChange(); |
170 Node* context = jsgraph()->HeapConstant(result.context); | 160 Node* context = jsgraph()->HeapConstant(result.context); |
171 effect = graph()->NewNode(javascript()->StoreContext(0, result.index), | 161 effect = graph()->NewNode(javascript()->StoreContext(0, result.index), |
172 context, value, context, effect, control); | 162 context, value, context, effect, control); |
173 ReplaceWithValue(node, value, effect, control); | 163 ReplaceWithValue(node, value, effect, control); |
174 return Replace(value); | 164 return Replace(value); |
175 } | 165 } |
176 | 166 |
177 // Lookup on the global object instead. We only deal with own data | 167 // Lookup on the global object instead. We only deal with own data |
178 // properties of the global object here (represented as PropertyCell). | 168 // properties of the global object here (represented as PropertyCell). |
179 LookupIterator it(global_object, name, LookupIterator::OWN); | 169 LookupIterator it(global_object(), name, LookupIterator::OWN); |
180 if (it.state() != LookupIterator::DATA) return NoChange(); | 170 if (it.state() != LookupIterator::DATA) return NoChange(); |
181 if (!it.GetHolder<JSObject>()->IsJSGlobalObject()) return NoChange(); | 171 if (!it.GetHolder<JSObject>()->IsJSGlobalObject()) return NoChange(); |
182 Handle<PropertyCell> property_cell = it.GetPropertyCell(); | 172 Handle<PropertyCell> property_cell = it.GetPropertyCell(); |
183 PropertyDetails property_details = property_cell->property_details(); | 173 PropertyDetails property_details = property_cell->property_details(); |
184 Handle<Object> property_cell_value(property_cell->value(), isolate()); | 174 Handle<Object> property_cell_value(property_cell->value(), isolate()); |
185 | 175 |
186 // Don't even bother trying to lower stores to read-only data properties. | 176 // Don't even bother trying to lower stores to read-only data properties. |
187 if (property_details.IsReadOnly()) return NoChange(); | 177 if (property_details.IsReadOnly()) return NoChange(); |
188 switch (property_details.cell_type()) { | 178 switch (property_details.cell_type()) { |
189 case PropertyCellType::kUndefined: { | 179 case PropertyCellType::kUndefined: { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 simplified()->StoreField(ForPropertyCellValue( | 234 simplified()->StoreField(ForPropertyCellValue( |
245 MachineRepresentation::kTagged, Type::NonInternal(), name)), | 235 MachineRepresentation::kTagged, Type::NonInternal(), name)), |
246 jsgraph()->HeapConstant(property_cell), value, effect, control); | 236 jsgraph()->HeapConstant(property_cell), value, effect, control); |
247 break; | 237 break; |
248 } | 238 } |
249 } | 239 } |
250 ReplaceWithValue(node, value, effect, control); | 240 ReplaceWithValue(node, value, effect, control); |
251 return Replace(value); | 241 return Replace(value); |
252 } | 242 } |
253 | 243 |
254 | |
255 MaybeHandle<JSGlobalObject> JSGlobalObjectSpecialization::GetGlobalObject( | |
256 Node* node) { | |
257 Node* const context = NodeProperties::GetContextInput(node); | |
258 return NodeProperties::GetSpecializationGlobalObject(context, | |
259 native_context()); | |
260 } | |
261 | |
262 | |
263 bool JSGlobalObjectSpecialization::LookupInScriptContextTable( | 244 bool JSGlobalObjectSpecialization::LookupInScriptContextTable( |
264 Handle<JSGlobalObject> global_object, Handle<Name> name, | 245 Handle<Name> name, ScriptContextTableLookupResult* result) { |
265 ScriptContextTableLookupResult* result) { | |
266 if (!name->IsString()) return false; | 246 if (!name->IsString()) return false; |
267 Handle<ScriptContextTable> script_context_table( | 247 Handle<ScriptContextTable> script_context_table( |
268 global_object->native_context()->script_context_table(), isolate()); | 248 global_object()->native_context()->script_context_table(), isolate()); |
269 ScriptContextTable::LookupResult lookup_result; | 249 ScriptContextTable::LookupResult lookup_result; |
270 if (!ScriptContextTable::Lookup(script_context_table, | 250 if (!ScriptContextTable::Lookup(script_context_table, |
271 Handle<String>::cast(name), &lookup_result)) { | 251 Handle<String>::cast(name), &lookup_result)) { |
272 return false; | 252 return false; |
273 } | 253 } |
274 Handle<Context> script_context = ScriptContextTable::GetContext( | 254 Handle<Context> script_context = ScriptContextTable::GetContext( |
275 script_context_table, lookup_result.context_index); | 255 script_context_table, lookup_result.context_index); |
276 result->context = script_context; | 256 result->context = script_context; |
277 result->immutable = lookup_result.mode == CONST; | 257 result->immutable = lookup_result.mode == CONST; |
278 result->index = lookup_result.slot_index; | 258 result->index = lookup_result.slot_index; |
279 return true; | 259 return true; |
280 } | 260 } |
281 | 261 |
282 | |
283 Graph* JSGlobalObjectSpecialization::graph() const { | 262 Graph* JSGlobalObjectSpecialization::graph() const { |
284 return jsgraph()->graph(); | 263 return jsgraph()->graph(); |
285 } | 264 } |
286 | 265 |
287 | |
288 Isolate* JSGlobalObjectSpecialization::isolate() const { | 266 Isolate* JSGlobalObjectSpecialization::isolate() const { |
289 return jsgraph()->isolate(); | 267 return jsgraph()->isolate(); |
290 } | 268 } |
291 | 269 |
292 | |
293 CommonOperatorBuilder* JSGlobalObjectSpecialization::common() const { | 270 CommonOperatorBuilder* JSGlobalObjectSpecialization::common() const { |
294 return jsgraph()->common(); | 271 return jsgraph()->common(); |
295 } | 272 } |
296 | 273 |
297 | |
298 JSOperatorBuilder* JSGlobalObjectSpecialization::javascript() const { | 274 JSOperatorBuilder* JSGlobalObjectSpecialization::javascript() const { |
299 return jsgraph()->javascript(); | 275 return jsgraph()->javascript(); |
300 } | 276 } |
301 | 277 |
302 | |
303 SimplifiedOperatorBuilder* JSGlobalObjectSpecialization::simplified() const { | 278 SimplifiedOperatorBuilder* JSGlobalObjectSpecialization::simplified() const { |
304 return jsgraph()->simplified(); | 279 return jsgraph()->simplified(); |
305 } | 280 } |
306 | 281 |
307 } // namespace compiler | 282 } // namespace compiler |
308 } // namespace internal | 283 } // namespace internal |
309 } // namespace v8 | 284 } // namespace v8 |
OLD | NEW |