diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 34e7ce905da2..242a3611492e 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -51,6 +51,7 @@ #include "mozilla/Unused.h" #include "mozilla/WidgetUtils.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/ChildProcessChannelListener.h" #include "mozilla/dom/ClientChannelHelper.h" #include "mozilla/dom/ClientHandle.h" diff --git a/dom/base/BodyStream.cpp b/dom/base/BodyStream.cpp index 12ed7fce2f99..05ab478a5b23 100644 --- a/dom/base/BodyStream.cpp +++ b/dom/base/BodyStream.cpp @@ -6,6 +6,7 @@ #include "BodyStream.h" #include "mozilla/CycleCollectedJSContext.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/DOMException.h" #include "mozilla/dom/ScriptSettings.h" #include "mozilla/dom/WorkerCommon.h" diff --git a/dom/base/CustomElementRegistry.cpp b/dom/base/CustomElementRegistry.cpp index a221b0ee5cc1..b971e6d96b2a 100644 --- a/dom/base/CustomElementRegistry.cpp +++ b/dom/base/CustomElementRegistry.cpp @@ -8,6 +8,7 @@ #include "mozilla/AsyncEventDispatcher.h" #include "mozilla/CycleCollectedJSContext.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/CustomElementRegistryBinding.h" #include "mozilla/dom/ElementBinding.h" #include "mozilla/dom/HTMLElementBinding.h" diff --git a/dom/base/Timeout.cpp b/dom/base/Timeout.cpp index 664695e87ff9..e240b5d58636 100644 --- a/dom/base/Timeout.cpp +++ b/dom/base/Timeout.cpp @@ -9,6 +9,10 @@ #include "mozilla/dom/TimeoutManager.h" #include "nsGlobalWindowInner.h" +#ifdef MOZ_GECKO_PROFILER +# include "GeckoProfiler.h" +#endif + namespace mozilla::dom { Timeout::Timeout() diff --git a/dom/base/TimeoutManager.cpp b/dom/base/TimeoutManager.cpp index 67e57f589ef8..4fbccad71530 100644 --- a/dom/base/TimeoutManager.cpp +++ b/dom/base/TimeoutManager.cpp @@ -25,6 +25,10 @@ #include "mozilla/net/WebSocketEventService.h" #include "mozilla/MediaManager.h" +#if MOZ_GECKO_PROFILER +# include "GeckoProfiler.h" +#endif + using namespace mozilla; using namespace mozilla::dom; diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index bc7c37503245..f0f57bb31778 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -126,6 +126,7 @@ #include "mozilla/Variant.h" #include "mozilla/ViewportUtils.h" #include "mozilla/dom/AncestorIterator.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/AutocompleteInfoBinding.h" #include "mozilla/dom/AutoSuppressEventHandlingAndSuspend.h" #include "mozilla/dom/BindingDeclarations.h" diff --git a/dom/base/nsFrameMessageManager.cpp b/dom/base/nsFrameMessageManager.cpp index fa369e5487c0..ac9e24eba48f 100644 --- a/dom/base/nsFrameMessageManager.cpp +++ b/dom/base/nsFrameMessageManager.cpp @@ -40,6 +40,7 @@ #include "mozilla/TimeStamp.h" #include "mozilla/TypedEnumBits.h" #include "mozilla/UniquePtr.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/BindingDeclarations.h" #include "mozilla/dom/CallbackObject.h" #include "mozilla/dom/ChildProcessMessageManager.h" diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp index 37b40cabf8a9..cfed7d20078e 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -86,6 +86,7 @@ #include "mozilla/UniquePtr.h" #include "mozilla/Unused.h" #include "mozilla/dom/AudioContext.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/BarProps.h" #include "mozilla/dom/BindingDeclarations.h" #include "mozilla/dom/BindingUtils.h" diff --git a/dom/bindings/CallbackObject.h b/dom/bindings/CallbackObject.h index 296402920141..3edecbfefcde 100644 --- a/dom/bindings/CallbackObject.h +++ b/dom/bindings/CallbackObject.h @@ -30,6 +30,7 @@ #include "mozilla/Maybe.h" #include "mozilla/MemoryReporting.h" #include "mozilla/RefPtr.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/BindingCallContext.h" #include "mozilla/dom/ScriptSettings.h" #include "nsCOMPtr.h" diff --git a/dom/fetch/FetchStreamReader.cpp b/dom/fetch/FetchStreamReader.cpp index b202dbe430ff..7e733b91d724 100644 --- a/dom/fetch/FetchStreamReader.cpp +++ b/dom/fetch/FetchStreamReader.cpp @@ -8,6 +8,7 @@ #include "InternalResponse.h" #include "js/Stream.h" #include "mozilla/ConsoleReportCollector.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/DOMException.h" #include "mozilla/dom/Promise.h" #include "mozilla/dom/PromiseBinding.h" diff --git a/dom/ipc/SharedMap.cpp b/dom/ipc/SharedMap.cpp index d08940666d33..575c4e2bcea7 100644 --- a/dom/ipc/SharedMap.cpp +++ b/dom/ipc/SharedMap.cpp @@ -10,6 +10,7 @@ #include "MemMapSnapshot.h" #include "ScriptPreloader-inl.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/BlobImpl.h" #include "mozilla/dom/ContentParent.h" #include "mozilla/dom/ContentProcessMessageManager.h" diff --git a/dom/ipc/jsactor/JSActor.cpp b/dom/ipc/jsactor/JSActor.cpp index e55365744917..493c91ab41e1 100644 --- a/dom/ipc/jsactor/JSActor.cpp +++ b/dom/ipc/jsactor/JSActor.cpp @@ -10,6 +10,7 @@ #include "chrome/common/ipc_channel.h" #include "mozilla/Attributes.h" #include "mozilla/FunctionRef.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/ClonedErrorHolder.h" #include "mozilla/dom/ClonedErrorHolderBinding.h" #include "mozilla/dom/DOMException.h" diff --git a/dom/ipc/jsactor/JSActorManager.cpp b/dom/ipc/jsactor/JSActorManager.cpp index 672223ada610..ba5745ccb97e 100644 --- a/dom/ipc/jsactor/JSActorManager.cpp +++ b/dom/ipc/jsactor/JSActorManager.cpp @@ -5,6 +5,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/dom/JSActorManager.h" + +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/JSActorService.h" #include "mozilla/dom/PWindowGlobal.h" #include "mozilla/ipc/ProtocolUtils.h" diff --git a/dom/jsurl/nsJSProtocolHandler.cpp b/dom/jsurl/nsJSProtocolHandler.cpp index 0bc617700c0d..5084fd8429cc 100644 --- a/dom/jsurl/nsJSProtocolHandler.cpp +++ b/dom/jsurl/nsJSProtocolHandler.cpp @@ -42,6 +42,7 @@ #include "nsSandboxFlags.h" #include "mozilla/BasePrincipal.h" #include "mozilla/CycleCollectedJSContext.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/DOMSecurityMonitor.h" #include "mozilla/dom/JSExecutionContext.h" #include "mozilla/dom/ScriptSettings.h" diff --git a/dom/l10n/DOMLocalization.cpp b/dom/l10n/DOMLocalization.cpp index 2d3f6c767b0f..fcb0f3c194ff 100644 --- a/dom/l10n/DOMLocalization.cpp +++ b/dom/l10n/DOMLocalization.cpp @@ -10,6 +10,7 @@ #include "nsIScriptError.h" #include "DOMLocalization.h" #include "mozilla/intl/LocaleService.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/L10nOverlays.h" diff --git a/dom/l10n/DocumentL10n.cpp b/dom/l10n/DocumentL10n.cpp index cd793697a602..760cd7f3328b 100644 --- a/dom/l10n/DocumentL10n.cpp +++ b/dom/l10n/DocumentL10n.cpp @@ -6,6 +6,7 @@ #include "DocumentL10n.h" #include "nsIContentSink.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/Document.h" #include "mozilla/dom/DocumentL10nBinding.h" #include "mozilla/Telemetry.h" diff --git a/dom/media/webaudio/AudioWorkletNode.cpp b/dom/media/webaudio/AudioWorkletNode.cpp index b6a395a044d7..eba441772705 100644 --- a/dom/media/webaudio/AudioWorkletNode.cpp +++ b/dom/media/webaudio/AudioWorkletNode.cpp @@ -14,6 +14,7 @@ #include "js/experimental/TypedData.h" // JS_NewFloat32Array, JS_GetFloat32ArrayData, JS_GetTypedArrayLength, JS_GetArrayBufferViewBuffer #include "mozilla/dom/AudioWorkletNodeBinding.h" #include "mozilla/dom/AudioParamMapBinding.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/RootedDictionary.h" #include "mozilla/dom/ErrorEvent.h" #include "mozilla/dom/Worklet.h" diff --git a/dom/media/webrtc/jsapi/RTCStatsReport.h b/dom/media/webrtc/jsapi/RTCStatsReport.h index 0de84114daba..60f5d50ceb51 100644 --- a/dom/media/webrtc/jsapi/RTCStatsReport.h +++ b/dom/media/webrtc/jsapi/RTCStatsReport.h @@ -10,8 +10,8 @@ #include "nsWrapperCache.h" #include "nsCOMPtr.h" -#include "nsPIDOMWindow.h" // nsPIDOMWindowInner -#include "mozilla/dom/ScriptSettings.h" // AutoEntryScript +#include "nsPIDOMWindow.h" // nsPIDOMWindowInner +#include "mozilla/dom/AutoEntryScript.h" #include "nsIGlobalObject.h" #include "js/RootingAPI.h" // JS::Rooted #include "js/Value.h" diff --git a/dom/plugins/base/nsJSNPRuntime.cpp b/dom/plugins/base/nsJSNPRuntime.cpp index 5fa02c8d43ad..ca6589dafa3c 100644 --- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -32,6 +32,7 @@ #include "mozilla/HashFunctions.h" #include "mozilla/ProfilerLabels.h" #include "mozilla/UniquePtr.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/ScriptSettings.h" #define NPRUNTIME_JSCLASS_NAME "NPObject JS wrapper class" diff --git a/dom/plugins/base/nsNPAPIPlugin.cpp b/dom/plugins/base/nsNPAPIPlugin.cpp index eef4d6e52c8b..f5b469e81999 100644 --- a/dom/plugins/base/nsNPAPIPlugin.cpp +++ b/dom/plugins/base/nsNPAPIPlugin.cpp @@ -32,6 +32,7 @@ #include "nsPIDOMWindow.h" #include "nsGlobalWindow.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/Document.h" #include "nsIContent.h" #include "nsIIDNService.h" diff --git a/dom/promise/Promise.cpp b/dom/promise/Promise.cpp index ab6a835d4a48..ae15725855c2 100644 --- a/dom/promise/Promise.cpp +++ b/dom/promise/Promise.cpp @@ -18,6 +18,7 @@ #include "mozilla/ResultExtensions.h" #include "mozilla/Unused.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/DOMException.h" #include "mozilla/dom/DOMExceptionBinding.h" diff --git a/dom/promise/Promise.h b/dom/promise/Promise.h index 47f5e5fce33b..5327b2f23bc6 100644 --- a/dom/promise/Promise.h +++ b/dom/promise/Promise.h @@ -19,6 +19,7 @@ #include "mozilla/RefPtr.h" #include "mozilla/Result.h" #include "mozilla/WeakPtr.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/ScriptSettings.h" #include "mozilla/dom/ToJSValue.h" #include "nsCycleCollectionParticipant.h" diff --git a/dom/prototype/PrototypeDocumentContentSink.cpp b/dom/prototype/PrototypeDocumentContentSink.cpp index cb493e8034d5..dcdf1c43417c 100644 --- a/dom/prototype/PrototypeDocumentContentSink.cpp +++ b/dom/prototype/PrototypeDocumentContentSink.cpp @@ -38,6 +38,7 @@ #include "nsMimeTypes.h" #include "nsHtml5SVGLoadDispatcher.h" #include "nsTextNode.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/CDATASection.h" #include "mozilla/dom/Comment.h" #include "mozilla/dom/DocumentType.h" diff --git a/dom/script/AutoEntryScript.cpp b/dom/script/AutoEntryScript.cpp new file mode 100644 index 000000000000..bb41cb9d4fd3 --- /dev/null +++ b/dom/script/AutoEntryScript.cpp @@ -0,0 +1,164 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/AutoEntryScript.h" + +#include +#include +#include "js/ProfilingCategory.h" +#include "js/ProfilingStack.h" +#include "jsapi.h" +#include "mozilla/Assertions.h" +#include "mozilla/Maybe.h" +#include "mozilla/Span.h" +#include "nsCOMPtr.h" +#include "nsContentUtils.h" +#include "nsGlobalWindowInner.h" +#include "nsIDocShell.h" +#include "nsJSUtils.h" +#include "nsPIDOMWindow.h" +#include "nsPIDOMWindowInlines.h" +#include "nsString.h" +#include "xpcpublic.h" + +namespace mozilla::dom { + +namespace { +// Assert if it's not safe to run script. The helper class +// AutoAllowLegacyScriptExecution allows to allow-list +// legacy cases where it's actually not safe to run script. +#ifdef DEBUG +void AssertIfNotSafeToRunScript() { + // if it's safe to run script, then there is nothing to do here. + if (nsContentUtils::IsSafeToRunScript()) { + return; + } + + // auto allowing legacy script execution is fine for now. + if (AutoAllowLegacyScriptExecution::IsAllowed()) { + return; + } + + MOZ_ASSERT(false, "is it safe to run script?"); +} +#endif + +static unsigned long gRunToCompletionListeners = 0; + +} // namespace + +void UseEntryScriptProfiling() { + MOZ_ASSERT(NS_IsMainThread()); + ++gRunToCompletionListeners; +} + +void UnuseEntryScriptProfiling() { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(gRunToCompletionListeners > 0); + --gRunToCompletionListeners; +} + +AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject, + const char* aReason, bool aIsMainThread) + : AutoJSAPI(aGlobalObject, aIsMainThread, eEntryScript), + mWebIDLCallerPrincipal(nullptr) + // This relies on us having a cx() because the AutoJSAPI constructor + // already ran. + , + mCallerOverride(cx()) +#ifdef MOZ_GECKO_PROFILER + , + mAutoProfilerLabel( + "", aReason, JS::ProfilingCategoryPair::JS, + uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)) +#endif + , + mJSThreadExecution(aGlobalObject, aIsMainThread) { + MOZ_ASSERT(aGlobalObject); + + if (aIsMainThread) { +#ifdef DEBUG + AssertIfNotSafeToRunScript(); +#endif + if (gRunToCompletionListeners > 0) { + mDocShellEntryMonitor.emplace(cx(), aReason); + } + mScriptActivity.emplace(true); + } +} + +AutoEntryScript::AutoEntryScript(JSObject* aObject, const char* aReason, + bool aIsMainThread) + : AutoEntryScript(xpc::NativeGlobal(aObject), aReason, aIsMainThread) { + // xpc::NativeGlobal uses JS::GetNonCCWObjectGlobal, which asserts that + // aObject is not a CCW. +} + +AutoEntryScript::~AutoEntryScript() = default; + +AutoEntryScript::DocshellEntryMonitor::DocshellEntryMonitor(JSContext* aCx, + const char* aReason) + : JS::dbg::AutoEntryMonitor(aCx), mReason(aReason) {} + +void AutoEntryScript::DocshellEntryMonitor::Entry( + JSContext* aCx, JSFunction* aFunction, JSScript* aScript, + JS::Handle aAsyncStack, const char* aAsyncCause) { + JS::Rooted rootedFunction(aCx); + if (aFunction) { + rootedFunction = aFunction; + } + JS::Rooted rootedScript(aCx); + if (aScript) { + rootedScript = aScript; + } + + nsCOMPtr window = xpc::CurrentWindowOrNull(aCx); + if (!window || !window->GetDocShell() || + !window->GetDocShell()->GetRecordProfileTimelineMarkers()) { + return; + } + + nsCOMPtr docShellForJSRunToCompletion = window->GetDocShell(); + + nsAutoJSString functionName; + if (rootedFunction) { + JS::Rooted displayId(aCx, + JS_GetFunctionDisplayId(rootedFunction)); + if (displayId) { + if (!functionName.init(aCx, displayId)) { + JS_ClearPendingException(aCx); + return; + } + } + } + + nsString filename; + uint32_t lineNumber = 0; + if (!rootedScript) { + rootedScript = JS_GetFunctionScript(aCx, rootedFunction); + } + if (rootedScript) { + CopyUTF8toUTF16(MakeStringSpan(JS_GetScriptFilename(rootedScript)), + filename); + lineNumber = JS_GetScriptBaseLineNumber(aCx, rootedScript); + } + + if (!filename.IsEmpty() || !functionName.IsEmpty()) { + docShellForJSRunToCompletion->NotifyJSRunToCompletionStart( + mReason, functionName, filename, lineNumber, aAsyncStack, aAsyncCause); + } +} + +void AutoEntryScript::DocshellEntryMonitor::Exit(JSContext* aCx) { + nsCOMPtr window = xpc::CurrentWindowOrNull(aCx); + // Not really worth checking GetRecordProfileTimelineMarkers here. + if (window && window->GetDocShell()) { + nsCOMPtr docShellForJSRunToCompletion = window->GetDocShell(); + docShellForJSRunToCompletion->NotifyJSRunToCompletionStop(); + } +} + +} // namespace mozilla::dom diff --git a/dom/script/AutoEntryScript.h b/dom/script/AutoEntryScript.h new file mode 100644 index 000000000000..83d917a13c0e --- /dev/null +++ b/dom/script/AutoEntryScript.h @@ -0,0 +1,125 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef DOM_SCRIPT_AUTOENTRYSCRIPT_H_ +#define DOM_SCRIPT_AUTOENTRYSCRIPT_H_ + +#include "MainThreadUtils.h" +#include "js/Debug.h" +#include "js/TypeDecls.h" +#include "jsapi.h" +#include "mozilla/Attributes.h" +#include "mozilla/Maybe.h" +#include "mozilla/dom/JSExecutionManager.h" +#include "mozilla/dom/ScriptSettings.h" + +#ifdef MOZ_GECKO_PROFILER +# include "mozilla/ProfilerLabels.h" +#endif + +class nsIGlobalObject; +class nsIPrincipal; + +namespace xpc { +class AutoScriptActivity; +} + +namespace mozilla::dom { + +/* + * Static helpers in ScriptSettings which track the number of listeners + * of Javascript RunToCompletion events. These should be used by the code in + * nsDocShell::SetRecordProfileTimelineMarkers to indicate to script + * settings that script run-to-completion needs to be monitored. + * SHOULD BE CALLED ONLY BY MAIN THREAD. + */ +void UseEntryScriptProfiling(); +void UnuseEntryScriptProfiling(); + +/* + * A class that represents a new script entry point. + * + * |aReason| should be a statically-allocated C string naming the reason we're + * invoking JavaScript code: "setTimeout", "event", and so on. The devtools use + * these strings to label JS execution in timeline and profiling displays. + * + */ +class MOZ_STACK_CLASS AutoEntryScript : public AutoJSAPI { + public: + // Constructing the AutoEntryScript will ensure that it enters the + // Realm of aGlobalObject's JSObject and exposes that JSObject to active JS. + AutoEntryScript(nsIGlobalObject* aGlobalObject, const char* aReason, + bool aIsMainThread = NS_IsMainThread()); + + // aObject can be any object from the relevant global. It must not be a + // cross-compartment wrapper because CCWs are not associated with a single + // global. + // + // Constructing the AutoEntryScript will ensure that it enters the + // Realm of aObject JSObject and exposes aObject's global to active JS. + AutoEntryScript(JSObject* aObject, const char* aReason, + bool aIsMainThread = NS_IsMainThread()); + + ~AutoEntryScript(); + + void SetWebIDLCallerPrincipal(nsIPrincipal* aPrincipal) { + mWebIDLCallerPrincipal = aPrincipal; + } + + private: + // A subclass of AutoEntryMonitor that notifies the docshell. + class DocshellEntryMonitor final : public JS::dbg::AutoEntryMonitor { + public: + DocshellEntryMonitor(JSContext* aCx, const char* aReason); + + // Please note that |aAsyncCause| here is owned by the caller, and its + // lifetime must outlive the lifetime of the DocshellEntryMonitor object. + // In practice, |aAsyncCause| is identical to |aReason| passed into + // the AutoEntryScript constructor, so the lifetime requirements are + // trivially satisfied by |aReason| being a statically allocated string. + void Entry(JSContext* aCx, JSFunction* aFunction, + JS::Handle aAsyncStack, + const char* aAsyncCause) override { + Entry(aCx, aFunction, nullptr, aAsyncStack, aAsyncCause); + } + + void Entry(JSContext* aCx, JSScript* aScript, + JS::Handle aAsyncStack, + const char* aAsyncCause) override { + Entry(aCx, nullptr, aScript, aAsyncStack, aAsyncCause); + } + + void Exit(JSContext* aCx) override; + + private: + void Entry(JSContext* aCx, JSFunction* aFunction, JSScript* aScript, + JS::Handle aAsyncStack, const char* aAsyncCause); + + const char* mReason; + }; + + // It's safe to make this a weak pointer, since it's the subject principal + // when we go on the stack, so can't go away until after we're gone. In + // particular, this is only used from the CallSetup constructor, and only in + // the aIsJSImplementedWebIDL case. And in that case, the subject principal + // is the principal of the callee function that is part of the CallArgs just a + // bit up the stack, and which will outlive us. So we know the principal + // can't go away until then either. + nsIPrincipal* MOZ_NON_OWNING_REF mWebIDLCallerPrincipal; + friend nsIPrincipal* GetWebIDLCallerPrincipal(); + + Maybe mDocShellEntryMonitor; + Maybe mScriptActivity; + JS::AutoHideScriptedCaller mCallerOverride; +#ifdef MOZ_GECKO_PROFILER + AutoProfilerLabel mAutoProfilerLabel; +#endif + AutoRequestJSThreadExecution mJSThreadExecution; +}; + +} // namespace mozilla::dom + +#endif // DOM_SCRIPT_AUTOENTRYSCRIPT_H_ diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp index a4f454badc45..52118693c7d0 100644 --- a/dom/script/ScriptLoader.cpp +++ b/dom/script/ScriptLoader.cpp @@ -29,6 +29,7 @@ #include "nsCycleCollectionParticipant.h" #include "nsIContent.h" #include "nsJSUtils.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/DocGroup.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/JSExecutionContext.h" diff --git a/dom/script/ScriptSettings.cpp b/dom/script/ScriptSettings.cpp index 589b46999c7f..692851f0652d 100644 --- a/dom/script/ScriptSettings.cpp +++ b/dom/script/ScriptSettings.cpp @@ -5,32 +5,47 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/dom/ScriptSettings.h" + +#include #include "LoadedScript.h" +#include "MainThreadUtils.h" +#include "js/CharacterEncoding.h" +#include "js/CompilationAndEvaluation.h" +#include "js/Conversions.h" +#include "js/ErrorReport.h" +#include "js/Exception.h" +#include "js/GCAPI.h" +#include "js/TypeDecls.h" +#include "js/Value.h" +#include "js/Warnings.h" +#include "js/Wrapper.h" +#include "js/friend/ErrorMessages.h" +#include "jsapi.h" #include "mozilla/Assertions.h" #include "mozilla/BasePrincipal.h" #include "mozilla/CycleCollectedJSContext.h" -#include "mozilla/ThreadLocal.h" +#include "mozilla/DebugOnly.h" #include "mozilla/Maybe.h" +#include "mozilla/RefPtr.h" +#include "mozilla/ThreadLocal.h" +#include "mozilla/dom/AutoEntryScript.h" +#include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/Document.h" #include "mozilla/dom/Element.h" -#include "mozilla/dom/JSExecutionManager.h" -#include "mozilla/dom/WorkerPrivate.h" - -#include "jsapi.h" -#include "js/CompilationAndEvaluation.h" -#include "js/friend/ErrorMessages.h" // JSMSG_OUT_OF_MEMORY -#include "js/Warnings.h" // JS::{Get,}WarningReporter -#include "xpcpublic.h" -#include "nsIGlobalObject.h" -#include "nsIDocShell.h" -#include "nsIScriptGlobalObject.h" -#include "nsIScriptContext.h" +#include "mozilla/dom/ScriptLoadRequest.h" +#include "mozilla/dom/WorkerCommon.h" #include "nsContentUtils.h" -#include "nsGlobalWindow.h" -#include "nsPIDOMWindow.h" -#include "nsTArray.h" +#include "nsDebug.h" +#include "nsGlobalWindowInner.h" +#include "nsIGlobalObject.h" +#include "nsINode.h" +#include "nsIPrincipal.h" +#include "nsISupports.h" #include "nsJSUtils.h" -#include "nsDOMJSUtils.h" +#include "nsPIDOMWindow.h" +#include "nsString.h" +#include "nscore.h" +#include "xpcpublic.h" namespace mozilla { namespace dom { @@ -66,25 +81,6 @@ JSObject* GetElementCallback(JSContext* aCx, JS::HandleValue aValue) { static MOZ_THREAD_LOCAL(ScriptSettingsStackEntry*) sScriptSettingsTLS; -// Assert if it's not safe to run script. The helper class -// AutoAllowLegacyScriptExecution allows to allow-list -// legacy cases where it's actually not safe to run script. -#ifdef DEBUG -static void AssertIfNotSafeToRunScript() { - // if it's safe to run script, then there is nothing to do here. - if (nsContentUtils::IsSafeToRunScript()) { - return; - } - - // auto allowing legacy script execution is fine for now. - if (AutoAllowLegacyScriptExecution::IsAllowed()) { - return; - } - - MOZ_ASSERT(false, "is it safe to run script?"); -} -#endif - class ScriptSettingsStack { public: static ScriptSettingsStackEntry* Top() { return sScriptSettingsTLS.get(); } @@ -152,19 +148,6 @@ class ScriptSettingsStack { #endif // DEBUG }; -static unsigned long gRunToCompletionListeners = 0; - -void UseEntryScriptProfiling() { - MOZ_ASSERT(NS_IsMainThread()); - ++gRunToCompletionListeners; -} - -void UnuseEntryScriptProfiling() { - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(gRunToCompletionListeners > 0); - --gRunToCompletionListeners; -} - void InitScriptSettings() { bool success = sScriptSettingsTLS.init(); if (!success) { @@ -632,106 +615,6 @@ bool AutoJSAPI::IsStackTop() const { } #endif // DEBUG -AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject, - const char* aReason, bool aIsMainThread) - : AutoJSAPI(aGlobalObject, aIsMainThread, eEntryScript), - mWebIDLCallerPrincipal(nullptr) - // This relies on us having a cx() because the AutoJSAPI constructor - // already ran. - , - mCallerOverride(cx()) -#ifdef MOZ_GECKO_PROFILER - , - mAutoProfilerLabel( - "", aReason, JS::ProfilingCategoryPair::JS, - uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)) -#endif - , - mJSThreadExecution(aGlobalObject, aIsMainThread) { - MOZ_ASSERT(aGlobalObject); - - if (aIsMainThread) { -#ifdef DEBUG - AssertIfNotSafeToRunScript(); -#endif - if (gRunToCompletionListeners > 0) { - mDocShellEntryMonitor.emplace(cx(), aReason); - } - mScriptActivity.emplace(true); - } -} - -AutoEntryScript::AutoEntryScript(JSObject* aObject, const char* aReason, - bool aIsMainThread) - : AutoEntryScript(xpc::NativeGlobal(aObject), aReason, aIsMainThread) { - // xpc::NativeGlobal uses JS::GetNonCCWObjectGlobal, which asserts that - // aObject is not a CCW. -} - -AutoEntryScript::~AutoEntryScript() = default; - -AutoEntryScript::DocshellEntryMonitor::DocshellEntryMonitor(JSContext* aCx, - const char* aReason) - : JS::dbg::AutoEntryMonitor(aCx), mReason(aReason) {} - -void AutoEntryScript::DocshellEntryMonitor::Entry( - JSContext* aCx, JSFunction* aFunction, JSScript* aScript, - JS::Handle aAsyncStack, const char* aAsyncCause) { - JS::Rooted rootedFunction(aCx); - if (aFunction) { - rootedFunction = aFunction; - } - JS::Rooted rootedScript(aCx); - if (aScript) { - rootedScript = aScript; - } - - nsCOMPtr window = xpc::CurrentWindowOrNull(aCx); - if (!window || !window->GetDocShell() || - !window->GetDocShell()->GetRecordProfileTimelineMarkers()) { - return; - } - - nsCOMPtr docShellForJSRunToCompletion = window->GetDocShell(); - - nsAutoJSString functionName; - if (rootedFunction) { - JS::Rooted displayId(aCx, - JS_GetFunctionDisplayId(rootedFunction)); - if (displayId) { - if (!functionName.init(aCx, displayId)) { - JS_ClearPendingException(aCx); - return; - } - } - } - - nsString filename; - uint32_t lineNumber = 0; - if (!rootedScript) { - rootedScript = JS_GetFunctionScript(aCx, rootedFunction); - } - if (rootedScript) { - CopyUTF8toUTF16(MakeStringSpan(JS_GetScriptFilename(rootedScript)), - filename); - lineNumber = JS_GetScriptBaseLineNumber(aCx, rootedScript); - } - - if (!filename.IsEmpty() || !functionName.IsEmpty()) { - docShellForJSRunToCompletion->NotifyJSRunToCompletionStart( - mReason, functionName, filename, lineNumber, aAsyncStack, aAsyncCause); - } -} - -void AutoEntryScript::DocshellEntryMonitor::Exit(JSContext* aCx) { - nsCOMPtr window = xpc::CurrentWindowOrNull(aCx); - // Not really worth checking GetRecordProfileTimelineMarkers here. - if (window && window->GetDocShell()) { - nsCOMPtr docShellForJSRunToCompletion = window->GetDocShell(); - docShellForJSRunToCompletion->NotifyJSRunToCompletionStop(); - } -} - AutoIncumbentScript::AutoIncumbentScript(nsIGlobalObject* aGlobalObject) : ScriptSettingsStackEntry(aGlobalObject, eIncumbentScript), mCallerOverride(nsContentUtils::GetCurrentJSContext()) { diff --git a/dom/script/ScriptSettings.h b/dom/script/ScriptSettings.h index 289ebe41ff5b..8526a0482d29 100644 --- a/dom/script/ScriptSettings.h +++ b/dom/script/ScriptSettings.h @@ -9,23 +9,15 @@ #ifndef mozilla_dom_ScriptSettings_h #define mozilla_dom_ScriptSettings_h -#include "MainThreadUtils.h" #include "xpcpublic.h" #include "mozilla/dom/JSExecutionManager.h" #include "mozilla/Maybe.h" #include "jsapi.h" -#include "js/Debug.h" #include "js/Warnings.h" // JS::WarningReporter -#ifdef MOZ_GECKO_PROFILER -# include "GeckoProfiler.h" -#endif - -class JSFunction; class JSObject; -class JSScript; class nsIGlobalObject; class nsIPrincipal; class nsPIDOMWindowInner; @@ -50,16 +42,6 @@ class Document; void InitScriptSettings(); void DestroyScriptSettings(); -/* - * Static helpers in ScriptSettings which track the number of listeners - * of Javascript RunToCompletion events. These should be used by the code in - * nsDocShell::SetRecordProfileTimelineMarkers to indicate to script - * settings that script run-to-completion needs to be monitored. - * SHOULD BE CALLED ONLY BY MAIN THREAD. - */ -void UseEntryScriptProfiling(); -void UnuseEntryScriptProfiling(); - // To implement a web-compatible browser, it is often necessary to obtain the // global object that is "associated" with the currently-running code. This // process is made more complicated by the fact that, historically, different @@ -317,87 +299,6 @@ class MOZ_STACK_CLASS AutoJSAPI : protected ScriptSettingsStackEntry { AutoJSAPI& operator=(const AutoJSAPI&) = delete; }; -/* - * A class that represents a new script entry point. - * - * |aReason| should be a statically-allocated C string naming the reason we're - * invoking JavaScript code: "setTimeout", "event", and so on. The devtools use - * these strings to label JS execution in timeline and profiling displays. - * - */ -class MOZ_STACK_CLASS AutoEntryScript : public AutoJSAPI { - public: - // Constructing the AutoEntryScript will ensure that it enters the - // Realm of aGlobalObject's JSObject and exposes that JSObject to active JS. - AutoEntryScript(nsIGlobalObject* aGlobalObject, const char* aReason, - bool aIsMainThread = NS_IsMainThread()); - - // aObject can be any object from the relevant global. It must not be a - // cross-compartment wrapper because CCWs are not associated with a single - // global. - // - // Constructing the AutoEntryScript will ensure that it enters the - // Realm of aObject JSObject and exposes aObject's global to active JS. - AutoEntryScript(JSObject* aObject, const char* aReason, - bool aIsMainThread = NS_IsMainThread()); - - ~AutoEntryScript(); - - void SetWebIDLCallerPrincipal(nsIPrincipal* aPrincipal) { - mWebIDLCallerPrincipal = aPrincipal; - } - - private: - // A subclass of AutoEntryMonitor that notifies the docshell. - class DocshellEntryMonitor final : public JS::dbg::AutoEntryMonitor { - public: - DocshellEntryMonitor(JSContext* aCx, const char* aReason); - - // Please note that |aAsyncCause| here is owned by the caller, and its - // lifetime must outlive the lifetime of the DocshellEntryMonitor object. - // In practice, |aAsyncCause| is identical to |aReason| passed into - // the AutoEntryScript constructor, so the lifetime requirements are - // trivially satisfied by |aReason| being a statically allocated string. - void Entry(JSContext* aCx, JSFunction* aFunction, - JS::Handle aAsyncStack, - const char* aAsyncCause) override { - Entry(aCx, aFunction, nullptr, aAsyncStack, aAsyncCause); - } - - void Entry(JSContext* aCx, JSScript* aScript, - JS::Handle aAsyncStack, - const char* aAsyncCause) override { - Entry(aCx, nullptr, aScript, aAsyncStack, aAsyncCause); - } - - void Exit(JSContext* aCx) override; - - private: - void Entry(JSContext* aCx, JSFunction* aFunction, JSScript* aScript, - JS::Handle aAsyncStack, const char* aAsyncCause); - - const char* mReason; - }; - - // It's safe to make this a weak pointer, since it's the subject principal - // when we go on the stack, so can't go away until after we're gone. In - // particular, this is only used from the CallSetup constructor, and only in - // the aIsJSImplementedWebIDL case. And in that case, the subject principal - // is the principal of the callee function that is part of the CallArgs just a - // bit up the stack, and which will outlive us. So we know the principal - // can't go away until then either. - nsIPrincipal* MOZ_NON_OWNING_REF mWebIDLCallerPrincipal; - friend nsIPrincipal* GetWebIDLCallerPrincipal(); - - Maybe mDocShellEntryMonitor; - Maybe mScriptActivity; - JS::AutoHideScriptedCaller mCallerOverride; -#ifdef MOZ_GECKO_PROFILER - AutoProfilerLabel mAutoProfilerLabel; -#endif - AutoRequestJSThreadExecution mJSThreadExecution; -}; - /* * A class that can be used to force a particular incumbent script on the stack. */ diff --git a/dom/script/moz.build b/dom/script/moz.build index 64ac2300de82..e983a8efdd79 100644 --- a/dom/script/moz.build +++ b/dom/script/moz.build @@ -18,6 +18,7 @@ EXPORTS += [ ] EXPORTS.mozilla.dom += [ + "AutoEntryScript.h", "LoadedScript.h", "ScriptDecoding.h", "ScriptElement.h", @@ -28,6 +29,7 @@ EXPORTS.mozilla.dom += [ ] UNIFIED_SOURCES += [ + "AutoEntryScript.cpp", "LoadedScript.cpp", "ModuleLoadRequest.cpp", "nsIScriptElement.cpp", diff --git a/dom/workers/WorkerScope.cpp b/dom/workers/WorkerScope.cpp index 0094bc61f372..f51a049b5903 100644 --- a/dom/workers/WorkerScope.cpp +++ b/dom/workers/WorkerScope.cpp @@ -39,6 +39,7 @@ #include "mozilla/StorageAccess.h" #include "mozilla/TaskCategory.h" #include "mozilla/UniquePtr.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/BindingDeclarations.h" #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/BlobURLProtocolHandler.h" diff --git a/dom/worklet/Worklet.cpp b/dom/worklet/Worklet.cpp index b488a016c741..5b599c0aced0 100644 --- a/dom/worklet/Worklet.cpp +++ b/dom/worklet/Worklet.cpp @@ -7,6 +7,7 @@ #include "Worklet.h" #include "WorkletThread.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/WorkletBinding.h" #include "mozilla/dom/WorkletGlobalScope.h" #include "mozilla/dom/BlobBinding.h" diff --git a/gfx/layers/ipc/ContentCompositorBridgeParent.cpp b/gfx/layers/ipc/ContentCompositorBridgeParent.cpp index 416f4fe79ffe..21806dde2e7d 100644 --- a/gfx/layers/ipc/ContentCompositorBridgeParent.cpp +++ b/gfx/layers/ipc/ContentCompositorBridgeParent.cpp @@ -41,6 +41,7 @@ #include "mozilla/Telemetry.h" #ifdef MOZ_GECKO_PROFILER # include "mozilla/BaseProfilerMarkerTypes.h" +# include "GeckoProfiler.h" #endif namespace mozilla { diff --git a/ipc/glue/MessageChannel.cpp b/ipc/glue/MessageChannel.cpp index 70e780753d37..ceb1d9c6edeb 100644 --- a/ipc/glue/MessageChannel.cpp +++ b/ipc/glue/MessageChannel.cpp @@ -44,6 +44,10 @@ using namespace mozilla::tasktracer; #endif +#ifdef MOZ_GECKO_PROFILER +# include "GeckoProfiler.h" +#endif + // Undo the damage done by mozzconf.h #undef compress @@ -2788,6 +2792,7 @@ void MessageChannel::DumpInterruptStack(const char* const pfx) const { void MessageChannel::AddProfilerMarker(const IPC::Message& aMessage, MessageDirection aDirection) { mMonitor->AssertCurrentThreadOwns(); + #ifdef MOZ_GECKO_PROFILER if (profiler_feature_active(ProfilerFeature::IPCMessages)) { int32_t pid = mListener->OtherPidMaybeInvalid(); diff --git a/ipc/testshell/TestShellParent.cpp b/ipc/testshell/TestShellParent.cpp index 013cb6a345f5..4cab1834e975 100644 --- a/ipc/testshell/TestShellParent.cpp +++ b/ipc/testshell/TestShellParent.cpp @@ -8,6 +8,7 @@ #include "jsfriendapi.h" #include "mozilla/ArrayUtils.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/ScriptSettings.h" #include "xpcpublic.h" diff --git a/ipc/testshell/XPCShellEnvironment.cpp b/ipc/testshell/XPCShellEnvironment.cpp index 516bc117fb88..9617bc0614fa 100644 --- a/ipc/testshell/XPCShellEnvironment.cpp +++ b/ipc/testshell/XPCShellEnvironment.cpp @@ -27,6 +27,7 @@ #include "mozilla/Utf8.h" // mozilla::Utf8Unit #include "mozilla/XPCOM.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/ScriptSettings.h" #include "nsIPrincipal.h" diff --git a/js/xpconnect/loader/mozJSComponentLoader.cpp b/js/xpconnect/loader/mozJSComponentLoader.cpp index e3f5372ee22d..4dbc1ecca73d 100644 --- a/js/xpconnect/loader/mozJSComponentLoader.cpp +++ b/js/xpconnect/loader/mozJSComponentLoader.cpp @@ -62,6 +62,7 @@ #include "mozilla/ResultExtensions.h" #include "mozilla/ScriptPreloader.h" #include "mozilla/ScopeExit.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/ScriptSettings.h" #include "mozilla/ResultExtensions.h" #include "mozilla/UniquePtrExtensions.h" diff --git a/js/xpconnect/src/Sandbox.cpp b/js/xpconnect/src/Sandbox.cpp index cf6669a4d812..4a1432ded9b0 100644 --- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -32,6 +32,7 @@ #include "xpc_make_class.h" #include "XPCWrapper.h" #include "Crypto.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/BindingCallContext.h" #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/BlobBinding.h" diff --git a/js/xpconnect/src/XPCJSContext.cpp b/js/xpconnect/src/XPCJSContext.cpp index adf72138ae30..7a201e8803fc 100644 --- a/js/xpconnect/src/XPCJSContext.cpp +++ b/js/xpconnect/src/XPCJSContext.cpp @@ -80,7 +80,6 @@ using namespace mozilla; using namespace xpc; using namespace JS; -using mozilla::dom::AutoEntryScript; // The watchdog thread loop is pretty trivial, and should not require much stack // space to do its job. So only give it 32KiB or the platform minimum. diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index 28327209cf8f..e8805daf1f3e 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -86,7 +86,6 @@ using namespace mozilla; using namespace xpc; using namespace JS; -using mozilla::dom::AutoEntryScript; using mozilla::dom::PerThreadAtomCache; /***************************************************************************/ diff --git a/js/xpconnect/src/XPCShellImpl.cpp b/js/xpconnect/src/XPCShellImpl.cpp index 7d9f1e0754ae..fd8f7478f2dc 100644 --- a/js/xpconnect/src/XPCShellImpl.cpp +++ b/js/xpconnect/src/XPCShellImpl.cpp @@ -15,6 +15,7 @@ #include "js/PropertySpec.h" #include "js/SourceText.h" // JS::SourceText #include "mozilla/ChaosMode.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/ScriptSettings.h" #include "mozilla/IOInterposer.h" #include "mozilla/Preferences.h" diff --git a/js/xpconnect/src/XPCWrappedJSClass.cpp b/js/xpconnect/src/XPCWrappedJSClass.cpp index 072d0c06ed3a..a583ec1f6449 100644 --- a/js/xpconnect/src/XPCWrappedJSClass.cpp +++ b/js/xpconnect/src/XPCWrappedJSClass.cpp @@ -17,6 +17,7 @@ #include "nsJSUtils.h" #include "nsPrintfCString.h" #include "mozilla/Attributes.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/DOMException.h" #include "mozilla/dom/DOMExceptionBinding.h" diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 898731c276ff..b87ec6d05769 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -161,6 +161,7 @@ namespace mozilla { namespace dom { +class AutoEntryScript; class Exception; } // namespace dom } // namespace mozilla diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index 71d42280d060..4622aedbcbf8 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -114,6 +114,10 @@ #include "mozilla/layers/WebRenderMessages.h" #include "mozilla/layers/WebRenderScrollData.h" +#ifdef MOZ_GECKO_PROFILER +# include "GeckoProfiler.h" +#endif + using namespace mozilla; using namespace mozilla::layers; using namespace mozilla::dom; diff --git a/netwerk/base/nsSocketTransportService2.cpp b/netwerk/base/nsSocketTransportService2.cpp index 2a06dad11236..d93e302e5c93 100644 --- a/netwerk/base/nsSocketTransportService2.cpp +++ b/netwerk/base/nsSocketTransportService2.cpp @@ -5,6 +5,7 @@ #include "nsSocketTransportService2.h" +#include "GeckoProfiler.h" #include "IOActivityMonitor.h" #include "mozilla/Atomics.h" #include "mozilla/ChaosMode.h" diff --git a/toolkit/components/extensions/webrequest/StreamFilter.cpp b/toolkit/components/extensions/webrequest/StreamFilter.cpp index 178689f333c3..a6483365afc6 100644 --- a/toolkit/components/extensions/webrequest/StreamFilter.cpp +++ b/toolkit/components/extensions/webrequest/StreamFilter.cpp @@ -15,6 +15,7 @@ #include "mozilla/extensions/StreamFilterChild.h" #include "mozilla/extensions/StreamFilterEvents.h" #include "mozilla/extensions/StreamFilterParent.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/ContentChild.h" #include "mozilla/ipc/Endpoint.h" #include "nsContentUtils.h" diff --git a/xpcom/base/CycleCollectedJSRuntime.cpp b/xpcom/base/CycleCollectedJSRuntime.cpp index 7fb074a91c97..f291e1b0cf75 100644 --- a/xpcom/base/CycleCollectedJSRuntime.cpp +++ b/xpcom/base/CycleCollectedJSRuntime.cpp @@ -77,6 +77,7 @@ #include "mozilla/TimelineConsumers.h" #include "mozilla/TimelineMarker.h" #include "mozilla/Unused.h" +#include "mozilla/dom/AutoEntryScript.h" #include "mozilla/dom/DOMJSClass.h" #include "mozilla/dom/JSExecutionManager.h" #include "mozilla/dom/ProfileTimelineMarkerBinding.h"