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
34namespace JSC { namespace DFG {
35
36enum 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
76class HeapLocation {
77public:
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
140private:
141 LocationKind m_kind;
142 AbstractHeap m_heap;
143 Node* m_base;
144 LazyNode m_index;
145 Node* m_descriptor;
146};
147
148struct 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
154LocationKind indexedPropertyLocForResultType(NodeFlags);
155
156inline 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
181namespace WTF {
182
183void printInternal(PrintStream&, JSC::DFG::LocationKind);
184
185template<typename T> struct DefaultHash;
186template<> struct DefaultHash<JSC::DFG::HeapLocation> {
187 typedef JSC::DFG::HeapLocationHash Hash;
188};
189
190template<typename T> struct HashTraits;
191template<> 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