JavaScriptCore-7600.1.4.11.8.tar.gz
[apple/javascriptcore.git] / runtime / WeakGCMap.h
CommitLineData
f9bf01c6
A
1/*
2 * Copyright (C) 2009 Apple Inc. All rights reserved.
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 WeakGCMap_h
27#define WeakGCMap_h
28
81345200
A
29#include "Weak.h"
30#include "WeakInlines.h"
f9bf01c6
A
31#include <wtf/HashMap.h>
32
33namespace JSC {
34
93a37866 35// A HashMap with Weak<JSCell> values, which automatically removes values once they're garbage collected.
f9bf01c6 36
81345200
A
37template<typename KeyArg, typename ValueArg, typename HashArg = typename DefaultHash<KeyArg>::Hash,
38 typename KeyTraitsArg = HashTraits<KeyArg>>
39class WeakGCMap {
40 WTF_MAKE_FAST_ALLOCATED;
41 typedef Weak<ValueArg> ValueType;
42 typedef HashMap<KeyArg, ValueType, HashArg, KeyTraitsArg> HashMapType;
f9bf01c6
A
43
44public:
81345200
A
45 typedef typename HashMapType::KeyType KeyType;
46 typedef typename HashMapType::AddResult AddResult;
47 typedef typename HashMapType::iterator iterator;
48 typedef typename HashMapType::const_iterator const_iterator;
6fe7ccc8 49
14957cd0 50 WeakGCMap()
93a37866 51 : m_gcThreshold(minGCThreshold)
14957cd0
A
52 {
53 }
54
81345200
A
55 ValueArg* get(const KeyType& key) const
56 {
57 return m_map.get(key);
58 }
59
60 AddResult set(const KeyType& key, ValueType value)
14957cd0 61 {
93a37866 62 gcMapIfNeeded();
81345200 63 return m_map.set(key, WTF::move(value));
14957cd0 64 }
f9bf01c6 65
81345200 66 ALWAYS_INLINE AddResult add(const KeyType& key, ValueType value)
14957cd0 67 {
93a37866 68 gcMapIfNeeded();
81345200 69 AddResult addResult = m_map.fastAdd(key, nullptr);
93a37866
A
70 if (!addResult.iterator->value) { // New value or found a zombie value.
71 addResult.isNewEntry = true;
81345200 72 addResult.iterator->value = WTF::move(value);
93a37866
A
73 }
74 return addResult;
14957cd0 75 }
f9bf01c6 76
81345200
A
77 bool remove(const KeyType& key)
78 {
79 return m_map.remove(key);
80 }
81
82 void clear()
83 {
84 m_map.clear();
85 }
86
14957cd0
A
87 iterator find(const KeyType& key)
88 {
81345200
A
89 iterator it = m_map.find(key);
90 iterator end = m_map.end();
93a37866
A
91 if (it != end && !it->value) // Found a zombie value.
92 return end;
93 return it;
14957cd0 94 }
f9bf01c6 95
93a37866 96 const_iterator find(const KeyType& key) const
14957cd0 97 {
81345200 98 return const_cast<WeakGCMap*>(this)->find(key);
14957cd0 99 }
f9bf01c6 100
93a37866 101 bool contains(const KeyType& key) const
14957cd0 102 {
81345200 103 return find(key) != m_map.end();
14957cd0 104 }
f9bf01c6 105
93a37866
A
106private:
107 static const int minGCThreshold = 3;
f9bf01c6 108
81345200 109 NEVER_INLINE void gcMap()
14957cd0 110 {
93a37866 111 Vector<KeyType, 4> zombies;
81345200
A
112
113 for (iterator it = m_map.begin(), end = m_map.end(); it != end; ++it) {
93a37866
A
114 if (!it->value)
115 zombies.append(it->key);
116 }
81345200 117
93a37866 118 for (size_t i = 0; i < zombies.size(); ++i)
81345200 119 m_map.remove(zombies[i]);
14957cd0
A
120 }
121
93a37866 122 void gcMapIfNeeded()
14957cd0 123 {
81345200 124 if (m_map.size() < m_gcThreshold)
93a37866 125 return;
14957cd0 126
93a37866 127 gcMap();
81345200 128 m_gcThreshold = std::max(minGCThreshold, m_map.size() * 2 - 1);
14957cd0
A
129 }
130
81345200 131 HashMapType m_map;
93a37866 132 int m_gcThreshold;
14957cd0 133};
f9bf01c6 134
93a37866
A
135template<typename KeyArg, typename RawMappedArg, typename HashArg, typename KeyTraitsArg>
136const int WeakGCMap<KeyArg, RawMappedArg, HashArg, KeyTraitsArg>::minGCThreshold;
137
f9bf01c6
A
138} // namespace JSC
139
140#endif // WeakGCMap_h