blob: cef8a541d98f4bd21a9f5680274c672eebd11182 [file] [log] [blame]
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001// Copyright 2012 the V8 project authors. All rights reserved.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_HYDROGEN_INSTRUCTIONS_H_
29#define V8_HYDROGEN_INSTRUCTIONS_H_
30
31#include "v8.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000032
lrn@chromium.org1c092762011-05-09 09:42:16 +000033#include "allocation.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000034#include "code-stubs.h"
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +000035#include "data-flow.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000036#include "small-pointer-list.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000037#include "string-stream.h"
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +000038#include "v8conversions.h"
39#include "v8utils.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000040#include "zone.h"
41
42namespace v8 {
43namespace internal {
44
45// Forward declarations.
46class HBasicBlock;
47class HEnvironment;
yangguo@chromium.orgfb377212012-11-16 14:43:43 +000048class HInferRepresentation;
kasperl@chromium.orga5551262010-12-07 12:49:48 +000049class HInstruction;
50class HLoopInformation;
51class HValue;
52class LInstruction;
53class LChunkBuilder;
54
55
ricow@chromium.orgdcebac02011-04-20 09:44:50 +000056#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000057 V(BinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000058 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000059 V(ControlInstruction) \
60 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000061
62
63#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +000064 V(AbnormalExit) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000065 V(AccessArgumentsAt) \
66 V(Add) \
danno@chromium.org94b0d6f2013-02-04 13:33:20 +000067 V(Allocate) \
ulan@chromium.org967e2702012-02-28 09:49:15 +000068 V(AllocateObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000069 V(ApplyArguments) \
70 V(ArgumentsElements) \
71 V(ArgumentsLength) \
72 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000073 V(ArrayLiteral) \
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000074 V(Bitwise) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000075 V(BitNot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000076 V(BlockEntry) \
77 V(BoundsCheck) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000078 V(Branch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000079 V(CallConstantFunction) \
80 V(CallFunction) \
81 V(CallGlobal) \
82 V(CallKeyed) \
83 V(CallKnownGlobal) \
84 V(CallNamed) \
85 V(CallNew) \
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +000086 V(CallNewArray) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000087 V(CallRuntime) \
88 V(CallStub) \
89 V(Change) \
90 V(CheckFunction) \
91 V(CheckInstanceType) \
jkummerow@chromium.org1456e702012-03-30 08:38:13 +000092 V(CheckMaps) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000093 V(CheckNonSmi) \
94 V(CheckPrototypeMaps) \
95 V(CheckSmi) \
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +000096 V(CheckSmiOrInt32) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +000097 V(ClampToUint8) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000098 V(ClassOfTestAndBranch) \
99 V(CompareIDAndBranch) \
100 V(CompareGeneric) \
101 V(CompareObjectEqAndBranch) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000102 V(CompareMap) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000103 V(CompareConstantEqAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000104 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000105 V(Context) \
yangguo@chromium.org56454712012-02-16 15:33:53 +0000106 V(DeclareGlobals) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000107 V(DeleteProperty) \
108 V(Deoptimize) \
109 V(Div) \
yangguo@chromium.org46a2a512013-01-18 16:29:40 +0000110 V(DummyUse) \
whesse@chromium.org7b260152011-06-20 15:33:18 +0000111 V(ElementsKind) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000112 V(EnterInlined) \
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000113 V(FastLiteral) \
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000114 V(FixedArrayBaseLength) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000115 V(ForceRepresentation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000116 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000117 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000118 V(GlobalObject) \
119 V(GlobalReceiver) \
120 V(Goto) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000121 V(HasCachedArrayIndexAndBranch) \
122 V(HasInstanceTypeAndBranch) \
ulan@chromium.org2e04b582013-02-21 14:06:02 +0000123 V(InductionVariableAnnotation) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000124 V(In) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000125 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000126 V(InstanceOfKnownGlobal) \
mstarzinger@chromium.org71fc3462013-02-27 09:34:27 +0000127 V(InstanceSize) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000128 V(InvokeFunction) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000129 V(IsConstructCallAndBranch) \
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000130 V(IsNilAndBranch) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000131 V(IsObjectAndBranch) \
erikcorry0ad885c2011-11-21 13:51:57 +0000132 V(IsStringAndBranch) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000133 V(IsSmiAndBranch) \
134 V(IsUndetectableAndBranch) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000135 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000136 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000137 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000138 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000139 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000140 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000141 V(LoadGlobalCell) \
142 V(LoadGlobalGeneric) \
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +0000143 V(LoadKeyed) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000144 V(LoadKeyedGeneric) \
145 V(LoadNamedField) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000146 V(LoadNamedFieldPolymorphic) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000147 V(LoadNamedGeneric) \
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000148 V(MapEnumLength) \
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +0000149 V(MathFloorOfDiv) \
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +0000150 V(MathMinMax) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000151 V(Mod) \
152 V(Mul) \
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000153 V(NumericConstraint) \
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000154 V(ObjectLiteral) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000155 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000156 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000157 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000158 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000159 V(PushArgument) \
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000160 V(Random) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000161 V(RegExpLiteral) \
162 V(Return) \
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +0000163 V(Ror) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000164 V(Sar) \
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +0000165 V(SeqStringSetChar) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000166 V(Shl) \
167 V(Shr) \
168 V(Simulate) \
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000169 V(SoftDeoptimize) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000170 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000171 V(StoreContextSlot) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000172 V(StoreGlobalCell) \
173 V(StoreGlobalGeneric) \
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +0000174 V(StoreKeyed) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000175 V(StoreKeyedGeneric) \
176 V(StoreNamedField) \
177 V(StoreNamedGeneric) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000178 V(StringAdd) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000179 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000180 V(StringCharFromCode) \
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +0000181 V(StringCompareAndBranch) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000182 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000183 V(Sub) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000184 V(ThisFunction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000185 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000186 V(ToFastProperties) \
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000187 V(TransitionElementsKind) \
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000188 V(TrapAllocationMemento) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000189 V(Typeof) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000190 V(TypeofIsAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000191 V(UnaryMathOperation) \
192 V(UnknownOSRValue) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000193 V(UseConst) \
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +0000194 V(ValueOf) \
195 V(ForInPrepareMap) \
196 V(ForInCacheArray) \
197 V(CheckMapValue) \
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000198 V(LoadFieldByIndex) \
yangguo@chromium.org154ff992012-03-13 08:09:54 +0000199 V(DateField) \
200 V(WrapReceiver)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000201
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000202#define GVN_TRACKED_FLAG_LIST(V) \
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000203 V(Maps) \
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000204 V(NewSpacePromotion)
205
206#define GVN_UNTRACKED_FLAG_LIST(V) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000207 V(Calls) \
208 V(InobjectFields) \
209 V(BackingStoreFields) \
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000210 V(ElementsKind) \
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000211 V(ElementsPointer) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000212 V(ArrayElements) \
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000213 V(DoubleArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000214 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000215 V(GlobalVars) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000216 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000217 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000218 V(OsrEntries)
219
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000220#define DECLARE_ABSTRACT_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000221 virtual bool Is##type() const { return true; } \
222 static H##type* cast(HValue* value) { \
223 ASSERT(value->Is##type()); \
224 return reinterpret_cast<H##type*>(value); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000225 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000226
227
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000228#define DECLARE_CONCRETE_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000229 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000230 static H##type* cast(HValue* value) { \
231 ASSERT(value->Is##type()); \
232 return reinterpret_cast<H##type*>(value); \
233 } \
234 virtual Opcode opcode() const { return HValue::k##type; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000235
236
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000237#ifdef DEBUG
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000238#define ASSERT_ALLOCATION_DISABLED \
239 ASSERT(isolate()->optimizing_compiler_thread()->IsOptimizerThread() || \
240 !isolate()->heap()->IsAllocationAllowed())
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000241#else
242#define ASSERT_ALLOCATION_DISABLED do {} while (0)
243#endif
244
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000245class Range: public ZoneObject {
246 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000247 Range()
248 : lower_(kMinInt),
249 upper_(kMaxInt),
250 next_(NULL),
251 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000252
253 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000254 : lower_(lower),
255 upper_(upper),
256 next_(NULL),
257 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000258
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000259 int32_t upper() const { return upper_; }
260 int32_t lower() const { return lower_; }
261 Range* next() const { return next_; }
ulan@chromium.org812308e2012-02-29 15:58:45 +0000262 Range* CopyClearLower(Zone* zone) const {
263 return new(zone) Range(kMinInt, upper_);
264 }
265 Range* CopyClearUpper(Zone* zone) const {
266 return new(zone) Range(lower_, kMaxInt);
267 }
268 Range* Copy(Zone* zone) const {
269 Range* result = new(zone) Range(lower_, upper_);
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000270 result->set_can_be_minus_zero(CanBeMinusZero());
271 return result;
272 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000273 int32_t Mask() const;
274 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
275 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
276 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
277 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000278 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000279 bool IsMostGeneric() const {
280 return lower_ == kMinInt && upper_ == kMaxInt && CanBeMinusZero();
281 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000282 bool IsInSmiRange() const {
283 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000284 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000285 void KeepOrder();
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000286#ifdef DEBUG
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000287 void Verify() const;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000288#endif
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000289
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000290 void StackUpon(Range* other) {
291 Intersect(other);
292 next_ = other;
293 }
294
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000295 void Intersect(Range* other);
296 void Union(Range* other);
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +0000297 void CombinedMax(Range* other);
298 void CombinedMin(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000299
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000300 void AddConstant(int32_t value);
301 void Sar(int32_t value);
302 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000303 bool AddAndCheckOverflow(Range* other);
304 bool SubAndCheckOverflow(Range* other);
305 bool MulAndCheckOverflow(Range* other);
306
307 private:
308 int32_t lower_;
309 int32_t upper_;
310 Range* next_;
311 bool can_be_minus_zero_;
312};
313
314
315class Representation {
316 public:
317 enum Kind {
318 kNone,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000319 kInteger32,
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000320 kDouble,
321 kTagged,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000322 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000323 kNumRepresentations
324 };
325
326 Representation() : kind_(kNone) { }
327
328 static Representation None() { return Representation(kNone); }
329 static Representation Tagged() { return Representation(kTagged); }
330 static Representation Integer32() { return Representation(kInteger32); }
331 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000332 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000333
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000334 static Representation FromKind(Kind kind) { return Representation(kind); }
335
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000336 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000337 return kind_ == other.kind_;
338 }
339
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000340 bool is_more_general_than(const Representation& other) {
341 ASSERT(kind_ != kExternal);
342 ASSERT(other.kind_ != kExternal);
343 return kind_ > other.kind_;
344 }
345
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000346 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000347 bool IsNone() const { return kind_ == kNone; }
348 bool IsTagged() const { return kind_ == kTagged; }
349 bool IsInteger32() const { return kind_ == kInteger32; }
350 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000351 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000352 bool IsSpecialization() const {
353 return kind_ == kInteger32 || kind_ == kDouble;
354 }
355 const char* Mnemonic() const;
356
357 private:
358 explicit Representation(Kind k) : kind_(k) { }
359
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000360 // Make sure kind fits in int8.
361 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
362
363 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000364};
365
366
367class HType {
368 public:
369 HType() : type_(kUninitialized) { }
370
371 static HType Tagged() { return HType(kTagged); }
372 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
373 static HType TaggedNumber() { return HType(kTaggedNumber); }
374 static HType Smi() { return HType(kSmi); }
375 static HType HeapNumber() { return HType(kHeapNumber); }
376 static HType String() { return HType(kString); }
377 static HType Boolean() { return HType(kBoolean); }
378 static HType NonPrimitive() { return HType(kNonPrimitive); }
379 static HType JSArray() { return HType(kJSArray); }
380 static HType JSObject() { return HType(kJSObject); }
381 static HType Uninitialized() { return HType(kUninitialized); }
382
383 // Return the weakest (least precise) common type.
384 HType Combine(HType other) {
385 return HType(static_cast<Type>(type_ & other.type_));
386 }
387
388 bool Equals(const HType& other) {
389 return type_ == other.type_;
390 }
391
392 bool IsSubtypeOf(const HType& other) {
393 return Combine(other).Equals(other);
394 }
395
396 bool IsTagged() {
397 ASSERT(type_ != kUninitialized);
398 return ((type_ & kTagged) == kTagged);
399 }
400
401 bool IsTaggedPrimitive() {
402 ASSERT(type_ != kUninitialized);
403 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
404 }
405
406 bool IsTaggedNumber() {
407 ASSERT(type_ != kUninitialized);
408 return ((type_ & kTaggedNumber) == kTaggedNumber);
409 }
410
411 bool IsSmi() {
412 ASSERT(type_ != kUninitialized);
413 return ((type_ & kSmi) == kSmi);
414 }
415
416 bool IsHeapNumber() {
417 ASSERT(type_ != kUninitialized);
418 return ((type_ & kHeapNumber) == kHeapNumber);
419 }
420
421 bool IsString() {
422 ASSERT(type_ != kUninitialized);
423 return ((type_ & kString) == kString);
424 }
425
426 bool IsBoolean() {
427 ASSERT(type_ != kUninitialized);
428 return ((type_ & kBoolean) == kBoolean);
429 }
430
431 bool IsNonPrimitive() {
432 ASSERT(type_ != kUninitialized);
433 return ((type_ & kNonPrimitive) == kNonPrimitive);
434 }
435
436 bool IsJSArray() {
437 ASSERT(type_ != kUninitialized);
438 return ((type_ & kJSArray) == kJSArray);
439 }
440
441 bool IsJSObject() {
442 ASSERT(type_ != kUninitialized);
443 return ((type_ & kJSObject) == kJSObject);
444 }
445
446 bool IsUninitialized() {
447 return type_ == kUninitialized;
448 }
449
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000450 bool IsHeapObject() {
451 ASSERT(type_ != kUninitialized);
452 return IsHeapNumber() || IsString() || IsNonPrimitive();
453 }
454
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000455 static HType TypeFromValue(Isolate* isolate, Handle<Object> value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000456
457 const char* ToString();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000458
459 private:
460 enum Type {
461 kTagged = 0x1, // 0000 0000 0000 0001
462 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
463 kTaggedNumber = 0xd, // 0000 0000 0000 1101
464 kSmi = 0x1d, // 0000 0000 0001 1101
465 kHeapNumber = 0x2d, // 0000 0000 0010 1101
466 kString = 0x45, // 0000 0000 0100 0101
467 kBoolean = 0x85, // 0000 0000 1000 0101
468 kNonPrimitive = 0x101, // 0000 0001 0000 0001
469 kJSObject = 0x301, // 0000 0011 0000 0001
whesse@chromium.org7b260152011-06-20 15:33:18 +0000470 kJSArray = 0x701, // 0000 0111 0000 0001
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000471 kUninitialized = 0x1fff // 0001 1111 1111 1111
472 };
473
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000474 // Make sure type fits in int16.
475 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
476
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000477 explicit HType(Type t) : type_(t) { }
478
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000479 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000480};
481
482
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000483class HUseListNode: public ZoneObject {
484 public:
485 HUseListNode(HValue* value, int index, HUseListNode* tail)
486 : tail_(tail), value_(value), index_(index) {
487 }
488
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +0000489 HUseListNode* tail();
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000490 HValue* value() const { return value_; }
491 int index() const { return index_; }
492
493 void set_tail(HUseListNode* list) { tail_ = list; }
494
495#ifdef DEBUG
496 void Zap() {
497 tail_ = reinterpret_cast<HUseListNode*>(1);
498 value_ = NULL;
499 index_ = -1;
500 }
501#endif
502
503 private:
504 HUseListNode* tail_;
505 HValue* value_;
506 int index_;
507};
508
509
510// We reuse use list nodes behind the scenes as uses are added and deleted.
511// This class is the safe way to iterate uses while deleting them.
512class HUseIterator BASE_EMBEDDED {
513 public:
514 bool Done() { return current_ == NULL; }
515 void Advance();
516
517 HValue* value() {
518 ASSERT(!Done());
519 return value_;
520 }
521
522 int index() {
523 ASSERT(!Done());
524 return index_;
525 }
526
527 private:
528 explicit HUseIterator(HUseListNode* head);
529
530 HUseListNode* current_;
531 HUseListNode* next_;
532 HValue* value_;
533 int index_;
534
535 friend class HValue;
536};
537
538
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000539// There must be one corresponding kDepends flag for every kChanges flag and
540// the order of the kChanges flags must be exactly the same as of the kDepends
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000541// flags. All tracked flags should appear before untracked ones.
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000542enum GVNFlag {
543 // Declare global value numbering flags.
544#define DECLARE_FLAG(type) kChanges##type, kDependsOn##type,
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000545 GVN_TRACKED_FLAG_LIST(DECLARE_FLAG)
546 GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000547#undef DECLARE_FLAG
548 kAfterLastFlag,
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000549 kLastFlag = kAfterLastFlag - 1,
550#define COUNT_FLAG(type) + 1
551 kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG)
552#undef COUNT_FLAG
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000553};
554
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000555
556class NumericRelation {
557 public:
558 enum Kind { NONE, EQ, GT, GE, LT, LE, NE };
559 static const char* MnemonicFromKind(Kind kind) {
560 switch (kind) {
561 case NONE: return "NONE";
562 case EQ: return "EQ";
563 case GT: return "GT";
564 case GE: return "GE";
565 case LT: return "LT";
566 case LE: return "LE";
567 case NE: return "NE";
568 }
569 UNREACHABLE();
570 return NULL;
571 }
572 const char* Mnemonic() const { return MnemonicFromKind(kind_); }
573
574 static NumericRelation None() { return NumericRelation(NONE); }
575 static NumericRelation Eq() { return NumericRelation(EQ); }
576 static NumericRelation Gt() { return NumericRelation(GT); }
577 static NumericRelation Ge() { return NumericRelation(GE); }
578 static NumericRelation Lt() { return NumericRelation(LT); }
579 static NumericRelation Le() { return NumericRelation(LE); }
580 static NumericRelation Ne() { return NumericRelation(NE); }
581
582 bool IsNone() { return kind_ == NONE; }
583
584 static NumericRelation FromToken(Token::Value token) {
585 switch (token) {
586 case Token::EQ: return Eq();
587 case Token::EQ_STRICT: return Eq();
588 case Token::LT: return Lt();
589 case Token::GT: return Gt();
590 case Token::LTE: return Le();
591 case Token::GTE: return Ge();
592 case Token::NE: return Ne();
593 case Token::NE_STRICT: return Ne();
594 default: return None();
595 }
596 }
597
598 // The semantics of "Reversed" is that if "x rel y" is true then also
599 // "y rel.Reversed() x" is true, and that rel.Reversed().Reversed() == rel.
600 NumericRelation Reversed() {
601 switch (kind_) {
602 case NONE: return None();
603 case EQ: return Eq();
604 case GT: return Lt();
605 case GE: return Le();
606 case LT: return Gt();
607 case LE: return Ge();
608 case NE: return Ne();
609 }
610 UNREACHABLE();
611 return None();
612 }
613
614 // The semantics of "Negated" is that if "x rel y" is true then also
615 // "!(x rel.Negated() y)" is true.
616 NumericRelation Negated() {
617 switch (kind_) {
618 case NONE: return None();
619 case EQ: return Ne();
620 case GT: return Le();
621 case GE: return Lt();
622 case LT: return Ge();
623 case LE: return Gt();
624 case NE: return Eq();
625 }
626 UNREACHABLE();
627 return None();
628 }
629
630 // The semantics of "Implies" is that if "x rel y" is true
631 // then also "x other_relation y" is true.
632 bool Implies(NumericRelation other_relation) {
633 switch (kind_) {
634 case NONE: return false;
635 case EQ: return (other_relation.kind_ == EQ)
636 || (other_relation.kind_ == GE)
637 || (other_relation.kind_ == LE);
638 case GT: return (other_relation.kind_ == GT)
639 || (other_relation.kind_ == GE)
640 || (other_relation.kind_ == NE);
641 case LT: return (other_relation.kind_ == LT)
642 || (other_relation.kind_ == LE)
643 || (other_relation.kind_ == NE);
644 case GE: return (other_relation.kind_ == GE);
645 case LE: return (other_relation.kind_ == LE);
646 case NE: return (other_relation.kind_ == NE);
647 }
648 UNREACHABLE();
649 return false;
650 }
651
652 // The semantics of "IsExtendable" is that if
653 // "rel.IsExtendable(direction)" is true then
654 // "x rel y" implies "(x + direction) rel y" .
655 bool IsExtendable(int direction) {
656 switch (kind_) {
657 case NONE: return false;
658 case EQ: return false;
659 case GT: return (direction >= 0);
660 case GE: return (direction >= 0);
661 case LT: return (direction <= 0);
662 case LE: return (direction <= 0);
663 case NE: return false;
664 }
665 UNREACHABLE();
666 return false;
667 }
668
669 private:
670 explicit NumericRelation(Kind kind) : kind_(kind) {}
671
672 Kind kind_;
673};
674
675
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000676typedef EnumSet<GVNFlag> GVNFlagSet;
677
678
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000679class HValue: public ZoneObject {
680 public:
681 static const int kNoNumber = -1;
682
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000683 enum Flag {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000684 kFlexibleRepresentation,
whesse@chromium.org7b260152011-06-20 15:33:18 +0000685 // Participate in Global Value Numbering, i.e. elimination of
686 // unnecessary recomputations. If an instruction sets this flag, it must
687 // implement DataEquals(), which will be used to determine if other
688 // occurrences of the instruction are indeed the same.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000689 kUseGVN,
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000690 // Track instructions that are dominating side effects. If an instruction
691 // sets this flag, it must implement SetSideEffectDominator() and should
692 // indicate which side effects to track by setting GVN flags.
693 kTrackSideEffectDominators,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000694 kCanOverflow,
695 kBailoutOnMinusZero,
696 kCanBeDivByZero,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000697 kDeoptimizeOnUndefined,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000698 kIsArguments,
699 kTruncatingToInt32,
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +0000700 kIsDead,
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000701 // Instructions that are allowed to produce full range unsigned integer
702 // values are marked with kUint32 flag. If arithmetic shift or a load from
703 // EXTERNAL_UNSIGNED_INT_ELEMENTS array is not marked with this flag
704 // it will deoptimize if result does not fit into signed integer range.
705 // HGraph::ComputeSafeUint32Operations is responsible for setting this
706 // flag.
707 kUint32,
ulan@chromium.org2e04b582013-02-21 14:06:02 +0000708 // If a phi is involved in the evaluation of a numeric constraint the
709 // recursion can cause an endless cycle: we use this flag to exit the loop.
710 kNumericConstraintEvaluationInProgress,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000711 // This flag is set to true after the SetupInformativeDefinitions() pass
712 // has processed this instruction.
713 kIDefsProcessingDone,
714 kLastFlag = kIDefsProcessingDone
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000715 };
716
717 STATIC_ASSERT(kLastFlag < kBitsPerInt);
718
719 static const int kChangesToDependsFlagsLeftShift = 1;
720
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000721 static GVNFlag ChangesFlagFromInt(int x) {
722 return static_cast<GVNFlag>(x * 2);
723 }
724 static GVNFlag DependsOnFlagFromInt(int x) {
725 return static_cast<GVNFlag>(x * 2 + 1);
726 }
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000727 static GVNFlagSet ConvertChangesToDependsFlags(GVNFlagSet flags) {
728 return GVNFlagSet(flags.ToIntegral() << kChangesToDependsFlagsLeftShift);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000729 }
730
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000731 static HValue* cast(HValue* value) { return value; }
732
733 enum Opcode {
734 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000735 #define DECLARE_OPCODE(type) k##type,
736 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
737 kPhi
738 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000739 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000740 virtual Opcode opcode() const = 0;
741
742 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
743 #define DECLARE_PREDICATE(type) \
744 bool Is##type() const { return opcode() == k##type; }
745 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
746 #undef DECLARE_PREDICATE
747 bool IsPhi() const { return opcode() == kPhi; }
748
749 // Declare virtual predicates for abstract HInstruction or HValue
750 #define DECLARE_PREDICATE(type) \
751 virtual bool Is##type() const { return false; }
752 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
753 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000754
755 HValue() : block_(NULL),
756 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000757 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000758 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000759 range_(NULL),
760 flags_(0) {}
761 virtual ~HValue() {}
762
763 HBasicBlock* block() const { return block_; }
764 void SetBlock(HBasicBlock* block);
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000765 int LoopWeight() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000766
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000767 // Note: Never call this method for an unlinked value.
768 Isolate* isolate() const;
769
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000770 int id() const { return id_; }
771 void set_id(int id) { id_ = id; }
772
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000773 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000774
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000775 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000776 Representation representation() const { return representation_; }
777 void ChangeRepresentation(Representation r) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000778 ASSERT(CheckFlag(kFlexibleRepresentation));
779 RepresentationChanged(r);
780 representation_ = r;
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000781 if (r.IsTagged()) {
782 // Tagged is the bottom of the lattice, don't go any further.
783 ClearFlag(kFlexibleRepresentation);
784 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000785 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000786 virtual void AssumeRepresentation(Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000787
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000788 virtual bool IsConvertibleToInteger() const { return true; }
789
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000790 HType type() const { return type_; }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000791 void set_type(HType new_type) {
792 ASSERT(new_type.IsSubtypeOf(type_));
793 type_ = new_type;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000794 }
795
796 // An operation needs to override this function iff:
797 // 1) it can produce an int32 output.
798 // 2) the true value of its output can potentially be minus zero.
799 // The implementation must set a flag so that it bails out in the case where
800 // it would otherwise output what should be a minus zero as an int32 zero.
801 // If the operation also exists in a form that takes int32 and outputs int32
802 // then the operation should return its input value so that we can propagate
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000803 // back. There are three operations that need to propagate back to more than
804 // one input. They are phi and binary div and mul. They always return NULL
805 // and expect the caller to take care of things.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000806 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
807 visited->Add(id());
808 return NULL;
809 }
810
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +0000811 // There are HInstructions that do not really change a value, they
812 // only add pieces of information to it (like bounds checks, map checks,
813 // smi checks...).
814 // We call these instructions "informative definitions", or "iDef".
815 // One of the iDef operands is special because it is the value that is
816 // "transferred" to the output, we call it the "redefined operand".
817 // If an HValue is an iDef it must override RedefinedOperandIndex() so that
818 // it does not return kNoRedefinedOperand;
819 static const int kNoRedefinedOperand = -1;
820 virtual int RedefinedOperandIndex() { return kNoRedefinedOperand; }
821 bool IsInformativeDefinition() {
822 return RedefinedOperandIndex() != kNoRedefinedOperand;
823 }
824 HValue* RedefinedOperand() {
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000825 return IsInformativeDefinition() ? OperandAt(RedefinedOperandIndex())
826 : NULL;
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +0000827 }
828
ulan@chromium.org2e04b582013-02-21 14:06:02 +0000829 // A purely informative definition is an idef that will not emit code and
830 // should therefore be removed from the graph in the RestoreActualValues
831 // phase (so that live ranges will be shorter).
832 virtual bool IsPurelyInformativeDefinition() { return false; }
833
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +0000834 // This method must always return the original HValue SSA definition
835 // (regardless of any iDef of this value).
836 HValue* ActualValue() {
837 return IsInformativeDefinition() ? RedefinedOperand()->ActualValue()
838 : this;
839 }
840
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000841 virtual void AddInformativeDefinitions() {}
842
843 void UpdateRedefinedUsesWhileSettingUpInformativeDefinitions() {
844 UpdateRedefinedUsesInner<TestDominanceUsingProcessedFlag>();
845 }
846 void UpdateRedefinedUses() {
847 UpdateRedefinedUsesInner<Dominates>();
848 }
849
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000850 bool IsInteger32Constant();
851 int32_t GetInteger32Constant();
852
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000853 bool IsDefinedAfter(HBasicBlock* other) const;
854
855 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000856 virtual int OperandCount() = 0;
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +0000857 virtual HValue* OperandAt(int index) const = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000858 void SetOperandAt(int index, HValue* value);
859
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000860 void DeleteAndReplaceWith(HValue* other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000861 void ReplaceAllUsesWith(HValue* other);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000862 bool HasNoUses() const { return use_list_ == NULL; }
863 bool HasMultipleUses() const {
864 return use_list_ != NULL && use_list_->tail() != NULL;
865 }
866 int UseCount() const;
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +0000867
868 // Mark this HValue as dead and to be removed from other HValues' use lists.
869 void Kill();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000870
871 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000872 void SetFlag(Flag f) { flags_ |= (1 << f); }
873 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
874 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
875
ulan@chromium.org812308e2012-02-29 15:58:45 +0000876 // Returns true if the flag specified is set for all uses, false otherwise.
877 bool CheckUsesForFlag(Flag f);
878
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000879 GVNFlagSet gvn_flags() const { return gvn_flags_; }
880 void SetGVNFlag(GVNFlag f) { gvn_flags_.Add(f); }
881 void ClearGVNFlag(GVNFlag f) { gvn_flags_.Remove(f); }
882 bool CheckGVNFlag(GVNFlag f) const { return gvn_flags_.Contains(f); }
883 void SetAllSideEffects() { gvn_flags_.Add(AllSideEffectsFlagSet()); }
884 void ClearAllSideEffects() {
885 gvn_flags_.Remove(AllSideEffectsFlagSet());
886 }
887 bool HasSideEffects() const {
888 return gvn_flags_.ContainsAnyOf(AllSideEffectsFlagSet());
889 }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000890 bool HasObservableSideEffects() const {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000891 return gvn_flags_.ContainsAnyOf(AllObservableSideEffectsFlagSet());
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000892 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000893
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000894 GVNFlagSet DependsOnFlags() const {
895 GVNFlagSet result = gvn_flags_;
896 result.Intersect(AllDependsOnFlagSet());
897 return result;
898 }
899
900 GVNFlagSet SideEffectFlags() const {
901 GVNFlagSet result = gvn_flags_;
902 result.Intersect(AllSideEffectsFlagSet());
903 return result;
904 }
905
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000906 GVNFlagSet ChangesFlags() const {
907 GVNFlagSet result = gvn_flags_;
908 result.Intersect(AllChangesFlagSet());
909 return result;
910 }
911
912 GVNFlagSet ObservableChangesFlags() const {
913 GVNFlagSet result = gvn_flags_;
914 result.Intersect(AllChangesFlagSet());
915 result.Intersect(AllObservableSideEffectsFlagSet());
916 return result;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000917 }
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000918
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000919 Range* range() const { return range_; }
920 bool HasRange() const { return range_ != NULL; }
ulan@chromium.org812308e2012-02-29 15:58:45 +0000921 void AddNewRange(Range* r, Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000922 void RemoveLastAddedRange();
ulan@chromium.org812308e2012-02-29 15:58:45 +0000923 void ComputeInitialRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000924
925 // Representation helpers.
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000926 virtual Representation observed_input_representation(int index) {
927 return Representation::None();
928 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000929 virtual Representation RequiredInputRepresentation(int index) = 0;
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000930 virtual void InferRepresentation(HInferRepresentation* h_infer);
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000931
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000932 // This gives the instruction an opportunity to replace itself with an
933 // instruction that does the same in some better way. To replace an
934 // instruction with a new one, first add the new instruction to the graph,
935 // then return it. Return NULL to have the instruction deleted.
936 virtual HValue* Canonicalize() { return this; }
937
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000938 bool Equals(HValue* other);
939 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000940
941 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000942 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000943 void PrintNameTo(StringStream* stream);
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000944 void PrintTypeTo(StringStream* stream);
945 void PrintRangeTo(StringStream* stream);
946 void PrintChangesTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000947
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000948 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000949
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +0000950 // Type information helpers.
951 bool HasMonomorphicJSObjectType();
952
953 // TODO(mstarzinger): For now instructions can override this function to
954 // specify statically known types, once HType can convey more information
955 // it should be based on the HType.
956 virtual Handle<Map> GetMonomorphicJSObjectMap() { return Handle<Map>(); }
957
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000958 // Updated the inferred type of this instruction and returns true if
959 // it has changed.
960 bool UpdateInferredType();
961
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000962 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000963
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000964 // This function must be overridden for instructions which have the
965 // kTrackSideEffectDominators flag set, to track instructions that are
966 // dominating side effects.
967 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) {
968 UNREACHABLE();
969 }
970
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +0000971 bool IsDead() const {
972 return HasNoUses() && !HasObservableSideEffects() && IsDeletable();
973 }
974
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000975#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000976 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000977#endif
978
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000979 // This method is recursive but it is guaranteed to terminate because
980 // RedefinedOperand() always dominates "this".
981 bool IsRelationTrue(NumericRelation relation, HValue* other) {
982 if (this == other) {
983 return NumericRelation::Eq().Implies(relation);
984 }
985
986 bool result = IsRelationTrueInternal(relation, other) ||
987 other->IsRelationTrueInternal(relation.Reversed(), this);
988 if (!result) {
989 HValue* redefined = RedefinedOperand();
990 if (redefined != NULL) {
991 result = redefined->IsRelationTrue(relation, other);
992 }
993 }
994 return result;
995 }
996
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000997 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000998 // This function must be overridden for instructions with flag kUseGVN, to
999 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001000 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00001001 UNREACHABLE();
1002 return false;
1003 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001004
1005 virtual Representation RepresentationFromInputs() {
1006 return representation();
1007 }
1008 Representation RepresentationFromUses();
1009 virtual void UpdateRepresentation(Representation new_rep,
1010 HInferRepresentation* h_infer,
1011 const char* reason);
1012 void AddDependantsToWorklist(HInferRepresentation* h_infer);
1013
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001014 virtual void RepresentationChanged(Representation to) { }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001015
ulan@chromium.org812308e2012-02-29 15:58:45 +00001016 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001017 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001018 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001019 void clear_block() {
1020 ASSERT(block_ != NULL);
1021 block_ = NULL;
1022 }
1023
1024 void set_representation(Representation r) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001025 ASSERT(representation_.IsNone() && !r.IsNone());
1026 representation_ = r;
1027 }
1028
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00001029 // Signature of a function testing if a HValue properly dominates another.
1030 typedef bool (*DominanceTest)(HValue*, HValue*);
1031
1032 // Simple implementation of DominanceTest implemented walking the chain
1033 // of Hinstructions (used in UpdateRedefinedUsesInner).
1034 static bool Dominates(HValue* dominator, HValue* dominated);
1035
1036 // A fast implementation of DominanceTest that works only for the
1037 // "current" instruction in the SetupInformativeDefinitions() phase.
1038 // During that phase we use a flag to mark processed instructions, and by
1039 // checking the flag we can quickly test if an instruction comes before or
1040 // after the "current" one.
1041 static bool TestDominanceUsingProcessedFlag(HValue* dominator,
1042 HValue* dominated);
1043
1044 // If we are redefining an operand, update all its dominated uses (the
1045 // function that checks if a use is dominated is the template argument).
1046 template<DominanceTest TestDominance>
1047 void UpdateRedefinedUsesInner() {
1048 HValue* input = RedefinedOperand();
1049 if (input != NULL) {
1050 for (HUseIterator uses = input->uses(); !uses.Done(); uses.Advance()) {
1051 HValue* use = uses.value();
1052 if (TestDominance(this, use)) {
1053 use->SetOperandAt(uses.index(), this);
1054 }
1055 }
1056 }
1057 }
1058
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001059 // Informative definitions can override this method to state any numeric
1060 // relation they provide on the redefined value.
1061 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) {
1062 return false;
1063 }
1064
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00001065 static GVNFlagSet AllDependsOnFlagSet() {
1066 GVNFlagSet result;
1067 // Create changes mask.
1068#define ADD_FLAG(type) result.Add(kDependsOn##type);
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001069 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
1070 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00001071#undef ADD_FLAG
1072 return result;
1073 }
1074
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001075 static GVNFlagSet AllChangesFlagSet() {
1076 GVNFlagSet result;
fschneider@chromium.org1805e212011-09-05 10:49:12 +00001077 // Create changes mask.
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001078#define ADD_FLAG(type) result.Add(kChanges##type);
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001079 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
1080 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
fschneider@chromium.org1805e212011-09-05 10:49:12 +00001081#undef ADD_FLAG
1082 return result;
1083 }
1084
ager@chromium.org378b34e2011-01-28 08:04:38 +00001085 // A flag mask to mark an instruction as having arbitrary side effects.
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001086 static GVNFlagSet AllSideEffectsFlagSet() {
1087 GVNFlagSet result = AllChangesFlagSet();
1088 result.Remove(kChangesOsrEntries);
1089 return result;
ager@chromium.org378b34e2011-01-28 08:04:38 +00001090 }
1091
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001092 // A flag mask of all side effects that can make observable changes in
1093 // an executing program (i.e. are not safe to repeat, move or remove);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001094 static GVNFlagSet AllObservableSideEffectsFlagSet() {
1095 GVNFlagSet result = AllChangesFlagSet();
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001096 result.Remove(kChangesNewSpacePromotion);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001097 result.Remove(kChangesElementsKind);
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00001098 result.Remove(kChangesElementsPointer);
1099 result.Remove(kChangesMaps);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001100 return result;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001101 }
1102
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00001103 // Remove the matching use from the use list if present. Returns the
1104 // removed list node or NULL.
1105 HUseListNode* RemoveUse(HValue* value, int index);
1106
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001107 void RegisterUse(int index, HValue* new_value);
1108
1109 HBasicBlock* block_;
1110
1111 // The id of this instruction in the hydrogen graph, assigned when first
1112 // added to the graph. Reflects creation order.
1113 int id_;
1114
1115 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001116 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00001117 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001118 Range* range_;
1119 int flags_;
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001120 GVNFlagSet gvn_flags_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001121
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001122 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001123 virtual bool IsDeletable() const { return false; }
1124
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001125 DISALLOW_COPY_AND_ASSIGN(HValue);
1126};
1127
1128
1129class HInstruction: public HValue {
1130 public:
1131 HInstruction* next() const { return next_; }
1132 HInstruction* previous() const { return previous_; }
1133
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001134 virtual void PrintTo(StringStream* stream);
1135 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001136
1137 bool IsLinked() const { return block() != NULL; }
1138 void Unlink();
1139 void InsertBefore(HInstruction* next);
1140 void InsertAfter(HInstruction* previous);
1141
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00001142 // The position is a write-once variable.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001143 int position() const { return position_; }
1144 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00001145 void set_position(int position) {
1146 ASSERT(!has_position());
1147 ASSERT(position != RelocInfo::kNoPosition);
1148 position_ = position;
1149 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001150
ulan@chromium.org812308e2012-02-29 15:58:45 +00001151 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
1152
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001153 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
1154
1155#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001156 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001157#endif
1158
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001159 virtual bool IsCall() { return false; }
1160
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001161 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001162
1163 protected:
1164 HInstruction()
1165 : next_(NULL),
1166 previous_(NULL),
1167 position_(RelocInfo::kNoPosition) {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001168 SetGVNFlag(kDependsOnOsrEntries);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001169 }
1170
1171 virtual void DeleteFromGraph() { Unlink(); }
1172
1173 private:
1174 void InitializeAsFirst(HBasicBlock* block) {
1175 ASSERT(!IsLinked());
1176 SetBlock(block);
1177 }
1178
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001179 void PrintMnemonicTo(StringStream* stream);
1180
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001181 HInstruction* next_;
1182 HInstruction* previous_;
1183 int position_;
1184
1185 friend class HBasicBlock;
1186};
1187
1188
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001189template<int V>
1190class HTemplateInstruction : public HInstruction {
1191 public:
1192 int OperandCount() { return V; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001193 HValue* OperandAt(int i) const { return inputs_[i]; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001194
1195 protected:
1196 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
1197
1198 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001199 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001200};
1201
1202
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001203class HControlInstruction: public HInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001204 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001205 virtual HBasicBlock* SuccessorAt(int i) = 0;
1206 virtual int SuccessorCount() = 0;
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001207 virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001208
1209 virtual void PrintDataTo(StringStream* stream);
1210
1211 HBasicBlock* FirstSuccessor() {
1212 return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
1213 }
1214 HBasicBlock* SecondSuccessor() {
1215 return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
1216 }
1217
1218 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
1219};
1220
1221
1222class HSuccessorIterator BASE_EMBEDDED {
1223 public:
1224 explicit HSuccessorIterator(HControlInstruction* instr)
1225 : instr_(instr), current_(0) { }
1226
1227 bool Done() { return current_ >= instr_->SuccessorCount(); }
1228 HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
1229 void Advance() { current_++; }
1230
1231 private:
1232 HControlInstruction* instr_;
1233 int current_;
1234};
1235
1236
1237template<int S, int V>
1238class HTemplateControlInstruction: public HControlInstruction {
1239 public:
1240 int SuccessorCount() { return S; }
1241 HBasicBlock* SuccessorAt(int i) { return successors_[i]; }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001242 void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001243
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001244 int OperandCount() { return V; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001245 HValue* OperandAt(int i) const { return inputs_[i]; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001246
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001247
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001248 protected:
1249 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
1250
1251 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001252 EmbeddedContainer<HBasicBlock*, S> successors_;
1253 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001254};
1255
1256
1257class HBlockEntry: public HTemplateInstruction<0> {
1258 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001259 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001260 return Representation::None();
1261 }
1262
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001263 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001264};
1265
1266
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00001267class HDummyUse: public HTemplateInstruction<1> {
1268 public:
1269 explicit HDummyUse(HValue* value) {
1270 SetOperandAt(0, value);
1271 // Pretend to be a Smi so that the HChange instructions inserted
1272 // before any use generate as little code as possible.
1273 set_representation(Representation::Tagged());
1274 set_type(HType::Smi());
1275 }
1276
1277 HValue* value() { return OperandAt(0); }
1278
1279 virtual Representation RequiredInputRepresentation(int index) {
1280 return Representation::None();
1281 }
1282
1283 virtual void PrintDataTo(StringStream* stream);
1284
1285 DECLARE_CONCRETE_INSTRUCTION(DummyUse);
1286};
1287
1288
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001289class HNumericConstraint : public HTemplateInstruction<2> {
1290 public:
1291 static HNumericConstraint* AddToGraph(HValue* constrained_value,
1292 NumericRelation relation,
1293 HValue* related_value,
1294 HInstruction* insertion_point = NULL);
1295
1296 HValue* constrained_value() { return OperandAt(0); }
1297 HValue* related_value() { return OperandAt(1); }
1298 NumericRelation relation() { return relation_; }
1299
1300 virtual int RedefinedOperandIndex() { return 0; }
ulan@chromium.org2e04b582013-02-21 14:06:02 +00001301 virtual bool IsPurelyInformativeDefinition() { return true; }
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001302
1303 virtual Representation RequiredInputRepresentation(int index) {
1304 return representation();
1305 }
1306
1307 virtual void PrintDataTo(StringStream* stream);
1308
1309 virtual bool IsRelationTrueInternal(NumericRelation other_relation,
1310 HValue* other_related_value) {
1311 if (related_value() == other_related_value) {
1312 return relation().Implies(other_relation);
1313 } else {
1314 return false;
1315 }
1316 }
1317
1318 DECLARE_CONCRETE_INSTRUCTION(NumericConstraint)
1319
1320 private:
1321 HNumericConstraint(HValue* constrained_value,
1322 NumericRelation relation,
1323 HValue* related_value)
1324 : relation_(relation) {
1325 SetOperandAt(0, constrained_value);
1326 SetOperandAt(1, related_value);
1327 set_representation(constrained_value->representation());
1328 }
1329
1330 NumericRelation relation_;
1331};
1332
1333
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001334// We insert soft-deoptimize when we hit code with unknown typefeedback,
1335// so that we get a chance of re-optimizing with useful typefeedback.
1336// HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
1337class HSoftDeoptimize: public HTemplateInstruction<0> {
1338 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001339 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001340 return Representation::None();
1341 }
1342
1343 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
1344};
1345
1346
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001347class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001348 public:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001349 HDeoptimize(int environment_length, Zone* zone)
1350 : values_(environment_length, zone) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001351
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001352 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001353 return Representation::None();
1354 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001355
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001356 virtual int OperandCount() { return values_.length(); }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001357 virtual HValue* OperandAt(int index) const { return values_[index]; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001358 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001359
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001360 virtual int SuccessorCount() { return 0; }
1361 virtual HBasicBlock* SuccessorAt(int i) {
1362 UNREACHABLE();
1363 return NULL;
1364 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001365 virtual void SetSuccessorAt(int i, HBasicBlock* block) {
1366 UNREACHABLE();
1367 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001368
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001369 void AddEnvironmentValue(HValue* value, Zone* zone) {
1370 values_.Add(NULL, zone);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001371 SetOperandAt(values_.length() - 1, value);
1372 }
1373
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001374 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001375
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00001376 enum UseEnvironment {
1377 kNoUses,
1378 kUseAll
1379 };
1380
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001381 protected:
1382 virtual void InternalSetOperandAt(int index, HValue* value) {
1383 values_[index] = value;
1384 }
1385
1386 private:
1387 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001388};
1389
1390
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001391class HGoto: public HTemplateControlInstruction<1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001392 public:
ager@chromium.org04921a82011-06-27 13:21:41 +00001393 explicit HGoto(HBasicBlock* target) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001394 SetSuccessorAt(0, target);
1395 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001396
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001397 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001398 return Representation::None();
1399 }
1400
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00001401 virtual void PrintDataTo(StringStream* stream);
1402
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001403 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001404};
1405
1406
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001407class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001408 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001409 HUnaryControlInstruction(HValue* value,
1410 HBasicBlock* true_target,
1411 HBasicBlock* false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001412 SetOperandAt(0, value);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001413 SetSuccessorAt(0, true_target);
1414 SetSuccessorAt(1, false_target);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001415 }
1416
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001417 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001418
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001419 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001420};
1421
1422
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001423class HBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001424 public:
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001425 HBranch(HValue* value,
1426 HBasicBlock* true_target,
1427 HBasicBlock* false_target,
1428 ToBooleanStub::Types expected_input_types = ToBooleanStub::no_types())
1429 : HUnaryControlInstruction(value, true_target, false_target),
1430 expected_input_types_(expected_input_types) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001431 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001432 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001433 explicit HBranch(HValue* value)
1434 : HUnaryControlInstruction(value, NULL, NULL) { }
1435
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001436
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001437 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001438 return Representation::None();
1439 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001440 virtual Representation observed_input_representation(int index);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001441
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001442 ToBooleanStub::Types expected_input_types() const {
1443 return expected_input_types_;
1444 }
1445
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001446 DECLARE_CONCRETE_INSTRUCTION(Branch)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001447
1448 private:
1449 ToBooleanStub::Types expected_input_types_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001450};
1451
1452
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001453class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001454 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001455 HCompareMap(HValue* value,
1456 Handle<Map> map,
1457 HBasicBlock* true_target,
1458 HBasicBlock* false_target)
1459 : HUnaryControlInstruction(value, true_target, false_target),
1460 map_(map) {
1461 ASSERT(true_target != NULL);
1462 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001463 ASSERT(!map.is_null());
1464 }
1465
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001466 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +00001467
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001468 Handle<Map> map() const { return map_; }
1469
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001470 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001471 return Representation::Tagged();
1472 }
1473
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001474 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001475
1476 private:
1477 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001478};
1479
1480
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00001481class HReturn: public HTemplateControlInstruction<0, 2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001482 public:
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00001483 HReturn(HValue* value, HValue* context) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001484 SetOperandAt(0, value);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00001485 SetOperandAt(1, context);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001486 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001487
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001488 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001489 return Representation::Tagged();
1490 }
1491
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001492 virtual void PrintDataTo(StringStream* stream);
1493
1494 HValue* value() { return OperandAt(0); }
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00001495 HValue* context() { return OperandAt(1); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001496
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001497 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001498};
1499
1500
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001501class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001502 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001503 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001504 return Representation::None();
1505 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001506
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001507 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001508};
1509
1510
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001511class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001512 public:
1513 explicit HUnaryOperation(HValue* value) {
1514 SetOperandAt(0, value);
1515 }
1516
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001517 static HUnaryOperation* cast(HValue* value) {
1518 return reinterpret_cast<HUnaryOperation*>(value);
1519 }
1520
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001521 HValue* value() const { return OperandAt(0); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001522 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001523};
1524
1525
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001526class HThrow: public HTemplateInstruction<2> {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001527 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001528 HThrow(HValue* context, HValue* value) {
1529 SetOperandAt(0, context);
1530 SetOperandAt(1, value);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001531 SetAllSideEffects();
1532 }
1533
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001534 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001535 return Representation::Tagged();
1536 }
1537
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001538 HValue* context() { return OperandAt(0); }
1539 HValue* value() { return OperandAt(1); }
1540
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001541 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001542};
1543
1544
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001545class HUseConst: public HUnaryOperation {
1546 public:
1547 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1548
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001549 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001550 return Representation::None();
1551 }
1552
1553 DECLARE_CONCRETE_INSTRUCTION(UseConst)
1554};
1555
1556
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001557class HForceRepresentation: public HTemplateInstruction<1> {
1558 public:
1559 HForceRepresentation(HValue* value, Representation required_representation) {
1560 SetOperandAt(0, value);
1561 set_representation(required_representation);
1562 }
1563
1564 HValue* value() { return OperandAt(0); }
1565
1566 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1567
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001568 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001569 return representation(); // Same as the output representation.
1570 }
1571
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00001572 virtual void PrintDataTo(StringStream* stream);
1573
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001574 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1575};
1576
1577
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001578class HChange: public HUnaryOperation {
1579 public:
1580 HChange(HValue* value,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001581 Representation to,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001582 bool is_truncating,
1583 bool deoptimize_on_undefined)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001584 : HUnaryOperation(value) {
1585 ASSERT(!value->representation().IsNone() && !to.IsNone());
1586 ASSERT(!value->representation().Equals(to));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001587 set_representation(to);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001588 set_type(HType::TaggedNumber());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001589 SetFlag(kUseGVN);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001590 if (deoptimize_on_undefined) SetFlag(kDeoptimizeOnUndefined);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001591 if (is_truncating) SetFlag(kTruncatingToInt32);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00001592 if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001593 }
1594
1595 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001596 virtual HType CalculateInferredType();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001597 virtual HValue* Canonicalize();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001598
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001599 Representation from() const { return value()->representation(); }
1600 Representation to() const { return representation(); }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001601 bool deoptimize_on_undefined() const {
1602 return CheckFlag(kDeoptimizeOnUndefined);
1603 }
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001604 bool deoptimize_on_minus_zero() const {
1605 return CheckFlag(kBailoutOnMinusZero);
1606 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001607 virtual Representation RequiredInputRepresentation(int index) {
1608 return from();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001609 }
1610
ulan@chromium.org812308e2012-02-29 15:58:45 +00001611 virtual Range* InferRange(Zone* zone);
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001612
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001613 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001614
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001615 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001616
1617 protected:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001618 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001619
1620 private:
1621 virtual bool IsDeletable() const {
1622 return !from().IsTagged() || value()->type().IsSmi();
1623 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001624};
1625
1626
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001627class HClampToUint8: public HUnaryOperation {
1628 public:
1629 explicit HClampToUint8(HValue* value)
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001630 : HUnaryOperation(value) {
1631 set_representation(Representation::Integer32());
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001632 SetFlag(kUseGVN);
1633 }
1634
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001635 virtual Representation RequiredInputRepresentation(int index) {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001636 return Representation::None();
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001637 }
1638
1639 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1640
1641 protected:
1642 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001643
1644 private:
1645 virtual bool IsDeletable() const { return true; }
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001646};
1647
1648
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001649enum RemovableSimulate {
1650 REMOVABLE_SIMULATE,
1651 FIXED_SIMULATE
1652};
1653
1654
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001655class HSimulate: public HInstruction {
1656 public:
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001657 HSimulate(BailoutId ast_id,
1658 int pop_count,
1659 Zone* zone,
1660 RemovableSimulate removable)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001661 : ast_id_(ast_id),
1662 pop_count_(pop_count),
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001663 values_(2, zone),
1664 assigned_indexes_(2, zone),
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001665 zone_(zone),
1666 removable_(removable) {}
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001667 virtual ~HSimulate() {}
1668
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001669 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001670
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001671 bool HasAstId() const { return !ast_id_.IsNone(); }
1672 BailoutId ast_id() const { return ast_id_; }
1673 void set_ast_id(BailoutId id) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001674 ASSERT(!HasAstId());
1675 ast_id_ = id;
1676 }
1677
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001678 int pop_count() const { return pop_count_; }
1679 const ZoneList<HValue*>* values() const { return &values_; }
1680 int GetAssignedIndexAt(int index) const {
1681 ASSERT(HasAssignedIndexAt(index));
1682 return assigned_indexes_[index];
1683 }
1684 bool HasAssignedIndexAt(int index) const {
1685 return assigned_indexes_[index] != kNoIndex;
1686 }
1687 void AddAssignedValue(int index, HValue* value) {
1688 AddValue(index, value);
1689 }
1690 void AddPushedValue(HValue* value) {
1691 AddValue(kNoIndex, value);
1692 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001693 virtual int OperandCount() { return values_.length(); }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001694 virtual HValue* OperandAt(int index) const { return values_[index]; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001695
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001696 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001697 return Representation::None();
1698 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001699
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001700 void MergeInto(HSimulate* other);
1701 bool is_candidate_for_removal() { return removable_ == REMOVABLE_SIMULATE; }
1702
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001703 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001704
1705#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001706 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001707#endif
1708
1709 protected:
1710 virtual void InternalSetOperandAt(int index, HValue* value) {
1711 values_[index] = value;
1712 }
1713
1714 private:
1715 static const int kNoIndex = -1;
1716 void AddValue(int index, HValue* value) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001717 assigned_indexes_.Add(index, zone_);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001718 // Resize the list of pushed values.
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001719 values_.Add(NULL, zone_);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001720 // Set the operand through the base method in HValue to make sure that the
1721 // use lists are correctly updated.
1722 SetOperandAt(values_.length() - 1, value);
1723 }
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001724 BailoutId ast_id_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001725 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001726 ZoneList<HValue*> values_;
1727 ZoneList<int> assigned_indexes_;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001728 Zone* zone_;
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001729 RemovableSimulate removable_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001730};
1731
1732
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001733class HStackCheck: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001734 public:
ager@chromium.org04921a82011-06-27 13:21:41 +00001735 enum Type {
1736 kFunctionEntry,
1737 kBackwardsBranch
1738 };
1739
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001740 HStackCheck(HValue* context, Type type) : type_(type) {
1741 SetOperandAt(0, context);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00001742 SetGVNFlag(kChangesNewSpacePromotion);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001743 }
1744
1745 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001746
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001747 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001748 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001749 }
1750
ager@chromium.org04921a82011-06-27 13:21:41 +00001751 void Eliminate() {
1752 // The stack check eliminator might try to eliminate the same stack
1753 // check instruction multiple times.
1754 if (IsLinked()) {
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001755 DeleteAndReplaceWith(NULL);
ager@chromium.org04921a82011-06-27 13:21:41 +00001756 }
1757 }
1758
1759 bool is_function_entry() { return type_ == kFunctionEntry; }
1760 bool is_backwards_branch() { return type_ == kBackwardsBranch; }
1761
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001762 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
ager@chromium.org04921a82011-06-27 13:21:41 +00001763
1764 private:
1765 Type type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001766};
1767
1768
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001769enum InliningKind {
1770 NORMAL_RETURN, // Normal function/method call and return.
1771 DROP_EXTRA_ON_RETURN, // Drop an extra value from the environment on return.
1772 CONSTRUCT_CALL_RETURN, // Either use allocated receiver or return value.
mstarzinger@chromium.orgde886792012-09-11 13:22:37 +00001773 GETTER_CALL_RETURN, // Returning from a getter, need to restore context.
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001774 SETTER_CALL_RETURN // Use the RHS of the assignment as the return value.
1775};
1776
1777
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001778class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001779 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +00001780 HEnterInlined(Handle<JSFunction> closure,
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001781 int arguments_count,
danno@chromium.org40cb8782011-05-25 07:58:50 +00001782 FunctionLiteral* function,
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001783 InliningKind inlining_kind,
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001784 Variable* arguments_var,
yangguo@chromium.org003650e2013-01-24 16:31:08 +00001785 ZoneList<HValue*>* arguments_values,
1786 bool undefined_receiver)
danno@chromium.org40cb8782011-05-25 07:58:50 +00001787 : closure_(closure),
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001788 arguments_count_(arguments_count),
ulan@chromium.org56c14af2012-09-20 12:51:09 +00001789 arguments_pushed_(false),
danno@chromium.org40cb8782011-05-25 07:58:50 +00001790 function_(function),
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001791 inlining_kind_(inlining_kind),
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001792 arguments_var_(arguments_var),
yangguo@chromium.org003650e2013-01-24 16:31:08 +00001793 arguments_values_(arguments_values),
1794 undefined_receiver_(undefined_receiver) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001795 }
1796
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001797 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001798
1799 Handle<JSFunction> closure() const { return closure_; }
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001800 int arguments_count() const { return arguments_count_; }
ulan@chromium.org56c14af2012-09-20 12:51:09 +00001801 bool arguments_pushed() const { return arguments_pushed_; }
1802 void set_arguments_pushed() { arguments_pushed_ = true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001803 FunctionLiteral* function() const { return function_; }
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001804 InliningKind inlining_kind() const { return inlining_kind_; }
yangguo@chromium.org003650e2013-01-24 16:31:08 +00001805 bool undefined_receiver() const { return undefined_receiver_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001806
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001807 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001808 return Representation::None();
1809 }
1810
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001811 Variable* arguments_var() { return arguments_var_; }
1812 ZoneList<HValue*>* arguments_values() { return arguments_values_; }
danno@chromium.org8c0a43f2012-04-03 08:37:53 +00001813
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001814 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001815
1816 private:
1817 Handle<JSFunction> closure_;
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001818 int arguments_count_;
ulan@chromium.org56c14af2012-09-20 12:51:09 +00001819 bool arguments_pushed_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001820 FunctionLiteral* function_;
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001821 InliningKind inlining_kind_;
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001822 Variable* arguments_var_;
1823 ZoneList<HValue*>* arguments_values_;
yangguo@chromium.org003650e2013-01-24 16:31:08 +00001824 bool undefined_receiver_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001825};
1826
1827
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001828class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001829 public:
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00001830 HLeaveInlined() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001831
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001832 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001833 return Representation::None();
1834 }
1835
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001836 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001837};
1838
1839
1840class HPushArgument: public HUnaryOperation {
1841 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001842 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1843 set_representation(Representation::Tagged());
1844 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001845
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001846 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001847 return Representation::Tagged();
1848 }
1849
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001850 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001851
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001852 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001853};
1854
1855
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001856class HThisFunction: public HTemplateInstruction<0> {
1857 public:
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001858 HThisFunction() {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001859 set_representation(Representation::Tagged());
1860 SetFlag(kUseGVN);
1861 }
1862
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001863 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001864 return Representation::None();
1865 }
1866
1867 DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
1868
1869 protected:
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001870 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001871
1872 private:
1873 virtual bool IsDeletable() const { return true; }
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001874};
1875
1876
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001877class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001878 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001879 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001880 set_representation(Representation::Tagged());
1881 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001882 }
1883
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001884 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001885 return Representation::None();
1886 }
1887
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001888 DECLARE_CONCRETE_INSTRUCTION(Context)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001889
1890 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001891 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001892
1893 private:
1894 virtual bool IsDeletable() const { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001895};
1896
1897
1898class HOuterContext: public HUnaryOperation {
1899 public:
1900 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1901 set_representation(Representation::Tagged());
1902 SetFlag(kUseGVN);
1903 }
1904
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001905 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001906
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001907 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001908 return Representation::Tagged();
1909 }
1910
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001911 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001912 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001913
1914 private:
1915 virtual bool IsDeletable() const { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001916};
1917
1918
yangguo@chromium.org56454712012-02-16 15:33:53 +00001919class HDeclareGlobals: public HUnaryOperation {
1920 public:
1921 HDeclareGlobals(HValue* context,
1922 Handle<FixedArray> pairs,
1923 int flags)
1924 : HUnaryOperation(context),
1925 pairs_(pairs),
1926 flags_(flags) {
1927 set_representation(Representation::Tagged());
1928 SetAllSideEffects();
1929 }
1930
1931 HValue* context() { return OperandAt(0); }
1932 Handle<FixedArray> pairs() const { return pairs_; }
1933 int flags() const { return flags_; }
1934
1935 DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals)
1936
1937 virtual Representation RequiredInputRepresentation(int index) {
1938 return Representation::Tagged();
1939 }
1940 private:
1941 Handle<FixedArray> pairs_;
1942 int flags_;
1943};
1944
1945
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001946class HGlobalObject: public HUnaryOperation {
1947 public:
1948 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1949 set_representation(Representation::Tagged());
1950 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001951 }
1952
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001953 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001954
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001955 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001956 return Representation::Tagged();
1957 }
1958
ager@chromium.org378b34e2011-01-28 08:04:38 +00001959 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001960 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001961
1962 private:
1963 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001964};
1965
1966
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001967class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001968 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001969 explicit HGlobalReceiver(HValue* global_object)
1970 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001971 set_representation(Representation::Tagged());
1972 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001973 }
1974
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001975 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001976
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001977 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001978 return Representation::Tagged();
1979 }
1980
ager@chromium.org378b34e2011-01-28 08:04:38 +00001981 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001982 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001983
1984 private:
1985 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001986};
1987
1988
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001989template <int V>
1990class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001991 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001992 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001993 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1994 this->set_representation(Representation::Tagged());
1995 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001996 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001997
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001998 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001999
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002000 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002001
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002002 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002003
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002004 private:
2005 int argument_count_;
2006};
2007
2008
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002009class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002010 public:
2011 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002012 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002013 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002014 }
2015
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002016 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002017 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002018 }
2019
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002020 virtual void PrintDataTo(StringStream* stream);
2021
2022 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002023};
2024
2025
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002026class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002027 public:
2028 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002029 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002030 SetOperandAt(0, first);
2031 SetOperandAt(1, second);
2032 }
2033
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002034 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002035
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002036 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002037 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002038 }
2039
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002040 HValue* first() { return OperandAt(0); }
2041 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002042};
2043
2044
danno@chromium.org160a7b02011-04-18 15:51:38 +00002045class HInvokeFunction: public HBinaryCall {
2046 public:
2047 HInvokeFunction(HValue* context, HValue* function, int argument_count)
2048 : HBinaryCall(context, function, argument_count) {
2049 }
2050
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002051 HInvokeFunction(HValue* context,
2052 HValue* function,
2053 Handle<JSFunction> known_function,
2054 int argument_count)
2055 : HBinaryCall(context, function, argument_count),
2056 known_function_(known_function) {
2057 }
2058
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002059 virtual Representation RequiredInputRepresentation(int index) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00002060 return Representation::Tagged();
2061 }
2062
2063 HValue* context() { return first(); }
2064 HValue* function() { return second(); }
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002065 Handle<JSFunction> known_function() { return known_function_; }
danno@chromium.org160a7b02011-04-18 15:51:38 +00002066
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002067 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002068
2069 private:
2070 Handle<JSFunction> known_function_;
danno@chromium.org160a7b02011-04-18 15:51:38 +00002071};
2072
2073
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002074class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002075 public:
2076 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002077 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002078
2079 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002080
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002081 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002082 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002083 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002084 }
2085
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002086 virtual void PrintDataTo(StringStream* stream);
2087
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002088 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002089 return Representation::None();
2090 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002091
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002092 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002093
2094 private:
2095 Handle<JSFunction> function_;
2096};
2097
2098
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002099class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002100 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002101 HCallKeyed(HValue* context, HValue* key, int argument_count)
2102 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002103 }
2104
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002105 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002106 return Representation::Tagged();
2107 }
2108
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002109 HValue* context() { return first(); }
2110 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002111
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002112 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002113};
2114
2115
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002116class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002117 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002118 HCallNamed(HValue* context, Handle<String> name, int argument_count)
2119 : HUnaryCall(context, argument_count), name_(name) {
2120 }
2121
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002122 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002123
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002124 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002125 Handle<String> name() const { return name_; }
2126
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002127 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002128
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002129 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002130 return Representation::Tagged();
2131 }
2132
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002133 private:
2134 Handle<String> name_;
2135};
2136
2137
danno@chromium.orgc612e022011-11-10 11:38:15 +00002138class HCallFunction: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002139 public:
danno@chromium.orgc612e022011-11-10 11:38:15 +00002140 HCallFunction(HValue* context, HValue* function, int argument_count)
2141 : HBinaryCall(context, function, argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002142 }
2143
danno@chromium.orgc612e022011-11-10 11:38:15 +00002144 HValue* context() { return first(); }
2145 HValue* function() { return second(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002146
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002147 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002148 return Representation::Tagged();
2149 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002150
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002151 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002152};
2153
2154
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002155class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002156 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002157 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
2158 : HUnaryCall(context, argument_count), name_(name) {
2159 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002160
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002161 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002162
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002163 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002164 Handle<String> name() const { return name_; }
2165
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002166 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002167 return Representation::Tagged();
2168 }
2169
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002170 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002171
2172 private:
2173 Handle<String> name_;
2174};
2175
2176
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002177class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002178 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002179 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002180 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002181
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002182 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002183
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002184 Handle<JSFunction> target() const { return target_; }
2185
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002186 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002187 return Representation::None();
2188 }
2189
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002190 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002191
2192 private:
2193 Handle<JSFunction> target_;
2194};
2195
2196
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002197class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002198 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002199 HCallNew(HValue* context, HValue* constructor, int argument_count)
2200 : HBinaryCall(context, constructor, argument_count) {
2201 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002202
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002203 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002204 return Representation::Tagged();
2205 }
2206
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002207 HValue* context() { return first(); }
2208 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002209
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002210 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002211};
2212
2213
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002214class HCallNewArray: public HCallNew {
2215 public:
2216 HCallNewArray(HValue* context, HValue* constructor, int argument_count,
2217 Handle<JSGlobalPropertyCell> type_cell)
2218 : HCallNew(context, constructor, argument_count),
2219 type_cell_(type_cell) {
2220 }
2221
2222 Handle<JSGlobalPropertyCell> property_cell() const {
2223 return type_cell_;
2224 }
2225
2226 DECLARE_CONCRETE_INSTRUCTION(CallNewArray)
2227
2228 private:
2229 Handle<JSGlobalPropertyCell> type_cell_;
2230};
2231
2232
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002233class HCallRuntime: public HCall<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002234 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002235 HCallRuntime(HValue* context,
2236 Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002237 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002238 int argument_count)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002239 : HCall<1>(argument_count), c_function_(c_function), name_(name) {
2240 SetOperandAt(0, context);
2241 }
2242
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002243 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002244
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002245 HValue* context() { return OperandAt(0); }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002246 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002247 Handle<String> name() const { return name_; }
2248
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002249 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002250 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002251 }
2252
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002253 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002254
2255 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002256 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002257 Handle<String> name_;
2258};
2259
2260
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002261class HJSArrayLength: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002262 public:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002263 HJSArrayLength(HValue* value, HValue* typecheck,
2264 HType type = HType::Tagged()) {
2265 set_type(type);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002266 // The length of an array is stored as a tagged value in the array
2267 // object. It is guaranteed to be 32 bit integer, but it can be
2268 // represented as either a smi or heap number.
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002269 SetOperandAt(0, value);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002270 SetOperandAt(1, typecheck != NULL ? typecheck : value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002271 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002272 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00002273 SetGVNFlag(kDependsOnArrayLengths);
2274 SetGVNFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002275 }
2276
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002277 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002278 return Representation::Tagged();
2279 }
2280
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00002281 virtual void PrintDataTo(StringStream* stream);
2282
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002283 HValue* value() { return OperandAt(0); }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002284 HValue* typecheck() {
2285 ASSERT(HasTypeCheck());
2286 return OperandAt(1);
2287 }
2288 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002289
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002290 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002291
2292 protected:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002293 virtual bool DataEquals(HValue* other_raw) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002294
2295 private:
2296 virtual bool IsDeletable() const { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002297};
2298
2299
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00002300class HFixedArrayBaseLength: public HUnaryOperation {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002301 public:
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00002302 explicit HFixedArrayBaseLength(HValue* value) : HUnaryOperation(value) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002303 set_type(HType::Smi());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002304 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002305 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00002306 SetGVNFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002307 }
2308
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002309 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002310 return Representation::Tagged();
2311 }
2312
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00002313 DECLARE_CONCRETE_INSTRUCTION(FixedArrayBaseLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002314
2315 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002316 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002317
2318 private:
2319 virtual bool IsDeletable() const { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002320};
2321
2322
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00002323class HMapEnumLength: public HUnaryOperation {
2324 public:
2325 explicit HMapEnumLength(HValue* value) : HUnaryOperation(value) {
2326 set_type(HType::Smi());
2327 set_representation(Representation::Tagged());
2328 SetFlag(kUseGVN);
2329 SetGVNFlag(kDependsOnMaps);
2330 }
2331
2332 virtual Representation RequiredInputRepresentation(int index) {
2333 return Representation::Tagged();
2334 }
2335
2336 DECLARE_CONCRETE_INSTRUCTION(MapEnumLength)
2337
2338 protected:
2339 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002340
2341 private:
2342 virtual bool IsDeletable() const { return true; }
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00002343};
2344
2345
whesse@chromium.org7b260152011-06-20 15:33:18 +00002346class HElementsKind: public HUnaryOperation {
2347 public:
2348 explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
2349 set_representation(Representation::Integer32());
2350 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00002351 SetGVNFlag(kDependsOnElementsKind);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002352 }
2353
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002354 virtual Representation RequiredInputRepresentation(int index) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002355 return Representation::Tagged();
2356 }
2357
2358 DECLARE_CONCRETE_INSTRUCTION(ElementsKind)
2359
2360 protected:
2361 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002362
2363 private:
2364 virtual bool IsDeletable() const { return true; }
whesse@chromium.org7b260152011-06-20 15:33:18 +00002365};
2366
2367
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002368class HBitNot: public HUnaryOperation {
2369 public:
2370 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
2371 set_representation(Representation::Integer32());
2372 SetFlag(kUseGVN);
2373 SetFlag(kTruncatingToInt32);
2374 }
2375
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002376 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002377 return Representation::Integer32();
2378 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002379 virtual Representation observed_input_representation(int index) {
2380 return Representation::Integer32();
2381 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002382 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002383
mstarzinger@chromium.org88d326b2012-04-23 12:57:22 +00002384 virtual HValue* Canonicalize();
2385
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002386 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002387
2388 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002389 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002390
2391 private:
2392 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002393};
2394
2395
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002396class HUnaryMathOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002397 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00002398 static HInstruction* New(Zone* zone,
2399 HValue* context,
2400 HValue* value,
2401 BuiltinFunctionId op);
2402
2403 HValue* context() { return OperandAt(0); }
2404 HValue* value() { return OperandAt(1); }
2405
2406 virtual void PrintDataTo(StringStream* stream);
2407
2408 virtual HType CalculateInferredType();
2409
2410 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2411
2412 virtual Representation RequiredInputRepresentation(int index) {
2413 if (index == 0) {
2414 return Representation::Tagged();
2415 } else {
2416 switch (op_) {
2417 case kMathFloor:
2418 case kMathRound:
2419 case kMathSqrt:
2420 case kMathPowHalf:
2421 case kMathLog:
2422 case kMathExp:
2423 case kMathSin:
2424 case kMathCos:
2425 case kMathTan:
2426 return Representation::Double();
2427 case kMathAbs:
2428 return representation();
2429 default:
2430 UNREACHABLE();
2431 return Representation::None();
2432 }
2433 }
2434 }
2435
2436 virtual HValue* Canonicalize();
2437
2438 BuiltinFunctionId op() const { return op_; }
2439 const char* OpName() const;
2440
2441 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
2442
2443 protected:
2444 virtual bool DataEquals(HValue* other) {
2445 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
2446 return op_ == b->op();
2447 }
2448
2449 private:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002450 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
2451 : op_(op) {
2452 SetOperandAt(0, context);
2453 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002454 switch (op) {
2455 case kMathFloor:
2456 case kMathRound:
2457 case kMathCeil:
2458 set_representation(Representation::Integer32());
2459 break;
2460 case kMathAbs:
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002461 // Not setting representation here: it is None intentionally.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002462 SetFlag(kFlexibleRepresentation);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002463 SetGVNFlag(kChangesNewSpacePromotion);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002464 break;
2465 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002466 case kMathPowHalf:
2467 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00002468 case kMathSin:
2469 case kMathCos:
ulan@chromium.org9a21ec42012-03-06 08:42:24 +00002470 case kMathTan:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002471 set_representation(Representation::Double());
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002472 SetGVNFlag(kChangesNewSpacePromotion);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002473 break;
danno@chromium.org1f34ad32012-11-26 14:53:56 +00002474 case kMathExp:
2475 set_representation(Representation::Double());
2476 break;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002477 default:
2478 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002479 }
2480 SetFlag(kUseGVN);
2481 }
2482
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002483 virtual bool IsDeletable() const { return true; }
2484
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002485 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002486};
2487
2488
verwaest@chromium.org68c05782012-09-04 09:58:32 +00002489class HLoadElements: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002490 public:
verwaest@chromium.org68c05782012-09-04 09:58:32 +00002491 HLoadElements(HValue* value, HValue* typecheck) {
2492 SetOperandAt(0, value);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002493 SetOperandAt(1, typecheck != NULL ? typecheck : value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002494 set_representation(Representation::Tagged());
2495 SetFlag(kUseGVN);
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00002496 SetGVNFlag(kDependsOnElementsPointer);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002497 }
2498
verwaest@chromium.org68c05782012-09-04 09:58:32 +00002499 HValue* value() { return OperandAt(0); }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002500 HValue* typecheck() {
2501 ASSERT(HasTypeCheck());
2502 return OperandAt(1);
2503 }
2504 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00002505
2506 virtual void PrintDataTo(StringStream* stream);
verwaest@chromium.org68c05782012-09-04 09:58:32 +00002507
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002508 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002509 return Representation::Tagged();
2510 }
2511
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002512 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002513
2514 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002515 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002516
2517 private:
2518 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002519};
2520
2521
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002522class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002523 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002524 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002525 : HUnaryOperation(value) {
2526 set_representation(Representation::External());
2527 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002528 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002529 // change once set, so it's no necessary to introduce any additional
2530 // dependencies on top of the inputs.
2531 SetFlag(kUseGVN);
2532 }
2533
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002534 virtual Representation RequiredInputRepresentation(int index) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002535 return Representation::Tagged();
2536 }
2537
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002538 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002539
2540 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002541 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002542
2543 private:
2544 virtual bool IsDeletable() const { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002545};
2546
2547
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002548class HCheckMaps: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002549 public:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002550 HCheckMaps(HValue* value, Handle<Map> map, Zone* zone,
2551 HValue* typecheck = NULL) {
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002552 SetOperandAt(0, value);
2553 // If callers don't depend on a typecheck, they can pass in NULL. In that
2554 // case we use a copy of the |value| argument as a dummy value.
2555 SetOperandAt(1, typecheck != NULL ? typecheck : value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002556 set_representation(Representation::Tagged());
2557 SetFlag(kUseGVN);
yangguo@chromium.org003650e2013-01-24 16:31:08 +00002558 SetFlag(kTrackSideEffectDominators);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00002559 SetGVNFlag(kDependsOnMaps);
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002560 SetGVNFlag(kDependsOnElementsKind);
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002561 map_set()->Add(map, zone);
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002562 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002563 HCheckMaps(HValue* value, SmallMapList* maps, Zone* zone) {
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002564 SetOperandAt(0, value);
2565 SetOperandAt(1, value);
2566 set_representation(Representation::Tagged());
2567 SetFlag(kUseGVN);
yangguo@chromium.org003650e2013-01-24 16:31:08 +00002568 SetFlag(kTrackSideEffectDominators);
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002569 SetGVNFlag(kDependsOnMaps);
2570 SetGVNFlag(kDependsOnElementsKind);
2571 for (int i = 0; i < maps->length(); i++) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002572 map_set()->Add(maps->at(i), zone);
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00002573 }
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002574 map_set()->Sort();
2575 }
2576
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002577 static HCheckMaps* NewWithTransitions(HValue* object, Handle<Map> map,
2578 Zone* zone) {
2579 HCheckMaps* check_map = new(zone) HCheckMaps(object, map, zone);
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002580 SmallMapList* map_set = check_map->map_set();
2581
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002582 // Since transitioned elements maps of the initial map don't fail the map
2583 // check, the CheckMaps instruction doesn't need to depend on ElementsKinds.
2584 check_map->ClearGVNFlag(kDependsOnElementsKind);
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002585
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002586 ElementsKind kind = map->elements_kind();
2587 bool packed = IsFastPackedElementsKind(kind);
2588 while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) {
2589 kind = GetNextMoreGeneralFastElementsKind(kind, packed);
2590 Map* transitioned_map =
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002591 map->LookupElementsTransitionMap(kind);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002592 if (transitioned_map) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002593 map_set->Add(Handle<Map>(transitioned_map), zone);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002594 }
2595 };
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002596 map_set->Sort();
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002597 return check_map;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002598 }
2599
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002600 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002601 return Representation::Tagged();
2602 }
yangguo@chromium.org003650e2013-01-24 16:31:08 +00002603 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002604 virtual void PrintDataTo(StringStream* stream);
2605 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002606
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002607 HValue* value() { return OperandAt(0); }
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002608 SmallMapList* map_set() { return &map_set_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002609
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002610 DECLARE_CONCRETE_INSTRUCTION(CheckMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002611
2612 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002613 virtual bool DataEquals(HValue* other) {
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002614 HCheckMaps* b = HCheckMaps::cast(other);
2615 // Relies on the fact that map_set has been sorted before.
2616 if (map_set()->length() != b->map_set()->length()) return false;
2617 for (int i = 0; i < map_set()->length(); i++) {
2618 if (!map_set()->at(i).is_identical_to(b->map_set()->at(i))) return false;
2619 }
2620 return true;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002621 }
2622
2623 private:
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002624 SmallMapList map_set_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002625};
2626
2627
2628class HCheckFunction: public HUnaryOperation {
2629 public:
2630 HCheckFunction(HValue* value, Handle<JSFunction> function)
2631 : HUnaryOperation(value), target_(function) {
2632 set_representation(Representation::Tagged());
2633 SetFlag(kUseGVN);
yangguo@chromium.org003650e2013-01-24 16:31:08 +00002634 target_in_new_space_ = Isolate::Current()->heap()->InNewSpace(*function);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002635 }
2636
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002637 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002638 return Representation::Tagged();
2639 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002640 virtual void PrintDataTo(StringStream* stream);
2641 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002642
2643#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002644 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002645#endif
2646
2647 Handle<JSFunction> target() const { return target_; }
yangguo@chromium.org003650e2013-01-24 16:31:08 +00002648 bool target_in_new_space() const { return target_in_new_space_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002649
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002650 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002651
2652 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002653 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002654 HCheckFunction* b = HCheckFunction::cast(other);
2655 return target_.is_identical_to(b->target());
2656 }
2657
2658 private:
2659 Handle<JSFunction> target_;
yangguo@chromium.org003650e2013-01-24 16:31:08 +00002660 bool target_in_new_space_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002661};
2662
2663
2664class HCheckInstanceType: public HUnaryOperation {
2665 public:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002666 static HCheckInstanceType* NewIsSpecObject(HValue* value, Zone* zone) {
2667 return new(zone) HCheckInstanceType(value, IS_SPEC_OBJECT);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002668 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002669 static HCheckInstanceType* NewIsJSArray(HValue* value, Zone* zone) {
2670 return new(zone) HCheckInstanceType(value, IS_JS_ARRAY);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002671 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002672 static HCheckInstanceType* NewIsString(HValue* value, Zone* zone) {
2673 return new(zone) HCheckInstanceType(value, IS_STRING);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002674 }
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002675 static HCheckInstanceType* NewIsInternalizedString(
2676 HValue* value, Zone* zone) {
2677 return new(zone) HCheckInstanceType(value, IS_INTERNALIZED_STRING);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002678 }
2679
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002680 virtual void PrintDataTo(StringStream* stream);
2681
2682 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002683 return Representation::Tagged();
2684 }
2685
sgjesse@chromium.org6db88712011-07-11 11:41:22 +00002686 virtual HValue* Canonicalize();
danno@chromium.org160a7b02011-04-18 15:51:38 +00002687
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002688 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
2689 void GetCheckInterval(InstanceType* first, InstanceType* last);
2690 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002691
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002692 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002693
2694 protected:
2695 // TODO(ager): It could be nice to allow the ommision of instance
2696 // type checks if we have already performed an instance type check
2697 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002698 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002699 HCheckInstanceType* b = HCheckInstanceType::cast(other);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002700 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002701 }
2702
2703 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002704 enum Check {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002705 IS_SPEC_OBJECT,
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002706 IS_JS_ARRAY,
2707 IS_STRING,
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002708 IS_INTERNALIZED_STRING,
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002709 LAST_INTERVAL_CHECK = IS_JS_ARRAY
2710 };
2711
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002712 const char* GetCheckName();
2713
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002714 HCheckInstanceType(HValue* value, Check check)
2715 : HUnaryOperation(value), check_(check) {
2716 set_representation(Representation::Tagged());
2717 SetFlag(kUseGVN);
2718 }
2719
2720 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002721};
2722
2723
2724class HCheckNonSmi: public HUnaryOperation {
2725 public:
2726 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
2727 set_representation(Representation::Tagged());
2728 SetFlag(kUseGVN);
2729 }
2730
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002731 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002732 return Representation::Tagged();
2733 }
2734
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002735 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002736
2737#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002738 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002739#endif
2740
danno@chromium.org160a7b02011-04-18 15:51:38 +00002741 virtual HValue* Canonicalize() {
2742 HType value_type = value()->type();
2743 if (!value_type.IsUninitialized() &&
2744 (value_type.IsHeapNumber() ||
2745 value_type.IsString() ||
2746 value_type.IsBoolean() ||
2747 value_type.IsNonPrimitive())) {
2748 return NULL;
2749 }
2750 return this;
2751 }
2752
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002753 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002754
2755 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002756 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002757};
2758
2759
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002760class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002761 public:
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00002762 HCheckPrototypeMaps(Handle<JSObject> prototype,
2763 Handle<JSObject> holder,
2764 Zone* zone) : prototypes_(2, zone), maps_(2, zone) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002765 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00002766 SetGVNFlag(kDependsOnMaps);
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00002767 // Keep a list of all objects on the prototype chain up to the holder
2768 // and the expected maps.
2769 while (true) {
2770 prototypes_.Add(prototype, zone);
2771 maps_.Add(Handle<Map>(prototype->map()), zone);
2772 if (prototype.is_identical_to(holder)) break;
2773 prototype = Handle<JSObject>(JSObject::cast(prototype->GetPrototype()));
2774 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002775 }
2776
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00002777 ZoneList<Handle<JSObject> >* prototypes() { return &prototypes_; }
2778
2779 ZoneList<Handle<Map> >* maps() { return &maps_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002780
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002781 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002782
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002783 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002784 return Representation::None();
2785 }
2786
danno@chromium.org81cac2b2012-07-10 11:28:27 +00002787 virtual void PrintDataTo(StringStream* stream);
2788
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002789 virtual intptr_t Hashcode() {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002790 ASSERT_ALLOCATION_DISABLED;
yangguo@chromium.org003650e2013-01-24 16:31:08 +00002791 // Dereferencing to use the object's raw address for hashing is safe.
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00002792 AllowHandleDereference allow_handle_deref(isolate());
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00002793 intptr_t hash = 0;
2794 for (int i = 0; i < prototypes_.length(); i++) {
2795 hash = 17 * hash + reinterpret_cast<intptr_t>(*prototypes_[i]);
2796 hash = 17 * hash + reinterpret_cast<intptr_t>(*maps_[i]);
2797 }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002798 return hash;
2799 }
2800
ulan@chromium.org2e04b582013-02-21 14:06:02 +00002801 bool CanOmitPrototypeChecks() {
2802 for (int i = 0; i < maps()->length(); i++) {
2803 if (!maps()->at(i)->CanOmitPrototypeChecks()) return false;
2804 }
2805 return true;
2806 }
2807
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002808 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002809 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002810 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00002811#ifdef DEBUG
2812 if (prototypes_.length() != b->prototypes()->length()) return false;
2813 for (int i = 0; i < prototypes_.length(); i++) {
2814 if (!prototypes_[i].is_identical_to(b->prototypes()->at(i))) return false;
2815 if (!maps_[i].is_identical_to(b->maps()->at(i))) return false;
2816 }
2817 return true;
2818#else
2819 return prototypes_.first().is_identical_to(b->prototypes()->first()) &&
2820 prototypes_.last().is_identical_to(b->prototypes()->last());
2821#endif // DEBUG
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002822 }
2823
2824 private:
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00002825 ZoneList<Handle<JSObject> > prototypes_;
2826 ZoneList<Handle<Map> > maps_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002827};
2828
2829
2830class HCheckSmi: public HUnaryOperation {
2831 public:
2832 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
2833 set_representation(Representation::Tagged());
2834 SetFlag(kUseGVN);
2835 }
2836
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002837 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002838 return Representation::Tagged();
2839 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002840 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002841
2842#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002843 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002844#endif
2845
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002846 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002847
2848 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002849 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002850};
2851
2852
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002853class HCheckSmiOrInt32: public HUnaryOperation {
2854 public:
2855 explicit HCheckSmiOrInt32(HValue* value) : HUnaryOperation(value) {
2856 SetFlag(kFlexibleRepresentation);
2857 SetFlag(kUseGVN);
2858 }
2859
2860 virtual int RedefinedOperandIndex() { return 0; }
2861 virtual Representation RequiredInputRepresentation(int index) {
2862 return representation();
2863 }
2864 virtual void InferRepresentation(HInferRepresentation* h_infer);
2865
ulan@chromium.org2e04b582013-02-21 14:06:02 +00002866 virtual Representation observed_input_representation(int index) {
2867 return Representation::Integer32();
2868 }
2869
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002870 virtual HValue* Canonicalize() {
2871 if (representation().IsTagged() && !type().IsSmi()) {
2872 return this;
2873 } else {
2874 return value();
2875 }
2876 }
2877
2878 DECLARE_CONCRETE_INSTRUCTION(CheckSmiOrInt32)
2879
2880 protected:
2881 virtual bool DataEquals(HValue* other) { return true; }
2882};
2883
2884
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002885class HPhi: public HValue {
2886 public:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002887 HPhi(int merged_index, Zone* zone)
2888 : inputs_(2, zone),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002889 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002890 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002891 is_live_(false),
2892 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002893 for (int i = 0; i < Representation::kNumRepresentations; i++) {
2894 non_phi_uses_[i] = 0;
2895 indirect_uses_[i] = 0;
2896 }
2897 ASSERT(merged_index >= 0);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002898 SetFlag(kFlexibleRepresentation);
2899 }
2900
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002901 virtual Representation RepresentationFromInputs();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002902
ulan@chromium.org812308e2012-02-29 15:58:45 +00002903 virtual Range* InferRange(Zone* zone);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002904 virtual void InferRepresentation(HInferRepresentation* h_infer);
2905 Representation RepresentationObservedByAllNonPhiUses();
2906 Representation RepresentationFromUseRequirements();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002907 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002908 return representation();
2909 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002910 virtual HType CalculateInferredType();
2911 virtual int OperandCount() { return inputs_.length(); }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002912 virtual HValue* OperandAt(int index) const { return inputs_[index]; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002913 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002914 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002915 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002916
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002917 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002918
2919 int merged_index() const { return merged_index_; }
2920
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002921 virtual void AddInformativeDefinitions();
2922
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002923 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002924
2925#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002926 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002927#endif
2928
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002929 void InitRealUses(int id);
2930 void AddNonPhiUsesFrom(HPhi* other);
2931 void AddIndirectUsesTo(int* use_count);
2932
2933 int tagged_non_phi_uses() const {
2934 return non_phi_uses_[Representation::kTagged];
2935 }
2936 int int32_non_phi_uses() const {
2937 return non_phi_uses_[Representation::kInteger32];
2938 }
2939 int double_non_phi_uses() const {
2940 return non_phi_uses_[Representation::kDouble];
2941 }
2942 int tagged_indirect_uses() const {
2943 return indirect_uses_[Representation::kTagged];
2944 }
2945 int int32_indirect_uses() const {
2946 return indirect_uses_[Representation::kInteger32];
2947 }
2948 int double_indirect_uses() const {
2949 return indirect_uses_[Representation::kDouble];
2950 }
2951 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002952 bool is_live() { return is_live_; }
2953 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002954
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002955 static HPhi* cast(HValue* value) {
2956 ASSERT(value->IsPhi());
2957 return reinterpret_cast<HPhi*>(value);
2958 }
2959 virtual Opcode opcode() const { return HValue::kPhi; }
2960
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002961 virtual bool IsConvertibleToInteger() const {
2962 return is_convertible_to_integer_;
2963 }
2964
2965 void set_is_convertible_to_integer(bool b) {
2966 is_convertible_to_integer_ = b;
2967 }
2968
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002969 bool AllOperandsConvertibleToInteger() {
2970 for (int i = 0; i < OperandCount(); ++i) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002971 if (!OperandAt(i)->IsConvertibleToInteger()) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002972 if (FLAG_trace_representation) {
2973 HValue* input = OperandAt(i);
2974 PrintF("#%d %s: Input #%d %s at %d is NCTI\n",
2975 id(), Mnemonic(), input->id(), input->Mnemonic(), i);
2976 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002977 return false;
2978 }
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002979 }
2980 return true;
2981 }
2982
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002983 protected:
2984 virtual void DeleteFromGraph();
2985 virtual void InternalSetOperandAt(int index, HValue* value) {
2986 inputs_[index] = value;
2987 }
2988
ulan@chromium.org2e04b582013-02-21 14:06:02 +00002989 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other);
2990
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002991 private:
2992 ZoneList<HValue*> inputs_;
2993 int merged_index_;
2994
2995 int non_phi_uses_[Representation::kNumRepresentations];
2996 int indirect_uses_[Representation::kNumRepresentations];
2997 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002998 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002999 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003000};
3001
3002
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003003class HInductionVariableAnnotation : public HUnaryOperation {
3004 public:
3005 static HInductionVariableAnnotation* AddToGraph(HPhi* phi,
3006 NumericRelation relation,
3007 int operand_index);
3008
3009 NumericRelation relation() { return relation_; }
3010 HValue* induction_base() { return phi_->OperandAt(operand_index_); }
3011
3012 virtual int RedefinedOperandIndex() { return 0; }
3013 virtual bool IsPurelyInformativeDefinition() { return true; }
3014 virtual Representation RequiredInputRepresentation(int index) {
3015 return representation();
3016 }
3017
3018 virtual void PrintDataTo(StringStream* stream);
3019
3020 virtual bool IsRelationTrueInternal(NumericRelation other_relation,
3021 HValue* other_related_value) {
3022 if (induction_base() == other_related_value) {
3023 return relation().Implies(other_relation);
3024 } else {
3025 return false;
3026 }
3027 }
3028
3029 DECLARE_CONCRETE_INSTRUCTION(InductionVariableAnnotation)
3030
3031 private:
3032 HInductionVariableAnnotation(HPhi* phi,
3033 NumericRelation relation,
3034 int operand_index)
3035 : HUnaryOperation(phi),
3036 phi_(phi), relation_(relation), operand_index_(operand_index) {
3037 set_representation(phi->representation());
3038 }
3039
3040 // We need to store the phi both here and in the instruction operand because
3041 // the operand can change if a new idef of the phi is added between the phi
3042 // and this instruction (inserting an idef updates every use).
3043 HPhi* phi_;
3044 NumericRelation relation_;
3045 int operand_index_;
3046};
3047
3048
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003049class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003050 public:
3051 HArgumentsObject() {
3052 set_representation(Representation::Tagged());
3053 SetFlag(kIsArguments);
3054 }
3055
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003056 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003057 return Representation::None();
3058 }
3059
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003060 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003061
3062 private:
3063 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003064};
3065
3066
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003067class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003068 public:
3069 HConstant(Handle<Object> handle, Representation r);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003070 HConstant(int32_t value, Representation r);
3071 HConstant(double value, Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003072
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003073 Handle<Object> handle() {
3074 if (handle_.is_null()) {
3075 handle_ = FACTORY->NewNumber(double_value_, TENURED);
3076 }
3077 ASSERT(has_int32_value_ || !handle_->IsSmi());
3078 return handle_;
3079 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003080
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003081 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003082
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003083 bool ImmortalImmovable() const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003084 if (has_int32_value_) {
3085 return false;
3086 }
3087 if (has_double_value_) {
3088 if (BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) ||
3089 isnan(double_value_)) {
3090 return true;
3091 }
3092 return false;
3093 }
3094
3095 ASSERT(!handle_.is_null());
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00003096 Heap* heap = isolate()->heap();
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003097 // We should have handled minus_zero_value and nan_value in the
3098 // has_double_value_ clause above.
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003099 // Dereferencing is safe to compare against singletons.
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00003100 AllowHandleDereference allow_handle_deref(isolate());
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003101 ASSERT(*handle_ != heap->minus_zero_value());
3102 ASSERT(*handle_ != heap->nan_value());
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003103 return *handle_ == heap->undefined_value() ||
3104 *handle_ == heap->null_value() ||
3105 *handle_ == heap->true_value() ||
3106 *handle_ == heap->false_value() ||
3107 *handle_ == heap->the_hole_value() ||
3108 *handle_ == heap->empty_string();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003109 }
3110
3111 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003112 return Representation::None();
3113 }
3114
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00003115 virtual bool IsConvertibleToInteger() const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003116 return has_int32_value_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00003117 }
3118
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003119 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003120 virtual void PrintDataTo(StringStream* stream);
3121 virtual HType CalculateInferredType();
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003122 bool IsInteger() { return handle()->IsSmi(); }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003123 HConstant* CopyToRepresentation(Representation r, Zone* zone) const;
3124 HConstant* CopyToTruncatedInt32(Zone* zone) const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003125 bool HasInteger32Value() const { return has_int32_value_; }
3126 int32_t Integer32Value() const {
3127 ASSERT(HasInteger32Value());
3128 return int32_value_;
3129 }
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003130 bool HasSmiValue() const {
3131 return HasInteger32Value() && Smi::IsValid(Integer32Value());
3132 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003133 bool HasDoubleValue() const { return has_double_value_; }
3134 double DoubleValue() const {
3135 ASSERT(HasDoubleValue());
3136 return double_value_;
3137 }
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003138 bool HasNumberValue() const { return has_double_value_; }
erikcorry0ad885c2011-11-21 13:51:57 +00003139 int32_t NumberValueAsInteger32() const {
3140 ASSERT(HasNumberValue());
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003141 // Irrespective of whether a numeric HConstant can be safely
3142 // represented as an int32, we store the (in some cases lossy)
3143 // representation of the number in int32_value_.
3144 return int32_value_;
erikcorry0ad885c2011-11-21 13:51:57 +00003145 }
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003146 bool HasStringValue() const {
3147 if (has_double_value_ || has_int32_value_) return false;
3148 ASSERT(!handle_.is_null());
3149 return handle_->IsString();
3150 }
3151 Handle<String> StringValue() const {
3152 ASSERT(HasStringValue());
3153 return Handle<String>::cast(handle_);
3154 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003155
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003156 bool ToBoolean();
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003157
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00003158 bool IsUint32() {
3159 return HasInteger32Value() && (Integer32Value() >= 0);
3160 }
3161
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003162 virtual intptr_t Hashcode() {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003163 ASSERT_ALLOCATION_DISABLED;
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003164 intptr_t hash;
3165
3166 if (has_int32_value_) {
3167 hash = static_cast<intptr_t>(int32_value_);
3168 } else if (has_double_value_) {
3169 hash = static_cast<intptr_t>(BitCast<int64_t>(double_value_));
3170 } else {
3171 ASSERT(!handle_.is_null());
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003172 // Dereferencing to use the object's raw address for hashing is safe.
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00003173 AllowHandleDereference allow_handle_deref(isolate());
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003174 hash = reinterpret_cast<intptr_t>(*handle_);
3175 }
3176
3177 return hash;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003178 }
3179
3180#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00003181 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003182#endif
3183
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003184 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003185
3186 protected:
ulan@chromium.org812308e2012-02-29 15:58:45 +00003187 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003188
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003189 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003190 HConstant* other_constant = HConstant::cast(other);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003191 if (has_int32_value_) {
3192 return other_constant->has_int32_value_ &&
3193 int32_value_ == other_constant->int32_value_;
3194 } else if (has_double_value_) {
3195 return other_constant->has_double_value_ &&
3196 BitCast<int64_t>(double_value_) ==
3197 BitCast<int64_t>(other_constant->double_value_);
3198 } else {
3199 ASSERT(!handle_.is_null());
3200 return !other_constant->handle_.is_null() &&
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003201 handle_.is_identical_to(other_constant->handle_);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003202 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003203 }
3204
3205 private:
hpayer@chromium.org8432c912013-02-28 15:55:26 +00003206 void Initialize(Representation r);
3207
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003208 virtual bool IsDeletable() const { return true; }
3209
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003210 // If this is a numerical constant, handle_ either points to to the
3211 // HeapObject the constant originated from or is null. If the
3212 // constant is non-numeric, handle_ always points to a valid
3213 // constant HeapObject.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003214 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003215
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003216 // We store the HConstant in the most specific form safely possible.
3217 // The two flags, has_int32_value_ and has_double_value_ tell us if
3218 // int32_value_ and double_value_ hold valid, safe representations
3219 // of the constant. has_int32_value_ implies has_double_value_ but
3220 // not the converse.
danno@chromium.org160a7b02011-04-18 15:51:38 +00003221 bool has_int32_value_ : 1;
3222 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003223 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003224 double double_value_;
3225};
3226
3227
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003228class HBinaryOperation: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003229 public:
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003230 HBinaryOperation(HValue* context, HValue* left, HValue* right)
3231 : observed_output_representation_(Representation::None()) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003232 ASSERT(left != NULL && right != NULL);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003233 SetOperandAt(0, context);
3234 SetOperandAt(1, left);
3235 SetOperandAt(2, right);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003236 observed_input_representation_[0] = Representation::None();
3237 observed_input_representation_[1] = Representation::None();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003238 }
3239
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003240 HValue* context() { return OperandAt(0); }
3241 HValue* left() { return OperandAt(1); }
3242 HValue* right() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003243
3244 // TODO(kasperl): Move these helpers to the IA-32 Lithium
3245 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003246 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003247 if (IsCommutative() && left()->IsConstant()) return right();
3248 return left();
3249 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003250
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003251 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003252 if (IsCommutative() && left()->IsConstant()) return left();
3253 return right();
3254 }
3255
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003256 void set_observed_input_representation(Representation left,
3257 Representation right) {
3258 observed_input_representation_[0] = left;
3259 observed_input_representation_[1] = right;
3260 }
3261
3262 virtual void initialize_output_representation(Representation observed) {
3263 observed_output_representation_ = observed;
3264 }
3265
3266 virtual Representation observed_input_representation(int index) {
3267 if (index == 0) return Representation::Tagged();
3268 return observed_input_representation_[index - 1];
3269 }
3270
3271 virtual void InferRepresentation(HInferRepresentation* h_infer);
3272 virtual Representation RepresentationFromInputs();
3273 virtual void AssumeRepresentation(Representation r);
3274
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003275 virtual bool IsCommutative() const { return false; }
3276
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003277 virtual void PrintDataTo(StringStream* stream);
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00003278
3279 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation)
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003280
3281 private:
3282 Representation observed_input_representation_[2];
3283 Representation observed_output_representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003284};
3285
3286
yangguo@chromium.org154ff992012-03-13 08:09:54 +00003287class HWrapReceiver: public HTemplateInstruction<2> {
3288 public:
3289 HWrapReceiver(HValue* receiver, HValue* function) {
3290 set_representation(Representation::Tagged());
3291 SetOperandAt(0, receiver);
3292 SetOperandAt(1, function);
3293 }
3294
3295 virtual Representation RequiredInputRepresentation(int index) {
3296 return Representation::Tagged();
3297 }
3298
3299 HValue* receiver() { return OperandAt(0); }
3300 HValue* function() { return OperandAt(1); }
3301
3302 virtual HValue* Canonicalize();
3303
yangguo@chromium.org39110192013-01-16 09:55:08 +00003304 virtual void PrintDataTo(StringStream* stream);
3305
yangguo@chromium.org154ff992012-03-13 08:09:54 +00003306 DECLARE_CONCRETE_INSTRUCTION(WrapReceiver)
3307};
3308
3309
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003310class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003311 public:
3312 HApplyArguments(HValue* function,
3313 HValue* receiver,
3314 HValue* length,
3315 HValue* elements) {
3316 set_representation(Representation::Tagged());
3317 SetOperandAt(0, function);
3318 SetOperandAt(1, receiver);
3319 SetOperandAt(2, length);
3320 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003321 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003322 }
3323
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003324 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003325 // The length is untagged, all other inputs are tagged.
3326 return (index == 2)
3327 ? Representation::Integer32()
3328 : Representation::Tagged();
3329 }
3330
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003331 HValue* function() { return OperandAt(0); }
3332 HValue* receiver() { return OperandAt(1); }
3333 HValue* length() { return OperandAt(2); }
3334 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003335
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003336 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003337};
3338
3339
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003340class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003341 public:
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00003342 explicit HArgumentsElements(bool from_inlined) : from_inlined_(from_inlined) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003343 // The value produced by this instruction is a pointer into the stack
3344 // that looks as if it was a smi because of alignment.
3345 set_representation(Representation::Tagged());
3346 SetFlag(kUseGVN);
3347 }
3348
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003349 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003350
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003351 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003352 return Representation::None();
3353 }
3354
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00003355 bool from_inlined() const { return from_inlined_; }
3356
ager@chromium.org378b34e2011-01-28 08:04:38 +00003357 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003358 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00003359
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003360 private:
3361 virtual bool IsDeletable() const { return true; }
3362
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00003363 bool from_inlined_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003364};
3365
3366
3367class HArgumentsLength: public HUnaryOperation {
3368 public:
3369 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
3370 set_representation(Representation::Integer32());
3371 SetFlag(kUseGVN);
3372 }
3373
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003374 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003375 return Representation::Tagged();
3376 }
3377
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003378 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003379
3380 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003381 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003382
3383 private:
3384 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003385};
3386
3387
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003388class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003389 public:
3390 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
3391 set_representation(Representation::Tagged());
3392 SetFlag(kUseGVN);
3393 SetOperandAt(0, arguments);
3394 SetOperandAt(1, length);
3395 SetOperandAt(2, index);
3396 }
3397
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003398 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003399
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003400 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003401 // The arguments elements is considered tagged.
3402 return index == 0
3403 ? Representation::Tagged()
3404 : Representation::Integer32();
3405 }
3406
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003407 HValue* arguments() { return OperandAt(0); }
3408 HValue* length() { return OperandAt(1); }
3409 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003410
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003411 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003412
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003413 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003414};
3415
3416
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003417enum BoundsCheckKeyMode {
3418 DONT_ALLOW_SMI_KEY,
3419 ALLOW_SMI_KEY
3420};
3421
3422
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003423class HBoundsCheck: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003424 public:
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003425 // Normally HBoundsCheck should be created using the
3426 // HGraphBuilder::AddBoundsCheck() helper, which also guards the index with
3427 // a HCheckSmiOrInt32 check.
3428 // However when building stubs, where we know that the arguments are Int32,
3429 // it makes sense to invoke this constructor directly.
3430 HBoundsCheck(HValue* index,
3431 HValue* length,
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00003432 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY,
3433 Representation r = Representation::None())
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003434 : key_mode_(key_mode), skip_check_(false) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003435 SetOperandAt(0, index);
3436 SetOperandAt(1, length);
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00003437 if (r.IsNone()) {
3438 // In the normal compilation pipeline the representation is flexible
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003439 // (see InferRepresentation).
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00003440 SetFlag(kFlexibleRepresentation);
3441 } else {
3442 // When compiling stubs we want to set the representation explicitly
3443 // so the compilation pipeline can skip the HInferRepresentation phase.
3444 set_representation(r);
3445 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003446 SetFlag(kUseGVN);
3447 }
3448
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003449 bool skip_check() { return skip_check_; }
3450 void set_skip_check(bool skip_check) { skip_check_ = skip_check; }
3451
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003452 virtual Representation RequiredInputRepresentation(int arg_index) {
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00003453 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003454 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003455 virtual Representation observed_input_representation(int index) {
3456 return Representation::Integer32();
3457 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003458
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003459 virtual bool IsRelationTrueInternal(NumericRelation relation,
3460 HValue* related_value);
3461
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003462 virtual void PrintDataTo(StringStream* stream);
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00003463 virtual void InferRepresentation(HInferRepresentation* h_infer);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003464
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003465 HValue* index() { return OperandAt(0); }
3466 HValue* length() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003467
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00003468 virtual int RedefinedOperandIndex() { return 0; }
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003469 virtual bool IsPurelyInformativeDefinition() { return skip_check(); }
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003470 virtual void AddInformativeDefinitions();
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00003471
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003472 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003473
3474 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003475 virtual bool DataEquals(HValue* other) { return true; }
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003476 BoundsCheckKeyMode key_mode_;
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003477 bool skip_check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003478};
3479
3480
3481class HBitwiseBinaryOperation: public HBinaryOperation {
3482 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003483 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
3484 : HBinaryOperation(context, left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003485 SetFlag(kFlexibleRepresentation);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003486 SetFlag(kTruncatingToInt32);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003487 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003488 }
3489
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003490 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003491 return index == 0
3492 ? Representation::Tagged()
3493 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003494 }
3495
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003496 virtual void RepresentationChanged(Representation to) {
3497 if (!to.IsTagged()) {
3498 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003499 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003500 SetFlag(kUseGVN);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003501 } else {
3502 SetAllSideEffects();
3503 ClearFlag(kUseGVN);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003504 }
3505 }
3506
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003507 virtual void UpdateRepresentation(Representation new_rep,
3508 HInferRepresentation* h_infer,
3509 const char* reason) {
3510 // We only generate either int32 or generic tagged bitwise operations.
3511 if (new_rep.IsDouble()) new_rep = Representation::Integer32();
3512 HValue::UpdateRepresentation(new_rep, h_infer, reason);
3513 }
3514
3515 virtual void initialize_output_representation(Representation observed) {
3516 if (observed.IsDouble()) observed = Representation::Integer32();
3517 HBinaryOperation::initialize_output_representation(observed);
3518 }
3519
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003520 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003521
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003522 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003523
3524 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003525 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003526};
3527
3528
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00003529class HMathFloorOfDiv: public HBinaryOperation {
3530 public:
3531 HMathFloorOfDiv(HValue* context, HValue* left, HValue* right)
3532 : HBinaryOperation(context, left, right) {
3533 set_representation(Representation::Integer32());
3534 SetFlag(kUseGVN);
yangguo@chromium.orgd2899aa2012-06-21 11:16:20 +00003535 SetFlag(kCanOverflow);
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003536 if (!right->IsConstant()) {
3537 SetFlag(kCanBeDivByZero);
3538 }
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00003539 }
3540
yangguo@chromium.orgd2899aa2012-06-21 11:16:20 +00003541 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3542
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00003543 virtual Representation RequiredInputRepresentation(int index) {
3544 return Representation::Integer32();
3545 }
3546
3547 DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv)
3548
3549 protected:
3550 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003551
3552 private:
3553 virtual bool IsDeletable() const { return true; }
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00003554};
3555
3556
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003557class HArithmeticBinaryOperation: public HBinaryOperation {
3558 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003559 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right)
3560 : HBinaryOperation(context, left, right) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00003561 SetAllSideEffects();
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003562 SetFlag(kFlexibleRepresentation);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003563 }
3564
3565 virtual void RepresentationChanged(Representation to) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003566 if (to.IsTagged()) {
3567 SetAllSideEffects();
3568 ClearFlag(kUseGVN);
3569 } else {
ager@chromium.org378b34e2011-01-28 08:04:38 +00003570 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003571 SetFlag(kUseGVN);
3572 }
3573 }
3574
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003575 virtual HType CalculateInferredType();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003576 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003577 return index == 0
3578 ? Representation::Tagged()
3579 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003580 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003581
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003582 private:
3583 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003584};
3585
3586
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003587class HCompareGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003588 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003589 HCompareGeneric(HValue* context,
3590 HValue* left,
3591 HValue* right,
3592 Token::Value token)
3593 : HBinaryOperation(context, left, right), token_(token) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003594 ASSERT(Token::IsCompareOp(token));
3595 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003596 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003597 }
3598
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003599 virtual Representation RequiredInputRepresentation(int index) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003600 return index == 0
3601 ? Representation::Tagged()
3602 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003603 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003604
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003605 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003606 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003607
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003608 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003609
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003610 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
3611
3612 private:
3613 Token::Value token_;
3614};
3615
3616
3617class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> {
3618 public:
3619 HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token)
3620 : token_(token) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003621 SetFlag(kFlexibleRepresentation);
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003622 ASSERT(Token::IsCompareOp(token));
3623 SetOperandAt(0, left);
3624 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003625 }
3626
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003627 HValue* left() { return OperandAt(0); }
3628 HValue* right() { return OperandAt(1); }
3629 Token::Value token() const { return token_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003630
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003631 void set_observed_input_representation(Representation left,
3632 Representation right) {
3633 observed_input_representation_[0] = left;
3634 observed_input_representation_[1] = right;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003635 }
3636
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003637 virtual void InferRepresentation(HInferRepresentation* h_infer);
3638
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003639 virtual Representation RequiredInputRepresentation(int index) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003640 return representation();
3641 }
3642 virtual Representation observed_input_representation(int index) {
3643 return observed_input_representation_[index];
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003644 }
3645 virtual void PrintDataTo(StringStream* stream);
3646
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003647 virtual void AddInformativeDefinitions();
3648
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003649 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch)
3650
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003651 private:
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003652 Representation observed_input_representation_[2];
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003653 Token::Value token_;
3654};
3655
3656
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003657class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003658 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003659 HCompareObjectEqAndBranch(HValue* left, HValue* right) {
3660 SetOperandAt(0, left);
3661 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003662 }
3663
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003664 HValue* left() { return OperandAt(0); }
3665 HValue* right() { return OperandAt(1); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003666
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003667 virtual void PrintDataTo(StringStream* stream);
3668
3669 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003670 return Representation::Tagged();
3671 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003672
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003673 DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003674};
3675
3676
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003677class HCompareConstantEqAndBranch: public HUnaryControlInstruction {
whesse@chromium.org7b260152011-06-20 15:33:18 +00003678 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003679 HCompareConstantEqAndBranch(HValue* left, int right, Token::Value op)
3680 : HUnaryControlInstruction(left, NULL, NULL), op_(op), right_(right) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00003681 ASSERT(op == Token::EQ_STRICT);
whesse@chromium.org7b260152011-06-20 15:33:18 +00003682 }
3683
3684 Token::Value op() const { return op_; }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003685 HValue* left() { return value(); }
whesse@chromium.org7b260152011-06-20 15:33:18 +00003686 int right() const { return right_; }
3687
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003688 virtual Representation RequiredInputRepresentation(int index) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00003689 return Representation::Integer32();
3690 }
3691
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003692 DECLARE_CONCRETE_INSTRUCTION(CompareConstantEqAndBranch);
whesse@chromium.org7b260152011-06-20 15:33:18 +00003693
3694 private:
3695 const Token::Value op_;
3696 const int right_;
3697};
3698
3699
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003700class HIsNilAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003701 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003702 HIsNilAndBranch(HValue* value, EqualityKind kind, NilValue nil)
3703 : HUnaryControlInstruction(value, NULL, NULL), kind_(kind), nil_(nil) { }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003704
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003705 EqualityKind kind() const { return kind_; }
3706 NilValue nil() const { return nil_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003707
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003708 virtual void PrintDataTo(StringStream* stream);
3709
3710 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003711 return Representation::Tagged();
3712 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003713 virtual Representation observed_input_representation(int index) {
3714 return Representation::Tagged();
3715 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003716
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003717 DECLARE_CONCRETE_INSTRUCTION(IsNilAndBranch)
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003718
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003719 private:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003720 EqualityKind kind_;
3721 NilValue nil_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003722};
3723
3724
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003725class HIsObjectAndBranch: public HUnaryControlInstruction {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003726 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003727 explicit HIsObjectAndBranch(HValue* value)
3728 : HUnaryControlInstruction(value, NULL, NULL) { }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003729
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003730 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003731 return Representation::Tagged();
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00003732 }
3733
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003734 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch)
3735};
3736
erikcorry0ad885c2011-11-21 13:51:57 +00003737class HIsStringAndBranch: public HUnaryControlInstruction {
3738 public:
3739 explicit HIsStringAndBranch(HValue* value)
3740 : HUnaryControlInstruction(value, NULL, NULL) { }
3741
3742 virtual Representation RequiredInputRepresentation(int index) {
3743 return Representation::Tagged();
3744 }
3745
3746 DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch)
3747};
3748
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003749
3750class HIsSmiAndBranch: public HUnaryControlInstruction {
3751 public:
3752 explicit HIsSmiAndBranch(HValue* value)
3753 : HUnaryControlInstruction(value, NULL, NULL) { }
3754
3755 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
3756
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003757 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003758 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003759 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00003760
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003761 protected:
3762 virtual bool DataEquals(HValue* other) { return true; }
3763};
3764
3765
3766class HIsUndetectableAndBranch: public HUnaryControlInstruction {
3767 public:
3768 explicit HIsUndetectableAndBranch(HValue* value)
3769 : HUnaryControlInstruction(value, NULL, NULL) { }
3770
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003771 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003772 return Representation::Tagged();
3773 }
3774
3775 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
3776};
3777
3778
erikcorry0ad885c2011-11-21 13:51:57 +00003779class HStringCompareAndBranch: public HTemplateControlInstruction<2, 3> {
3780 public:
3781 HStringCompareAndBranch(HValue* context,
3782 HValue* left,
3783 HValue* right,
3784 Token::Value token)
3785 : token_(token) {
3786 ASSERT(Token::IsCompareOp(token));
3787 SetOperandAt(0, context);
3788 SetOperandAt(1, left);
3789 SetOperandAt(2, right);
3790 set_representation(Representation::Tagged());
3791 }
3792
3793 HValue* context() { return OperandAt(0); }
3794 HValue* left() { return OperandAt(1); }
3795 HValue* right() { return OperandAt(2); }
3796 Token::Value token() const { return token_; }
3797
3798 virtual void PrintDataTo(StringStream* stream);
3799
3800 virtual Representation RequiredInputRepresentation(int index) {
3801 return Representation::Tagged();
3802 }
3803
3804 Representation GetInputRepresentation() const {
3805 return Representation::Tagged();
3806 }
3807
3808 DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch)
3809
3810 private:
3811 Token::Value token_;
3812};
3813
3814
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003815class HIsConstructCallAndBranch: public HTemplateControlInstruction<2, 0> {
3816 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003817 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003818 return Representation::None();
3819 }
3820
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003821 DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00003822};
3823
3824
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003825class HHasInstanceTypeAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003826 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003827 HHasInstanceTypeAndBranch(HValue* value, InstanceType type)
3828 : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { }
3829 HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to)
3830 : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003831 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
3832 }
3833
3834 InstanceType from() { return from_; }
3835 InstanceType to() { return to_; }
3836
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003837 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003838
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003839 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003840 return Representation::Tagged();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003841 }
3842
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003843 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
3844
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003845 private:
3846 InstanceType from_;
3847 InstanceType to_; // Inclusive range, not all combinations work.
3848};
3849
3850
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003851class HHasCachedArrayIndexAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003852 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003853 explicit HHasCachedArrayIndexAndBranch(HValue* value)
3854 : HUnaryControlInstruction(value, NULL, NULL) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003855
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003856 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003857 return Representation::Tagged();
3858 }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003859
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003860 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003861};
3862
3863
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00003864class HGetCachedArrayIndex: public HUnaryOperation {
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00003865 public:
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00003866 explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) {
3867 set_representation(Representation::Tagged());
3868 SetFlag(kUseGVN);
3869 }
3870
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003871 virtual Representation RequiredInputRepresentation(int index) {
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00003872 return Representation::Tagged();
3873 }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00003874
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003875 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00003876
3877 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003878 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003879
3880 private:
3881 virtual bool IsDeletable() const { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00003882};
3883
3884
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003885class HClassOfTestAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003886 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003887 HClassOfTestAndBranch(HValue* value, Handle<String> class_name)
3888 : HUnaryControlInstruction(value, NULL, NULL),
3889 class_name_(class_name) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003890
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003891 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch)
3892
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003893 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003894 return Representation::Tagged();
3895 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003896
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003897 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003898
3899 Handle<String> class_name() const { return class_name_; }
3900
3901 private:
3902 Handle<String> class_name_;
3903};
3904
3905
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003906class HTypeofIsAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003907 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003908 HTypeofIsAndBranch(HValue* value, Handle<String> type_literal)
3909 : HUnaryControlInstruction(value, NULL, NULL),
3910 type_literal_(type_literal) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003911
3912 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003913 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003914
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003915 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003916
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003917 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003918 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003919 }
3920
3921 private:
3922 Handle<String> type_literal_;
3923};
3924
3925
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003926class HInstanceOf: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003927 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003928 HInstanceOf(HValue* context, HValue* left, HValue* right)
3929 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003930 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003931 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003932 }
3933
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003934 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003935 return Representation::Tagged();
3936 }
3937
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003938 virtual HType CalculateInferredType();
3939
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003940 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003941
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003942 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003943};
3944
3945
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003946class HInstanceOfKnownGlobal: public HTemplateInstruction<2> {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00003947 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003948 HInstanceOfKnownGlobal(HValue* context,
3949 HValue* left,
3950 Handle<JSFunction> right)
3951 : function_(right) {
3952 SetOperandAt(0, context);
3953 SetOperandAt(1, left);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00003954 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003955 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00003956 }
3957
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003958 HValue* context() { return OperandAt(0); }
3959 HValue* left() { return OperandAt(1); }
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00003960 Handle<JSFunction> function() { return function_; }
3961
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003962 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00003963 return Representation::Tagged();
3964 }
3965
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003966 virtual HType CalculateInferredType();
3967
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003968 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00003969
3970 private:
3971 Handle<JSFunction> function_;
3972};
3973
3974
mstarzinger@chromium.org71fc3462013-02-27 09:34:27 +00003975// TODO(mstarzinger): This instruction should be modeled as a load of the map
3976// field followed by a load of the instance size field once HLoadNamedField is
3977// flexible enough to accommodate byte-field loads.
3978class HInstanceSize: public HTemplateInstruction<1> {
3979 public:
3980 explicit HInstanceSize(HValue* object) {
3981 SetOperandAt(0, object);
3982 set_representation(Representation::Integer32());
3983 }
3984
3985 HValue* object() { return OperandAt(0); }
3986
3987 virtual Representation RequiredInputRepresentation(int index) {
3988 return Representation::Tagged();
3989 }
3990
3991 DECLARE_CONCRETE_INSTRUCTION(InstanceSize)
3992};
3993
3994
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003995class HPower: public HTemplateInstruction<2> {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003996 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003997 static HInstruction* New(Zone* zone, HValue* left, HValue* right);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003998
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003999 HValue* left() { return OperandAt(0); }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004000 HValue* right() const { return OperandAt(1); }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004001
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004002 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004003 return index == 0
4004 ? Representation::Double()
4005 : Representation::None();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004006 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00004007 virtual Representation observed_input_representation(int index) {
4008 return RequiredInputRepresentation(index);
4009 }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004010
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004011 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00004012
4013 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004014 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004015
4016 private:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004017 HPower(HValue* left, HValue* right) {
4018 SetOperandAt(0, left);
4019 SetOperandAt(1, right);
4020 set_representation(Representation::Double());
4021 SetFlag(kUseGVN);
4022 SetGVNFlag(kChangesNewSpacePromotion);
4023 }
4024
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004025 virtual bool IsDeletable() const {
4026 return !right()->representation().IsTagged();
4027 }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004028};
4029
4030
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004031class HRandom: public HTemplateInstruction<1> {
4032 public:
4033 explicit HRandom(HValue* global_object) {
4034 SetOperandAt(0, global_object);
4035 set_representation(Representation::Double());
4036 }
4037
4038 HValue* global_object() { return OperandAt(0); }
4039
4040 virtual Representation RequiredInputRepresentation(int index) {
4041 return Representation::Tagged();
4042 }
4043
4044 DECLARE_CONCRETE_INSTRUCTION(Random)
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004045
4046 private:
4047 virtual bool IsDeletable() const { return true; }
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004048};
4049
4050
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004051class HAdd: public HArithmeticBinaryOperation {
4052 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004053 static HInstruction* New(Zone* zone,
4054 HValue* context,
4055 HValue* left,
4056 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004057
4058 // Add is only commutative if two integer values are added and not if two
4059 // tagged values are added (because it might be a String concatenation).
4060 virtual bool IsCommutative() const {
4061 return !representation().IsTagged();
4062 }
4063
4064 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4065
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004066 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004067
ulan@chromium.org812308e2012-02-29 15:58:45 +00004068 virtual HValue* Canonicalize();
4069
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00004070 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) {
4071 HValue* base = NULL;
4072 int32_t offset = 0;
4073 if (left()->IsInteger32Constant()) {
4074 base = right();
4075 offset = left()->GetInteger32Constant();
4076 } else if (right()->IsInteger32Constant()) {
4077 base = left();
4078 offset = right()->GetInteger32Constant();
4079 } else {
4080 return false;
4081 }
4082
4083 return relation.IsExtendable(offset)
4084 ? base->IsRelationTrue(relation, other) : false;
4085 }
4086
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004087 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004088
4089 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004090 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004091
ulan@chromium.org812308e2012-02-29 15:58:45 +00004092 virtual Range* InferRange(Zone* zone);
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004093
4094 private:
4095 HAdd(HValue* context, HValue* left, HValue* right)
4096 : HArithmeticBinaryOperation(context, left, right) {
4097 SetFlag(kCanOverflow);
4098 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004099};
4100
4101
4102class HSub: public HArithmeticBinaryOperation {
4103 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004104 static HInstruction* New(Zone* zone,
4105 HValue* context,
4106 HValue* left,
4107 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004108
4109 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4110
ulan@chromium.org812308e2012-02-29 15:58:45 +00004111 virtual HValue* Canonicalize();
4112
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00004113 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) {
4114 if (right()->IsInteger32Constant()) {
4115 HValue* base = left();
4116 int32_t offset = right()->GetInteger32Constant();
4117 return relation.IsExtendable(-offset)
4118 ? base->IsRelationTrue(relation, other) : false;
4119 } else {
4120 return false;
4121 }
4122 }
4123
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004124 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004125
4126 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004127 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004128
ulan@chromium.org812308e2012-02-29 15:58:45 +00004129 virtual Range* InferRange(Zone* zone);
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004130
4131 private:
4132 HSub(HValue* context, HValue* left, HValue* right)
4133 : HArithmeticBinaryOperation(context, left, right) {
4134 SetFlag(kCanOverflow);
4135 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004136};
4137
4138
4139class HMul: public HArithmeticBinaryOperation {
4140 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004141 static HInstruction* New(Zone* zone,
4142 HValue* context,
4143 HValue* left,
4144 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004145
4146 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4147
4148 // Only commutative if it is certain that not two objects are multiplicated.
4149 virtual bool IsCommutative() const {
4150 return !representation().IsTagged();
4151 }
4152
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004153 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004154
4155 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004156 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004157
ulan@chromium.org812308e2012-02-29 15:58:45 +00004158 virtual Range* InferRange(Zone* zone);
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004159
4160 private:
4161 HMul(HValue* context, HValue* left, HValue* right)
4162 : HArithmeticBinaryOperation(context, left, right) {
4163 SetFlag(kCanOverflow);
4164 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004165};
4166
4167
4168class HMod: public HArithmeticBinaryOperation {
4169 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004170 static HInstruction* New(Zone* zone,
4171 HValue* context,
4172 HValue* left,
4173 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004174
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004175 bool HasPowerOf2Divisor() {
4176 if (right()->IsConstant() &&
4177 HConstant::cast(right())->HasInteger32Value()) {
4178 int32_t value = HConstant::cast(right())->Integer32Value();
4179 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
4180 }
4181
4182 return false;
4183 }
4184
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004185 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4186
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004187 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004188
4189 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004190 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004191
ulan@chromium.org812308e2012-02-29 15:58:45 +00004192 virtual Range* InferRange(Zone* zone);
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004193
4194 private:
4195 HMod(HValue* context, HValue* left, HValue* right)
4196 : HArithmeticBinaryOperation(context, left, right) {
4197 SetFlag(kCanBeDivByZero);
4198 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004199};
4200
4201
4202class HDiv: public HArithmeticBinaryOperation {
4203 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004204 static HInstruction* New(Zone* zone,
4205 HValue* context,
4206 HValue* left,
4207 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004208
jkummerow@chromium.org5323a9c2012-12-10 19:00:50 +00004209 bool HasPowerOf2Divisor() {
4210 if (right()->IsConstant() &&
4211 HConstant::cast(right())->HasInteger32Value()) {
4212 int32_t value = HConstant::cast(right())->Integer32Value();
4213 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
4214 }
4215
4216 return false;
4217 }
4218
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004219 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4220
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004221 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004222
4223 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004224 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004225
ulan@chromium.org812308e2012-02-29 15:58:45 +00004226 virtual Range* InferRange(Zone* zone);
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004227
4228 private:
4229 HDiv(HValue* context, HValue* left, HValue* right)
4230 : HArithmeticBinaryOperation(context, left, right) {
4231 SetFlag(kCanBeDivByZero);
4232 SetFlag(kCanOverflow);
4233 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004234};
4235
4236
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004237class HMathMinMax: public HArithmeticBinaryOperation {
4238 public:
4239 enum Operation { kMathMin, kMathMax };
4240
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004241 static HInstruction* New(Zone* zone,
4242 HValue* context,
4243 HValue* left,
4244 HValue* right,
4245 Operation op);
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004246
4247 virtual Representation RequiredInputRepresentation(int index) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00004248 return index == 0 ? Representation::Tagged()
4249 : representation();
4250 }
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004251
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00004252 virtual Representation observed_input_representation(int index) {
4253 return RequiredInputRepresentation(index);
4254 }
4255
jkummerow@chromium.org5323a9c2012-12-10 19:00:50 +00004256 virtual void InferRepresentation(HInferRepresentation* h_infer);
4257
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00004258 virtual Representation RepresentationFromInputs() {
4259 Representation left_rep = left()->representation();
4260 Representation right_rep = right()->representation();
4261 if ((left_rep.IsNone() || left_rep.IsInteger32()) &&
4262 (right_rep.IsNone() || right_rep.IsInteger32())) {
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004263 return Representation::Integer32();
4264 }
4265 return Representation::Double();
4266 }
4267
4268 virtual bool IsCommutative() const { return true; }
4269
4270 Operation operation() { return operation_; }
4271
4272 DECLARE_CONCRETE_INSTRUCTION(MathMinMax)
4273
4274 protected:
4275 virtual bool DataEquals(HValue* other) {
4276 return other->IsMathMinMax() &&
4277 HMathMinMax::cast(other)->operation_ == operation_;
4278 }
4279
4280 virtual Range* InferRange(Zone* zone);
4281
4282 private:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004283 HMathMinMax(HValue* context, HValue* left, HValue* right, Operation op)
4284 : HArithmeticBinaryOperation(context, left, right),
4285 operation_(op) { }
4286
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004287 Operation operation_;
4288};
4289
4290
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004291class HBitwise: public HBitwiseBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004292 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004293 static HInstruction* New(Zone* zone,
4294 Token::Value op,
4295 HValue* context,
4296 HValue* left,
4297 HValue* right);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004298
4299 Token::Value op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004300
4301 virtual bool IsCommutative() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004302
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004303 virtual HValue* Canonicalize();
4304
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004305 virtual void PrintDataTo(StringStream* stream);
4306
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004307 DECLARE_CONCRETE_INSTRUCTION(Bitwise)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004308
4309 protected:
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004310 virtual bool DataEquals(HValue* other) {
4311 return op() == HBitwise::cast(other)->op();
4312 }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004313
ulan@chromium.org812308e2012-02-29 15:58:45 +00004314 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004315
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004316 private:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004317 HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right)
4318 : HBitwiseBinaryOperation(context, left, right), op_(op) {
4319 ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR);
4320 }
4321
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004322 Token::Value op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004323};
4324
4325
4326class HShl: public HBitwiseBinaryOperation {
4327 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004328 static HInstruction* New(Zone* zone,
4329 HValue* context,
4330 HValue* left,
4331 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004332
ulan@chromium.org812308e2012-02-29 15:58:45 +00004333 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004334
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004335 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00004336
4337 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004338 virtual bool DataEquals(HValue* other) { return true; }
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004339
4340 private:
4341 HShl(HValue* context, HValue* left, HValue* right)
4342 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004343};
4344
4345
4346class HShr: public HBitwiseBinaryOperation {
4347 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004348 static HInstruction* New(Zone* zone,
4349 HValue* context,
4350 HValue* left,
4351 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004352
ulan@chromium.org812308e2012-02-29 15:58:45 +00004353 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004354
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004355 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00004356
4357 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004358 virtual bool DataEquals(HValue* other) { return true; }
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004359
4360 private:
4361 HShr(HValue* context, HValue* left, HValue* right)
4362 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004363};
4364
4365
4366class HSar: public HBitwiseBinaryOperation {
4367 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004368 static HInstruction* New(Zone* zone,
4369 HValue* context,
4370 HValue* left,
4371 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004372
ulan@chromium.org812308e2012-02-29 15:58:45 +00004373 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004374
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004375 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00004376
4377 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004378 virtual bool DataEquals(HValue* other) { return true; }
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004379
4380 private:
4381 HSar(HValue* context, HValue* left, HValue* right)
4382 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004383};
4384
4385
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00004386class HRor: public HBitwiseBinaryOperation {
4387 public:
4388 HRor(HValue* context, HValue* left, HValue* right)
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004389 : HBitwiseBinaryOperation(context, left, right) {
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00004390 ChangeRepresentation(Representation::Integer32());
4391 }
4392
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00004393 DECLARE_CONCRETE_INSTRUCTION(Ror)
4394
4395 protected:
4396 virtual bool DataEquals(HValue* other) { return true; }
4397};
4398
4399
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004400class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004401 public:
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004402 explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004403 SetGVNFlag(kChangesOsrEntries);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004404 }
4405
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004406 BailoutId ast_id() const { return ast_id_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004407
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004408 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004409 return Representation::None();
4410 }
4411
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004412 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004413
4414 private:
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004415 BailoutId ast_id_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004416};
4417
4418
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004419class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004420 public:
mmassi@chromium.org2f0efde2013-02-06 14:12:58 +00004421 enum ParameterKind {
4422 STACK_PARAMETER,
4423 REGISTER_PARAMETER
4424 };
4425
4426 explicit HParameter(unsigned index,
4427 ParameterKind kind = STACK_PARAMETER)
4428 : index_(index),
4429 kind_(kind) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004430 set_representation(Representation::Tagged());
4431 }
4432
4433 unsigned index() const { return index_; }
mmassi@chromium.org2f0efde2013-02-06 14:12:58 +00004434 ParameterKind kind() const { return kind_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004435
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004436 virtual void PrintDataTo(StringStream* stream);
4437
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004438 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004439 return Representation::None();
4440 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004441
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004442 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004443
4444 private:
4445 unsigned index_;
mmassi@chromium.org2f0efde2013-02-06 14:12:58 +00004446 ParameterKind kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004447};
4448
4449
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004450class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004451 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004452 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
4453 : HUnaryCall(context, argument_count),
4454 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004455 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004456 }
4457
4458 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004459
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004460 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004461
4462 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
4463 transcendental_type_ = transcendental_type;
4464 }
4465 TranscendentalCache::Type transcendental_type() {
4466 return transcendental_type_;
4467 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004468
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004469 virtual void PrintDataTo(StringStream* stream);
4470
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004471 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004472 return Representation::Tagged();
4473 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004474
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004475 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004476
4477 private:
4478 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004479 TranscendentalCache::Type transcendental_type_;
4480};
4481
4482
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004483class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004484 public:
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004485 HUnknownOSRValue()
4486 : incoming_value_(NULL) {
4487 set_representation(Representation::Tagged());
4488 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004489
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004490 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004491 return Representation::None();
4492 }
4493
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004494 void set_incoming_value(HPhi* value) {
4495 incoming_value_ = value;
4496 }
4497
4498 HPhi* incoming_value() {
4499 return incoming_value_;
4500 }
4501
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004502 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004503
4504 private:
4505 HPhi* incoming_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004506};
4507
4508
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004509class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004510 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004511 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, PropertyDetails details)
4512 : cell_(cell), details_(details) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004513 set_representation(Representation::Tagged());
4514 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004515 SetGVNFlag(kDependsOnGlobalVars);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004516 }
4517
yangguo@chromium.org003650e2013-01-24 16:31:08 +00004518 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004519 bool RequiresHoleCheck() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004520
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004521 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004522
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004523 virtual intptr_t Hashcode() {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004524 ASSERT_ALLOCATION_DISABLED;
yangguo@chromium.org003650e2013-01-24 16:31:08 +00004525 // Dereferencing to use the object's raw address for hashing is safe.
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00004526 AllowHandleDereference allow_handle_deref(isolate());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004527 return reinterpret_cast<intptr_t>(*cell_);
4528 }
4529
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004530 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004531 return Representation::None();
4532 }
4533
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004534 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004535
4536 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004537 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004538 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004539 return cell_.is_identical_to(b->cell());
4540 }
4541
4542 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004543 virtual bool IsDeletable() const { return !RequiresHoleCheck(); }
4544
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004545 Handle<JSGlobalPropertyCell> cell_;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004546 PropertyDetails details_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004547};
4548
4549
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004550class HLoadGlobalGeneric: public HTemplateInstruction<2> {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004551 public:
4552 HLoadGlobalGeneric(HValue* context,
4553 HValue* global_object,
4554 Handle<Object> name,
4555 bool for_typeof)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004556 : name_(name),
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004557 for_typeof_(for_typeof) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004558 SetOperandAt(0, context);
4559 SetOperandAt(1, global_object);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004560 set_representation(Representation::Tagged());
4561 SetAllSideEffects();
4562 }
4563
4564 HValue* context() { return OperandAt(0); }
4565 HValue* global_object() { return OperandAt(1); }
4566 Handle<Object> name() const { return name_; }
4567 bool for_typeof() const { return for_typeof_; }
4568
4569 virtual void PrintDataTo(StringStream* stream);
4570
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004571 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004572 return Representation::Tagged();
4573 }
4574
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004575 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004576
4577 private:
4578 Handle<Object> name_;
4579 bool for_typeof_;
4580};
4581
4582
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00004583class HAllocateObject: public HTemplateInstruction<1> {
4584 public:
4585 HAllocateObject(HValue* context, Handle<JSFunction> constructor)
4586 : constructor_(constructor) {
4587 SetOperandAt(0, context);
4588 set_representation(Representation::Tagged());
4589 SetGVNFlag(kChangesNewSpacePromotion);
4590 }
4591
4592 // Maximum instance size for which allocations will be inlined.
4593 static const int kMaxSize = 64 * kPointerSize;
4594
4595 HValue* context() { return OperandAt(0); }
4596 Handle<JSFunction> constructor() { return constructor_; }
4597
4598 virtual Representation RequiredInputRepresentation(int index) {
4599 return Representation::Tagged();
4600 }
4601 virtual Handle<Map> GetMonomorphicJSObjectMap() {
4602 ASSERT(constructor()->has_initial_map());
4603 return Handle<Map>(constructor()->initial_map());
4604 }
4605 virtual HType CalculateInferredType();
4606
4607 DECLARE_CONCRETE_INSTRUCTION(AllocateObject)
4608
4609 private:
4610 // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
4611 // virtual bool IsDeletable() const { return true; }
4612
4613 Handle<JSFunction> constructor_;
4614};
4615
4616
4617class HAllocate: public HTemplateInstruction<2> {
4618 public:
4619 enum Flags {
4620 CAN_ALLOCATE_IN_NEW_SPACE = 1 << 0,
4621 CAN_ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1,
4622 CAN_ALLOCATE_IN_OLD_POINTER_SPACE = 1 << 2,
4623 ALLOCATE_DOUBLE_ALIGNED = 1 << 3
4624 };
4625
4626 HAllocate(HValue* context, HValue* size, HType type, Flags flags)
4627 : type_(type),
4628 flags_(flags) {
4629 ASSERT((flags & CAN_ALLOCATE_IN_OLD_DATA_SPACE) == 0); // unimplemented
4630 ASSERT((flags & CAN_ALLOCATE_IN_OLD_POINTER_SPACE) == 0); // unimplemented
4631 SetOperandAt(0, context);
4632 SetOperandAt(1, size);
4633 set_representation(Representation::Tagged());
4634 SetGVNFlag(kChangesNewSpacePromotion);
4635 }
4636
4637 HValue* context() { return OperandAt(0); }
4638 HValue* size() { return OperandAt(1); }
4639
4640 virtual Representation RequiredInputRepresentation(int index) {
4641 if (index == 0) {
4642 return Representation::Tagged();
4643 } else {
4644 return Representation::Integer32();
4645 }
4646 }
4647
4648 virtual HType CalculateInferredType();
4649
4650 bool CanAllocateInNewSpace() const {
4651 return (flags_ & CAN_ALLOCATE_IN_NEW_SPACE) != 0;
4652 }
4653
4654 bool CanAllocateInOldDataSpace() const {
4655 return (flags_ & CAN_ALLOCATE_IN_OLD_DATA_SPACE) != 0;
4656 }
4657
4658 bool CanAllocateInOldPointerSpace() const {
4659 return (flags_ & CAN_ALLOCATE_IN_OLD_POINTER_SPACE) != 0;
4660 }
4661
4662 bool CanAllocateInOldSpace() const {
4663 return CanAllocateInOldDataSpace() ||
4664 CanAllocateInOldPointerSpace();
4665 }
4666
4667 bool GuaranteedInNewSpace() const {
4668 return CanAllocateInNewSpace() && !CanAllocateInOldSpace();
4669 }
4670
4671 bool MustAllocateDoubleAligned() const {
4672 return (flags_ & ALLOCATE_DOUBLE_ALIGNED) != 0;
4673 }
4674
4675 DECLARE_CONCRETE_INSTRUCTION(Allocate)
4676
4677 private:
4678 HType type_;
4679 Flags flags_;
4680};
4681
4682
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004683inline bool StoringValueNeedsWriteBarrier(HValue* value) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004684 return !value->type().IsBoolean()
4685 && !value->type().IsSmi()
4686 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable());
4687}
4688
4689
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00004690inline bool ReceiverObjectNeedsWriteBarrier(HValue* object,
4691 HValue* new_space_dominator) {
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00004692 if (object != new_space_dominator) return true;
4693 if (object->IsFastLiteral()) return false;
4694 if (object->IsAllocateObject()) return false;
4695 if (object->IsAllocate()) {
4696 return !HAllocate::cast(object)->GuaranteedInNewSpace();
4697 }
4698 return true;
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00004699}
4700
4701
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00004702class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004703 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00004704 HStoreGlobalCell(HValue* value,
4705 Handle<JSGlobalPropertyCell> cell,
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004706 PropertyDetails details)
ager@chromium.org378b34e2011-01-28 08:04:38 +00004707 : HUnaryOperation(value),
4708 cell_(cell),
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004709 details_(details) {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004710 SetGVNFlag(kChangesGlobalVars);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004711 }
4712
4713 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004714 bool RequiresHoleCheck() {
4715 return !details_.IsDontDelete() || details_.IsReadOnly();
4716 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004717 bool NeedsWriteBarrier() {
4718 return StoringValueNeedsWriteBarrier(value());
4719 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004720
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004721 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004722 return Representation::Tagged();
4723 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004724 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004725
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004726 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004727
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004728 private:
4729 Handle<JSGlobalPropertyCell> cell_;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004730 PropertyDetails details_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004731};
4732
4733
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00004734class HStoreGlobalGeneric: public HTemplateInstruction<3> {
4735 public:
4736 HStoreGlobalGeneric(HValue* context,
4737 HValue* global_object,
4738 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004739 HValue* value,
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004740 StrictModeFlag strict_mode_flag)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004741 : name_(name),
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004742 strict_mode_flag_(strict_mode_flag) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00004743 SetOperandAt(0, context);
4744 SetOperandAt(1, global_object);
4745 SetOperandAt(2, value);
4746 set_representation(Representation::Tagged());
4747 SetAllSideEffects();
4748 }
4749
4750 HValue* context() { return OperandAt(0); }
4751 HValue* global_object() { return OperandAt(1); }
4752 Handle<Object> name() const { return name_; }
4753 HValue* value() { return OperandAt(2); }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004754 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00004755
4756 virtual void PrintDataTo(StringStream* stream);
4757
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004758 virtual Representation RequiredInputRepresentation(int index) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00004759 return Representation::Tagged();
4760 }
4761
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004762 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00004763
4764 private:
4765 Handle<Object> name_;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004766 StrictModeFlag strict_mode_flag_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00004767};
4768
4769
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004770class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004771 public:
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004772 enum Mode {
4773 // Perform a normal load of the context slot without checking its value.
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004774 kNoCheck,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004775 // Load and check the value of the context slot. Deoptimize if it's the
4776 // hole value. This is used for checking for loading of uninitialized
4777 // harmony bindings where we deoptimize into full-codegen generated code
4778 // which will subsequently throw a reference error.
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004779 kCheckDeoptimize,
4780 // Load and check the value of the context slot. Return undefined if it's
4781 // the hole value. This is used for non-harmony const assignments
4782 kCheckReturnUndefined
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004783 };
4784
4785 HLoadContextSlot(HValue* context, Variable* var)
4786 : HUnaryOperation(context), slot_index_(var->index()) {
4787 ASSERT(var->IsContextSlot());
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004788 switch (var->mode()) {
4789 case LET:
4790 case CONST_HARMONY:
4791 mode_ = kCheckDeoptimize;
4792 break;
4793 case CONST:
4794 mode_ = kCheckReturnUndefined;
4795 break;
4796 default:
4797 mode_ = kNoCheck;
4798 }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004799 set_representation(Representation::Tagged());
4800 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004801 SetGVNFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004802 }
4803
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004804 int slot_index() const { return slot_index_; }
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004805 Mode mode() const { return mode_; }
4806
4807 bool DeoptimizesOnHole() {
4808 return mode_ == kCheckDeoptimize;
4809 }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004810
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004811 bool RequiresHoleCheck() const {
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004812 return mode_ != kNoCheck;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004813 }
4814
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004815 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004816 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004817 }
4818
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004819 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004820
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004821 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004822
4823 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004824 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004825 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004826 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004827 }
4828
4829 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004830 virtual bool IsDeletable() const { return !RequiresHoleCheck(); }
4831
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004832 int slot_index_;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004833 Mode mode_;
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004834};
4835
4836
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004837class HStoreContextSlot: public HTemplateInstruction<2> {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004838 public:
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004839 enum Mode {
4840 // Perform a normal store to the context slot without checking its previous
4841 // value.
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004842 kNoCheck,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004843 // Check the previous value of the context slot and deoptimize if it's the
4844 // hole value. This is used for checking for assignments to uninitialized
4845 // harmony bindings where we deoptimize into full-codegen generated code
4846 // which will subsequently throw a reference error.
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004847 kCheckDeoptimize,
4848 // Check the previous value and ignore assignment if it isn't a hole value
4849 kCheckIgnoreAssignment
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004850 };
4851
4852 HStoreContextSlot(HValue* context, int slot_index, Mode mode, HValue* value)
4853 : slot_index_(slot_index), mode_(mode) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004854 SetOperandAt(0, context);
4855 SetOperandAt(1, value);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004856 SetGVNFlag(kChangesContextSlots);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004857 }
4858
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004859 HValue* context() { return OperandAt(0); }
4860 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004861 int slot_index() const { return slot_index_; }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004862 Mode mode() const { return mode_; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004863
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004864 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004865 return StoringValueNeedsWriteBarrier(value());
4866 }
4867
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004868 bool DeoptimizesOnHole() {
4869 return mode_ == kCheckDeoptimize;
4870 }
4871
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004872 bool RequiresHoleCheck() {
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004873 return mode_ != kNoCheck;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004874 }
4875
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004876 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004877 return Representation::Tagged();
4878 }
4879
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004880 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004881
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004882 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004883
4884 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004885 int slot_index_;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004886 Mode mode_;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004887};
4888
4889
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004890class HLoadNamedField: public HUnaryOperation {
4891 public:
4892 HLoadNamedField(HValue* object, bool is_in_object, int offset)
4893 : HUnaryOperation(object),
4894 is_in_object_(is_in_object),
4895 offset_(offset) {
4896 set_representation(Representation::Tagged());
4897 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004898 SetGVNFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004899 if (is_in_object) {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004900 SetGVNFlag(kDependsOnInobjectFields);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004901 } else {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004902 SetGVNFlag(kDependsOnBackingStoreFields);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004903 }
4904 }
4905
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004906 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004907 bool is_in_object() const { return is_in_object_; }
4908 int offset() const { return offset_; }
4909
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004910 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004911 return Representation::Tagged();
4912 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004913 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004914
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004915 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004916
4917 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004918 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004919 HLoadNamedField* b = HLoadNamedField::cast(other);
4920 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
4921 }
4922
4923 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004924 virtual bool IsDeletable() const { return true; }
4925
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004926 bool is_in_object_;
4927 int offset_;
4928};
4929
4930
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004931class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004932 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004933 HLoadNamedFieldPolymorphic(HValue* context,
4934 HValue* object,
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00004935 SmallMapList* types,
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004936 Handle<String> name,
4937 Zone* zone);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004938
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004939 HValue* context() { return OperandAt(0); }
4940 HValue* object() { return OperandAt(1); }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00004941 SmallMapList* types() { return &types_; }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004942 Handle<String> name() { return name_; }
4943 bool need_generic() { return need_generic_; }
4944
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004945 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004946 return Representation::Tagged();
4947 }
4948
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00004949 virtual void PrintDataTo(StringStream* stream);
4950
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004951 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004952
4953 static const int kMaxLoadPolymorphism = 4;
4954
4955 protected:
4956 virtual bool DataEquals(HValue* value);
4957
4958 private:
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00004959 SmallMapList types_;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004960 Handle<String> name_;
4961 bool need_generic_;
4962};
4963
4964
4965
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004966class HLoadNamedGeneric: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004967 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004968 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004969 : name_(name) {
4970 SetOperandAt(0, context);
4971 SetOperandAt(1, object);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004972 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004973 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004974 }
4975
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004976 HValue* context() { return OperandAt(0); }
4977 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004978 Handle<Object> name() const { return name_; }
4979
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004980 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004981 return Representation::Tagged();
4982 }
4983
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00004984 virtual void PrintDataTo(StringStream* stream);
4985
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004986 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004987
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004988 private:
4989 Handle<Object> name_;
4990};
4991
4992
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00004993class HLoadFunctionPrototype: public HUnaryOperation {
4994 public:
4995 explicit HLoadFunctionPrototype(HValue* function)
4996 : HUnaryOperation(function) {
4997 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004998 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004999 SetGVNFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00005000 }
5001
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005002 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00005003
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005004 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00005005 return Representation::Tagged();
5006 }
5007
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005008 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00005009
5010 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005011 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00005012};
5013
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00005014class ArrayInstructionInterface {
5015 public:
5016 virtual HValue* GetKey() = 0;
5017 virtual void SetKey(HValue* key) = 0;
5018 virtual void SetIndexOffset(uint32_t index_offset) = 0;
5019 virtual bool IsDehoisted() = 0;
5020 virtual void SetDehoisted(bool is_dehoisted) = 0;
5021 virtual ~ArrayInstructionInterface() { };
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00005022
5023 static Representation KeyedAccessIndexRequirement(Representation r) {
5024 return r.IsInteger32() ? Representation::Integer32()
5025 : Representation::Tagged();
5026 }
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00005027};
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00005028
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005029
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005030enum LoadKeyedHoleMode {
5031 NEVER_RETURN_HOLE,
5032 ALLOW_RETURN_HOLE
5033};
5034
5035
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005036class HLoadKeyed
yangguo@chromium.org304cc332012-07-24 07:59:48 +00005037 : public HTemplateInstruction<3>, public ArrayInstructionInterface {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005038 public:
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005039 HLoadKeyed(HValue* obj,
5040 HValue* key,
5041 HValue* dependency,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005042 ElementsKind elements_kind,
5043 LoadKeyedHoleMode mode = NEVER_RETURN_HOLE)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005044 : bit_field_(0) {
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005045 bit_field_ = ElementsKindField::encode(elements_kind) |
5046 HoleModeField::encode(mode);
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005047
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005048 SetOperandAt(0, obj);
5049 SetOperandAt(1, key);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005050 SetOperandAt(2, dependency != NULL ? dependency : obj);
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005051
5052 if (!is_external()) {
5053 // I can detect the case between storing double (holey and fast) and
5054 // smi/object by looking at elements_kind_.
5055 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
5056 IsFastDoubleElementsKind(elements_kind));
5057
5058 if (IsFastSmiOrObjectElementsKind(elements_kind)) {
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005059 if (IsFastSmiElementsKind(elements_kind)) {
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005060 set_type(HType::Smi());
5061 }
5062
5063 set_representation(Representation::Tagged());
5064 SetGVNFlag(kDependsOnArrayElements);
5065 } else {
5066 set_representation(Representation::Double());
5067 SetGVNFlag(kDependsOnDoubleArrayElements);
5068 }
5069 } else {
5070 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
5071 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
5072 set_representation(Representation::Double());
5073 } else {
5074 set_representation(Representation::Integer32());
5075 }
5076
5077 SetGVNFlag(kDependsOnSpecializedArrayElements);
5078 // Native code could change the specialized array.
5079 SetGVNFlag(kDependsOnCalls);
5080 }
5081
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005082 SetFlag(kUseGVN);
5083 }
5084
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005085 bool is_external() const {
5086 return IsExternalArrayElementsKind(elements_kind());
5087 }
5088 HValue* elements() { return OperandAt(0); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005089 HValue* key() { return OperandAt(1); }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005090 HValue* dependency() {
5091 ASSERT(HasDependency());
5092 return OperandAt(2);
5093 }
5094 bool HasDependency() const { return OperandAt(0) != OperandAt(2); }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005095 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); }
5096 void SetIndexOffset(uint32_t index_offset) {
5097 bit_field_ = IndexOffsetField::update(bit_field_, index_offset);
5098 }
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00005099 HValue* GetKey() { return key(); }
5100 void SetKey(HValue* key) { SetOperandAt(1, key); }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005101 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); }
5102 void SetDehoisted(bool is_dehoisted) {
5103 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted);
5104 }
5105 ElementsKind elements_kind() const {
5106 return ElementsKindField::decode(bit_field_);
5107 }
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005108 LoadKeyedHoleMode hole_mode() const {
5109 return HoleModeField::decode(bit_field_);
5110 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005111
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005112 virtual Representation RequiredInputRepresentation(int index) {
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005113 // kind_fast: tagged[int32] (none)
5114 // kind_double: tagged[int32] (none)
5115 // kind_external: external[int32] (none)
5116 if (index == 0) {
5117 return is_external() ? Representation::External()
5118 : Representation::Tagged();
5119 }
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00005120 if (index == 1) {
5121 return ArrayInstructionInterface::KeyedAccessIndexRequirement(
5122 OperandAt(1)->representation());
5123 }
yangguo@chromium.org304cc332012-07-24 07:59:48 +00005124 return Representation::None();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005125 }
5126
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005127 virtual Representation observed_input_representation(int index) {
5128 return RequiredInputRepresentation(index);
5129 }
5130
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005131 virtual void PrintDataTo(StringStream* stream);
5132
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005133 bool UsesMustHandleHole() const;
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005134 bool RequiresHoleCheck() const;
karlklose@chromium.org83a47282011-05-11 11:54:09 +00005135
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005136 virtual Range* InferRange(Zone* zone);
5137
5138 DECLARE_CONCRETE_INSTRUCTION(LoadKeyed)
ager@chromium.org378b34e2011-01-28 08:04:38 +00005139
5140 protected:
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +00005141 virtual bool DataEquals(HValue* other) {
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005142 if (!other->IsLoadKeyed()) return false;
5143 HLoadKeyed* other_load = HLoadKeyed::cast(other);
5144
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005145 if (IsDehoisted() && index_offset() != other_load->index_offset())
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00005146 return false;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005147 return elements_kind() == other_load->elements_kind();
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +00005148 }
5149
5150 private:
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005151 virtual bool IsDeletable() const {
5152 return !RequiresHoleCheck();
5153 }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005154
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005155 // Establish some checks around our packed fields
5156 enum LoadKeyedBits {
5157 kBitsForElementsKind = 5,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005158 kBitsForHoleMode = 1,
5159 kBitsForIndexOffset = 25,
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005160 kBitsForIsDehoisted = 1,
5161
5162 kStartElementsKind = 0,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005163 kStartHoleMode = kStartElementsKind + kBitsForElementsKind,
5164 kStartIndexOffset = kStartHoleMode + kBitsForHoleMode,
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005165 kStartIsDehoisted = kStartIndexOffset + kBitsForIndexOffset
5166 };
5167
5168 STATIC_ASSERT((kBitsForElementsKind + kBitsForIndexOffset +
5169 kBitsForIsDehoisted) <= sizeof(uint32_t)*8);
5170 STATIC_ASSERT(kElementsKindCount <= (1 << kBitsForElementsKind));
5171 class ElementsKindField:
5172 public BitField<ElementsKind, kStartElementsKind, kBitsForElementsKind>
5173 {}; // NOLINT
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005174 class HoleModeField:
5175 public BitField<LoadKeyedHoleMode, kStartHoleMode, kBitsForHoleMode>
5176 {}; // NOLINT
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005177 class IndexOffsetField:
5178 public BitField<uint32_t, kStartIndexOffset, kBitsForIndexOffset>
5179 {}; // NOLINT
5180 class IsDehoistedField:
5181 public BitField<bool, kStartIsDehoisted, kBitsForIsDehoisted>
5182 {}; // NOLINT
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005183 uint32_t bit_field_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005184};
5185
5186
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005187class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005188 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00005189 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005190 set_representation(Representation::Tagged());
5191 SetOperandAt(0, obj);
5192 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005193 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00005194 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005195 }
5196
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005197 HValue* object() { return OperandAt(0); }
5198 HValue* key() { return OperandAt(1); }
5199 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005200
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005201 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005202
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005203 virtual Representation RequiredInputRepresentation(int index) {
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005204 // tagged[tagged]
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005205 return Representation::Tagged();
5206 }
5207
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +00005208 virtual HValue* Canonicalize();
5209
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005210 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005211};
5212
5213
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005214class HStoreNamedField: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005215 public:
5216 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005217 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005218 HValue* val,
5219 bool in_object,
5220 int offset)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005221 : name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005222 is_in_object_(in_object),
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005223 offset_(offset),
5224 new_space_dominator_(NULL) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005225 SetOperandAt(0, obj);
5226 SetOperandAt(1, val);
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005227 SetFlag(kTrackSideEffectDominators);
5228 SetGVNFlag(kDependsOnNewSpacePromotion);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005229 if (is_in_object_) {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00005230 SetGVNFlag(kChangesInobjectFields);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005231 } else {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00005232 SetGVNFlag(kChangesBackingStoreFields);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005233 }
5234 }
5235
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005236 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005237
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005238 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00005239 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005240 }
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005241 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) {
5242 ASSERT(side_effect == kChangesNewSpacePromotion);
5243 new_space_dominator_ = dominator;
5244 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005245 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005246
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005247 HValue* object() { return OperandAt(0); }
5248 HValue* value() { return OperandAt(1); }
5249
5250 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005251 bool is_in_object() const { return is_in_object_; }
5252 int offset() const { return offset_; }
5253 Handle<Map> transition() const { return transition_; }
5254 void set_transition(Handle<Map> map) { transition_ = map; }
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005255 HValue* new_space_dominator() const { return new_space_dominator_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005256
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005257 bool NeedsWriteBarrier() {
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005258 return StoringValueNeedsWriteBarrier(value()) &&
5259 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
ricow@chromium.org83aa5492011-02-07 12:42:56 +00005260 }
5261
verwaest@chromium.org37141392012-05-31 13:27:02 +00005262 bool NeedsWriteBarrierForMap() {
5263 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
5264 }
5265
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005266 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005267 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005268 bool is_in_object_;
5269 int offset_;
5270 Handle<Map> transition_;
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005271 HValue* new_space_dominator_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005272};
5273
5274
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005275class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005276 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005277 HStoreNamedGeneric(HValue* context,
5278 HValue* object,
5279 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005280 HValue* value,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005281 StrictModeFlag strict_mode_flag)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005282 : name_(name),
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005283 strict_mode_flag_(strict_mode_flag) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005284 SetOperandAt(0, object);
5285 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005286 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00005287 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005288 }
5289
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005290 HValue* object() { return OperandAt(0); }
5291 HValue* value() { return OperandAt(1); }
5292 HValue* context() { return OperandAt(2); }
5293 Handle<String> name() { return name_; }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005294 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005295
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005296 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005297
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005298 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005299 return Representation::Tagged();
5300 }
5301
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005302 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005303
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005304 private:
5305 Handle<String> name_;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005306 StrictModeFlag strict_mode_flag_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005307};
5308
5309
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005310class HStoreKeyed
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00005311 : public HTemplateInstruction<3>, public ArrayInstructionInterface {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005312 public:
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005313 HStoreKeyed(HValue* obj, HValue* key, HValue* val,
5314 ElementsKind elements_kind)
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005315 : elements_kind_(elements_kind),
5316 index_offset_(0),
5317 is_dehoisted_(false),
5318 new_space_dominator_(NULL) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005319 SetOperandAt(0, obj);
5320 SetOperandAt(1, key);
5321 SetOperandAt(2, val);
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005322
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005323 if (IsFastObjectElementsKind(elements_kind)) {
5324 SetFlag(kTrackSideEffectDominators);
5325 SetGVNFlag(kDependsOnNewSpacePromotion);
5326 }
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005327 if (is_external()) {
5328 SetGVNFlag(kChangesSpecializedArrayElements);
5329 } else if (IsFastDoubleElementsKind(elements_kind)) {
5330 SetGVNFlag(kChangesDoubleArrayElements);
5331 SetFlag(kDeoptimizeOnUndefined);
5332 } else {
5333 SetGVNFlag(kChangesArrayElements);
5334 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005335
5336 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating.
5337 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS &&
5338 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) {
5339 SetFlag(kTruncatingToInt32);
5340 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005341 }
5342
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005343 virtual Representation RequiredInputRepresentation(int index) {
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005344 // kind_fast: tagged[int32] = tagged
5345 // kind_double: tagged[int32] = double
5346 // kind_external: external[int32] = (double | int32)
5347 if (index == 0) {
5348 return is_external() ? Representation::External()
5349 : Representation::Tagged();
5350 } else if (index == 1) {
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00005351 return ArrayInstructionInterface::KeyedAccessIndexRequirement(
5352 OperandAt(1)->representation());
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005353 }
5354
5355 ASSERT_EQ(index, 2);
5356 if (IsDoubleOrFloatElementsKind(elements_kind())) {
5357 return Representation::Double();
5358 }
5359
5360 return is_external() ? Representation::Integer32()
5361 : Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005362 }
5363
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005364 bool is_external() const {
5365 return IsExternalArrayElementsKind(elements_kind());
5366 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005367
5368 virtual Representation observed_input_representation(int index) {
5369 if (index < 2) return RequiredInputRepresentation(index);
5370 if (IsDoubleOrFloatElementsKind(elements_kind())) {
5371 return Representation::Double();
5372 }
5373 if (is_external()) {
5374 return Representation::Integer32();
5375 }
5376 // For fast object elements kinds, don't assume anything.
5377 return Representation::None();
5378 }
5379
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005380 HValue* elements() { return OperandAt(0); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005381 HValue* key() { return OperandAt(1); }
5382 HValue* value() { return OperandAt(2); }
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005383 bool value_is_smi() const {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005384 return IsFastSmiElementsKind(elements_kind_);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005385 }
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005386 ElementsKind elements_kind() const { return elements_kind_; }
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00005387 uint32_t index_offset() { return index_offset_; }
5388 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
5389 HValue* GetKey() { return key(); }
5390 void SetKey(HValue* key) { SetOperandAt(1, key); }
5391 bool IsDehoisted() { return is_dehoisted_; }
5392 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005393
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005394 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) {
5395 ASSERT(side_effect == kChangesNewSpacePromotion);
5396 new_space_dominator_ = dominator;
5397 }
5398
5399 HValue* new_space_dominator() const { return new_space_dominator_; }
5400
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005401 bool NeedsWriteBarrier() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005402 if (value_is_smi()) {
5403 return false;
5404 } else {
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005405 return StoringValueNeedsWriteBarrier(value()) &&
5406 ReceiverObjectNeedsWriteBarrier(elements(), new_space_dominator());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005407 }
5408 }
5409
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005410 bool NeedsCanonicalization();
5411
rossberg@chromium.org717967f2011-07-20 13:44:42 +00005412 virtual void PrintDataTo(StringStream* stream);
5413
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005414 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed)
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005415
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005416 private:
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00005417 ElementsKind elements_kind_;
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00005418 uint32_t index_offset_;
5419 bool is_dehoisted_;
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005420 HValue* new_space_dominator_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005421};
5422
5423
5424class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005425 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005426 HStoreKeyedGeneric(HValue* context,
5427 HValue* object,
5428 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005429 HValue* value,
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00005430 StrictModeFlag strict_mode_flag)
5431 : strict_mode_flag_(strict_mode_flag) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005432 SetOperandAt(0, object);
5433 SetOperandAt(1, key);
5434 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005435 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00005436 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005437 }
5438
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005439 HValue* object() { return OperandAt(0); }
5440 HValue* key() { return OperandAt(1); }
5441 HValue* value() { return OperandAt(2); }
5442 HValue* context() { return OperandAt(3); }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00005443 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005444
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005445 virtual Representation RequiredInputRepresentation(int index) {
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005446 // tagged[tagged] = tagged
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005447 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005448 }
5449
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005450 virtual void PrintDataTo(StringStream* stream);
5451
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005452 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005453
5454 private:
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00005455 StrictModeFlag strict_mode_flag_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005456};
5457
5458
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005459class HTransitionElementsKind: public HTemplateInstruction<2> {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005460 public:
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005461 HTransitionElementsKind(HValue* context,
5462 HValue* object,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005463 Handle<Map> original_map,
5464 Handle<Map> transitioned_map)
5465 : original_map_(original_map),
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005466 transitioned_map_(transitioned_map),
5467 from_kind_(original_map->elements_kind()),
5468 to_kind_(transitioned_map->elements_kind()) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005469 SetOperandAt(0, object);
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005470 SetOperandAt(1, context);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005471 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00005472 SetGVNFlag(kChangesElementsKind);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005473 if (original_map->has_fast_double_elements()) {
5474 SetGVNFlag(kChangesElementsPointer);
5475 SetGVNFlag(kChangesNewSpacePromotion);
5476 }
5477 if (transitioned_map->has_fast_double_elements()) {
5478 SetGVNFlag(kChangesElementsPointer);
5479 SetGVNFlag(kChangesNewSpacePromotion);
5480 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005481 set_representation(Representation::Tagged());
5482 }
5483
5484 virtual Representation RequiredInputRepresentation(int index) {
5485 return Representation::Tagged();
5486 }
5487
5488 HValue* object() { return OperandAt(0); }
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005489 HValue* context() { return OperandAt(1); }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005490 Handle<Map> original_map() { return original_map_; }
5491 Handle<Map> transitioned_map() { return transitioned_map_; }
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005492 ElementsKind from_kind() { return from_kind_; }
5493 ElementsKind to_kind() { return to_kind_; }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005494
5495 virtual void PrintDataTo(StringStream* stream);
5496
5497 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind)
5498
5499 protected:
5500 virtual bool DataEquals(HValue* other) {
5501 HTransitionElementsKind* instr = HTransitionElementsKind::cast(other);
5502 return original_map_.is_identical_to(instr->original_map()) &&
5503 transitioned_map_.is_identical_to(instr->transitioned_map());
5504 }
5505
5506 private:
5507 Handle<Map> original_map_;
5508 Handle<Map> transitioned_map_;
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005509 ElementsKind from_kind_;
5510 ElementsKind to_kind_;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005511};
5512
5513
danno@chromium.org160a7b02011-04-18 15:51:38 +00005514class HStringAdd: public HBinaryOperation {
5515 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00005516 static HInstruction* New(Zone* zone,
5517 HValue* context,
5518 HValue* left,
5519 HValue* right);
danno@chromium.org160a7b02011-04-18 15:51:38 +00005520
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005521 virtual Representation RequiredInputRepresentation(int index) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00005522 return Representation::Tagged();
5523 }
5524
5525 virtual HType CalculateInferredType() {
5526 return HType::String();
5527 }
5528
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005529 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00005530
5531 protected:
5532 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005533
ulan@chromium.org2e04b582013-02-21 14:06:02 +00005534
5535 private:
5536 HStringAdd(HValue* context, HValue* left, HValue* right)
5537 : HBinaryOperation(context, left, right) {
5538 set_representation(Representation::Tagged());
5539 SetFlag(kUseGVN);
5540 SetGVNFlag(kDependsOnMaps);
5541 SetGVNFlag(kChangesNewSpacePromotion);
5542 }
5543
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005544 // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005545 // virtual bool IsDeletable() const { return true; }
danno@chromium.org160a7b02011-04-18 15:51:38 +00005546};
5547
5548
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005549class HStringCharCodeAt: public HTemplateInstruction<3> {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005550 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005551 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
5552 SetOperandAt(0, context);
5553 SetOperandAt(1, string);
5554 SetOperandAt(2, index);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005555 set_representation(Representation::Integer32());
5556 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00005557 SetGVNFlag(kDependsOnMaps);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00005558 SetGVNFlag(kChangesNewSpacePromotion);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005559 }
5560
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005561 virtual Representation RequiredInputRepresentation(int index) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005562 // The index is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005563 return index == 2
5564 ? Representation::Integer32()
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005565 : Representation::Tagged();
5566 }
5567
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005568 HValue* context() { return OperandAt(0); }
5569 HValue* string() { return OperandAt(1); }
5570 HValue* index() { return OperandAt(2); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005571
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005572 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005573
5574 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005575 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00005576
ulan@chromium.org812308e2012-02-29 15:58:45 +00005577 virtual Range* InferRange(Zone* zone) {
yangguo@chromium.org154ff992012-03-13 08:09:54 +00005578 return new(zone) Range(0, String::kMaxUtf16CodeUnit);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005579 }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005580
5581 // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
5582 // private:
5583 // virtual bool IsDeletable() const { return true; }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005584};
5585
5586
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005587class HStringCharFromCode: public HTemplateInstruction<2> {
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005588 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00005589 static HInstruction* New(Zone* zone,
5590 HValue* context,
5591 HValue* char_code);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005592
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005593 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005594 return index == 0
5595 ? Representation::Tagged()
5596 : Representation::Integer32();
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005597 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005598 virtual HType CalculateInferredType();
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005599
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005600 HValue* context() { return OperandAt(0); }
5601 HValue* value() { return OperandAt(1); }
5602
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005603 virtual bool DataEquals(HValue* other) { return true; }
5604
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005605 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005606
ulan@chromium.org2e04b582013-02-21 14:06:02 +00005607 private:
5608 HStringCharFromCode(HValue* context, HValue* char_code) {
5609 SetOperandAt(0, context);
5610 SetOperandAt(1, char_code);
5611 set_representation(Representation::Tagged());
5612 SetFlag(kUseGVN);
5613 SetGVNFlag(kChangesNewSpacePromotion);
5614 }
5615
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005616 // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
ulan@chromium.org2e04b582013-02-21 14:06:02 +00005617 // virtual bool IsDeletable() const { return true; }
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005618};
5619
5620
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005621class HStringLength: public HUnaryOperation {
5622 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00005623 static HInstruction* New(Zone* zone, HValue* string);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005624
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005625 virtual Representation RequiredInputRepresentation(int index) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005626 return Representation::Tagged();
5627 }
5628
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005629 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005630 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
5631 return HType::Smi();
5632 }
5633
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005634 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005635
5636 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005637 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00005638
ulan@chromium.org812308e2012-02-29 15:58:45 +00005639 virtual Range* InferRange(Zone* zone) {
5640 return new(zone) Range(0, String::kMaxLength);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005641 }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005642
5643 private:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00005644 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
5645 set_representation(Representation::Tagged());
5646 SetFlag(kUseGVN);
5647 SetGVNFlag(kDependsOnMaps);
5648 }
5649
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005650 virtual bool IsDeletable() const { return true; }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005651};
5652
5653
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005654template <int V>
5655class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005656 public:
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00005657 HMaterializedLiteral<V>(int index, int depth, AllocationSiteMode mode)
5658 : literal_index_(index), depth_(depth), allocation_site_mode_(mode) {
5659 this->set_representation(Representation::Tagged());
5660 }
5661
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005662 HMaterializedLiteral<V>(int index, int depth)
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00005663 : literal_index_(index), depth_(depth),
5664 allocation_site_mode_(DONT_TRACK_ALLOCATION_SITE) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005665 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005666 }
5667
5668 int literal_index() const { return literal_index_; }
5669 int depth() const { return depth_; }
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00005670 AllocationSiteMode allocation_site_mode() const {
5671 return allocation_site_mode_;
5672 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005673
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005674 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005675 virtual bool IsDeletable() const { return true; }
5676
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005677 int literal_index_;
5678 int depth_;
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00005679 AllocationSiteMode allocation_site_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005680};
5681
5682
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005683class HFastLiteral: public HMaterializedLiteral<1> {
5684 public:
5685 HFastLiteral(HValue* context,
5686 Handle<JSObject> boilerplate,
5687 int total_size,
5688 int literal_index,
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00005689 int depth,
5690 AllocationSiteMode mode)
5691 : HMaterializedLiteral<1>(literal_index, depth, mode),
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005692 boilerplate_(boilerplate),
5693 total_size_(total_size) {
5694 SetOperandAt(0, context);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00005695 SetGVNFlag(kChangesNewSpacePromotion);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005696 }
5697
5698 // Maximum depth and total number of elements and properties for literal
5699 // graphs to be considered for fast deep-copying.
5700 static const int kMaxLiteralDepth = 3;
5701 static const int kMaxLiteralProperties = 8;
5702
5703 HValue* context() { return OperandAt(0); }
5704 Handle<JSObject> boilerplate() const { return boilerplate_; }
5705 int total_size() const { return total_size_; }
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005706 virtual Representation RequiredInputRepresentation(int index) {
5707 return Representation::Tagged();
5708 }
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +00005709 virtual Handle<Map> GetMonomorphicJSObjectMap() {
5710 return Handle<Map>(boilerplate()->map());
5711 }
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005712 virtual HType CalculateInferredType();
5713
5714 DECLARE_CONCRETE_INSTRUCTION(FastLiteral)
5715
5716 private:
5717 Handle<JSObject> boilerplate_;
5718 int total_size_;
5719};
5720
5721
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005722class HArrayLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005723 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005724 HArrayLiteral(HValue* context,
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005725 Handle<HeapObject> boilerplate_object,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005726 int length,
5727 int literal_index,
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00005728 int depth,
5729 AllocationSiteMode mode)
5730 : HMaterializedLiteral<1>(literal_index, depth, mode),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005731 length_(length),
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005732 boilerplate_object_(boilerplate_object) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005733 SetOperandAt(0, context);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00005734 SetGVNFlag(kChangesNewSpacePromotion);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005735 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005736
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005737 HValue* context() { return OperandAt(0); }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005738 ElementsKind boilerplate_elements_kind() const {
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005739 if (!boilerplate_object_->IsJSObject()) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005740 return TERMINAL_FAST_ELEMENTS_KIND;
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005741 }
5742 return Handle<JSObject>::cast(boilerplate_object_)->GetElementsKind();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005743 }
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005744 Handle<HeapObject> boilerplate_object() const { return boilerplate_object_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005745 int length() const { return length_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005746 bool IsCopyOnWrite() const;
5747
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005748 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005749 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005750 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005751 virtual HType CalculateInferredType();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005752
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005753 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005754
5755 private:
5756 int length_;
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005757 Handle<HeapObject> boilerplate_object_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005758};
5759
5760
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005761class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005762 public:
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005763 HObjectLiteral(HValue* context,
5764 Handle<FixedArray> constant_properties,
5765 bool fast_elements,
5766 int literal_index,
5767 int depth,
5768 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005769 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005770 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005771 fast_elements_(fast_elements),
5772 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005773 SetOperandAt(0, context);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00005774 SetGVNFlag(kChangesNewSpacePromotion);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005775 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005776
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005777 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005778 Handle<FixedArray> constant_properties() const {
5779 return constant_properties_;
5780 }
5781 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005782 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005783
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005784 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005785 return Representation::Tagged();
5786 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005787 virtual HType CalculateInferredType();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005788
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005789 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005790
5791 private:
5792 Handle<FixedArray> constant_properties_;
5793 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005794 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005795};
5796
5797
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005798class HRegExpLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005799 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005800 HRegExpLiteral(HValue* context,
yangguo@chromium.org9c741c82012-06-28 15:04:22 +00005801 Handle<FixedArray> literals,
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005802 Handle<String> pattern,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005803 Handle<String> flags,
5804 int literal_index)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005805 : HMaterializedLiteral<1>(literal_index, 0),
yangguo@chromium.org9c741c82012-06-28 15:04:22 +00005806 literals_(literals),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005807 pattern_(pattern),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005808 flags_(flags) {
5809 SetOperandAt(0, context);
ricow@chromium.org27bf2882011-11-17 08:34:43 +00005810 SetAllSideEffects();
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005811 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005812
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005813 HValue* context() { return OperandAt(0); }
yangguo@chromium.org9c741c82012-06-28 15:04:22 +00005814 Handle<FixedArray> literals() { return literals_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005815 Handle<String> pattern() { return pattern_; }
5816 Handle<String> flags() { return flags_; }
5817
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005818 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005819 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005820 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005821 virtual HType CalculateInferredType();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005822
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005823 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005824
5825 private:
yangguo@chromium.org9c741c82012-06-28 15:04:22 +00005826 Handle<FixedArray> literals_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005827 Handle<String> pattern_;
5828 Handle<String> flags_;
5829};
5830
5831
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005832class HFunctionLiteral: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005833 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005834 HFunctionLiteral(HValue* context,
5835 Handle<SharedFunctionInfo> shared,
5836 bool pretenure)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005837 : shared_info_(shared), pretenure_(pretenure) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005838 SetOperandAt(0, context);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005839 set_representation(Representation::Tagged());
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00005840 SetGVNFlag(kChangesNewSpacePromotion);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005841 }
5842
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005843 HValue* context() { return OperandAt(0); }
5844
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005845 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005846 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005847 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005848 virtual HType CalculateInferredType();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005849
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005850 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005851
5852 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
5853 bool pretenure() const { return pretenure_; }
5854
5855 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005856 virtual bool IsDeletable() const { return true; }
5857
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005858 Handle<SharedFunctionInfo> shared_info_;
5859 bool pretenure_;
5860};
5861
5862
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005863class HTypeof: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005864 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005865 explicit HTypeof(HValue* context, HValue* value) {
5866 SetOperandAt(0, context);
5867 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005868 set_representation(Representation::Tagged());
5869 }
5870
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005871 HValue* context() { return OperandAt(0); }
5872 HValue* value() { return OperandAt(1); }
5873
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005874 virtual void PrintDataTo(StringStream* stream);
5875
5876 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00005877 return Representation::Tagged();
5878 }
5879
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005880 DECLARE_CONCRETE_INSTRUCTION(Typeof)
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005881
5882 private:
5883 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005884};
5885
5886
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005887class HTrapAllocationMemento : public HTemplateInstruction<1> {
5888 public:
5889 explicit HTrapAllocationMemento(HValue* obj) {
5890 SetOperandAt(0, obj);
5891 }
5892
5893 virtual Representation RequiredInputRepresentation(int index) {
5894 return Representation::Tagged();
5895 }
5896
5897 HValue* object() { return OperandAt(0); }
5898
5899 DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento)
5900};
5901
5902
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005903class HToFastProperties: public HUnaryOperation {
5904 public:
5905 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
5906 // This instruction is not marked as having side effects, but
5907 // changes the map of the input operand. Use it only when creating
5908 // object literals.
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005909 ASSERT(value->IsObjectLiteral() || value->IsFastLiteral());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005910 set_representation(Representation::Tagged());
5911 }
5912
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005913 virtual Representation RequiredInputRepresentation(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005914 return Representation::Tagged();
5915 }
5916
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005917 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005918
5919 private:
5920 virtual bool IsDeletable() const { return true; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005921};
5922
5923
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005924class HValueOf: public HUnaryOperation {
5925 public:
5926 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
5927 set_representation(Representation::Tagged());
5928 }
5929
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005930 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005931 return Representation::Tagged();
5932 }
5933
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005934 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005935
5936 private:
5937 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005938};
5939
5940
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00005941class HDateField: public HUnaryOperation {
5942 public:
5943 HDateField(HValue* date, Smi* index)
5944 : HUnaryOperation(date), index_(index) {
5945 set_representation(Representation::Tagged());
5946 }
5947
5948 Smi* index() const { return index_; }
5949
5950 virtual Representation RequiredInputRepresentation(int index) {
5951 return Representation::Tagged();
5952 }
5953
5954 DECLARE_CONCRETE_INSTRUCTION(DateField)
5955
5956 private:
5957 Smi* index_;
5958};
5959
5960
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00005961class HSeqStringSetChar: public HTemplateInstruction<3> {
5962 public:
5963 HSeqStringSetChar(String::Encoding encoding,
5964 HValue* string,
5965 HValue* index,
5966 HValue* value) : encoding_(encoding) {
5967 SetOperandAt(0, string);
5968 SetOperandAt(1, index);
5969 SetOperandAt(2, value);
5970 }
5971
5972 String::Encoding encoding() { return encoding_; }
5973 HValue* string() { return OperandAt(0); }
5974 HValue* index() { return OperandAt(1); }
5975 HValue* value() { return OperandAt(2); }
5976
5977 virtual Representation RequiredInputRepresentation(int index) {
5978 return Representation::Tagged();
5979 }
5980
5981 DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar)
5982
5983 private:
5984 String::Encoding encoding_;
5985};
5986
5987
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005988class HDeleteProperty: public HBinaryOperation {
5989 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005990 HDeleteProperty(HValue* context, HValue* obj, HValue* key)
5991 : HBinaryOperation(context, obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005992 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00005993 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005994 }
5995
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005996 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005997 return Representation::Tagged();
5998 }
5999
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00006000 virtual HType CalculateInferredType();
6001
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00006002 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006003
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00006004 HValue* object() { return left(); }
6005 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006006};
6007
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00006008
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006009class HIn: public HTemplateInstruction<3> {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00006010 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006011 HIn(HValue* context, HValue* key, HValue* object) {
6012 SetOperandAt(0, context);
6013 SetOperandAt(1, key);
6014 SetOperandAt(2, object);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00006015 set_representation(Representation::Tagged());
6016 SetAllSideEffects();
6017 }
6018
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006019 HValue* context() { return OperandAt(0); }
6020 HValue* key() { return OperandAt(1); }
6021 HValue* object() { return OperandAt(2); }
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00006022
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00006023 virtual Representation RequiredInputRepresentation(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00006024 return Representation::Tagged();
6025 }
6026
6027 virtual HType CalculateInferredType() {
6028 return HType::Boolean();
6029 }
6030
6031 virtual void PrintDataTo(StringStream* stream);
6032
6033 DECLARE_CONCRETE_INSTRUCTION(In)
6034};
6035
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +00006036
6037class HCheckMapValue: public HTemplateInstruction<2> {
6038 public:
6039 HCheckMapValue(HValue* value,
6040 HValue* map) {
6041 SetOperandAt(0, value);
6042 SetOperandAt(1, map);
6043 set_representation(Representation::Tagged());
6044 SetFlag(kUseGVN);
6045 SetGVNFlag(kDependsOnMaps);
6046 SetGVNFlag(kDependsOnElementsKind);
6047 }
6048
6049 virtual Representation RequiredInputRepresentation(int index) {
6050 return Representation::Tagged();
6051 }
6052
6053 virtual void PrintDataTo(StringStream* stream);
6054
6055 virtual HType CalculateInferredType() {
6056 return HType::Tagged();
6057 }
6058
6059 HValue* value() { return OperandAt(0); }
6060 HValue* map() { return OperandAt(1); }
6061
6062 DECLARE_CONCRETE_INSTRUCTION(CheckMapValue)
6063
6064 protected:
6065 virtual bool DataEquals(HValue* other) {
6066 return true;
6067 }
6068};
6069
6070
6071class HForInPrepareMap : public HTemplateInstruction<2> {
6072 public:
6073 HForInPrepareMap(HValue* context,
6074 HValue* object) {
6075 SetOperandAt(0, context);
6076 SetOperandAt(1, object);
6077 set_representation(Representation::Tagged());
6078 SetAllSideEffects();
6079 }
6080
6081 virtual Representation RequiredInputRepresentation(int index) {
6082 return Representation::Tagged();
6083 }
6084
6085 HValue* context() { return OperandAt(0); }
6086 HValue* enumerable() { return OperandAt(1); }
6087
6088 virtual void PrintDataTo(StringStream* stream);
6089
6090 virtual HType CalculateInferredType() {
6091 return HType::Tagged();
6092 }
6093
6094 DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap);
6095};
6096
6097
6098class HForInCacheArray : public HTemplateInstruction<2> {
6099 public:
6100 HForInCacheArray(HValue* enumerable,
6101 HValue* keys,
6102 int idx) : idx_(idx) {
6103 SetOperandAt(0, enumerable);
6104 SetOperandAt(1, keys);
6105 set_representation(Representation::Tagged());
6106 }
6107
6108 virtual Representation RequiredInputRepresentation(int index) {
6109 return Representation::Tagged();
6110 }
6111
6112 HValue* enumerable() { return OperandAt(0); }
6113 HValue* map() { return OperandAt(1); }
6114 int idx() { return idx_; }
6115
6116 HForInCacheArray* index_cache() {
6117 return index_cache_;
6118 }
6119
6120 void set_index_cache(HForInCacheArray* index_cache) {
6121 index_cache_ = index_cache;
6122 }
6123
6124 virtual void PrintDataTo(StringStream* stream);
6125
6126 virtual HType CalculateInferredType() {
6127 return HType::Tagged();
6128 }
6129
6130 DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray);
6131
6132 private:
6133 int idx_;
6134 HForInCacheArray* index_cache_;
6135};
6136
6137
6138class HLoadFieldByIndex : public HTemplateInstruction<2> {
6139 public:
6140 HLoadFieldByIndex(HValue* object,
6141 HValue* index) {
6142 SetOperandAt(0, object);
6143 SetOperandAt(1, index);
6144 set_representation(Representation::Tagged());
6145 }
6146
6147 virtual Representation RequiredInputRepresentation(int index) {
6148 return Representation::Tagged();
6149 }
6150
6151 HValue* object() { return OperandAt(0); }
6152 HValue* index() { return OperandAt(1); }
6153
6154 virtual void PrintDataTo(StringStream* stream);
6155
6156 virtual HType CalculateInferredType() {
6157 return HType::Tagged();
6158 }
6159
6160 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex);
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00006161
6162 private:
6163 virtual bool IsDeletable() const { return true; }
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +00006164};
6165
6166
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006167#undef DECLARE_INSTRUCTION
6168#undef DECLARE_CONCRETE_INSTRUCTION
6169
6170} } // namespace v8::internal
6171
6172#endif // V8_HYDROGEN_INSTRUCTIONS_H_