Bug 753517 part 2. Make all CSS declarations wrappercached and make them correctly handle preserved wrappers. r=mccr8,peterv,smaug,dbaron

This commit is contained in:
Boris Zbarsky 2012-08-05 22:16:30 -04:00
parent c4ec20c33e
commit faa7bcc004
9 changed files with 127 additions and 56 deletions

View File

@ -10181,11 +10181,11 @@ NS_IMETHODIMP
nsCSSStyleDeclSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
JSObject *globalObj, JSObject **parentObj)
{
#ifdef DEBUG
nsWrapperCache* cache = nullptr;
CallQueryInterface(nativeObj, &cache);
if (!cache) {
return nsDOMClassInfo::PreCreate(nativeObj, cx, globalObj, parentObj);
}
MOZ_ASSERT(cache, "All CSS declarations must be wrappercached");
#endif
nsICSSDeclaration *declaration = static_cast<nsICSSDeclaration*>(nativeObj);
nsINode *native_parent = declaration->GetParentObject();

View File

@ -979,9 +979,9 @@ public:
virtual nsIDocument* DocToUpdate();
// Override |AddRef| and |Release| for being a member of
// |DOMCSSStyleRule|.
NS_IMETHOD_(nsrefcnt) AddRef(void);
NS_IMETHOD_(nsrefcnt) Release(void);
// |DOMCSSStyleRule|. Also, we need to forward QI for cycle
// collection things to DOMCSSStyleRule.
NS_DECL_ISUPPORTS_INHERITED
virtual nsINode *GetParentObject()
{
@ -1013,7 +1013,8 @@ public:
DOMCSSStyleRule(StyleRule *aRule);
virtual ~DOMCSSStyleRule();
NS_DECL_ISUPPORTS
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMCSSStyleRule)
NS_DECL_NSIDOMCSSRULE
NS_DECL_NSIDOMCSSSTYLERULE
@ -1058,6 +1059,16 @@ inline css::DOMCSSStyleRule* DOMCSSDeclarationImpl::DomRule()
NS_IMPL_ADDREF_USING_AGGREGATOR(DOMCSSDeclarationImpl, DomRule())
NS_IMPL_RELEASE_USING_AGGREGATOR(DOMCSSDeclarationImpl, DomRule())
NS_INTERFACE_MAP_BEGIN(DOMCSSDeclarationImpl)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
// We forward the cycle collection interfaces to DomRule(), which is
// never null (in fact, we're part of that object!)
if (aIID.Equals(NS_GET_IID(nsCycleCollectionISupports)) ||
aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) {
return DomRule()->QueryInterface(aIID, aInstancePtr);
}
NS_IMPL_QUERY_TAIL_INHERITING(nsDOMCSSDeclaration)
void
DOMCSSDeclarationImpl::DropReference(void)
{
@ -1146,7 +1157,7 @@ DOMCSSStyleRule::~DOMCSSStyleRule()
{
}
NS_INTERFACE_MAP_BEGIN(DOMCSSStyleRule)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMCSSStyleRule)
NS_INTERFACE_MAP_ENTRY(nsICSSStyleRuleDOMWrapper)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
@ -1154,8 +1165,31 @@ NS_INTERFACE_MAP_BEGIN(DOMCSSStyleRule)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSStyleRule)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(DOMCSSStyleRule)
NS_IMPL_RELEASE(DOMCSSStyleRule)
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMCSSStyleRule)
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMCSSStyleRule)
NS_IMPL_CYCLE_COLLECTION_CLASS(DOMCSSStyleRule)
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMCSSStyleRule)
// Trace the wrapper for our declaration. This just expands out
// NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER which we can't use
// directly because the wrapper is on the declaration, not on us.
nsContentUtils::TraceWrapper(tmp->DOMDeclaration(), aCallback, aClosure);
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMCSSStyleRule)
// Unlink the wrapper for our declaraton. This just expands out
// NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER which we can't use
// directly because the wrapper is on the declaration, not on us.
nsContentUtils::ReleaseWrapper(s, tmp->DOMDeclaration());
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMCSSStyleRule)
// Just NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS here: that will call
// into our Trace hook, where we do the right thing with declarations
// already.
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMETHODIMP
DOMCSSStyleRule::GetType(PRUint16* aType)

View File

@ -1368,9 +1368,16 @@ DOMCI_DATA(CSSFontFaceStyleDecl, nsCSSFontFaceStyleDecl)
// QueryInterface implementation for nsCSSFontFaceStyleDecl
NS_INTERFACE_MAP_BEGIN(nsCSSFontFaceStyleDecl)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleDeclaration)
NS_INTERFACE_MAP_ENTRY(nsICSSDeclaration)
NS_INTERFACE_MAP_ENTRY(nsISupports)
// We forward the cycle collection interfaces to ContainingRule(), which is
// never null (in fact, we're part of that object!)
if (aIID.Equals(NS_GET_IID(nsCycleCollectionISupports)) ||
aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) {
return ContainingRule()->QueryInterface(aIID, aInstancePtr);
}
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSFontFaceStyleDecl)
NS_INTERFACE_MAP_END
@ -1611,13 +1618,36 @@ nsCSSFontFaceRule::Clone() const
return clone.forget();
}
NS_IMPL_ADDREF_INHERITED(nsCSSFontFaceRule, Rule)
NS_IMPL_RELEASE_INHERITED(nsCSSFontFaceRule, Rule)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSFontFaceRule)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSFontFaceRule)
NS_IMPL_CYCLE_COLLECTION_CLASS(nsCSSFontFaceRule)
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsCSSFontFaceRule)
// Trace the wrapper for our declaration. This just expands out
// NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER which we can't use
// directly because the wrapper is on the declaration, not on us.
nsContentUtils::TraceWrapper(&tmp->mDecl, aCallback, aClosure);
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCSSFontFaceRule)
// Unlink the wrapper for our declaraton. This just expands out
// NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER which we can't use
// directly because the wrapper is on the declaration, not on us.
nsContentUtils::ReleaseWrapper(s, &tmp->mDecl);
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCSSFontFaceRule)
// Just NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS here: that will call
// into our Trace hook, where we do the right thing with declarations
// already.
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
DOMCI_DATA(CSSFontFaceRule, nsCSSFontFaceRule)
// QueryInterface implementation for nsCSSFontFaceRule
NS_INTERFACE_MAP_BEGIN(nsCSSFontFaceRule)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSFontFaceRule)
NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSFontFaceRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
@ -1756,8 +1786,14 @@ nsCSSKeyframeStyleDeclaration::~nsCSSKeyframeStyleDeclaration()
NS_ASSERTION(!mRule, "DropReference not called.");
}
NS_IMPL_ADDREF(nsCSSKeyframeStyleDeclaration)
NS_IMPL_RELEASE(nsCSSKeyframeStyleDeclaration)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSKeyframeStyleDeclaration)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSKeyframeStyleDeclaration)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(nsCSSKeyframeStyleDeclaration)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSKeyframeStyleDeclaration)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration)
css::Declaration*
nsCSSKeyframeStyleDeclaration::GetCSSDeclaration(bool aAllocate)

View File

@ -160,7 +160,7 @@ class nsCSSFontFaceRule;
class nsCSSFontFaceStyleDecl : public nsICSSDeclaration
{
public:
NS_DECL_ISUPPORTS
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIDOMCSSSTYLEDECLARATION
NS_DECL_NSICSSDECLARATION
@ -196,7 +196,9 @@ public:
// copy everything except our reference count
: mozilla::css::Rule(aCopy), mDecl(aCopy.mDecl) {}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsCSSFontFaceRule,
mozilla::css::Rule)
// nsIStyleRule methods
#ifdef DEBUG
@ -304,15 +306,13 @@ public:
virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv);
virtual nsIDocument* DocToUpdate();
NS_IMETHOD_(nsrefcnt) AddRef();
NS_IMETHOD_(nsrefcnt) Release();
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsCSSKeyframeStyleDeclaration,
nsICSSDeclaration)
virtual nsINode* GetParentObject();
protected:
nsAutoRefCnt mRefCnt;
NS_DECL_OWNINGTHREAD
// This reference is not reference-counted. The rule object tells us
// when it's about to go away.
nsCSSKeyframeRule *mRule;

View File

@ -149,30 +149,23 @@ nsComputedDOMStyle::Shutdown()
}
// If nsComputedDOMStyle is changed so that any additional fields are
// traversed by the cycle collector (for instance, if wrapper cache
// handling is changed) then CAN_SKIP must be updated.
NS_IMPL_CYCLE_COLLECTION_1(nsComputedDOMStyle, mContent)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(nsComputedDOMStyle, mContent)
// nsComputedDOMStyle has only one cycle collected field, so if
// mContent is going to be skipped, the style isn't part of a garbage
// cycle.
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsComputedDOMStyle)
return !tmp->mContent || nsGenericElement::CanSkip(tmp->mContent, true);
return tmp->IsBlack();
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsComputedDOMStyle)
return !tmp->mContent || nsGenericElement::CanSkipInCC(tmp->mContent);
return tmp->IsBlack();
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
// CanSkipThis returns false to avoid problems with incomplete unlinking.
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsComputedDOMStyle)
return tmp->IsBlack();
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
// QueryInterface implementation for nsComputedDOMStyle
NS_INTERFACE_MAP_BEGIN(nsComputedDOMStyle)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsComputedDOMStyle)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsComputedDOMStyle)
NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration)

View File

@ -24,13 +24,12 @@
class nsIPresShell;
class nsComputedDOMStyle : public nsDOMCSSDeclaration,
public nsWrapperCache
class nsComputedDOMStyle : public nsDOMCSSDeclaration
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_CLASS_AMBIGUOUS(nsComputedDOMStyle,
nsICSSDeclaration)
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsComputedDOMStyle,
nsICSSDeclaration)
NS_DECL_NSICSSDECLARATION

View File

@ -17,6 +17,8 @@
#include "nsIURI.h"
#include "nsNodeUtils.h"
#include "nsGenericElement.h"
#include "nsContentUtils.h"
#include "xpcpublic.h"
namespace css = mozilla::css;
namespace dom = mozilla::dom;
@ -36,29 +38,36 @@ nsDOMCSSAttributeDeclaration::~nsDOMCSSAttributeDeclaration()
MOZ_COUNT_DTOR(nsDOMCSSAttributeDeclaration);
}
// If nsDOMCSSAttributeDeclaration is changed so that any additional
// fields are traversed by the cycle collector (for instance, if
// wrapper cache handling is changed) then CAN_SKIP must be updated.
NS_IMPL_CYCLE_COLLECTION_1(nsDOMCSSAttributeDeclaration, mElement)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(nsDOMCSSAttributeDeclaration, mElement)
// nsDOMCSSAttributeDeclaration has only one cycle collected field, so
// if mElement is going to be skipped, the attribute declaration can't
// be part of a garbage cycle.
// mElement holds a strong ref to us, so if it's going to be
// skipped, the attribute declaration can't be part of a garbage
// cycle.
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsDOMCSSAttributeDeclaration)
return !tmp->mElement || nsGenericElement::CanSkip(tmp->mElement, true);
if (tmp->mElement && nsGenericElement::CanSkip(tmp->mElement, true)) {
if (tmp->PreservingWrapper()) {
// Not relying on GetWrapper to unmark us gray because the
// side-effect thing is pretty weird.
JSObject* o = tmp->GetWrapperPreserveColor();
xpc_UnmarkGrayObject(o);
}
return true;
}
return tmp->IsBlack();
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsDOMCSSAttributeDeclaration)
return !tmp->mElement || nsGenericElement::CanSkipInCC(tmp->mElement);
return tmp->IsBlack() ||
(tmp->mElement && nsGenericElement::CanSkipInCC(tmp->mElement));
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
// CanSkipThis returns false to avoid problems with incomplete unlinking.
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsDOMCSSAttributeDeclaration)
return tmp->IsBlack() ||
(tmp->mElement && nsGenericElement::CanSkipThis(tmp->mElement));
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
NS_INTERFACE_MAP_BEGIN(nsDOMCSSAttributeDeclaration)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMCSSAttributeDeclaration)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsDOMCSSAttributeDeclaration)
NS_IMPL_QUERY_TAIL_INHERITING(nsDOMCSSDeclaration)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMCSSAttributeDeclaration)

View File

@ -12,7 +12,6 @@
#include "nsAutoPtr.h"
#include "nsString.h"
#include "nsWrapperCache.h"
namespace mozilla {
namespace css {
@ -24,8 +23,7 @@ class Element;
}
}
class nsDOMCSSAttributeDeclaration : public nsDOMCSSDeclaration,
public nsWrapperCache
class nsDOMCSSAttributeDeclaration : public nsDOMCSSDeclaration
{
public:
typedef mozilla::dom::Element Element;
@ -33,8 +31,8 @@ public:
~nsDOMCSSAttributeDeclaration();
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_CLASS_AMBIGUOUS(nsDOMCSSAttributeDeclaration,
nsICSSDeclaration)
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDOMCSSAttributeDeclaration,
nsICSSDeclaration)
// If GetCSSDeclaration returns non-null, then the decl it returns
// is owned by our current style rule.

View File

@ -21,6 +21,7 @@
#include "nsIDOMCSSStyleDeclaration.h"
#include "nsCSSProperty.h"
#include "nsWrapperCache.h"
// 57eb81d1-a607-4429-926b-802519d43aad
#define NS_ICSSDECLARATION_IID \
@ -29,7 +30,8 @@
class nsINode;
class nsICSSDeclaration : public nsIDOMCSSStyleDeclaration
class nsICSSDeclaration : public nsIDOMCSSStyleDeclaration,
public nsWrapperCache
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICSSDECLARATION_IID)