fourthTier: Landing the initial FTL logic in a single commit to avoid spurious
[WebKit-https.git] / Source / JavaScriptCore / ftl / FTLExitValue.h
1 /*
2  * Copyright (C) 2013 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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. 
24  */
25
26 #ifndef FTLExitValue_h
27 #define FTLExitValue_h
28
29 #include <wtf/Platform.h>
30
31 #if ENABLE(FTL_JIT)
32
33 #include "FTLExitArgument.h"
34 #include "JSCJSValue.h"
35 #include <wtf/PrintStream.h>
36
37 namespace JSC { namespace FTL {
38
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
43 // the call.
44
45 enum ExitValueKind {
46     InvalidExitValue,
47     ExitValueDead,
48     ExitValueArgument,
49     ExitValueConstant,
50     ExitValueInJSStack,
51     ExitValueInJSStackAsInt32,
52     ExitValueInJSStackAsDouble
53 };
54
55 class ExitValue {
56 public:
57     ExitValue()
58         : m_kind(InvalidExitValue)
59     {
60     }
61     
62     bool operator!() const { return m_kind == InvalidExitValue; }
63     
64     static ExitValue dead()
65     {
66         ExitValue result;
67         result.m_kind = ExitValueDead;
68         return result;
69     }
70     
71     static ExitValue inJSStack()
72     {
73         ExitValue result;
74         result.m_kind = ExitValueInJSStack;
75         return result;
76     }
77     
78     static ExitValue inJSStackAsInt32()
79     {
80         ExitValue result;
81         result.m_kind = ExitValueInJSStackAsInt32;
82         return result;
83     }
84     
85     static ExitValue inJSStackAsDouble()
86     {
87         ExitValue result;
88         result.m_kind = ExitValueInJSStackAsDouble;
89         return result;
90     }
91     
92     static ExitValue constant(JSValue value)
93     {
94         ExitValue result;
95         result.m_kind = ExitValueConstant;
96         result.u.constant = JSValue::encode(value);
97         return result;
98     }
99     
100     static ExitValue exitArgument(const ExitArgument& argument)
101     {
102         ExitValue result;
103         result.m_kind = ExitValueArgument;
104         result.u.argument = argument.representation();
105         return result;
106     }
107     
108     ExitValueKind kind() const { return m_kind; }
109     
110     bool isDead() const { return kind() == ExitValueDead; }
111     bool isInJSStackSomehow() const
112     {
113         switch (kind()) {
114         case ExitValueInJSStack:
115         case ExitValueInJSStackAsInt32:
116         case ExitValueInJSStackAsDouble:
117             return true;
118         default:
119             return false;
120         }
121     }
122     bool isConstant() const { return kind() == ExitValueConstant; }
123     bool isArgument() const { return kind() == ExitValueArgument; }
124     
125     ExitArgument exitArgument() const
126     {
127         ASSERT(isArgument());
128         return ExitArgument(u.argument);
129     }
130     
131     JSValue constant() const
132     {
133         ASSERT(isConstant());
134         return JSValue::decode(u.constant);
135     }
136     
137     void dump(PrintStream&) const;
138     
139 private:
140     ExitValueKind m_kind;
141     union {
142         ExitArgumentRepresentation argument;
143         EncodedJSValue constant;
144     } u;
145 };
146
147 } } // namespace JSC::FTL
148
149 #endif // ENABLE(FTL_JIT)
150
151 #endif // FTLExitValue_h