]> git.saurik.com Git - apple/javascriptcore.git/blame - dfg/DFGValueSource.h
JavaScriptCore-1218.34.tar.gz
[apple/javascriptcore.git] / dfg / DFGValueSource.h
CommitLineData
93a37866
A
1/*
2 * Copyright (C) 2011, 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 DFGValueSource_h
27#define DFGValueSource_h
28
29#include <wtf/Platform.h>
30
31#if ENABLE(DFG_JIT)
32
33#include "DFGCommon.h"
34#include "DFGMinifiedID.h"
35#include "DataFormat.h"
36#include "SpeculatedType.h"
37#include "ValueRecovery.h"
38
39namespace JSC { namespace DFG {
40
41enum ValueSourceKind {
42 SourceNotSet,
43 ValueInJSStack,
44 Int32InJSStack,
45 CellInJSStack,
46 BooleanInJSStack,
47 DoubleInJSStack,
48 ArgumentsSource,
49 SourceIsDead,
50 HaveNode
51};
52
53static inline ValueSourceKind dataFormatToValueSourceKind(DataFormat dataFormat)
54{
55 switch (dataFormat) {
56 case DataFormatInteger:
57 return Int32InJSStack;
58 case DataFormatDouble:
59 return DoubleInJSStack;
60 case DataFormatBoolean:
61 return BooleanInJSStack;
62 case DataFormatCell:
63 return CellInJSStack;
64 case DataFormatDead:
65 return SourceIsDead;
66 case DataFormatArguments:
67 return ArgumentsSource;
68 default:
69 RELEASE_ASSERT(dataFormat & DataFormatJS);
70 return ValueInJSStack;
71 }
72}
73
74static inline DataFormat valueSourceKindToDataFormat(ValueSourceKind kind)
75{
76 switch (kind) {
77 case ValueInJSStack:
78 return DataFormatJS;
79 case Int32InJSStack:
80 return DataFormatInteger;
81 case CellInJSStack:
82 return DataFormatCell;
83 case BooleanInJSStack:
84 return DataFormatBoolean;
85 case DoubleInJSStack:
86 return DataFormatDouble;
87 case ArgumentsSource:
88 return DataFormatArguments;
89 case SourceIsDead:
90 return DataFormatDead;
91 default:
92 return DataFormatNone;
93 }
94}
95
96static inline bool isInJSStack(ValueSourceKind kind)
97{
98 DataFormat format = valueSourceKindToDataFormat(kind);
99 return format != DataFormatNone && format < DataFormatOSRMarker;
100}
101
102// Can this value be recovered without having to look at register allocation state or
103// DFG node liveness?
104static inline bool isTriviallyRecoverable(ValueSourceKind kind)
105{
106 return valueSourceKindToDataFormat(kind) != DataFormatNone;
107}
108
109class ValueSource {
110public:
111 ValueSource()
112 : m_value(idFromKind(SourceNotSet))
113 {
114 }
115
116 explicit ValueSource(ValueSourceKind valueSourceKind)
117 : m_value(idFromKind(valueSourceKind))
118 {
119 ASSERT(kind() != SourceNotSet);
120 ASSERT(kind() != HaveNode);
121 }
122
123 explicit ValueSource(MinifiedID id)
124 : m_value(id)
125 {
126 ASSERT(!!id);
127 ASSERT(kind() == HaveNode);
128 }
129
130 static ValueSource forSpeculation(SpeculatedType prediction)
131 {
132 if (isInt32Speculation(prediction))
133 return ValueSource(Int32InJSStack);
134 if (isArraySpeculation(prediction) || isCellSpeculation(prediction))
135 return ValueSource(CellInJSStack);
136 if (isBooleanSpeculation(prediction))
137 return ValueSource(BooleanInJSStack);
138 return ValueSource(ValueInJSStack);
139 }
140
141 static ValueSource forDataFormat(DataFormat dataFormat)
142 {
143 return ValueSource(dataFormatToValueSourceKind(dataFormat));
144 }
145
146 bool isSet() const
147 {
148 return kindFromID(m_value) != SourceNotSet;
149 }
150
151 ValueSourceKind kind() const
152 {
153 return kindFromID(m_value);
154 }
155
156 bool isInJSStack() const { return JSC::DFG::isInJSStack(kind()); }
157 bool isTriviallyRecoverable() const { return JSC::DFG::isTriviallyRecoverable(kind()); }
158
159 DataFormat dataFormat() const
160 {
161 return valueSourceKindToDataFormat(kind());
162 }
163
164 ValueRecovery valueRecovery() const
165 {
166 ASSERT(isTriviallyRecoverable());
167 switch (kind()) {
168 case ValueInJSStack:
169 return ValueRecovery::alreadyInJSStack();
170
171 case Int32InJSStack:
172 return ValueRecovery::alreadyInJSStackAsUnboxedInt32();
173
174 case CellInJSStack:
175 return ValueRecovery::alreadyInJSStackAsUnboxedCell();
176
177 case BooleanInJSStack:
178 return ValueRecovery::alreadyInJSStackAsUnboxedBoolean();
179
180 case DoubleInJSStack:
181 return ValueRecovery::alreadyInJSStackAsUnboxedDouble();
182
183 case SourceIsDead:
184 return ValueRecovery::constant(jsUndefined());
185
186 case ArgumentsSource:
187 return ValueRecovery::argumentsThatWereNotCreated();
188
189 default:
190 RELEASE_ASSERT_NOT_REACHED();
191 return ValueRecovery();
192 }
193 }
194
195 MinifiedID id() const
196 {
197 ASSERT(kind() == HaveNode);
198 return m_value;
199 }
200
201 void dump(PrintStream&) const;
202
203private:
204 static MinifiedID idFromKind(ValueSourceKind kind)
205 {
206 ASSERT(kind >= SourceNotSet && kind < HaveNode);
207 return MinifiedID::fromBits(MinifiedID::invalidID() - kind);
208 }
209
210 static ValueSourceKind kindFromID(MinifiedID id)
211 {
212 uintptr_t kind = static_cast<uintptr_t>(MinifiedID::invalidID() - id.m_id);
213 if (kind >= static_cast<uintptr_t>(HaveNode))
214 return HaveNode;
215 return static_cast<ValueSourceKind>(kind);
216 }
217
218 MinifiedID m_value;
219};
220
221} } // namespace JSC::DFG
222
223#endif // ENABLE(DFG_JIT)
224
225#endif // DFGValueSource_h
226