e696c1ed755417a0087d6f598b8f69fc5f17b5ff
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGHeapLocation.h
1 /*
2  * Copyright (C) 2014-2018 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 #if ENABLE(DFG_JIT)
29
30 #include "DFGAbstractHeap.h"
31 #include "DFGLazyNode.h"
32 #include "DFGNode.h"
33
34 namespace JSC { namespace DFG {
35
36 enum LocationKind {
37     InvalidLocationKind,
38     
39     ArrayLengthLoc,
40     ArrayMaskLoc,
41     VectorLengthLoc,
42     ButterflyLoc,
43     CheckTypeInfoFlagsLoc,
44     OverridesHasInstanceLoc,
45     ClosureVariableLoc,
46     DirectArgumentsLoc,
47     GetterLoc,
48     GlobalVariableLoc,
49     HasIndexedPropertyLoc,
50     IndexedPropertyDoubleLoc,
51     IndexedPropertyDoubleSaneChainLoc,
52     IndexedPropertyInt32Loc,
53     IndexedPropertyInt52Loc,
54     IndexedPropertyJSLoc,
55     IndexedPropertyStorageLoc,
56     InvalidationPointLoc,
57     IsFunctionLoc,
58     IsObjectOrNullLoc,
59     NamedPropertyLoc,
60     RegExpObjectLastIndexLoc,
61     SetterLoc,
62     StructureLoc,
63     TypedArrayByteOffsetLoc,
64     PrototypeLoc,
65     StackLoc,
66     StackPayloadLoc,
67     MapBucketLoc,
68     MapBucketHeadLoc,
69     MapBucketValueLoc,
70     MapBucketKeyLoc,
71     MapBucketNextLoc,
72     WeakMapGetLoc,
73     PromiseInternalFieldLoc,
74     DOMStateLoc,
75 };
76
77 class HeapLocation {
78 public:
79     HeapLocation(
80         LocationKind kind = InvalidLocationKind,
81         AbstractHeap heap = AbstractHeap(),
82         Node* base = nullptr, LazyNode index = LazyNode(), Node* descriptor = nullptr)
83         : m_kind(kind)
84         , m_heap(heap)
85         , m_base(base)
86         , m_index(index)
87         , m_descriptor(descriptor)
88     {
89         ASSERT((kind == InvalidLocationKind) == !heap);
90         ASSERT(!!m_heap || !m_base);
91         ASSERT(m_base || (!m_index && !m_descriptor));
92     }
93
94     HeapLocation(LocationKind kind, AbstractHeap heap, Node* base, Node* index, Node* descriptor = nullptr)
95         : HeapLocation(kind, heap, base, LazyNode(index), descriptor)
96     {
97     }
98     
99     HeapLocation(LocationKind kind, AbstractHeap heap, Edge base, Edge index = Edge(), Edge descriptor = Edge())
100         : HeapLocation(kind, heap, base.node(), index.node(), descriptor.node())
101     {
102     }
103     
104     HeapLocation(WTF::HashTableDeletedValueType)
105         : m_kind(InvalidLocationKind)
106         , m_heap(WTF::HashTableDeletedValue)
107         , m_base(nullptr)
108         , m_index(nullptr)
109         , m_descriptor(nullptr)
110     {
111     }
112     
113     bool operator!() const { return !m_heap; }
114     
115     LocationKind kind() const { return m_kind; }
116     AbstractHeap heap() const { return m_heap; }
117     Node* base() const { return m_base; }
118     LazyNode index() const { return m_index; }
119     
120     unsigned hash() const
121     {
122         return m_kind + m_heap.hash() + m_index.hash() + static_cast<unsigned>(bitwise_cast<uintptr_t>(m_base)) + static_cast<unsigned>(bitwise_cast<uintptr_t>(m_descriptor));
123     }
124     
125     bool operator==(const HeapLocation& other) const
126     {
127         return m_kind == other.m_kind
128             && m_heap == other.m_heap
129             && m_base == other.m_base
130             && m_index == other.m_index
131             && m_descriptor == other.m_descriptor;
132     }
133     
134     bool isHashTableDeletedValue() const
135     {
136         return m_heap.isHashTableDeletedValue();
137     }
138     
139     void dump(PrintStream& out) const;
140     
141 private:
142     LocationKind m_kind;
143     AbstractHeap m_heap;
144     Node* m_base;
145     LazyNode m_index;
146     Node* m_descriptor;
147 };
148
149 struct HeapLocationHash {
150     static unsigned hash(const HeapLocation& key) { return key.hash(); }
151     static bool equal(const HeapLocation& a, const HeapLocation& b) { return a == b; }
152     static const bool safeToCompareToEmptyOrDeleted = true;
153 };
154
155 LocationKind indexedPropertyLocForResultType(NodeFlags);
156
157 inline LocationKind indexedPropertyLocForResultType(NodeFlags canonicalResultRepresentation)
158 {
159     if (!canonicalResultRepresentation)
160         return IndexedPropertyJSLoc;
161
162     ASSERT((canonicalResultRepresentation & NodeResultMask) == canonicalResultRepresentation);
163     switch (canonicalResultRepresentation) {
164     case NodeResultDouble:
165         return IndexedPropertyDoubleLoc;
166     case NodeResultInt52:
167         return IndexedPropertyInt52Loc;
168     case NodeResultInt32:
169         return IndexedPropertyInt32Loc;
170     case NodeResultJS:
171         return IndexedPropertyJSLoc;
172     case NodeResultStorage:
173         RELEASE_ASSERT_NOT_REACHED();
174     default:
175         break;
176     }
177     RELEASE_ASSERT_NOT_REACHED();
178 }
179
180 } } // namespace JSC::DFG
181
182 namespace WTF {
183
184 void printInternal(PrintStream&, JSC::DFG::LocationKind);
185
186 template<typename T> struct DefaultHash;
187 template<> struct DefaultHash<JSC::DFG::HeapLocation> {
188     typedef JSC::DFG::HeapLocationHash Hash;
189 };
190
191 template<typename T> struct HashTraits;
192 template<> struct HashTraits<JSC::DFG::HeapLocation> : SimpleClassHashTraits<JSC::DFG::HeapLocation> {
193     static const bool emptyValueIsZero = false;
194 };
195
196 } // namespace WTF
197
198 #endif // ENABLE(DFG_JIT)