13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifndef V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_
6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_
7b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <cstring>
9958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include <iosfwd>
10958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/allocation.h"
12f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/ast/ast.h"
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/bits.h"
14958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/bit-vector.h"
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/conversions.h"
16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-types.h"
17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/unique.h"
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/deoptimizer.h"
19f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/globals.h"
20c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/interface-descriptors.h"
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/small-pointer-list.h"
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/utils.h"
23f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/zone/zone.h"
24b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
25b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace v8 {
26b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace internal {
27b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
28b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Forward declarations.
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct ChangesOf;
30b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HBasicBlock;
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HDiv;
32b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HEnvironment;
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HInferRepresentationPhase;
34b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HInstruction;
35b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HLoopInformation;
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HStoreNamedField;
37b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HValue;
38b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass LInstruction;
39b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass LChunkBuilder;
40f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochclass SmallMapList;
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ArithmeticBinaryOperation)                \
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(BinaryOperation)                          \
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(BitwiseBinaryOperation)                   \
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ControlInstruction)                       \
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Instruction)
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(AbnormalExit)                             \
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(AccessArgumentsAt)                        \
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Add)                                      \
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Allocate)                                 \
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ApplyArguments)                           \
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ArgumentsElements)                        \
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ArgumentsLength)                          \
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ArgumentsObject)                          \
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Bitwise)                                  \
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(BlockEntry)                               \
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(BoundsCheck)                              \
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Branch)                                   \
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(CallWithDescriptor)                       \
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(CallNewArray)                             \
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(CallRuntime)                              \
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(CapturedObject)                           \
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Change)                                   \
68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(CheckArrayBufferNotNeutered)              \
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(CheckHeapObject)                          \
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(CheckInstanceType)                        \
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(CheckMaps)                                \
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(CheckMapValue)                            \
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(CheckSmi)                                 \
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(CheckValue)                               \
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ClampToUint8)                             \
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ClassOfTestAndBranch)                     \
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(CompareNumericAndBranch)                  \
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(CompareHoleAndBranch)                     \
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(CompareGeneric)                           \
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(CompareObjectEqAndBranch)                 \
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(CompareMap)                               \
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Constant)                                 \
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Context)                                  \
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(DebugBreak)                               \
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(DeclareGlobals)                           \
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Deoptimize)                               \
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Div)                                      \
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(DummyUse)                                 \
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(EnterInlined)                             \
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(EnvironmentMarker)                        \
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ForceRepresentation)                      \
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ForInCacheArray)                          \
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ForInPrepareMap)                          \
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Goto)                                     \
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(HasInstanceTypeAndBranch)                 \
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(InnerAllocatedObject)                     \
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(InvokeFunction)                           \
98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(HasInPrototypeChainAndBranch)             \
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(IsStringAndBranch)                        \
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(IsSmiAndBranch)                           \
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(IsUndetectableAndBranch)                  \
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(LeaveInlined)                             \
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(LoadContextSlot)                          \
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(LoadFieldByIndex)                         \
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(LoadFunctionPrototype)                    \
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(LoadKeyed)                                \
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(LoadNamedField)                           \
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(LoadRoot)                                 \
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(MathFloorOfDiv)                           \
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(MathMinMax)                               \
111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(MaybeGrowElements)                        \
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Mod)                                      \
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Mul)                                      \
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(OsrEntry)                                 \
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Parameter)                                \
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Power)                                    \
117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(Prologue)                                 \
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(PushArguments)                            \
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Return)                                   \
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Ror)                                      \
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Sar)                                      \
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(SeqStringGetChar)                         \
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(SeqStringSetChar)                         \
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Shl)                                      \
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Shr)                                      \
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Simulate)                                 \
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(StackCheck)                               \
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(StoreCodeEntry)                           \
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(StoreContextSlot)                         \
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(StoreKeyed)                               \
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(StoreNamedField)                          \
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(StringAdd)                                \
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(StringCharCodeAt)                         \
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(StringCharFromCode)                       \
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(StringCompareAndBranch)                   \
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Sub)                                      \
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ThisFunction)                             \
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(TransitionElementsKind)                   \
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(TrapAllocationMemento)                    \
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Typeof)                                   \
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(TypeofIsAndBranch)                        \
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(UnaryMathOperation)                       \
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(UnknownOSRValue)                          \
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(UseConst)                                 \
1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(WrapReceiver)
146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define GVN_TRACKED_FLAG_LIST(V)               \
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(NewSpacePromotion)
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define GVN_UNTRACKED_FLAG_LIST(V)             \
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ArrayElements)                             \
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ArrayLengths)                              \
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(StringLengths)                             \
154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(BackingStoreFields)                        \
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Calls)                                     \
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ContextSlots)                              \
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(DoubleArrayElements)                       \
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(DoubleFields)                              \
1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(ElementsKind)                              \
1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(ElementsPointer)                           \
161b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(GlobalVars)                                \
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(InobjectFields)                            \
163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(Maps)                                      \
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(OsrEntries)                                \
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ExternalMemory)                            \
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(StringChars)                               \
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(TypedArrayElements)
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define DECLARE_ABSTRACT_INSTRUCTION(type)     \
171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool Is##type() const final { return true; } \
172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static H##type* cast(HValue* value) {        \
173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(value->Is##type());                 \
174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return reinterpret_cast<H##type*>(value);  \
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
176b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define DECLARE_CONCRETE_INSTRUCTION(type)                      \
179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LInstruction* CompileToLithium(LChunkBuilder* builder) final; \
180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static H##type* cast(HValue* value) {                         \
181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(value->Is##type());                                  \
182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return reinterpret_cast<H##type*>(value);                   \
183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }                                                             \
184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Opcode opcode() const final { return HValue::k##type; }
185b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
186b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum PropertyAccessType { LOAD, STORE };
188b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
189c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochRepresentation RepresentationFromMachineType(MachineType type);
190b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Range final : public ZoneObject {
192b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
193e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  Range()
194e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      : lower_(kMinInt),
195e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch        upper_(kMaxInt),
196e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch        next_(NULL),
197e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch        can_be_minus_zero_(false) { }
198b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
199b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Range(int32_t lower, int32_t upper)
200e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      : lower_(lower),
201e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch        upper_(upper),
202e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch        next_(NULL),
203e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch        can_be_minus_zero_(false) { }
204b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
205b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int32_t upper() const { return upper_; }
206b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int32_t lower() const { return lower_; }
207b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Range* next() const { return next_; }
2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Range* CopyClearLower(Zone* zone) const {
2093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return new(zone) Range(kMinInt, upper_);
2103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Range* CopyClearUpper(Zone* zone) const {
2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return new(zone) Range(lower_, kMaxInt);
2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Range* Copy(Zone* zone) const {
2153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Range* result = new(zone) Range(lower_, upper_);
21669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    result->set_can_be_minus_zero(CanBeMinusZero());
21769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    return result;
21869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  }
219b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int32_t Mask() const;
220b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
222b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
223b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool CanBeNegative() const { return lower_ < 0; }
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool CanBePositive() const { return upper_ > 0; }
225e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
22669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  bool IsMostGeneric() const {
22769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    return lower_ == kMinInt && upper_ == kMaxInt && CanBeMinusZero();
22869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  }
229e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  bool IsInSmiRange() const {
230e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ClampToSmi() {
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    lower_ = Max(lower_, Smi::kMinValue);
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    upper_ = Min(upper_, Smi::kMaxValue);
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
236f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void Clear();
237e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void KeepOrder();
2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG
239e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void Verify() const;
2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
241b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
242b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void StackUpon(Range* other) {
243b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Intersect(other);
244b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    next_ = other;
245b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
247e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void Intersect(Range* other);
248e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void Union(Range* other);
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CombinedMax(Range* other);
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CombinedMin(Range* other);
251b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
252e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void AddConstant(int32_t value);
253e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void Sar(int32_t value);
254e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void Shl(int32_t value);
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool AddAndCheckOverflow(const Representation& r, Range* other);
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool SubAndCheckOverflow(const Representation& r, Range* other);
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool MulAndCheckOverflow(const Representation& r, Range* other);
258b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
259b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
260b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int32_t lower_;
261b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int32_t upper_;
262b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Range* next_;
263b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool can_be_minus_zero_;
264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
265b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
267257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass HUseListNode: public ZoneObject {
268257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
269257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HUseListNode(HValue* value, int index, HUseListNode* tail)
270257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      : tail_(tail), value_(value), index_(index) {
271257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
272257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HUseListNode* tail();
274257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HValue* value() const { return value_; }
275257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int index() const { return index_; }
276257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
277257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void set_tail(HUseListNode* list) { tail_ = list; }
278257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
279257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef DEBUG
280257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void Zap() {
281257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    tail_ = reinterpret_cast<HUseListNode*>(1);
282257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    value_ = NULL;
283257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    index_ = -1;
284257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
285257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif
286257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
287257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private:
288257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HUseListNode* tail_;
289257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HValue* value_;
290257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int index_;
291257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
292257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
293257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
294257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// We reuse use list nodes behind the scenes as uses are added and deleted.
295257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// This class is the safe way to iterate uses while deleting them.
296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HUseIterator final BASE_EMBEDDED {
297257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
298257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool Done() { return current_ == NULL; }
299257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void Advance();
300257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
301257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HValue* value() {
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!Done());
303257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return value_;
304257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
305257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
306257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int index() {
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!Done());
308257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return index_;
309257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
310257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
311257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private:
312257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  explicit HUseIterator(HUseListNode* head);
313257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
314257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HUseListNode* current_;
315257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HUseListNode* next_;
316257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HValue* value_;
317257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int index_;
318257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
319257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  friend class HValue;
320257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
321257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
322257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// All tracked flags should appear before untracked ones.
3243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochenum GVNFlag {
3253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Declare global value numbering flags.
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DECLARE_FLAG(Type) k##Type,
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GVN_TRACKED_FLAG_LIST(DECLARE_FLAG)
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
3293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#undef DECLARE_FLAG
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define COUNT_FLAG(Type) + 1
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG),
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  kNumberOfUntrackedSideEffects = 0 GVN_UNTRACKED_FLAG_LIST(COUNT_FLAG),
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef COUNT_FLAG
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  kNumberOfFlags = kNumberOfTrackedSideEffects + kNumberOfUntrackedSideEffects
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline GVNFlag GVNFlagFromInt(int i) {
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(i >= 0);
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(i < kNumberOfFlags);
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return static_cast<GVNFlag>(i);
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass DecompositionResult final BASE_EMBEDDED {
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DecompositionResult() : base_(NULL), offset_(0), scale_(0) {}
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* base() { return base_; }
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int offset() { return offset_; }
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int scale() { return scale_; }
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool Apply(HValue* other_base, int other_offset, int other_scale = 0) {
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (base_ == NULL) {
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      base_ = other_base;
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      offset_ = other_offset;
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      scale_ = other_scale;
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return true;
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (scale_ == 0) {
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        base_ = other_base;
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        offset_ += other_offset;
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        scale_ = other_scale;
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return true;
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return false;
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SwapValues(HValue** other_base, int* other_offset, int* other_scale) {
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    swap(&base_, other_base);
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    swap(&offset_, other_offset);
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    swap(&scale_, other_scale);
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template <class T> void swap(T* a, T* b) {
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    T c(*a);
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *a = *b;
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *b = c;
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* base_;
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int offset_;
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int scale_;
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef EnumSet<GVNFlag, int32_t> GVNFlagSet;
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HValue : public ZoneObject {
394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kNoNumber = -1;
396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  enum Flag {
398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    kFlexibleRepresentation,
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kCannotBeTagged,
4003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // Participate in Global Value Numbering, i.e. elimination of
4013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // unnecessary recomputations. If an instruction sets this flag, it must
4023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // implement DataEquals(), which will be used to determine if other
4033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // occurrences of the instruction are indeed the same.
404b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    kUseGVN,
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Track instructions that are dominating side effects. If an instruction
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // sets this flag, it must implement HandleSideEffectDominator() and should
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // indicate which side effects to track by setting GVN flags.
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kTrackSideEffectDominators,
409b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    kCanOverflow,
410b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    kBailoutOnMinusZero,
411b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    kCanBeDivByZero,
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kLeftCanBeMinInt,
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kLeftCanBeNegative,
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kLeftCanBePositive,
415c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    kTruncatingToNumber,
416b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    kIsArguments,
417b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    kTruncatingToInt32,
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kAllUsesTruncatingToInt32,
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kTruncatingToSmi,
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kAllUsesTruncatingToSmi,
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Set after an instruction is killed.
4223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kIsDead,
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Instructions that are allowed to produce full range unsigned integer
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // values are marked with kUint32 flag. If arithmetic shift or a load from
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // EXTERNAL_UINT32_ELEMENTS array is not marked with this flag
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // it will deoptimize if result does not fit into signed integer range.
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // HGraph::ComputeSafeUint32Operations is responsible for setting this
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // flag.
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kUint32,
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kHasNoObservableSideEffects,
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Indicates an instruction shouldn't be replaced by optimization, this flag
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // is useful to set in cases where recomputing a value is cheaper than
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // extending the value's live range and spilling it.
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kCantBeReplaced,
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Indicates the instruction is live during dead code elimination.
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kIsLive,
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // HEnvironmentMarkers are deleted before dead code
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // elimination takes place, so they can repurpose the kIsLive flag:
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kEndsLiveRange = kIsLive,
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(everyone): Don't forget to update this!
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kLastFlag = kIsLive
444b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  };
445b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
446b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  STATIC_ASSERT(kLastFlag < kBitsPerInt);
447b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
448b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static HValue* cast(HValue* value) { return value; }
449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  enum Opcode {
451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Declare a unique enum value for each hydrogen instruction.
452257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  #define DECLARE_OPCODE(type) k##type,
453257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
454257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    kPhi
455257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  #undef DECLARE_OPCODE
456b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  };
457257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  virtual Opcode opcode() const = 0;
458257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
459257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Declare a non-virtual predicates for each concrete HInstruction or HValue.
460257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  #define DECLARE_PREDICATE(type) \
461257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    bool Is##type() const { return opcode() == k##type; }
462257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
463257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  #undef DECLARE_PREDICATE
464257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    bool IsPhi() const { return opcode() == kPhi; }
465257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
466257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Declare virtual predicates for abstract HInstruction or HValue
467257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  #define DECLARE_PREDICATE(type) \
468257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    virtual bool Is##type() const { return false; }
469257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
470257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  #undef DECLARE_PREDICATE
471b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsBitwiseBinaryShift() {
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return IsShl() || IsShr() || IsSar();
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HValue(HType type = HType::Tagged())
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : block_(NULL),
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        id_(kNoNumber),
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        type_(type),
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        use_list_(NULL),
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        range_(NULL),
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        range_poisoned_(false),
484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        flags_(0) {}
486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual ~HValue() {}
487b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  virtual SourcePosition position() const { return SourcePosition::Unknown(); }
489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
490b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* block() const { return block_; }
491b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SetBlock(HBasicBlock* block);
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Note: Never call this method for an unlinked value.
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate() const;
495b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
496b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int id() const { return id_; }
497b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void set_id(int id) { id_ = id; }
498b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
499257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HUseIterator uses() const { return HUseIterator(use_list_); }
500b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
50144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  virtual bool EmitAtUses() { return false; }
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
503b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Representation representation() const { return representation_; }
504b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void ChangeRepresentation(Representation r) {
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(CheckFlag(kFlexibleRepresentation));
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!CheckFlag(kCannotBeTagged) || !r.IsTagged());
507b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    RepresentationChanged(r);
508b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    representation_ = r;
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (r.IsTagged()) {
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Tagged is the bottom of the lattice, don't go any further.
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ClearFlag(kFlexibleRepresentation);
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
513b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual void AssumeRepresentation(Representation r);
515257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual Representation KnownOptimalRepresentation() {
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Representation r = representation();
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (r.IsTagged()) {
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HType t = type();
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (t.IsSmi()) return Representation::Smi();
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (t.IsHeapNumber()) return Representation::Double();
522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (t.IsHeapObject()) return r;
523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return Representation::None();
524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return r;
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
527b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HType type() const { return type_; }
52969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  void set_type(HType new_type) {
530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(new_type.IsSubtypeOf(type_));
53169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    type_ = new_type;
532b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
533b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // There are HInstructions that do not really change a value, they
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // only add pieces of information to it (like bounds checks, map checks,
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // smi checks...).
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We call these instructions "informative definitions", or "iDef".
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // One of the iDef operands is special because it is the value that is
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // "transferred" to the output, we call it the "redefined operand".
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If an HValue is an iDef it must override RedefinedOperandIndex() so that
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // it does not return kNoRedefinedOperand;
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kNoRedefinedOperand = -1;
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual int RedefinedOperandIndex() { return kNoRedefinedOperand; }
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsInformativeDefinition() {
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return RedefinedOperandIndex() != kNoRedefinedOperand;
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* RedefinedOperand() {
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int index = RedefinedOperandIndex();
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return index == kNoRedefinedOperand ? NULL : OperandAt(index);
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool CanReplaceWithDummyUses();
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual int argument_delta() const { return 0; }
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A purely informative definition is an idef that will not emit code and
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // should therefore be removed from the graph in the RestoreActualValues
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // phase (so that live ranges will be shorter).
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual bool IsPurelyInformativeDefinition() { return false; }
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This method must always return the original HValue SSA definition,
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // regardless of any chain of iDefs of this value.
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* ActualValue() {
564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HValue* value = this;
565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int index;
566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    while ((index = value->RedefinedOperandIndex()) != kNoRedefinedOperand) {
567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      value = value->OperandAt(index);
568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return value;
570b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
571b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsInteger32Constant();
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t GetInteger32Constant();
574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool EqualsInteger32Constant(int32_t value);
575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
576b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool IsDefinedAfter(HBasicBlock* other) const;
577b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
578b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Operands.
579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual int OperandCount() const = 0;
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual HValue* OperandAt(int index) const = 0;
581b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SetOperandAt(int index, HValue* value);
582b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
583257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void DeleteAndReplaceWith(HValue* other);
584257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void ReplaceAllUsesWith(HValue* other);
585257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool HasNoUses() const { return use_list_ == NULL; }
586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasOneUse() const {
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return use_list_ != NULL && use_list_->tail() == NULL;
588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
589257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool HasMultipleUses() const {
590257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return use_list_ != NULL && use_list_->tail() != NULL;
591257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
592257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int UseCount() const;
5933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Mark this HValue as dead and to be removed from other HValues' use lists.
5953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void Kill();
596b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
597b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int flags() const { return flags_; }
5981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void SetFlag(Flag f) { flags_ |= (1 << f); }
5991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
6001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CopyFlag(Flag f, HValue* other) {
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (other->CheckFlag(f)) SetFlag(f);
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Returns true if the flag specified is set for all uses, false otherwise.
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool CheckUsesForFlag(Flag f) const;
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Same as before and the first one without the flag is returned in value.
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool CheckUsesForFlag(Flag f, HValue** value) const;
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Returns true if the flag specified is set for all uses, and this set
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // of uses is non-empty.
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasAtLeastOneUseWithFlagAndNoneWithout(Flag f) const;
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GVNFlagSet ChangesFlags() const { return changes_flags_; }
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GVNFlagSet DependsOnFlags() const { return depends_on_flags_; }
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SetChangesFlag(GVNFlag f) { changes_flags_.Add(f); }
616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SetDependsOnFlag(GVNFlag f) { depends_on_flags_.Add(f); }
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ClearChangesFlag(GVNFlag f) { changes_flags_.Remove(f); }
618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ClearDependsOnFlag(GVNFlag f) { depends_on_flags_.Remove(f); }
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool CheckChangesFlag(GVNFlag f) const {
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return changes_flags_.Contains(f);
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool CheckDependsOnFlag(GVNFlag f) const {
623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return depends_on_flags_.Contains(f);
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SetAllSideEffects() { changes_flags_.Add(AllSideEffectsFlagSet()); }
6263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void ClearAllSideEffects() {
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    changes_flags_.Remove(AllSideEffectsFlagSet());
6283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
6293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool HasSideEffects() const {
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return changes_flags_.ContainsAnyOf(AllSideEffectsFlagSet());
6313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
6323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool HasObservableSideEffects() const {
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return !CheckFlag(kHasNoObservableSideEffects) &&
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        changes_flags_.ContainsAnyOf(AllObservableSideEffectsFlagSet());
6353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
6363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GVNFlagSet SideEffectFlags() const {
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GVNFlagSet result = ChangesFlags();
6393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    result.Intersect(AllSideEffectsFlagSet());
6403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return result;
6413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
6423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GVNFlagSet ObservableChangesFlags() const {
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GVNFlagSet result = ChangesFlags();
6453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    result.Intersect(AllObservableSideEffectsFlagSet());
6463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return result;
6473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
648589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Range* range() const {
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!range_poisoned_);
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return range_;
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasRange() const {
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!range_poisoned_);
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return range_ != NULL;
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void PoisonRange() { range_poisoned_ = true; }
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
6603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void AddNewRange(Range* r, Zone* zone);
661b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void RemoveLastAddedRange();
6623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void ComputeInitialRange(Zone* zone);
663b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Escape analysis helpers.
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual bool HasEscapingOperandAt(int index) { return true; }
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual bool HasOutOfBoundsAccess(int size) { return false; }
667e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Representation helpers.
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual Representation observed_input_representation(int index) {
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Representation::None();
671b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual Representation RequiredInputRepresentation(int index) = 0;
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual void InferRepresentation(HInferRepresentationPhase* h_infer);
674b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
675b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // This gives the instruction an opportunity to replace itself with an
676b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // instruction that does the same in some better way.  To replace an
677b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // instruction with a new one, first add the new instruction to the graph,
678b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // then return it.  Return NULL to have the instruction deleted.
679b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual HValue* Canonicalize() { return this; }
680b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
681e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  bool Equals(HValue* other);
682e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  virtual intptr_t Hashcode();
683b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute unique ids upfront that is safe wrt GC and concurrent compilation.
685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual void FinalizeUniqueness() { }
686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
687b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Printing support.
688958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  virtual std::ostream& PrintTo(std::ostream& os) const = 0;  // NOLINT
689b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
690257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  const char* Mnemonic() const;
691b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Type information helpers.
693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasMonomorphicJSObjectType();
694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(mstarzinger): For now instructions can override this function to
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // specify statically known types, once HType can convey more information
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // it should be based on the HType.
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual Handle<Map> GetMonomorphicJSObjectMap() { return Handle<Map>(); }
699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
700b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Updated the inferred type of this instruction and returns true if
701b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // it has changed.
702b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool UpdateInferredType();
703b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
704e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  virtual HType CalculateInferredType();
705b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This function must be overridden for instructions which have the
707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // kTrackSideEffectDominators flag set, to track instructions that are
708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // dominating side effects.
709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // It returns true if it removed an instruction which had side effects.
710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual bool HandleSideEffectDominator(GVNFlag side_effect,
711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         HValue* dominator) {
712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UNREACHABLE();
713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check if this instruction has some reason that prevents elimination.
717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool CannotBeEliminated() const {
718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HasObservableSideEffects() || !IsDeletable();
719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
721b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG
7221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  virtual void Verify() = 0;
723b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
724b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Returns true conservatively if the program might be able to observe a
726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ToString() operation on this value.
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool ToStringCanBeObserved() const {
728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return ToStringOrToNumberCanBeObserved();
729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Returns true conservatively if the program might be able to observe a
732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ToNumber() operation on this value.
733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool ToNumberCanBeObserved() const {
734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return ToStringOrToNumberCanBeObserved();
735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MinusZeroMode GetMinusZeroMode() {
738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return CheckFlag(kBailoutOnMinusZero)
739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ? FAIL_ON_MINUS_ZERO : TREAT_MINUS_ZERO_AS_ZERO;
740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
742b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected:
7431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // This function must be overridden for instructions with flag kUseGVN, to
7441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // compare the non-Operand parts of the instruction.
745e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  virtual bool DataEquals(HValue* other) {
7461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    UNREACHABLE();
7471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return false;
7481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool ToStringOrToNumberCanBeObserved() const {
751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (type().IsTaggedPrimitive()) return false;
752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (type().IsJSReceiver()) return true;
753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return !representation().IsSmiOrInteger32() && !representation().IsDouble();
754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual Representation RepresentationFromInputs() {
757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return representation();
758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual Representation RepresentationFromUses();
760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Representation RepresentationFromUseRequirements();
761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasNonSmiUse();
762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual void UpdateRepresentation(Representation new_rep,
763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    HInferRepresentationPhase* h_infer,
764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    const char* reason);
765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddDependantsToWorklist(HInferRepresentationPhase* h_infer);
766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
767b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual void RepresentationChanged(Representation to) { }
768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  virtual Range* InferRange(Zone* zone);
770b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual void DeleteFromGraph() = 0;
771e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  virtual void InternalSetOperandAt(int index, HValue* value) = 0;
772b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void clear_block() {
773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(block_ != NULL);
774b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    block_ = NULL;
775b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
776b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
777b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void set_representation(Representation r) {
778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(representation_.IsNone() && !r.IsNone());
779b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    representation_ = r;
780b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
781b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static GVNFlagSet AllFlagSet() {
7833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    GVNFlagSet result;
784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ADD_FLAG(Type) result.Add(k##Type);
785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GVN_TRACKED_FLAG_LIST(ADD_FLAG)
786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
787589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#undef ADD_FLAG
788589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return result;
789589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
790589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
7911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // A flag mask to mark an instruction as having arbitrary side effects.
7923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static GVNFlagSet AllSideEffectsFlagSet() {
793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GVNFlagSet result = AllFlagSet();
794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result.Remove(kOsrEntries);
7953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return result;
7963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
797958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  friend std::ostream& operator<<(std::ostream& os, const ChangesOf& v);
7983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // A flag mask of all side effects that can make observable changes in
8003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // an executing program (i.e. are not safe to repeat, move or remove);
8013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static GVNFlagSet AllObservableSideEffectsFlagSet() {
802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GVNFlagSet result = AllFlagSet();
803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result.Remove(kNewSpacePromotion);
804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result.Remove(kElementsKind);
805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result.Remove(kElementsPointer);
806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result.Remove(kMaps);
8073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return result;
808592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch  }
809592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
810257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Remove the matching use from the use list if present.  Returns the
811257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // removed list node or NULL.
812257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HUseListNode* RemoveUse(HValue* value, int index);
813257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
814b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void RegisterUse(int index, HValue* new_value);
815b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
816b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* block_;
817b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
818b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // The id of this instruction in the hydrogen graph, assigned when first
819b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // added to the graph. Reflects creation order.
820b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int id_;
821b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
822b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Representation representation_;
823b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HType type_;
824257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HUseListNode* use_list_;
825b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Range* range_;
826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool range_poisoned_;
828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
829b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int flags_;
830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GVNFlagSet changes_flags_;
831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GVNFlagSet depends_on_flags_;
832b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
8333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual bool IsDeletable() const { return false; }
835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
836b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(HValue);
837b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
838b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Support for printing various aspects of an HValue.
840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct NameOf {
841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit NameOf(const HValue* const v) : value(v) {}
842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const HValue* value;
843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
844b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
845b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct TypeOf {
847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit TypeOf(const HValue* const v) : value(v) {}
848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const HValue* value;
849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
850b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
851b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct ChangesOf {
853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit ChangesOf(const HValue* const v) : value(v) {}
854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const HValue* value;
855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
856b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
8573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
858958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream& os, const HValue& v);
859958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream& os, const NameOf& v);
860958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream& os, const TypeOf& v);
861958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream& os, const ChangesOf& v);
862b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
863b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_INSTRUCTION_FACTORY_P0(I)                        \
865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static I* New(Isolate* isolate, Zone* zone, HValue* context) { \
866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return new (zone) I();                                       \
867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
868e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_INSTRUCTION_FACTORY_P1(I, P1)                           \
870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1) { \
871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return new (zone) I(p1);                                            \
872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
873b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DECLARE_INSTRUCTION_FACTORY_P2(I, P1, P2)                              \
875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2) { \
876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return new (zone) I(p1, p2);                                               \
877b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
878b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_INSTRUCTION_FACTORY_P3(I, P1, P2, P3)                        \
880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2, \
881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                P3 p3) {                                                     \
882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return new (zone) I(p1, p2, p3);                                         \
883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
884b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_INSTRUCTION_FACTORY_P4(I, P1, P2, P3, P4)                    \
886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2, \
887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                P3 p3, P4 p4) {                                              \
888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return new (zone) I(p1, p2, p3, p4);                                     \
889b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
890b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_INSTRUCTION_FACTORY_P5(I, P1, P2, P3, P4, P5)                \
892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2, \
893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                P3 p3, P4 p4, P5 p5) {                                       \
894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return new (zone) I(p1, p2, p3, p4, p5);                                 \
895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
896257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_INSTRUCTION_FACTORY_P6(I, P1, P2, P3, P4, P5, P6)            \
898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2, \
899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                P3 p3, P4 p4, P5 p5, P6 p6) {                                \
900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return new (zone) I(p1, p2, p3, p4, p5, p6);                             \
901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
902b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_INSTRUCTION_FACTORY_P7(I, P1, P2, P3, P4, P5, P6, P7)        \
904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2, \
905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {                         \
906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return new (zone) I(p1, p2, p3, p4, p5, p6, p7);                         \
907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
908b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P0(I)           \
910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static I* New(Isolate* isolate, Zone* zone, HValue* context) { \
911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return new (zone) I(context);                                \
912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(I, P1)              \
915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1) { \
916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return new (zone) I(context, p1);                                   \
917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
918b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(I, P1, P2)                 \
920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2) { \
921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return new (zone) I(context, p1, p2);                                      \
922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(I, P1, P2, P3)           \
925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2, \
926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                P3 p3) {                                                     \
927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return new (zone) I(context, p1, p2, p3);                                \
928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
929b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(I, P1, P2, P3, P4)       \
931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2, \
932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                P3 p3, P4 p4) {                                              \
933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return new (zone) I(context, p1, p2, p3, p4);                            \
934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
9351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P5(I, P1, P2, P3, P4, P5)   \
937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2, \
938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                P3 p3, P4 p4, P5 p5) {                                       \
939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return new (zone) I(context, p1, p2, p3, p4, p5);                        \
940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
941b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P6(I, P1, P2, P3, P4, P5, P6) \
943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2,   \
944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                P3 p3, P4 p4, P5 p5, P6 p6) {                                  \
945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return new (zone) I(context, p1, p2, p3, p4, p5, p6);                      \
946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
947b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HInstruction : public HValue {
949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* next() const { return next_; }
951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* previous() const { return previous_; }
952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintTo(std::ostream& os) const override;          // NOLINT
954958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  virtual std::ostream& PrintDataTo(std::ostream& os) const;       // NOLINT
955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsLinked() const { return block() != NULL; }
957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Unlink();
958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void InsertBefore(HInstruction* next);
960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class T> T* Prepend(T* instr) {
962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr->InsertBefore(this);
963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return instr;
964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void InsertAfter(HInstruction* previous);
967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class T> T* Append(T* instr) {
969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr->InsertAfter(this);
970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return instr;
971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The position is a write-once variable.
974c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  SourcePosition position() const override { return position_; }
975c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  bool has_position() const { return position_.IsKnown(); }
976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_position(SourcePosition position) {
977c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    DCHECK(position.IsKnown());
978c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    position_ = position;
979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool Dominates(HInstruction* other);
982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool CanTruncateToSmi() const { return CheckFlag(kTruncatingToSmi); }
983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
984c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  bool CanTruncateToNumber() const { return CheckFlag(kTruncatingToNumber); }
985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Verify() override;
990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool CanDeoptimize();
993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual bool HasStackCheck() { return false; }
995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_ABSTRACT_INSTRUCTION(Instruction)
997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HInstruction(HType type = HType::Tagged())
1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HValue(type),
1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        next_(NULL),
1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        previous_(NULL),
1003c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        position_(SourcePosition::Unknown()) {
1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetDependsOnFlag(kOsrEntries);
1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void DeleteFromGraph() override { Unlink(); }
1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void InitializeAsFirst(HBasicBlock* block) {
1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!IsLinked());
1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetBlock(block);
1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* next_;
1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* previous_;
1017c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  SourcePosition position_;
1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class HBasicBlock;
1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<int V>
1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HTemplateInstruction : public HInstruction {
1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
1026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int OperandCount() const final { return V; }
1027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* OperandAt(int i) const final { return inputs_[i]; }
1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HTemplateInstruction(HType type = HType::Tagged())
1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HInstruction(type) {}
1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void InternalSetOperandAt(int i, HValue* value) final { inputs_[i] = value; }
1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EmbeddedContainer<HValue*, V> inputs_;
1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HControlInstruction : public HInstruction {
1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual HBasicBlock* SuccessorAt(int i) const = 0;
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual int SuccessorCount() const = 0;
1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0;
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual bool KnownSuccessorBlock(HBasicBlock** block) {
1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *block = NULL;
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBasicBlock* FirstSuccessor() {
1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBasicBlock* SecondSuccessor() {
1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Not() {
1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBasicBlock* swap = SuccessorAt(0);
1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetSuccessorAt(0, SuccessorAt(1));
1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetSuccessorAt(1, swap);
1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HSuccessorIterator final BASE_EMBEDDED {
1071e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public:
1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HSuccessorIterator(const HControlInstruction* instr)
1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : instr_(instr), current_(0) {}
1074e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
10753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool Done() { return current_ >= instr_->SuccessorCount(); }
10763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
10773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void Advance() { current_++; }
1078e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1079e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch private:
1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const HControlInstruction* instr_;
10813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  int current_;
1082e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch};
1083e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1084e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
10853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate<int S, int V>
1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HTemplateControlInstruction : public HControlInstruction {
1087e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public:
1088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int SuccessorCount() const override { return S; }
1089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HBasicBlock* SuccessorAt(int i) const override { return successors_[i]; }
1090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void SetSuccessorAt(int i, HBasicBlock* block) override {
1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    successors_[i] = block;
1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
10933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int OperandCount() const override { return V; }
1095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* OperandAt(int i) const override { return inputs_[i]; }
1096e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
10973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1098e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch protected:
1099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void InternalSetOperandAt(int i, HValue* value) override {
1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    inputs_[i] = value;
1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1102e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1103e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch private:
11043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  EmbeddedContainer<HBasicBlock*, S> successors_;
11053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  EmbeddedContainer<HValue*, V> inputs_;
1106e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch};
1107e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1108e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HBlockEntry final : public HTemplateInstruction<0> {
1110e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public:
1111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
1112e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::None();
1113e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
1114e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1115257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
1116e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch};
1117e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1118e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HDummyUse final : public HTemplateInstruction<1> {
11203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public:
1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HDummyUse(HValue* value)
1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HTemplateInstruction<1>(HType::Smi()) {
1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, value);
1124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Pretend to be a Smi so that the HChange instructions inserted
1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // before any use generate as little code as possible.
1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* value() const { return OperandAt(0); }
1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool HasEscapingOperandAt(int index) override { return false; }
1132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
11333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return Representation::None();
11343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
11353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(DummyUse);
11393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch};
11403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
11413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Inserts an int3/stop break instruction for debugging purposes.
1143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HDebugBreak final : public HTemplateInstruction<0> {
1144e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public:
1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P0(HDebugBreak);
1146e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
1148e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::None();
1149e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
11501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(DebugBreak)
1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
11533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
115444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HPrologue final : public HTemplateInstruction<0> {
1156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
1157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HPrologue* New(Zone* zone) { return new (zone) HPrologue(); }
1158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
1160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Representation::None();
1161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(Prologue)
1164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
1165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HGoto final : public HTemplateControlInstruction<1, 0> {
1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HGoto(HBasicBlock* target) {
1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetSuccessorAt(0, target);
117144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
117244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool KnownSuccessorBlock(HBasicBlock** block) override {
1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *block = FirstSuccessor();
1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return true;
1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
117744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Representation::None();
118044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
118144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
1183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(Goto)
1185b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
1186b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1187b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HDeoptimize final : public HTemplateControlInstruction<1, 0> {
1189b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
1190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HDeoptimize* New(Isolate* isolate, Zone* zone, HValue* context,
1191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                          DeoptimizeReason reason,
1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          Deoptimizer::BailoutType type,
1193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          HBasicBlock* unreachable_continuation) {
1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return new(zone) HDeoptimize(reason, type, unreachable_continuation);
11953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1196b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool KnownSuccessorBlock(HBasicBlock** block) override {
1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *block = NULL;
1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return true;
1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
1203e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::None();
1204e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
1205e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1206f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeoptimizeReason reason() const { return reason_; }
1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Deoptimizer::BailoutType type() { return type_; }
1208589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1212f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  explicit HDeoptimize(DeoptimizeReason reason, Deoptimizer::BailoutType type,
1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       HBasicBlock* unreachable_continuation)
1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : reason_(reason), type_(type) {
1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetSuccessorAt(0, unreachable_continuation);
1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1218f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeoptimizeReason reason_;
1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Deoptimizer::BailoutType type_;
1220b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
1221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1222b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HUnaryControlInstruction : public HTemplateControlInstruction<2, 1> {
1224b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
12253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HUnaryControlInstruction(HValue* value,
12263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                           HBasicBlock* true_target,
12273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                           HBasicBlock* false_target) {
1228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetOperandAt(0, value);
12293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    SetSuccessorAt(0, true_target);
12303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    SetSuccessorAt(1, false_target);
1231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
1234b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* value() const { return OperandAt(0); }
1236b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
1237b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1238b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HBranch final : public HUnaryControlInstruction {
1240b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HBranch, HValue*);
1242c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P2(HBranch, HValue*, ToBooleanHints);
1243c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P4(HBranch, HValue*, ToBooleanHints, HBasicBlock*,
1244c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                 HBasicBlock*);
12453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
1247b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return Representation::None();
1248b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation observed_input_representation(int index) override;
1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool KnownSuccessorBlock(HBasicBlock** block) override;
1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
1254b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1255c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  ToBooleanHints expected_input_types() const { return expected_input_types_; }
125669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
12573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(Branch)
125869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
125969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch private:
1260c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  HBranch(HValue* value,
1261c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          ToBooleanHints expected_input_types = ToBooleanHint::kNone,
12623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          HBasicBlock* true_target = NULL, HBasicBlock* false_target = NULL)
1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HUnaryControlInstruction(value, true_target, false_target),
1264c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        expected_input_types_(expected_input_types) {}
1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1266c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  ToBooleanHints expected_input_types_;
1267b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
1268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1269b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HCompareMap final : public HUnaryControlInstruction {
1271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P2(HCompareMap, HValue*, Handle<Map>);
1273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P4(HCompareMap, HValue*, Handle<Map>,
1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 HBasicBlock*, HBasicBlock*);
1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool KnownSuccessorBlock(HBasicBlock** block) override {
1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (known_successor_index() != kNoKnownSuccessorIndex) {
1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *block = SuccessorAt(known_successor_index());
1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return true;
1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *block = NULL;
1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
1283b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kNoKnownSuccessorIndex = -1;
1288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int known_successor_index() const {
1289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return KnownSuccessorIndexField::decode(bit_field_) -
1290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           kInternalKnownSuccessorOffset;
1291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void set_known_successor_index(int index) {
1293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(index >= 0 - kInternalKnownSuccessorOffset);
1294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    bit_field_ = KnownSuccessorIndexField::update(
1295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        bit_field_, index + kInternalKnownSuccessorOffset);
1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Unique<Map> map() const { return map_; }
1299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool map_is_stable() const { return MapIsStableField::decode(bit_field_); }
1300b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
1302e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::Tagged();
1303e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
1304e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1305257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(CompareMap)
1306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
1308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int RedefinedOperandIndex() override { return 0; }
1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1310b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
1311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  HCompareMap(HValue* value, Handle<Map> map, HBasicBlock* true_target = NULL,
1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              HBasicBlock* false_target = NULL)
1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HUnaryControlInstruction(value, true_target, false_target),
1314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        bit_field_(KnownSuccessorIndexField::encode(
1315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                       kNoKnownSuccessorIndex + kInternalKnownSuccessorOffset) |
1316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                   MapIsStableField::encode(map->is_stable())),
1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        map_(Unique<Map>::CreateImmovable(map)) {
1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // BitFields can only store unsigned values, so use an offset.
1322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Adding kInternalKnownSuccessorOffset must yield an unsigned value.
1323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static const int kInternalKnownSuccessorOffset = 1;
1324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  STATIC_ASSERT(kNoKnownSuccessorIndex + kInternalKnownSuccessorOffset >= 0);
1325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class KnownSuccessorIndexField : public BitField<int, 0, 31> {};
1327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class MapIsStableField : public BitField<bool, 31, 1> {};
1328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  uint32_t bit_field_;
1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Unique<Map> map_;
1331b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
1332b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1333b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HContext final : public HTemplateInstruction<0> {
1335b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HContext* New(Zone* zone) {
1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return new(zone) HContext();
13381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
1339b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Representation::None();
1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(Context)
1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
1347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HContext() {
1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
1352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kUseGVN);
1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override { return true; }
1356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HReturn final : public HTemplateControlInstruction<0, 3> {
1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HReturn, HValue*, HValue*);
1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HReturn, HValue*);
1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(titzer): require an Int32 input for faster returns.
1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (index == 2) return Representation::Smi();
1367e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::Tagged();
1368e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
1369e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
13713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* value() const { return OperandAt(0); }
1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* context() const { return OperandAt(1); }
1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* parameter_count() const { return OperandAt(2); }
13753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1376257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(Return)
1377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HReturn(HValue* context, HValue* value, HValue* parameter_count = 0) {
1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, value);
1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, context);
1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(2, parameter_count);
1383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
1385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HAbnormalExit final : public HTemplateControlInstruction<0, 0> {
1388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
1389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P0(HAbnormalExit);
1390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
1392e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::None();
1393e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
1394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1395257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
1396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HAbnormalExit() {}
1398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
1399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1400b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HUnaryOperation : public HTemplateInstruction<1> {
1402b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
1403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HUnaryOperation(HValue* value, HType type = HType::Tagged())
1404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HTemplateInstruction<1>(type) {
1405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetOperandAt(0, value);
1406b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
14083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static HUnaryOperation* cast(HValue* value) {
14093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return reinterpret_cast<HUnaryOperation*>(value);
14103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
14113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* value() const { return OperandAt(0); }
1413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
1414b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
1415b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1416b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HUseConst final : public HUnaryOperation {
14181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public:
1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HUseConst, HValue*);
14201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
1422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Representation::None();
14231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
14241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(UseConst)
14263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1429257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
1430257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1431257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HForceRepresentation final : public HTemplateInstruction<1> {
14333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public:
1434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
1435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           HValue* value,
1436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           Representation required_representation);
14373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* value() const { return OperandAt(0); }
1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation observed_input_representation(int index) override {
1441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // We haven't actually *observed* this, but it's closer to the truth
1442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // than 'None'.
1443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return representation();  // Same as the output representation.
1444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
1446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return representation();  // Same as the output representation.
14473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
14483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
14503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
14523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1454257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HForceRepresentation(HValue* value, Representation required_representation) {
1455257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    SetOperandAt(0, value);
1456257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    set_representation(required_representation);
1457257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
14581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
14591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HChange final : public HUnaryOperation {
1461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
1462c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  HChange(HValue* value, Representation to, bool is_truncating_to_smi,
1463c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          bool is_truncating_to_int32, bool is_truncating_to_number)
14643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      : HUnaryOperation(value) {
1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!value->representation().IsNone());
1466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!to.IsNone());
1467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!value->representation().Equals(to));
1468b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    set_representation(to);
1469b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetFlag(kUseGVN);
1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kCanOverflow);
1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (is_truncating_to_smi && to.IsSmi()) {
1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetFlag(kTruncatingToSmi);
1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetFlag(kTruncatingToInt32);
1474c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      SetFlag(kTruncatingToNumber);
1475c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    } else if (is_truncating_to_int32) {
1476c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      SetFlag(kTruncatingToInt32);
1477c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      SetFlag(kTruncatingToNumber);
1478c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    } else if (is_truncating_to_number) {
1479c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      SetFlag(kTruncatingToNumber);
1480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (value->representation().IsSmi() || value->type().IsSmi()) {
1482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      set_type(HType::Smi());
1483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      set_type(HType::TaggedNumber());
1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion);
1486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1487b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1488b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HType CalculateInferredType() override;
1490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* Canonicalize() override;
1491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Representation from() const { return value()->representation(); }
1493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Representation to() const { return representation(); }
14943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool deoptimize_on_minus_zero() const {
14953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return CheckFlag(kBailoutOnMinusZero);
14963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
14983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return from();
1499b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1500b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Range* InferRange(Zone* zone) override;
150269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
1503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
1504b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1505257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(Change)
1506b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1507b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected:
1508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
1509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override {
1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return !from().IsTagged() || value()->type().IsSmi();
1513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1514b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
1515b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1516b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HClampToUint8 final : public HUnaryOperation {
1518257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
1519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HClampToUint8, HValue*);
1520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
1522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Representation::None();
1523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
1529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HClampToUint8(HValue* value)
1532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HUnaryOperation(value) {
15333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    set_representation(Representation::Integer32());
1534c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    SetFlag(kTruncatingToNumber);
1535257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    SetFlag(kUseGVN);
1536257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1537257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override { return true; }
1539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum RemovableSimulate {
1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  REMOVABLE_SIMULATE,
1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FIXED_SIMULATE
1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HSimulate final : public HInstruction {
1549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
1550958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  HSimulate(BailoutId ast_id, int pop_count, Zone* zone,
1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            RemovableSimulate removable)
1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : ast_id_(ast_id),
1553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        pop_count_(pop_count),
1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        values_(2, zone),
1555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        assigned_indexes_(2, zone),
1556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        zone_(zone),
1557958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        bit_field_(RemovableField::encode(removable) |
1558958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                   DoneWithReplayField::encode(false)) {}
1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ~HSimulate() {}
1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
1562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasAstId() const { return !ast_id_.IsNone(); }
1564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BailoutId ast_id() const { return ast_id_; }
1565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_ast_id(BailoutId id) {
1566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!HasAstId());
1567b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ast_id_ = id;
1568b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1569b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1570b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int pop_count() const { return pop_count_; }
1571b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const ZoneList<HValue*>* values() const { return &values_; }
1572b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int GetAssignedIndexAt(int index) const {
1573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(HasAssignedIndexAt(index));
1574b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return assigned_indexes_[index];
1575b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1576b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool HasAssignedIndexAt(int index) const {
1577b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return assigned_indexes_[index] != kNoIndex;
1578b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1579b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AddAssignedValue(int index, HValue* value) {
1580b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    AddValue(index, value);
1581b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1582b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AddPushedValue(HValue* value) {
1583b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    AddValue(kNoIndex, value);
1584b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int ToOperandIndex(int environment_index) {
1586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 0; i < assigned_indexes_.length(); ++i) {
1587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (assigned_indexes_[i] == environment_index) return i;
1588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return -1;
1590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int OperandCount() const override { return values_.length(); }
1592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* OperandAt(int index) const override { return values_[index]; }
1593e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool HasEscapingOperandAt(int index) override { return false; }
1595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
1596e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::None();
1597e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
1598b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void MergeWith(ZoneList<HSimulate*>* list);
1600958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool is_candidate_for_removal() {
1601958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return RemovableField::decode(bit_field_) == REMOVABLE_SIMULATE;
1602958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Replay effects of this instruction on the given environment.
1605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ReplayEnvironment(HEnvironment* env);
1606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1607257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(Simulate)
1608b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1609b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG
1610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Verify() override;
1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_closure(Handle<JSFunction> closure) { closure_ = closure; }
1612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<JSFunction> closure() const { return closure_; }
1613b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
1614b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1615b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected:
1616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void InternalSetOperandAt(int index, HValue* value) override {
1617b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    values_[index] = value;
1618b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1619b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1620b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
1621b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kNoIndex = -1;
1622b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AddValue(int index, HValue* value) {
1623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assigned_indexes_.Add(index, zone_);
1624b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Resize the list of pushed values.
1625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    values_.Add(NULL, zone_);
1626b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Set the operand through the base method in HValue to make sure that the
1627b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // use lists are correctly updated.
1628b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetOperandAt(values_.length() - 1, value);
1629b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasValueForIndex(int index) {
1631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 0; i < assigned_indexes_.length(); ++i) {
1632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (assigned_indexes_[i] == index) return true;
1633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
1635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1636958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool is_done_with_replay() const {
1637958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return DoneWithReplayField::decode(bit_field_);
1638958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1639958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void set_done_with_replay() {
1640958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    bit_field_ = DoneWithReplayField::update(bit_field_, true);
1641958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1642958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1643958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class RemovableField : public BitField<RemovableSimulate, 0, 1> {};
1644958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class DoneWithReplayField : public BitField<bool, 1, 1> {};
1645958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BailoutId ast_id_;
1647b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int pop_count_;
1648b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<HValue*> values_;
1649b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<int> assigned_indexes_;
1650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone_;
1651958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  uint32_t bit_field_;
1652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
1654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<JSFunction> closure_;
1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
1656b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
1657b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1658b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HEnvironmentMarker final : public HTemplateInstruction<1> {
1660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
1661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum Kind { BIND, LOOKUP };
1662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P2(HEnvironmentMarker, Kind, int);
1664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Kind kind() const { return kind_; }
1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int index() const { return index_; }
1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HSimulate* next_simulate() { return next_simulate_; }
1668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_next_simulate(HSimulate* simulate) {
1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    next_simulate_ = simulate;
1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
1673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Representation::None();
1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
1677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
1679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_closure(Handle<JSFunction> closure) {
1680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(closure_.is_null());
1681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!closure.is_null());
1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    closure_ = closure;
1683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<JSFunction> closure() const { return closure_; }
1685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
1686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(EnvironmentMarker);
1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HEnvironmentMarker(Kind kind, int index)
1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : kind_(kind), index_(index), next_simulate_(NULL) { }
1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Kind kind_;
1694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int index_;
1695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HSimulate* next_simulate_;
1696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
1698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<JSFunction> closure_;
1699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
1700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HStackCheck final : public HTemplateInstruction<1> {
1704b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
17053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  enum Type {
17063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    kFunctionEntry,
17073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    kBackwardsBranch
17083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  };
17093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HStackCheck, Type);
17113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
17123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HValue* context() { return OperandAt(0); }
1713b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
17153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return Representation::Tagged();
1716e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
1717e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
17183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void Eliminate() {
17193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // The stack check eliminator might try to eliminate the same stack
17203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // check instruction multiple times.
17213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (IsLinked()) {
1722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DeleteAndReplaceWith(NULL);
17233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
17243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
17253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
17263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool is_function_entry() { return type_ == kFunctionEntry; }
17273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool is_backwards_branch() { return type_ == kBackwardsBranch; }
17283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1729257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(StackCheck)
17303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
17313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch private:
1732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HStackCheck(HValue* context, Type type) : type_(type) {
1733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, context);
1734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetChangesFlag(kNewSpacePromotion);
1735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
17373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Type type_;
1738b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
1739b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1740b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum InliningKind {
1742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NORMAL_RETURN,          // Drop the function from the environment on return.
1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CONSTRUCT_CALL_RETURN,  // Either use allocated receiver or return value.
1744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GETTER_CALL_RETURN,     // Returning from a getter, need to restore context.
1745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SETTER_CALL_RETURN      // Use the RHS of the assignment as the return value.
1746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HArgumentsObject;
1750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HConstant;
1751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HEnterInlined final : public HTemplateInstruction<0> {
1754b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
1755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HEnterInlined* New(Isolate* isolate, Zone* zone, HValue* context,
1756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            BailoutId return_id, Handle<JSFunction> closure,
1757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            HConstant* closure_context, int arguments_count,
1758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            FunctionLiteral* function,
1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            InliningKind inlining_kind, Variable* arguments_var,
17603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                            HArgumentsObject* arguments_object,
17613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                            TailCallMode syntactic_tail_call_mode) {
17623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return new (zone)
17633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        HEnterInlined(return_id, closure, closure_context, arguments_count,
17643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      function, inlining_kind, arguments_var, arguments_object,
17653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      syntactic_tail_call_mode, zone);
1766b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1767b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void RegisterReturnTarget(HBasicBlock* return_target, Zone* zone);
1769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<HBasicBlock*>* return_targets() { return &return_targets_; }
1770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
1772b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<SharedFunctionInfo> shared() const { return shared_; }
1774b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Handle<JSFunction> closure() const { return closure_; }
1775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HConstant* closure_context() const { return closure_context_; }
17763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int arguments_count() const { return arguments_count_; }
1777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool arguments_pushed() const { return arguments_pushed_; }
1778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_arguments_pushed() { arguments_pushed_ = true; }
1779b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  FunctionLiteral* function() const { return function_; }
1780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  InliningKind inlining_kind() const { return inlining_kind_; }
17813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  TailCallMode syntactic_tail_call_mode() const {
17823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return syntactic_tail_call_mode_;
17833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
1784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BailoutId ReturnId() const { return return_id_; }
1785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int inlining_id() const { return inlining_id_; }
1786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_inlining_id(int inlining_id) { inlining_id_ = inlining_id; }
1787b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
1789e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::None();
1790e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
1791e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Variable* arguments_var() { return arguments_var_; }
1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HArgumentsObject* arguments_object() { return arguments_object_; }
17943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1795257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
1796b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1797b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HEnterInlined(BailoutId return_id, Handle<JSFunction> closure,
1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                HConstant* closure_context, int arguments_count,
1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                FunctionLiteral* function, InliningKind inlining_kind,
1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                Variable* arguments_var, HArgumentsObject* arguments_object,
18023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                TailCallMode syntactic_tail_call_mode, Zone* zone)
1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : return_id_(return_id),
1804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        shared_(handle(closure->shared())),
1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        closure_(closure),
1806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        closure_context_(closure_context),
1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        arguments_count_(arguments_count),
1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        arguments_pushed_(false),
1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        function_(function),
1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        inlining_kind_(inlining_kind),
18113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        syntactic_tail_call_mode_(syntactic_tail_call_mode),
1812c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        inlining_id_(-1),
1813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        arguments_var_(arguments_var),
1814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        arguments_object_(arguments_object),
1815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return_targets_(2, zone) {}
1816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BailoutId return_id_;
1818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<SharedFunctionInfo> shared_;
1819b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Handle<JSFunction> closure_;
1820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HConstant* closure_context_;
18213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int arguments_count_;
1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool arguments_pushed_;
1823b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  FunctionLiteral* function_;
1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  InliningKind inlining_kind_;
18253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  TailCallMode syntactic_tail_call_mode_;
1826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int inlining_id_;
1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Variable* arguments_var_;
1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HArgumentsObject* arguments_object_;
1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<HBasicBlock*> return_targets_;
1830b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
1831b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1832b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HLeaveInlined final : public HTemplateInstruction<0> {
1834b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HLeaveInlined(HEnterInlined* entry,
1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                int drop_count)
1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : entry_(entry),
1838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        drop_count_(drop_count) { }
1839b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
1841e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::None();
1842e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
1843e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int argument_delta() const override {
1845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return entry_->arguments_pushed() ? -drop_count_ : 0;
1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1848257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
1849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HEnterInlined* entry_;
1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int drop_count_;
1853b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
1854b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1855b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HPushArguments final : public HInstruction {
1857b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
1858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HPushArguments* New(Isolate* isolate, Zone* zone, HValue* context) {
1859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return new(zone) HPushArguments(zone);
1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HPushArguments* New(Isolate* isolate, Zone* zone, HValue* context,
1862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             HValue* arg1) {
1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HPushArguments* instr = new(zone) HPushArguments(zone);
1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr->AddInput(arg1);
1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return instr;
1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HPushArguments* New(Isolate* isolate, Zone* zone, HValue* context,
1868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             HValue* arg1, HValue* arg2) {
1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HPushArguments* instr = new(zone) HPushArguments(zone);
1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr->AddInput(arg1);
1871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr->AddInput(arg2);
1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return instr;
1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HPushArguments* New(Isolate* isolate, Zone* zone, HValue* context,
1875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             HValue* arg1, HValue* arg2, HValue* arg3) {
1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HPushArguments* instr = new(zone) HPushArguments(zone);
1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr->AddInput(arg1);
1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr->AddInput(arg2);
1879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr->AddInput(arg3);
1880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return instr;
1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HPushArguments* New(Isolate* isolate, Zone* zone, HValue* context,
1883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             HValue* arg1, HValue* arg2, HValue* arg3,
1884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             HValue* arg4) {
1885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HPushArguments* instr = new(zone) HPushArguments(zone);
1886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr->AddInput(arg1);
1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr->AddInput(arg2);
1888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr->AddInput(arg3);
1889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr->AddInput(arg4);
1890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return instr;
1891e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
1892b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
1894b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return Representation::Tagged();
1895b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1896b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int argument_delta() const override { return inputs_.length(); }
1898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* argument(int i) { return OperandAt(i); }
18991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int OperandCount() const final { return inputs_.length(); }
1901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* OperandAt(int i) const final { return inputs_[i]; }
19023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddInput(HValue* value);
19043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(PushArguments)
19063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
19073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch protected:
1908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void InternalSetOperandAt(int i, HValue* value) final { inputs_[i] = value; }
19093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
19103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
1911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HPushArguments(Zone* zone)
1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HInstruction(HType::Tagged()), inputs_(4, zone) {
1913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<HValue*> inputs_;
19173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch};
19183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
19193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HThisFunction final : public HTemplateInstruction<0> {
19211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public:
1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P0(HThisFunction);
19231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
1925e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::None();
1926e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
1927e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
19291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
19301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block protected:
1931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
1932b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HThisFunction() {
19351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    set_representation(Representation::Tagged());
19361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    SetFlag(kUseGVN);
19371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
19381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override { return true; }
19401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
19411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
19421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HDeclareGlobals final : public HUnaryOperation {
19443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
1945f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HDeclareGlobals,
1946f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                              Handle<FixedArray>, int,
194762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                              Handle<FeedbackVector>);
19483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
19493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HValue* context() { return OperandAt(0); }
195062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Handle<FixedArray> declarations() const { return declarations_; }
19513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int flags() const { return flags_; }
195262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Handle<FeedbackVector> feedback_vector() const { return feedback_vector_; }
19533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
19543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals)
19553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
1957e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::Tagged();
1958e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
1959e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
196162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  HDeclareGlobals(HValue* context, Handle<FixedArray> declarations, int flags,
196262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                  Handle<FeedbackVector> feedback_vector)
1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HUnaryOperation(context),
196462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        declarations_(declarations),
1965f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        feedback_vector_(feedback_vector),
1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        flags_(flags) {
1967b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    set_representation(Representation::Tagged());
1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetAllSideEffects();
1969e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
1970e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
197162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Handle<FixedArray> declarations_;
197262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Handle<FeedbackVector> feedback_vector_;
1973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int flags_;
1974b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
1975b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1976b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1977e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochtemplate <int V>
1978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HCall : public HTemplateInstruction<V> {
1979b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
19801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // The argument count includes the receiver.
1981e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1982e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    this->set_representation(Representation::Tagged());
1983e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    this->SetAllSideEffects();
19841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
1985b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual int argument_count() const {
1987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return argument_count_;
1988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
19891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int argument_delta() const override { return -argument_count(); }
19911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
19921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block private:
19931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  int argument_count_;
19941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
19951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
19961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HUnaryCall : public HCall<1> {
19981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public:
19991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  HUnaryCall(HValue* value, int argument_count)
2000e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      : HCall<1>(argument_count) {
20011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    SetOperandAt(0, value);
20021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
20031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) final {
2005e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::Tagged();
2006b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
20071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
20091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* value() const { return OperandAt(0); }
20111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
20121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
20131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HBinaryCall : public HCall<2> {
20151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public:
20161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  HBinaryCall(HValue* first, HValue* second, int argument_count)
2017e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      : HCall<2>(argument_count) {
20181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    SetOperandAt(0, first);
20191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    SetOperandAt(1, second);
2020b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2021b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
2023b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) final {
2025e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::Tagged();
2026e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
20271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* first() const { return OperandAt(0); }
2029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* second() const { return OperandAt(1); }
2030257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
2031257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
20321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HCallWithDescriptor final : public HInstruction {
2034b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
20353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static HCallWithDescriptor* New(
20363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Isolate* isolate, Zone* zone, HValue* context, HValue* target,
20373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      int argument_count, CallInterfaceDescriptor descriptor,
20383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      const Vector<HValue*>& operands,
20393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      TailCallMode syntactic_tail_call_mode = TailCallMode::kDisallow,
20403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      TailCallMode tail_call_mode = TailCallMode::kDisallow) {
2041c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    HCallWithDescriptor* res = new (zone) HCallWithDescriptor(
2042c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        Code::STUB, context, target, argument_count, descriptor, operands,
2043c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        syntactic_tail_call_mode, tail_call_mode, zone);
2044c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return res;
2045c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
2046c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
2047c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  static HCallWithDescriptor* New(
2048c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      Isolate* isolate, Zone* zone, HValue* context, Code::Kind kind,
2049c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      HValue* target, int argument_count, CallInterfaceDescriptor descriptor,
2050c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      const Vector<HValue*>& operands,
2051c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      TailCallMode syntactic_tail_call_mode = TailCallMode::kDisallow,
2052c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      TailCallMode tail_call_mode = TailCallMode::kDisallow) {
2053c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    HCallWithDescriptor* res = new (zone) HCallWithDescriptor(
2054c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        kind, context, target, argument_count, descriptor, operands,
2055c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        syntactic_tail_call_mode, tail_call_mode, zone);
2056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return res;
2057b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2058b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int OperandCount() const final { return values_.length(); }
2060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* OperandAt(int index) const final { return values_[index]; }
20611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) final {
2063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (index == 0 || index == 1) {
2064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Target + context
2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return Representation::Tagged();
2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int par_index = index - 2;
2068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(par_index < GetParameterCount());
2069f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return RepresentationFromMachineType(
2070f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          descriptor_.GetParameterType(par_index));
2071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2073b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor)
2075b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
20763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Defines whether this instruction corresponds to a JS call at tail position.
20773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  TailCallMode syntactic_tail_call_mode() const {
20783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return SyntacticTailCallModeField::decode(bit_field_);
20793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
20803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
20813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Defines whether this call should be generated as a tail call.
20823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  TailCallMode tail_call_mode() const {
20833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return TailCallModeField::decode(bit_field_);
20843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
20853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bool IsTailCall() const { return tail_call_mode() == TailCallMode::kAllow; }
2086b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2087c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Code::Kind kind() const { return KindField::decode(bit_field_); }
2088c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
2089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual int argument_count() const {
2090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return argument_count_;
2091e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
2092e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
2093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int argument_delta() const override { return -argument_count_; }
2094b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CallInterfaceDescriptor descriptor() const { return descriptor_; }
2096b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2097c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  HValue* target() { return OperandAt(0); }
2098c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  HValue* context() { return OperandAt(1); }
2099c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  HValue* parameter(int index) {
2100c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    DCHECK_LT(index, GetParameterCount());
2101c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return OperandAt(index + 2);
21021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
21031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2104c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  HValue* Canonicalize() override;
2105c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
2106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
2107e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
2108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The argument count includes the receiver.
2110c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  HCallWithDescriptor(Code::Kind kind, HValue* context, HValue* target,
2111c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                      int argument_count, CallInterfaceDescriptor descriptor,
21123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      const Vector<HValue*>& operands,
21133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      TailCallMode syntactic_tail_call_mode,
21143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      TailCallMode tail_call_mode, Zone* zone)
2115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : descriptor_(descriptor),
2116c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        values_(GetParameterCount() + 2, zone),  // +2 for context and target.
2117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        argument_count_(argument_count),
21183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        bit_field_(
21193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            TailCallModeField::encode(tail_call_mode) |
2120c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            SyntacticTailCallModeField::encode(syntactic_tail_call_mode) |
2121c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            KindField::encode(kind)) {
21223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    DCHECK_EQ(operands.length(), GetParameterCount());
2123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // We can only tail call without any stack arguments.
21243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    DCHECK(tail_call_mode != TailCallMode::kAllow || argument_count == 0);
2125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddOperand(target, zone);
2126c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    AddOperand(context, zone);
2127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 0; i < operands.length(); i++) {
2128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AddOperand(operands[i], zone);
2129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this->set_representation(Representation::Tagged());
2131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this->SetAllSideEffects();
2132e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
2133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddOperand(HValue* v, Zone* zone) {
2135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    values_.Add(NULL, zone);
2136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(values_.length() - 1, v);
2137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2139c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int GetParameterCount() const { return descriptor_.GetParameterCount(); }
2140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void InternalSetOperandAt(int index, HValue* value) final {
2142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    values_[index] = value;
2143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CallInterfaceDescriptor descriptor_;
2146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<HValue*> values_;
2147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int argument_count_;
21483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  class TailCallModeField : public BitField<TailCallMode, 0, 1> {};
21493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  class SyntacticTailCallModeField
21503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      : public BitField<TailCallMode, TailCallModeField::kNext, 1> {};
2151c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  class KindField
2152c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      : public BitField<Code::Kind, SyntacticTailCallModeField::kNext, 5> {};
21533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  uint32_t bit_field_;
2154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
2155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HInvokeFunction final : public HBinaryCall {
2158b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
21593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P5(HInvokeFunction, HValue*,
21603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                              Handle<JSFunction>, int,
21613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                              TailCallMode, TailCallMode);
2162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* context() { return first(); }
2164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* function() { return second(); }
2165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<JSFunction> known_function() { return known_function_; }
2166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int formal_parameter_count() const { return formal_parameter_count_; }
2167b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
21683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bool HasStackCheck() final { return HasStackCheckField::decode(bit_field_); }
2169e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
21703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Defines whether this instruction corresponds to a JS call at tail position.
21713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  TailCallMode syntactic_tail_call_mode() const {
21723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return SyntacticTailCallModeField::decode(bit_field_);
2173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
21753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Defines whether this call should be generated as a tail call.
21763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  TailCallMode tail_call_mode() const {
21773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return TailCallModeField::decode(bit_field_);
2178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2179b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
21803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
2181b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
21823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  std::ostream& PrintTo(std::ostream& os) const override;      // NOLINT
2183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
2184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
21863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void set_has_stack_check(bool has_stack_check) {
21873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    bit_field_ = HasStackCheckField::update(bit_field_, has_stack_check);
21883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
21893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
21903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  HInvokeFunction(HValue* context, HValue* function,
21913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                  Handle<JSFunction> known_function, int argument_count,
21923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                  TailCallMode syntactic_tail_call_mode,
21933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                  TailCallMode tail_call_mode)
2194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : HBinaryCall(context, function, argument_count),
21953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        known_function_(known_function),
21963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        bit_field_(
21973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            TailCallModeField::encode(tail_call_mode) |
21983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            SyntacticTailCallModeField::encode(syntactic_tail_call_mode)) {
21993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    DCHECK(tail_call_mode != TailCallMode::kAllow ||
22003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch           syntactic_tail_call_mode == TailCallMode::kAllow);
22013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    formal_parameter_count_ =
22023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        known_function.is_null()
22033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            ? 0
22043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            : known_function->shared()->internal_formal_parameter_count();
22053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    set_has_stack_check(
22063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        !known_function.is_null() &&
22073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        (known_function->code()->kind() == Code::FUNCTION ||
22083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch         known_function->code()->kind() == Code::OPTIMIZED_FUNCTION));
22093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
2210109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
22113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Handle<JSFunction> known_function_;
22123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  int formal_parameter_count_;
2213109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
22143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  class HasStackCheckField : public BitField<bool, 0, 1> {};
22153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  class TailCallModeField
22163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      : public BitField<TailCallMode, HasStackCheckField::kNext, 1> {};
22173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  class SyntacticTailCallModeField
22183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      : public BitField<TailCallMode, TailCallModeField::kNext, 1> {};
2219109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  uint32_t bit_field_;
2220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
2221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HCallNewArray final : public HBinaryCall {
2224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
2225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HCallNewArray, HValue*, int,
2226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              ElementsKind,
2227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              Handle<AllocationSite>);
2228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2229e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HValue* context() { return first(); }
2230e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HValue* constructor() { return second(); }
2231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
2233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ElementsKind elements_kind() const { return elements_kind_; }
2235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<AllocationSite> site() const { return site_; }
2236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(CallNewArray)
2238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
2240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HCallNewArray(HValue* context, HValue* constructor, int argument_count,
2241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                ElementsKind elements_kind, Handle<AllocationSite> site)
2242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HBinaryCall(context, constructor, argument_count),
2243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        elements_kind_(elements_kind),
2244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        site_(site) {}
2245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ElementsKind elements_kind_;
2247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<AllocationSite> site_;
2248b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
2249b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HCallRuntime final : public HCall<1> {
2252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
2253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallRuntime,
2254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              const Runtime::Function*, int);
22553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
2257b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
22583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HValue* context() { return OperandAt(0); }
225944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  const Runtime::Function* function() const { return c_function_; }
2260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SaveFPRegsMode save_doubles() const { return save_doubles_; }
2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_save_doubles(SaveFPRegsMode save_doubles) {
2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    save_doubles_ = save_doubles;
2263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
22663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return Representation::Tagged();
2267e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
2268e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
2269257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
2270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
2272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HCallRuntime(HValue* context, const Runtime::Function* c_function,
2273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               int argument_count)
2274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : HCall<1>(argument_count),
2275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        c_function_(c_function),
2276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        save_doubles_(kDontSaveFPRegs) {
2277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, context);
2278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
228044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  const Runtime::Function* c_function_;
2281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SaveFPRegsMode save_doubles_;
2282b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
2283b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HUnaryMathOperation final : public HTemplateInstruction<2> {
22863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public:
2287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
2288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           HValue* value, BuiltinFunctionId op);
22893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* context() const { return OperandAt(0); }
2291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* value() const { return OperandAt(1); }
22923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
22943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (index == 0) {
2297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return Representation::Tagged();
2298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      switch (op_) {
230013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        case kMathCos:
2301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case kMathFloor:
2302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case kMathRound:
2303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case kMathFround:
230413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        case kMathSin:
2305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case kMathSqrt:
2306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case kMathPowHalf:
2307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case kMathLog:
2308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case kMathExp:
2309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return Representation::Double();
2310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case kMathAbs:
2311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return representation();
2312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case kMathClz32:
2313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return Representation::Integer32();
2314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        default:
2315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          UNREACHABLE();
2316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return Representation::None();
2317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
23203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Range* InferRange(Zone* zone) override;
23223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* Canonicalize() override;
2324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RepresentationFromUses() override;
2325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RepresentationFromInputs() override;
2326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BuiltinFunctionId op() const { return op_; }
2328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const char* OpName() const;
2329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
23311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
23321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block protected:
2333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override {
2334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
2335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return op_ == b->op();
2336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2337b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
2339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Indicates if we support a double (and int32) output for Math.floor and
2340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Math.round.
2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool SupportsFlexibleFloorAndRound() const {
2342bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_PPC
23433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return true;
23443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#elif V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64
23453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return CpuFeatures::IsSupported(SSE4_1);
2346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else
2347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
2348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
2349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
23503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
2351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HTemplateInstruction<2>(HType::TaggedNumber()), op_(op) {
23523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    SetOperandAt(0, context);
23533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    SetOperandAt(1, value);
2354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    switch (op) {
2355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      case kMathFloor:
2356b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      case kMathRound:
2357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (SupportsFlexibleFloorAndRound()) {
2358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          SetFlag(kFlexibleRepresentation);
2359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else {
2360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          set_representation(Representation::Integer32());
2361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
2362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
2363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case kMathClz32:
2364b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        set_representation(Representation::Integer32());
2365b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        break;
2366b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      case kMathAbs:
2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Not setting representation here: it is None intentionally.
2368b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        SetFlag(kFlexibleRepresentation);
2369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // TODO(svenpanne) This flag is actually only needed if representation()
2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // is tagged, and not when it is an unboxed double or unboxed integer.
2371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        SetChangesFlag(kNewSpacePromotion);
2372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        break;
237313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      case kMathCos:
2374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case kMathFround:
2375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case kMathLog:
2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case kMathExp:
237713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      case kMathSin:
2378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      case kMathSqrt:
2379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      case kMathPowHalf:
2380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        set_representation(Representation::Double());
2381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        break;
2382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      default:
2383b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        UNREACHABLE();
2384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
2385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetFlag(kUseGVN);
2386c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    SetFlag(kTruncatingToNumber);
2387b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override {
2390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // TODO(crankshaft): This should be true, however the semantics of this
2391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // instruction also include the ToNumber conversion that is mentioned in the
2392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // spec, which is of course observable.
2393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
2394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
23953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* SimplifiedDividendForMathFloorOfDiv(HDiv* hdiv);
2397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* SimplifiedDivisorForMathFloorOfDiv(HDiv* hdiv);
2398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BuiltinFunctionId op_;
2400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
2401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2402b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HLoadRoot final : public HTemplateInstruction<0> {
2404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
2405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HLoadRoot, Heap::RootListIndex);
2406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P2(HLoadRoot, Heap::RootListIndex, HType);
2407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
2409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Representation::None();
2410b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2411b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Heap::RootListIndex index() const { return index_; }
2413b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(LoadRoot)
2415b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2416b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected:
2417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override {
2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HLoadRoot* b = HLoadRoot::cast(other);
2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return index_ == b->index_;
2420b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2421b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2422b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
2423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HLoadRoot(Heap::RootListIndex index, HType type = HType::Tagged())
2424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HTemplateInstruction<0>(type), index_(index) {
2425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kUseGVN);
2426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(bmeurer): We'll need kDependsOnRoots once we add the
2427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // corresponding HStoreRoot instruction.
2428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetDependsOnFlag(kCalls);
2429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    set_representation(Representation::Tagged());
2430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override { return true; }
2433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Heap::RootListIndex index_;
2435b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
2436b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2437b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HCheckMaps final : public HTemplateInstruction<2> {
2439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
2440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HCheckMaps* New(Isolate* isolate, Zone* zone, HValue* context,
2441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         HValue* value, Handle<Map> map,
2442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         HValue* typecheck = NULL) {
2443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return new(zone) HCheckMaps(value, new(zone) UniqueSet<Map>(
2444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Unique<Map>::CreateImmovable(map), zone), typecheck);
2445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HCheckMaps* New(Isolate* isolate, Zone* zone, HValue* context,
2447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         HValue* value, SmallMapList* map_list,
2448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         HValue* typecheck = NULL) {
2449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UniqueSet<Map>* maps = new(zone) UniqueSet<Map>(map_list->length(), zone);
2450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 0; i < map_list->length(); ++i) {
2451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      maps->Add(Unique<Map>::CreateImmovable(map_list->at(i)), zone);
2452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return new(zone) HCheckMaps(value, maps, typecheck);
2454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2456958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool IsStabilityCheck() const {
2457958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return IsStabilityCheckField::decode(bit_field_);
2458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void MarkAsStabilityCheck() {
2460958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    bit_field_ = MapsAreStableField::encode(true) |
2461958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                 HasMigrationTargetField::encode(false) |
2462958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                 IsStabilityCheckField::encode(true);
2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ClearChangesFlag(kNewSpacePromotion);
2464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ClearDependsOnFlag(kElementsKind);
2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ClearDependsOnFlag(kMaps);
2466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool HasEscapingOperandAt(int index) override { return false; }
2469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
2470b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return Representation::Tagged();
2471b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2472b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HType CalculateInferredType() override {
2474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (value()->type().IsHeapObject()) return value()->type();
2475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HType::HeapObject();
2476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
24791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* value() const { return OperandAt(0); }
2481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* typecheck() const { return OperandAt(1); }
24821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const UniqueSet<Map>* maps() const { return maps_; }
2484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_maps(const UniqueSet<Map>* maps) { maps_ = maps; }
24851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2486958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool maps_are_stable() const {
2487958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return MapsAreStableField::decode(bit_field_);
2488958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2490958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool HasMigrationTarget() const {
2491958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return HasMigrationTargetField::decode(bit_field_);
2492958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* Canonicalize() override;
2495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HCheckMaps* CreateAndInsertAfter(Zone* zone,
2497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          HValue* value,
2498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          Unique<Map> map,
2499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          bool map_is_stable,
2500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          HInstruction* instr) {
2501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return instr->Append(new(zone) HCheckMaps(
2502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            value, new(zone) UniqueSet<Map>(map, zone), map_is_stable));
25031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
25041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HCheckMaps* CreateAndInsertBefore(Zone* zone,
2506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           HValue* value,
2507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           const UniqueSet<Map>* maps,
2508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           bool maps_are_stable,
2509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           HInstruction* instr) {
2510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return instr->Prepend(new(zone) HCheckMaps(value, maps, maps_are_stable));
25111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
25121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(CheckMaps)
25141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
25151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block protected:
2516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override {
2517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return this->maps()->Equals(HCheckMaps::cast(other)->maps());
2518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2519b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int RedefinedOperandIndex() override { return 0; }
2521b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
2523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HCheckMaps(HValue* value, const UniqueSet<Map>* maps, bool maps_are_stable)
2524958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      : HTemplateInstruction<2>(HType::HeapObject()),
2525958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        maps_(maps),
2526958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        bit_field_(HasMigrationTargetField::encode(false) |
2527958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                   IsStabilityCheckField::encode(false) |
2528958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                   MapsAreStableField::encode(maps_are_stable)) {
2529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK_NE(0, maps->size());
253069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    SetOperandAt(0, value);
2531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Use the object value for the dependency.
2532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, value);
2533b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    set_representation(Representation::Tagged());
2534b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetFlag(kUseGVN);
2535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetDependsOnFlag(kMaps);
2536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetDependsOnFlag(kElementsKind);
2537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2538b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HCheckMaps(HValue* value, const UniqueSet<Map>* maps, HValue* typecheck)
2540958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      : HTemplateInstruction<2>(HType::HeapObject()),
2541958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        maps_(maps),
2542958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        bit_field_(HasMigrationTargetField::encode(false) |
2543958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                   IsStabilityCheckField::encode(false) |
2544958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                   MapsAreStableField::encode(true)) {
2545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK_NE(0, maps->size());
2546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, value);
2547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Use the object value for the dependency if NULL is passed.
2548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, typecheck ? typecheck : value);
2549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
2550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kUseGVN);
2551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetDependsOnFlag(kMaps);
2552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetDependsOnFlag(kElementsKind);
2553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 0; i < maps->size(); ++i) {
2554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Handle<Map> map = maps->at(i).handle();
2555958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (map->is_migration_target()) {
2556958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        bit_field_ = HasMigrationTargetField::update(bit_field_, true);
2557958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
2558958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (!map->is_stable()) {
2559958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        bit_field_ = MapsAreStableField::update(bit_field_, false);
2560958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
2561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2562958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (HasMigrationTarget()) SetChangesFlag(kNewSpacePromotion);
2563b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2564b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2565958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class HasMigrationTargetField : public BitField<bool, 0, 1> {};
2566958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class IsStabilityCheckField : public BitField<bool, 1, 1> {};
2567958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class MapsAreStableField : public BitField<bool, 2, 1> {};
2568958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const UniqueSet<Map>* maps_;
2570958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  uint32_t bit_field_;
2571b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
2572b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2573b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HCheckValue final : public HUnaryOperation {
2575b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
2576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HCheckValue* New(Isolate* isolate, Zone* zone, HValue* context,
2577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          HValue* value, Handle<JSFunction> func) {
2578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool in_new_space = isolate->heap()->InNewSpace(*func);
2579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // NOTE: We create an uninitialized Unique and initialize it later.
2580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This is because a JSFunction can move due to GC during graph creation.
2581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Unique<JSFunction> target = Unique<JSFunction>::CreateUninitialized(func);
2582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HCheckValue* check = new(zone) HCheckValue(value, target, in_new_space);
2583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return check;
2584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HCheckValue* New(Isolate* isolate, Zone* zone, HValue* context,
2586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          HValue* value, Unique<HeapObject> target,
2587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          bool object_in_new_space) {
2588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return new(zone) HCheckValue(value, target, object_in_new_space);
2589b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2590b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void FinalizeUniqueness() override {
2592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    object_ = Unique<HeapObject>(object_.handle());
2593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
2596b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return Representation::Tagged();
2597b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
2599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* Canonicalize() override;
2601b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2602b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG
2603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Verify() override;
2604b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
2605b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Unique<HeapObject> object() const { return object_; }
2607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool object_in_new_space() const { return object_in_new_space_; }
2608b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(CheckValue)
2610b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2611b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected:
2612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override {
2613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HCheckValue* b = HCheckValue::cast(other);
2614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return object_ == b->object_;
2615b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2616b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2617b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
2618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HCheckValue(HValue* value, Unique<HeapObject> object,
2619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               bool object_in_new_space)
2620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HUnaryOperation(value, value->type()),
2621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        object_(object),
2622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        object_in_new_space_(object_in_new_space) {
2623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
2624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kUseGVN);
2625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Unique<HeapObject> object_;
2628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool object_in_new_space_;
2629b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
2630b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2631b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HCheckInstanceType final : public HUnaryOperation {
2633b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
2634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum Check {
2635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    IS_JS_RECEIVER,
2636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    IS_JS_ARRAY,
263713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    IS_JS_FUNCTION,
2638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    IS_JS_DATE,
2639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    IS_STRING,
2640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    IS_INTERNALIZED_STRING,
2641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LAST_INTERVAL_CHECK = IS_JS_DATE
2642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
2643b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P2(HCheckInstanceType, HValue*, Check);
26453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
2647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
2649b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return Representation::Tagged();
2650b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2651b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HType CalculateInferredType() override {
2653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    switch (check_) {
2654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case IS_JS_RECEIVER: return HType::JSReceiver();
2655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case IS_JS_ARRAY: return HType::JSArray();
265613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      case IS_JS_FUNCTION:
265713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        return HType::JSObject();
2658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case IS_JS_DATE: return HType::JSObject();
2659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case IS_STRING: return HType::String();
2660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case IS_INTERNALIZED_STRING: return HType::String();
2661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UNREACHABLE();
2663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HType::Tagged();
2664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* Canonicalize() override;
2667b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2668257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
2669257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void GetCheckInterval(InstanceType* first, InstanceType* last);
2670257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
2671b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Check check() const { return check_; }
2673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2674257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
2675b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2676b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected:
2677b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // TODO(ager): It could be nice to allow the ommision of instance
2678b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // type checks if we have already performed an instance type check
2679b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // with a larger range.
2680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override {
2681b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    HCheckInstanceType* b = HCheckInstanceType::cast(other);
2682257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return check_ == b->check_;
2683b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2684b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int RedefinedOperandIndex() override { return 0; }
2686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2687b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
2688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const char* GetCheckName() const;
26893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2690257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HCheckInstanceType(HValue* value, Check check)
2691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HUnaryOperation(value, HType::HeapObject()), check_(check) {
2692257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    set_representation(Representation::Tagged());
2693257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    SetFlag(kUseGVN);
2694257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
2695257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2696257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  const Check check_;
2697b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
2698b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2699b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HCheckSmi final : public HUnaryOperation {
2701b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
2702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HCheckSmi, HValue*);
2703b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
2705b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return Representation::Tagged();
2706b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2707b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* Canonicalize() override {
2709257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    HType value_type = value()->type();
2710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (value_type.IsSmi()) {
2711257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      return NULL;
2712257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
2713257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return this;
2714257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
2715257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
27171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
27181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block protected:
2719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
2720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
2722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HCheckSmi(HValue* value) : HUnaryOperation(value, HType::Smi()) {
2723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Smi());
2724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kUseGVN);
2725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2726b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
2727b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2728b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HCheckArrayBufferNotNeutered final : public HUnaryOperation {
2730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
2731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HCheckArrayBufferNotNeutered, HValue*);
2732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool HasEscapingOperandAt(int index) override { return false; }
2734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
2735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Representation::Tagged();
2736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HType CalculateInferredType() override {
2739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (value()->type().IsHeapObject()) return value()->type();
2740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return HType::HeapObject();
2741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(CheckArrayBufferNotNeutered)
2744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch protected:
2746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
2747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int RedefinedOperandIndex() override { return 0; }
2748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
2750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit HCheckArrayBufferNotNeutered(HValue* value)
2751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : HUnaryOperation(value) {
2752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    set_representation(Representation::Tagged());
2753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetFlag(kUseGVN);
2754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetDependsOnFlag(kCalls);
2755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
2757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HCheckHeapObject final : public HUnaryOperation {
2760b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
2761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HCheckHeapObject, HValue*);
2762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool HasEscapingOperandAt(int index) override { return false; }
2764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
2765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Representation::Tagged();
2766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HType CalculateInferredType() override {
2769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (value()->type().IsHeapObject()) return value()->type();
2770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HType::HeapObject();
2771b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2772b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2773b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG
2774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Verify() override;
2775b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
2776b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* Canonicalize() override {
2778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return value()->type().IsHeapObject() ? NULL : this;
2779e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
2780e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
2781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(CheckHeapObject)
2782b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
2783b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected:
2784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
2785b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2786b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
2787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HCheckHeapObject(HValue* value) : HUnaryOperation(value) {
2788b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    set_representation(Representation::Tagged());
2789b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetFlag(kUseGVN);
2790b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
2792b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2793b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HPhi final : public HValue {
2795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
2796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HPhi(int merged_index, Zone* zone)
2797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : inputs_(2, zone), merged_index_(merged_index) {
2798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(merged_index >= 0 || merged_index == kInvalidMergedIndex);
2799b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetFlag(kFlexibleRepresentation);
2800b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2801b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RepresentationFromInputs() override;
2803b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Range* InferRange(Zone* zone) override;
2805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void InferRepresentation(HInferRepresentationPhase* h_infer) override;
2806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
2807b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return representation();
2808b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation KnownOptimalRepresentation() override {
2810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return representation();
2811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HType CalculateInferredType() override;
2813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int OperandCount() const override { return inputs_.length(); }
2814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* OperandAt(int index) const override { return inputs_[index]; }
2815e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HValue* GetRedundantReplacement();
2816b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AddInput(HValue* value);
281744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool HasRealUses();
2818b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsReceiver() const { return merged_index_ == 0; }
2820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasMergedIndex() const { return merged_index_ != kInvalidMergedIndex; }
2821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SourcePosition position() const override;
2823b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2824b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int merged_index() const { return merged_index_; }
2825b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintTo(std::ostream& os) const override;  // NOLINT
2827b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2828b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG
2829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Verify() override;
2830b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
2831b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2832b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void InitRealUses(int id);
2833b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AddNonPhiUsesFrom(HPhi* other);
2834b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation representation_from_indirect_uses() const {
2836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return representation_from_indirect_uses_;
2837b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool has_type_feedback_from_uses() const {
2840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return has_type_feedback_from_uses_;
2841b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2843b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int phi_id() { return phi_id_; }
2844b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2845257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static HPhi* cast(HValue* value) {
2846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(value->IsPhi());
2847257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return reinterpret_cast<HPhi*>(value);
2848257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
2849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Opcode opcode() const override { return HValue::kPhi; }
2850257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SimplifyConstantInputs();
2852257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Marker value representing an invalid merge index.
2854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kInvalidMergedIndex = -1;
2855589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
2856b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected:
2857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void DeleteFromGraph() override;
2858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void InternalSetOperandAt(int index, HValue* value) override {
2859b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    inputs_[index] = value;
2860b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2861b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2862b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
2863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation representation_from_non_phi_uses() const {
2864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return representation_from_non_phi_uses_;
2865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2867b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<HValue*> inputs_;
2868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int merged_index_ = 0;
2869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int phi_id_ = -1;
2871b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation representation_from_indirect_uses_ = Representation::None();
2873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation representation_from_non_phi_uses_ = Representation::None();
2874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool has_type_feedback_from_uses_ = false;
2875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override { return !IsReceiver(); }
2877b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
2878b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2879b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Common base class for HArgumentsObject and HCapturedObject.
2881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HDematerializedObject : public HInstruction {
2882b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
2883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HDematerializedObject(int count, Zone* zone) : values_(count, zone) {}
2884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int OperandCount() const final { return values_.length(); }
2886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* OperandAt(int index) const final { return values_[index]; }
2887b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool HasEscapingOperandAt(int index) final { return false; }
2889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) final {
2890e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::None();
2891e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
2892e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
2893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
2894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void InternalSetOperandAt(int index, HValue* value) final {
2895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    values_[index] = value;
2896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // List of values tracked by this marker.
2899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<HValue*> values_;
2900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
2901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HArgumentsObject final : public HDematerializedObject {
2904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
2905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HArgumentsObject* New(Isolate* isolate, Zone* zone, HValue* context,
2906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               int count) {
2907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return new(zone) HArgumentsObject(count, zone);
2908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The values contain a list of all elements in the arguments object
2911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // including the receiver object, which is skipped when materializing.
2912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const ZoneList<HValue*>* arguments_values() const { return &values_; }
2913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int arguments_count() const { return values_.length(); }
2914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddArgument(HValue* argument, Zone* zone) {
2916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    values_.Add(NULL, zone);  // Resize list.
2917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(values_.length() - 1, argument);
2918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2920257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
2921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
2923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HArgumentsObject(int count, Zone* zone)
2924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HDematerializedObject(count, zone) {
2925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
2926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kIsArguments);
2927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2928b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
2929b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2930b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HCapturedObject final : public HDematerializedObject {
2932b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
2933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HCapturedObject(int length, int id, Zone* zone)
2934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HDematerializedObject(length, zone), capture_id_(id) {
2935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
2936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    values_.AddBlock(NULL, length, zone);  // Resize list.
2937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2938b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The values contain a list of all in-object properties inside the
2940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // captured object and is index by field index. Properties in the
2941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // properties or elements backing store are not tracked here.
2942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const ZoneList<HValue*>* values() const { return &values_; }
2943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int length() const { return values_.length(); }
2944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int capture_id() const { return capture_id_; }
2945b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Shortcut for the map value of this captured object.
2947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* map_value() const { return values()->first(); }
29489fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
2949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ReuseSideEffectsFromStore(HInstruction* store) {
2950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(store->HasObservableSideEffects());
2951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(store->IsStoreNamedField());
2952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    changes_flags_.Add(store->ChangesFlags());
29533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
29543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Replay effects of this instruction on the given environment.
2956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ReplayEnvironment(HEnvironment* env);
2957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
2959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(CapturedObject)
2961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
2963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int capture_id_;
2964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Note that we cannot DCE captured objects as they are used to replay
2966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the environment. This method is here as an explicit reminder.
2967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(mstarzinger): Turn HSimulates into full snapshots maybe?
2968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const final { return false; }
2969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
2970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HConstant final : public HTemplateInstruction<0> {
2973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
2974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum Special { kHoleNaN };
2975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HConstant, Special);
2977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HConstant, int32_t);
2978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P2(HConstant, int32_t, Representation);
2979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HConstant, double);
2980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HConstant, Handle<Object>);
2981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HConstant, ExternalReference);
2982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HConstant* CreateAndInsertAfter(Isolate* isolate, Zone* zone,
2984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         HValue* context, int32_t value,
2985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         Representation representation,
2986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         HInstruction* instruction) {
2987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return instruction->Append(
2988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        HConstant::New(isolate, zone, context, value, representation));
2989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Map> GetMonomorphicJSObjectMap() override {
2992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<Object> object = object_.handle();
2993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!object.is_null() && object->IsHeapObject()) {
2994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return v8::internal::handle(HeapObject::cast(*object)->map());
2995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Handle<Map>();
2997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HConstant* CreateAndInsertBefore(Isolate* isolate, Zone* zone,
3000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          HValue* context, int32_t value,
3001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          Representation representation,
3002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          HInstruction* instruction) {
3003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return instruction->Prepend(
3004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        HConstant::New(isolate, zone, context, value, representation));
3005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HConstant* CreateAndInsertBefore(Zone* zone,
3008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          Unique<Map> map,
3009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          bool map_is_stable,
3010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          HInstruction* instruction) {
3011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return instruction->Prepend(new(zone) HConstant(
3012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        map, Unique<Map>(Handle<Map>::null()), map_is_stable,
3013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Representation::Tagged(), HType::HeapObject(), true,
3014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        false, false, MAP_TYPE));
3015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HConstant* CreateAndInsertAfter(Zone* zone,
3018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         Unique<Map> map,
3019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         bool map_is_stable,
3020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         HInstruction* instruction) {
3021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return instruction->Append(new(zone) HConstant(
3022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            map, Unique<Map>(Handle<Map>::null()), map_is_stable,
3023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Representation::Tagged(), HType::HeapObject(), true,
3024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            false, false, MAP_TYPE));
3025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Object> handle(Isolate* isolate) {
3028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (object_.handle().is_null()) {
3029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Default arguments to is_not_in_new_space depend on this heap number
3030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // to be tenured so that it's guaranteed not to be located in new space.
3031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      object_ = Unique<Object>::CreateUninitialized(
3032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          isolate->factory()->NewNumber(double_value_, TENURED));
3033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllowDeferredHandleDereference smi_check;
3035958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(HasInteger32Value() || !object_.handle()->IsSmi());
3036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return object_.handle();
3037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsSpecialDouble() const {
3040958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return HasDoubleValue() &&
3041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           (bit_cast<int64_t>(double_value_) == bit_cast<int64_t>(-0.0) ||
3042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            std::isnan(double_value_));
3043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool NotInNewSpace() const {
3046958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return IsNotInNewSpaceField::decode(bit_field_);
3047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool ImmortalImmovable() const;
3050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsCell() const {
3052958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    InstanceType instance_type = GetInstanceType();
3053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return instance_type == CELL_TYPE;
3054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
3057e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::None();
3058e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
3059e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
3060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation KnownOptimalRepresentation() override {
3061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (HasSmiValue() && SmiValuesAre31Bits()) return Representation::Smi();
3062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (HasInteger32Value()) return Representation::Integer32();
3063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (HasNumberValue()) return Representation::Double();
3064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (HasExternalReferenceValue()) return Representation::External();
3065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Representation::Tagged();
3066257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
3067257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool EmitAtUses() override;
3069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
3070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HConstant* CopyToRepresentation(Representation r, Zone* zone) const;
3071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone);
3072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Maybe<HConstant*> CopyToTruncatedNumber(Isolate* isolate, Zone* zone);
3073958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool HasInteger32Value() const {
3074958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return HasInt32ValueField::decode(bit_field_);
3075958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
3076b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int32_t Integer32Value() const {
3077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(HasInteger32Value());
3078b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return int32_value_;
3079b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3080958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool HasSmiValue() const { return HasSmiValueField::decode(bit_field_); }
3081958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool HasDoubleValue() const {
3082958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return HasDoubleValueField::decode(bit_field_);
3083958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
3084b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  double DoubleValue() const {
3085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(HasDoubleValue());
3086b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return double_value_;
3087b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint64_t DoubleValueAsBits() const {
3089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(HasDoubleValue());
309062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return bit_cast<uint64_t>(double_value_);
3091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsTheHole() const {
3093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (HasDoubleValue() && DoubleValueAsBits() == kHoleNanInt64) {
3094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return true;
3095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return object_.IsInitialized() &&
3097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           object_.IsKnownGlobal(isolate()->heap()->the_hole_value());
3098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3099958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool HasNumberValue() const { return HasDoubleValue(); }
31003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int32_t NumberValueAsInteger32() const {
3101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(HasNumberValue());
3102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Irrespective of whether a numeric HConstant can be safely
3103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // represented as an int32, we store the (in some cases lossy)
3104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // representation of the number in int32_value_.
3105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return int32_value_;
3106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasStringValue() const {
3108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (HasNumberValue()) return false;
3109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!object_.handle().is_null());
3110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return GetInstanceType() < FIRST_NONSTRING_TYPE;
3111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<String> StringValue() const {
3113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(HasStringValue());
3114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Handle<String>::cast(object_.handle());
3115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasInternalizedStringValue() const {
3117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return HasStringValue() && StringShape(GetInstanceType()).IsInternalized();
3118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasExternalReferenceValue() const {
3121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return HasExternalReferenceValueField::decode(bit_field_);
3122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExternalReference ExternalReferenceValue() const {
3124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return external_reference_value_;
3125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasBooleanValue() const { return type_.IsBoolean(); }
3128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool BooleanValue() const { return BooleanValueField::decode(bit_field_); }
3129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsCallable() const { return IsCallableField::decode(bit_field_); }
3130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool IsUndetectable() const {
3131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return IsUndetectableField::decode(bit_field_);
3132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
3133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  InstanceType GetInstanceType() const {
3134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return InstanceTypeField::decode(bit_field_);
3135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
3136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool HasMapValue() const { return GetInstanceType() == MAP_TYPE; }
3138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Unique<Map> MapValue() const {
3139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(HasMapValue());
3140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Unique<Map>::cast(GetUnique());
3141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasStableMapValue() const {
3143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(HasMapValue() || !HasStableMapValueField::decode(bit_field_));
3144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return HasStableMapValueField::decode(bit_field_);
3145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasObjectMap() const { return !object_map_.IsNull(); }
3148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Unique<Map> ObjectMap() const {
3149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(HasObjectMap());
3150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return object_map_;
3151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t Hashcode() override {
3154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (HasInteger32Value()) {
3155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return static_cast<intptr_t>(int32_value_);
3156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else if (HasDoubleValue()) {
3157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint64_t bits = DoubleValueAsBits();
3158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (sizeof(bits) > sizeof(intptr_t)) {
3159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        bits ^= (bits >> 32);
3160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return static_cast<intptr_t>(bits);
3162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else if (HasExternalReferenceValue()) {
3163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return reinterpret_cast<intptr_t>(external_reference_value_.address());
3164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
3165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(!object_.handle().is_null());
3166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return object_.Hashcode();
3167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
31683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void FinalizeUniqueness() override {
3171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (!HasDoubleValue() && !HasExternalReferenceValue()) {
3172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(!object_.handle().is_null());
3173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      object_ = Unique<Object>(object_.handle());
3174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Unique<Object> GetUnique() const {
3178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return object_;
3179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
31808b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool EqualsUnique(Unique<Object> other) const {
3182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return object_.IsInitialized() && object_ == other;
3183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override {
3186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HConstant* other_constant = HConstant::cast(other);
3187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (HasInteger32Value()) {
3188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return other_constant->HasInteger32Value() &&
3189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier             int32_value_ == other_constant->int32_value_;
3190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else if (HasDoubleValue()) {
3191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return other_constant->HasDoubleValue() &&
3192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             std::memcmp(&double_value_, &other_constant->double_value_,
3193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         sizeof(double_value_)) == 0;
3194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else if (HasExternalReferenceValue()) {
3195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return other_constant->HasExternalReferenceValue() &&
3196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier             external_reference_value_ ==
3197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                 other_constant->external_reference_value_;
3198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
3199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (other_constant->HasInteger32Value() ||
3200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          other_constant->HasDoubleValue() ||
3201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          other_constant->HasExternalReferenceValue()) {
3202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return false;
3203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(!object_.handle().is_null());
3205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return other_constant->object_ == object_;
3206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3207b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3208b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG
3210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Verify() override {}
3211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
3212b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3213257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(Constant)
3214b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3215b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected:
3216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Range* InferRange(Zone* zone) override;
3217b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3218b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
3219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class HGraph;
3220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit HConstant(Special special);
3221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HConstant(Handle<Object> handle,
3222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     Representation r = Representation::None());
3223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HConstant(int32_t value,
3224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Representation r = Representation::None(),
3225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            bool is_not_in_new_space = true,
3226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Unique<Object> optional = Unique<Object>(Handle<Object>::null()));
3227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HConstant(double value,
3228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Representation r = Representation::None(),
3229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            bool is_not_in_new_space = true,
3230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Unique<Object> optional = Unique<Object>(Handle<Object>::null()));
3231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HConstant(Unique<Object> object,
3232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Unique<Map> object_map,
3233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            bool has_stable_map_value,
3234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Representation r,
3235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            HType type,
3236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            bool is_not_in_new_space,
3237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            bool boolean_value,
3238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            bool is_undetectable,
3239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            InstanceType instance_type);
3240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HConstant(ExternalReference reference);
3242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Initialize(Representation r);
3244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override { return true; }
3246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
3247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // If object_ is a map, this indicates whether the map is stable.
3248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class HasStableMapValueField : public BitField<bool, 0, 1> {};
3249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
3250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // We store the HConstant in the most specific form safely possible.
3251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // These flags tell us if the respective member fields hold valid, safe
3252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // representations of the constant. More specific flags imply more general
3253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // flags, but not the converse (i.e. smi => int32 => double).
3254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class HasSmiValueField : public BitField<bool, 1, 1> {};
3255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class HasInt32ValueField : public BitField<bool, 2, 1> {};
3256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class HasDoubleValueField : public BitField<bool, 3, 1> {};
3257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
3258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class HasExternalReferenceValueField : public BitField<bool, 4, 1> {};
3259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class IsNotInNewSpaceField : public BitField<bool, 5, 1> {};
3260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class BooleanValueField : public BitField<bool, 6, 1> {};
3261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class IsUndetectableField : public BitField<bool, 7, 1> {};
3262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class IsCallableField : public BitField<bool, 8, 1> {};
3263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
3264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static const InstanceType kUnknownInstanceType = FILLER_TYPE;
3265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class InstanceTypeField : public BitField<InstanceType, 16, 8> {};
3266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If this is a numerical constant, object_ either points to the
3268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // HeapObject the constant originated from or is null.  If the
3269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // constant is non-numeric, object_ always points to a valid
3270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // constant HeapObject.
3271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Unique<Object> object_;
3272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If object_ is a heap object, this points to the stable map of the object.
3274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Unique<Map> object_map_;
3275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  uint32_t bit_field_;
3277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3278b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int32_t int32_value_;
3279b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  double double_value_;
3280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExternalReference external_reference_value_;
3281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
3282b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3283b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HBinaryOperation : public HTemplateInstruction<3> {
3285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
3286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBinaryOperation(HValue* context, HValue* left, HValue* right,
3287109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                   HType type = HType::Tagged())
3288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HTemplateInstruction<3>(type),
3289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        observed_output_representation_(Representation::None()) {
3290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(left != NULL && right != NULL);
32913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    SetOperandAt(0, context);
32923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    SetOperandAt(1, left);
32933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    SetOperandAt(2, right);
3294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    observed_input_representation_[0] = Representation::None();
3295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    observed_input_representation_[1] = Representation::None();
3296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* context() const { return OperandAt(0); }
3299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* left() const { return OperandAt(1); }
3300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* right() const { return OperandAt(2); }
3301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // True if switching left and right operands likely generates better code.
3303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool AreOperandsBetterSwitched() {
3304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!IsCommutative()) return false;
3305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Constant operands are better off on the right, they can be inlined in
3307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // many situations on most platforms.
3308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (left()->IsConstant()) return true;
3309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (right()->IsConstant()) return false;
3310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Otherwise, if there is only one use of the right operand, it would be
3312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // better off on the left for platforms that only have 2-arg arithmetic
3313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // ops (e.g ia32, x64) that clobber the left operand.
3314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return right()->HasOneUse();
3315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BetterLeftOperand() {
3318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return AreOperandsBetterSwitched() ? right() : left();
3319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BetterRightOperand() {
3322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return AreOperandsBetterSwitched() ? left() : right();
3323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_observed_input_representation(int index, Representation rep) {
3326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(index >= 1 && index <= 2);
3327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    observed_input_representation_[index - 1] = rep;
3328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual void initialize_output_representation(Representation observed) {
3331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    observed_output_representation_ = observed;
3332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3333b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation observed_input_representation(int index) override {
3335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (index == 0) return Representation::Tagged();
3336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return observed_input_representation_[index - 1];
3337b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void UpdateRepresentation(Representation new_rep,
3340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            HInferRepresentationPhase* h_infer,
3341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            const char* reason) override {
3342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Representation rep = !FLAG_smi_binop && new_rep.IsSmi()
3343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ? Representation::Integer32() : new_rep;
3344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HValue::UpdateRepresentation(rep, h_infer, reason);
3345b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3346b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void InferRepresentation(HInferRepresentationPhase* h_infer) override;
3348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RepresentationFromInputs() override;
3349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Representation RepresentationFromOutput();
3350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AssumeRepresentation(Representation r) override;
3351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3352b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual bool IsCommutative() const { return false; }
3353b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
3355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
3357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (index == 0) return Representation::Tagged();
3358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return representation();
3359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool RightIsPowerOf2() {
3362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!right()->IsInteger32Constant()) return false;
3363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int32_t value = right()->GetInteger32Constant();
3364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (value < 0) {
3365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return base::bits::IsPowerOfTwo32(static_cast<uint32_t>(-value));
3366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return base::bits::IsPowerOfTwo32(static_cast<uint32_t>(value));
3368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation)
3371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
3373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IgnoreObservedOutputRepresentation(Representation current_rep);
3374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Representation observed_input_representation_[2];
3376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Representation observed_output_representation_;
3377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
3378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HWrapReceiver final : public HTemplateInstruction<2> {
33813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
3382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P2(HWrapReceiver, HValue*, HValue*);
33833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
3385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
33873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return Representation::Tagged();
33883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
33893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* receiver() const { return OperandAt(0); }
3391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* function() const { return OperandAt(1); }
3392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* Canonicalize() override;
33943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
3396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool known_function() const { return known_function_; }
33973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(WrapReceiver)
3399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
3401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HWrapReceiver(HValue* receiver, HValue* function) {
3402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    known_function_ = function->IsConstant() &&
3403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        HConstant::cast(function)->handle(function->isolate())->IsJSFunction();
3404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
3405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, receiver);
3406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, function);
3407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kUseGVN);
3408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool known_function_;
34113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
34123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
34133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HApplyArguments final : public HTemplateInstruction<4> {
3415b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
34163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DECLARE_INSTRUCTION_FACTORY_P5(HApplyArguments, HValue*, HValue*, HValue*,
34173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                 HValue*, TailCallMode);
3418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
3420b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // The length is untagged, all other inputs are tagged.
3421b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return (index == 2)
3422b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        ? Representation::Integer32()
3423b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        : Representation::Tagged();
3424b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3425b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3426e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HValue* function() { return OperandAt(0); }
3427e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HValue* receiver() { return OperandAt(1); }
3428e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HValue* length() { return OperandAt(2); }
3429e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HValue* elements() { return OperandAt(3); }
3430b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
34313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  TailCallMode tail_call_mode() const {
34323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return TailCallModeField::decode(bit_field_);
34333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
34343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
3435257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
3436b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
34383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  HApplyArguments(HValue* function, HValue* receiver, HValue* length,
34393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                  HValue* elements, TailCallMode tail_call_mode)
34403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      : bit_field_(TailCallModeField::encode(tail_call_mode)) {
3441b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    set_representation(Representation::Tagged());
3442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, function);
3443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, receiver);
3444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(2, length);
3445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(3, elements);
3446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetAllSideEffects();
3447b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
34483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
34493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  class TailCallModeField : public BitField<TailCallMode, 0, 1> {};
34503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  uint32_t bit_field_;
3451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
3452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HArgumentsElements final : public HTemplateInstruction<0> {
3455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
3456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HArgumentsElements, bool);
34573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DECLARE_INSTRUCTION_FACTORY_P2(HArgumentsElements, bool, bool);
3458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3459257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
34601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
3462e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::None();
3463e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
3464e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
3465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool from_inlined() const { return from_inlined_; }
34663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bool arguments_adaptor() const { return arguments_adaptor_; }
3467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
34681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block protected:
3469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
3470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
34723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  explicit HArgumentsElements(bool from_inlined, bool arguments_adaptor = true)
34733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      : from_inlined_(from_inlined), arguments_adaptor_(arguments_adaptor) {
3474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The value produced by this instruction is a pointer into the stack
3475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // that looks as if it was a smi because of alignment.
3476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
3477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kUseGVN);
3478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override { return true; }
3481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool from_inlined_;
34833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bool arguments_adaptor_;
3484b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
3485b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HArgumentsLength final : public HUnaryOperation {
3488b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
3489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HArgumentsLength, HValue*);
3490b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
3492e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::Tagged();
3493e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
3494e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
3495257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
34961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
34971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block protected:
3498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
3499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
3501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
3502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Integer32());
3503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kUseGVN);
3504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override { return true; }
3507b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
3508b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3509b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HAccessArgumentsAt final : public HTemplateInstruction<3> {
3511b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
3512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P3(HAccessArgumentsAt, HValue*, HValue*, HValue*);
3513b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
3515b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
3517b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // The arguments elements is considered tagged.
3518b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return index == 0
3519b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        ? Representation::Tagged()
3520b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        : Representation::Integer32();
3521b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3522b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* arguments() const { return OperandAt(0); }
3524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* length() const { return OperandAt(1); }
3525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* index() const { return OperandAt(2); }
3526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3527257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
3528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
3530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
3531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
3532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kUseGVN);
3533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, arguments);
3534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, length);
3535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(2, index);
3536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
3539b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
3540b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3541b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HBoundsCheck final : public HTemplateInstruction<2> {
3543b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
3544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P2(HBoundsCheck, HValue*, HValue*);
3545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool skip_check() const { return skip_check_; }
3547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_skip_check() { skip_check_ = true; }
3548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* base() const { return base_; }
3550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int offset() const { return offset_; }
3551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int scale() const { return scale_; }
3552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
3554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return representation();
3555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
3558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void InferRepresentation(HInferRepresentationPhase* h_infer) override;
3559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* index() const { return OperandAt(0); }
3561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* length() const { return OperandAt(1); }
3562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool allow_equality() const { return allow_equality_; }
3563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_allow_equality(bool v) { allow_equality_ = v; }
3564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int RedefinedOperandIndex() override { return 0; }
3566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsPurelyInformativeDefinition() override { return skip_check(); }
3567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
3569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
3571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Range* InferRange(Zone* zone) override;
3572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
3574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool skip_check_;
3575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* base_;
3576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int offset_;
3577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int scale_;
3578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool allow_equality_;
3579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
3581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Normally HBoundsCheck should be created using the
3582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // HGraphBuilder::AddBoundsCheck() helper.
3583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // However when building stubs, where we know that the arguments are Int32,
3584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // it makes sense to invoke this constructor directly.
3585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBoundsCheck(HValue* index, HValue* length)
3586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : skip_check_(false),
3587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      base_(NULL), offset_(0), scale_(0),
3588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      allow_equality_(false) {
35893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    SetOperandAt(0, index);
35903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    SetOperandAt(1, length);
3591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kFlexibleRepresentation);
3592b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetFlag(kUseGVN);
3593b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3594b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override { return skip_check() && !FLAG_debug_code; }
3596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
3597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HBitwiseBinaryOperation : public HBinaryOperation {
3600b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
3601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right,
3602109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                          HType type = HType::TaggedNumber())
3603109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : HBinaryOperation(context, left, right, type) {
36041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    SetFlag(kFlexibleRepresentation);
3605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kTruncatingToInt32);
3606c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    SetFlag(kTruncatingToNumber);
36071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    SetAllSideEffects();
3608b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3609b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void RepresentationChanged(Representation to) override {
3611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (to.IsTagged() &&
3612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) {
3613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetAllSideEffects();
3614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ClearFlag(kUseGVN);
3615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
36161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      ClearAllSideEffects();
36171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      SetFlag(kUseGVN);
36181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    }
3619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion);
36201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
36211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void UpdateRepresentation(Representation new_rep,
3623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            HInferRepresentationPhase* h_infer,
3624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            const char* reason) override {
3625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // We only generate either int32 or generic tagged bitwise operations.
3626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (new_rep.IsDouble()) new_rep = Representation::Integer32();
3627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
3628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation observed_input_representation(int index) override {
3631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Representation r = HBinaryOperation::observed_input_representation(index);
3632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (r.IsDouble()) return Representation::Integer32();
3633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return r;
3634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void initialize_output_representation(Representation observed) override {
3637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (observed.IsDouble()) observed = Representation::Integer32();
3638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBinaryOperation::initialize_output_representation(observed);
3639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
36401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3641257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
3642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
3644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override { return true; }
3645b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
3646b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3647b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HMathFloorOfDiv final : public HBinaryOperation {
3649b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
3650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HMathFloorOfDiv,
3651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                              HValue*,
3652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                              HValue*);
3653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv)
3655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
3657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
3658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
3660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HMathFloorOfDiv(HValue* context, HValue* left, HValue* right)
3661109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : HBinaryOperation(context, left, right) {
3662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Integer32());
3663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kUseGVN);
3664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kCanOverflow);
3665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kCanBeDivByZero);
3666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kLeftCanBeMinInt);
3667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kLeftCanBeNegative);
3668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kLeftCanBePositive);
3669c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    SetFlag(kTruncatingToNumber);
3670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Range* InferRange(Zone* zone) override;
3673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override { return true; }
3675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
3676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HArithmeticBinaryOperation : public HBinaryOperation {
3679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
3680c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right,
3681c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                             HType type = HType::TaggedNumber())
3682c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      : HBinaryOperation(context, left, right, type) {
36831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    SetAllSideEffects();
3684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kFlexibleRepresentation);
3685c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    SetFlag(kTruncatingToNumber);
3686b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3687b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void RepresentationChanged(Representation to) override {
3689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (to.IsTagged() &&
3690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) {
3691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetAllSideEffects();
3692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ClearFlag(kUseGVN);
3693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
36941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      ClearAllSideEffects();
3695b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      SetFlag(kUseGVN);
3696b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
3697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion);
3698b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3699b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_ABSTRACT_INSTRUCTION(ArithmeticBinaryOperation)
3701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
3703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override { return true; }
3704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
3705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HCompareGeneric final : public HBinaryOperation {
3708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
3709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HCompareGeneric* New(Isolate* isolate, Zone* zone, HValue* context,
3710109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                              HValue* left, HValue* right, Token::Value token) {
3711109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return new (zone) HCompareGeneric(context, left, right, token);
3712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
37153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return index == 0
37163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        ? Representation::Tagged()
37173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        : representation();
3718b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
37193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Token::Value token() const { return token_; }
3721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
3722b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
3724b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
3726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HCompareGeneric(HValue* context, HValue* left, HValue* right,
3727109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                  Token::Value token)
3728109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : HBinaryOperation(context, left, right, HType::Boolean()),
3729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        token_(token) {
3730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(Token::IsCompareOp(token));
3731b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    set_representation(Representation::Tagged());
37321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    SetAllSideEffects();
3733b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3734b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3735b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Token::Value token_;
3736b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
3737b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3738b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HCompareNumericAndBranch : public HTemplateControlInstruction<2, 2> {
3740b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
3741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HCompareNumericAndBranch* New(Isolate* isolate, Zone* zone,
3742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       HValue* context, HValue* left,
3743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       HValue* right, Token::Value token,
3744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       HBasicBlock* true_target = NULL,
3745109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                       HBasicBlock* false_target = NULL) {
3746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return new (zone)
3747109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        HCompareNumericAndBranch(left, right, token, true_target, false_target);
3748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3749b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* left() const { return OperandAt(0); }
3751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* right() const { return OperandAt(1); }
37523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Token::Value token() const { return token_; }
37533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_observed_input_representation(Representation left,
3755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         Representation right) {
3756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      observed_input_representation_[0] = left;
3757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      observed_input_representation_[1] = right;
37581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
37591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void InferRepresentation(HInferRepresentationPhase* h_infer) override;
3761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
3763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return representation();
3764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation observed_input_representation(int index) override {
3766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return observed_input_representation_[index];
3767b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3768b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool KnownSuccessorBlock(HBasicBlock** block) override;
37701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
3772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch)
3774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
3776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HCompareNumericAndBranch(HValue* left, HValue* right, Token::Value token,
3777109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                           HBasicBlock* true_target, HBasicBlock* false_target)
3778109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : token_(token) {
3779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kFlexibleRepresentation);
3780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(Token::IsCompareOp(token));
37813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    SetOperandAt(0, left);
37823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    SetOperandAt(1, right);
3783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetSuccessorAt(0, true_target);
3784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetSuccessorAt(1, false_target);
3785257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
3786257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Representation observed_input_representation_[2];
3788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Token::Value token_;
3789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
3790257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
37913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HCompareHoleAndBranch final : public HUnaryControlInstruction {
3793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
3794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HCompareHoleAndBranch, HValue*);
3795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P3(HCompareHoleAndBranch, HValue*,
3796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 HBasicBlock*, HBasicBlock*);
3797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void InferRepresentation(HInferRepresentationPhase* h_infer) override;
3799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
3801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return representation();
3802257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
3803257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(CompareHoleAndBranch)
3805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
3807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HCompareHoleAndBranch(HValue* value,
3808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        HBasicBlock* true_target = NULL,
3809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        HBasicBlock* false_target = NULL)
3810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HUnaryControlInstruction(value, true_target, false_target) {
3811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kFlexibleRepresentation);
3812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3813257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
3814257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3815257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HCompareObjectEqAndBranch : public HTemplateControlInstruction<2, 2> {
3817b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
3818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P2(HCompareObjectEqAndBranch, HValue*, HValue*);
3819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P4(HCompareObjectEqAndBranch, HValue*, HValue*,
3820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 HBasicBlock*, HBasicBlock*);
3821592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
3822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool KnownSuccessorBlock(HBasicBlock** block) override;
3823b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kNoKnownSuccessorIndex = -1;
3825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int known_successor_index() const { return known_successor_index_; }
3826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_known_successor_index(int known_successor_index) {
3827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    known_successor_index_ = known_successor_index;
3828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
38293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* left() const { return OperandAt(0); }
3831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* right() const { return OperandAt(1); }
3832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
3834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
38363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return Representation::Tagged();
3837b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3838b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation observed_input_representation(int index) override {
3840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Representation::Tagged();
3841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
38443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3845b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
3846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HCompareObjectEqAndBranch(HValue* left,
3847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            HValue* right,
3848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            HBasicBlock* true_target = NULL,
3849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            HBasicBlock* false_target = NULL)
3850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : known_successor_index_(kNoKnownSuccessorIndex) {
3851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, left);
3852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, right);
3853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetSuccessorAt(0, true_target);
3854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetSuccessorAt(1, false_target);
3855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int known_successor_index_;
3858b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
3859b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3860b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HIsStringAndBranch final : public HUnaryControlInstruction {
38623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
3863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HIsStringAndBranch, HValue*);
3864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P3(HIsStringAndBranch, HValue*,
3865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 HBasicBlock*, HBasicBlock*);
38663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
38683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return Representation::Tagged();
38693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
38703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool KnownSuccessorBlock(HBasicBlock** block) override;
3872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kNoKnownSuccessorIndex = -1;
3874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int known_successor_index() const { return known_successor_index_; }
3875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_known_successor_index(int known_successor_index) {
3876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    known_successor_index_ = known_successor_index;
3877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
38793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch)
3880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
3882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int RedefinedOperandIndex() override { return 0; }
3883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
3885958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  HIsStringAndBranch(HValue* value, HBasicBlock* true_target = NULL,
3886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     HBasicBlock* false_target = NULL)
3887958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      : HUnaryControlInstruction(value, true_target, false_target),
3888958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        known_successor_index_(kNoKnownSuccessorIndex) {
3889958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    set_representation(Representation::Tagged());
3890958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
3891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int known_successor_index_;
38933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
38943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3895b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HIsSmiAndBranch final : public HUnaryControlInstruction {
3897b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
3898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HIsSmiAndBranch, HValue*);
3899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P3(HIsSmiAndBranch, HValue*,
3900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 HBasicBlock*, HBasicBlock*);
39013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
39023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
3903b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
39053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return Representation::Tagged();
39063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
3907257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3908257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch protected:
3909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
3910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int RedefinedOperandIndex() override { return 0; }
3911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
3913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HIsSmiAndBranch(HValue* value,
3914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  HBasicBlock* true_target = NULL,
3915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  HBasicBlock* false_target = NULL)
3916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HUnaryControlInstruction(value, true_target, false_target) {
3917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
3918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3919257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
3920257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3921257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HIsUndetectableAndBranch final : public HUnaryControlInstruction {
3923257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
3924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HIsUndetectableAndBranch, HValue*);
3925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P3(HIsUndetectableAndBranch, HValue*,
3926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 HBasicBlock*, HBasicBlock*);
3927257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
39293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return Representation::Tagged();
39303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
39311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool KnownSuccessorBlock(HBasicBlock** block) override;
3933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
39343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
3935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
3937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HIsUndetectableAndBranch(HValue* value,
3938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           HBasicBlock* true_target = NULL,
3939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           HBasicBlock* false_target = NULL)
3940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HUnaryControlInstruction(value, true_target, false_target) {}
39411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
39421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
39431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HStringCompareAndBranch final : public HTemplateControlInstruction<2, 3> {
39453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
3946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HStringCompareAndBranch,
3947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                              HValue*,
3948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                              HValue*,
3949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                              Token::Value);
39503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* context() const { return OperandAt(0); }
3952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* left() const { return OperandAt(1); }
3953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* right() const { return OperandAt(2); }
39543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Token::Value token() const { return token_; }
39553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const final;  // NOLINT
39573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) final {
39593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return Representation::Tagged();
39603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
39613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
39623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch)
39633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
39643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
3965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HStringCompareAndBranch(HValue* context, HValue* left, HValue* right,
3966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          Token::Value token)
3967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : token_(token) {
3968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(Token::IsCompareOp(token));
3969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, context);
3970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, left);
3971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(2, right);
3972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
3973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetChangesFlag(kNewSpacePromotion);
3974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetDependsOnFlag(kStringChars);
3975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetDependsOnFlag(kStringLengths);
3976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Token::Value const token_;
3979b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
3980b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3981b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HHasInstanceTypeAndBranch final : public HUnaryControlInstruction {
3983b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
3984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P2(
3985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HHasInstanceTypeAndBranch, HValue*, InstanceType);
3986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P3(
3987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HHasInstanceTypeAndBranch, HValue*, InstanceType, InstanceType);
3988b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3989b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  InstanceType from() { return from_; }
3990b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  InstanceType to() { return to_; }
3991b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
3993b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
39953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return Representation::Tagged();
3996b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3997b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool KnownSuccessorBlock(HBasicBlock** block) override;
3999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
40003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
40013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4002b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
4003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HHasInstanceTypeAndBranch(HValue* value, InstanceType type)
4004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { }
4005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to)
4006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) {
4007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(to == LAST_TYPE);  // Others not implemented yet in backend.
4008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4010b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  InstanceType from_;
4011b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  InstanceType to_;  // Inclusive range, not all combinations work.
4012b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
4013b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HClassOfTestAndBranch final : public HUnaryControlInstruction {
4015b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
4016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P2(HClassOfTestAndBranch, HValue*,
4017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Handle<String>);
4018b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
40193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch)
40203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
40223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return Representation::Tagged();
40233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
4024b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
4026b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4027b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Handle<String> class_name() const { return class_name_; }
4028b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4029b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
4030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HClassOfTestAndBranch(HValue* value, Handle<String> class_name)
4031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HUnaryControlInstruction(value, NULL, NULL),
4032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        class_name_(class_name) { }
4033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4034b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Handle<String> class_name_;
4035b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
4036b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4037b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HTypeofIsAndBranch final : public HUnaryControlInstruction {
4039b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
4040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P2(HTypeofIsAndBranch, HValue*, Handle<String>);
4041b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<String> type_literal() const { return type_literal_.handle(); }
4043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
4044b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
40453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
4046b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
4048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Representation::None();
4049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool KnownSuccessorBlock(HBasicBlock** block) override;
4052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void FinalizeUniqueness() override {
4054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    type_literal_ = Unique<String>(type_literal_.handle());
4055b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
4056b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4057b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
4058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HTypeofIsAndBranch(HValue* value, Handle<String> type_literal)
4059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HUnaryControlInstruction(value, NULL, NULL),
4060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        type_literal_(Unique<String>::CreateUninitialized(type_literal)) { }
4061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Unique<String> type_literal_;
4063b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
4064b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4065b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HHasInPrototypeChainAndBranch final
4067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : public HTemplateControlInstruction<2, 2> {
4068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
4069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DECLARE_INSTRUCTION_FACTORY_P2(HHasInPrototypeChainAndBranch, HValue*,
4070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 HValue*);
4071086aeeaae12517475c22695a200be45495516549Ben Murdoch
4072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* object() const { return OperandAt(0); }
4073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* prototype() const { return OperandAt(1); }
4074086aeeaae12517475c22695a200be45495516549Ben Murdoch
4075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
4076086aeeaae12517475c22695a200be45495516549Ben Murdoch    return Representation::Tagged();
4077086aeeaae12517475c22695a200be45495516549Ben Murdoch  }
4078086aeeaae12517475c22695a200be45495516549Ben Murdoch
4079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool ObjectNeedsSmiCheck() const {
4080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return !object()->type().IsHeapObject() &&
4081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           !object()->representation().IsHeapObject();
4082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(HasInPrototypeChainAndBranch)
4085086aeeaae12517475c22695a200be45495516549Ben Murdoch
4086086aeeaae12517475c22695a200be45495516549Ben Murdoch private:
4087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HHasInPrototypeChainAndBranch(HValue* object, HValue* prototype) {
4088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetOperandAt(0, object);
4089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetOperandAt(1, prototype);
4090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetDependsOnFlag(kCalls);
4091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4092086aeeaae12517475c22695a200be45495516549Ben Murdoch};
4093086aeeaae12517475c22695a200be45495516549Ben Murdoch
4094086aeeaae12517475c22695a200be45495516549Ben Murdoch
4095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HPower final : public HTemplateInstruction<2> {
4096b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
4097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
4098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           HValue* left, HValue* right);
4099b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
41003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HValue* left() { return OperandAt(0); }
4101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* right() const { return OperandAt(1); }
41023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
41043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return index == 0
41053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      ? Representation::Double()
41063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      : Representation::None();
4107b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
4108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation observed_input_representation(int index) override {
4109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return RequiredInputRepresentation(index);
4110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4111b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4112257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(Power)
41131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
41141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block protected:
4115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
4116b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
4118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HPower(HValue* left, HValue* right) {
4119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, left);
4120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, right);
41213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    set_representation(Representation::Double());
4122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kUseGVN);
4123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetChangesFlag(kNewSpacePromotion);
41243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
41253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override {
4127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return !right()->representation().IsTagged();
41283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
41293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
41303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
41313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochenum ExternalAddType {
4133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AddOfExternalAndTagged,
4134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AddOfExternalAndInt32,
4135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  NoExternalAdd
4136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
4137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HAdd final : public HArithmeticBinaryOperation {
4140b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
4141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
4142109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                           HValue* left, HValue* right);
4143f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
4144109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                           HValue* left, HValue* right,
4145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           ExternalAddType external_add_type);
4146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Add is only commutative if two integer values are added and not if two
4148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // tagged values are added (because it might be a String concatenation).
4149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We also do not commute (pointer + offset).
4150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsCommutative() const override {
4151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return !representation().IsTagged() && !representation().IsExternal();
4152b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
4153b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* Canonicalize() override;
4155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void RepresentationChanged(Representation to) override {
4157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (to.IsTagged() &&
4158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved() ||
4159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         left()->ToStringCanBeObserved() || right()->ToStringCanBeObserved())) {
4160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetAllSideEffects();
4161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ClearFlag(kUseGVN);
4162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
4163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ClearAllSideEffects();
4164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetFlag(kUseGVN);
4165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (to.IsTagged()) {
4167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetChangesFlag(kNewSpacePromotion);
4168c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      ClearFlag(kTruncatingToNumber);
4169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
417013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (!right()->type().IsTaggedNumber() &&
417113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        !right()->representation().IsDouble() &&
417213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        !right()->representation().IsSmiOrInteger32()) {
4173c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      ClearFlag(kTruncatingToNumber);
417413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
4175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
41763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RepresentationFromInputs() override;
4178b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override;
4180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsConsistentExternalRepresentation() {
4182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return left()->representation().IsExternal() &&
4183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           ((external_add_type_ == AddOfExternalAndInt32 &&
4184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             right()->representation().IsInteger32()) ||
4185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            (external_add_type_ == AddOfExternalAndTagged &&
4186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             right()->representation().IsTagged()));
4187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ExternalAddType external_add_type() const { return external_add_type_; }
41903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4191257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(Add)
4192b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4193b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected:
4194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
4195b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Range* InferRange(Zone* zone) override;
4197b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
4199109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  HAdd(HValue* context, HValue* left, HValue* right,
4200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       ExternalAddType external_add_type = NoExternalAdd)
4201c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      : HArithmeticBinaryOperation(context, left, right, HType::Tagged()),
4202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        external_add_type_(external_add_type) {
4203b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetFlag(kCanOverflow);
4204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (external_add_type_) {
4205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case AddOfExternalAndTagged:
4206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(left->representation().IsExternal());
4207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(right->representation().IsTagged());
4208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        SetDependsOnFlag(kNewSpacePromotion);
4209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ClearFlag(HValue::kCanOverflow);
4210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        SetFlag(kHasNoObservableSideEffects);
4211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
4212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case NoExternalAdd:
4214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // This is a bit of a hack: The call to this constructor is generated
4215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // by a macro that also supports sub and mul, so it doesn't pass in
4216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // a value for external_add_type but uses the default.
4217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (left->representation().IsExternal()) {
4218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          external_add_type_ = AddOfExternalAndInt32;
4219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
4220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
4221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case AddOfExternalAndInt32:
4223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // See comment above.
4224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UNREACHABLE();
4225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
4226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
4227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
4228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ExternalAddType external_add_type_;
4230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
4231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HSub final : public HArithmeticBinaryOperation {
4234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
4235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
4236109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                           HValue* left, HValue* right);
4237b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* Canonicalize() override;
42393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4240257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(Sub)
4241b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4242b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected:
4243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
42441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
4245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Range* InferRange(Zone* zone) override;
4246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
4248109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  HSub(HValue* context, HValue* left, HValue* right)
4249109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : HArithmeticBinaryOperation(context, left, right) {
4250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kCanOverflow);
4251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
4253b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4254b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HMul final : public HArithmeticBinaryOperation {
4256b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
4257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
4258109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                           HValue* left, HValue* right);
4259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HInstruction* NewImul(Isolate* isolate, Zone* zone, HValue* context,
4261109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                               HValue* left, HValue* right) {
4262109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    HInstruction* instr = HMul::New(isolate, zone, context, left, right);
4263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!instr->IsMul()) return instr;
4264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HMul* mul = HMul::cast(instr);
4265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(mstarzinger): Prevent bailout on minus zero for imul.
4266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    mul->AssumeRepresentation(Representation::Integer32());
4267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    mul->ClearFlag(HValue::kCanOverflow);
4268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return mul;
4269b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
4270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* Canonicalize() override;
4272b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4273b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Only commutative if it is certain that not two objects are multiplicated.
4274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsCommutative() const override { return !representation().IsTagged(); }
4275b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void UpdateRepresentation(Representation new_rep,
4277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            HInferRepresentationPhase* h_infer,
4278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            const char* reason) override {
4279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
4280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool MulMinusOne();
42833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4284257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(Mul)
4285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected:
4287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
4288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Range* InferRange(Zone* zone) override;
4290b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
4292109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  HMul(HValue* context, HValue* left, HValue* right)
4293109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : HArithmeticBinaryOperation(context, left, right) {
4294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kCanOverflow);
4295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
4296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
4297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
429844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
4299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HMod final : public HArithmeticBinaryOperation {
4300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
4301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
4302109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                           HValue* left, HValue* right);
430344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
4304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* Canonicalize() override;
4305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void UpdateRepresentation(Representation new_rep,
4307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            HInferRepresentationPhase* h_infer,
4308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            const char* reason) override {
4309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (new_rep.IsSmi()) new_rep = Representation::Integer32();
4310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
4311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
43123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4313257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(Mod)
4314b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4315b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected:
4316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
43171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
4318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Range* InferRange(Zone* zone) override;
4319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
4321109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  HMod(HValue* context, HValue* left, HValue* right)
4322109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : HArithmeticBinaryOperation(context, left, right) {
4323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kCanBeDivByZero);
4324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kCanOverflow);
4325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kLeftCanBeNegative);
4326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
4328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HDiv final : public HArithmeticBinaryOperation {
4331b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
4332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
4333109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                           HValue* left, HValue* right);
4334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* Canonicalize() override;
4336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void UpdateRepresentation(Representation new_rep,
4338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            HInferRepresentationPhase* h_infer,
4339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            const char* reason) override {
4340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (new_rep.IsSmi()) new_rep = Representation::Integer32();
4341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
4342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(Div)
4345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
4347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
4348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Range* InferRange(Zone* zone) override;
4350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
4352109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  HDiv(HValue* context, HValue* left, HValue* right)
4353109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : HArithmeticBinaryOperation(context, left, right) {
4354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetFlag(kCanBeDivByZero);
4355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetFlag(kCanOverflow);
4356b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
4357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
4358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HMathMinMax final : public HArithmeticBinaryOperation {
4361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
4362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum Operation { kMathMin, kMathMax };
4363b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
4365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           HValue* left, HValue* right, Operation op);
43663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation observed_input_representation(int index) override {
4368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return RequiredInputRepresentation(index);
4369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void InferRepresentation(HInferRepresentationPhase* h_infer) override;
4372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RepresentationFromInputs() override {
4374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Representation left_rep = left()->representation();
4375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Representation right_rep = right()->representation();
4376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Representation result = Representation::Smi();
4377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = result.generalize(left_rep);
4378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = result.generalize(right_rep);
4379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (result.IsTagged()) return Representation::Double();
4380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result;
4381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsCommutative() const override { return true; }
4384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Operation operation() { return operation_; }
4386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(MathMinMax)
4388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4389b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected:
4390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override {
4391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return other->IsMathMinMax() &&
4392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        HMathMinMax::cast(other)->operation_ == operation_;
4393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
43941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
4395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Range* InferRange(Zone* zone) override;
4396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
4398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HMathMinMax(HValue* context, HValue* left, HValue* right, Operation op)
4399109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : HArithmeticBinaryOperation(context, left, right), operation_(op) {}
4400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Operation operation_;
4402b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
4403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4404b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HBitwise final : public HBitwiseBinaryOperation {
4406b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
4407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
4408109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                           Token::Value op, HValue* left, HValue* right);
4409c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
44103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Token::Value op() const { return op_; }
441185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
4412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsCommutative() const override { return true; }
4413592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
4414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* Canonicalize() override;
441585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
4416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
441785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
44183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(Bitwise)
441985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
442085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch protected:
4421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override {
44223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return op() == HBitwise::cast(other)->op();
44233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
442485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
4425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Range* InferRange(Zone* zone) override;
44263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
44273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
4428109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  HBitwise(HValue* context, Token::Value op, HValue* left, HValue* right)
4429109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : HBitwiseBinaryOperation(context, left, right), op_(op) {
4430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR);
4431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // BIT_AND with a smi-range positive value will always unset the
4432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // entire sign-extension of the smi-sign.
4433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (op == Token::BIT_AND &&
4434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ((left->IsConstant() &&
4435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          left->representation().IsSmi() &&
4436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          HConstant::cast(left)->Integer32Value() >= 0) ||
4437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         (right->IsConstant() &&
4438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          right->representation().IsSmi() &&
4439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          HConstant::cast(right)->Integer32Value() >= 0))) {
4440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetFlag(kTruncatingToSmi);
4441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetFlag(kTruncatingToInt32);
4442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // BIT_OR with a smi-range negative value will always set the entire
4443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // sign-extension of the smi-sign.
4444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (op == Token::BIT_OR &&
4445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ((left->IsConstant() &&
4446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          left->representation().IsSmi() &&
4447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          HConstant::cast(left)->Integer32Value() < 0) ||
4448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         (right->IsConstant() &&
4449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          right->representation().IsSmi() &&
4450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          HConstant::cast(right)->Integer32Value() < 0))) {
4451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetFlag(kTruncatingToSmi);
4452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetFlag(kTruncatingToInt32);
4453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
44563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Token::Value op_;
4457b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
4458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HShl final : public HBitwiseBinaryOperation {
4461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
4462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
4463109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                           HValue* left, HValue* right);
4464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Range* InferRange(Zone* zone) override;
44663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void UpdateRepresentation(Representation new_rep,
4468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            HInferRepresentationPhase* h_infer,
4469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            const char* reason) override {
4470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (new_rep.IsSmi() &&
4471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        !(right()->IsInteger32Constant() &&
4472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          right()->GetInteger32Constant() >= 0)) {
4473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new_rep = Representation::Integer32();
4474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
4476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4477b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4478257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(Shl)
44791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
44801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block protected:
4481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
4482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
4484109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  HShl(HValue* context, HValue* left, HValue* right)
4485109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : HBitwiseBinaryOperation(context, left, right) {}
4486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
4487b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4488b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HShr final : public HBitwiseBinaryOperation {
4490b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
4491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
4492109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                           HValue* left, HValue* right);
4493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Range* InferRange(Zone* zone) override;
44953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void UpdateRepresentation(Representation new_rep,
4497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            HInferRepresentationPhase* h_infer,
4498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            const char* reason) override {
4499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (new_rep.IsSmi()) new_rep = Representation::Integer32();
4500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
4501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4502b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4503257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(Shr)
45041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
45051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block protected:
4506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
4507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
4509109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  HShr(HValue* context, HValue* left, HValue* right)
4510109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : HBitwiseBinaryOperation(context, left, right) {}
4511b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
4512b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4513b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HSar final : public HBitwiseBinaryOperation {
4515b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
4516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
4517109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                           HValue* left, HValue* right);
4518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Range* InferRange(Zone* zone) override;
4520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void UpdateRepresentation(Representation new_rep,
4522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            HInferRepresentationPhase* h_infer,
4523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            const char* reason) override {
4524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (new_rep.IsSmi()) new_rep = Representation::Integer32();
4525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
4526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4527b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4528257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(Sar)
45291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
45301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block protected:
4531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
4532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
4534109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  HSar(HValue* context, HValue* left, HValue* right)
4535109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : HBitwiseBinaryOperation(context, left, right) {}
4536b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
4537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4538b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HRor final : public HBitwiseBinaryOperation {
4540b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
4541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
4542109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                           HValue* left, HValue* right) {
4543109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return new (zone) HRor(context, left, right);
4544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void UpdateRepresentation(Representation new_rep,
4547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            HInferRepresentationPhase* h_infer,
4548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            const char* reason) override {
4549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (new_rep.IsSmi()) new_rep = Representation::Integer32();
4550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
4551b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
4552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(Ror)
4554b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
4556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
4557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
4559109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  HRor(HValue* context, HValue* left, HValue* right)
4560109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : HBitwiseBinaryOperation(context, left, right) {
4561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ChangeRepresentation(Representation::Integer32());
4562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
4564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HOsrEntry final : public HTemplateInstruction<0> {
4567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
4568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HOsrEntry, BailoutId);
4569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BailoutId ast_id() const { return ast_id_; }
4571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
4573e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::None();
4574e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
4575e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
4576257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
4577b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4578b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
4579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) {
4580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetChangesFlag(kOsrEntries);
4581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetChangesFlag(kNewSpacePromotion);
4582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BailoutId ast_id_;
4585b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
4586b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4587b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HParameter final : public HTemplateInstruction<0> {
4589b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
4590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum ParameterKind {
4591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    STACK_PARAMETER,
4592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    REGISTER_PARAMETER
4593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
4594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HParameter, unsigned);
4596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P2(HParameter, unsigned, ParameterKind);
4597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P3(HParameter, unsigned, ParameterKind,
4598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Representation);
4599b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4600b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned index() const { return index_; }
4601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ParameterKind kind() const { return kind_; }
4602b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
4604e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
4605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
4606e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::None();
4607e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
4608b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation KnownOptimalRepresentation() override {
4610958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // If a parameter is an input to a phi, that phi should not
4611958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // choose any more optimistic representation than Tagged.
4612958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return Representation::Tagged();
4613958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
4614958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
4615257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(Parameter)
4616b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4617b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
4618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HParameter(unsigned index,
4619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      ParameterKind kind = STACK_PARAMETER)
4620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : index_(index),
4621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        kind_(kind) {
4622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
4623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HParameter(unsigned index,
4626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      ParameterKind kind,
4627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      Representation r)
4628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : index_(index),
4629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        kind_(kind) {
4630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(r);
4631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4633b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned index_;
4634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ParameterKind kind_;
4635b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
4636b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4637b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HUnknownOSRValue final : public HTemplateInstruction<0> {
4639b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
4640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P2(HUnknownOSRValue, HEnvironment*, int);
4641b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
4643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
4645e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::None();
4646e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
4647e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
4648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_incoming_value(HPhi* value) { incoming_value_ = value; }
4649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HPhi* incoming_value() { return incoming_value_; }
4650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HEnvironment *environment() { return environment_; }
4651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int index() { return index_; }
46523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation KnownOptimalRepresentation() override {
4654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (incoming_value_ == NULL) return Representation::None();
4655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return incoming_value_->KnownOptimalRepresentation();
46563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
46573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4658257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
46593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
46603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
4661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HUnknownOSRValue(HEnvironment* environment, int index)
4662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : environment_(environment),
4663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        index_(index),
4664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        incoming_value_(NULL) {
4665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
4666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HEnvironment* environment_;
4669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int index_;
46703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HPhi* incoming_value_;
4671b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
4672b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4673bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochclass HAllocate final : public HTemplateInstruction<3> {
4674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
4675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool CompatibleInstanceTypes(InstanceType type1,
4676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      InstanceType type2) {
4677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return ComputeFlags(TENURED, type1) == ComputeFlags(TENURED, type2) &&
4678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ComputeFlags(NOT_TENURED, type1) == ComputeFlags(NOT_TENURED, type2);
4679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
46803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HAllocate* New(
4682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Isolate* isolate, Zone* zone, HValue* context, HValue* size, HType type,
4683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PretenureFlag pretenure_flag, InstanceType instance_type,
4684bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      HValue* dominator,
4685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null()) {
4686bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    return new (zone) HAllocate(context, size, type, pretenure_flag,
4687bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                instance_type, dominator, allocation_site);
4688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
46893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Maximum instance size for which allocations will be inlined.
4691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kMaxInlineSize = 64 * kPointerSize;
4692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* context() const { return OperandAt(0); }
4694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* size() const { return OperandAt(1); }
4695bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  HValue* allocation_folding_dominator() const { return OperandAt(2); }
4696b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
4698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (index == 0) {
4699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return Representation::Tagged();
4700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
4701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return Representation::Integer32();
4702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
47033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Map> GetMonomorphicJSObjectMap() override {
4706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return known_initial_map_;
4707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_known_initial_map(Handle<Map> known_initial_map) {
4710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    known_initial_map_ = known_initial_map;
4711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsNewSpaceAllocation() const {
4714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return (flags_ & ALLOCATE_IN_NEW_SPACE) != 0;
4715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsOldSpaceAllocation() const {
4718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return (flags_ & ALLOCATE_IN_OLD_SPACE) != 0;
4719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool MustAllocateDoubleAligned() const {
4722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return (flags_ & ALLOCATE_DOUBLE_ALIGNED) != 0;
4723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool MustPrefillWithFiller() const {
4726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return (flags_ & PREFILL_WITH_FILLER) != 0;
4727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void MakePrefillWithFiller() {
4730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    flags_ = static_cast<HAllocate::Flags>(flags_ | PREFILL_WITH_FILLER);
4731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void MakeDoubleAligned() {
4734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATE_DOUBLE_ALIGNED);
4735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4737bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void MakeAllocationFoldingDominator() {
4738bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    flags_ =
4739bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        static_cast<HAllocate::Flags>(flags_ | ALLOCATION_FOLDING_DOMINATOR);
4740bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
4741bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
4742f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool IsAllocationFoldingDominator() const {
4743bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    return (flags_ & ALLOCATION_FOLDING_DOMINATOR) != 0;
4744bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
4745bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
4746bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void MakeFoldedAllocation(HAllocate* dominator) {
4747bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATION_FOLDED);
4748bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    ClearFlag(kTrackSideEffectDominators);
4749bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    ClearChangesFlag(kNewSpacePromotion);
4750bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    SetOperandAt(2, dominator);
4751bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
4752bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
4753f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool IsAllocationFolded() const { return (flags_ & ALLOCATION_FOLDED) != 0; }
4754bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
4755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool HandleSideEffectDominator(GVNFlag side_effect,
4756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 HValue* dominator) override;
4757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
4759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(Allocate)
4761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
4763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum Flags {
4764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_IN_NEW_SPACE = 1 << 0,
4765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ALLOCATE_IN_OLD_SPACE = 1 << 2,
4766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_DOUBLE_ALIGNED = 1 << 3,
4767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PREFILL_WITH_FILLER = 1 << 4,
4768bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    ALLOCATION_FOLDING_DOMINATOR = 1 << 5,
4769bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    ALLOCATION_FOLDED = 1 << 6
4770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
4771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4772bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  HAllocate(
4773bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      HValue* context, HValue* size, HType type, PretenureFlag pretenure_flag,
4774bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      InstanceType instance_type, HValue* dominator,
4775bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null())
4776bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      : HTemplateInstruction<3>(type),
4777bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        flags_(ComputeFlags(pretenure_flag, instance_type)) {
4778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, context);
4779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UpdateSize(size);
4780bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    SetOperandAt(2, dominator);
4781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
4782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kTrackSideEffectDominators);
4783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetChangesFlag(kNewSpacePromotion);
4784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetDependsOnFlag(kNewSpacePromotion);
4785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (FLAG_trace_pretenuring) {
4787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrintF("HAllocate with AllocationSite %p %s\n",
4788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             allocation_site.is_null()
4789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 ? static_cast<void*>(NULL)
4790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 : static_cast<void*>(*allocation_site),
4791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             pretenure_flag == TENURED ? "tenured" : "not tenured");
4792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Flags ComputeFlags(PretenureFlag pretenure_flag,
4796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            InstanceType instance_type) {
4797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Flags flags = pretenure_flag == TENURED ? ALLOCATE_IN_OLD_SPACE
4798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            : ALLOCATE_IN_NEW_SPACE;
4799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
4800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      flags = static_cast<Flags>(flags | ALLOCATE_DOUBLE_ALIGNED);
4801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // We have to fill the allocated object with one word fillers if we do
4803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // not use allocation folding since some allocations may depend on each
4804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // other, i.e., have a pointer to each other. A GC in between these
4805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // allocations may leave such objects behind in a not completely initialized
4806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // state.
4807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!FLAG_use_gvn || !FLAG_use_allocation_folding) {
4808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      flags = static_cast<Flags>(flags | PREFILL_WITH_FILLER);
4809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return flags;
4811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void UpdateSize(HValue* size) {
4814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, size);
4815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsFoldable(HAllocate* allocate) {
4818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return (IsNewSpaceAllocation() && allocate->IsNewSpaceAllocation()) ||
4819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           (IsOldSpaceAllocation() && allocate->IsOldSpaceAllocation());
4820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Flags flags_;
4823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Map> known_initial_map_;
4824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
4825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HStoreCodeEntry final : public HTemplateInstruction<2> {
4828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
4829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HStoreCodeEntry* New(Isolate* isolate, Zone* zone, HValue* context,
4830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              HValue* function, HValue* code) {
4831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return new(zone) HStoreCodeEntry(function, code);
48323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4833b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
4835b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return Representation::Tagged();
4836b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
4837b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* function() { return OperandAt(0); }
4839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* code_object() { return OperandAt(1); }
4840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry)
4842b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4843b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
4844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HStoreCodeEntry(HValue* function, HValue* code) {
4845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, function);
4846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, code);
4847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4848b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
4849b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4850b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HInnerAllocatedObject final : public HTemplateInstruction<2> {
48528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch public:
4853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HInnerAllocatedObject* New(Isolate* isolate, Zone* zone,
4854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    HValue* context, HValue* value,
4855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    HValue* offset, HType type) {
4856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return new(zone) HInnerAllocatedObject(value, offset, type);
4857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* base_object() const { return OperandAt(0); }
4860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* offset() const { return OperandAt(1); }
4861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
4863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return index == 0 ? Representation::Tagged() : Representation::Integer32();
4864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
4867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject)
4869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
4871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInnerAllocatedObject(HValue* value,
4872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        HValue* offset,
4873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        HType type) : HTemplateInstruction<2>(type) {
4874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(value->IsAllocate());
4875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(type.IsHeapObject());
4876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, value);
4877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, offset);
48788b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    set_representation(Representation::Tagged());
48798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
4880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
48818b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
48828b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
4883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline bool StoringValueNeedsWriteBarrier(HValue* value) {
4884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return !value->type().IsSmi()
4885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      && !value->type().IsNull()
4886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      && !value->type().IsBoolean()
4887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      && !value->type().IsUndefined()
4888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable());
4889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
48918b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
4892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline bool ReceiverObjectNeedsWriteBarrier(HValue* object,
4893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            HValue* value,
4894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            HValue* dominator) {
4895bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // There may be multiple inner allocates dominated by one allocate.
4896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (object->IsInnerAllocatedObject()) {
4897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    object = HInnerAllocatedObject::cast(object)->base_object();
4898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4899bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
4900bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (object->IsAllocate()) {
4901bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    HAllocate* allocate = HAllocate::cast(object);
4902bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (allocate->IsAllocationFolded()) {
4903bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      HValue* dominator = allocate->allocation_folding_dominator();
490413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // There is no guarantee that all allocations are folded together because
490513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // GVN performs a fixpoint.
490613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (HAllocate::cast(dominator)->IsAllocationFoldingDominator()) {
490713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        object = dominator;
490813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
4909bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
4910bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
4911bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
4912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (object->IsConstant() &&
4913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HConstant::cast(object)->HasExternalReferenceValue()) {
4914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Stores to external references require no write barriers
4915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
4916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We definitely need a write barrier unless the object is the allocation
4918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // dominator.
4919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (object == dominator && object->IsAllocate()) {
4920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Stores to new space allocations require no write barriers.
4921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (HAllocate::cast(object)->IsNewSpaceAllocation()) {
4922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return false;
4923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
4926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline PointersToHereCheck PointersToHereCheckForObject(HValue* object,
4930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        HValue* dominator) {
4931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (object->IsInnerAllocatedObject()) {
4932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    object = HInnerAllocatedObject::cast(object)->base_object();
4933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (object == dominator &&
4935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      object->IsAllocate() &&
4936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HAllocate::cast(object)->IsNewSpaceAllocation()) {
4937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return kPointersToHereAreAlwaysInteresting;
4938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return kPointersToHereMaybeInteresting;
4940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HLoadContextSlot final : public HUnaryOperation {
4944b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch public:
49453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  enum Mode {
49463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Perform a normal load of the context slot without checking its value.
49473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kNoCheck,
49483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Load and check the value of the context slot. Deoptimize if it's the
49493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // hole value. This is used for checking for loading of uninitialized
49503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // harmony bindings where we deoptimize into full-codegen generated code
49513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // which will subsequently throw a reference error.
4952bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    kCheckDeoptimize
49533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
49543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HLoadContextSlot(HValue* context, int slot_index, Mode mode)
4956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HUnaryOperation(context), slot_index_(slot_index), mode_(mode) {
4957b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    set_representation(Representation::Tagged());
4958b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    SetFlag(kUseGVN);
4959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetDependsOnFlag(kContextSlots);
4960b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
4961b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
4962b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int slot_index() const { return slot_index_; }
49633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Mode mode() const { return mode_; }
49643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
49653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool DeoptimizesOnHole() {
49663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return mode_ == kCheckDeoptimize;
49673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4968c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
4969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool RequiresHoleCheck() const {
49703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return mode_ != kNoCheck;
49713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
49723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
49741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return Representation::Tagged();
4975b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
4976b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
4977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
49781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
4979257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
4980b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
4981b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch protected:
4982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override {
4983b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    HLoadContextSlot* b = HLoadContextSlot::cast(other);
49841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return (slot_index() == b->slot_index());
4985b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
4986b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
4987b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private:
4988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override { return !RequiresHoleCheck(); }
4989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
49901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  int slot_index_;
49913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Mode mode_;
49921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
49931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
49941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
4995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HStoreContextSlot final : public HTemplateInstruction<2> {
49961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public:
49973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  enum Mode {
49983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Perform a normal store to the context slot without checking its previous
49993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // value.
50003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kNoCheck,
50013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Check the previous value of the context slot and deoptimize if it's the
50023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // hole value. This is used for checking for assignments to uninitialized
50033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // harmony bindings where we deoptimize into full-codegen generated code
50043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // which will subsequently throw a reference error.
5005bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    kCheckDeoptimize
50063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
50073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P4(HStoreContextSlot, HValue*, int,
5009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Mode, HValue*);
50101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* context() const { return OperandAt(0); }
5012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* value() const { return OperandAt(1); }
50131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  int slot_index() const { return slot_index_; }
50143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Mode mode() const { return mode_; }
50151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5016e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  bool NeedsWriteBarrier() {
50171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return StoringValueNeedsWriteBarrier(value());
50181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
50191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
50203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool DeoptimizesOnHole() {
50213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return mode_ == kCheckDeoptimize;
50223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
50233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
50243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool RequiresHoleCheck() {
50253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return mode_ != kNoCheck;
50263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
50273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
50291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return Representation::Tagged();
50301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
50311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
50331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5034257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
50351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
50361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block private:
5037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HStoreContextSlot(HValue* context, int slot_index, Mode mode, HValue* value)
5038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : slot_index_(slot_index), mode_(mode) {
5039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, context);
5040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, value);
5041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetChangesFlag(kContextSlots);
5042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5044b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  int slot_index_;
50453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Mode mode_;
5046b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch};
5047b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
5048b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
5049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Represents an access to a portion of an object, such as the map pointer,
5050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// array elements pointer, etc, but not accesses to array elements themselves.
5051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HObjectAccess final {
5052b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
5053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline bool IsInobject() const {
5054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return portion() != kBackingStore && portion() != kExternalMemory;
5055b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5056b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline bool IsExternalMemory() const {
5058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return portion() == kExternalMemory;
5059b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5060b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline bool IsStringLength() const {
5062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return portion() == kStringLengths;
5063b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5064b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline bool IsMap() const {
5066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return portion() == kMaps;
506744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
506844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline int offset() const {
5070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return OffsetField::decode(value_);
5071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
507269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
5073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline Representation representation() const {
5074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Representation::FromKind(RepresentationField::decode(value_));
5075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
507644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline Handle<Name> name() const { return name_; }
507844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline bool immutable() const {
5080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return ImmutableField::decode(value_);
5081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
508244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Returns true if access is being made to an in-object property that
5084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // was already added to the object.
5085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline bool existing_inobject_property() const {
5086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return ExistingInobjectPropertyField::decode(value_);
5087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
508844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline HObjectAccess WithRepresentation(Representation representation) {
5090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(portion(), offset(), representation, name(),
5091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         immutable(), existing_inobject_property());
5092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
509344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForHeapNumberValue() {
5095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(
5096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        kDouble, HeapNumber::kValueOffset, Representation::Double());
5097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
509844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForHeapNumberValueLowestBits() {
5100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kDouble,
5101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         HeapNumber::kValueOffset,
5102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Representation::Integer32());
5103b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForHeapNumberValueHighestBits() {
5106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kDouble,
5107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         HeapNumber::kValueOffset + kIntSize,
5108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Representation::Integer32());
5109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5110b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HObjectAccess ForOddballToNumber(
5112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Representation representation = Representation::Tagged()) {
5113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return HObjectAccess(kInobject, Oddball::kToNumberOffset, representation);
5114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HObjectAccess ForOddballTypeOf() {
5117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return HObjectAccess(kInobject, Oddball::kTypeOfOffset,
5118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         Representation::HeapObject());
5119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForElementsPointer() {
5122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kElementsPointer, JSObject::kElementsOffset);
5123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForNextFunctionLinkPointer() {
5126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kInobject, JSFunction::kNextFunctionLinkOffset);
5127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForArrayLength(ElementsKind elements_kind) {
5130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(
5131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        kArrayLengths,
5132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        JSArray::kLengthOffset,
5133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        IsFastElementsKind(elements_kind)
5134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            ? Representation::Smi() : Representation::Tagged());
5135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForAllocationSiteOffset(int offset);
5138b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForAllocationSiteList() {
5140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kExternalMemory, 0, Representation::Tagged(),
5141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         Handle<Name>::null(), false, false);
51429fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  }
51439fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
5144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForFixedArrayLength() {
5145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(
5146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        kArrayLengths,
5147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        FixedArray::kLengthOffset,
5148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Representation::Smi());
5149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
51509fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
5151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HObjectAccess ForFixedTypedArrayBaseBasePointer() {
5152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return HObjectAccess(kInobject, FixedTypedArrayBase::kBasePointerOffset,
5153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         Representation::Tagged());
5154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HObjectAccess ForFixedTypedArrayBaseExternalPointer() {
5157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return HObjectAccess::ForObservableJSObjectOffset(
5158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        FixedTypedArrayBase::kExternalPointerOffset,
5159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Representation::External());
5160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForStringHashField() {
5163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kInobject,
5164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         String::kHashFieldOffset,
5165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Representation::Integer32());
51669fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  }
51679fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
5168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForStringLength() {
5169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
5170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(
5171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        kStringLengths,
5172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        String::kLengthOffset,
5173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Representation::Smi());
5174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
51759fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
5176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForConsStringFirst() {
5177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kInobject, ConsString::kFirstOffset);
5178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
51799fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
5180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForConsStringSecond() {
5181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kInobject, ConsString::kSecondOffset);
5182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
51839fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
5184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForPropertiesPointer() {
5185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kInobject, JSObject::kPropertiesOffset);
5186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
51873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForPrototypeOrInitialMap() {
5189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kInobject, JSFunction::kPrototypeOrInitialMapOffset);
5190b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5191b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForSharedFunctionInfoPointer() {
5193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kInobject, JSFunction::kSharedFunctionInfoOffset);
5194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5195e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
5196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForCodeEntryPointer() {
5197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kInobject, JSFunction::kCodeEntryOffset);
5198b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5199b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForCodeOffset() {
5201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kInobject, SharedFunctionInfo::kCodeOffset);
5202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5203e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
5204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForOptimizedCodeMap() {
5205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kInobject,
5206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         SharedFunctionInfo::kOptimizedCodeMapOffset);
5207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5208257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
5209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForFunctionContextPointer() {
5210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kInobject, JSFunction::kContextOffset);
5211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
52121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForMap() {
5214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kMaps, JSObject::kMapOffset);
52153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
52163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static HObjectAccess ForPrototype() {
5218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return HObjectAccess(kMaps, Map::kPrototypeOffset);
5219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
5220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
5221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForMapAsInteger32() {
5222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kMaps, JSObject::kMapOffset,
5223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Representation::Integer32());
5224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
52251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HObjectAccess ForMapInObjectPropertiesOrConstructorFunctionIndex() {
5227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return HObjectAccess(
5228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        kInobject, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset,
5229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Representation::UInteger8());
5230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
52311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForMapInstanceType() {
5233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kInobject,
5234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Map::kInstanceTypeOffset,
5235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Representation::UInteger8());
52363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
52373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForMapInstanceSize() {
5239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kInobject,
5240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Map::kInstanceSizeOffset,
5241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Representation::UInteger8());
5242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
52433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForMapBitField() {
5245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kInobject,
5246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Map::kBitFieldOffset,
5247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Representation::UInteger8());
52483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
52493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForMapBitField2() {
5251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kInobject,
5252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Map::kBitField2Offset,
5253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Representation::UInteger8());
5254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
52553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5256109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  static HObjectAccess ForMapBitField3() {
5257109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return HObjectAccess(kInobject, Map::kBitField3Offset,
5258109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                         Representation::Integer32());
5259109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
5260109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
52613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static HObjectAccess ForMapDescriptors() {
52623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return HObjectAccess(kInobject, Map::kDescriptorsOffset);
52633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
52643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
5265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForNameHashField() {
5266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kInobject,
5267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Name::kHashFieldOffset,
5268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Representation::Integer32());
5269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
52703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForMapInstanceTypeAndBitField() {
5272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    STATIC_ASSERT((Map::kInstanceTypeAndBitFieldOffset & 1) == 0);
5273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Ensure the two fields share one 16-bit word, endian-independent.
5274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    STATIC_ASSERT((Map::kBitFieldOffset & ~1) ==
5275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  (Map::kInstanceTypeOffset & ~1));
5276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kInobject,
5277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Map::kInstanceTypeAndBitFieldOffset,
5278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Representation::UInteger16());
5279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
52803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForPropertyCellValue() {
5282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kInobject, PropertyCell::kValueOffset);
5283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
52843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HObjectAccess ForPropertyCellDetails() {
5286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return HObjectAccess(kInobject, PropertyCell::kDetailsOffset,
5287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         Representation::Smi());
5288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForCellValue() {
5291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kInobject, Cell::kValueOffset);
52921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
52931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static HObjectAccess ForWeakCellValue() {
5295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return HObjectAccess(kInobject, WeakCell::kValueOffset);
5296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
5297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
5298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HObjectAccess ForWeakCellNext() {
5299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return HObjectAccess(kInobject, WeakCell::kNextOffset);
5300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForAllocationMementoSite() {
5303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset);
5304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
53051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForCounter() {
5307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kExternalMemory, 0, Representation::Integer32(),
5308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         Handle<Name>::null(), false, false);
53091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
53101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForExternalUInteger8() {
5312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess(kExternalMemory, 0, Representation::UInteger8(),
5313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         Handle<Name>::null(), false, false);
5314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
53151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
531613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  static HObjectAccess ForBoundTargetFunction() {
531713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return HObjectAccess(kInobject,
531813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                         JSBoundFunction::kBoundTargetFunctionOffset);
531913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
532013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
532113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  static HObjectAccess ForBoundThis() {
532213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return HObjectAccess(kInobject, JSBoundFunction::kBoundThisOffset);
532313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
532413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
532513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  static HObjectAccess ForBoundArguments() {
532613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return HObjectAccess(kInobject, JSBoundFunction::kBoundArgumentsOffset);
532713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
532813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
5329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create an access to an offset in a fixed array header.
5330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForFixedArrayHeader(int offset);
53313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create an access to an in-object property in a JSObject.
5333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This kind of access must be used when the object |map| is known and
5334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // in-object properties are being accessed. Accesses of the in-object
5335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // properties can have different semantics depending on whether corresponding
5336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // property was added to the map or not.
5337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForMapAndOffset(Handle<Map> map, int offset,
5338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Representation representation = Representation::Tagged());
53391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create an access to an in-object property in a JSObject.
5341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This kind of access can be used for accessing object header fields or
5342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // in-object properties if the map of the object is not known.
5343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForObservableJSObjectOffset(int offset,
5344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Representation representation = Representation::Tagged()) {
5345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return ForMapAndOffset(Handle<Map>::null(), offset, representation);
534644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
534744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create an access to an in-object property in a JSArray.
5349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForJSArrayOffset(int offset);
5350b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForContextSlot(int index);
5352b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static HObjectAccess ForScriptContext(int index);
5354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
5355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create an access to the backing store of an object.
5356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForBackingStoreOffset(int offset,
5357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Representation representation = Representation::Tagged());
53581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create an access to a resolved field (in-object or backing store).
5360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForField(Handle<Map> map, int index,
5361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                Representation representation,
5362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                Handle<Name> name);
5363b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForJSTypedArrayLength() {
5365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess::ForObservableJSObjectOffset(
5366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        JSTypedArray::kLengthOffset);
5367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5368b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForJSArrayBufferBackingStore() {
5370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess::ForObservableJSObjectOffset(
5371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        JSArrayBuffer::kBackingStoreOffset, Representation::External());
5372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
53733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForJSArrayBufferByteLength() {
5375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess::ForObservableJSObjectOffset(
5376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        JSArrayBuffer::kByteLengthOffset, Representation::Tagged());
5377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HObjectAccess ForJSArrayBufferBitField() {
5380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess::ForObservableJSObjectOffset(
5381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        JSArrayBuffer::kBitFieldOffset, Representation::Integer32());
5382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5383b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HObjectAccess ForJSArrayBufferBitFieldSlot() {
5385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess::ForObservableJSObjectOffset(
5386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        JSArrayBuffer::kBitFieldSlot, Representation::Smi());
5387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForJSArrayBufferViewBuffer() {
5390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess::ForObservableJSObjectOffset(
5391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        JSArrayBufferView::kBufferOffset);
5392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5393e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
5394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForJSArrayBufferViewByteOffset() {
5395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess::ForObservableJSObjectOffset(
5396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        JSArrayBufferView::kByteOffsetOffset);
5397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static HObjectAccess ForJSArrayBufferViewByteLength() {
5400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HObjectAccess::ForObservableJSObjectOffset(
5401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        JSArrayBufferView::kByteLengthOffset);
5402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HObjectAccess ForJSGlobalObjectNativeContext() {
5405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return HObjectAccess(kInobject, JSGlobalObject::kNativeContextOffset);
5406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HObjectAccess ForJSRegExpFlags() {
5409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return HObjectAccess(kInobject, JSRegExp::kFlagsOffset);
5410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HObjectAccess ForJSRegExpSource() {
5413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return HObjectAccess(kInobject, JSRegExp::kSourceOffset);
54141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
54151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5416958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static HObjectAccess ForJSCollectionTable() {
5417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return HObjectAccess::ForObservableJSObjectOffset(
5418958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        JSCollection::kTableOffset);
5419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
5420958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
5421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  template <typename CollectionType>
5422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static HObjectAccess ForOrderedHashTableNumberOfBuckets() {
5423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return HObjectAccess(kInobject, CollectionType::kNumberOfBucketsOffset,
5424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                         Representation::Smi());
5425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
5426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
5427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  template <typename CollectionType>
5428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static HObjectAccess ForOrderedHashTableNumberOfElements() {
5429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return HObjectAccess(kInobject, CollectionType::kNumberOfElementsOffset,
5430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                         Representation::Smi());
5431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
5432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
5433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  template <typename CollectionType>
5434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static HObjectAccess ForOrderedHashTableNumberOfDeletedElements() {
5435958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return HObjectAccess(kInobject,
5436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                         CollectionType::kNumberOfDeletedElementsOffset,
5437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                         Representation::Smi());
5438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
5439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
5440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  template <typename CollectionType>
5441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static HObjectAccess ForOrderedHashTableNextTable() {
5442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return HObjectAccess(kInobject, CollectionType::kNextTableOffset);
5443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
5444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
5445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  template <typename CollectionType>
5446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static HObjectAccess ForOrderedHashTableBucket(int bucket) {
5447958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return HObjectAccess(kInobject, CollectionType::kHashTableStartOffset +
5448958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                        (bucket * kPointerSize),
5449958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                         Representation::Smi());
5450958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
5451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
5452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Access into the data table of an OrderedHashTable with a
5453958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // known-at-compile-time bucket count.
5454958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  template <typename CollectionType, int kBucketCount>
5455958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static HObjectAccess ForOrderedHashTableDataTableIndex(int index) {
5456958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return HObjectAccess(kInobject, CollectionType::kHashTableStartOffset +
5457958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                        (kBucketCount * kPointerSize) +
5458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                        (index * kPointerSize));
5459958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
5460958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
5461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline bool Equals(HObjectAccess that) const {
5462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return value_ == that.value_;  // portion and offset must match
5463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
5466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SetGVNFlags(HValue *instr, PropertyAccessType access_type);
5467b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
5469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // internal use only; different parts of an object or array
5470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum Portion {
5471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kMaps,             // map of an object
5472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kArrayLengths,     // the length of an array
5473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kStringLengths,    // the length of a string
5474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kElementsPointer,  // elements pointer
5475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kBackingStore,     // some field in the backing store
5476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kDouble,           // some double field
5477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kInobject,         // some other in-object field
5478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kExternalMemory    // some field in external memory
5479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
54801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HObjectAccess() : value_(0) {}
5482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HObjectAccess(Portion portion, int offset,
5484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                Representation representation = Representation::Tagged(),
5485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                Handle<Name> name = Handle<Name>::null(),
5486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                bool immutable = false, bool existing_inobject_property = true)
5487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : value_(PortionField::encode(portion) |
5488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               RepresentationField::encode(representation.kind()) |
5489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               ImmutableField::encode(immutable ? 1 : 0) |
5490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               ExistingInobjectPropertyField::encode(
5491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   existing_inobject_property ? 1 : 0) |
5492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               OffsetField::encode(offset)),
5493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        name_(name) {
5494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // assert that the fields decode correctly
5495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(this->offset() == offset);
5496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(this->portion() == portion);
5497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(this->immutable() == immutable);
5498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(this->existing_inobject_property() == existing_inobject_property);
5499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(RepresentationField::decode(value_) == representation.kind());
5500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!this->existing_inobject_property() || IsInobject());
5501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class PortionField : public BitField<Portion, 0, 3> {};
5504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class RepresentationField : public BitField<Representation::Kind, 3, 4> {};
5505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class ImmutableField : public BitField<bool, 7, 1> {};
5506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class ExistingInobjectPropertyField : public BitField<bool, 8, 1> {};
5507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class OffsetField : public BitField<int, 9, 23> {};
5508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t value_;  // encodes portion, representation, immutable, and offset
5510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Name> name_;
55111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class HLoadNamedField;
5513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class HStoreNamedField;
5514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class SideEffectsTracker;
5515958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  friend std::ostream& operator<<(std::ostream& os,
5516958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                  const HObjectAccess& access);
55171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline Portion portion() const {
5519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return PortionField::decode(value_);
5520b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
5522b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
55231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5524958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream& os, const HObjectAccess& access);
5525b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HLoadNamedField final : public HTemplateInstruction<2> {
5528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
5529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P3(HLoadNamedField, HValue*,
5530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 HValue*, HObjectAccess);
5531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P5(HLoadNamedField, HValue*, HValue*,
5532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 HObjectAccess, const UniqueSet<Map>*, HType);
5533b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* object() const { return OperandAt(0); }
5535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* dependency() const {
5536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(HasDependency());
5537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return OperandAt(1);
5538b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasDependency() const { return OperandAt(0) != OperandAt(1); }
5540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HObjectAccess access() const { return access_; }
5541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Representation field_representation() const {
5542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return access_.representation();
55433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
5544b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const UniqueSet<Map>* maps() const { return maps_; }
5546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool HasEscapingOperandAt(int index) override { return false; }
5548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool HasOutOfBoundsAccess(int size) override {
5549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return !access().IsInobject() || access().offset() >= size;
5550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
5552958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (index == 0) {
5553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // object must be external in case of external memory access
5554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return access().IsExternalMemory() ? Representation::External()
5555958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                         : Representation::Tagged();
55563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
5557958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(index == 1);
5558958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return Representation::None();
5559592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch  }
5560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Range* InferRange(Zone* zone) override;
5561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
5562592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
5563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool CanBeReplacedWith(HValue* other) const {
5564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!CheckFlag(HValue::kCantBeReplaced)) return false;
5565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!type().Equals(other->type())) return false;
5566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!representation().Equals(other->representation())) return false;
5567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!other->IsLoadNamedField()) return true;
5568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HLoadNamedField* that = HLoadNamedField::cast(other);
5569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (this->maps_ == that->maps_) return true;
5570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (this->maps_ == NULL || that->maps_ == NULL) return false;
5571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return this->maps_->IsSubset(that->maps_);
5572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5573b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
5575b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
5577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override {
5578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HLoadNamedField* that = HLoadNamedField::cast(other);
5579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!this->access_.Equals(that->access_)) return false;
5580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (this->maps_ == that->maps_) return true;
5581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return (this->maps_ != NULL &&
5582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            that->maps_ != NULL &&
5583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            this->maps_->Equals(that->maps_));
55843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
55853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
5587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HLoadNamedField(HValue* object,
5588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  HValue* dependency,
5589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  HObjectAccess access)
5590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : access_(access), maps_(NULL) {
5591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK_NOT_NULL(object);
5592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, object);
5593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, dependency ? dependency : object);
5594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Representation representation = access.representation();
5596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (representation.IsInteger8() ||
5597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        representation.IsUInteger8() ||
5598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        representation.IsInteger16() ||
5599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        representation.IsUInteger16()) {
5600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      set_representation(Representation::Integer32());
5601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (representation.IsSmi()) {
5602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      set_type(HType::Smi());
5603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (SmiValuesAre32Bits()) {
5604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        set_representation(Representation::Integer32());
5605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
5606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        set_representation(representation);
5607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
5608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (representation.IsDouble() ||
5609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               representation.IsExternal() ||
5610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               representation.IsInteger32()) {
5611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      set_representation(representation);
5612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (representation.IsHeapObject()) {
5613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      set_type(HType::HeapObject());
5614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      set_representation(Representation::Tagged());
56153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    } else {
5616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      set_representation(Representation::Tagged());
56173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
5618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    access.SetGVNFlags(this, LOAD);
56193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
56203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HLoadNamedField(HValue* object,
5622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  HValue* dependency,
5623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  HObjectAccess access,
5624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  const UniqueSet<Map>* maps,
5625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  HType type)
5626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HTemplateInstruction<2>(type), access_(access), maps_(maps) {
5627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK_NOT_NULL(maps);
5628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK_NE(0, maps->size());
56293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK_NOT_NULL(object);
5631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, object);
5632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, dependency ? dependency : object);
5633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(access.representation().IsHeapObject());
5635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(type.IsHeapObject());
5636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
5637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    access.SetGVNFlags(this, LOAD);
56393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
56403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override { return true; }
56423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HObjectAccess access_;
5644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const UniqueSet<Map>* maps_;
56453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch};
56463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
56473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HLoadFunctionPrototype final : public HUnaryOperation {
5649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
5650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HLoadFunctionPrototype, HValue*);
5651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* function() { return OperandAt(0); }
5653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
5655e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::Tagged();
5656b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5657b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
56591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
5661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
56628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
56638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch private:
5664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HLoadFunctionPrototype(HValue* function)
5665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HUnaryOperation(function) {
5666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
5667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kUseGVN);
5668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetDependsOnFlag(kCalls);
5669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
5671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ArrayInstructionInterface {
5673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
5674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual HValue* GetKey() = 0;
5675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual void SetKey(HValue* key) = 0;
5676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ElementsKind elements_kind() const = 0;
5677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TryIncreaseBaseOffset returns false if overflow would result.
5678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual bool TryIncreaseBaseOffset(uint32_t increase_by_value) = 0;
5679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual bool IsDehoisted() const = 0;
5680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual void SetDehoisted(bool is_dehoisted) = 0;
5681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~ArrayInstructionInterface() { }
5682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Representation KeyedAccessIndexRequirement(Representation r) {
5684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return r.IsInteger32() || SmiValuesAre32Bits()
5685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ? Representation::Integer32() : Representation::Smi();
5686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
56873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
56883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
56893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kDefaultKeyedHeaderOffsetSentinel = -1;
5691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum LoadKeyedHoleMode {
5693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NEVER_RETURN_HOLE,
5694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ALLOW_RETURN_HOLE,
5695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CONVERT_HOLE_TO_UNDEFINED
5696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
5697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HLoadKeyed final : public HTemplateInstruction<4>,
5700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         public ArrayInstructionInterface {
57013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
5702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DECLARE_INSTRUCTION_FACTORY_P5(HLoadKeyed, HValue*, HValue*, HValue*, HValue*,
5703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 ElementsKind);
5704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DECLARE_INSTRUCTION_FACTORY_P6(HLoadKeyed, HValue*, HValue*, HValue*, HValue*,
5705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 ElementsKind, LoadKeyedHoleMode);
5706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DECLARE_INSTRUCTION_FACTORY_P7(HLoadKeyed, HValue*, HValue*, HValue*, HValue*,
5707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 ElementsKind, LoadKeyedHoleMode, int);
5708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_fixed_typed_array() const {
5710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return IsFixedTypedArrayElementsKind(elements_kind());
5711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* elements() const { return OperandAt(0); }
5713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* key() const { return OperandAt(1); }
5714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* dependency() const {
5715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(HasDependency());
5716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return OperandAt(2);
5717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasDependency() const { return OperandAt(0) != OperandAt(2); }
5719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* backing_store_owner() const {
5720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(HasBackingStoreOwner());
5721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return OperandAt(3);
5722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool HasBackingStoreOwner() const { return OperandAt(0) != OperandAt(3); }
5724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t base_offset() const { return BaseOffsetField::decode(bit_field_); }
5725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool TryIncreaseBaseOffset(uint32_t increase_by_value) override;
5726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* GetKey() override { return key(); }
5727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void SetKey(HValue* key) override { SetOperandAt(1, key); }
5728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDehoisted() const override {
5729958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return IsDehoistedField::decode(bit_field_);
5730958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
5731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void SetDehoisted(bool is_dehoisted) override {
5732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted);
5733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ElementsKind elements_kind() const override {
5735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return ElementsKindField::decode(bit_field_);
5736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LoadKeyedHoleMode hole_mode() const {
5738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HoleModeField::decode(bit_field_);
57393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
57403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
5742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // kind_fast:                 tagged[int32] (none)
5743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // kind_double:               tagged[int32] (none)
5744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // kind_fixed_typed_array:    external[int32] (none)
5745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // kind_external:             external[int32] (none)
5746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (index == 0) {
5747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return is_fixed_typed_array() ? Representation::External()
5748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    : Representation::Tagged();
5749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
5750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (index == 1) {
5751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return ArrayInstructionInterface::KeyedAccessIndexRequirement(
5752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          OperandAt(1)->representation());
5753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
5754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (index == 2) {
5755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return Representation::None();
5756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
5757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(3, index);
5758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return HasBackingStoreOwner() ? Representation::Tagged()
5759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  : Representation::None();
57603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
57613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation observed_input_representation(int index) override {
5763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return RequiredInputRepresentation(index);
5764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
57653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
57673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool UsesMustHandleHole() const;
5769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool AllUsesCanTreatHoleAsNaN() const;
5770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool RequiresHoleCheck() const;
5771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Range* InferRange(Zone* zone) override;
5773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(LoadKeyed)
57753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
57763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch protected:
5777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override {
5778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!other->IsLoadKeyed()) return false;
5779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HLoadKeyed* other_load = HLoadKeyed::cast(other);
5780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5781958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (base_offset() != other_load->base_offset()) return false;
5782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return elements_kind() == other_load->elements_kind();
57833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
57843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
57853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
5786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HLoadKeyed(HValue* obj, HValue* key, HValue* dependency,
5787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             HValue* backing_store_owner, ElementsKind elements_kind,
5788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             LoadKeyedHoleMode mode = NEVER_RETURN_HOLE,
5789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             int offset = kDefaultKeyedHeaderOffsetSentinel)
5790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : bit_field_(0) {
5791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    offset = offset == kDefaultKeyedHeaderOffsetSentinel
5792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ? GetDefaultHeaderSizeForElementsKind(elements_kind)
5793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        : offset;
5794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bit_field_ = ElementsKindField::encode(elements_kind) |
5795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        HoleModeField::encode(mode) |
5796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        BaseOffsetField::encode(offset);
57978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
5798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, obj);
5799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, key);
5800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetOperandAt(2, dependency != nullptr ? dependency : obj);
5801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetOperandAt(3, backing_store_owner != nullptr ? backing_store_owner : obj);
5802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(HasBackingStoreOwner(), is_fixed_typed_array());
5803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!is_fixed_typed_array()) {
5805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // I can detect the case between storing double (holey and fast) and
5806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // smi/object by looking at elements_kind_.
5807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
5808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             IsFastDoubleElementsKind(elements_kind));
5809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (IsFastSmiOrObjectElementsKind(elements_kind)) {
5811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (IsFastSmiElementsKind(elements_kind) &&
5812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            (!IsHoleyElementsKind(elements_kind) ||
5813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             mode == NEVER_RETURN_HOLE)) {
5814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          set_type(HType::Smi());
5815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          if (SmiValuesAre32Bits() && !RequiresHoleCheck()) {
5816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            set_representation(Representation::Integer32());
5817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          } else {
5818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            set_representation(Representation::Smi());
5819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
5820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else {
5821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          set_representation(Representation::Tagged());
5822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
5823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        SetDependsOnFlag(kArrayElements);
5825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
5826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        set_representation(Representation::Double());
5827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        SetDependsOnFlag(kDoubleArrayElements);
5828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
5829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
5830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (elements_kind == FLOAT32_ELEMENTS ||
5831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          elements_kind == FLOAT64_ELEMENTS) {
5832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        set_representation(Representation::Double());
5833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
5834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        set_representation(Representation::Integer32());
5835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
5836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (is_fixed_typed_array()) {
5838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        SetDependsOnFlag(kExternalMemory);
5839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        SetDependsOnFlag(kTypedArrayElements);
5840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
5841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        UNREACHABLE();
5842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
5843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Native code could change the specialized array.
5844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetDependsOnFlag(kCalls);
5845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
58468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
5847257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    SetFlag(kUseGVN);
5848257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
5849257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
5850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override { return !RequiresHoleCheck(); }
5851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Establish some checks around our packed fields
5853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum LoadKeyedBits {
5854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kBitsForElementsKind = 5,
5855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kBitsForHoleMode = 2,
5856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kBitsForBaseOffset = 24,
5857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kBitsForIsDehoisted = 1,
5858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kStartElementsKind = 0,
5860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kStartHoleMode = kStartElementsKind + kBitsForElementsKind,
5861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kStartBaseOffset = kStartHoleMode + kBitsForHoleMode,
5862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kStartIsDehoisted = kStartBaseOffset + kBitsForBaseOffset
5863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
5864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5865958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  STATIC_ASSERT((kBitsForElementsKind + kBitsForHoleMode + kBitsForBaseOffset +
5866958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                 kBitsForIsDehoisted) <= sizeof(uint32_t) * 8);
5867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kElementsKindCount <= (1 << kBitsForElementsKind));
5868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class ElementsKindField:
5869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    public BitField<ElementsKind, kStartElementsKind, kBitsForElementsKind>
5870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {};  // NOLINT
5871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class HoleModeField:
5872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    public BitField<LoadKeyedHoleMode, kStartHoleMode, kBitsForHoleMode>
5873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {};  // NOLINT
5874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class BaseOffsetField:
5875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    public BitField<uint32_t, kStartBaseOffset, kBitsForBaseOffset>
5876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {};  // NOLINT
5877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class IsDehoistedField:
5878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    public BitField<bool, kStartIsDehoisted, kBitsForIsDehoisted>
5879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {};  // NOLINT
5880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t bit_field_;
5881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
5882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Indicates whether the store is a store to an entry that was previously
5885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// initialized or not.
5886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum StoreFieldOrKeyedMode {
5887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The entry could be either previously initialized or not.
5888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  INITIALIZING_STORE,
5889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // At the time of this store it is guaranteed that the entry is already
5890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // initialized.
5891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STORE_TO_INITIALIZED_ENTRY
5892257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
5893257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
5894257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
5895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HStoreNamedField final : public HTemplateInstruction<3> {
58961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public:
5897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P3(HStoreNamedField, HValue*,
5898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 HObjectAccess, HValue*);
5899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P4(HStoreNamedField, HValue*,
5900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 HObjectAccess, HValue*, StoreFieldOrKeyedMode);
5901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
5903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool HasEscapingOperandAt(int index) override { return index == 1; }
5905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool HasOutOfBoundsAccess(int size) override {
5906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return !access().IsInobject() || access().offset() >= size;
5907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
5909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (index == 0 && access().IsExternalMemory()) {
5910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // object must be external in case of external memory access
5911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return Representation::External();
5912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (index == 1) {
5913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (field_representation().IsInteger8() ||
5914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          field_representation().IsUInteger8() ||
5915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          field_representation().IsInteger16() ||
5916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          field_representation().IsUInteger16() ||
5917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          field_representation().IsInteger32()) {
5918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return Representation::Integer32();
5919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (field_representation().IsDouble()) {
5920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return field_representation();
5921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (field_representation().IsSmi()) {
5922958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        if (SmiValuesAre32Bits() &&
5923958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            store_mode() == STORE_TO_INITIALIZED_ENTRY) {
5924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return Representation::Integer32();
5925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
5926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return field_representation();
5927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (field_representation().IsExternal()) {
5928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return Representation::External();
5929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
5930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
5931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Representation::Tagged();
5932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool HandleSideEffectDominator(GVNFlag side_effect,
5934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 HValue* dominator) override {
5935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(side_effect == kNewSpacePromotion);
5936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!FLAG_use_write_barrier_elimination) return false;
5937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    dominator_ = dominator;
5938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
5939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
59411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* object() const { return OperandAt(0); }
5943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* value() const { return OperandAt(1); }
5944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* transition() const { return OperandAt(2); }
5945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HObjectAccess access() const { return access_; }
5947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* dominator() const { return dominator_; }
5948958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool has_transition() const { return HasTransitionField::decode(bit_field_); }
5949958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  StoreFieldOrKeyedMode store_mode() const {
5950958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return StoreModeField::decode(bit_field_);
5951958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
5952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Map> transition_map() const {
5954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (has_transition()) {
5955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return Handle<Map>::cast(
5956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          HConstant::cast(transition())->handle(isolate()));
5957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
5958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return Handle<Map>();
5959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
59601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
59611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SetTransition(HConstant* transition) {
5963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!has_transition());  // Only set once.
5964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(2, transition);
5965958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    bit_field_ = HasTransitionField::update(bit_field_, true);
5966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetChangesFlag(kMaps);
5967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
59681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool NeedsWriteBarrier() const {
5970958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(!field_representation().IsDouble() ||
5971958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           (FLAG_unbox_double_fields && access_.IsInobject()) ||
5972958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           !has_transition());
5973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (field_representation().IsDouble()) return false;
5974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (field_representation().IsSmi()) return false;
5975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (field_representation().IsInteger32()) return false;
5976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (field_representation().IsExternal()) return false;
5977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return StoringValueNeedsWriteBarrier(value()) &&
5978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ReceiverObjectNeedsWriteBarrier(object(), value(), dominator());
5979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
59801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool NeedsWriteBarrierForMap() {
5982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return ReceiverObjectNeedsWriteBarrier(object(), transition(),
5983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           dominator());
5984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
59851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
5986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SmiCheck SmiCheckForWriteBarrier() const {
5987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (field_representation().IsHeapObject()) return OMIT_SMI_CHECK;
5988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (value()->type().IsHeapObject()) return OMIT_SMI_CHECK;
5989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return INLINE_SMI_CHECK;
5990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PointersToHereCheck PointersToHereCheckForValue() const {
5993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return PointersToHereCheckForObject(value(), dominator());
5994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Representation field_representation() const {
5997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return access_.representation();
5998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void UpdateValue(HValue* value) {
6001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, value);
6002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool CanBeReplacedWith(HStoreNamedField* that) const {
6005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!this->access().Equals(that->access())) return false;
6006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (SmiValuesAre32Bits() &&
6007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        this->field_representation().IsSmi() &&
6008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        this->store_mode() == INITIALIZING_STORE &&
6009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        that->store_mode() == STORE_TO_INITIALIZED_ENTRY) {
6010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // We cannot replace an initializing store to a smi field with a store to
6011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // an initialized entry on 64-bit architectures (with 32-bit smis).
6012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return false;
6013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return true;
60151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
6016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
6018958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  HStoreNamedField(HValue* obj, HObjectAccess access, HValue* val,
6019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE)
6020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : access_(access),
6021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        dominator_(NULL),
6022958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        bit_field_(HasTransitionField::encode(false) |
6023958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                   StoreModeField::encode(store_mode)) {
6024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Stores to a non existing in-object property are allowed only to the
6025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // newly allocated objects (via HAllocate or HInnerAllocatedObject).
6026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!access.IsInobject() || access.existing_inobject_property() ||
6027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           obj->IsAllocate() || obj->IsInnerAllocatedObject());
6028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, obj);
6029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, val);
6030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(2, obj);
6031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    access.SetGVNFlags(this, STORE);
6032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6034958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class HasTransitionField : public BitField<bool, 0, 1> {};
6035958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class StoreModeField : public BitField<StoreFieldOrKeyedMode, 1, 1> {};
6036958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
6037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HObjectAccess access_;
6038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* dominator_;
6039958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  uint32_t bit_field_;
60401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
60411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HStoreKeyed final : public HTemplateInstruction<4>,
6043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                          public ArrayInstructionInterface {
60441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public:
6045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P5(HStoreKeyed, HValue*, HValue*, HValue*,
6046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 HValue*, ElementsKind);
6047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P6(HStoreKeyed, HValue*, HValue*, HValue*,
6048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 HValue*, ElementsKind, StoreFieldOrKeyedMode);
6049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DECLARE_INSTRUCTION_FACTORY_P7(HStoreKeyed, HValue*, HValue*, HValue*,
6050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 HValue*, ElementsKind, StoreFieldOrKeyedMode,
6051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 int);
6052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
6054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // kind_fast:               tagged[int32] = tagged
6055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // kind_double:             tagged[int32] = double
6056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // kind_smi   :             tagged[int32] = smi
6057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // kind_fixed_typed_array:  tagged[int32] = (double | int32)
6058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // kind_external:           external[int32] = (double | int32)
6059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (index == 0) {
6060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return is_fixed_typed_array() ? Representation::External()
6061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    : Representation::Tagged();
6062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (index == 1) {
6063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return ArrayInstructionInterface::KeyedAccessIndexRequirement(
6064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          OperandAt(1)->representation());
6065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (index == 2) {
6066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return RequiredValueRepresentation(elements_kind(), store_mode());
6067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(3, index);
6070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return HasBackingStoreOwner() ? Representation::Tagged()
6071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  : Representation::None();
60721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
60731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Representation RequiredValueRepresentation(
6075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ElementsKind kind, StoreFieldOrKeyedMode mode) {
6076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (IsDoubleOrFloatElementsKind(kind)) {
6077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return Representation::Double();
6078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (kind == FAST_SMI_ELEMENTS && SmiValuesAre32Bits() &&
6081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        mode == STORE_TO_INITIALIZED_ENTRY) {
6082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return Representation::Integer32();
6083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (IsFastSmiElementsKind(kind)) {
6086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return Representation::Smi();
6087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (IsFixedTypedArrayElementsKind(kind)) {
6090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return Representation::Integer32();
6091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
6092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Representation::Tagged();
6093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_fixed_typed_array() const {
6096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return IsFixedTypedArrayElementsKind(elements_kind());
6097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation observed_input_representation(int index) override {
6100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (index != 2) return RequiredInputRepresentation(index);
6101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (IsUninitialized()) {
6102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return Representation::None();
6103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Representation r =
6105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        RequiredValueRepresentation(elements_kind(), store_mode());
6106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // For fast object elements kinds, don't assume anything.
6107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (r.IsTagged()) return Representation::None();
6108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return r;
6109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* elements() const { return OperandAt(0); }
6112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* key() const { return OperandAt(1); }
6113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* value() const { return OperandAt(2); }
6114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* backing_store_owner() const {
6115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(HasBackingStoreOwner());
6116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return OperandAt(3);
6117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
6118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool HasBackingStoreOwner() const { return OperandAt(0) != OperandAt(3); }
6119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool value_is_smi() const { return IsFastSmiElementsKind(elements_kind()); }
6120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  StoreFieldOrKeyedMode store_mode() const {
6121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return StoreModeField::decode(bit_field_);
6122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
6123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ElementsKind elements_kind() const override {
6124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return ElementsKindField::decode(bit_field_);
6125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t base_offset() const { return base_offset_; }
6127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool TryIncreaseBaseOffset(uint32_t increase_by_value) override;
6128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* GetKey() override { return key(); }
6129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void SetKey(HValue* key) override { SetOperandAt(1, key); }
6130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDehoisted() const override {
6131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return IsDehoistedField::decode(bit_field_);
6132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
6133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void SetDehoisted(bool is_dehoisted) override {
6134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted);
6135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
6136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool IsUninitialized() { return IsUninitializedField::decode(bit_field_); }
6137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SetUninitialized(bool is_uninitialized) {
6138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    bit_field_ = IsUninitializedField::update(bit_field_, is_uninitialized);
6139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsConstantHoleStore() {
6142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return value()->IsConstant() && HConstant::cast(value())->IsTheHole();
6143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool HandleSideEffectDominator(GVNFlag side_effect,
6146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 HValue* dominator) override {
6147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(side_effect == kNewSpacePromotion);
6148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    dominator_ = dominator;
6149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
6150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* dominator() const { return dominator_; }
6153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool NeedsWriteBarrier() {
6155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (value_is_smi()) {
6156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return false;
6157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
6158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return StoringValueNeedsWriteBarrier(value()) &&
6159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          ReceiverObjectNeedsWriteBarrier(elements(), value(), dominator());
6160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PointersToHereCheck PointersToHereCheckForValue() const {
6164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return PointersToHereCheckForObject(value(), dominator());
6165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool NeedsCanonicalization();
6168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
6170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(StoreKeyed)
6172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
6174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HStoreKeyed(HValue* obj, HValue* key, HValue* val,
6175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              HValue* backing_store_owner, ElementsKind elements_kind,
6176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE,
6177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              int offset = kDefaultKeyedHeaderOffsetSentinel)
6178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      : base_offset_(offset == kDefaultKeyedHeaderOffsetSentinel
6179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                         ? GetDefaultHeaderSizeForElementsKind(elements_kind)
6180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                         : offset),
6181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        bit_field_(IsDehoistedField::encode(false) |
6182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                   IsUninitializedField::encode(false) |
6183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                   StoreModeField::encode(store_mode) |
6184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                   ElementsKindField::encode(elements_kind)),
6185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        dominator_(NULL) {
6186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, obj);
6187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, key);
6188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(2, val);
6189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetOperandAt(3, backing_store_owner != nullptr ? backing_store_owner : obj);
6190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(HasBackingStoreOwner(), is_fixed_typed_array());
6191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (IsFastObjectElementsKind(elements_kind)) {
6193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetFlag(kTrackSideEffectDominators);
6194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetDependsOnFlag(kNewSpacePromotion);
6195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (IsFastDoubleElementsKind(elements_kind)) {
6197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetChangesFlag(kDoubleArrayElements);
6198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (IsFastSmiElementsKind(elements_kind)) {
6199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetChangesFlag(kArrayElements);
6200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (is_fixed_typed_array()) {
6201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetChangesFlag(kTypedArrayElements);
6202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SetChangesFlag(kExternalMemory);
6203c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      SetFlag(kTruncatingToNumber);
6204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
6205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetChangesFlag(kArrayElements);
6206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // {UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating.
6209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (elements_kind >= UINT8_ELEMENTS && elements_kind <= INT32_ELEMENTS) {
6210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetFlag(kTruncatingToInt32);
6211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class IsDehoistedField : public BitField<bool, 0, 1> {};
6215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class IsUninitializedField : public BitField<bool, 1, 1> {};
6216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class StoreModeField : public BitField<StoreFieldOrKeyedMode, 2, 1> {};
6217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class ElementsKindField : public BitField<ElementsKind, 3, 5> {};
6218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
6219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t base_offset_;
6220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  uint32_t bit_field_;
6221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* dominator_;
6222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
6223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HTransitionElementsKind final : public HTemplateInstruction<2> {
6225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
6226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline static HTransitionElementsKind* New(Isolate* isolate, Zone* zone,
6227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                             HValue* context, HValue* object,
6228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             Handle<Map> original_map,
6229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             Handle<Map> transitioned_map) {
6230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return new(zone) HTransitionElementsKind(context, object,
6231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             original_map, transitioned_map);
6232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
6235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Representation::Tagged();
6236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* object() const { return OperandAt(0); }
6239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* context() const { return OperandAt(1); }
6240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Unique<Map> original_map() const { return original_map_; }
6241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Unique<Map> transitioned_map() const { return transitioned_map_; }
6242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ElementsKind from_kind() const {
6243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return FromElementsKindField::decode(bit_field_);
6244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
6245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ElementsKind to_kind() const {
6246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return ToElementsKindField::decode(bit_field_);
6247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
6248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool map_is_stable() const { return MapIsStableField::decode(bit_field_); }
6249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
6251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind)
62531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
62541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block protected:
6255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override {
6256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HTransitionElementsKind* instr = HTransitionElementsKind::cast(other);
6257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return original_map_ == instr->original_map_ &&
6258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           transitioned_map_ == instr->transitioned_map_;
6259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int RedefinedOperandIndex() override { return 0; }
62621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
6264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HTransitionElementsKind(HValue* context, HValue* object,
6265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          Handle<Map> original_map,
6266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          Handle<Map> transitioned_map)
6267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : original_map_(Unique<Map>(original_map)),
6268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        transitioned_map_(Unique<Map>(transitioned_map)),
6269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        bit_field_(
6270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            FromElementsKindField::encode(original_map->elements_kind()) |
6271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            ToElementsKindField::encode(transitioned_map->elements_kind()) |
6272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            MapIsStableField::encode(transitioned_map->is_stable())) {
6273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, object);
6274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, context);
6275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kUseGVN);
6276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetChangesFlag(kElementsKind);
6277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!IsSimpleMapChangeTransition(from_kind(), to_kind())) {
6278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetChangesFlag(kElementsPointer);
6279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetChangesFlag(kNewSpacePromotion);
6280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
62823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
6283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class FromElementsKindField : public BitField<ElementsKind, 0, 5> {};
6285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class ToElementsKindField : public BitField<ElementsKind, 5, 5> {};
6286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class MapIsStableField : public BitField<bool, 10, 1> {};
6287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Unique<Map> original_map_;
6289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Unique<Map> transitioned_map_;
6290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t bit_field_;
62913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
62923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
62933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HStringAdd final : public HBinaryOperation {
62953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
6296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HInstruction* New(
6297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Isolate* isolate, Zone* zone, HValue* context, HValue* left,
6298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      HValue* right, PretenureFlag pretenure_flag = NOT_TENURED,
6299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      StringAddFlags flags = STRING_ADD_CHECK_BOTH,
6300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null());
6301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StringAddFlags flags() const { return flags_; }
6303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PretenureFlag pretenure_flag() const { return pretenure_flag_; }
6304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
6306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Representation::Tagged();
6307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
6310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(StringAdd)
6312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
6314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override {
6315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return flags_ == HStringAdd::cast(other)->flags_ &&
6316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        pretenure_flag_ == HStringAdd::cast(other)->pretenure_flag_;
6317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
6320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HStringAdd(HValue* context, HValue* left, HValue* right,
6321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             PretenureFlag pretenure_flag, StringAddFlags flags,
6322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             Handle<AllocationSite> allocation_site)
6323109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : HBinaryOperation(context, left, right, HType::String()),
6324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        flags_(flags),
6325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        pretenure_flag_(pretenure_flag) {
63263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    set_representation(Representation::Tagged());
6327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if ((flags & STRING_ADD_CONVERT) == STRING_ADD_CONVERT) {
6328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SetAllSideEffects();
6329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ClearFlag(kUseGVN);
6330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
6331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SetChangesFlag(kNewSpacePromotion);
6332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SetFlag(kUseGVN);
6333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
6334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetDependsOnFlag(kMaps);
6335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (FLAG_trace_pretenuring) {
6336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrintF("HStringAdd with AllocationSite %p %s\n",
6337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             allocation_site.is_null()
6338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 ? static_cast<void*>(NULL)
6339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 : static_cast<void*>(*allocation_site),
6340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             pretenure_flag == TENURED ? "tenured" : "not tenured");
6341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
63423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
63433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const final {
6345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return (flags_ & STRING_ADD_CONVERT) != STRING_ADD_CONVERT;
6346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
6347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const StringAddFlags flags_;
6349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const PretenureFlag pretenure_flag_;
6350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
6351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HStringCharCodeAt final : public HTemplateInstruction<3> {
6354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
6355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HStringCharCodeAt,
6356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                              HValue*,
6357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                              HValue*);
63583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
6360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The index is supposed to be Integer32.
6361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return index == 2
6362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ? Representation::Integer32()
6363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        : Representation::Tagged();
63645d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch  }
63653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* context() const { return OperandAt(0); }
6367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* string() const { return OperandAt(1); }
6368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* index() const { return OperandAt(2); }
6369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
6371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
6373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
6374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Range* InferRange(Zone* zone) override {
6376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return new(zone) Range(0, String::kMaxUtf16CodeUnit);
6377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
6380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
6381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, context);
6382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, string);
6383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(2, index);
6384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Integer32());
6385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kUseGVN);
6386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetDependsOnFlag(kMaps);
6387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetDependsOnFlag(kStringChars);
6388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetChangesFlag(kNewSpacePromotion);
6389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
63903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // No side effects: runtime function assumes string + number inputs.
6392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override { return true; }
63935d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch};
63945d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
63955d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
6396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HStringCharFromCode final : public HTemplateInstruction<2> {
6397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
6398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
6399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           HValue* char_code);
6400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
6402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return index == 0
6403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ? Representation::Tagged()
6404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        : Representation::Integer32();
6405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
6406b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* context() const { return OperandAt(0); }
6408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* value() const { return OperandAt(1); }
6409b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
6411b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
6413b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
6415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HStringCharFromCode(HValue* context, HValue* char_code)
6416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HTemplateInstruction<2>(HType::String()) {
64173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    SetOperandAt(0, context);
6418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, char_code);
6419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
6420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kUseGVN);
6421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetChangesFlag(kNewSpacePromotion);
64223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
64233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override {
6425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return !value()->ToNumberCanBeObserved();
64263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
64273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
64283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
64293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HTypeof final : public HTemplateInstruction<2> {
6431b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
6432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HTypeof, HValue*);
6433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* context() const { return OperandAt(0); }
6435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* value() const { return OperandAt(1); }
6436b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
6438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
6440e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return Representation::Tagged();
6441e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
64421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(Typeof)
6444b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6445b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
6446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit HTypeof(HValue* context, HValue* value) {
64473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    SetOperandAt(0, context);
6448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetOperandAt(1, value);
6449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    set_representation(Representation::Tagged());
64503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
6451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override { return true; }
6453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
6454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HTrapAllocationMemento final : public HTemplateInstruction<1> {
6457b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
6458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DECLARE_INSTRUCTION_FACTORY_P1(HTrapAllocationMemento, HValue*);
64593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
6460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
64613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return Representation::Tagged();
6462e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
6463e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
6464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* object() { return OperandAt(0); }
6465b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento)
6467b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6468b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
6469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit HTrapAllocationMemento(HValue* obj) {
6470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetOperandAt(0, obj);
6471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6472b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
6473b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6474b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HMaybeGrowElements final : public HTemplateInstruction<5> {
6476b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
6477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P6(HMaybeGrowElements, HValue*,
6478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              HValue*, HValue*, HValue*, bool,
6479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              ElementsKind);
6480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
6482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (index < 3) {
6483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return Representation::Tagged();
6484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
6485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(index == 3 || index == 4);
6486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Representation::Integer32();
6487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
6488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* context() const { return OperandAt(0); }
6490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* object() const { return OperandAt(1); }
6491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* elements() const { return OperandAt(2); }
6492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* key() const { return OperandAt(3); }
6493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* current_capacity() const { return OperandAt(4); }
6494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_js_array() const { return is_js_array_; }
6496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ElementsKind kind() const { return kind_; }
6497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DECLARE_CONCRETE_INSTRUCTION(MaybeGrowElements)
6499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch protected:
6501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
6502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
6504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit HMaybeGrowElements(HValue* context, HValue* object, HValue* elements,
6505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              HValue* key, HValue* current_capacity,
6506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              bool is_js_array, ElementsKind kind) {
6507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    is_js_array_ = is_js_array;
6508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kind_ = kind;
65093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetOperandAt(0, context);
6511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetOperandAt(1, object);
6512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetOperandAt(2, elements);
6513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetOperandAt(3, key);
6514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetOperandAt(4, current_capacity);
6515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetFlag(kUseGVN);
6517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetChangesFlag(kElementsPointer);
6518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetChangesFlag(kNewSpacePromotion);
6519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    set_representation(Representation::Tagged());
65201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
65211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_js_array_;
6523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ElementsKind kind_;
6524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
6525b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HSeqStringGetChar final : public HTemplateInstruction<2> {
6528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
6529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
6530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           String::Encoding encoding, HValue* string,
6531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           HValue* index);
6532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
6534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return (index == 0) ? Representation::Tagged()
6535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        : Representation::Integer32();
6536b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
6537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  String::Encoding encoding() const { return encoding_; }
6539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* string() const { return OperandAt(0); }
6540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* index() const { return OperandAt(1); }
6541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(SeqStringGetChar)
6543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
6545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override {
6546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return encoding() == HSeqStringGetChar::cast(other)->encoding();
6547b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
6548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Range* InferRange(Zone* zone) override {
6550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (encoding() == String::ONE_BYTE_ENCODING) {
6551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return new(zone) Range(0, String::kMaxOneByteCharCode);
6552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
6553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK_EQ(String::TWO_BYTE_ENCODING, encoding());
6554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return  new(zone) Range(0, String::kMaxUtf16CodeUnit);
6555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
6559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HSeqStringGetChar(String::Encoding encoding,
6560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    HValue* string,
6561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    HValue* index) : encoding_(encoding) {
6562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, string);
6563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, index);
6564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Integer32());
6565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kUseGVN);
6566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetDependsOnFlag(kStringChars);
6567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
65683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
6569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override { return true; }
6570b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  String::Encoding encoding_;
6572b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
6573b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6574257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
6575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HSeqStringSetChar final : public HTemplateInstruction<4> {
6576257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
6577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(
6578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HSeqStringSetChar, String::Encoding,
6579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HValue*, HValue*, HValue*);
6580257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
6581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  String::Encoding encoding() { return encoding_; }
65823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HValue* context() { return OperandAt(0); }
6583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* string() { return OperandAt(1); }
6584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* index() { return OperandAt(2); }
6585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* value() { return OperandAt(3); }
6586257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
6587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
6588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return (index <= 1) ? Representation::Tagged()
6589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        : Representation::Integer32();
6590257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
6591257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
6592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar)
6593257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
6594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
6595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HSeqStringSetChar(HValue* context,
6596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    String::Encoding encoding,
6597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    HValue* string,
6598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    HValue* index,
6599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    HValue* value) : encoding_(encoding) {
6600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, context);
6601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, string);
6602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(2, index);
6603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(3, value);
6604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
6605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetChangesFlag(kStringChars);
6606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6607257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
6608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  String::Encoding encoding_;
6609257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
6610257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
66113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HCheckMapValue final : public HTemplateInstruction<2> {
66133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
6614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P2(HCheckMapValue, HValue*, HValue*);
66153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
66173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return Representation::Tagged();
66183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
66193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
66213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HType CalculateInferredType() override {
6623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (value()->type().IsHeapObject()) return value()->type();
6624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HType::HeapObject();
66253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
66263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* value() const { return OperandAt(0); }
6628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* map() const { return OperandAt(1); }
6629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* Canonicalize() override;
66313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
66323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(CheckMapValue)
66333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
66343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch protected:
6635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int RedefinedOperandIndex() override { return 0; }
6636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DataEquals(HValue* other) override { return true; }
6638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
6640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HCheckMapValue(HValue* value, HValue* map)
6641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : HTemplateInstruction<2>(HType::HeapObject()) {
6642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, value);
6643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, map);
6644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
6645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetFlag(kUseGVN);
6646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetDependsOnFlag(kMaps);
6647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetDependsOnFlag(kElementsKind);
6648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
66493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
66503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
66513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HForInPrepareMap final : public HTemplateInstruction<2> {
66533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
6654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HForInPrepareMap, HValue*);
66553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
66573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return Representation::Tagged();
66583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
66593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* context() const { return OperandAt(0); }
6661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* enumerable() const { return OperandAt(1); }
66623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
66643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HType CalculateInferredType() override { return HType::Tagged(); }
66663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
66673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap);
6668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
6670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HForInPrepareMap(HValue* context,
6671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   HValue* object) {
6672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, context);
6673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, object);
6674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
6675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetAllSideEffects();
6676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
66773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
66783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
66793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HForInCacheArray final : public HTemplateInstruction<2> {
66813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
6682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P3(HForInCacheArray, HValue*, HValue*, int);
66833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
66853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return Representation::Tagged();
66863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
66873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* enumerable() const { return OperandAt(0); }
6689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* map() const { return OperandAt(1); }
6690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int idx() const { return idx_; }
66913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
66923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HForInCacheArray* index_cache() {
66933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return index_cache_;
66943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
66953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
66963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void set_index_cache(HForInCacheArray* index_cache) {
66973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    index_cache_ = index_cache;
66983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
66993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
67013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HType CalculateInferredType() override { return HType::Tagged(); }
67033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
67043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray);
67053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
67063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
6707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HForInCacheArray(HValue* enumerable,
6708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   HValue* keys,
6709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   int idx) : idx_(idx) {
6710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(0, enumerable);
6711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetOperandAt(1, keys);
6712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_representation(Representation::Tagged());
6713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
67153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int idx_;
67163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HForInCacheArray* index_cache_;
67173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
67183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
67193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HLoadFieldByIndex final : public HTemplateInstruction<2> {
67213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
6722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DECLARE_INSTRUCTION_FACTORY_P2(HLoadFieldByIndex, HValue*, HValue*);
6723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
67243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HLoadFieldByIndex(HValue* object,
67253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                    HValue* index) {
67263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    SetOperandAt(0, object);
67273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    SetOperandAt(1, index);
6728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetChangesFlag(kNewSpacePromotion);
67293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    set_representation(Representation::Tagged());
67303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
67313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Representation RequiredInputRepresentation(int index) override {
6733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (index == 1) {
6734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return Representation::Smi();
6735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
6736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return Representation::Tagged();
6737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
67383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
67393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* object() const { return OperandAt(0); }
6741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* index() const { return OperandAt(1); }
67423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT
67443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HType CalculateInferredType() override { return HType::Tagged(); }
67463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
67473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex);
6748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
6750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsDeletable() const override { return true; }
67513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
67523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6753b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#undef DECLARE_INSTRUCTION
6754b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#undef DECLARE_CONCRETE_INSTRUCTION
6755b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
6757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
6758b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif  // V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_
6760