blob: fa62cb1cd0cce24e5d63585adb74608d817e831c [file] [log] [blame]
barraclough@apple.com2302c042011-03-14 23:31:00 +00001/*
msaboff@apple.com95894332014-01-29 19:18:54 +00002 * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
barraclough@apple.com2302c042011-03-14 23:31:00 +00003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef DFGNode_h
27#define DFGNode_h
28
barraclough@apple.com50d09502011-10-13 22:11:13 +000029#if ENABLE(DFG_JIT)
30
fpizlo@apple.com594887a2011-09-06 09:23:55 +000031#include "CodeBlock.h"
fpizlo@apple.comf8f33842013-01-14 06:58:57 +000032#include "DFGAbstractValue.h"
fpizlo@apple.come5abbae2012-03-19 21:44:23 +000033#include "DFGAdjacencyList.h"
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +000034#include "DFGArithMode.h"
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +000035#include "DFGArrayMode.h"
fpizlo@apple.com0bef2a12014-02-10 19:26:29 +000036#include "DFGCommon.h"
oliver@apple.com9e1c8092013-07-25 04:03:16 +000037#include "DFGLazyJSValue.h"
fpizlo@apple.com0bef2a12014-02-10 19:26:29 +000038#include "DFGNodeFlags.h"
fpizlo@apple.com6793a322014-02-12 05:42:32 +000039#include "DFGNodeOrigin.h"
fpizlo@apple.comd7897b12012-03-12 23:15:45 +000040#include "DFGNodeType.h"
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +000041#include "DFGTransition.h"
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +000042#include "DFGUseKind.h"
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +000043#include "DFGVariableAccessData.h"
fpizlo@apple.com51614cc2014-02-17 06:35:32 +000044#include "GetByIdVariant.h"
fpizlo@apple.com0bef2a12014-02-10 19:26:29 +000045#include "JSCJSValue.h"
46#include "Operands.h"
fpizlo@apple.com43219522014-02-25 02:02:50 +000047#include "PutByIdVariant.h"
fpizlo@apple.com0bef2a12014-02-10 19:26:29 +000048#include "SpeculatedType.h"
49#include "StructureSet.h"
fpizlo@apple.com594887a2011-09-06 09:23:55 +000050#include "ValueProfile.h"
oliver@apple.com827d2cf2013-07-25 04:04:45 +000051#include <wtf/ListDump.h>
barraclough@apple.com74213b42011-04-16 01:19:27 +000052
barraclough@apple.com2302c042011-03-14 23:31:00 +000053namespace JSC { namespace DFG {
54
oliver@apple.com827d2cf2013-07-25 04:04:45 +000055class Graph;
oliver@apple.com426f5b02013-07-25 04:04:27 +000056struct BasicBlock;
57
fpizlo@apple.com51614cc2014-02-17 06:35:32 +000058struct MultiGetByOffsetData {
59 unsigned identifierNumber;
60 Vector<GetByIdVariant, 2> variants;
61};
62
fpizlo@apple.com43219522014-02-25 02:02:50 +000063struct MultiPutByOffsetData {
64 unsigned identifierNumber;
65 Vector<PutByIdVariant, 2> variants;
66
67 bool writesStructures() const;
68 bool reallocatesStorage() const;
69};
70
fpizlo@apple.comf7b42982012-10-25 17:09:42 +000071struct NewArrayBufferData {
72 unsigned startConstant;
73 unsigned numConstants;
fpizlo@apple.com75c91a72012-11-08 22:28:25 +000074 IndexingType indexingType;
fpizlo@apple.comf7b42982012-10-25 17:09:42 +000075};
76
fpizlo@apple.comb8377cd2014-02-20 08:00:28 +000077struct BranchTarget {
78 BranchTarget()
79 : block(0)
fpizlo@apple.combeef4522014-04-16 22:44:00 +000080 , count(PNaN)
fpizlo@apple.comb8377cd2014-02-20 08:00:28 +000081 {
82 }
83
84 explicit BranchTarget(BasicBlock* block)
85 : block(block)
fpizlo@apple.combeef4522014-04-16 22:44:00 +000086 , count(PNaN)
fpizlo@apple.comb8377cd2014-02-20 08:00:28 +000087 {
88 }
89
90 void setBytecodeIndex(unsigned bytecodeIndex)
91 {
92 block = bitwise_cast<BasicBlock*>(static_cast<uintptr_t>(bytecodeIndex));
93 }
94 unsigned bytecodeIndex() const { return bitwise_cast<uintptr_t>(block); }
95
96 void dump(PrintStream&) const;
97
98 BasicBlock* block;
99 float count;
100};
101
102struct BranchData {
103 static BranchData withBytecodeIndices(
104 unsigned takenBytecodeIndex, unsigned notTakenBytecodeIndex)
105 {
106 BranchData result;
107 result.taken.block = bitwise_cast<BasicBlock*>(static_cast<uintptr_t>(takenBytecodeIndex));
108 result.notTaken.block = bitwise_cast<BasicBlock*>(static_cast<uintptr_t>(notTakenBytecodeIndex));
109 return result;
110 }
111
112 unsigned takenBytecodeIndex() const { return taken.bytecodeIndex(); }
113 unsigned notTakenBytecodeIndex() const { return notTaken.bytecodeIndex(); }
114
115 BasicBlock*& forCondition(bool condition)
116 {
117 if (condition)
118 return taken.block;
119 return notTaken.block;
120 }
121
122 BranchTarget taken;
123 BranchTarget notTaken;
124};
125
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000126// The SwitchData and associated data structures duplicate the information in
127// JumpTable. The DFG may ultimately end up using the JumpTable, though it may
128// instead decide to do something different - this is entirely up to the DFG.
129// These data structures give the DFG a higher-level semantic description of
130// what is going on, which will allow it to make the right decision.
oliver@apple.com6ce44682013-07-25 04:03:03 +0000131//
132// Note that there will never be multiple SwitchCases in SwitchData::cases that
133// have the same SwitchCase::value, since the bytecode's JumpTables never have
134// duplicates - since the JumpTable maps a value to a target. It's a
135// one-to-many mapping. So we may have duplicate targets, but never duplicate
136// values.
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000137struct SwitchCase {
138 SwitchCase()
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000139 {
140 }
141
oliver@apple.com426f5b02013-07-25 04:04:27 +0000142 SwitchCase(LazyJSValue value, BasicBlock* target)
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000143 : value(value)
144 , target(target)
145 {
146 }
147
oliver@apple.com426f5b02013-07-25 04:04:27 +0000148 static SwitchCase withBytecodeIndex(LazyJSValue value, unsigned bytecodeIndex)
149 {
150 SwitchCase result;
151 result.value = value;
fpizlo@apple.comb8377cd2014-02-20 08:00:28 +0000152 result.target.setBytecodeIndex(bytecodeIndex);
oliver@apple.com426f5b02013-07-25 04:04:27 +0000153 return result;
154 }
155
oliver@apple.com9e1c8092013-07-25 04:03:16 +0000156 LazyJSValue value;
fpizlo@apple.comb8377cd2014-02-20 08:00:28 +0000157 BranchTarget target;
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000158};
159
160enum SwitchKind {
oliver@apple.com9e1c8092013-07-25 04:03:16 +0000161 SwitchImm,
oliver@apple.com5c826c02013-07-25 04:03:51 +0000162 SwitchChar,
163 SwitchString
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000164};
165
166struct SwitchData {
167 // Initializes most fields to obviously invalid values. Anyone
168 // constructing this should make sure to initialize everything they
169 // care about manually.
170 SwitchData()
fpizlo@apple.comb8377cd2014-02-20 08:00:28 +0000171 : kind(static_cast<SwitchKind>(-1))
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000172 , switchTableIndex(UINT_MAX)
173 , didUseJumpTable(false)
174 {
175 }
176
177 Vector<SwitchCase> cases;
fpizlo@apple.comb8377cd2014-02-20 08:00:28 +0000178 BranchTarget fallThrough;
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000179 SwitchKind kind;
180 unsigned switchTableIndex;
181 bool didUseJumpTable;
182};
183
barraclough@apple.com2302c042011-03-14 23:31:00 +0000184// This type used in passing an immediate argument to Node constructor;
185// distinguishes an immediate value (typically an index into a CodeBlock data structure -
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000186// a constant index, argument, or identifier) from a Node*.
barraclough@apple.com2302c042011-03-14 23:31:00 +0000187struct OpInfo {
barraclough@apple.com2decbec2011-09-28 01:09:33 +0000188 explicit OpInfo(int32_t value) : m_value(static_cast<uintptr_t>(value)) { }
189 explicit OpInfo(uint32_t value) : m_value(static_cast<uintptr_t>(value)) { }
commit-queue@webkit.orgc9fcb1f2011-09-29 07:52:49 +0000190#if OS(DARWIN) || USE(JSVALUE64)
barraclough@apple.com2decbec2011-09-28 01:09:33 +0000191 explicit OpInfo(size_t value) : m_value(static_cast<uintptr_t>(value)) { }
commit-queue@webkit.orgc9fcb1f2011-09-29 07:52:49 +0000192#endif
fpizlo@apple.comffb7d5e2011-09-20 09:41:16 +0000193 explicit OpInfo(void* value) : m_value(reinterpret_cast<uintptr_t>(value)) { }
194 uintptr_t m_value;
barraclough@apple.com2302c042011-03-14 23:31:00 +0000195};
196
197// === Node ===
198//
199// Node represents a single operation in the data flow graph.
200struct Node {
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +0000201 enum VarArgTag { VarArg };
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +0000202
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +0000203 Node() { }
204
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000205 Node(NodeType op, NodeOrigin nodeOrigin, const AdjacencyList& children)
206 : origin(nodeOrigin)
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +0000207 , children(children)
msaboff@apple.com62aa8b72013-09-26 22:53:54 +0000208 , m_virtualRegister(VirtualRegister())
fpizlo@apple.com06f82b52013-03-06 02:27:16 +0000209 , m_refCount(1)
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +0000210 , m_prediction(SpecNone)
211 {
oliver@apple.com6c816f42013-07-25 04:04:53 +0000212 misc.replacement = 0;
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +0000213 setOpAndDefaultFlags(op);
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +0000214 }
215
barraclough@apple.com2302c042011-03-14 23:31:00 +0000216 // Construct a node with up to 3 children, no immediate value.
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000217 Node(NodeType op, NodeOrigin nodeOrigin, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
218 : origin(nodeOrigin)
fpizlo@apple.come5abbae2012-03-19 21:44:23 +0000219 , children(AdjacencyList::Fixed, child1, child2, child3)
msaboff@apple.com62aa8b72013-09-26 22:53:54 +0000220 , m_virtualRegister(VirtualRegister())
fpizlo@apple.com06f82b52013-03-06 02:27:16 +0000221 , m_refCount(1)
fpizlo@apple.com62336162012-06-07 01:35:59 +0000222 , m_prediction(SpecNone)
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000223 , m_opInfo(0)
224 , m_opInfo2(0)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000225 {
oliver@apple.com6c816f42013-07-25 04:04:53 +0000226 misc.replacement = 0;
fpizlo@apple.comc35b8f72012-03-12 09:50:38 +0000227 setOpAndDefaultFlags(op);
fpizlo@apple.comd7897b12012-03-12 23:15:45 +0000228 ASSERT(!(m_flags & NodeHasVarArgs));
barraclough@apple.com2302c042011-03-14 23:31:00 +0000229 }
230
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000231 // Construct a node with up to 3 children, no immediate value.
232 Node(NodeFlags result, NodeType op, NodeOrigin nodeOrigin, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
233 : origin(nodeOrigin)
234 , children(AdjacencyList::Fixed, child1, child2, child3)
235 , m_virtualRegister(VirtualRegister())
236 , m_refCount(1)
237 , m_prediction(SpecNone)
238 , m_opInfo(0)
239 , m_opInfo2(0)
240 {
241 misc.replacement = 0;
242 setOpAndDefaultFlags(op);
243 setResult(result);
244 ASSERT(!(m_flags & NodeHasVarArgs));
245 }
246
barraclough@apple.com2302c042011-03-14 23:31:00 +0000247 // Construct a node with up to 3 children and an immediate value.
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000248 Node(NodeType op, NodeOrigin nodeOrigin, OpInfo imm, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
249 : origin(nodeOrigin)
fpizlo@apple.come5abbae2012-03-19 21:44:23 +0000250 , children(AdjacencyList::Fixed, child1, child2, child3)
msaboff@apple.com62aa8b72013-09-26 22:53:54 +0000251 , m_virtualRegister(VirtualRegister())
fpizlo@apple.com06f82b52013-03-06 02:27:16 +0000252 , m_refCount(1)
fpizlo@apple.com62336162012-06-07 01:35:59 +0000253 , m_prediction(SpecNone)
oliver@apple.comd83bc442013-07-25 04:04:21 +0000254 , m_opInfo(imm.m_value)
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +0000255 , m_opInfo2(0)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000256 {
oliver@apple.com6c816f42013-07-25 04:04:53 +0000257 misc.replacement = 0;
fpizlo@apple.comc35b8f72012-03-12 09:50:38 +0000258 setOpAndDefaultFlags(op);
fpizlo@apple.comd7897b12012-03-12 23:15:45 +0000259 ASSERT(!(m_flags & NodeHasVarArgs));
barraclough@apple.com2302c042011-03-14 23:31:00 +0000260 }
261
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000262 // Construct a node with up to 3 children and an immediate value.
263 Node(NodeFlags result, NodeType op, NodeOrigin nodeOrigin, OpInfo imm, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
264 : origin(nodeOrigin)
265 , children(AdjacencyList::Fixed, child1, child2, child3)
266 , m_virtualRegister(VirtualRegister())
267 , m_refCount(1)
268 , m_prediction(SpecNone)
269 , m_opInfo(imm.m_value)
270 , m_opInfo2(0)
271 {
272 misc.replacement = 0;
273 setOpAndDefaultFlags(op);
274 setResult(result);
275 ASSERT(!(m_flags & NodeHasVarArgs));
276 }
277
barraclough@apple.come23e0402011-04-15 23:02:09 +0000278 // Construct a node with up to 3 children and two immediate values.
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000279 Node(NodeType op, NodeOrigin nodeOrigin, OpInfo imm1, OpInfo imm2, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
280 : origin(nodeOrigin)
fpizlo@apple.come5abbae2012-03-19 21:44:23 +0000281 , children(AdjacencyList::Fixed, child1, child2, child3)
msaboff@apple.com62aa8b72013-09-26 22:53:54 +0000282 , m_virtualRegister(VirtualRegister())
fpizlo@apple.com06f82b52013-03-06 02:27:16 +0000283 , m_refCount(1)
fpizlo@apple.com62336162012-06-07 01:35:59 +0000284 , m_prediction(SpecNone)
oliver@apple.comd83bc442013-07-25 04:04:21 +0000285 , m_opInfo(imm1.m_value)
286 , m_opInfo2(imm2.m_value)
barraclough@apple.come23e0402011-04-15 23:02:09 +0000287 {
oliver@apple.com6c816f42013-07-25 04:04:53 +0000288 misc.replacement = 0;
fpizlo@apple.comc35b8f72012-03-12 09:50:38 +0000289 setOpAndDefaultFlags(op);
fpizlo@apple.comd7897b12012-03-12 23:15:45 +0000290 ASSERT(!(m_flags & NodeHasVarArgs));
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +0000291 }
292
fpizlo@apple.com7ab54822011-08-10 00:51:11 +0000293 // Construct a node with a variable number of children and two immediate values.
fpizlo@apple.com6793a322014-02-12 05:42:32 +0000294 Node(VarArgTag, NodeType op, NodeOrigin nodeOrigin, OpInfo imm1, OpInfo imm2, unsigned firstChild, unsigned numChildren)
295 : origin(nodeOrigin)
fpizlo@apple.come5abbae2012-03-19 21:44:23 +0000296 , children(AdjacencyList::Variable, firstChild, numChildren)
msaboff@apple.com62aa8b72013-09-26 22:53:54 +0000297 , m_virtualRegister(VirtualRegister())
fpizlo@apple.com06f82b52013-03-06 02:27:16 +0000298 , m_refCount(1)
fpizlo@apple.com62336162012-06-07 01:35:59 +0000299 , m_prediction(SpecNone)
oliver@apple.comd83bc442013-07-25 04:04:21 +0000300 , m_opInfo(imm1.m_value)
301 , m_opInfo2(imm2.m_value)
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +0000302 {
oliver@apple.com6c816f42013-07-25 04:04:53 +0000303 misc.replacement = 0;
fpizlo@apple.comc35b8f72012-03-12 09:50:38 +0000304 setOpAndDefaultFlags(op);
fpizlo@apple.comd7897b12012-03-12 23:15:45 +0000305 ASSERT(m_flags & NodeHasVarArgs);
306 }
307
308 NodeType op() const { return static_cast<NodeType>(m_op); }
309 NodeFlags flags() const { return m_flags; }
310
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000311 // This is not a fast method.
312 unsigned index() const;
313
fpizlo@apple.comd7897b12012-03-12 23:15:45 +0000314 void setOp(NodeType op)
315 {
316 m_op = op;
317 }
318
319 void setFlags(NodeFlags flags)
320 {
321 m_flags = flags;
322 }
323
324 bool mergeFlags(NodeFlags flags)
325 {
326 NodeFlags newFlags = m_flags | flags;
327 if (newFlags == m_flags)
328 return false;
329 m_flags = newFlags;
330 return true;
331 }
332
333 bool filterFlags(NodeFlags flags)
334 {
335 NodeFlags newFlags = m_flags & flags;
336 if (newFlags == m_flags)
337 return false;
338 m_flags = newFlags;
339 return true;
340 }
341
342 bool clearFlags(NodeFlags flags)
343 {
344 return filterFlags(~flags);
fpizlo@apple.comc35b8f72012-03-12 09:50:38 +0000345 }
346
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000347 void setResult(NodeFlags result)
348 {
349 ASSERT(!(result & ~NodeResultMask));
350 clearFlags(NodeResultMask);
351 mergeFlags(result);
352 }
353
354 NodeFlags result() const
355 {
356 return flags() & NodeResultMask;
357 }
358
fpizlo@apple.comc35b8f72012-03-12 09:50:38 +0000359 void setOpAndDefaultFlags(NodeType op)
360 {
fpizlo@apple.comd7897b12012-03-12 23:15:45 +0000361 m_op = op;
362 m_flags = defaultFlags(op);
barraclough@apple.come23e0402011-04-15 23:02:09 +0000363 }
msaboff@apple.combb1c1702013-03-19 22:22:06 +0000364
fpizlo@apple.com955073c2013-02-28 21:51:25 +0000365 void convertToPhantom()
366 {
fpizlo@apple.com9df7fef2013-12-29 21:50:55 +0000367 setOpAndDefaultFlags(Phantom);
fpizlo@apple.com955073c2013-02-28 21:51:25 +0000368 }
msaboff@apple.combb1c1702013-03-19 22:22:06 +0000369
370 void convertToPhantomUnchecked()
371 {
fpizlo@apple.com9df7fef2013-12-29 21:50:55 +0000372 setOpAndDefaultFlags(Phantom);
msaboff@apple.combb1c1702013-03-19 22:22:06 +0000373 }
374
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000375 void convertToIdentity();
barraclough@apple.come23e0402011-04-15 23:02:09 +0000376
barraclough@apple.com2302c042011-03-14 23:31:00 +0000377 bool mustGenerate()
378 {
fpizlo@apple.comd7897b12012-03-12 23:15:45 +0000379 return m_flags & NodeMustGenerate;
barraclough@apple.com2302c042011-03-14 23:31:00 +0000380 }
fpizlo@apple.com91b2c682012-05-24 06:24:36 +0000381
barraclough@apple.com2302c042011-03-14 23:31:00 +0000382 bool isConstant()
383 {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000384 switch (op()) {
385 case JSConstant:
386 case DoubleConstant:
387 case Int52Constant:
388 return true;
389 default:
390 return false;
391 }
barraclough@apple.com2302c042011-03-14 23:31:00 +0000392 }
fpizlo@apple.com6f1a3442011-09-16 06:33:55 +0000393
fpizlo@apple.com7e0f6502012-05-25 22:45:57 +0000394 bool isPhantomArguments()
395 {
396 return op() == PhantomArguments;
397 }
398
fpizlo@apple.com6f1a3442011-09-16 06:33:55 +0000399 bool hasConstant()
400 {
fpizlo@apple.com7e0f6502012-05-25 22:45:57 +0000401 switch (op()) {
402 case JSConstant:
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000403 case DoubleConstant:
404 case Int52Constant:
fpizlo@apple.com7e0f6502012-05-25 22:45:57 +0000405 case PhantomArguments:
406 return true;
407 default:
408 return false;
409 }
fpizlo@apple.com6f1a3442011-09-16 06:33:55 +0000410 }
barraclough@apple.com2302c042011-03-14 23:31:00 +0000411
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000412 FrozenValue* constant()
barraclough@apple.com2302c042011-03-14 23:31:00 +0000413 {
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000414 ASSERT(hasConstant());
415 if (op() == PhantomArguments)
416 return FrozenValue::emptySingleton();
417 return bitwise_cast<FrozenValue*>(m_opInfo);
barraclough@apple.com2302c042011-03-14 23:31:00 +0000418 }
fpizlo@apple.com594887a2011-09-06 09:23:55 +0000419
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000420 // Don't call this directly - use Graph::convertToConstant() instead!
421 void convertToConstant(FrozenValue* value)
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000422 {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000423 if (hasDoubleResult())
424 m_op = DoubleConstant;
425 else if (hasInt52Result())
426 m_op = Int52Constant;
427 else
428 m_op = JSConstant;
fpizlo@apple.com9b928722012-05-24 00:18:55 +0000429 m_flags &= ~(NodeMustGenerate | NodeMightClobber | NodeClobbersWorld);
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000430 m_opInfo = bitwise_cast<uintptr_t>(value);
fpizlo@apple.com33b10ee2013-03-07 09:04:57 +0000431 children.reset();
432 }
433
fpizlo@apple.com9ca951e2013-12-09 01:08:53 +0000434 void convertToConstantStoragePointer(void* pointer)
435 {
436 ASSERT(op() == GetIndexedPropertyStorage);
437 m_op = ConstantStoragePointer;
438 m_opInfo = bitwise_cast<uintptr_t>(pointer);
439 }
440
fpizlo@apple.com9b928722012-05-24 00:18:55 +0000441 void convertToGetLocalUnlinked(VirtualRegister local)
442 {
443 m_op = GetLocalUnlinked;
fpizlo@apple.com9b928722012-05-24 00:18:55 +0000444 m_flags &= ~(NodeMustGenerate | NodeMightClobber | NodeClobbersWorld);
msaboff@apple.com62aa8b72013-09-26 22:53:54 +0000445 m_opInfo = local.offset();
fpizlo@apple.coma62d4822013-10-06 04:22:43 +0000446 m_opInfo2 = VirtualRegister().offset();
fpizlo@apple.com9b928722012-05-24 00:18:55 +0000447 children.reset();
448 }
449
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000450 void convertToGetByOffset(unsigned storageAccessDataIndex, Edge storage)
fpizlo@apple.comc2c67632012-11-17 08:37:14 +0000451 {
fpizlo@apple.com51614cc2014-02-17 06:35:32 +0000452 ASSERT(m_op == GetById || m_op == GetByIdFlush || m_op == MultiGetByOffset);
fpizlo@apple.comc2c67632012-11-17 08:37:14 +0000453 m_opInfo = storageAccessDataIndex;
oliver@apple.com0402d952013-07-25 04:05:07 +0000454 children.setChild2(children.child1());
455 children.child2().setUseKind(KnownCellUse);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000456 children.setChild1(storage);
fpizlo@apple.comc2c67632012-11-17 08:37:14 +0000457 m_op = GetByOffset;
458 m_flags &= ~NodeClobbersWorld;
459 }
460
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000461 void convertToPutByOffset(unsigned storageAccessDataIndex, Edge storage)
fpizlo@apple.comc2c67632012-11-17 08:37:14 +0000462 {
fpizlo@apple.com43219522014-02-25 02:02:50 +0000463 ASSERT(m_op == PutById || m_op == PutByIdDirect || m_op == MultiPutByOffset);
fpizlo@apple.comc2c67632012-11-17 08:37:14 +0000464 m_opInfo = storageAccessDataIndex;
465 children.setChild3(children.child2());
466 children.setChild2(children.child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000467 children.setChild1(storage);
fpizlo@apple.comc2c67632012-11-17 08:37:14 +0000468 m_op = PutByOffset;
469 m_flags &= ~NodeClobbersWorld;
470 }
471
fpizlo@apple.com3fa6f5d2013-02-09 19:33:00 +0000472 void convertToPhantomLocal()
473 {
474 ASSERT(m_op == Phantom && (child1()->op() == Phi || child1()->op() == SetLocal || child1()->op() == SetArgument));
475 m_op = PhantomLocal;
476 m_opInfo = child1()->m_opInfo; // Copy the variableAccessData.
477 children.setChild1(Edge());
478 }
479
480 void convertToGetLocal(VariableAccessData* variable, Node* phi)
481 {
482 ASSERT(m_op == GetLocalUnlinked);
483 m_op = GetLocal;
484 m_opInfo = bitwise_cast<uintptr_t>(variable);
fpizlo@apple.coma62d4822013-10-06 04:22:43 +0000485 m_opInfo2 = 0;
fpizlo@apple.com3fa6f5d2013-02-09 19:33:00 +0000486 children.setChild1(Edge(phi));
487 }
488
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +0000489 void convertToToString()
490 {
491 ASSERT(m_op == ToPrimitive);
492 m_op = ToString;
493 }
494
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000495 JSValue asJSValue()
fpizlo@apple.comd93c9ad2011-09-26 02:25:02 +0000496 {
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000497 return constant()->value();
498 }
499
500 bool isInt32Constant()
501 {
502 return isConstant() && constant()->value().isInt32();
503 }
504
505 int32_t asInt32()
506 {
507 return asJSValue().asInt32();
508 }
509
510 uint32_t asUInt32()
511 {
512 return asInt32();
513 }
514
515 bool isDoubleConstant()
516 {
517 return isConstant() && constant()->value().isDouble();
518 }
519
520 bool isNumberConstant()
521 {
522 return isConstant() && constant()->value().isNumber();
fpizlo@apple.com53aa8dc2011-11-15 21:54:38 +0000523 }
524
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000525 double asNumber()
fpizlo@apple.com53aa8dc2011-11-15 21:54:38 +0000526 {
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000527 return asJSValue().asNumber();
fpizlo@apple.comd93c9ad2011-09-26 02:25:02 +0000528 }
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000529
530 bool isMachineIntConstant()
fpizlo@apple.com594887a2011-09-06 09:23:55 +0000531 {
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000532 return isConstant() && constant()->value().isMachineInt();
fpizlo@apple.com594887a2011-09-06 09:23:55 +0000533 }
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000534
535 int64_t asMachineInt()
fpizlo@apple.com594887a2011-09-06 09:23:55 +0000536 {
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000537 return asJSValue().asMachineInt();
fpizlo@apple.com0ef13dc2011-09-14 00:37:01 +0000538 }
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000539
540 bool isBooleanConstant()
fpizlo@apple.com0ef13dc2011-09-14 00:37:01 +0000541 {
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000542 return isConstant() && constant()->value().isBoolean();
fpizlo@apple.com594887a2011-09-06 09:23:55 +0000543 }
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000544
545 bool asBoolean()
fpizlo@apple.comf2999932014-07-15 00:41:39 +0000546 {
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000547 return constant()->value().asBoolean();
fpizlo@apple.comf2999932014-07-15 00:41:39 +0000548 }
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000549
550 bool isCellConstant()
fpizlo@apple.com746c6d072011-09-07 02:47:51 +0000551 {
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000552 return isConstant() && constant()->value().isCell();
fpizlo@apple.com746c6d072011-09-07 02:47:51 +0000553 }
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000554
555 JSCell* asCell()
556 {
557 return constant()->value().asCell();
558 }
559
560 template<typename T>
561 T dynamicCastConstant()
562 {
563 if (!isCellConstant())
564 return nullptr;
565 return jsDynamicCast<T>(asCell());
566 }
567
fpizlo@apple.com06f82b52013-03-06 02:27:16 +0000568 bool containsMovHint()
569 {
570 switch (op()) {
fpizlo@apple.com06f82b52013-03-06 02:27:16 +0000571 case MovHint:
fpizlo@apple.com06f82b52013-03-06 02:27:16 +0000572 case ZombieHint:
573 return true;
574 default:
575 return false;
576 }
577 }
578
oliver@apple.com827d2cf2013-07-25 04:04:45 +0000579 bool hasVariableAccessData(Graph&);
580 bool hasLocal(Graph& graph)
fpizlo@apple.comdc4cae72011-09-29 23:17:19 +0000581 {
oliver@apple.com827d2cf2013-07-25 04:04:45 +0000582 return hasVariableAccessData(graph);
barraclough@apple.com2302c042011-03-14 23:31:00 +0000583 }
fpizlo@apple.comdc4cae72011-09-29 23:17:19 +0000584
fpizlo@apple.coma14dfc02014-01-30 23:00:16 +0000585 // This is useful for debugging code, where a node that should have a variable
586 // access data doesn't have one because it hasn't been initialized yet.
587 VariableAccessData* tryGetVariableAccessData()
588 {
589 VariableAccessData* result = reinterpret_cast<VariableAccessData*>(m_opInfo);
590 if (!result)
591 return 0;
592 return result->find();
593 }
594
fpizlo@apple.comdc4cae72011-09-29 23:17:19 +0000595 VariableAccessData* variableAccessData()
596 {
597 return reinterpret_cast<VariableAccessData*>(m_opInfo)->find();
598 }
599
barraclough@apple.com5540b562011-04-15 22:30:06 +0000600 VirtualRegister local()
barraclough@apple.com2302c042011-03-14 23:31:00 +0000601 {
fpizlo@apple.comdc4cae72011-09-29 23:17:19 +0000602 return variableAccessData()->local();
barraclough@apple.com2302c042011-03-14 23:31:00 +0000603 }
fpizlo@apple.com31659de2012-02-23 22:51:09 +0000604
fpizlo@apple.coma62d4822013-10-06 04:22:43 +0000605 VirtualRegister machineLocal()
606 {
607 return variableAccessData()->machineLocal();
608 }
609
fpizlo@apple.com532f1e52013-09-04 06:26:04 +0000610 bool hasUnlinkedLocal()
611 {
612 switch (op()) {
613 case GetLocalUnlinked:
614 case ExtractOSREntryLocal:
fpizlo@apple.com9df7fef2013-12-29 21:50:55 +0000615 case MovHint:
616 case ZombieHint:
fpizlo@apple.com532f1e52013-09-04 06:26:04 +0000617 return true;
618 default:
619 return false;
620 }
621 }
622
fpizlo@apple.com9b928722012-05-24 00:18:55 +0000623 VirtualRegister unlinkedLocal()
624 {
fpizlo@apple.com532f1e52013-09-04 06:26:04 +0000625 ASSERT(hasUnlinkedLocal());
fpizlo@apple.com9b928722012-05-24 00:18:55 +0000626 return static_cast<VirtualRegister>(m_opInfo);
627 }
628
fpizlo@apple.coma62d4822013-10-06 04:22:43 +0000629 bool hasUnlinkedMachineLocal()
630 {
631 return op() == GetLocalUnlinked;
632 }
633
634 void setUnlinkedMachineLocal(VirtualRegister reg)
635 {
636 ASSERT(hasUnlinkedMachineLocal());
637 m_opInfo2 = reg.offset();
638 }
639
640 VirtualRegister unlinkedMachineLocal()
641 {
642 ASSERT(hasUnlinkedMachineLocal());
643 return VirtualRegister(m_opInfo2);
644 }
645
oliver@apple.com827d2cf2013-07-25 04:04:45 +0000646 bool hasPhi()
647 {
648 return op() == Upsilon;
649 }
650
651 Node* phi()
652 {
653 ASSERT(hasPhi());
654 return bitwise_cast<Node*>(m_opInfo);
655 }
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000656
657 bool isStoreBarrier()
658 {
659 switch (op()) {
660 case StoreBarrier:
mhahnenberg@apple.com4968e1a2013-12-18 22:50:40 +0000661 case StoreBarrierWithNullCheck:
662 return true;
663 default:
664 return false;
665 }
666 }
667
barraclough@apple.com2302c042011-03-14 23:31:00 +0000668 bool hasIdentifier()
669 {
fpizlo@apple.comd7897b12012-03-12 23:15:45 +0000670 switch (op()) {
fpizlo@apple.com6f1a3442011-09-16 06:33:55 +0000671 case GetById:
fpizlo@apple.comdc03dc52012-01-17 00:53:40 +0000672 case GetByIdFlush:
fpizlo@apple.com6f1a3442011-09-16 06:33:55 +0000673 case PutById:
oliver@apple.com11ce5ff2014-03-06 21:27:13 +0000674 case PutByIdFlush:
fpizlo@apple.com6f1a3442011-09-16 06:33:55 +0000675 case PutByIdDirect:
fpizlo@apple.com6f1a3442011-09-16 06:33:55 +0000676 return true;
677 default:
678 return false;
679 }
barraclough@apple.com2302c042011-03-14 23:31:00 +0000680 }
681
682 unsigned identifierNumber()
683 {
684 ASSERT(hasIdentifier());
685 return m_opInfo;
686 }
fpizlo@apple.com6f1a3442011-09-16 06:33:55 +0000687
fpizlo@apple.come887adf2011-09-20 20:10:56 +0000688 bool hasArithNodeFlags()
689 {
fpizlo@apple.comd7897b12012-03-12 23:15:45 +0000690 switch (op()) {
fpizlo@apple.come887adf2011-09-20 20:10:56 +0000691 case UInt32ToNumber:
692 case ArithAdd:
693 case ArithSub:
barraclough@apple.com8ff7e8c2012-02-28 00:31:28 +0000694 case ArithNegate:
fpizlo@apple.come887adf2011-09-20 20:10:56 +0000695 case ArithMul:
696 case ArithAbs:
697 case ArithMin:
698 case ArithMax:
fpizlo@apple.com9eb8ac22011-09-21 02:22:52 +0000699 case ArithMod:
fpizlo@apple.comde08b632011-09-22 22:02:24 +0000700 case ArithDiv:
fpizlo@apple.come887adf2011-09-20 20:10:56 +0000701 case ValueAdd:
702 return true;
703 default:
704 return false;
705 }
706 }
707
fpizlo@apple.come887adf2011-09-20 20:10:56 +0000708 // This corrects the arithmetic node flags, so that irrelevant bits are
709 // ignored. In particular, anything other than ArithMul does not need
710 // to know if it can speculate on negative zero.
fpizlo@apple.comc35b8f72012-03-12 09:50:38 +0000711 NodeFlags arithNodeFlags()
fpizlo@apple.come887adf2011-09-20 20:10:56 +0000712 {
fpizlo@apple.comb4f3cb82013-01-30 21:02:20 +0000713 NodeFlags result = m_flags & NodeArithFlagsMask;
commit-queue@webkit.org9f56bcd2013-04-25 22:52:34 +0000714 if (op() == ArithMul || op() == ArithDiv || op() == ArithMod || op() == ArithNegate || op() == DoubleAsInt32)
fpizlo@apple.come887adf2011-09-20 20:10:56 +0000715 return result;
fpizlo@apple.comdc36e832013-09-11 03:24:09 +0000716 return result & ~NodeBytecodeNeedsNegZero;
fpizlo@apple.come887adf2011-09-20 20:10:56 +0000717 }
718
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000719 bool hasConstantBuffer()
720 {
fpizlo@apple.comd7897b12012-03-12 23:15:45 +0000721 return op() == NewArrayBuffer;
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000722 }
723
fpizlo@apple.comf7b42982012-10-25 17:09:42 +0000724 NewArrayBufferData* newArrayBufferData()
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000725 {
726 ASSERT(hasConstantBuffer());
fpizlo@apple.comf7b42982012-10-25 17:09:42 +0000727 return reinterpret_cast<NewArrayBufferData*>(m_opInfo);
728 }
729
730 unsigned startConstant()
731 {
732 return newArrayBufferData()->startConstant;
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000733 }
734
735 unsigned numConstants()
736 {
fpizlo@apple.comf7b42982012-10-25 17:09:42 +0000737 return newArrayBufferData()->numConstants;
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000738 }
739
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000740 bool hasIndexingType()
741 {
742 switch (op()) {
743 case NewArray:
744 case NewArrayWithSize:
745 case NewArrayBuffer:
746 return true;
747 default:
748 return false;
749 }
750 }
751
752 IndexingType indexingType()
753 {
754 ASSERT(hasIndexingType());
755 if (op() == NewArrayBuffer)
756 return newArrayBufferData()->indexingType;
757 return m_opInfo;
758 }
759
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000760 bool hasTypedArrayType()
761 {
762 switch (op()) {
763 case NewTypedArray:
764 return true;
765 default:
766 return false;
767 }
768 }
769
770 TypedArrayType typedArrayType()
771 {
772 ASSERT(hasTypedArrayType());
773 TypedArrayType result = static_cast<TypedArrayType>(m_opInfo);
774 ASSERT(isTypedView(result));
775 return result;
776 }
777
ggaren@apple.comc862eac2013-01-29 05:48:01 +0000778 bool hasInlineCapacity()
779 {
780 return op() == CreateThis;
781 }
782
783 unsigned inlineCapacity()
784 {
785 ASSERT(hasInlineCapacity());
786 return m_opInfo;
787 }
788
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000789 void setIndexingType(IndexingType indexingType)
790 {
791 ASSERT(hasIndexingType());
792 m_opInfo = indexingType;
793 }
794
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000795 bool hasRegexpIndex()
796 {
fpizlo@apple.comd7897b12012-03-12 23:15:45 +0000797 return op() == NewRegexp;
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000798 }
799
800 unsigned regexpIndex()
801 {
802 ASSERT(hasRegexpIndex());
803 return m_opInfo;
804 }
805
barraclough@apple.com2302c042011-03-14 23:31:00 +0000806 bool hasVarNumber()
807 {
oliver@apple.com58c86752013-07-25 04:02:40 +0000808 return op() == GetClosureVar || op() == PutClosureVar;
barraclough@apple.com2302c042011-03-14 23:31:00 +0000809 }
810
fpizlo@apple.com1a724092013-11-28 07:10:10 +0000811 int varNumber()
barraclough@apple.com2302c042011-03-14 23:31:00 +0000812 {
813 ASSERT(hasVarNumber());
814 return m_opInfo;
815 }
fpizlo@apple.com26af9b62012-06-07 00:49:34 +0000816
817 bool hasRegisterPointer()
818 {
fpizlo@apple.com86468342013-11-27 02:47:43 +0000819 return op() == GetGlobalVar || op() == PutGlobalVar;
fpizlo@apple.com26af9b62012-06-07 00:49:34 +0000820 }
821
822 WriteBarrier<Unknown>* registerPointer()
823 {
824 return bitwise_cast<WriteBarrier<Unknown>*>(m_opInfo);
825 }
fpizlo@apple.com1a724092013-11-28 07:10:10 +0000826
barraclough@apple.comde174fb2011-04-22 20:38:27 +0000827 bool hasResult()
828 {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000829 return !!result();
barraclough@apple.comde174fb2011-04-22 20:38:27 +0000830 }
831
barraclough@apple.com2302c042011-03-14 23:31:00 +0000832 bool hasInt32Result()
833 {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000834 return result() == NodeResultInt32;
835 }
836
837 bool hasInt52Result()
838 {
839 return result() == NodeResultInt52;
barraclough@apple.com2302c042011-03-14 23:31:00 +0000840 }
fpizlo@apple.com0ef13dc2011-09-14 00:37:01 +0000841
842 bool hasNumberResult()
barraclough@apple.com2302c042011-03-14 23:31:00 +0000843 {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000844 return result() == NodeResultNumber;
845 }
846
847 bool hasDoubleResult()
848 {
849 return result() == NodeResultDouble;
barraclough@apple.com2302c042011-03-14 23:31:00 +0000850 }
fpizlo@apple.com0ef13dc2011-09-14 00:37:01 +0000851
barraclough@apple.com2302c042011-03-14 23:31:00 +0000852 bool hasJSResult()
853 {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000854 return result() == NodeResultJS;
barraclough@apple.com2302c042011-03-14 23:31:00 +0000855 }
fpizlo@apple.com746c6d072011-09-07 02:47:51 +0000856
857 bool hasBooleanResult()
858 {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000859 return result() == NodeResultBoolean;
fpizlo@apple.com746c6d072011-09-07 02:47:51 +0000860 }
barraclough@apple.com2302c042011-03-14 23:31:00 +0000861
fpizlo@apple.comc2c67632012-11-17 08:37:14 +0000862 bool hasStorageResult()
863 {
fpizlo@apple.com7b33e0c2014-04-15 20:26:16 +0000864 return result() == NodeResultStorage;
865 }
866
867 UseKind defaultUseKind()
868 {
869 return useKindForResult(result());
870 }
871
872 Edge defaultEdge()
873 {
874 return Edge(this, defaultUseKind());
fpizlo@apple.comc2c67632012-11-17 08:37:14 +0000875 }
876
barraclough@apple.come23e0402011-04-15 23:02:09 +0000877 bool isJump()
878 {
fpizlo@apple.comd7897b12012-03-12 23:15:45 +0000879 return op() == Jump;
barraclough@apple.come23e0402011-04-15 23:02:09 +0000880 }
881
882 bool isBranch()
883 {
fpizlo@apple.comd7897b12012-03-12 23:15:45 +0000884 return op() == Branch;
barraclough@apple.come23e0402011-04-15 23:02:09 +0000885 }
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000886
887 bool isSwitch()
888 {
889 return op() == Switch;
890 }
barraclough@apple.come23e0402011-04-15 23:02:09 +0000891
barraclough@apple.comb6de6912011-04-22 21:33:36 +0000892 bool isTerminal()
893 {
fpizlo@apple.comd7897b12012-03-12 23:15:45 +0000894 switch (op()) {
fpizlo@apple.comc35b8f72012-03-12 09:50:38 +0000895 case Jump:
896 case Branch:
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000897 case Switch:
fpizlo@apple.comc35b8f72012-03-12 09:50:38 +0000898 case Return:
oliver@apple.com1fc04182013-08-19 19:40:13 +0000899 case Unreachable:
fpizlo@apple.comc35b8f72012-03-12 09:50:38 +0000900 return true;
901 default:
902 return false;
903 }
barraclough@apple.comb6de6912011-04-22 21:33:36 +0000904 }
905
fpizlo@apple.comb8377cd2014-02-20 08:00:28 +0000906 unsigned targetBytecodeOffsetDuringParsing()
barraclough@apple.come23e0402011-04-15 23:02:09 +0000907 {
fpizlo@apple.comb8377cd2014-02-20 08:00:28 +0000908 ASSERT(isJump());
barraclough@apple.come23e0402011-04-15 23:02:09 +0000909 return m_opInfo;
910 }
911
fpizlo@apple.comb8377cd2014-02-20 08:00:28 +0000912 BasicBlock*& targetBlock()
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000913 {
fpizlo@apple.comb8377cd2014-02-20 08:00:28 +0000914 ASSERT(isJump());
oliver@apple.com827d2cf2013-07-25 04:04:45 +0000915 return *bitwise_cast<BasicBlock**>(&m_opInfo);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000916 }
917
fpizlo@apple.comb8377cd2014-02-20 08:00:28 +0000918 BranchData* branchData()
barraclough@apple.come23e0402011-04-15 23:02:09 +0000919 {
920 ASSERT(isBranch());
fpizlo@apple.comb8377cd2014-02-20 08:00:28 +0000921 return bitwise_cast<BranchData*>(m_opInfo);
barraclough@apple.come23e0402011-04-15 23:02:09 +0000922 }
fpizlo@apple.com7ab54822011-08-10 00:51:11 +0000923
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000924 SwitchData* switchData()
925 {
926 ASSERT(isSwitch());
927 return bitwise_cast<SwitchData*>(m_opInfo);
928 }
929
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +0000930 unsigned numSuccessors()
931 {
932 switch (op()) {
933 case Jump:
934 return 1;
935 case Branch:
936 return 2;
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000937 case Switch:
938 return switchData()->cases.size() + 1;
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +0000939 default:
940 return 0;
941 }
942 }
943
oliver@apple.com827d2cf2013-07-25 04:04:45 +0000944 BasicBlock*& successor(unsigned index)
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +0000945 {
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000946 if (isSwitch()) {
947 if (index < switchData()->cases.size())
fpizlo@apple.comb8377cd2014-02-20 08:00:28 +0000948 return switchData()->cases[index].target.block;
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000949 RELEASE_ASSERT(index == switchData()->cases.size());
fpizlo@apple.comb8377cd2014-02-20 08:00:28 +0000950 return switchData()->fallThrough.block;
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000951 }
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +0000952 switch (index) {
953 case 0:
fpizlo@apple.comb8377cd2014-02-20 08:00:28 +0000954 if (isJump())
955 return targetBlock();
956 return branchData()->taken.block;
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +0000957 case 1:
fpizlo@apple.comb8377cd2014-02-20 08:00:28 +0000958 return branchData()->notTaken.block;
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +0000959 default:
oliver@apple.com5598c182013-01-23 22:25:07 +0000960 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.comb8377cd2014-02-20 08:00:28 +0000961 return targetBlock();
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +0000962 }
963 }
964
oliver@apple.com827d2cf2013-07-25 04:04:45 +0000965 BasicBlock*& successorForCondition(bool condition)
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +0000966 {
fpizlo@apple.comb8377cd2014-02-20 08:00:28 +0000967 return branchData()->forCondition(condition);
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +0000968 }
969
fpizlo@apple.comd30b1202011-10-04 01:05:38 +0000970 bool hasHeapPrediction()
fpizlo@apple.com7ab54822011-08-10 00:51:11 +0000971 {
fpizlo@apple.comd7897b12012-03-12 23:15:45 +0000972 switch (op()) {
fpizlo@apple.com7ab54822011-08-10 00:51:11 +0000973 case GetById:
fpizlo@apple.comdc03dc52012-01-17 00:53:40 +0000974 case GetByIdFlush:
fpizlo@apple.com7ab54822011-08-10 00:51:11 +0000975 case GetByVal:
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +0000976 case GetMyArgumentByVal:
fpizlo@apple.com9a548f12012-05-24 05:33:09 +0000977 case GetMyArgumentByValSafe:
fpizlo@apple.com7ab54822011-08-10 00:51:11 +0000978 case Call:
979 case Construct:
fpizlo@apple.comb41e6822014-07-25 20:55:17 +0000980 case NativeCall:
981 case NativeConstruct:
fpizlo@apple.comffb7d5e2011-09-20 09:41:16 +0000982 case GetByOffset:
fpizlo@apple.com51614cc2014-02-17 06:35:32 +0000983 case MultiGetByOffset:
oliver@apple.com58c86752013-07-25 04:02:40 +0000984 case GetClosureVar:
fpizlo@apple.com24d24e52011-10-04 02:55:54 +0000985 case ArrayPop:
986 case ArrayPush:
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000987 case RegExpExec:
988 case RegExpTest:
fpizlo@apple.come9915ef2012-04-11 20:51:21 +0000989 case GetGlobalVar:
fpizlo@apple.com7ab54822011-08-10 00:51:11 +0000990 return true;
991 default:
992 return false;
993 }
994 }
995
fpizlo@apple.com62336162012-06-07 01:35:59 +0000996 SpeculatedType getHeapPrediction()
fpizlo@apple.com7ab54822011-08-10 00:51:11 +0000997 {
fpizlo@apple.comd30b1202011-10-04 01:05:38 +0000998 ASSERT(hasHeapPrediction());
fpizlo@apple.com62336162012-06-07 01:35:59 +0000999 return static_cast<SpeculatedType>(m_opInfo2);
fpizlo@apple.com7ab54822011-08-10 00:51:11 +00001000 }
1001
fpizlo@apple.com62336162012-06-07 01:35:59 +00001002 bool predictHeap(SpeculatedType prediction)
fpizlo@apple.com7ab54822011-08-10 00:51:11 +00001003 {
fpizlo@apple.comd30b1202011-10-04 01:05:38 +00001004 ASSERT(hasHeapPrediction());
fpizlo@apple.comdc325432011-09-02 21:16:25 +00001005
fpizlo@apple.com62336162012-06-07 01:35:59 +00001006 return mergeSpeculation(m_opInfo2, prediction);
fpizlo@apple.com7ab54822011-08-10 00:51:11 +00001007 }
fpizlo@apple.com594887a2011-09-06 09:23:55 +00001008
fpizlo@apple.com884300d2014-05-21 03:49:16 +00001009 void setHeapPrediction(SpeculatedType prediction)
1010 {
1011 ASSERT(hasHeapPrediction());
1012 m_opInfo2 = prediction;
1013 }
1014
fpizlo@apple.comff27eed2014-07-23 04:33:37 +00001015 bool canBeKnownFunction()
1016 {
1017 switch (op()) {
fpizlo@apple.comb41e6822014-07-25 20:55:17 +00001018 case NativeConstruct:
1019 case NativeCall:
fpizlo@apple.comff27eed2014-07-23 04:33:37 +00001020 return true;
1021 default:
1022 return false;
1023 }
1024 }
1025
1026 bool hasKnownFunction()
1027 {
1028 switch (op()) {
fpizlo@apple.comb41e6822014-07-25 20:55:17 +00001029 case NativeConstruct:
1030 case NativeCall:
fpizlo@apple.comff27eed2014-07-23 04:33:37 +00001031 return (bool)m_opInfo;
1032 default:
1033 return false;
1034 }
1035 }
1036
1037 JSFunction* knownFunction()
1038 {
1039 ASSERT(canBeKnownFunction());
1040 return bitwise_cast<JSFunction*>(m_opInfo);
1041 }
1042
1043 void giveKnownFunction(JSFunction* callData)
1044 {
1045 ASSERT(canBeKnownFunction());
1046 m_opInfo = bitwise_cast<uintptr_t>(callData);
1047 }
1048
fpizlo@apple.comf5db15e2012-11-14 07:22:57 +00001049 bool hasFunction()
oliver@apple.com1386ec92011-10-07 18:39:45 +00001050 {
fpizlo@apple.comf5db15e2012-11-14 07:22:57 +00001051 switch (op()) {
1052 case CheckFunction:
ggaren@apple.comc862eac2013-01-29 05:48:01 +00001053 case AllocationProfileWatchpoint:
fpizlo@apple.comf5db15e2012-11-14 07:22:57 +00001054 return true;
1055 default:
1056 return false;
1057 }
oliver@apple.com1386ec92011-10-07 18:39:45 +00001058 }
1059
fpizlo@apple.comb41e6822014-07-25 20:55:17 +00001060 FrozenValue* function()
oliver@apple.com1386ec92011-10-07 18:39:45 +00001061 {
fpizlo@apple.comf5db15e2012-11-14 07:22:57 +00001062 ASSERT(hasFunction());
fpizlo@apple.comb41e6822014-07-25 20:55:17 +00001063 return reinterpret_cast<FrozenValue*>(m_opInfo);
oliver@apple.com1386ec92011-10-07 18:39:45 +00001064 }
fpizlo@apple.com5e2296a2013-01-07 02:24:58 +00001065
1066 bool hasExecutable()
1067 {
1068 return op() == CheckExecutable;
1069 }
1070
1071 ExecutableBase* executable()
1072 {
1073 return jsCast<ExecutableBase*>(reinterpret_cast<JSCell*>(m_opInfo));
1074 }
fpizlo@apple.com86468342013-11-27 02:47:43 +00001075
1076 bool hasVariableWatchpointSet()
1077 {
1078 return op() == NotifyWrite || op() == VariableWatchpoint;
1079 }
1080
1081 VariableWatchpointSet* variableWatchpointSet()
1082 {
1083 return reinterpret_cast<VariableWatchpointSet*>(m_opInfo);
1084 }
fpizlo@apple.comce995b22013-12-08 19:01:17 +00001085
1086 bool hasTypedArray()
1087 {
1088 return op() == TypedArrayWatchpoint;
1089 }
1090
1091 JSArrayBufferView* typedArray()
1092 {
1093 return reinterpret_cast<JSArrayBufferView*>(m_opInfo);
1094 }
fpizlo@apple.com9ca951e2013-12-09 01:08:53 +00001095
1096 bool hasStoragePointer()
1097 {
1098 return op() == ConstantStoragePointer;
1099 }
1100
1101 void* storagePointer()
1102 {
1103 return reinterpret_cast<void*>(m_opInfo);
1104 }
oliver@apple.com1386ec92011-10-07 18:39:45 +00001105
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00001106 bool hasTransition()
fpizlo@apple.comffb7d5e2011-09-20 09:41:16 +00001107 {
fpizlo@apple.com1ffdcff2012-07-19 00:30:34 +00001108 switch (op()) {
1109 case PutStructure:
1110 case PhantomPutStructure:
1111 case AllocatePropertyStorage:
1112 case ReallocatePropertyStorage:
1113 return true;
1114 default:
1115 return false;
1116 }
fpizlo@apple.comffb7d5e2011-09-20 09:41:16 +00001117 }
1118
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00001119 Transition* transition()
fpizlo@apple.comffb7d5e2011-09-20 09:41:16 +00001120 {
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +00001121 ASSERT(hasTransition());
1122 return reinterpret_cast<Transition*>(m_opInfo);
fpizlo@apple.com752f7d92011-10-03 19:25:16 +00001123 }
1124
1125 bool hasStructureSet()
1126 {
fpizlo@apple.comcaa68812012-08-02 04:32:30 +00001127 switch (op()) {
1128 case CheckStructure:
fpizlo@apple.comcaa68812012-08-02 04:32:30 +00001129 return true;
1130 default:
1131 return false;
1132 }
fpizlo@apple.com752f7d92011-10-03 19:25:16 +00001133 }
1134
1135 StructureSet& structureSet()
1136 {
1137 ASSERT(hasStructureSet());
1138 return *reinterpret_cast<StructureSet*>(m_opInfo);
fpizlo@apple.comffb7d5e2011-09-20 09:41:16 +00001139 }
1140
fpizlo@apple.com04e41152012-06-15 22:14:53 +00001141 bool hasStructure()
1142 {
fpizlo@apple.comeb3323d2012-08-20 06:11:24 +00001143 switch (op()) {
fpizlo@apple.com99f37622012-10-29 04:02:08 +00001144 case ArrayifyToStructure:
fpizlo@apple.comf5db15e2012-11-14 07:22:57 +00001145 case NewObject:
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001146 case NewStringObject:
fpizlo@apple.comeb3323d2012-08-20 06:11:24 +00001147 return true;
1148 default:
1149 return false;
1150 }
fpizlo@apple.com04e41152012-06-15 22:14:53 +00001151 }
1152
1153 Structure* structure()
1154 {
1155 ASSERT(hasStructure());
1156 return reinterpret_cast<Structure*>(m_opInfo);
1157 }
1158
fpizlo@apple.comffb7d5e2011-09-20 09:41:16 +00001159 bool hasStorageAccessData()
1160 {
fpizlo@apple.com4c6b8ad2014-07-22 21:08:50 +00001161 return op() == GetByOffset || op() == GetGetterSetterByOffset || op() == PutByOffset;
fpizlo@apple.comffb7d5e2011-09-20 09:41:16 +00001162 }
1163
1164 unsigned storageAccessDataIndex()
1165 {
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001166 ASSERT(hasStorageAccessData());
1167 return m_opInfo;
1168 }
1169
fpizlo@apple.com51614cc2014-02-17 06:35:32 +00001170 bool hasMultiGetByOffsetData()
1171 {
1172 return op() == MultiGetByOffset;
1173 }
1174
1175 MultiGetByOffsetData& multiGetByOffsetData()
1176 {
1177 return *reinterpret_cast<MultiGetByOffsetData*>(m_opInfo);
1178 }
1179
fpizlo@apple.com43219522014-02-25 02:02:50 +00001180 bool hasMultiPutByOffsetData()
1181 {
1182 return op() == MultiPutByOffset;
1183 }
1184
1185 MultiPutByOffsetData& multiPutByOffsetData()
1186 {
1187 return *reinterpret_cast<MultiPutByOffsetData*>(m_opInfo);
1188 }
1189
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001190 bool hasFunctionDeclIndex()
1191 {
fpizlo@apple.comd7897b12012-03-12 23:15:45 +00001192 return op() == NewFunction
1193 || op() == NewFunctionNoCheck;
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001194 }
1195
1196 unsigned functionDeclIndex()
1197 {
1198 ASSERT(hasFunctionDeclIndex());
1199 return m_opInfo;
1200 }
1201
1202 bool hasFunctionExprIndex()
1203 {
fpizlo@apple.comd7897b12012-03-12 23:15:45 +00001204 return op() == NewFunctionExpression;
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001205 }
1206
1207 unsigned functionExprIndex()
1208 {
1209 ASSERT(hasFunctionExprIndex());
fpizlo@apple.comffb7d5e2011-09-20 09:41:16 +00001210 return m_opInfo;
1211 }
1212
fpizlo@apple.com1a724092013-11-28 07:10:10 +00001213 bool hasSymbolTable()
1214 {
fpizlo@apple.coma4ea0662013-12-02 19:09:15 +00001215 return op() == FunctionReentryWatchpoint;
fpizlo@apple.com1a724092013-11-28 07:10:10 +00001216 }
1217
1218 SymbolTable* symbolTable()
1219 {
1220 ASSERT(hasSymbolTable());
1221 return reinterpret_cast<SymbolTable*>(m_opInfo);
1222 }
1223
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001224 bool hasArrayMode()
1225 {
1226 switch (op()) {
1227 case GetIndexedPropertyStorage:
1228 case GetArrayLength:
oliver@apple.come050d642013-10-19 00:09:28 +00001229 case PutByValDirect:
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001230 case PutByVal:
1231 case PutByValAlias:
1232 case GetByVal:
1233 case StringCharAt:
1234 case StringCharCodeAt:
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001235 case CheckArray:
fpizlo@apple.com497c7512012-09-19 01:20:52 +00001236 case Arrayify:
fpizlo@apple.com99f37622012-10-29 04:02:08 +00001237 case ArrayifyToStructure:
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001238 case ArrayPush:
1239 case ArrayPop:
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001240 return true;
1241 default:
1242 return false;
1243 }
1244 }
1245
fpizlo@apple.com34d1f082012-10-28 06:13:23 +00001246 ArrayMode arrayMode()
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001247 {
1248 ASSERT(hasArrayMode());
fpizlo@apple.com99f37622012-10-29 04:02:08 +00001249 if (op() == ArrayifyToStructure)
1250 return ArrayMode::fromWord(m_opInfo2);
fpizlo@apple.com34d1f082012-10-28 06:13:23 +00001251 return ArrayMode::fromWord(m_opInfo);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001252 }
1253
fpizlo@apple.com34d1f082012-10-28 06:13:23 +00001254 bool setArrayMode(ArrayMode arrayMode)
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001255 {
1256 ASSERT(hasArrayMode());
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001257 if (this->arrayMode() == arrayMode)
1258 return false;
fpizlo@apple.com34d1f082012-10-28 06:13:23 +00001259 m_opInfo = arrayMode.asWord();
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001260 return true;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001261 }
1262
fpizlo@apple.coma0fb09052014-01-07 04:52:48 +00001263 bool hasArithMode()
1264 {
1265 switch (op()) {
1266 case ArithAdd:
1267 case ArithSub:
1268 case ArithNegate:
1269 case ArithMul:
1270 case ArithDiv:
1271 case ArithMod:
1272 case UInt32ToNumber:
1273 case DoubleAsInt32:
1274 return true;
1275 default:
1276 return false;
1277 }
1278 }
1279
1280 Arith::Mode arithMode()
1281 {
1282 ASSERT(hasArithMode());
1283 return static_cast<Arith::Mode>(m_opInfo);
1284 }
1285
1286 void setArithMode(Arith::Mode mode)
1287 {
1288 m_opInfo = mode;
1289 }
1290
fpizlo@apple.com75ee46c2011-09-18 03:47:04 +00001291 bool hasVirtualRegister()
1292 {
msaboff@apple.com62aa8b72013-09-26 22:53:54 +00001293 return m_virtualRegister.isValid();
fpizlo@apple.com75ee46c2011-09-18 03:47:04 +00001294 }
1295
barraclough@apple.comde174fb2011-04-22 20:38:27 +00001296 VirtualRegister virtualRegister()
barraclough@apple.com73e6fc12011-04-20 20:47:53 +00001297 {
barraclough@apple.comde174fb2011-04-22 20:38:27 +00001298 ASSERT(hasResult());
msaboff@apple.com62aa8b72013-09-26 22:53:54 +00001299 ASSERT(m_virtualRegister.isValid());
barraclough@apple.comde174fb2011-04-22 20:38:27 +00001300 return m_virtualRegister;
barraclough@apple.com73e6fc12011-04-20 20:47:53 +00001301 }
fpizlo@apple.com8618e4b2012-07-03 01:27:16 +00001302
barraclough@apple.comde174fb2011-04-22 20:38:27 +00001303 void setVirtualRegister(VirtualRegister virtualRegister)
1304 {
1305 ASSERT(hasResult());
msaboff@apple.com62aa8b72013-09-26 22:53:54 +00001306 ASSERT(!m_virtualRegister.isValid());
barraclough@apple.comde174fb2011-04-22 20:38:27 +00001307 m_virtualRegister = virtualRegister;
1308 }
fpizlo@apple.comb80bc2a32012-06-02 22:58:48 +00001309
fpizlo@apple.com4a81fa42012-12-05 01:26:13 +00001310 bool hasExecutionCounter()
1311 {
1312 return op() == CountExecution;
1313 }
1314
1315 Profiler::ExecutionCounter* executionCounter()
1316 {
1317 return bitwise_cast<Profiler::ExecutionCounter*>(m_opInfo);
1318 }
barraclough@apple.comde174fb2011-04-22 20:38:27 +00001319
barraclough@apple.com9f8b54b2011-04-23 20:16:10 +00001320 bool shouldGenerate()
1321 {
fpizlo@apple.comb0da6b62012-02-24 21:31:37 +00001322 return m_refCount;
barraclough@apple.com9f8b54b2011-04-23 20:16:10 +00001323 }
fpizlo@apple.com3d517672012-06-20 17:48:23 +00001324
fpizlo@apple.com12c18392012-06-27 23:16:10 +00001325 bool willHaveCodeGenOrOSR()
fpizlo@apple.com3d517672012-06-20 17:48:23 +00001326 {
fpizlo@apple.com12c18392012-06-27 23:16:10 +00001327 switch (op()) {
1328 case SetLocal:
fpizlo@apple.com06f82b52013-03-06 02:27:16 +00001329 case MovHint:
1330 case ZombieHint:
fpizlo@apple.com53090e42012-09-18 22:26:41 +00001331 case PhantomArguments:
fpizlo@apple.com12c18392012-06-27 23:16:10 +00001332 return true;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001333 case Phantom:
fpizlo@apple.com4c96a842014-02-13 22:46:51 +00001334 case HardPhantom:
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001335 return child1().useKindUnchecked() != UntypedUse || child2().useKindUnchecked() != UntypedUse || child3().useKindUnchecked() != UntypedUse;
fpizlo@apple.com12c18392012-06-27 23:16:10 +00001336 default:
1337 return shouldGenerate();
1338 }
fpizlo@apple.com3d517672012-06-20 17:48:23 +00001339 }
msaboff@apple.com95894332014-01-29 19:18:54 +00001340
1341 bool isSemanticallySkippable()
1342 {
1343 return op() == CountExecution;
1344 }
barraclough@apple.com9f8b54b2011-04-23 20:16:10 +00001345
barraclough@apple.comde174fb2011-04-22 20:38:27 +00001346 unsigned refCount()
1347 {
1348 return m_refCount;
1349 }
1350
fpizlo@apple.com78009012013-01-17 20:45:06 +00001351 unsigned postfixRef()
1352 {
1353 return m_refCount++;
barraclough@apple.comde174fb2011-04-22 20:38:27 +00001354 }
barraclough@apple.comde174fb2011-04-22 20:38:27 +00001355
1356 unsigned adjustedRefCount()
1357 {
1358 return mustGenerate() ? m_refCount - 1 : m_refCount;
1359 }
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +00001360
fpizlo@apple.com75ee46c2011-09-18 03:47:04 +00001361 void setRefCount(unsigned refCount)
1362 {
1363 m_refCount = refCount;
1364 }
1365
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001366 Edge& child1()
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +00001367 {
fpizlo@apple.comd7897b12012-03-12 23:15:45 +00001368 ASSERT(!(m_flags & NodeHasVarArgs));
fpizlo@apple.com1996b4b2012-02-06 06:44:24 +00001369 return children.child1();
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +00001370 }
fpizlo@apple.com7f6c6802011-09-13 01:33:43 +00001371
1372 // This is useful if you want to do a fast check on the first child
1373 // before also doing a check on the opcode. Use this with care and
1374 // avoid it if possible.
fpizlo@apple.come5abbae2012-03-19 21:44:23 +00001375 Edge child1Unchecked()
fpizlo@apple.com7f6c6802011-09-13 01:33:43 +00001376 {
fpizlo@apple.com1996b4b2012-02-06 06:44:24 +00001377 return children.child1Unchecked();
fpizlo@apple.com7f6c6802011-09-13 01:33:43 +00001378 }
barraclough@apple.com73e6fc12011-04-20 20:47:53 +00001379
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001380 Edge& child2()
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +00001381 {
fpizlo@apple.comd7897b12012-03-12 23:15:45 +00001382 ASSERT(!(m_flags & NodeHasVarArgs));
fpizlo@apple.com1996b4b2012-02-06 06:44:24 +00001383 return children.child2();
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +00001384 }
1385
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001386 Edge& child3()
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +00001387 {
fpizlo@apple.comd7897b12012-03-12 23:15:45 +00001388 ASSERT(!(m_flags & NodeHasVarArgs));
fpizlo@apple.com1996b4b2012-02-06 06:44:24 +00001389 return children.child3();
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +00001390 }
1391
1392 unsigned firstChild()
1393 {
fpizlo@apple.comd7897b12012-03-12 23:15:45 +00001394 ASSERT(m_flags & NodeHasVarArgs);
fpizlo@apple.com1996b4b2012-02-06 06:44:24 +00001395 return children.firstChild();
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +00001396 }
1397
1398 unsigned numChildren()
1399 {
fpizlo@apple.comd7897b12012-03-12 23:15:45 +00001400 ASSERT(m_flags & NodeHasVarArgs);
fpizlo@apple.com1996b4b2012-02-06 06:44:24 +00001401 return children.numChildren();
commit-queue@webkit.org4ea48922011-07-06 00:56:49 +00001402 }
1403
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001404 UseKind binaryUseKind()
1405 {
1406 ASSERT(child1().useKind() == child2().useKind());
1407 return child1().useKind();
1408 }
1409
fpizlo@apple.com312efcd2014-03-10 22:11:35 +00001410 bool isBinaryUseKind(UseKind left, UseKind right)
1411 {
1412 return child1().useKind() == left && child2().useKind() == right;
1413 }
1414
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001415 bool isBinaryUseKind(UseKind useKind)
1416 {
fpizlo@apple.com312efcd2014-03-10 22:11:35 +00001417 return isBinaryUseKind(useKind, useKind);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001418 }
1419
fpizlo@apple.com385a33a2014-03-18 20:53:07 +00001420 Edge childFor(UseKind useKind)
1421 {
1422 if (child1().useKind() == useKind)
1423 return child1();
1424 if (child2().useKind() == useKind)
1425 return child2();
1426 if (child3().useKind() == useKind)
1427 return child3();
1428 return Edge();
1429 }
1430
fpizlo@apple.com62336162012-06-07 01:35:59 +00001431 SpeculatedType prediction()
fpizlo@apple.comd30b1202011-10-04 01:05:38 +00001432 {
1433 return m_prediction;
1434 }
1435
fpizlo@apple.com62336162012-06-07 01:35:59 +00001436 bool predict(SpeculatedType prediction)
fpizlo@apple.comd30b1202011-10-04 01:05:38 +00001437 {
fpizlo@apple.com62336162012-06-07 01:35:59 +00001438 return mergeSpeculation(m_prediction, prediction);
fpizlo@apple.comd30b1202011-10-04 01:05:38 +00001439 }
1440
fpizlo@apple.comefacb612013-09-10 22:16:00 +00001441 bool shouldSpeculateInt32()
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001442 {
fpizlo@apple.com62336162012-06-07 01:35:59 +00001443 return isInt32Speculation(prediction());
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001444 }
1445
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001446 bool sawBooleans()
1447 {
1448 return !!(prediction() & SpecBoolean);
1449 }
1450
1451 bool shouldSpeculateInt32OrBoolean()
1452 {
1453 return isInt32OrBooleanSpeculation(prediction());
1454 }
1455
fpizlo@apple.comefacb612013-09-10 22:16:00 +00001456 bool shouldSpeculateInt32ForArithmetic()
fpizlo@apple.com81f75372012-11-08 22:55:27 +00001457 {
1458 return isInt32SpeculationForArithmetic(prediction());
1459 }
1460
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001461 bool shouldSpeculateInt32OrBooleanForArithmetic()
fpizlo@apple.com81f75372012-11-08 22:55:27 +00001462 {
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001463 return isInt32OrBooleanSpeculationForArithmetic(prediction());
1464 }
1465
1466 bool shouldSpeculateInt32OrBooleanExpectingDefined()
1467 {
1468 return isInt32OrBooleanSpeculationExpectingDefined(prediction());
fpizlo@apple.com81f75372012-11-08 22:55:27 +00001469 }
1470
fpizlo@apple.com3f780e42013-09-11 04:35:16 +00001471 bool shouldSpeculateMachineInt()
1472 {
1473 return isMachineIntSpeculation(prediction());
1474 }
1475
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001476 bool shouldSpeculateDouble()
1477 {
fpizlo@apple.com62336162012-06-07 01:35:59 +00001478 return isDoubleSpeculation(prediction());
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001479 }
1480
1481 bool shouldSpeculateNumber()
1482 {
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001483 return isFullNumberSpeculation(prediction());
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001484 }
1485
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001486 bool shouldSpeculateNumberOrBoolean()
fpizlo@apple.com81f75372012-11-08 22:55:27 +00001487 {
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001488 return isFullNumberOrBooleanSpeculation(prediction());
1489 }
1490
1491 bool shouldSpeculateNumberOrBooleanExpectingDefined()
1492 {
1493 return isFullNumberOrBooleanSpeculationExpectingDefined(prediction());
fpizlo@apple.com81f75372012-11-08 22:55:27 +00001494 }
1495
fpizlo@apple.com2fc3dbd2012-03-14 02:54:58 +00001496 bool shouldSpeculateBoolean()
1497 {
fpizlo@apple.com62336162012-06-07 01:35:59 +00001498 return isBooleanSpeculation(prediction());
fpizlo@apple.com2fc3dbd2012-03-14 02:54:58 +00001499 }
fpizlo@apple.come079bb52014-03-05 07:41:03 +00001500
fpizlo@apple.com312efcd2014-03-10 22:11:35 +00001501 bool shouldSpeculateOther()
1502 {
1503 return isOtherSpeculation(prediction());
1504 }
1505
fpizlo@apple.come079bb52014-03-05 07:41:03 +00001506 bool shouldSpeculateMisc()
1507 {
1508 return isMiscSpeculation(prediction());
1509 }
mhahnenberg@apple.com030c9da2012-08-30 21:11:21 +00001510
oliver@apple.combd15be82013-07-25 04:03:42 +00001511 bool shouldSpeculateStringIdent()
1512 {
1513 return isStringIdentSpeculation(prediction());
1514 }
fpizlo@apple.com385a33a2014-03-18 20:53:07 +00001515
1516 bool shouldSpeculateNotStringVar()
1517 {
1518 return isNotStringVarSpeculation(prediction());
1519 }
oliver@apple.combd15be82013-07-25 04:03:42 +00001520
mhahnenberg@apple.com030c9da2012-08-30 21:11:21 +00001521 bool shouldSpeculateString()
1522 {
1523 return isStringSpeculation(prediction());
1524 }
1525
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001526 bool shouldSpeculateStringObject()
1527 {
1528 return isStringObjectSpeculation(prediction());
1529 }
1530
1531 bool shouldSpeculateStringOrStringObject()
1532 {
1533 return isStringOrStringObjectSpeculation(prediction());
1534 }
1535
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001536 bool shouldSpeculateFinalObject()
1537 {
fpizlo@apple.com62336162012-06-07 01:35:59 +00001538 return isFinalObjectSpeculation(prediction());
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001539 }
1540
1541 bool shouldSpeculateFinalObjectOrOther()
1542 {
fpizlo@apple.com62336162012-06-07 01:35:59 +00001543 return isFinalObjectOrOtherSpeculation(prediction());
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001544 }
1545
1546 bool shouldSpeculateArray()
1547 {
fpizlo@apple.com62336162012-06-07 01:35:59 +00001548 return isArraySpeculation(prediction());
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001549 }
1550
fpizlo@apple.comf860f9b2012-05-22 20:02:25 +00001551 bool shouldSpeculateArguments()
1552 {
fpizlo@apple.com62336162012-06-07 01:35:59 +00001553 return isArgumentsSpeculation(prediction());
fpizlo@apple.comf860f9b2012-05-22 20:02:25 +00001554 }
1555
oliver@apple.comaeec3d82011-12-02 01:56:53 +00001556 bool shouldSpeculateInt8Array()
1557 {
fpizlo@apple.com62336162012-06-07 01:35:59 +00001558 return isInt8ArraySpeculation(prediction());
oliver@apple.comaeec3d82011-12-02 01:56:53 +00001559 }
1560
1561 bool shouldSpeculateInt16Array()
1562 {
fpizlo@apple.com62336162012-06-07 01:35:59 +00001563 return isInt16ArraySpeculation(prediction());
oliver@apple.comaeec3d82011-12-02 01:56:53 +00001564 }
1565
1566 bool shouldSpeculateInt32Array()
1567 {
fpizlo@apple.com62336162012-06-07 01:35:59 +00001568 return isInt32ArraySpeculation(prediction());
oliver@apple.comaeec3d82011-12-02 01:56:53 +00001569 }
1570
1571 bool shouldSpeculateUint8Array()
1572 {
fpizlo@apple.com62336162012-06-07 01:35:59 +00001573 return isUint8ArraySpeculation(prediction());
oliver@apple.comaeec3d82011-12-02 01:56:53 +00001574 }
caio.oliveira@openbossa.org992fc372012-01-18 01:11:16 +00001575
1576 bool shouldSpeculateUint8ClampedArray()
1577 {
fpizlo@apple.com62336162012-06-07 01:35:59 +00001578 return isUint8ClampedArraySpeculation(prediction());
caio.oliveira@openbossa.org992fc372012-01-18 01:11:16 +00001579 }
oliver@apple.comaeec3d82011-12-02 01:56:53 +00001580
1581 bool shouldSpeculateUint16Array()
1582 {
fpizlo@apple.com62336162012-06-07 01:35:59 +00001583 return isUint16ArraySpeculation(prediction());
oliver@apple.comaeec3d82011-12-02 01:56:53 +00001584 }
1585
1586 bool shouldSpeculateUint32Array()
1587 {
fpizlo@apple.com62336162012-06-07 01:35:59 +00001588 return isUint32ArraySpeculation(prediction());
oliver@apple.comaeec3d82011-12-02 01:56:53 +00001589 }
1590
1591 bool shouldSpeculateFloat32Array()
1592 {
fpizlo@apple.com62336162012-06-07 01:35:59 +00001593 return isFloat32ArraySpeculation(prediction());
oliver@apple.comaeec3d82011-12-02 01:56:53 +00001594 }
1595
1596 bool shouldSpeculateFloat64Array()
1597 {
fpizlo@apple.com62336162012-06-07 01:35:59 +00001598 return isFloat64ArraySpeculation(prediction());
oliver@apple.comaeec3d82011-12-02 01:56:53 +00001599 }
1600
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001601 bool shouldSpeculateArrayOrOther()
1602 {
fpizlo@apple.com62336162012-06-07 01:35:59 +00001603 return isArrayOrOtherSpeculation(prediction());
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001604 }
1605
1606 bool shouldSpeculateObject()
1607 {
fpizlo@apple.com62336162012-06-07 01:35:59 +00001608 return isObjectSpeculation(prediction());
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001609 }
1610
fpizlo@apple.comb7ad4b42013-02-11 23:34:05 +00001611 bool shouldSpeculateObjectOrOther()
1612 {
1613 return isObjectOrOtherSpeculation(prediction());
1614 }
1615
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001616 bool shouldSpeculateCell()
1617 {
fpizlo@apple.com62336162012-06-07 01:35:59 +00001618 return isCellSpeculation(prediction());
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001619 }
1620
ggaren@apple.com0f001eb2013-04-24 15:48:55 +00001621 static bool shouldSpeculateBoolean(Node* op1, Node* op2)
1622 {
1623 return op1->shouldSpeculateBoolean() && op2->shouldSpeculateBoolean();
1624 }
1625
fpizlo@apple.comefacb612013-09-10 22:16:00 +00001626 static bool shouldSpeculateInt32(Node* op1, Node* op2)
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001627 {
fpizlo@apple.comefacb612013-09-10 22:16:00 +00001628 return op1->shouldSpeculateInt32() && op2->shouldSpeculateInt32();
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001629 }
1630
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001631 static bool shouldSpeculateInt32OrBoolean(Node* op1, Node* op2)
fpizlo@apple.com81f75372012-11-08 22:55:27 +00001632 {
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001633 return op1->shouldSpeculateInt32OrBoolean()
1634 && op2->shouldSpeculateInt32OrBoolean();
fpizlo@apple.com81f75372012-11-08 22:55:27 +00001635 }
1636
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001637 static bool shouldSpeculateInt32OrBooleanForArithmetic(Node* op1, Node* op2)
fpizlo@apple.com81f75372012-11-08 22:55:27 +00001638 {
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001639 return op1->shouldSpeculateInt32OrBooleanForArithmetic()
1640 && op2->shouldSpeculateInt32OrBooleanForArithmetic();
1641 }
1642
1643 static bool shouldSpeculateInt32OrBooleanExpectingDefined(Node* op1, Node* op2)
1644 {
1645 return op1->shouldSpeculateInt32OrBooleanExpectingDefined()
1646 && op2->shouldSpeculateInt32OrBooleanExpectingDefined();
fpizlo@apple.com81f75372012-11-08 22:55:27 +00001647 }
1648
fpizlo@apple.com3f780e42013-09-11 04:35:16 +00001649 static bool shouldSpeculateMachineInt(Node* op1, Node* op2)
1650 {
1651 return op1->shouldSpeculateMachineInt() && op2->shouldSpeculateMachineInt();
1652 }
1653
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001654 static bool shouldSpeculateNumber(Node* op1, Node* op2)
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001655 {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001656 return op1->shouldSpeculateNumber() && op2->shouldSpeculateNumber();
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001657 }
1658
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001659 static bool shouldSpeculateNumberOrBoolean(Node* op1, Node* op2)
fpizlo@apple.com81f75372012-11-08 22:55:27 +00001660 {
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001661 return op1->shouldSpeculateNumberOrBoolean()
1662 && op2->shouldSpeculateNumberOrBoolean();
1663 }
1664
1665 static bool shouldSpeculateNumberOrBooleanExpectingDefined(Node* op1, Node* op2)
1666 {
1667 return op1->shouldSpeculateNumberOrBooleanExpectingDefined()
1668 && op2->shouldSpeculateNumberOrBooleanExpectingDefined();
fpizlo@apple.com81f75372012-11-08 22:55:27 +00001669 }
1670
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001671 static bool shouldSpeculateFinalObject(Node* op1, Node* op2)
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001672 {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001673 return op1->shouldSpeculateFinalObject() && op2->shouldSpeculateFinalObject();
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001674 }
1675
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001676 static bool shouldSpeculateArray(Node* op1, Node* op2)
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001677 {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001678 return op1->shouldSpeculateArray() && op2->shouldSpeculateArray();
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001679 }
1680
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001681 bool canSpeculateInt32(RareCaseProfilingSource source)
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001682 {
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001683 return nodeCanSpeculateInt32(arithNodeFlags(), source);
fpizlo@apple.come40bc052011-10-06 23:39:03 +00001684 }
1685
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001686 bool canSpeculateInt52(RareCaseProfilingSource source)
fpizlo@apple.com3f780e42013-09-11 04:35:16 +00001687 {
fpizlo@apple.com96509b72014-05-26 17:43:41 +00001688 return nodeCanSpeculateInt52(arithNodeFlags(), source);
1689 }
1690
1691 RareCaseProfilingSource sourceFor(PredictionPass pass)
1692 {
1693 if (pass == PrimaryPass || child1()->sawBooleans() || (child2() && child2()->sawBooleans()))
1694 return DFGRareCase;
1695 return AllRareCases;
1696 }
1697
1698 bool canSpeculateInt32(PredictionPass pass)
1699 {
1700 return canSpeculateInt32(sourceFor(pass));
1701 }
1702
1703 bool canSpeculateInt52(PredictionPass pass)
1704 {
1705 return canSpeculateInt52(sourceFor(pass));
fpizlo@apple.com3f780e42013-09-11 04:35:16 +00001706 }
1707
fpizlo@apple.com8a8b45e2012-11-28 01:29:29 +00001708 void dumpChildren(PrintStream& out)
fpizlo@apple.comfab66052011-11-22 03:02:33 +00001709 {
fpizlo@apple.com1996b4b2012-02-06 06:44:24 +00001710 if (!child1())
fpizlo@apple.comfab66052011-11-22 03:02:33 +00001711 return;
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001712 out.printf("@%u", child1()->index());
fpizlo@apple.com1996b4b2012-02-06 06:44:24 +00001713 if (!child2())
fpizlo@apple.comfab66052011-11-22 03:02:33 +00001714 return;
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001715 out.printf(", @%u", child2()->index());
fpizlo@apple.com1996b4b2012-02-06 06:44:24 +00001716 if (!child3())
fpizlo@apple.comfab66052011-11-22 03:02:33 +00001717 return;
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001718 out.printf(", @%u", child3()->index());
fpizlo@apple.comfab66052011-11-22 03:02:33 +00001719 }
fpizlo@apple.comfab66052011-11-22 03:02:33 +00001720
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001721 // NB. This class must have a trivial destructor.
fpizlo@apple.com6793a322014-02-12 05:42:32 +00001722
1723 NodeOrigin origin;
1724
fpizlo@apple.com1996b4b2012-02-06 06:44:24 +00001725 // References to up to 3 children, or links to a variable length set of children.
fpizlo@apple.come5abbae2012-03-19 21:44:23 +00001726 AdjacencyList children;
barraclough@apple.com2302c042011-03-14 23:31:00 +00001727
1728private:
fpizlo@apple.com955073c2013-02-28 21:51:25 +00001729 unsigned m_op : 10; // real type is NodeType
1730 unsigned m_flags : 22;
barraclough@apple.comde174fb2011-04-22 20:38:27 +00001731 // The virtual register number (spill location) associated with this .
1732 VirtualRegister m_virtualRegister;
1733 // The number of uses of the result of this operation (+1 for 'must generate' nodes, which have side-effects).
1734 unsigned m_refCount;
oliver@apple.comd83bc442013-07-25 04:04:21 +00001735 // The prediction ascribed to this node after propagation.
1736 SpeculatedType m_prediction;
fpizlo@apple.comffb7d5e2011-09-20 09:41:16 +00001737 // Immediate values, accesses type-checked via accessors above. The first one is
1738 // big enough to store a pointer.
1739 uintptr_t m_opInfo;
oliver@apple.comd83bc442013-07-25 04:04:21 +00001740 uintptr_t m_opInfo2;
fpizlo@apple.comf8f33842013-01-14 06:58:57 +00001741
1742public:
1743 // Fields used by various analyses.
1744 AbstractValue value;
oliver@apple.com78a7c622013-07-25 04:05:26 +00001745
1746 // Miscellaneous data that is usually meaningless, but can hold some analysis results
1747 // if you ask right. For example, if you do Graph::initializeNodeOwners(), misc.owner
1748 // will tell you which basic block a node belongs to. You cannot rely on this persisting
1749 // across transformations unless you do the maintenance work yourself. Other phases use
1750 // misc.replacement, but they do so manually: first you do Graph::clearReplacements()
1751 // and then you set, and use, replacement's yourself.
1752 //
1753 // Bottom line: don't use these fields unless you initialize them yourself, or by
1754 // calling some appropriate methods that initialize them the way you want. Otherwise,
1755 // these fields are meaningless.
oliver@apple.com6c816f42013-07-25 04:04:53 +00001756 union {
1757 Node* replacement;
oliver@apple.com78a7c622013-07-25 04:05:26 +00001758 BasicBlock* owner;
oliver@apple.com6c816f42013-07-25 04:04:53 +00001759 } misc;
barraclough@apple.com2302c042011-03-14 23:31:00 +00001760};
1761
oliver@apple.com827d2cf2013-07-25 04:04:45 +00001762inline bool nodeComparator(Node* a, Node* b)
1763{
1764 return a->index() < b->index();
1765}
1766
1767template<typename T>
1768CString nodeListDump(const T& nodeList)
1769{
1770 return sortedListDump(nodeList, nodeComparator);
1771}
1772
1773template<typename T>
oliver@apple.com237b1462013-07-25 04:05:36 +00001774CString nodeMapDump(const T& nodeMap, DumpContext* context = 0)
oliver@apple.com827d2cf2013-07-25 04:04:45 +00001775{
oliver@apple.com237b1462013-07-25 04:05:36 +00001776 Vector<typename T::KeyType> keys;
1777 for (
1778 typename T::const_iterator iter = nodeMap.begin();
1779 iter != nodeMap.end(); ++iter)
1780 keys.append(iter->key);
1781 std::sort(keys.begin(), keys.end(), nodeComparator);
1782 StringPrintStream out;
1783 CommaPrinter comma;
1784 for(unsigned i = 0; i < keys.size(); ++i)
1785 out.print(comma, keys[i], "=>", inContext(nodeMap.get(keys[i]), context));
1786 return out.toCString();
oliver@apple.com827d2cf2013-07-25 04:04:45 +00001787}
1788
barraclough@apple.com2302c042011-03-14 23:31:00 +00001789} } // namespace JSC::DFG
1790
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001791namespace WTF {
1792
oliver@apple.com39478942013-07-25 04:03:18 +00001793void printInternal(PrintStream&, JSC::DFG::SwitchKind);
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001794void printInternal(PrintStream&, JSC::DFG::Node*);
1795
oliver@apple.com237b1462013-07-25 04:05:36 +00001796inline JSC::DFG::Node* inContext(JSC::DFG::Node* node, JSC::DumpContext*) { return node; }
1797
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001798} // namespace WTF
1799
oliver@apple.com237b1462013-07-25 04:05:36 +00001800using WTF::inContext;
1801
barraclough@apple.com2302c042011-03-14 23:31:00 +00001802#endif
1803#endif