| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 return ReduceJSStoreGlobal(node); | 42 return ReduceJSStoreGlobal(node); |
| 43 default: | 43 default: |
| 44 break; | 44 break; |
| 45 } | 45 } |
| 46 return NoChange(); | 46 return NoChange(); |
| 47 } | 47 } |
| 48 | 48 |
| 49 namespace { | 49 namespace { |
| 50 | 50 |
| 51 FieldAccess ForPropertyCellValue(MachineRepresentation representation, | 51 FieldAccess ForPropertyCellValue(MachineRepresentation representation, |
| 52 Type* type, Handle<Name> name) { | 52 Type* type, MaybeHandle<Map> map, |
| 53 Handle<Name> name) { |
| 53 WriteBarrierKind kind = kFullWriteBarrier; | 54 WriteBarrierKind kind = kFullWriteBarrier; |
| 54 if (representation == MachineRepresentation::kTaggedSigned) { | 55 if (representation == MachineRepresentation::kTaggedSigned) { |
| 55 kind = kNoWriteBarrier; | 56 kind = kNoWriteBarrier; |
| 56 } else if (representation == MachineRepresentation::kTaggedPointer) { | 57 } else if (representation == MachineRepresentation::kTaggedPointer) { |
| 57 kind = kPointerWriteBarrier; | 58 kind = kPointerWriteBarrier; |
| 58 } | 59 } |
| 59 MachineType r = MachineType::TypeForRepresentation(representation); | 60 MachineType r = MachineType::TypeForRepresentation(representation); |
| 60 FieldAccess access = {kTaggedBase, PropertyCell::kValueOffset, name, type, r, | 61 FieldAccess access = { |
| 61 kind}; | 62 kTaggedBase, PropertyCell::kValueOffset, name, map, type, r, kind}; |
| 62 return access; | 63 return access; |
| 63 } | 64 } |
| 64 } // namespace | 65 } // namespace |
| 65 | 66 |
| 66 Reduction JSGlobalObjectSpecialization::ReduceJSLoadGlobal(Node* node) { | 67 Reduction JSGlobalObjectSpecialization::ReduceJSLoadGlobal(Node* node) { |
| 67 DCHECK_EQ(IrOpcode::kJSLoadGlobal, node->opcode()); | 68 DCHECK_EQ(IrOpcode::kJSLoadGlobal, node->opcode()); |
| 68 Handle<Name> name = LoadGlobalParametersOf(node->op()).name(); | 69 Handle<Name> name = LoadGlobalParametersOf(node->op()).name(); |
| 69 Node* effect = NodeProperties::GetEffectInput(node); | 70 Node* effect = NodeProperties::GetEffectInput(node); |
| 70 Node* control = NodeProperties::GetControlInput(node); | 71 Node* control = NodeProperties::GetControlInput(node); |
| 71 | 72 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 | 109 |
| 109 // Load from constant/undefined global property can be constant-folded. | 110 // Load from constant/undefined global property can be constant-folded. |
| 110 if (property_details.cell_type() == PropertyCellType::kConstant || | 111 if (property_details.cell_type() == PropertyCellType::kConstant || |
| 111 property_details.cell_type() == PropertyCellType::kUndefined) { | 112 property_details.cell_type() == PropertyCellType::kUndefined) { |
| 112 Node* value = jsgraph()->Constant(property_cell_value); | 113 Node* value = jsgraph()->Constant(property_cell_value); |
| 113 ReplaceWithValue(node, value); | 114 ReplaceWithValue(node, value); |
| 114 return Replace(value); | 115 return Replace(value); |
| 115 } | 116 } |
| 116 | 117 |
| 117 // Load from constant type cell can benefit from type feedback. | 118 // Load from constant type cell can benefit from type feedback. |
| 119 MaybeHandle<Map> map; |
| 118 Type* property_cell_value_type = Type::NonInternal(); | 120 Type* property_cell_value_type = Type::NonInternal(); |
| 119 MachineRepresentation representation = MachineRepresentation::kTagged; | 121 MachineRepresentation representation = MachineRepresentation::kTagged; |
| 120 if (property_details.cell_type() == PropertyCellType::kConstantType) { | 122 if (property_details.cell_type() == PropertyCellType::kConstantType) { |
| 121 // Compute proper type based on the current value in the cell. | 123 // Compute proper type based on the current value in the cell. |
| 122 if (property_cell_value->IsSmi()) { | 124 if (property_cell_value->IsSmi()) { |
| 123 property_cell_value_type = Type::SignedSmall(); | 125 property_cell_value_type = Type::SignedSmall(); |
| 124 representation = MachineRepresentation::kTaggedSigned; | 126 representation = MachineRepresentation::kTaggedSigned; |
| 125 } else if (property_cell_value->IsNumber()) { | 127 } else if (property_cell_value->IsNumber()) { |
| 126 property_cell_value_type = Type::Number(); | 128 property_cell_value_type = Type::Number(); |
| 127 representation = MachineRepresentation::kTaggedPointer; | 129 representation = MachineRepresentation::kTaggedPointer; |
| 128 } else { | 130 } else { |
| 129 // TODO(turbofan): Track the property_cell_value_map on the FieldAccess | |
| 130 // below and use it in LoadElimination to eliminate map checks. | |
| 131 Handle<Map> property_cell_value_map( | 131 Handle<Map> property_cell_value_map( |
| 132 Handle<HeapObject>::cast(property_cell_value)->map(), isolate()); | 132 Handle<HeapObject>::cast(property_cell_value)->map(), isolate()); |
| 133 property_cell_value_type = Type::For(property_cell_value_map); | 133 property_cell_value_type = Type::For(property_cell_value_map); |
| 134 representation = MachineRepresentation::kTaggedPointer; | 134 representation = MachineRepresentation::kTaggedPointer; |
| 135 |
| 136 // We can only use the property cell value map for map check elimination |
| 137 // if it's stable, i.e. the HeapObject wasn't mutated without the cell |
| 138 // state being updated. |
| 139 if (property_cell_value_map->is_stable()) { |
| 140 dependencies()->AssumeMapStable(property_cell_value_map); |
| 141 map = property_cell_value_map; |
| 142 } |
| 135 } | 143 } |
| 136 } | 144 } |
| 137 Node* value = effect = | 145 Node* value = effect = graph()->NewNode( |
| 138 graph()->NewNode(simplified()->LoadField(ForPropertyCellValue( | 146 simplified()->LoadField(ForPropertyCellValue( |
| 139 representation, property_cell_value_type, name)), | 147 representation, property_cell_value_type, map, name)), |
| 140 jsgraph()->HeapConstant(property_cell), effect, control); | 148 jsgraph()->HeapConstant(property_cell), effect, control); |
| 141 ReplaceWithValue(node, value, effect, control); | 149 ReplaceWithValue(node, value, effect, control); |
| 142 return Replace(value); | 150 return Replace(value); |
| 143 } | 151 } |
| 144 | 152 |
| 145 | 153 |
| 146 Reduction JSGlobalObjectSpecialization::ReduceJSStoreGlobal(Node* node) { | 154 Reduction JSGlobalObjectSpecialization::ReduceJSStoreGlobal(Node* node) { |
| 147 DCHECK_EQ(IrOpcode::kJSStoreGlobal, node->opcode()); | 155 DCHECK_EQ(IrOpcode::kJSStoreGlobal, node->opcode()); |
| 148 Handle<Name> name = StoreGlobalParametersOf(node->op()).name(); | 156 Handle<Name> name = StoreGlobalParametersOf(node->op()).name(); |
| 149 Node* value = NodeProperties::GetValueInput(node, 0); | 157 Node* value = NodeProperties::GetValueInput(node, 0); |
| 150 Node* effect = NodeProperties::GetEffectInput(node); | 158 Node* effect = NodeProperties::GetEffectInput(node); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 value, effect, control); | 219 value, effect, control); |
| 212 property_cell_value_type = Type::OtherInternal(); | 220 property_cell_value_type = Type::OtherInternal(); |
| 213 representation = MachineRepresentation::kTaggedPointer; | 221 representation = MachineRepresentation::kTaggedPointer; |
| 214 } else { | 222 } else { |
| 215 // Check that the {value} is a Smi. | 223 // Check that the {value} is a Smi. |
| 216 value = effect = | 224 value = effect = |
| 217 graph()->NewNode(simplified()->CheckSmi(), value, effect, control); | 225 graph()->NewNode(simplified()->CheckSmi(), value, effect, control); |
| 218 property_cell_value_type = Type::SignedSmall(); | 226 property_cell_value_type = Type::SignedSmall(); |
| 219 representation = MachineRepresentation::kTaggedSigned; | 227 representation = MachineRepresentation::kTaggedSigned; |
| 220 } | 228 } |
| 221 effect = graph()->NewNode( | 229 effect = graph()->NewNode(simplified()->StoreField(ForPropertyCellValue( |
| 222 simplified()->StoreField(ForPropertyCellValue( | 230 representation, property_cell_value_type, |
| 223 representation, property_cell_value_type, name)), | 231 MaybeHandle<Map>(), name)), |
| 224 jsgraph()->HeapConstant(property_cell), value, effect, control); | 232 jsgraph()->HeapConstant(property_cell), value, |
| 233 effect, control); |
| 225 break; | 234 break; |
| 226 } | 235 } |
| 227 case PropertyCellType::kMutable: { | 236 case PropertyCellType::kMutable: { |
| 228 // Record a code dependency on the cell, and just deoptimize if the | 237 // Record a code dependency on the cell, and just deoptimize if the |
| 229 // property ever becomes read-only. | 238 // property ever becomes read-only. |
| 230 dependencies()->AssumePropertyCell(property_cell); | 239 dependencies()->AssumePropertyCell(property_cell); |
| 231 effect = graph()->NewNode( | 240 effect = graph()->NewNode( |
| 232 simplified()->StoreField(ForPropertyCellValue( | 241 simplified()->StoreField(ForPropertyCellValue( |
| 233 MachineRepresentation::kTagged, Type::NonInternal(), name)), | 242 MachineRepresentation::kTagged, Type::NonInternal(), |
| 243 MaybeHandle<Map>(), name)), |
| 234 jsgraph()->HeapConstant(property_cell), value, effect, control); | 244 jsgraph()->HeapConstant(property_cell), value, effect, control); |
| 235 break; | 245 break; |
| 236 } | 246 } |
| 237 } | 247 } |
| 238 ReplaceWithValue(node, value, effect, control); | 248 ReplaceWithValue(node, value, effect, control); |
| 239 return Replace(value); | 249 return Replace(value); |
| 240 } | 250 } |
| 241 | 251 |
| 242 bool JSGlobalObjectSpecialization::LookupInScriptContextTable( | 252 bool JSGlobalObjectSpecialization::LookupInScriptContextTable( |
| 243 Handle<Name> name, ScriptContextTableLookupResult* result) { | 253 Handle<Name> name, ScriptContextTableLookupResult* result) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 273 return jsgraph()->javascript(); | 283 return jsgraph()->javascript(); |
| 274 } | 284 } |
| 275 | 285 |
| 276 SimplifiedOperatorBuilder* JSGlobalObjectSpecialization::simplified() const { | 286 SimplifiedOperatorBuilder* JSGlobalObjectSpecialization::simplified() const { |
| 277 return jsgraph()->simplified(); | 287 return jsgraph()->simplified(); |
| 278 } | 288 } |
| 279 | 289 |
| 280 } // namespace compiler | 290 } // namespace compiler |
| 281 } // namespace internal | 291 } // namespace internal |
| 282 } // namespace v8 | 292 } // namespace v8 |
| OLD | NEW |