| 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/flow_graph_optimizer.h" | 5 #include "vm/flow_graph_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/cha.h" | 8 #include "vm/cha.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
| (...skipping 2494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2505 } | 2505 } |
| 2506 } | 2506 } |
| 2507 | 2507 |
| 2508 | 2508 |
| 2509 // Returns a Boolean constant if all classes in ic_data yield the same type-test | 2509 // Returns a Boolean constant if all classes in ic_data yield the same type-test |
| 2510 // result and the type tests do not depend on type arguments. Otherwise return | 2510 // result and the type tests do not depend on type arguments. Otherwise return |
| 2511 // Bool::null(). | 2511 // Bool::null(). |
| 2512 RawBool* FlowGraphOptimizer::InstanceOfAsBool(const ICData& ic_data, | 2512 RawBool* FlowGraphOptimizer::InstanceOfAsBool(const ICData& ic_data, |
| 2513 const AbstractType& type) const { | 2513 const AbstractType& type) const { |
| 2514 ASSERT(ic_data.num_args_tested() == 1); // Unary checks only. | 2514 ASSERT(ic_data.num_args_tested() == 1); // Unary checks only. |
| 2515 if (!type.IsInstantiated() || type.IsMalformed()) return Bool::null(); | 2515 if (!type.IsInstantiated() || type.IsMalformed() || type.IsMalbounded()) { |
| 2516 return Bool::null(); |
| 2517 } |
| 2516 const Class& type_class = Class::Handle(type.type_class()); | 2518 const Class& type_class = Class::Handle(type.type_class()); |
| 2517 if (type_class.HasTypeArguments()) { | 2519 if (type_class.HasTypeArguments()) { |
| 2518 // Only raw types can be directly compared, thus disregarding type | 2520 // Only raw types can be directly compared, thus disregarding type |
| 2519 // arguments. | 2521 // arguments. |
| 2520 const AbstractTypeArguments& type_arguments = | 2522 const AbstractTypeArguments& type_arguments = |
| 2521 AbstractTypeArguments::Handle(type.arguments()); | 2523 AbstractTypeArguments::Handle(type.arguments()); |
| 2522 const bool is_raw_type = type_arguments.IsNull() || | 2524 const bool is_raw_type = type_arguments.IsNull() || |
| 2523 type_arguments.IsRaw(type_arguments.Length()); | 2525 type_arguments.IsRaw(type_arguments.Length()); |
| 2524 if (!is_raw_type) { | 2526 if (!is_raw_type) { |
| 2525 // Unknown result. | 2527 // Unknown result. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2589 } | 2591 } |
| 2590 | 2592 |
| 2591 | 2593 |
| 2592 void FlowGraphOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) { | 2594 void FlowGraphOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) { |
| 2593 ASSERT(Token::IsTypeCastOperator(call->token_kind())); | 2595 ASSERT(Token::IsTypeCastOperator(call->token_kind())); |
| 2594 Definition* left = call->ArgumentAt(0); | 2596 Definition* left = call->ArgumentAt(0); |
| 2595 Definition* instantiator = call->ArgumentAt(1); | 2597 Definition* instantiator = call->ArgumentAt(1); |
| 2596 Definition* type_args = call->ArgumentAt(2); | 2598 Definition* type_args = call->ArgumentAt(2); |
| 2597 const AbstractType& type = | 2599 const AbstractType& type = |
| 2598 AbstractType::Cast(call->ArgumentAt(3)->AsConstant()->value()); | 2600 AbstractType::Cast(call->ArgumentAt(3)->AsConstant()->value()); |
| 2599 ASSERT(!type.IsMalformed()); | 2601 ASSERT(!type.IsMalformed() && !type.IsMalbounded()); |
| 2600 const ICData& unary_checks = | 2602 const ICData& unary_checks = |
| 2601 ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks()); | 2603 ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks()); |
| 2602 if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) { | 2604 if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) { |
| 2603 Bool& as_bool = Bool::ZoneHandle(InstanceOfAsBool(unary_checks, type)); | 2605 Bool& as_bool = Bool::ZoneHandle(InstanceOfAsBool(unary_checks, type)); |
| 2604 if (as_bool.raw() == Bool::True().raw()) { | 2606 if (as_bool.raw() == Bool::True().raw()) { |
| 2605 AddReceiverCheck(call); | 2607 AddReceiverCheck(call); |
| 2606 // Remove the original push arguments. | 2608 // Remove the original push arguments. |
| 2607 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { | 2609 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { |
| 2608 PushArgumentInstr* push = call->PushArgumentAt(i); | 2610 PushArgumentInstr* push = call->PushArgumentAt(i); |
| 2609 push->ReplaceUsesWith(push->value()->definition()); | 2611 push->ReplaceUsesWith(push->value()->definition()); |
| (...skipping 4931 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7541 } | 7543 } |
| 7542 | 7544 |
| 7543 // Insert materializations at environment uses. | 7545 // Insert materializations at environment uses. |
| 7544 for (intptr_t i = 0; i < exits.length(); i++) { | 7546 for (intptr_t i = 0; i < exits.length(); i++) { |
| 7545 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); | 7547 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); |
| 7546 } | 7548 } |
| 7547 } | 7549 } |
| 7548 | 7550 |
| 7549 | 7551 |
| 7550 } // namespace dart | 7552 } // namespace dart |
| OLD | NEW |