Backed out changeset b1fe3750580d (bug 1471989) for build bustages on a CLOSED TREE

This commit is contained in:
Andreea Pavel 2018-12-19 20:48:10 +02:00
Родитель 017a925896
Коммит f9260c6914
8 изменённых файлов: 3 добавлений и 164 удалений

Просмотреть файл

@ -109,9 +109,6 @@ WindowDestroyedEvent::Run() {
JS::Rooted<JSObject*> obj(cx, currentInner->FastGetGlobalJSObject());
if (obj && !js::IsSystemRealm(js::GetNonCCWObjectRealm(obj))) {
JS::Realm* realm = js::GetNonCCWObjectRealm(obj);
xpc::NukeJSStackFrames(realm);
nsCOMPtr<nsIPrincipal> pc =
nsJSPrincipals::get(JS::GetRealmPrincipals(realm));

Просмотреть файл

@ -10,7 +10,6 @@
#include "js/TypeDecls.h"
#include "jsapi.h"
#include "js/SavedFrameAPI.h"
#include "xpcpublic.h"
#include "mozilla/CycleCollectedJSContext.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/DOMException.h"
@ -198,7 +197,7 @@ already_AddRefed<nsIStackFrame> GetCurrentJSStack(int32_t aMaxDepth) {
namespace exceptions {
class JSStackFrame final : public nsIStackFrame, public xpc::JSStackFrameBase {
class JSStackFrame : public nsIStackFrame {
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(JSStackFrame)
@ -210,12 +209,6 @@ class JSStackFrame final : public nsIStackFrame, public xpc::JSStackFrameBase {
private:
virtual ~JSStackFrame();
void Clear() override { mStack = nullptr; }
// Remove this frame from the per-realm list of live frames,
// and clear out the stack pointer.
void UnregisterAndClear();
JS::Heap<JSObject*> mStack;
nsString mFormattedStack;
@ -253,29 +246,15 @@ JSStackFrame::JSStackFrame(JS::Handle<JSObject*> aStack)
MOZ_ASSERT(JS::IsUnwrappedSavedFrame(mStack));
mozilla::HoldJSObjects(this);
xpc::RegisterJSStackFrame(js::GetNonCCWObjectRealm(aStack), this);
}
JSStackFrame::~JSStackFrame() {
UnregisterAndClear();
mozilla::DropJSObjects(this);
}
void JSStackFrame::UnregisterAndClear() {
if (!mStack) {
return;
}
xpc::UnregisterJSStackFrame(js::GetNonCCWObjectRealm(mStack), this);
Clear();
}
JSStackFrame::~JSStackFrame() { mozilla::DropJSObjects(this); }
NS_IMPL_CYCLE_COLLECTION_CLASS(JSStackFrame)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(JSStackFrame)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCaller)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAsyncCaller)
tmp->UnregisterAndClear();
tmp->mStack = nullptr;
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(JSStackFrame)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCaller)

Просмотреть файл

@ -382,51 +382,6 @@ static bool PrincipalImmuneToScriptPolicy(nsIPrincipal* aPrincipal) {
return false;
}
void RealmPrivate::RegisterStackFrame(JSStackFrameBase* aFrame) {
mJSStackFrames.PutEntry(aFrame);
}
void RealmPrivate::UnregisterStackFrame(JSStackFrameBase* aFrame) {
mJSStackFrames.RemoveEntry(aFrame);
}
void RealmPrivate::NukeJSStackFrames() {
for (auto iter = mJSStackFrames.Iter(); !iter.Done(); iter.Next()) {
iter.Get()->GetKey()->Clear();
}
mJSStackFrames.Clear();
}
void xpc::RegisterJSStackFrame(JS::Realm* aRealm,
JSStackFrameBase* aStackFrame) {
RealmPrivate* realmPrivate = RealmPrivate::Get(aRealm);
if (!realmPrivate) {
return;
}
realmPrivate->RegisterStackFrame(aStackFrame);
}
void xpc::UnregisterJSStackFrame(JS::Realm* aRealm,
JSStackFrameBase* aStackFrame) {
RealmPrivate* realmPrivate = RealmPrivate::Get(aRealm);
if (!realmPrivate) {
return;
}
realmPrivate->UnregisterStackFrame(aStackFrame);
}
void xpc::NukeJSStackFrames(JS::Realm* aRealm) {
RealmPrivate* realmPrivate = RealmPrivate::Get(aRealm);
if (!realmPrivate) {
return;
}
realmPrivate->NukeJSStackFrames();
}
Scriptability::Scriptability(JS::Realm* realm)
: mScriptBlocks(0),
mDocShellAllowsScript(true),

Просмотреть файл

@ -2915,19 +2915,11 @@ class RealmPrivate {
locationURI = aLocationURI;
}
// JSStackFrames are tracked on a per-realm basis so they
// can be cleared when the associated window goes away.
void RegisterStackFrame(JSStackFrameBase* aFrame);
void UnregisterStackFrame(JSStackFrameBase* aFrame);
void NukeJSStackFrames();
private:
nsCString location;
nsCOMPtr<nsIURI> locationURI;
bool TryParseLocationURI(LocationHint aType, nsIURI** aURI);
nsTHashtable<nsPtrHashKey<JSStackFrameBase>> mJSStackFrames;
};
inline XPCWrappedNativeScope* ObjectScope(JSObject* obj) {

Просмотреть файл

@ -714,15 +714,6 @@ bool IfaceID2JSValue(JSContext* aCx, const nsXPTInterfaceInfo& aInfo,
bool ContractID2JSValue(JSContext* aCx, JSString* aContract,
JS::MutableHandleValue aVal);
class JSStackFrameBase {
public:
virtual void Clear() = 0;
};
void RegisterJSStackFrame(JS::Realm* aRealm, JSStackFrameBase* aStackFrame);
void UnregisterJSStackFrame(JS::Realm* aRealm, JSStackFrameBase* aStackFrame);
void NukeJSStackFrames(JS::Realm* aRealm);
} // namespace xpc
namespace mozilla {

Просмотреть файл

@ -1,6 +1,4 @@
[DEFAULT]
support-files =
browser_consoleStack.html
browser_deadObjectOnUnload.html
[browser_dead_object.js]
[browser_exception_leak.js]

Просмотреть файл

@ -1,21 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
Test page for https://bugzilla.mozilla.org/show_bug.cgi?id=1471989
-->
<head>
<meta charset="utf-8">
<title>Test page for Bug 1471989</title>
</head>
<body onUnload="onUnload();">
<p><span id="samplepage">sample page</span></p>
<script type="application/javascript">
// Get something sent to ConsoleStorageAPI that has a stack.
console.trace("whatever");
function onUnload() {
console.log('in unload');
}
</script>
</body>
</html>

Просмотреть файл

@ -1,52 +0,0 @@
/* 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/.
*/
// For bug 1471989, test that an exception saved by chrome code can't leak the page.
add_task(async function test() {
const url = "http://mochi.test:8888/browser/js/xpconnect/tests/browser/browser_consoleStack.html";
let newTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
let browser = gBrowser.selectedBrowser;
let innerWindowId = browser.innerWindowID;
let stackTraceEmpty = await ContentTask.spawn(browser, {innerWindowId}, async function(args) {
let {TestUtils} = ChromeUtils.import("resource://testing-common/TestUtils.jsm", {});
let {Assert} = ChromeUtils.import("resource://testing-common/Assert.jsm", {});
const ConsoleAPIStorage = Cc["@mozilla.org/consoleAPI-storage;1"].getService(Ci.nsIConsoleAPIStorage);
let consoleEvents = ConsoleAPIStorage.getEvents(args.innerWindowId);
Assert.equal(consoleEvents.length, 1, "Should only be one console event for the window");
// Intentionally hold a reference to the console event.
let leakedConsoleEvent = consoleEvents[0];
let doc = content.document;
let promise = TestUtils.topicObserved("inner-window-nuked", (subject, data) => {
let id = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
return id == args.innerWindowId;
});
content.location = "http://example.org/";
await promise;
// This string should be empty. For that to happen, two things
// need to be true:
//
// a) ConsoleCallData::mStack is not null. This means that the
// stack trace was not reified before the page was nuked. If it
// was, then the correct |filename| value would be stored on the
// object. (This is not a problem, except that it stops us from
// testing the next condition.)
//
// b) ConsoleData::mStack.mStack is null. This means that the
// JSStackFrame is keeping alive the JS object in the page after
// the page was nuked, which leaks the page.
return leakedConsoleEvent.stacktrace[0].filename;
});
is(stackTraceEmpty, "",
"JSStackFrame shouldn't leak mStack after window nuking");
BrowserTestUtils.removeTab(newTab);
});