| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/flow_graph_allocator.h" | 9 #include "vm/flow_graph_allocator.h" |
| 10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 | 62 |
| 63 | 63 |
| 64 bool Value::Equals(Value* other) const { | 64 bool Value::Equals(Value* other) const { |
| 65 return definition() == other->definition(); | 65 return definition() == other->definition(); |
| 66 } | 66 } |
| 67 | 67 |
| 68 | 68 |
| 69 CheckClassInstr::CheckClassInstr(Value* value, | 69 CheckClassInstr::CheckClassInstr(Value* value, |
| 70 intptr_t deopt_id, | 70 intptr_t deopt_id, |
| 71 const ICData& unary_checks) | 71 const ICData& unary_checks) |
| 72 : unary_checks_(unary_checks) { | 72 : unary_checks_(unary_checks), |
| 73 null_check_(false) { |
| 73 ASSERT(unary_checks.IsZoneHandle()); | 74 ASSERT(unary_checks.IsZoneHandle()); |
| 74 // Expected useful check data. | 75 // Expected useful check data. |
| 75 ASSERT(!unary_checks_.IsNull()); | 76 ASSERT(!unary_checks_.IsNull()); |
| 76 ASSERT(unary_checks_.NumberOfChecks() > 0); | 77 ASSERT(unary_checks_.NumberOfChecks() > 0); |
| 77 ASSERT(unary_checks_.num_args_tested() == 1); | 78 ASSERT(unary_checks_.num_args_tested() == 1); |
| 78 SetInputAt(0, value); | 79 SetInputAt(0, value); |
| 79 deopt_id_ = deopt_id; | 80 deopt_id_ = deopt_id; |
| 80 // Otherwise use CheckSmiInstr. | 81 // Otherwise use CheckSmiInstr. |
| 81 ASSERT((unary_checks_.NumberOfChecks() != 1) || | 82 ASSERT((unary_checks_.NumberOfChecks() != 1) || |
| 82 (unary_checks_.GetReceiverClassIdAt(0) != kSmiCid)); | 83 (unary_checks_.GetReceiverClassIdAt(0) != kSmiCid)); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 102 | 103 |
| 103 | 104 |
| 104 bool CheckClassInstr::AffectedBySideEffect() const { | 105 bool CheckClassInstr::AffectedBySideEffect() const { |
| 105 // The class-id of string objects is not invariant: Externalization of strings | 106 // The class-id of string objects is not invariant: Externalization of strings |
| 106 // via the API can change the class-id. | 107 // via the API can change the class-id. |
| 107 return unary_checks().HasReceiverClassId(kOneByteStringCid) | 108 return unary_checks().HasReceiverClassId(kOneByteStringCid) |
| 108 || unary_checks().HasReceiverClassId(kTwoByteStringCid); | 109 || unary_checks().HasReceiverClassId(kTwoByteStringCid); |
| 109 } | 110 } |
| 110 | 111 |
| 111 | 112 |
| 113 bool GuardFieldInstr::AttributesEqual(Instruction* other) const { |
| 114 return field().raw() == other->AsGuardField()->field().raw(); |
| 115 } |
| 116 |
| 117 |
| 118 bool GuardFieldInstr::AffectedBySideEffect() const { |
| 119 return false; |
| 120 } |
| 121 |
| 122 |
| 112 bool CheckArrayBoundInstr::AttributesEqual(Instruction* other) const { | 123 bool CheckArrayBoundInstr::AttributesEqual(Instruction* other) const { |
| 113 CheckArrayBoundInstr* other_check = other->AsCheckArrayBound(); | 124 CheckArrayBoundInstr* other_check = other->AsCheckArrayBound(); |
| 114 ASSERT(other_check != NULL); | 125 ASSERT(other_check != NULL); |
| 115 return array_type() == other_check->array_type(); | 126 return array_type() == other_check->array_type(); |
| 116 } | 127 } |
| 117 | 128 |
| 118 | 129 |
| 119 bool AssertAssignableInstr::AttributesEqual(Instruction* other) const { | 130 bool AssertAssignableInstr::AttributesEqual(Instruction* other) const { |
| 120 AssertAssignableInstr* other_assert = other->AsAssertAssignable(); | 131 AssertAssignableInstr* other_assert = other->AsAssertAssignable(); |
| 121 ASSERT(other_assert != NULL); | 132 ASSERT(other_assert != NULL); |
| (...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 other->LinkTo(next()); | 594 other->LinkTo(next()); |
| 584 // Remove this definition's input uses. | 595 // Remove this definition's input uses. |
| 585 UnuseAllInputs(); | 596 UnuseAllInputs(); |
| 586 } | 597 } |
| 587 set_previous(NULL); | 598 set_previous(NULL); |
| 588 set_next(NULL); | 599 set_next(NULL); |
| 589 } | 600 } |
| 590 | 601 |
| 591 | 602 |
| 592 BranchInstr::BranchInstr(ComparisonInstr* comparison, bool is_checked) | 603 BranchInstr::BranchInstr(ComparisonInstr* comparison, bool is_checked) |
| 593 : comparison_(comparison), is_checked_(is_checked) { | 604 : comparison_(comparison), |
| 605 is_checked_(is_checked), |
| 606 constrained_type_(NULL) { |
| 594 for (intptr_t i = comparison->InputCount() - 1; i >= 0; --i) { | 607 for (intptr_t i = comparison->InputCount() - 1; i >= 0; --i) { |
| 595 comparison->InputAt(i)->set_instruction(this); | 608 comparison->InputAt(i)->set_instruction(this); |
| 596 } | 609 } |
| 597 } | 610 } |
| 598 | 611 |
| 599 | 612 |
| 600 void BranchInstr::RawSetInputAt(intptr_t i, Value* value) { | 613 void BranchInstr::RawSetInputAt(intptr_t i, Value* value) { |
| 601 comparison()->RawSetInputAt(i, value); | 614 comparison()->RawSetInputAt(i, value); |
| 602 } | 615 } |
| 603 | 616 |
| (...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1301 if (value_cid == unary_checks().GetReceiverClassIdAt(i)) { | 1314 if (value_cid == unary_checks().GetReceiverClassIdAt(i)) { |
| 1302 // No checks needed. | 1315 // No checks needed. |
| 1303 return NULL; | 1316 return NULL; |
| 1304 } | 1317 } |
| 1305 } | 1318 } |
| 1306 | 1319 |
| 1307 return this; | 1320 return this; |
| 1308 } | 1321 } |
| 1309 | 1322 |
| 1310 | 1323 |
| 1324 Instruction* GuardFieldInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| 1325 if (field().guarded_cid() == kDynamicCid) { |
| 1326 return NULL; // Nothing to guard. |
| 1327 } |
| 1328 |
| 1329 if (field().is_nullable() && value()->Type()->IsNull()) { |
| 1330 return NULL; |
| 1331 } |
| 1332 |
| 1333 const intptr_t cid = field().is_nullable() ? value()->Type()->ToNullableCid() |
| 1334 : value()->Type()->ToCid(); |
| 1335 if (field().guarded_cid() == cid) { |
| 1336 return NULL; // Value is guaranteed to have this cid. |
| 1337 } |
| 1338 |
| 1339 return this; |
| 1340 } |
| 1341 |
| 1342 |
| 1311 Instruction* CheckSmiInstr::Canonicalize(FlowGraphOptimizer* optimizer) { | 1343 Instruction* CheckSmiInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| 1312 return (value()->Type()->ToCid() == kSmiCid) ? NULL : this; | 1344 return (value()->Type()->ToCid() == kSmiCid) ? NULL : this; |
| 1313 } | 1345 } |
| 1314 | 1346 |
| 1315 | 1347 |
| 1316 Instruction* CheckEitherNonSmiInstr::Canonicalize( | 1348 Instruction* CheckEitherNonSmiInstr::Canonicalize( |
| 1317 FlowGraphOptimizer* optimizer) { | 1349 FlowGraphOptimizer* optimizer) { |
| 1318 if ((left()->Type()->ToCid() == kDoubleCid) || | 1350 if ((left()->Type()->ToCid() == kDoubleCid) || |
| 1319 (right()->Type()->ToCid() == kDoubleCid)) { | 1351 (right()->Type()->ToCid() == kDoubleCid)) { |
| 1320 return NULL; // Remove from the graph. | 1352 return NULL; // Remove from the graph. |
| (...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2286 default: | 2318 default: |
| 2287 UNREACHABLE(); | 2319 UNREACHABLE(); |
| 2288 } | 2320 } |
| 2289 return kPowRuntimeEntry; | 2321 return kPowRuntimeEntry; |
| 2290 } | 2322 } |
| 2291 | 2323 |
| 2292 | 2324 |
| 2293 #undef __ | 2325 #undef __ |
| 2294 | 2326 |
| 2295 } // namespace dart | 2327 } // namespace dart |
| OLD | NEW |