| 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 |