]> git.saurik.com Git - apple/javascriptcore.git/blame - dfg/DFGVariableAccessData.h
JavaScriptCore-7600.1.4.15.12.tar.gz
[apple/javascriptcore.git] / dfg / DFGVariableAccessData.h
CommitLineData
6fe7ccc8 1/*
81345200 2 * Copyright (C) 2011-2014 Apple Inc. All rights reserved.
6fe7ccc8
A
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#ifndef DFGVariableAccessData_h
27#define DFGVariableAccessData_h
28
81345200
A
29#if ENABLE(DFG_JIT)
30
31#include "DFGCommon.h"
6fe7ccc8 32#include "DFGDoubleFormatState.h"
81345200
A
33#include "DFGFlushFormat.h"
34#include "DFGFlushedAt.h"
6fe7ccc8
A
35#include "DFGNodeFlags.h"
36#include "Operands.h"
93a37866 37#include "SpeculatedType.h"
6fe7ccc8 38#include "VirtualRegister.h"
6fe7ccc8
A
39#include <wtf/UnionFind.h>
40#include <wtf/Vector.h>
41
42namespace JSC { namespace DFG {
43
81345200
A
44struct Node;
45
93a37866
A
46enum DoubleBallot { VoteValue, VoteDouble };
47
6fe7ccc8
A
48class VariableAccessData : public UnionFind<VariableAccessData> {
49public:
81345200
A
50 VariableAccessData();
51 VariableAccessData(VirtualRegister local, bool isCaptured);
6fe7ccc8
A
52
53 VirtualRegister local()
54 {
55 ASSERT(m_local == find()->m_local);
56 return m_local;
57 }
58
81345200 59 VirtualRegister& machineLocal()
6fe7ccc8 60 {
81345200
A
61 ASSERT(find() == this);
62 return m_machineLocal;
93a37866 63 }
81345200
A
64
65 bool mergeIsCaptured(bool isCaptured);
93a37866
A
66
67 bool isCaptured()
68 {
69 return m_isCaptured;
70 }
71
72 bool mergeIsProfitableToUnbox(bool isProfitableToUnbox)
73 {
74 return checkAndSet(m_isProfitableToUnbox, m_isProfitableToUnbox | isProfitableToUnbox);
75 }
76
77 bool isProfitableToUnbox()
78 {
79 return m_isProfitableToUnbox;
80 }
81
81345200 82 bool mergeShouldNeverUnbox(bool shouldNeverUnbox);
93a37866
A
83
84 // Returns true if it would be unsound to store the value in an unboxed fashion.
85 // If this returns false, it simply means that it is sound to unbox; it doesn't
86 // mean that we have actually done so.
87 bool shouldNeverUnbox()
88 {
89 ASSERT(!(m_isCaptured && !m_shouldNeverUnbox));
90 return m_shouldNeverUnbox;
91 }
92
93 // Returns true if we should be unboxing the value provided that the predictions
94 // and double format vote say so. This may return false even if shouldNeverUnbox()
95 // returns false, since this incorporates heuristics of profitability.
96 bool shouldUnboxIfPossible()
97 {
98 return !shouldNeverUnbox() && isProfitableToUnbox();
99 }
100
101 bool mergeStructureCheckHoistingFailed(bool failed)
102 {
103 return checkAndSet(m_structureCheckHoistingFailed, m_structureCheckHoistingFailed | failed);
104 }
105
81345200
A
106 bool mergeCheckArrayHoistingFailed(bool failed)
107 {
108 return checkAndSet(m_checkArrayHoistingFailed, m_checkArrayHoistingFailed | failed);
109 }
110
93a37866
A
111 bool structureCheckHoistingFailed()
112 {
113 return m_structureCheckHoistingFailed;
114 }
115
81345200
A
116 bool checkArrayHoistingFailed()
117 {
118 return m_checkArrayHoistingFailed;
119 }
120
93a37866
A
121 bool mergeIsArgumentsAlias(bool isArgumentsAlias)
122 {
123 return checkAndSet(m_isArgumentsAlias, m_isArgumentsAlias | isArgumentsAlias);
124 }
125
126 bool isArgumentsAlias()
127 {
128 return m_isArgumentsAlias;
129 }
130
131 bool mergeIsLoadedFrom(bool isLoadedFrom)
132 {
133 return checkAndSet(m_isLoadedFrom, m_isLoadedFrom | isLoadedFrom);
134 }
135
136 void setIsLoadedFrom(bool isLoadedFrom)
137 {
138 m_isLoadedFrom = isLoadedFrom;
139 }
140
141 bool isLoadedFrom()
142 {
143 return m_isLoadedFrom;
144 }
145
81345200 146 bool predict(SpeculatedType prediction);
6fe7ccc8 147
93a37866 148 SpeculatedType nonUnifiedPrediction()
6fe7ccc8
A
149 {
150 return m_prediction;
151 }
152
93a37866 153 SpeculatedType prediction()
6fe7ccc8
A
154 {
155 return find()->m_prediction;
156 }
157
93a37866 158 SpeculatedType argumentAwarePrediction()
6fe7ccc8
A
159 {
160 return find()->m_argumentAwarePrediction;
161 }
162
81345200 163 bool mergeArgumentAwarePrediction(SpeculatedType prediction);
6fe7ccc8
A
164
165 void clearVotes()
166 {
167 ASSERT(find() == this);
93a37866
A
168 m_votes[0] = 0;
169 m_votes[1] = 0;
6fe7ccc8
A
170 }
171
81345200 172 void vote(unsigned ballot, float weight = 1)
6fe7ccc8 173 {
93a37866 174 ASSERT(ballot < 2);
81345200 175 m_votes[ballot] += weight;
6fe7ccc8
A
176 }
177
93a37866 178 double voteRatio()
6fe7ccc8
A
179 {
180 ASSERT(find() == this);
93a37866 181 return static_cast<double>(m_votes[1]) / m_votes[0];
6fe7ccc8
A
182 }
183
81345200 184 bool shouldUseDoubleFormatAccordingToVote();
6fe7ccc8
A
185
186 DoubleFormatState doubleFormatState()
187 {
188 return find()->m_doubleFormatState;
189 }
190
191 bool shouldUseDoubleFormat()
192 {
193 ASSERT(isRoot());
93a37866
A
194 bool doubleState = m_doubleFormatState == UsingDoubleFormat;
195 ASSERT(!(doubleState && shouldNeverUnbox()));
196 ASSERT(!(doubleState && isCaptured()));
197 return doubleState && isProfitableToUnbox();
6fe7ccc8
A
198 }
199
81345200 200 bool tallyVotesForShouldUseDoubleFormat();
6fe7ccc8 201
81345200 202 bool mergeDoubleFormatState(DoubleFormatState);
6fe7ccc8 203
81345200 204 bool makePredictionForDoubleFormat();
6fe7ccc8
A
205
206 NodeFlags flags() const { return m_flags; }
207
208 bool mergeFlags(NodeFlags newFlags)
209 {
93a37866 210 return checkAndSet(m_flags, m_flags | newFlags);
6fe7ccc8
A
211 }
212
81345200
A
213 FlushFormat flushFormat();
214
215 bool couldRepresentInt52();
216
217 FlushedAt flushedAt()
218 {
219 return FlushedAt(flushFormat(), machineLocal());
220 }
221
6fe7ccc8 222private:
81345200
A
223 bool couldRepresentInt52Impl();
224
6fe7ccc8
A
225 // This is slightly space-inefficient, since anything we're unified with
226 // will have the same operand and should have the same prediction. But
227 // putting them here simplifies the code, and we don't expect DFG space
228 // usage for variable access nodes do be significant.
229
230 VirtualRegister m_local;
81345200 231 VirtualRegister m_machineLocal;
93a37866
A
232 SpeculatedType m_prediction;
233 SpeculatedType m_argumentAwarePrediction;
6fe7ccc8 234 NodeFlags m_flags;
93a37866
A
235
236 bool m_isCaptured;
237 bool m_shouldNeverUnbox;
238 bool m_isArgumentsAlias;
239 bool m_structureCheckHoistingFailed;
81345200 240 bool m_checkArrayHoistingFailed;
93a37866
A
241 bool m_isProfitableToUnbox;
242 bool m_isLoadedFrom;
243
244 float m_votes[2]; // Used primarily for double voting but may be reused for other purposes.
6fe7ccc8
A
245 DoubleFormatState m_doubleFormatState;
246};
247
248} } // namespace JSC::DFG
249
81345200
A
250#endif // ENABLE(DFG_JIT)
251
6fe7ccc8 252#endif // DFGVariableAccessData_h