blob: 36207264787ce63b6efdfe79ab8cc283b53dcaa2 [file] [log] [blame]
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +00001/*
fpizlo@apple.com7e2c6462013-01-26 06:07:23 +00002 * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +00003 *
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"
fpizlo@apple.com7e2c6462013-01-26 06:07:23 +000034#include "DFGMinifiedID.h"
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +000035#include "DataFormat.h"
36#include "SpeculatedType.h"
37#include "ValueRecovery.h"
38
39namespace JSC { namespace DFG {
40
41enum ValueSourceKind {
42 SourceNotSet,
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +000043 ValueInJSStack,
44 Int32InJSStack,
45 CellInJSStack,
46 BooleanInJSStack,
47 DoubleInJSStack,
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +000048 ArgumentsSource,
49 SourceIsDead,
50 HaveNode
51};
52
53static inline ValueSourceKind dataFormatToValueSourceKind(DataFormat dataFormat)
54{
55 switch (dataFormat) {
56 case DataFormatInteger:
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +000057 return Int32InJSStack;
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +000058 case DataFormatDouble:
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +000059 return DoubleInJSStack;
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +000060 case DataFormatBoolean:
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +000061 return BooleanInJSStack;
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +000062 case DataFormatCell:
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +000063 return CellInJSStack;
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +000064 case DataFormatDead:
65 return SourceIsDead;
66 case DataFormatArguments:
67 return ArgumentsSource;
68 default:
oliver@apple.com903b0c02013-01-24 01:40:37 +000069 RELEASE_ASSERT(dataFormat & DataFormatJS);
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +000070 return ValueInJSStack;
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +000071 }
72}
73
74static inline DataFormat valueSourceKindToDataFormat(ValueSourceKind kind)
75{
76 switch (kind) {
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +000077 case ValueInJSStack:
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +000078 return DataFormatJS;
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +000079 case Int32InJSStack:
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +000080 return DataFormatInteger;
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +000081 case CellInJSStack:
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +000082 return DataFormatCell;
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +000083 case BooleanInJSStack:
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +000084 return DataFormatBoolean;
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +000085 case DoubleInJSStack:
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +000086 return DataFormatDouble;
87 case ArgumentsSource:
88 return DataFormatArguments;
89 case SourceIsDead:
90 return DataFormatDead;
91 default:
92 return DataFormatNone;
93 }
94}
95
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +000096static inline bool isInJSStack(ValueSourceKind kind)
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +000097{
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()
fpizlo@apple.com7e2c6462013-01-26 06:07:23 +0000112 : m_value(idFromKind(SourceNotSet))
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000113 {
114 }
115
116 explicit ValueSource(ValueSourceKind valueSourceKind)
fpizlo@apple.com7e2c6462013-01-26 06:07:23 +0000117 : m_value(idFromKind(valueSourceKind))
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000118 {
119 ASSERT(kind() != SourceNotSet);
120 ASSERT(kind() != HaveNode);
121 }
122
fpizlo@apple.com7e2c6462013-01-26 06:07:23 +0000123 explicit ValueSource(MinifiedID id)
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000124 : m_value(id)
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000125 {
fpizlo@apple.com7e2c6462013-01-26 06:07:23 +0000126 ASSERT(!!id);
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000127 ASSERT(kind() == HaveNode);
128 }
129
130 static ValueSource forSpeculation(SpeculatedType prediction)
131 {
132 if (isInt32Speculation(prediction))
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +0000133 return ValueSource(Int32InJSStack);
fpizlo@apple.com00528432012-07-20 03:50:02 +0000134 if (isArraySpeculation(prediction) || isCellSpeculation(prediction))
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +0000135 return ValueSource(CellInJSStack);
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000136 if (isBooleanSpeculation(prediction))
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +0000137 return ValueSource(BooleanInJSStack);
138 return ValueSource(ValueInJSStack);
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000139 }
140
141 static ValueSource forDataFormat(DataFormat dataFormat)
142 {
143 return ValueSource(dataFormatToValueSourceKind(dataFormat));
144 }
145
146 bool isSet() const
147 {
fpizlo@apple.com7e2c6462013-01-26 06:07:23 +0000148 return kindFromID(m_value) != SourceNotSet;
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000149 }
150
151 ValueSourceKind kind() const
152 {
fpizlo@apple.com7e2c6462013-01-26 06:07:23 +0000153 return kindFromID(m_value);
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000154 }
155
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +0000156 bool isInJSStack() const { return JSC::DFG::isInJSStack(kind()); }
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000157 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()) {
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +0000168 case ValueInJSStack:
169 return ValueRecovery::alreadyInJSStack();
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000170
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +0000171 case Int32InJSStack:
172 return ValueRecovery::alreadyInJSStackAsUnboxedInt32();
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000173
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +0000174 case CellInJSStack:
175 return ValueRecovery::alreadyInJSStackAsUnboxedCell();
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000176
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +0000177 case BooleanInJSStack:
178 return ValueRecovery::alreadyInJSStackAsUnboxedBoolean();
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000179
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +0000180 case DoubleInJSStack:
181 return ValueRecovery::alreadyInJSStackAsUnboxedDouble();
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000182
183 case SourceIsDead:
184 return ValueRecovery::constant(jsUndefined());
185
186 case ArgumentsSource:
187 return ValueRecovery::argumentsThatWereNotCreated();
188
189 default:
oliver@apple.com5598c182013-01-23 22:25:07 +0000190 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000191 return ValueRecovery();
192 }
193 }
194
fpizlo@apple.com7e2c6462013-01-26 06:07:23 +0000195 MinifiedID id() const
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000196 {
197 ASSERT(kind() == HaveNode);
fpizlo@apple.com7e2c6462013-01-26 06:07:23 +0000198 return m_value;
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000199 }
200
fpizlo@apple.com7e2c6462013-01-26 06:07:23 +0000201 void dump(PrintStream&) const;
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000202
203private:
fpizlo@apple.com7e2c6462013-01-26 06:07:23 +0000204 static MinifiedID idFromKind(ValueSourceKind kind)
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000205 {
206 ASSERT(kind >= SourceNotSet && kind < HaveNode);
fpizlo@apple.com7e2c6462013-01-26 06:07:23 +0000207 return MinifiedID::fromBits(MinifiedID::invalidID() - kind);
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000208 }
209
fpizlo@apple.com7e2c6462013-01-26 06:07:23 +0000210 static ValueSourceKind kindFromID(MinifiedID id)
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000211 {
fpizlo@apple.com7e2c6462013-01-26 06:07:23 +0000212 uintptr_t kind = static_cast<uintptr_t>(MinifiedID::invalidID() - id.m_id);
213 if (kind >= static_cast<uintptr_t>(HaveNode))
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000214 return HaveNode;
215 return static_cast<ValueSourceKind>(kind);
216 }
217
fpizlo@apple.com7e2c6462013-01-26 06:07:23 +0000218 MinifiedID m_value;
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +0000219};
220
221} } // namespace JSC::DFG
222
223#endif // ENABLE(DFG_JIT)
224
225#endif // DFGValueSource_h
226