Object cycles should not prevent allocation elimination/sinking
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGPromotedHeapLocation.h
1 /*
2  * Copyright (C) 2014, 2015 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 #ifndef DFGPromotedHeapLocation_h
27 #define DFGPromotedHeapLocation_h
28
29 #if ENABLE(DFG_JIT)
30
31 #include "DFGNode.h"
32 #include <wtf/PrintStream.h>
33
34 namespace JSC { namespace DFG {
35
36 enum PromotedLocationKind {
37     InvalidPromotedLocationKind,
38     
39     StructurePLoc,
40     ActivationSymbolTablePLoc,
41     NamedPropertyPLoc,
42     ArgumentPLoc,
43     ArgumentCountPLoc,
44     ArgumentsCalleePLoc,
45
46     FunctionExecutablePLoc,
47     FunctionActivationPLoc,
48     ActivationScopePLoc,
49     ClosureVarPLoc,
50 };
51
52 class PromotedLocationDescriptor {
53 public:
54     PromotedLocationDescriptor(
55         PromotedLocationKind kind = InvalidPromotedLocationKind, unsigned info = 0)
56         : m_kind(kind)
57         , m_info(info)
58     {
59     }
60
61     PromotedLocationDescriptor(WTF::HashTableDeletedValueType)
62         : m_kind(InvalidPromotedLocationKind)
63         , m_info(1)
64     {
65     }
66
67     bool operator!() const { return m_kind == InvalidPromotedLocationKind; }
68
69     explicit operator bool() const { return !!*this; }
70     
71     PromotedLocationKind kind() const { return m_kind; }
72     unsigned info() const { return m_info; }
73     
74     OpInfo imm1() const { return OpInfo(static_cast<uint32_t>(m_kind)); }
75     OpInfo imm2() const { return OpInfo(static_cast<uint32_t>(m_info)); }
76     
77     unsigned hash() const
78     {
79         return m_kind + m_info;
80     }
81     
82     bool operator==(const PromotedLocationDescriptor& other) const
83     {
84         return m_kind == other.m_kind
85             && m_info == other.m_info;
86     }
87     
88     bool operator!=(const PromotedLocationDescriptor& other) const
89     {
90         return !(*this == other);
91     }
92
93     bool isHashTableDeletedValue() const
94     {
95         return m_kind == InvalidPromotedLocationKind && m_info;
96     }
97
98     bool neededForMaterialization() const
99     {
100         switch (kind()) {
101         case NamedPropertyPLoc:
102         case ClosureVarPLoc:
103             return false;
104
105         default:
106             return true;
107         }
108     }
109     
110     void dump(PrintStream& out) const;
111
112 private:
113     PromotedLocationKind m_kind;
114     unsigned m_info;
115 };
116
117 struct PromotedLocationDescriptorHash {
118     static unsigned hash(const PromotedLocationDescriptor& key) { return key.hash(); }
119     static bool equal(const PromotedLocationDescriptor& a, const PromotedLocationDescriptor& b) { return a == b; }
120     static const bool safeToCompareToEmptyOrDeleted = true;
121 };
122
123 class PromotedHeapLocation {
124 public:
125     PromotedHeapLocation(
126         PromotedLocationKind kind = InvalidPromotedLocationKind,
127         Node* base = nullptr, unsigned info = 0)
128         : m_base(base)
129         , m_meta(kind, info)
130     {
131     }
132     
133     PromotedHeapLocation(
134         PromotedLocationKind kind, Edge base, unsigned info = 0)
135         : PromotedHeapLocation(kind, base.node(), info)
136     {
137     }
138     
139     PromotedHeapLocation(Node* base, PromotedLocationDescriptor meta)
140         : m_base(base)
141         , m_meta(meta)
142     {
143     }
144     
145     PromotedHeapLocation(WTF::HashTableDeletedValueType)
146         : m_base(nullptr)
147         , m_meta(InvalidPromotedLocationKind, 1)
148     {
149     }
150     
151     Node* createHint(Graph&, NodeOrigin, Node* value);
152     
153     bool operator!() const { return kind() == InvalidPromotedLocationKind; }
154     
155     PromotedLocationKind kind() const { return m_meta.kind(); }
156     Node* base() const { return m_base; }
157     unsigned info() const { return m_meta.info(); }
158     PromotedLocationDescriptor descriptor() const { return m_meta; }
159     
160     unsigned hash() const
161     {
162         return m_meta.hash() + WTF::PtrHash<Node*>::hash(m_base);
163     }
164     
165     bool operator==(const PromotedHeapLocation& other) const
166     {
167         return m_base == other.m_base
168             && m_meta == other.m_meta;
169     }
170     
171     bool isHashTableDeletedValue() const
172     {
173         return m_meta.isHashTableDeletedValue();
174     }
175     
176     void dump(PrintStream& out) const;
177     
178 private:
179     Node* m_base;
180     PromotedLocationDescriptor m_meta;
181 };
182
183 struct PromotedHeapLocationHash {
184     static unsigned hash(const PromotedHeapLocation& key) { return key.hash(); }
185     static bool equal(const PromotedHeapLocation& a, const PromotedHeapLocation& b) { return a == b; }
186     static const bool safeToCompareToEmptyOrDeleted = true;
187 };
188
189 } } // namespace JSC::DFG
190
191 namespace WTF {
192
193 void printInternal(PrintStream&, JSC::DFG::PromotedLocationKind);
194
195 template<typename T> struct DefaultHash;
196 template<> struct DefaultHash<JSC::DFG::PromotedHeapLocation> {
197     typedef JSC::DFG::PromotedHeapLocationHash Hash;
198 };
199
200 template<typename T> struct HashTraits;
201 template<> struct HashTraits<JSC::DFG::PromotedHeapLocation> : SimpleClassHashTraits<JSC::DFG::PromotedHeapLocation> {
202     static const bool emptyValueIsZero = false;
203 };
204
205 template<typename T> struct DefaultHash;
206 template<> struct DefaultHash<JSC::DFG::PromotedLocationDescriptor> {
207     typedef JSC::DFG::PromotedLocationDescriptorHash Hash;
208 };
209
210 template<typename T> struct HashTraits;
211 template<> struct HashTraits<JSC::DFG::PromotedLocationDescriptor> : SimpleClassHashTraits<JSC::DFG::PromotedLocationDescriptor> {
212     static const bool emptyValueIsZero = false;
213 };
214
215 } // namespace WTF
216
217 #endif // ENABLE(DFG_JIT)
218
219 #endif // DFGPromotedHeapLocation_h
220