Chromium Code Reviews| 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/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 33 "Maximum number of polymorphic check, otherwise it is megamorphic."); | 33 "Maximum number of polymorphic check, otherwise it is megamorphic."); |
| 34 DEFINE_FLAG(int, max_equality_polymorphic_checks, 32, | 34 DEFINE_FLAG(int, max_equality_polymorphic_checks, 32, |
| 35 "Maximum number of polymorphic checks in equality operator," | 35 "Maximum number of polymorphic checks in equality operator," |
| 36 " otherwise use megamorphic dispatch."); | 36 " otherwise use megamorphic dispatch."); |
| 37 DEFINE_FLAG(bool, merge_sin_cos, false, "Merge sin/cos into sincos"); | 37 DEFINE_FLAG(bool, merge_sin_cos, false, "Merge sin/cos into sincos"); |
| 38 DEFINE_FLAG(bool, trace_load_optimization, false, | 38 DEFINE_FLAG(bool, trace_load_optimization, false, |
| 39 "Print live sets for load optimization pass."); | 39 "Print live sets for load optimization pass."); |
| 40 DEFINE_FLAG(bool, trace_optimization, false, "Print optimization details."); | 40 DEFINE_FLAG(bool, trace_optimization, false, "Print optimization details."); |
| 41 DEFINE_FLAG(bool, truncating_left_shift, true, | 41 DEFINE_FLAG(bool, truncating_left_shift, true, |
| 42 "Optimize left shift to truncate if possible"); | 42 "Optimize left shift to truncate if possible"); |
| 43 DEFINE_FLAG(bool, use_cha, true, "Use class hierarchy analysis."); | 43 DEFINE_FLAG(bool, use_cha_deopt, true, |
| 44 "Use class hierarchy analysis even if it can cause deoptimization."); | |
| 44 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_IA32) | 45 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_IA32) |
| 45 DEFINE_FLAG(bool, trace_smi_widening, false, "Trace Smi->Int32 widening pass."); | 46 DEFINE_FLAG(bool, trace_smi_widening, false, "Trace Smi->Int32 widening pass."); |
| 46 #endif | 47 #endif |
| 47 DECLARE_FLAG(bool, source_lines); | 48 DECLARE_FLAG(bool, source_lines); |
| 48 DECLARE_FLAG(bool, trace_type_check_elimination); | 49 DECLARE_FLAG(bool, trace_type_check_elimination); |
| 49 DECLARE_FLAG(bool, warn_on_javascript_compatibility); | 50 DECLARE_FLAG(bool, warn_on_javascript_compatibility); |
| 50 | 51 |
| 51 // Quick access to the current isolate and zone. | 52 // Quick access to the current isolate and zone. |
| 52 #define I (isolate()) | 53 #define I (isolate()) |
| 53 #define Z (zone()) | 54 #define Z (zone()) |
| (...skipping 2215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2269 } | 2270 } |
| 2270 return Field::null(); | 2271 return Field::null(); |
| 2271 } | 2272 } |
| 2272 | 2273 |
| 2273 | 2274 |
| 2274 // Use CHA to determine if the call needs a class check: if the callee's | 2275 // Use CHA to determine if the call needs a class check: if the callee's |
| 2275 // receiver is the same as the caller's receiver and there are no overriden | 2276 // receiver is the same as the caller's receiver and there are no overriden |
| 2276 // callee functions, then no class check is needed. | 2277 // callee functions, then no class check is needed. |
| 2277 bool FlowGraphOptimizer::InstanceCallNeedsClassCheck( | 2278 bool FlowGraphOptimizer::InstanceCallNeedsClassCheck( |
| 2278 InstanceCallInstr* call, RawFunction::Kind kind) const { | 2279 InstanceCallInstr* call, RawFunction::Kind kind) const { |
| 2279 if (!FLAG_use_cha) return true; | 2280 if (!FLAG_use_cha_deopt) { |
| 2281 // Even if class or function are private, lazy class finalization | |
| 2282 // may later add overriding methods. | |
| 2283 return true; | |
| 2284 } | |
| 2280 Definition* callee_receiver = call->ArgumentAt(0); | 2285 Definition* callee_receiver = call->ArgumentAt(0); |
| 2281 ASSERT(callee_receiver != NULL); | 2286 ASSERT(callee_receiver != NULL); |
| 2282 const Function& function = flow_graph_->function(); | 2287 const Function& function = flow_graph_->function(); |
| 2283 if (function.IsDynamicFunction() && | 2288 if (function.IsDynamicFunction() && |
| 2284 callee_receiver->IsParameter() && | 2289 callee_receiver->IsParameter() && |
| 2285 (callee_receiver->AsParameter()->index() == 0)) { | 2290 (callee_receiver->AsParameter()->index() == 0)) { |
|
rmacnak
2015/05/28 23:16:52
If we are inside a closure function, parameter 0 i
srdjan
2015/05/28 23:28:57
IsDynamicFunction() returns false for closures.
| |
| 2286 const String& name = (kind == RawFunction::kMethodExtractor) | 2291 const String& name = (kind == RawFunction::kMethodExtractor) |
| 2287 ? String::Handle(Z, Field::NameFromGetter(call->function_name())) | 2292 ? String::Handle(Z, Field::NameFromGetter(call->function_name())) |
| 2288 : call->function_name(); | 2293 : call->function_name(); |
| 2289 return thread()->cha()->HasOverride(Class::Handle(Z, function.Owner()), | 2294 const Class& cls = Class::Handle(Z, function.Owner()); |
| 2290 name); | 2295 if (!thread()->cha()->HasOverride(cls, name)) { |
| 2296 thread()->cha()->AddToLeafClasses(cls); | |
| 2297 return false; | |
| 2298 } | |
| 2291 } | 2299 } |
| 2292 return true; | 2300 return true; |
| 2293 } | 2301 } |
| 2294 | 2302 |
| 2295 | 2303 |
| 2296 bool FlowGraphOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call, | 2304 bool FlowGraphOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call, |
| 2297 bool allow_check) { | 2305 bool allow_check) { |
| 2298 ASSERT(call->HasICData()); | 2306 ASSERT(call->HasICData()); |
| 2299 const ICData& ic_data = *call->ic_data(); | 2307 const ICData& ic_data = *call->ic_data(); |
| 2300 ASSERT(ic_data.HasOneTarget()); | 2308 ASSERT(ic_data.HasOneTarget()); |
| (...skipping 1657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3958 } | 3966 } |
| 3959 } | 3967 } |
| 3960 return results_differ ? Bool::null() : prev.raw(); | 3968 return results_differ ? Bool::null() : prev.raw(); |
| 3961 } | 3969 } |
| 3962 | 3970 |
| 3963 | 3971 |
| 3964 // Returns true if checking against this type is a direct class id comparison. | 3972 // Returns true if checking against this type is a direct class id comparison. |
| 3965 bool FlowGraphOptimizer::TypeCheckAsClassEquality(const AbstractType& type) { | 3973 bool FlowGraphOptimizer::TypeCheckAsClassEquality(const AbstractType& type) { |
| 3966 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); | 3974 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); |
| 3967 // Requires CHA. | 3975 // Requires CHA. |
| 3968 if (!FLAG_use_cha) return false; | |
| 3969 if (!type.IsInstantiated()) return false; | 3976 if (!type.IsInstantiated()) return false; |
| 3970 const Class& type_class = Class::Handle(type.type_class()); | 3977 const Class& type_class = Class::Handle(type.type_class()); |
| 3971 // Signature classes have different type checking rules. | 3978 // Signature classes have different type checking rules. |
| 3972 if (type_class.IsSignatureClass()) return false; | 3979 if (type_class.IsSignatureClass()) return false; |
| 3973 // Could be an interface check? | 3980 // Could be an interface check? |
| 3974 if (thread()->cha()->IsImplemented(type_class)) return false; | 3981 if (thread()->cha()->IsImplemented(type_class)) return false; |
| 3975 // Check if there are subclasses. | 3982 // Check if there are subclasses. |
| 3976 if (thread()->cha()->HasSubclasses(type_class)) return false; | 3983 if (thread()->cha()->HasSubclasses(type_class)) { |
| 3984 return false; | |
| 3985 } | |
| 3986 | |
| 3987 // Private classes cannot be subclassed by later loaded libs. | |
| 3988 if (!type_class.IsPrivate()) { | |
| 3989 if (FLAG_use_cha_deopt) { | |
| 3990 thread()->cha()->AddToLeafClasses(type_class); | |
| 3991 } else { | |
| 3992 return false; | |
| 3993 } | |
| 3994 } | |
| 3977 const intptr_t num_type_args = type_class.NumTypeArguments(); | 3995 const intptr_t num_type_args = type_class.NumTypeArguments(); |
| 3978 if (num_type_args > 0) { | 3996 if (num_type_args > 0) { |
| 3979 // Only raw types can be directly compared, thus disregarding type | 3997 // Only raw types can be directly compared, thus disregarding type |
| 3980 // arguments. | 3998 // arguments. |
| 3981 const intptr_t num_type_params = type_class.NumTypeParameters(); | 3999 const intptr_t num_type_params = type_class.NumTypeParameters(); |
| 3982 const intptr_t from_index = num_type_args - num_type_params; | 4000 const intptr_t from_index = num_type_args - num_type_params; |
| 3983 const TypeArguments& type_arguments = | 4001 const TypeArguments& type_arguments = |
| 3984 TypeArguments::Handle(type.arguments()); | 4002 TypeArguments::Handle(type.arguments()); |
| 3985 const bool is_raw_type = type_arguments.IsNull() || | 4003 const bool is_raw_type = type_arguments.IsNull() || |
| 3986 type_arguments.IsRaw(from_index, num_type_params); | 4004 type_arguments.IsRaw(from_index, num_type_params); |
| (...skipping 4659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8646 | 8664 |
| 8647 // Insert materializations at environment uses. | 8665 // Insert materializations at environment uses. |
| 8648 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { | 8666 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { |
| 8649 CreateMaterializationAt( | 8667 CreateMaterializationAt( |
| 8650 exits_collector_.exits()[i], alloc, *slots); | 8668 exits_collector_.exits()[i], alloc, *slots); |
| 8651 } | 8669 } |
| 8652 } | 8670 } |
| 8653 | 8671 |
| 8654 | 8672 |
| 8655 } // namespace dart | 8673 } // namespace dart |
| OLD | NEW |