Skip to content

Commit

Permalink
Bug 950745 - Flag when we're processing urgent messages and disallow …
Browse files Browse the repository at this point in the history
…certain activities (r=bsmedberg,luke)
  • Loading branch information
bill-mccloskey committed Aug 6, 2014
1 parent 93d0498 commit e7051ac
Show file tree
Hide file tree
Showing 13 changed files with 71 additions and 1 deletion.
5 changes: 5 additions & 0 deletions dom/events/EventDispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "mozilla/EventDispatcher.h"
#include "mozilla/EventListenerManager.h"
#include "mozilla/InternalMutationEvent.h"
#include "mozilla/ipc/MessageChannel.h"
#include "mozilla/MiscEvents.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/TextEvents.h"
Expand Down Expand Up @@ -400,6 +401,10 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
NS_ERROR_DOM_INVALID_STATE_ERR);
NS_ASSERTION(!aTargets || !aEvent->message, "Wrong parameters!");

#ifdef NIGHTLY_BUILD
MOZ_RELEASE_ASSERT(!mozilla::ipc::ProcessingUrgentMessages());
#endif

// If we're dispatching an already created DOMEvent object, make
// sure it is initialized!
// If aTargets is non-null, the event isn't going to be dispatched.
Expand Down
12 changes: 12 additions & 0 deletions ipc/glue/MessageChannel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ struct RunnableMethodTraits<mozilla::ipc::MessageChannel>
DebugAbort(__FILE__, __LINE__, #_cond,## __VA_ARGS__); \
} while (0)

static uintptr_t gDispatchingUrgentMessageCount;

namespace mozilla {
namespace ipc {

Expand Down Expand Up @@ -1099,9 +1101,13 @@ MessageChannel::DispatchUrgentMessage(const Message& aMsg)

Message *reply = nullptr;

MOZ_ASSERT(NS_IsMainThread());

gDispatchingUrgentMessageCount++;
mDispatchingUrgentMessageCount++;
Result rv = mListener->OnCallReceived(aMsg, reply);
mDispatchingUrgentMessageCount--;
gDispatchingUrgentMessageCount--;

if (!MaybeHandleError(rv, "DispatchUrgentMessage")) {
delete reply;
Expand Down Expand Up @@ -1752,5 +1758,11 @@ MessageChannel::DumpInterruptStack(const char* const pfx) const
}
}

bool
ProcessingUrgentMessages()
{
return gDispatchingUrgentMessageCount > 0;
}

} // ipc
} // mozilla
3 changes: 3 additions & 0 deletions ipc/glue/MessageChannel.h
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,9 @@ class MessageChannel : HasResultCodes
bool mAbortOnError;
};

bool
ProcessingUrgentMessages();

} // namespace ipc
} // namespace mozilla

Expand Down
16 changes: 16 additions & 0 deletions js/ipc/JavaScriptChild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,30 @@
#include "JavaScriptChild.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/ipc/MessageChannel.h"
#include "nsContentUtils.h"
#include "xpcprivate.h"
#include "jsfriendapi.h"
#include "nsCxPusher.h"
#include "AccessCheck.h"

using namespace JS;
using namespace mozilla;
using namespace mozilla::jsipc;

using mozilla::AutoSafeJSContext;

#ifdef NIGHTLY_BUILD
static void
UrgentMessageCheck(JSContext *cx, HandleScript script)
{
// We're only allowed to enter chrome JS code while processing urgent
// messages.
if (ipc::ProcessingUrgentMessages())
MOZ_RELEASE_ASSERT(xpc::AccessCheck::isChrome(js::GetContextCompartment(cx)));
}
#endif

static void
FinalizeChild(JSFreeOp *fop, JSFinalizeStatus status, bool isCompartment, void *data)
{
Expand All @@ -31,6 +44,9 @@ JavaScriptChild::JavaScriptChild(JSRuntime *rt)
: JavaScriptShared(rt),
JavaScriptBase<PJavaScriptChild>(rt)
{
#ifdef NIGHTLY_BUILD
js::SetAssertOnScriptEntryHook(rt, UrgentMessageCheck);
#endif
}

JavaScriptChild::~JavaScriptChild()
Expand Down
1 change: 1 addition & 0 deletions js/ipc/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ LOCAL_INCLUDES += [
'/js/ipc',
'/js/public',
'/js/xpconnect/src',
'/js/xpconnect/wrappers',
]

8 changes: 8 additions & 0 deletions js/src/jsfriendapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ js::ForgetSourceHook(JSRuntime *rt)
return Move(rt->sourceHook);
}

#ifdef NIGHTLY_BUILD
JS_FRIEND_API(void)
js::SetAssertOnScriptEntryHook(JSRuntime *rt, AssertOnScriptEntryHook hook)
{
rt->assertOnScriptEntryHook_ = hook;
}
#endif

JS_FRIEND_API(void)
JS_SetGrayGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data)
{
Expand Down
7 changes: 7 additions & 0 deletions js/src/jsfriendapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,13 @@ SetSourceHook(JSRuntime *rt, mozilla::UniquePtr<SourceHook> hook);
extern JS_FRIEND_API(mozilla::UniquePtr<SourceHook>)
ForgetSourceHook(JSRuntime *rt);

#ifdef NIGHTLY_BUILD
typedef void (*AssertOnScriptEntryHook)(JSContext *cx, JS::HandleScript script);

extern JS_FRIEND_API(void)
SetAssertOnScriptEntryHook(JSRuntime *rt, AssertOnScriptEntryHook hook);
#endif

extern JS_FRIEND_API(JS::Zone *)
GetCompartmentZone(JSCompartment *comp);

Expand Down
5 changes: 5 additions & 0 deletions js/src/vm/Interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,11 @@ js::RunScript(JSContext *cx, RunState &state)
{
JS_CHECK_RECURSION(cx, return false);

#ifdef NIGHTLY_BUILD
if (AssertOnScriptEntryHook hook = cx->runtime()->assertOnScriptEntryHook_)
(*hook)(cx, state.script());
#endif

SPSEntryMarker marker(cx->runtime(), state.script());

state.script()->ensureNonLazyCanonicalFunction(cx);
Expand Down
2 changes: 1 addition & 1 deletion js/src/vm/Interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ class RunState
return (GeneratorState *)this;
}

JSScript *script() const { return script_; }
JS::HandleScript script() const { return script_; }

virtual InterpreterFrame *pushInterpreterFrame(JSContext *cx) = 0;
virtual void setReturnValue(Value v) = 0;
Expand Down
3 changes: 3 additions & 0 deletions js/src/vm/Runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,9 @@ JSRuntime::JSRuntime(JSRuntime *parentRuntime)
negativeInfinityValue(DoubleValue(NegativeInfinity<double>())),
positiveInfinityValue(DoubleValue(PositiveInfinity<double>())),
emptyString(nullptr),
#ifdef NIGHTLY_BUILD
assertOnScriptEntryHook_(nullptr),
#endif
debugMode(false),
spsProfiler(thisFromCtor()),
profilingScripts(false),
Expand Down
4 changes: 4 additions & 0 deletions js/src/vm/Runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,10 @@ struct JSRuntime : public JS::shadow::Runtime,

mozilla::UniquePtr<js::SourceHook> sourceHook;

#ifdef NIGHTLY_BUILD
js::AssertOnScriptEntryHook assertOnScriptEntryHook_;
#endif

/* If true, new compartments are initially in debug mode. */
bool debugMode;

Expand Down
2 changes: 2 additions & 0 deletions widget/windows/nsWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4341,6 +4341,8 @@ inline static mozilla::HangMonitor::ActivityType ActivityTypeForMessage(UINT msg
// and http://msdn.microsoft.com/en-us/library/ms633573%28VS.85%29.aspx
LRESULT CALLBACK nsWindow::WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
MOZ_RELEASE_ASSERT(!ipc::ProcessingUrgentMessages());

HangMonitor::NotifyActivity(ActivityTypeForMessage(msg));

return mozilla::CallWindowProcCrashProtected(WindowProcInternal, hWnd, msg, wParam, lParam);
Expand Down
4 changes: 4 additions & 0 deletions xpcom/threads/nsThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "nsIObserverService.h"
#include "mozilla/HangMonitor.h"
#include "mozilla/IOInterposer.h"
#include "mozilla/ipc/MessageChannel.h"
#include "mozilla/Services.h"
#include "nsXPCOMPrivate.h"
#include "mozilla/ChaosMode.h"
Expand Down Expand Up @@ -686,6 +687,9 @@ nsThread::ProcessNextEvent(bool aMayWait, bool* aResult)
{
LOG(("THRD(%p) ProcessNextEvent [%u %u]\n", this, aMayWait, mRunningEvent));

// If we're on the main thread, we shouldn't be dispatching CPOWs.
MOZ_RELEASE_ASSERT(mIsMainThread != MAIN_THREAD || !ipc::ProcessingUrgentMessages());

if (NS_WARN_IF(PR_GetCurrentThread() != mThread)) {
return NS_ERROR_NOT_SAME_THREAD;
}
Expand Down

0 comments on commit e7051ac

Please sign in to comment.