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/WTFString.h>
32
33#if USE(WEB_THREAD)
34#include <wtf/SpinLock.h>
35#endif
36
37namespace WTF {
38
39// Since StringImpl* used for Symbol uid doesn't have a hash value reflecting the string content,
40// to compare with an external string in string contents, introduce SymbolRegistryKey.
41// SymbolRegistryKey holds a hash value reflecting the string content additionally.
42class SymbolRegistryKey {
43public:
44 SymbolRegistryKey() = default;
45 explicit SymbolRegistryKey(StringImpl* uid);
46 SymbolRegistryKey(WTF::HashTableDeletedValueType);
47
48 unsigned hash() const { return m_hash; }
49 StringImpl* impl() const { return m_impl; }
50
51 bool isHashTableDeletedValue() const { return m_impl == hashTableDeletedValue(); }
52
53private:
54 static StringImpl* hashTableDeletedValue() { return reinterpret_cast<StringImpl*>(-1); }
55
56 StringImpl* m_impl { nullptr };
57 unsigned m_hash { 0 };
58};
59
60template<typename T> struct DefaultHash;
61template<> struct DefaultHash<SymbolRegistryKey> {
62 struct Hash : StringHash {
63 static unsigned hash(const SymbolRegistryKey& key)
64 {
65 return key.hash();
66 }
67 static bool equal(const SymbolRegistryKey& a, const SymbolRegistryKey& b)
68 {
69 return StringHash::equal(a.impl(), b.impl());
70 }
71 };
72};
73
74template<> struct HashTraits<SymbolRegistryKey> : SimpleClassHashTraits<SymbolRegistryKey> {
75 static const bool hasIsEmptyValueFunction = true;
76 static bool isEmptyValue(const SymbolRegistryKey& key)
77 {
78 return key.impl() == nullptr;
79 }
80};
81
82class SymbolRegistry {
83 WTF_MAKE_NONCOPYABLE(SymbolRegistry);
84public:
85 SymbolRegistry() = default;
86 WTF_EXPORT_PRIVATE ~SymbolRegistry();
87
88 WTF_EXPORT_PRIVATE Ref<StringImpl> symbolForKey(const String&);
89 WTF_EXPORT_PRIVATE String keyForSymbol(StringImpl* uid);
90
91 void remove(StringImpl* uid);
92
93#if USE(WEB_THREAD)
94 SpinLock& spinLock()
95 {
96 return m_spinLock;
97 }
98#endif
99
100private:
101 HashSet<SymbolRegistryKey> m_table;
102#if USE(WEB_THREAD)
103 SpinLock m_spinLock;
104#endif
105};
106
107inline SymbolRegistryKey::SymbolRegistryKey(StringImpl* uid)
108 : m_impl(uid)
109{
110 if (uid->isSymbol()) {
111 if (uid->is8Bit())
112 m_hash = StringHasher::computeHashAndMaskTop8Bits(uid->characters8(), uid->length());
113 else
114 m_hash = StringHasher::computeHashAndMaskTop8Bits(uid->characters16(), uid->length());
115 } else
116 m_hash = uid->hash();
117}
118
119inline SymbolRegistryKey::SymbolRegistryKey(WTF::HashTableDeletedValueType)
120 : m_impl(hashTableDeletedValue())
121{
122}
123
124}
125
126#endif