[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.19-706-ge5415e9

ap at apple.com ap at apple.com
Thu Feb 4 21:29:58 UTC 2010


The following commit has been merged in the webkit-1.1 branch:
commit 9e997cae9806575b161ccf8b935597909e048192
Author: ap at apple.com <ap at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Jan 27 23:41:50 2010 +0000

            Reviewed by Darin Adler.
    
            https://bugs.webkit.org/show_bug.cgi?id=34150
            WebKit needs a mechanism to catch stale HashMap entries
    
            It is very difficult to catch stale pointers that are HashMap keys - since a pointer's hash
            is just its value, it is very unlikely that any observable problem is reproducible.
    
            This extends hash table consistency checks to check that pointers are referencing allocated
            memory blocks, and makes it possible to invoke the checks explicitly (it is not feasible
            to enable CHECK_HASHTABLE_CONSISTENCY by default, because that affects performance too much).
    
            * wtf/HashMap.h: (WTF::::checkConsistency): Call through to HashTable implementation. We can
            add similar calls to HashSet and HashCountedSet, but I haven't seen hard to debug problems
            with those yet.
    
            * wtf/HashSet.h: (WTF::::remove): The version of checkTableConsistency that's guarded by
            CHECK_HASHTABLE_CONSISTENCY is now called internalCheckTableConsistency().
    
            * wtf/HashTable.h:
            (WTF::HashTable::internalCheckTableConsistency):
            (WTF::HashTable::internalCheckTableConsistencyExceptSize):
            (WTF::HashTable::checkTableConsistencyExceptSize):
            Expose checkTableConsistency() even if CHECK_HASHTABLE_CONSISTENCY is off.
            (WTF::::add): Updated for checkTableConsistency renaming.
            (WTF::::addPassingHashCode): Ditto.
            (WTF::::removeAndInvalidate): Ditto.
            (WTF::::remove): Ditto.
            (WTF::::rehash): Ditto.
            (WTF::::checkTableConsistency): The assertion for !shouldExpand() was not correct - this
            function returns true for tables with m_table == 0.
            (WTF::::checkTableConsistencyExceptSize): Call checkValueConsistency for key. Potentially,
            we could do the same for values.
    
            * wtf/HashTraits.h:
            (WTF::GenericHashTraits::checkValueConsistency): An empty function that can be overridden
            to add checks. Currently, the only override is for pointer hashes.
    
            * wtf/RefPtrHashMap.h: (WTF::::remove): Updated for checkTableConsistency renaming.
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@53957 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 5adeb63..71f801f 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,45 @@
+2010-01-27  Alexey Proskuryakov  <ap at apple.com>
+
+        Reviewed by Darin Adler.
+
+        https://bugs.webkit.org/show_bug.cgi?id=34150
+        WebKit needs a mechanism to catch stale HashMap entries
+
+        It is very difficult to catch stale pointers that are HashMap keys - since a pointer's hash
+        is just its value, it is very unlikely that any observable problem is reproducible.
+
+        This extends hash table consistency checks to check that pointers are referencing allocated
+        memory blocks, and makes it possible to invoke the checks explicitly (it is not feasible
+        to enable CHECK_HASHTABLE_CONSISTENCY by default, because that affects performance too much).
+
+        * wtf/HashMap.h: (WTF::::checkConsistency): Call through to HashTable implementation. We can
+        add similar calls to HashSet and HashCountedSet, but I haven't seen hard to debug problems
+        with those yet.
+
+        * wtf/HashSet.h: (WTF::::remove): The version of checkTableConsistency that's guarded by
+        CHECK_HASHTABLE_CONSISTENCY is now called internalCheckTableConsistency().
+
+        * wtf/HashTable.h:
+        (WTF::HashTable::internalCheckTableConsistency):
+        (WTF::HashTable::internalCheckTableConsistencyExceptSize):
+        (WTF::HashTable::checkTableConsistencyExceptSize):
+        Expose checkTableConsistency() even if CHECK_HASHTABLE_CONSISTENCY is off.
+        (WTF::::add): Updated for checkTableConsistency renaming.
+        (WTF::::addPassingHashCode): Ditto.
+        (WTF::::removeAndInvalidate): Ditto.
+        (WTF::::remove): Ditto.
+        (WTF::::rehash): Ditto.
+        (WTF::::checkTableConsistency): The assertion for !shouldExpand() was not correct - this
+        function returns true for tables with m_table == 0.
+        (WTF::::checkTableConsistencyExceptSize): Call checkValueConsistency for key. Potentially,
+        we could do the same for values.
+
+        * wtf/HashTraits.h:
+        (WTF::GenericHashTraits::checkValueConsistency): An empty function that can be overridden
+        to add checks. Currently, the only override is for pointer hashes.
+
+        * wtf/RefPtrHashMap.h: (WTF::::remove): Updated for checkTableConsistency renaming.
+
 2010-01-27  Anton Muhin  <antonm at chromium.org>
 
         Reviewed by Darin Adler.
diff --git a/JavaScriptCore/wtf/HashMap.h b/JavaScriptCore/wtf/HashMap.h
index ece3812..d63a8d4 100644
--- a/JavaScriptCore/wtf/HashMap.h
+++ b/JavaScriptCore/wtf/HashMap.h
@@ -100,6 +100,8 @@ namespace WTF {
         //   static translate(ValueType&, const T&, unsigned hashCode);
         template<typename T, typename HashTranslator> pair<iterator, bool> add(const T&, const MappedType&);
 
+        void checkConsistency() const;
+
     private:
         pair<iterator, bool> inlineAdd(const KeyType&, const MappedType&);
 
@@ -281,7 +283,7 @@ namespace WTF {
     {
         if (it.m_impl == m_impl.end())
             return;
-        m_impl.checkTableConsistency();
+        m_impl.internalCheckTableConsistency();
         m_impl.removeWithoutEntryConsistencyCheck(it.m_impl);
     }
 
@@ -311,6 +313,13 @@ namespace WTF {
     }
 
     template<typename T, typename U, typename V, typename W, typename X>
+    inline void HashMap<T, U, V, W, X>::checkConsistency() const
+    {
+        m_impl.checkTableConsistency();
+    }
+
+
+    template<typename T, typename U, typename V, typename W, typename X>
     bool operator==(const HashMap<T, U, V, W, X>& a, const HashMap<T, U, V, W, X>& b)
     {
         if (a.size() != b.size())
diff --git a/JavaScriptCore/wtf/HashSet.h b/JavaScriptCore/wtf/HashSet.h
index 0d7b4bb..4429490 100644
--- a/JavaScriptCore/wtf/HashSet.h
+++ b/JavaScriptCore/wtf/HashSet.h
@@ -224,7 +224,7 @@ namespace WTF {
     {
         if (it.m_impl == m_impl.end())
             return;
-        m_impl.checkTableConsistency();
+        m_impl.internalCheckTableConsistency();
         m_impl.removeWithoutEntryConsistencyCheck(it.m_impl);
     }
 
diff --git a/JavaScriptCore/wtf/HashTable.h b/JavaScriptCore/wtf/HashTable.h
index 92533fa..f1473e3 100644
--- a/JavaScriptCore/wtf/HashTable.h
+++ b/JavaScriptCore/wtf/HashTable.h
@@ -30,6 +30,7 @@
 namespace WTF {
 
 #define DUMP_HASHTABLE_STATS 0
+// Enables internal WTF consistency checks that are invoked automatically. Non-WTF callers can call checkTableConsistency() even if internal checks are disabled.
 #define CHECK_HASHTABLE_CONSISTENCY 0
 
 #ifdef NDEBUG
@@ -340,11 +341,18 @@ namespace WTF {
         ValueType* lookup(const Key& key) { return lookup<Key, IdentityTranslatorType>(key); }
         template<typename T, typename HashTranslator> ValueType* lookup(const T&);
 
-#if CHECK_HASHTABLE_CONSISTENCY
+#if !ASSERT_DISABLED
         void checkTableConsistency() const;
 #else
         static void checkTableConsistency() { }
 #endif
+#if CHECK_HASHTABLE_CONSISTENCY
+        void internalCheckTableConsistency() const { checkTableConsistency(); }
+        void internalCheckTableConsistencyExceptSize() const { checkTableConsistencyExceptSize(); }
+#else
+        static void internalCheckTableConsistencyExceptSize() { }
+        static void internalCheckTableConsistency() { }
+#endif
 
     private:
         static ValueType* allocateTable(int size);
@@ -383,7 +391,7 @@ namespace WTF {
         iterator makeKnownGoodIterator(ValueType* pos) { return iterator(this, pos, m_table + m_tableSize, HashItemKnownGood); }
         const_iterator makeKnownGoodConstIterator(ValueType* pos) const { return const_iterator(this, pos, m_table + m_tableSize, HashItemKnownGood); }
 
-#if CHECK_HASHTABLE_CONSISTENCY
+#if !ASSERT_DISABLED
         void checkTableConsistencyExceptSize() const;
 #else
         static void checkTableConsistencyExceptSize() { }
@@ -624,7 +632,7 @@ namespace WTF {
         if (!m_table)
             expand();
 
-        checkTableConsistency();
+        internalCheckTableConsistency();
 
         ASSERT(m_table);
 
@@ -693,7 +701,7 @@ namespace WTF {
             return p;
         }
         
-        checkTableConsistency();
+        internalCheckTableConsistency();
         
         return std::make_pair(makeKnownGoodIterator(entry), true);
     }
@@ -709,7 +717,7 @@ namespace WTF {
         if (!m_table)
             expand();
 
-        checkTableConsistency();
+        internalCheckTableConsistency();
 
         FullLookupType lookupResult = fullLookupForWriting<T, HashTranslator>(key);
 
@@ -738,7 +746,7 @@ namespace WTF {
             return p;
         }
 
-        checkTableConsistency();
+        internalCheckTableConsistency();
 
         return std::make_pair(makeKnownGoodIterator(entry), true);
     }
@@ -805,7 +813,7 @@ namespace WTF {
     void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::removeAndInvalidate(ValueType* pos)
     {
         invalidateIterators();
-        checkTableConsistency();
+        internalCheckTableConsistency();
         remove(pos);
     }
 
@@ -823,7 +831,7 @@ namespace WTF {
         if (shouldShrink())
             shrink();
 
-        checkTableConsistency();
+        internalCheckTableConsistency();
     }
 
     template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>
@@ -892,7 +900,7 @@ namespace WTF {
     template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>
     void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::rehash(int newTableSize)
     {
-        checkTableConsistencyExceptSize();
+        internalCheckTableConsistencyExceptSize();
 
         int oldTableSize = m_tableSize;
         ValueType* oldTable = m_table;
@@ -914,7 +922,7 @@ namespace WTF {
 
         deallocateTable(oldTable, oldTableSize);
 
-        checkTableConsistency();
+        internalCheckTableConsistency();
     }
 
     template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>
@@ -981,13 +989,13 @@ namespace WTF {
         return *this;
     }
 
-#if CHECK_HASHTABLE_CONSISTENCY
+#if !ASSERT_DISABLED
 
     template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>
     void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::checkTableConsistency() const
     {
         checkTableConsistencyExceptSize();
-        ASSERT(!shouldExpand());
+        ASSERT(!m_table || !shouldExpand());
         ASSERT(!shouldShrink());
     }
 
@@ -1012,6 +1020,8 @@ namespace WTF {
             const_iterator it = find(Extractor::extract(*entry));
             ASSERT(entry == it.m_position);
             ++count;
+
+            KeyTraits::checkValueConsistency(it->first);
         }
 
         ASSERT(count == m_keyCount);
@@ -1021,7 +1031,7 @@ namespace WTF {
         ASSERT(m_tableSize == m_tableSizeMask + 1);
     }
 
-#endif // CHECK_HASHTABLE_CONSISTENCY
+#endif // ASSERT_DISABLED
 
 #if CHECK_HASHTABLE_ITERATORS
 
diff --git a/JavaScriptCore/wtf/HashTraits.h b/JavaScriptCore/wtf/HashTraits.h
index c8d40f7..96ecac9 100644
--- a/JavaScriptCore/wtf/HashTraits.h
+++ b/JavaScriptCore/wtf/HashTraits.h
@@ -26,6 +26,13 @@
 #include <utility>
 #include <limits>
 
+// For malloc_size and _msize.
+#if OS(DARWIN)
+#include <malloc/malloc.h>
+#elif COMPILER(MSVC)
+#include <malloc.h>
+#endif
+
 namespace WTF {
 
     using std::pair;
@@ -51,6 +58,7 @@ namespace WTF {
     template<typename T> struct GenericHashTraits : GenericHashTraitsBase<IsInteger<T>::value, T> {
         typedef T TraitType;
         static T emptyValue() { return T(); }
+        static void checkValueConsistency(const T&) { }
     };
 
     template<typename T> struct HashTraits : GenericHashTraits<T> { };
@@ -79,6 +87,19 @@ namespace WTF {
         static const bool needsDestruction = false;
         static void constructDeletedValue(P*& slot) { slot = reinterpret_cast<P*>(-1); }
         static bool isDeletedValue(P* value) { return value == reinterpret_cast<P*>(-1); }
+#if !ASSERT_DISABLED
+        static void checkValueConsistency(const P* p)
+        {
+#if (defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC) || !defined(NDEBUG)
+#if OS(DARWIN)
+            ASSERT(malloc_size(p));
+#elif COMPILER(MSVC)
+            ASSERT(_msize(const_cast<P*>(p)));
+#endif
+#endif
+            HashTraits<P>::checkValueConsistency(*p);
+        }
+#endif
     };
 
     template<typename P> struct HashTraits<RefPtr<P> > : GenericHashTraits<RefPtr<P> > {
diff --git a/JavaScriptCore/wtf/RefPtrHashMap.h b/JavaScriptCore/wtf/RefPtrHashMap.h
index 9433025..7f6ebfe 100644
--- a/JavaScriptCore/wtf/RefPtrHashMap.h
+++ b/JavaScriptCore/wtf/RefPtrHashMap.h
@@ -285,7 +285,7 @@ namespace WTF {
     {
         if (it.m_impl == m_impl.end())
             return;
-        m_impl.checkTableConsistency();
+        m_impl.internalCheckTableConsistency();
         m_impl.removeWithoutEntryConsistencyCheck(it.m_impl);
     }
 
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index fd48756..cfb3c1a 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,71 @@
+2010-01-27  Alexey Proskuryakov  <ap at apple.com>
+
+        Reviewed by Darin Adler.
+
+        https://bugs.webkit.org/show_bug.cgi?id=34150
+        WebKit needs a mechanism to catch stale HashMap entries
+
+        * css/CSSStyleSelector.cpp:
+        (WebCore::CSSRuleSet::getIDRules):
+        (WebCore::CSSRuleSet::getClassRules):
+        (WebCore::CSSRuleSet::getTagRules):
+        (WebCore::CSSStyleSelector::keyframeStylesForAnimation):
+        * dom/CheckedRadioButtons.cpp:
+        (WebCore::CheckedRadioButtons::checkedButtonForGroup):
+        (WebCore::CheckedRadioButtons::removeButton):
+        * editing/markup.cpp:
+        (WebCore::shouldAddNamespaceAttr):
+        (WebCore::appendNamespace):
+        (WebCore::appendStartMarkup):
+        * html/HTMLCollection.cpp:
+        (WebCore::HTMLCollection::namedItems):
+        (WebCore::HTMLCollection::nextNamedItem):
+        * html/HTMLFormCollection.cpp:
+        (WebCore::HTMLFormCollection::formCollectionInfo):
+        * html/HTMLSelectElement.h:
+        (WebCore::HTMLSelectElement::collectionInfo):
+        * loader/loader.cpp:
+        (WebCore::Loader::load):
+        (WebCore::Loader::servePendingRequests):
+        (WebCore::Loader::nonCacheRequestInFlight):
+        (WebCore::Loader::nonCacheRequestComplete):
+        (WebCore::Loader::cancelRequests):
+        * page/animation/CompositeAnimation.cpp:
+        (WebCore::CompositeAnimation::clearRenderer):
+        (WebCore::CompositeAnimation::updateKeyframeAnimations):
+        (WebCore::CompositeAnimation::animate):
+        (WebCore::CompositeAnimation::getAnimatedStyle):
+        (WebCore::CompositeAnimation::setAnimating):
+        (WebCore::CompositeAnimation::timeToNextService):
+        (WebCore::CompositeAnimation::getAnimationForProperty):
+        (WebCore::CompositeAnimation::suspendAnimations):
+        (WebCore::CompositeAnimation::resumeAnimations):
+        (WebCore::CompositeAnimation::isAnimatingProperty):
+        (WebCore::CompositeAnimation::pauseAnimationAtTime):
+        (WebCore::CompositeAnimation::numberOfActiveAnimations):
+        Added checkConsistency checks before lookups in HashMaps with AtomicStringImpl* keys.
+
+        * dom/Document.cpp:
+        (WebCore::Document::removedLastRef): Clear m_elementsById map, because removeAllChildren()
+        doesn't always update it correctly when called during docuemnt destruction.
+        (WebCore::Document::getElementById): Added checkConsistency().
+        (WebCore::Document::removeElementById): Ditto.
+        (WebCore::Document::removeImageMap): Ditto.
+        (WebCore::Document::getImageMap): Ditto.
+        (WebCore::Document::nameCollectionInfo): Ditto.
+        * dom/Document.h:
+        (WebCore::Document::collectionInfo): Ditto.
+
+        * html/CollectionCache.cpp:
+        (WebCore::CollectionCache::checkConsistency):
+        * html/CollectionCache.h:
+        Added a checkConsistency() method that checks both HashMaps in the cache.
+
+        * platform/TreeShared.h:
+        (WebCore::TreeShared::~TreeShared): Assert that m_refCount is null. Since Nodes can be
+        destroyed with operator delete (as done in ContainerNodeAlgorithms), this is important to check.
+        (WebCore::TreeShared::deref): Assert that m_refCount isn't already negative.
+
 2010-01-27  Brian Tarricone  <brian at kakai.com>
 
         Reviewed by Gustavo Noronha Silva.
diff --git a/WebCore/css/CSSStyleSelector.cpp b/WebCore/css/CSSStyleSelector.cpp
index 5054754..841ad52 100644
--- a/WebCore/css/CSSStyleSelector.cpp
+++ b/WebCore/css/CSSStyleSelector.cpp
@@ -361,9 +361,9 @@ public:
     void addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map,
                       CSSStyleRule* rule, CSSSelector* sel);
     
-    CSSRuleDataList* getIDRules(AtomicStringImpl* key) { return m_idRules.get(key); }
-    CSSRuleDataList* getClassRules(AtomicStringImpl* key) { return m_classRules.get(key); }
-    CSSRuleDataList* getTagRules(AtomicStringImpl* key) { return m_tagRules.get(key); }
+    CSSRuleDataList* getIDRules(AtomicStringImpl* key) { m_idRules.checkConsistency(); return m_idRules.get(key); }
+    CSSRuleDataList* getClassRules(AtomicStringImpl* key) { m_classRules.checkConsistency(); return m_classRules.get(key); }
+    CSSRuleDataList* getTagRules(AtomicStringImpl* key) { m_tagRules.checkConsistency(); return m_tagRules.get(key); }
     CSSRuleDataList* getUniversalRules() { return m_universalRules; }
     
 public:
@@ -1301,7 +1301,9 @@ void CSSStyleSelector::keyframeStylesForAnimation(Element* e, const RenderStyle*
     // Get the keyframesRule for this name
     if (!e || list.animationName().isEmpty())
         return;
-            
+
+    m_keyframesRuleMap.checkConsistency();
+   
     if (!m_keyframesRuleMap.contains(list.animationName().impl()))
         return;
         
diff --git a/WebCore/dom/CheckedRadioButtons.cpp b/WebCore/dom/CheckedRadioButtons.cpp
index 9883f58..3cf8848 100644
--- a/WebCore/dom/CheckedRadioButtons.cpp
+++ b/WebCore/dom/CheckedRadioButtons.cpp
@@ -60,6 +60,8 @@ HTMLInputElement* CheckedRadioButtons::checkedButtonForGroup(const AtomicString&
 {
     if (!m_nameToCheckedRadioButtonMap)
         return 0;
+
+    m_nameToCheckedRadioButtonMap->checkConsistency();
     
     return m_nameToCheckedRadioButtonMap->get(name.impl());
 }
@@ -69,6 +71,8 @@ void CheckedRadioButtons::removeButton(HTMLFormControlElement* element)
     if (element->name().isEmpty() || !m_nameToCheckedRadioButtonMap)
         return;
     
+    m_nameToCheckedRadioButtonMap->checkConsistency();
+
     NameToInputMap::iterator it = m_nameToCheckedRadioButtonMap->find(element->name().impl());
     if (it == m_nameToCheckedRadioButtonMap->end() || it->second != element)
         return;
diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp
index 25b9561..01c465c 100644
--- a/WebCore/dom/Document.cpp
+++ b/WebCore/dom/Document.cpp
@@ -475,6 +475,9 @@ void Document::removedLastRef()
         m_titleElement = 0;
         m_documentElement = 0;
 
+        // removeAllChildren() doesn't always unregister IDs, do it upfront to avoid having stale references in the map.
+        m_elementsById.clear();
+
         removeAllChildren();
 
         deleteAllValues(m_markers);
@@ -884,6 +887,8 @@ Element* Document::getElementById(const AtomicString& elementId) const
     if (elementId.isEmpty())
         return 0;
 
+    m_elementsById.checkConsistency();
+
     Element* element = m_elementsById.get(elementId.impl());
     if (element)
         return element;
@@ -1075,6 +1080,8 @@ void Document::addElementById(const AtomicString& elementId, Element* element)
 
 void Document::removeElementById(const AtomicString& elementId, Element* element)
 {
+    m_elementsById.checkConsistency();
+
     if (m_elementsById.get(elementId.impl()) == element)
         m_elementsById.remove(elementId.impl());
     else
@@ -3351,6 +3358,8 @@ void Document::removeImageMap(HTMLMapElement* imageMap)
     if (!name.impl())
         return;
 
+    m_imageMapsByName.checkConsistency();
+
     ImageMapsByName::iterator it = m_imageMapsByName.find(name.impl());
     if (it != m_imageMapsByName.end() && it->second == imageMap)
         m_imageMapsByName.remove(it);
@@ -3363,6 +3372,7 @@ HTMLMapElement *Document::getImageMap(const String& url) const
     int hashPos = url.find('#');
     String name = (hashPos < 0 ? url : url.substring(hashPos + 1)).impl();
     AtomicString mapName = isHTMLDocument() ? name.lower() : name;
+    m_imageMapsByName.checkConsistency();
     return m_imageMapsByName.get(mapName.impl());
 }
 
@@ -4168,6 +4178,7 @@ CollectionCache* Document::nameCollectionInfo(CollectionType type, const AtomicS
     NamedCollectionMap::iterator iter = map.find(name.impl());
     if (iter == map.end())
         iter = map.add(name.impl(), new CollectionCache).first;
+    iter->second->checkConsistency();
     return iter->second;
 }
 
diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h
index 6d36e28..ad560f3 100644
--- a/WebCore/dom/Document.h
+++ b/WebCore/dom/Document.h
@@ -349,6 +349,7 @@ public:
         ASSERT(type >= FirstUnnamedDocumentCachedType);
         unsigned index = type - FirstUnnamedDocumentCachedType;
         ASSERT(index < NumUnnamedDocumentCachedTypes);
+        m_collectionInfo[index].checkConsistency();
         return &m_collectionInfo[index]; 
     }
 
diff --git a/WebCore/editing/markup.cpp b/WebCore/editing/markup.cpp
index 714909f..8986cd0 100644
--- a/WebCore/editing/markup.cpp
+++ b/WebCore/editing/markup.cpp
@@ -315,6 +315,8 @@ static bool shouldAddNamespaceElem(const Element* elem)
 
 static bool shouldAddNamespaceAttr(const Attribute* attr, HashMap<AtomicStringImpl*, AtomicStringImpl*>& namespaces)
 {
+    namespaces.checkConsistency();
+
     // Don't add namespace attributes twice
     if (attr->name() == XMLNSNames::xmlnsAttr) {
         namespaces.set(emptyAtom.impl(), attr->value().impl());
@@ -332,6 +334,7 @@ static bool shouldAddNamespaceAttr(const Attribute* attr, HashMap<AtomicStringIm
 
 static void appendNamespace(Vector<UChar>& result, const AtomicString& prefix, const AtomicString& ns, HashMap<AtomicStringImpl*, AtomicStringImpl*>& namespaces)
 {
+    namespaces.checkConsistency();
     if (ns.isEmpty())
         return;
         
@@ -392,6 +395,9 @@ enum RangeFullySelectsNode { DoesFullySelectNode, DoesNotFullySelectNode };
 
 static void appendStartMarkup(Vector<UChar>& result, const Node* node, const Range* range, EAnnotateForInterchange annotate, bool convertBlocksToInlines = false, HashMap<AtomicStringImpl*, AtomicStringImpl*>* namespaces = 0, RangeFullySelectsNode rangeFullySelectsNode = DoesFullySelectNode)
 {
+    if (namespaces)
+        namespaces->checkConsistency();
+
     bool documentIsHTML = node->document()->isHTMLDocument();
     switch (node->nodeType()) {
         case Node::TEXT_NODE: {
diff --git a/WebCore/html/CollectionCache.cpp b/WebCore/html/CollectionCache.cpp
index feecd96..745cf6e 100644
--- a/WebCore/html/CollectionCache.cpp
+++ b/WebCore/html/CollectionCache.cpp
@@ -85,4 +85,12 @@ void CollectionCache::reset()
     hasNameCache = false;
 }
 
+#if !ASSERT_DISABLED
+void CollectionCache::checkConsistency()
+{
+    idCache.checkConsistency();
+    nameCache.checkConsistency();
+}
+#endif
+
 } // namespace WebCore
diff --git a/WebCore/html/CollectionCache.h b/WebCore/html/CollectionCache.h
index 0a49fb8..70a5af7 100644
--- a/WebCore/html/CollectionCache.h
+++ b/WebCore/html/CollectionCache.h
@@ -43,6 +43,8 @@ struct CollectionCache : FastAllocBase {
     void reset();
     void swap(CollectionCache&);
 
+    void checkConsistency();
+
     typedef HashMap<AtomicStringImpl*, Vector<Element*>*> NodeCacheMap;
 
     unsigned version;
@@ -59,6 +61,10 @@ private:
     static void copyCacheMap(NodeCacheMap&, const NodeCacheMap&);
 };
 
+#if ASSERT_DISABLED
+    inline void CollectionCache::checkConsistency() { }
+#endif
+
 } // namespace
 
 #endif
diff --git a/WebCore/html/HTMLCollection.cpp b/WebCore/html/HTMLCollection.cpp
index 6b90cf1..0c65121 100644
--- a/WebCore/html/HTMLCollection.cpp
+++ b/WebCore/html/HTMLCollection.cpp
@@ -358,7 +358,8 @@ void HTMLCollection::namedItems(const AtomicString& name, Vector<RefPtr<Node> >&
 
     resetCollectionInfo();
     updateNameCache();
-    
+    m_info->checkConsistency();
+
     Vector<Element*>* idResults = m_info->idCache.get(name.impl());
     Vector<Element*>* nameResults = m_info->nameCache.get(name.impl());
     
@@ -373,6 +374,7 @@ void HTMLCollection::namedItems(const AtomicString& name, Vector<RefPtr<Node> >&
 Node* HTMLCollection::nextNamedItem(const AtomicString& name) const
 {
     resetCollectionInfo();
+    m_info->checkConsistency();
 
     for (Element* e = itemAfter(m_info->current); e; e = itemAfter(e)) {
         if (checkForNameMatch(e, m_idsDone, name)) {
diff --git a/WebCore/html/HTMLFormCollection.cpp b/WebCore/html/HTMLFormCollection.cpp
index 65c48fe..602f23b 100644
--- a/WebCore/html/HTMLFormCollection.cpp
+++ b/WebCore/html/HTMLFormCollection.cpp
@@ -40,6 +40,7 @@ inline CollectionCache* HTMLFormCollection::formCollectionInfo(HTMLFormElement*
 {
     if (!form->collectionInfo)
         form->collectionInfo = new CollectionCache;
+    form->collectionInfo->checkConsistency();
     return form->collectionInfo;
 }
 
diff --git a/WebCore/html/HTMLSelectElement.h b/WebCore/html/HTMLSelectElement.h
index d772e4d..0a2050e 100644
--- a/WebCore/html/HTMLSelectElement.h
+++ b/WebCore/html/HTMLSelectElement.h
@@ -76,7 +76,7 @@ public:
     Node* namedItem(const AtomicString& name);
     Node* item(unsigned index);
 
-    CollectionCache* collectionInfo() { return &m_collectionInfo; }
+    CollectionCache* collectionInfo() { m_collectionInfo.checkConsistency(); return &m_collectionInfo; }
 
     void scrollToSelection();
 
diff --git a/WebCore/loader/loader.cpp b/WebCore/loader/loader.cpp
index a99bf87..d693341 100644
--- a/WebCore/loader/loader.cpp
+++ b/WebCore/loader/loader.cpp
@@ -125,6 +125,7 @@ void Loader::load(DocLoader* docLoader, CachedResource* resource, bool increment
     RefPtr<Host> host;
     KURL url(ParsedURLString, resource->url());
     if (url.protocolInHTTPFamily()) {
+        m_hosts.checkConsistency();
         AtomicString hostName = url.host();
         host = m_hosts.get(hostName.impl());
         if (!host) {
@@ -169,6 +170,7 @@ void Loader::servePendingRequests(Priority minimumPriority)
     m_nonHTTPProtocolHost->servePendingRequests(minimumPriority);
 
     Vector<Host*> hostsToServe;
+    m_hosts.checkConsistency();
     HostMap::iterator i = m_hosts.begin();
     HostMap::iterator end = m_hosts.end();
     for (;i != end; ++i)
@@ -205,6 +207,7 @@ void Loader::nonCacheRequestInFlight(const KURL& url)
         return;
     
     AtomicString hostName = url.host();
+    m_hosts.checkConsistency();
     RefPtr<Host> host = m_hosts.get(hostName.impl());
     if (!host) {
         host = Host::create(hostName, maxRequestsInFlightPerHost);
@@ -220,6 +223,7 @@ void Loader::nonCacheRequestComplete(const KURL& url)
         return;
     
     AtomicString hostName = url.host();
+    m_hosts.checkConsistency();
     RefPtr<Host> host = m_hosts.get(hostName.impl());
     ASSERT(host);
     if (!host)
@@ -236,6 +240,7 @@ void Loader::cancelRequests(DocLoader* docLoader)
         m_nonHTTPProtocolHost->cancelRequests(docLoader);
     
     Vector<Host*> hostsToCancel;
+    m_hosts.checkConsistency();
     HostMap::iterator i = m_hosts.begin();
     HostMap::iterator end = m_hosts.end();
     for (;i != end; ++i)
diff --git a/WebCore/page/animation/CompositeAnimation.cpp b/WebCore/page/animation/CompositeAnimation.cpp
index 8946d80..34f03c7 100644
--- a/WebCore/page/animation/CompositeAnimation.cpp
+++ b/WebCore/page/animation/CompositeAnimation.cpp
@@ -57,6 +57,7 @@ void CompositeAnimation::clearRenderer()
         }
     }
     if (!m_keyframeAnimations.isEmpty()) {
+        m_keyframeAnimations.checkConsistency();
         AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
         for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
             KeyframeAnimation* anim = it->second.get();
@@ -186,6 +187,8 @@ void CompositeAnimation::updateKeyframeAnimations(RenderObject* renderer, Render
     if (m_keyframeAnimations.isEmpty() && !targetStyle->hasAnimations())
         return;
 
+    m_keyframeAnimations.checkConsistency();
+
     AnimationNameMap::const_iterator kfend = m_keyframeAnimations.end();
     
     if (currentStyle && currentStyle->hasAnimations() && targetStyle->hasAnimations() && *(currentStyle->animations()) == *(targetStyle->animations())) {
@@ -262,6 +265,7 @@ PassRefPtr<RenderStyle> CompositeAnimation::animate(RenderObject* renderer, Rend
     // We don't do any transitions if we don't have a currentStyle (on startup).
     updateTransitions(renderer, currentStyle, targetStyle);
     updateKeyframeAnimations(renderer, currentStyle, targetStyle);
+    m_keyframeAnimations.checkConsistency();
 
     if (currentStyle) {
         // Now that we have transition objects ready, let them know about the new goal state.  We want them
@@ -295,6 +299,8 @@ PassRefPtr<RenderStyle> CompositeAnimation::getAnimatedStyle() const
             implicitAnimation->getAnimatedStyle(resultStyle);
     }
 
+    m_keyframeAnimations.checkConsistency();
+
     for (Vector<AtomicStringImpl*>::const_iterator it = m_keyframeAnimationOrderMap.begin(); it != m_keyframeAnimationOrderMap.end(); ++it) {
         RefPtr<KeyframeAnimation> keyframeAnimation = m_keyframeAnimations.get(*it);
         if (keyframeAnimation)
@@ -315,6 +321,7 @@ void CompositeAnimation::setAnimating(bool animating)
         }
     }
     if (!m_keyframeAnimations.isEmpty()) {
+        m_keyframeAnimations.checkConsistency();
         AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
         for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
             KeyframeAnimation* anim = it->second.get();
@@ -341,6 +348,7 @@ double CompositeAnimation::timeToNextService() const
         }
     }
     if (!m_keyframeAnimations.isEmpty()) {
+        m_keyframeAnimations.checkConsistency();
         AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
         for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
             KeyframeAnimation* animation = it->second.get();
@@ -362,6 +370,7 @@ PassRefPtr<KeyframeAnimation> CompositeAnimation::getAnimationForProperty(int pr
     // We want to send back the last animation with the property if there are multiples.
     // So we need to iterate through all animations
     if (!m_keyframeAnimations.isEmpty()) {
+        m_keyframeAnimations.checkConsistency();
         AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
         for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
             RefPtr<KeyframeAnimation> anim = it->second;
@@ -381,6 +390,7 @@ void CompositeAnimation::suspendAnimations()
     m_isSuspended = true;
 
     if (!m_keyframeAnimations.isEmpty()) {
+        m_keyframeAnimations.checkConsistency();
         AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
         for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
             if (KeyframeAnimation* anim = it->second.get())
@@ -405,6 +415,7 @@ void CompositeAnimation::resumeAnimations()
     m_isSuspended = false;
 
     if (!m_keyframeAnimations.isEmpty()) {
+        m_keyframeAnimations.checkConsistency();
         AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
         for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
             KeyframeAnimation* anim = it->second.get();
@@ -450,6 +461,7 @@ void CompositeAnimation::resumeOverriddenImplicitAnimations(int property)
 bool CompositeAnimation::isAnimatingProperty(int property, bool isRunningNow) const
 {
     if (!m_keyframeAnimations.isEmpty()) {
+        m_keyframeAnimations.checkConsistency();
         AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
         for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
             KeyframeAnimation* anim = it->second.get();
@@ -474,6 +486,8 @@ bool CompositeAnimation::pauseAnimationAtTime(const AtomicString& name, double t
     if (!name)
         return false;
 
+    m_keyframeAnimations.checkConsistency();
+
     RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(name.impl());
     if (!keyframeAnim || !keyframeAnim->running())
         return false;
@@ -509,6 +523,7 @@ unsigned CompositeAnimation::numberOfActiveAnimations() const
     unsigned count = 0;
     
     if (!m_keyframeAnimations.isEmpty()) {
+        m_keyframeAnimations.checkConsistency();
         AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
         for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
             KeyframeAnimation* anim = it->second.get();
diff --git a/WebCore/platform/TreeShared.h b/WebCore/platform/TreeShared.h
index a60ad0d..b844e5f 100644
--- a/WebCore/platform/TreeShared.h
+++ b/WebCore/platform/TreeShared.h
@@ -44,6 +44,7 @@ public:
     virtual ~TreeShared()
     {
         ASSERT(isMainThread());
+        ASSERT(!m_refCount);
         ASSERT(m_deletionHasBegun);
     }
 
@@ -58,6 +59,7 @@ public:
     void deref()
     {
         ASSERT(isMainThread());
+        ASSERT(m_refCount >= 0);
         ASSERT(!m_deletionHasBegun);
         ASSERT(!m_inRemovedLastRefFunction);
         if (--m_refCount <= 0 && !m_parent) {

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list