Bug 1384238 - Annotate BHR hangs which occur while there is a pending input event, r=smaug
MozReview-Commit-ID: HRPMw2IfEKB
This commit is contained in:
@@ -10686,6 +10686,29 @@ nsContentUtils::GetSourceMapURL(nsIHttpChannel* aChannel, nsACString& aResult)
|
||||
return NS_SUCCEEDED(rv);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
nsContentUtils::IsMessageInputEvent(const IPC::Message& aMsg)
|
||||
{
|
||||
if ((aMsg.type() & mozilla::dom::PBrowser::PBrowserStart)
|
||||
== mozilla::dom::PBrowser::PBrowserStart) {
|
||||
switch (aMsg.type()) {
|
||||
case mozilla::dom::PBrowser::Msg_RealMouseMoveEvent__ID:
|
||||
case mozilla::dom::PBrowser::Msg_RealMouseButtonEvent__ID:
|
||||
case mozilla::dom::PBrowser::Msg_RealKeyEvent__ID:
|
||||
case mozilla::dom::PBrowser::Msg_MouseWheelEvent__ID:
|
||||
case mozilla::dom::PBrowser::Msg_RealTouchEvent__ID:
|
||||
case mozilla::dom::PBrowser::Msg_RealTouchMoveEvent__ID:
|
||||
case mozilla::dom::PBrowser::Msg_RealDragEvent__ID:
|
||||
case mozilla::dom::PBrowser::Msg_UpdateDimensions__ID:
|
||||
case mozilla::dom::PBrowser::Msg_MouseEvent__ID:
|
||||
case mozilla::dom::PBrowser::Msg_KeyEvent__ID:
|
||||
case mozilla::dom::PBrowser::Msg_SetDocShellIsActive__ID:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static const char* kUserInteractionInactive = "user-interaction-inactive";
|
||||
static const char* kUserInteractionActive = "user-interaction-active";
|
||||
|
||||
|
||||
@@ -3126,6 +3126,13 @@ public:
|
||||
*/
|
||||
static bool GetSourceMapURL(nsIHttpChannel* aChannel, nsACString& aResult);
|
||||
|
||||
/**
|
||||
* Returns true if the passed-in mesasge is a pending InputEvent.
|
||||
*
|
||||
* @param aMsg The message to check
|
||||
*/
|
||||
static bool IsMessageInputEvent(const IPC::Message& aMsg);
|
||||
|
||||
private:
|
||||
static bool InitializeEventTable();
|
||||
|
||||
|
||||
@@ -491,6 +491,29 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
/**
|
||||
* The singleton of this class is registered with the HangMonitor as an
|
||||
* annotator, so that the hang monitor can record whether or not there were
|
||||
* pending input events when the thread hung.
|
||||
*/
|
||||
class PendingInputEventHangAnnotator final
|
||||
: public HangMonitor::Annotator
|
||||
{
|
||||
public:
|
||||
virtual void AnnotateHang(HangMonitor::HangAnnotations& aAnnotations)
|
||||
{
|
||||
int32_t pending = ContentChild::GetSingleton()->GetPendingInputEvents();
|
||||
if (pending > 0) {
|
||||
aAnnotations.AddAnnotation(NS_LITERAL_STRING("PendingInput"), pending);
|
||||
}
|
||||
}
|
||||
|
||||
static PendingInputEventHangAnnotator sSingleton;
|
||||
};
|
||||
PendingInputEventHangAnnotator PendingInputEventHangAnnotator::sSingleton;
|
||||
#endif
|
||||
|
||||
NS_IMPL_ISUPPORTS(BackgroundChildPrimer, nsIIPCBackgroundChildCreateCallback)
|
||||
|
||||
ContentChild* ContentChild::sSingleton;
|
||||
@@ -638,6 +661,10 @@ ContentChild::Init(MessageLoop* aIOLoop,
|
||||
|
||||
SetProcessName(NS_LITERAL_STRING("Web Content"));
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
HangMonitor::RegisterAnnotator(PendingInputEventHangAnnotator::sSingleton);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2930,6 +2957,10 @@ ContentChild::RecvShutdown()
|
||||
|
||||
mShuttingDown = true;
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
HangMonitor::UnregisterAnnotator(PendingInputEventHangAnnotator::sSingleton);
|
||||
#endif
|
||||
|
||||
if (mPolicy) {
|
||||
mPolicy->Deactivate();
|
||||
mPolicy = nullptr;
|
||||
@@ -3580,6 +3611,33 @@ ContentChild::GetSpecificMessageEventTarget(const Message& aMsg)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
void
|
||||
ContentChild::OnChannelReceivedMessage(const Message& aMsg)
|
||||
{
|
||||
if (nsContentUtils::IsMessageInputEvent(aMsg)) {
|
||||
mPendingInputEvents++;
|
||||
}
|
||||
}
|
||||
|
||||
PContentChild::Result
|
||||
ContentChild::OnMessageReceived(const Message& aMsg)
|
||||
{
|
||||
if (nsContentUtils::IsMessageInputEvent(aMsg)) {
|
||||
DebugOnly<uint32_t> prevEvts = mPendingInputEvents--;
|
||||
MOZ_ASSERT(prevEvts > 0);
|
||||
}
|
||||
|
||||
return PContentChild::OnMessageReceived(aMsg);
|
||||
}
|
||||
|
||||
PContentChild::Result
|
||||
ContentChild::OnMessageReceived(const Message& aMsg, Message*& aReply)
|
||||
{
|
||||
return PContentChild::OnMessageReceived(aMsg, aReply);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace dom
|
||||
|
||||
#if !defined(XP_WIN)
|
||||
|
||||
@@ -681,6 +681,17 @@ public:
|
||||
nsTArray<PluginTag>&& aPluginTags,
|
||||
nsTArray<FakePluginTag>&& aFakePluginTags) override;
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
// Fetch the current number of pending input events.
|
||||
//
|
||||
// NOTE: This method performs an atomic read, and is safe to call from all threads.
|
||||
uint32_t
|
||||
GetPendingInputEvents()
|
||||
{
|
||||
return mPendingInputEvents;
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
static void ForceKillTimerCallback(nsITimer* aTimer, void* aClosure);
|
||||
void StartForceKillTimer();
|
||||
@@ -695,6 +706,17 @@ private:
|
||||
virtual already_AddRefed<nsIEventTarget>
|
||||
GetSpecificMessageEventTarget(const Message& aMsg) override;
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
virtual void
|
||||
OnChannelReceivedMessage(const Message& aMsg) override;
|
||||
|
||||
virtual PContentChild::Result
|
||||
OnMessageReceived(const Message& aMsg) override;
|
||||
|
||||
virtual PContentChild::Result
|
||||
OnMessageReceived(const Message& aMsg, Message*& aReply) override;
|
||||
#endif
|
||||
|
||||
InfallibleTArray<nsAutoPtr<AlertObserver> > mAlertObservers;
|
||||
RefPtr<ConsoleListener> mConsoleListener;
|
||||
|
||||
@@ -765,6 +787,11 @@ private:
|
||||
|
||||
mozilla::Atomic<bool> mShuttingDown;
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
// NOTE: This member is atomic because it can be accessed from off-main-thread.
|
||||
mozilla::Atomic<uint32_t> mPendingInputEvents;
|
||||
#endif
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(ContentChild);
|
||||
};
|
||||
|
||||
|
||||
@@ -1404,24 +1404,10 @@ PuppetWidget::HasPendingInputEvent()
|
||||
|
||||
mTabChild->GetIPCChannel()->PeekMessages(
|
||||
[&ret](const IPC::Message& aMsg) -> bool {
|
||||
if ((aMsg.type() & mozilla::dom::PBrowser::PBrowserStart)
|
||||
== mozilla::dom::PBrowser::PBrowserStart) {
|
||||
switch (aMsg.type()) {
|
||||
case mozilla::dom::PBrowser::Msg_RealMouseMoveEvent__ID:
|
||||
case mozilla::dom::PBrowser::Msg_RealMouseButtonEvent__ID:
|
||||
case mozilla::dom::PBrowser::Msg_RealKeyEvent__ID:
|
||||
case mozilla::dom::PBrowser::Msg_MouseWheelEvent__ID:
|
||||
case mozilla::dom::PBrowser::Msg_RealTouchEvent__ID:
|
||||
case mozilla::dom::PBrowser::Msg_RealTouchMoveEvent__ID:
|
||||
case mozilla::dom::PBrowser::Msg_RealDragEvent__ID:
|
||||
case mozilla::dom::PBrowser::Msg_UpdateDimensions__ID:
|
||||
case mozilla::dom::PBrowser::Msg_MouseEvent__ID:
|
||||
case mozilla::dom::PBrowser::Msg_KeyEvent__ID:
|
||||
case mozilla::dom::PBrowser::Msg_SetDocShellIsActive__ID:
|
||||
if (nsContentUtils::IsMessageInputEvent(aMsg)) {
|
||||
ret = true;
|
||||
return false; // Stop peeking.
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user