Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(596)

Side by Side Diff: runtime/vm/flow_graph_optimizer.cc

Issue 1158673004: Do not eagerly add guarded leaf classes with CHA; do not add them for private names. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: typos in comments Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698