2 * Copyright (C) 2011-2015 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
);
53 VirtualRegister
local()
55 ASSERT(m_local
== find()->m_local
);
59 VirtualRegister
& machineLocal()
61 ASSERT(find() == this);
62 return m_machineLocal
;
65 bool mergeIsProfitableToUnbox(bool isProfitableToUnbox
)
67 return checkAndSet(m_isProfitableToUnbox
, m_isProfitableToUnbox
|| isProfitableToUnbox
);
70 bool isProfitableToUnbox()
72 return m_isProfitableToUnbox
;
75 bool mergeShouldNeverUnbox(bool shouldNeverUnbox
);
77 // Returns true if it would be unsound to store the value in an unboxed fashion.
78 // If this returns false, it simply means that it is sound to unbox; it doesn't
79 // mean that we have actually done so.
80 bool shouldNeverUnbox()
82 return m_shouldNeverUnbox
;
85 // Returns true if we should be unboxing the value provided that the predictions
86 // and double format vote say so. This may return false even if shouldNeverUnbox()
87 // returns false, since this incorporates heuristics of profitability.
88 bool shouldUnboxIfPossible()
90 return !shouldNeverUnbox() && isProfitableToUnbox();
93 bool mergeStructureCheckHoistingFailed(bool failed
)
95 return checkAndSet(m_structureCheckHoistingFailed
, m_structureCheckHoistingFailed
|| failed
);
98 bool mergeCheckArrayHoistingFailed(bool failed
)
100 return checkAndSet(m_checkArrayHoistingFailed
, m_checkArrayHoistingFailed
|| failed
);
103 bool structureCheckHoistingFailed()
105 return m_structureCheckHoistingFailed
;
108 bool checkArrayHoistingFailed()
110 return m_checkArrayHoistingFailed
;
113 bool mergeIsLoadedFrom(bool isLoadedFrom
)
115 return checkAndSet(m_isLoadedFrom
, m_isLoadedFrom
|| isLoadedFrom
);
118 void setIsLoadedFrom(bool isLoadedFrom
)
120 m_isLoadedFrom
= isLoadedFrom
;
125 return m_isLoadedFrom
;
128 bool predict(SpeculatedType prediction
);
130 SpeculatedType
nonUnifiedPrediction()
135 SpeculatedType
prediction()
137 return find()->m_prediction
;
140 SpeculatedType
argumentAwarePrediction()
142 return find()->m_argumentAwarePrediction
;
145 bool mergeArgumentAwarePrediction(SpeculatedType prediction
);
149 ASSERT(find() == this);
154 void vote(unsigned ballot
, float weight
= 1)
157 m_votes
[ballot
] += weight
;
162 ASSERT(find() == this);
163 return static_cast<double>(m_votes
[1]) / m_votes
[0];
166 bool shouldUseDoubleFormatAccordingToVote();
168 DoubleFormatState
doubleFormatState()
170 return find()->m_doubleFormatState
;
173 bool shouldUseDoubleFormat()
176 bool doubleState
= m_doubleFormatState
== UsingDoubleFormat
;
177 ASSERT(!(doubleState
&& shouldNeverUnbox()));
178 return doubleState
&& isProfitableToUnbox();
181 bool tallyVotesForShouldUseDoubleFormat();
183 bool mergeDoubleFormatState(DoubleFormatState
);
185 bool makePredictionForDoubleFormat();
187 NodeFlags
flags() const { return m_flags
; }
189 bool mergeFlags(NodeFlags newFlags
)
191 return checkAndSet(m_flags
, m_flags
| newFlags
);
194 FlushFormat
flushFormat();
196 bool couldRepresentInt52();
198 FlushedAt
flushedAt()
200 return FlushedAt(flushFormat(), machineLocal());
204 bool couldRepresentInt52Impl();
206 // This is slightly space-inefficient, since anything we're unified with
207 // will have the same operand and should have the same prediction. But
208 // putting them here simplifies the code, and we don't expect DFG space
209 // usage for variable access nodes do be significant.
211 VirtualRegister m_local
;
212 VirtualRegister m_machineLocal
;
213 SpeculatedType m_prediction
;
214 SpeculatedType m_argumentAwarePrediction
;
217 bool m_shouldNeverUnbox
;
218 bool m_structureCheckHoistingFailed
;
219 bool m_checkArrayHoistingFailed
;
220 bool m_isProfitableToUnbox
;
223 float m_votes
[2]; // Used primarily for double voting but may be reused for other purposes.
224 DoubleFormatState m_doubleFormatState
;
227 } } // namespace JSC::DFG
229 #endif // ENABLE(DFG_JIT)
231 #endif // DFGVariableAccessData_h