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
Родитель adec753d03
Коммит 10d7ccf23e
15 изменённых файлов: 71 добавлений и 16 удалений

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

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

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

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

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

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

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

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

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

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

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

@ -35,6 +35,7 @@
#include "mozilla/AntiTrackingCommon.h" #include "mozilla/AntiTrackingCommon.h"
#include "mozilla/ArrayUtils.h" #include "mozilla/ArrayUtils.h"
#include "mozilla/Atomics.h" #include "mozilla/Atomics.h"
#include "mozilla/Attributes.h"
#include "mozilla/CycleCollectedJSContext.h" #include "mozilla/CycleCollectedJSContext.h"
#include "mozilla/CycleCollectedJSRuntime.h" #include "mozilla/CycleCollectedJSRuntime.h"
#include "mozilla/Telemetry.h" #include "mozilla/Telemetry.h"
@ -931,7 +932,10 @@ class WorkerJSContext final : public mozilla::CycleCollectedJSContext {
SetTargetedMicroTaskRecursionDepth(2); 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); MOZ_COUNT_DTOR_INHERITED(WorkerJSContext, CycleCollectedJSContext);
JSContext* cx = MaybeContext(); JSContext* cx = MaybeContext();
if (!cx) { if (!cx) {
@ -2215,6 +2219,9 @@ bool LogViolationDetailsRunnable::MainThreadRun() {
return true; 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 NS_IMETHODIMP
WorkerThreadPrimaryRunnable::Run() { WorkerThreadPrimaryRunnable::Run() {
AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING( AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING(
@ -2291,7 +2298,11 @@ WorkerThreadPrimaryRunnable::Run() {
PROFILER_SET_JS_CONTEXT(cx); 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 // The AutoJSAPI in DoRunLoop should have reported any exceptions left
// on cx. // on cx.
MOZ_ASSERT(!JS_IsExceptionPending(cx)); MOZ_ASSERT(!JS_IsExceptionPending(cx));

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

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

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

@ -894,7 +894,11 @@ void WorkerDebuggerGlobalScope::LoadSubScript(
} }
void WorkerDebuggerGlobalScope::EnterEventLoop() { 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() { void WorkerDebuggerGlobalScope::LeaveEventLoop() {

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

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

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

@ -9,6 +9,7 @@
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsCycleCollector.h" #include "nsCycleCollector.h"
#include "mozilla/dom/AtomList.h" #include "mozilla/dom/AtomList.h"
#include "mozilla/Attributes.h"
#include "mozilla/EventQueue.h" #include "mozilla/EventQueue.h"
#include "mozilla/ThreadEventQueue.h" #include "mozilla/ThreadEventQueue.h"
@ -100,7 +101,10 @@ class WorkletJSContext final : public CycleCollectedJSContext {
nsCycleCollector_startup(); 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()); MOZ_ASSERT(!NS_IsMainThread());
JSContext* cx = MaybeContext(); JSContext* cx = MaybeContext();

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

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

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

@ -9,6 +9,7 @@
#include <queue> #include <queue>
#include "mozilla/Attributes.h"
#include "mozilla/DeferredFinalize.h" #include "mozilla/DeferredFinalize.h"
#include "mozilla/LinkedList.h" #include "mozilla/LinkedList.h"
#include "mozilla/mozalloc.h" #include "mozilla/mozalloc.h"
@ -75,7 +76,7 @@ class MicroTaskRunnable {
public: public:
MicroTaskRunnable() = default; MicroTaskRunnable() = default;
NS_INLINE_DECL_REFCOUNTING(MicroTaskRunnable) 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; } virtual bool Suppressed() { return false; }
protected: protected:
@ -166,7 +167,16 @@ class CycleCollectedJSContext
public: public:
// nsThread entrypoints // 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); 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); virtual void AfterProcessTask(uint32_t aRecursionDepth);
// Check whether we need an idle GC task. // 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. // Usually the best way to do this is to use nsAutoMicroTask.
void EnterMicroTask() { ++mMicroTaskLevel; } void EnterMicroTask() { ++mMicroTaskLevel; }
MOZ_CAN_RUN_SCRIPT
void LeaveMicroTask() { void LeaveMicroTask() {
if (--mMicroTaskLevel == 0) { if (--mMicroTaskLevel == 0) {
PerformMicroTaskCheckPoint(); PerformMicroTaskCheckPoint();
@ -208,8 +219,10 @@ class CycleCollectedJSContext
void SetMicroTaskLevel(uint32_t aLevel) { mMicroTaskLevel = aLevel; } void SetMicroTaskLevel(uint32_t aLevel) { mMicroTaskLevel = aLevel; }
MOZ_CAN_RUN_SCRIPT
bool PerformMicroTaskCheckPoint(bool aForce = false); bool PerformMicroTaskCheckPoint(bool aForce = false);
MOZ_CAN_RUN_SCRIPT
void PerformDebuggerMicroTaskCheckpoint(); void PerformDebuggerMicroTaskCheckpoint();
bool IsInStableOrMetaStableState() const { return mDoingStableStates; } bool IsInStableOrMetaStableState() const { return mDoingStableStates; }
@ -243,6 +256,10 @@ class CycleCollectedJSContext
bool enqueuePromiseJob(JSContext* cx, JS::HandleObject promise, bool enqueuePromiseJob(JSContext* cx, JS::HandleObject promise,
JS::HandleObject job, JS::HandleObject allocationSite, JS::HandleObject job, JS::HandleObject allocationSite,
JS::HandleObject incumbentGlobal) override; 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; void runJobs(JSContext* cx) override;
bool empty() const override; bool empty() const override;
class SavedMicroTaskQueue; class SavedMicroTaskQueue;
@ -292,7 +309,7 @@ class MOZ_STACK_CLASS nsAutoMicroTask {
ccjs->EnterMicroTask(); ccjs->EnterMicroTask();
} }
} }
~nsAutoMicroTask() { MOZ_CAN_RUN_SCRIPT ~nsAutoMicroTask() {
CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get(); CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
if (ccjs) { if (ccjs) {
ccjs->LeaveMicroTask(); ccjs->LeaveMicroTask();

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

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

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

@ -9,6 +9,7 @@
#include "nscore.h" #include "nscore.h"
#include "nsXPCOMCID.h" #include "nsXPCOMCID.h"
#include "mozilla/Attributes.h"
#ifdef __cplusplus #ifdef __cplusplus
# define DECL_CLASS(c) class c # define DECL_CLASS(c) class c
@ -92,8 +93,12 @@ NS_InitMinimalXPCOM();
* *
* @return NS_OK for success; * @return NS_OK for success;
* other error codes indicate a failure during initialisation. * 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. * Public Method to access to the service manager.

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

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