Commit 2408dde5 authored by ager@chromium.org's avatar ager@chromium.org

Move StyleSheet to the oilpan heap using transition types.

This makes StyleSheets RefCountedGarbageCollected. Next step is
removing RefPtrs and raw pointers and dealing with finalization
order issues.

R=erik.corry@gmail.com, haraken@chromium.org, wibling@chromium.org
BUG=

Review URL: https://codereview.chromium.org/187313005

git-svn-id: svn://svn.chromium.org/blink/trunk@168583 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent b8baaeb5
...@@ -4,5 +4,6 @@ ...@@ -4,5 +4,6 @@
# With Oilpan, the parent pointer in the CSSRule hierarchy is # With Oilpan, the parent pointer in the CSSRule hierarchy is
# strong. This is the intended behavior. # strong. This is the intended behavior.
crbug.com/345630 fast/dom/StyleSheet/gc-parent-rule.html [ Failure ] crbug.com/345630 fast/dom/StyleSheet/gc-parent-rule.html [ Failure ]
crbug.com/345630 fast/dom/StyleSheet/gc-parent-stylesheet.html [ Failure ]
crbug.com/345655 fast/dom/StyleSheet/detached-parent-rule-without-wrapper.html [ Failure ] crbug.com/345655 fast/dom/StyleSheet/detached-parent-rule-without-wrapper.html [ Failure ]
crbug.com/345655 fast/dom/StyleSheet/detached-stylesheet-without-wrapper.html [ Failure ]
...@@ -84,8 +84,8 @@ void CSSFilterRule::reattach(StyleRuleBase* rule) ...@@ -84,8 +84,8 @@ void CSSFilterRule::reattach(StyleRuleBase* rule)
void CSSFilterRule::trace(Visitor* visitor) void CSSFilterRule::trace(Visitor* visitor)
{ {
CSSRule::trace(visitor);
visitor->trace(m_filterRule); visitor->trace(m_filterRule);
CSSRule::trace(visitor);
} }
} // namespace WebCore } // namespace WebCore
......
...@@ -57,6 +57,8 @@ void CSSRule::trace(Visitor* visitor) ...@@ -57,6 +57,8 @@ void CSSRule::trace(Visitor* visitor)
// some circumstances. // some circumstances.
if (m_parentIsRule) if (m_parentIsRule)
visitor->trace(m_parentRule); visitor->trace(m_parentRule);
else
visitor->trace(m_parentStyleSheet);
} }
} // namespace WebCore } // namespace WebCore
...@@ -108,8 +108,9 @@ private: ...@@ -108,8 +108,9 @@ private:
mutable unsigned char m_hasCachedSelectorText : 1; mutable unsigned char m_hasCachedSelectorText : 1;
unsigned char m_parentIsRule : 1; unsigned char m_parentIsRule : 1;
// These should be Members, but no Members in unions.
union { union {
CSSRule* m_parentRule; // Should be Member, but no Members in unions. CSSRule* m_parentRule;
CSSStyleSheet* m_parentStyleSheet; CSSStyleSheet* m_parentStyleSheet;
}; };
}; };
......
...@@ -71,27 +71,27 @@ static bool isAcceptableCSSStyleSheetParent(Node* parentNode) ...@@ -71,27 +71,27 @@ static bool isAcceptableCSSStyleSheetParent(Node* parentNode)
} }
#endif #endif
PassRefPtr<CSSStyleSheet> CSSStyleSheet::create(PassRefPtrWillBeRawPtr<StyleSheetContents> sheet, CSSImportRule* ownerRule) PassRefPtrWillBeRawPtr<CSSStyleSheet> CSSStyleSheet::create(PassRefPtrWillBeRawPtr<StyleSheetContents> sheet, CSSImportRule* ownerRule)
{ {
return adoptRef(new CSSStyleSheet(sheet, ownerRule)); return adoptRefWillBeRefCountedGarbageCollected(new CSSStyleSheet(sheet, ownerRule));
} }
PassRefPtr<CSSStyleSheet> CSSStyleSheet::create(PassRefPtrWillBeRawPtr<StyleSheetContents> sheet, Node* ownerNode) PassRefPtrWillBeRawPtr<CSSStyleSheet> CSSStyleSheet::create(PassRefPtrWillBeRawPtr<StyleSheetContents> sheet, Node* ownerNode)
{ {
return adoptRef(new CSSStyleSheet(sheet, ownerNode, false, TextPosition::minimumPosition())); return adoptRefWillBeRefCountedGarbageCollected(new CSSStyleSheet(sheet, ownerNode, false, TextPosition::minimumPosition()));
} }
PassRefPtr<CSSStyleSheet> CSSStyleSheet::createInline(PassRefPtrWillBeRawPtr<StyleSheetContents> sheet, Node* ownerNode, const TextPosition& startPosition) PassRefPtrWillBeRawPtr<CSSStyleSheet> CSSStyleSheet::createInline(PassRefPtrWillBeRawPtr<StyleSheetContents> sheet, Node* ownerNode, const TextPosition& startPosition)
{ {
ASSERT(sheet); ASSERT(sheet);
return adoptRef(new CSSStyleSheet(sheet, ownerNode, true, startPosition)); return adoptRefWillBeRefCountedGarbageCollected(new CSSStyleSheet(sheet, ownerNode, true, startPosition));
} }
PassRefPtr<CSSStyleSheet> CSSStyleSheet::createInline(Node* ownerNode, const KURL& baseURL, const TextPosition& startPosition, const String& encoding) PassRefPtrWillBeRawPtr<CSSStyleSheet> CSSStyleSheet::createInline(Node* ownerNode, const KURL& baseURL, const TextPosition& startPosition, const String& encoding)
{ {
CSSParserContext parserContext(ownerNode->document(), 0, baseURL, encoding); CSSParserContext parserContext(ownerNode->document(), 0, baseURL, encoding);
RefPtrWillBeRawPtr<StyleSheetContents> sheet = StyleSheetContents::create(baseURL.string(), parserContext); RefPtrWillBeRawPtr<StyleSheetContents> sheet = StyleSheetContents::create(baseURL.string(), parserContext);
return adoptRef(new CSSStyleSheet(sheet.release(), ownerNode, true, startPosition)); return adoptRefWillBeRefCountedGarbageCollected(new CSSStyleSheet(sheet.release(), ownerNode, true, startPosition));
} }
CSSStyleSheet::CSSStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> contents, CSSImportRule* ownerRule) CSSStyleSheet::CSSStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> contents, CSSImportRule* ownerRule)
...@@ -111,7 +111,7 @@ CSSStyleSheet::CSSStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> contents ...@@ -111,7 +111,7 @@ CSSStyleSheet::CSSStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> contents
, m_isInlineStylesheet(isInlineStylesheet) , m_isInlineStylesheet(isInlineStylesheet)
, m_isDisabled(false) , m_isDisabled(false)
, m_ownerNode(ownerNode) , m_ownerNode(ownerNode)
, m_ownerRule(0) , m_ownerRule(nullptr)
, m_startPosition(startPosition) , m_startPosition(startPosition)
, m_loadCompleted(false) , m_loadCompleted(false)
{ {
...@@ -121,6 +121,11 @@ CSSStyleSheet::CSSStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> contents ...@@ -121,6 +121,11 @@ CSSStyleSheet::CSSStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> contents
CSSStyleSheet::~CSSStyleSheet() CSSStyleSheet::~CSSStyleSheet()
{ {
// With oilpan the parent style sheet pointer is strong and the sheet and
// its RuleCSSOMWrappers die together and we don't need to clear them here.
// Also with oilpan the StyleSheetContents client pointers are weak and
// therefore do not need to be cleared here.
#if !ENABLE(OILPAN)
// For style rules outside the document, .parentStyleSheet can become null even if the style rule // For style rules outside the document, .parentStyleSheet can become null even if the style rule
// is still observable from JavaScript. This matches the behavior of .parentNode for nodes, but // is still observable from JavaScript. This matches the behavior of .parentNode for nodes, but
// it's not ideal because it makes the CSSOM's behavior depend on the timing of garbage collection. // it's not ideal because it makes the CSSOM's behavior depend on the timing of garbage collection.
...@@ -133,6 +138,7 @@ CSSStyleSheet::~CSSStyleSheet() ...@@ -133,6 +138,7 @@ CSSStyleSheet::~CSSStyleSheet()
m_mediaCSSOMWrapper->clearParentStyleSheet(); m_mediaCSSOMWrapper->clearParentStyleSheet();
m_contents->unregisterClient(this); m_contents->unregisterClient(this);
#endif
} }
void CSSStyleSheet::willMutateRules() void CSSStyleSheet::willMutateRules()
...@@ -406,4 +412,13 @@ void CSSStyleSheet::startLoadingDynamicSheet() ...@@ -406,4 +412,13 @@ void CSSStyleSheet::startLoadingDynamicSheet()
m_ownerNode->startLoadingDynamicSheet(); m_ownerNode->startLoadingDynamicSheet();
} }
void CSSStyleSheet::trace(Visitor* visitor)
{
visitor->trace(m_contents);
visitor->trace(m_mediaQueries);
visitor->trace(m_ownerRule);
visitor->trace(m_mediaCSSOMWrapper);
visitor->trace(m_childRuleCSSOMWrappers);
}
} }
...@@ -49,10 +49,10 @@ enum StyleSheetUpdateType { ...@@ -49,10 +49,10 @@ enum StyleSheetUpdateType {
class CSSStyleSheet FINAL : public StyleSheet { class CSSStyleSheet FINAL : public StyleSheet {
public: public:
static PassRefPtr<CSSStyleSheet> create(PassRefPtrWillBeRawPtr<StyleSheetContents>, CSSImportRule* ownerRule = 0); static PassRefPtrWillBeRawPtr<CSSStyleSheet> create(PassRefPtrWillBeRawPtr<StyleSheetContents>, CSSImportRule* ownerRule = 0);
static PassRefPtr<CSSStyleSheet> create(PassRefPtrWillBeRawPtr<StyleSheetContents>, Node* ownerNode); static PassRefPtrWillBeRawPtr<CSSStyleSheet> create(PassRefPtrWillBeRawPtr<StyleSheetContents>, Node* ownerNode);
static PassRefPtr<CSSStyleSheet> createInline(Node*, const KURL&, const TextPosition& startPosition = TextPosition::minimumPosition(), const String& encoding = String()); static PassRefPtrWillBeRawPtr<CSSStyleSheet> createInline(Node*, const KURL&, const TextPosition& startPosition = TextPosition::minimumPosition(), const String& encoding = String());
static PassRefPtr<CSSStyleSheet> createInline(PassRefPtrWillBeRawPtr<StyleSheetContents>, Node* ownerNode, const TextPosition& startPosition = TextPosition::minimumPosition()); static PassRefPtrWillBeRawPtr<CSSStyleSheet> createInline(PassRefPtrWillBeRawPtr<StyleSheetContents>, Node* ownerNode, const TextPosition& startPosition = TextPosition::minimumPosition());
virtual ~CSSStyleSheet(); virtual ~CSSStyleSheet();
...@@ -84,7 +84,7 @@ public: ...@@ -84,7 +84,7 @@ public:
virtual KURL baseURL() const OVERRIDE; virtual KURL baseURL() const OVERRIDE;
virtual bool isLoading() const OVERRIDE; virtual bool isLoading() const OVERRIDE;
void clearOwnerRule() { m_ownerRule = 0; } void clearOwnerRule() { m_ownerRule = nullptr; }
Document* ownerDocument() const; Document* ownerDocument() const;
MediaQuerySet* mediaQueries() const { return m_mediaQueries.get(); } MediaQuerySet* mediaQueries() const { return m_mediaQueries.get(); }
void setMediaQueries(PassRefPtrWillBeRawPtr<MediaQuerySet>); void setMediaQueries(PassRefPtrWillBeRawPtr<MediaQuerySet>);
...@@ -116,6 +116,8 @@ public: ...@@ -116,6 +116,8 @@ public:
bool loadCompleted() const { return m_loadCompleted; } bool loadCompleted() const { return m_loadCompleted; }
void startLoadingDynamicSheet(); void startLoadingDynamicSheet();
virtual void trace(Visitor*) OVERRIDE;
private: private:
CSSStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents>, CSSImportRule* ownerRule); CSSStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents>, CSSImportRule* ownerRule);
CSSStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents>, Node* ownerNode, bool isInlineStylesheet, const TextPosition& startPosition); CSSStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents>, Node* ownerNode, bool isInlineStylesheet, const TextPosition& startPosition);
...@@ -127,28 +129,20 @@ private: ...@@ -127,28 +129,20 @@ private:
bool canAccessRules() const; bool canAccessRules() const;
RefPtrWillBePersistent<StyleSheetContents> m_contents; RefPtrWillBeMember<StyleSheetContents> m_contents;
bool m_isInlineStylesheet; bool m_isInlineStylesheet;
bool m_isDisabled; bool m_isDisabled;
String m_title; String m_title;
RefPtrWillBePersistent<MediaQuerySet> m_mediaQueries; RefPtrWillBeMember<MediaQuerySet> m_mediaQueries;
Node* m_ownerNode; Node* m_ownerNode;
// FIXME: oilpan: This is a back pointer from CSSImportRule, corresponding RawPtrWillBeMember<CSSRule> m_ownerRule;
// to the forward pointer on that, called m_styleSheetCSSOMWrapper. (It is
// not related to the m_parentStyleSheet pointer which is also typed as
// CSSStyleSheet, and which is inherited by CSSImportRule from CSSRule).
// Since m_styleSheetCSSOMWrapper is a RefPtr we know that this object
// cannot die before the CSSImportRule is destructed, which makes it OK to
// clear this from ~CSSImportRule. When this is on the GC heap we can make
// this a regular Member.
CSSRule* m_ownerRule;
TextPosition m_startPosition; TextPosition m_startPosition;
bool m_loadCompleted; bool m_loadCompleted;
mutable RefPtrWillBePersistent<MediaList> m_mediaCSSOMWrapper; mutable RefPtrWillBeMember<MediaList> m_mediaCSSOMWrapper;
mutable WillBePersistentHeapVector<RefPtrWillBeMember<CSSRule> > m_childRuleCSSOMWrappers; mutable WillBeHeapVector<RefPtrWillBeMember<CSSRule> > m_childRuleCSSOMWrappers;
mutable OwnPtr<CSSRuleList> m_ruleListCSSOMWrapper; mutable OwnPtr<CSSRuleList> m_ruleListCSSOMWrapper;
}; };
......
...@@ -176,7 +176,7 @@ MediaList::MediaList(MediaQuerySet* mediaQueries, CSSStyleSheet* parentSheet) ...@@ -176,7 +176,7 @@ MediaList::MediaList(MediaQuerySet* mediaQueries, CSSStyleSheet* parentSheet)
MediaList::MediaList(MediaQuerySet* mediaQueries, CSSRule* parentRule) MediaList::MediaList(MediaQuerySet* mediaQueries, CSSRule* parentRule)
: m_mediaQueries(mediaQueries) : m_mediaQueries(mediaQueries)
, m_parentStyleSheet(0) , m_parentStyleSheet(nullptr)
, m_parentRule(parentRule) , m_parentRule(parentRule)
{ {
} }
...@@ -239,6 +239,7 @@ void MediaList::reattach(MediaQuerySet* mediaQueries) ...@@ -239,6 +239,7 @@ void MediaList::reattach(MediaQuerySet* mediaQueries)
void MediaList::trace(Visitor* visitor) void MediaList::trace(Visitor* visitor)
{ {
visitor->trace(m_mediaQueries); visitor->trace(m_mediaQueries);
visitor->trace(m_parentStyleSheet);
visitor->trace(m_parentRule); visitor->trace(m_parentRule);
} }
......
...@@ -92,8 +92,12 @@ public: ...@@ -92,8 +92,12 @@ public:
// Not part of CSSOM. // Not part of CSSOM.
CSSRule* parentRule() const { return m_parentRule; } CSSRule* parentRule() const { return m_parentRule; }
CSSStyleSheet* parentStyleSheet() const { return m_parentStyleSheet; } CSSStyleSheet* parentStyleSheet() const { return m_parentStyleSheet; }
void clearParentStyleSheet() { ASSERT(m_parentStyleSheet); m_parentStyleSheet = 0; }
#if !ENABLE(OILPAN)
void clearParentStyleSheet() { ASSERT(m_parentStyleSheet); m_parentStyleSheet = nullptr; }
void clearParentRule() { ASSERT(m_parentRule); m_parentRule = nullptr; } void clearParentRule() { ASSERT(m_parentRule); m_parentRule = nullptr; }
#endif
const MediaQuerySet* queries() const { return m_mediaQueries.get(); } const MediaQuerySet* queries() const { return m_mediaQueries.get(); }
void reattach(MediaQuerySet*); void reattach(MediaQuerySet*);
...@@ -106,8 +110,8 @@ private: ...@@ -106,8 +110,8 @@ private:
MediaList(MediaQuerySet*, CSSRule* parentRule); MediaList(MediaQuerySet*, CSSRule* parentRule);
RefPtrWillBeMember<MediaQuerySet> m_mediaQueries; RefPtrWillBeMember<MediaQuerySet> m_mediaQueries;
// Cleared in ~CSSStyleSheet destructor. // Cleared in ~CSSStyleSheet destructor when oilpan is not enabled.
CSSStyleSheet* m_parentStyleSheet; RawPtrWillBeMember<CSSStyleSheet> m_parentStyleSheet;
// Cleared in the ~CSSMediaRule and ~CSSImportRule destructors when oilpan is not enabled. // Cleared in the ~CSSMediaRule and ~CSSImportRule destructors when oilpan is not enabled.
RawPtrWillBeMember<CSSRule> m_parentRule; RawPtrWillBeMember<CSSRule> m_parentRule;
}; };
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#define StyleSheet_h #define StyleSheet_h
#include "core/css/CSSParserMode.h" #include "core/css/CSSParserMode.h"
#include "heap/Handle.h"
#include "wtf/Forward.h" #include "wtf/Forward.h"
#include "wtf/RefCounted.h" #include "wtf/RefCounted.h"
...@@ -33,7 +34,7 @@ class MediaList; ...@@ -33,7 +34,7 @@ class MediaList;
class Node; class Node;
class StyleSheet; class StyleSheet;
class StyleSheet : public RefCounted<StyleSheet> { class StyleSheet : public RefCountedWillBeRefCountedGarbageCollected<StyleSheet> {
public: public:
virtual ~StyleSheet(); virtual ~StyleSheet();
...@@ -51,6 +52,8 @@ public: ...@@ -51,6 +52,8 @@ public:
virtual KURL baseURL() const = 0; virtual KURL baseURL() const = 0;
virtual bool isLoading() const = 0; virtual bool isLoading() const = 0;
virtual bool isCSSStyleSheet() const { return false; } virtual bool isCSSStyleSheet() const { return false; }
virtual void trace(Visitor*) = 0;
}; };
} // namespace } // namespace
......
...@@ -374,8 +374,8 @@ bool StyleSheetContents::loadCompleted() const ...@@ -374,8 +374,8 @@ bool StyleSheetContents::loadCompleted() const
return parentSheet->loadCompleted(); return parentSheet->loadCompleted();
StyleSheetContents* root = rootStyleSheet(); StyleSheetContents* root = rootStyleSheet();
for (unsigned i = 0; i < root->m_clients.size(); ++i) { for (ClientsIterator it = root->m_clients.begin(); it != root->m_clients.end(); ++it) {
if (!root->m_clients[i]->loadCompleted()) if (!(*it)->loadCompleted())
return false; return false;
} }
return true; return true;
...@@ -401,18 +401,25 @@ void StyleSheetContents::checkLoaded() ...@@ -401,18 +401,25 @@ void StyleSheetContents::checkLoaded()
if (root->m_clients.isEmpty()) if (root->m_clients.isEmpty())
return; return;
Vector<CSSStyleSheet*> clients(root->m_clients); // Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that run via
for (unsigned i = 0; i < clients.size(); ++i) { // ScriptableDocumentParser::executeScriptsWaitingForResources(). Also protect
// Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that run via // the |CSSStyleSheet| from being deleted during iteration via the |sheetLoaded|
// ScriptableDocumentParser::executeScriptsWaitingForResources(). // method.
RefPtr<CSSStyleSheet> protectClient(clients[i]); //
// FIXME: oilpan: with oilpan we do not need to protect the CSSStyleSheets
if (clients[i]->loadCompleted()) // explicitly during the iteration. The iterator will make the pointers
// strong during iteration so we can just directly iterate root->m_clients.
WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet>, 5> protectedClients;
for (ClientsIterator it = root->m_clients.begin(); it != root->m_clients.end(); ++it)
protectedClients.append(*it);
for (unsigned i = 0; i < protectedClients.size(); ++i) {
if (protectedClients[i]->loadCompleted())
continue; continue;
// sheetLoaded might be invoked after its owner node is removed from document. // sheetLoaded might be invoked after its owner node is removed from document.
if (RefPtr<Node> ownerNode = clients[i]->ownerNode()) { if (RefPtr<Node> ownerNode = protectedClients[i]->ownerNode()) {
if (clients[i]->sheetLoaded()) if (protectedClients[i]->sheetLoaded())
ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOccur); ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOccur);
} }
} }
...@@ -431,8 +438,8 @@ void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet) ...@@ -431,8 +438,8 @@ void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet)
void StyleSheetContents::startLoadingDynamicSheet() void StyleSheetContents::startLoadingDynamicSheet()
{ {
StyleSheetContents* root = rootStyleSheet(); StyleSheetContents* root = rootStyleSheet();
for (unsigned i = 0; i < root->m_clients.size(); ++i) for (ClientsIterator it = root->m_clients.begin(); it != root->m_clients.end(); ++it)
root->m_clients[i]->startLoadingDynamicSheet(); (*it)->startLoadingDynamicSheet();
} }
StyleSheetContents* StyleSheetContents::rootStyleSheet() const StyleSheetContents* StyleSheetContents::rootStyleSheet() const
...@@ -457,7 +464,7 @@ Node* StyleSheetContents::singleOwnerNode() const ...@@ -457,7 +464,7 @@ Node* StyleSheetContents::singleOwnerNode() const
if (root->m_clients.isEmpty()) if (root->m_clients.isEmpty())
return 0; return 0;
ASSERT(root->m_clients.size() == 1); ASSERT(root->m_clients.size() == 1);
return root->m_clients[0]->ownerNode(); return (*root->m_clients.begin())->ownerNode();
} }
Document* StyleSheetContents::singleOwnerDocument() const Document* StyleSheetContents::singleOwnerDocument() const
...@@ -519,14 +526,13 @@ StyleSheetContents* StyleSheetContents::parentStyleSheet() const ...@@ -519,14 +526,13 @@ StyleSheetContents* StyleSheetContents::parentStyleSheet() const
void StyleSheetContents::registerClient(CSSStyleSheet* sheet) void StyleSheetContents::registerClient(CSSStyleSheet* sheet)
{ {
ASSERT(!m_clients.contains(sheet)); ASSERT(!m_clients.contains(sheet));
m_clients.append(sheet); m_clients.add(sheet);
} }
void StyleSheetContents::unregisterClient(CSSStyleSheet* sheet) void StyleSheetContents::unregisterClient(CSSStyleSheet* sheet)
{ {
size_t position = m_clients.find(sheet); ASSERT(m_clients.contains(sheet));
ASSERT(position != kNotFound); m_clients.remove(sheet);
m_clients.remove(position);
} }
void StyleSheetContents::addedToMemoryCache() void StyleSheetContents::addedToMemoryCache()
...@@ -571,8 +577,8 @@ void StyleSheetContents::clearRuleSet() ...@@ -571,8 +577,8 @@ void StyleSheetContents::clearRuleSet()
// Clearing the ruleSet means we need to recreate the styleResolver data structures. // Clearing the ruleSet means we need to recreate the styleResolver data structures.
// See the StyleResolver calls in ScopedStyleResolver::addRulesFromSheet. // See the StyleResolver calls in ScopedStyleResolver::addRulesFromSheet.
for (size_t i = 0; i < m_clients.size(); ++i) { for (ClientsIterator it = m_clients.begin(); it != m_clients.end(); ++it) {
if (Document* document = m_clients[i]->ownerDocument()) if (Document* document = (*it)->ownerDocument())
document->styleEngine()->clearResolver(); document->styleEngine()->clearResolver();
} }
m_ruleSet.clear(); m_ruleSet.clear();
...@@ -582,8 +588,8 @@ void StyleSheetContents::notifyRemoveFontFaceRule(const StyleRuleFontFace* fontF ...@@ -582,8 +588,8 @@ void StyleSheetContents::notifyRemoveFontFaceRule(const StyleRuleFontFace* fontF
{ {
StyleSheetContents* root = rootStyleSheet(); StyleSheetContents* root = rootStyleSheet();
for (unsigned i = 0; i < root->m_clients.size(); ++i) { for (ClientsIterator it = root->m_clients.begin(); it != root->m_clients.end(); ++it) {
if (Node* ownerNode = root->m_clients[0]->ownerNode()) if (Node* ownerNode = (*it)->ownerNode())
ownerNode->document().styleEngine()->removeFontFaceRules(WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >(1, fontFaceRule)); ownerNode->document().styleEngine()->removeFontFaceRules(WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >(1, fontFaceRule));
} }
} }
...@@ -620,6 +626,7 @@ void StyleSheetContents::trace(Visitor* visitor) ...@@ -620,6 +626,7 @@ void StyleSheetContents::trace(Visitor* visitor)
visitor->trace(m_ownerRule); visitor->trace(m_ownerRule);
visitor->trace(m_importRules); visitor->trace(m_importRules);
visitor->trace(m_childRules); visitor->trace(m_childRules);
visitor->trace(m_clients);
} }
} }
...@@ -185,7 +185,9 @@ private: ...@@ -185,7 +185,9 @@ private:
CSSParserContext m_parserContext; CSSParserContext m_parserContext;
Vector<CSSStyleSheet*> m_clients; WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> > m_clients;
typedef WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >::iterator ClientsIterator;
OwnPtr<RuleSet> m_ruleSet; OwnPtr<RuleSet> m_ruleSet;
}; };
......
...@@ -38,28 +38,28 @@ class XSLImportRule; ...@@ -38,28 +38,28 @@ class XSLImportRule;
class XSLStyleSheet FINAL : public StyleSheet { class XSLStyleSheet FINAL : public StyleSheet {
public: public:
static PassRefPtr<XSLStyleSheet> create(XSLImportRule* parentImport, const String& originalURL, const KURL& finalURL) static PassRefPtrWillBeRawPtr<XSLStyleSheet> create(XSLImportRule* parentImport, const String& originalURL, const KURL& finalURL)
{ {
ASSERT(RuntimeEnabledFeatures::xsltEnabled()); ASSERT(RuntimeEnabledFeatures::xsltEnabled());
return adoptRef(new XSLStyleSheet(parentImport, originalURL, finalURL)); return adoptRefWillBeRefCountedGarbageCollected(new XSLStyleSheet(parentImport, originalURL, finalURL));
} }
static PassRefPtr<XSLStyleSheet> create(ProcessingInstruction* parentNode, const String& originalURL, const KURL& finalURL) static PassRefPtrWillBeRawPtr<XSLStyleSheet> create(ProcessingInstruction* parentNode, const String& originalURL, const KURL& finalURL)
{ {
ASSERT(RuntimeEnabledFeatures::xsltEnabled()); ASSERT(RuntimeEnabledFeatures::xsltEnabled());
return adoptRef(new XSLStyleSheet(parentNode, originalURL, finalURL, false)); return adoptRefWillBeRefCountedGarbageCollected(new XSLStyleSheet(parentNode, originalURL, finalURL, false));
} }
static PassRefPtr<XSLStyleSheet> createEmbedded(ProcessingInstruction* parentNode, const KURL& finalURL) static PassRefPtrWillBeRawPtr<XSLStyleSheet> createEmbedded(ProcessingInstruction* parentNode, const KURL& finalURL)
{ {
ASSERT(RuntimeEnabledFeatures::xsltEnabled()); ASSERT(RuntimeEnabledFeatures::xsltEnabled());
return adoptRef(new XSLStyleSheet(parentNode, finalURL.string(), finalURL, true)); return adoptRefWillBeRefCountedGarbageCollected(new XSLStyleSheet(parentNode, finalURL.string(), finalURL, true));
} }
// Taking an arbitrary node is unsafe, because owner node pointer can become stale. // Taking an arbitrary node is unsafe, because owner node pointer can become stale.
// XSLTProcessor ensures that the stylesheet doesn't outlive its parent, in part by not exposing it to JavaScript. // XSLTProcessor ensures that the stylesheet doesn't outlive its parent, in part by not exposing it to JavaScript.
static PassRefPtr<XSLStyleSheet> createForXSLTProcessor(Node* parentNode, const String& originalURL, const KURL& finalURL) static PassRefPtrWillBeRawPtr<XSLStyleSheet> createForXSLTProcessor(Node* parentNode, const String& originalURL, const KURL& finalURL)
{ {
ASSERT(RuntimeEnabledFeatures::xsltEnabled()); ASSERT(RuntimeEnabledFeatures::xsltEnabled());
return adoptRef(new XSLStyleSheet(parentNode, originalURL, finalURL, false)); return adoptRefWillBeRefCountedGarbageCollected(new XSLStyleSheet(parentNode, originalURL, finalURL, false));
} }
virtual ~XSLStyleSheet(); virtual ~XSLStyleSheet();
...@@ -99,6 +99,8 @@ public: ...@@ -99,6 +99,8 @@ public:
virtual KURL baseURL() const OVERRIDE { return m_finalURL; } virtual KURL baseURL() const OVERRIDE { return m_finalURL; }
virtual bool isLoading() const OVERRIDE; virtual bool isLoading() const OVERRIDE;
virtual void trace(Visitor*) OVERRIDE;
private: private:
XSLStyleSheet(Node* parentNode, const String& originalURL, const KURL& finalURL, bool embedded); XSLStyleSheet(Node* parentNode, const String& originalURL, const KURL& finalURL, bool embedded);
XSLStyleSheet(XSLImportRule* parentImport, const String& originalURL, const KURL& finalURL); XSLStyleSheet(XSLImportRule* parentImport, const String& originalURL, const KURL& finalURL);
......
...@@ -303,4 +303,8 @@ void XSLStyleSheet::markAsProcessed() ...@@ -303,4 +303,8 @@ void XSLStyleSheet::markAsProcessed()
m_stylesheetDocTaken = true; m_stylesheetDocTaken = true;
} }
void XSLStyleSheet::trace(Visitor*)
{
}
} // namespace WebCore } // namespace WebCore
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment