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