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