Treat dispatchers and implicit accessors the same for inlining decisions.

R=fschneider@google.com

Review-Url: https://codereview.chromium.org/2572543003 .
This commit is contained in:
Ryan Macnak 2016-12-12 15:36:43 -08:00
parent 7eef11a0e8
commit 66182e5881
3 changed files with 23 additions and 13 deletions

View file

@ -381,7 +381,8 @@ class CallSites : public ValueObject {
current->AsPolymorphicInstanceCall();
if (!inline_only_recognized_methods ||
instance_call->HasSingleRecognizedTarget() ||
instance_call->ic_data().HasOnlyDispatcherTargets()) {
instance_call->ic_data()
.HasOnlyDispatcherOrImplicitAccessorTargets()) {
instance_calls_.Add(InstanceCallInfo(instance_call, graph));
} else {
// Method not inlined because inlining too deep and method
@ -397,7 +398,8 @@ class CallSites : public ValueObject {
} else if (current->IsStaticCall()) {
StaticCallInstr* static_call = current->AsStaticCall();
if (!inline_only_recognized_methods ||
static_call->function().IsRecognized()) {
static_call->function().IsRecognized() ||
static_call->function().IsDispatcherOrImplicitAccessor()) {
static_calls_.Add(StaticCallInfo(static_call, graph));
} else {
// Method not inlined because inlining too deep and method
@ -936,10 +938,8 @@ class CallSiteInliner : public ValueObject {
}
// Inline dispatcher methods regardless of the current depth.
const intptr_t depth = (function.IsInvokeFieldDispatcher() ||
function.IsNoSuchMethodDispatcher())
? 0
: inlining_depth_;
const intptr_t depth =
function.IsDispatcherOrImplicitAccessor() ? 0 : inlining_depth_;
collected_call_sites_->FindCallSites(callee_graph, depth,
&inlined_info_);
@ -1924,9 +1924,8 @@ bool FlowGraphInliner::AlwaysInline(const Function& function) {
return true;
}
if (function.IsImplicitGetterFunction() ||
function.IsImplicitSetterFunction()) {
// Inlined accessors are smaller than a call.
if (function.IsDispatcherOrImplicitAccessor()) {
// Smaller or same size as the call.
return true;
}

View file

@ -13441,13 +13441,12 @@ bool ICData::HasOneTarget() const {
}
bool ICData::HasOnlyDispatcherTargets() const {
bool ICData::HasOnlyDispatcherOrImplicitAccessorTargets() const {
const intptr_t len = NumberOfChecks();
Function& target = Function::Handle();
for (intptr_t i = 0; i < len; i++) {
target = GetTargetAt(i);
if (!target.IsNoSuchMethodDispatcher() &&
!target.IsInvokeFieldDispatcher()) {
if (!target.IsDispatcherOrImplicitAccessor()) {
return false;
}
}

View file

@ -2033,7 +2033,7 @@ class ICData : public Object {
bool AllTargetsHaveSameOwner(intptr_t owner_cid) const;
bool AllReceiversAreNumbers() const;
bool HasOneTarget() const;
bool HasOnlyDispatcherTargets() const;
bool HasOnlyDispatcherOrImplicitAccessorTargets() const;
bool HasReceiverClassId(intptr_t class_id) const;
static RawICData* New(const Function& owner,
@ -2649,6 +2649,18 @@ class Function : public Object {
Error* bound_error,
Heap::Space space) const;
bool IsDispatcherOrImplicitAccessor() const {
switch (kind()) {
case RawFunction::kImplicitGetter:
case RawFunction::kImplicitSetter:
case RawFunction::kNoSuchMethodDispatcher:
case RawFunction::kInvokeFieldDispatcher:
return true;
default:
return false;
}
}
// Returns true if this function represents an explicit getter function.
bool IsGetterFunction() const {
return kind() == RawFunction::kGetterFunction;