Record the HashSet/HashMap operations in DFG/FTL/B3 and replay them in a benchmark
[WebKit-https.git] / Source / WTF / wtf / LoggingHashSet.h
1 /*
2  * Copyright (C) 2017 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. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #pragma once
27
28 #include <wtf/DataLog.h>
29 #include <wtf/HashSet.h>
30 #include <wtf/LoggingHashID.h>
31 #include <wtf/LoggingHashTraits.h>
32
33 namespace WTF {
34
35 template<
36     const char* typeArguments,
37     typename ValueArg, typename HashArg = typename DefaultHash<ValueArg>::Hash,
38     typename TraitsArg = HashTraits<ValueArg>,
39     typename LoggingTraits = LoggingHashKeyTraits<ValueArg>>
40 class LoggingHashSet final {
41     WTF_MAKE_FAST_ALLOCATED;
42
43     typedef TraitsArg ValueTraits;
44     typedef typename ValueTraits::TakeType TakeType;
45     
46 public:
47     typedef WTF::HashSet<ValueArg, HashArg, TraitsArg> HashSet;
48     
49     typedef typename HashSet::ValueType ValueType;
50     typedef typename HashSet::iterator iterator;
51     typedef typename HashSet::const_iterator const_iterator;
52     typedef typename HashSet::AddResult AddResult;
53     
54     LoggingHashSet()
55     {
56         dataLog("auto* ", m_id, " = new HashSet<", typeArguments, ">();\n");
57     }
58     
59     ~LoggingHashSet()
60     {
61         dataLog("delete ", m_id, ";\n");
62     }
63     
64     LoggingHashSet(const LoggingHashSet& other)
65         : m_set(other.m_set)
66     {
67         dataLog("auto* ", m_id, " = new HashSet<", typeArguments, ">(*", other.m_id, ");\n");
68     }
69     
70     LoggingHashSet(LoggingHashSet&& other)
71         : m_set(other.m_set)
72     {
73         dataLog("auto* ", m_id, " = new HashSet<", typeArguments, ">(WTFMove(*", other.m_id, "));\n");
74     }
75     
76     LoggingHashSet& operator=(const LoggingHashSet& other)
77     {
78         dataLog("*", m_id, " = *", other.m_id, ";\n");
79         m_set = other.m_set;
80         return *this;
81     }
82     
83     LoggingHashSet& operator=(LoggingHashSet&& other)
84     {
85         dataLog("*", m_id, " = WTFMove(*", other.m_id, ");\n");
86         m_set = WTFMove(other.m_set);
87         return *this;
88     }
89     
90     void swap(LoggingHashSet& other)
91     {
92         dataLog(m_id, "->swap(*", other.m_id, ");\n");
93         m_set.swap(other.m_set);
94     }
95     
96     unsigned size() const { return m_set.size(); }
97     unsigned capacity() const { return m_set.capacity(); }
98     bool isEmpty() const { return m_set.isEmpty(); }
99     
100     iterator begin() const { return m_set.begin(); }
101     iterator end() const { return m_set.end(); }
102     
103     iterator find(const ValueType& value) const
104     {
105         StringPrintStream string;
106         string.print("{\n");
107         string.print("    auto iter = ", m_id, "->find(");
108         LoggingTraits::print(string, value);
109         string.print(");\n");
110         iterator result = m_set.find(value);
111         if (result == m_set.end())
112             string.print("    RELEASE_ASSERT(iter == ", m_id, "->end());\n");
113         else
114             string.print("    RELEASE_ASSERT(iter != ", m_id, "->end());\n");
115         string.print("}\n");
116         dataLog(string.toCString());
117         return result;
118     }
119     
120     bool contains(const ValueType& value) const
121     {
122         return find(value) != end();
123     }
124     
125     // FIXME: Implement the translator versions of find() and friends.
126     
127     AddResult add(const ValueType& value)
128     {
129         StringPrintStream string;
130         string.print(m_id, "->add(");
131         LoggingTraits::print(string, value);
132         string.print(");\n");
133         dataLog(string.toCString());
134         return m_set.add(value);
135     }
136
137     AddResult add(ValueType&& value)
138     {
139         StringPrintStream string;
140         string.print(m_id, "->add(");
141         LoggingTraits::print(string, value);
142         string.print(");\n");
143         dataLog(string.toCString());
144         return m_set.add(WTFMove(value));
145     }
146     
147     void addVoid(const ValueType& value)
148     {
149         StringPrintStream string;
150         string.print(m_id, "->addVoid(");
151         LoggingTraits::print(string, value);
152         string.print(");\n");
153         dataLog(string.toCString());
154         m_set.addVoid(value);
155     }
156
157     void addVoid(ValueType&& value)
158     {
159         StringPrintStream string;
160         string.print(m_id, "->addVoid(");
161         LoggingTraits::print(string, value);
162         string.print(");\n");
163         dataLog(string.toCString());
164         m_set.addVoid(WTFMove(value));
165     }
166     
167     template<typename IteratorType>
168     bool add(IteratorType begin, IteratorType end)
169     {
170         bool changed = false;
171         for (IteratorType iter = begin; iter != end; ++iter)
172             changed |= add(*iter).isNewEntry;
173         return changed;
174     }
175     
176     bool remove(iterator iter)
177     {
178         // FIXME: We should do much better than this!
179         if (iter == end())
180             return false;
181         return remove(*iter);
182     }
183     
184     bool remove(const ValueType& value)
185     {
186         StringPrintStream string;
187         string.print(m_id, "->remove(");
188         LoggingTraits::print(string, value);
189         string.print(");\n");
190         dataLog(string.toCString());
191         return m_set.remove(value);
192     }
193     
194     // FIXME: Implement removeIf
195     
196     void clear()
197     {
198         dataLog(m_id, "->clear();\n");
199         m_set.clear();
200     }
201     
202     TakeType take(const ValueType& value)
203     {
204         StringPrintStream string;
205         string.print(m_id, "->remove(");
206         LoggingTraits::print(string, value);
207         string.print(");\n");
208         dataLog(string.toCString());
209         return m_set.take(value);
210     }
211     
212     TakeType take(iterator iter)
213     {
214         return take(*iter);
215     }
216     
217     TakeType takeAny()
218     {
219         dataLog(m_id, "->takeAny();\n");
220         return m_set.takeAny();
221     }
222     
223     template<typename OtherCollection>
224     bool operator==(const OtherCollection& otherCollection) const
225     {
226         if (size() != otherCollection.size())
227             return false;
228         for (const auto& other : otherCollection) {
229             if (!contains(other))
230                 return false;
231         }
232         return true;
233     }
234     
235     template<typename OtherCollection>
236     bool operator!=(const OtherCollection& other) const
237     {
238         return !(*this == other);
239     }
240     
241 private:
242     HashSet m_set;
243     LoggingHashID m_id;
244 };
245
246 } // namespace WTF
247
248 using WTF::LoggingHashSet;