mirror of
https://github.com/dart-lang/sdk
synced 2024-09-19 23:31:42 +00:00
Do not recompute unary_checks repeatedly. Add special (and quicker) way to check for method overrides using CHA.
Review URL: https://codereview.chromium.org//11275110 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@14434 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
a2c7ebced0
commit
251169951b
|
@ -70,6 +70,27 @@ ZoneGrowableArray<intptr_t>* CHA::GetSubclassIdsOf(intptr_t cid) {
|
|||
}
|
||||
|
||||
|
||||
bool CHA::HasOverride(const Class& cls, const String& function_name) {
|
||||
const GrowableObjectArray& cls_direct_subclasses =
|
||||
GrowableObjectArray::Handle(cls.direct_subclasses());
|
||||
if (cls_direct_subclasses.IsNull()) {
|
||||
return false;
|
||||
}
|
||||
Class& direct_subclass = Class::Handle();
|
||||
for (intptr_t i = 0; i < cls_direct_subclasses.Length(); i++) {
|
||||
direct_subclass ^= cls_direct_subclasses.At(i);
|
||||
if (direct_subclass.LookupDynamicFunction(function_name) !=
|
||||
Function::null()) {
|
||||
return true;
|
||||
}
|
||||
if (HasOverride(direct_subclass, function_name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
ZoneGrowableArray<Function*>* CHA::GetNamedInstanceFunctionsOf(
|
||||
const ZoneGrowableArray<intptr_t>& cids,
|
||||
const String& function_name) {
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
namespace dart {
|
||||
|
||||
class Class;
|
||||
class Function;
|
||||
template <typename T> class ZoneGrowableArray;
|
||||
class String;
|
||||
|
@ -33,6 +34,9 @@ class CHA : public AllStatic {
|
|||
// Returns an array of functions overriding the given function.
|
||||
// Must not be called for a function of class Object.
|
||||
static ZoneGrowableArray<Function*>* GetOverridesOf(const Function& function);
|
||||
|
||||
// Returns true if any subclass of 'cls' contains the function.
|
||||
static bool HasOverride(const Class& cls, const String& function_name);
|
||||
};
|
||||
|
||||
} // namespace dart
|
||||
|
|
|
@ -876,19 +876,8 @@ bool FlowGraphOptimizer::InstanceCallNeedsClassCheck(
|
|||
if (function.IsDynamicFunction() &&
|
||||
callee_receiver->IsParameter() &&
|
||||
(callee_receiver->AsParameter()->index() == 0)) {
|
||||
const intptr_t static_receiver_cid = Class::Handle(function.Owner()).id();
|
||||
ZoneGrowableArray<intptr_t>* subclass_cids =
|
||||
CHA::GetSubclassIdsOf(static_receiver_cid);
|
||||
if (subclass_cids->is_empty()) {
|
||||
// No subclasses, no check needed.
|
||||
return false;
|
||||
}
|
||||
ZoneGrowableArray<Function*>* overriding_functions =
|
||||
CHA::GetNamedInstanceFunctionsOf(*subclass_cids, call->function_name());
|
||||
if (overriding_functions->is_empty()) {
|
||||
// No overriding functions.
|
||||
return false;
|
||||
}
|
||||
return CHA::HasOverride(Class::Handle(function.Owner()),
|
||||
call->function_name());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1155,7 +1144,8 @@ void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) {
|
|||
if ((op_kind == Token::kGET) && TryInlineInstanceGetter(instr)) {
|
||||
return;
|
||||
}
|
||||
if ((op_kind == Token::kSET) && TryInlineInstanceSetter(instr)) {
|
||||
if ((op_kind == Token::kSET) &&
|
||||
TryInlineInstanceSetter(instr, unary_checks)) {
|
||||
return;
|
||||
}
|
||||
if (TryInlineInstanceMethod(instr)) {
|
||||
|
@ -1198,15 +1188,16 @@ void FlowGraphOptimizer::VisitStaticCall(StaticCallInstr* call) {
|
|||
}
|
||||
|
||||
|
||||
bool FlowGraphOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr) {
|
||||
bool FlowGraphOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr,
|
||||
const ICData& unary_ic_data) {
|
||||
ASSERT((unary_ic_data.NumberOfChecks() > 0) &&
|
||||
(unary_ic_data.num_args_tested() == 1));
|
||||
if (FLAG_enable_type_checks) {
|
||||
// TODO(srdjan): Add assignable check node if --enable_type_checks.
|
||||
return false;
|
||||
}
|
||||
|
||||
ASSERT(instr->HasICData());
|
||||
const ICData& unary_ic_data =
|
||||
ICData::Handle(instr->ic_data()->AsUnaryClassChecks());
|
||||
if (unary_ic_data.NumberOfChecks() == 0) {
|
||||
// No type feedback collected.
|
||||
return false;
|
||||
|
|
|
@ -63,7 +63,8 @@ class FlowGraphOptimizer : public FlowGraphVisitor {
|
|||
bool TryReplaceWithUnaryOp(InstanceCallInstr* call, Token::Kind op_kind);
|
||||
|
||||
bool TryInlineInstanceGetter(InstanceCallInstr* call);
|
||||
bool TryInlineInstanceSetter(InstanceCallInstr* call);
|
||||
bool TryInlineInstanceSetter(InstanceCallInstr* call,
|
||||
const ICData& unary_ic_data);
|
||||
|
||||
bool TryInlineInstanceMethod(InstanceCallInstr* call);
|
||||
|
||||
|
|
Loading…
Reference in a new issue