author | Tooru Fujisawa <arai_a@mac.com> |
Tue, 17 Apr 2018 14:59:57 +0200 | |
changeset 414101 | e66e4b3ee60f04411e0df5d446794d4166c3ba80 |
parent 414100 | f054209125461575f57ce0f1e6b962653c523572 |
child 414102 | 7674892ac2302b03c75cae1174bff06bffe280ea |
push id | 33858 |
push user | ncsoregi@mozilla.com |
push date | Tue, 17 Apr 2018 21:55:44 +0000 |
treeherder | mozilla-central@d6eb5597d744 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | till |
bugs | 1342070 |
milestone | 61.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/builtin/Promise.cpp +++ b/js/src/builtin/Promise.cpp @@ -3049,21 +3049,49 @@ Promise_catch_impl(JSContext* cx, unsign FixedInvokeArgs<2> iargs(cx); iargs[0].setUndefined(); iargs[1].set(args.get(0)); return Call(cx, thenVal, args.thisv(), iargs, args.rval()); } +static MOZ_ALWAYS_INLINE bool +IsPromiseThenOrCatchRetValImplicitlyUsed(JSContext* cx) +{ + // The returned promise of Promise#then and Promise#catch contains + // stack info if async stack is enabled. Even if their return value is not + // 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; + + // If devtools is opened, the current compartment will become debuggee. + if (cx->compartment()->isDebuggee()) + return true; + + // There are 2 profilers, and they can be independently enabled. + if (cx->runtime()->geckoProfiler().enabled()) + return true; + if (JS::IsProfileTimelineRecordingEnabled()) + return true; + + // The stack is also observable from Error#stack, but we don't care since + // it's nonstandard feature. + return false; +} + // ES2016, 25.4.5.3. static bool Promise_catch_noRetVal(JSContext* cx, unsigned argc, Value* vp) { - return Promise_catch_impl(cx, argc, vp, false); + return Promise_catch_impl(cx, argc, vp, IsPromiseThenOrCatchRetValImplicitlyUsed(cx)); } // ES2016, 25.4.5.3. static bool Promise_catch(JSContext* cx, unsigned argc, Value* vp) { return Promise_catch_impl(cx, argc, vp, true); } @@ -3117,17 +3145,18 @@ Promise_then_impl(JSContext* cx, HandleV return true; } // ES2016, 25.4.5.3. bool Promise_then_noRetVal(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); - return Promise_then_impl(cx, args.thisv(), args.get(0), args.get(1), args.rval(), false); + return Promise_then_impl(cx, args.thisv(), args.get(0), args.get(1), args.rval(), + IsPromiseThenOrCatchRetValImplicitlyUsed(cx)); } // ES2016, 25.4.5.3. static bool Promise_then(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); return Promise_then_impl(cx, args.thisv(), args.get(0), args.get(1), args.rval(), true);