1/*
2 * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef WTF_SymbolRegistry_h
27#define WTF_SymbolRegistry_h
28
29#include <wtf/HashSet.h>
30#include <wtf/text/StringHash.h>
31#include <wtf/text/SymbolImpl.h>
32#include <wtf/text/WTFString.h>
33
34namespace WTF {
35
36// Since StringImpl* used for Symbol uid doesn't have a hash value reflecting the string content,
37// to compare with an external string in string contents, introduce SymbolRegistryKey.
38// SymbolRegistryKey holds a hash value reflecting the string content additionally.
39class SymbolRegistryKey {
40public:
41 SymbolRegistryKey() = default;
42 explicit SymbolRegistryKey(StringImpl* uid);
43 SymbolRegistryKey(WTF::HashTableDeletedValueType);
44
45 unsigned hash() const { return m_hash; }
46 StringImpl* impl() const { return m_impl; }
47
48 bool isHashTableDeletedValue() const { return m_impl == hashTableDeletedValue(); }
49
50private:
51 static StringImpl* hashTableDeletedValue() { return reinterpret_cast<StringImpl*>(-1); }
52
53 StringImpl* m_impl { nullptr };
54 unsigned m_hash { 0 };
55};
56
57template<typename T> struct DefaultHash;
58template<> struct DefaultHash<SymbolRegistryKey> {
59 struct Hash : StringHash {
60 static unsigned hash(const SymbolRegistryKey& key)
61 {
62 return key.hash();
63 }
64 static bool equal(const SymbolRegistryKey& a, const SymbolRegistryKey& b)
65 {
66 return StringHash::equal(a.impl(), b.impl());
67 }
68 };
69};
70
71template<> struct HashTraits<SymbolRegistryKey> : SimpleClassHashTraits<SymbolRegistryKey> {
72 static const bool hasIsEmptyValueFunction = true;
73 static bool isEmptyValue(const SymbolRegistryKey& key)
74 {
75 return key.impl() == nullptr;
76 }
77};
78
79class SymbolRegistry {
80 WTF_MAKE_NONCOPYABLE(SymbolRegistry);
81public:
82 SymbolRegistry() = default;
83 WTF_EXPORT_PRIVATE ~SymbolRegistry();
84
85 WTF_EXPORT_PRIVATE Ref<SymbolImpl> symbolForKey(const String&);
86 WTF_EXPORT_PRIVATE String keyForSymbol(SymbolImpl&);
87
88 void remove(SymbolImpl&);
89
90private:
91 HashSet<SymbolRegistryKey> m_table;
92};
93
94inline SymbolRegistryKey::SymbolRegistryKey(StringImpl* uid)
95 : m_impl(uid)
96{
97 if (uid->isSymbol()) {
98 if (uid->is8Bit())
99 m_hash = StringHasher::computeHashAndMaskTop8Bits(uid->characters8(), uid->length());
100 else
101 m_hash = StringHasher::computeHashAndMaskTop8Bits(uid->characters16(), uid->length());
102 } else
103 m_hash = uid->hash();
104}
105
106inline SymbolRegistryKey::SymbolRegistryKey(WTF::HashTableDeletedValueType)
107 : m_impl(hashTableDeletedValue())
108{
109}
110
111}
112
113#endif
114