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