blob: 52b0d05723b959185654e819bf25fc426559e756 [file] [log] [blame]
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001/*
fpizlo@apple.com8fefdd32015-02-18 19:55:47 +00002 * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +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
oliver@apple.com55d32d92013-07-25 04:05:03 +000026#ifndef DFGAbstractInterpreterInlines_h
27#define DFGAbstractInterpreterInlines_h
28
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +000029#if ENABLE(DFG_JIT)
30
oliver@apple.com55d32d92013-07-25 04:05:03 +000031#include "DFGAbstractInterpreter.h"
fpizlo@apple.comc2c67632012-11-17 08:37:14 +000032#include "GetByIdStatus.h"
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +000033#include "GetterSetter.h"
benjamin@webkit.org903025b2015-02-14 04:20:21 +000034#include "JITOperations.h"
benjamin@webkit.org28b4f2d2015-02-18 08:01:01 +000035#include "MathCommon.h"
oliver@apple.come722ad02013-01-09 02:37:29 +000036#include "Operations.h"
fpizlo@apple.comc2c67632012-11-17 08:37:14 +000037#include "PutByIdStatus.h"
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +000038#include "StringObject.h"
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +000039
40namespace JSC { namespace DFG {
41
oliver@apple.com55d32d92013-07-25 04:05:03 +000042template<typename AbstractStateType>
43AbstractInterpreter<AbstractStateType>::AbstractInterpreter(Graph& graph, AbstractStateType& state)
fpizlo@apple.comadf274c2012-02-18 07:56:10 +000044 : m_codeBlock(graph.m_codeBlock)
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +000045 , m_graph(graph)
oliver@apple.com55d32d92013-07-25 04:05:03 +000046 , m_state(state)
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +000047{
fpizlo@apple.comfc70ba62014-09-26 03:59:33 +000048 if (m_graph.m_form == SSA)
49 m_phiChildren = std::make_unique<PhiChildren>(m_graph);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +000050}
51
oliver@apple.com55d32d92013-07-25 04:05:03 +000052template<typename AbstractStateType>
53AbstractInterpreter<AbstractStateType>::~AbstractInterpreter()
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +000054{
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +000055}
56
oliver@apple.com55d32d92013-07-25 04:05:03 +000057template<typename AbstractStateType>
58typename AbstractInterpreter<AbstractStateType>::BooleanResult
59AbstractInterpreter<AbstractStateType>::booleanResult(
60 Node* node, AbstractValue& value)
fpizlo@apple.com367a1102012-11-10 23:33:29 +000061{
62 JSValue childConst = value.value();
63 if (childConst) {
fpizlo@apple.com6793a322014-02-12 05:42:32 +000064 if (childConst.toBoolean(m_codeBlock->globalObjectFor(node->origin.semantic)->globalExec()))
fpizlo@apple.com367a1102012-11-10 23:33:29 +000065 return DefinitelyTrue;
66 return DefinitelyFalse;
67 }
68
69 // Next check if we can fold because we know that the source is an object or string and does not equal undefined.
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +000070 if (isCellSpeculation(value.m_type) && !value.m_structure.isTop()) {
71 bool allTrue = true;
72 for (unsigned i = value.m_structure.size(); i--;) {
73 Structure* structure = value.m_structure[i];
74 if (structure->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->origin.semantic))
75 || structure->typeInfo().type() == StringType) {
76 allTrue = false;
77 break;
78 }
79 }
80 if (allTrue)
fpizlo@apple.com367a1102012-11-10 23:33:29 +000081 return DefinitelyTrue;
82 }
83
84 return UnknownBooleanResult;
85}
86
oliver@apple.com55d32d92013-07-25 04:05:03 +000087template<typename AbstractStateType>
fpizlo@apple.comfc70ba62014-09-26 03:59:33 +000088void AbstractInterpreter<AbstractStateType>::startExecuting()
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +000089{
oliver@apple.com55d32d92013-07-25 04:05:03 +000090 ASSERT(m_state.block());
91 ASSERT(m_state.isValid());
fpizlo@apple.comb75911b2012-06-13 20:53:52 +000092
oliver@apple.com55d32d92013-07-25 04:05:03 +000093 m_state.setDidClobber(false);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +000094}
95
oliver@apple.com55d32d92013-07-25 04:05:03 +000096template<typename AbstractStateType>
97void AbstractInterpreter<AbstractStateType>::executeEdges(Node* node)
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +000098{
99 DFG_NODE_DO_TO_CHILDREN(m_graph, node, filterEdgeByUse);
100}
101
oliver@apple.com55d32d92013-07-25 04:05:03 +0000102template<typename AbstractStateType>
103void AbstractInterpreter<AbstractStateType>::executeEdges(unsigned indexInBlock)
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000104{
oliver@apple.com55d32d92013-07-25 04:05:03 +0000105 executeEdges(m_state.block()->at(indexInBlock));
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000106}
107
oliver@apple.com55d32d92013-07-25 04:05:03 +0000108template<typename AbstractStateType>
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +0000109void AbstractInterpreter<AbstractStateType>::verifyEdge(Node* node, Edge edge)
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000110{
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +0000111 if (!(forNode(edge).m_type & ~typeFilterFor(edge.useKind())))
112 return;
113
fpizlo@apple.com97812a32014-10-04 17:18:25 +0000114 DFG_CRASH(m_graph, node, toCString("Edge verification error: ", node, "->", edge, " was expected to have type ", SpeculationDump(typeFilterFor(edge.useKind())), " but has type ", SpeculationDump(forNode(edge).m_type), " (", forNode(edge).m_type, ")").data());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000115}
116
oliver@apple.com55d32d92013-07-25 04:05:03 +0000117template<typename AbstractStateType>
118void AbstractInterpreter<AbstractStateType>::verifyEdges(Node* node)
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000119{
120 DFG_NODE_DO_TO_CHILDREN(m_graph, node, verifyEdge);
121}
122
oliver@apple.com55d32d92013-07-25 04:05:03 +0000123template<typename AbstractStateType>
oliver@apple.come17632e2013-07-25 04:05:31 +0000124bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimit, Node* node)
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000125{
126 if (!ASSERT_DISABLED)
127 verifyEdges(node);
128
oliver@apple.com02e7a972013-07-25 04:05:04 +0000129 m_state.createValueForNode(node);
130
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000131 switch (node->op()) {
fpizlo@apple.com53aa8dc2011-11-15 21:54:38 +0000132 case JSConstant:
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000133 case DoubleConstant:
134 case Int52Constant:
fpizlo@apple.com7e0f6502012-05-25 22:45:57 +0000135 case PhantomArguments: {
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000136 setBuiltInConstant(node, *node->constant());
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000137 break;
138 }
fpizlo@apple.com5d271712012-11-16 06:19:54 +0000139
140 case Identity: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000141 forNode(node) = forNode(node->child1());
fpizlo@apple.com5d271712012-11-16 06:19:54 +0000142 break;
143 }
oliver@apple.com827d2cf2013-07-25 04:04:45 +0000144
fpizlo@apple.com532f1e52013-09-04 06:26:04 +0000145 case ExtractOSREntryLocal: {
rniwa@webkit.orgeb7ac192015-03-13 01:11:15 +0000146 forNode(node).makeBytecodeTop();
fpizlo@apple.com532f1e52013-09-04 06:26:04 +0000147 break;
148 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000149
150 case GetLocal: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000151 VariableAccessData* variableAccessData = node->variableAccessData();
msaboff@apple.com62aa8b72013-09-26 22:53:54 +0000152 AbstractValue value = m_state.variables().operand(variableAccessData->local().offset());
fpizlo@apple.com064f0812015-02-16 19:27:37 +0000153 // The value in the local should already be checked.
154 DFG_ASSERT(m_graph, node, value.isType(typeFilterFor(variableAccessData->flushFormat())));
fpizlo@apple.com8e537cd2012-06-01 23:54:36 +0000155 if (value.value())
oliver@apple.com55d32d92013-07-25 04:05:03 +0000156 m_state.setFoundConstants(true);
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000157 forNode(node) = value;
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000158 break;
159 }
160
fpizlo@apple.combcfd8eb2015-02-26 19:51:52 +0000161 case GetStack: {
162 StackAccessData* data = node->stackAccessData();
163 AbstractValue value = m_state.variables().operand(data->local);
164 // The value in the local should already be checked.
165 DFG_ASSERT(m_graph, node, value.isType(typeFilterFor(data->format)));
166 if (value.value())
167 m_state.setFoundConstants(true);
168 forNode(node) = value;
169 break;
170 }
171
fpizlo@apple.com9b928722012-05-24 00:18:55 +0000172 case GetLocalUnlinked: {
msaboff@apple.com62aa8b72013-09-26 22:53:54 +0000173 AbstractValue value = m_state.variables().operand(node->unlinkedLocal().offset());
fpizlo@apple.com8e537cd2012-06-01 23:54:36 +0000174 if (value.value())
oliver@apple.com55d32d92013-07-25 04:05:03 +0000175 m_state.setFoundConstants(true);
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000176 forNode(node) = value;
fpizlo@apple.com9b928722012-05-24 00:18:55 +0000177 break;
178 }
179
fpizlo@apple.combcfd8eb2015-02-26 19:51:52 +0000180 case SetLocal: {
181 m_state.variables().operand(node->local()) = forNode(node->child1());
182 break;
183 }
184
185 case PutStack: {
186 m_state.variables().operand(node->stackAccessData()->local) = forNode(node->child1());
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000187 break;
188 }
fpizlo@apple.com06f82b52013-03-06 02:27:16 +0000189
fpizlo@apple.com9df7fef2013-12-29 21:50:55 +0000190 case MovHint: {
191 // Don't need to do anything. A MovHint only informs us about what would have happened
192 // in bytecode, but this code is just concerned with what is actually happening during
193 // DFG execution.
fpizlo@apple.com06f82b52013-03-06 02:27:16 +0000194 break;
195 }
196
fpizlo@apple.combcfd8eb2015-02-26 19:51:52 +0000197 case KillStack: {
fpizlo@apple.com832490a2014-10-01 20:12:11 +0000198 // This is just a hint telling us that the OSR state of the local is no longer inside the
199 // flushed data.
200 break;
201 }
202
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000203 case SetArgument:
fpizlo@apple.com8fefdd32015-02-18 19:55:47 +0000204 // Assert that the state of arguments has been set. SetArgument means that someone set
205 // the argument values out-of-band, and currently this always means setting to a
206 // non-clear value.
207 ASSERT(!m_state.variables().operand(node->local()).isClear());
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000208 break;
fpizlo@apple.com8fefdd32015-02-18 19:55:47 +0000209
210 case LoadVarargs: {
211 clobberWorld(node->origin.semantic, clobberLimit);
212 LoadVarargsData* data = node->loadVarargsData();
213 m_state.variables().operand(data->count).setType(SpecInt32);
214 for (unsigned i = data->limit - 1; i--;)
215 m_state.variables().operand(data->start.offset() + i).makeHeapTop();
216 break;
217 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000218
219 case BitAnd:
220 case BitOr:
221 case BitXor:
222 case BitRShift:
223 case BitLShift:
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000224 case BitURShift: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000225 JSValue left = forNode(node->child1()).value();
226 JSValue right = forNode(node->child2()).value();
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000227 if (left && right && left.isInt32() && right.isInt32()) {
228 int32_t a = left.asInt32();
229 int32_t b = right.asInt32();
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000230 switch (node->op()) {
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000231 case BitAnd:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000232 setConstant(node, JSValue(a & b));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000233 break;
234 case BitOr:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000235 setConstant(node, JSValue(a | b));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000236 break;
237 case BitXor:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000238 setConstant(node, JSValue(a ^ b));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000239 break;
240 case BitRShift:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000241 setConstant(node, JSValue(a >> static_cast<uint32_t>(b)));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000242 break;
243 case BitLShift:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000244 setConstant(node, JSValue(a << static_cast<uint32_t>(b)));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000245 break;
246 case BitURShift:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000247 setConstant(node, JSValue(static_cast<uint32_t>(a) >> static_cast<uint32_t>(b)));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000248 break;
249 default:
oliver@apple.com5598c182013-01-23 22:25:07 +0000250 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.comcacd7dc2012-07-09 23:28:53 +0000251 break;
252 }
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000253 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000254 }
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000255 forNode(node).setType(SpecInt32);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000256 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000257 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000258
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000259 case UInt32ToNumber: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000260 JSValue child = forNode(node->child1()).value();
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000261 if (doesOverflow(node->arithMode())) {
262 if (child && child.isInt32()) {
263 uint32_t value = child.asInt32();
264 setConstant(node, jsNumber(value));
265 break;
266 }
fpizlo@apple.combeef4522014-04-16 22:44:00 +0000267 forNode(node).setType(SpecInt52AsDouble);
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000268 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000269 }
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000270 if (child && child.isInt32()) {
271 int32_t value = child.asInt32();
272 if (value >= 0) {
273 setConstant(node, jsNumber(value));
274 break;
275 }
fpizlo@apple.com91b2c682012-05-24 06:24:36 +0000276 }
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000277 forNode(node).setType(SpecInt32);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000278 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000279 }
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000280
281 case BooleanToNumber: {
282 JSValue concreteValue = forNode(node->child1()).value();
283 if (concreteValue) {
284 if (concreteValue.isBoolean())
285 setConstant(node, jsNumber(concreteValue.asBoolean()));
286 else
fpizlo@apple.comf8cb6182015-02-23 18:03:49 +0000287 setConstant(node, *m_graph.freeze(concreteValue));
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000288 break;
289 }
290 AbstractValue& value = forNode(node);
291 value = forNode(node->child1());
292 if (node->child1().useKind() == UntypedUse && !(value.m_type & ~SpecBoolean))
293 m_state.setFoundConstants(true);
294 if (value.m_type & SpecBoolean) {
295 value.merge(SpecInt32);
296 value.filter(~SpecBoolean);
297 }
298 break;
299 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000300
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000301 case DoubleAsInt32: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000302 JSValue child = forNode(node->child1()).value();
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000303 if (child && child.isNumber()) {
304 double asDouble = child.asNumber();
305 int32_t asInt = JSC::toInt32(asDouble);
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000306 if (bitwise_cast<int64_t>(static_cast<double>(asInt)) == bitwise_cast<int64_t>(asDouble)) {
307 setConstant(node, JSValue(asInt));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000308 break;
309 }
310 }
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000311 forNode(node).setType(SpecInt32);
fpizlo@apple.com3d223382012-04-24 19:19:35 +0000312 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000313 }
fpizlo@apple.com3d223382012-04-24 19:19:35 +0000314
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000315 case ValueToInt32: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000316 JSValue child = forNode(node->child1()).value();
commit-queue@webkit.orga4990a52013-10-03 08:43:07 +0000317 if (child) {
318 if (child.isNumber()) {
319 if (child.isInt32())
320 setConstant(node, child);
321 else
322 setConstant(node, JSValue(JSC::toInt32(child.asDouble())));
323 break;
324 }
325 if (child.isBoolean()) {
fpizlo@apple.com96509b72014-05-26 17:43:41 +0000326 setConstant(node, jsNumber(child.asBoolean()));
commit-queue@webkit.orga4990a52013-10-03 08:43:07 +0000327 break;
328 }
fpizlo@apple.com29594fe2014-03-21 00:32:37 +0000329 if (child.isUndefinedOrNull()) {
330 setConstant(node, jsNumber(0));
331 break;
332 }
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000333 }
fpizlo@apple.com9c7addf2012-03-08 10:01:32 +0000334
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000335 forNode(node).setType(SpecInt32);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000336 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000337 }
oliver@apple.com500b53a2013-07-25 04:05:25 +0000338
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000339 case DoubleRep: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000340 JSValue child = forNode(node->child1()).value();
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000341 if (child && child.isNumber()) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000342 setConstant(node, jsDoubleNumber(child.asNumber()));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000343 break;
344 }
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000345 forNode(node).setType(forNode(node->child1()).m_type);
346 forNode(node).fixTypeForRepresentation(node);
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000347 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000348 }
fpizlo@apple.coma1cc0fd2012-04-24 20:43:01 +0000349
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000350 case Int52Rep: {
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000351 JSValue child = forNode(node->child1()).value();
fpizlo@apple.comf2999932014-07-15 00:41:39 +0000352 if (child && child.isMachineInt()) {
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000353 setConstant(node, child);
354 break;
355 }
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000356
357 forNode(node).setType(SpecInt32);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000358 break;
359 }
360
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000361 case ValueRep: {
362 JSValue value = forNode(node->child1()).value();
363 if (value) {
364 setConstant(node, value);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000365 break;
366 }
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000367
fpizlo@apple.com85bde1f2014-04-17 04:57:29 +0000368 forNode(node).setType(forNode(node->child1()).m_type & ~SpecDoubleImpureNaN);
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000369 forNode(node).fixTypeForRepresentation(node);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000370 break;
371 }
372
fpizlo@apple.com97756552014-01-02 20:15:25 +0000373 case ValueAdd: {
fpizlo@apple.com97756552014-01-02 20:15:25 +0000374 ASSERT(node->binaryUseKind() == UntypedUse);
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000375 clobberWorld(node->origin.semantic, clobberLimit);
fpizlo@apple.com97756552014-01-02 20:15:25 +0000376 forNode(node).setType(SpecString | SpecBytecodeNumber);
377 break;
378 }
379
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000380 case ArithAdd: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000381 JSValue left = forNode(node->child1()).value();
382 JSValue right = forNode(node->child2()).value();
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000383 switch (node->binaryUseKind()) {
384 case Int32Use:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000385 if (left && right && left.isInt32() && right.isInt32()) {
386 if (!shouldCheckOverflow(node->arithMode())) {
387 setConstant(node, jsNumber(left.asInt32() + right.asInt32()));
388 break;
389 }
390 JSValue result = jsNumber(left.asNumber() + right.asNumber());
391 if (result.isInt32()) {
392 setConstant(node, result);
393 break;
394 }
395 }
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000396 forNode(node).setType(SpecInt32);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000397 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000398 case Int52RepUse:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000399 if (left && right && left.isMachineInt() && right.isMachineInt()) {
400 JSValue result = jsNumber(left.asMachineInt() + right.asMachineInt());
401 if (result.isMachineInt()) {
402 setConstant(node, result);
403 break;
404 }
405 }
fpizlo@apple.com2058e2e2014-05-02 17:23:30 +0000406 forNode(node).setType(SpecMachineInt);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000407 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000408 case DoubleRepUse:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000409 if (left && right && left.isNumber() && right.isNumber()) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000410 setConstant(node, jsDoubleNumber(left.asNumber() + right.asNumber()));
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000411 break;
412 }
fpizlo@apple.combeef4522014-04-16 22:44:00 +0000413 forNode(node).setType(
414 typeOfDoubleSum(
415 forNode(node->child1()).m_type, forNode(node->child2()).m_type));
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000416 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000417 default:
fpizlo@apple.com97756552014-01-02 20:15:25 +0000418 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.comc0d21912012-02-14 21:26:26 +0000419 break;
420 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000421 break;
422 }
fpizlo@apple.com4463e442013-03-20 20:29:37 +0000423
424 case MakeRope: {
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000425 forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
fpizlo@apple.com4463e442013-03-20 20:29:37 +0000426 break;
427 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000428
fpizlo@apple.com0c31ace2012-02-01 23:08:54 +0000429 case ArithSub: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000430 JSValue left = forNode(node->child1()).value();
431 JSValue right = forNode(node->child2()).value();
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000432 switch (node->binaryUseKind()) {
433 case Int32Use:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000434 if (left && right && left.isInt32() && right.isInt32()) {
435 if (!shouldCheckOverflow(node->arithMode())) {
436 setConstant(node, jsNumber(left.asInt32() - right.asInt32()));
437 break;
438 }
439 JSValue result = jsNumber(left.asNumber() - right.asNumber());
440 if (result.isInt32()) {
441 setConstant(node, result);
442 break;
443 }
444 }
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000445 forNode(node).setType(SpecInt32);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000446 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000447 case Int52RepUse:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000448 if (left && right && left.isMachineInt() && right.isMachineInt()) {
449 JSValue result = jsNumber(left.asMachineInt() - right.asMachineInt());
450 if (result.isMachineInt() || !shouldCheckOverflow(node->arithMode())) {
451 setConstant(node, result);
452 break;
453 }
454 }
fpizlo@apple.com2058e2e2014-05-02 17:23:30 +0000455 forNode(node).setType(SpecMachineInt);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000456 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000457 case DoubleRepUse:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000458 if (left && right && left.isNumber() && right.isNumber()) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000459 setConstant(node, jsDoubleNumber(left.asNumber() - right.asNumber()));
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000460 break;
461 }
fpizlo@apple.combeef4522014-04-16 22:44:00 +0000462 forNode(node).setType(
463 typeOfDoubleDifference(
464 forNode(node->child1()).m_type, forNode(node->child2()).m_type));
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000465 break;
466 default:
467 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.com0c31ace2012-02-01 23:08:54 +0000468 break;
469 }
fpizlo@apple.com0c31ace2012-02-01 23:08:54 +0000470 break;
471 }
472
barraclough@apple.com8ff7e8c2012-02-28 00:31:28 +0000473 case ArithNegate: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000474 JSValue child = forNode(node->child1()).value();
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000475 switch (node->child1().useKind()) {
476 case Int32Use:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000477 if (child && child.isInt32()) {
478 if (!shouldCheckOverflow(node->arithMode())) {
479 setConstant(node, jsNumber(-child.asInt32()));
480 break;
481 }
482 double doubleResult;
483 if (shouldCheckNegativeZero(node->arithMode()))
484 doubleResult = -child.asNumber();
485 else
486 doubleResult = 0 - child.asNumber();
487 JSValue valueResult = jsNumber(doubleResult);
488 if (valueResult.isInt32()) {
489 setConstant(node, valueResult);
490 break;
491 }
492 }
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000493 forNode(node).setType(SpecInt32);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000494 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000495 case Int52RepUse:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000496 if (child && child.isMachineInt()) {
497 double doubleResult;
498 if (shouldCheckNegativeZero(node->arithMode()))
499 doubleResult = -child.asNumber();
500 else
501 doubleResult = 0 - child.asNumber();
502 JSValue valueResult = jsNumber(doubleResult);
503 if (valueResult.isMachineInt()) {
504 setConstant(node, valueResult);
505 break;
506 }
507 }
fpizlo@apple.com2058e2e2014-05-02 17:23:30 +0000508 forNode(node).setType(SpecMachineInt);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000509 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000510 case DoubleRepUse:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000511 if (child && child.isNumber()) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000512 setConstant(node, jsDoubleNumber(-child.asNumber()));
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000513 break;
514 }
fpizlo@apple.combeef4522014-04-16 22:44:00 +0000515 forNode(node).setType(
516 typeOfDoubleNegation(
517 forNode(node->child1()).m_type));
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000518 break;
519 default:
520 RELEASE_ASSERT_NOT_REACHED();
barraclough@apple.com8ff7e8c2012-02-28 00:31:28 +0000521 break;
522 }
barraclough@apple.com8ff7e8c2012-02-28 00:31:28 +0000523 break;
524 }
525
fpizlo@apple.comfa9f10c2012-05-22 17:18:21 +0000526 case ArithMul: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000527 JSValue left = forNode(node->child1()).value();
528 JSValue right = forNode(node->child2()).value();
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000529 switch (node->binaryUseKind()) {
530 case Int32Use:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000531 if (left && right && left.isInt32() && right.isInt32()) {
532 if (!shouldCheckOverflow(node->arithMode())) {
533 setConstant(node, jsNumber(left.asInt32() * right.asInt32()));
534 break;
535 }
536 double doubleResult = left.asNumber() * right.asNumber();
537 if (!shouldCheckNegativeZero(node->arithMode()))
538 doubleResult += 0; // Sanitizes zero.
539 JSValue valueResult = jsNumber(doubleResult);
540 if (valueResult.isInt32()) {
541 setConstant(node, valueResult);
542 break;
543 }
544 }
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000545 forNode(node).setType(SpecInt32);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000546 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000547 case Int52RepUse:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000548 if (left && right && left.isMachineInt() && right.isMachineInt()) {
549 double doubleResult = left.asNumber() * right.asNumber();
550 if (!shouldCheckNegativeZero(node->arithMode()))
551 doubleResult += 0;
552 JSValue valueResult = jsNumber(doubleResult);
553 if (valueResult.isMachineInt()) {
554 setConstant(node, valueResult);
555 break;
556 }
557 }
fpizlo@apple.com2058e2e2014-05-02 17:23:30 +0000558 forNode(node).setType(SpecMachineInt);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000559 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000560 case DoubleRepUse:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000561 if (left && right && left.isNumber() && right.isNumber()) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000562 setConstant(node, jsDoubleNumber(left.asNumber() * right.asNumber()));
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000563 break;
564 }
fpizlo@apple.combeef4522014-04-16 22:44:00 +0000565 forNode(node).setType(
566 typeOfDoubleProduct(
567 forNode(node->child1()).m_type, forNode(node->child2()).m_type));
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000568 break;
569 default:
570 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.comfa9f10c2012-05-22 17:18:21 +0000571 break;
572 }
fpizlo@apple.comfa9f10c2012-05-22 17:18:21 +0000573 break;
574 }
575
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000576 case ArithDiv: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000577 JSValue left = forNode(node->child1()).value();
578 JSValue right = forNode(node->child2()).value();
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000579 switch (node->binaryUseKind()) {
580 case Int32Use:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000581 if (left && right && left.isInt32() && right.isInt32()) {
582 double doubleResult = left.asNumber() / right.asNumber();
583 if (!shouldCheckOverflow(node->arithMode()))
584 doubleResult = toInt32(doubleResult);
585 else if (!shouldCheckNegativeZero(node->arithMode()))
586 doubleResult += 0; // Sanitizes zero.
587 JSValue valueResult = jsNumber(doubleResult);
588 if (valueResult.isInt32()) {
589 setConstant(node, valueResult);
590 break;
591 }
592 }
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000593 forNode(node).setType(SpecInt32);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000594 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000595 case DoubleRepUse:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000596 if (left && right && left.isNumber() && right.isNumber()) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000597 setConstant(node, jsDoubleNumber(left.asNumber() / right.asNumber()));
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000598 break;
599 }
fpizlo@apple.combeef4522014-04-16 22:44:00 +0000600 forNode(node).setType(
601 typeOfDoubleQuotient(
602 forNode(node->child1()).m_type, forNode(node->child2()).m_type));
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000603 break;
604 default:
605 RELEASE_ASSERT_NOT_REACHED();
606 break;
607 }
608 break;
609 }
610
611 case ArithMod: {
612 JSValue left = forNode(node->child1()).value();
613 JSValue right = forNode(node->child2()).value();
614 switch (node->binaryUseKind()) {
615 case Int32Use:
616 if (left && right && left.isInt32() && right.isInt32()) {
617 double doubleResult = fmod(left.asNumber(), right.asNumber());
618 if (!shouldCheckOverflow(node->arithMode()))
619 doubleResult = toInt32(doubleResult);
620 else if (!shouldCheckNegativeZero(node->arithMode()))
621 doubleResult += 0; // Sanitizes zero.
622 JSValue valueResult = jsNumber(doubleResult);
623 if (valueResult.isInt32()) {
624 setConstant(node, valueResult);
625 break;
626 }
627 }
628 forNode(node).setType(SpecInt32);
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000629 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000630 case DoubleRepUse:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000631 if (left && right && left.isNumber() && right.isNumber()) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000632 setConstant(node, jsDoubleNumber(fmod(left.asNumber(), right.asNumber())));
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000633 break;
634 }
fpizlo@apple.combeef4522014-04-16 22:44:00 +0000635 forNode(node).setType(
636 typeOfDoubleBinaryOp(
637 forNode(node->child1()).m_type, forNode(node->child2()).m_type));
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000638 break;
639 default:
640 RELEASE_ASSERT_NOT_REACHED();
641 break;
642 }
643 break;
644 }
645
646 case ArithMin: {
647 JSValue left = forNode(node->child1()).value();
648 JSValue right = forNode(node->child2()).value();
649 switch (node->binaryUseKind()) {
650 case Int32Use:
651 if (left && right && left.isInt32() && right.isInt32()) {
652 setConstant(node, jsNumber(std::min(left.asInt32(), right.asInt32())));
653 break;
654 }
655 forNode(node).setType(SpecInt32);
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000656 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000657 case DoubleRepUse:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000658 if (left && right && left.isNumber() && right.isNumber()) {
659 double a = left.asNumber();
660 double b = right.asNumber();
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000661 setConstant(node, jsDoubleNumber(a < b ? a : (b <= a ? b : a + b)));
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000662 break;
663 }
fpizlo@apple.combeef4522014-04-16 22:44:00 +0000664 forNode(node).setType(
665 typeOfDoubleMinMax(
666 forNode(node->child1()).m_type, forNode(node->child2()).m_type));
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000667 break;
668 default:
669 RELEASE_ASSERT_NOT_REACHED();
670 break;
671 }
672 break;
673 }
674
675 case ArithMax: {
676 JSValue left = forNode(node->child1()).value();
677 JSValue right = forNode(node->child2()).value();
678 switch (node->binaryUseKind()) {
679 case Int32Use:
680 if (left && right && left.isInt32() && right.isInt32()) {
681 setConstant(node, jsNumber(std::max(left.asInt32(), right.asInt32())));
682 break;
683 }
684 forNode(node).setType(SpecInt32);
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000685 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000686 case DoubleRepUse:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000687 if (left && right && left.isNumber() && right.isNumber()) {
688 double a = left.asNumber();
689 double b = right.asNumber();
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000690 setConstant(node, jsDoubleNumber(a > b ? a : (b >= a ? b : a + b)));
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000691 break;
692 }
fpizlo@apple.combeef4522014-04-16 22:44:00 +0000693 forNode(node).setType(
694 typeOfDoubleMinMax(
695 forNode(node->child1()).m_type, forNode(node->child2()).m_type));
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000696 break;
697 default:
698 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000699 break;
700 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000701 break;
702 }
703
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000704 case ArithAbs: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000705 JSValue child = forNode(node->child1()).value();
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000706 switch (node->child1().useKind()) {
707 case Int32Use:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000708 if (child && child.isInt32()) {
709 JSValue result = jsNumber(fabs(child.asNumber()));
710 if (result.isInt32()) {
711 setConstant(node, result);
712 break;
713 }
714 }
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000715 forNode(node).setType(SpecInt32);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000716 break;
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000717 case DoubleRepUse:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000718 if (child && child.isNumber()) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000719 setConstant(node, jsDoubleNumber(child.asNumber()));
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000720 break;
721 }
fpizlo@apple.combeef4522014-04-16 22:44:00 +0000722 forNode(node).setType(typeOfDoubleAbs(forNode(node->child1()).m_type));
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000723 break;
724 default:
725 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000726 break;
727 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000728 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000729 }
benjamin@webkit.org903025b2015-02-14 04:20:21 +0000730
731 case ArithPow: {
732 JSValue childY = forNode(node->child2()).value();
733 if (childY && childY.isNumber()) {
734 if (!childY.asNumber()) {
735 setConstant(node, jsDoubleNumber(1));
736 break;
737 }
738
739 JSValue childX = forNode(node->child1()).value();
740 if (childX && childX.isNumber()) {
741 setConstant(node, jsDoubleNumber(operationMathPow(childX.asNumber(), childY.asNumber())));
742 break;
743 }
744 }
745 forNode(node).setType(typeOfDoublePow(forNode(node->child1()).m_type, forNode(node->child2()).m_type));
746 break;
747 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000748
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000749 case ArithSqrt: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000750 JSValue child = forNode(node->child1()).value();
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000751 if (child && child.isNumber()) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000752 setConstant(node, jsDoubleNumber(sqrt(child.asNumber())));
fpizlo@apple.comb3336c72013-10-31 19:19:15 +0000753 break;
754 }
fpizlo@apple.combeef4522014-04-16 22:44:00 +0000755 forNode(node).setType(typeOfDoubleUnaryOp(forNode(node->child1()).m_type));
fpizlo@apple.comb3336c72013-10-31 19:19:15 +0000756 break;
757 }
758
fpizlo@apple.comc5919412014-04-12 23:01:33 +0000759 case ArithFRound: {
760 JSValue child = forNode(node->child1()).value();
761 if (child && child.isNumber()) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000762 setConstant(node, jsDoubleNumber(static_cast<float>(child.asNumber())));
fpizlo@apple.comc5919412014-04-12 23:01:33 +0000763 break;
764 }
fpizlo@apple.combeef4522014-04-16 22:44:00 +0000765 forNode(node).setType(typeOfDoubleFRound(forNode(node->child1()).m_type));
fpizlo@apple.comc5919412014-04-12 23:01:33 +0000766 break;
767 }
768
fpizlo@apple.comb3336c72013-10-31 19:19:15 +0000769 case ArithSin: {
770 JSValue child = forNode(node->child1()).value();
fpizlo@apple.com8a5fd182015-02-02 18:38:08 +0000771 if (false && child && child.isNumber()) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000772 setConstant(node, jsDoubleNumber(sin(child.asNumber())));
fpizlo@apple.comb3336c72013-10-31 19:19:15 +0000773 break;
774 }
fpizlo@apple.combeef4522014-04-16 22:44:00 +0000775 forNode(node).setType(typeOfDoubleUnaryOp(forNode(node->child1()).m_type));
fpizlo@apple.comb3336c72013-10-31 19:19:15 +0000776 break;
777 }
778
779 case ArithCos: {
780 JSValue child = forNode(node->child1()).value();
fpizlo@apple.com8a5fd182015-02-02 18:38:08 +0000781 if (false && child && child.isNumber()) {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000782 setConstant(node, jsDoubleNumber(cos(child.asNumber())));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000783 break;
784 }
fpizlo@apple.combeef4522014-04-16 22:44:00 +0000785 forNode(node).setType(typeOfDoubleUnaryOp(forNode(node->child1()).m_type));
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000786 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000787 }
benjamin@webkit.org2b5682d2015-03-04 22:39:28 +0000788
789 case ArithLog: {
790 JSValue child = forNode(node->child1()).value();
791 if (child && child.isNumber()) {
792 setConstant(node, jsDoubleNumber(log(child.asNumber())));
793 break;
794 }
795 forNode(node).setType(typeOfDoubleUnaryOp(forNode(node->child1()).m_type));
796 break;
797 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000798
799 case LogicalNot: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000800 switch (booleanResult(node, forNode(node->child1()))) {
fpizlo@apple.com367a1102012-11-10 23:33:29 +0000801 case DefinitelyTrue:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000802 setConstant(node, jsBoolean(false));
fpizlo@apple.com367a1102012-11-10 23:33:29 +0000803 break;
804 case DefinitelyFalse:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000805 setConstant(node, jsBoolean(true));
fpizlo@apple.com367a1102012-11-10 23:33:29 +0000806 break;
807 default:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000808 forNode(node).setType(SpecBoolean);
fpizlo@apple.com367a1102012-11-10 23:33:29 +0000809 break;
810 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000811 break;
812 }
fpizlo@apple.com1d216892012-04-12 00:55:44 +0000813
814 case IsUndefined:
815 case IsBoolean:
816 case IsNumber:
817 case IsString:
818 case IsObject:
utatane.tea@gmail.com0bfb74c2015-02-24 23:01:58 +0000819 case IsObjectOrNull:
fpizlo@apple.com1d216892012-04-12 00:55:44 +0000820 case IsFunction: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000821 JSValue child = forNode(node->child1()).value();
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000822 if (child) {
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000823 bool constantWasSet = true;
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000824 switch (node->op()) {
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000825 case IsUndefined:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000826 setConstant(node, jsBoolean(
oliver@apple.com67e0f332013-07-25 03:59:00 +0000827 child.isCell()
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000828 ? child.asCell()->structure()->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->origin.semantic))
oliver@apple.com67e0f332013-07-25 03:59:00 +0000829 : child.isUndefined()));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000830 break;
831 case IsBoolean:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000832 setConstant(node, jsBoolean(child.isBoolean()));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000833 break;
834 case IsNumber:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000835 setConstant(node, jsBoolean(child.isNumber()));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000836 break;
837 case IsString:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000838 setConstant(node, jsBoolean(isJSString(child)));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000839 break;
oliver@apple.come722ad02013-01-09 02:37:29 +0000840 case IsObject:
utatane.tea@gmail.com0bfb74c2015-02-24 23:01:58 +0000841 setConstant(node, jsBoolean(child.isObject()));
842 break;
843 case IsObjectOrNull:
oliver@apple.come722ad02013-01-09 02:37:29 +0000844 if (child.isNull() || !child.isObject()) {
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000845 setConstant(node, jsBoolean(child.isNull()));
oliver@apple.come722ad02013-01-09 02:37:29 +0000846 break;
847 }
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000848 constantWasSet = false;
849 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000850 default:
fpizlo@apple.comcacd7dc2012-07-09 23:28:53 +0000851 constantWasSet = false;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000852 break;
853 }
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000854 if (constantWasSet)
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000855 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000856 }
oliver@apple.come722ad02013-01-09 02:37:29 +0000857
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000858 forNode(node).setType(SpecBoolean);
fpizlo@apple.com1d216892012-04-12 00:55:44 +0000859 break;
860 }
oliver@apple.come722ad02013-01-09 02:37:29 +0000861
862 case TypeOf: {
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000863 VM* vm = m_codeBlock->vm();
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000864 JSValue child = forNode(node->child1()).value();
865 AbstractValue& abstractChild = forNode(node->child1());
oliver@apple.come722ad02013-01-09 02:37:29 +0000866 if (child) {
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000867 JSValue typeString = jsTypeStringForValue(*vm, m_codeBlock->globalObjectFor(node->origin.semantic), child);
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000868 setConstant(node, *m_graph.freeze(typeString));
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000869 break;
870 }
871
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000872 if (isFullNumberSpeculation(abstractChild.m_type)) {
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000873 setConstant(node, *m_graph.freeze(vm->smallStrings.numberString()));
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000874 break;
875 }
876
877 if (isStringSpeculation(abstractChild.m_type)) {
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000878 setConstant(node, *m_graph.freeze(vm->smallStrings.stringString()));
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000879 break;
880 }
881
882 if (isFinalObjectSpeculation(abstractChild.m_type) || isArraySpeculation(abstractChild.m_type) || isArgumentsSpeculation(abstractChild.m_type)) {
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000883 setConstant(node, *m_graph.freeze(vm->smallStrings.objectString()));
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000884 break;
885 }
886
887 if (isFunctionSpeculation(abstractChild.m_type)) {
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000888 setConstant(node, *m_graph.freeze(vm->smallStrings.functionString()));
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000889 break;
890 }
891
892 if (isBooleanSpeculation(abstractChild.m_type)) {
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000893 setConstant(node, *m_graph.freeze(vm->smallStrings.booleanString()));
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000894 break;
fpizlo@apple.comcd81b572013-02-11 21:39:35 +0000895 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000896
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000897 forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
oliver@apple.come722ad02013-01-09 02:37:29 +0000898 break;
899 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000900
901 case CompareLess:
902 case CompareLessEq:
903 case CompareGreater:
904 case CompareGreaterEq:
fpizlo@apple.comb03b1402013-02-11 22:23:08 +0000905 case CompareEq:
906 case CompareEqConstant: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000907 JSValue leftConst = forNode(node->child1()).value();
908 JSValue rightConst = forNode(node->child2()).value();
oliver@apple.combd15be82013-07-25 04:03:42 +0000909 if (leftConst && rightConst) {
910 if (leftConst.isNumber() && rightConst.isNumber()) {
911 double a = leftConst.asNumber();
912 double b = rightConst.asNumber();
913 switch (node->op()) {
914 case CompareLess:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000915 setConstant(node, jsBoolean(a < b));
oliver@apple.combd15be82013-07-25 04:03:42 +0000916 break;
917 case CompareLessEq:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000918 setConstant(node, jsBoolean(a <= b));
oliver@apple.combd15be82013-07-25 04:03:42 +0000919 break;
920 case CompareGreater:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000921 setConstant(node, jsBoolean(a > b));
oliver@apple.combd15be82013-07-25 04:03:42 +0000922 break;
923 case CompareGreaterEq:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000924 setConstant(node, jsBoolean(a >= b));
oliver@apple.combd15be82013-07-25 04:03:42 +0000925 break;
926 case CompareEq:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000927 setConstant(node, jsBoolean(a == b));
oliver@apple.combd15be82013-07-25 04:03:42 +0000928 break;
929 default:
930 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000931 break;
932 }
933 break;
934 }
935
936 if (node->op() == CompareEq && leftConst.isString() && rightConst.isString()) {
937 const StringImpl* a = asString(leftConst)->tryGetValueImpl();
938 const StringImpl* b = asString(rightConst)->tryGetValueImpl();
939 if (a && b) {
940 setConstant(node, jsBoolean(WTF::equal(a, b)));
oliver@apple.combd15be82013-07-25 04:03:42 +0000941 break;
942 }
943 }
fpizlo@apple.comf884bb72012-11-09 01:57:14 +0000944 }
945
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000946 if (node->op() == CompareEqConstant || node->op() == CompareEq) {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000947 SpeculatedType leftType = forNode(node->child1()).m_type;
948 SpeculatedType rightType = forNode(node->child2()).m_type;
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000949 if (!valuesCouldBeEqual(leftType, rightType)) {
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000950 setConstant(node, jsBoolean(false));
951 break;
952 }
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000953 }
954
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000955 forNode(node).setType(SpecBoolean);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000956 break;
957 }
958
fpizlo@apple.com312efcd2014-03-10 22:11:35 +0000959 case CompareStrictEq: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000960 Node* leftNode = node->child1().node();
961 Node* rightNode = node->child2().node();
962 JSValue left = forNode(leftNode).value();
963 JSValue right = forNode(rightNode).value();
oliver@apple.combd15be82013-07-25 04:03:42 +0000964 if (left && right) {
oliver@apple.combd15be82013-07-25 04:03:42 +0000965 if (left.isString() && right.isString()) {
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000966 // We need this case because JSValue::strictEqual is otherwise too racy for
967 // string comparisons.
oliver@apple.combd15be82013-07-25 04:03:42 +0000968 const StringImpl* a = asString(left)->tryGetValueImpl();
969 const StringImpl* b = asString(right)->tryGetValueImpl();
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000970 if (a && b) {
971 setConstant(node, jsBoolean(WTF::equal(a, b)));
oliver@apple.combd15be82013-07-25 04:03:42 +0000972 break;
973 }
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000974 } else {
975 setConstant(node, jsBoolean(JSValue::strictEqual(0, left, right)));
976 break;
oliver@apple.combd15be82013-07-25 04:03:42 +0000977 }
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000978 }
fpizlo@apple.come079bb52014-03-05 07:41:03 +0000979
980 SpeculatedType leftLUB = leastUpperBoundOfStrictlyEquivalentSpeculations(forNode(leftNode).m_type);
981 SpeculatedType rightLUB = leastUpperBoundOfStrictlyEquivalentSpeculations(forNode(rightNode).m_type);
982 if (!(leftLUB & rightLUB)) {
983 setConstant(node, jsBoolean(false));
984 break;
985 }
986
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000987 forNode(node).setType(SpecBoolean);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000988 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000989 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000990
991 case StringCharCodeAt:
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000992 forNode(node).setType(SpecInt32);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000993 break;
994
commit-queue@webkit.orgaa31a5e2013-04-09 06:45:16 +0000995 case StringFromCharCode:
oliver@apple.com67e0f332013-07-25 03:59:00 +0000996 forNode(node).setType(SpecString);
commit-queue@webkit.orgaa31a5e2013-04-09 06:45:16 +0000997 break;
998
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000999 case StringCharAt:
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001000 forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001001 break;
1002
1003 case GetByVal: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001004 switch (node->arrayMode().type()) {
fpizlo@apple.coma0ec0592012-10-22 23:52:15 +00001005 case Array::SelectUsingPredictions:
fpizlo@apple.com97af5762012-09-19 22:36:44 +00001006 case Array::Unprofiled:
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001007 case Array::Undecided:
oliver@apple.com5598c182013-01-23 22:25:07 +00001008 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001009 break;
1010 case Array::ForceExit:
oliver@apple.com55d32d92013-07-25 04:05:03 +00001011 m_state.setIsValid(false);
fpizlo@apple.com6306b5652011-12-23 05:47:17 +00001012 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001013 case Array::Generic:
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001014 clobberWorld(node->origin.semantic, clobberLimit);
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001015 forNode(node).makeHeapTop();
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001016 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001017 case Array::String:
oliver@apple.com211b3be2013-07-25 04:03:39 +00001018 if (node->arrayMode().isOutOfBounds()) {
1019 // If the watchpoint was still valid we could totally set this to be
1020 // SpecString | SpecOther. Except that we'd have to be careful. If we
1021 // tested the watchpoint state here then it could change by the time
1022 // we got to the backend. So to do this right, we'd have to get the
1023 // fixup phase to check the watchpoint state and then bake into the
1024 // GetByVal operation the fact that we're using a watchpoint, using
1025 // something like Array::SaneChain (except not quite, because that
1026 // implies an in-bounds access). None of this feels like it's worth it,
oliver@apple.come6427742013-07-25 04:05:12 +00001027 // so we're going with TOP for now. The same thing applies to
1028 // clobbering the world.
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001029 clobberWorld(node->origin.semantic, clobberLimit);
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001030 forNode(node).makeHeapTop();
oliver@apple.com211b3be2013-07-25 04:03:39 +00001031 } else
1032 forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001033 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001034 case Array::Arguments:
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001035 forNode(node).makeHeapTop();
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001036 break;
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001037 case Array::Int32:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001038 if (node->arrayMode().isOutOfBounds()) {
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001039 clobberWorld(node->origin.semantic, clobberLimit);
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001040 forNode(node).makeHeapTop();
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001041 } else
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001042 forNode(node).setType(SpecInt32);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001043 break;
1044 case Array::Double:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001045 if (node->arrayMode().isOutOfBounds()) {
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001046 clobberWorld(node->origin.semantic, clobberLimit);
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001047 forNode(node).makeHeapTop();
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001048 } else if (node->arrayMode().isSaneChain())
fpizlo@apple.combeef4522014-04-16 22:44:00 +00001049 forNode(node).setType(SpecBytecodeDouble);
fpizlo@apple.com94e84e92012-11-11 02:56:12 +00001050 else
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001051 forNode(node).setType(SpecDoubleReal);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001052 break;
fpizlo@apple.com34d1f082012-10-28 06:13:23 +00001053 case Array::Contiguous:
1054 case Array::ArrayStorage:
1055 case Array::SlowPutArrayStorage:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001056 if (node->arrayMode().isOutOfBounds())
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001057 clobberWorld(node->origin.semantic, clobberLimit);
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001058 forNode(node).makeHeapTop();
fpizlo@apple.comfa34ff82012-09-05 01:27:50 +00001059 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001060 case Array::Int8Array:
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001061 forNode(node).setType(SpecInt32);
oliver@apple.comaeec3d82011-12-02 01:56:53 +00001062 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001063 case Array::Int16Array:
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001064 forNode(node).setType(SpecInt32);
oliver@apple.comaeec3d82011-12-02 01:56:53 +00001065 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001066 case Array::Int32Array:
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001067 forNode(node).setType(SpecInt32);
oliver@apple.comaeec3d82011-12-02 01:56:53 +00001068 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001069 case Array::Uint8Array:
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001070 forNode(node).setType(SpecInt32);
oliver@apple.comaeec3d82011-12-02 01:56:53 +00001071 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001072 case Array::Uint8ClampedArray:
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001073 forNode(node).setType(SpecInt32);
caio.oliveira@openbossa.org992fc372012-01-18 01:11:16 +00001074 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001075 case Array::Uint16Array:
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001076 forNode(node).setType(SpecInt32);
oliver@apple.comaeec3d82011-12-02 01:56:53 +00001077 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001078 case Array::Uint32Array:
fpizlo@apple.comefacb612013-09-10 22:16:00 +00001079 if (node->shouldSpeculateInt32())
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001080 forNode(node).setType(SpecInt32);
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001081 else if (enableInt52() && node->shouldSpeculateMachineInt())
1082 forNode(node).setType(SpecInt52);
fpizlo@apple.com691ac792012-03-13 22:59:43 +00001083 else
fpizlo@apple.combeef4522014-04-16 22:44:00 +00001084 forNode(node).setType(SpecInt52AsDouble);
oliver@apple.comaeec3d82011-12-02 01:56:53 +00001085 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001086 case Array::Float32Array:
fpizlo@apple.com85bde1f2014-04-17 04:57:29 +00001087 forNode(node).setType(SpecFullDouble);
oliver@apple.com07d75732011-12-03 01:47:27 +00001088 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001089 case Array::Float64Array:
fpizlo@apple.com85bde1f2014-04-17 04:57:29 +00001090 forNode(node).setType(SpecFullDouble);
oliver@apple.com07d75732011-12-03 01:47:27 +00001091 break;
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001092 default:
oliver@apple.com5598c182013-01-23 22:25:07 +00001093 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001094 break;
oliver@apple.com07d75732011-12-03 01:47:27 +00001095 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001096 break;
1097 }
1098
oliver@apple.come050d642013-10-19 00:09:28 +00001099 case PutByValDirect:
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001100 case PutByVal:
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001101 case PutByValAlias: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001102 switch (node->arrayMode().modeForPut().type()) {
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001103 case Array::ForceExit:
oliver@apple.com55d32d92013-07-25 04:05:03 +00001104 m_state.setIsValid(false);
fpizlo@apple.com6306b5652011-12-23 05:47:17 +00001105 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001106 case Array::Generic:
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001107 clobberWorld(node->origin.semantic, clobberLimit);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001108 break;
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001109 case Array::Int32:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001110 if (node->arrayMode().isOutOfBounds())
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001111 clobberWorld(node->origin.semantic, clobberLimit);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001112 break;
1113 case Array::Double:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001114 if (node->arrayMode().isOutOfBounds())
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001115 clobberWorld(node->origin.semantic, clobberLimit);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001116 break;
fpizlo@apple.com34d1f082012-10-28 06:13:23 +00001117 case Array::Contiguous:
1118 case Array::ArrayStorage:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001119 if (node->arrayMode().isOutOfBounds())
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001120 clobberWorld(node->origin.semantic, clobberLimit);
fpizlo@apple.com34d1f082012-10-28 06:13:23 +00001121 break;
1122 case Array::SlowPutArrayStorage:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001123 if (node->arrayMode().mayStoreToHole())
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001124 clobberWorld(node->origin.semantic, clobberLimit);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001125 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001126 default:
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001127 break;
oliver@apple.com07d75732011-12-03 01:47:27 +00001128 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001129 break;
1130 }
1131
1132 case ArrayPush:
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001133 clobberWorld(node->origin.semantic, clobberLimit);
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001134 forNode(node).setType(SpecBytecodeNumber);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001135 break;
1136
1137 case ArrayPop:
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001138 clobberWorld(node->origin.semantic, clobberLimit);
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001139 forNode(node).makeHeapTop();
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001140 break;
1141
barraclough@apple.com077fdd42012-03-18 01:08:16 +00001142 case RegExpExec:
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001143 forNode(node).makeHeapTop();
barraclough@apple.com077fdd42012-03-18 01:08:16 +00001144 break;
msaboff@apple.com3fc51292013-04-25 18:35:04 +00001145
1146 case RegExpTest:
oliver@apple.com67e0f332013-07-25 03:59:00 +00001147 forNode(node).setType(SpecBoolean);
msaboff@apple.com3fc51292013-04-25 18:35:04 +00001148 break;
barraclough@apple.com077fdd42012-03-18 01:08:16 +00001149
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001150 case Jump:
1151 break;
1152
1153 case Branch: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001154 Node* child = node->child1().node();
1155 BooleanResult result = booleanResult(node, forNode(child));
fpizlo@apple.com367a1102012-11-10 23:33:29 +00001156 if (result == DefinitelyTrue) {
oliver@apple.com55d32d92013-07-25 04:05:03 +00001157 m_state.setBranchDirection(TakeTrue);
fpizlo@apple.com367a1102012-11-10 23:33:29 +00001158 break;
1159 }
1160 if (result == DefinitelyFalse) {
oliver@apple.com55d32d92013-07-25 04:05:03 +00001161 m_state.setBranchDirection(TakeFalse);
fpizlo@apple.comdb7ba192012-05-24 02:28:52 +00001162 break;
1163 }
1164 // FIXME: The above handles the trivial cases of sparse conditional
1165 // constant propagation, but we can do better:
fpizlo@apple.com367a1102012-11-10 23:33:29 +00001166 // We can specialize the source variable's value on each direction of
1167 // the branch.
oliver@apple.com55d32d92013-07-25 04:05:03 +00001168 m_state.setBranchDirection(TakeBoth);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001169 break;
1170 }
oliver@apple.com9b7647b2013-07-25 04:03:00 +00001171
1172 case Switch: {
1173 // Nothing to do for now.
1174 // FIXME: Do sparse conditional things.
1175 break;
1176 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001177
1178 case Return:
oliver@apple.com55d32d92013-07-25 04:05:03 +00001179 m_state.setIsValid(false);
fpizlo@apple.com91b2c682012-05-24 06:24:36 +00001180 break;
1181
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001182 case Throw:
1183 case ThrowReferenceError:
oliver@apple.com55d32d92013-07-25 04:05:03 +00001184 m_state.setIsValid(false);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001185 break;
1186
1187 case ToPrimitive: {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001188 JSValue childConst = forNode(node->child1()).value();
fpizlo@apple.com49e37d32013-09-11 21:49:47 +00001189 if (childConst && childConst.isNumber()) {
1190 setConstant(node, childConst);
fpizlo@apple.com3187c922012-05-18 21:47:53 +00001191 break;
1192 }
1193
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001194 ASSERT(node->child1().useKind() == UntypedUse);
1195
fpizlo@apple.com6e550a42014-02-17 20:23:34 +00001196 if (!forNode(node->child1()).m_type) {
1197 m_state.setIsValid(false);
1198 break;
1199 }
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001200
utatane.tea@gmail.com0bfb74c2015-02-24 23:01:58 +00001201 if (!(forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean | SpecString | SpecCellOther))) {
fpizlo@apple.com6e550a42014-02-17 20:23:34 +00001202 m_state.setFoundConstants(true);
1203 forNode(node) = forNode(node->child1());
1204 break;
1205 }
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001206
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001207 clobberWorld(node->origin.semantic, clobberLimit);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001208
utatane.tea@gmail.com0bfb74c2015-02-24 23:01:58 +00001209 forNode(node).setType((SpecHeapTop & ~SpecCell) | SpecString | SpecCellOther);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001210 break;
1211 }
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001212
1213 case ToString: {
1214 switch (node->child1().useKind()) {
1215 case StringObjectUse:
1216 // This also filters that the StringObject has the primordial StringObject
1217 // structure.
oliver@apple.com33913872013-07-25 04:02:13 +00001218 filter(
1219 node->child1(),
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001220 m_graph.globalObjectFor(node->origin.semantic)->stringObjectStructure());
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001221 break;
1222 case StringOrStringObjectUse:
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001223 break;
1224 case CellUse:
1225 case UntypedUse:
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001226 clobberWorld(node->origin.semantic, clobberLimit);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001227 break;
1228 default:
1229 RELEASE_ASSERT_NOT_REACHED();
1230 break;
1231 }
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001232 forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001233 break;
1234 }
1235
1236 case NewStringObject: {
fpizlo@apple.com10ae2d02013-08-14 02:41:47 +00001237 ASSERT(node->structure()->classInfo() == StringObject::info());
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001238 forNode(node).set(m_graph, node->structure());
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001239 break;
1240 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001241
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001242 case NewArray:
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001243 forNode(node).set(
1244 m_graph,
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001245 m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
fpizlo@apple.com6c89cd32012-06-26 19:42:05 +00001246 break;
1247
fpizlo@apple.com1c4a32c2012-09-17 20:56:39 +00001248 case NewArrayBuffer:
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001249 forNode(node).set(
1250 m_graph,
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001251 m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
fpizlo@apple.com1c4a32c2012-09-17 20:56:39 +00001252 break;
1253
fpizlo@apple.com6c89cd32012-06-26 19:42:05 +00001254 case NewArrayWithSize:
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001255 forNode(node).setType(SpecArray);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001256 break;
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001257
1258 case NewTypedArray:
1259 switch (node->child1().useKind()) {
1260 case Int32Use:
1261 break;
1262 case UntypedUse:
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001263 clobberWorld(node->origin.semantic, clobberLimit);
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001264 break;
1265 default:
1266 RELEASE_ASSERT_NOT_REACHED();
1267 break;
1268 }
1269 forNode(node).set(
1270 m_graph,
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001271 m_graph.globalObjectFor(node->origin.semantic)->typedArrayStructure(
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001272 node->typedArrayType()));
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001273 break;
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001274
1275 case NewRegexp:
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001276 forNode(node).set(m_graph, m_graph.globalObjectFor(node->origin.semantic)->regExpStructure());
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001277 break;
1278
oliver@apple.come2fe4ce2013-07-25 03:59:41 +00001279 case ToThis: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001280 AbstractValue& source = forNode(node->child1());
1281 AbstractValue& destination = forNode(node);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001282
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001283 if (m_graph.executableFor(node->origin.semantic)->isStrictMode())
fpizlo@apple.com018818d2013-09-13 23:18:19 +00001284 destination.makeHeapTop();
1285 else {
1286 destination = source;
1287 destination.merge(SpecObject);
1288 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001289 break;
1290 }
barraclough@apple.comcef11dc2012-05-10 18:40:29 +00001291
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001292 case CreateThis: {
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001293 forNode(node).setType(SpecFinalObject);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001294 break;
1295 }
fpizlo@apple.comf5db15e2012-11-14 07:22:57 +00001296
ggaren@apple.comc862eac2013-01-29 05:48:01 +00001297 case AllocationProfileWatchpoint:
fpizlo@apple.comf5db15e2012-11-14 07:22:57 +00001298 break;
barraclough@apple.comcef11dc2012-05-10 18:40:29 +00001299
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001300 case NewObject:
fpizlo@apple.com62203aa2013-12-03 22:24:53 +00001301 ASSERT(node->structure());
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001302 forNode(node).set(m_graph, node->structure());
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001303 break;
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001304
fpizlo@apple.comfc70ba62014-09-26 03:59:33 +00001305 case PhantomNewObject:
1306 case BottomValue:
1307 m_state.setDidClobber(true); // Prevent constant folding.
1308 // This claims to return bottom.
1309 break;
1310
1311 case PutByOffsetHint:
1312 case PutStructureHint:
1313 break;
1314
1315 case MaterializeNewObject: {
1316 StructureSet set;
1317
1318 m_phiChildren->forAllTransitiveIncomingValues(
1319 m_graph.varArgChild(node, 0).node(),
1320 [&] (Node* incoming) {
1321 set.add(incoming->castConstant<Structure*>());
1322 });
1323
1324 forNode(node).set(m_graph, set);
1325 break;
1326 }
1327
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001328 case CreateActivation:
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001329 forNode(node).set(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001330 m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->activationStructure());
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001331 break;
fpizlo@apple.com1a724092013-11-28 07:10:10 +00001332
fpizlo@apple.comce995b22013-12-08 19:01:17 +00001333 case TypedArrayWatchpoint:
fpizlo@apple.com1a724092013-11-28 07:10:10 +00001334 break;
oliver@apple.com83ec76b2013-09-21 00:00:30 +00001335
fpizlo@apple.comf860f9b2012-05-22 20:02:25 +00001336 case CreateArguments:
fpizlo@apple.come5fd43b2014-01-09 20:41:06 +00001337 forNode(node) = forNode(node->child1());
1338 forNode(node).filter(~SpecEmpty);
1339 forNode(node).merge(SpecArguments);
fpizlo@apple.comf860f9b2012-05-22 20:02:25 +00001340 break;
1341
fpizlo@apple.com15c03c72012-05-23 02:34:13 +00001342 case TearOffArguments:
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001343 // Does nothing that is user-visible.
1344 break;
fpizlo@apple.com91b2c682012-05-24 06:24:36 +00001345
1346 case CheckArgumentsNotCreated:
fpizlo@apple.com62336162012-06-07 01:35:59 +00001347 if (isEmptySpeculation(
oliver@apple.com55d32d92013-07-25 04:05:03 +00001348 m_state.variables().operand(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001349 m_graph.argumentsRegisterFor(node->origin.semantic).offset()).m_type))
oliver@apple.com55d32d92013-07-25 04:05:03 +00001350 m_state.setFoundConstants(true);
fpizlo@apple.com91b2c682012-05-24 06:24:36 +00001351 break;
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001352
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +00001353 case GetMyArgumentsLength:
fpizlo@apple.com9a548f12012-05-24 05:33:09 +00001354 // We know that this executable does not escape its arguments, so we can optimize
1355 // the arguments a bit. Note that this is not sufficient to force constant folding
1356 // of GetMyArgumentsLength, because GetMyArgumentsLength is a clobbering operation.
1357 // We perform further optimizations on this later on.
fpizlo@apple.com8fefdd32015-02-18 19:55:47 +00001358 if (node->origin.semantic.inlineCallFrame
1359 && !node->origin.semantic.inlineCallFrame->isVarargs()) {
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00001360 setConstant(
1361 node, jsNumber(node->origin.semantic.inlineCallFrame->arguments.size() - 1));
1362 m_state.setDidClobber(true); // Pretend that we clobbered to prevent constant folding.
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001363 } else
1364 forNode(node).setType(SpecInt32);
fpizlo@apple.com9a548f12012-05-24 05:33:09 +00001365 break;
1366
1367 case GetMyArgumentsLengthSafe:
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +00001368 // This potentially clobbers all structures if the arguments object had a getter
1369 // installed on the length property.
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001370 clobberWorld(node->origin.semantic, clobberLimit);
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +00001371 // We currently make no guarantee about what this returns because it does not
1372 // speculate that the length property is actually a length.
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001373 forNode(node).makeHeapTop();
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +00001374 break;
1375
fpizlo@apple.comb41e6822014-07-25 20:55:17 +00001376 case GetMyArgumentByVal: {
1377 InlineCallFrame* inlineCallFrame = node->origin.semantic.inlineCallFrame;
1378 JSValue value = forNode(node->child1()).m_value;
1379 if (inlineCallFrame && value && value.isInt32()) {
1380 int32_t index = value.asInt32();
1381 if (index >= 0
1382 && static_cast<size_t>(index + 1) < inlineCallFrame->arguments.size()) {
1383 forNode(node) = m_state.variables().operand(
1384 inlineCallFrame->stackOffset +
1385 m_graph.baselineCodeBlockFor(inlineCallFrame)->argumentIndexAfterCapture(index));
1386 m_state.setFoundConstants(true);
1387 break;
1388 }
1389 }
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001390 forNode(node).makeHeapTop();
fpizlo@apple.com9a548f12012-05-24 05:33:09 +00001391 break;
fpizlo@apple.comb41e6822014-07-25 20:55:17 +00001392 }
fpizlo@apple.com9a548f12012-05-24 05:33:09 +00001393
1394 case GetMyArgumentByValSafe:
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +00001395 // This potentially clobbers all structures if the property we're accessing has
1396 // a getter. We don't speculate against this.
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001397 clobberWorld(node->origin.semantic, clobberLimit);
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +00001398 // And the result is unknown.
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001399 forNode(node).makeHeapTop();
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +00001400 break;
1401
fpizlo@apple.com507dca12013-07-17 23:27:31 +00001402 case NewFunction: {
1403 AbstractValue& value = forNode(node);
1404 value = forNode(node->child1());
1405
1406 if (!(value.m_type & SpecEmpty)) {
oliver@apple.com55d32d92013-07-25 04:05:03 +00001407 m_state.setFoundConstants(true);
fpizlo@apple.com507dca12013-07-17 23:27:31 +00001408 break;
1409 }
1410
oliver@apple.com02039462013-07-25 03:59:29 +00001411 value.setType((value.m_type & ~SpecEmpty) | SpecFunction);
fpizlo@apple.com507dca12013-07-17 23:27:31 +00001412 break;
1413 }
1414
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001415 case NewFunctionExpression:
1416 case NewFunctionNoCheck:
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001417 forNode(node).set(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001418 m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->functionStructure());
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001419 break;
1420
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001421 case GetCallee:
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001422 forNode(node).setType(SpecFunction);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001423 break;
fpizlo@apple.com5e2296a2013-01-07 02:24:58 +00001424
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001425 case GetGetter: {
1426 JSValue base = forNode(node->child1()).m_value;
1427 if (base) {
msaboff@apple.com9a7dc802014-12-09 19:52:40 +00001428 GetterSetter* getterSetter = jsCast<GetterSetter*>(base);
1429 if (!getterSetter->isGetterNull()) {
1430 setConstant(node, *m_graph.freeze(getterSetter->getterConcurrently()));
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001431 break;
1432 }
1433 }
1434
1435 forNode(node).setType(SpecObject);
1436 break;
1437 }
1438
1439 case GetSetter: {
1440 JSValue base = forNode(node->child1()).m_value;
1441 if (base) {
msaboff@apple.com9a7dc802014-12-09 19:52:40 +00001442 GetterSetter* getterSetter = jsCast<GetterSetter*>(base);
1443 if (!getterSetter->isSetterNull()) {
1444 setConstant(node, *m_graph.freeze(getterSetter->setterConcurrently()));
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001445 break;
1446 }
1447 }
1448
1449 forNode(node).setType(SpecObject);
1450 break;
1451 }
1452
fpizlo@apple.com90640ab2015-03-04 05:26:54 +00001453 case GetScope:
1454 if (JSValue base = forNode(node->child1()).m_value) {
1455 if (JSFunction* function = jsDynamicCast<JSFunction*>(base)) {
1456 setConstant(node, *m_graph.freeze(function->scope()));
1457 break;
1458 }
1459 }
oliver@apple.comeca9fbe2013-07-28 18:04:18 +00001460 forNode(node).setType(SpecObjectOther);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001461 break;
ggaren@apple.comce086ca2012-09-23 22:48:19 +00001462
fpizlo@apple.coma0bd0582012-12-04 20:25:24 +00001463 case SkipScope: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001464 JSValue child = forNode(node->child1()).value();
fpizlo@apple.com49e37d32013-09-11 21:49:47 +00001465 if (child) {
fpizlo@apple.comb41e6822014-07-25 20:55:17 +00001466 setConstant(node, *m_graph.freeze(JSValue(jsCast<JSScope*>(child.asCell())->next())));
fpizlo@apple.coma0bd0582012-12-04 20:25:24 +00001467 break;
1468 }
oliver@apple.comeca9fbe2013-07-28 18:04:18 +00001469 forNode(node).setType(SpecObjectOther);
fpizlo@apple.coma0bd0582012-12-04 20:25:24 +00001470 break;
1471 }
1472
oliver@apple.com58c86752013-07-25 04:02:40 +00001473 case GetClosureRegisters:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001474 forNode(node).clear(); // The result is not a JS value.
ggaren@apple.comce086ca2012-09-23 22:48:19 +00001475 break;
1476
oliver@apple.com58c86752013-07-25 04:02:40 +00001477 case GetClosureVar:
fpizlo@apple.com90640ab2015-03-04 05:26:54 +00001478 if (JSValue value = m_graph.tryGetConstantClosureVar(forNode(node->child1()), VirtualRegister(node->varNumber()))) {
1479 setConstant(node, *m_graph.freeze(value));
1480 break;
1481 }
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001482 forNode(node).makeHeapTop();
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001483 break;
1484
oliver@apple.com58c86752013-07-25 04:02:40 +00001485 case PutClosureVar:
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001486 clobberCapturedVars(node->origin.semantic);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001487 break;
1488
1489 case GetById:
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001490 case GetByIdFlush: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001491 if (!node->prediction()) {
oliver@apple.com55d32d92013-07-25 04:05:03 +00001492 m_state.setIsValid(false);
fpizlo@apple.com49bfe572011-10-31 23:50:57 +00001493 break;
1494 }
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001495
1496 AbstractValue& value = forNode(node->child1());
1497 if (!value.m_structure.isTop() && !value.m_structure.isClobbered()
1498 && (node->child1().useKind() == CellUse || !(value.m_type & ~SpecCell))) {
1499 GetByIdStatus status = GetByIdStatus::computeFor(
fpizlo@apple.com15ec1b22014-09-21 19:18:40 +00001500 value.m_structure.set(), m_graph.identifiers()[node->identifierNumber()]);
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001501 if (status.isSimple()) {
1502 // Figure out what the result is going to be - is it TOP, a constant, or maybe
1503 // something more subtle?
1504 AbstractValue result;
1505 for (unsigned i = status.numVariants(); i--;) {
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001506 DFG_ASSERT(m_graph, node, !status[i].alternateBase());
1507 JSValue constantResult =
1508 m_graph.tryGetConstantProperty(value, status[i].offset());
1509 if (!constantResult) {
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001510 result.makeHeapTop();
1511 break;
1512 }
fpizlo@apple.comc2c67632012-11-17 08:37:14 +00001513
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001514 AbstractValue thisResult;
1515 thisResult.set(
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001516 m_graph, *m_graph.freeze(constantResult),
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001517 m_state.structureClobberState());
1518 result.merge(thisResult);
fpizlo@apple.com9f624432014-07-26 19:06:44 +00001519 }
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001520 if (status.numVariants() == 1 || isFTL(m_graph.m_plan.mode))
1521 m_state.setFoundConstants(true);
1522 forNode(node) = result;
1523 break;
fpizlo@apple.comc2c67632012-11-17 08:37:14 +00001524 }
1525 }
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001526
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001527 clobberWorld(node->origin.semantic, clobberLimit);
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001528 forNode(node).makeHeapTop();
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001529 break;
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001530 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001531
1532 case GetArrayLength:
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001533 forNode(node).setType(SpecInt32);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001534 break;
fpizlo@apple.com5e2296a2013-01-07 02:24:58 +00001535
oliver@apple.com500b53a2013-07-25 04:05:25 +00001536 case CheckStructure: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001537 AbstractValue& value = forNode(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001538 ASSERT(!(value.m_type & ~SpecCell)); // Edge filtering should have already ensured this.
oliver@apple.com33913872013-07-25 04:02:13 +00001539
1540 StructureSet& set = node->structureSet();
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00001541
1542 // It's interesting that we could have proven that the object has a larger structure set
1543 // that includes the set we're testing. In that case we could make the structure check
1544 // more efficient. We currently don't.
1545
1546 if (value.m_structure.isSubsetOf(set)) {
oliver@apple.com55d32d92013-07-25 04:05:03 +00001547 m_state.setFoundConstants(true);
oliver@apple.com33913872013-07-25 04:02:13 +00001548 break;
1549 }
1550
oliver@apple.com37bd9382013-07-25 04:02:17 +00001551 filter(value, set);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001552 break;
fpizlo@apple.com91b2c682012-05-24 06:24:36 +00001553 }
fpizlo@apple.com04e41152012-06-15 22:14:53 +00001554
fpizlo@apple.comfc70ba62014-09-26 03:59:33 +00001555 case CheckStructureImmediate: {
1556 // FIXME: This currently can only reason about one structure at a time.
1557 // https://bugs.webkit.org/show_bug.cgi?id=136988
1558
1559 AbstractValue& value = forNode(node->child1());
1560 StructureSet& set = node->structureSet();
1561
1562 if (value.value()) {
1563 if (Structure* structure = jsDynamicCast<Structure*>(value.value())) {
1564 if (set.contains(structure)) {
1565 m_state.setFoundConstants(true);
1566 break;
1567 }
1568 }
1569 m_state.setIsValid(false);
1570 break;
1571 }
1572
1573 if (m_phiChildren) {
1574 bool allGood = true;
1575 m_phiChildren->forAllTransitiveIncomingValues(
1576 node,
1577 [&] (Node* incoming) {
1578 if (Structure* structure = incoming->dynamicCastConstant<Structure*>()) {
1579 if (set.contains(structure))
1580 return;
1581 }
1582 allGood = false;
1583 });
1584 if (allGood) {
1585 m_state.setFoundConstants(true);
1586 break;
1587 }
1588 }
1589
1590 if (Structure* structure = set.onlyStructure()) {
1591 filterByValue(node->child1(), *m_graph.freeze(structure));
1592 break;
1593 }
1594
1595 // Aw shucks, we can't do anything!
1596 break;
1597 }
1598
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001599 case PutStructure:
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00001600 if (!forNode(node->child1()).m_structure.isClear()) {
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001601 if (forNode(node->child1()).m_structure.onlyStructure() == node->transition()->next)
1602 m_state.setFoundConstants(true);
1603 else {
1604 observeTransition(
1605 clobberLimit, node->transition()->previous, node->transition()->next);
1606 forNode(node->child1()).changeStructure(m_graph, node->transition()->next);
1607 }
fpizlo@apple.com6e0a9ed2012-09-16 02:36:22 +00001608 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001609 break;
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +00001610 case GetButterfly:
fpizlo@apple.com1ffdcff2012-07-19 00:30:34 +00001611 case AllocatePropertyStorage:
1612 case ReallocatePropertyStorage:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001613 forNode(node).clear(); // The result is not a JS value.
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001614 break;
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001615 case CheckArray: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001616 if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
oliver@apple.com55d32d92013-07-25 04:05:03 +00001617 m_state.setFoundConstants(true);
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001618 break;
1619 }
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001620 switch (node->arrayMode().type()) {
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001621 case Array::String:
oliver@apple.com33913872013-07-25 04:02:13 +00001622 filter(node->child1(), SpecString);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001623 break;
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001624 case Array::Int32:
1625 case Array::Double:
fpizlo@apple.com34d1f082012-10-28 06:13:23 +00001626 case Array::Contiguous:
1627 case Array::ArrayStorage:
1628 case Array::SlowPutArrayStorage:
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001629 break;
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001630 case Array::Arguments:
oliver@apple.com33913872013-07-25 04:02:13 +00001631 filter(node->child1(), SpecArguments);
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001632 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001633 case Array::Int8Array:
oliver@apple.com33913872013-07-25 04:02:13 +00001634 filter(node->child1(), SpecInt8Array);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001635 break;
1636 case Array::Int16Array:
oliver@apple.com33913872013-07-25 04:02:13 +00001637 filter(node->child1(), SpecInt16Array);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001638 break;
1639 case Array::Int32Array:
oliver@apple.com33913872013-07-25 04:02:13 +00001640 filter(node->child1(), SpecInt32Array);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001641 break;
1642 case Array::Uint8Array:
oliver@apple.com33913872013-07-25 04:02:13 +00001643 filter(node->child1(), SpecUint8Array);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001644 break;
1645 case Array::Uint8ClampedArray:
oliver@apple.com33913872013-07-25 04:02:13 +00001646 filter(node->child1(), SpecUint8ClampedArray);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001647 break;
1648 case Array::Uint16Array:
oliver@apple.com33913872013-07-25 04:02:13 +00001649 filter(node->child1(), SpecUint16Array);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001650 break;
1651 case Array::Uint32Array:
oliver@apple.com33913872013-07-25 04:02:13 +00001652 filter(node->child1(), SpecUint32Array);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001653 break;
1654 case Array::Float32Array:
oliver@apple.com33913872013-07-25 04:02:13 +00001655 filter(node->child1(), SpecFloat32Array);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001656 break;
1657 case Array::Float64Array:
oliver@apple.com33913872013-07-25 04:02:13 +00001658 filter(node->child1(), SpecFloat64Array);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001659 break;
1660 default:
oliver@apple.com5598c182013-01-23 22:25:07 +00001661 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.comf860f9b2012-05-22 20:02:25 +00001662 break;
1663 }
oliver@apple.com52be8f82013-07-25 04:04:33 +00001664 filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001665 break;
1666 }
fpizlo@apple.com497c7512012-09-19 01:20:52 +00001667 case Arrayify: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001668 if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
oliver@apple.com55d32d92013-07-25 04:05:03 +00001669 m_state.setFoundConstants(true);
fpizlo@apple.com372c6d52012-10-20 06:53:04 +00001670 break;
1671 }
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001672 ASSERT(node->arrayMode().conversion() == Array::Convert
1673 || node->arrayMode().conversion() == Array::RageConvert);
oliver@apple.come17632e2013-07-25 04:05:31 +00001674 clobberStructures(clobberLimit);
oliver@apple.com33913872013-07-25 04:02:13 +00001675 filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
fpizlo@apple.com497c7512012-09-19 01:20:52 +00001676 break;
1677 }
fpizlo@apple.com99f37622012-10-29 04:02:08 +00001678 case ArrayifyToStructure: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001679 AbstractValue& value = forNode(node->child1());
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00001680 if (value.m_structure.isSubsetOf(StructureSet(node->structure())))
oliver@apple.com55d32d92013-07-25 04:05:03 +00001681 m_state.setFoundConstants(true);
oliver@apple.come17632e2013-07-25 04:05:31 +00001682 clobberStructures(clobberLimit);
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00001683
1684 // We have a bunch of options of how to express the abstract set at this point. Let set S
1685 // be the set of structures that the value had before clobbering and assume that all of
1686 // them are watchable. The new value should be the least expressible upper bound of the
1687 // intersection of "values that currently have structure = node->structure()" and "values
1688 // that have structure in S plus any structure transition-reachable from S". Assume that
1689 // node->structure() is not in S but it is transition-reachable from S. Then we would
1690 // like to say that the result is "values that have structure = node->structure() until
1691 // we invalidate", but there is no way to express this using the AbstractValue syntax. So
1692 // we must choose between:
1693 //
1694 // 1) "values that currently have structure = node->structure()". This is a valid
1695 // superset of the value that we really want, and it's specific enough to satisfy the
1696 // preconditions of the array access that this is guarding. It's also specific enough
1697 // to allow relevant optimizations in the case that we didn't have a contradiction
1698 // like in this example. Notice that in the abscence of any contradiction, this result
1699 // is precise rather than being a conservative LUB.
1700 //
1701 // 2) "values that currently hava structure in S plus any structure transition-reachable
1702 // from S". This is also a valid superset of the value that we really want, but it's
1703 // not specific enough to satisfy the preconditions of the array access that this is
1704 // guarding - so playing such shenanigans would preclude us from having assertions on
1705 // the typing preconditions of any array accesses. This would also not be a desirable
1706 // answer in the absence of a contradiction.
1707 //
1708 // Note that it's tempting to simply say that the resulting value is BOTTOM because of
1709 // the contradiction. That would be wrong, since we haven't hit an invalidation point,
1710 // yet.
1711 value.set(m_graph, node->structure());
fpizlo@apple.com99f37622012-10-29 04:02:08 +00001712 break;
1713 }
fpizlo@apple.com9ca951e2013-12-09 01:08:53 +00001714 case GetIndexedPropertyStorage:
1715 case ConstantStoragePointer: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001716 forNode(node).clear();
oliver@apple.com43e511c2011-12-09 08:45:46 +00001717 break;
1718 }
fpizlo@apple.com537a4772013-08-19 23:16:01 +00001719
1720 case GetTypedArrayByteOffset: {
1721 forNode(node).setType(SpecInt32);
1722 break;
1723 }
1724
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001725 case GetByOffset: {
fpizlo@apple.com9800ede2014-09-20 17:59:58 +00001726 StorageAccessData& data = node->storageAccessData();
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001727 JSValue result = m_graph.tryGetConstantProperty(forNode(node->child2()), data.offset);
1728 if (result) {
1729 setConstant(node, *m_graph.freeze(result));
1730 break;
1731 }
1732
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001733 forNode(node).makeHeapTop();
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001734 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001735 }
fpizlo@apple.com51614cc2014-02-17 06:35:32 +00001736
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +00001737 case GetGetterSetterByOffset: {
fpizlo@apple.com9800ede2014-09-20 17:59:58 +00001738 StorageAccessData& data = node->storageAccessData();
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001739 JSValue result = m_graph.tryGetConstantProperty(forNode(node->child2()), data.offset);
1740 if (result && jsDynamicCast<GetterSetter*>(result)) {
1741 setConstant(node, *m_graph.freeze(result));
1742 break;
1743 }
1744
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +00001745 forNode(node).set(m_graph, m_graph.m_vm.getterSetterStructure.get());
1746 break;
1747 }
1748
fpizlo@apple.com51614cc2014-02-17 06:35:32 +00001749 case MultiGetByOffset: {
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001750 // This code will filter the base value in a manner that is possibly different (either more
1751 // or less precise) than the way it would be filtered if this was strength-reduced to a
1752 // CheckStructure. This is fine. It's legal for different passes over the code to prove
1753 // different things about the code, so long as all of them are sound. That even includes
1754 // one guy proving that code should never execute (due to a contradiction) and another guy
1755 // not finding that contradiction. If someone ever proved that there would be a
1756 // contradiction then there must always be a contradiction even if subsequent passes don't
1757 // realize it. This is the case here.
1758
1759 // Ordinarily you have to be careful with calling setFoundConstants()
1760 // because of the effect on compile times, but this node is FTL-only.
1761 m_state.setFoundConstants(true);
1762
1763 AbstractValue base = forNode(node->child1());
1764 StructureSet baseSet;
1765 AbstractValue result;
1766 for (unsigned i = node->multiGetByOffsetData().variants.size(); i--;) {
1767 GetByIdVariant& variant = node->multiGetByOffsetData().variants[i];
1768 StructureSet set = variant.structureSet();
1769 set.filter(base);
1770 if (set.isEmpty())
1771 continue;
1772 baseSet.merge(set);
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001773
1774 JSValue baseForLoad;
1775 if (variant.alternateBase())
1776 baseForLoad = variant.alternateBase();
1777 else
1778 baseForLoad = base.m_value;
1779 JSValue constantResult =
1780 m_graph.tryGetConstantProperty(
1781 baseForLoad, variant.baseStructure(), variant.offset());
1782 if (!constantResult) {
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001783 result.makeHeapTop();
1784 continue;
fpizlo@apple.com51614cc2014-02-17 06:35:32 +00001785 }
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001786 AbstractValue thisResult;
1787 thisResult.set(
1788 m_graph,
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001789 *m_graph.freeze(constantResult),
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001790 m_state.structureClobberState());
1791 result.merge(thisResult);
fpizlo@apple.com51614cc2014-02-17 06:35:32 +00001792 }
1793
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001794 if (forNode(node->child1()).changeStructure(m_graph, baseSet) == Contradiction)
1795 m_state.setIsValid(false);
fpizlo@apple.com51614cc2014-02-17 06:35:32 +00001796
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001797 forNode(node) = result;
fpizlo@apple.com51614cc2014-02-17 06:35:32 +00001798 break;
1799 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001800
fpizlo@apple.comc2c67632012-11-17 08:37:14 +00001801 case PutByOffset: {
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001802 break;
fpizlo@apple.comc2c67632012-11-17 08:37:14 +00001803 }
fpizlo@apple.com43219522014-02-25 02:02:50 +00001804
1805 case MultiPutByOffset: {
fpizlo@apple.com43219522014-02-25 02:02:50 +00001806 StructureSet newSet;
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00001807 TransitionVector transitions;
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001808
1809 // Ordinarily you have to be careful with calling setFoundConstants()
1810 // because of the effect on compile times, but this node is FTL-only.
1811 m_state.setFoundConstants(true);
1812
1813 AbstractValue base = forNode(node->child1());
1814
fpizlo@apple.com43219522014-02-25 02:02:50 +00001815 for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
1816 const PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001817 StructureSet thisSet = variant.oldStructure();
1818 thisSet.filter(base);
1819 if (thisSet.isEmpty())
1820 continue;
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00001821 if (variant.kind() == PutByIdVariant::Transition) {
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001822 if (thisSet.onlyStructure() != variant.newStructure()) {
1823 transitions.append(
1824 Transition(variant.oldStructureForTransition(), variant.newStructure()));
1825 } // else this is really a replace.
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00001826 newSet.add(variant.newStructure());
1827 } else {
1828 ASSERT(variant.kind() == PutByIdVariant::Replace);
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001829 newSet.merge(thisSet);
fpizlo@apple.com43219522014-02-25 02:02:50 +00001830 }
fpizlo@apple.com43219522014-02-25 02:02:50 +00001831 }
1832
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00001833 observeTransitions(clobberLimit, transitions);
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001834 if (forNode(node->child1()).changeStructure(m_graph, newSet) == Contradiction)
1835 m_state.setIsValid(false);
fpizlo@apple.com43219522014-02-25 02:02:50 +00001836 break;
1837 }
fpizlo@apple.com29abafe2014-08-28 19:09:48 +00001838
1839 case GetExecutable: {
fpizlo@apple.com731e7762014-08-25 22:35:40 +00001840 JSValue value = forNode(node->child1()).value();
fpizlo@apple.com29abafe2014-08-28 19:09:48 +00001841 if (value) {
1842 JSFunction* function = jsDynamicCast<JSFunction*>(value);
1843 if (function) {
1844 setConstant(node, *m_graph.freeze(function->executable()));
1845 break;
1846 }
1847 }
1848 forNode(node).setType(SpecCellOther);
1849 break;
1850 }
1851
1852 case CheckCell: {
1853 JSValue value = forNode(node->child1()).value();
1854 if (value == node->cellOperand()->value()) {
oliver@apple.com55d32d92013-07-25 04:05:03 +00001855 m_state.setFoundConstants(true);
fpizlo@apple.com18e7bc12012-11-12 22:52:32 +00001856 ASSERT(value);
fpizlo@apple.com18e7bc12012-11-12 22:52:32 +00001857 break;
1858 }
fpizlo@apple.com29abafe2014-08-28 19:09:48 +00001859 filterByValue(node->child1(), *node->cellOperand());
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001860 break;
fpizlo@apple.com18e7bc12012-11-12 22:52:32 +00001861 }
rniwa@webkit.orgeb7ac192015-03-13 01:11:15 +00001862
1863 case CheckNotEmpty: {
1864 AbstractValue& value = forNode(node->child1());
1865 if (!(value.m_type & SpecEmpty)) {
1866 m_state.setFoundConstants(true);
1867 break;
1868 }
fpizlo@apple.comb75911b2012-06-13 20:53:52 +00001869
rniwa@webkit.orgeb7ac192015-03-13 01:11:15 +00001870 filter(value, ~SpecEmpty);
1871 break;
1872 }
1873
fpizlo@apple.com8624c4b2013-12-10 03:24:31 +00001874 case CheckInBounds: {
1875 JSValue left = forNode(node->child1()).value();
1876 JSValue right = forNode(node->child2()).value();
1877 if (left && right && left.isInt32() && right.isInt32()
1878 && static_cast<uint32_t>(left.asInt32()) < static_cast<uint32_t>(right.asInt32())) {
1879 m_state.setFoundConstants(true);
1880 break;
1881 }
fpizlo@apple.com8624c4b2013-12-10 03:24:31 +00001882 break;
1883 }
1884
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001885 case PutById:
oliver@apple.com11ce5ff2014-03-06 21:27:13 +00001886 case PutByIdFlush:
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001887 case PutByIdDirect: {
1888 AbstractValue& value = forNode(node->child1());
1889 if (!value.m_structure.isTop() && !value.m_structure.isClobbered()) {
fpizlo@apple.comc2c67632012-11-17 08:37:14 +00001890 PutByIdStatus status = PutByIdStatus::computeFor(
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001891 m_graph.globalObjectFor(node->origin.semantic),
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001892 value.m_structure.set(),
oliver@apple.com90fce822013-07-25 04:00:13 +00001893 m_graph.identifiers()[node->identifierNumber()],
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001894 node->op() == PutByIdDirect);
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001895
1896 if (status.isSimple()) {
1897 StructureSet newSet;
1898 TransitionVector transitions;
1899
1900 for (unsigned i = status.numVariants(); i--;) {
1901 const PutByIdVariant& variant = status[i];
1902 if (variant.kind() == PutByIdVariant::Transition) {
1903 transitions.append(
1904 Transition(
1905 variant.oldStructureForTransition(), variant.newStructure()));
fpizlo@apple.com920c1672014-08-19 00:55:31 +00001906 m_graph.registerStructure(variant.newStructure());
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001907 newSet.add(variant.newStructure());
1908 } else {
1909 ASSERT(variant.kind() == PutByIdVariant::Replace);
1910 newSet.merge(variant.oldStructure());
1911 }
fpizlo@apple.com9f624432014-07-26 19:06:44 +00001912 }
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001913
1914 if (status.numVariants() == 1 || isFTL(m_graph.m_plan.mode))
fpizlo@apple.com9f624432014-07-26 19:06:44 +00001915 m_state.setFoundConstants(true);
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001916
1917 observeTransitions(clobberLimit, transitions);
1918 if (forNode(node->child1()).changeStructure(m_graph, newSet) == Contradiction)
1919 m_state.setIsValid(false);
1920 break;
fpizlo@apple.comc2c67632012-11-17 08:37:14 +00001921 }
1922 }
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001923
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001924 clobberWorld(node->origin.semantic, clobberLimit);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001925 break;
fpizlo@apple.com3378c482014-07-27 23:14:40 +00001926 }
oliver@apple.comb3e5acb2013-07-25 04:02:53 +00001927
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001928 case In: {
oliver@apple.comb3e5acb2013-07-25 04:02:53 +00001929 // FIXME: We can determine when the property definitely exists based on abstract
1930 // value information.
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001931 clobberWorld(node->origin.semantic, clobberLimit);
oliver@apple.comb3e5acb2013-07-25 04:02:53 +00001932 forNode(node).setType(SpecBoolean);
1933 break;
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001934 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001935
fpizlo@apple.coma398a562014-08-06 21:32:55 +00001936 case GetEnumerableLength: {
1937 forNode(node).setType(SpecInt32);
1938 break;
1939 }
1940 case HasGenericProperty: {
1941 forNode(node).setType(SpecBoolean);
1942 break;
1943 }
1944 case HasStructureProperty: {
1945 forNode(node).setType(SpecBoolean);
1946 break;
1947 }
1948 case HasIndexedProperty: {
1949 ArrayMode mode = node->arrayMode();
1950 switch (mode.type()) {
1951 case Array::Int32:
1952 case Array::Double:
1953 case Array::Contiguous:
1954 case Array::ArrayStorage: {
1955 break;
1956 }
1957 default: {
1958 clobberWorld(node->origin.semantic, clobberLimit);
1959 break;
1960 }
1961 }
1962 forNode(node).setType(SpecBoolean);
1963 break;
1964 }
1965 case GetDirectPname: {
1966 clobberWorld(node->origin.semantic, clobberLimit);
1967 forNode(node).makeHeapTop();
1968 break;
1969 }
1970 case GetStructurePropertyEnumerator: {
1971 forNode(node).setType(SpecCell);
1972 break;
1973 }
1974 case GetGenericPropertyEnumerator: {
1975 forNode(node).setType(SpecCell);
1976 break;
1977 }
1978 case GetEnumeratorPname: {
1979 forNode(node).setType(SpecString | SpecOther);
1980 break;
1981 }
1982 case ToIndexString: {
1983 forNode(node).setType(SpecString);
1984 break;
1985 }
1986
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001987 case GetGlobalVar:
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001988 forNode(node).makeHeapTop();
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001989 break;
fpizlo@apple.comb75911b2012-06-13 20:53:52 +00001990
oliver@apple.com58c86752013-07-25 04:02:40 +00001991 case VarInjectionWatchpoint:
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001992 case PutGlobalVar:
fpizlo@apple.com86468342013-11-27 02:47:43 +00001993 case NotifyWrite:
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001994 break;
1995
1996 case CheckHasInstance:
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001997 // Sadly, we don't propagate the fact that we've done CheckHasInstance
1998 break;
1999
2000 case InstanceOf:
2001 // Again, sadly, we don't propagate the fact that we've done InstanceOf
oliver@apple.comfe0cc192013-07-25 03:58:58 +00002002 forNode(node).setType(SpecBoolean);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00002003 break;
2004
2005 case Phi:
oliver@apple.com827d2cf2013-07-25 04:04:45 +00002006 RELEASE_ASSERT(m_graph.m_form == SSA);
fpizlo@apple.comb41e6822014-07-25 20:55:17 +00002007 // The state of this node would have already been decided, but it may have become a
2008 // constant, in which case we'd like to know.
2009 if (forNode(node).m_value)
2010 m_state.setFoundConstants(true);
oliver@apple.com827d2cf2013-07-25 04:04:45 +00002011 break;
2012
2013 case Upsilon: {
oliver@apple.com02e7a972013-07-25 04:05:04 +00002014 m_state.createValueForNode(node->phi());
fpizlo@apple.comb41e6822014-07-25 20:55:17 +00002015 forNode(node->phi()) = forNode(node->child1());
oliver@apple.com827d2cf2013-07-25 04:04:45 +00002016 break;
2017 }
2018
fpizlo@apple.comd9ded3b2011-10-22 01:22:46 +00002019 case Flush:
fpizlo@apple.com3fa6f5d2013-02-09 19:33:00 +00002020 case PhantomLocal:
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00002021 break;
2022
2023 case Call:
2024 case Construct:
fpizlo@apple.comb41e6822014-07-25 20:55:17 +00002025 case NativeCall:
2026 case NativeConstruct:
fpizlo@apple.com8fefdd32015-02-18 19:55:47 +00002027 case CallVarargs:
2028 case CallForwardVarargs:
2029 case ConstructVarargs:
fpizlo@apple.com6793a322014-02-12 05:42:32 +00002030 clobberWorld(node->origin.semantic, clobberLimit);
fpizlo@apple.comff779d02013-09-10 21:55:45 +00002031 forNode(node).makeHeapTop();
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00002032 break;
oliver@apple.comc909f5f2012-10-18 23:37:40 +00002033
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00002034 case ForceOSRExit:
fpizlo@apple.com29abafe2014-08-28 19:09:48 +00002035 case CheckBadCell:
oliver@apple.com55d32d92013-07-25 04:05:03 +00002036 m_state.setIsValid(false);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00002037 break;
fpizlo@apple.comd84425d2013-10-30 19:58:08 +00002038
2039 case InvalidationPoint:
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00002040 forAllValues(clobberLimit, AbstractValue::observeInvalidationPointFor);
2041 m_state.setStructureClobberState(StructuresAreWatched);
fpizlo@apple.comd84425d2013-10-30 19:58:08 +00002042 break;
mark.lam@apple.comeb19fea2014-01-23 23:13:23 +00002043
mark.lam@apple.com10d23a12013-04-25 02:59:51 +00002044 case CheckWatchdogTimer:
mark.lam@apple.com10d23a12013-04-25 02:59:51 +00002045 break;
mark.lam@apple.comeb19fea2014-01-23 23:13:23 +00002046
mark.lam@apple.com6c4085b2014-01-28 17:43:07 +00002047 case Breakpoint:
2048 case ProfileWillCall:
2049 case ProfileDidCall:
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00002050 case ProfileType:
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +00002051 case ProfileControlFlow:
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00002052 case Phantom:
fpizlo@apple.com4c96a842014-02-13 22:46:51 +00002053 case HardPhantom:
fpizlo@apple.com4a81fa42012-12-05 01:26:13 +00002054 case CountExecution:
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002055 case CheckTierUpInLoop:
2056 case CheckTierUpAtReturn:
2057 break;
2058
fpizlo@apple.coma398a562014-08-06 21:32:55 +00002059 case Check: {
2060 // Simplify out checks that don't actually do checking.
2061 for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
2062 Edge edge = node->children.child(i);
2063 if (!edge)
2064 break;
2065 if (edge.isProved() || edge.willNotHaveCheck()) {
2066 m_state.setFoundConstants(true);
2067 break;
2068 }
2069 }
2070 break;
2071 }
2072
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +00002073 case StoreBarrier: {
2074 filter(node->child1(), SpecCell);
2075 break;
2076 }
2077
2078 case StoreBarrierWithNullCheck: {
2079 break;
2080 }
2081
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00002082 case CheckTierUpAndOSREnter:
2083 case LoopHint:
fpizlo@apple.comfc70ba62014-09-26 03:59:33 +00002084 case ZombieHint:
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00002085 break;
oliver@apple.com1fc04182013-08-19 19:40:13 +00002086
2087 case Unreachable:
fpizlo@apple.comd7897b12012-03-12 23:15:45 +00002088 case LastNodeType:
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +00002089 case ArithIMul:
fpizlo@apple.comf2999932014-07-15 00:41:39 +00002090 case FiatInt52:
fpizlo@apple.com29abafe2014-08-28 19:09:48 +00002091 DFG_CRASH(m_graph, node, "Unexpected node type");
fpizlo@apple.comd7897b12012-03-12 23:15:45 +00002092 break;
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00002093 }
2094
oliver@apple.com55d32d92013-07-25 04:05:03 +00002095 return m_state.isValid();
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00002096}
2097
oliver@apple.com55d32d92013-07-25 04:05:03 +00002098template<typename AbstractStateType>
2099bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned indexInBlock)
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002100{
oliver@apple.com55d32d92013-07-25 04:05:03 +00002101 return executeEffects(indexInBlock, m_state.block()->at(indexInBlock));
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002102}
2103
oliver@apple.com55d32d92013-07-25 04:05:03 +00002104template<typename AbstractStateType>
2105bool AbstractInterpreter<AbstractStateType>::execute(unsigned indexInBlock)
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002106{
oliver@apple.com55d32d92013-07-25 04:05:03 +00002107 Node* node = m_state.block()->at(indexInBlock);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002108
fpizlo@apple.comfc70ba62014-09-26 03:59:33 +00002109 startExecuting();
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00002110 executeEdges(node);
2111 return executeEffects(indexInBlock, node);
2112}
2113
oliver@apple.com55d32d92013-07-25 04:05:03 +00002114template<typename AbstractStateType>
oliver@apple.come17632e2013-07-25 04:05:31 +00002115bool AbstractInterpreter<AbstractStateType>::execute(Node* node)
2116{
fpizlo@apple.comfc70ba62014-09-26 03:59:33 +00002117 startExecuting();
oliver@apple.come17632e2013-07-25 04:05:31 +00002118 executeEdges(node);
2119 return executeEffects(UINT_MAX, node);
2120}
2121
2122template<typename AbstractStateType>
oliver@apple.com55d32d92013-07-25 04:05:03 +00002123void AbstractInterpreter<AbstractStateType>::clobberWorld(
oliver@apple.come17632e2013-07-25 04:05:31 +00002124 const CodeOrigin& codeOrigin, unsigned clobberLimit)
fpizlo@apple.com75824e82012-05-30 17:02:49 +00002125{
fpizlo@apple.comcaa68812012-08-02 04:32:30 +00002126 clobberCapturedVars(codeOrigin);
oliver@apple.come17632e2013-07-25 04:05:31 +00002127 clobberStructures(clobberLimit);
fpizlo@apple.comcaa68812012-08-02 04:32:30 +00002128}
2129
oliver@apple.com55d32d92013-07-25 04:05:03 +00002130template<typename AbstractStateType>
2131void AbstractInterpreter<AbstractStateType>::clobberCapturedVars(const CodeOrigin& codeOrigin)
fpizlo@apple.comcaa68812012-08-02 04:32:30 +00002132{
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00002133 SamplingRegion samplingRegion("DFG AI Clobber Captured Vars");
fpizlo@apple.com75824e82012-05-30 17:02:49 +00002134 if (codeOrigin.inlineCallFrame) {
2135 const BitVector& capturedVars = codeOrigin.inlineCallFrame->capturedVars;
2136 for (size_t i = capturedVars.size(); i--;) {
2137 if (!capturedVars.quickGet(i))
2138 continue;
fpizlo@apple.comff779d02013-09-10 21:55:45 +00002139 m_state.variables().local(i).makeHeapTop();
fpizlo@apple.com75824e82012-05-30 17:02:49 +00002140 }
2141 } else {
ggaren@apple.com81c360e2012-09-14 02:17:01 +00002142 for (size_t i = m_codeBlock->m_numVars; i--;) {
msaboff@apple.com62aa8b72013-09-26 22:53:54 +00002143 if (m_codeBlock->isCaptured(virtualRegisterForLocal(i)))
fpizlo@apple.comff779d02013-09-10 21:55:45 +00002144 m_state.variables().local(i).makeHeapTop();
ggaren@apple.com81c360e2012-09-14 02:17:01 +00002145 }
fpizlo@apple.com75824e82012-05-30 17:02:49 +00002146 }
ggaren@apple.com81c360e2012-09-14 02:17:01 +00002147
oliver@apple.com55d32d92013-07-25 04:05:03 +00002148 for (size_t i = m_state.variables().numberOfArguments(); i--;) {
msaboff@apple.com62aa8b72013-09-26 22:53:54 +00002149 if (m_codeBlock->isCaptured(virtualRegisterForArgument(i)))
fpizlo@apple.comff779d02013-09-10 21:55:45 +00002150 m_state.variables().argument(i).makeHeapTop();
fpizlo@apple.com75824e82012-05-30 17:02:49 +00002151 }
fpizlo@apple.com75824e82012-05-30 17:02:49 +00002152}
2153
oliver@apple.com55d32d92013-07-25 04:05:03 +00002154template<typename AbstractStateType>
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00002155template<typename Functor>
2156void AbstractInterpreter<AbstractStateType>::forAllValues(
2157 unsigned clobberLimit, Functor& functor)
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00002158{
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00002159 SamplingRegion samplingRegion("DFG AI For All Values");
oliver@apple.come17632e2013-07-25 04:05:31 +00002160 if (clobberLimit >= m_state.block()->size())
2161 clobberLimit = m_state.block()->size();
2162 else
2163 clobberLimit++;
2164 ASSERT(clobberLimit <= m_state.block()->size());
2165 for (size_t i = clobberLimit; i--;)
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00002166 functor(forNode(m_state.block()->at(i)));
oliver@apple.com96feafa2013-07-25 04:04:57 +00002167 if (m_graph.m_form == SSA) {
oliver@apple.com55d32d92013-07-25 04:05:03 +00002168 HashSet<Node*>::iterator iter = m_state.block()->ssa->liveAtHead.begin();
2169 HashSet<Node*>::iterator end = m_state.block()->ssa->liveAtHead.end();
oliver@apple.com96feafa2013-07-25 04:04:57 +00002170 for (; iter != end; ++iter)
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00002171 functor(forNode(*iter));
oliver@apple.com96feafa2013-07-25 04:04:57 +00002172 }
oliver@apple.com55d32d92013-07-25 04:05:03 +00002173 for (size_t i = m_state.variables().numberOfArguments(); i--;)
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00002174 functor(m_state.variables().argument(i));
oliver@apple.com55d32d92013-07-25 04:05:03 +00002175 for (size_t i = m_state.variables().numberOfLocals(); i--;)
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00002176 functor(m_state.variables().local(i));
2177}
2178
2179template<typename AbstractStateType>
2180void AbstractInterpreter<AbstractStateType>::clobberStructures(unsigned clobberLimit)
2181{
2182 SamplingRegion samplingRegion("DFG AI Clobber Structures");
2183 forAllValues(clobberLimit, AbstractValue::clobberStructuresFor);
2184 setDidClobber();
2185}
2186
2187template<typename AbstractStateType>
2188void AbstractInterpreter<AbstractStateType>::observeTransition(
2189 unsigned clobberLimit, Structure* from, Structure* to)
2190{
2191 AbstractValue::TransitionObserver transitionObserver(from, to);
2192 forAllValues(clobberLimit, transitionObserver);
fpizlo@apple.com3378c482014-07-27 23:14:40 +00002193
2194 ASSERT(!from->dfgShouldWatch()); // We don't need to claim to be in a clobbered state because 'from' was never watchable (during the time we were compiling), hence no constants ever introduced into the DFG IR that ever had a watchable structure would ever have the same structure as from.
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00002195}
2196
2197template<typename AbstractStateType>
2198void AbstractInterpreter<AbstractStateType>::observeTransitions(
2199 unsigned clobberLimit, const TransitionVector& vector)
2200{
2201 AbstractValue::TransitionsObserver transitionsObserver(vector);
2202 forAllValues(clobberLimit, transitionsObserver);
fpizlo@apple.com3378c482014-07-27 23:14:40 +00002203
2204 if (!ASSERT_DISABLED) {
2205 // We don't need to claim to be in a clobbered state because none of the Transition::previous structures are watchable.
2206 for (unsigned i = vector.size(); i--;)
2207 ASSERT(!vector[i].previous->dfgShouldWatch());
2208 }
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00002209}
2210
2211template<typename AbstractStateType>
2212void AbstractInterpreter<AbstractStateType>::setDidClobber()
2213{
oliver@apple.com55d32d92013-07-25 04:05:03 +00002214 m_state.setDidClobber(true);
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00002215 m_state.setStructureClobberState(StructuresAreClobbered);
2216}
2217
2218template<typename AbstractStateType>
2219void AbstractInterpreter<AbstractStateType>::dump(PrintStream& out) const
2220{
2221 const_cast<AbstractInterpreter<AbstractStateType>*>(this)->dump(out);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00002222}
2223
oliver@apple.com55d32d92013-07-25 04:05:03 +00002224template<typename AbstractStateType>
2225void AbstractInterpreter<AbstractStateType>::dump(PrintStream& out)
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00002226{
oliver@apple.com96feafa2013-07-25 04:04:57 +00002227 CommaPrinter comma(" ");
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00002228 HashSet<Node*> seen;
oliver@apple.com96feafa2013-07-25 04:04:57 +00002229 if (m_graph.m_form == SSA) {
oliver@apple.com55d32d92013-07-25 04:05:03 +00002230 HashSet<Node*>::iterator iter = m_state.block()->ssa->liveAtHead.begin();
2231 HashSet<Node*>::iterator end = m_state.block()->ssa->liveAtHead.end();
oliver@apple.com96feafa2013-07-25 04:04:57 +00002232 for (; iter != end; ++iter) {
2233 Node* node = *iter;
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00002234 seen.add(node);
oliver@apple.com96feafa2013-07-25 04:04:57 +00002235 AbstractValue& value = forNode(node);
2236 if (value.isClear())
2237 continue;
2238 out.print(comma, node, ":", value);
2239 }
2240 }
oliver@apple.com55d32d92013-07-25 04:05:03 +00002241 for (size_t i = 0; i < m_state.block()->size(); ++i) {
2242 Node* node = m_state.block()->at(i);
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00002243 seen.add(node);
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00002244 AbstractValue& value = forNode(node);
yuqiang.xian@intel.com861d9182012-03-01 07:39:31 +00002245 if (value.isClear())
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00002246 continue;
oliver@apple.com96feafa2013-07-25 04:04:57 +00002247 out.print(comma, node, ":", value);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00002248 }
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00002249 if (m_graph.m_form == SSA) {
2250 HashSet<Node*>::iterator iter = m_state.block()->ssa->liveAtTail.begin();
2251 HashSet<Node*>::iterator end = m_state.block()->ssa->liveAtTail.end();
2252 for (; iter != end; ++iter) {
2253 Node* node = *iter;
2254 if (seen.contains(node))
2255 continue;
2256 AbstractValue& value = forNode(node);
2257 if (value.isClear())
2258 continue;
2259 out.print(comma, node, ":", value);
2260 }
2261 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00002262}
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00002263
oliver@apple.com55d32d92013-07-25 04:05:03 +00002264template<typename AbstractStateType>
2265FiltrationResult AbstractInterpreter<AbstractStateType>::filter(
2266 AbstractValue& value, const StructureSet& set)
oliver@apple.com33913872013-07-25 04:02:13 +00002267{
2268 if (value.filter(m_graph, set) == FiltrationOK)
2269 return FiltrationOK;
oliver@apple.com55d32d92013-07-25 04:05:03 +00002270 m_state.setIsValid(false);
oliver@apple.com33913872013-07-25 04:02:13 +00002271 return Contradiction;
2272}
oliver@apple.com55d32d92013-07-25 04:05:03 +00002273
2274template<typename AbstractStateType>
2275FiltrationResult AbstractInterpreter<AbstractStateType>::filterArrayModes(
2276 AbstractValue& value, ArrayModes arrayModes)
oliver@apple.com33913872013-07-25 04:02:13 +00002277{
2278 if (value.filterArrayModes(arrayModes) == FiltrationOK)
2279 return FiltrationOK;
oliver@apple.com55d32d92013-07-25 04:05:03 +00002280 m_state.setIsValid(false);
oliver@apple.com33913872013-07-25 04:02:13 +00002281 return Contradiction;
2282}
oliver@apple.com55d32d92013-07-25 04:05:03 +00002283
2284template<typename AbstractStateType>
2285FiltrationResult AbstractInterpreter<AbstractStateType>::filter(
2286 AbstractValue& value, SpeculatedType type)
oliver@apple.com33913872013-07-25 04:02:13 +00002287{
2288 if (value.filter(type) == FiltrationOK)
2289 return FiltrationOK;
oliver@apple.com55d32d92013-07-25 04:05:03 +00002290 m_state.setIsValid(false);
oliver@apple.com33913872013-07-25 04:02:13 +00002291 return Contradiction;
2292}
oliver@apple.com55d32d92013-07-25 04:05:03 +00002293
2294template<typename AbstractStateType>
2295FiltrationResult AbstractInterpreter<AbstractStateType>::filterByValue(
fpizlo@apple.comb41e6822014-07-25 20:55:17 +00002296 AbstractValue& abstractValue, FrozenValue concreteValue)
oliver@apple.com33913872013-07-25 04:02:13 +00002297{
2298 if (abstractValue.filterByValue(concreteValue) == FiltrationOK)
2299 return FiltrationOK;
oliver@apple.com55d32d92013-07-25 04:05:03 +00002300 m_state.setIsValid(false);
oliver@apple.com33913872013-07-25 04:02:13 +00002301 return Contradiction;
2302}
2303
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00002304} } // namespace JSC::DFG
2305
2306#endif // ENABLE(DFG_JIT)
2307
oliver@apple.com55d32d92013-07-25 04:05:03 +00002308#endif // DFGAbstractInterpreterInlines_h
2309