Diff
Modified: trunk/Source/WTF/ChangeLog (254880 => 254881)
--- trunk/Source/WTF/ChangeLog 2020-01-21 22:04:13 UTC (rev 254880)
+++ trunk/Source/WTF/ChangeLog 2020-01-21 22:05:43 UTC (rev 254881)
@@ -1,3 +1,72 @@
+2020-01-21 Yusuke Suzuki <[email protected]>
+
+ [WTF] AtomStringTable should be small
+ https://bugs.webkit.org/show_bug.cgi?id=206400
+
+ Reviewed by Sam Weinig.
+
+ AtomStringTable is the largest hashtable typically. It takes more
+ than 256KB per WebProcess (sometimes, it took 1MB or more).
+ This patch leverages PackedPtr to compact it from 8 bytes per entry
+ to 6 bytes per entry.
+
+ While this is still large, we should investigate how to compact C++
+ pointers in 4 bytes[1] to shrink memory footprint, since WebKit
+ memory is used by Vector and HashTable fulfilled with pointers.
+
+ [1]: https://bugs.webkit.org/show_bug.cgi?id=206469
+
+ * wtf/DumbPtrTraits.h:
+ (WTF::DumbPtrTraits::hashTableDeletedValue):
+ (WTF::DumbPtrTraits::isHashTableDeletedValue):
+ * wtf/Forward.h:
+ * wtf/HashTraits.h:
+ * wtf/Packed.h:
+ (WTF::Packed<T::Packed):
+ (WTF::Packed<T::isHashTableDeletedValue const):
+ (WTF::GetPtrHelper<PackedPtr<T>>::getPtr):
+ (WTF::PackedPtrTraits::hashTableDeletedValue):
+ (WTF::PackedPtrTraits::isHashTableDeletedValue):
+ (WTF::alignof): Deleted.
+ * wtf/Ref.h:
+ (WTF::Ref::Ref):
+ (WTF::Ref::isHashTableDeletedValue const):
+ (WTF::Ref::hashTableDeletedValue): Deleted.
+ * wtf/RefPtr.h:
+ (WTF::RefPtr::RefPtr):
+ (WTF::RefPtr::isHashTableDeletedValue const):
+ (WTF::RefPtr::hashTableDeletedValue): Deleted.
+ * wtf/text/AtomStringImpl.cpp:
+ (WTF::addToStringTable):
+ (WTF::CStringTranslator::equal):
+ (WTF::CStringTranslator::translate):
+ (WTF::UCharBufferTranslator::equal):
+ (WTF::UCharBufferTranslator::translate):
+ (WTF::HashAndUTF8CharactersTranslator::equal):
+ (WTF::HashAndUTF8CharactersTranslator::translate):
+ (WTF::SubstringTranslator::translate):
+ (WTF::SubstringTranslator8::equal):
+ (WTF::SubstringTranslator16::equal):
+ (WTF::LCharBufferTranslator::equal):
+ (WTF::LCharBufferTranslator::translate):
+ (WTF::BufferFromStaticDataTranslator::equal):
+ (WTF::BufferFromStaticDataTranslator::translate):
+ (WTF::AtomStringImpl::addSlowCase):
+ (WTF::AtomStringImpl::remove):
+ (WTF::AtomStringImpl::lookUpSlowCase):
+ (WTF::AtomStringImpl::lookUp):
+ * wtf/text/AtomStringTable.cpp:
+ (WTF::AtomStringTable::~AtomStringTable):
+ * wtf/text/AtomStringTable.h:
+ (WTF::AtomStringTable::table):
+ (): Deleted.
+ * wtf/text/StringHash.h:
+ (WTF::StringHash::hash):
+ (WTF::StringHash::equal):
+ (WTF::ASCIICaseInsensitiveHash::hash):
+ (WTF::ASCIICaseInsensitiveHash::equal):
+ * wtf/text/StringImpl.h:
+
2020-01-17 Sam Weinig <[email protected]>
Platform.h is out of control Part 8: Macros are used inconsistently
Modified: trunk/Source/WTF/wtf/DumbPtrTraits.h (254880 => 254881)
--- trunk/Source/WTF/wtf/DumbPtrTraits.h 2020-01-21 22:04:13 UTC (rev 254880)
+++ trunk/Source/WTF/wtf/DumbPtrTraits.h 2020-01-21 22:05:43 UTC (rev 254881)
@@ -41,6 +41,9 @@
static ALWAYS_INLINE void swap(StorageType& a, StorageType& b) { std::swap(a, b); }
static ALWAYS_INLINE T* unwrap(const StorageType& ptr) { return ptr; }
+
+ static StorageType hashTableDeletedValue() { return bitwise_cast<StorageType>(static_cast<uintptr_t>(-1)); }
+ static ALWAYS_INLINE bool isHashTableDeletedValue(const StorageType& ptr) { return ptr == hashTableDeletedValue(); }
};
} // namespace WTF
Modified: trunk/Source/WTF/wtf/Forward.h (254880 => 254881)
--- trunk/Source/WTF/wtf/Forward.h 2020-01-21 22:04:13 UTC (rev 254880)
+++ trunk/Source/WTF/wtf/Forward.h 2020-01-21 22:05:43 UTC (rev 254881)
@@ -62,6 +62,8 @@
template<typename> class NeverDestroyed;
template<typename> class OptionSet;
template<typename> class Optional;
+template<typename T> class Packed;
+template<typename T, size_t = alignof(T)> class PackedAlignedPtr;
template<typename T, typename = DumbPtrTraits<T>> class Ref;
template<typename T, typename = DumbPtrTraits<T>> class RefPtr;
template<typename> class StringBuffer;
Modified: trunk/Source/WTF/wtf/HashTraits.h (254880 => 254881)
--- trunk/Source/WTF/wtf/HashTraits.h 2020-01-21 22:04:13 UTC (rev 254880)
+++ trunk/Source/WTF/wtf/HashTraits.h 2020-01-21 22:05:43 UTC (rev 254881)
@@ -220,6 +220,19 @@
template<typename P> struct HashTraits<Ref<P>> : RefHashTraits<P> { };
+template<typename P> struct HashTraits<Packed<P*>> : SimpleClassHashTraits<Packed<P*>> {
+ static constexpr bool hasIsEmptyValueFunction = true;
+ using TargetType = Packed<P*>;
+ static_assert(TargetType::alignment < 4 * KB, "The first page is always unmapped since it includes nullptr.");
+
+ static Packed<P*> emptyValue() { return nullptr; }
+ static bool isEmptyValue(const TargetType& value) { return value.get() == nullptr; }
+
+ using PeekType = P*;
+ static PeekType peek(const TargetType& value) { return value.get(); }
+ static PeekType peek(P* value) { return value; }
+};
+
template<> struct HashTraits<String> : SimpleClassHashTraits<String> {
static constexpr bool hasIsEmptyValueFunction = true;
static bool isEmptyValue(const String&);
Modified: trunk/Source/WTF/wtf/Packed.h (254880 => 254881)
--- trunk/Source/WTF/wtf/Packed.h 2020-01-21 22:04:13 UTC (rev 254880)
+++ trunk/Source/WTF/wtf/Packed.h 2020-01-21 22:05:43 UTC (rev 254881)
@@ -26,6 +26,9 @@
#pragma once
#include <array>
+#include <wtf/Forward.h>
+#include <wtf/GetPtr.h>
+#include <wtf/HashFunctions.h>
#include <wtf/MathExtras.h>
#include <wtf/StdLibExtras.h>
#include <wtf/UnalignedAccess.h>
@@ -100,11 +103,12 @@
// PackedAlignedPtr can take alignment parameter too. PackedAlignedPtr only uses this alignment information if it is profitable: we use
// alignment information only when we can reduce the size of the storage. Since the pointer width is 36 bits and JSCells are aligned to 16 bytes,
// we can use 4 bits in Darwin ARM64, we can compact cell pointer into 4 bytes (32 bits).
-template<typename T, size_t alignment = alignof(T)>
+template<typename T, size_t passedAlignment>
class PackedAlignedPtr {
WTF_MAKE_FAST_ALLOCATED;
public:
- static_assert(hasOneBitSet(alignment), "Alignment needs to be power-of-two");
+ static_assert(hasOneBitSet(passedAlignment), "Alignment needs to be power-of-two");
+ static constexpr size_t alignment = passedAlignment;
static constexpr bool isPackedType = true;
static constexpr unsigned alignmentShiftSizeIfProfitable = getLSBSetConstexpr(alignment);
static constexpr unsigned storageSizeWithoutAlignmentShift = roundUpToMultipleOf<8>(OS_CONSTANT(EFFECTIVE_ADDRESS_WIDTH)) / 8;
@@ -215,11 +219,26 @@
public:
using Base = PackedAlignedPtr<T, 1>;
using Base::Base;
+
+ // Hash table deleted values, which are only constructed and never copied or destroyed.
+ Packed(HashTableDeletedValueType) : Base(bitwise_cast<T*>(static_cast<uintptr_t>(Base::alignment))) { }
+ bool isHashTableDeletedValue() const { return Base::get() == bitwise_cast<T*>(static_cast<uintptr_t>(Base::alignment)); }
};
template<typename T>
using PackedPtr = Packed<T*>;
+template <typename T>
+struct GetPtrHelper<PackedPtr<T>> {
+ using PtrType = T*;
+ static T* getPtr(const PackedPtr<T>& p) { return const_cast<T*>(p.get()); }
+};
+
+template <typename T>
+struct IsSmartPtr<PackedPtr<T>> {
+ static constexpr bool value = true;
+};
+
template<typename T>
struct PackedPtrTraits {
template<typename U> using RebindTraits = PackedPtrTraits<U>;
@@ -231,8 +250,16 @@
template<typename Other> static ALWAYS_INLINE void swap(PackedPtr<T>& a, Other& b) { a.swap(b); }
static ALWAYS_INLINE T* unwrap(const StorageType& ptr) { return ptr.get(); }
+
+ // We assume that,
+ // 1. The alignment is < 4KB. (It is tested by HashTraits).
+ // 2. The first page (including nullptr) is never mapped.
+ static StorageType hashTableDeletedValue() { return StorageType { bitwise_cast<T*>(static_cast<uintptr_t>(StorageType::alignment)) }; }
+ static ALWAYS_INLINE bool isHashTableDeletedValue(const StorageType& ptr) { return ptr.get() == bitwise_cast<T*>(static_cast<uintptr_t>(StorageType::alignment)); }
};
+template<typename P> struct DefaultHash<PackedPtr<P>> { using Hash = PtrHash<PackedPtr<P>>; };
+
} // namespace WTF
using WTF::Packed;
Modified: trunk/Source/WTF/wtf/Ref.h (254880 => 254881)
--- trunk/Source/WTF/wtf/Ref.h 2020-01-21 22:04:13 UTC (rev 254880)
+++ trunk/Source/WTF/wtf/Ref.h 2020-01-21 22:05:43 UTC (rev 254881)
@@ -45,9 +45,10 @@
template<typename T, typename PtrTraits> class Ref;
template<typename T, typename PtrTraits = DumbPtrTraits<T>> Ref<T, PtrTraits> adoptRef(T&);
-template<typename T, typename PtrTraits>
+template<typename T, typename Traits>
class Ref {
public:
+ using PtrTraits = Traits;
static constexpr bool isRef = true;
~Ref()
@@ -94,9 +95,8 @@
template<typename X, typename Y> void swap(Ref<X, Y>&);
// Hash table deleted values, which are only constructed and never copied or destroyed.
- Ref(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
- bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
- static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); }
+ Ref(HashTableDeletedValueType) : m_ptr(PtrTraits::hashTableDeletedValue()) { }
+ bool isHashTableDeletedValue() const { return PtrTraits::isHashTableDeletedValue(m_ptr); }
Ref(HashTableEmptyValueType) : m_ptr(hashTableEmptyValue()) { }
bool isHashTableEmptyValue() const { return m_ptr == hashTableEmptyValue(); }
Modified: trunk/Source/WTF/wtf/RefPtr.h (254880 => 254881)
--- trunk/Source/WTF/wtf/RefPtr.h 2020-01-21 22:04:13 UTC (rev 254880)
+++ trunk/Source/WTF/wtf/RefPtr.h 2020-01-21 22:05:43 UTC (rev 254881)
@@ -44,10 +44,11 @@
ptr->deref();
}
-template<typename T, typename PtrTraits>
+template<typename T, typename Traits>
class RefPtr {
WTF_MAKE_FAST_ALLOCATED;
public:
+ using PtrTraits = Traits;
typedef T ValueType;
typedef ValueType* PtrType;
@@ -63,8 +64,8 @@
template<typename X, typename Y> RefPtr(Ref<X, Y>&&);
// Hash table deleted values, which are only constructed and never copied or destroyed.
- RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
- bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
+ RefPtr(HashTableDeletedValueType) : m_ptr(PtrTraits::hashTableDeletedValue()) { }
+ bool isHashTableDeletedValue() const { return PtrTraits::isHashTableDeletedValue(m_ptr); }
ALWAYS_INLINE ~RefPtr() { derefIfNotNull(PtrTraits::exchange(m_ptr, nullptr)); }
@@ -96,8 +97,6 @@
template<typename X, typename Y> void swap(RefPtr<X, Y>&);
- static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); }
-
RefPtr copyRef() && = delete;
RefPtr copyRef() const & WARN_UNUSED_RETURN { return RefPtr(m_ptr); }
Modified: trunk/Source/WTF/wtf/text/AtomStringImpl.cpp (254880 => 254881)
--- trunk/Source/WTF/wtf/text/AtomStringImpl.cpp 2020-01-21 22:04:13 UTC (rev 254880)
+++ trunk/Source/WTF/wtf/text/AtomStringImpl.cpp 2020-01-21 22:05:43 UTC (rev 254881)
@@ -67,7 +67,7 @@
#endif // USE(WEB_THREAD)
-using StringTableImpl = HashSet<StringImpl*>;
+using StringTableImpl = HashSet<PackedPtr<StringImpl>>;
static ALWAYS_INLINE StringTableImpl& stringTable()
{
@@ -82,8 +82,8 @@
// If the string is newly-translated, then we need to adopt it.
// The boolean in the pair tells us if that is so.
if (addResult.isNewEntry)
- return adoptRef(static_cast<AtomStringImpl&>(**addResult.iterator));
- return *static_cast<AtomStringImpl*>(*addResult.iterator);
+ return adoptRef(static_cast<AtomStringImpl&>(*addResult.iterator->get()));
+ return *static_cast<AtomStringImpl*>(addResult.iterator->get());
}
template<typename T, typename HashTranslator>
@@ -99,16 +99,17 @@
return StringHasher::computeHashAndMaskTop8Bits(characters);
}
- static inline bool equal(StringImpl* str, const LChar* characters)
+ static inline bool equal(PackedPtr<StringImpl> str, const LChar* characters)
{
- return WTF::equal(str, characters);
+ return WTF::equal(str.get(), characters);
}
- static void translate(StringImpl*& location, const LChar* const& characters, unsigned hash)
+ static void translate(PackedPtr<StringImpl>& location, const LChar* const& characters, unsigned hash)
{
- location = &StringImpl::create(characters).leakRef();
- location->setHash(hash);
- location->setIsAtom(true);
+ auto* pointer = &StringImpl::create(characters).leakRef();
+ pointer->setHash(hash);
+ pointer->setIsAtom(true);
+ location = pointer;
}
};
@@ -150,16 +151,17 @@
return buf.hash;
}
- static bool equal(StringImpl* const& str, const UCharBuffer& buf)
+ static bool equal(PackedPtr<StringImpl> const& str, const UCharBuffer& buf)
{
- return WTF::equal(str, buf.characters, buf.length);
+ return WTF::equal(str.get(), buf.characters, buf.length);
}
- static void translate(StringImpl*& location, const UCharBuffer& buf, unsigned hash)
+ static void translate(PackedPtr<StringImpl>& location, const UCharBuffer& buf, unsigned hash)
{
- location = &StringImpl::create8BitIfPossible(buf.characters, buf.length).leakRef();
- location->setHash(hash);
- location->setIsAtom(true);
+ auto* pointer = &StringImpl::create8BitIfPossible(buf.characters, buf.length).leakRef();
+ pointer->setHash(hash);
+ pointer->setIsAtom(true);
+ location = pointer;
}
};
@@ -176,8 +178,9 @@
return buffer.hash;
}
- static bool equal(StringImpl* const& string, const HashAndUTF8Characters& buffer)
+ static bool equal(PackedPtr<StringImpl> const& passedString, const HashAndUTF8Characters& buffer)
{
+ auto* string = passedString.get();
if (buffer.utf16Length != string->length())
return false;
@@ -212,7 +215,7 @@
return true;
}
- static void translate(StringImpl*& location, const HashAndUTF8Characters& buffer, unsigned hash)
+ static void translate(PackedPtr<StringImpl>& location, const HashAndUTF8Characters& buffer, unsigned hash)
{
UChar* target;
auto newString = StringImpl::createUninitialized(buffer.utf16Length, target);
@@ -225,9 +228,10 @@
if (isAllASCII)
newString = StringImpl::create(buffer.characters, buffer.length);
- location = &newString.leakRef();
- location->setHash(hash);
- location->setIsAtom(true);
+ auto* pointer = &newString.leakRef();
+ pointer->setHash(hash);
+ pointer->setIsAtom(true);
+ location = pointer;
}
};
@@ -266,11 +270,12 @@
};
struct SubstringTranslator {
- static void translate(StringImpl*& location, const SubstringLocation& buffer, unsigned hash)
+ static void translate(PackedPtr<StringImpl>& location, const SubstringLocation& buffer, unsigned hash)
{
- location = &StringImpl::createSubstringSharingImpl(*buffer.baseString, buffer.start, buffer.length).leakRef();
- location->setHash(hash);
- location->setIsAtom(true);
+ auto* pointer = &StringImpl::createSubstringSharingImpl(*buffer.baseString, buffer.start, buffer.length).leakRef();
+ pointer->setHash(hash);
+ pointer->setIsAtom(true);
+ location = pointer;
}
};
@@ -280,9 +285,9 @@
return StringHasher::computeHashAndMaskTop8Bits(buffer.baseString->characters8() + buffer.start, buffer.length);
}
- static bool equal(StringImpl* const& string, const SubstringLocation& buffer)
+ static bool equal(PackedPtr<StringImpl> const& string, const SubstringLocation& buffer)
{
- return WTF::equal(string, buffer.baseString->characters8() + buffer.start, buffer.length);
+ return WTF::equal(string.get(), buffer.baseString->characters8() + buffer.start, buffer.length);
}
};
@@ -292,9 +297,9 @@
return StringHasher::computeHashAndMaskTop8Bits(buffer.baseString->characters16() + buffer.start, buffer.length);
}
- static bool equal(StringImpl* const& string, const SubstringLocation& buffer)
+ static bool equal(PackedPtr<StringImpl> const& string, const SubstringLocation& buffer)
{
- return WTF::equal(string, buffer.baseString->characters16() + buffer.start, buffer.length);
+ return WTF::equal(string.get(), buffer.baseString->characters16() + buffer.start, buffer.length);
}
};
@@ -326,16 +331,17 @@
return buf.hash;
}
- static bool equal(StringImpl* const& str, const LCharBuffer& buf)
+ static bool equal(PackedPtr<StringImpl> const& str, const LCharBuffer& buf)
{
- return WTF::equal(str, buf.characters, buf.length);
+ return WTF::equal(str.get(), buf.characters, buf.length);
}
- static void translate(StringImpl*& location, const LCharBuffer& buf, unsigned hash)
+ static void translate(PackedPtr<StringImpl>& location, const LCharBuffer& buf, unsigned hash)
{
- location = &StringImpl::create(buf.characters, buf.length).leakRef();
- location->setHash(hash);
- location->setIsAtom(true);
+ auto* pointer = &StringImpl::create(buf.characters, buf.length).leakRef();
+ pointer->setHash(hash);
+ pointer->setIsAtom(true);
+ location = pointer;
}
};
@@ -347,16 +353,17 @@
return buf.hash;
}
- static bool equal(StringImpl* const& str, const Buffer& buf)
+ static bool equal(PackedPtr<StringImpl> const& str, const Buffer& buf)
{
- return WTF::equal(str, buf.characters, buf.length);
+ return WTF::equal(str.get(), buf.characters, buf.length);
}
- static void translate(StringImpl*& location, const Buffer& buf, unsigned hash)
+ static void translate(PackedPtr<StringImpl>& location, const Buffer& buf, unsigned hash)
{
- location = &StringImpl::createWithoutCopying(buf.characters, buf.length).leakRef();
- location->setHash(hash);
- location->setIsAtom(true);
+ auto* pointer = &StringImpl::createWithoutCopying(buf.characters, buf.length).leakRef();
+ pointer->setHash(hash);
+ pointer->setIsAtom(true);
+ location = pointer;
}
};
@@ -443,11 +450,11 @@
auto addResult = stringTable().add(&string);
if (addResult.isNewEntry) {
- ASSERT(*addResult.iterator == &string);
+ ASSERT(addResult.iterator->get() == &string);
string.setIsAtom(true);
}
- return *static_cast<AtomStringImpl*>(*addResult.iterator);
+ return *static_cast<AtomStringImpl*>(addResult.iterator->get());
}
Ref<AtomStringImpl> AtomStringImpl::addSlowCase(AtomStringTable& stringTable, StringImpl& string)
@@ -473,11 +480,11 @@
auto addResult = stringTable.table().add(&string);
if (addResult.isNewEntry) {
- ASSERT(*addResult.iterator == &string);
+ ASSERT(addResult.iterator->get() == &string);
string.setIsAtom(true);
}
- return *static_cast<AtomStringImpl*>(*addResult.iterator);
+ return *static_cast<AtomStringImpl*>(addResult.iterator->get());
}
void AtomStringImpl::remove(AtomStringImpl* string)
@@ -487,7 +494,7 @@
auto& atomStringTable = stringTable();
auto iterator = atomStringTable.find(string);
ASSERT_WITH_MESSAGE(iterator != atomStringTable.end(), "The string being removed is an atom in the string table of an other thread!");
- ASSERT(string == *iterator);
+ ASSERT(string == iterator->get());
atomStringTable.remove(iterator);
}
@@ -502,7 +509,7 @@
auto& atomStringTable = stringTable();
auto iterator = atomStringTable.find(&string);
if (iterator != atomStringTable.end())
- return static_cast<AtomStringImpl*>(*iterator);
+ return static_cast<AtomStringImpl*>(iterator->get());
return nullptr;
}
@@ -526,7 +533,7 @@
LCharBuffer buffer = { characters, length };
auto iterator = table.find<LCharBufferTranslator>(buffer);
if (iterator != table.end())
- return static_cast<AtomStringImpl*>(*iterator);
+ return static_cast<AtomStringImpl*>(iterator->get());
return nullptr;
}
@@ -538,7 +545,7 @@
UCharBuffer buffer { characters, length };
auto iterator = table.find<UCharBufferTranslator>(buffer);
if (iterator != table.end())
- return static_cast<AtomStringImpl*>(*iterator);
+ return static_cast<AtomStringImpl*>(iterator->get());
return nullptr;
}
Modified: trunk/Source/WTF/wtf/text/AtomStringTable.cpp (254880 => 254881)
--- trunk/Source/WTF/wtf/text/AtomStringTable.cpp 2020-01-21 22:04:13 UTC (rev 254880)
+++ trunk/Source/WTF/wtf/text/AtomStringTable.cpp 2020-01-21 22:05:43 UTC (rev 254881)
@@ -31,7 +31,7 @@
AtomStringTable::~AtomStringTable()
{
- for (auto* string : m_table)
+ for (const PackedPtr<StringImpl>& string : m_table)
string->setIsAtom(false);
}
Modified: trunk/Source/WTF/wtf/text/AtomStringTable.h (254880 => 254881)
--- trunk/Source/WTF/wtf/text/AtomStringTable.h 2020-01-21 22:04:13 UTC (rev 254880)
+++ trunk/Source/WTF/wtf/text/AtomStringTable.h 2020-01-21 22:05:43 UTC (rev 254881)
@@ -23,6 +23,7 @@
#pragma once
#include <wtf/HashSet.h>
+#include <wtf/Packed.h>
#include <wtf/text/StringImpl.h>
namespace WTF {
@@ -34,10 +35,10 @@
public:
WTF_EXPORT_PRIVATE ~AtomStringTable();
- HashSet<StringImpl*>& table() { return m_table; }
+ HashSet<PackedPtr<StringImpl>>& table() { return m_table; }
private:
- HashSet<StringImpl*> m_table;
+ HashSet<PackedPtr<StringImpl>> m_table;
};
}
Modified: trunk/Source/WTF/wtf/text/StringHash.h (254880 => 254881)
--- trunk/Source/WTF/wtf/text/StringHash.h 2020-01-21 22:04:13 UTC (rev 254880)
+++ trunk/Source/WTF/wtf/text/StringHash.h 2020-01-21 22:05:43 UTC (rev 254881)
@@ -56,6 +56,7 @@
}
static unsigned hash(const RefPtr<StringImpl>& key) { return key->hash(); }
+ static unsigned hash(const PackedPtr<StringImpl>& key) { return key->hash(); }
static bool equal(const RefPtr<StringImpl>& a, const RefPtr<StringImpl>& b)
{
return equal(a.get(), b.get());
@@ -69,6 +70,19 @@
return equal(a, b.get());
}
+ static bool equal(const PackedPtr<StringImpl>& a, const PackedPtr<StringImpl>& b)
+ {
+ return equal(a.get(), b.get());
+ }
+ static bool equal(const PackedPtr<StringImpl>& a, const StringImpl* b)
+ {
+ return equal(a.get(), b);
+ }
+ static bool equal(const StringImpl* a, const PackedPtr<StringImpl>& b)
+ {
+ return equal(a, b.get());
+ }
+
static unsigned hash(const String& key) { return key.impl()->hash(); }
static bool equal(const String& a, const String& b)
{
@@ -135,6 +149,16 @@
return equal(a.get(), b.get());
}
+ static unsigned hash(const PackedPtr<StringImpl>& key)
+ {
+ return hash(key.get());
+ }
+
+ static bool equal(const PackedPtr<StringImpl>& a, const PackedPtr<StringImpl>& b)
+ {
+ return equal(a.get(), b.get());
+ }
+
static unsigned hash(const String& key)
{
return hash(key.impl());
Modified: trunk/Source/WTF/wtf/text/StringImpl.h (254880 => 254881)
--- trunk/Source/WTF/wtf/text/StringImpl.h 2020-01-21 22:04:13 UTC (rev 254880)
+++ trunk/Source/WTF/wtf/text/StringImpl.h 2020-01-21 22:05:43 UTC (rev 254881)
@@ -29,6 +29,7 @@
#include <wtf/DebugHeap.h>
#include <wtf/Expected.h>
#include <wtf/MathExtras.h>
+#include <wtf/Packed.h>
#include <wtf/StdLibExtras.h>
#include <wtf/Vector.h>
#include <wtf/text/ASCIIFastPath.h>
@@ -598,6 +599,9 @@
template<> struct DefaultHash<RefPtr<StringImpl>> {
typedef StringHash Hash;
};
+template<> struct DefaultHash<PackedPtr<StringImpl>> {
+ using Hash = StringHash;
+};
#define MAKE_STATIC_STRING_IMPL(characters) ([] { \
static StaticStringImpl impl(characters); \
Modified: trunk/Source/WebCore/ChangeLog (254880 => 254881)
--- trunk/Source/WebCore/ChangeLog 2020-01-21 22:04:13 UTC (rev 254880)
+++ trunk/Source/WebCore/ChangeLog 2020-01-21 22:05:43 UTC (rev 254881)
@@ -1,3 +1,15 @@
+2020-01-21 Yusuke Suzuki <[email protected]>
+
+ [WTF] AtomStringTable should be small
+ https://bugs.webkit.org/show_bug.cgi?id=206400
+
+ Reviewed by Sam Weinig.
+
+ * dom/GCReachableRef.h:
+ (WebCore::GCReachableRef::GCReachableRef):
+ * dom/QualifiedName.h:
+ (WebCore::QualifiedName::hashTableDeletedValue):
+
2020-01-21 Jer Noble <[email protected]>
[iPad] YouTube does not automatically AirPlay when a route is selected from Control Center
Modified: trunk/Source/WebCore/dom/GCReachableRef.h (254880 => 254881)
--- trunk/Source/WebCore/dom/GCReachableRef.h 2020-01-21 22:04:13 UTC (rev 254880)
+++ trunk/Source/WebCore/dom/GCReachableRef.h 2020-01-21 22:05:43 UTC (rev 254881)
@@ -74,7 +74,7 @@
// Hash table deleted values, which are only constructed and never copied or destroyed.
GCReachableRef(WTF::HashTableDeletedValueType)
- : m_ptr(RefPtr<T>::hashTableDeletedValue())
+ : m_ptr(RefPtr<T>::PtrTraits::hashTableDeletedValue())
{ }
bool isHashTableDeletedValue() const { return m_ptr.isHashTableDeletedValue(); }
Modified: trunk/Source/WebCore/dom/QualifiedName.h (254880 => 254881)
--- trunk/Source/WebCore/dom/QualifiedName.h 2020-01-21 22:04:13 UTC (rev 254880)
+++ trunk/Source/WebCore/dom/QualifiedName.h 2020-01-21 22:05:43 UTC (rev 254881)
@@ -104,7 +104,7 @@
WEBCORE_EXPORT static void init();
private:
- static QualifiedNameImpl* hashTableDeletedValue() { return RefPtr<QualifiedNameImpl>::hashTableDeletedValue(); }
+ static QualifiedNameImpl* hashTableDeletedValue() { return RefPtr<QualifiedNameImpl>::PtrTraits::hashTableDeletedValue(); }
RefPtr<QualifiedNameImpl> m_impl;
};
Modified: trunk/Tools/ChangeLog (254880 => 254881)
--- trunk/Tools/ChangeLog 2020-01-21 22:04:13 UTC (rev 254880)
+++ trunk/Tools/ChangeLog 2020-01-21 22:05:43 UTC (rev 254881)
@@ -1,3 +1,17 @@
+2020-01-21 Yusuke Suzuki <[email protected]>
+
+ [WTF] AtomStringTable should be small
+ https://bugs.webkit.org/show_bug.cgi?id=206400
+
+ Reviewed by Sam Weinig.
+
+ * TestWebKitAPI/Tests/WTF/HashMap.cpp:
+ (TestWebKitAPI::TEST):
+ * TestWebKitAPI/Tests/WTF/HashSet.cpp:
+ (TestWebKitAPI::TEST):
+ * TestWebKitAPI/Tests/WTF/Packed.cpp:
+ (TestWebKitAPI::TEST):
+
2020-01-21 Alex Christensen <[email protected]>
Add SPI on WKURLSchemeTask to access WKFrameInfo of originating frame
Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp (254880 => 254881)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp 2020-01-21 22:04:13 UTC (rev 254880)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp 2020-01-21 22:05:43 UTC (rev 254881)
@@ -716,7 +716,7 @@
// value.
// A zero would be a incorrect outcome as it would mean we nulled the bucket before an opaque
// call.
- EXPECT_TRUE(observer->observedBucket == observer.get() || observer->observedBucket == RefPtr<DerefObserver>::hashTableDeletedValue());
+ EXPECT_TRUE(observer->observedBucket == observer.get() || observer->observedBucket == RefPtr<DerefObserver>::PtrTraits::hashTableDeletedValue());
EXPECT_EQ(observer->count, 0u);
}
Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/HashSet.cpp (254880 => 254881)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/HashSet.cpp 2020-01-21 22:04:13 UTC (rev 254880)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/HashSet.cpp 2020-01-21 22:05:43 UTC (rev 254881)
@@ -315,7 +315,7 @@
// value.
// A zero would be a incorrect outcome as it would mean we nulled the bucket before an opaque
// call.
- EXPECT_TRUE(observer->observedBucket == observer.get() || observer->observedBucket == RefPtr<DerefObserver>::hashTableDeletedValue());
+ EXPECT_TRUE(observer->observedBucket == observer.get() || observer->observedBucket == RefPtr<DerefObserver>::PtrTraits::hashTableDeletedValue());
EXPECT_EQ(observer->count, 0u);
}
Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/Packed.cpp (254880 => 254881)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/Packed.cpp 2020-01-21 22:04:13 UTC (rev 254880)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/Packed.cpp 2020-01-21 22:05:43 UTC (rev 254881)
@@ -26,6 +26,8 @@
#include "config.h"
#include <wtf/Packed.h>
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
namespace TestWebKitAPI {
@@ -82,4 +84,25 @@
}
}
+struct PackingTarget {
+ unsigned m_value { 0 };
+};
+TEST(WTF_Packed, HashMap)
+{
+ Vector<PackingTarget> vector;
+ HashMap<PackedPtr<PackingTarget>, unsigned> map;
+ vector.reserveCapacity(10000);
+ for (unsigned i = 0; i < 10000; ++i)
+ vector.uncheckedAppend(PackingTarget { i });
+
+ for (auto& target : vector)
+ map.add(&target, target.m_value);
+
+ for (auto& target : vector) {
+ EXPECT_TRUE(map.contains(&target));
+ EXPECT_EQ(map.get(&target), target.m_value);
+ }
+}
+
+
} // namespace TestWebKitAPI