Changeset 27710 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Nov 11, 2007, 10:44:26 PM (18 years ago)
Author:
Adam Roben
Message:

Fix <rdar://5578982> ASSERT in HashTable::checkTableConsistencyExceptSize beneath WebNotificationCenter

The bug was due to a mismatch between HashMap::remove and
HashTable::checkTableConsistency. HashMap::remove can delete the value
stored in the HashTable (by derefing it), which is not normally
allowed by HashTable. It's OK in this case because the value is about
to be removed from the table, but HashTable wasn't aware of this.

HashMap::remove now performs the consistency check itself before
derefing the value.

Darin noticed that the same bug would occur in HashSet, so I've fixed
it there as well.

Reviewed by Darin.

  • wtf/HashMap.h: (WTF::HashMap::remove): Perform the HashTable consistency check manually before calling deref.
  • wtf/HashSet.h: (WTF::HashSet::remove): Ditto.
  • wtf/HashTable.h: Made checkTableConsistency public so that HashMap and HashSet can call it. (WTF::HashTable::removeAndInvalidateWithoutEntryConsistencyCheck): Added. (WTF::HashTable::removeAndInvalidate): Added. (WTF::HashTable::remove): (WTF::HashTable::removeWithoutEntryConsistencyCheck): Added.
Location:
trunk/JavaScriptCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r27709 r27710  
     12007-11-11  Adam Roben  <[email protected]>
     2
     3        Fix <rdar://5578982> ASSERT in HashTable::checkTableConsistencyExceptSize beneath WebNotificationCenter
     4
     5        The bug was due to a mismatch between HashMap::remove and
     6        HashTable::checkTableConsistency. HashMap::remove can delete the value
     7        stored in the HashTable (by derefing it), which is not normally
     8        allowed by HashTable. It's OK in this case because the value is about
     9        to be removed from the table, but HashTable wasn't aware of this.
     10
     11        HashMap::remove now performs the consistency check itself before
     12        derefing the value.
     13
     14        Darin noticed that the same bug would occur in HashSet, so I've fixed
     15        it there as well.
     16
     17        Reviewed by Darin.
     18
     19        * wtf/HashMap.h:
     20        (WTF::HashMap::remove): Perform the HashTable consistency check
     21        manually before calling deref.
     22        * wtf/HashSet.h:
     23        (WTF::HashSet::remove): Ditto.
     24        * wtf/HashTable.h: Made checkTableConsistency public so that HashMap
     25        and HashSet can call it.
     26        (WTF::HashTable::removeAndInvalidateWithoutEntryConsistencyCheck):
     27        Added.
     28        (WTF::HashTable::removeAndInvalidate): Added.
     29        (WTF::HashTable::remove):
     30        (WTF::HashTable::removeWithoutEntryConsistencyCheck): Added.
     31
    1322007-11-11  Mark Rowe  <[email protected]>
    233
  • trunk/JavaScriptCore/wtf/HashMap.h

    r27385 r27710  
    308308        if (it.m_impl == m_impl.end())
    309309            return;
     310        m_impl.checkTableConsistency();
    310311        RefCounter<ValueTraits, ValueStorageTraits>::deref(*it.m_impl);
    311         m_impl.remove(it.m_impl);
     312        m_impl.removeWithoutEntryConsistencyCheck(it.m_impl);
    312313    }
    313314
  • trunk/JavaScriptCore/wtf/HashSet.h

    r27176 r27710  
    285285        if (it.m_impl == m_impl.end())
    286286            return;
     287        m_impl.checkTableConsistency();
    287288        RefCounter<ValueTraits, StorageTraits>::deref(*it.m_impl);
    288         m_impl.remove(it.m_impl);
     289        m_impl.removeWithoutEntryConsistencyCheck(it.m_impl);
    289290    }
    290291
  • trunk/JavaScriptCore/wtf/HashTable.h

    r27359 r27710  
    322322        void remove(const KeyType&);
    323323        void remove(iterator);
     324        void removeWithoutEntryConsistencyCheck(iterator);
    324325        void clear();
    325326
     
    329330
    330331        ValueType* lookup(const Key& key) { return lookup<Key, IdentityTranslatorType>(key); }
     332
     333#if CHECK_HASHTABLE_CONSISTENCY
     334        void checkTableConsistency() const;
     335#else
     336        static void checkTableConsistency() { }
     337#endif
    331338
    332339    private:
     
    342349        template<typename T, typename HashTranslator> LookupType lookupForWriting(const T&);
    343350
     351        void removeAndInvalidateWithoutEntryConsistencyCheck(ValueType*);
     352        void removeAndInvalidate(ValueType*);
    344353        void remove(ValueType*);
    345354
     
    365374
    366375#if CHECK_HASHTABLE_CONSISTENCY
    367         void checkTableConsistency() const;
    368376        void checkTableConsistencyExceptSize() const;
    369377#else
    370         static void checkTableConsistency() { }
    371378        static void checkTableConsistencyExceptSize() { }
    372379#endif
     
    759766
    760767    template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>
    761     void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::remove(ValueType* pos)
     768    void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::removeAndInvalidateWithoutEntryConsistencyCheck(ValueType* pos)
     769    {
     770        invalidateIterators();
     771        remove(pos);
     772    }
     773
     774    template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>
     775    void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::removeAndInvalidate(ValueType* pos)
    762776    {
    763777        invalidateIterators();
    764778        checkTableConsistency();
    765 
     779        remove(pos);
     780    }
     781
     782    template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>
     783    void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::remove(ValueType* pos)
     784    {
    766785#if DUMP_HASHTABLE_STATS
    767786        ++HashTableStats::numRemoves;
     
    784803            return;
    785804
    786         remove(const_cast<ValueType*>(it.m_iterator.m_position));
     805        removeAndInvalidate(const_cast<ValueType*>(it.m_iterator.m_position));
     806    }
     807
     808    template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>
     809    inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::removeWithoutEntryConsistencyCheck(iterator it)
     810    {
     811        if (it == end())
     812            return;
     813
     814        removeAndInvalidateWithoutEntryConsistencyCheck(const_cast<ValueType*>(it.m_iterator.m_position));
    787815    }
    788816
Note: See TracChangeset for help on using the changeset viewer.