| Index: third_party/WebKit/Source/platform/heap/HeapTest.cpp
|
| diff --git a/third_party/WebKit/Source/platform/heap/HeapTest.cpp b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
|
| index 85a2c7c42b285c456983ac854984bdb0a74d05b4..1ed1d4063bb8d6e9d840aa9daf4d6a128a72bb72 100644
|
| --- a/third_party/WebKit/Source/platform/heap/HeapTest.cpp
|
| +++ b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
|
| @@ -87,6 +87,49 @@ class IntWrapper : public GarbageCollectedFinalized<IntWrapper> {
|
| static_assert(WTF::IsTraceable<IntWrapper>::value,
|
| "IsTraceable<> template failed to recognize trace method.");
|
|
|
| +class KeyWithCopyingMoveConstructor final {
|
| + public:
|
| + struct Hash final {
|
| + STATIC_ONLY(Hash);
|
| +
|
| + public:
|
| + static unsigned GetHash(const KeyWithCopyingMoveConstructor& key) {
|
| + return key.hash_;
|
| + }
|
| +
|
| + static bool Equal(const KeyWithCopyingMoveConstructor& x,
|
| + const KeyWithCopyingMoveConstructor& y) {
|
| + return x.hash_ == y.hash_;
|
| + }
|
| +
|
| + static constexpr bool safe_to_compare_to_empty_or_deleted = true;
|
| + };
|
| +
|
| + KeyWithCopyingMoveConstructor() = default;
|
| + KeyWithCopyingMoveConstructor(WTF::HashTableDeletedValueType) : hash_(-1) {}
|
| + ~KeyWithCopyingMoveConstructor() = default;
|
| + KeyWithCopyingMoveConstructor(unsigned hash, const String& string)
|
| + : hash_(hash), string_(string) {
|
| + DCHECK_NE(hash_, 0);
|
| + DCHECK_NE(hash_, -1);
|
| + }
|
| + KeyWithCopyingMoveConstructor(const KeyWithCopyingMoveConstructor&) = default;
|
| + // The move constructor delegates to the copy constructor intentionally.
|
| + KeyWithCopyingMoveConstructor(KeyWithCopyingMoveConstructor&& x)
|
| + : KeyWithCopyingMoveConstructor(x) {}
|
| + KeyWithCopyingMoveConstructor& operator=(
|
| + const KeyWithCopyingMoveConstructor&) = default;
|
| + bool operator==(const KeyWithCopyingMoveConstructor& x) const {
|
| + return hash_ == x.hash_;
|
| + }
|
| +
|
| + bool IsHashTableDeletedValue() const { return hash_ == -1; }
|
| +
|
| + private:
|
| + int hash_ = 0;
|
| + String string_;
|
| +};
|
| +
|
| struct SameSizeAsPersistent {
|
| void* pointer_[4];
|
| };
|
| @@ -272,6 +315,15 @@ struct IsTraceable<blink::PairWithWeakHandling> {
|
| static const bool value = IsTraceable<blink::StrongWeakPair>::value;
|
| };
|
|
|
| +template <>
|
| +struct DefaultHash<blink::KeyWithCopyingMoveConstructor> {
|
| + using Hash = blink::KeyWithCopyingMoveConstructor::Hash;
|
| +};
|
| +
|
| +template <>
|
| +struct HashTraits<blink::KeyWithCopyingMoveConstructor>
|
| + : public SimpleClassHashTraits<blink::KeyWithCopyingMoveConstructor> {};
|
| +
|
| } // namespace WTF
|
|
|
| namespace blink {
|
| @@ -6491,4 +6543,23 @@ TEST(HeapTest, IsGarbageCollected) {
|
| "HeapTerminatedArray");
|
| }
|
|
|
| +TEST(HeapTest, HeapHashMapCallsDestructor) {
|
| + String string = "string";
|
| + EXPECT_TRUE(string.Impl()->HasOneRef());
|
| +
|
| + HeapHashMap<KeyWithCopyingMoveConstructor, Member<IntWrapper>> map;
|
| +
|
| + EXPECT_TRUE(string.Impl()->HasOneRef());
|
| +
|
| + for (int i = 1; i <= 100; ++i) {
|
| + KeyWithCopyingMoveConstructor key(i, string);
|
| + map.insert(key, IntWrapper::Create(i));
|
| + }
|
| +
|
| + EXPECT_FALSE(string.Impl()->HasOneRef());
|
| + map.Clear();
|
| +
|
| + EXPECT_TRUE(string.Impl()->HasOneRef());
|
| +}
|
| +
|
| } // namespace blink
|
|
|