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" |
(...skipping 10 matching lines...) Expand all Loading... |
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 | 28 |
29 JSGlobalObjectSpecialization::JSGlobalObjectSpecialization( | 29 JSGlobalObjectSpecialization::JSGlobalObjectSpecialization( |
30 Editor* editor, JSGraph* jsgraph, Flags flags, | 30 Editor* editor, JSGraph* jsgraph, Flags flags, |
31 Handle<JSGlobalObject> global_object, CompilationDependencies* dependencies) | 31 MaybeHandle<Context> native_context, CompilationDependencies* dependencies) |
32 : AdvancedReducer(editor), | 32 : AdvancedReducer(editor), |
33 jsgraph_(jsgraph), | 33 jsgraph_(jsgraph), |
34 flags_(flags), | 34 flags_(flags), |
35 global_object_(global_object), | 35 native_context_(native_context), |
36 script_context_table_( | |
37 global_object->native_context()->script_context_table(), isolate()), | |
38 dependencies_(dependencies), | 36 dependencies_(dependencies), |
39 type_cache_(TypeCache::Get()) {} | 37 type_cache_(TypeCache::Get()) {} |
40 | 38 |
41 | 39 |
42 Reduction JSGlobalObjectSpecialization::Reduce(Node* node) { | 40 Reduction JSGlobalObjectSpecialization::Reduce(Node* node) { |
43 switch (node->opcode()) { | 41 switch (node->opcode()) { |
44 case IrOpcode::kJSLoadGlobal: | 42 case IrOpcode::kJSLoadGlobal: |
45 return ReduceJSLoadGlobal(node); | 43 return ReduceJSLoadGlobal(node); |
46 case IrOpcode::kJSStoreGlobal: | 44 case IrOpcode::kJSStoreGlobal: |
47 return ReduceJSStoreGlobal(node); | 45 return ReduceJSStoreGlobal(node); |
48 default: | 46 default: |
49 break; | 47 break; |
50 } | 48 } |
51 return NoChange(); | 49 return NoChange(); |
52 } | 50 } |
53 | 51 |
54 | 52 |
55 Reduction JSGlobalObjectSpecialization::ReduceJSLoadGlobal(Node* node) { | 53 Reduction JSGlobalObjectSpecialization::ReduceJSLoadGlobal(Node* node) { |
56 DCHECK_EQ(IrOpcode::kJSLoadGlobal, node->opcode()); | 54 DCHECK_EQ(IrOpcode::kJSLoadGlobal, node->opcode()); |
57 Handle<Name> name = LoadGlobalParametersOf(node->op()).name(); | 55 Handle<Name> name = LoadGlobalParametersOf(node->op()).name(); |
58 Node* effect = NodeProperties::GetEffectInput(node); | 56 Node* effect = NodeProperties::GetEffectInput(node); |
59 Node* control = NodeProperties::GetControlInput(node); | 57 Node* control = NodeProperties::GetControlInput(node); |
60 | 58 |
| 59 // Retrieve the global object from the given {node}. |
| 60 Handle<JSGlobalObject> global_object; |
| 61 if (!GetGlobalObject(node).ToHandle(&global_object)) return NoChange(); |
| 62 |
61 // Try to lookup the name on the script context table first (lexical scoping). | 63 // Try to lookup the name on the script context table first (lexical scoping). |
62 ScriptContextTableLookupResult result; | 64 ScriptContextTableLookupResult result; |
63 if (LookupInScriptContextTable(name, &result)) { | 65 if (LookupInScriptContextTable(global_object, name, &result)) { |
64 if (result.context->is_the_hole(result.index)) return NoChange(); | 66 if (result.context->is_the_hole(result.index)) return NoChange(); |
65 Node* context = jsgraph()->HeapConstant(result.context); | 67 Node* context = jsgraph()->HeapConstant(result.context); |
66 Node* value = effect = graph()->NewNode( | 68 Node* value = effect = graph()->NewNode( |
67 javascript()->LoadContext(0, result.index, result.immutable), context, | 69 javascript()->LoadContext(0, result.index, result.immutable), context, |
68 context, effect); | 70 context, effect); |
69 ReplaceWithValue(node, value, effect); | 71 ReplaceWithValue(node, value, effect); |
70 return Replace(value); | 72 return Replace(value); |
71 } | 73 } |
72 | 74 |
73 // Lookup on the global object instead. We only deal with own data | 75 // Lookup on the global object instead. We only deal with own data |
74 // properties of the global object here (represented as PropertyCell). | 76 // properties of the global object here (represented as PropertyCell). |
75 LookupIterator it(global_object(), name, LookupIterator::OWN); | 77 LookupIterator it(global_object, name, LookupIterator::OWN); |
76 if (it.state() != LookupIterator::DATA) return NoChange(); | 78 if (it.state() != LookupIterator::DATA) return NoChange(); |
77 Handle<PropertyCell> property_cell = it.GetPropertyCell(); | 79 Handle<PropertyCell> property_cell = it.GetPropertyCell(); |
78 PropertyDetails property_details = property_cell->property_details(); | 80 PropertyDetails property_details = property_cell->property_details(); |
79 Handle<Object> property_cell_value(property_cell->value(), isolate()); | 81 Handle<Object> property_cell_value(property_cell->value(), isolate()); |
80 | 82 |
81 // Load from non-configurable, read-only data property on the global | 83 // Load from non-configurable, read-only data property on the global |
82 // object can be constant-folded, even without deoptimization support. | 84 // object can be constant-folded, even without deoptimization support. |
83 if (!property_details.IsConfigurable() && property_details.IsReadOnly()) { | 85 if (!property_details.IsConfigurable() && property_details.IsReadOnly()) { |
84 Node* value = jsgraph()->Constant(property_cell_value); | 86 Node* value = jsgraph()->Constant(property_cell_value); |
85 ReplaceWithValue(node, value); | 87 ReplaceWithValue(node, value); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 | 140 |
139 | 141 |
140 Reduction JSGlobalObjectSpecialization::ReduceJSStoreGlobal(Node* node) { | 142 Reduction JSGlobalObjectSpecialization::ReduceJSStoreGlobal(Node* node) { |
141 DCHECK_EQ(IrOpcode::kJSStoreGlobal, node->opcode()); | 143 DCHECK_EQ(IrOpcode::kJSStoreGlobal, node->opcode()); |
142 Handle<Name> name = StoreGlobalParametersOf(node->op()).name(); | 144 Handle<Name> name = StoreGlobalParametersOf(node->op()).name(); |
143 Node* value = NodeProperties::GetValueInput(node, 0); | 145 Node* value = NodeProperties::GetValueInput(node, 0); |
144 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 146 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); |
145 Node* effect = NodeProperties::GetEffectInput(node); | 147 Node* effect = NodeProperties::GetEffectInput(node); |
146 Node* control = NodeProperties::GetControlInput(node); | 148 Node* control = NodeProperties::GetControlInput(node); |
147 | 149 |
| 150 // Retrieve the global object from the given {node}. |
| 151 Handle<JSGlobalObject> global_object; |
| 152 if (!GetGlobalObject(node).ToHandle(&global_object)) return NoChange(); |
| 153 |
148 // Try to lookup the name on the script context table first (lexical scoping). | 154 // Try to lookup the name on the script context table first (lexical scoping). |
149 ScriptContextTableLookupResult result; | 155 ScriptContextTableLookupResult result; |
150 if (LookupInScriptContextTable(name, &result)) { | 156 if (LookupInScriptContextTable(global_object, name, &result)) { |
151 if (result.context->is_the_hole(result.index)) return NoChange(); | 157 if (result.context->is_the_hole(result.index)) return NoChange(); |
152 if (result.immutable) return NoChange(); | 158 if (result.immutable) return NoChange(); |
153 Node* context = jsgraph()->HeapConstant(result.context); | 159 Node* context = jsgraph()->HeapConstant(result.context); |
154 effect = graph()->NewNode(javascript()->StoreContext(0, result.index), | 160 effect = graph()->NewNode(javascript()->StoreContext(0, result.index), |
155 context, value, context, effect, control); | 161 context, value, context, effect, control); |
156 ReplaceWithValue(node, value, effect, control); | 162 ReplaceWithValue(node, value, effect, control); |
157 return Replace(value); | 163 return Replace(value); |
158 } | 164 } |
159 | 165 |
160 // Lookup on the global object instead. We only deal with own data | 166 // Lookup on the global object instead. We only deal with own data |
161 // properties of the global object here (represented as PropertyCell). | 167 // properties of the global object here (represented as PropertyCell). |
162 LookupIterator it(global_object(), name, LookupIterator::OWN); | 168 LookupIterator it(global_object, name, LookupIterator::OWN); |
163 if (it.state() != LookupIterator::DATA) return NoChange(); | 169 if (it.state() != LookupIterator::DATA) return NoChange(); |
164 Handle<PropertyCell> property_cell = it.GetPropertyCell(); | 170 Handle<PropertyCell> property_cell = it.GetPropertyCell(); |
165 PropertyDetails property_details = property_cell->property_details(); | 171 PropertyDetails property_details = property_cell->property_details(); |
166 Handle<Object> property_cell_value(property_cell->value(), isolate()); | 172 Handle<Object> property_cell_value(property_cell->value(), isolate()); |
167 | 173 |
168 // Don't even bother trying to lower stores to read-only data properties. | 174 // Don't even bother trying to lower stores to read-only data properties. |
169 if (property_details.IsReadOnly()) return NoChange(); | 175 if (property_details.IsReadOnly()) return NoChange(); |
170 switch (property_details.cell_type()) { | 176 switch (property_details.cell_type()) { |
171 case PropertyCellType::kUndefined: { | 177 case PropertyCellType::kUndefined: { |
172 return NoChange(); | 178 return NoChange(); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 simplified()->StoreField(AccessBuilder::ForPropertyCellValue()), | 253 simplified()->StoreField(AccessBuilder::ForPropertyCellValue()), |
248 jsgraph()->HeapConstant(property_cell), value, effect, control); | 254 jsgraph()->HeapConstant(property_cell), value, effect, control); |
249 break; | 255 break; |
250 } | 256 } |
251 } | 257 } |
252 ReplaceWithValue(node, value, effect, control); | 258 ReplaceWithValue(node, value, effect, control); |
253 return Replace(value); | 259 return Replace(value); |
254 } | 260 } |
255 | 261 |
256 | 262 |
| 263 MaybeHandle<JSGlobalObject> JSGlobalObjectSpecialization::GetGlobalObject( |
| 264 Node* node) { |
| 265 Node* const context = NodeProperties::GetContextInput(node); |
| 266 return NodeProperties::GetSpecializationGlobalObject(context, |
| 267 native_context()); |
| 268 } |
| 269 |
| 270 |
257 bool JSGlobalObjectSpecialization::LookupInScriptContextTable( | 271 bool JSGlobalObjectSpecialization::LookupInScriptContextTable( |
258 Handle<Name> name, ScriptContextTableLookupResult* result) { | 272 Handle<JSGlobalObject> global_object, Handle<Name> name, |
| 273 ScriptContextTableLookupResult* result) { |
259 if (!name->IsString()) return false; | 274 if (!name->IsString()) return false; |
| 275 Handle<ScriptContextTable> script_context_table( |
| 276 global_object->native_context()->script_context_table(), isolate()); |
260 ScriptContextTable::LookupResult lookup_result; | 277 ScriptContextTable::LookupResult lookup_result; |
261 if (!ScriptContextTable::Lookup(script_context_table(), | 278 if (!ScriptContextTable::Lookup(script_context_table, |
262 Handle<String>::cast(name), &lookup_result)) { | 279 Handle<String>::cast(name), &lookup_result)) { |
263 return false; | 280 return false; |
264 } | 281 } |
265 Handle<Context> script_context = ScriptContextTable::GetContext( | 282 Handle<Context> script_context = ScriptContextTable::GetContext( |
266 script_context_table(), lookup_result.context_index); | 283 script_context_table, lookup_result.context_index); |
267 result->context = script_context; | 284 result->context = script_context; |
268 result->immutable = IsImmutableVariableMode(lookup_result.mode); | 285 result->immutable = IsImmutableVariableMode(lookup_result.mode); |
269 result->index = lookup_result.slot_index; | 286 result->index = lookup_result.slot_index; |
270 return true; | 287 return true; |
271 } | 288 } |
272 | 289 |
273 | 290 |
274 Graph* JSGlobalObjectSpecialization::graph() const { | 291 Graph* JSGlobalObjectSpecialization::graph() const { |
275 return jsgraph()->graph(); | 292 return jsgraph()->graph(); |
276 } | 293 } |
(...skipping 14 matching lines...) Expand all Loading... |
291 } | 308 } |
292 | 309 |
293 | 310 |
294 SimplifiedOperatorBuilder* JSGlobalObjectSpecialization::simplified() const { | 311 SimplifiedOperatorBuilder* JSGlobalObjectSpecialization::simplified() const { |
295 return jsgraph()->simplified(); | 312 return jsgraph()->simplified(); |
296 } | 313 } |
297 | 314 |
298 } // namespace compiler | 315 } // namespace compiler |
299 } // namespace internal | 316 } // namespace internal |
300 } // namespace v8 | 317 } // namespace v8 |
OLD | NEW |