1 | /* |
2 | * Copyright (C) 2014-2019 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 | DateFieldLoc, |
68 | MapBucketLoc, |
69 | MapBucketHeadLoc, |
70 | MapBucketValueLoc, |
71 | MapBucketKeyLoc, |
72 | MapBucketNextLoc, |
73 | WeakMapGetLoc, |
74 | PromiseInternalFieldLoc, |
75 | DOMStateLoc, |
76 | }; |
77 | |
78 | class HeapLocation { |
79 | public: |
80 | HeapLocation( |
81 | LocationKind kind = InvalidLocationKind, |
82 | AbstractHeap heap = AbstractHeap(), |
83 | Node* base = nullptr, LazyNode index = LazyNode(), Node* descriptor = nullptr) |
84 | : m_kind(kind) |
85 | , m_heap(heap) |
86 | , m_base(base) |
87 | , m_index(index) |
88 | , m_descriptor(descriptor) |
89 | { |
90 | ASSERT((kind == InvalidLocationKind) == !heap); |
91 | ASSERT(!!m_heap || !m_base); |
92 | ASSERT(m_base || (!m_index && !m_descriptor)); |
93 | } |
94 | |
95 | HeapLocation(LocationKind kind, AbstractHeap heap, Node* base, Node* index, Node* descriptor = nullptr) |
96 | : HeapLocation(kind, heap, base, LazyNode(index), descriptor) |
97 | { |
98 | } |
99 | |
100 | HeapLocation(LocationKind kind, AbstractHeap heap, Edge base, Edge index = Edge(), Edge descriptor = Edge()) |
101 | : HeapLocation(kind, heap, base.node(), index.node(), descriptor.node()) |
102 | { |
103 | } |
104 | |
105 | HeapLocation(WTF::HashTableDeletedValueType) |
106 | : m_kind(InvalidLocationKind) |
107 | , m_heap(WTF::HashTableDeletedValue) |
108 | , m_base(nullptr) |
109 | , m_index(nullptr) |
110 | , m_descriptor(nullptr) |
111 | { |
112 | } |
113 | |
114 | bool operator!() const { return !m_heap; } |
115 | |
116 | LocationKind kind() const { return m_kind; } |
117 | AbstractHeap heap() const { return m_heap; } |
118 | Node* base() const { return m_base; } |
119 | LazyNode index() const { return m_index; } |
120 | |
121 | unsigned hash() const |
122 | { |
123 | 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)); |
124 | } |
125 | |
126 | bool operator==(const HeapLocation& other) const |
127 | { |
128 | return m_kind == other.m_kind |
129 | && m_heap == other.m_heap |
130 | && m_base == other.m_base |
131 | && m_index == other.m_index |
132 | && m_descriptor == other.m_descriptor; |
133 | } |
134 | |
135 | bool isHashTableDeletedValue() const |
136 | { |
137 | return m_heap.isHashTableDeletedValue(); |
138 | } |
139 | |
140 | void dump(PrintStream& out) const; |
141 | |
142 | private: |
143 | LocationKind m_kind; |
144 | AbstractHeap m_heap; |
145 | Node* m_base; |
146 | LazyNode m_index; |
147 | Node* m_descriptor; |
148 | }; |
149 | |
150 | struct HeapLocationHash { |
151 | static unsigned hash(const HeapLocation& key) { return key.hash(); } |
152 | static bool equal(const HeapLocation& a, const HeapLocation& b) { return a == b; } |
153 | static constexpr bool safeToCompareToEmptyOrDeleted = true; |
154 | }; |
155 | |
156 | LocationKind indexedPropertyLocForResultType(NodeFlags); |
157 | |
158 | inline LocationKind indexedPropertyLocForResultType(NodeFlags canonicalResultRepresentation) |
159 | { |
160 | if (!canonicalResultRepresentation) |
161 | return IndexedPropertyJSLoc; |
162 | |
163 | ASSERT((canonicalResultRepresentation & NodeResultMask) == canonicalResultRepresentation); |
164 | switch (canonicalResultRepresentation) { |
165 | case NodeResultDouble: |
166 | return IndexedPropertyDoubleLoc; |
167 | case NodeResultInt52: |
168 | return IndexedPropertyInt52Loc; |
169 | case NodeResultInt32: |
170 | return IndexedPropertyInt32Loc; |
171 | case NodeResultJS: |
172 | return IndexedPropertyJSLoc; |
173 | case NodeResultStorage: |
174 | RELEASE_ASSERT_NOT_REACHED(); |
175 | default: |
176 | break; |
177 | } |
178 | RELEASE_ASSERT_NOT_REACHED(); |
179 | } |
180 | |
181 | } } // namespace JSC::DFG |
182 | |
183 | namespace WTF { |
184 | |
185 | void printInternal(PrintStream&, JSC::DFG::LocationKind); |
186 | |
187 | template<typename T> struct DefaultHash; |
188 | template<> struct DefaultHash<JSC::DFG::HeapLocation> { |
189 | typedef JSC::DFG::HeapLocationHash Hash; |
190 | }; |
191 | |
192 | template<typename T> struct HashTraits; |
193 | template<> struct HashTraits<JSC::DFG::HeapLocation> : SimpleClassHashTraits<JSC::DFG::HeapLocation> { |
194 | static constexpr bool emptyValueIsZero = false; |
195 | }; |
196 | |
197 | } // namespace WTF |
198 | |
199 | #endif // ENABLE(DFG_JIT) |
200 | |