Bug 1535384 part 5. Eliminate MOZ_CAN_RUN_SCRIPT_BOUNDARY for mutation callbacks. r=mccr8

Differential Revision: https://phabricator.services.mozilla.com/D23776

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Boris Zbarsky 2019-03-19 15:14:11 +00:00
parent adec753d03
commit 10d7ccf23e
15 changed files with 71 additions and 16 deletions

View File

@ -536,6 +536,7 @@ void nsDOMMutationObserver::ScheduleForRun() {
class MutationObserverMicroTask final : public MicroTaskRunnable {
public:
MOZ_CAN_RUN_SCRIPT
virtual void Run(AutoSlowOperation& aAso) override {
nsDOMMutationObserver::HandleMutations(aAso);
}
@ -804,7 +805,8 @@ void nsDOMMutationObserver::HandleMutation() {
}
ClearPendingRecords();
mCallback->Call(this, mutations, *this);
RefPtr<dom::MutationCallback> callback(mCallback);
callback->Call(this, mutations, *this);
}
void nsDOMMutationObserver::HandleMutationsInternal(AutoSlowOperation& aAso) {

View File

@ -467,7 +467,7 @@ class nsDOMMutationObserver final : public nsISupports, public nsWrapperCache {
void TakeRecords(nsTArray<RefPtr<nsDOMMutationRecord>>& aRetVal);
void HandleMutation();
MOZ_CAN_RUN_SCRIPT void HandleMutation();
void GetObservingInfo(
nsTArray<mozilla::dom::Nullable<MutationObservingInfo>>& aResult,
@ -514,6 +514,7 @@ class nsDOMMutationObserver final : public nsISupports, public nsWrapperCache {
// static methods
static void QueueMutationObserverMicroTask();
MOZ_CAN_RUN_SCRIPT
static void HandleMutations(mozilla::AutoSlowOperation& aAso);
static bool AllScheduledMutationObserversAreSuppressed() {
@ -561,6 +562,7 @@ class nsDOMMutationObserver final : public nsISupports, public nsWrapperCache {
return mOwner && nsGlobalWindowInner::Cast(mOwner)->IsInSyncOperation();
}
MOZ_CAN_RUN_SCRIPT
static void HandleMutationsInternal(mozilla::AutoSlowOperation& aAso);
static void AddCurrentlyHandlingObserver(nsDOMMutationObserver* aObserver,

View File

@ -312,7 +312,7 @@ class CallbackObject : public nsISupports {
const char* aExecutionReason,
ExceptionHandling aExceptionHandling, JS::Realm* aRealm = nullptr,
bool aIsJSImplementedWebIDL = false);
~CallSetup();
MOZ_CAN_RUN_SCRIPT ~CallSetup();
JSContext* GetContext() const { return mCx; }

View File

@ -52,7 +52,6 @@ interface MutationObserver {
attribute boolean mergeAttributeRecords;
};
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
callback MutationCallback = void (sequence<MutationRecord> mutations, MutationObserver observer);
dictionary MutationObserverInit {

View File

@ -7,7 +7,6 @@
* Web IDL infrastructure.
*/
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
callback PromiseJobCallback = void();
[TreatNonCallableAsNull]

View File

@ -35,6 +35,7 @@
#include "mozilla/AntiTrackingCommon.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/Atomics.h"
#include "mozilla/Attributes.h"
#include "mozilla/CycleCollectedJSContext.h"
#include "mozilla/CycleCollectedJSRuntime.h"
#include "mozilla/Telemetry.h"
@ -931,7 +932,10 @@ class WorkerJSContext final : public mozilla::CycleCollectedJSContext {
SetTargetedMicroTaskRecursionDepth(2);
}
~WorkerJSContext() {
// MOZ_CAN_RUN_SCRIPT_BOUNDARY because otherwise we have to annotate the
// SpiderMonkey JS::JobQueue's destructor as MOZ_CAN_RUN_SCRIPT, which is a
// bit of a pain.
MOZ_CAN_RUN_SCRIPT_BOUNDARY ~WorkerJSContext() {
MOZ_COUNT_DTOR_INHERITED(WorkerJSContext, CycleCollectedJSContext);
JSContext* cx = MaybeContext();
if (!cx) {
@ -2215,6 +2219,9 @@ bool LogViolationDetailsRunnable::MainThreadRun() {
return true;
}
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See
// bug 1535398.
MOZ_CAN_RUN_SCRIPT_BOUNDARY
NS_IMETHODIMP
WorkerThreadPrimaryRunnable::Run() {
AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING(
@ -2291,7 +2298,11 @@ WorkerThreadPrimaryRunnable::Run() {
PROFILER_SET_JS_CONTEXT(cx);
{
mWorkerPrivate->DoRunLoop(cx);
// We're on the worker thread here, and WorkerPrivate's refcounting is
// non-threadsafe: you can only do it on the parent thread. What that
// means in practice is that we're relying on it being kept alive while
// we run. Hopefully.
MOZ_KnownLive(mWorkerPrivate)->DoRunLoop(cx);
// The AutoJSAPI in DoRunLoop should have reported any exceptions left
// on cx.
MOZ_ASSERT(!JS_IsExceptionPending(cx));

View File

@ -8,6 +8,7 @@
#define mozilla_dom_workers_workerprivate_h__
#include "mozilla/dom/WorkerCommon.h"
#include "mozilla/Attributes.h"
#include "mozilla/CondVar.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/RelativeTimeline.h"
@ -193,6 +194,7 @@ class WorkerPrivate : public RelativeTimeline {
return std::move(mDefaultLocale);
}
MOZ_CAN_RUN_SCRIPT
void DoRunLoop(JSContext* aCx);
bool InterruptCallback(JSContext* aCx);
@ -226,7 +228,7 @@ class WorkerPrivate : public RelativeTimeline {
const Sequence<JSObject*>& aTransferable,
ErrorResult& aRv);
void EnterDebuggerEventLoop();
MOZ_CAN_RUN_SCRIPT void EnterDebuggerEventLoop();
void LeaveDebuggerEventLoop();

View File

@ -894,7 +894,11 @@ void WorkerDebuggerGlobalScope::LoadSubScript(
}
void WorkerDebuggerGlobalScope::EnterEventLoop() {
mWorkerPrivate->EnterDebuggerEventLoop();
// We're on the worker thread here, and WorkerPrivate's refcounting is
// non-threadsafe: you can only do it on the parent thread. What that
// means in practice is that we're relying on it being kept alive while
// we run. Hopefully.
MOZ_KnownLive(mWorkerPrivate)->EnterDebuggerEventLoop();
}
void WorkerDebuggerGlobalScope::LeaveEventLoop() {

View File

@ -7,6 +7,7 @@
#ifndef mozilla_dom_workerscope_h__
#define mozilla_dom_workerscope_h__
#include "mozilla/Attributes.h"
#include "mozilla/dom/WorkerCommon.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/DOMPrefs.h"
@ -312,7 +313,7 @@ class WorkerDebuggerGlobalScope final : public DOMEventTargetHelper,
const Optional<JS::Handle<JSObject*>>& aSandbox,
ErrorResult& aRv);
void EnterEventLoop();
MOZ_CAN_RUN_SCRIPT void EnterEventLoop();
void LeaveEventLoop();

View File

@ -9,6 +9,7 @@
#include "nsContentUtils.h"
#include "nsCycleCollector.h"
#include "mozilla/dom/AtomList.h"
#include "mozilla/Attributes.h"
#include "mozilla/EventQueue.h"
#include "mozilla/ThreadEventQueue.h"
@ -100,7 +101,10 @@ class WorkletJSContext final : public CycleCollectedJSContext {
nsCycleCollector_startup();
}
~WorkletJSContext() override {
// MOZ_CAN_RUN_SCRIPT_BOUNDARY because otherwise we have to annotate the
// SpiderMonkey JS::JobQueue's destructor as MOZ_CAN_RUN_SCRIPT, which is a
// bit of a pain.
MOZ_CAN_RUN_SCRIPT_BOUNDARY ~WorkletJSContext() override {
MOZ_ASSERT(!NS_IsMainThread());
JSContext* cx = MaybeContext();

View File

@ -219,6 +219,7 @@ class PromiseJobRunnable final : public MicroTaskRunnable {
virtual ~PromiseJobRunnable() {}
protected:
MOZ_CAN_RUN_SCRIPT
virtual void Run(AutoSlowOperation& aAso) override {
JSObject* callback = mCallback->CallbackPreserveColor();
nsIGlobalObject* global = callback ? xpc::NativeGlobal(callback) : nullptr;
@ -232,7 +233,8 @@ class PromiseJobRunnable final : public MicroTaskRunnable {
AutoHandlingUserInputStatePusher userInpStatePusher(
mPropagateUserInputEventHandling, nullptr, doc);
mCallback->Call("promise callback");
// mCallback is const, so can't suddenly become null.
MOZ_KnownLive(mCallback)->Call("promise callback");
aAso.CheckForInterrupt();
}
// Now that mCallback is no longer needed, clear any pointers it contains to
@ -250,7 +252,7 @@ class PromiseJobRunnable final : public MicroTaskRunnable {
}
private:
RefPtr<PromiseJobCallback> mCallback;
const RefPtr<PromiseJobCallback> mCallback;
bool mPropagateUserInputEventHandling;
};
@ -525,6 +527,9 @@ class AsyncMutationHandler final : public mozilla::Runnable {
public:
AsyncMutationHandler() : mozilla::Runnable("AsyncMutationHandler") {}
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See
// bug 1535398.
MOZ_CAN_RUN_SCRIPT_BOUNDARY
NS_IMETHOD Run() override {
CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
if (ccjs) {

View File

@ -9,6 +9,7 @@
#include <queue>
#include "mozilla/Attributes.h"
#include "mozilla/DeferredFinalize.h"
#include "mozilla/LinkedList.h"
#include "mozilla/mozalloc.h"
@ -75,7 +76,7 @@ class MicroTaskRunnable {
public:
MicroTaskRunnable() = default;
NS_INLINE_DECL_REFCOUNTING(MicroTaskRunnable)
virtual void Run(AutoSlowOperation& aAso) = 0;
MOZ_CAN_RUN_SCRIPT virtual void Run(AutoSlowOperation& aAso) = 0;
virtual bool Suppressed() { return false; }
protected:
@ -166,7 +167,16 @@ class CycleCollectedJSContext
public:
// nsThread entrypoints
//
// MOZ_CAN_RUN_SCRIPT_BOUNDARY so we don't need to annotate
// nsThread::ProcessNextEvent and all its callers MOZ_CAN_RUN_SCRIPT for now.
// But we really should!
MOZ_CAN_RUN_SCRIPT_BOUNDARY
virtual void BeforeProcessTask(bool aMightBlock);
// MOZ_CAN_RUN_SCRIPT_BOUNDARY so we don't need to annotate
// nsThread::ProcessNextEvent and all its callers MOZ_CAN_RUN_SCRIPT for now.
// But we really should!
MOZ_CAN_RUN_SCRIPT_BOUNDARY
virtual void AfterProcessTask(uint32_t aRecursionDepth);
// Check whether we need an idle GC task.
@ -196,6 +206,7 @@ class CycleCollectedJSContext
// Usually the best way to do this is to use nsAutoMicroTask.
void EnterMicroTask() { ++mMicroTaskLevel; }
MOZ_CAN_RUN_SCRIPT
void LeaveMicroTask() {
if (--mMicroTaskLevel == 0) {
PerformMicroTaskCheckPoint();
@ -208,8 +219,10 @@ class CycleCollectedJSContext
void SetMicroTaskLevel(uint32_t aLevel) { mMicroTaskLevel = aLevel; }
MOZ_CAN_RUN_SCRIPT
bool PerformMicroTaskCheckPoint(bool aForce = false);
MOZ_CAN_RUN_SCRIPT
void PerformDebuggerMicroTaskCheckpoint();
bool IsInStableOrMetaStableState() const { return mDoingStableStates; }
@ -243,6 +256,10 @@ class CycleCollectedJSContext
bool enqueuePromiseJob(JSContext* cx, JS::HandleObject promise,
JS::HandleObject job, JS::HandleObject allocationSite,
JS::HandleObject incumbentGlobal) override;
// MOZ_CAN_RUN_SCRIPT_BOUNDARY for now so we don't have to change SpiderMonkey
// headers. The caller presumably knows this can run script (like everything
// in SpiderMonkey!) and will deal.
MOZ_CAN_RUN_SCRIPT_BOUNDARY
void runJobs(JSContext* cx) override;
bool empty() const override;
class SavedMicroTaskQueue;
@ -292,7 +309,7 @@ class MOZ_STACK_CLASS nsAutoMicroTask {
ccjs->EnterMicroTask();
}
}
~nsAutoMicroTask() {
MOZ_CAN_RUN_SCRIPT ~nsAutoMicroTask() {
CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
if (ccjs) {
ccjs->LeaveMicroTask();

View File

@ -16,6 +16,7 @@ struct already_AddRefed;
#include "nsError.h"
#include "nsID.h"
#include "mozilla/Attributes.h"
#include "js/SliceBudget.h"
namespace mozilla {
@ -59,6 +60,7 @@ uint32_t nsCycleCollector_suspectedCount();
// If aDoCollect is true, then run the GC and CC a few times before
// shutting down the CC completely.
MOZ_CAN_RUN_SCRIPT
void nsCycleCollector_shutdown(bool aDoCollect = true);
// Helpers for interacting with JS

View File

@ -9,6 +9,7 @@
#include "nscore.h"
#include "nsXPCOMCID.h"
#include "mozilla/Attributes.h"
#ifdef __cplusplus
# define DECL_CLASS(c) class c
@ -92,8 +93,12 @@ NS_InitMinimalXPCOM();
*
* @return NS_OK for success;
* other error codes indicate a failure during initialisation.
*
* MOZ_CAN_RUN_SCRIPT_BOUNDARY for now, but really it should maybe be
* MOZ_CAN_RUN_SCRIPT.
*/
XPCOM_API(nsresult) NS_ShutdownXPCOM(nsIServiceManager* aServMgr);
XPCOM_API(MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult)
NS_ShutdownXPCOM(nsIServiceManager* aServMgr);
/**
* Public Method to access to the service manager.

View File

@ -9,6 +9,7 @@
#include "nscore.h"
#include "nsXPCOM.h"
#include "mozilla/Attributes.h"
/**
* During this shutdown notification all threads which run XPCOM code must
@ -30,6 +31,7 @@ namespace mozilla {
* other error codes indicate a failure during shutdown
*
*/
MOZ_CAN_RUN_SCRIPT
nsresult ShutdownXPCOM(nsIServiceManager* aServMgr);
void SetICUMemoryFunctions();