зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1676361 - Move AutoEntryScript to a separate header file to avoid pulling in GeckoProfiler.h everywhere. r=mccr8
Differential Revision: https://phabricator.services.mozilla.com/D97742
This commit is contained in:
Родитель
c6ace2f153
Коммит
e1330cc8f0
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 <stdint.h>
|
||||
#include <utility>
|
||||
#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<JS::Value> aAsyncStack, const char* aAsyncCause) {
|
||||
JS::Rooted<JSFunction*> rootedFunction(aCx);
|
||||
if (aFunction) {
|
||||
rootedFunction = aFunction;
|
||||
}
|
||||
JS::Rooted<JSScript*> rootedScript(aCx);
|
||||
if (aScript) {
|
||||
rootedScript = aScript;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = xpc::CurrentWindowOrNull(aCx);
|
||||
if (!window || !window->GetDocShell() ||
|
||||
!window->GetDocShell()->GetRecordProfileTimelineMarkers()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShellForJSRunToCompletion = window->GetDocShell();
|
||||
|
||||
nsAutoJSString functionName;
|
||||
if (rootedFunction) {
|
||||
JS::Rooted<JSString*> 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<nsPIDOMWindowInner> window = xpc::CurrentWindowOrNull(aCx);
|
||||
// Not really worth checking GetRecordProfileTimelineMarkers here.
|
||||
if (window && window->GetDocShell()) {
|
||||
nsCOMPtr<nsIDocShell> docShellForJSRunToCompletion = window->GetDocShell();
|
||||
docShellForJSRunToCompletion->NotifyJSRunToCompletionStop();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
|
@ -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/RootingAPI.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 "GeckoProfiler.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<JS::Value> aAsyncStack,
|
||||
const char* aAsyncCause) override {
|
||||
Entry(aCx, aFunction, nullptr, aAsyncStack, aAsyncCause);
|
||||
}
|
||||
|
||||
void Entry(JSContext* aCx, JSScript* aScript,
|
||||
JS::Handle<JS::Value> 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<JS::Value> 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<DocshellEntryMonitor> mDocShellEntryMonitor;
|
||||
Maybe<xpc::AutoScriptActivity> mScriptActivity;
|
||||
JS::AutoHideScriptedCaller mCallerOverride;
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
AutoProfilerLabel mAutoProfilerLabel;
|
||||
#endif
|
||||
AutoRequestJSThreadExecution mJSThreadExecution;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
#endif // DOM_SCRIPT_AUTOENTRYSCRIPT_H_
|
|
@ -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"
|
||||
|
|
|
@ -5,32 +5,47 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
|
||||
#include <utility>
|
||||
#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<JS::Value> aAsyncStack, const char* aAsyncCause) {
|
||||
JS::Rooted<JSFunction*> rootedFunction(aCx);
|
||||
if (aFunction) {
|
||||
rootedFunction = aFunction;
|
||||
}
|
||||
JS::Rooted<JSScript*> rootedScript(aCx);
|
||||
if (aScript) {
|
||||
rootedScript = aScript;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = xpc::CurrentWindowOrNull(aCx);
|
||||
if (!window || !window->GetDocShell() ||
|
||||
!window->GetDocShell()->GetRecordProfileTimelineMarkers()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShellForJSRunToCompletion = window->GetDocShell();
|
||||
|
||||
nsAutoJSString functionName;
|
||||
if (rootedFunction) {
|
||||
JS::Rooted<JSString*> 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<nsPIDOMWindowInner> window = xpc::CurrentWindowOrNull(aCx);
|
||||
// Not really worth checking GetRecordProfileTimelineMarkers here.
|
||||
if (window && window->GetDocShell()) {
|
||||
nsCOMPtr<nsIDocShell> docShellForJSRunToCompletion = window->GetDocShell();
|
||||
docShellForJSRunToCompletion->NotifyJSRunToCompletionStop();
|
||||
}
|
||||
}
|
||||
|
||||
AutoIncumbentScript::AutoIncumbentScript(nsIGlobalObject* aGlobalObject)
|
||||
: ScriptSettingsStackEntry(aGlobalObject, eIncumbentScript),
|
||||
mCallerOverride(nsContentUtils::GetCurrentJSContext()) {
|
||||
|
|
|
@ -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<JS::Value> aAsyncStack,
|
||||
const char* aAsyncCause) override {
|
||||
Entry(aCx, aFunction, nullptr, aAsyncStack, aAsyncCause);
|
||||
}
|
||||
|
||||
void Entry(JSContext* aCx, JSScript* aScript,
|
||||
JS::Handle<JS::Value> 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<JS::Value> 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<DocshellEntryMonitor> mDocShellEntryMonitor;
|
||||
Maybe<xpc::AutoScriptActivity> 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.
|
||||
*/
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "jsfriendapi.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
|
||||
#include "mozilla/dom/AutoEntryScript.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
|
||||
#include "xpcpublic.h"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -86,7 +86,6 @@
|
|||
using namespace mozilla;
|
||||
using namespace xpc;
|
||||
using namespace JS;
|
||||
using mozilla::dom::AutoEntryScript;
|
||||
using mozilla::dom::PerThreadAtomCache;
|
||||
|
||||
/***************************************************************************/
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -161,6 +161,7 @@
|
|||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class AutoEntryScript;
|
||||
class Exception;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
Загрузка…
Ссылка в новой задаче