| Index: Source/wtf/HashTable.h
|
| diff --git a/Source/wtf/HashTable.h b/Source/wtf/HashTable.h
|
| index 6012f53e49ef9925ae8bd3f9a40c622353f56943..7330393c092dc83584c5dddd232ca0f13ab053b0 100644
|
| --- a/Source/wtf/HashTable.h
|
| +++ b/Source/wtf/HashTable.h
|
| @@ -480,7 +480,8 @@ namespace WTF {
|
| #endif
|
|
|
| private:
|
| - static ValueType* allocateTable(unsigned size);
|
| + static ValueType* allocateTable(unsigned size, void* holder);
|
| + static ValueType* allocateExpandedTable(unsigned size, void* holder);
|
| static void deleteAllBucketsAndDeallocate(ValueType* table, unsigned size);
|
|
|
| typedef std::pair<ValueType*, bool> LookupType;
|
| @@ -970,7 +971,7 @@ namespace WTF {
|
| }
|
|
|
| template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits, typename Allocator>
|
| - Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::allocateTable(unsigned size)
|
| + Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::allocateTable(unsigned size, void* holder)
|
| {
|
| size_t allocSize = size * sizeof(ValueType);
|
| ValueType* result;
|
| @@ -988,9 +989,30 @@ namespace WTF {
|
| , "Cannot put ALLOW_ONLY_INLINE_ALLOCATION objects that have trace methods into an off-heap HashTable");
|
| #endif
|
| if (Traits::emptyValueIsZero) {
|
| - result = Allocator::template allocateZeroedHashTableBacking<ValueType, HashTable>(allocSize);
|
| + result = Allocator::template allocateZeroedHashTableBacking<ValueType, HashTable>(allocSize, holder);
|
| } else {
|
| - result = Allocator::template allocateHashTableBacking<ValueType, HashTable>(allocSize);
|
| + result = Allocator::template allocateHashTableBacking<ValueType, HashTable>(allocSize, holder);
|
| + for (unsigned i = 0; i < size; i++)
|
| + initializeBucket(result[i]);
|
| + }
|
| + return result;
|
| + }
|
| +
|
| + template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits, typename Allocator>
|
| + Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::allocateExpandedTable(unsigned size, void* holder)
|
| + {
|
| + size_t allocSize = size * sizeof(ValueType);
|
| + ValueType* result;
|
| + // Assert that we will not use memset on things with a vtable entry.
|
| + // The compiler will also check this on some platforms. We would
|
| + // like to check this on the whole value (key-value pair), but
|
| + // IsPolymorphic will return false for a pair of two types, even if
|
| + // one of the components is polymorphic.
|
| + static_assert(!Traits::emptyValueIsZero || !IsPolymorphic<KeyType>::value, "empty value cannot be zero for things with a vtable");
|
| + if (Traits::emptyValueIsZero) {
|
| + result = Allocator::template allocateZeroedExpandedHashTableBacking<ValueType, HashTable>(allocSize, holder);
|
| + } else {
|
| + result = Allocator::template allocateExpandedHashTableBacking<ValueType, HashTable>(allocSize, holder);
|
| for (unsigned i = 0; i < size; i++)
|
| initializeBucket(result[i]);
|
| }
|
| @@ -1053,7 +1075,7 @@ namespace WTF {
|
| unsigned oldTableSize = m_tableSize;
|
| ValueType* originalTable = m_table;
|
|
|
| - ValueType* temporaryTable = allocateTable(oldTableSize);
|
| + ValueType* temporaryTable = allocateTable(oldTableSize, nullptr);
|
| for (unsigned i = 0; i < oldTableSize; i++) {
|
| if (&m_table[i] == entry)
|
| newEntry = &temporaryTable[i];
|
| @@ -1135,17 +1157,14 @@ template<typename Key, typename Value, typename Extractor, typename HashFunction
|
| ++m_stats->numRehashes;
|
| #endif
|
|
|
| - // The Allocator::isGarbageCollected check is not needed.
|
| - // The check is just a static hint for a compiler to indicate that
|
| - // Base::expandBuffer returns false if Allocator is a DefaultAllocator.
|
| - if (Allocator::isGarbageCollected && newTableSize > oldTableSize) {
|
| + if (newTableSize > oldTableSize) {
|
| bool success;
|
| Value* newEntry = expandBuffer(newTableSize, entry, success);
|
| if (success)
|
| return newEntry;
|
| }
|
|
|
| - ValueType* newTable = allocateTable(newTableSize);
|
| + ValueType* newTable = allocateExpandedTable(newTableSize, this);
|
| Value* newEntry = rehashTo(newTable, newTableSize, entry);
|
| deleteAllBucketsAndDeallocate(oldTable, oldTableSize);
|
|
|
|
|