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.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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.