зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1601179 - Enable async stacks but limit captured async stacks to debuggees. r=jorendorff,smaug
The 'asyncStack' flag on JS execution contexts is used as a general switch to enable async stack capture across all locations in SpiderMonkey, but this causes problems because it can at times be too much of a performance burden to general and track all of these stacks. Since the introduction of this option, we have only enabled it on Nightly and DevEdition for non-mobile builds, which has left a lot of users unable to take advantage of this data while debugging. This patch enables async stack traces across all of Firefox, but introduces a new pref to toggle the scope of the actual expensive part of async stacks, which is _capturing_ them and keeping them alive in memory. The new pref limits the capturing of async stack traces to only debuggees, unless an explicit pref is flipped to capture async traces for all cases. This means that while async stacks are technically enabled, and code could manually capture a stack and pass it back to SpiderMonkey and see that stack reflected in later captured stacks, SpiderMonkey itself and related async DOM APIs, among others, will not capture stacks or pass them to SpiderMonkey, so there should be no general change in performance by enabling the broader feature itself, unless the user is actively debugging the page. One effect of this patch is that if you have the debugger open and then close it, objects that have async stacks associated with them will retain those stacks and they will continue to show up in stack traces, no _new_ stacks will be captured. jorendorff and I have decided that this is okay because the expectation that the debugger fully revert every possible effect that it could have on a page is a nice goal but not a strict requirement. Differential Revision: https://phabricator.services.mozilla.com/D68503
This commit is contained in:
Родитель
dbf76d8e3e
Коммит
25d491b792
|
@ -6,7 +6,6 @@
|
|||
|
||||
add_task(async function() {
|
||||
pushPref("devtools.debugger.features.async-captured-stacks", true);
|
||||
pushPref("javascript.options.asyncstack", true);
|
||||
const dbg = await initDebugger("doc-frames-async.html");
|
||||
|
||||
invokeInTab("main");
|
||||
|
|
|
@ -166,11 +166,6 @@ const REQUEST_COUNT =
|
|||
EXPECTED_REQUESTS_TOP.length + EXPECTED_REQUESTS_SUB.length;
|
||||
|
||||
add_task(async function() {
|
||||
// Async stacks aren't on by default in all builds
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["javascript.options.asyncstack", true]],
|
||||
});
|
||||
|
||||
// the initNetMonitor function clears the network request list after the
|
||||
// page is loaded. That's why we first load a bogus page from SIMPLE_URL,
|
||||
// and only then load the real thing from TOP_URL - we want to catch
|
||||
|
|
|
@ -133,11 +133,6 @@ const EXPECTED_REQUESTS = [
|
|||
];
|
||||
|
||||
add_task(async function() {
|
||||
// Async stacks aren't on by default in all builds
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["javascript.options.asyncstack", true]],
|
||||
});
|
||||
|
||||
// the initNetMonitor function clears the network request list after the
|
||||
// page is loaded. That's why we first load a bogus page from SIMPLE_URL,
|
||||
// and only then load the real thing from INITIATOR_URL - we want to catch
|
||||
|
|
|
@ -18,9 +18,6 @@ add_task(async function() {
|
|||
// Set a higher panel height in order to get full CodeMirror content
|
||||
await pushPref("devtools.toolbox.footer.height", 400);
|
||||
|
||||
// Async stacks aren't on by default in all builds
|
||||
await pushPref("javascript.options.asyncstack", true);
|
||||
|
||||
const { tab, monitor, toolbox } = await initNetMonitor(POST_DATA_URL, {
|
||||
requestCount: 1,
|
||||
});
|
||||
|
|
|
@ -298,6 +298,14 @@ function initNetMonitor(url, { requestCount, enableCache = false }) {
|
|||
}
|
||||
|
||||
return (async function() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
// Capture all stacks so that the timing of devtools opening
|
||||
// doesn't affect the stack trace results.
|
||||
["javascript.options.asyncstack_capture_debuggee_only", false],
|
||||
],
|
||||
});
|
||||
|
||||
const tab = await addTab(url);
|
||||
info("Net tab added successfully: " + url);
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ promiseThen(onPromiseThen);
|
|||
</script>`;
|
||||
|
||||
add_task(async function() {
|
||||
await pushPref("javascript.options.asyncstack", true);
|
||||
await pushPref("javascript.options.asyncstack_capture_debuggee_only", false);
|
||||
const hud = await openNewTabAndConsole(TEST_URI);
|
||||
|
||||
// Cached messages stacktrace are missing "promise callback" frames, so we reload
|
||||
|
|
|
@ -35,7 +35,7 @@ httpServer.registerPathHandler("/test.js", function(_, response) {
|
|||
const TEST_URI = `http://localhost:${httpServer.identity.primaryPort}/`;
|
||||
|
||||
add_task(async function() {
|
||||
await pushPref("javascript.options.asyncstack", true);
|
||||
await pushPref("javascript.options.asyncstack_capture_debuggee_only", false);
|
||||
const hud = await openNewTabAndConsole(TEST_URI);
|
||||
|
||||
info("Call the log function defined in the test page");
|
||||
|
|
|
@ -37,7 +37,7 @@ const TEST_URI = `data:text/html;charset=utf-8,
|
|||
</script>`;
|
||||
|
||||
add_task(async function() {
|
||||
await pushPref("javascript.options.asyncstack", true);
|
||||
await pushPref("javascript.options.asyncstack_capture_debuggee_only", false);
|
||||
const hud = await openNewTabAndConsole(TEST_URI);
|
||||
|
||||
const expectedErrors = [
|
||||
|
|
|
@ -17,7 +17,7 @@ const TEST_URI =
|
|||
const STUB_FILE = "pageError.js";
|
||||
|
||||
add_task(async function() {
|
||||
await pushPref("javascript.options.asyncstack", true);
|
||||
await pushPref("javascript.options.asyncstack_capture_debuggee_only", false);
|
||||
|
||||
const isStubsUpdate = env.get(STUBS_UPDATE_ENV) == "true";
|
||||
info(`${isStubsUpdate ? "Update" : "Check"} ${STUB_FILE}`);
|
||||
|
|
|
@ -11,7 +11,8 @@ const TEST_URI =
|
|||
"test/browser/test-error-worker.html";
|
||||
|
||||
add_task(async function() {
|
||||
await pushPref("javascript.options.asyncstack", true);
|
||||
await pushPref("javascript.options.asyncstack_capture_debuggee_only", false);
|
||||
|
||||
const hud = await openNewTabAndConsole(TEST_URI);
|
||||
|
||||
await checkMessageStack(hud, "hello", [13, 4, 3]);
|
||||
|
|
|
@ -64,11 +64,6 @@ function init() {
|
|||
}
|
||||
|
||||
function checkStack(expectedName) {
|
||||
if (!Services.prefs.getBoolPref("javascript.options.asyncstack")) {
|
||||
info("Async stacks are disabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
let stack = Components.stack;
|
||||
while (stack) {
|
||||
info(stack.name);
|
||||
|
|
|
@ -58,11 +58,6 @@ class RootFront extends protocol.FrontClassWithSpec(rootSpec) {
|
|||
protocol.registerFront(RootFront);
|
||||
|
||||
function run_test() {
|
||||
if (!Services.prefs.getBoolPref("javascript.options.asyncstack")) {
|
||||
info("Async stacks are disabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
DevToolsServer.createRootActor = RootActor;
|
||||
DevToolsServer.init();
|
||||
|
||||
|
|
|
@ -13,20 +13,7 @@
|
|||
var { executeSoon } = require("devtools/shared/DevToolsUtils");
|
||||
var defer = require("devtools/shared/defer");
|
||||
|
||||
var asyncStackEnabled = Services.prefs.getBoolPref(
|
||||
"javascript.options.asyncstack"
|
||||
);
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.setBoolPref(
|
||||
"javascript.options.asyncstack",
|
||||
asyncStackEnabled
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function() {
|
||||
Services.prefs.setBoolPref("javascript.options.asyncstack", true);
|
||||
|
||||
await waitForTick();
|
||||
|
||||
let stack = Components.stack;
|
||||
|
|
|
@ -41,7 +41,11 @@ var TESTS = [
|
|||
},
|
||||
];
|
||||
|
||||
if (Services.prefs.getBoolPref("javascript.options.asyncstack")) {
|
||||
if (
|
||||
!Services.prefs.getBoolPref(
|
||||
"javascript.options.asyncstack_capture_debuggee_only"
|
||||
)
|
||||
) {
|
||||
TESTS.push(
|
||||
{
|
||||
desc: "Async stack trace on Javascript marker",
|
||||
|
|
|
@ -97,7 +97,11 @@ var TESTS = [
|
|||
},
|
||||
];
|
||||
|
||||
if (Services.prefs.getBoolPref("javascript.options.asyncstack")) {
|
||||
if (
|
||||
!Services.prefs.getBoolPref(
|
||||
"javascript.options.asyncstack_capture_debuggee_only"
|
||||
)
|
||||
) {
|
||||
TESTS.push({
|
||||
desc: "Async stack trace on Promise",
|
||||
searchFor: "ConsoleTime",
|
||||
|
|
|
@ -53,7 +53,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1142577
|
|||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{"set": [['javascript.options.asyncstack', true]]},
|
||||
{"set": [['javascript.options.asyncstack_capture_debuggee_only', false]]},
|
||||
a);
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -53,7 +53,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1142577
|
|||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{"set": [['javascript.options.asyncstack', true]]},
|
||||
{"set": [['javascript.options.asyncstack_capture_debuggee_only', false]]},
|
||||
a);
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -100,7 +100,7 @@ void CallbackObject::FinishSlowJSInitIfMoreThanOneOwner(JSContext* aCx) {
|
|||
MOZ_ASSERT(mRefCnt.get() > 0);
|
||||
if (mRefCnt.get() > 1) {
|
||||
mozilla::HoldJSObjects(this);
|
||||
if (JS::ContextOptionsRef(aCx).asyncStack()) {
|
||||
if (JS::IsAsyncStackCaptureEnabledForRealm(aCx)) {
|
||||
JS::RootedObject stack(aCx);
|
||||
if (!JS::CaptureCurrentStack(aCx, &stack)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
|
|
|
@ -65,7 +65,7 @@ class CallbackObject : public nsISupports {
|
|||
explicit CallbackObject(JSContext* aCx, JS::Handle<JSObject*> aCallback,
|
||||
JS::Handle<JSObject*> aCallbackGlobal,
|
||||
nsIGlobalObject* aIncumbentGlobal) {
|
||||
if (aCx && JS::ContextOptionsRef(aCx).asyncStack()) {
|
||||
if (aCx && JS::IsAsyncStackCaptureEnabledForRealm(aCx)) {
|
||||
JS::RootedObject stack(aCx);
|
||||
if (!JS::CaptureCurrentStack(aCx, &stack)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
|
|
|
@ -92,7 +92,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1148593
|
|||
|
||||
addLoadEvent(function() {
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{"set": [["javascript.options.asyncstack", true]]},
|
||||
{"set": [["javascript.options.asyncstack_capture_debuggee_only", false]]},
|
||||
runTests);
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -19,7 +19,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1107592
|
|||
|
||||
var asyncFrame;
|
||||
/* Async parent frames from pushPrefEnv don't show up in e10s. */
|
||||
if (SpecialPowers.getBoolPref("javascript.options.asyncstack")) {
|
||||
if (!SpecialPowers.getBoolPref("javascript.options.asyncstack_capture_debuggee_only")) {
|
||||
asyncFrame = `Async*@${file}:153:17
|
||||
`;
|
||||
} else {
|
||||
|
|
|
@ -39,7 +39,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1107592
|
|||
var t = new TestInterfaceJS();
|
||||
|
||||
|
||||
var asyncStack = SpecialPowers.getBoolPref("javascript.options.asyncstack");
|
||||
var asyncStack = !SpecialPowers.getBoolPref("javascript.options.asyncstack_capture_debuggee_only");
|
||||
var ourFile = location.href;
|
||||
var unwrapError = "Promise rejection value is a non-unwrappable cross-compartment wrapper.";
|
||||
var parentFrame = asyncStack ? `Async*@${ourFile}:130:17
|
||||
|
|
|
@ -195,7 +195,7 @@ static ipc::StructuredCloneData CloneJSStack(JSContext* aCx,
|
|||
|
||||
static ipc::StructuredCloneData CaptureJSStack(JSContext* aCx) {
|
||||
JS::Rooted<JSObject*> stack(aCx, nullptr);
|
||||
if (JS::ContextOptionsRef(aCx).asyncStack() &&
|
||||
if (JS::IsAsyncStackCaptureEnabledForRealm(aCx) &&
|
||||
!JS::CaptureCurrentStack(aCx, &stack)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,11 @@
|
|||
"use strict";
|
||||
|
||||
function maybeAsyncStack(offset, column) {
|
||||
if (!Services.prefs.getBoolPref("javascript.options.asyncstack")) {
|
||||
if (
|
||||
Services.prefs.getBoolPref(
|
||||
"javascript.options.asyncstack_capture_debuggee_only"
|
||||
)
|
||||
) {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,11 @@
|
|||
"use strict";
|
||||
|
||||
function maybeAsyncStack(offset, column) {
|
||||
if (!Services.prefs.getBoolPref("javascript.options.asyncstack")) {
|
||||
if (
|
||||
Services.prefs.getBoolPref(
|
||||
"javascript.options.asyncstack_capture_debuggee_only"
|
||||
)
|
||||
) {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
|
@ -302,7 +302,9 @@ void LoadContextOptions(const char* aPrefName, void* /* aClosure */) {
|
|||
NS_LITERAL_CSTRING("throw_on_asmjs_validation_failure")))
|
||||
.setSourcePragmas(
|
||||
GetWorkerPref<bool>(NS_LITERAL_CSTRING("source_pragmas")))
|
||||
.setAsyncStack(GetWorkerPref<bool>(NS_LITERAL_CSTRING("asyncstack")));
|
||||
.setAsyncStack(GetWorkerPref<bool>(NS_LITERAL_CSTRING("asyncstack")))
|
||||
.setAsyncStackCaptureDebuggeeOnly(GetWorkerPref<bool>(
|
||||
NS_LITERAL_CSTRING("asyncstack_capture_debuggee_only")));
|
||||
|
||||
nsCOMPtr<nsIXULRuntime> xr = do_GetService("@mozilla.org/xre/runtime;1");
|
||||
if (xr) {
|
||||
|
|
|
@ -34,6 +34,7 @@ class JS_PUBLIC_API ContextOptions {
|
|||
disableIon_(false),
|
||||
disableEvalSecurityChecks_(false),
|
||||
asyncStack_(true),
|
||||
asyncStackCaptureDebuggeeOnly_(false),
|
||||
sourcePragmas_(true),
|
||||
throwOnDebuggeeWouldRun_(true),
|
||||
dumpStackOnDebuggeeWouldRun_(false),
|
||||
|
@ -152,6 +153,14 @@ class JS_PUBLIC_API ContextOptions {
|
|||
return *this;
|
||||
}
|
||||
|
||||
bool asyncStackCaptureDebuggeeOnly() const {
|
||||
return asyncStackCaptureDebuggeeOnly_;
|
||||
}
|
||||
ContextOptions& setAsyncStackCaptureDebuggeeOnly(bool flag) {
|
||||
asyncStackCaptureDebuggeeOnly_ = flag;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Enable/disable support for parsing '//(#@) source(Mapping)?URL=' pragmas.
|
||||
bool sourcePragmas() const { return sourcePragmas_; }
|
||||
ContextOptions& setSourcePragmas(bool flag) {
|
||||
|
@ -232,6 +241,7 @@ class JS_PUBLIC_API ContextOptions {
|
|||
bool disableIon_ : 1;
|
||||
bool disableEvalSecurityChecks_ : 1;
|
||||
bool asyncStack_ : 1;
|
||||
bool asyncStackCaptureDebuggeeOnly_ : 1;
|
||||
bool sourcePragmas_ : 1;
|
||||
bool throwOnDebuggeeWouldRun_ : 1;
|
||||
bool dumpStackOnDebuggeeWouldRun_ : 1;
|
||||
|
|
|
@ -386,10 +386,6 @@ namespace {
|
|||
mozilla::Atomic<uint64_t> gIDGenerator(0);
|
||||
} // namespace
|
||||
|
||||
static MOZ_ALWAYS_INLINE bool ShouldCaptureDebugInfo(JSContext* cx) {
|
||||
return cx->options().asyncStack() || cx->realm()->isDebuggee();
|
||||
}
|
||||
|
||||
class PromiseDebugInfo : public NativeObject {
|
||||
private:
|
||||
enum Slots {
|
||||
|
@ -479,7 +475,7 @@ class PromiseDebugInfo : public NativeObject {
|
|||
MOZ_ASSERT_IF(unwrappedRejectionStack,
|
||||
promise->state() == JS::PromiseState::Rejected);
|
||||
|
||||
if (!ShouldCaptureDebugInfo(cx)) {
|
||||
if (!JS::IsAsyncStackCaptureEnabledForRealm(cx)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2255,7 +2251,7 @@ CreatePromiseObjectInternal(JSContext* cx, HandleObject proto /* = nullptr */,
|
|||
// Step 7.
|
||||
// Implicit, the handled flag is unset by default.
|
||||
|
||||
if (MOZ_LIKELY(!ShouldCaptureDebugInfo(cx))) {
|
||||
if (MOZ_LIKELY(!JS::IsAsyncStackCaptureEnabledForRealm(cx))) {
|
||||
return promise;
|
||||
}
|
||||
|
||||
|
@ -5160,8 +5156,6 @@ static MOZ_ALWAYS_INLINE bool IsPromiseThenOrCatchRetValImplicitlyUsed(
|
|||
// used explicitly in the script, the stack info is observable in devtools
|
||||
// and profilers. We shouldn't apply the optimization not to allocate the
|
||||
// returned Promise object if the it's implicitly used by them.
|
||||
//
|
||||
// FIXME: Once bug 1280819 gets fixed, we can use ShouldCaptureDebugInfo.
|
||||
if (!cx->options().asyncStack()) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -5861,6 +5861,15 @@ JS_PUBLIC_API bool JS::CaptureCurrentStack(
|
|||
return true;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API bool JS::IsAsyncStackCaptureEnabledForRealm(JSContext* cx) {
|
||||
if (!cx->options().asyncStack()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !cx->options().asyncStackCaptureDebuggeeOnly() ||
|
||||
cx->realm()->isDebuggee();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API bool JS::CopyAsyncStack(JSContext* cx,
|
||||
JS::HandleObject asyncStack,
|
||||
JS::HandleString asyncCause,
|
||||
|
|
|
@ -3026,6 +3026,16 @@ extern JS_PUBLIC_API bool CaptureCurrentStack(
|
|||
JSContext* cx, MutableHandleObject stackp,
|
||||
StackCapture&& capture = StackCapture(AllFrames()));
|
||||
|
||||
/**
|
||||
* Returns true if capturing stack trace data to associate with an asynchronous
|
||||
* operation is currently enabled for the current context realm.
|
||||
*
|
||||
* Users should check this state before capturing a stack that will be passed
|
||||
* back to AutoSetAsyncStackForNewCalls later, in order to avoid capturing a
|
||||
* stack for async use when we don't actually want to capture it.
|
||||
*/
|
||||
extern JS_PUBLIC_API bool IsAsyncStackCaptureEnabledForRealm(JSContext* cx);
|
||||
|
||||
/*
|
||||
* This is a utility function for preparing an async stack to be used
|
||||
* by some other object. This may be used when you need to treat a
|
||||
|
|
|
@ -506,6 +506,7 @@ bool shell::enableWasmVerbose = false;
|
|||
bool shell::enableTestWasmAwaitTier2 = false;
|
||||
bool shell::enableSourcePragmas = true;
|
||||
bool shell::enableAsyncStacks = false;
|
||||
bool shell::enableAsyncStackCaptureDebuggeeOnly = false;
|
||||
bool shell::enableStreams = false;
|
||||
bool shell::enableReadableByteStreams = false;
|
||||
bool shell::enableBYOBStreamReaders = false;
|
||||
|
@ -10303,6 +10304,8 @@ static bool SetContextOptions(JSContext* cx, const OptionParser& op) {
|
|||
enableTestWasmAwaitTier2 = op.getBoolOption("test-wasm-await-tier2");
|
||||
enableSourcePragmas = !op.getBoolOption("no-source-pragmas");
|
||||
enableAsyncStacks = !op.getBoolOption("no-async-stacks");
|
||||
enableAsyncStackCaptureDebuggeeOnly =
|
||||
op.getBoolOption("async-stacks-capture-debuggee-only");
|
||||
enableStreams = !op.getBoolOption("no-streams");
|
||||
enableReadableByteStreams = op.getBoolOption("enable-readable-byte-streams");
|
||||
enableBYOBStreamReaders = op.getBoolOption("enable-byob-stream-readers");
|
||||
|
@ -10337,7 +10340,8 @@ static bool SetContextOptions(JSContext* cx, const OptionParser& op) {
|
|||
.setWasmVerbose(enableWasmVerbose)
|
||||
.setTestWasmAwaitTier2(enableTestWasmAwaitTier2)
|
||||
.setSourcePragmas(enableSourcePragmas)
|
||||
.setAsyncStack(enableAsyncStacks);
|
||||
.setAsyncStack(enableAsyncStacks)
|
||||
.setAsyncStackCaptureDebuggeeOnly(enableAsyncStackCaptureDebuggeeOnly);
|
||||
|
||||
if (op.getBoolOption("no-ion-for-main-context")) {
|
||||
JS::ContextOptionsRef(cx).setDisableIon();
|
||||
|
@ -11372,6 +11376,8 @@ int main(int argc, char** argv, char** envp) {
|
|||
!op.addBoolOption('\0', "no-source-pragmas",
|
||||
"Disable source(Mapping)URL pragma parsing") ||
|
||||
!op.addBoolOption('\0', "no-async-stacks", "Disable async stacks") ||
|
||||
!op.addBoolOption('\0', "async-stacks-capture-debuggee-only",
|
||||
"Limit async stack capture to only debuggees") ||
|
||||
!op.addMultiStringOption('\0', "dll", "LIBRARY",
|
||||
"Dynamically load LIBRARY") ||
|
||||
!op.addBoolOption('\0', "suppress-minidump",
|
||||
|
|
|
@ -130,6 +130,7 @@ extern bool enableWasmVerbose;
|
|||
extern bool enableTestWasmAwaitTier2;
|
||||
extern bool enableSourcePragmas;
|
||||
extern bool enableAsyncStacks;
|
||||
extern bool enableAsyncStackCaptureDebuggeeOnly;
|
||||
extern bool enableStreams;
|
||||
extern bool enableReadableByteStreams;
|
||||
extern bool enableBYOBStreamReaders;
|
||||
|
|
|
@ -947,6 +947,8 @@ static void ReloadPrefsCallback(const char* pref, void* aXpccx) {
|
|||
bool useSourcePragmas =
|
||||
Preferences::GetBool(JS_OPTIONS_DOT_STR "source_pragmas");
|
||||
bool useAsyncStack = Preferences::GetBool(JS_OPTIONS_DOT_STR "asyncstack");
|
||||
bool useAsyncStackCaptureDebuggeeOnly = Preferences::GetBool(
|
||||
JS_OPTIONS_DOT_STR "asyncstack_capture_debuggee_only");
|
||||
|
||||
bool throwOnDebuggeeWouldRun =
|
||||
Preferences::GetBool(JS_OPTIONS_DOT_STR "throw_on_debuggee_would_run");
|
||||
|
@ -1006,6 +1008,7 @@ static void ReloadPrefsCallback(const char* pref, void* aXpccx) {
|
|||
.setThrowOnAsmJSValidationFailure(throwOnAsmJSValidationFailure)
|
||||
.setSourcePragmas(useSourcePragmas)
|
||||
.setAsyncStack(useAsyncStack)
|
||||
.setAsyncStackCaptureDebuggeeOnly(useAsyncStackCaptureDebuggeeOnly)
|
||||
.setThrowOnDebuggeeWouldRun(throwOnDebuggeeWouldRun)
|
||||
.setDumpStackOnDebuggeeWouldRun(dumpStackOnDebuggeeWouldRun);
|
||||
|
||||
|
|
|
@ -43,8 +43,9 @@ function hasExpectedProperties(message, exception) {
|
|||
}
|
||||
|
||||
add_task(async () => {
|
||||
await SpecialPowers.pushPrefEnv({"set": [["javascript.options.asyncstack",
|
||||
true]]});
|
||||
await SpecialPowers.pushPrefEnv({"set": [
|
||||
["javascript.options.asyncstack_capture_debuggee_only", false],
|
||||
]});
|
||||
|
||||
const TESTS = [
|
||||
"abc",
|
||||
|
|
|
@ -1115,17 +1115,12 @@ pref("javascript.options.wasm_reftypes", true);
|
|||
pref("javascript.options.native_regexp", true);
|
||||
pref("javascript.options.parallel_parsing", true);
|
||||
pref("javascript.options.source_pragmas", true);
|
||||
// Async stacks instrumentation adds overhead that is only
|
||||
// advisable for developers, so we limit it to Nightly and DevEdition
|
||||
#if defined(ANDROID) || defined(XP_IOS)
|
||||
pref("javascript.options.asyncstack", false);
|
||||
#else
|
||||
#if defined(NIGHTLY_BUILD) || defined(MOZ_DEV_EDITION)
|
||||
pref("javascript.options.asyncstack", true);
|
||||
#else
|
||||
pref("javascript.options.asyncstack", false);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
pref("javascript.options.asyncstack", true);
|
||||
// Broadly capturing async stack data adds overhead that is only advisable for
|
||||
// developers, so we only enable it when the devtools are open, by default.
|
||||
pref("javascript.options.asyncstack_capture_debuggee_only", true);
|
||||
|
||||
pref("javascript.options.throw_on_asmjs_validation_failure", false);
|
||||
pref("javascript.options.ion.offthread_compilation", true);
|
||||
#ifdef DEBUG
|
||||
|
|
Загрузка…
Ссылка в новой задаче