2 * Copyright (C) 2011-2014 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef DFGVariableAccessData_h
27 #define DFGVariableAccessData_h
31 #include "DFGCommon.h"
32 #include "DFGDoubleFormatState.h"
33 #include "DFGFlushFormat.h"
34 #include "DFGFlushedAt.h"
35 #include "DFGNodeFlags.h"
37 #include "SpeculatedType.h"
38 #include "VirtualRegister.h"
39 #include <wtf/UnionFind.h>
40 #include <wtf/Vector.h>
42 namespace JSC
{ namespace DFG
{
46 enum DoubleBallot
{ VoteValue
, VoteDouble
};
48 class VariableAccessData
: public UnionFind
<VariableAccessData
> {
51 VariableAccessData(VirtualRegister local
, bool isCaptured
);
53 VirtualRegister
local()
55 ASSERT(m_local
== find()->m_local
);
59 VirtualRegister
& machineLocal()
61 ASSERT(find() == this);
62 return m_machineLocal
;
65 bool mergeIsCaptured(bool isCaptured
);
72 bool mergeIsProfitableToUnbox(bool isProfitableToUnbox
)
74 return checkAndSet(m_isProfitableToUnbox
, m_isProfitableToUnbox
| isProfitableToUnbox
);
77 bool isProfitableToUnbox()
79 return m_isProfitableToUnbox
;
82 bool mergeShouldNeverUnbox(bool shouldNeverUnbox
);
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()
89 ASSERT(!(m_isCaptured
&& !m_shouldNeverUnbox
));
90 return m_shouldNeverUnbox
;
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()
98 return !shouldNeverUnbox() && isProfitableToUnbox();
101 bool mergeStructureCheckHoistingFailed(bool failed
)
103 return checkAndSet(m_structureCheckHoistingFailed
, m_structureCheckHoistingFailed
| failed
);
106 bool mergeCheckArrayHoistingFailed(bool failed
)
108 return checkAndSet(m_checkArrayHoistingFailed
, m_checkArrayHoistingFailed
| failed
);
111 bool structureCheckHoistingFailed()
113 return m_structureCheckHoistingFailed
;
116 bool checkArrayHoistingFailed()
118 return m_checkArrayHoistingFailed
;
121 bool mergeIsArgumentsAlias(bool isArgumentsAlias
)
123 return checkAndSet(m_isArgumentsAlias
, m_isArgumentsAlias
| isArgumentsAlias
);
126 bool isArgumentsAlias()
128 return m_isArgumentsAlias
;
131 bool mergeIsLoadedFrom(bool isLoadedFrom
)
133 return checkAndSet(m_isLoadedFrom
, m_isLoadedFrom
| isLoadedFrom
);
136 void setIsLoadedFrom(bool isLoadedFrom
)
138 m_isLoadedFrom
= isLoadedFrom
;
143 return m_isLoadedFrom
;
146 bool predict(SpeculatedType prediction
);
148 SpeculatedType
nonUnifiedPrediction()
153 SpeculatedType
prediction()
155 return find()->m_prediction
;
158 SpeculatedType
argumentAwarePrediction()
160 return find()->m_argumentAwarePrediction
;
163 bool mergeArgumentAwarePrediction(SpeculatedType prediction
);
167 ASSERT(find() == this);
172 void vote(unsigned ballot
, float weight
= 1)
175 m_votes
[ballot
] += weight
;
180 ASSERT(find() == this);
181 return static_cast<double>(m_votes
[1]) / m_votes
[0];
184 bool shouldUseDoubleFormatAccordingToVote();
186 DoubleFormatState
doubleFormatState()
188 return find()->m_doubleFormatState
;
191 bool shouldUseDoubleFormat()
194 bool doubleState
= m_doubleFormatState
== UsingDoubleFormat
;
195 ASSERT(!(doubleState
&& shouldNeverUnbox()));
196 ASSERT(!(doubleState
&& isCaptured()));
197 return doubleState
&& isProfitableToUnbox();
200 bool tallyVotesForShouldUseDoubleFormat();
202 bool mergeDoubleFormatState(DoubleFormatState
);
204 bool makePredictionForDoubleFormat();
206 NodeFlags
flags() const { return m_flags
; }
208 bool mergeFlags(NodeFlags newFlags
)
210 return checkAndSet(m_flags
, m_flags
| newFlags
);
213 FlushFormat
flushFormat();
215 bool couldRepresentInt52();
217 FlushedAt
flushedAt()
219 return FlushedAt(flushFormat(), machineLocal());
223 bool couldRepresentInt52Impl();
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.
230 VirtualRegister m_local
;
231 VirtualRegister m_machineLocal
;
232 SpeculatedType m_prediction
;
233 SpeculatedType m_argumentAwarePrediction
;
237 bool m_shouldNeverUnbox
;
238 bool m_isArgumentsAlias
;
239 bool m_structureCheckHoistingFailed
;
240 bool m_checkArrayHoistingFailed
;
241 bool m_isProfitableToUnbox
;
244 float m_votes
[2]; // Used primarily for double voting but may be reused for other purposes.
245 DoubleFormatState m_doubleFormatState
;
248 } } // namespace JSC::DFG
250 #endif // ENABLE(DFG_JIT)
252 #endif // DFGVariableAccessData_h