mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 785493, part 2 - mark XUL protos of live docs black during GC. r=smaug
This commit is contained in:
parent
3072627fad
commit
0654b292c3
@ -10,6 +10,7 @@
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsXULDocument.h"
|
||||
#include "nsIWindowMediator.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
@ -394,30 +395,48 @@ nsCCUncollectableMarker::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
struct TraceClosure
|
||||
{
|
||||
TraceClosure(JSTracer* aTrc, uint32_t aGCNumber)
|
||||
: mTrc(aTrc), mGCNumber(aGCNumber)
|
||||
{}
|
||||
JSTracer* mTrc;
|
||||
uint32_t mGCNumber;
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
TraceActiveWindowGlobal(const uint64_t& aId, nsGlobalWindow*& aWindow, void* aClosure)
|
||||
{
|
||||
if (aWindow->GetDocShell() && aWindow->IsOuterWindow()) {
|
||||
TraceClosure* closure = static_cast<TraceClosure*>(aClosure);
|
||||
if (JSObject* global = aWindow->FastGetGlobalJSObject()) {
|
||||
JSTracer* trc = static_cast<JSTracer *>(aClosure);
|
||||
JS_CALL_OBJECT_TRACER(trc, global, "active window global");
|
||||
JS_CALL_OBJECT_TRACER(closure->mTrc, global, "active window global");
|
||||
}
|
||||
#ifdef MOZ_XUL
|
||||
nsIDocument* doc = aWindow->GetExtantDoc();
|
||||
if (doc && doc->IsXUL()) {
|
||||
nsXULDocument* xulDoc = static_cast<nsXULDocument*>(doc);
|
||||
xulDoc->TraceProtos(closure->mTrc, closure->mGCNumber);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
mozilla::dom::TraceBlackJS(JSTracer* aTrc)
|
||||
mozilla::dom::TraceBlackJS(JSTracer* aTrc, uint32_t aGCNumber)
|
||||
{
|
||||
if (!nsCCUncollectableMarker::sGeneration) {
|
||||
return;
|
||||
}
|
||||
|
||||
TraceClosure closure(aTrc, aGCNumber);
|
||||
|
||||
// Mark globals of active windows black.
|
||||
nsGlobalWindow::WindowByIdTable* windowsById =
|
||||
nsGlobalWindow::GetWindowsTable();
|
||||
if (windowsById) {
|
||||
windowsById->Enumerate(TraceActiveWindowGlobal, aTrc);
|
||||
windowsById->Enumerate(TraceActiveWindowGlobal, &closure);
|
||||
}
|
||||
|
||||
// Mark the safe context black
|
||||
|
@ -45,7 +45,7 @@ private:
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
void TraceBlackJS(JSTracer* aTrc);
|
||||
void TraceBlackJS(JSTracer* aTrc, uint32_t aGCNumber);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2231,6 +2231,22 @@ nsXULPrototypeElement::Unlink()
|
||||
mAttributes = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsXULPrototypeElement::TraceAllScripts(JSTracer* aTrc)
|
||||
{
|
||||
for (uint32_t i = 0; i < mChildren.Length(); ++i) {
|
||||
nsXULPrototypeNode* child = mChildren[i];
|
||||
if (child->mType == nsXULPrototypeNode::eType_Element) {
|
||||
static_cast<nsXULPrototypeElement*>(child)->TraceAllScripts(aTrc);
|
||||
} else if (child->mType == nsXULPrototypeNode::eType_Script) {
|
||||
JSScript* script = static_cast<nsXULPrototypeScript*>(child)->GetScriptObject();
|
||||
if (script) {
|
||||
JS_CALL_SCRIPT_TRACER(aTrc, script, "active window XUL prototype script");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
// nsXULPrototypeScript
|
||||
|
@ -186,6 +186,9 @@ public:
|
||||
|
||||
void Unlink();
|
||||
|
||||
// Trace all scripts held by this element and its children.
|
||||
void TraceAllScripts(JSTracer* aTrc);
|
||||
|
||||
nsPrototypeArray mChildren;
|
||||
|
||||
nsCOMPtr<nsINodeInfo> mNodeInfo; // [OWNER]
|
||||
|
@ -2221,6 +2221,15 @@ nsXULDocument::ApplyPersistentAttributesToElements(nsIRDFResource* aResource,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsXULDocument::TraceProtos(JSTracer* aTrc, uint32_t aGCNumber)
|
||||
{
|
||||
uint32_t i, count = mPrototypes.Length();
|
||||
for (i = 0; i < count; ++i) {
|
||||
mPrototypes[i]->TraceProtos(aTrc, aGCNumber);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
// nsXULDocument::ContextStack
|
||||
|
@ -40,8 +40,9 @@ class nsIXULPrototypeScript;
|
||||
#endif
|
||||
#include "nsURIHashKey.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
|
||||
|
||||
struct JSObject;
|
||||
struct JSTracer;
|
||||
struct PRLogModuleInfo;
|
||||
|
||||
class nsRefMapEntry : public nsStringHashKey
|
||||
@ -178,6 +179,9 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXULDocument, nsXMLDocument)
|
||||
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
|
||||
void TraceProtos(JSTracer* aTrc, uint32_t aGCNumber);
|
||||
|
||||
protected:
|
||||
// Implementation methods
|
||||
friend nsresult
|
||||
|
@ -127,7 +127,8 @@ JSClass nsXULPDGlobalObject::gSharedGlobalClass = {
|
||||
nsXULPrototypeDocument::nsXULPrototypeDocument()
|
||||
: mRoot(nullptr),
|
||||
mLoaded(false),
|
||||
mCCGeneration(0)
|
||||
mCCGeneration(0),
|
||||
mGCNumber(0)
|
||||
{
|
||||
++gRefCnt;
|
||||
}
|
||||
@ -678,6 +679,18 @@ nsXULPrototypeDocument::NotifyLoadDone()
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsXULPrototypeDocument::TraceProtos(JSTracer* aTrc, uint32_t aGCNumber)
|
||||
{
|
||||
// Only trace the protos once per GC.
|
||||
if (mGCNumber == aGCNumber) {
|
||||
return;
|
||||
}
|
||||
|
||||
mGCNumber = aGCNumber;
|
||||
mRoot->TraceAllScripts(aTrc);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
// nsIScriptGlobalObjectOwner methods
|
||||
|
@ -22,6 +22,7 @@ class nsXULDocument;
|
||||
class nsXULPrototypeElement;
|
||||
class nsXULPrototypePI;
|
||||
class nsXULPDGlobalObject;
|
||||
struct JSTracer;
|
||||
|
||||
/**
|
||||
* A "prototype" document that stores shared document information
|
||||
@ -118,6 +119,8 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXULPrototypeDocument,
|
||||
nsIScriptGlobalObjectOwner)
|
||||
|
||||
void TraceProtos(JSTracer* aTrc, uint32_t aGCNumber);
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsRefPtr<nsXULPrototypeElement> mRoot;
|
||||
@ -132,6 +135,7 @@ protected:
|
||||
nsRefPtr<nsNodeInfoManager> mNodeInfoManager;
|
||||
|
||||
uint32_t mCCGeneration;
|
||||
uint32_t mGCNumber;
|
||||
|
||||
nsXULPrototypeDocument();
|
||||
virtual ~nsXULPrototypeDocument();
|
||||
|
@ -322,8 +322,7 @@ void XPCJSRuntime::TraceBlackJS(JSTracer* trc, void* data)
|
||||
static_cast<XPCJSObjectHolder*>(e)->TraceJS(trc);
|
||||
}
|
||||
|
||||
dom::TraceBlackJS(trc);
|
||||
|
||||
dom::TraceBlackJS(trc, JS_GetGCParameter(self->GetJSRuntime(), JSGC_NUMBER));
|
||||
}
|
||||
|
||||
// static
|
||||
|
Loading…
Reference in New Issue
Block a user