Changeset 53899 in webkit


Ignore:
Timestamp:
Jan 26, 2010 9:57:34 PM (14 years ago)
Author:
ap@apple.com
Message:

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.
Location:
trunk
Files:
21 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r53891 r53899  
     12010-01-26  Alexey Proskuryakov  <ap@apple.com>
     2
     3        Reviewed by Darin Adler.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=34150
     6        WebKit needs a mechanism to catch stale HashMap entries
     7
     8        It is very difficult to catch stale pointers that are HashMap keys - since a pointer's hash
     9        is just its value, it is very unlikely that any observable problem is reproducible.
     10
     11        This extends hash table consistency checks to check that pointers are referencing allocated
     12        memory blocks, and makes it possible to invoke the checks explicitly (it is not feasible
     13        to enable CHECK_HASHTABLE_CONSISTENCY by default, because that affects performance too much).
     14
     15        * wtf/HashMap.h: (WTF::::checkConsistency): Call through to HashTable implementation. We can
     16        add similar calls to HashSet and HashCountedSet, but I haven't seen hard to debug problems
     17        with those yet.
     18
     19        * wtf/HashSet.h: (WTF::::remove): The version of checkTableConsistency that's guarded by
     20        CHECK_HASHTABLE_CONSISTENCY is now called internalCheckTableConsistency().
     21
     22        * wtf/HashTable.h:
     23        (WTF::HashTable::internalCheckTableConsistency):
     24        (WTF::HashTable::internalCheckTableConsistencyExceptSize):
     25        (WTF::HashTable::checkTableConsistencyExceptSize):
     26        Expose checkTableConsistency() even if CHECK_HASHTABLE_CONSISTENCY is off.
     27        (WTF::::add): Updated for checkTableConsistency renaming.
     28        (WTF::::addPassingHashCode): Ditto.
     29        (WTF::::removeAndInvalidate): Ditto.
     30        (WTF::::remove): Ditto.
     31        (WTF::::rehash): Ditto.
     32        (WTF::::checkTableConsistency): The assertion for !shouldExpand() was not correct - this
     33        function returns true for tables with m_table == 0.
     34        (WTF::::checkTableConsistencyExceptSize): Call checkValueConsistency for key. Potentially,
     35        we could do the same for values.
     36
     37        * wtf/HashTraits.h:
     38        (WTF::GenericHashTraits::checkValueConsistency): An empty function that can be overridden
     39        to add checks. Currently, the only override is for pointer hashes.
     40
     41        * wtf/RefPtrHashMap.h: (WTF::::remove): Updated for checkTableConsistency renaming.
     42
    1432010-01-26  Lyon Chen  <liachen@rim.com>
    244
  • trunk/JavaScriptCore/wtf/HashMap.h

    r51566 r53899  
    101101        template<typename T, typename HashTranslator> pair<iterator, bool> add(const T&, const MappedType&);
    102102
     103        void checkConsistency() const;
     104
    103105    private:
    104106        pair<iterator, bool> inlineAdd(const KeyType&, const MappedType&);
     
    282284        if (it.m_impl == m_impl.end())
    283285            return;
    284         m_impl.checkTableConsistency();
     286        m_impl.internalCheckTableConsistency();
    285287        m_impl.removeWithoutEntryConsistencyCheck(it.m_impl);
    286288    }
     
    310312        return result;
    311313    }
     314
     315    template<typename T, typename U, typename V, typename W, typename X>
     316    inline void HashMap<T, U, V, W, X>::checkConsistency() const
     317    {
     318        m_impl.checkTableConsistency();
     319    }
     320
    312321
    313322    template<typename T, typename U, typename V, typename W, typename X>
  • trunk/JavaScriptCore/wtf/HashSet.h

    r51566 r53899  
    225225        if (it.m_impl == m_impl.end())
    226226            return;
    227         m_impl.checkTableConsistency();
     227        m_impl.internalCheckTableConsistency();
    228228        m_impl.removeWithoutEntryConsistencyCheck(it.m_impl);
    229229    }
  • trunk/JavaScriptCore/wtf/HashTable.h

    r53151 r53899  
    3131
    3232#define DUMP_HASHTABLE_STATS 0
     33// Enables internal WTF consistency checks that are invoked automatically. Non-WTF callers can call checkTableConsistency() even if internal checks are disabled.
    3334#define CHECK_HASHTABLE_CONSISTENCY 0
    3435
     
    341342        template<typename T, typename HashTranslator> ValueType* lookup(const T&);
    342343
    343 #if CHECK_HASHTABLE_CONSISTENCY
     344#if !ASSERT_DISABLED
    344345        void checkTableConsistency() const;
    345346#else
    346347        static void checkTableConsistency() { }
     348#endif
     349#if CHECK_HASHTABLE_CONSISTENCY
     350        void internalCheckTableConsistency() const { checkTableConsistency(); }
     351        void internalCheckTableConsistencyExceptSize() const { checkTableConsistencyExceptSize(); }
     352#else
     353        static void internalCheckTableConsistencyExceptSize() { }
     354        static void internalCheckTableConsistency() { }
    347355#endif
    348356
     
    384392        const_iterator makeKnownGoodConstIterator(ValueType* pos) const { return const_iterator(this, pos, m_table + m_tableSize, HashItemKnownGood); }
    385393
    386 #if CHECK_HASHTABLE_CONSISTENCY
     394#if !ASSERT_DISABLED
    387395        void checkTableConsistencyExceptSize() const;
    388396#else
    389         static void checkTableConsistencyExceptSize() { }
     397        static void checkTableConsistencyExceptSize() const { }
    390398#endif
    391399
     
    625633            expand();
    626634
    627         checkTableConsistency();
     635        internalCheckTableConsistency();
    628636
    629637        ASSERT(m_table);
     
    694702        }
    695703       
    696         checkTableConsistency();
     704        internalCheckTableConsistency();
    697705       
    698706        return std::make_pair(makeKnownGoodIterator(entry), true);
     
    710718            expand();
    711719
    712         checkTableConsistency();
     720        internalCheckTableConsistency();
    713721
    714722        FullLookupType lookupResult = fullLookupForWriting<T, HashTranslator>(key);
     
    739747        }
    740748
    741         checkTableConsistency();
     749        internalCheckTableConsistency();
    742750
    743751        return std::make_pair(makeKnownGoodIterator(entry), true);
     
    806814    {
    807815        invalidateIterators();
    808         checkTableConsistency();
     816        internalCheckTableConsistency();
    809817        remove(pos);
    810818    }
     
    824832            shrink();
    825833
    826         checkTableConsistency();
     834        internalCheckTableConsistency();
    827835    }
    828836
     
    893901    void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::rehash(int newTableSize)
    894902    {
    895         checkTableConsistencyExceptSize();
     903        internalCheckTableConsistencyExceptSize();
    896904
    897905        int oldTableSize = m_tableSize;
     
    915923        deallocateTable(oldTable, oldTableSize);
    916924
    917         checkTableConsistency();
     925        internalCheckTableConsistency();
    918926    }
    919927
     
    982990    }
    983991
    984 #if CHECK_HASHTABLE_CONSISTENCY
     992#if !ASSERT_DISABLED
    985993
    986994    template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>
     
    988996    {
    989997        checkTableConsistencyExceptSize();
    990         ASSERT(!shouldExpand());
     998        ASSERT(!m_table || !shouldExpand());
    991999        ASSERT(!shouldShrink());
    9921000    }
     
    10131021            ASSERT(entry == it.m_position);
    10141022            ++count;
     1023
     1024            KeyTraits::checkValueConsistency(it->first);
    10151025        }
    10161026
     
    10221032    }
    10231033
    1024 #endif // CHECK_HASHTABLE_CONSISTENCY
     1034#endif // ASSERT_DISABLED
    10251035
    10261036#if CHECK_HASHTABLE_ITERATORS
  • trunk/JavaScriptCore/wtf/HashTraits.h

    r40678 r53899  
    2727#include <limits>
    2828
     29#if OS(DARWIN)
     30#include <malloc/malloc.h>
     31#endif
     32
    2933namespace WTF {
    3034
     
    5256        typedef T TraitType;
    5357        static T emptyValue() { return T(); }
     58        static void checkValueConsistency(const T&) { }
    5459    };
    5560
     
    8085        static void constructDeletedValue(P*& slot) { slot = reinterpret_cast<P*>(-1); }
    8186        static bool isDeletedValue(P* value) { return value == reinterpret_cast<P*>(-1); }
     87#if !ASSERT_DISABLED
     88        static void checkValueConsistency(const P* p)
     89        {
     90#if (defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC) || !defined(NDEBUG)
     91#if OS(DARWIN)
     92            ASSERT(malloc_size(p));
     93#elif COMPILER(MSVC)
     94            ASSERT(_msize(p));
     95#endif
     96#endif
     97            HashTraits<P>::checkValueConsistency(*p);
     98        }
     99#endif
    82100    };
    83101
  • trunk/JavaScriptCore/wtf/RefPtrHashMap.h

    r46675 r53899  
    286286        if (it.m_impl == m_impl.end())
    287287            return;
    288         m_impl.checkTableConsistency();
     288        m_impl.internalCheckTableConsistency();
    289289        m_impl.removeWithoutEntryConsistencyCheck(it.m_impl);
    290290    }
  • trunk/WebCore/ChangeLog

    r53897 r53899  
     12010-01-26  Alexey Proskuryakov  <ap@apple.com>
     2
     3        Reviewed by Darin Adler.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=34150
     6        WebKit needs a mechanism to catch stale HashMap entries
     7
     8        * WebCore.xcodeproj/project.pbxproj: Added ContainerNodeAlgorithms.h to the project to make
     9        it easier to search for.
     10
     11        * css/CSSStyleSelector.cpp:
     12        (WebCore::CSSRuleSet::getIDRules):
     13        (WebCore::CSSRuleSet::getClassRules):
     14        (WebCore::CSSRuleSet::getTagRules):
     15        (WebCore::CSSStyleSelector::keyframeStylesForAnimation):
     16        * dom/CheckedRadioButtons.cpp:
     17        (WebCore::CheckedRadioButtons::checkedButtonForGroup):
     18        (WebCore::CheckedRadioButtons::removeButton):
     19        * dom/Document.cpp:
     20        (WebCore::Document::getElementById):
     21        (WebCore::Document::removeElementById):
     22        (WebCore::Document::removeImageMap):
     23        (WebCore::Document::getImageMap):
     24        (WebCore::Document::nameCollectionInfo):
     25        * dom/Document.h:
     26        (WebCore::Document::collectionInfo):
     27        * editing/markup.cpp:
     28        (WebCore::shouldAddNamespaceAttr):
     29        (WebCore::appendNamespace):
     30        (WebCore::appendStartMarkup):
     31        * html/HTMLCollection.cpp:
     32        (WebCore::HTMLCollection::namedItems):
     33        (WebCore::HTMLCollection::nextNamedItem):
     34        * html/HTMLFormCollection.cpp:
     35        (WebCore::HTMLFormCollection::formCollectionInfo):
     36        * html/HTMLSelectElement.h:
     37        (WebCore::HTMLSelectElement::collectionInfo):
     38        * loader/loader.cpp:
     39        (WebCore::Loader::load):
     40        (WebCore::Loader::servePendingRequests):
     41        (WebCore::Loader::nonCacheRequestInFlight):
     42        (WebCore::Loader::nonCacheRequestComplete):
     43        (WebCore::Loader::cancelRequests):
     44        * page/animation/CompositeAnimation.cpp:
     45        (WebCore::CompositeAnimation::clearRenderer):
     46        (WebCore::CompositeAnimation::updateKeyframeAnimations):
     47        (WebCore::CompositeAnimation::animate):
     48        (WebCore::CompositeAnimation::getAnimatedStyle):
     49        (WebCore::CompositeAnimation::setAnimating):
     50        (WebCore::CompositeAnimation::timeToNextService):
     51        (WebCore::CompositeAnimation::getAnimationForProperty):
     52        (WebCore::CompositeAnimation::suspendAnimations):
     53        (WebCore::CompositeAnimation::resumeAnimations):
     54        (WebCore::CompositeAnimation::isAnimatingProperty):
     55        (WebCore::CompositeAnimation::pauseAnimationAtTime):
     56        (WebCore::CompositeAnimation::numberOfActiveAnimations):
     57        Added checkConsistency checks before lookups in HashMaps with AtomicStringImpl* keys.
     58
     59        * dom/ContainerNodeAlgorithms.h: (WebCore::removeAllChildrenInContainer): Be sure to notify
     60        about removed child nodes that can be deleted immediately.
     61
     62        * html/CollectionCache.cpp:
     63        (WebCore::CollectionCache::checkConsistency):
     64        * html/CollectionCache.h:
     65        Added a checkConsistency() method that checks both HashMaps in the cache.
     66
     67        * platform/TreeShared.h:
     68        (WebCore::TreeShared::~TreeShared): Assert that m_refCount is null. Since Nodes can be
     69        destroyed with operator delete (as done in ContainerNodeAlgorithms), this is important to check.
     70        (WebCore::TreeShared::deref): Assert that m_refCount isn't already negative.
     71
    1722010-01-26  Daniel Bates  <dbates@webkit.org>
    273
  • trunk/WebCore/css/CSSStyleSelector.cpp

    r53878 r53899  
    362362                      CSSStyleRule* rule, CSSSelector* sel);
    363363   
    364     CSSRuleDataList* getIDRules(AtomicStringImpl* key) { return m_idRules.get(key); }
    365     CSSRuleDataList* getClassRules(AtomicStringImpl* key) { return m_classRules.get(key); }
    366     CSSRuleDataList* getTagRules(AtomicStringImpl* key) { return m_tagRules.get(key); }
     364    CSSRuleDataList* getIDRules(AtomicStringImpl* key) { m_idRules.checkConsistency(); return m_idRules.get(key); }
     365    CSSRuleDataList* getClassRules(AtomicStringImpl* key) { m_classRules.checkConsistency(); return m_classRules.get(key); }
     366    CSSRuleDataList* getTagRules(AtomicStringImpl* key) { m_tagRules.checkConsistency(); return m_tagRules.get(key); }
    367367    CSSRuleDataList* getUniversalRules() { return m_universalRules; }
    368368   
     
    13021302    if (!e || list.animationName().isEmpty())
    13031303        return;
    1304            
     1304
     1305    m_keyframesRuleMap.checkConsistency();
     1306   
    13051307    if (!m_keyframesRuleMap.contains(list.animationName().impl()))
    13061308        return;
  • trunk/WebCore/dom/CheckedRadioButtons.cpp

    r42084 r53899  
    6161    if (!m_nameToCheckedRadioButtonMap)
    6262        return 0;
     63
     64    m_nameToCheckedRadioButtonMap->checkConsistency();
    6365   
    6466    return m_nameToCheckedRadioButtonMap->get(name.impl());
     
    7072        return;
    7173   
     74    m_nameToCheckedRadioButtonMap->checkConsistency();
     75
    7276    NameToInputMap::iterator it = m_nameToCheckedRadioButtonMap->find(element->name().impl());
    7377    if (it == m_nameToCheckedRadioButtonMap->end() || it->second != element)
  • trunk/WebCore/dom/ContainerNodeAlgorithms.h

    r36866 r53899  
    3434    void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer* container);
    3535
     36    template<class GenericNode, bool dispatchRemovalNotification>
     37    struct NodeRemovalDispatcher;
     38
     39    template<class GenericNode>
     40    struct ShouldDispatchRemovalNotification;
     41
    3642};
    3743
     
    6268            Private::addChildNodesToDeletionQueue<GenericNode, GenericNodeContainer>(head, tail, static_cast<GenericNodeContainer*>(n));
    6369
     70        Private::NodeRemovalDispatcher<GenericNode, Private::ShouldDispatchRemovalNotification<GenericNode>::value>::dispatch(n);
    6471        delete n;
    6572    }
  • trunk/WebCore/dom/Document.cpp

    r53878 r53899  
    885885        return 0;
    886886
     887    m_elementsById.checkConsistency();
     888
    887889    Element* element = m_elementsById.get(elementId.impl());
    888890    if (element)
     
    10761078void Document::removeElementById(const AtomicString& elementId, Element* element)
    10771079{
     1080    m_elementsById.checkConsistency();
     1081
    10781082    if (m_elementsById.get(elementId.impl()) == element)
    10791083        m_elementsById.remove(elementId.impl());
     
    33583362        return;
    33593363
     3364    m_imageMapsByName.checkConsistency();
     3365
    33603366    ImageMapsByName::iterator it = m_imageMapsByName.find(name.impl());
    33613367    if (it != m_imageMapsByName.end() && it->second == imageMap)
     
    33703376    String name = (hashPos < 0 ? url : url.substring(hashPos + 1)).impl();
    33713377    AtomicString mapName = isHTMLDocument() ? name.lower() : name;
     3378    m_imageMapsByName.checkConsistency();
    33723379    return m_imageMapsByName.get(mapName.impl());
    33733380}
     
    41754182    if (iter == map.end())
    41764183        iter = map.add(name.impl(), new CollectionCache).first;
     4184    iter->second->checkConsistency();
    41774185    return iter->second;
    41784186}
  • trunk/WebCore/dom/Document.h

    r53878 r53899  
    350350        unsigned index = type - FirstUnnamedDocumentCachedType;
    351351        ASSERT(index < NumUnnamedDocumentCachedTypes);
     352        m_collectionInfo[index].checkConsistency();
    352353        return &m_collectionInfo[index];
    353354    }
  • trunk/WebCore/editing/markup.cpp

    r53442 r53899  
    316316static bool shouldAddNamespaceAttr(const Attribute* attr, HashMap<AtomicStringImpl*, AtomicStringImpl*>& namespaces)
    317317{
     318    namespaces.checkConsistency();
     319
    318320    // Don't add namespace attributes twice
    319321    if (attr->name() == XMLNSNames::xmlnsAttr) {
     
    333335static void appendNamespace(Vector<UChar>& result, const AtomicString& prefix, const AtomicString& ns, HashMap<AtomicStringImpl*, AtomicStringImpl*>& namespaces)
    334336{
     337    namespaces.checkConsistency();
    335338    if (ns.isEmpty())
    336339        return;
     
    393396static void appendStartMarkup(Vector<UChar>& result, const Node* node, const Range* range, EAnnotateForInterchange annotate, bool convertBlocksToInlines = false, HashMap<AtomicStringImpl*, AtomicStringImpl*>* namespaces = 0, RangeFullySelectsNode rangeFullySelectsNode = DoesFullySelectNode)
    394397{
     398    if (namespaces)
     399        namespaces->checkConsistency();
     400
    395401    bool documentIsHTML = node->document()->isHTMLDocument();
    396402    switch (node->nodeType()) {
  • trunk/WebCore/html/CollectionCache.cpp

    r43187 r53899  
    8686}
    8787
     88#if !ASSERT_DISABLED
     89void CollectionCache::checkConsistency()
     90{
     91    idCache.checkConsistency();
     92    nameCache.checkConsistency();
     93}
     94#endif
     95
    8896} // namespace WebCore
  • trunk/WebCore/html/CollectionCache.h

    r51693 r53899  
    4444    void swap(CollectionCache&);
    4545
     46    void checkConsistency();
     47
    4648    typedef HashMap<AtomicStringImpl*, Vector<Element*>*> NodeCacheMap;
    4749
     
    6062};
    6163
     64#if ASSERT_DISABLED
     65    inline void CollectionCache::checkConsistency() { }
     66#endif
     67
    6268} // namespace
    6369
  • trunk/WebCore/html/HTMLCollection.cpp

    r52312 r53899  
    359359    resetCollectionInfo();
    360360    updateNameCache();
    361    
     361    m_info->checkConsistency();
     362
    362363    Vector<Element*>* idResults = m_info->idCache.get(name.impl());
    363364    Vector<Element*>* nameResults = m_info->nameCache.get(name.impl());
     
    374375{
    375376    resetCollectionInfo();
     377    m_info->checkConsistency();
    376378
    377379    for (Element* e = itemAfter(m_info->current); e; e = itemAfter(e)) {
  • trunk/WebCore/html/HTMLFormCollection.cpp

    r52312 r53899  
    4141    if (!form->collectionInfo)
    4242        form->collectionInfo = new CollectionCache;
     43    form->collectionInfo->checkConsistency();
    4344    return form->collectionInfo;
    4445}
  • trunk/WebCore/html/HTMLSelectElement.h

    r53761 r53899  
    7777    Node* item(unsigned index);
    7878
    79     CollectionCache* collectionInfo() { return &m_collectionInfo; }
     79    CollectionCache* collectionInfo() { m_collectionInfo.checkConsistency(); return &m_collectionInfo; }
    8080
    8181    void scrollToSelection();
  • trunk/WebCore/loader/loader.cpp

    r52456 r53899  
    126126    KURL url(ParsedURLString, resource->url());
    127127    if (url.protocolInHTTPFamily()) {
     128        m_hosts.checkConsistency();
    128129        AtomicString hostName = url.host();
    129130        host = m_hosts.get(hostName.impl());
     
    170171
    171172    Vector<Host*> hostsToServe;
     173    m_hosts.checkConsistency();
    172174    HostMap::iterator i = m_hosts.begin();
    173175    HostMap::iterator end = m_hosts.end();
     
    206208   
    207209    AtomicString hostName = url.host();
     210    m_hosts.checkConsistency();
    208211    RefPtr<Host> host = m_hosts.get(hostName.impl());
    209212    if (!host) {
     
    221224   
    222225    AtomicString hostName = url.host();
     226    m_hosts.checkConsistency();
    223227    RefPtr<Host> host = m_hosts.get(hostName.impl());
    224228    ASSERT(host);
     
    237241   
    238242    Vector<Host*> hostsToCancel;
     243    m_hosts.checkConsistency();
    239244    HostMap::iterator i = m_hosts.begin();
    240245    HostMap::iterator end = m_hosts.end();
  • trunk/WebCore/page/animation/CompositeAnimation.cpp

    r46727 r53899  
    5858    }
    5959    if (!m_keyframeAnimations.isEmpty()) {
     60        m_keyframeAnimations.checkConsistency();
    6061        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
    6162        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
     
    187188        return;
    188189
     190    m_keyframeAnimations.checkConsistency();
     191
    189192    AnimationNameMap::const_iterator kfend = m_keyframeAnimations.end();
    190193   
     
    263266    updateTransitions(renderer, currentStyle, targetStyle);
    264267    updateKeyframeAnimations(renderer, currentStyle, targetStyle);
     268    m_keyframeAnimations.checkConsistency();
    265269
    266270    if (currentStyle) {
     
    296300    }
    297301
     302    m_keyframeAnimations.checkConsistency();
     303
    298304    for (Vector<AtomicStringImpl*>::const_iterator it = m_keyframeAnimationOrderMap.begin(); it != m_keyframeAnimationOrderMap.end(); ++it) {
    299305        RefPtr<KeyframeAnimation> keyframeAnimation = m_keyframeAnimations.get(*it);
     
    316322    }
    317323    if (!m_keyframeAnimations.isEmpty()) {
     324        m_keyframeAnimations.checkConsistency();
    318325        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
    319326        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
     
    342349    }
    343350    if (!m_keyframeAnimations.isEmpty()) {
     351        m_keyframeAnimations.checkConsistency();
    344352        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
    345353        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
     
    363371    // So we need to iterate through all animations
    364372    if (!m_keyframeAnimations.isEmpty()) {
     373        m_keyframeAnimations.checkConsistency();
    365374        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
    366375        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
     
    382391
    383392    if (!m_keyframeAnimations.isEmpty()) {
     393        m_keyframeAnimations.checkConsistency();
    384394        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
    385395        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
     
    406416
    407417    if (!m_keyframeAnimations.isEmpty()) {
     418        m_keyframeAnimations.checkConsistency();
    408419        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
    409420        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
     
    451462{
    452463    if (!m_keyframeAnimations.isEmpty()) {
     464        m_keyframeAnimations.checkConsistency();
    453465        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
    454466        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
     
    474486    if (!name)
    475487        return false;
     488
     489    m_keyframeAnimations.checkConsistency();
    476490
    477491    RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(name.impl());
     
    510524   
    511525    if (!m_keyframeAnimations.isEmpty()) {
     526        m_keyframeAnimations.checkConsistency();
    512527        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
    513528        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
  • trunk/WebCore/platform/TreeShared.h

    r51158 r53899  
    4545    {
    4646        ASSERT(isMainThread());
     47        ASSERT(!m_refCount);
    4748        ASSERT(m_deletionHasBegun);
    4849    }
     
    5960    {
    6061        ASSERT(isMainThread());
     62        ASSERT(m_refCount >= 0);
    6163        ASSERT(!m_deletionHasBegun);
    6264        ASSERT(!m_inRemovedLastRefFunction);
Note: See TracChangeset for help on using the changeset viewer.