[SCM] WebKit Debian packaging branch, webkit-1.3, updated. upstream/1.3.7-4207-g178b198

antti at apple.com antti at apple.com
Sun Feb 20 23:51:30 UTC 2011


The following commit has been merged in the webkit-1.3 branch:
commit 3c9313022c8ae99d2591a9993258016e0a5e24b6
Author: antti at apple.com <antti at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Jan 25 23:31:18 2011 +0000

    https://bugs.webkit.org/show_bug.cgi?id=52983
    Eliminate m_tagHistory pointer from CSSSelector
    
    Reviewed by Darin Adler.
    
    Keep the component selectors in the array in CSSSelectorList instead
    of maintaining a linked list between them. This allows eliminating
    m_tagHistory pointer, shrinking CSSSelector by 25% (selection performance
    seems to improve some too due to better locality).
    
    * WebCore.xcodeproj/project.pbxproj:
    
        Make CSSSelector.h a private header.
    
    * css/CSSGrammar.y:
    
        Use CSSParserSelector during parsing to keep the tag history in
        a linked list. This is flattened to an array after parsing.
        Use accessors for setting selector values.
        Use OwnPtr in selector vector.
    
    * css/CSSPageRule.cpp:
    (WebCore::CSSPageRule::CSSPageRule):
    * css/CSSPageRule.h:
    (WebCore::CSSPageRule::create):
    
        Simplify.
    
    * css/CSSParser.cpp:
    (WebCore::CSSParser::~CSSParser):
    (WebCore::CSSParser::createFloatingSelector):
    (WebCore::CSSParser::sinkFloatingSelector):
    (WebCore::CSSParser::createStyleRule):
    (WebCore::CSSParser::updateSpecifiersWithElementName):
    (WebCore::CSSParser::createPageRule):
    * css/CSSParser.h:
    (WebCore::CSSParser::reusableSelectorVector):
    
        CSSSelector -> CSSParserSelector.
        Use OwnPtr in selector vector.
    
    * css/CSSParserValues.cpp:
    (WebCore::CSSParserSelector::CSSParserSelector):
    (WebCore::CSSParserSelector::~CSSParserSelector):
    * css/CSSParserValues.h:
    (WebCore::CSSParserSelector::releaseSelector):
    (WebCore::CSSParserSelector::setTag):
    (WebCore::CSSParserSelector::setValue):
    (WebCore::CSSParserSelector::setAttribute):
    (WebCore::CSSParserSelector::setArgument):
    (WebCore::CSSParserSelector::setSimpleSelector):
    (WebCore::CSSParserSelector::setMatch):
    (WebCore::CSSParserSelector::setRelation):
    (WebCore::CSSParserSelector::setForPage):
    (WebCore::CSSParserSelector::pseudoType):
    (WebCore::CSSParserSelector::isUnknownPseudoElement):
    (WebCore::CSSParserSelector::isSimple):
    (WebCore::CSSParserSelector::tagHistory):
    (WebCore::CSSParserSelector::setTagHistory):
    
        Linked list used during parsing.
        Avoid recursive destruction.
    
    * css/CSSSelector.cpp:
    (WebCore::CSSSelector::extractPseudoType):
    (WebCore::CSSSelector::operator==):
    (WebCore::CSSSelector::selectorText):
    (WebCore::CSSSelector::setSimpleSelector):
    * css/CSSSelector.h:
    (WebCore::CSSSelector::CSSSelector):
    (WebCore::CSSSelector::~CSSSelector):
    (WebCore::CSSSelector::tagHistory):
    (WebCore::CSSSelector::tag):
    (WebCore::CSSSelector::value):
    (WebCore::CSSSelector::setTag):
    (WebCore::CSSSelector::isLastInTagHistory):
    (WebCore::CSSSelector::setNotLastInTagHistory):
    (WebCore::CSSSelector::RareData::RareData):
    (WebCore::CSSSelector::RareData::~RareData):
    (WebCore::CSSSelector::createRareData):
    (WebCore::CSSSelector::setValue):
    
        Remove m_tagHistory.
        Keep m_value in the union with the rare data pointer instead.
        Make m_value and m_tag private, implement accessors.
        Add a new bit to indicate end of the tag history (multipart selector).
        Eliminate complex destruction. Selectors are now deleted as an array or by a CSSParserSelector chain.
    
    * css/CSSSelectorList.cpp:
    (WebCore::CSSSelectorList::adoptSelectorVector):
    
        Flatten everything to an array.
    
    (WebCore::SelectorNeedsNamespaceResolutionFunctor::operator()):
    * css/CSSSelectorList.h:
    (WebCore::CSSSelectorList::hasOneSelector):
    (WebCore::CSSSelectorList::next):
    
        Skip over the subparts of multipart selectors to find the next selector.
    
    * css/CSSStyleRule.h:
    (WebCore::CSSStyleRule::adoptSelectorVector):
    
        CSSSelector -> CSSParserSelector.
    
    * css/CSSStyleSelector.cpp:
    (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector):
    (WebCore::CSSRuleSet::addRule):
    (WebCore::collectIdsAndSiblingRulesFromList):
    (WebCore::CSSStyleSelector::matchPageRulesForList):
    * dom/Node.cpp:
    (WebCore::Node::querySelector):
    * dom/SelectorNodeList.cpp:
    (WebCore::createSelectorNodeList):
    
        Use accessors.
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@76648 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 383ce37..f3c1248 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,122 @@
+2011-01-23  Antti Koivisto  <antti at apple.com>
+
+        Reviewed by Darin Adler.
+
+        https://bugs.webkit.org/show_bug.cgi?id=52983
+        Eliminate m_tagHistory pointer from CSSSelector
+
+        Keep the component selectors in the array in CSSSelectorList instead
+        of maintaining a linked list between them. This allows eliminating
+        m_tagHistory pointer, shrinking CSSSelector by 25% (selection performance
+        seems to improve some too due to better locality).
+
+        * WebCore.xcodeproj/project.pbxproj:
+        
+            Make CSSSelector.h a private header.
+        
+        * css/CSSGrammar.y:
+        
+            Use CSSParserSelector during parsing to keep the tag history in 
+            a linked list. This is flattened to an array after parsing.
+            Use accessors for setting selector values.
+            Use OwnPtr in selector vector.
+            
+        * css/CSSPageRule.cpp:
+        (WebCore::CSSPageRule::CSSPageRule):
+        * css/CSSPageRule.h:
+        (WebCore::CSSPageRule::create):
+        
+            Simplify.
+    
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::~CSSParser):
+        (WebCore::CSSParser::createFloatingSelector):
+        (WebCore::CSSParser::sinkFloatingSelector):
+        (WebCore::CSSParser::createStyleRule):
+        (WebCore::CSSParser::updateSpecifiersWithElementName):
+        (WebCore::CSSParser::createPageRule):
+        * css/CSSParser.h:
+        (WebCore::CSSParser::reusableSelectorVector):
+        
+            CSSSelector -> CSSParserSelector.
+            Use OwnPtr in selector vector.
+            
+        * css/CSSParserValues.cpp:
+        (WebCore::CSSParserSelector::CSSParserSelector):
+        (WebCore::CSSParserSelector::~CSSParserSelector):
+        * css/CSSParserValues.h:
+        (WebCore::CSSParserSelector::releaseSelector):
+        (WebCore::CSSParserSelector::setTag):
+        (WebCore::CSSParserSelector::setValue):
+        (WebCore::CSSParserSelector::setAttribute):
+        (WebCore::CSSParserSelector::setArgument):
+        (WebCore::CSSParserSelector::setSimpleSelector):
+        (WebCore::CSSParserSelector::setMatch):
+        (WebCore::CSSParserSelector::setRelation):
+        (WebCore::CSSParserSelector::setForPage):
+        (WebCore::CSSParserSelector::pseudoType):
+        (WebCore::CSSParserSelector::isUnknownPseudoElement):
+        (WebCore::CSSParserSelector::isSimple):
+        (WebCore::CSSParserSelector::tagHistory):
+        (WebCore::CSSParserSelector::setTagHistory):
+        
+            Linked list used during parsing.
+            Avoid recursive destruction.
+
+        * css/CSSSelector.cpp:
+        (WebCore::CSSSelector::extractPseudoType):
+        (WebCore::CSSSelector::operator==):
+        (WebCore::CSSSelector::selectorText):
+        (WebCore::CSSSelector::setSimpleSelector):
+        * css/CSSSelector.h:
+        (WebCore::CSSSelector::CSSSelector):
+        (WebCore::CSSSelector::~CSSSelector):
+        (WebCore::CSSSelector::tagHistory):
+        (WebCore::CSSSelector::tag):
+        (WebCore::CSSSelector::value):
+        (WebCore::CSSSelector::setTag):
+        (WebCore::CSSSelector::isLastInTagHistory):
+        (WebCore::CSSSelector::setNotLastInTagHistory):
+        (WebCore::CSSSelector::RareData::RareData):
+        (WebCore::CSSSelector::RareData::~RareData):
+        (WebCore::CSSSelector::createRareData):
+        (WebCore::CSSSelector::setValue):
+        
+            Remove m_tagHistory.
+            Keep m_value in the union with the rare data pointer instead.
+            Make m_value and m_tag private, implement accessors.
+            Add a new bit to indicate end of the tag history (multipart selector).
+            Eliminate complex destruction. Selectors are now deleted as an array or by a CSSParserSelector chain.
+            
+        * css/CSSSelectorList.cpp:
+        (WebCore::CSSSelectorList::adoptSelectorVector):
+        
+            Flatten everything to an array.
+        
+        (WebCore::SelectorNeedsNamespaceResolutionFunctor::operator()):
+        * css/CSSSelectorList.h:
+        (WebCore::CSSSelectorList::hasOneSelector):
+        (WebCore::CSSSelectorList::next):
+        
+            Skip over the subparts of multipart selectors to find the next selector.
+    
+        * css/CSSStyleRule.h:
+        (WebCore::CSSStyleRule::adoptSelectorVector):
+        
+            CSSSelector -> CSSParserSelector.
+            
+        * css/CSSStyleSelector.cpp:
+        (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector):
+        (WebCore::CSSRuleSet::addRule):
+        (WebCore::collectIdsAndSiblingRulesFromList):
+        (WebCore::CSSStyleSelector::matchPageRulesForList):
+        * dom/Node.cpp:
+        (WebCore::Node::querySelector):
+        * dom/SelectorNodeList.cpp:
+        (WebCore::createSelectorNodeList):
+        
+            Use accessors.
+
 2011-01-25  James Simonsen  <simonjam at chromium.org>
 
         Reviewed by Tony Chang.
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
index ab1a38d..3c7def3 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -3273,7 +3273,7 @@
 		A80E734F0A199C77007FB8C5 /* CSSSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A80E73480A199C77007FB8C5 /* CSSSelector.cpp */; };
 		A80E73500A199C77007FB8C5 /* StyleBase.h in Headers */ = {isa = PBXBuildFile; fileRef = A80E73490A199C77007FB8C5 /* StyleBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		A80E73510A199C77007FB8C5 /* StyleList.h in Headers */ = {isa = PBXBuildFile; fileRef = A80E734A0A199C77007FB8C5 /* StyleList.h */; };
-		A80E73520A199C77007FB8C5 /* CSSSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = A80E734B0A199C77007FB8C5 /* CSSSelector.h */; };
+		A80E73520A199C77007FB8C5 /* CSSSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = A80E734B0A199C77007FB8C5 /* CSSSelector.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		A80E73530A199C77007FB8C5 /* StyleBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A80E734C0A199C77007FB8C5 /* StyleBase.cpp */; };
 		A80E7A170A19C3D6007FB8C5 /* JSHTMLMetaElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A80E7A150A19C3D6007FB8C5 /* JSHTMLMetaElement.cpp */; };
 		A80E7A180A19C3D6007FB8C5 /* JSHTMLMetaElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A80E7A160A19C3D6007FB8C5 /* JSHTMLMetaElement.h */; };
diff --git a/Source/WebCore/css/CSSGrammar.y b/Source/WebCore/css/CSSGrammar.y
index a5fe795..03d25d9 100644
--- a/Source/WebCore/css/CSSGrammar.y
+++ b/Source/WebCore/css/CSSGrammar.y
@@ -69,8 +69,8 @@ using namespace HTMLNames;
 
     CSSRule* rule;
     CSSRuleList* ruleList;
-    CSSSelector* selector;
-    Vector<CSSSelector*>* selectorList;
+    CSSParserSelector* selector;
+    Vector<OwnPtr<CSSParserSelector> >* selectorList;
     CSSSelector::MarginBoxType marginBox;
     CSSSelector::Relation relation;
     MediaList* mediaList;
@@ -663,14 +663,14 @@ page_selector:
     IDENT {
         CSSParser* p = static_cast<CSSParser*>(parser);
         $$ = p->createFloatingSelector();
-        $$->m_tag = QualifiedName(nullAtom, $1, p->m_defaultNamespace);
+        $$->setTag(QualifiedName(nullAtom, $1, p->m_defaultNamespace));
         $$->setForPage();
     }
     | IDENT pseudo_page {
         CSSParser* p = static_cast<CSSParser*>(parser);
         $$ = $2;
         if ($$) {
-            $$->m_tag = QualifiedName(nullAtom, $1, p->m_defaultNamespace);
+            $$->setTag(QualifiedName(nullAtom, $1, p->m_defaultNamespace));
             $$->setForPage();
         }
     }
@@ -812,7 +812,6 @@ selector_list:
         if ($1) {
             CSSParser* p = static_cast<CSSParser*>(parser);
             $$ = p->reusableSelectorVector();
-            deleteAllValues(*$$);
             $$->shrink(0);
             $$->append(p->sinkFloatingSelector($1));
             p->updateLastSelectorLineAndPosition();
@@ -853,10 +852,10 @@ selector:
             $$ = 0;
         else if ($$) {
             CSSParser* p = static_cast<CSSParser*>(parser);
-            CSSSelector* end = $$;
+            CSSParserSelector* end = $$;
             while (end->tagHistory())
                 end = end->tagHistory();
-            end->m_relation = CSSSelector::Descendant;
+            end->setRelation(CSSSelector::Descendant);
             end->setTagHistory(p->sinkFloatingSelector($1));
             if (Document* doc = p->document())
                 doc->setUsesDescendantRules(true);
@@ -868,10 +867,10 @@ selector:
             $$ = 0;
         else if ($$) {
             CSSParser* p = static_cast<CSSParser*>(parser);
-            CSSSelector* end = $$;
+            CSSParserSelector* end = $$;
             while (end->tagHistory())
                 end = end->tagHistory();
-            end->m_relation = $2;
+            end->setRelation($2);
             end->setTagHistory(p->sinkFloatingSelector($1));
             if ($2 == CSSSelector::Child) {
                 if (Document* doc = p->document())
@@ -897,7 +896,7 @@ simple_selector:
     element_name {
         CSSParser* p = static_cast<CSSParser*>(parser);
         $$ = p->createFloatingSelector();
-        $$->m_tag = QualifiedName(nullAtom, $1, p->m_defaultNamespace);
+        $$->setTag(QualifiedName(nullAtom, $1, p->m_defaultNamespace));
     }
     | element_name specifier_list {
         $$ = $2;
@@ -914,10 +913,10 @@ simple_selector:
         CSSParser* p = static_cast<CSSParser*>(parser);
         $$ = p->createFloatingSelector();
         if (p->m_styleSheet)
-            $$->m_tag = QualifiedName(namespacePrefix, $2,
-                                      p->m_styleSheet->determineNamespace(namespacePrefix));
+            $$->setTag(QualifiedName(namespacePrefix, $2,
+                                      p->m_styleSheet->determineNamespace(namespacePrefix)));
         else // FIXME: Shouldn't this case be an error?
-            $$->m_tag = QualifiedName(nullAtom, $2, p->m_defaultNamespace);
+            $$->setTag(QualifiedName(nullAtom, $2, p->m_defaultNamespace));
     }
     | namespace_selector element_name specifier_list {
         $$ = $3;
@@ -956,8 +955,8 @@ specifier_list:
             $$ = 0;
         else if ($1) {
             CSSParser* p = static_cast<CSSParser*>(parser);
-            CSSSelector* end;
-            CSSSelector* history;
+            CSSParserSelector* end;
+            CSSParserSelector* history;
             // Ensure that unknown pseudo element always stays at the top of selector chain.
             if ($2->isUnknownPseudoElement()) {
                 end = $2;
@@ -969,7 +968,7 @@ specifier_list:
             $$ = end;
             while(end->tagHistory())
                 end = end->tagHistory();
-            end->m_relation = CSSSelector::SubSelector;
+            end->setRelation(CSSSelector::SubSelector);
             end->setTagHistory(p->sinkFloatingSelector(history));
         }
     }
@@ -982,10 +981,10 @@ specifier:
     IDSEL {
         CSSParser* p = static_cast<CSSParser*>(parser);
         $$ = p->createFloatingSelector();
-        $$->m_match = CSSSelector::Id;
+        $$->setMatch(CSSSelector::Id);
         if (!p->m_strict)
             $1.lower();
-        $$->m_value = $1;
+        $$->setValue($1);
     }
   | HEX {
         if ($1.characters[0] >= '0' && $1.characters[0] <= '9') {
@@ -993,10 +992,10 @@ specifier:
         } else {
             CSSParser* p = static_cast<CSSParser*>(parser);
             $$ = p->createFloatingSelector();
-            $$->m_match = CSSSelector::Id;
+            $$->setMatch(CSSSelector::Id);
             if (!p->m_strict)
                 $1.lower();
-            $$->m_value = $1;
+            $$->setValue($1);
         }
     }
   | class
@@ -1008,10 +1007,10 @@ class:
     '.' IDENT {
         CSSParser* p = static_cast<CSSParser*>(parser);
         $$ = p->createFloatingSelector();
-        $$->m_match = CSSSelector::Class;
+        $$->setMatch(CSSSelector::Class);
         if (!p->m_strict)
             $2.lower();
-        $$->m_value = $2;
+        $$->setValue($2);
     }
   ;
 
@@ -1030,13 +1029,13 @@ attrib:
     '[' maybe_space attr_name ']' {
         $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
         $$->setAttribute(QualifiedName(nullAtom, $3, nullAtom));
-        $$->m_match = CSSSelector::Set;
+        $$->setMatch(CSSSelector::Set);
     }
     | '[' maybe_space attr_name match maybe_space ident_or_string maybe_space ']' {
         $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
         $$->setAttribute(QualifiedName(nullAtom, $3, nullAtom));
-        $$->m_match = (CSSSelector::Match)$4;
-        $$->m_value = $6;
+        $$->setMatch((CSSSelector::Match)$4);
+        $$->setValue($6);
     }
     | '[' maybe_space namespace_selector attr_name ']' {
         AtomicString namespacePrefix = $3;
@@ -1044,7 +1043,7 @@ attrib:
         $$ = p->createFloatingSelector();
         $$->setAttribute(QualifiedName(namespacePrefix, $4,
                                    p->m_styleSheet->determineNamespace(namespacePrefix)));
-        $$->m_match = CSSSelector::Set;
+        $$->setMatch(CSSSelector::Set);
     }
     | '[' maybe_space namespace_selector attr_name match maybe_space ident_or_string maybe_space ']' {
         AtomicString namespacePrefix = $3;
@@ -1052,8 +1051,8 @@ attrib:
         $$ = p->createFloatingSelector();
         $$->setAttribute(QualifiedName(namespacePrefix, $4,
                                    p->m_styleSheet->determineNamespace(namespacePrefix)));
-        $$->m_match = (CSSSelector::Match)$5;
-        $$->m_value = $7;
+        $$->setMatch((CSSSelector::Match)$5);
+        $$->setValue($7);
     }
   ;
 
@@ -1086,9 +1085,9 @@ ident_or_string:
 pseudo_page:
     ':' IDENT {
         $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
-        $$->m_match = CSSSelector::PagePseudoClass;
+        $$->setMatch(CSSSelector::PagePseudoClass);
         $2.lower();
-        $$->m_value = $2;
+        $$->setValue($2);
         CSSSelector::PseudoType type = $$->pseudoType();
         if (type == CSSSelector::PseudoUnknown)
             $$ = 0;
@@ -1097,9 +1096,9 @@ pseudo_page:
 pseudo:
     ':' IDENT {
         $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
-        $$->m_match = CSSSelector::PseudoClass;
+        $$->setMatch(CSSSelector::PseudoClass);
         $2.lower();
-        $$->m_value = $2;
+        $$->setValue($2);
         CSSSelector::PseudoType type = $$->pseudoType();
         if (type == CSSSelector::PseudoUnknown)
             $$ = 0;
@@ -1131,9 +1130,9 @@ pseudo:
     }
     | ':' ':' IDENT {
         $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
-        $$->m_match = CSSSelector::PseudoElement;
+        $$->setMatch(CSSSelector::PseudoElement);
         $3.lower();
-        $$->m_value = $3;
+        $$->setValue($3);
         CSSSelector::PseudoType type = $$->pseudoType();
         if (type == CSSSelector::PseudoFirstLine) {
             CSSParser* p = static_cast<CSSParser*>(parser);
@@ -1150,9 +1149,9 @@ pseudo:
     | ':' FUNCTION maybe_space NTH maybe_space ')' {
         CSSParser *p = static_cast<CSSParser*>(parser);
         $$ = p->createFloatingSelector();
-        $$->m_match = CSSSelector::PseudoClass;
+        $$->setMatch(CSSSelector::PseudoClass);
         $$->setArgument($4);
-        $$->m_value = $2;
+        $$->setValue($2);
         CSSSelector::PseudoType type = $$->pseudoType();
         if (type == CSSSelector::PseudoUnknown)
             $$ = 0;
@@ -1168,9 +1167,9 @@ pseudo:
     | ':' FUNCTION maybe_space maybe_unary_operator INTEGER maybe_space ')' {
         CSSParser *p = static_cast<CSSParser*>(parser);
         $$ = p->createFloatingSelector();
-        $$->m_match = CSSSelector::PseudoClass;
+        $$->setMatch(CSSSelector::PseudoClass);
         $$->setArgument(String::number($4 * $5));
-        $$->m_value = $2;
+        $$->setValue($2);
         CSSSelector::PseudoType type = $$->pseudoType();
         if (type == CSSSelector::PseudoUnknown)
             $$ = 0;
@@ -1186,10 +1185,10 @@ pseudo:
     | ':' FUNCTION maybe_space IDENT maybe_space ')' {
         CSSParser *p = static_cast<CSSParser*>(parser);
         $$ = p->createFloatingSelector();
-        $$->m_match = CSSSelector::PseudoClass;
+        $$->setMatch(CSSSelector::PseudoClass);
         $$->setArgument($4);
         $2.lower();
-        $$->m_value = $2;
+        $$->setValue($2);
         CSSSelector::PseudoType type = $$->pseudoType();
         if (type == CSSSelector::PseudoUnknown)
             $$ = 0;
@@ -1211,10 +1210,10 @@ pseudo:
         else {
             CSSParser* p = static_cast<CSSParser*>(parser);
             $$ = p->createFloatingSelector();
-            $$->m_match = CSSSelector::PseudoClass;
-            $$->setSimpleSelector(p->sinkFloatingSelector($4));
+            $$->setMatch(CSSSelector::PseudoClass);
+            $$->setSimpleSelector(p->sinkFloatingSelector($4)->releaseSelector());
             $2.lower();
-            $$->m_value = $2;
+            $$->setValue($2);
         }
     }
   ;
diff --git a/Source/WebCore/css/CSSPageRule.cpp b/Source/WebCore/css/CSSPageRule.cpp
index c85c1aa..c3dbcaa 100644
--- a/Source/WebCore/css/CSSPageRule.cpp
+++ b/Source/WebCore/css/CSSPageRule.cpp
@@ -27,12 +27,9 @@
 
 namespace WebCore {
 
-CSSPageRule::CSSPageRule(CSSStyleSheet* parent, CSSSelector* selector, int sourceLine)
+CSSPageRule::CSSPageRule(CSSStyleSheet* parent, int sourceLine)
     : CSSStyleRule(parent, sourceLine)
 {
-    Vector<CSSSelector*> selectors;
-    selectors.append(selector);
-    adoptSelectorVector(selectors);
 }
 
 CSSPageRule::~CSSPageRule()
diff --git a/Source/WebCore/css/CSSPageRule.h b/Source/WebCore/css/CSSPageRule.h
index bdfb751..9c1c41f 100644
--- a/Source/WebCore/css/CSSPageRule.h
+++ b/Source/WebCore/css/CSSPageRule.h
@@ -34,9 +34,9 @@ class CSSSelectorList;
 
 class CSSPageRule : public CSSStyleRule {
 public:
-    static PassRefPtr<CSSPageRule> create(CSSStyleSheet* parent, CSSSelector* selector, int sourceLine)
+    static PassRefPtr<CSSPageRule> create(CSSStyleSheet* parent, int sourceLine)
     {
-        return adoptRef(new CSSPageRule(parent, selector, sourceLine));
+        return adoptRef(new CSSPageRule(parent, sourceLine));
     }
 
     virtual ~CSSPageRule();
@@ -44,7 +44,7 @@ public:
     virtual String selectorText() const;
 
 private:
-    CSSPageRule(CSSStyleSheet* parent, CSSSelector* selector, int sourceLine);
+    CSSPageRule(CSSStyleSheet* parent, int sourceLine);
 
     virtual bool isPageRule() { return true; }
 
diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp
index 89220cd..817d46c 100644
--- a/Source/WebCore/css/CSSParser.cpp
+++ b/Source/WebCore/css/CSSParser.cpp
@@ -179,7 +179,6 @@ CSSParser::~CSSParser()
     fastDeleteAllValues(m_floatingSelectors);
     deleteAllValues(m_floatingValueLists);
     deleteAllValues(m_floatingFunctions);
-    deleteAllValues(m_reusableSelectorVector);
 }
 
 void CSSParserString::lower()
@@ -5700,20 +5699,20 @@ void CSSParser::countLines()
     }
 }
 
-CSSSelector* CSSParser::createFloatingSelector()
+CSSParserSelector* CSSParser::createFloatingSelector()
 {
-    CSSSelector* selector = fastNew<CSSSelector>();
+    CSSParserSelector* selector = new CSSParserSelector;
     m_floatingSelectors.add(selector);
     return selector;
 }
 
-CSSSelector* CSSParser::sinkFloatingSelector(CSSSelector* selector)
+PassOwnPtr<CSSParserSelector> CSSParser::sinkFloatingSelector(CSSParserSelector* selector)
 {
     if (selector) {
         ASSERT(m_floatingSelectors.contains(selector));
         m_floatingSelectors.remove(selector);
     }
-    return selector;
+    return adoptPtr(selector);
 }
 
 CSSParserValueList* CSSParser::createFloatingValueList()
@@ -5855,7 +5854,7 @@ WebKitCSSKeyframesRule* CSSParser::createKeyframesRule()
     return rulePtr;
 }
 
-CSSRule* CSSParser::createStyleRule(Vector<CSSSelector*>* selectors)
+CSSRule* CSSParser::createStyleRule(Vector<OwnPtr<CSSParserSelector> >* selectors)
 {
     CSSStyleRule* result = 0;
     markRuleBodyEnd();
@@ -5917,21 +5916,21 @@ void CSSParser::addNamespace(const AtomicString& prefix, const AtomicString& uri
     m_styleSheet->addNamespace(this, prefix, uri);
 }
 
-void CSSParser::updateSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSSelector* specifiers)
+void CSSParser::updateSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector* specifiers)
 {
     AtomicString determinedNamespace = namespacePrefix != nullAtom && m_styleSheet ? m_styleSheet->determineNamespace(namespacePrefix) : m_defaultNamespace;
     QualifiedName tag = QualifiedName(namespacePrefix, elementName, determinedNamespace);
     if (!specifiers->isUnknownPseudoElement()) {
-        specifiers->m_tag = tag;
+        specifiers->setTag(tag);
         return;
     }
 
     if (Document* doc = document())
         doc->setUsesDescendantRules(true);
 
-    specifiers->m_relation = CSSSelector::ShadowDescendant;
-    if (CSSSelector* history = specifiers->tagHistory()) {
-        history->m_tag = tag;
+    specifiers->setRelation(CSSSelector::ShadowDescendant);
+    if (CSSParserSelector* history = specifiers->tagHistory()) {
+        history->setTag(tag);
         return;
     }
 
@@ -5940,19 +5939,22 @@ void CSSParser::updateSpecifiersWithElementName(const AtomicString& namespacePre
     if (elementName == starAtom && m_defaultNamespace == starAtom)
         return;
 
-    CSSSelector* elementNameSelector = fastNew<CSSSelector>();
-    elementNameSelector->m_tag = tag;
+    CSSParserSelector* elementNameSelector = new CSSParserSelector;
+    elementNameSelector->setTag(tag);
     specifiers->setTagHistory(elementNameSelector);
 }
 
 
-CSSRule* CSSParser::createPageRule(CSSSelector* pageSelector)
+CSSRule* CSSParser::createPageRule(PassOwnPtr<CSSParserSelector> pageSelector)
 {
     // FIXME: Margin at-rules are ignored.
     m_allowImportRules = m_allowNamespaceDeclarations = false;
     CSSPageRule* pageRule = 0;
     if (pageSelector) {
-        RefPtr<CSSPageRule> rule = CSSPageRule::create(m_styleSheet, pageSelector, m_lastSelectorLineNumber);
+        RefPtr<CSSPageRule> rule = CSSPageRule::create(m_styleSheet, m_lastSelectorLineNumber);
+        Vector<OwnPtr<CSSParserSelector> > selectorVector;
+        selectorVector.append(pageSelector);
+        rule->adoptSelectorVector(selectorVector);
         rule->setDeclaration(CSSMutableStyleDeclaration::create(rule.get(), m_parsedProperties, m_numParsedProperties));
         pageRule = rule.get();
         m_parsedStyleObjects.append(rule.release());
diff --git a/Source/WebCore/css/CSSParser.h b/Source/WebCore/css/CSSParser.h
index d326812..d1b2061 100644
--- a/Source/WebCore/css/CSSParser.h
+++ b/Source/WebCore/css/CSSParser.h
@@ -170,8 +170,8 @@ namespace WebCore {
 
         int yyparse();
 
-        CSSSelector* createFloatingSelector();
-        CSSSelector* sinkFloatingSelector(CSSSelector*);
+        CSSParserSelector* createFloatingSelector();
+        PassOwnPtr<CSSParserSelector> sinkFloatingSelector(CSSParserSelector*);
 
         CSSParserValueList* createFloatingValueList();
         CSSParserValueList* sinkFloatingValueList(CSSParserValueList*);
@@ -188,9 +188,9 @@ namespace WebCore {
         WebKitCSSKeyframesRule* createKeyframesRule();
         CSSRule* createMediaRule(MediaList*, CSSRuleList*);
         CSSRuleList* createRuleList();
-        CSSRule* createStyleRule(Vector<CSSSelector*>* selectors);
+        CSSRule* createStyleRule(Vector<OwnPtr<CSSParserSelector> >* selectors);
         CSSRule* createFontFaceRule();
-        CSSRule* createPageRule(CSSSelector* pageSelector);
+        CSSRule* createPageRule(PassOwnPtr<CSSParserSelector> pageSelector);
         CSSRule* createMarginAtRule(CSSSelector::MarginBoxType marginBox);
         void startDeclarationsForMarginBox();
         void endDeclarationsForMarginBox();
@@ -204,11 +204,11 @@ namespace WebCore {
         PassOwnPtr<MediaQuery> sinkFloatingMediaQuery(MediaQuery*);
 
         void addNamespace(const AtomicString& prefix, const AtomicString& uri);
-        void updateSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSSelector*);
+        void updateSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector*);
 
         void invalidBlockHit();
 
-        Vector<CSSSelector*>* reusableSelectorVector() { return &m_reusableSelectorVector; }
+        Vector<OwnPtr<CSSParserSelector> >* reusableSelectorVector() { return &m_reusableSelectorVector; }
 
         void updateLastSelectorLineAndPosition();
 
@@ -302,7 +302,7 @@ namespace WebCore {
 
         Vector<RefPtr<StyleBase> > m_parsedStyleObjects;
         Vector<RefPtr<CSSRuleList> > m_parsedRuleLists;
-        HashSet<CSSSelector*> m_floatingSelectors;
+        HashSet<CSSParserSelector*> m_floatingSelectors;
         HashSet<CSSParserValueList*> m_floatingValueLists;
         HashSet<CSSParserFunction*> m_floatingFunctions;
 
@@ -310,7 +310,7 @@ namespace WebCore {
         OwnPtr<MediaQueryExp> m_floatingMediaQueryExp;
         OwnPtr<Vector<OwnPtr<MediaQueryExp> > > m_floatingMediaQueryExpList;
 
-        Vector<CSSSelector*> m_reusableSelectorVector;
+        Vector<OwnPtr<CSSParserSelector> > m_reusableSelectorVector;
 
         // defines units allowed for a certain property, used in parseUnit
         enum Units {
diff --git a/Source/WebCore/css/CSSParserValues.cpp b/Source/WebCore/css/CSSParserValues.cpp
index 06651f1..dc0e82b 100644
--- a/Source/WebCore/css/CSSParserValues.cpp
+++ b/Source/WebCore/css/CSSParserValues.cpp
@@ -20,11 +20,15 @@
 
 #include "config.h"
 #include "CSSParserValues.h"
+
 #include "CSSPrimitiveValue.h"
 #include "CSSFunctionValue.h"
 #include "CSSQuirkPrimitiveValue.h"
+#include "CSSSelector.h"
 
 namespace WebCore {
+        
+using namespace WTF;
 
 CSSParserValueList::~CSSParserValueList()
 {
@@ -70,6 +74,27 @@ PassRefPtr<CSSValue> CSSParserValue::createCSSValue()
         parsedValue = CSSQuirkPrimitiveValue::create(fValue, CSSPrimitiveValue::CSS_EMS);
     return parsedValue;
 }
+    
+CSSParserSelector::CSSParserSelector()
+    : m_selector(adoptPtr(fastNew<CSSSelector>()))
+{
+}
+
+CSSParserSelector::~CSSParserSelector()
+{
+    if (!m_tagHistory)
+        return;
+    Vector<CSSParserSelector*, 16> toDelete;
+    CSSParserSelector* selector = m_tagHistory.leakPtr();
+    while (true) {
+        toDelete.append(selector);
+        CSSParserSelector* next = selector->m_tagHistory.leakPtr();
+        if (!next)
+            break;
+        selector = next;
+    }
+    deleteAllValues(toDelete);
+}
 
 }
 
diff --git a/Source/WebCore/css/CSSParserValues.h b/Source/WebCore/css/CSSParserValues.h
index 996e783..d084091 100644
--- a/Source/WebCore/css/CSSParserValues.h
+++ b/Source/WebCore/css/CSSParserValues.h
@@ -21,11 +21,13 @@
 #ifndef CSSParserValues_h
 #define CSSParserValues_h
 
+#include "CSSSelector.h"
 #include <wtf/text/AtomicString.h>
 
 namespace WebCore {
 
 class CSSValue;
+class QualifiedName;
 
 struct CSSParserString {
     UChar* characters;
@@ -91,6 +93,35 @@ public:
     OwnPtr<CSSParserValueList> args;
 };
 
+class CSSParserSelector {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    CSSParserSelector();
+    ~CSSParserSelector();
+
+    PassOwnPtr<CSSSelector> releaseSelector() { return m_selector.release(); }
+    
+    void setTag(const QualifiedName& value) { m_selector->setTag(value); }
+    void setValue(const AtomicString& value) { m_selector->setValue(value); }
+    void setAttribute(const QualifiedName& value) { m_selector->setAttribute(value); }
+    void setArgument(const AtomicString& value) { m_selector->setArgument(value); }
+    void setSimpleSelector(PassOwnPtr<CSSSelector> value) { m_selector->setSimpleSelector(value); }
+    void setMatch(CSSSelector::Match value) { m_selector->m_match = value; }
+    void setRelation(CSSSelector::Relation value) { m_selector->m_relation = value; }
+    void setForPage() { m_selector->setForPage(); }
+    
+    CSSSelector::PseudoType pseudoType() const { return m_selector->pseudoType(); }
+    bool isUnknownPseudoElement() const { return m_selector->isUnknownPseudoElement(); }
+    bool isSimple() const { return !m_tagHistory && m_selector->isSimple(); }
+
+    CSSParserSelector* tagHistory() const { return m_tagHistory.get(); }
+    void setTagHistory(PassOwnPtr<CSSParserSelector> selector) { m_tagHistory = selector; }
+
+private:
+    OwnPtr<CSSSelector> m_selector;
+    OwnPtr<CSSParserSelector> m_tagHistory;
+};
+
 }
 
 #endif
diff --git a/Source/WebCore/css/CSSSelector.cpp b/Source/WebCore/css/CSSSelector.cpp
index ca3814a..8ff3859 100644
--- a/Source/WebCore/css/CSSSelector.cpp
+++ b/Source/WebCore/css/CSSSelector.cpp
@@ -36,38 +36,15 @@
 namespace WebCore {
 
 using namespace HTMLNames;
-
-class CSSSelectorBag {
-    WTF_MAKE_NONCOPYABLE(CSSSelectorBag);
-public:
-    CSSSelectorBag() { }
-    ~CSSSelectorBag()
-    {
-        ASSERT(isEmpty());
-    }
-
-    bool isEmpty() const
-    {
-        return m_stack.isEmpty();
-    }
-
-    void add(PassOwnPtr<CSSSelector> selector)
-    {
-        if (selector)
-            m_stack.append(selector.leakPtr());
-    }
-
-    PassOwnPtr<CSSSelector> takeAny()
-    {
-        ASSERT(!isEmpty());
-        OwnPtr<CSSSelector> selector = adoptPtr(m_stack.last());
-        m_stack.removeLast();
-        return selector.release();
-    }
-
-private:
-    Vector<CSSSelector*, 16> m_stack;
-};
+    
+void CSSSelector::createRareData()
+{
+    if (m_hasRareData) 
+        return;
+    // Move the value to the rare data stucture.
+    m_data.m_rareData = new RareData(adoptRef(m_data.m_value));
+    m_hasRareData = true;
+}
 
 unsigned CSSSelector::specificity() const
 {
@@ -577,7 +554,7 @@ void CSSSelector::extractPseudoType() const
     if (m_match != PseudoClass && m_match != PseudoElement && m_match != PagePseudoClass)
         return;
 
-    m_pseudoType = parsePseudoType(m_value);
+    m_pseudoType = parsePseudoType(value());
 
     bool element = false; // pseudo-element
     bool compat = false; // single colon compatbility mode
@@ -721,7 +698,7 @@ bool CSSSelector::operator==(const CSSSelector& other)
     while (sel1 && sel2) {
         if (sel1->m_tag != sel2->m_tag || sel1->attribute() != sel2->attribute() ||
              sel1->relation() != sel2->relation() || sel1->m_match != sel2->m_match ||
-             sel1->m_value != sel2->m_value ||
+             sel1->value() != sel2->value() ||
              sel1->pseudoType() != sel2->pseudoType() ||
              sel1->argument() != sel2->argument())
             return false;
@@ -755,13 +732,13 @@ String CSSSelector::selectorText() const
     while (true) {
         if (cs->m_match == CSSSelector::Id) {
             str += "#";
-            serializeIdentifier(cs->m_value, str);
+            serializeIdentifier(cs->value(), str);
         } else if (cs->m_match == CSSSelector::Class) {
             str += ".";
-            serializeIdentifier(cs->m_value, str);
+            serializeIdentifier(cs->value(), str);
         } else if (cs->m_match == CSSSelector::PseudoClass || cs->m_match == CSSSelector::PagePseudoClass) {
             str += ":";
-            str += cs->m_value;
+            str += cs->value();
             if (cs->pseudoType() == PseudoNot) {
                 if (CSSSelector* subSel = cs->simpleSelector())
                     str += subSel->selectorText();
@@ -776,7 +753,7 @@ String CSSSelector::selectorText() const
             }
         } else if (cs->m_match == CSSSelector::PseudoElement) {
             str += "::";
-            str += cs->m_value;
+            str += cs->value();
         } else if (cs->hasAttribute()) {
             str += "[";
             const AtomicString& prefix = cs->attribute().prefix();
@@ -812,7 +789,7 @@ String CSSSelector::selectorText() const
                     break;
             }
             if (cs->m_match != CSSSelector::Set) {
-                serializeString(cs->m_value, str);
+                serializeString(cs->value(), str);
                 str += "]";
             }
         }
@@ -836,14 +813,6 @@ String CSSSelector::selectorText() const
 
     return str;
 }
-    
-void CSSSelector::setTagHistory(CSSSelector* tagHistory) 
-{ 
-    if (m_hasRareData) 
-        m_data.m_rareData->m_tagHistory.set(tagHistory); 
-    else 
-        m_data.m_tagHistory = tagHistory; 
-}
 
 const QualifiedName& CSSSelector::attribute() const
 { 
@@ -869,10 +838,10 @@ void CSSSelector::setArgument(const AtomicString& value)
     m_data.m_rareData->m_argument = value; 
 }
 
-void CSSSelector::setSimpleSelector(CSSSelector* value)
+void CSSSelector::setSimpleSelector(PassOwnPtr<CSSSelector> value)
 {
     createRareData(); 
-    m_data.m_rareData->m_simpleSelector.set(value); 
+    m_data.m_rareData->m_simpleSelector = value; 
 }
 
 bool CSSSelector::parseNth()
@@ -975,33 +944,4 @@ bool CSSSelector::RareData::matchNth(int count)
     }
 }
 
-inline void CSSSelector::releaseOwnedSelectorsToBag(CSSSelectorBag& bag)
-{
-    if (m_hasRareData) {
-        ASSERT(m_data.m_rareData);
-        bag.add(m_data.m_rareData->m_tagHistory.release());
-        bag.add(m_data.m_rareData->m_simpleSelector.release());
-        delete m_data.m_rareData;
-        // Clear the pointer so that a destructor of this selector will not
-        // traverse this chain.
-        m_data.m_rareData = 0;
-    } else {
-        bag.add(adoptPtr(m_data.m_tagHistory));
-        // Clear the pointer for the same reason.
-        m_data.m_tagHistory = 0;
-    }
-}
-
-void CSSSelector::deleteReachableSelectors()
-{
-    // Traverse the chain of selectors and delete each iteratively.
-    CSSSelectorBag selectorsToBeDeleted;
-    releaseOwnedSelectorsToBag(selectorsToBeDeleted);
-    while (!selectorsToBeDeleted.isEmpty()) {
-        OwnPtr<CSSSelector> selector(selectorsToBeDeleted.takeAny());
-        ASSERT(selector);
-        selector->releaseOwnedSelectorsToBag(selectorsToBeDeleted);
-    }
-}
-
 } // namespace WebCore
diff --git a/Source/WebCore/css/CSSSelector.h b/Source/WebCore/css/CSSSelector.h
index b930353..66c94f3 100644
--- a/Source/WebCore/css/CSSSelector.h
+++ b/Source/WebCore/css/CSSSelector.h
@@ -30,8 +30,6 @@
 
 namespace WebCore {
 
-    class CSSSelectorBag;
-
     // this class represents a selector for a StyleRule
     class CSSSelector {
         WTF_MAKE_NONCOPYABLE(CSSSelector); WTF_MAKE_FAST_ALLOCATED;
@@ -42,6 +40,7 @@ namespace WebCore {
             , m_pseudoType(PseudoNotParsed)
             , m_parsedNth(false)
             , m_isLastInSelectorList(false)
+            , m_isLastInTagHistory(true)
             , m_hasRareData(false)
             , m_isForPage(false)
             , m_tag(anyQName())
@@ -54,6 +53,7 @@ namespace WebCore {
             , m_pseudoType(PseudoNotParsed)
             , m_parsedNth(false)
             , m_isLastInSelectorList(false)
+            , m_isLastInTagHistory(true)
             , m_hasRareData(false)
             , m_isForPage(false)
             , m_tag(qName)
@@ -62,18 +62,10 @@ namespace WebCore {
 
         ~CSSSelector()
         {
-            // Exit if this selector does not own any objects to be deleted.
-            if (m_hasRareData) {
-                if (!m_data.m_rareData)
-                    return;
-            } else if (!m_data.m_tagHistory)
-                return;
-
-            // We can not delete the owned object(s) by simply calling delete
-            // directly on them. That would lead to recursive destructor calls
-            // which might cause stack overflow. We have to delete them
-            // iteratively.
-            deleteReachableSelectors();
+            if (m_hasRareData)
+                delete m_data.m_rareData;
+            else if (m_data.m_value)
+                m_data.m_value->deref();
         }
 
         /**
@@ -255,29 +247,31 @@ namespace WebCore {
         static PseudoType parsePseudoType(const AtomicString&);
         static PseudoId pseudoId(PseudoType);
 
-        CSSSelector* tagHistory() const { return m_hasRareData ? m_data.m_rareData->m_tagHistory.get() : m_data.m_tagHistory; }
-        void setTagHistory(CSSSelector* tagHistory);
+        // Selectors are kept in an array by CSSSelectorList. The next component of the selector is 
+        // the next item in the array.
+        CSSSelector* tagHistory() const { return m_isLastInTagHistory ? 0 : const_cast<CSSSelector*>(this + 1); }
 
         bool hasTag() const { return m_tag != anyQName(); }
         bool hasAttribute() const { return m_match == Id || m_match == Class || (m_hasRareData && m_data.m_rareData->m_attribute != anyQName()); }
         
+        const QualifiedName& tag() const { return m_tag; }
+        // AtomicString is really just an AtomicStringImpl* so the cast below is safe.
+        // FIXME: Perhaps call sites could be changed to accept AtomicStringImpl?
+        const AtomicString& value() const { return *reinterpret_cast<const AtomicString*>(m_hasRareData ? &m_data.m_rareData->m_value : &m_data.m_value); }
         const QualifiedName& attribute() const;
         const AtomicString& argument() const { return m_hasRareData ? m_data.m_rareData->m_argument : nullAtom; }
         CSSSelector* simpleSelector() const { return m_hasRareData ? m_data.m_rareData->m_simpleSelector.get() : 0; }
         
-        void setAttribute(const QualifiedName& value);
-        void setArgument(const AtomicString& value);
-        void setSimpleSelector(CSSSelector* value);
+        void setTag(const QualifiedName& value) { m_tag = value; }
+        void setValue(const AtomicString&);
+        void setAttribute(const QualifiedName&);
+        void setArgument(const AtomicString&);
+        void setSimpleSelector(PassOwnPtr<CSSSelector>);
         
         bool parseNth();
         bool matchNth(int count);
 
-        bool matchesPseudoElement() const 
-        { 
-            if (m_pseudoType == PseudoUnknown)
-                extractPseudoType();
-            return m_match == PseudoElement;
-        }
+        bool matchesPseudoElement() const;
         bool isUnknownPseudoElement() const;
         bool isSiblingSelector() const;
 
@@ -285,6 +279,9 @@ namespace WebCore {
 
         bool isLastInSelectorList() const { return m_isLastInSelectorList; }
         void setLastInSelectorList() { m_isLastInSelectorList = true; }
+        bool isLastInTagHistory() const { return m_isLastInTagHistory; }
+        void setNotLastInTagHistory() { m_isLastInTagHistory = false; }
+
         bool isSimple() const;
 
         bool isForPage() const { return m_isForPage; }
@@ -297,12 +294,10 @@ namespace WebCore {
     private:
         bool m_parsedNth              : 1; // Used for :nth-* 
         bool m_isLastInSelectorList   : 1;
+        bool m_isLastInTagHistory     : 1;
         bool m_hasRareData            : 1;
         bool m_isForPage              : 1;
 
-        void releaseOwnedSelectorsToBag(CSSSelectorBag&);
-        void deleteReachableSelectors();
-
         unsigned specificityForOneSelector() const;
         unsigned specificityForPage() const;
         void extractPseudoType() const;
@@ -310,44 +305,47 @@ namespace WebCore {
         struct RareData {
             WTF_MAKE_NONCOPYABLE(RareData); WTF_MAKE_FAST_ALLOCATED;
         public:
-            RareData(PassOwnPtr<CSSSelector> tagHistory)
-                : m_a(0)
+            RareData(PassRefPtr<AtomicStringImpl> value)
+                : m_value(value.leakRef())
+                , m_a(0)
                 , m_b(0)
-                , m_tagHistory(tagHistory)
                 , m_attribute(anyQName())
                 , m_argument(nullAtom)
             {
             }
+            ~RareData()
+            {
+                if (m_value)
+                    m_value->deref();
+            }
 
             bool parseNth();
             bool matchNth(int count);
 
+            AtomicStringImpl* m_value; // Plain pointer to keep things uniform with the union.
             int m_a; // Used for :nth-*
             int m_b; // Used for :nth-*
-            OwnPtr<CSSSelector> m_tagHistory;
             OwnPtr<CSSSelector> m_simpleSelector; // Used for :not.
             QualifiedName m_attribute; // used for attribute selector
             AtomicString m_argument; // Used for :contains, :lang and :nth-*
         };
-
-        void createRareData()
-        {
-            if (m_hasRareData) 
-                return;
-            m_data.m_rareData = new RareData(adoptPtr(m_data.m_tagHistory));
-            m_hasRareData = true;
-        }
+        void createRareData();
         
         union DataUnion {
-            DataUnion() : m_tagHistory(0) { }
-            CSSSelector* m_tagHistory;
+            DataUnion() : m_value(0) { }
+            AtomicStringImpl* m_value;
             RareData* m_rareData;
         } m_data;
         
-    public:
-        mutable AtomicString m_value;
         QualifiedName m_tag;
     };
+    
+inline bool CSSSelector::matchesPseudoElement() const 
+{ 
+    if (m_pseudoType == PseudoUnknown)
+        extractPseudoType();
+    return m_match == PseudoElement;
+}
 
 inline bool CSSSelector::isUnknownPseudoElement() const
 {
@@ -371,6 +369,26 @@ inline bool CSSSelector::isSiblingSelector() const
         || type == PseudoNthLastChild
         || type == PseudoNthLastOfType;
 }
+    
+inline void CSSSelector::setValue(const AtomicString& value)
+{ 
+    // Need to do ref counting manually for the union.
+    if (m_hasRareData) {
+        m_data.m_rareData->m_value = value.impl();
+        m_data.m_rareData->m_value->ref();
+        return;
+    }
+    m_data.m_value = value.impl();
+    m_data.m_value->ref();
+}
+
+inline void move(PassOwnPtr<CSSSelector> from, CSSSelector* to) 
+{
+    memcpy(to, from.get(), sizeof(CSSSelector));
+    // We want to free the memory (which was allocated with fastNew), but we
+    // don't want the destructor to run since it will affect the copy we've just made.
+    fastDeleteSkippingDestructor(from.leakPtr());
+}
 
 } // namespace WebCore
 
diff --git a/Source/WebCore/css/CSSSelectorList.cpp b/Source/WebCore/css/CSSSelectorList.cpp
index 7cb4df4..f4a8165 100644
--- a/Source/WebCore/css/CSSSelectorList.cpp
+++ b/Source/WebCore/css/CSSSelectorList.cpp
@@ -27,6 +27,8 @@
 #include "config.h"
 #include "CSSSelectorList.h"
 
+#include "CSSParserValues.h"
+
 namespace WebCore {
 
 CSSSelectorList::~CSSSelectorList() 
@@ -41,26 +43,40 @@ void CSSSelectorList::adopt(CSSSelectorList& list)
     list.m_selectorArray = 0;
 }
 
-void CSSSelectorList::adoptSelectorVector(Vector<CSSSelector*>& selectorVector)
+void CSSSelectorList::adoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectorVector)
 {
     deleteSelectors();
-    const size_t size = selectorVector.size();
-    ASSERT(size);
-    if (size == 1) {
-        m_selectorArray = selectorVector[0];
+    const size_t vectorSize = selectorVector.size();
+    size_t flattenedSize = 0;
+    for (size_t i = 0; i < vectorSize; ++i) {        
+        for (CSSParserSelector* selector = selectorVector[i].get(); selector; selector = selector->tagHistory())
+            ++flattenedSize;
+    }
+    ASSERT(flattenedSize);
+    if (flattenedSize == 1) {
+        m_selectorArray = selectorVector[0]->releaseSelector().leakPtr();
         m_selectorArray->setLastInSelectorList();
+        ASSERT(m_selectorArray->isLastInTagHistory());
         selectorVector.shrink(0);
         return;
     }
-    m_selectorArray = reinterpret_cast<CSSSelector*>(fastMalloc(sizeof(CSSSelector) * selectorVector.size()));
-    for (size_t i = 0; i < size; ++i) {
-        memcpy(&m_selectorArray[i], selectorVector[i], sizeof(CSSSelector));
-        // We want to free the memory (which was allocated with fastNew), but we
-        // don't want the destructor to run since it will affect the copy we've just made.
-        fastDeleteSkippingDestructor(selectorVector[i]);
-        ASSERT(!m_selectorArray[i].isLastInSelectorList());
+    m_selectorArray = reinterpret_cast<CSSSelector*>(fastMalloc(sizeof(CSSSelector) * flattenedSize));
+    size_t arrayIndex = 0;
+    for (size_t i = 0; i < vectorSize; ++i) {
+        CSSParserSelector* current = selectorVector[i].get();
+        while (current) {
+            OwnPtr<CSSSelector> selector = current->releaseSelector();
+            current = current->tagHistory();
+            move(selector.release(), &m_selectorArray[arrayIndex]);
+            ASSERT(!m_selectorArray[arrayIndex].isLastInSelectorList());
+            if (current)
+                m_selectorArray[arrayIndex].setNotLastInTagHistory();
+            ++arrayIndex;
+        }
+        ASSERT(m_selectorArray[arrayIndex - 1].isLastInTagHistory());
     }
-    m_selectorArray[size - 1].setLastInSelectorList();
+    ASSERT(flattenedSize == arrayIndex);
+    m_selectorArray[arrayIndex - 1].setLastInSelectorList();
     selectorVector.shrink(0);
 }
 
@@ -122,7 +138,7 @@ class SelectorNeedsNamespaceResolutionFunctor {
 public:
     bool operator()(CSSSelector* selector)
     {
-        if (selector->hasTag() && selector->m_tag.prefix() != nullAtom && selector->m_tag.prefix() != starAtom)
+        if (selector->hasTag() && selector->tag().prefix() != nullAtom && selector->tag().prefix() != starAtom)
             return true;
         if (selector->hasAttribute() && selector->attribute().prefix() != nullAtom && selector->attribute().prefix() != starAtom)
             return true;
diff --git a/Source/WebCore/css/CSSSelectorList.h b/Source/WebCore/css/CSSSelectorList.h
index abd9bc8..b3c4c03 100644
--- a/Source/WebCore/css/CSSSelectorList.h
+++ b/Source/WebCore/css/CSSSelectorList.h
@@ -30,6 +30,8 @@
 
 namespace WebCore {
     
+class CSSParserSelector;
+    
 class CSSSelectorList {
     WTF_MAKE_NONCOPYABLE(CSSSelectorList); WTF_MAKE_FAST_ALLOCATED;
 public:
@@ -37,11 +39,11 @@ public:
     ~CSSSelectorList();
 
     void adopt(CSSSelectorList& list);
-    void adoptSelectorVector(Vector<CSSSelector*>& selectorVector);
+    void adoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectorVector);
     
     CSSSelector* first() const { return m_selectorArray ? m_selectorArray : 0; }
-    static CSSSelector* next(CSSSelector* previous) { return previous->isLastInSelectorList() ? 0 : previous + 1; }
-    bool hasOneSelector() const { return m_selectorArray ? m_selectorArray->isLastInSelectorList() : false; }
+    static CSSSelector* next(CSSSelector*);
+    bool hasOneSelector() const { return m_selectorArray && !next(m_selectorArray); }
 
     bool selectorsNeedNamespaceResolution();
     bool hasUnknownPseudoElements() const;
@@ -49,10 +51,19 @@ public:
 private:
     void deleteSelectors();
 
+    // End of a multipart selector is indicated by m_isLastInTagHistory bit in the last item.
     // End of the array is indicated by m_isLastInSelectorList bit in the last item.
     CSSSelector* m_selectorArray;
 };
 
+inline CSSSelector* CSSSelectorList::next(CSSSelector* current)
+{
+    // Skip subparts of combound selectors.
+    while (!current->isLastInTagHistory())
+        current++;
+    return current->isLastInSelectorList() ? 0 : current + 1;
+}
+
 } // namespace WebCore
 
 #endif // CSSSelectorList_h
diff --git a/Source/WebCore/css/CSSStyleRule.h b/Source/WebCore/css/CSSStyleRule.h
index 171b636..2d35043 100644
--- a/Source/WebCore/css/CSSStyleRule.h
+++ b/Source/WebCore/css/CSSStyleRule.h
@@ -50,7 +50,7 @@ public:
     // Not part of the CSSOM
     virtual bool parseString(const String&, bool = false);
 
-    void adoptSelectorVector(Vector<CSSSelector*>& selectors) { m_selectorList.adoptSelectorVector(selectors); }
+    void adoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectors) { m_selectorList.adoptSelectorVector(selectors); }
     void setDeclaration(PassRefPtr<CSSMutableStyleDeclaration>);
 
     const CSSSelectorList& selectorList() const { return m_selectorList; }
diff --git a/Source/WebCore/css/CSSStyleSelector.cpp b/Source/WebCore/css/CSSStyleSelector.cpp
index 54ae413..6536193 100644
--- a/Source/WebCore/css/CSSStyleSelector.cpp
+++ b/Source/WebCore/css/CSSStyleSelector.cpp
@@ -2217,20 +2217,20 @@ bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Eleme
         return false;
 
     if (sel->hasTag()) {
-        const AtomicString& selLocalName = sel->m_tag.localName();
+        const AtomicString& selLocalName = sel->tag().localName();
         if (selLocalName != starAtom && selLocalName != e->localName())
             return false;
-        const AtomicString& selNS = sel->m_tag.namespaceURI();
+        const AtomicString& selNS = sel->tag().namespaceURI();
         if (selNS != starAtom && selNS != e->namespaceURI())
             return false;
     }
 
     if (sel->hasAttribute()) {
         if (sel->m_match == CSSSelector::Class)
-            return e->hasClass() && static_cast<StyledElement*>(e)->classNames().contains(sel->m_value);
+            return e->hasClass() && static_cast<StyledElement*>(e)->classNames().contains(sel->value());
 
         if (sel->m_match == CSSSelector::Id)
-            return e->hasID() && e->idForStyleResolution() == sel->m_value;
+            return e->hasID() && e->idForStyleResolution() == sel->value();
         
         const QualifiedName& attr = sel->attribute();
 
@@ -2249,22 +2249,22 @@ bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Eleme
 
         switch (sel->m_match) {
         case CSSSelector::Exact:
-            if (caseSensitive ? sel->m_value != value : !equalIgnoringCase(sel->m_value, value))
+            if (caseSensitive ? sel->value() != value : !equalIgnoringCase(sel->value(), value))
                 return false;
             break;
         case CSSSelector::List:
         {
             // Ignore empty selectors or selectors containing spaces
-            if (sel->m_value.contains(' ') || sel->m_value.isEmpty())
+            if (sel->value().contains(' ') || sel->value().isEmpty())
                 return false;
 
             unsigned startSearchAt = 0;
             while (true) {
-                size_t foundPos = value.find(sel->m_value, startSearchAt, caseSensitive);
+                size_t foundPos = value.find(sel->value(), startSearchAt, caseSensitive);
                 if (foundPos == notFound)
                     return false;
                 if (foundPos == 0 || value[foundPos - 1] == ' ') {
-                    unsigned endStr = foundPos + sel->m_value.length();
+                    unsigned endStr = foundPos + sel->value().length();
                     if (endStr == value.length() || value[endStr] == ' ')
                         break; // We found a match.
                 }
@@ -2275,24 +2275,24 @@ bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Eleme
             break;
         }
         case CSSSelector::Contain:
-            if (!value.contains(sel->m_value, caseSensitive) || sel->m_value.isEmpty())
+            if (!value.contains(sel->value(), caseSensitive) || sel->value().isEmpty())
                 return false;
             break;
         case CSSSelector::Begin:
-            if (!value.startsWith(sel->m_value, caseSensitive) || sel->m_value.isEmpty())
+            if (!value.startsWith(sel->value(), caseSensitive) || sel->value().isEmpty())
                 return false;
             break;
         case CSSSelector::End:
-            if (!value.endsWith(sel->m_value, caseSensitive) || sel->m_value.isEmpty())
+            if (!value.endsWith(sel->value(), caseSensitive) || sel->value().isEmpty())
                 return false;
             break;
         case CSSSelector::Hyphen:
-            if (value.length() < sel->m_value.length())
+            if (value.length() < sel->value().length())
                 return false;
-            if (!value.startsWith(sel->m_value, caseSensitive))
+            if (!value.startsWith(sel->value(), caseSensitive))
                 return false;
             // It they start the same, check for exact match or following '-':
-            if (value.length() != sel->m_value.length() && value[sel->m_value.length()] != '-')
+            if (value.length() != sel->value().length() && value[sel->value().length()] != '-')
                 return false;
             break;
         case CSSSelector::PseudoClass:
@@ -2905,20 +2905,20 @@ void CSSRuleSet::addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map,
 void CSSRuleSet::addRule(CSSStyleRule* rule, CSSSelector* sel)
 {
     if (sel->m_match == CSSSelector::Id) {
-        addToRuleSet(sel->m_value.impl(), m_idRules, rule, sel);
+        addToRuleSet(sel->value().impl(), m_idRules, rule, sel);
         return;
     }
     if (sel->m_match == CSSSelector::Class) {
-        addToRuleSet(sel->m_value.impl(), m_classRules, rule, sel);
+        addToRuleSet(sel->value().impl(), m_classRules, rule, sel);
         return;
     }
      
     if (sel->isUnknownPseudoElement()) {
-        addToRuleSet(sel->m_value.impl(), m_pseudoRules, rule, sel);
+        addToRuleSet(sel->value().impl(), m_pseudoRules, rule, sel);
         return;
     }
 
-    const AtomicString& localName = sel->m_tag.localName();
+    const AtomicString& localName = sel->tag().localName();
     if (localName != starAtom) {
         addToRuleSet(localName.impl(), m_tagRules, rule, sel);
         return;
@@ -3006,12 +3006,12 @@ static void collectIdsAndSiblingRulesFromList(HashSet<AtomicStringImpl*>& ids, O
     for (CSSRuleData* data = rules->first(); data; data = data->next()) {
         bool foundSiblingSelector = false;
         for (CSSSelector* selector = data->selector(); selector; selector = selector->tagHistory()) {
-            if (selector->m_match == CSSSelector::Id && !selector->m_value.isEmpty())
-                ids.add(selector->m_value.impl());
+            if (selector->m_match == CSSSelector::Id && !selector->value().isEmpty())
+                ids.add(selector->value().impl());
             if (CSSSelector* simpleSelector = selector->simpleSelector()) {
                 ASSERT(!simpleSelector->simpleSelector());
-                if (simpleSelector->m_match == CSSSelector::Id && !simpleSelector->m_value.isEmpty())
-                    ids.add(simpleSelector->m_value.impl());
+                if (simpleSelector->m_match == CSSSelector::Id && !simpleSelector->value().isEmpty())
+                    ids.add(simpleSelector->value().impl());
             }
             if (selector->isSiblingSelector())
                 foundSiblingSelector = true;
@@ -3136,7 +3136,7 @@ void CSSStyleSelector::matchPageRulesForList(CSSRuleDataList* rules, bool isLeft
 
     for (CSSRuleData* d = rules->first(); d; d = d->next()) {
         CSSStyleRule* rule = d->rule();
-        const AtomicString& selectorLocalName = d->selector()->m_tag.localName();
+        const AtomicString& selectorLocalName = d->selector()->tag().localName();
         if (selectorLocalName != starAtom && selectorLocalName != pageName)
             continue;
         CSSSelector::PseudoType pseudoType = d->selector()->pseudoType();
diff --git a/Source/WebCore/dom/Node.cpp b/Source/WebCore/dom/Node.cpp
index cd72662..fec2cff 100644
--- a/Source/WebCore/dom/Node.cpp
+++ b/Source/WebCore/dom/Node.cpp
@@ -1636,7 +1636,7 @@ PassRefPtr<Element> Node::querySelector(const String& selectors, ExceptionCode&
 
     // FIXME: we could also optimize for the the [id="foo"] case
     if (strictParsing && inDocument() && querySelectorList.hasOneSelector() && querySelectorList.first()->m_match == CSSSelector::Id) {
-        Element* element = document()->getElementById(querySelectorList.first()->m_value);
+        Element* element = document()->getElementById(querySelectorList.first()->value());
         if (element && (isDocumentNode() || element->isDescendantOf(this)) && selectorChecker.checkSelector(querySelectorList.first(), element))
             return element;
         return 0;
diff --git a/Source/WebCore/dom/SelectorNodeList.cpp b/Source/WebCore/dom/SelectorNodeList.cpp
index 039a29f..7611488 100644
--- a/Source/WebCore/dom/SelectorNodeList.cpp
+++ b/Source/WebCore/dom/SelectorNodeList.cpp
@@ -50,8 +50,8 @@ PassRefPtr<StaticNodeList> createSelectorNodeList(Node* rootNode, const CSSSelec
 
     CSSStyleSelector::SelectorChecker selectorChecker(document, strictParsing);
 
-    if (strictParsing && rootNode->inDocument() && onlySelector && onlySelector->m_match == CSSSelector::Id && !document->containsMultipleElementsWithId(onlySelector->m_value)) {
-        Element* element = document->getElementById(onlySelector->m_value);
+    if (strictParsing && rootNode->inDocument() && onlySelector && onlySelector->m_match == CSSSelector::Id && !document->containsMultipleElementsWithId(onlySelector->value())) {
+        Element* element = document->getElementById(onlySelector->value());
         if (element && (rootNode->isDocumentNode() || element->isDescendantOf(rootNode)) && selectorChecker.checkSelector(onlySelector, element))
             nodes.append(element);
     } else {

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list