OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights | 2 * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights |
3 * reserved. | 3 * reserved. |
4 * Copyright (C) 2008 David Levin <levin@chromium.org> | 4 * Copyright (C) 2008 David Levin <levin@chromium.org> |
5 * | 5 * |
6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
10 * | 10 * |
(...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 void trace(VisitorDispatcher); | 785 void trace(VisitorDispatcher); |
786 | 786 |
787 #if DCHECK_IS_ON() | 787 #if DCHECK_IS_ON() |
788 void enterAccessForbiddenScope() { | 788 void enterAccessForbiddenScope() { |
789 DCHECK(!m_accessForbidden); | 789 DCHECK(!m_accessForbidden); |
790 m_accessForbidden = true; | 790 m_accessForbidden = true; |
791 } | 791 } |
792 void leaveAccessForbiddenScope() { m_accessForbidden = false; } | 792 void leaveAccessForbiddenScope() { m_accessForbidden = false; } |
793 bool accessForbidden() const { return m_accessForbidden; } | 793 bool accessForbidden() const { return m_accessForbidden; } |
794 int64_t modifications() const { return m_modifications; } | 794 int64_t modifications() const { return m_modifications; } |
| 795 void checkCreationThread() const { |
| 796 DCHECK(!Allocator::isGarbageCollected || |
| 797 m_creationThread == currentThread()); |
| 798 } |
795 void registerModification() { m_modifications++; } | 799 void registerModification() { m_modifications++; } |
796 // HashTable and collections that build on it do not support modifications | 800 // HashTable and collections that build on it do not support modifications |
797 // while there is an iterator in use. The exception is ListHashSet, which | 801 // while there is an iterator in use. The exception is ListHashSet, which |
798 // has its own iterators that tolerate modification of the underlying set. | 802 // has its own iterators that tolerate modification of the underlying set. |
799 void checkModifications(int64_t mods) const { | 803 void checkModifications(int64_t mods) const { |
800 DCHECK_EQ(mods, m_modifications); | 804 DCHECK_EQ(mods, m_modifications); |
801 } | 805 } |
802 #else | 806 #else |
803 ALWAYS_INLINE void enterAccessForbiddenScope() {} | 807 ALWAYS_INLINE void enterAccessForbiddenScope() {} |
804 ALWAYS_INLINE void leaveAccessForbiddenScope() {} | 808 ALWAYS_INLINE void leaveAccessForbiddenScope() {} |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
887 bool enqueued() { return m_queueFlag; } | 891 bool enqueued() { return m_queueFlag; } |
888 | 892 |
889 ValueType* m_table; | 893 ValueType* m_table; |
890 unsigned m_tableSize; | 894 unsigned m_tableSize; |
891 unsigned m_keyCount; | 895 unsigned m_keyCount; |
892 #if DCHECK_IS_ON() | 896 #if DCHECK_IS_ON() |
893 unsigned m_deletedCount : 30; | 897 unsigned m_deletedCount : 30; |
894 unsigned m_queueFlag : 1; | 898 unsigned m_queueFlag : 1; |
895 unsigned m_accessForbidden : 1; | 899 unsigned m_accessForbidden : 1; |
896 unsigned m_modifications; | 900 unsigned m_modifications; |
| 901 ThreadIdentifier m_creationThread; |
897 #else | 902 #else |
898 unsigned m_deletedCount : 31; | 903 unsigned m_deletedCount : 31; |
899 unsigned m_queueFlag : 1; | 904 unsigned m_queueFlag : 1; |
900 #endif | 905 #endif |
901 | 906 |
902 #if DUMP_HASHTABLE_STATS_PER_TABLE | 907 #if DUMP_HASHTABLE_STATS_PER_TABLE |
903 public: | 908 public: |
904 mutable | 909 mutable |
905 typename std::conditional<Allocator::isGarbageCollected, | 910 typename std::conditional<Allocator::isGarbageCollected, |
906 HashTableStats*, | 911 HashTableStats*, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
942 #if DCHECK_IS_ON() | 947 #if DCHECK_IS_ON() |
943 , | 948 , |
944 m_accessForbidden(false), | 949 m_accessForbidden(false), |
945 m_modifications(0) | 950 m_modifications(0) |
946 #endif | 951 #endif |
947 #if DUMP_HASHTABLE_STATS_PER_TABLE | 952 #if DUMP_HASHTABLE_STATS_PER_TABLE |
948 , | 953 , |
949 m_stats(nullptr) | 954 m_stats(nullptr) |
950 #endif | 955 #endif |
951 { | 956 { |
| 957 #if DCHECK_IS_ON() |
| 958 if (Allocator::isGarbageCollected) |
| 959 m_creationThread = currentThread(); |
| 960 #endif |
952 static_assert(Allocator::isGarbageCollected || | 961 static_assert(Allocator::isGarbageCollected || |
953 (!IsPointerToGarbageCollectedType<Key>::value && | 962 (!IsPointerToGarbageCollectedType<Key>::value && |
954 !IsPointerToGarbageCollectedType<Value>::value), | 963 !IsPointerToGarbageCollectedType<Value>::value), |
955 "Cannot put raw pointers to garbage-collected classes into an " | 964 "Cannot put raw pointers to garbage-collected classes into an " |
956 "off-heap collection."); | 965 "off-heap collection."); |
957 } | 966 } |
958 | 967 |
959 inline unsigned doubleHash(unsigned key) { | 968 inline unsigned doubleHash(unsigned key) { |
960 key = ~key + (key >> 23); | 969 key = ~key + (key >> 23); |
961 key ^= (key << 12); | 970 key ^= (key << 12); |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1223 template <typename HashTranslator, typename T, typename Extra> | 1232 template <typename HashTranslator, typename T, typename Extra> |
1224 typename HashTable<Key, | 1233 typename HashTable<Key, |
1225 Value, | 1234 Value, |
1226 Extractor, | 1235 Extractor, |
1227 HashFunctions, | 1236 HashFunctions, |
1228 Traits, | 1237 Traits, |
1229 KeyTraits, | 1238 KeyTraits, |
1230 Allocator>::AddResult | 1239 Allocator>::AddResult |
1231 HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>:: | 1240 HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>:: |
1232 add(T&& key, Extra&& extra) { | 1241 add(T&& key, Extra&& extra) { |
| 1242 checkCreationThread(); |
1233 DCHECK(!accessForbidden()); | 1243 DCHECK(!accessForbidden()); |
1234 DCHECK(Allocator::isAllocationAllowed()); | 1244 DCHECK(Allocator::isAllocationAllowed()); |
1235 if (!m_table) | 1245 if (!m_table) |
1236 expand(); | 1246 expand(); |
1237 | 1247 |
1238 DCHECK(m_table); | 1248 DCHECK(m_table); |
1239 | 1249 |
1240 ValueType* table = m_table; | 1250 ValueType* table = m_table; |
1241 size_t k = 0; | 1251 size_t k = 0; |
1242 size_t sizeMask = tableSizeMask(); | 1252 size_t sizeMask = tableSizeMask(); |
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1820 #if DCHECK_IS_ON() | 1830 #if DCHECK_IS_ON() |
1821 , | 1831 , |
1822 m_accessForbidden(false), | 1832 m_accessForbidden(false), |
1823 m_modifications(0) | 1833 m_modifications(0) |
1824 #endif | 1834 #endif |
1825 #if DUMP_HASHTABLE_STATS_PER_TABLE | 1835 #if DUMP_HASHTABLE_STATS_PER_TABLE |
1826 , | 1836 , |
1827 m_stats(HashTableStatsPtr<Allocator>::copy(other.m_stats)) | 1837 m_stats(HashTableStatsPtr<Allocator>::copy(other.m_stats)) |
1828 #endif | 1838 #endif |
1829 { | 1839 { |
| 1840 #if DCHECK_IS_ON() |
| 1841 if (Allocator::isGarbageCollected) |
| 1842 m_creationThread = currentThread(); |
| 1843 #endif |
1830 if (other.size()) | 1844 if (other.size()) |
1831 reserveCapacityForSize(other.size()); | 1845 reserveCapacityForSize(other.size()); |
1832 // Copy the hash table the dumb way, by adding each element to the new | 1846 // Copy the hash table the dumb way, by adding each element to the new |
1833 // table. It might be more efficient to copy the table slots, but it's not | 1847 // table. It might be more efficient to copy the table slots, but it's not |
1834 // clear that efficiency is needed. | 1848 // clear that efficiency is needed. |
1835 for (const auto& element : other) | 1849 for (const auto& element : other) |
1836 add(element); | 1850 add(element); |
1837 } | 1851 } |
1838 | 1852 |
1839 template <typename Key, | 1853 template <typename Key, |
(...skipping 13 matching lines...) Expand all Loading... |
1853 #if DCHECK_IS_ON() | 1867 #if DCHECK_IS_ON() |
1854 , | 1868 , |
1855 m_accessForbidden(false), | 1869 m_accessForbidden(false), |
1856 m_modifications(0) | 1870 m_modifications(0) |
1857 #endif | 1871 #endif |
1858 #if DUMP_HASHTABLE_STATS_PER_TABLE | 1872 #if DUMP_HASHTABLE_STATS_PER_TABLE |
1859 , | 1873 , |
1860 m_stats(HashTableStatsPtr<Allocator>::copy(other.m_stats)) | 1874 m_stats(HashTableStatsPtr<Allocator>::copy(other.m_stats)) |
1861 #endif | 1875 #endif |
1862 { | 1876 { |
| 1877 #if DCHECK_IS_ON() |
| 1878 if (Allocator::isGarbageCollected) |
| 1879 m_creationThread = currentThread(); |
| 1880 #endif |
1863 swap(other); | 1881 swap(other); |
1864 } | 1882 } |
1865 | 1883 |
1866 template <typename Key, | 1884 template <typename Key, |
1867 typename Value, | 1885 typename Value, |
1868 typename Extractor, | 1886 typename Extractor, |
1869 typename HashFunctions, | 1887 typename HashFunctions, |
1870 typename Traits, | 1888 typename Traits, |
1871 typename KeyTraits, | 1889 typename KeyTraits, |
1872 typename Allocator> | 1890 typename Allocator> |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2271 CollectionIterator end(toBeRemoved.end()); | 2289 CollectionIterator end(toBeRemoved.end()); |
2272 for (CollectionIterator it(toBeRemoved.begin()); it != end; ++it) | 2290 for (CollectionIterator it(toBeRemoved.begin()); it != end; ++it) |
2273 collection.erase(*it); | 2291 collection.erase(*it); |
2274 } | 2292 } |
2275 | 2293 |
2276 } // namespace WTF | 2294 } // namespace WTF |
2277 | 2295 |
2278 #include "wtf/HashIterators.h" | 2296 #include "wtf/HashIterators.h" |
2279 | 2297 |
2280 #endif // WTF_HashTable_h | 2298 #endif // WTF_HashTable_h |
OLD | NEW |