diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 242a3611492e..34e7ce905da2 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -51,7 +51,6 @@ #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 05ab478a5b23..12ed7fce2f99 100644 --- a/dom/base/BodyStream.cpp +++ b/dom/base/BodyStream.cpp @@ -6,7 +6,6 @@ #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 b971e6d96b2a..a221b0ee5cc1 100644 --- a/dom/base/CustomElementRegistry.cpp +++ b/dom/base/CustomElementRegistry.cpp @@ -8,7 +8,6 @@ #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 e240b5d58636..664695e87ff9 100644 --- a/dom/base/Timeout.cpp +++ b/dom/base/Timeout.cpp @@ -9,10 +9,6 @@ #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/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index f0f57bb31778..bc7c37503245 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -126,7 +126,6 @@ #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 ac9e24eba48f..fa369e5487c0 100644 --- a/dom/base/nsFrameMessageManager.cpp +++ b/dom/base/nsFrameMessageManager.cpp @@ -40,7 +40,6 @@ #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 cfed7d20078e..37b40cabf8a9 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -86,7 +86,6 @@ #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 3edecbfefcde..296402920141 100644 --- a/dom/bindings/CallbackObject.h +++ b/dom/bindings/CallbackObject.h @@ -30,7 +30,6 @@ #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 7e733b91d724..b202dbe430ff 100644 --- a/dom/fetch/FetchStreamReader.cpp +++ b/dom/fetch/FetchStreamReader.cpp @@ -8,7 +8,6 @@ #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 cfbe73e5775d..71d5e49d394d 100644 --- a/dom/ipc/SharedMap.cpp +++ b/dom/ipc/SharedMap.cpp @@ -10,7 +10,6 @@ #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 493c91ab41e1..e55365744917 100644 --- a/dom/ipc/jsactor/JSActor.cpp +++ b/dom/ipc/jsactor/JSActor.cpp @@ -10,7 +10,6 @@ #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 ba5745ccb97e..672223ada610 100644 --- a/dom/ipc/jsactor/JSActorManager.cpp +++ b/dom/ipc/jsactor/JSActorManager.cpp @@ -5,8 +5,6 @@ * 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 5084fd8429cc..0bc617700c0d 100644 --- a/dom/jsurl/nsJSProtocolHandler.cpp +++ b/dom/jsurl/nsJSProtocolHandler.cpp @@ -42,7 +42,6 @@ #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 fcb0f3c194ff..2d3f6c767b0f 100644 --- a/dom/l10n/DOMLocalization.cpp +++ b/dom/l10n/DOMLocalization.cpp @@ -10,7 +10,6 @@ #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 760cd7f3328b..cd793697a602 100644 --- a/dom/l10n/DocumentL10n.cpp +++ b/dom/l10n/DocumentL10n.cpp @@ -6,7 +6,6 @@ #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 eba441772705..b6a395a044d7 100644 --- a/dom/media/webaudio/AudioWorkletNode.cpp +++ b/dom/media/webaudio/AudioWorkletNode.cpp @@ -14,7 +14,6 @@ #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 60f5d50ceb51..0de84114daba 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/AutoEntryScript.h" +#include "nsPIDOMWindow.h" // nsPIDOMWindowInner +#include "mozilla/dom/ScriptSettings.h" // AutoEntryScript #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 ca6589dafa3c..5fa02c8d43ad 100644 --- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -32,7 +32,6 @@ #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 f5b469e81999..eef4d6e52c8b 100644 --- a/dom/plugins/base/nsNPAPIPlugin.cpp +++ b/dom/plugins/base/nsNPAPIPlugin.cpp @@ -32,7 +32,6 @@ #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 ae15725855c2..ab6a835d4a48 100644 --- a/dom/promise/Promise.cpp +++ b/dom/promise/Promise.cpp @@ -18,7 +18,6 @@ #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 5327b2f23bc6..47f5e5fce33b 100644 --- a/dom/promise/Promise.h +++ b/dom/promise/Promise.h @@ -19,7 +19,6 @@ #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 dcdf1c43417c..cb493e8034d5 100644 --- a/dom/prototype/PrototypeDocumentContentSink.cpp +++ b/dom/prototype/PrototypeDocumentContentSink.cpp @@ -38,7 +38,6 @@ #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 deleted file mode 100644 index bb41cb9d4fd3..000000000000 --- a/dom/script/AutoEntryScript.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* -*- 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 deleted file mode 100644 index 83d917a13c0e..000000000000 --- a/dom/script/AutoEntryScript.h +++ /dev/null @@ -1,125 +0,0 @@ -/* -*- 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 52118693c7d0..a4f454badc45 100644 --- a/dom/script/ScriptLoader.cpp +++ b/dom/script/ScriptLoader.cpp @@ -29,7 +29,6 @@ #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 692851f0652d..589b46999c7f 100644 --- a/dom/script/ScriptSettings.cpp +++ b/dom/script/ScriptSettings.cpp @@ -5,47 +5,32 @@ * 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/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/Maybe.h" #include "mozilla/dom/Document.h" #include "mozilla/dom/Element.h" -#include "mozilla/dom/ScriptLoadRequest.h" -#include "mozilla/dom/WorkerCommon.h" -#include "nsContentUtils.h" -#include "nsDebug.h" -#include "nsGlobalWindowInner.h" -#include "nsIGlobalObject.h" -#include "nsINode.h" -#include "nsIPrincipal.h" -#include "nsISupports.h" -#include "nsJSUtils.h" -#include "nsPIDOMWindow.h" -#include "nsString.h" -#include "nscore.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 "nsContentUtils.h" +#include "nsGlobalWindow.h" +#include "nsPIDOMWindow.h" +#include "nsTArray.h" +#include "nsJSUtils.h" +#include "nsDOMJSUtils.h" namespace mozilla { namespace dom { @@ -81,6 +66,25 @@ 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(); } @@ -148,6 +152,19 @@ 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) { @@ -615,6 +632,106 @@ 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 8526a0482d29..289ebe41ff5b 100644 --- a/dom/script/ScriptSettings.h +++ b/dom/script/ScriptSettings.h @@ -9,15 +9,23 @@ #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; @@ -42,6 +50,16 @@ 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 @@ -299,6 +317,87 @@ 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 e983a8efdd79..64ac2300de82 100644 --- a/dom/script/moz.build +++ b/dom/script/moz.build @@ -18,7 +18,6 @@ EXPORTS += [ ] EXPORTS.mozilla.dom += [ - "AutoEntryScript.h", "LoadedScript.h", "ScriptDecoding.h", "ScriptElement.h", @@ -29,7 +28,6 @@ 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 f51a049b5903..0094bc61f372 100644 --- a/dom/workers/WorkerScope.cpp +++ b/dom/workers/WorkerScope.cpp @@ -39,7 +39,6 @@ #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 5b599c0aced0..b488a016c741 100644 --- a/dom/worklet/Worklet.cpp +++ b/dom/worklet/Worklet.cpp @@ -7,7 +7,6 @@ #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/ipc/glue/MessageChannel.cpp b/ipc/glue/MessageChannel.cpp index ceb1d9c6edeb..70e780753d37 100644 --- a/ipc/glue/MessageChannel.cpp +++ b/ipc/glue/MessageChannel.cpp @@ -44,10 +44,6 @@ using namespace mozilla::tasktracer; #endif -#ifdef MOZ_GECKO_PROFILER -# include "GeckoProfiler.h" -#endif - // Undo the damage done by mozzconf.h #undef compress @@ -2792,7 +2788,6 @@ 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 4cab1834e975..013cb6a345f5 100644 --- a/ipc/testshell/TestShellParent.cpp +++ b/ipc/testshell/TestShellParent.cpp @@ -8,7 +8,6 @@ #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 9617bc0614fa..516bc117fb88 100644 --- a/ipc/testshell/XPCShellEnvironment.cpp +++ b/ipc/testshell/XPCShellEnvironment.cpp @@ -27,7 +27,6 @@ #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 4dbc1ecca73d..e3f5372ee22d 100644 --- a/js/xpconnect/loader/mozJSComponentLoader.cpp +++ b/js/xpconnect/loader/mozJSComponentLoader.cpp @@ -62,7 +62,6 @@ #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 4a1432ded9b0..cf6669a4d812 100644 --- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -32,7 +32,6 @@ #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 7a201e8803fc..adf72138ae30 100644 --- a/js/xpconnect/src/XPCJSContext.cpp +++ b/js/xpconnect/src/XPCJSContext.cpp @@ -80,6 +80,7 @@ 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 e8805daf1f3e..28327209cf8f 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -86,6 +86,7 @@ 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 fd8f7478f2dc..7d9f1e0754ae 100644 --- a/js/xpconnect/src/XPCShellImpl.cpp +++ b/js/xpconnect/src/XPCShellImpl.cpp @@ -15,7 +15,6 @@ #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 a583ec1f6449..072d0c06ed3a 100644 --- a/js/xpconnect/src/XPCWrappedJSClass.cpp +++ b/js/xpconnect/src/XPCWrappedJSClass.cpp @@ -17,7 +17,6 @@ #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 b87ec6d05769..898731c276ff 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -161,7 +161,6 @@ 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 501aeb10db68..4c26afdc37fb 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -114,10 +114,6 @@ #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/toolkit/components/extensions/webrequest/StreamFilter.cpp b/toolkit/components/extensions/webrequest/StreamFilter.cpp index a6483365afc6..178689f333c3 100644 --- a/toolkit/components/extensions/webrequest/StreamFilter.cpp +++ b/toolkit/components/extensions/webrequest/StreamFilter.cpp @@ -15,7 +15,6 @@ #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 f291e1b0cf75..7fb074a91c97 100644 --- a/xpcom/base/CycleCollectedJSRuntime.cpp +++ b/xpcom/base/CycleCollectedJSRuntime.cpp @@ -77,7 +77,6 @@ #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"