Bug 1447744 - don't implement nsINamed for mozilla::Runnable when it's unused; r=erahm

We only use nsINamed on runnables for certain kinds of telemetry, and
those kinds of telemetry aren't being gathered on RELEASE_OR_BETA
builds.  We effectively make nsINamed::GetName a no-op when we're not
collecting said telemetry.  But implementing nsINamed does have a cost:
the vtable of every runnable (and we have hundreds of subclasses of
mozilla::Runnable) will contain pointers for GetName (and extra pointers
for QueryInterface/AddRef/Release), and all those pointers times all
those subclasses adds up quickly.  Let's not implement nsINamed when
nsINamed isn't going to be used.

This change saves ~100K of binary size on x86-64 Linux; the savings
should be similar on other 64-bit systems, and ~50K on 32-bit systems.
This commit is contained in:
Nathan Froyd 2018-03-23 14:53:55 -04:00
Родитель f7414393ca
Коммит efd709bd4f
10 изменённых файлов: 45 добавлений и 20 удалений

Просмотреть файл

@ -170,11 +170,9 @@ static void Expect(const char* aContext, int aCounter, int aMaxExpected)
static void ExpectRunnableName(Runnable* aRunnable, const char* aExpectedName)
{
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
nsAutoCString name;
EXPECT_TRUE(NS_SUCCEEDED(aRunnable->GetName(name))) << "Runnable::GetName()";
#ifdef RELEASE_OR_BETA
EXPECT_TRUE(name.IsEmpty()) << "Runnable name shall be empty in RELEASE or BETA!";
#else
EXPECT_TRUE(name.EqualsASCII(aExpectedName)) << "Verify Runnable name";
#endif
}

Просмотреть файл

@ -173,6 +173,7 @@ private:
return rv;
}
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
NS_IMETHOD GetName(nsACString& aName) override
{
aName.AssignLiteral("AbstractThread::Runner");
@ -186,6 +187,7 @@ private:
}
return NS_OK;
}
#endif
private:
RefPtr<EventTargetWrapper> mThread;

Просмотреть файл

@ -384,6 +384,7 @@ SchedulerGroup::Runnable::DocGroup() const
return mDocGroup;
}
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
NS_IMETHODIMP
SchedulerGroup::Runnable::GetName(nsACString& aName)
{
@ -398,6 +399,7 @@ SchedulerGroup::Runnable::GetName(nsACString& aName)
return NS_OK;
}
#endif
NS_IMETHODIMP
SchedulerGroup::Runnable::Run()

Просмотреть файл

@ -122,7 +122,9 @@ public:
SchedulerGroup* Group() const { return mGroup; }
dom::DocGroup* DocGroup() const;
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
NS_IMETHOD GetName(nsACString& aName) override;
#endif
bool IsBackground() const { return mGroup->IsBackground(); }

Просмотреть файл

@ -80,11 +80,13 @@ class ThrottledEventQueue::Inner final : public nsIObserver
return NS_OK;
}
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
NS_IMETHODIMP
GetName(nsACString& aName) override
{
return mInner->CurrentName(aName);
}
#endif
};
mutable Mutex mMutex;

Просмотреть файл

@ -145,7 +145,9 @@ public:
return NS_OK;
}
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
NS_IMETHOD GetName(nsACString& aName) override;
#endif
nsTimerEvent()
: mozilla::CancelableRunnable("nsTimerEvent")
@ -263,6 +265,7 @@ nsTimerEvent::DeleteAllocatorIfNeeded()
}
}
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
NS_IMETHODIMP
nsTimerEvent::GetName(nsACString& aName)
{
@ -272,6 +275,7 @@ nsTimerEvent::GetName(nsACString& aName)
mTimer->GetName(aName);
return NS_OK;
}
#endif
NS_IMETHODIMP
nsTimerEvent::Run()

Просмотреть файл

@ -44,19 +44,17 @@ public:
return Run();
}
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
NS_IMETHOD GetName(nsACString& aName) override
{
#ifdef RELEASE_OR_BETA
aName.Truncate();
#else
if (mName) {
aName.Append(nsPrintfCString("ProxyReleaseEvent for %s", mName));
} else {
aName.AssignLiteral("ProxyReleaseEvent");
}
#endif
return NS_OK;
}
#endif
private:
T* MOZ_OWNING_REF mDoomed;

Просмотреть файл

@ -900,7 +900,7 @@ void canary_alarm_handler(int signum)
} \
} while(0)
#ifndef RELEASE_OR_BETA
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
static bool
GetLabeledRunnableName(nsIRunnable* aEvent,
nsACString& aName,
@ -1011,7 +1011,7 @@ nsThread::ProcessNextEvent(bool aMayWait, bool* aResult)
HangMonitor::NotifyActivity();
}
#ifndef RELEASE_OR_BETA
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
bool schedulerLoggingEnabled = GetSchedulerLoggingEnabled();
if (schedulerLoggingEnabled
&& mNestedEventLoopDepth > mCurrentEventLoopDepth

Просмотреть файл

@ -43,8 +43,8 @@ IdlePeriod::GetIdlePeriodHint(TimeStamp* aIdleDeadline)
// NS_IMPL_NAMED_* relies on the mName field, which is not present on
// release or beta. Instead, fall back to using "Runnable" for all
// runnables.
#ifdef RELEASE_OR_BETA
NS_IMPL_ISUPPORTS(Runnable, nsIRunnable, nsINamed)
#ifndef MOZ_COLLECTING_RUNNABLE_TELEMETRY
NS_IMPL_ISUPPORTS(Runnable, nsIRunnable)
#else
NS_IMPL_NAMED_ADDREF(Runnable, mName)
NS_IMPL_NAMED_RELEASE(Runnable, mName)
@ -58,20 +58,18 @@ Runnable::Run()
return NS_OK;
}
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
NS_IMETHODIMP
Runnable::GetName(nsACString& aName)
{
#ifdef RELEASE_OR_BETA
aName.Truncate();
#else
if (mName) {
aName.AssignASCII(mName);
} else {
aName.Truncate();
}
#endif
return NS_OK;
}
#endif
NS_IMPL_ISUPPORTS_INHERITED(CancelableRunnable, Runnable,
nsICancelableRunnable)
@ -102,6 +100,7 @@ PrioritizableRunnable::PrioritizableRunnable(already_AddRefed<nsIRunnable>&& aRu
#endif
}
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
NS_IMETHODIMP
PrioritizableRunnable::GetName(nsACString& aName)
{
@ -112,6 +111,7 @@ PrioritizableRunnable::GetName(nsACString& aName)
}
return NS_OK;
}
#endif
NS_IMETHODIMP
PrioritizableRunnable::Run()
@ -364,6 +364,7 @@ public:
aTarget);
}
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
NS_IMETHOD GetName(nsACString& aName) override
{
aName.AssignLiteral("IdleRunnableWrapper");
@ -377,6 +378,7 @@ public:
}
return NS_OK;
}
#endif
private:
~IdleRunnableWrapper()

Просмотреть файл

@ -425,26 +425,39 @@ enum RunnableKind
IdleWithTimer
};
// Implementing nsINamed on Runnable bloats vtables for the hundreds of
// Runnable subclasses that we have, so we want to avoid that overhead
// when we're not using nsINamed for anything.
#ifndef RELEASE_OR_BETA
#define MOZ_COLLECTING_RUNNABLE_TELEMETRY
#endif
// This class is designed to be subclassed.
class Runnable : public nsIRunnable, public nsINamed
class Runnable
: public nsIRunnable
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
, public nsINamed
#endif
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIRUNNABLE
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
NS_DECL_NSINAMED
#endif
Runnable() = delete;
#ifdef RELEASE_OR_BETA
explicit Runnable(const char* aName) {}
#else
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
explicit Runnable(const char* aName) : mName(aName) {}
#else
explicit Runnable(const char* aName) {}
#endif
protected:
virtual ~Runnable() {}
#ifndef RELEASE_OR_BETA
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
const char* mName = nullptr;
#endif
@ -503,7 +516,9 @@ public:
PrioritizableRunnable(already_AddRefed<nsIRunnable>&& aRunnable,
uint32_t aPriority);
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
NS_IMETHOD GetName(nsACString& aName) override;
#endif
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIRUNNABLE