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 2982 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2993 } | 2993 } |
2994 } | 2994 } |
2995 | 2995 |
2996 | 2996 |
2997 // Returns a Boolean constant if all classes in ic_data yield the same type-test | 2997 // Returns a Boolean constant if all classes in ic_data yield the same type-test |
2998 // result and the type tests do not depend on type arguments. Otherwise return | 2998 // result and the type tests do not depend on type arguments. Otherwise return |
2999 // Bool::null(). | 2999 // Bool::null(). |
3000 RawBool* FlowGraphOptimizer::InstanceOfAsBool(const ICData& ic_data, | 3000 RawBool* FlowGraphOptimizer::InstanceOfAsBool(const ICData& ic_data, |
3001 const AbstractType& type) const { | 3001 const AbstractType& type) const { |
3002 ASSERT(ic_data.num_args_tested() == 1); // Unary checks only. | 3002 ASSERT(ic_data.num_args_tested() == 1); // Unary checks only. |
3003 if (!type.IsInstantiated() || type.IsMalformed() || type.IsMalbounded()) { | 3003 if (!type.IsInstantiated() || type.IsMalformedOrMalbounded()) { |
3004 return Bool::null(); | 3004 return Bool::null(); |
3005 } | 3005 } |
3006 const Class& type_class = Class::Handle(type.type_class()); | 3006 const Class& type_class = Class::Handle(type.type_class()); |
3007 if (type_class.NumTypeArguments() > 0) { | 3007 if (type_class.NumTypeArguments() > 0) { |
3008 // Only raw types can be directly compared, thus disregarding type | 3008 // Only raw types can be directly compared, thus disregarding type |
3009 // arguments. | 3009 // arguments. |
3010 const AbstractTypeArguments& type_arguments = | 3010 const AbstractTypeArguments& type_arguments = |
3011 AbstractTypeArguments::Handle(type.arguments()); | 3011 AbstractTypeArguments::Handle(type.arguments()); |
3012 const bool is_raw_type = type_arguments.IsNull() || | 3012 const bool is_raw_type = type_arguments.IsNull() || |
3013 type_arguments.IsRaw(type_arguments.Length()); | 3013 type_arguments.IsRaw(type_arguments.Length()); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3091 } | 3091 } |
3092 | 3092 |
3093 | 3093 |
3094 void FlowGraphOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) { | 3094 void FlowGraphOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) { |
3095 ASSERT(Token::IsTypeCastOperator(call->token_kind())); | 3095 ASSERT(Token::IsTypeCastOperator(call->token_kind())); |
3096 Definition* left = call->ArgumentAt(0); | 3096 Definition* left = call->ArgumentAt(0); |
3097 Definition* instantiator = call->ArgumentAt(1); | 3097 Definition* instantiator = call->ArgumentAt(1); |
3098 Definition* type_args = call->ArgumentAt(2); | 3098 Definition* type_args = call->ArgumentAt(2); |
3099 const AbstractType& type = | 3099 const AbstractType& type = |
3100 AbstractType::Cast(call->ArgumentAt(3)->AsConstant()->value()); | 3100 AbstractType::Cast(call->ArgumentAt(3)->AsConstant()->value()); |
3101 ASSERT(!type.IsMalformed() && !type.IsMalbounded()); | 3101 ASSERT(!type.IsMalformedOrMalbounded()); |
3102 const ICData& unary_checks = | 3102 const ICData& unary_checks = |
3103 ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks()); | 3103 ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks()); |
3104 if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) { | 3104 if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) { |
3105 Bool& as_bool = Bool::ZoneHandle(InstanceOfAsBool(unary_checks, type)); | 3105 Bool& as_bool = Bool::ZoneHandle(InstanceOfAsBool(unary_checks, type)); |
3106 if (as_bool.raw() == Bool::True().raw()) { | 3106 if (as_bool.raw() == Bool::True().raw()) { |
3107 AddReceiverCheck(call); | 3107 AddReceiverCheck(call); |
3108 // Remove the original push arguments. | 3108 // Remove the original push arguments. |
3109 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { | 3109 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { |
3110 PushArgumentInstr* push = call->PushArgumentAt(i); | 3110 PushArgumentInstr* push = call->PushArgumentAt(i); |
3111 push->ReplaceUsesWith(push->value()->definition()); | 3111 push->ReplaceUsesWith(push->value()->definition()); |
(...skipping 4800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7912 } | 7912 } |
7913 | 7913 |
7914 // Insert materializations at environment uses. | 7914 // Insert materializations at environment uses. |
7915 for (intptr_t i = 0; i < exits.length(); i++) { | 7915 for (intptr_t i = 0; i < exits.length(); i++) { |
7916 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); | 7916 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); |
7917 } | 7917 } |
7918 } | 7918 } |
7919 | 7919 |
7920 | 7920 |
7921 } // namespace dart | 7921 } // namespace dart |
OLD | NEW |