2 * Copyright (C) 2011, 2013, 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 ValueRecovery_h
27 #define ValueRecovery_h
29 #include "DFGMinifiedID.h"
30 #include "DataFormat.h"
35 #include "JSCJSValue.h"
36 #include "MacroAssembler.h"
37 #include "VirtualRegister.h"
42 struct InlineCallFrame
;
44 // Describes how to recover a given bytecode virtual register at a given
46 enum ValueRecoveryTechnique
{
47 // It's in a register.
51 UnboxedStrictInt52InGPR
,
58 // It's in the stack, but at a different location.
60 // It's in the stack, at a different location, and it's unboxed.
61 Int32DisplacedInJSStack
,
62 Int52DisplacedInJSStack
,
63 StrictInt52DisplacedInJSStack
,
64 DoubleDisplacedInJSStack
,
65 CellDisplacedInJSStack
,
66 BooleanDisplacedInJSStack
,
67 // It's an Arguments object. This arises because of the simplified arguments simplification done by the DFG.
68 DirectArgumentsThatWereNotCreated
,
69 ClonedArgumentsThatWereNotCreated
,
72 // Don't know how to recover it.
79 : m_technique(DontKnow
)
83 bool isSet() const { return m_technique
!= DontKnow
; }
84 bool operator!() const { return !isSet(); }
86 static ValueRecovery
inGPR(MacroAssembler::RegisterID gpr
, DataFormat dataFormat
)
88 ASSERT(dataFormat
!= DataFormatNone
);
90 ASSERT(dataFormat
== DataFormatInt32
|| dataFormat
== DataFormatCell
|| dataFormat
== DataFormatBoolean
);
93 if (dataFormat
== DataFormatInt32
)
94 result
.m_technique
= UnboxedInt32InGPR
;
95 else if (dataFormat
== DataFormatInt52
)
96 result
.m_technique
= UnboxedInt52InGPR
;
97 else if (dataFormat
== DataFormatStrictInt52
)
98 result
.m_technique
= UnboxedStrictInt52InGPR
;
99 else if (dataFormat
== DataFormatBoolean
)
100 result
.m_technique
= UnboxedBooleanInGPR
;
101 else if (dataFormat
== DataFormatCell
)
102 result
.m_technique
= UnboxedCellInGPR
;
104 result
.m_technique
= InGPR
;
105 result
.m_source
.gpr
= gpr
;
109 #if USE(JSVALUE32_64)
110 static ValueRecovery
inPair(MacroAssembler::RegisterID tagGPR
, MacroAssembler::RegisterID payloadGPR
)
112 ValueRecovery result
;
113 result
.m_technique
= InPair
;
114 result
.m_source
.pair
.tagGPR
= tagGPR
;
115 result
.m_source
.pair
.payloadGPR
= payloadGPR
;
120 static ValueRecovery
inFPR(MacroAssembler::FPRegisterID fpr
)
122 ValueRecovery result
;
123 result
.m_technique
= InFPR
;
124 result
.m_source
.fpr
= fpr
;
128 static ValueRecovery
displacedInJSStack(VirtualRegister virtualReg
, DataFormat dataFormat
)
130 ValueRecovery result
;
131 switch (dataFormat
) {
132 case DataFormatInt32
:
133 result
.m_technique
= Int32DisplacedInJSStack
;
136 case DataFormatInt52
:
137 result
.m_technique
= Int52DisplacedInJSStack
;
140 case DataFormatStrictInt52
:
141 result
.m_technique
= StrictInt52DisplacedInJSStack
;
144 case DataFormatDouble
:
145 result
.m_technique
= DoubleDisplacedInJSStack
;
149 result
.m_technique
= CellDisplacedInJSStack
;
152 case DataFormatBoolean
:
153 result
.m_technique
= BooleanDisplacedInJSStack
;
157 ASSERT(dataFormat
!= DataFormatNone
&& dataFormat
!= DataFormatStorage
);
158 result
.m_technique
= DisplacedInJSStack
;
161 result
.m_source
.virtualReg
= virtualReg
.offset();
165 static ValueRecovery
constant(JSValue value
)
167 ValueRecovery result
;
168 result
.m_technique
= Constant
;
169 result
.m_source
.constant
= JSValue::encode(value
);
173 static ValueRecovery
directArgumentsThatWereNotCreated(DFG::MinifiedID id
)
175 ValueRecovery result
;
176 result
.m_technique
= DirectArgumentsThatWereNotCreated
;
177 result
.m_source
.nodeID
= id
.bits();
181 static ValueRecovery
outOfBandArgumentsThatWereNotCreated(DFG::MinifiedID id
)
183 ValueRecovery result
;
184 result
.m_technique
= ClonedArgumentsThatWereNotCreated
;
185 result
.m_source
.nodeID
= id
.bits();
189 ValueRecoveryTechnique
technique() const { return m_technique
; }
191 bool isConstant() const { return m_technique
== Constant
; }
193 bool isInRegisters() const
195 switch (m_technique
) {
197 case UnboxedInt32InGPR
:
198 case UnboxedBooleanInGPR
:
199 case UnboxedCellInGPR
:
200 case UnboxedInt52InGPR
:
201 case UnboxedStrictInt52InGPR
:
202 #if USE(JSVALUE32_64)
212 MacroAssembler::RegisterID
gpr() const
214 ASSERT(m_technique
== InGPR
|| m_technique
== UnboxedInt32InGPR
|| m_technique
== UnboxedBooleanInGPR
|| m_technique
== UnboxedInt52InGPR
|| m_technique
== UnboxedStrictInt52InGPR
|| m_technique
== UnboxedCellInGPR
);
218 #if USE(JSVALUE32_64)
219 MacroAssembler::RegisterID
tagGPR() const
221 ASSERT(m_technique
== InPair
);
222 return m_source
.pair
.tagGPR
;
225 MacroAssembler::RegisterID
payloadGPR() const
227 ASSERT(m_technique
== InPair
);
228 return m_source
.pair
.payloadGPR
;
232 MacroAssembler::FPRegisterID
fpr() const
234 ASSERT(m_technique
== InFPR
);
238 VirtualRegister
virtualRegister() const
240 ASSERT(m_technique
== DisplacedInJSStack
|| m_technique
== Int32DisplacedInJSStack
|| m_technique
== DoubleDisplacedInJSStack
|| m_technique
== CellDisplacedInJSStack
|| m_technique
== BooleanDisplacedInJSStack
|| m_technique
== Int52DisplacedInJSStack
|| m_technique
== StrictInt52DisplacedInJSStack
);
241 return VirtualRegister(m_source
.virtualReg
);
244 ValueRecovery
withLocalsOffset(int offset
) const
246 switch (m_technique
) {
247 case DisplacedInJSStack
:
248 case Int32DisplacedInJSStack
:
249 case DoubleDisplacedInJSStack
:
250 case CellDisplacedInJSStack
:
251 case BooleanDisplacedInJSStack
:
252 case Int52DisplacedInJSStack
:
253 case StrictInt52DisplacedInJSStack
: {
254 ValueRecovery result
;
255 result
.m_technique
= m_technique
;
256 result
.m_source
.virtualReg
= m_source
.virtualReg
+ offset
;
265 JSValue
constant() const
267 ASSERT(m_technique
== Constant
);
268 return JSValue::decode(m_source
.constant
);
271 DFG::MinifiedID
nodeID() const
273 ASSERT(m_technique
== DirectArgumentsThatWereNotCreated
|| m_technique
== ClonedArgumentsThatWereNotCreated
);
274 return DFG::MinifiedID::fromBits(m_source
.nodeID
);
277 JSValue
recover(ExecState
*) const;
280 void dumpInContext(PrintStream
& out
, DumpContext
* context
) const;
281 void dump(PrintStream
& out
) const;
285 ValueRecoveryTechnique m_technique
;
287 MacroAssembler::RegisterID gpr
;
288 MacroAssembler::FPRegisterID fpr
;
289 #if USE(JSVALUE32_64)
291 MacroAssembler::RegisterID tagGPR
;
292 MacroAssembler::RegisterID payloadGPR
;
296 EncodedJSValue constant
;
303 #endif // ValueRecovery_h