| 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 2466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2477 } | 2477 } |
| 2478 } | 2478 } |
| 2479 | 2479 |
| 2480 | 2480 |
| 2481 // Returns a Boolean constant if all classes in ic_data yield the same type-test | 2481 // Returns a Boolean constant if all classes in ic_data yield the same type-test |
| 2482 // result and the type tests do not depend on type arguments. Otherwise return | 2482 // result and the type tests do not depend on type arguments. Otherwise return |
| 2483 // Bool::null(). | 2483 // Bool::null(). |
| 2484 RawBool* FlowGraphOptimizer::InstanceOfAsBool(const ICData& ic_data, | 2484 RawBool* FlowGraphOptimizer::InstanceOfAsBool(const ICData& ic_data, |
| 2485 const AbstractType& type) const { | 2485 const AbstractType& type) const { |
| 2486 ASSERT(ic_data.num_args_tested() == 1); // Unary checks only. | 2486 ASSERT(ic_data.num_args_tested() == 1); // Unary checks only. |
| 2487 if (!type.IsInstantiated() || type.IsMalformed()) return Bool::null(); | 2487 if (!type.IsInstantiated() || type.IsMalformed() || type.IsMalbounded(NULL)) { |
| 2488 return Bool::null(); |
| 2489 } |
| 2488 const Class& type_class = Class::Handle(type.type_class()); | 2490 const Class& type_class = Class::Handle(type.type_class()); |
| 2489 if (type_class.HasTypeArguments()) { | 2491 if (type_class.HasTypeArguments()) { |
| 2490 // Only raw types can be directly compared, thus disregarding type | 2492 // Only raw types can be directly compared, thus disregarding type |
| 2491 // arguments. | 2493 // arguments. |
| 2492 const AbstractTypeArguments& type_arguments = | 2494 const AbstractTypeArguments& type_arguments = |
| 2493 AbstractTypeArguments::Handle(type.arguments()); | 2495 AbstractTypeArguments::Handle(type.arguments()); |
| 2494 const bool is_raw_type = type_arguments.IsNull() || | 2496 const bool is_raw_type = type_arguments.IsNull() || |
| 2495 type_arguments.IsRaw(type_arguments.Length()); | 2497 type_arguments.IsRaw(type_arguments.Length()); |
| 2496 if (!is_raw_type) { | 2498 if (!is_raw_type) { |
| 2497 // Unknown result. | 2499 // Unknown result. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2561 } | 2563 } |
| 2562 | 2564 |
| 2563 | 2565 |
| 2564 void FlowGraphOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) { | 2566 void FlowGraphOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) { |
| 2565 ASSERT(Token::IsTypeCastOperator(call->token_kind())); | 2567 ASSERT(Token::IsTypeCastOperator(call->token_kind())); |
| 2566 Definition* left = call->ArgumentAt(0); | 2568 Definition* left = call->ArgumentAt(0); |
| 2567 Definition* instantiator = call->ArgumentAt(1); | 2569 Definition* instantiator = call->ArgumentAt(1); |
| 2568 Definition* type_args = call->ArgumentAt(2); | 2570 Definition* type_args = call->ArgumentAt(2); |
| 2569 const AbstractType& type = | 2571 const AbstractType& type = |
| 2570 AbstractType::Cast(call->ArgumentAt(3)->AsConstant()->value()); | 2572 AbstractType::Cast(call->ArgumentAt(3)->AsConstant()->value()); |
| 2571 ASSERT(!type.IsMalformed()); | 2573 ASSERT(!type.IsMalformed() && !type.IsMalbounded(NULL)); |
| 2572 const ICData& unary_checks = | 2574 const ICData& unary_checks = |
| 2573 ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks()); | 2575 ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks()); |
| 2574 if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) { | 2576 if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) { |
| 2575 Bool& as_bool = Bool::ZoneHandle(InstanceOfAsBool(unary_checks, type)); | 2577 Bool& as_bool = Bool::ZoneHandle(InstanceOfAsBool(unary_checks, type)); |
| 2576 if (as_bool.raw() == Bool::True().raw()) { | 2578 if (as_bool.raw() == Bool::True().raw()) { |
| 2577 AddReceiverCheck(call); | 2579 AddReceiverCheck(call); |
| 2578 // Remove the original push arguments. | 2580 // Remove the original push arguments. |
| 2579 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { | 2581 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { |
| 2580 PushArgumentInstr* push = call->PushArgumentAt(i); | 2582 PushArgumentInstr* push = call->PushArgumentAt(i); |
| 2581 push->ReplaceUsesWith(push->value()->definition()); | 2583 push->ReplaceUsesWith(push->value()->definition()); |
| (...skipping 4925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7507 } | 7509 } |
| 7508 | 7510 |
| 7509 // Insert materializations at environment uses. | 7511 // Insert materializations at environment uses. |
| 7510 for (intptr_t i = 0; i < exits.length(); i++) { | 7512 for (intptr_t i = 0; i < exits.length(); i++) { |
| 7511 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); | 7513 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); |
| 7512 } | 7514 } |
| 7513 } | 7515 } |
| 7514 | 7516 |
| 7515 | 7517 |
| 7516 } // namespace dart | 7518 } // namespace dart |
| OLD | NEW |