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 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); | 188 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); |
189 control = graph()->NewNode(common()->IfTrue(), branch); | 189 control = graph()->NewNode(common()->IfTrue(), branch); |
190 break; | 190 break; |
191 } | 191 } |
192 case PropertyCellType::kConstantType: { | 192 case PropertyCellType::kConstantType: { |
193 // Store to constant-type property cell requires deoptimization support, | 193 // Store to constant-type property cell requires deoptimization support, |
194 // because we might even need to eager deoptimize for mismatch. | 194 // because we might even need to eager deoptimize for mismatch. |
195 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); | 195 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); |
196 dependencies()->AssumePropertyCell(property_cell); | 196 dependencies()->AssumePropertyCell(property_cell); |
197 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value); | 197 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value); |
| 198 Type* property_cell_value_type = Type::TaggedSigned(); |
198 if (property_cell_value->IsHeapObject()) { | 199 if (property_cell_value->IsHeapObject()) { |
| 200 // Deoptimize if the {value} is a Smi. |
199 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse), | 201 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
200 check, control); | 202 check, control); |
201 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 203 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
202 Node* deoptimize = graph()->NewNode(common()->Deoptimize(), frame_state, | 204 Node* deoptimize = graph()->NewNode(common()->Deoptimize(), frame_state, |
203 effect, if_true); | 205 effect, if_true); |
204 // TODO(bmeurer): This should be on the AdvancedReducer somehow. | 206 // TODO(bmeurer): This should be on the AdvancedReducer somehow. |
205 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); | 207 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); |
206 control = graph()->NewNode(common()->IfFalse(), branch); | 208 control = graph()->NewNode(common()->IfFalse(), branch); |
207 Node* value_map = | 209 |
| 210 // Load the {value} map check against the {property_cell} map. |
| 211 Node* value_map = effect = |
208 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), | 212 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
209 value, effect, control); | 213 value, effect, control); |
210 Handle<Map> property_cell_value_map( | 214 Handle<Map> property_cell_value_map( |
211 Handle<HeapObject>::cast(property_cell_value)->map(), isolate()); | 215 Handle<HeapObject>::cast(property_cell_value)->map(), isolate()); |
212 check = graph()->NewNode( | 216 check = graph()->NewNode( |
213 simplified()->ReferenceEqual(Type::Any()), value_map, | 217 simplified()->ReferenceEqual(Type::Any()), value_map, |
214 jsgraph()->HeapConstant(property_cell_value_map)); | 218 jsgraph()->HeapConstant(property_cell_value_map)); |
| 219 property_cell_value_type = Type::TaggedPointer(); |
215 } | 220 } |
216 Node* branch = | 221 Node* branch = |
217 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); | 222 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
218 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | 223 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
219 Node* deoptimize = graph()->NewNode(common()->Deoptimize(), frame_state, | 224 Node* deoptimize = graph()->NewNode(common()->Deoptimize(), frame_state, |
220 effect, if_false); | 225 effect, if_false); |
221 // TODO(bmeurer): This should be on the AdvancedReducer somehow. | 226 // TODO(bmeurer): This should be on the AdvancedReducer somehow. |
222 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); | 227 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); |
223 control = graph()->NewNode(common()->IfTrue(), branch); | 228 control = graph()->NewNode(common()->IfTrue(), branch); |
224 effect = graph()->NewNode( | 229 effect = graph()->NewNode( |
225 simplified()->StoreField(AccessBuilder::ForPropertyCellValue()), | 230 simplified()->StoreField( |
| 231 AccessBuilder::ForPropertyCellValue(property_cell_value_type)), |
226 jsgraph()->HeapConstant(property_cell), value, effect, control); | 232 jsgraph()->HeapConstant(property_cell), value, effect, control); |
227 break; | 233 break; |
228 } | 234 } |
229 case PropertyCellType::kMutable: { | 235 case PropertyCellType::kMutable: { |
230 // Store to non-configurable, data property on the global can be lowered | 236 // Store to non-configurable, data property on the global can be lowered |
231 // to a field store, even without deoptimization, because the property | 237 // to a field store, even without deoptimization, because the property |
232 // cannot be deleted or reconfigured to an accessor/interceptor property. | 238 // cannot be deleted or reconfigured to an accessor/interceptor property. |
233 if (property_details.IsConfigurable()) { | 239 if (property_details.IsConfigurable()) { |
234 // With deoptimization support, we can lower stores even to configurable | 240 // With deoptimization support, we can lower stores even to configurable |
235 // data properties on the global object, by adding a code dependency on | 241 // data properties on the global object, by adding a code dependency on |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 } | 291 } |
286 | 292 |
287 | 293 |
288 SimplifiedOperatorBuilder* JSGlobalObjectSpecialization::simplified() const { | 294 SimplifiedOperatorBuilder* JSGlobalObjectSpecialization::simplified() const { |
289 return jsgraph()->simplified(); | 295 return jsgraph()->simplified(); |
290 } | 296 } |
291 | 297 |
292 } // namespace compiler | 298 } // namespace compiler |
293 } // namespace internal | 299 } // namespace internal |
294 } // namespace v8 | 300 } // namespace v8 |
OLD | NEW |