blob: edd93f0748e0ca90e5f884542a9bf38399177875 [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;
48class HInstruction;
49class HLoopInformation;
50class HValue;
51class LInstruction;
52class LChunkBuilder;
53
54
ricow@chromium.orgdcebac02011-04-20 09:44:50 +000055#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000056 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000057 V(ControlInstruction) \
58 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000059
60
61#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +000062 V(AbnormalExit) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000063 V(AccessArgumentsAt) \
64 V(Add) \
ulan@chromium.org967e2702012-02-28 09:49:15 +000065 V(AllocateObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000066 V(ApplyArguments) \
67 V(ArgumentsElements) \
68 V(ArgumentsLength) \
69 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000070 V(ArrayLiteral) \
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000071 V(Bitwise) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000072 V(BitNot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000073 V(BlockEntry) \
74 V(BoundsCheck) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000075 V(Branch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000076 V(CallConstantFunction) \
77 V(CallFunction) \
78 V(CallGlobal) \
79 V(CallKeyed) \
80 V(CallKnownGlobal) \
81 V(CallNamed) \
82 V(CallNew) \
83 V(CallRuntime) \
84 V(CallStub) \
85 V(Change) \
86 V(CheckFunction) \
87 V(CheckInstanceType) \
jkummerow@chromium.org1456e702012-03-30 08:38:13 +000088 V(CheckMaps) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000089 V(CheckNonSmi) \
90 V(CheckPrototypeMaps) \
91 V(CheckSmi) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +000092 V(ClampToUint8) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000093 V(ClassOfTestAndBranch) \
94 V(CompareIDAndBranch) \
95 V(CompareGeneric) \
96 V(CompareObjectEqAndBranch) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000097 V(CompareMap) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000098 V(CompareConstantEqAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000099 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000100 V(Context) \
yangguo@chromium.org56454712012-02-16 15:33:53 +0000101 V(DeclareGlobals) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000102 V(DeleteProperty) \
103 V(Deoptimize) \
104 V(Div) \
whesse@chromium.org7b260152011-06-20 15:33:18 +0000105 V(ElementsKind) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000106 V(EnterInlined) \
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000107 V(FastLiteral) \
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000108 V(FixedArrayBaseLength) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000109 V(ForceRepresentation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000110 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000111 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000112 V(GlobalObject) \
113 V(GlobalReceiver) \
114 V(Goto) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000115 V(HasCachedArrayIndexAndBranch) \
116 V(HasInstanceTypeAndBranch) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000117 V(In) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000118 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000119 V(InstanceOfKnownGlobal) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000120 V(InvokeFunction) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000121 V(IsConstructCallAndBranch) \
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000122 V(IsNilAndBranch) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000123 V(IsObjectAndBranch) \
erikcorry0ad885c2011-11-21 13:51:57 +0000124 V(IsStringAndBranch) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000125 V(IsSmiAndBranch) \
126 V(IsUndetectableAndBranch) \
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000127 V(StringCompareAndBranch) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000128 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000129 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000130 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000131 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000132 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000133 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000134 V(LoadGlobalCell) \
135 V(LoadGlobalGeneric) \
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000136 V(LoadKeyedFastDoubleElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000137 V(LoadKeyedFastElement) \
138 V(LoadKeyedGeneric) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000139 V(LoadKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000140 V(LoadNamedField) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000141 V(LoadNamedFieldPolymorphic) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000142 V(LoadNamedGeneric) \
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +0000143 V(MathFloorOfDiv) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000144 V(Mod) \
145 V(Mul) \
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000146 V(ObjectLiteral) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000147 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000148 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000149 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000150 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000151 V(PushArgument) \
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000152 V(Random) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000153 V(RegExpLiteral) \
154 V(Return) \
155 V(Sar) \
156 V(Shl) \
157 V(Shr) \
158 V(Simulate) \
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000159 V(SoftDeoptimize) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000160 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000161 V(StoreContextSlot) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000162 V(StoreGlobalCell) \
163 V(StoreGlobalGeneric) \
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000164 V(StoreKeyedFastDoubleElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000165 V(StoreKeyedFastElement) \
166 V(StoreKeyedGeneric) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000167 V(StoreKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000168 V(StoreNamedField) \
169 V(StoreNamedGeneric) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000170 V(StringAdd) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000171 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000172 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000173 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000174 V(Sub) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000175 V(ThisFunction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000176 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000177 V(ToFastProperties) \
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000178 V(TransitionElementsKind) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000179 V(Typeof) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000180 V(TypeofIsAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000181 V(UnaryMathOperation) \
182 V(UnknownOSRValue) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000183 V(UseConst) \
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +0000184 V(ValueOf) \
185 V(ForInPrepareMap) \
186 V(ForInCacheArray) \
187 V(CheckMapValue) \
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000188 V(LoadFieldByIndex) \
yangguo@chromium.org154ff992012-03-13 08:09:54 +0000189 V(DateField) \
190 V(WrapReceiver)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000191
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000192#define GVN_TRACKED_FLAG_LIST(V) \
193 V(NewSpacePromotion)
194
195#define GVN_UNTRACKED_FLAG_LIST(V) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000196 V(Calls) \
197 V(InobjectFields) \
198 V(BackingStoreFields) \
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000199 V(ElementsKind) \
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000200 V(ElementsPointer) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000201 V(ArrayElements) \
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000202 V(DoubleArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000203 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000204 V(GlobalVars) \
205 V(Maps) \
206 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000207 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000208 V(OsrEntries)
209
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000210#define DECLARE_ABSTRACT_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000211 virtual bool Is##type() const { return true; } \
212 static H##type* cast(HValue* value) { \
213 ASSERT(value->Is##type()); \
214 return reinterpret_cast<H##type*>(value); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000215 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000216
217
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000218#define DECLARE_CONCRETE_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000219 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000220 static H##type* cast(HValue* value) { \
221 ASSERT(value->Is##type()); \
222 return reinterpret_cast<H##type*>(value); \
223 } \
224 virtual Opcode opcode() const { return HValue::k##type; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000225
226
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000227class Range: public ZoneObject {
228 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000229 Range()
230 : lower_(kMinInt),
231 upper_(kMaxInt),
232 next_(NULL),
233 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000234
235 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000236 : lower_(lower),
237 upper_(upper),
238 next_(NULL),
239 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000240
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000241 int32_t upper() const { return upper_; }
242 int32_t lower() const { return lower_; }
243 Range* next() const { return next_; }
ulan@chromium.org812308e2012-02-29 15:58:45 +0000244 Range* CopyClearLower(Zone* zone) const {
245 return new(zone) Range(kMinInt, upper_);
246 }
247 Range* CopyClearUpper(Zone* zone) const {
248 return new(zone) Range(lower_, kMaxInt);
249 }
250 Range* Copy(Zone* zone) const {
251 Range* result = new(zone) Range(lower_, upper_);
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000252 result->set_can_be_minus_zero(CanBeMinusZero());
253 return result;
254 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000255 int32_t Mask() const;
256 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
257 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
258 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
259 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000260 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000261 bool IsMostGeneric() const {
262 return lower_ == kMinInt && upper_ == kMaxInt && CanBeMinusZero();
263 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000264 bool IsInSmiRange() const {
265 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000266 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000267 void KeepOrder();
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000268#ifdef DEBUG
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000269 void Verify() const;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000270#endif
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000271
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000272 void StackUpon(Range* other) {
273 Intersect(other);
274 next_ = other;
275 }
276
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000277 void Intersect(Range* other);
278 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000279
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000280 void AddConstant(int32_t value);
281 void Sar(int32_t value);
282 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000283 bool AddAndCheckOverflow(Range* other);
284 bool SubAndCheckOverflow(Range* other);
285 bool MulAndCheckOverflow(Range* other);
286
287 private:
288 int32_t lower_;
289 int32_t upper_;
290 Range* next_;
291 bool can_be_minus_zero_;
292};
293
294
295class Representation {
296 public:
297 enum Kind {
298 kNone,
299 kTagged,
300 kDouble,
301 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000302 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000303 kNumRepresentations
304 };
305
306 Representation() : kind_(kNone) { }
307
308 static Representation None() { return Representation(kNone); }
309 static Representation Tagged() { return Representation(kTagged); }
310 static Representation Integer32() { return Representation(kInteger32); }
311 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000312 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000313
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000314 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000315 return kind_ == other.kind_;
316 }
317
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000318 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000319 bool IsNone() const { return kind_ == kNone; }
320 bool IsTagged() const { return kind_ == kTagged; }
321 bool IsInteger32() const { return kind_ == kInteger32; }
322 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000323 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000324 bool IsSpecialization() const {
325 return kind_ == kInteger32 || kind_ == kDouble;
326 }
327 const char* Mnemonic() const;
328
329 private:
330 explicit Representation(Kind k) : kind_(k) { }
331
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000332 // Make sure kind fits in int8.
333 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
334
335 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000336};
337
338
339class HType {
340 public:
341 HType() : type_(kUninitialized) { }
342
343 static HType Tagged() { return HType(kTagged); }
344 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
345 static HType TaggedNumber() { return HType(kTaggedNumber); }
346 static HType Smi() { return HType(kSmi); }
347 static HType HeapNumber() { return HType(kHeapNumber); }
348 static HType String() { return HType(kString); }
349 static HType Boolean() { return HType(kBoolean); }
350 static HType NonPrimitive() { return HType(kNonPrimitive); }
351 static HType JSArray() { return HType(kJSArray); }
352 static HType JSObject() { return HType(kJSObject); }
353 static HType Uninitialized() { return HType(kUninitialized); }
354
355 // Return the weakest (least precise) common type.
356 HType Combine(HType other) {
357 return HType(static_cast<Type>(type_ & other.type_));
358 }
359
360 bool Equals(const HType& other) {
361 return type_ == other.type_;
362 }
363
364 bool IsSubtypeOf(const HType& other) {
365 return Combine(other).Equals(other);
366 }
367
368 bool IsTagged() {
369 ASSERT(type_ != kUninitialized);
370 return ((type_ & kTagged) == kTagged);
371 }
372
373 bool IsTaggedPrimitive() {
374 ASSERT(type_ != kUninitialized);
375 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
376 }
377
378 bool IsTaggedNumber() {
379 ASSERT(type_ != kUninitialized);
380 return ((type_ & kTaggedNumber) == kTaggedNumber);
381 }
382
383 bool IsSmi() {
384 ASSERT(type_ != kUninitialized);
385 return ((type_ & kSmi) == kSmi);
386 }
387
388 bool IsHeapNumber() {
389 ASSERT(type_ != kUninitialized);
390 return ((type_ & kHeapNumber) == kHeapNumber);
391 }
392
393 bool IsString() {
394 ASSERT(type_ != kUninitialized);
395 return ((type_ & kString) == kString);
396 }
397
398 bool IsBoolean() {
399 ASSERT(type_ != kUninitialized);
400 return ((type_ & kBoolean) == kBoolean);
401 }
402
403 bool IsNonPrimitive() {
404 ASSERT(type_ != kUninitialized);
405 return ((type_ & kNonPrimitive) == kNonPrimitive);
406 }
407
408 bool IsJSArray() {
409 ASSERT(type_ != kUninitialized);
410 return ((type_ & kJSArray) == kJSArray);
411 }
412
413 bool IsJSObject() {
414 ASSERT(type_ != kUninitialized);
415 return ((type_ & kJSObject) == kJSObject);
416 }
417
418 bool IsUninitialized() {
419 return type_ == kUninitialized;
420 }
421
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000422 bool IsHeapObject() {
423 ASSERT(type_ != kUninitialized);
424 return IsHeapNumber() || IsString() || IsNonPrimitive();
425 }
426
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000427 static HType TypeFromValue(Handle<Object> value);
428
429 const char* ToString();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000430
431 private:
432 enum Type {
433 kTagged = 0x1, // 0000 0000 0000 0001
434 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
435 kTaggedNumber = 0xd, // 0000 0000 0000 1101
436 kSmi = 0x1d, // 0000 0000 0001 1101
437 kHeapNumber = 0x2d, // 0000 0000 0010 1101
438 kString = 0x45, // 0000 0000 0100 0101
439 kBoolean = 0x85, // 0000 0000 1000 0101
440 kNonPrimitive = 0x101, // 0000 0001 0000 0001
441 kJSObject = 0x301, // 0000 0011 0000 0001
whesse@chromium.org7b260152011-06-20 15:33:18 +0000442 kJSArray = 0x701, // 0000 0111 0000 0001
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000443 kUninitialized = 0x1fff // 0001 1111 1111 1111
444 };
445
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000446 // Make sure type fits in int16.
447 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
448
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000449 explicit HType(Type t) : type_(t) { }
450
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000451 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000452};
453
454
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000455class HUseListNode: public ZoneObject {
456 public:
457 HUseListNode(HValue* value, int index, HUseListNode* tail)
458 : tail_(tail), value_(value), index_(index) {
459 }
460
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +0000461 HUseListNode* tail();
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000462 HValue* value() const { return value_; }
463 int index() const { return index_; }
464
465 void set_tail(HUseListNode* list) { tail_ = list; }
466
467#ifdef DEBUG
468 void Zap() {
469 tail_ = reinterpret_cast<HUseListNode*>(1);
470 value_ = NULL;
471 index_ = -1;
472 }
473#endif
474
475 private:
476 HUseListNode* tail_;
477 HValue* value_;
478 int index_;
479};
480
481
482// We reuse use list nodes behind the scenes as uses are added and deleted.
483// This class is the safe way to iterate uses while deleting them.
484class HUseIterator BASE_EMBEDDED {
485 public:
486 bool Done() { return current_ == NULL; }
487 void Advance();
488
489 HValue* value() {
490 ASSERT(!Done());
491 return value_;
492 }
493
494 int index() {
495 ASSERT(!Done());
496 return index_;
497 }
498
499 private:
500 explicit HUseIterator(HUseListNode* head);
501
502 HUseListNode* current_;
503 HUseListNode* next_;
504 HValue* value_;
505 int index_;
506
507 friend class HValue;
508};
509
510
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000511// There must be one corresponding kDepends flag for every kChanges flag and
512// the order of the kChanges flags must be exactly the same as of the kDepends
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000513// flags. All tracked flags should appear before untracked ones.
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000514enum GVNFlag {
515 // Declare global value numbering flags.
516#define DECLARE_FLAG(type) kChanges##type, kDependsOn##type,
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000517 GVN_TRACKED_FLAG_LIST(DECLARE_FLAG)
518 GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000519#undef DECLARE_FLAG
520 kAfterLastFlag,
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000521 kLastFlag = kAfterLastFlag - 1,
522#define COUNT_FLAG(type) + 1
523 kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG)
524#undef COUNT_FLAG
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000525};
526
527typedef EnumSet<GVNFlag> GVNFlagSet;
528
529
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000530class HValue: public ZoneObject {
531 public:
532 static const int kNoNumber = -1;
533
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000534 enum Flag {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000535 kFlexibleRepresentation,
whesse@chromium.org7b260152011-06-20 15:33:18 +0000536 // Participate in Global Value Numbering, i.e. elimination of
537 // unnecessary recomputations. If an instruction sets this flag, it must
538 // implement DataEquals(), which will be used to determine if other
539 // occurrences of the instruction are indeed the same.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000540 kUseGVN,
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000541 // Track instructions that are dominating side effects. If an instruction
542 // sets this flag, it must implement SetSideEffectDominator() and should
543 // indicate which side effects to track by setting GVN flags.
544 kTrackSideEffectDominators,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000545 kCanOverflow,
546 kBailoutOnMinusZero,
547 kCanBeDivByZero,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000548 kDeoptimizeOnUndefined,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000549 kIsArguments,
550 kTruncatingToInt32,
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +0000551 kIsDead,
552 kLastFlag = kIsDead
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000553 };
554
555 STATIC_ASSERT(kLastFlag < kBitsPerInt);
556
557 static const int kChangesToDependsFlagsLeftShift = 1;
558
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000559 static GVNFlag ChangesFlagFromInt(int x) {
560 return static_cast<GVNFlag>(x * 2);
561 }
562 static GVNFlag DependsOnFlagFromInt(int x) {
563 return static_cast<GVNFlag>(x * 2 + 1);
564 }
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000565 static GVNFlagSet ConvertChangesToDependsFlags(GVNFlagSet flags) {
566 return GVNFlagSet(flags.ToIntegral() << kChangesToDependsFlagsLeftShift);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000567 }
568
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000569 static HValue* cast(HValue* value) { return value; }
570
571 enum Opcode {
572 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000573 #define DECLARE_OPCODE(type) k##type,
574 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
575 kPhi
576 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000577 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000578 virtual Opcode opcode() const = 0;
579
580 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
581 #define DECLARE_PREDICATE(type) \
582 bool Is##type() const { return opcode() == k##type; }
583 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
584 #undef DECLARE_PREDICATE
585 bool IsPhi() const { return opcode() == kPhi; }
586
587 // Declare virtual predicates for abstract HInstruction or HValue
588 #define DECLARE_PREDICATE(type) \
589 virtual bool Is##type() const { return false; }
590 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
591 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000592
593 HValue() : block_(NULL),
594 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000595 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000596 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000597 range_(NULL),
598 flags_(0) {}
599 virtual ~HValue() {}
600
601 HBasicBlock* block() const { return block_; }
602 void SetBlock(HBasicBlock* block);
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000603 int LoopWeight() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000604
605 int id() const { return id_; }
606 void set_id(int id) { id_ = id; }
607
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000608 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000609
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000610 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000611 Representation representation() const { return representation_; }
612 void ChangeRepresentation(Representation r) {
613 // Representation was already set and is allowed to be changed.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000614 ASSERT(!r.IsNone());
615 ASSERT(CheckFlag(kFlexibleRepresentation));
616 RepresentationChanged(r);
617 representation_ = r;
618 }
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000619 void AssumeRepresentation(Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000620
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000621 virtual bool IsConvertibleToInteger() const { return true; }
622
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000623 HType type() const { return type_; }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000624 void set_type(HType new_type) {
625 ASSERT(new_type.IsSubtypeOf(type_));
626 type_ = new_type;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000627 }
628
629 // An operation needs to override this function iff:
630 // 1) it can produce an int32 output.
631 // 2) the true value of its output can potentially be minus zero.
632 // The implementation must set a flag so that it bails out in the case where
633 // it would otherwise output what should be a minus zero as an int32 zero.
634 // If the operation also exists in a form that takes int32 and outputs int32
635 // then the operation should return its input value so that we can propagate
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000636 // back. There are three operations that need to propagate back to more than
637 // one input. They are phi and binary div and mul. They always return NULL
638 // and expect the caller to take care of things.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000639 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
640 visited->Add(id());
641 return NULL;
642 }
643
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000644 bool IsDefinedAfter(HBasicBlock* other) const;
645
646 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000647 virtual int OperandCount() = 0;
648 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000649 void SetOperandAt(int index, HValue* value);
650
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000651 void DeleteAndReplaceWith(HValue* other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000652 void ReplaceAllUsesWith(HValue* other);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000653 bool HasNoUses() const { return use_list_ == NULL; }
654 bool HasMultipleUses() const {
655 return use_list_ != NULL && use_list_->tail() != NULL;
656 }
657 int UseCount() const;
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +0000658
659 // Mark this HValue as dead and to be removed from other HValues' use lists.
660 void Kill();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000661
662 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000663 void SetFlag(Flag f) { flags_ |= (1 << f); }
664 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
665 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
666
ulan@chromium.org812308e2012-02-29 15:58:45 +0000667 // Returns true if the flag specified is set for all uses, false otherwise.
668 bool CheckUsesForFlag(Flag f);
669
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000670 GVNFlagSet gvn_flags() const { return gvn_flags_; }
671 void SetGVNFlag(GVNFlag f) { gvn_flags_.Add(f); }
672 void ClearGVNFlag(GVNFlag f) { gvn_flags_.Remove(f); }
673 bool CheckGVNFlag(GVNFlag f) const { return gvn_flags_.Contains(f); }
674 void SetAllSideEffects() { gvn_flags_.Add(AllSideEffectsFlagSet()); }
675 void ClearAllSideEffects() {
676 gvn_flags_.Remove(AllSideEffectsFlagSet());
677 }
678 bool HasSideEffects() const {
679 return gvn_flags_.ContainsAnyOf(AllSideEffectsFlagSet());
680 }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000681 bool HasObservableSideEffects() const {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000682 return gvn_flags_.ContainsAnyOf(AllObservableSideEffectsFlagSet());
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000683 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000684
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000685 GVNFlagSet DependsOnFlags() const {
686 GVNFlagSet result = gvn_flags_;
687 result.Intersect(AllDependsOnFlagSet());
688 return result;
689 }
690
691 GVNFlagSet SideEffectFlags() const {
692 GVNFlagSet result = gvn_flags_;
693 result.Intersect(AllSideEffectsFlagSet());
694 return result;
695 }
696
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000697 GVNFlagSet ChangesFlags() const {
698 GVNFlagSet result = gvn_flags_;
699 result.Intersect(AllChangesFlagSet());
700 return result;
701 }
702
703 GVNFlagSet ObservableChangesFlags() const {
704 GVNFlagSet result = gvn_flags_;
705 result.Intersect(AllChangesFlagSet());
706 result.Intersect(AllObservableSideEffectsFlagSet());
707 return result;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000708 }
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000709
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000710 Range* range() const { return range_; }
711 bool HasRange() const { return range_ != NULL; }
ulan@chromium.org812308e2012-02-29 15:58:45 +0000712 void AddNewRange(Range* r, Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000713 void RemoveLastAddedRange();
ulan@chromium.org812308e2012-02-29 15:58:45 +0000714 void ComputeInitialRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000715
716 // Representation helpers.
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000717 virtual Representation RequiredInputRepresentation(int index) = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000718
719 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000720 return representation();
721 }
722
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000723 // Type feedback access.
724 virtual Representation ObservedInputRepresentation(int index) {
725 return RequiredInputRepresentation(index);
726 }
727
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000728 // This gives the instruction an opportunity to replace itself with an
729 // instruction that does the same in some better way. To replace an
730 // instruction with a new one, first add the new instruction to the graph,
731 // then return it. Return NULL to have the instruction deleted.
732 virtual HValue* Canonicalize() { return this; }
733
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000734 bool Equals(HValue* other);
735 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000736
737 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000738 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000739 void PrintNameTo(StringStream* stream);
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000740 void PrintTypeTo(StringStream* stream);
741 void PrintRangeTo(StringStream* stream);
742 void PrintChangesTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000743
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000744 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000745
746 // Updated the inferred type of this instruction and returns true if
747 // it has changed.
748 bool UpdateInferredType();
749
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000750 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000751
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000752 // This function must be overridden for instructions which have the
753 // kTrackSideEffectDominators flag set, to track instructions that are
754 // dominating side effects.
755 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) {
756 UNREACHABLE();
757 }
758
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000759#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000760 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000761#endif
762
763 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000764 // This function must be overridden for instructions with flag kUseGVN, to
765 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000766 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000767 UNREACHABLE();
768 return false;
769 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000770 virtual void RepresentationChanged(Representation to) { }
ulan@chromium.org812308e2012-02-29 15:58:45 +0000771 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000772 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000773 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000774 void clear_block() {
775 ASSERT(block_ != NULL);
776 block_ = NULL;
777 }
778
779 void set_representation(Representation r) {
780 // Representation is set-once.
781 ASSERT(representation_.IsNone() && !r.IsNone());
782 representation_ = r;
783 }
784
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000785 static GVNFlagSet AllDependsOnFlagSet() {
786 GVNFlagSet result;
787 // Create changes mask.
788#define ADD_FLAG(type) result.Add(kDependsOn##type);
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000789 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
790 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000791#undef ADD_FLAG
792 return result;
793 }
794
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000795 static GVNFlagSet AllChangesFlagSet() {
796 GVNFlagSet result;
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000797 // Create changes mask.
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000798#define ADD_FLAG(type) result.Add(kChanges##type);
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000799 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
800 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000801#undef ADD_FLAG
802 return result;
803 }
804
ager@chromium.org378b34e2011-01-28 08:04:38 +0000805 // A flag mask to mark an instruction as having arbitrary side effects.
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000806 static GVNFlagSet AllSideEffectsFlagSet() {
807 GVNFlagSet result = AllChangesFlagSet();
808 result.Remove(kChangesOsrEntries);
809 return result;
ager@chromium.org378b34e2011-01-28 08:04:38 +0000810 }
811
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000812 // A flag mask of all side effects that can make observable changes in
813 // an executing program (i.e. are not safe to repeat, move or remove);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000814 static GVNFlagSet AllObservableSideEffectsFlagSet() {
815 GVNFlagSet result = AllChangesFlagSet();
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000816 result.Remove(kChangesNewSpacePromotion);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000817 result.Remove(kChangesElementsKind);
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000818 result.Remove(kChangesElementsPointer);
819 result.Remove(kChangesMaps);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000820 return result;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000821 }
822
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000823 // Remove the matching use from the use list if present. Returns the
824 // removed list node or NULL.
825 HUseListNode* RemoveUse(HValue* value, int index);
826
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000827 void RegisterUse(int index, HValue* new_value);
828
829 HBasicBlock* block_;
830
831 // The id of this instruction in the hydrogen graph, assigned when first
832 // added to the graph. Reflects creation order.
833 int id_;
834
835 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000836 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000837 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000838 Range* range_;
839 int flags_;
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000840 GVNFlagSet gvn_flags_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000841
yangguo@chromium.org659ceec2012-01-26 07:37:54 +0000842 private:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000843 DISALLOW_COPY_AND_ASSIGN(HValue);
844};
845
846
847class HInstruction: public HValue {
848 public:
849 HInstruction* next() const { return next_; }
850 HInstruction* previous() const { return previous_; }
851
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000852 virtual void PrintTo(StringStream* stream);
853 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000854
855 bool IsLinked() const { return block() != NULL; }
856 void Unlink();
857 void InsertBefore(HInstruction* next);
858 void InsertAfter(HInstruction* previous);
859
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000860 // The position is a write-once variable.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000861 int position() const { return position_; }
862 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000863 void set_position(int position) {
864 ASSERT(!has_position());
865 ASSERT(position != RelocInfo::kNoPosition);
866 position_ = position;
867 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000868
ulan@chromium.org812308e2012-02-29 15:58:45 +0000869 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
870
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000871 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
872
873#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000874 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000875#endif
876
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000877 virtual bool IsCall() { return false; }
878
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000879 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000880
881 protected:
882 HInstruction()
883 : next_(NULL),
884 previous_(NULL),
885 position_(RelocInfo::kNoPosition) {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000886 SetGVNFlag(kDependsOnOsrEntries);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000887 }
888
889 virtual void DeleteFromGraph() { Unlink(); }
890
891 private:
892 void InitializeAsFirst(HBasicBlock* block) {
893 ASSERT(!IsLinked());
894 SetBlock(block);
895 }
896
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000897 void PrintMnemonicTo(StringStream* stream);
898
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000899 HInstruction* next_;
900 HInstruction* previous_;
901 int position_;
902
903 friend class HBasicBlock;
904};
905
906
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000907template<int V>
908class HTemplateInstruction : public HInstruction {
909 public:
910 int OperandCount() { return V; }
911 HValue* OperandAt(int i) { return inputs_[i]; }
912
913 protected:
914 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
915
916 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000917 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000918};
919
920
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000921class HControlInstruction: public HInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000922 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000923 virtual HBasicBlock* SuccessorAt(int i) = 0;
924 virtual int SuccessorCount() = 0;
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000925 virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000926
927 virtual void PrintDataTo(StringStream* stream);
928
929 HBasicBlock* FirstSuccessor() {
930 return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
931 }
932 HBasicBlock* SecondSuccessor() {
933 return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
934 }
935
936 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
937};
938
939
940class HSuccessorIterator BASE_EMBEDDED {
941 public:
942 explicit HSuccessorIterator(HControlInstruction* instr)
943 : instr_(instr), current_(0) { }
944
945 bool Done() { return current_ >= instr_->SuccessorCount(); }
946 HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
947 void Advance() { current_++; }
948
949 private:
950 HControlInstruction* instr_;
951 int current_;
952};
953
954
955template<int S, int V>
956class HTemplateControlInstruction: public HControlInstruction {
957 public:
958 int SuccessorCount() { return S; }
959 HBasicBlock* SuccessorAt(int i) { return successors_[i]; }
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000960 void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000961
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000962 int OperandCount() { return V; }
963 HValue* OperandAt(int i) { return inputs_[i]; }
964
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000965
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000966 protected:
967 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
968
969 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000970 EmbeddedContainer<HBasicBlock*, S> successors_;
971 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000972};
973
974
975class HBlockEntry: public HTemplateInstruction<0> {
976 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000977 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000978 return Representation::None();
979 }
980
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000981 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000982};
983
984
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000985// We insert soft-deoptimize when we hit code with unknown typefeedback,
986// so that we get a chance of re-optimizing with useful typefeedback.
987// HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
988class HSoftDeoptimize: public HTemplateInstruction<0> {
989 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000990 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000991 return Representation::None();
992 }
993
994 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
995};
996
997
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000998class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000999 public:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001000 HDeoptimize(int environment_length, Zone* zone)
1001 : values_(environment_length, zone) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001002
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001003 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001004 return Representation::None();
1005 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001006
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001007 virtual int OperandCount() { return values_.length(); }
1008 virtual HValue* OperandAt(int index) { return values_[index]; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001009 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001010
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001011 virtual int SuccessorCount() { return 0; }
1012 virtual HBasicBlock* SuccessorAt(int i) {
1013 UNREACHABLE();
1014 return NULL;
1015 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001016 virtual void SetSuccessorAt(int i, HBasicBlock* block) {
1017 UNREACHABLE();
1018 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001019
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001020 void AddEnvironmentValue(HValue* value, Zone* zone) {
1021 values_.Add(NULL, zone);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001022 SetOperandAt(values_.length() - 1, value);
1023 }
1024
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001025 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001026
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00001027 enum UseEnvironment {
1028 kNoUses,
1029 kUseAll
1030 };
1031
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001032 protected:
1033 virtual void InternalSetOperandAt(int index, HValue* value) {
1034 values_[index] = value;
1035 }
1036
1037 private:
1038 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001039};
1040
1041
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001042class HGoto: public HTemplateControlInstruction<1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001043 public:
ager@chromium.org04921a82011-06-27 13:21:41 +00001044 explicit HGoto(HBasicBlock* target) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001045 SetSuccessorAt(0, target);
1046 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001047
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001048 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001049 return Representation::None();
1050 }
1051
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00001052 virtual void PrintDataTo(StringStream* stream);
1053
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001054 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001055};
1056
1057
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001058class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001059 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001060 HUnaryControlInstruction(HValue* value,
1061 HBasicBlock* true_target,
1062 HBasicBlock* false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001063 SetOperandAt(0, value);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001064 SetSuccessorAt(0, true_target);
1065 SetSuccessorAt(1, false_target);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001066 }
1067
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001068 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001069
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001070 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001071};
1072
1073
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001074class HBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001075 public:
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001076 HBranch(HValue* value,
1077 HBasicBlock* true_target,
1078 HBasicBlock* false_target,
1079 ToBooleanStub::Types expected_input_types = ToBooleanStub::no_types())
1080 : HUnaryControlInstruction(value, true_target, false_target),
1081 expected_input_types_(expected_input_types) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001082 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001083 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001084 explicit HBranch(HValue* value)
1085 : HUnaryControlInstruction(value, NULL, NULL) { }
1086
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001087
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001088 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001089 return Representation::None();
1090 }
1091
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001092 ToBooleanStub::Types expected_input_types() const {
1093 return expected_input_types_;
1094 }
1095
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001096 DECLARE_CONCRETE_INSTRUCTION(Branch)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001097
1098 private:
1099 ToBooleanStub::Types expected_input_types_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001100};
1101
1102
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001103class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001104 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001105 HCompareMap(HValue* value,
1106 Handle<Map> map,
1107 HBasicBlock* true_target,
1108 HBasicBlock* false_target)
1109 : HUnaryControlInstruction(value, true_target, false_target),
1110 map_(map) {
1111 ASSERT(true_target != NULL);
1112 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001113 ASSERT(!map.is_null());
1114 }
1115
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001116 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +00001117
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001118 Handle<Map> map() const { return map_; }
1119
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001120 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001121 return Representation::Tagged();
1122 }
1123
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001124 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001125
1126 private:
1127 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001128};
1129
1130
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001131class HReturn: public HTemplateControlInstruction<0, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001132 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001133 explicit HReturn(HValue* value) {
1134 SetOperandAt(0, value);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001135 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001136
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001137 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001138 return Representation::Tagged();
1139 }
1140
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001141 virtual void PrintDataTo(StringStream* stream);
1142
1143 HValue* value() { return OperandAt(0); }
1144
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001145 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001146};
1147
1148
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001149class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001150 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001151 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001152 return Representation::None();
1153 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001154
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001155 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001156};
1157
1158
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001159class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001160 public:
1161 explicit HUnaryOperation(HValue* value) {
1162 SetOperandAt(0, value);
1163 }
1164
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001165 static HUnaryOperation* cast(HValue* value) {
1166 return reinterpret_cast<HUnaryOperation*>(value);
1167 }
1168
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001169 HValue* value() { return OperandAt(0); }
1170 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001171};
1172
1173
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001174class HThrow: public HTemplateInstruction<2> {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001175 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001176 HThrow(HValue* context, HValue* value) {
1177 SetOperandAt(0, context);
1178 SetOperandAt(1, value);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001179 SetAllSideEffects();
1180 }
1181
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001182 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001183 return Representation::Tagged();
1184 }
1185
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001186 HValue* context() { return OperandAt(0); }
1187 HValue* value() { return OperandAt(1); }
1188
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001189 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001190};
1191
1192
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001193class HUseConst: public HUnaryOperation {
1194 public:
1195 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1196
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001197 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001198 return Representation::None();
1199 }
1200
1201 DECLARE_CONCRETE_INSTRUCTION(UseConst)
1202};
1203
1204
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001205class HForceRepresentation: public HTemplateInstruction<1> {
1206 public:
1207 HForceRepresentation(HValue* value, Representation required_representation) {
1208 SetOperandAt(0, value);
1209 set_representation(required_representation);
1210 }
1211
1212 HValue* value() { return OperandAt(0); }
1213
1214 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1215
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001216 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001217 return representation(); // Same as the output representation.
1218 }
1219
1220 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1221};
1222
1223
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001224class HChange: public HUnaryOperation {
1225 public:
1226 HChange(HValue* value,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001227 Representation to,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001228 bool is_truncating,
1229 bool deoptimize_on_undefined)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001230 : HUnaryOperation(value) {
1231 ASSERT(!value->representation().IsNone() && !to.IsNone());
1232 ASSERT(!value->representation().Equals(to));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001233 set_representation(to);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001234 set_type(HType::TaggedNumber());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001235 SetFlag(kUseGVN);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001236 if (deoptimize_on_undefined) SetFlag(kDeoptimizeOnUndefined);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001237 if (is_truncating) SetFlag(kTruncatingToInt32);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00001238 if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001239 }
1240
1241 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001242 virtual HType CalculateInferredType();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001243 virtual HValue* Canonicalize();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001244
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001245 Representation from() { return value()->representation(); }
1246 Representation to() { return representation(); }
1247 bool deoptimize_on_undefined() const {
1248 return CheckFlag(kDeoptimizeOnUndefined);
1249 }
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001250 bool deoptimize_on_minus_zero() const {
1251 return CheckFlag(kBailoutOnMinusZero);
1252 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001253 virtual Representation RequiredInputRepresentation(int index) {
1254 return from();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001255 }
1256
ulan@chromium.org812308e2012-02-29 15:58:45 +00001257 virtual Range* InferRange(Zone* zone);
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001258
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001259 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001260
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001261 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001262
1263 protected:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001264 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001265};
1266
1267
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001268class HClampToUint8: public HUnaryOperation {
1269 public:
1270 explicit HClampToUint8(HValue* value)
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001271 : HUnaryOperation(value) {
1272 set_representation(Representation::Integer32());
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001273 SetFlag(kUseGVN);
1274 }
1275
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001276 virtual Representation RequiredInputRepresentation(int index) {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001277 return Representation::None();
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001278 }
1279
1280 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1281
1282 protected:
1283 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001284};
1285
1286
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001287class HSimulate: public HInstruction {
1288 public:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001289 HSimulate(int ast_id, int pop_count, Zone* zone)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001290 : ast_id_(ast_id),
1291 pop_count_(pop_count),
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001292 values_(2, zone),
1293 assigned_indexes_(2, zone),
1294 zone_(zone) {}
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001295 virtual ~HSimulate() {}
1296
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001297 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001298
1299 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1300 int ast_id() const { return ast_id_; }
1301 void set_ast_id(int id) {
1302 ASSERT(!HasAstId());
1303 ast_id_ = id;
1304 }
1305
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001306 int pop_count() const { return pop_count_; }
1307 const ZoneList<HValue*>* values() const { return &values_; }
1308 int GetAssignedIndexAt(int index) const {
1309 ASSERT(HasAssignedIndexAt(index));
1310 return assigned_indexes_[index];
1311 }
1312 bool HasAssignedIndexAt(int index) const {
1313 return assigned_indexes_[index] != kNoIndex;
1314 }
1315 void AddAssignedValue(int index, HValue* value) {
1316 AddValue(index, value);
1317 }
1318 void AddPushedValue(HValue* value) {
1319 AddValue(kNoIndex, value);
1320 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001321 virtual int OperandCount() { return values_.length(); }
1322 virtual HValue* OperandAt(int index) { return values_[index]; }
1323
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001324 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001325 return Representation::None();
1326 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001327
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001328 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001329
1330#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001331 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001332#endif
1333
1334 protected:
1335 virtual void InternalSetOperandAt(int index, HValue* value) {
1336 values_[index] = value;
1337 }
1338
1339 private:
1340 static const int kNoIndex = -1;
1341 void AddValue(int index, HValue* value) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001342 assigned_indexes_.Add(index, zone_);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001343 // Resize the list of pushed values.
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001344 values_.Add(NULL, zone_);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001345 // Set the operand through the base method in HValue to make sure that the
1346 // use lists are correctly updated.
1347 SetOperandAt(values_.length() - 1, value);
1348 }
1349 int ast_id_;
1350 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001351 ZoneList<HValue*> values_;
1352 ZoneList<int> assigned_indexes_;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001353 Zone* zone_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001354};
1355
1356
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001357class HStackCheck: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001358 public:
ager@chromium.org04921a82011-06-27 13:21:41 +00001359 enum Type {
1360 kFunctionEntry,
1361 kBackwardsBranch
1362 };
1363
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001364 HStackCheck(HValue* context, Type type) : type_(type) {
1365 SetOperandAt(0, context);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00001366 SetGVNFlag(kChangesNewSpacePromotion);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001367 }
1368
1369 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001370
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001371 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001372 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001373 }
1374
ager@chromium.org04921a82011-06-27 13:21:41 +00001375 void Eliminate() {
1376 // The stack check eliminator might try to eliminate the same stack
1377 // check instruction multiple times.
1378 if (IsLinked()) {
1379 DeleteFromGraph();
1380 }
1381 }
1382
1383 bool is_function_entry() { return type_ == kFunctionEntry; }
1384 bool is_backwards_branch() { return type_ == kBackwardsBranch; }
1385
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001386 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
ager@chromium.org04921a82011-06-27 13:21:41 +00001387
1388 private:
1389 Type type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001390};
1391
1392
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001393class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001394 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +00001395 HEnterInlined(Handle<JSFunction> closure,
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001396 int arguments_count,
danno@chromium.org40cb8782011-05-25 07:58:50 +00001397 FunctionLiteral* function,
ulan@chromium.org967e2702012-02-28 09:49:15 +00001398 CallKind call_kind,
danno@chromium.org8c0a43f2012-04-03 08:37:53 +00001399 bool is_construct,
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001400 Variable* arguments_var,
1401 ZoneList<HValue*>* arguments_values)
danno@chromium.org40cb8782011-05-25 07:58:50 +00001402 : closure_(closure),
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001403 arguments_count_(arguments_count),
danno@chromium.org40cb8782011-05-25 07:58:50 +00001404 function_(function),
ulan@chromium.org967e2702012-02-28 09:49:15 +00001405 call_kind_(call_kind),
danno@chromium.org8c0a43f2012-04-03 08:37:53 +00001406 is_construct_(is_construct),
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001407 arguments_var_(arguments_var),
1408 arguments_values_(arguments_values) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001409 }
1410
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001411 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001412
1413 Handle<JSFunction> closure() const { return closure_; }
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001414 int arguments_count() const { return arguments_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001415 FunctionLiteral* function() const { return function_; }
danno@chromium.org40cb8782011-05-25 07:58:50 +00001416 CallKind call_kind() const { return call_kind_; }
ulan@chromium.org967e2702012-02-28 09:49:15 +00001417 bool is_construct() const { return is_construct_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001418
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001419 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001420 return Representation::None();
1421 }
1422
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001423 Variable* arguments_var() { return arguments_var_; }
1424 ZoneList<HValue*>* arguments_values() { return arguments_values_; }
danno@chromium.org8c0a43f2012-04-03 08:37:53 +00001425
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001426 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001427
1428 private:
1429 Handle<JSFunction> closure_;
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001430 int arguments_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001431 FunctionLiteral* function_;
danno@chromium.org40cb8782011-05-25 07:58:50 +00001432 CallKind call_kind_;
ulan@chromium.org967e2702012-02-28 09:49:15 +00001433 bool is_construct_;
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001434 Variable* arguments_var_;
1435 ZoneList<HValue*>* arguments_values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001436};
1437
1438
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001439class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001440 public:
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001441 explicit HLeaveInlined(bool arguments_pushed)
1442 : arguments_pushed_(arguments_pushed) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001443
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001444 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001445 return Representation::None();
1446 }
1447
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001448 bool arguments_pushed() {
1449 return arguments_pushed_;
1450 }
1451
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001452 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001453
1454 private:
1455 bool arguments_pushed_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001456};
1457
1458
1459class HPushArgument: public HUnaryOperation {
1460 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001461 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1462 set_representation(Representation::Tagged());
1463 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001464
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001465 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001466 return Representation::Tagged();
1467 }
1468
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001469 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001470
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001471 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001472};
1473
1474
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001475class HThisFunction: public HTemplateInstruction<0> {
1476 public:
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001477 HThisFunction() {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001478 set_representation(Representation::Tagged());
1479 SetFlag(kUseGVN);
1480 }
1481
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001482 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001483 return Representation::None();
1484 }
1485
1486 DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
1487
1488 protected:
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001489 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001490};
1491
1492
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001493class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001494 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001495 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001496 set_representation(Representation::Tagged());
1497 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001498 }
1499
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001500 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001501 return Representation::None();
1502 }
1503
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001504 DECLARE_CONCRETE_INSTRUCTION(Context)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001505
1506 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001507 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001508};
1509
1510
1511class HOuterContext: public HUnaryOperation {
1512 public:
1513 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1514 set_representation(Representation::Tagged());
1515 SetFlag(kUseGVN);
1516 }
1517
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001518 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001519
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001520 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001521 return Representation::Tagged();
1522 }
1523
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001524 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001525 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001526};
1527
1528
yangguo@chromium.org56454712012-02-16 15:33:53 +00001529class HDeclareGlobals: public HUnaryOperation {
1530 public:
1531 HDeclareGlobals(HValue* context,
1532 Handle<FixedArray> pairs,
1533 int flags)
1534 : HUnaryOperation(context),
1535 pairs_(pairs),
1536 flags_(flags) {
1537 set_representation(Representation::Tagged());
1538 SetAllSideEffects();
1539 }
1540
1541 HValue* context() { return OperandAt(0); }
1542 Handle<FixedArray> pairs() const { return pairs_; }
1543 int flags() const { return flags_; }
1544
1545 DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals)
1546
1547 virtual Representation RequiredInputRepresentation(int index) {
1548 return Representation::Tagged();
1549 }
1550 private:
1551 Handle<FixedArray> pairs_;
1552 int flags_;
1553};
1554
1555
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001556class HGlobalObject: public HUnaryOperation {
1557 public:
1558 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1559 set_representation(Representation::Tagged());
1560 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001561 }
1562
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001563 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001564
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001565 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001566 return Representation::Tagged();
1567 }
1568
ager@chromium.org378b34e2011-01-28 08:04:38 +00001569 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001570 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001571};
1572
1573
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001574class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001575 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001576 explicit HGlobalReceiver(HValue* global_object)
1577 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001578 set_representation(Representation::Tagged());
1579 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001580 }
1581
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001582 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001583
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001584 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001585 return Representation::Tagged();
1586 }
1587
ager@chromium.org378b34e2011-01-28 08:04:38 +00001588 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001589 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001590};
1591
1592
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001593template <int V>
1594class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001595 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001596 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001597 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1598 this->set_representation(Representation::Tagged());
1599 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001600 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001601
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001602 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001603
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001604 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001605
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001606 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001607
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001608 private:
1609 int argument_count_;
1610};
1611
1612
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001613class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001614 public:
1615 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001616 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001617 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001618 }
1619
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001620 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001621 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001622 }
1623
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001624 virtual void PrintDataTo(StringStream* stream);
1625
1626 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001627};
1628
1629
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001630class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001631 public:
1632 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001633 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001634 SetOperandAt(0, first);
1635 SetOperandAt(1, second);
1636 }
1637
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001638 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001639
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001640 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001641 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001642 }
1643
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001644 HValue* first() { return OperandAt(0); }
1645 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001646};
1647
1648
danno@chromium.org160a7b02011-04-18 15:51:38 +00001649class HInvokeFunction: public HBinaryCall {
1650 public:
1651 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1652 : HBinaryCall(context, function, argument_count) {
1653 }
1654
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00001655 HInvokeFunction(HValue* context,
1656 HValue* function,
1657 Handle<JSFunction> known_function,
1658 int argument_count)
1659 : HBinaryCall(context, function, argument_count),
1660 known_function_(known_function) {
1661 }
1662
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001663 virtual Representation RequiredInputRepresentation(int index) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00001664 return Representation::Tagged();
1665 }
1666
1667 HValue* context() { return first(); }
1668 HValue* function() { return second(); }
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00001669 Handle<JSFunction> known_function() { return known_function_; }
danno@chromium.org160a7b02011-04-18 15:51:38 +00001670
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001671 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00001672
1673 private:
1674 Handle<JSFunction> known_function_;
danno@chromium.org160a7b02011-04-18 15:51:38 +00001675};
1676
1677
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001678class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001679 public:
1680 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001681 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001682
1683 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001684
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001685 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001686 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001687 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001688 }
1689
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001690 virtual void PrintDataTo(StringStream* stream);
1691
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001692 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001693 return Representation::None();
1694 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001695
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001696 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001697
1698 private:
1699 Handle<JSFunction> function_;
1700};
1701
1702
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001703class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001704 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001705 HCallKeyed(HValue* context, HValue* key, int argument_count)
1706 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001707 }
1708
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001709 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001710 return Representation::Tagged();
1711 }
1712
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001713 HValue* context() { return first(); }
1714 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001715
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001716 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001717};
1718
1719
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001720class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001721 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001722 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1723 : HUnaryCall(context, argument_count), name_(name) {
1724 }
1725
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001726 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001727
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001728 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001729 Handle<String> name() const { return name_; }
1730
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001731 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001732
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001733 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001734 return Representation::Tagged();
1735 }
1736
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001737 private:
1738 Handle<String> name_;
1739};
1740
1741
danno@chromium.orgc612e022011-11-10 11:38:15 +00001742class HCallFunction: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001743 public:
danno@chromium.orgc612e022011-11-10 11:38:15 +00001744 HCallFunction(HValue* context, HValue* function, int argument_count)
1745 : HBinaryCall(context, function, argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001746 }
1747
danno@chromium.orgc612e022011-11-10 11:38:15 +00001748 HValue* context() { return first(); }
1749 HValue* function() { return second(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001750
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001751 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001752 return Representation::Tagged();
1753 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001754
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001755 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001756};
1757
1758
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001759class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001760 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001761 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1762 : HUnaryCall(context, argument_count), name_(name) {
1763 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001764
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001765 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001766
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001767 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001768 Handle<String> name() const { return name_; }
1769
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001770 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001771 return Representation::Tagged();
1772 }
1773
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001774 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001775
1776 private:
1777 Handle<String> name_;
1778};
1779
1780
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001781class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001782 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001783 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001784 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001785
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001786 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001787
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001788 Handle<JSFunction> target() const { return target_; }
1789
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001790 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001791 return Representation::None();
1792 }
1793
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001794 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001795
1796 private:
1797 Handle<JSFunction> target_;
1798};
1799
1800
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001801class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001802 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001803 HCallNew(HValue* context, HValue* constructor, int argument_count)
1804 : HBinaryCall(context, constructor, argument_count) {
1805 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001806
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001807 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001808 return Representation::Tagged();
1809 }
1810
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001811 HValue* context() { return first(); }
1812 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001813
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001814 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001815};
1816
1817
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001818class HCallRuntime: public HCall<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001819 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001820 HCallRuntime(HValue* context,
1821 Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001822 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001823 int argument_count)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001824 : HCall<1>(argument_count), c_function_(c_function), name_(name) {
1825 SetOperandAt(0, context);
1826 }
1827
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001828 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001829
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001830 HValue* context() { return OperandAt(0); }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001831 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001832 Handle<String> name() const { return name_; }
1833
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001834 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001835 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001836 }
1837
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001838 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001839
1840 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001841 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001842 Handle<String> name_;
1843};
1844
1845
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001846class HJSArrayLength: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001847 public:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001848 HJSArrayLength(HValue* value, HValue* typecheck,
1849 HType type = HType::Tagged()) {
1850 set_type(type);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001851 // The length of an array is stored as a tagged value in the array
1852 // object. It is guaranteed to be 32 bit integer, but it can be
1853 // represented as either a smi or heap number.
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001854 SetOperandAt(0, value);
1855 SetOperandAt(1, typecheck);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001856 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001857 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001858 SetGVNFlag(kDependsOnArrayLengths);
1859 SetGVNFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001860 }
1861
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001862 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001863 return Representation::Tagged();
1864 }
1865
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001866 virtual void PrintDataTo(StringStream* stream);
1867
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001868 HValue* value() { return OperandAt(0); }
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001869 HValue* typecheck() { return OperandAt(1); }
ricow@chromium.org9fa09672011-07-25 11:05:35 +00001870
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001871 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001872
1873 protected:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001874 virtual bool DataEquals(HValue* other_raw) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001875};
1876
1877
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001878class HFixedArrayBaseLength: public HUnaryOperation {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001879 public:
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001880 explicit HFixedArrayBaseLength(HValue* value) : HUnaryOperation(value) {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001881 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001882 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001883 SetGVNFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001884 }
1885
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001886 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001887 return Representation::Tagged();
1888 }
1889
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001890 DECLARE_CONCRETE_INSTRUCTION(FixedArrayBaseLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001891
1892 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001893 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001894};
1895
1896
whesse@chromium.org7b260152011-06-20 15:33:18 +00001897class HElementsKind: public HUnaryOperation {
1898 public:
1899 explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
1900 set_representation(Representation::Integer32());
1901 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001902 SetGVNFlag(kDependsOnElementsKind);
whesse@chromium.org7b260152011-06-20 15:33:18 +00001903 }
1904
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001905 virtual Representation RequiredInputRepresentation(int index) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00001906 return Representation::Tagged();
1907 }
1908
1909 DECLARE_CONCRETE_INSTRUCTION(ElementsKind)
1910
1911 protected:
1912 virtual bool DataEquals(HValue* other) { return true; }
1913};
1914
1915
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001916class HBitNot: public HUnaryOperation {
1917 public:
1918 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1919 set_representation(Representation::Integer32());
1920 SetFlag(kUseGVN);
1921 SetFlag(kTruncatingToInt32);
1922 }
1923
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001924 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001925 return Representation::Integer32();
1926 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001927 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001928
mstarzinger@chromium.org88d326b2012-04-23 12:57:22 +00001929 virtual HValue* Canonicalize();
1930
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001931 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001932
1933 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001934 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001935};
1936
1937
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001938class HUnaryMathOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001939 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001940 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
1941 : op_(op) {
1942 SetOperandAt(0, context);
1943 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001944 switch (op) {
1945 case kMathFloor:
1946 case kMathRound:
1947 case kMathCeil:
1948 set_representation(Representation::Integer32());
1949 break;
1950 case kMathAbs:
1951 set_representation(Representation::Tagged());
1952 SetFlag(kFlexibleRepresentation);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00001953 SetGVNFlag(kChangesNewSpacePromotion);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001954 break;
1955 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001956 case kMathPowHalf:
1957 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001958 case kMathSin:
1959 case kMathCos:
ulan@chromium.org9a21ec42012-03-06 08:42:24 +00001960 case kMathTan:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001961 set_representation(Representation::Double());
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00001962 SetGVNFlag(kChangesNewSpacePromotion);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001963 break;
1964 default:
1965 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001966 }
1967 SetFlag(kUseGVN);
1968 }
1969
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001970 HValue* context() { return OperandAt(0); }
1971 HValue* value() { return OperandAt(1); }
1972
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001973 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001974
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001975 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001976
1977 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1978
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001979 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001980 if (index == 0) {
1981 return Representation::Tagged();
1982 } else {
1983 switch (op_) {
1984 case kMathFloor:
1985 case kMathRound:
1986 case kMathCeil:
1987 case kMathSqrt:
1988 case kMathPowHalf:
1989 case kMathLog:
1990 case kMathSin:
1991 case kMathCos:
ulan@chromium.org9a21ec42012-03-06 08:42:24 +00001992 case kMathTan:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001993 return Representation::Double();
1994 case kMathAbs:
1995 return representation();
1996 default:
1997 UNREACHABLE();
1998 return Representation::None();
1999 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002000 }
2001 }
2002
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00002003 virtual HValue* Canonicalize();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002004
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002005 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002006 const char* OpName() const;
2007
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002008 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002009
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002010 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002011 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002012 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
2013 return op_ == b->op();
2014 }
2015
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002016 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002017 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002018};
2019
2020
2021class HLoadElements: public HUnaryOperation {
2022 public:
2023 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
2024 set_representation(Representation::Tagged());
2025 SetFlag(kUseGVN);
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00002026 SetGVNFlag(kDependsOnElementsPointer);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002027 }
2028
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002029 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002030 return Representation::Tagged();
2031 }
2032
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002033 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002034
2035 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002036 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002037};
2038
2039
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002040class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002041 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002042 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002043 : HUnaryOperation(value) {
2044 set_representation(Representation::External());
2045 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002046 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002047 // change once set, so it's no necessary to introduce any additional
2048 // dependencies on top of the inputs.
2049 SetFlag(kUseGVN);
2050 }
2051
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002052 virtual Representation RequiredInputRepresentation(int index) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002053 return Representation::Tagged();
2054 }
2055
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002056 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002057
2058 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002059 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002060};
2061
2062
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002063class HCheckMaps: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002064 public:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002065 HCheckMaps(HValue* value, Handle<Map> map, Zone* zone,
2066 HValue* typecheck = NULL) {
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002067 SetOperandAt(0, value);
2068 // If callers don't depend on a typecheck, they can pass in NULL. In that
2069 // case we use a copy of the |value| argument as a dummy value.
2070 SetOperandAt(1, typecheck != NULL ? typecheck : value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002071 set_representation(Representation::Tagged());
2072 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00002073 SetGVNFlag(kDependsOnMaps);
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002074 SetGVNFlag(kDependsOnElementsKind);
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002075 map_set()->Add(map, zone);
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002076 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002077 HCheckMaps(HValue* value, SmallMapList* maps, Zone* zone) {
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002078 SetOperandAt(0, value);
2079 SetOperandAt(1, value);
2080 set_representation(Representation::Tagged());
2081 SetFlag(kUseGVN);
2082 SetGVNFlag(kDependsOnMaps);
2083 SetGVNFlag(kDependsOnElementsKind);
2084 for (int i = 0; i < maps->length(); i++) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002085 map_set()->Add(maps->at(i), zone);
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00002086 }
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002087 map_set()->Sort();
2088 }
2089
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002090 static HCheckMaps* NewWithTransitions(HValue* object, Handle<Map> map,
2091 Zone* zone) {
2092 HCheckMaps* check_map = new(zone) HCheckMaps(object, map, zone);
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002093 SmallMapList* map_set = check_map->map_set();
2094
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002095 // Since transitioned elements maps of the initial map don't fail the map
2096 // check, the CheckMaps instruction doesn't need to depend on ElementsKinds.
2097 check_map->ClearGVNFlag(kDependsOnElementsKind);
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002098
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002099 ElementsKind kind = map->elements_kind();
2100 bool packed = IsFastPackedElementsKind(kind);
2101 while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) {
2102 kind = GetNextMoreGeneralFastElementsKind(kind, packed);
2103 Map* transitioned_map =
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002104 map->LookupElementsTransitionMap(kind);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002105 if (transitioned_map) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002106 map_set->Add(Handle<Map>(transitioned_map), zone);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002107 }
2108 };
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002109 map_set->Sort();
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002110 return check_map;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002111 }
2112
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002113 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002114 return Representation::Tagged();
2115 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002116 virtual void PrintDataTo(StringStream* stream);
2117 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002118
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002119 HValue* value() { return OperandAt(0); }
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002120 SmallMapList* map_set() { return &map_set_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002121
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002122 DECLARE_CONCRETE_INSTRUCTION(CheckMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002123
2124 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002125 virtual bool DataEquals(HValue* other) {
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002126 HCheckMaps* b = HCheckMaps::cast(other);
2127 // Relies on the fact that map_set has been sorted before.
2128 if (map_set()->length() != b->map_set()->length()) return false;
2129 for (int i = 0; i < map_set()->length(); i++) {
2130 if (!map_set()->at(i).is_identical_to(b->map_set()->at(i))) return false;
2131 }
2132 return true;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002133 }
2134
2135 private:
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002136 SmallMapList map_set_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002137};
2138
2139
2140class HCheckFunction: public HUnaryOperation {
2141 public:
2142 HCheckFunction(HValue* value, Handle<JSFunction> function)
2143 : HUnaryOperation(value), target_(function) {
2144 set_representation(Representation::Tagged());
2145 SetFlag(kUseGVN);
2146 }
2147
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002148 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002149 return Representation::Tagged();
2150 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002151 virtual void PrintDataTo(StringStream* stream);
2152 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002153
2154#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002155 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002156#endif
2157
2158 Handle<JSFunction> target() const { return target_; }
2159
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002160 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002161
2162 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002163 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002164 HCheckFunction* b = HCheckFunction::cast(other);
2165 return target_.is_identical_to(b->target());
2166 }
2167
2168 private:
2169 Handle<JSFunction> target_;
2170};
2171
2172
2173class HCheckInstanceType: public HUnaryOperation {
2174 public:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002175 static HCheckInstanceType* NewIsSpecObject(HValue* value, Zone* zone) {
2176 return new(zone) HCheckInstanceType(value, IS_SPEC_OBJECT);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002177 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002178 static HCheckInstanceType* NewIsJSArray(HValue* value, Zone* zone) {
2179 return new(zone) HCheckInstanceType(value, IS_JS_ARRAY);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002180 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002181 static HCheckInstanceType* NewIsString(HValue* value, Zone* zone) {
2182 return new(zone) HCheckInstanceType(value, IS_STRING);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002183 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002184 static HCheckInstanceType* NewIsSymbol(HValue* value, Zone* zone) {
2185 return new(zone) HCheckInstanceType(value, IS_SYMBOL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002186 }
2187
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002188 virtual void PrintDataTo(StringStream* stream);
2189
2190 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002191 return Representation::Tagged();
2192 }
2193
sgjesse@chromium.org6db88712011-07-11 11:41:22 +00002194 virtual HValue* Canonicalize();
danno@chromium.org160a7b02011-04-18 15:51:38 +00002195
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002196 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
2197 void GetCheckInterval(InstanceType* first, InstanceType* last);
2198 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002199
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002200 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002201
2202 protected:
2203 // TODO(ager): It could be nice to allow the ommision of instance
2204 // type checks if we have already performed an instance type check
2205 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002206 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002207 HCheckInstanceType* b = HCheckInstanceType::cast(other);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002208 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002209 }
2210
2211 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002212 enum Check {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002213 IS_SPEC_OBJECT,
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002214 IS_JS_ARRAY,
2215 IS_STRING,
2216 IS_SYMBOL,
2217 LAST_INTERVAL_CHECK = IS_JS_ARRAY
2218 };
2219
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002220 const char* GetCheckName();
2221
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002222 HCheckInstanceType(HValue* value, Check check)
2223 : HUnaryOperation(value), check_(check) {
2224 set_representation(Representation::Tagged());
2225 SetFlag(kUseGVN);
2226 }
2227
2228 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002229};
2230
2231
2232class HCheckNonSmi: public HUnaryOperation {
2233 public:
2234 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
2235 set_representation(Representation::Tagged());
2236 SetFlag(kUseGVN);
2237 }
2238
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002239 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002240 return Representation::Tagged();
2241 }
2242
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002243 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002244
2245#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002246 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002247#endif
2248
danno@chromium.org160a7b02011-04-18 15:51:38 +00002249 virtual HValue* Canonicalize() {
2250 HType value_type = value()->type();
2251 if (!value_type.IsUninitialized() &&
2252 (value_type.IsHeapNumber() ||
2253 value_type.IsString() ||
2254 value_type.IsBoolean() ||
2255 value_type.IsNonPrimitive())) {
2256 return NULL;
2257 }
2258 return this;
2259 }
2260
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002261 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002262
2263 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002264 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002265};
2266
2267
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002268class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002269 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002270 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
2271 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002272 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00002273 SetGVNFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002274 }
2275
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002276#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002277 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002278#endif
2279
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002280 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002281 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002282
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002283 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002284
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002285 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002286 return Representation::None();
2287 }
2288
danno@chromium.org81cac2b2012-07-10 11:28:27 +00002289 virtual void PrintDataTo(StringStream* stream);
2290
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002291 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002292 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002293 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
2294 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
2295 return hash;
2296 }
2297
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002298 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002299 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002300 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002301 return prototype_.is_identical_to(b->prototype()) &&
2302 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002303 }
2304
2305 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002306 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002307 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002308};
2309
2310
2311class HCheckSmi: public HUnaryOperation {
2312 public:
2313 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
2314 set_representation(Representation::Tagged());
2315 SetFlag(kUseGVN);
2316 }
2317
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002318 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002319 return Representation::Tagged();
2320 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002321 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002322
2323#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002324 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002325#endif
2326
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002327 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002328
2329 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002330 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002331};
2332
2333
2334class HPhi: public HValue {
2335 public:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002336 HPhi(int merged_index, Zone* zone)
2337 : inputs_(2, zone),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002338 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002339 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002340 is_live_(false),
2341 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002342 for (int i = 0; i < Representation::kNumRepresentations; i++) {
2343 non_phi_uses_[i] = 0;
2344 indirect_uses_[i] = 0;
2345 }
2346 ASSERT(merged_index >= 0);
2347 set_representation(Representation::Tagged());
2348 SetFlag(kFlexibleRepresentation);
2349 }
2350
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00002351 virtual Representation InferredRepresentation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002352
ulan@chromium.org812308e2012-02-29 15:58:45 +00002353 virtual Range* InferRange(Zone* zone);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002354 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002355 return representation();
2356 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002357 virtual HType CalculateInferredType();
2358 virtual int OperandCount() { return inputs_.length(); }
2359 virtual HValue* OperandAt(int index) { return inputs_[index]; }
2360 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002361 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002362 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002363
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002364 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002365
2366 int merged_index() const { return merged_index_; }
2367
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002368 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002369
2370#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002371 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002372#endif
2373
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002374 void InitRealUses(int id);
2375 void AddNonPhiUsesFrom(HPhi* other);
2376 void AddIndirectUsesTo(int* use_count);
2377
2378 int tagged_non_phi_uses() const {
2379 return non_phi_uses_[Representation::kTagged];
2380 }
2381 int int32_non_phi_uses() const {
2382 return non_phi_uses_[Representation::kInteger32];
2383 }
2384 int double_non_phi_uses() const {
2385 return non_phi_uses_[Representation::kDouble];
2386 }
2387 int tagged_indirect_uses() const {
2388 return indirect_uses_[Representation::kTagged];
2389 }
2390 int int32_indirect_uses() const {
2391 return indirect_uses_[Representation::kInteger32];
2392 }
2393 int double_indirect_uses() const {
2394 return indirect_uses_[Representation::kDouble];
2395 }
2396 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002397 bool is_live() { return is_live_; }
2398 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002399
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002400 static HPhi* cast(HValue* value) {
2401 ASSERT(value->IsPhi());
2402 return reinterpret_cast<HPhi*>(value);
2403 }
2404 virtual Opcode opcode() const { return HValue::kPhi; }
2405
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002406 virtual bool IsConvertibleToInteger() const {
2407 return is_convertible_to_integer_;
2408 }
2409
2410 void set_is_convertible_to_integer(bool b) {
2411 is_convertible_to_integer_ = b;
2412 }
2413
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002414 bool AllOperandsConvertibleToInteger() {
2415 for (int i = 0; i < OperandCount(); ++i) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002416 if (!OperandAt(i)->IsConvertibleToInteger()) {
2417 return false;
2418 }
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002419 }
2420 return true;
2421 }
2422
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002423 void ResetInteger32Uses();
2424
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002425 protected:
2426 virtual void DeleteFromGraph();
2427 virtual void InternalSetOperandAt(int index, HValue* value) {
2428 inputs_[index] = value;
2429 }
2430
2431 private:
2432 ZoneList<HValue*> inputs_;
2433 int merged_index_;
2434
2435 int non_phi_uses_[Representation::kNumRepresentations];
2436 int indirect_uses_[Representation::kNumRepresentations];
2437 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002438 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002439 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002440};
2441
2442
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002443class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002444 public:
2445 HArgumentsObject() {
2446 set_representation(Representation::Tagged());
2447 SetFlag(kIsArguments);
2448 }
2449
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002450 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002451 return Representation::None();
2452 }
2453
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002454 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002455};
2456
2457
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002458class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002459 public:
2460 HConstant(Handle<Object> handle, Representation r);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00002461 HConstant(int32_t value, Representation r);
2462 HConstant(double value, Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002463
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00002464 Handle<Object> handle() {
2465 if (handle_.is_null()) {
2466 handle_ = FACTORY->NewNumber(double_value_, TENURED);
2467 }
2468 ASSERT(has_int32_value_ || !handle_->IsSmi());
2469 return handle_;
2470 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002471
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002472 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002473
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002474 bool ImmortalImmovable() const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00002475 if (has_int32_value_) {
2476 return false;
2477 }
2478 if (has_double_value_) {
2479 if (BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) ||
2480 isnan(double_value_)) {
2481 return true;
2482 }
2483 return false;
2484 }
2485
2486 ASSERT(!handle_.is_null());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002487 Heap* heap = HEAP;
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00002488 // We should have handled minus_zero_value and nan_value in the
2489 // has_double_value_ clause above.
2490 ASSERT(*handle_ != heap->minus_zero_value());
2491 ASSERT(*handle_ != heap->nan_value());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002492 if (*handle_ == heap->undefined_value()) return true;
2493 if (*handle_ == heap->null_value()) return true;
2494 if (*handle_ == heap->true_value()) return true;
2495 if (*handle_ == heap->false_value()) return true;
2496 if (*handle_ == heap->the_hole_value()) return true;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002497 if (*handle_ == heap->empty_string()) return true;
2498 return false;
2499 }
2500
2501 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002502 return Representation::None();
2503 }
2504
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002505 virtual bool IsConvertibleToInteger() const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00002506 return has_int32_value_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002507 }
2508
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002509 virtual bool EmitAtUses() { return !representation().IsDouble(); }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002510 virtual HValue* Canonicalize();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002511 virtual void PrintDataTo(StringStream* stream);
2512 virtual HType CalculateInferredType();
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00002513 bool IsInteger() { return handle()->IsSmi(); }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002514 HConstant* CopyToRepresentation(Representation r, Zone* zone) const;
2515 HConstant* CopyToTruncatedInt32(Zone* zone) const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002516 bool HasInteger32Value() const { return has_int32_value_; }
2517 int32_t Integer32Value() const {
2518 ASSERT(HasInteger32Value());
2519 return int32_value_;
2520 }
2521 bool HasDoubleValue() const { return has_double_value_; }
2522 double DoubleValue() const {
2523 ASSERT(HasDoubleValue());
2524 return double_value_;
2525 }
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00002526 bool HasNumberValue() const { return has_double_value_; }
erikcorry0ad885c2011-11-21 13:51:57 +00002527 int32_t NumberValueAsInteger32() const {
2528 ASSERT(HasNumberValue());
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00002529 // Irrespective of whether a numeric HConstant can be safely
2530 // represented as an int32, we store the (in some cases lossy)
2531 // representation of the number in int32_value_.
2532 return int32_value_;
erikcorry0ad885c2011-11-21 13:51:57 +00002533 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002534
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00002535 bool ToBoolean();
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002536
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002537 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002538 ASSERT(!HEAP->allow_allocation(false));
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00002539 intptr_t hash;
2540
2541 if (has_int32_value_) {
2542 hash = static_cast<intptr_t>(int32_value_);
2543 } else if (has_double_value_) {
2544 hash = static_cast<intptr_t>(BitCast<int64_t>(double_value_));
2545 } else {
2546 ASSERT(!handle_.is_null());
2547 hash = reinterpret_cast<intptr_t>(*handle_);
2548 }
2549
2550 return hash;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002551 }
2552
2553#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002554 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002555#endif
2556
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002557 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002558
2559 protected:
ulan@chromium.org812308e2012-02-29 15:58:45 +00002560 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002561
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002562 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002563 HConstant* other_constant = HConstant::cast(other);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00002564 if (has_int32_value_) {
2565 return other_constant->has_int32_value_ &&
2566 int32_value_ == other_constant->int32_value_;
2567 } else if (has_double_value_) {
2568 return other_constant->has_double_value_ &&
2569 BitCast<int64_t>(double_value_) ==
2570 BitCast<int64_t>(other_constant->double_value_);
2571 } else {
2572 ASSERT(!handle_.is_null());
2573 return !other_constant->handle_.is_null() &&
2574 *handle_ == *other_constant->handle_;
2575 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002576 }
2577
2578 private:
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00002579 // If this is a numerical constant, handle_ either points to to the
2580 // HeapObject the constant originated from or is null. If the
2581 // constant is non-numeric, handle_ always points to a valid
2582 // constant HeapObject.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002583 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002584
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00002585 // We store the HConstant in the most specific form safely possible.
2586 // The two flags, has_int32_value_ and has_double_value_ tell us if
2587 // int32_value_ and double_value_ hold valid, safe representations
2588 // of the constant. has_int32_value_ implies has_double_value_ but
2589 // not the converse.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002590 bool has_int32_value_ : 1;
2591 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002592 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002593 double double_value_;
2594};
2595
2596
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002597class HBinaryOperation: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002598 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002599 HBinaryOperation(HValue* context, HValue* left, HValue* right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002600 ASSERT(left != NULL && right != NULL);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002601 SetOperandAt(0, context);
2602 SetOperandAt(1, left);
2603 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002604 }
2605
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002606 HValue* context() { return OperandAt(0); }
2607 HValue* left() { return OperandAt(1); }
2608 HValue* right() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002609
2610 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2611 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002612 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002613 if (IsCommutative() && left()->IsConstant()) return right();
2614 return left();
2615 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002616
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002617 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002618 if (IsCommutative() && left()->IsConstant()) return left();
2619 return right();
2620 }
2621
2622 virtual bool IsCommutative() const { return false; }
2623
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002624 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002625};
2626
2627
yangguo@chromium.org154ff992012-03-13 08:09:54 +00002628class HWrapReceiver: public HTemplateInstruction<2> {
2629 public:
2630 HWrapReceiver(HValue* receiver, HValue* function) {
2631 set_representation(Representation::Tagged());
2632 SetOperandAt(0, receiver);
2633 SetOperandAt(1, function);
2634 }
2635
2636 virtual Representation RequiredInputRepresentation(int index) {
2637 return Representation::Tagged();
2638 }
2639
2640 HValue* receiver() { return OperandAt(0); }
2641 HValue* function() { return OperandAt(1); }
2642
2643 virtual HValue* Canonicalize();
2644
2645 DECLARE_CONCRETE_INSTRUCTION(WrapReceiver)
2646};
2647
2648
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002649class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002650 public:
2651 HApplyArguments(HValue* function,
2652 HValue* receiver,
2653 HValue* length,
2654 HValue* elements) {
2655 set_representation(Representation::Tagged());
2656 SetOperandAt(0, function);
2657 SetOperandAt(1, receiver);
2658 SetOperandAt(2, length);
2659 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002660 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002661 }
2662
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002663 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002664 // The length is untagged, all other inputs are tagged.
2665 return (index == 2)
2666 ? Representation::Integer32()
2667 : Representation::Tagged();
2668 }
2669
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002670 HValue* function() { return OperandAt(0); }
2671 HValue* receiver() { return OperandAt(1); }
2672 HValue* length() { return OperandAt(2); }
2673 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002674
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002675 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002676};
2677
2678
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002679class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002680 public:
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00002681 explicit HArgumentsElements(bool from_inlined) : from_inlined_(from_inlined) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002682 // The value produced by this instruction is a pointer into the stack
2683 // that looks as if it was a smi because of alignment.
2684 set_representation(Representation::Tagged());
2685 SetFlag(kUseGVN);
2686 }
2687
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002688 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002689
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002690 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002691 return Representation::None();
2692 }
2693
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00002694 bool from_inlined() const { return from_inlined_; }
2695
ager@chromium.org378b34e2011-01-28 08:04:38 +00002696 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002697 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00002698
2699 bool from_inlined_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002700};
2701
2702
2703class HArgumentsLength: public HUnaryOperation {
2704 public:
2705 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2706 set_representation(Representation::Integer32());
2707 SetFlag(kUseGVN);
2708 }
2709
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002710 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002711 return Representation::Tagged();
2712 }
2713
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002714 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002715
2716 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002717 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002718};
2719
2720
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002721class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002722 public:
2723 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2724 set_representation(Representation::Tagged());
2725 SetFlag(kUseGVN);
2726 SetOperandAt(0, arguments);
2727 SetOperandAt(1, length);
2728 SetOperandAt(2, index);
2729 }
2730
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002731 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002732
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002733 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002734 // The arguments elements is considered tagged.
2735 return index == 0
2736 ? Representation::Tagged()
2737 : Representation::Integer32();
2738 }
2739
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002740 HValue* arguments() { return OperandAt(0); }
2741 HValue* length() { return OperandAt(1); }
2742 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002743
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002744 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002745
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002746 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002747};
2748
2749
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002750class HBoundsCheck: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002751 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002752 HBoundsCheck(HValue* index, HValue* length) {
2753 SetOperandAt(0, index);
2754 SetOperandAt(1, length);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002755 set_representation(Representation::Integer32());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002756 SetFlag(kUseGVN);
2757 }
2758
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002759 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002760 return Representation::Integer32();
2761 }
2762
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00002763 virtual void PrintDataTo(StringStream* stream);
2764
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002765 HValue* index() { return OperandAt(0); }
2766 HValue* length() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002767
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002768 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002769
2770 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002771 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002772};
2773
2774
2775class HBitwiseBinaryOperation: public HBinaryOperation {
2776 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002777 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
2778 : HBinaryOperation(context, left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002779 set_representation(Representation::Tagged());
2780 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002781 SetAllSideEffects();
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002782 observed_input_representation_[0] = Representation::Tagged();
2783 observed_input_representation_[1] = Representation::None();
2784 observed_input_representation_[2] = Representation::None();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002785 }
2786
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002787 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002788 return index == 0
2789 ? Representation::Tagged()
2790 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002791 }
2792
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002793 virtual void RepresentationChanged(Representation to) {
2794 if (!to.IsTagged()) {
2795 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002796 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002797 SetFlag(kTruncatingToInt32);
2798 SetFlag(kUseGVN);
2799 }
2800 }
2801
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002802 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002803
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002804 virtual Representation ObservedInputRepresentation(int index) {
2805 return observed_input_representation_[index];
2806 }
2807
2808 void InitializeObservedInputRepresentation(Representation r) {
2809 observed_input_representation_[1] = r;
2810 observed_input_representation_[2] = r;
2811 }
2812
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002813 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002814
2815 private:
2816 Representation observed_input_representation_[3];
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002817};
2818
2819
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00002820class HMathFloorOfDiv: public HBinaryOperation {
2821 public:
2822 HMathFloorOfDiv(HValue* context, HValue* left, HValue* right)
2823 : HBinaryOperation(context, left, right) {
2824 set_representation(Representation::Integer32());
2825 SetFlag(kUseGVN);
yangguo@chromium.orgd2899aa2012-06-21 11:16:20 +00002826 SetFlag(kCanOverflow);
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00002827 }
2828
yangguo@chromium.orgd2899aa2012-06-21 11:16:20 +00002829 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2830
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00002831 virtual Representation RequiredInputRepresentation(int index) {
2832 return Representation::Integer32();
2833 }
2834
2835 DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv)
2836
2837 protected:
2838 virtual bool DataEquals(HValue* other) { return true; }
2839};
2840
2841
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002842class HArithmeticBinaryOperation: public HBinaryOperation {
2843 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002844 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right)
2845 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002846 set_representation(Representation::Tagged());
2847 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002848 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002849 }
2850
2851 virtual void RepresentationChanged(Representation to) {
2852 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002853 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002854 SetFlag(kUseGVN);
2855 }
2856 }
2857
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002858 virtual HType CalculateInferredType();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002859 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002860 return index == 0
2861 ? Representation::Tagged()
2862 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002863 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002864
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002865 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002866 if (left()->representation().Equals(right()->representation())) {
2867 return left()->representation();
2868 }
2869 return HValue::InferredRepresentation();
2870 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002871};
2872
2873
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002874class HCompareGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002875 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002876 HCompareGeneric(HValue* context,
2877 HValue* left,
2878 HValue* right,
2879 Token::Value token)
2880 : HBinaryOperation(context, left, right), token_(token) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002881 ASSERT(Token::IsCompareOp(token));
2882 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002883 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002884 }
2885
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002886 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002887 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002888 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002889
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002890 Representation GetInputRepresentation() const {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002891 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002892 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002893
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002894 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002895 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002896
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002897 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002898
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002899 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
2900
2901 private:
2902 Token::Value token_;
2903};
2904
2905
2906class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> {
2907 public:
2908 HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token)
2909 : token_(token) {
2910 ASSERT(Token::IsCompareOp(token));
2911 SetOperandAt(0, left);
2912 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002913 }
2914
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002915 HValue* left() { return OperandAt(0); }
2916 HValue* right() { return OperandAt(1); }
2917 Token::Value token() const { return token_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002918
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002919 void SetInputRepresentation(Representation r);
2920 Representation GetInputRepresentation() const {
2921 return input_representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002922 }
2923
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002924 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002925 return input_representation_;
2926 }
2927 virtual void PrintDataTo(StringStream* stream);
2928
2929 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch)
2930
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002931 private:
2932 Representation input_representation_;
2933 Token::Value token_;
2934};
2935
2936
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002937class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002938 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002939 HCompareObjectEqAndBranch(HValue* left, HValue* right) {
2940 SetOperandAt(0, left);
2941 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002942 }
2943
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002944 HValue* left() { return OperandAt(0); }
2945 HValue* right() { return OperandAt(1); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002946
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002947 virtual void PrintDataTo(StringStream* stream);
2948
2949 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002950 return Representation::Tagged();
2951 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002952
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002953 DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002954};
2955
2956
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002957class HCompareConstantEqAndBranch: public HUnaryControlInstruction {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002958 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002959 HCompareConstantEqAndBranch(HValue* left, int right, Token::Value op)
2960 : HUnaryControlInstruction(left, NULL, NULL), op_(op), right_(right) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002961 ASSERT(op == Token::EQ_STRICT);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002962 }
2963
2964 Token::Value op() const { return op_; }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002965 HValue* left() { return value(); }
whesse@chromium.org7b260152011-06-20 15:33:18 +00002966 int right() const { return right_; }
2967
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002968 virtual Representation RequiredInputRepresentation(int index) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002969 return Representation::Integer32();
2970 }
2971
ricow@chromium.org4f693d62011-07-04 14:01:31 +00002972 DECLARE_CONCRETE_INSTRUCTION(CompareConstantEqAndBranch);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002973
2974 private:
2975 const Token::Value op_;
2976 const int right_;
2977};
2978
2979
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002980class HIsNilAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002981 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002982 HIsNilAndBranch(HValue* value, EqualityKind kind, NilValue nil)
2983 : HUnaryControlInstruction(value, NULL, NULL), kind_(kind), nil_(nil) { }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002984
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002985 EqualityKind kind() const { return kind_; }
2986 NilValue nil() const { return nil_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002987
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002988 virtual void PrintDataTo(StringStream* stream);
2989
2990 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002991 return Representation::Tagged();
2992 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002993
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002994 DECLARE_CONCRETE_INSTRUCTION(IsNilAndBranch)
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002995
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002996 private:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002997 EqualityKind kind_;
2998 NilValue nil_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002999};
3000
3001
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003002class HIsObjectAndBranch: public HUnaryControlInstruction {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003003 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003004 explicit HIsObjectAndBranch(HValue* value)
3005 : HUnaryControlInstruction(value, NULL, NULL) { }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003006
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003007 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003008 return Representation::Tagged();
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00003009 }
3010
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003011 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch)
3012};
3013
erikcorry0ad885c2011-11-21 13:51:57 +00003014class HIsStringAndBranch: public HUnaryControlInstruction {
3015 public:
3016 explicit HIsStringAndBranch(HValue* value)
3017 : HUnaryControlInstruction(value, NULL, NULL) { }
3018
3019 virtual Representation RequiredInputRepresentation(int index) {
3020 return Representation::Tagged();
3021 }
3022
3023 DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch)
3024};
3025
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003026
3027class HIsSmiAndBranch: public HUnaryControlInstruction {
3028 public:
3029 explicit HIsSmiAndBranch(HValue* value)
3030 : HUnaryControlInstruction(value, NULL, NULL) { }
3031
3032 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
3033
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003034 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003035 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003036 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00003037
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003038 protected:
3039 virtual bool DataEquals(HValue* other) { return true; }
3040};
3041
3042
3043class HIsUndetectableAndBranch: public HUnaryControlInstruction {
3044 public:
3045 explicit HIsUndetectableAndBranch(HValue* value)
3046 : HUnaryControlInstruction(value, NULL, NULL) { }
3047
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003048 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003049 return Representation::Tagged();
3050 }
3051
3052 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
3053};
3054
3055
erikcorry0ad885c2011-11-21 13:51:57 +00003056class HStringCompareAndBranch: public HTemplateControlInstruction<2, 3> {
3057 public:
3058 HStringCompareAndBranch(HValue* context,
3059 HValue* left,
3060 HValue* right,
3061 Token::Value token)
3062 : token_(token) {
3063 ASSERT(Token::IsCompareOp(token));
3064 SetOperandAt(0, context);
3065 SetOperandAt(1, left);
3066 SetOperandAt(2, right);
3067 set_representation(Representation::Tagged());
3068 }
3069
3070 HValue* context() { return OperandAt(0); }
3071 HValue* left() { return OperandAt(1); }
3072 HValue* right() { return OperandAt(2); }
3073 Token::Value token() const { return token_; }
3074
3075 virtual void PrintDataTo(StringStream* stream);
3076
3077 virtual Representation RequiredInputRepresentation(int index) {
3078 return Representation::Tagged();
3079 }
3080
3081 Representation GetInputRepresentation() const {
3082 return Representation::Tagged();
3083 }
3084
3085 DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch)
3086
3087 private:
3088 Token::Value token_;
3089};
3090
3091
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003092class HIsConstructCallAndBranch: public HTemplateControlInstruction<2, 0> {
3093 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003094 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003095 return Representation::None();
3096 }
3097
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003098 DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00003099};
3100
3101
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003102class HHasInstanceTypeAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003103 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003104 HHasInstanceTypeAndBranch(HValue* value, InstanceType type)
3105 : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { }
3106 HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to)
3107 : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003108 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
3109 }
3110
3111 InstanceType from() { return from_; }
3112 InstanceType to() { return to_; }
3113
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003114 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003115
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003116 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003117 return Representation::Tagged();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003118 }
3119
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003120 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
3121
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003122 private:
3123 InstanceType from_;
3124 InstanceType to_; // Inclusive range, not all combinations work.
3125};
3126
3127
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003128class HHasCachedArrayIndexAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003129 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003130 explicit HHasCachedArrayIndexAndBranch(HValue* value)
3131 : HUnaryControlInstruction(value, NULL, NULL) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003132
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003133 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003134 return Representation::Tagged();
3135 }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003136
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003137 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003138};
3139
3140
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00003141class HGetCachedArrayIndex: public HUnaryOperation {
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00003142 public:
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00003143 explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) {
3144 set_representation(Representation::Tagged());
3145 SetFlag(kUseGVN);
3146 }
3147
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003148 virtual Representation RequiredInputRepresentation(int index) {
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00003149 return Representation::Tagged();
3150 }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00003151
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003152 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00003153
3154 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003155 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00003156};
3157
3158
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003159class HClassOfTestAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003160 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003161 HClassOfTestAndBranch(HValue* value, Handle<String> class_name)
3162 : HUnaryControlInstruction(value, NULL, NULL),
3163 class_name_(class_name) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003164
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003165 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch)
3166
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003167 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003168 return Representation::Tagged();
3169 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003170
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003171 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003172
3173 Handle<String> class_name() const { return class_name_; }
3174
3175 private:
3176 Handle<String> class_name_;
3177};
3178
3179
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003180class HTypeofIsAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003181 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003182 HTypeofIsAndBranch(HValue* value, Handle<String> type_literal)
3183 : HUnaryControlInstruction(value, NULL, NULL),
3184 type_literal_(type_literal) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003185
3186 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003187 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003188
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003189 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003190
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003191 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003192 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003193 }
3194
3195 private:
3196 Handle<String> type_literal_;
3197};
3198
3199
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003200class HInstanceOf: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003201 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003202 HInstanceOf(HValue* context, HValue* left, HValue* right)
3203 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003204 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003205 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003206 }
3207
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003208 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003209 return Representation::Tagged();
3210 }
3211
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003212 virtual HType CalculateInferredType();
3213
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003214 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003215
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003216 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003217};
3218
3219
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003220class HInstanceOfKnownGlobal: public HTemplateInstruction<2> {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00003221 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003222 HInstanceOfKnownGlobal(HValue* context,
3223 HValue* left,
3224 Handle<JSFunction> right)
3225 : function_(right) {
3226 SetOperandAt(0, context);
3227 SetOperandAt(1, left);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00003228 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003229 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00003230 }
3231
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003232 HValue* context() { return OperandAt(0); }
3233 HValue* left() { return OperandAt(1); }
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00003234 Handle<JSFunction> function() { return function_; }
3235
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003236 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00003237 return Representation::Tagged();
3238 }
3239
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003240 virtual HType CalculateInferredType();
3241
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003242 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00003243
3244 private:
3245 Handle<JSFunction> function_;
3246};
3247
3248
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003249class HPower: public HTemplateInstruction<2> {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003250 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003251 HPower(HValue* left, HValue* right) {
3252 SetOperandAt(0, left);
3253 SetOperandAt(1, right);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003254 set_representation(Representation::Double());
3255 SetFlag(kUseGVN);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00003256 SetGVNFlag(kChangesNewSpacePromotion);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003257 }
3258
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003259 HValue* left() { return OperandAt(0); }
3260 HValue* right() { return OperandAt(1); }
3261
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003262 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003263 return index == 0
3264 ? Representation::Double()
3265 : Representation::None();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003266 }
3267
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003268 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003269
3270 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003271 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003272};
3273
3274
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003275class HRandom: public HTemplateInstruction<1> {
3276 public:
3277 explicit HRandom(HValue* global_object) {
3278 SetOperandAt(0, global_object);
3279 set_representation(Representation::Double());
3280 }
3281
3282 HValue* global_object() { return OperandAt(0); }
3283
3284 virtual Representation RequiredInputRepresentation(int index) {
3285 return Representation::Tagged();
3286 }
3287
3288 DECLARE_CONCRETE_INSTRUCTION(Random)
3289};
3290
3291
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003292class HAdd: public HArithmeticBinaryOperation {
3293 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003294 HAdd(HValue* context, HValue* left, HValue* right)
3295 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003296 SetFlag(kCanOverflow);
3297 }
3298
3299 // Add is only commutative if two integer values are added and not if two
3300 // tagged values are added (because it might be a String concatenation).
3301 virtual bool IsCommutative() const {
3302 return !representation().IsTagged();
3303 }
3304
3305 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3306
erikcorry0ad885c2011-11-21 13:51:57 +00003307 static HInstruction* NewHAdd(Zone* zone,
3308 HValue* context,
3309 HValue* left,
3310 HValue* right);
3311
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003312 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003313
ulan@chromium.org812308e2012-02-29 15:58:45 +00003314 virtual HValue* Canonicalize();
3315
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003316 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003317
3318 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003319 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003320
ulan@chromium.org812308e2012-02-29 15:58:45 +00003321 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003322};
3323
3324
3325class HSub: public HArithmeticBinaryOperation {
3326 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003327 HSub(HValue* context, HValue* left, HValue* right)
3328 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003329 SetFlag(kCanOverflow);
3330 }
3331
3332 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3333
ulan@chromium.org812308e2012-02-29 15:58:45 +00003334 virtual HValue* Canonicalize();
3335
erikcorry0ad885c2011-11-21 13:51:57 +00003336 static HInstruction* NewHSub(Zone* zone,
3337 HValue* context,
3338 HValue* left,
3339 HValue* right);
3340
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003341 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003342
3343 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003344 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003345
ulan@chromium.org812308e2012-02-29 15:58:45 +00003346 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003347};
3348
3349
3350class HMul: public HArithmeticBinaryOperation {
3351 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003352 HMul(HValue* context, HValue* left, HValue* right)
3353 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003354 SetFlag(kCanOverflow);
3355 }
3356
3357 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3358
3359 // Only commutative if it is certain that not two objects are multiplicated.
3360 virtual bool IsCommutative() const {
3361 return !representation().IsTagged();
3362 }
3363
erikcorry0ad885c2011-11-21 13:51:57 +00003364 static HInstruction* NewHMul(Zone* zone,
3365 HValue* context,
3366 HValue* left,
3367 HValue* right);
3368
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003369 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003370
3371 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003372 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003373
ulan@chromium.org812308e2012-02-29 15:58:45 +00003374 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003375};
3376
3377
3378class HMod: public HArithmeticBinaryOperation {
3379 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003380 HMod(HValue* context, HValue* left, HValue* right)
3381 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003382 SetFlag(kCanBeDivByZero);
3383 }
3384
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003385 bool HasPowerOf2Divisor() {
3386 if (right()->IsConstant() &&
3387 HConstant::cast(right())->HasInteger32Value()) {
3388 int32_t value = HConstant::cast(right())->Integer32Value();
3389 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
3390 }
3391
3392 return false;
3393 }
3394
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003395 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3396
erikcorry0ad885c2011-11-21 13:51:57 +00003397 static HInstruction* NewHMod(Zone* zone,
3398 HValue* context,
3399 HValue* left,
3400 HValue* right);
3401
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003402 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003403
3404 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003405 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003406
ulan@chromium.org812308e2012-02-29 15:58:45 +00003407 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003408};
3409
3410
3411class HDiv: public HArithmeticBinaryOperation {
3412 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003413 HDiv(HValue* context, HValue* left, HValue* right)
3414 : HArithmeticBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003415 SetFlag(kCanBeDivByZero);
3416 SetFlag(kCanOverflow);
3417 }
3418
3419 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3420
erikcorry0ad885c2011-11-21 13:51:57 +00003421 static HInstruction* NewHDiv(Zone* zone,
3422 HValue* context,
3423 HValue* left,
3424 HValue* right);
3425
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003426 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003427
3428 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003429 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003430
ulan@chromium.org812308e2012-02-29 15:58:45 +00003431 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003432};
3433
3434
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003435class HBitwise: public HBitwiseBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003436 public:
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003437 HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right)
3438 : HBitwiseBinaryOperation(context, left, right), op_(op) {
3439 ASSERT(op == Token::BIT_AND ||
3440 op == Token::BIT_OR ||
3441 op == Token::BIT_XOR);
3442 }
3443
3444 Token::Value op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003445
3446 virtual bool IsCommutative() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003447
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003448 virtual HValue* Canonicalize();
3449
erikcorry0ad885c2011-11-21 13:51:57 +00003450 static HInstruction* NewHBitwise(Zone* zone,
3451 Token::Value op,
3452 HValue* context,
3453 HValue* left,
3454 HValue* right);
3455
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00003456 virtual void PrintDataTo(StringStream* stream);
3457
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003458 DECLARE_CONCRETE_INSTRUCTION(Bitwise)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003459
3460 protected:
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003461 virtual bool DataEquals(HValue* other) {
3462 return op() == HBitwise::cast(other)->op();
3463 }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003464
ulan@chromium.org812308e2012-02-29 15:58:45 +00003465 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003466
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003467 private:
3468 Token::Value op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003469};
3470
3471
3472class HShl: public HBitwiseBinaryOperation {
3473 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003474 HShl(HValue* context, HValue* left, HValue* right)
3475 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003476
ulan@chromium.org812308e2012-02-29 15:58:45 +00003477 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003478
erikcorry0ad885c2011-11-21 13:51:57 +00003479 static HInstruction* NewHShl(Zone* zone,
3480 HValue* context,
3481 HValue* left,
3482 HValue* right);
3483
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003484 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003485
3486 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003487 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003488};
3489
3490
3491class HShr: public HBitwiseBinaryOperation {
3492 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003493 HShr(HValue* context, HValue* left, HValue* right)
3494 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003495
ulan@chromium.org812308e2012-02-29 15:58:45 +00003496 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003497
erikcorry0ad885c2011-11-21 13:51:57 +00003498 static HInstruction* NewHShr(Zone* zone,
3499 HValue* context,
3500 HValue* left,
3501 HValue* right);
3502
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003503 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003504
3505 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003506 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003507};
3508
3509
3510class HSar: public HBitwiseBinaryOperation {
3511 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003512 HSar(HValue* context, HValue* left, HValue* right)
3513 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003514
ulan@chromium.org812308e2012-02-29 15:58:45 +00003515 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003516
erikcorry0ad885c2011-11-21 13:51:57 +00003517 static HInstruction* NewHSar(Zone* zone,
3518 HValue* context,
3519 HValue* left,
3520 HValue* right);
3521
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003522 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003523
3524 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003525 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003526};
3527
3528
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003529class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003530 public:
3531 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00003532 SetGVNFlag(kChangesOsrEntries);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003533 }
3534
3535 int ast_id() const { return ast_id_; }
3536
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003537 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003538 return Representation::None();
3539 }
3540
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003541 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003542
3543 private:
3544 int ast_id_;
3545};
3546
3547
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003548class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003549 public:
3550 explicit HParameter(unsigned index) : index_(index) {
3551 set_representation(Representation::Tagged());
3552 }
3553
3554 unsigned index() const { return index_; }
3555
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003556 virtual void PrintDataTo(StringStream* stream);
3557
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003558 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003559 return Representation::None();
3560 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003561
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003562 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003563
3564 private:
3565 unsigned index_;
3566};
3567
3568
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003569class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003570 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003571 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
3572 : HUnaryCall(context, argument_count),
3573 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003574 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003575 }
3576
3577 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003578
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003579 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003580
3581 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
3582 transcendental_type_ = transcendental_type;
3583 }
3584 TranscendentalCache::Type transcendental_type() {
3585 return transcendental_type_;
3586 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003587
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003588 virtual void PrintDataTo(StringStream* stream);
3589
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003590 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003591 return Representation::Tagged();
3592 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003593
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003594 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003595
3596 private:
3597 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003598 TranscendentalCache::Type transcendental_type_;
3599};
3600
3601
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003602class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003603 public:
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003604 HUnknownOSRValue()
3605 : incoming_value_(NULL) {
3606 set_representation(Representation::Tagged());
3607 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003608
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003609 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003610 return Representation::None();
3611 }
3612
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003613 void set_incoming_value(HPhi* value) {
3614 incoming_value_ = value;
3615 }
3616
3617 HPhi* incoming_value() {
3618 return incoming_value_;
3619 }
3620
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003621 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003622
3623 private:
3624 HPhi* incoming_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003625};
3626
3627
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003628class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003629 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003630 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, PropertyDetails details)
3631 : cell_(cell), details_(details) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003632 set_representation(Representation::Tagged());
3633 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00003634 SetGVNFlag(kDependsOnGlobalVars);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003635 }
3636
3637 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003638 bool RequiresHoleCheck();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003639
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003640 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003641
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003642 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003643 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003644 return reinterpret_cast<intptr_t>(*cell_);
3645 }
3646
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003647 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003648 return Representation::None();
3649 }
3650
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003651 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003652
3653 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003654 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003655 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003656 return cell_.is_identical_to(b->cell());
3657 }
3658
3659 private:
3660 Handle<JSGlobalPropertyCell> cell_;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003661 PropertyDetails details_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003662};
3663
3664
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003665class HLoadGlobalGeneric: public HTemplateInstruction<2> {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003666 public:
3667 HLoadGlobalGeneric(HValue* context,
3668 HValue* global_object,
3669 Handle<Object> name,
3670 bool for_typeof)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003671 : name_(name),
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003672 for_typeof_(for_typeof) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003673 SetOperandAt(0, context);
3674 SetOperandAt(1, global_object);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003675 set_representation(Representation::Tagged());
3676 SetAllSideEffects();
3677 }
3678
3679 HValue* context() { return OperandAt(0); }
3680 HValue* global_object() { return OperandAt(1); }
3681 Handle<Object> name() const { return name_; }
3682 bool for_typeof() const { return for_typeof_; }
3683
3684 virtual void PrintDataTo(StringStream* stream);
3685
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003686 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003687 return Representation::Tagged();
3688 }
3689
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003690 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003691
3692 private:
3693 Handle<Object> name_;
3694 bool for_typeof_;
3695};
3696
3697
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003698inline bool StoringValueNeedsWriteBarrier(HValue* value) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003699 return !value->type().IsBoolean()
3700 && !value->type().IsSmi()
3701 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable());
3702}
3703
3704
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00003705inline bool ReceiverObjectNeedsWriteBarrier(HValue* object,
3706 HValue* new_space_dominator) {
3707 return !object->IsAllocateObject() || (object != new_space_dominator);
3708}
3709
3710
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003711class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003712 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003713 HStoreGlobalCell(HValue* value,
3714 Handle<JSGlobalPropertyCell> cell,
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003715 PropertyDetails details)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003716 : HUnaryOperation(value),
3717 cell_(cell),
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003718 details_(details) {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00003719 SetGVNFlag(kChangesGlobalVars);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003720 }
3721
3722 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003723 bool RequiresHoleCheck() {
3724 return !details_.IsDontDelete() || details_.IsReadOnly();
3725 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003726 bool NeedsWriteBarrier() {
3727 return StoringValueNeedsWriteBarrier(value());
3728 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003729
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003730 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003731 return Representation::Tagged();
3732 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003733 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003734
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003735 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003736
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003737 private:
3738 Handle<JSGlobalPropertyCell> cell_;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003739 PropertyDetails details_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003740};
3741
3742
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003743class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3744 public:
3745 HStoreGlobalGeneric(HValue* context,
3746 HValue* global_object,
3747 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003748 HValue* value,
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003749 StrictModeFlag strict_mode_flag)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003750 : name_(name),
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003751 strict_mode_flag_(strict_mode_flag) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003752 SetOperandAt(0, context);
3753 SetOperandAt(1, global_object);
3754 SetOperandAt(2, value);
3755 set_representation(Representation::Tagged());
3756 SetAllSideEffects();
3757 }
3758
3759 HValue* context() { return OperandAt(0); }
3760 HValue* global_object() { return OperandAt(1); }
3761 Handle<Object> name() const { return name_; }
3762 HValue* value() { return OperandAt(2); }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003763 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003764
3765 virtual void PrintDataTo(StringStream* stream);
3766
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003767 virtual Representation RequiredInputRepresentation(int index) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003768 return Representation::Tagged();
3769 }
3770
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003771 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003772
3773 private:
3774 Handle<Object> name_;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003775 StrictModeFlag strict_mode_flag_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003776};
3777
3778
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003779class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003780 public:
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00003781 enum Mode {
3782 // Perform a normal load of the context slot without checking its value.
ricow@chromium.org7ad65222011-12-19 12:13:11 +00003783 kNoCheck,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00003784 // Load and check the value of the context slot. Deoptimize if it's the
3785 // hole value. This is used for checking for loading of uninitialized
3786 // harmony bindings where we deoptimize into full-codegen generated code
3787 // which will subsequently throw a reference error.
ricow@chromium.org7ad65222011-12-19 12:13:11 +00003788 kCheckDeoptimize,
3789 // Load and check the value of the context slot. Return undefined if it's
3790 // the hole value. This is used for non-harmony const assignments
3791 kCheckReturnUndefined
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00003792 };
3793
3794 HLoadContextSlot(HValue* context, Variable* var)
3795 : HUnaryOperation(context), slot_index_(var->index()) {
3796 ASSERT(var->IsContextSlot());
ricow@chromium.org7ad65222011-12-19 12:13:11 +00003797 switch (var->mode()) {
3798 case LET:
3799 case CONST_HARMONY:
3800 mode_ = kCheckDeoptimize;
3801 break;
3802 case CONST:
3803 mode_ = kCheckReturnUndefined;
3804 break;
3805 default:
3806 mode_ = kNoCheck;
3807 }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003808 set_representation(Representation::Tagged());
3809 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00003810 SetGVNFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003811 }
3812
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003813 int slot_index() const { return slot_index_; }
ricow@chromium.org7ad65222011-12-19 12:13:11 +00003814 Mode mode() const { return mode_; }
3815
3816 bool DeoptimizesOnHole() {
3817 return mode_ == kCheckDeoptimize;
3818 }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003819
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00003820 bool RequiresHoleCheck() {
ricow@chromium.org7ad65222011-12-19 12:13:11 +00003821 return mode_ != kNoCheck;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00003822 }
3823
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003824 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003825 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003826 }
3827
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003828 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003829
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003830 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003831
3832 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003833 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003834 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003835 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003836 }
3837
3838 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003839 int slot_index_;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00003840 Mode mode_;
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003841};
3842
3843
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003844class HStoreContextSlot: public HTemplateInstruction<2> {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003845 public:
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00003846 enum Mode {
3847 // Perform a normal store to the context slot without checking its previous
3848 // value.
ricow@chromium.org7ad65222011-12-19 12:13:11 +00003849 kNoCheck,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00003850 // Check the previous value of the context slot and deoptimize if it's the
3851 // hole value. This is used for checking for assignments to uninitialized
3852 // harmony bindings where we deoptimize into full-codegen generated code
3853 // which will subsequently throw a reference error.
ricow@chromium.org7ad65222011-12-19 12:13:11 +00003854 kCheckDeoptimize,
3855 // Check the previous value and ignore assignment if it isn't a hole value
3856 kCheckIgnoreAssignment
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00003857 };
3858
3859 HStoreContextSlot(HValue* context, int slot_index, Mode mode, HValue* value)
3860 : slot_index_(slot_index), mode_(mode) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003861 SetOperandAt(0, context);
3862 SetOperandAt(1, value);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00003863 SetGVNFlag(kChangesContextSlots);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003864 }
3865
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003866 HValue* context() { return OperandAt(0); }
3867 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003868 int slot_index() const { return slot_index_; }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00003869 Mode mode() const { return mode_; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003870
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003871 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003872 return StoringValueNeedsWriteBarrier(value());
3873 }
3874
ricow@chromium.org7ad65222011-12-19 12:13:11 +00003875 bool DeoptimizesOnHole() {
3876 return mode_ == kCheckDeoptimize;
3877 }
3878
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00003879 bool RequiresHoleCheck() {
ricow@chromium.org7ad65222011-12-19 12:13:11 +00003880 return mode_ != kNoCheck;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00003881 }
3882
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003883 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003884 return Representation::Tagged();
3885 }
3886
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003887 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003888
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003889 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003890
3891 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003892 int slot_index_;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00003893 Mode mode_;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003894};
3895
3896
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003897class HLoadNamedField: public HUnaryOperation {
3898 public:
3899 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3900 : HUnaryOperation(object),
3901 is_in_object_(is_in_object),
3902 offset_(offset) {
3903 set_representation(Representation::Tagged());
3904 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00003905 SetGVNFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003906 if (is_in_object) {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00003907 SetGVNFlag(kDependsOnInobjectFields);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003908 } else {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00003909 SetGVNFlag(kDependsOnBackingStoreFields);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003910 }
3911 }
3912
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003913 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003914 bool is_in_object() const { return is_in_object_; }
3915 int offset() const { return offset_; }
3916
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003917 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003918 return Representation::Tagged();
3919 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003920 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003921
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003922 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003923
3924 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003925 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003926 HLoadNamedField* b = HLoadNamedField::cast(other);
3927 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3928 }
3929
3930 private:
3931 bool is_in_object_;
3932 int offset_;
3933};
3934
3935
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003936class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003937 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003938 HLoadNamedFieldPolymorphic(HValue* context,
3939 HValue* object,
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00003940 SmallMapList* types,
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003941 Handle<String> name,
3942 Zone* zone);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003943
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003944 HValue* context() { return OperandAt(0); }
3945 HValue* object() { return OperandAt(1); }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00003946 SmallMapList* types() { return &types_; }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003947 Handle<String> name() { return name_; }
3948 bool need_generic() { return need_generic_; }
3949
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003950 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003951 return Representation::Tagged();
3952 }
3953
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003954 virtual void PrintDataTo(StringStream* stream);
3955
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003956 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003957
3958 static const int kMaxLoadPolymorphism = 4;
3959
3960 protected:
3961 virtual bool DataEquals(HValue* value);
3962
3963 private:
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00003964 SmallMapList types_;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003965 Handle<String> name_;
3966 bool need_generic_;
3967};
3968
3969
3970
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003971class HLoadNamedGeneric: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003972 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003973 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003974 : name_(name) {
3975 SetOperandAt(0, context);
3976 SetOperandAt(1, object);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003977 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003978 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003979 }
3980
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003981 HValue* context() { return OperandAt(0); }
3982 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003983 Handle<Object> name() const { return name_; }
3984
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003985 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003986 return Representation::Tagged();
3987 }
3988
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003989 virtual void PrintDataTo(StringStream* stream);
3990
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003991 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003992
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003993 private:
3994 Handle<Object> name_;
3995};
3996
3997
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003998class HLoadFunctionPrototype: public HUnaryOperation {
3999 public:
4000 explicit HLoadFunctionPrototype(HValue* function)
4001 : HUnaryOperation(function) {
4002 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004003 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004004 SetGVNFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00004005 }
4006
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004007 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00004008
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004009 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00004010 return Representation::Tagged();
4011 }
4012
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004013 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00004014
4015 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004016 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00004017};
4018
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004019class ArrayInstructionInterface {
4020 public:
4021 virtual HValue* GetKey() = 0;
4022 virtual void SetKey(HValue* key) = 0;
4023 virtual void SetIndexOffset(uint32_t index_offset) = 0;
4024 virtual bool IsDehoisted() = 0;
4025 virtual void SetDehoisted(bool is_dehoisted) = 0;
4026 virtual ~ArrayInstructionInterface() { };
4027};
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00004028
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004029class HLoadKeyedFastElement
4030 : public HTemplateInstruction<2>, public ArrayInstructionInterface {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004031 public:
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +00004032 HLoadKeyedFastElement(HValue* obj,
4033 HValue* key,
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004034 ElementsKind elements_kind = FAST_ELEMENTS)
4035 : bit_field_(0) {
4036 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind));
4037 bit_field_ = ElementsKindField::encode(elements_kind);
4038 if (IsFastSmiElementsKind(elements_kind) &&
4039 IsFastPackedElementsKind(elements_kind)) {
4040 set_type(HType::Smi());
4041 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004042 SetOperandAt(0, obj);
4043 SetOperandAt(1, key);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004044 set_representation(Representation::Tagged());
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004045 SetGVNFlag(kDependsOnArrayElements);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004046 SetFlag(kUseGVN);
4047 }
4048
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004049 HValue* object() { return OperandAt(0); }
4050 HValue* key() { return OperandAt(1); }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004051 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); }
4052 void SetIndexOffset(uint32_t index_offset) {
4053 bit_field_ = IndexOffsetField::update(bit_field_, index_offset);
4054 }
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004055 HValue* GetKey() { return key(); }
4056 void SetKey(HValue* key) { SetOperandAt(1, key); }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004057 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); }
4058 void SetDehoisted(bool is_dehoisted) {
4059 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted);
4060 }
4061 ElementsKind elements_kind() const {
4062 return ElementsKindField::decode(bit_field_);
4063 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004064
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004065 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004066 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004067 return index == 0
4068 ? Representation::Tagged()
4069 : Representation::Integer32();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004070 }
4071
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004072 virtual void PrintDataTo(StringStream* stream);
4073
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004074 bool RequiresHoleCheck();
karlklose@chromium.org83a47282011-05-11 11:54:09 +00004075
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004076 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00004077
4078 protected:
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +00004079 virtual bool DataEquals(HValue* other) {
4080 if (!other->IsLoadKeyedFastElement()) return false;
4081 HLoadKeyedFastElement* other_load = HLoadKeyedFastElement::cast(other);
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004082 if (IsDehoisted() && index_offset() != other_load->index_offset())
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004083 return false;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004084 return elements_kind() == other_load->elements_kind();
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +00004085 }
4086
4087 private:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004088 class ElementsKindField: public BitField<ElementsKind, 0, 4> {};
4089 class IndexOffsetField: public BitField<uint32_t, 4, 27> {};
4090 class IsDehoistedField: public BitField<bool, 31, 1> {};
4091 uint32_t bit_field_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004092};
4093
4094
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004095enum HoleCheckMode { PERFORM_HOLE_CHECK, OMIT_HOLE_CHECK };
4096
4097
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004098class HLoadKeyedFastDoubleElement
4099 : public HTemplateInstruction<2>, public ArrayInstructionInterface {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004100 public:
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004101 HLoadKeyedFastDoubleElement(
4102 HValue* elements,
4103 HValue* key,
4104 HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004105 : index_offset_(0),
4106 is_dehoisted_(false),
4107 hole_check_mode_(hole_check_mode) {
4108 SetOperandAt(0, elements);
4109 SetOperandAt(1, key);
4110 set_representation(Representation::Double());
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004111 SetGVNFlag(kDependsOnDoubleArrayElements);
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004112 SetFlag(kUseGVN);
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004113 }
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004114
4115 HValue* elements() { return OperandAt(0); }
4116 HValue* key() { return OperandAt(1); }
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004117 uint32_t index_offset() { return index_offset_; }
4118 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4119 HValue* GetKey() { return key(); }
4120 void SetKey(HValue* key) { SetOperandAt(1, key); }
4121 bool IsDehoisted() { return is_dehoisted_; }
4122 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004123
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004124 virtual Representation RequiredInputRepresentation(int index) {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004125 // The key is supposed to be Integer32.
4126 return index == 0
4127 ? Representation::Tagged()
4128 : Representation::Integer32();
4129 }
4130
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004131 bool RequiresHoleCheck() {
4132 return hole_check_mode_ == PERFORM_HOLE_CHECK;
4133 }
4134
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004135 virtual void PrintDataTo(StringStream* stream);
4136
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004137 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement)
4138
4139 protected:
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004140 virtual bool DataEquals(HValue* other) {
4141 if (!other->IsLoadKeyedFastDoubleElement()) return false;
4142 HLoadKeyedFastDoubleElement* other_load =
4143 HLoadKeyedFastDoubleElement::cast(other);
4144 return hole_check_mode_ == other_load->hole_check_mode_;
4145 }
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004146
4147 private:
4148 uint32_t index_offset_;
4149 bool is_dehoisted_;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004150 HoleCheckMode hole_check_mode_;
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004151};
4152
4153
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004154class HLoadKeyedSpecializedArrayElement
4155 : public HTemplateInstruction<2>, public ArrayInstructionInterface {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004156 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004157 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
4158 HValue* key,
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004159 ElementsKind elements_kind)
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004160 : elements_kind_(elements_kind),
4161 index_offset_(0),
4162 is_dehoisted_(false) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004163 SetOperandAt(0, external_elements);
4164 SetOperandAt(1, key);
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004165 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
4166 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004167 set_representation(Representation::Double());
4168 } else {
4169 set_representation(Representation::Integer32());
4170 }
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004171 SetGVNFlag(kDependsOnSpecializedArrayElements);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004172 // Native code could change the specialized array.
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004173 SetGVNFlag(kDependsOnCalls);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004174 SetFlag(kUseGVN);
4175 }
4176
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004177 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004178
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004179 virtual Representation RequiredInputRepresentation(int index) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004180 // The key is supposed to be Integer32, but the base pointer
4181 // for the element load is a naked pointer.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004182 return index == 0
4183 ? Representation::External()
4184 : Representation::Integer32();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004185 }
4186
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004187 HValue* external_pointer() { return OperandAt(0); }
4188 HValue* key() { return OperandAt(1); }
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004189 ElementsKind elements_kind() const { return elements_kind_; }
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004190 uint32_t index_offset() { return index_offset_; }
4191 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4192 HValue* GetKey() { return key(); }
4193 void SetKey(HValue* key) { SetOperandAt(1, key); }
4194 bool IsDehoisted() { return is_dehoisted_; }
4195 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004196
ulan@chromium.org812308e2012-02-29 15:58:45 +00004197 virtual Range* InferRange(Zone* zone);
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004198
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004199 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004200
4201 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004202 virtual bool DataEquals(HValue* other) {
4203 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
4204 HLoadKeyedSpecializedArrayElement* cast_other =
4205 HLoadKeyedSpecializedArrayElement::cast(other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004206 return elements_kind_ == cast_other->elements_kind();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004207 }
4208
4209 private:
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004210 ElementsKind elements_kind_;
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004211 uint32_t index_offset_;
4212 bool is_dehoisted_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004213};
4214
4215
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004216class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004217 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00004218 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004219 set_representation(Representation::Tagged());
4220 SetOperandAt(0, obj);
4221 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004222 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00004223 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004224 }
4225
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004226 HValue* object() { return OperandAt(0); }
4227 HValue* key() { return OperandAt(1); }
4228 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004229
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004230 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004231
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004232 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004233 return Representation::Tagged();
4234 }
4235
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +00004236 virtual HValue* Canonicalize();
4237
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004238 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004239};
4240
4241
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004242class HStoreNamedField: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004243 public:
4244 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004245 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004246 HValue* val,
4247 bool in_object,
4248 int offset)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004249 : name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004250 is_in_object_(in_object),
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00004251 offset_(offset),
4252 new_space_dominator_(NULL) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004253 SetOperandAt(0, obj);
4254 SetOperandAt(1, val);
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00004255 SetFlag(kTrackSideEffectDominators);
4256 SetGVNFlag(kDependsOnNewSpacePromotion);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004257 if (is_in_object_) {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004258 SetGVNFlag(kChangesInobjectFields);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004259 } else {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004260 SetGVNFlag(kChangesBackingStoreFields);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004261 }
4262 }
4263
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004264 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004265
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004266 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004267 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004268 }
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00004269 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) {
4270 ASSERT(side_effect == kChangesNewSpacePromotion);
4271 new_space_dominator_ = dominator;
4272 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004273 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004274
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004275 HValue* object() { return OperandAt(0); }
4276 HValue* value() { return OperandAt(1); }
4277
4278 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004279 bool is_in_object() const { return is_in_object_; }
4280 int offset() const { return offset_; }
4281 Handle<Map> transition() const { return transition_; }
4282 void set_transition(Handle<Map> map) { transition_ = map; }
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00004283 HValue* new_space_dominator() const { return new_space_dominator_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004284
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004285 bool NeedsWriteBarrier() {
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00004286 return StoringValueNeedsWriteBarrier(value()) &&
4287 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004288 }
4289
verwaest@chromium.org37141392012-05-31 13:27:02 +00004290 bool NeedsWriteBarrierForMap() {
4291 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
4292 }
4293
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004294 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004295 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004296 bool is_in_object_;
4297 int offset_;
4298 Handle<Map> transition_;
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00004299 HValue* new_space_dominator_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004300};
4301
4302
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004303class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004304 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004305 HStoreNamedGeneric(HValue* context,
4306 HValue* object,
4307 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004308 HValue* value,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004309 StrictModeFlag strict_mode_flag)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004310 : name_(name),
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004311 strict_mode_flag_(strict_mode_flag) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004312 SetOperandAt(0, object);
4313 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004314 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00004315 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004316 }
4317
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004318 HValue* object() { return OperandAt(0); }
4319 HValue* value() { return OperandAt(1); }
4320 HValue* context() { return OperandAt(2); }
4321 Handle<String> name() { return name_; }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004322 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004323
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004324 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004325
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004326 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004327 return Representation::Tagged();
4328 }
4329
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004330 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004331
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004332 private:
4333 Handle<String> name_;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004334 StrictModeFlag strict_mode_flag_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004335};
4336
4337
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004338class HStoreKeyedFastElement
4339 : public HTemplateInstruction<3>, public ArrayInstructionInterface {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004340 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004341 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val,
4342 ElementsKind elements_kind = FAST_ELEMENTS)
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004343 : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004344 SetOperandAt(0, obj);
4345 SetOperandAt(1, key);
4346 SetOperandAt(2, val);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004347 SetGVNFlag(kChangesArrayElements);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004348 }
4349
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004350 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004351 // The key is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004352 return index == 1
4353 ? Representation::Integer32()
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004354 : Representation::Tagged();
4355 }
4356
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004357 HValue* object() { return OperandAt(0); }
4358 HValue* key() { return OperandAt(1); }
4359 HValue* value() { return OperandAt(2); }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004360 bool value_is_smi() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004361 return IsFastSmiElementsKind(elements_kind_);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004362 }
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004363 uint32_t index_offset() { return index_offset_; }
4364 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4365 HValue* GetKey() { return key(); }
4366 void SetKey(HValue* key) { SetOperandAt(1, key); }
4367 bool IsDehoisted() { return is_dehoisted_; }
4368 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004369
4370 bool NeedsWriteBarrier() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004371 if (value_is_smi()) {
4372 return false;
4373 } else {
4374 return StoringValueNeedsWriteBarrier(value());
4375 }
4376 }
4377
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004378 virtual void PrintDataTo(StringStream* stream);
4379
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004380 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004381
4382 private:
4383 ElementsKind elements_kind_;
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004384 uint32_t index_offset_;
4385 bool is_dehoisted_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004386};
4387
4388
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004389class HStoreKeyedFastDoubleElement
4390 : public HTemplateInstruction<3>, public ArrayInstructionInterface {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004391 public:
4392 HStoreKeyedFastDoubleElement(HValue* elements,
4393 HValue* key,
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004394 HValue* val)
4395 : index_offset_(0), is_dehoisted_(false) {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004396 SetOperandAt(0, elements);
4397 SetOperandAt(1, key);
4398 SetOperandAt(2, val);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004399 SetGVNFlag(kChangesDoubleArrayElements);
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004400 }
4401
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004402 virtual Representation RequiredInputRepresentation(int index) {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004403 if (index == 1) {
4404 return Representation::Integer32();
4405 } else if (index == 2) {
4406 return Representation::Double();
4407 } else {
4408 return Representation::Tagged();
4409 }
4410 }
4411
4412 HValue* elements() { return OperandAt(0); }
4413 HValue* key() { return OperandAt(1); }
4414 HValue* value() { return OperandAt(2); }
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004415 uint32_t index_offset() { return index_offset_; }
4416 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4417 HValue* GetKey() { return key(); }
4418 void SetKey(HValue* key) { SetOperandAt(1, key); }
4419 bool IsDehoisted() { return is_dehoisted_; }
4420 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004421
4422 bool NeedsWriteBarrier() {
4423 return StoringValueNeedsWriteBarrier(value());
4424 }
4425
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00004426 bool NeedsCanonicalization();
4427
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004428 virtual void PrintDataTo(StringStream* stream);
4429
4430 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement)
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004431
4432 private:
4433 uint32_t index_offset_;
4434 bool is_dehoisted_;
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004435};
4436
4437
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004438class HStoreKeyedSpecializedArrayElement
4439 : public HTemplateInstruction<3>, public ArrayInstructionInterface {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004440 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004441 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
4442 HValue* key,
4443 HValue* val,
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004444 ElementsKind elements_kind)
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004445 : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004446 SetGVNFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004447 SetOperandAt(0, external_elements);
4448 SetOperandAt(1, key);
4449 SetOperandAt(2, val);
4450 }
4451
4452 virtual void PrintDataTo(StringStream* stream);
4453
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004454 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004455 if (index == 0) {
4456 return Representation::External();
4457 } else {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004458 bool float_or_double_elements =
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004459 elements_kind() == EXTERNAL_FLOAT_ELEMENTS ||
4460 elements_kind() == EXTERNAL_DOUBLE_ELEMENTS;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004461 if (index == 2 && float_or_double_elements) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004462 return Representation::Double();
4463 } else {
4464 return Representation::Integer32();
4465 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004466 }
4467 }
4468
4469 HValue* external_pointer() { return OperandAt(0); }
4470 HValue* key() { return OperandAt(1); }
4471 HValue* value() { return OperandAt(2); }
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004472 ElementsKind elements_kind() const { return elements_kind_; }
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004473 uint32_t index_offset() { return index_offset_; }
4474 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4475 HValue* GetKey() { return key(); }
4476 void SetKey(HValue* key) { SetOperandAt(1, key); }
4477 bool IsDehoisted() { return is_dehoisted_; }
4478 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004479
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004480 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
4481
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004482 private:
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004483 ElementsKind elements_kind_;
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004484 uint32_t index_offset_;
4485 bool is_dehoisted_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004486};
4487
4488
4489class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004490 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004491 HStoreKeyedGeneric(HValue* context,
4492 HValue* object,
4493 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004494 HValue* value,
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004495 StrictModeFlag strict_mode_flag)
4496 : strict_mode_flag_(strict_mode_flag) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004497 SetOperandAt(0, object);
4498 SetOperandAt(1, key);
4499 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004500 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00004501 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004502 }
4503
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004504 HValue* object() { return OperandAt(0); }
4505 HValue* key() { return OperandAt(1); }
4506 HValue* value() { return OperandAt(2); }
4507 HValue* context() { return OperandAt(3); }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004508 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004509
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004510 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004511 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004512 }
4513
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004514 virtual void PrintDataTo(StringStream* stream);
4515
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004516 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004517
4518 private:
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004519 StrictModeFlag strict_mode_flag_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004520};
4521
4522
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004523class HTransitionElementsKind: public HTemplateInstruction<1> {
4524 public:
4525 HTransitionElementsKind(HValue* object,
4526 Handle<Map> original_map,
4527 Handle<Map> transitioned_map)
4528 : original_map_(original_map),
4529 transitioned_map_(transitioned_map) {
4530 SetOperandAt(0, object);
4531 SetFlag(kUseGVN);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004532 // Don't set GVN DependOn flags here. That would defeat GVN's detection of
4533 // congruent HTransitionElementsKind instructions. Instruction hoisting
4534 // handles HTransitionElementsKind instruction specially, explicitly adding
4535 // DependsOn flags during its dependency calculations.
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004536 SetGVNFlag(kChangesElementsKind);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004537 if (original_map->has_fast_double_elements()) {
4538 SetGVNFlag(kChangesElementsPointer);
4539 SetGVNFlag(kChangesNewSpacePromotion);
4540 }
4541 if (transitioned_map->has_fast_double_elements()) {
4542 SetGVNFlag(kChangesElementsPointer);
4543 SetGVNFlag(kChangesNewSpacePromotion);
4544 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004545 set_representation(Representation::Tagged());
4546 }
4547
4548 virtual Representation RequiredInputRepresentation(int index) {
4549 return Representation::Tagged();
4550 }
4551
4552 HValue* object() { return OperandAt(0); }
4553 Handle<Map> original_map() { return original_map_; }
4554 Handle<Map> transitioned_map() { return transitioned_map_; }
4555
4556 virtual void PrintDataTo(StringStream* stream);
4557
4558 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind)
4559
4560 protected:
4561 virtual bool DataEquals(HValue* other) {
4562 HTransitionElementsKind* instr = HTransitionElementsKind::cast(other);
4563 return original_map_.is_identical_to(instr->original_map()) &&
4564 transitioned_map_.is_identical_to(instr->transitioned_map());
4565 }
4566
4567 private:
4568 Handle<Map> original_map_;
4569 Handle<Map> transitioned_map_;
4570};
4571
4572
danno@chromium.org160a7b02011-04-18 15:51:38 +00004573class HStringAdd: public HBinaryOperation {
4574 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004575 HStringAdd(HValue* context, HValue* left, HValue* right)
4576 : HBinaryOperation(context, left, right) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00004577 set_representation(Representation::Tagged());
4578 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004579 SetGVNFlag(kDependsOnMaps);
danno@chromium.org160a7b02011-04-18 15:51:38 +00004580 }
4581
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004582 virtual Representation RequiredInputRepresentation(int index) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00004583 return Representation::Tagged();
4584 }
4585
4586 virtual HType CalculateInferredType() {
4587 return HType::String();
4588 }
4589
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004590 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00004591
4592 protected:
4593 virtual bool DataEquals(HValue* other) { return true; }
4594};
4595
4596
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004597class HStringCharCodeAt: public HTemplateInstruction<3> {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004598 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004599 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
4600 SetOperandAt(0, context);
4601 SetOperandAt(1, string);
4602 SetOperandAt(2, index);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004603 set_representation(Representation::Integer32());
4604 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004605 SetGVNFlag(kDependsOnMaps);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00004606 SetGVNFlag(kChangesNewSpacePromotion);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004607 }
4608
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004609 virtual Representation RequiredInputRepresentation(int index) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004610 // The index is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004611 return index == 2
4612 ? Representation::Integer32()
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004613 : Representation::Tagged();
4614 }
4615
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004616 HValue* context() { return OperandAt(0); }
4617 HValue* string() { return OperandAt(1); }
4618 HValue* index() { return OperandAt(2); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004619
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004620 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004621
4622 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004623 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004624
ulan@chromium.org812308e2012-02-29 15:58:45 +00004625 virtual Range* InferRange(Zone* zone) {
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004626 return new(zone) Range(0, String::kMaxUtf16CodeUnit);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004627 }
4628};
4629
4630
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004631class HStringCharFromCode: public HTemplateInstruction<2> {
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004632 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004633 HStringCharFromCode(HValue* context, HValue* char_code) {
4634 SetOperandAt(0, context);
4635 SetOperandAt(1, char_code);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004636 set_representation(Representation::Tagged());
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004637 SetFlag(kUseGVN);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00004638 SetGVNFlag(kChangesNewSpacePromotion);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004639 }
4640
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004641 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004642 return index == 0
4643 ? Representation::Tagged()
4644 : Representation::Integer32();
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004645 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004646 virtual HType CalculateInferredType();
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004647
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004648 HValue* context() { return OperandAt(0); }
4649 HValue* value() { return OperandAt(1); }
4650
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004651 virtual bool DataEquals(HValue* other) { return true; }
4652
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004653 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004654};
4655
4656
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004657class HStringLength: public HUnaryOperation {
4658 public:
4659 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
4660 set_representation(Representation::Tagged());
4661 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004662 SetGVNFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004663 }
4664
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004665 virtual Representation RequiredInputRepresentation(int index) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004666 return Representation::Tagged();
4667 }
4668
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004669 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004670 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
4671 return HType::Smi();
4672 }
4673
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004674 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004675
4676 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004677 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004678
ulan@chromium.org812308e2012-02-29 15:58:45 +00004679 virtual Range* InferRange(Zone* zone) {
4680 return new(zone) Range(0, String::kMaxLength);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00004681 }
4682};
4683
4684
ulan@chromium.org967e2702012-02-28 09:49:15 +00004685class HAllocateObject: public HTemplateInstruction<1> {
4686 public:
4687 HAllocateObject(HValue* context, Handle<JSFunction> constructor)
4688 : constructor_(constructor) {
4689 SetOperandAt(0, context);
4690 set_representation(Representation::Tagged());
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00004691 SetGVNFlag(kChangesNewSpacePromotion);
ulan@chromium.org967e2702012-02-28 09:49:15 +00004692 }
4693
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00004694 // Maximum instance size for which allocations will be inlined.
4695 static const int kMaxSize = 64 * kPointerSize;
4696
ulan@chromium.org967e2702012-02-28 09:49:15 +00004697 HValue* context() { return OperandAt(0); }
4698 Handle<JSFunction> constructor() { return constructor_; }
4699
4700 virtual Representation RequiredInputRepresentation(int index) {
4701 return Representation::Tagged();
4702 }
4703 virtual HType CalculateInferredType();
4704
4705 DECLARE_CONCRETE_INSTRUCTION(AllocateObject)
4706
4707 private:
4708 Handle<JSFunction> constructor_;
4709};
4710
4711
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004712template <int V>
4713class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004714 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004715 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004716 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004717 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004718 }
4719
4720 int literal_index() const { return literal_index_; }
4721 int depth() const { return depth_; }
4722
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004723 private:
4724 int literal_index_;
4725 int depth_;
4726};
4727
4728
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004729class HFastLiteral: public HMaterializedLiteral<1> {
4730 public:
4731 HFastLiteral(HValue* context,
4732 Handle<JSObject> boilerplate,
4733 int total_size,
4734 int literal_index,
4735 int depth)
4736 : HMaterializedLiteral<1>(literal_index, depth),
4737 boilerplate_(boilerplate),
4738 total_size_(total_size) {
4739 SetOperandAt(0, context);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00004740 SetGVNFlag(kChangesNewSpacePromotion);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004741 }
4742
4743 // Maximum depth and total number of elements and properties for literal
4744 // graphs to be considered for fast deep-copying.
4745 static const int kMaxLiteralDepth = 3;
4746 static const int kMaxLiteralProperties = 8;
4747
4748 HValue* context() { return OperandAt(0); }
4749 Handle<JSObject> boilerplate() const { return boilerplate_; }
4750 int total_size() const { return total_size_; }
4751
4752 virtual Representation RequiredInputRepresentation(int index) {
4753 return Representation::Tagged();
4754 }
4755 virtual HType CalculateInferredType();
4756
4757 DECLARE_CONCRETE_INSTRUCTION(FastLiteral)
4758
4759 private:
4760 Handle<JSObject> boilerplate_;
4761 int total_size_;
4762};
4763
4764
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004765class HArrayLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004766 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004767 HArrayLiteral(HValue* context,
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004768 Handle<HeapObject> boilerplate_object,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004769 int length,
4770 int literal_index,
4771 int depth)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004772 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004773 length_(length),
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004774 boilerplate_object_(boilerplate_object) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004775 SetOperandAt(0, context);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00004776 SetGVNFlag(kChangesNewSpacePromotion);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004777 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004778
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004779 HValue* context() { return OperandAt(0); }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004780 ElementsKind boilerplate_elements_kind() const {
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004781 if (!boilerplate_object_->IsJSObject()) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004782 return TERMINAL_FAST_ELEMENTS_KIND;
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004783 }
4784 return Handle<JSObject>::cast(boilerplate_object_)->GetElementsKind();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004785 }
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004786 Handle<HeapObject> boilerplate_object() const { return boilerplate_object_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004787 int length() const { return length_; }
4788
4789 bool IsCopyOnWrite() const;
4790
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004791 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004792 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004793 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004794 virtual HType CalculateInferredType();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004795
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004796 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004797
4798 private:
4799 int length_;
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004800 Handle<HeapObject> boilerplate_object_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004801};
4802
4803
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004804class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004805 public:
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004806 HObjectLiteral(HValue* context,
4807 Handle<FixedArray> constant_properties,
4808 bool fast_elements,
4809 int literal_index,
4810 int depth,
4811 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004812 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004813 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004814 fast_elements_(fast_elements),
4815 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004816 SetOperandAt(0, context);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00004817 SetGVNFlag(kChangesNewSpacePromotion);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004818 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004819
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004820 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004821 Handle<FixedArray> constant_properties() const {
4822 return constant_properties_;
4823 }
4824 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004825 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004826
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004827 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004828 return Representation::Tagged();
4829 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004830 virtual HType CalculateInferredType();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004831
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004832 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004833
4834 private:
4835 Handle<FixedArray> constant_properties_;
4836 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004837 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004838};
4839
4840
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004841class HRegExpLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004842 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004843 HRegExpLiteral(HValue* context,
yangguo@chromium.org9c741c82012-06-28 15:04:22 +00004844 Handle<FixedArray> literals,
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004845 Handle<String> pattern,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004846 Handle<String> flags,
4847 int literal_index)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004848 : HMaterializedLiteral<1>(literal_index, 0),
yangguo@chromium.org9c741c82012-06-28 15:04:22 +00004849 literals_(literals),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004850 pattern_(pattern),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004851 flags_(flags) {
4852 SetOperandAt(0, context);
ricow@chromium.org27bf2882011-11-17 08:34:43 +00004853 SetAllSideEffects();
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004854 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004855
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004856 HValue* context() { return OperandAt(0); }
yangguo@chromium.org9c741c82012-06-28 15:04:22 +00004857 Handle<FixedArray> literals() { return literals_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004858 Handle<String> pattern() { return pattern_; }
4859 Handle<String> flags() { return flags_; }
4860
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004861 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004862 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004863 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004864 virtual HType CalculateInferredType();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004865
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004866 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004867
4868 private:
yangguo@chromium.org9c741c82012-06-28 15:04:22 +00004869 Handle<FixedArray> literals_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004870 Handle<String> pattern_;
4871 Handle<String> flags_;
4872};
4873
4874
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004875class HFunctionLiteral: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004876 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004877 HFunctionLiteral(HValue* context,
4878 Handle<SharedFunctionInfo> shared,
4879 bool pretenure)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004880 : shared_info_(shared), pretenure_(pretenure) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004881 SetOperandAt(0, context);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004882 set_representation(Representation::Tagged());
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00004883 SetGVNFlag(kChangesNewSpacePromotion);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004884 }
4885
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004886 HValue* context() { return OperandAt(0); }
4887
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004888 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004889 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004890 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004891 virtual HType CalculateInferredType();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004892
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004893 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004894
4895 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
4896 bool pretenure() const { return pretenure_; }
4897
4898 private:
4899 Handle<SharedFunctionInfo> shared_info_;
4900 bool pretenure_;
4901};
4902
4903
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004904class HTypeof: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004905 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004906 explicit HTypeof(HValue* context, HValue* value) {
4907 SetOperandAt(0, context);
4908 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004909 set_representation(Representation::Tagged());
4910 }
4911
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004912 HValue* context() { return OperandAt(0); }
4913 HValue* value() { return OperandAt(1); }
4914
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004915 virtual HValue* Canonicalize();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004916 virtual void PrintDataTo(StringStream* stream);
4917
4918 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004919 return Representation::Tagged();
4920 }
4921
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004922 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004923};
4924
4925
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004926class HToFastProperties: public HUnaryOperation {
4927 public:
4928 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
4929 // This instruction is not marked as having side effects, but
4930 // changes the map of the input operand. Use it only when creating
4931 // object literals.
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004932 ASSERT(value->IsObjectLiteral() || value->IsFastLiteral());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004933 set_representation(Representation::Tagged());
4934 }
4935
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004936 virtual Representation RequiredInputRepresentation(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004937 return Representation::Tagged();
4938 }
4939
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004940 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004941};
4942
4943
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004944class HValueOf: public HUnaryOperation {
4945 public:
4946 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
4947 set_representation(Representation::Tagged());
4948 }
4949
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004950 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004951 return Representation::Tagged();
4952 }
4953
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004954 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004955};
4956
4957
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004958class HDateField: public HUnaryOperation {
4959 public:
4960 HDateField(HValue* date, Smi* index)
4961 : HUnaryOperation(date), index_(index) {
4962 set_representation(Representation::Tagged());
4963 }
4964
4965 Smi* index() const { return index_; }
4966
4967 virtual Representation RequiredInputRepresentation(int index) {
4968 return Representation::Tagged();
4969 }
4970
4971 DECLARE_CONCRETE_INSTRUCTION(DateField)
4972
4973 private:
4974 Smi* index_;
4975};
4976
4977
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004978class HDeleteProperty: public HBinaryOperation {
4979 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004980 HDeleteProperty(HValue* context, HValue* obj, HValue* key)
4981 : HBinaryOperation(context, obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004982 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004983 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004984 }
4985
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004986 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004987 return Representation::Tagged();
4988 }
4989
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004990 virtual HType CalculateInferredType();
4991
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004992 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004993
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004994 HValue* object() { return left(); }
4995 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004996};
4997
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004998
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004999class HIn: public HTemplateInstruction<3> {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00005000 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005001 HIn(HValue* context, HValue* key, HValue* object) {
5002 SetOperandAt(0, context);
5003 SetOperandAt(1, key);
5004 SetOperandAt(2, object);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00005005 set_representation(Representation::Tagged());
5006 SetAllSideEffects();
5007 }
5008
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005009 HValue* context() { return OperandAt(0); }
5010 HValue* key() { return OperandAt(1); }
5011 HValue* object() { return OperandAt(2); }
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00005012
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005013 virtual Representation RequiredInputRepresentation(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00005014 return Representation::Tagged();
5015 }
5016
5017 virtual HType CalculateInferredType() {
5018 return HType::Boolean();
5019 }
5020
5021 virtual void PrintDataTo(StringStream* stream);
5022
5023 DECLARE_CONCRETE_INSTRUCTION(In)
5024};
5025
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +00005026
5027class HCheckMapValue: public HTemplateInstruction<2> {
5028 public:
5029 HCheckMapValue(HValue* value,
5030 HValue* map) {
5031 SetOperandAt(0, value);
5032 SetOperandAt(1, map);
5033 set_representation(Representation::Tagged());
5034 SetFlag(kUseGVN);
5035 SetGVNFlag(kDependsOnMaps);
5036 SetGVNFlag(kDependsOnElementsKind);
5037 }
5038
5039 virtual Representation RequiredInputRepresentation(int index) {
5040 return Representation::Tagged();
5041 }
5042
5043 virtual void PrintDataTo(StringStream* stream);
5044
5045 virtual HType CalculateInferredType() {
5046 return HType::Tagged();
5047 }
5048
5049 HValue* value() { return OperandAt(0); }
5050 HValue* map() { return OperandAt(1); }
5051
5052 DECLARE_CONCRETE_INSTRUCTION(CheckMapValue)
5053
5054 protected:
5055 virtual bool DataEquals(HValue* other) {
5056 return true;
5057 }
5058};
5059
5060
5061class HForInPrepareMap : public HTemplateInstruction<2> {
5062 public:
5063 HForInPrepareMap(HValue* context,
5064 HValue* object) {
5065 SetOperandAt(0, context);
5066 SetOperandAt(1, object);
5067 set_representation(Representation::Tagged());
5068 SetAllSideEffects();
5069 }
5070
5071 virtual Representation RequiredInputRepresentation(int index) {
5072 return Representation::Tagged();
5073 }
5074
5075 HValue* context() { return OperandAt(0); }
5076 HValue* enumerable() { return OperandAt(1); }
5077
5078 virtual void PrintDataTo(StringStream* stream);
5079
5080 virtual HType CalculateInferredType() {
5081 return HType::Tagged();
5082 }
5083
5084 DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap);
5085};
5086
5087
5088class HForInCacheArray : public HTemplateInstruction<2> {
5089 public:
5090 HForInCacheArray(HValue* enumerable,
5091 HValue* keys,
5092 int idx) : idx_(idx) {
5093 SetOperandAt(0, enumerable);
5094 SetOperandAt(1, keys);
5095 set_representation(Representation::Tagged());
5096 }
5097
5098 virtual Representation RequiredInputRepresentation(int index) {
5099 return Representation::Tagged();
5100 }
5101
5102 HValue* enumerable() { return OperandAt(0); }
5103 HValue* map() { return OperandAt(1); }
5104 int idx() { return idx_; }
5105
5106 HForInCacheArray* index_cache() {
5107 return index_cache_;
5108 }
5109
5110 void set_index_cache(HForInCacheArray* index_cache) {
5111 index_cache_ = index_cache;
5112 }
5113
5114 virtual void PrintDataTo(StringStream* stream);
5115
5116 virtual HType CalculateInferredType() {
5117 return HType::Tagged();
5118 }
5119
5120 DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray);
5121
5122 private:
5123 int idx_;
5124 HForInCacheArray* index_cache_;
5125};
5126
5127
5128class HLoadFieldByIndex : public HTemplateInstruction<2> {
5129 public:
5130 HLoadFieldByIndex(HValue* object,
5131 HValue* index) {
5132 SetOperandAt(0, object);
5133 SetOperandAt(1, index);
5134 set_representation(Representation::Tagged());
5135 }
5136
5137 virtual Representation RequiredInputRepresentation(int index) {
5138 return Representation::Tagged();
5139 }
5140
5141 HValue* object() { return OperandAt(0); }
5142 HValue* index() { return OperandAt(1); }
5143
5144 virtual void PrintDataTo(StringStream* stream);
5145
5146 virtual HType CalculateInferredType() {
5147 return HType::Tagged();
5148 }
5149
5150 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex);
5151};
5152
5153
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005154#undef DECLARE_INSTRUCTION
5155#undef DECLARE_CONCRETE_INSTRUCTION
5156
5157} } // namespace v8::internal
5158
5159#endif // V8_HYDROGEN_INSTRUCTIONS_H_