Chromium Code Reviews| Index: src/compiler/js-global-specialization.cc |
| diff --git a/src/compiler/js-global-specialization.cc b/src/compiler/js-global-specialization.cc |
| index 00ade7a9c8546b596c922482ff65b40407f4e308..01a837b3450a02c33f4484564bfe511e6af2202e 100644 |
| --- a/src/compiler/js-global-specialization.cc |
| +++ b/src/compiler/js-global-specialization.cc |
| @@ -184,6 +184,7 @@ Reduction JSGlobalSpecialization::ReduceStoreToPropertyCell( |
| Node* value = NodeProperties::GetValueInput(node, 2); |
| Node* effect = NodeProperties::GetEffectInput(node); |
| Node* control = NodeProperties::GetControlInput(node); |
| + Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); |
| // We only specialize global data property access. |
| PropertyDetails property_details = property_cell->property_details(); |
| DCHECK_EQ(kData, property_details.kind()); |
| @@ -193,19 +194,75 @@ Reduction JSGlobalSpecialization::ReduceStoreToPropertyCell( |
| if (property_details.IsReadOnly()) return NoChange(); |
| // Not much we can do if we run the generic pipeline here. |
| if (!(flags() & kTypingEnabled)) return NoChange(); |
| - // TODO(bmeurer): For now we deal only with cells in mutable state. |
| - if (property_details.cell_type() != PropertyCellType::kMutable) { |
| - return NoChange(); |
| - } |
| - // Store to non-configurable, data property on the global can be lowered to |
| - // a field store, even without deoptimization, because the property cannot be |
| - // deleted or reconfigured to an accessor/interceptor property. |
| - if (property_details.IsConfigurable()) { |
| - // With deoptimization support, we can lower stores even to configurable |
| - // data properties on the global object, by adding a code dependency on |
| - // the cell. |
| - if (!(flags() & kDeoptimizationEnabled)) return NoChange(); |
| - dependencies()->AssumePropertyCell(property_cell); |
| + switch (property_details.cell_type()) { |
| + case PropertyCellType::kUndefined: { |
| + return NoChange(); |
| + } |
| + case PropertyCellType::kConstant: { |
| + // Store to constant property cell requires deoptimization support, |
| + // because we might even need to eager deoptimize for mismatch. |
| + if (!(flags() & kDeoptimizationEnabled)) return NoChange(); |
| + dependencies()->AssumePropertyCell(property_cell); |
| + Node* check = |
| + graph()->NewNode(simplified()->ReferenceEqual(Type::Tagged()), value, |
| + jsgraph()->Constant(property_cell_value)); |
| + Node* branch = |
| + graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
| + Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| + Node* deoptimize = graph()->NewNode(common()->Deoptimize(), frame_state, |
| + effect, if_false); |
| + // TODO(bmeurer): This should be on the AdvancedReducer somehow. |
| + NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); |
| + control = graph()->NewNode(common()->IfTrue(), branch); |
| + return Replace(node, value, effect, control); |
| + } |
| + case PropertyCellType::kConstantType: { |
| + // Store to constant-type property cell requires deoptimization support, |
| + // because we might even need to eager deoptimize for mismatch. |
| + if (!(flags() & kDeoptimizationEnabled)) return NoChange(); |
| + dependencies()->AssumePropertyCell(property_cell); |
| + Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value); |
| + if (property_cell_value->IsHeapObject()) { |
| + Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
| + check, control); |
|
Jarin
2015/10/08 12:41:32
Hmm, interesting code reuse...
Benedikt Meurer
2015/10/08 12:52:28
Acknowledged.
|
| + Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| + Node* deoptimize = graph()->NewNode(common()->Deoptimize(), frame_state, |
| + effect, if_true); |
| + // TODO(bmeurer): This should be on the AdvancedReducer somehow. |
| + NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); |
| + control = graph()->NewNode(common()->IfFalse(), branch); |
| + Node* value_map = |
| + graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
| + value, effect, control); |
| + Handle<Map> property_cell_value_map( |
| + Handle<HeapObject>::cast(property_cell_value)->map(), isolate()); |
| + check = graph()->NewNode(simplified()->ReferenceEqual(Type::Internal()), |
| + value_map, |
| + jsgraph()->Constant(property_cell_value_map)); |
| + } |
| + Node* branch = |
| + graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
| + Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| + Node* deoptimize = graph()->NewNode(common()->Deoptimize(), frame_state, |
| + effect, if_false); |
| + // TODO(bmeurer): This should be on the AdvancedReducer somehow. |
| + NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); |
| + control = graph()->NewNode(common()->IfTrue(), branch); |
| + break; |
| + } |
| + case PropertyCellType::kMutable: { |
| + // Store to non-configurable, data property on the global can be lowered |
| + // to a field store, even without deoptimization, because the property |
| + // cannot be deleted or reconfigured to an accessor/interceptor property. |
| + if (property_details.IsConfigurable()) { |
| + // With deoptimization support, we can lower stores even to configurable |
| + // data properties on the global object, by adding a code dependency on |
| + // the cell. |
| + if (!(flags() & kDeoptimizationEnabled)) return NoChange(); |
| + dependencies()->AssumePropertyCell(property_cell); |
| + } |
| + break; |
| + } |
| } |
| effect = graph()->NewNode( |
| simplified()->StoreField(AccessBuilder::ForPropertyCellValue()), |
| @@ -230,6 +287,11 @@ Isolate* JSGlobalSpecialization::isolate() const { |
| } |
| +CommonOperatorBuilder* JSGlobalSpecialization::common() const { |
| + return jsgraph()->common(); |
| +} |
| + |
| + |
| JSOperatorBuilder* JSGlobalSpecialization::javascript() const { |
| return jsgraph()->javascript(); |
| } |