2 * Copyright (C) 2013, 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 FTLExitValue_h
27 #define FTLExitValue_h
31 #include "FTLExitArgument.h"
32 #include "FTLRecoveryOpcode.h"
33 #include "JSCJSValue.h"
34 #include "VirtualRegister.h"
35 #include <wtf/PrintStream.h>
37 namespace JSC
{ namespace FTL
{
39 // This is like ValueRecovery, but respects the way that the FTL does OSR
40 // exit: the live non-constant non-flushed values are passed as arguments
41 // to a noreturn tail call. ExitValue is hence mostly responsible for
42 // telling us the mapping between operands in bytecode and the arguments to
51 ExitValueInJSStackAsInt32
,
52 ExitValueInJSStackAsInt52
,
53 ExitValueInJSStackAsDouble
,
54 ExitValueArgumentsObjectThatWasNotCreated
,
61 : m_kind(InvalidExitValue
)
65 bool operator!() const { return m_kind
== InvalidExitValue
; }
67 static ExitValue
dead()
70 result
.m_kind
= ExitValueDead
;
74 static ExitValue
inJSStack(VirtualRegister reg
)
77 result
.m_kind
= ExitValueInJSStack
;
78 result
.u
.virtualRegister
= reg
.offset();
82 static ExitValue
inJSStackAsInt32(VirtualRegister reg
)
85 result
.m_kind
= ExitValueInJSStackAsInt32
;
86 result
.u
.virtualRegister
= reg
.offset();
90 static ExitValue
inJSStackAsInt52(VirtualRegister reg
)
93 result
.m_kind
= ExitValueInJSStackAsInt52
;
94 result
.u
.virtualRegister
= reg
.offset();
98 static ExitValue
inJSStackAsDouble(VirtualRegister reg
)
101 result
.m_kind
= ExitValueInJSStackAsDouble
;
102 result
.u
.virtualRegister
= reg
.offset();
106 static ExitValue
constant(JSValue value
)
109 result
.m_kind
= ExitValueConstant
;
110 result
.u
.constant
= JSValue::encode(value
);
114 static ExitValue
exitArgument(const ExitArgument
& argument
)
117 result
.m_kind
= ExitValueArgument
;
118 result
.u
.argument
= argument
.representation();
122 static ExitValue
argumentsObjectThatWasNotCreated()
125 result
.m_kind
= ExitValueArgumentsObjectThatWasNotCreated
;
129 static ExitValue
recovery(RecoveryOpcode opcode
, unsigned leftArgument
, unsigned rightArgument
, ValueFormat format
)
132 result
.m_kind
= ExitValueRecovery
;
133 result
.u
.recovery
.opcode
= opcode
;
134 result
.u
.recovery
.leftArgument
= leftArgument
;
135 result
.u
.recovery
.rightArgument
= rightArgument
;
136 result
.u
.recovery
.format
= format
;
140 ExitValueKind
kind() const { return m_kind
; }
142 bool isDead() const { return kind() == ExitValueDead
; }
143 bool isInJSStackSomehow() const
146 case ExitValueInJSStack
:
147 case ExitValueInJSStackAsInt32
:
148 case ExitValueInJSStackAsInt52
:
149 case ExitValueInJSStackAsDouble
:
155 bool isConstant() const { return kind() == ExitValueConstant
; }
156 bool isArgument() const { return kind() == ExitValueArgument
; }
157 bool isArgumentsObjectThatWasNotCreated() const { return kind() == ExitValueArgumentsObjectThatWasNotCreated
; }
158 bool isRecovery() const { return kind() == ExitValueRecovery
; }
160 ExitArgument
exitArgument() const
162 ASSERT(isArgument());
163 return ExitArgument(u
.argument
);
166 unsigned leftRecoveryArgument() const
168 ASSERT(isRecovery());
169 return u
.recovery
.leftArgument
;
172 unsigned rightRecoveryArgument() const
174 ASSERT(isRecovery());
175 return u
.recovery
.rightArgument
;
178 ValueFormat
recoveryFormat() const
180 ASSERT(isRecovery());
181 return static_cast<ValueFormat
>(u
.recovery
.format
);
184 RecoveryOpcode
recoveryOpcode() const
186 ASSERT(isRecovery());
187 return static_cast<RecoveryOpcode
>(u
.recovery
.opcode
);
190 JSValue
constant() const
192 ASSERT(isConstant());
193 return JSValue::decode(u
.constant
);
196 VirtualRegister
virtualRegister() const
198 ASSERT(isInJSStackSomehow());
199 return VirtualRegister(u
.virtualRegister
);
202 ExitValue
withVirtualRegister(VirtualRegister virtualRegister
)
204 ASSERT(isInJSStackSomehow());
206 result
.m_kind
= m_kind
;
207 result
.u
.virtualRegister
= virtualRegister
.offset();
211 // If it's in the JSStack somehow, this will tell you what format it's in, in a manner
212 // that is compatible with exitArgument().format(). If it's a constant or it's dead, it
213 // will claim to be a JSValue. If it's an argument then it will tell you the argument's
215 ValueFormat
valueFormat() const
218 case InvalidExitValue
:
219 RELEASE_ASSERT_NOT_REACHED();
220 return InvalidValueFormat
;
223 case ExitValueConstant
:
224 case ExitValueInJSStack
:
225 case ExitValueArgumentsObjectThatWasNotCreated
:
226 return ValueFormatJSValue
;
228 case ExitValueArgument
:
229 return exitArgument().format();
231 case ExitValueInJSStackAsInt32
:
232 return ValueFormatInt32
;
234 case ExitValueInJSStackAsInt52
:
235 return ValueFormatInt52
;
237 case ExitValueInJSStackAsDouble
:
238 return ValueFormatDouble
;
240 case ExitValueRecovery
:
241 return recoveryFormat();
244 RELEASE_ASSERT_NOT_REACHED();
245 return InvalidValueFormat
;
248 void dump(PrintStream
&) const;
249 void dumpInContext(PrintStream
&, DumpContext
*) const;
252 ExitValueKind m_kind
;
254 ExitArgumentRepresentation argument
;
255 EncodedJSValue constant
;
258 uint16_t leftArgument
;
259 uint16_t rightArgument
;
266 } } // namespace JSC::FTL
268 #endif // ENABLE(FTL_JIT)
270 #endif // FTLExitValue_h