2 * Copyright (C) 2011, 2013 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 "DataFormat.h"
34 #include "JSCJSValue.h"
35 #include "MacroAssembler.h"
36 #include "VirtualRegister.h"
42 // Describes how to recover a given bytecode virtual register at a given
44 enum ValueRecoveryTechnique
{
45 // It's in a register.
49 UnboxedStrictInt52InGPR
,
56 // It's in the stack, but at a different location.
58 // It's in the stack, at a different location, and it's unboxed.
59 Int32DisplacedInJSStack
,
60 Int52DisplacedInJSStack
,
61 StrictInt52DisplacedInJSStack
,
62 DoubleDisplacedInJSStack
,
63 CellDisplacedInJSStack
,
64 BooleanDisplacedInJSStack
,
65 // It's an Arguments object.
66 ArgumentsThatWereNotCreated
,
69 // Don't know how to recover it.
76 : m_technique(DontKnow
)
80 bool isSet() const { return m_technique
!= DontKnow
; }
81 bool operator!() const { return !isSet(); }
83 static ValueRecovery
inGPR(MacroAssembler::RegisterID gpr
, DataFormat dataFormat
)
85 ASSERT(dataFormat
!= DataFormatNone
);
87 ASSERT(dataFormat
== DataFormatInt32
|| dataFormat
== DataFormatCell
|| dataFormat
== DataFormatBoolean
);
90 if (dataFormat
== DataFormatInt32
)
91 result
.m_technique
= UnboxedInt32InGPR
;
92 else if (dataFormat
== DataFormatInt52
)
93 result
.m_technique
= UnboxedInt52InGPR
;
94 else if (dataFormat
== DataFormatStrictInt52
)
95 result
.m_technique
= UnboxedStrictInt52InGPR
;
96 else if (dataFormat
== DataFormatBoolean
)
97 result
.m_technique
= UnboxedBooleanInGPR
;
98 else if (dataFormat
== DataFormatCell
)
99 result
.m_technique
= UnboxedCellInGPR
;
101 result
.m_technique
= InGPR
;
102 result
.m_source
.gpr
= gpr
;
106 #if USE(JSVALUE32_64)
107 static ValueRecovery
inPair(MacroAssembler::RegisterID tagGPR
, MacroAssembler::RegisterID payloadGPR
)
109 ValueRecovery result
;
110 result
.m_technique
= InPair
;
111 result
.m_source
.pair
.tagGPR
= tagGPR
;
112 result
.m_source
.pair
.payloadGPR
= payloadGPR
;
117 static ValueRecovery
inFPR(MacroAssembler::FPRegisterID fpr
)
119 ValueRecovery result
;
120 result
.m_technique
= InFPR
;
121 result
.m_source
.fpr
= fpr
;
125 static ValueRecovery
displacedInJSStack(VirtualRegister virtualReg
, DataFormat dataFormat
)
127 ValueRecovery result
;
128 switch (dataFormat
) {
129 case DataFormatInt32
:
130 result
.m_technique
= Int32DisplacedInJSStack
;
133 case DataFormatInt52
:
134 result
.m_technique
= Int52DisplacedInJSStack
;
137 case DataFormatStrictInt52
:
138 result
.m_technique
= StrictInt52DisplacedInJSStack
;
141 case DataFormatDouble
:
142 result
.m_technique
= DoubleDisplacedInJSStack
;
146 result
.m_technique
= CellDisplacedInJSStack
;
149 case DataFormatBoolean
:
150 result
.m_technique
= BooleanDisplacedInJSStack
;
154 ASSERT(dataFormat
!= DataFormatNone
&& dataFormat
!= DataFormatStorage
);
155 result
.m_technique
= DisplacedInJSStack
;
158 result
.m_source
.virtualReg
= virtualReg
.offset();
162 static ValueRecovery
constant(JSValue value
)
164 ValueRecovery result
;
165 result
.m_technique
= Constant
;
166 result
.m_source
.constant
= JSValue::encode(value
);
170 static ValueRecovery
argumentsThatWereNotCreated()
172 ValueRecovery result
;
173 result
.m_technique
= ArgumentsThatWereNotCreated
;
177 ValueRecoveryTechnique
technique() const { return m_technique
; }
179 bool isConstant() const { return m_technique
== Constant
; }
181 bool isInRegisters() const
183 switch (m_technique
) {
185 case UnboxedInt32InGPR
:
186 case UnboxedBooleanInGPR
:
187 case UnboxedCellInGPR
:
188 case UnboxedInt52InGPR
:
189 case UnboxedStrictInt52InGPR
:
190 #if USE(JSVALUE32_64)
200 MacroAssembler::RegisterID
gpr() const
202 ASSERT(m_technique
== InGPR
|| m_technique
== UnboxedInt32InGPR
|| m_technique
== UnboxedBooleanInGPR
|| m_technique
== UnboxedInt52InGPR
|| m_technique
== UnboxedStrictInt52InGPR
|| m_technique
== UnboxedCellInGPR
);
206 #if USE(JSVALUE32_64)
207 MacroAssembler::RegisterID
tagGPR() const
209 ASSERT(m_technique
== InPair
);
210 return m_source
.pair
.tagGPR
;
213 MacroAssembler::RegisterID
payloadGPR() const
215 ASSERT(m_technique
== InPair
);
216 return m_source
.pair
.payloadGPR
;
220 MacroAssembler::FPRegisterID
fpr() const
222 ASSERT(m_technique
== InFPR
);
226 VirtualRegister
virtualRegister() const
228 ASSERT(m_technique
== DisplacedInJSStack
|| m_technique
== Int32DisplacedInJSStack
|| m_technique
== DoubleDisplacedInJSStack
|| m_technique
== CellDisplacedInJSStack
|| m_technique
== BooleanDisplacedInJSStack
|| m_technique
== Int52DisplacedInJSStack
|| m_technique
== StrictInt52DisplacedInJSStack
);
229 return VirtualRegister(m_source
.virtualReg
);
232 ValueRecovery
withLocalsOffset(int offset
) const
234 switch (m_technique
) {
235 case DisplacedInJSStack
:
236 case Int32DisplacedInJSStack
:
237 case DoubleDisplacedInJSStack
:
238 case CellDisplacedInJSStack
:
239 case BooleanDisplacedInJSStack
:
240 case Int52DisplacedInJSStack
:
241 case StrictInt52DisplacedInJSStack
: {
242 ValueRecovery result
;
243 result
.m_technique
= m_technique
;
244 result
.m_source
.virtualReg
= m_source
.virtualReg
+ offset
;
253 JSValue
constant() const
255 ASSERT(m_technique
== Constant
);
256 return JSValue::decode(m_source
.constant
);
259 JSValue
recover(ExecState
*) const;
262 void dumpInContext(PrintStream
& out
, DumpContext
* context
) const;
263 void dump(PrintStream
& out
) const;
267 ValueRecoveryTechnique m_technique
;
269 MacroAssembler::RegisterID gpr
;
270 MacroAssembler::FPRegisterID fpr
;
271 #if USE(JSVALUE32_64)
273 MacroAssembler::RegisterID tagGPR
;
274 MacroAssembler::RegisterID payloadGPR
;
278 EncodedJSValue constant
;
284 #endif // ValueRecovery_h