Unreviewed, rolling out r234489.
[WebKit-https.git] / Source / WTF / wtf / StackShot.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/Assertions.h>
29 #include <wtf/UniqueArray.h>
30
31 namespace WTF {
32
33 class StackShot {
34 public:
35     StackShot() { }
36     
37     ALWAYS_INLINE StackShot(size_t size)
38         : m_size(size)
39     {
40         if (size) {
41             m_array = makeUniqueArray<void*>(size);
42             int intSize = size;
43             WTFGetBacktrace(m_array.get(), &intSize);
44             RELEASE_ASSERT(static_cast<size_t>(intSize) <= size);
45             m_size = intSize;
46             if (!m_size)
47                 m_array = nullptr;
48         }
49     }
50     
51     StackShot(WTF::HashTableDeletedValueType)
52         : m_array(deletedValueArray())
53         , m_size(0)
54     {
55     }
56     
57     StackShot& operator=(const StackShot& other)
58     {
59         auto newArray = makeUniqueArray<void*>(other.m_size);
60         for (size_t i = other.m_size; i--;)
61             newArray[i] = other.m_array[i];
62         m_size = other.m_size;
63         m_array = WTFMove(newArray);
64         return *this;
65     }
66     
67     StackShot(const StackShot& other)
68     {
69         *this = other;
70     }
71     
72     void** array() const { return m_array.get(); }
73     size_t size() const { return m_size; }
74     
75     explicit operator bool() const { return !!m_array; }
76     
77     bool operator==(const StackShot& other) const
78     {
79         if (m_size != other.m_size)
80             return false;
81         
82         for (size_t i = m_size; i--;) {
83             if (m_array[i] != other.m_array[i])
84                 return false;
85         }
86         
87         return true;
88     }
89     
90     unsigned hash() const
91     {
92         unsigned result = m_size;
93         
94         for (size_t i = m_size; i--;)
95             result ^= PtrHash<void*>::hash(m_array[i]);
96         
97         return result;
98     }
99     
100     bool isHashTableDeletedValue() const
101     {
102         return !m_size && m_array.get() == deletedValueArray();
103     }
104     
105     // Make Spectrum<> happy.
106     bool operator>(const StackShot&) const { return false; }
107     
108 private:
109     static void** deletedValueArray() { return bitwise_cast<void**>(static_cast<uintptr_t>(1)); }
110
111     UniqueArray<void*> m_array;
112     size_t m_size { 0 };
113 };
114
115 struct StackShotHash {
116     static unsigned hash(const StackShot& shot) { return shot.hash(); }
117     static bool equal(const StackShot& a, const StackShot& b) { return a == b; }
118     static const bool safeToCompareToEmptyOrDeleted = false;
119 };
120
121 template<typename T> struct DefaultHash;
122 template<> struct DefaultHash<StackShot> {
123     typedef StackShotHash Hash;
124 };
125
126 template<typename T> struct HashTraits;
127 template<> struct HashTraits<StackShot> : SimpleClassHashTraits<StackShot> { };
128
129 } // namespace WTF
130