blob: 15e3e1e515466d86dfc7edccbfa1fd1df5f6113e [file] [log] [blame]
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001// Copyright 2011 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"
38#include "zone.h"
39
40namespace v8 {
41namespace internal {
42
43// Forward declarations.
44class HBasicBlock;
45class HEnvironment;
46class HInstruction;
47class HLoopInformation;
48class HValue;
49class LInstruction;
50class LChunkBuilder;
51
52
ricow@chromium.orgdcebac02011-04-20 09:44:50 +000053#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000054 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000055 V(ControlInstruction) \
56 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000057
58
59#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +000060 V(AbnormalExit) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000061 V(AccessArgumentsAt) \
62 V(Add) \
63 V(ApplyArguments) \
64 V(ArgumentsElements) \
65 V(ArgumentsLength) \
66 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000067 V(ArrayLiteral) \
68 V(BitAnd) \
69 V(BitNot) \
70 V(BitOr) \
71 V(BitXor) \
72 V(BlockEntry) \
73 V(BoundsCheck) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000074 V(CallConstantFunction) \
75 V(CallFunction) \
76 V(CallGlobal) \
77 V(CallKeyed) \
78 V(CallKnownGlobal) \
79 V(CallNamed) \
80 V(CallNew) \
81 V(CallRuntime) \
82 V(CallStub) \
83 V(Change) \
84 V(CheckFunction) \
85 V(CheckInstanceType) \
86 V(CheckMap) \
87 V(CheckNonSmi) \
88 V(CheckPrototypeMaps) \
89 V(CheckSmi) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +000090 V(ClampToUint8) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +000091 V(ClassOfTest) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000092 V(Compare) \
93 V(CompareJSObjectEq) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000094 V(CompareMap) \
vegorov@chromium.org7304bca2011-05-16 12:14:13 +000095 V(CompareSymbolEq) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000096 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +000097 V(Context) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000098 V(DeleteProperty) \
99 V(Deoptimize) \
100 V(Div) \
101 V(EnterInlined) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000102 V(ExternalArrayLength) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000103 V(FixedArrayLength) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000104 V(ForceRepresentation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000105 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000106 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000107 V(GlobalObject) \
108 V(GlobalReceiver) \
109 V(Goto) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000110 V(HasCachedArrayIndex) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000111 V(HasInstanceType) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000112 V(In) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000113 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000114 V(InstanceOfKnownGlobal) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000115 V(InvokeFunction) \
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000116 V(IsConstructCall) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000117 V(IsNull) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000118 V(IsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000119 V(IsSmi) \
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000120 V(IsUndetectable) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000121 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000122 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000123 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000124 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000125 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000126 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000127 V(LoadGlobalCell) \
128 V(LoadGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000129 V(LoadKeyedFastElement) \
130 V(LoadKeyedGeneric) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000131 V(LoadKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000132 V(LoadNamedField) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000133 V(LoadNamedFieldPolymorphic) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000134 V(LoadNamedGeneric) \
135 V(Mod) \
136 V(Mul) \
137 V(ObjectLiteral) \
138 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000139 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000140 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000141 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000142 V(PushArgument) \
143 V(RegExpLiteral) \
144 V(Return) \
145 V(Sar) \
146 V(Shl) \
147 V(Shr) \
148 V(Simulate) \
149 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000150 V(StoreContextSlot) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000151 V(StoreGlobalCell) \
152 V(StoreGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000153 V(StoreKeyedFastElement) \
154 V(StoreKeyedGeneric) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000155 V(StoreKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000156 V(StoreNamedField) \
157 V(StoreNamedGeneric) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000158 V(StringAdd) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000159 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000160 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000161 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000162 V(Sub) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000163 V(Test) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000164 V(ThisFunction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000165 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000166 V(ToFastProperties) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000167 V(ToInt32) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000168 V(Typeof) \
169 V(TypeofIs) \
170 V(UnaryMathOperation) \
171 V(UnknownOSRValue) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000172 V(UseConst) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000173 V(ValueOf)
174
175#define GVN_FLAG_LIST(V) \
176 V(Calls) \
177 V(InobjectFields) \
178 V(BackingStoreFields) \
179 V(ArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000180 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000181 V(GlobalVars) \
182 V(Maps) \
183 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000184 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000185 V(OsrEntries)
186
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000187#define DECLARE_ABSTRACT_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000188 virtual bool Is##type() const { return true; } \
189 static H##type* cast(HValue* value) { \
190 ASSERT(value->Is##type()); \
191 return reinterpret_cast<H##type*>(value); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000192 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000193
194
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000195#define DECLARE_CONCRETE_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000196 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000197 static H##type* cast(HValue* value) { \
198 ASSERT(value->Is##type()); \
199 return reinterpret_cast<H##type*>(value); \
200 } \
201 virtual Opcode opcode() const { return HValue::k##type; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000202
203
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000204class Range: public ZoneObject {
205 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000206 Range()
207 : lower_(kMinInt),
208 upper_(kMaxInt),
209 next_(NULL),
210 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000211
212 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000213 : lower_(lower),
214 upper_(upper),
215 next_(NULL),
216 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000217
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000218 int32_t upper() const { return upper_; }
219 int32_t lower() const { return lower_; }
220 Range* next() const { return next_; }
221 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
222 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000223 Range* Copy() const { return new Range(lower_, upper_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000224 int32_t Mask() const;
225 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
226 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
227 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
228 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000229 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
230 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
231 bool IsInSmiRange() const {
232 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000233 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000234 void KeepOrder();
235 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000236
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000237 void StackUpon(Range* other) {
238 Intersect(other);
239 next_ = other;
240 }
241
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000242 void Intersect(Range* other);
243 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000244
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000245 void AddConstant(int32_t value);
246 void Sar(int32_t value);
247 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000248 bool AddAndCheckOverflow(Range* other);
249 bool SubAndCheckOverflow(Range* other);
250 bool MulAndCheckOverflow(Range* other);
251
252 private:
253 int32_t lower_;
254 int32_t upper_;
255 Range* next_;
256 bool can_be_minus_zero_;
257};
258
259
260class Representation {
261 public:
262 enum Kind {
263 kNone,
264 kTagged,
265 kDouble,
266 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000267 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000268 kNumRepresentations
269 };
270
271 Representation() : kind_(kNone) { }
272
273 static Representation None() { return Representation(kNone); }
274 static Representation Tagged() { return Representation(kTagged); }
275 static Representation Integer32() { return Representation(kInteger32); }
276 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000277 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000278
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000279 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000280 return kind_ == other.kind_;
281 }
282
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000283 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000284 bool IsNone() const { return kind_ == kNone; }
285 bool IsTagged() const { return kind_ == kTagged; }
286 bool IsInteger32() const { return kind_ == kInteger32; }
287 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000288 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000289 bool IsSpecialization() const {
290 return kind_ == kInteger32 || kind_ == kDouble;
291 }
292 const char* Mnemonic() const;
293
294 private:
295 explicit Representation(Kind k) : kind_(k) { }
296
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000297 // Make sure kind fits in int8.
298 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
299
300 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000301};
302
303
304class HType {
305 public:
306 HType() : type_(kUninitialized) { }
307
308 static HType Tagged() { return HType(kTagged); }
309 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
310 static HType TaggedNumber() { return HType(kTaggedNumber); }
311 static HType Smi() { return HType(kSmi); }
312 static HType HeapNumber() { return HType(kHeapNumber); }
313 static HType String() { return HType(kString); }
314 static HType Boolean() { return HType(kBoolean); }
315 static HType NonPrimitive() { return HType(kNonPrimitive); }
316 static HType JSArray() { return HType(kJSArray); }
317 static HType JSObject() { return HType(kJSObject); }
318 static HType Uninitialized() { return HType(kUninitialized); }
319
320 // Return the weakest (least precise) common type.
321 HType Combine(HType other) {
322 return HType(static_cast<Type>(type_ & other.type_));
323 }
324
325 bool Equals(const HType& other) {
326 return type_ == other.type_;
327 }
328
329 bool IsSubtypeOf(const HType& other) {
330 return Combine(other).Equals(other);
331 }
332
333 bool IsTagged() {
334 ASSERT(type_ != kUninitialized);
335 return ((type_ & kTagged) == kTagged);
336 }
337
338 bool IsTaggedPrimitive() {
339 ASSERT(type_ != kUninitialized);
340 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
341 }
342
343 bool IsTaggedNumber() {
344 ASSERT(type_ != kUninitialized);
345 return ((type_ & kTaggedNumber) == kTaggedNumber);
346 }
347
348 bool IsSmi() {
349 ASSERT(type_ != kUninitialized);
350 return ((type_ & kSmi) == kSmi);
351 }
352
353 bool IsHeapNumber() {
354 ASSERT(type_ != kUninitialized);
355 return ((type_ & kHeapNumber) == kHeapNumber);
356 }
357
358 bool IsString() {
359 ASSERT(type_ != kUninitialized);
360 return ((type_ & kString) == kString);
361 }
362
363 bool IsBoolean() {
364 ASSERT(type_ != kUninitialized);
365 return ((type_ & kBoolean) == kBoolean);
366 }
367
368 bool IsNonPrimitive() {
369 ASSERT(type_ != kUninitialized);
370 return ((type_ & kNonPrimitive) == kNonPrimitive);
371 }
372
373 bool IsJSArray() {
374 ASSERT(type_ != kUninitialized);
375 return ((type_ & kJSArray) == kJSArray);
376 }
377
378 bool IsJSObject() {
379 ASSERT(type_ != kUninitialized);
380 return ((type_ & kJSObject) == kJSObject);
381 }
382
383 bool IsUninitialized() {
384 return type_ == kUninitialized;
385 }
386
387 static HType TypeFromValue(Handle<Object> value);
388
389 const char* ToString();
390 const char* ToShortString();
391
392 private:
393 enum Type {
394 kTagged = 0x1, // 0000 0000 0000 0001
395 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
396 kTaggedNumber = 0xd, // 0000 0000 0000 1101
397 kSmi = 0x1d, // 0000 0000 0001 1101
398 kHeapNumber = 0x2d, // 0000 0000 0010 1101
399 kString = 0x45, // 0000 0000 0100 0101
400 kBoolean = 0x85, // 0000 0000 1000 0101
401 kNonPrimitive = 0x101, // 0000 0001 0000 0001
402 kJSObject = 0x301, // 0000 0011 0000 0001
403 kJSArray = 0x701, // 0000 0111 1000 0001
404 kUninitialized = 0x1fff // 0001 1111 1111 1111
405 };
406
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000407 // Make sure type fits in int16.
408 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
409
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000410 explicit HType(Type t) : type_(t) { }
411
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000412 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000413};
414
415
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000416class HUseListNode: public ZoneObject {
417 public:
418 HUseListNode(HValue* value, int index, HUseListNode* tail)
419 : tail_(tail), value_(value), index_(index) {
420 }
421
422 HUseListNode* tail() const { return tail_; }
423 HValue* value() const { return value_; }
424 int index() const { return index_; }
425
426 void set_tail(HUseListNode* list) { tail_ = list; }
427
428#ifdef DEBUG
429 void Zap() {
430 tail_ = reinterpret_cast<HUseListNode*>(1);
431 value_ = NULL;
432 index_ = -1;
433 }
434#endif
435
436 private:
437 HUseListNode* tail_;
438 HValue* value_;
439 int index_;
440};
441
442
443// We reuse use list nodes behind the scenes as uses are added and deleted.
444// This class is the safe way to iterate uses while deleting them.
445class HUseIterator BASE_EMBEDDED {
446 public:
447 bool Done() { return current_ == NULL; }
448 void Advance();
449
450 HValue* value() {
451 ASSERT(!Done());
452 return value_;
453 }
454
455 int index() {
456 ASSERT(!Done());
457 return index_;
458 }
459
460 private:
461 explicit HUseIterator(HUseListNode* head);
462
463 HUseListNode* current_;
464 HUseListNode* next_;
465 HValue* value_;
466 int index_;
467
468 friend class HValue;
469};
470
471
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000472class HValue: public ZoneObject {
473 public:
474 static const int kNoNumber = -1;
475
476 // There must be one corresponding kDepends flag for every kChanges flag and
477 // the order of the kChanges flags must be exactly the same as of the kDepends
478 // flags.
479 enum Flag {
480 // Declare global value numbering flags.
481 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
482 GVN_FLAG_LIST(DECLARE_DO)
483 #undef DECLARE_DO
484 kFlexibleRepresentation,
485 kUseGVN,
486 kCanOverflow,
487 kBailoutOnMinusZero,
488 kCanBeDivByZero,
489 kIsArguments,
490 kTruncatingToInt32,
491 kLastFlag = kTruncatingToInt32
492 };
493
494 STATIC_ASSERT(kLastFlag < kBitsPerInt);
495
496 static const int kChangesToDependsFlagsLeftShift = 1;
497
498 static int ChangesFlagsMask() {
499 int result = 0;
500 // Create changes mask.
501#define DECLARE_DO(type) result |= (1 << kChanges##type);
502 GVN_FLAG_LIST(DECLARE_DO)
503#undef DECLARE_DO
504 return result;
505 }
506
507 static int DependsFlagsMask() {
508 return ConvertChangesToDependsFlags(ChangesFlagsMask());
509 }
510
511 static int ConvertChangesToDependsFlags(int flags) {
512 return flags << kChangesToDependsFlagsLeftShift;
513 }
514
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000515 static HValue* cast(HValue* value) { return value; }
516
517 enum Opcode {
518 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000519 #define DECLARE_OPCODE(type) k##type,
520 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
521 kPhi
522 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000523 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000524 virtual Opcode opcode() const = 0;
525
526 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
527 #define DECLARE_PREDICATE(type) \
528 bool Is##type() const { return opcode() == k##type; }
529 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
530 #undef DECLARE_PREDICATE
531 bool IsPhi() const { return opcode() == kPhi; }
532
533 // Declare virtual predicates for abstract HInstruction or HValue
534 #define DECLARE_PREDICATE(type) \
535 virtual bool Is##type() const { return false; }
536 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
537 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000538
539 HValue() : block_(NULL),
540 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000541 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000542 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000543 range_(NULL),
544 flags_(0) {}
545 virtual ~HValue() {}
546
547 HBasicBlock* block() const { return block_; }
548 void SetBlock(HBasicBlock* block);
549
550 int id() const { return id_; }
551 void set_id(int id) { id_ = id; }
552
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000553 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000554
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000555 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000556 Representation representation() const { return representation_; }
557 void ChangeRepresentation(Representation r) {
558 // Representation was already set and is allowed to be changed.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000559 ASSERT(!r.IsNone());
560 ASSERT(CheckFlag(kFlexibleRepresentation));
561 RepresentationChanged(r);
562 representation_ = r;
563 }
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000564 void AssumeRepresentation(Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000565
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000566 virtual bool IsConvertibleToInteger() const { return true; }
567
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000568 HType type() const { return type_; }
569 void set_type(HType type) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000570 ASSERT(HasNoUses());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000571 type_ = type;
572 }
573
574 // An operation needs to override this function iff:
575 // 1) it can produce an int32 output.
576 // 2) the true value of its output can potentially be minus zero.
577 // The implementation must set a flag so that it bails out in the case where
578 // it would otherwise output what should be a minus zero as an int32 zero.
579 // If the operation also exists in a form that takes int32 and outputs int32
580 // then the operation should return its input value so that we can propagate
581 // back. There are two operations that need to propagate back to more than
582 // one input. They are phi and binary add. They always return NULL and
583 // expect the caller to take care of things.
584 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
585 visited->Add(id());
586 return NULL;
587 }
588
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000589 bool IsDefinedAfter(HBasicBlock* other) const;
590
591 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000592 virtual int OperandCount() = 0;
593 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000594 void SetOperandAt(int index, HValue* value);
595
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000596 void DeleteAndReplaceWith(HValue* other);
597 bool HasNoUses() const { return use_list_ == NULL; }
598 bool HasMultipleUses() const {
599 return use_list_ != NULL && use_list_->tail() != NULL;
600 }
601 int UseCount() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000602 void ClearOperands();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000603
604 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000605 void SetFlag(Flag f) { flags_ |= (1 << f); }
606 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
607 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
608
609 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
610 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
611 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000612
613 Range* range() const { return range_; }
614 bool HasRange() const { return range_ != NULL; }
615 void AddNewRange(Range* r);
616 void RemoveLastAddedRange();
617 void ComputeInitialRange();
618
619 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000620 virtual Representation RequiredInputRepresentation(int index) const = 0;
621
622 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000623 return representation();
624 }
625
626 // This gives the instruction an opportunity to replace itself with an
627 // instruction that does the same in some better way. To replace an
628 // instruction with a new one, first add the new instruction to the graph,
629 // then return it. Return NULL to have the instruction deleted.
630 virtual HValue* Canonicalize() { return this; }
631
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000632 bool Equals(HValue* other);
633 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000634
635 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000636 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000637 void PrintNameTo(StringStream* stream);
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000638 void PrintTypeTo(StringStream* stream);
639 void PrintRangeTo(StringStream* stream);
640 void PrintChangesTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000641
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000642 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000643
644 // Updated the inferred type of this instruction and returns true if
645 // it has changed.
646 bool UpdateInferredType();
647
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000648 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000649
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000650#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000651 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000652#endif
653
654 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000655 // This function must be overridden for instructions with flag kUseGVN, to
656 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000657 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000658 UNREACHABLE();
659 return false;
660 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000661 virtual void RepresentationChanged(Representation to) { }
662 virtual Range* InferRange();
663 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000664 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000665 void clear_block() {
666 ASSERT(block_ != NULL);
667 block_ = NULL;
668 }
669
670 void set_representation(Representation r) {
671 // Representation is set-once.
672 ASSERT(representation_.IsNone() && !r.IsNone());
673 representation_ = r;
674 }
675
676 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000677 // A flag mask to mark an instruction as having arbitrary side effects.
678 static int AllSideEffects() {
679 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
680 }
681
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000682 // Remove the matching use from the use list if present. Returns the
683 // removed list node or NULL.
684 HUseListNode* RemoveUse(HValue* value, int index);
685
686 void ReplaceAllUsesWith(HValue* other);
687
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000688 void RegisterUse(int index, HValue* new_value);
689
690 HBasicBlock* block_;
691
692 // The id of this instruction in the hydrogen graph, assigned when first
693 // added to the graph. Reflects creation order.
694 int id_;
695
696 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000697 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000698 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000699 Range* range_;
700 int flags_;
701
702 DISALLOW_COPY_AND_ASSIGN(HValue);
703};
704
705
706class HInstruction: public HValue {
707 public:
708 HInstruction* next() const { return next_; }
709 HInstruction* previous() const { return previous_; }
710
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000711 virtual void PrintTo(StringStream* stream);
712 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000713
714 bool IsLinked() const { return block() != NULL; }
715 void Unlink();
716 void InsertBefore(HInstruction* next);
717 void InsertAfter(HInstruction* previous);
718
719 int position() const { return position_; }
720 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
721 void set_position(int position) { position_ = position; }
722
723 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
724
725#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000726 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000727#endif
728
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000729 // Returns whether this is some kind of deoptimizing check
730 // instruction.
731 virtual bool IsCheckInstruction() const { return false; }
732
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000733 virtual bool IsCall() { return false; }
734
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000735 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000736
737 protected:
738 HInstruction()
739 : next_(NULL),
740 previous_(NULL),
741 position_(RelocInfo::kNoPosition) {
742 SetFlag(kDependsOnOsrEntries);
743 }
744
745 virtual void DeleteFromGraph() { Unlink(); }
746
747 private:
748 void InitializeAsFirst(HBasicBlock* block) {
749 ASSERT(!IsLinked());
750 SetBlock(block);
751 }
752
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000753 void PrintMnemonicTo(StringStream* stream);
754
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000755 HInstruction* next_;
756 HInstruction* previous_;
757 int position_;
758
759 friend class HBasicBlock;
760};
761
762
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000763class HControlInstruction: public HInstruction {
764 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000765 HControlInstruction(HBasicBlock* first, HBasicBlock* second)
766 : first_successor_(first), second_successor_(second) {
767 }
768
769 HBasicBlock* FirstSuccessor() const { return first_successor_; }
770 HBasicBlock* SecondSuccessor() const { return second_successor_; }
771
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000772 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000773
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000774 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000775
776 private:
777 HBasicBlock* first_successor_;
778 HBasicBlock* second_successor_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000779};
780
781
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000782template<int NumElements>
783class HOperandContainer {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000784 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000785 HOperandContainer() : elems_() { }
786
787 int length() { return NumElements; }
788 HValue*& operator[](int i) {
789 ASSERT(i < length());
790 return elems_[i];
791 }
792
793 private:
794 HValue* elems_[NumElements];
795};
796
797
798template<>
799class HOperandContainer<0> {
800 public:
801 int length() { return 0; }
802 HValue*& operator[](int i) {
803 UNREACHABLE();
804 static HValue* t = 0;
805 return t;
806 }
807};
808
809
810template<int V>
811class HTemplateInstruction : public HInstruction {
812 public:
813 int OperandCount() { return V; }
814 HValue* OperandAt(int i) { return inputs_[i]; }
815
816 protected:
817 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
818
819 private:
820 HOperandContainer<V> inputs_;
821};
822
823
824template<int V>
825class HTemplateControlInstruction : public HControlInstruction {
826 public:
827 HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second)
828 : HControlInstruction(first, second) { }
829 int OperandCount() { return V; }
830 HValue* OperandAt(int i) { return inputs_[i]; }
831
832 protected:
833 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
834
835 private:
836 HOperandContainer<V> inputs_;
837};
838
839
840class HBlockEntry: public HTemplateInstruction<0> {
841 public:
842 virtual Representation RequiredInputRepresentation(int index) const {
843 return Representation::None();
844 }
845
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000846 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000847};
848
849
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000850class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000851 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000852 explicit HDeoptimize(int environment_length)
853 : HControlInstruction(NULL, NULL),
854 values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000855
856 virtual Representation RequiredInputRepresentation(int index) const {
857 return Representation::None();
858 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000859
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000860 virtual int OperandCount() { return values_.length(); }
861 virtual HValue* OperandAt(int index) { return values_[index]; }
862
863 void AddEnvironmentValue(HValue* value) {
864 values_.Add(NULL);
865 SetOperandAt(values_.length() - 1, value);
866 }
867
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000868 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000869
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000870 enum UseEnvironment {
871 kNoUses,
872 kUseAll
873 };
874
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000875 protected:
876 virtual void InternalSetOperandAt(int index, HValue* value) {
877 values_[index] = value;
878 }
879
880 private:
881 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000882};
883
884
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000885class HGoto: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000886 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000887 explicit HGoto(HBasicBlock* target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000888 : HTemplateControlInstruction<0>(target, NULL),
889 include_stack_check_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000890
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000891 void set_include_stack_check(bool include_stack_check) {
892 include_stack_check_ = include_stack_check;
893 }
894 bool include_stack_check() const { return include_stack_check_; }
895
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000896 virtual Representation RequiredInputRepresentation(int index) const {
897 return Representation::None();
898 }
899
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000900 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000901
902 private:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000903 bool include_stack_check_;
904};
905
906
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000907class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000908 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000909 explicit HUnaryControlInstruction(HValue* value,
910 HBasicBlock* true_target,
911 HBasicBlock* false_target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000912 : HTemplateControlInstruction<1>(true_target, false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000913 SetOperandAt(0, value);
914 }
915
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000916 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000917
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000918 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000919};
920
921
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000922class HTest: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000923 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000924 HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
925 : HUnaryControlInstruction(value, true_target, false_target) {
926 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000927 }
928
929 virtual Representation RequiredInputRepresentation(int index) const {
930 return Representation::None();
931 }
932
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000933 DECLARE_CONCRETE_INSTRUCTION(Test)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000934};
935
936
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000937class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000938 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000939 HCompareMap(HValue* value,
940 Handle<Map> map,
941 HBasicBlock* true_target,
942 HBasicBlock* false_target)
943 : HUnaryControlInstruction(value, true_target, false_target),
944 map_(map) {
945 ASSERT(true_target != NULL);
946 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000947 ASSERT(!map.is_null());
948 }
949
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000950 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000951
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000952 Handle<Map> map() const { return map_; }
953
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000954 virtual Representation RequiredInputRepresentation(int index) const {
955 return Representation::Tagged();
956 }
957
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000958 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000959
960 private:
961 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000962};
963
964
965class HReturn: public HUnaryControlInstruction {
966 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000967 explicit HReturn(HValue* value)
968 : HUnaryControlInstruction(value, NULL, NULL) {
969 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000970
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000971 virtual Representation RequiredInputRepresentation(int index) const {
972 return Representation::Tagged();
973 }
974
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000975 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000976};
977
978
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000979class HAbnormalExit: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000980 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000981 HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
982
983 virtual Representation RequiredInputRepresentation(int index) const {
984 return Representation::None();
985 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000986
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000987 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000988};
989
990
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000991class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000992 public:
993 explicit HUnaryOperation(HValue* value) {
994 SetOperandAt(0, value);
995 }
996
ricow@chromium.orgc54d3652011-05-30 09:20:16 +0000997 static HUnaryOperation* cast(HValue* value) {
998 return reinterpret_cast<HUnaryOperation*>(value);
999 }
1000
1001 virtual bool CanTruncateToInt32() const {
1002 return CheckFlag(kTruncatingToInt32);
1003 }
1004
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001005 HValue* value() { return OperandAt(0); }
1006 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001007};
1008
1009
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001010class HThrow: public HUnaryOperation {
1011 public:
1012 explicit HThrow(HValue* value) : HUnaryOperation(value) {
1013 SetAllSideEffects();
1014 }
1015
1016 virtual Representation RequiredInputRepresentation(int index) const {
1017 return Representation::Tagged();
1018 }
1019
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001020 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001021};
1022
1023
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001024class HUseConst: public HUnaryOperation {
1025 public:
1026 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1027
1028 virtual Representation RequiredInputRepresentation(int index) const {
1029 return Representation::None();
1030 }
1031
1032 DECLARE_CONCRETE_INSTRUCTION(UseConst)
1033};
1034
1035
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001036class HForceRepresentation: public HTemplateInstruction<1> {
1037 public:
1038 HForceRepresentation(HValue* value, Representation required_representation) {
1039 SetOperandAt(0, value);
1040 set_representation(required_representation);
1041 }
1042
1043 HValue* value() { return OperandAt(0); }
1044
1045 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1046
1047 virtual Representation RequiredInputRepresentation(int index) const {
1048 return representation(); // Same as the output representation.
1049 }
1050
1051 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1052};
1053
1054
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001055class HChange: public HUnaryOperation {
1056 public:
1057 HChange(HValue* value,
1058 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001059 Representation to,
1060 bool is_truncating)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001061 : HUnaryOperation(value), from_(from) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001062 ASSERT(!from.IsNone() && !to.IsNone());
1063 ASSERT(!from.Equals(to));
1064 set_representation(to);
1065 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001066 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001067 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
1068 value->range()->IsInSmiRange()) {
1069 set_type(HType::Smi());
1070 }
1071 }
1072
1073 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1074
1075 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001076 Representation to() const { return representation(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001077 virtual Representation RequiredInputRepresentation(int index) const {
1078 return from_;
1079 }
1080
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001081 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001082
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001083 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001084
1085 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001086 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001087 if (!other->IsChange()) return false;
1088 HChange* change = HChange::cast(other);
1089 return value() == change->value()
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001090 && to().Equals(change->to());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001091 }
1092
1093 private:
1094 Representation from_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001095};
1096
1097
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001098class HClampToUint8: public HUnaryOperation {
1099 public:
1100 explicit HClampToUint8(HValue* value)
1101 : HUnaryOperation(value),
1102 input_rep_(Representation::None()) {
1103 SetFlag(kFlexibleRepresentation);
1104 set_representation(Representation::Tagged());
1105 SetFlag(kUseGVN);
1106 }
1107
1108 virtual Representation RequiredInputRepresentation(int index) const {
1109 return input_rep_;
1110 }
1111
1112 virtual Representation InferredRepresentation() {
1113 // TODO(danno): Inference on input types should happen separately from
1114 // return representation.
1115 Representation new_rep = value()->representation();
1116 if (input_rep_.IsNone()) {
1117 if (!new_rep.IsNone()) {
1118 input_rep_ = new_rep;
1119 return Representation::Integer32();
1120 } else {
1121 return Representation::None();
1122 }
1123 } else {
1124 return Representation::Integer32();
1125 }
1126 }
1127
1128 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1129
1130 protected:
1131 virtual bool DataEquals(HValue* other) { return true; }
1132
1133 private:
1134 Representation input_rep_;
1135};
1136
1137
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001138class HToInt32: public HUnaryOperation {
1139 public:
1140 explicit HToInt32(HValue* value)
1141 : HUnaryOperation(value) {
1142 set_representation(Representation::Integer32());
1143 SetFlag(kUseGVN);
1144 }
1145
1146 virtual Representation RequiredInputRepresentation(int index) const {
1147 return Representation::None();
1148 }
1149
1150 virtual bool CanTruncateToInt32() const {
1151 return true;
1152 }
1153
1154 virtual HValue* Canonicalize() {
1155 if (value()->representation().IsInteger32()) {
1156 return value();
1157 } else {
1158 return this;
1159 }
1160 }
1161
1162 DECLARE_CONCRETE_INSTRUCTION(ToInt32)
1163
1164 protected:
1165 virtual bool DataEquals(HValue* other) { return true; }
1166};
1167
1168
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001169class HSimulate: public HInstruction {
1170 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00001171 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001172 : ast_id_(ast_id),
1173 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001174 values_(2),
1175 assigned_indexes_(2) {}
1176 virtual ~HSimulate() {}
1177
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001178 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001179
1180 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1181 int ast_id() const { return ast_id_; }
1182 void set_ast_id(int id) {
1183 ASSERT(!HasAstId());
1184 ast_id_ = id;
1185 }
1186
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001187 int pop_count() const { return pop_count_; }
1188 const ZoneList<HValue*>* values() const { return &values_; }
1189 int GetAssignedIndexAt(int index) const {
1190 ASSERT(HasAssignedIndexAt(index));
1191 return assigned_indexes_[index];
1192 }
1193 bool HasAssignedIndexAt(int index) const {
1194 return assigned_indexes_[index] != kNoIndex;
1195 }
1196 void AddAssignedValue(int index, HValue* value) {
1197 AddValue(index, value);
1198 }
1199 void AddPushedValue(HValue* value) {
1200 AddValue(kNoIndex, value);
1201 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001202 virtual int OperandCount() { return values_.length(); }
1203 virtual HValue* OperandAt(int index) { return values_[index]; }
1204
1205 virtual Representation RequiredInputRepresentation(int index) const {
1206 return Representation::None();
1207 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001208
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001209 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001210
1211#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001212 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001213#endif
1214
1215 protected:
1216 virtual void InternalSetOperandAt(int index, HValue* value) {
1217 values_[index] = value;
1218 }
1219
1220 private:
1221 static const int kNoIndex = -1;
1222 void AddValue(int index, HValue* value) {
1223 assigned_indexes_.Add(index);
1224 // Resize the list of pushed values.
1225 values_.Add(NULL);
1226 // Set the operand through the base method in HValue to make sure that the
1227 // use lists are correctly updated.
1228 SetOperandAt(values_.length() - 1, value);
1229 }
1230 int ast_id_;
1231 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001232 ZoneList<HValue*> values_;
1233 ZoneList<int> assigned_indexes_;
1234};
1235
1236
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001237class HStackCheck: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001238 public:
1239 HStackCheck() { }
1240
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001241 virtual Representation RequiredInputRepresentation(int index) const {
1242 return Representation::None();
1243 }
1244
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001245 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001246};
1247
1248
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001249class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001250 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +00001251 HEnterInlined(Handle<JSFunction> closure,
1252 FunctionLiteral* function,
1253 CallKind call_kind)
1254 : closure_(closure),
1255 function_(function),
1256 call_kind_(call_kind) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001257 }
1258
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001259 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001260
1261 Handle<JSFunction> closure() const { return closure_; }
1262 FunctionLiteral* function() const { return function_; }
danno@chromium.org40cb8782011-05-25 07:58:50 +00001263 CallKind call_kind() const { return call_kind_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001264
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001265 virtual Representation RequiredInputRepresentation(int index) const {
1266 return Representation::None();
1267 }
1268
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001269 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001270
1271 private:
1272 Handle<JSFunction> closure_;
1273 FunctionLiteral* function_;
danno@chromium.org40cb8782011-05-25 07:58:50 +00001274 CallKind call_kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001275};
1276
1277
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001278class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001279 public:
1280 HLeaveInlined() {}
1281
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001282 virtual Representation RequiredInputRepresentation(int index) const {
1283 return Representation::None();
1284 }
1285
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001286 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001287};
1288
1289
1290class HPushArgument: public HUnaryOperation {
1291 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001292 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1293 set_representation(Representation::Tagged());
1294 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001295
1296 virtual Representation RequiredInputRepresentation(int index) const {
1297 return Representation::Tagged();
1298 }
1299
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001300 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001301
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001302 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001303};
1304
1305
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001306class HThisFunction: public HTemplateInstruction<0> {
1307 public:
1308 HThisFunction() {
1309 set_representation(Representation::Tagged());
1310 SetFlag(kUseGVN);
1311 }
1312
1313 virtual Representation RequiredInputRepresentation(int index) const {
1314 return Representation::None();
1315 }
1316
1317 DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
1318
1319 protected:
1320 virtual bool DataEquals(HValue* other) { return true; }
1321};
1322
1323
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001324class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001325 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001326 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001327 set_representation(Representation::Tagged());
1328 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001329 }
1330
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001331 virtual Representation RequiredInputRepresentation(int index) const {
1332 return Representation::None();
1333 }
1334
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001335 DECLARE_CONCRETE_INSTRUCTION(Context)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001336
1337 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001338 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001339};
1340
1341
1342class HOuterContext: public HUnaryOperation {
1343 public:
1344 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1345 set_representation(Representation::Tagged());
1346 SetFlag(kUseGVN);
1347 }
1348
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001349 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001350
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001351 virtual Representation RequiredInputRepresentation(int index) const {
1352 return Representation::Tagged();
1353 }
1354
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001355 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001356 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001357};
1358
1359
1360class HGlobalObject: public HUnaryOperation {
1361 public:
1362 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1363 set_representation(Representation::Tagged());
1364 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001365 }
1366
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001367 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001368
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001369 virtual Representation RequiredInputRepresentation(int index) const {
1370 return Representation::Tagged();
1371 }
1372
ager@chromium.org378b34e2011-01-28 08:04:38 +00001373 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001374 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001375};
1376
1377
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001378class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001379 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001380 explicit HGlobalReceiver(HValue* global_object)
1381 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001382 set_representation(Representation::Tagged());
1383 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001384 }
1385
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001386 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001387
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001388 virtual Representation RequiredInputRepresentation(int index) const {
1389 return Representation::Tagged();
1390 }
1391
ager@chromium.org378b34e2011-01-28 08:04:38 +00001392 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001393 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001394};
1395
1396
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001397template <int V>
1398class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001399 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001400 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001401 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1402 this->set_representation(Representation::Tagged());
1403 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001404 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001405
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001406 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001407
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001408 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001409
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001410 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001411
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001412 private:
1413 int argument_count_;
1414};
1415
1416
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001417class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001418 public:
1419 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001420 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001421 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001422 }
1423
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001424 virtual Representation RequiredInputRepresentation(int index) const {
1425 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001426 }
1427
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001428 virtual void PrintDataTo(StringStream* stream);
1429
1430 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001431};
1432
1433
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001434class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001435 public:
1436 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001437 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001438 SetOperandAt(0, first);
1439 SetOperandAt(1, second);
1440 }
1441
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001442 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001443
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001444 virtual Representation RequiredInputRepresentation(int index) const {
1445 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001446 }
1447
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001448 HValue* first() { return OperandAt(0); }
1449 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001450};
1451
1452
danno@chromium.org160a7b02011-04-18 15:51:38 +00001453class HInvokeFunction: public HBinaryCall {
1454 public:
1455 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1456 : HBinaryCall(context, function, argument_count) {
1457 }
1458
1459 virtual Representation RequiredInputRepresentation(int index) const {
1460 return Representation::Tagged();
1461 }
1462
1463 HValue* context() { return first(); }
1464 HValue* function() { return second(); }
1465
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001466 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
danno@chromium.org160a7b02011-04-18 15:51:38 +00001467};
1468
1469
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001470class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001471 public:
1472 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001473 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001474
1475 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001476
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001477 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001478 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001479 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001480 }
1481
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001482 virtual void PrintDataTo(StringStream* stream);
1483
1484 virtual Representation RequiredInputRepresentation(int index) const {
1485 return Representation::None();
1486 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001487
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001488 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001489
1490 private:
1491 Handle<JSFunction> function_;
1492};
1493
1494
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001495class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001496 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001497 HCallKeyed(HValue* context, HValue* key, int argument_count)
1498 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001499 }
1500
1501 virtual Representation RequiredInputRepresentation(int index) const {
1502 return Representation::Tagged();
1503 }
1504
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001505 HValue* context() { return first(); }
1506 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001507
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001508 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001509};
1510
1511
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001512class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001513 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001514 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1515 : HUnaryCall(context, argument_count), name_(name) {
1516 }
1517
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001518 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001519
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001520 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001521 Handle<String> name() const { return name_; }
1522
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001523 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001524
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001525 virtual Representation RequiredInputRepresentation(int index) const {
1526 return Representation::Tagged();
1527 }
1528
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001529 private:
1530 Handle<String> name_;
1531};
1532
1533
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001534class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001535 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001536 HCallFunction(HValue* context, int argument_count)
1537 : HUnaryCall(context, argument_count) {
1538 }
1539
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001540 HValue* context() { return value(); }
1541
1542 virtual Representation RequiredInputRepresentation(int index) const {
1543 return Representation::Tagged();
1544 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001545
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001546 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001547};
1548
1549
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001550class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001551 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001552 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1553 : HUnaryCall(context, argument_count), name_(name) {
1554 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001555
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001556 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001557
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001558 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001559 Handle<String> name() const { return name_; }
1560
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001561 virtual Representation RequiredInputRepresentation(int index) const {
1562 return Representation::Tagged();
1563 }
1564
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001565 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001566
1567 private:
1568 Handle<String> name_;
1569};
1570
1571
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001572class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001573 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001574 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001575 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001576
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001577 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001578
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001579 Handle<JSFunction> target() const { return target_; }
1580
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001581 virtual Representation RequiredInputRepresentation(int index) const {
1582 return Representation::None();
1583 }
1584
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001585 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001586
1587 private:
1588 Handle<JSFunction> target_;
1589};
1590
1591
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001592class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001593 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001594 HCallNew(HValue* context, HValue* constructor, int argument_count)
1595 : HBinaryCall(context, constructor, argument_count) {
1596 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001597
1598 virtual Representation RequiredInputRepresentation(int index) const {
1599 return Representation::Tagged();
1600 }
1601
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001602 HValue* context() { return first(); }
1603 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001604
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001605 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001606};
1607
1608
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001609class HCallRuntime: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001610 public:
1611 HCallRuntime(Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001612 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001613 int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001614 : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
1615 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001616
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001617 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001618 Handle<String> name() const { return name_; }
1619
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001620 virtual Representation RequiredInputRepresentation(int index) const {
1621 return Representation::None();
1622 }
1623
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001624 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001625
1626 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001627 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001628 Handle<String> name_;
1629};
1630
1631
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001632class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001633 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001634 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001635 // The length of an array is stored as a tagged value in the array
1636 // object. It is guaranteed to be 32 bit integer, but it can be
1637 // represented as either a smi or heap number.
1638 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001639 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001640 SetFlag(kDependsOnArrayLengths);
1641 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001642 }
1643
1644 virtual Representation RequiredInputRepresentation(int index) const {
1645 return Representation::Tagged();
1646 }
1647
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001648 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001649
1650 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001651 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001652};
1653
1654
1655class HFixedArrayLength: public HUnaryOperation {
1656 public:
1657 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1658 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001659 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001660 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001661 }
1662
1663 virtual Representation RequiredInputRepresentation(int index) const {
1664 return Representation::Tagged();
1665 }
1666
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001667 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001668
1669 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001670 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001671};
1672
1673
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001674class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001675 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001676 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001677 set_representation(Representation::Integer32());
1678 // The result of this instruction is idempotent as long as its inputs don't
1679 // change. The length of a pixel array cannot change once set, so it's not
1680 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1681 SetFlag(kUseGVN);
1682 }
1683
1684 virtual Representation RequiredInputRepresentation(int index) const {
1685 return Representation::Tagged();
1686 }
1687
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001688 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001689
1690 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001691 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001692};
1693
1694
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001695class HBitNot: public HUnaryOperation {
1696 public:
1697 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1698 set_representation(Representation::Integer32());
1699 SetFlag(kUseGVN);
1700 SetFlag(kTruncatingToInt32);
1701 }
1702
1703 virtual Representation RequiredInputRepresentation(int index) const {
1704 return Representation::Integer32();
1705 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001706 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001707
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001708 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001709
1710 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001711 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001712};
1713
1714
1715class HUnaryMathOperation: public HUnaryOperation {
1716 public:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001717 HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001718 : HUnaryOperation(value), op_(op) {
1719 switch (op) {
1720 case kMathFloor:
1721 case kMathRound:
1722 case kMathCeil:
1723 set_representation(Representation::Integer32());
1724 break;
1725 case kMathAbs:
1726 set_representation(Representation::Tagged());
1727 SetFlag(kFlexibleRepresentation);
1728 break;
1729 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001730 case kMathPowHalf:
1731 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001732 case kMathSin:
1733 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001734 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001735 break;
1736 default:
1737 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001738 }
1739 SetFlag(kUseGVN);
1740 }
1741
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001742 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001743
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001744 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001745
1746 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1747
1748 virtual Representation RequiredInputRepresentation(int index) const {
1749 switch (op_) {
1750 case kMathFloor:
1751 case kMathRound:
1752 case kMathCeil:
1753 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001754 case kMathPowHalf:
1755 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001756 case kMathSin:
1757 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001758 return Representation::Double();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001759 case kMathAbs:
1760 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001761 default:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001762 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001763 return Representation::None();
1764 }
1765 }
1766
1767 virtual HValue* Canonicalize() {
1768 // If the input is integer32 then we replace the floor instruction
1769 // with its inputs. This happens before the representation changes are
1770 // introduced.
1771 if (op() == kMathFloor) {
1772 if (value()->representation().IsInteger32()) return value();
1773 }
1774 return this;
1775 }
1776
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001777 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001778 const char* OpName() const;
1779
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001780 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001781
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001782 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001783 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001784 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1785 return op_ == b->op();
1786 }
1787
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001788 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001789 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001790};
1791
1792
1793class HLoadElements: public HUnaryOperation {
1794 public:
1795 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1796 set_representation(Representation::Tagged());
1797 SetFlag(kUseGVN);
1798 SetFlag(kDependsOnMaps);
1799 }
1800
1801 virtual Representation RequiredInputRepresentation(int index) const {
1802 return Representation::Tagged();
1803 }
1804
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001805 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001806
1807 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001808 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001809};
1810
1811
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001812class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001813 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001814 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001815 : HUnaryOperation(value) {
1816 set_representation(Representation::External());
1817 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001818 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001819 // change once set, so it's no necessary to introduce any additional
1820 // dependencies on top of the inputs.
1821 SetFlag(kUseGVN);
1822 }
1823
1824 virtual Representation RequiredInputRepresentation(int index) const {
1825 return Representation::Tagged();
1826 }
1827
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001828 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001829
1830 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001831 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001832};
1833
1834
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001835class HCheckMap: public HUnaryOperation {
1836 public:
1837 HCheckMap(HValue* value, Handle<Map> map)
1838 : HUnaryOperation(value), map_(map) {
1839 set_representation(Representation::Tagged());
1840 SetFlag(kUseGVN);
1841 SetFlag(kDependsOnMaps);
1842 }
1843
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001844 virtual bool IsCheckInstruction() const { return true; }
1845
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001846 virtual Representation RequiredInputRepresentation(int index) const {
1847 return Representation::Tagged();
1848 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001849 virtual void PrintDataTo(StringStream* stream);
1850 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001851
1852#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001853 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001854#endif
1855
1856 Handle<Map> map() const { return map_; }
1857
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001858 DECLARE_CONCRETE_INSTRUCTION(CheckMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001859
1860 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001861 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001862 HCheckMap* b = HCheckMap::cast(other);
1863 return map_.is_identical_to(b->map());
1864 }
1865
1866 private:
1867 Handle<Map> map_;
1868};
1869
1870
1871class HCheckFunction: public HUnaryOperation {
1872 public:
1873 HCheckFunction(HValue* value, Handle<JSFunction> function)
1874 : HUnaryOperation(value), target_(function) {
1875 set_representation(Representation::Tagged());
1876 SetFlag(kUseGVN);
1877 }
1878
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001879 virtual bool IsCheckInstruction() const { return true; }
1880
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001881 virtual Representation RequiredInputRepresentation(int index) const {
1882 return Representation::Tagged();
1883 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001884 virtual void PrintDataTo(StringStream* stream);
1885 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001886
1887#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001888 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001889#endif
1890
1891 Handle<JSFunction> target() const { return target_; }
1892
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001893 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001894
1895 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001896 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001897 HCheckFunction* b = HCheckFunction::cast(other);
1898 return target_.is_identical_to(b->target());
1899 }
1900
1901 private:
1902 Handle<JSFunction> target_;
1903};
1904
1905
1906class HCheckInstanceType: public HUnaryOperation {
1907 public:
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001908 static HCheckInstanceType* NewIsSpecObject(HValue* value) {
1909 return new HCheckInstanceType(value, IS_SPEC_OBJECT);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001910 }
1911 static HCheckInstanceType* NewIsJSArray(HValue* value) {
1912 return new HCheckInstanceType(value, IS_JS_ARRAY);
1913 }
1914 static HCheckInstanceType* NewIsString(HValue* value) {
1915 return new HCheckInstanceType(value, IS_STRING);
1916 }
1917 static HCheckInstanceType* NewIsSymbol(HValue* value) {
1918 return new HCheckInstanceType(value, IS_SYMBOL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001919 }
1920
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001921 virtual bool IsCheckInstruction() const { return true; }
1922
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001923 virtual Representation RequiredInputRepresentation(int index) const {
1924 return Representation::Tagged();
1925 }
1926
1927#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001928 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001929#endif
1930
danno@chromium.org160a7b02011-04-18 15:51:38 +00001931 virtual HValue* Canonicalize() {
1932 if (!value()->type().IsUninitialized() &&
1933 value()->type().IsString() &&
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001934 check_ == IS_STRING) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00001935 return NULL;
1936 }
1937 return this;
1938 }
1939
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001940 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
1941 void GetCheckInterval(InstanceType* first, InstanceType* last);
1942 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001943
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001944 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001945
1946 protected:
1947 // TODO(ager): It could be nice to allow the ommision of instance
1948 // type checks if we have already performed an instance type check
1949 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001950 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001951 HCheckInstanceType* b = HCheckInstanceType::cast(other);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001952 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001953 }
1954
1955 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001956 enum Check {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001957 IS_SPEC_OBJECT,
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001958 IS_JS_ARRAY,
1959 IS_STRING,
1960 IS_SYMBOL,
1961 LAST_INTERVAL_CHECK = IS_JS_ARRAY
1962 };
1963
1964 HCheckInstanceType(HValue* value, Check check)
1965 : HUnaryOperation(value), check_(check) {
1966 set_representation(Representation::Tagged());
1967 SetFlag(kUseGVN);
1968 }
1969
1970 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001971};
1972
1973
1974class HCheckNonSmi: public HUnaryOperation {
1975 public:
1976 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
1977 set_representation(Representation::Tagged());
1978 SetFlag(kUseGVN);
1979 }
1980
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001981 virtual bool IsCheckInstruction() const { return true; }
1982
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001983 virtual Representation RequiredInputRepresentation(int index) const {
1984 return Representation::Tagged();
1985 }
1986
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001987 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001988
1989#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001990 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001991#endif
1992
danno@chromium.org160a7b02011-04-18 15:51:38 +00001993 virtual HValue* Canonicalize() {
1994 HType value_type = value()->type();
1995 if (!value_type.IsUninitialized() &&
1996 (value_type.IsHeapNumber() ||
1997 value_type.IsString() ||
1998 value_type.IsBoolean() ||
1999 value_type.IsNonPrimitive())) {
2000 return NULL;
2001 }
2002 return this;
2003 }
2004
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002005 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002006
2007 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002008 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002009};
2010
2011
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002012class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002013 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002014 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
2015 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002016 SetFlag(kUseGVN);
2017 SetFlag(kDependsOnMaps);
2018 }
2019
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002020 virtual bool IsCheckInstruction() const { return true; }
2021
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002022#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002023 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002024#endif
2025
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002026 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002027 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002028
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002029 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002030
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002031 virtual Representation RequiredInputRepresentation(int index) const {
2032 return Representation::None();
2033 }
2034
2035 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002036 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002037 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
2038 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
2039 return hash;
2040 }
2041
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002042 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002043 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002044 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002045 return prototype_.is_identical_to(b->prototype()) &&
2046 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002047 }
2048
2049 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002050 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002051 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002052};
2053
2054
2055class HCheckSmi: public HUnaryOperation {
2056 public:
2057 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
2058 set_representation(Representation::Tagged());
2059 SetFlag(kUseGVN);
2060 }
2061
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002062 virtual bool IsCheckInstruction() const { return true; }
2063
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002064 virtual Representation RequiredInputRepresentation(int index) const {
2065 return Representation::Tagged();
2066 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002067 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002068
2069#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002070 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002071#endif
2072
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002073 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002074
2075 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002076 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002077};
2078
2079
2080class HPhi: public HValue {
2081 public:
2082 explicit HPhi(int merged_index)
2083 : inputs_(2),
2084 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002085 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002086 is_live_(false),
2087 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002088 for (int i = 0; i < Representation::kNumRepresentations; i++) {
2089 non_phi_uses_[i] = 0;
2090 indirect_uses_[i] = 0;
2091 }
2092 ASSERT(merged_index >= 0);
2093 set_representation(Representation::Tagged());
2094 SetFlag(kFlexibleRepresentation);
2095 }
2096
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002097 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002098 bool double_occurred = false;
2099 bool int32_occurred = false;
2100 for (int i = 0; i < OperandCount(); ++i) {
2101 HValue* value = OperandAt(i);
2102 if (value->representation().IsDouble()) double_occurred = true;
2103 if (value->representation().IsInteger32()) int32_occurred = true;
2104 if (value->representation().IsTagged()) return Representation::Tagged();
2105 }
2106
2107 if (double_occurred) return Representation::Double();
2108 if (int32_occurred) return Representation::Integer32();
2109 return Representation::None();
2110 }
2111
2112 virtual Range* InferRange();
2113 virtual Representation RequiredInputRepresentation(int index) const {
2114 return representation();
2115 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002116 virtual HType CalculateInferredType();
2117 virtual int OperandCount() { return inputs_.length(); }
2118 virtual HValue* OperandAt(int index) { return inputs_[index]; }
2119 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002120 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002121 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002122
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002123 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002124
2125 int merged_index() const { return merged_index_; }
2126
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002127 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002128
2129#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002130 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002131#endif
2132
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002133 void InitRealUses(int id);
2134 void AddNonPhiUsesFrom(HPhi* other);
2135 void AddIndirectUsesTo(int* use_count);
2136
2137 int tagged_non_phi_uses() const {
2138 return non_phi_uses_[Representation::kTagged];
2139 }
2140 int int32_non_phi_uses() const {
2141 return non_phi_uses_[Representation::kInteger32];
2142 }
2143 int double_non_phi_uses() const {
2144 return non_phi_uses_[Representation::kDouble];
2145 }
2146 int tagged_indirect_uses() const {
2147 return indirect_uses_[Representation::kTagged];
2148 }
2149 int int32_indirect_uses() const {
2150 return indirect_uses_[Representation::kInteger32];
2151 }
2152 int double_indirect_uses() const {
2153 return indirect_uses_[Representation::kDouble];
2154 }
2155 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002156 bool is_live() { return is_live_; }
2157 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002158
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002159 static HPhi* cast(HValue* value) {
2160 ASSERT(value->IsPhi());
2161 return reinterpret_cast<HPhi*>(value);
2162 }
2163 virtual Opcode opcode() const { return HValue::kPhi; }
2164
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002165 virtual bool IsConvertibleToInteger() const {
2166 return is_convertible_to_integer_;
2167 }
2168
2169 void set_is_convertible_to_integer(bool b) {
2170 is_convertible_to_integer_ = b;
2171 }
2172
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002173 protected:
2174 virtual void DeleteFromGraph();
2175 virtual void InternalSetOperandAt(int index, HValue* value) {
2176 inputs_[index] = value;
2177 }
2178
2179 private:
2180 ZoneList<HValue*> inputs_;
2181 int merged_index_;
2182
2183 int non_phi_uses_[Representation::kNumRepresentations];
2184 int indirect_uses_[Representation::kNumRepresentations];
2185 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002186 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002187 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002188};
2189
2190
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002191class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002192 public:
2193 HArgumentsObject() {
2194 set_representation(Representation::Tagged());
2195 SetFlag(kIsArguments);
2196 }
2197
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002198 virtual Representation RequiredInputRepresentation(int index) const {
2199 return Representation::None();
2200 }
2201
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002202 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002203};
2204
2205
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002206class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002207 public:
2208 HConstant(Handle<Object> handle, Representation r);
2209
2210 Handle<Object> handle() const { return handle_; }
2211
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002212 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002213
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002214 virtual Representation RequiredInputRepresentation(int index) const {
2215 return Representation::None();
2216 }
2217
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002218 virtual bool IsConvertibleToInteger() const {
2219 if (handle_->IsSmi()) return true;
2220 if (handle_->IsHeapNumber() &&
2221 (HeapNumber::cast(*handle_)->value() ==
2222 static_cast<double>(NumberToInt32(*handle_)))) return true;
2223 return false;
2224 }
2225
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002226 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002227 virtual void PrintDataTo(StringStream* stream);
2228 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002229 bool IsInteger() const { return handle_->IsSmi(); }
2230 HConstant* CopyToRepresentation(Representation r) const;
2231 HConstant* CopyToTruncatedInt32() const;
2232 bool HasInteger32Value() const { return has_int32_value_; }
2233 int32_t Integer32Value() const {
2234 ASSERT(HasInteger32Value());
2235 return int32_value_;
2236 }
2237 bool HasDoubleValue() const { return has_double_value_; }
2238 double DoubleValue() const {
2239 ASSERT(HasDoubleValue());
2240 return double_value_;
2241 }
2242 bool HasStringValue() const { return handle_->IsString(); }
2243
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002244 bool ToBoolean() const;
2245
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002246 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002247 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002248 return reinterpret_cast<intptr_t>(*handle());
2249 }
2250
2251#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002252 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002253#endif
2254
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002255 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002256
2257 protected:
2258 virtual Range* InferRange();
2259
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002260 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002261 HConstant* other_constant = HConstant::cast(other);
2262 return handle().is_identical_to(other_constant->handle());
2263 }
2264
2265 private:
2266 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002267
2268 // The following two values represent the int32 and the double value of the
2269 // given constant if there is a lossless conversion between the constant
2270 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002271 bool has_int32_value_ : 1;
2272 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002273 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002274 double double_value_;
2275};
2276
2277
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002278class HBinaryOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002279 public:
2280 HBinaryOperation(HValue* left, HValue* right) {
2281 ASSERT(left != NULL && right != NULL);
2282 SetOperandAt(0, left);
2283 SetOperandAt(1, right);
2284 }
2285
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002286 HValue* left() { return OperandAt(0); }
2287 HValue* right() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002288
2289 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2290 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002291 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002292 if (IsCommutative() && left()->IsConstant()) return right();
2293 return left();
2294 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002295 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002296 if (IsCommutative() && left()->IsConstant()) return left();
2297 return right();
2298 }
2299
2300 virtual bool IsCommutative() const { return false; }
2301
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002302 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002303};
2304
2305
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002306class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002307 public:
2308 HApplyArguments(HValue* function,
2309 HValue* receiver,
2310 HValue* length,
2311 HValue* elements) {
2312 set_representation(Representation::Tagged());
2313 SetOperandAt(0, function);
2314 SetOperandAt(1, receiver);
2315 SetOperandAt(2, length);
2316 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002317 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002318 }
2319
2320 virtual Representation RequiredInputRepresentation(int index) const {
2321 // The length is untagged, all other inputs are tagged.
2322 return (index == 2)
2323 ? Representation::Integer32()
2324 : Representation::Tagged();
2325 }
2326
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002327 HValue* function() { return OperandAt(0); }
2328 HValue* receiver() { return OperandAt(1); }
2329 HValue* length() { return OperandAt(2); }
2330 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002331
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002332 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002333};
2334
2335
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002336class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002337 public:
2338 HArgumentsElements() {
2339 // The value produced by this instruction is a pointer into the stack
2340 // that looks as if it was a smi because of alignment.
2341 set_representation(Representation::Tagged());
2342 SetFlag(kUseGVN);
2343 }
2344
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002345 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002346
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002347 virtual Representation RequiredInputRepresentation(int index) const {
2348 return Representation::None();
2349 }
2350
ager@chromium.org378b34e2011-01-28 08:04:38 +00002351 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002352 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002353};
2354
2355
2356class HArgumentsLength: public HUnaryOperation {
2357 public:
2358 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2359 set_representation(Representation::Integer32());
2360 SetFlag(kUseGVN);
2361 }
2362
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002363 virtual Representation RequiredInputRepresentation(int index) const {
2364 return Representation::Tagged();
2365 }
2366
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002367 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002368
2369 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002370 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002371};
2372
2373
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002374class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002375 public:
2376 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2377 set_representation(Representation::Tagged());
2378 SetFlag(kUseGVN);
2379 SetOperandAt(0, arguments);
2380 SetOperandAt(1, length);
2381 SetOperandAt(2, index);
2382 }
2383
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002384 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002385
2386 virtual Representation RequiredInputRepresentation(int index) const {
2387 // The arguments elements is considered tagged.
2388 return index == 0
2389 ? Representation::Tagged()
2390 : Representation::Integer32();
2391 }
2392
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002393 HValue* arguments() { return OperandAt(0); }
2394 HValue* length() { return OperandAt(1); }
2395 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002396
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002397 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002398
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002399 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002400};
2401
2402
2403class HBoundsCheck: public HBinaryOperation {
2404 public:
2405 HBoundsCheck(HValue* index, HValue* length)
2406 : HBinaryOperation(index, length) {
2407 SetFlag(kUseGVN);
2408 }
2409
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002410 virtual bool IsCheckInstruction() const { return true; }
2411
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002412 virtual Representation RequiredInputRepresentation(int index) const {
2413 return Representation::Integer32();
2414 }
2415
2416#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002417 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002418#endif
2419
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002420 HValue* index() { return left(); }
2421 HValue* length() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002422
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002423 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002424
2425 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002426 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002427};
2428
2429
2430class HBitwiseBinaryOperation: public HBinaryOperation {
2431 public:
2432 HBitwiseBinaryOperation(HValue* left, HValue* right)
2433 : HBinaryOperation(left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002434 set_representation(Representation::Tagged());
2435 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002436 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002437 }
2438
2439 virtual Representation RequiredInputRepresentation(int index) const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002440 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002441 }
2442
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002443 virtual void RepresentationChanged(Representation to) {
2444 if (!to.IsTagged()) {
2445 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002446 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002447 SetFlag(kTruncatingToInt32);
2448 SetFlag(kUseGVN);
2449 }
2450 }
2451
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002452 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002453
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002454 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002455};
2456
2457
2458class HArithmeticBinaryOperation: public HBinaryOperation {
2459 public:
2460 HArithmeticBinaryOperation(HValue* left, HValue* right)
2461 : HBinaryOperation(left, right) {
2462 set_representation(Representation::Tagged());
2463 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002464 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002465 }
2466
2467 virtual void RepresentationChanged(Representation to) {
2468 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002469 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002470 SetFlag(kUseGVN);
2471 }
2472 }
2473
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002474 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002475 virtual Representation RequiredInputRepresentation(int index) const {
2476 return representation();
2477 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002478 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002479 if (left()->representation().Equals(right()->representation())) {
2480 return left()->representation();
2481 }
2482 return HValue::InferredRepresentation();
2483 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002484};
2485
2486
2487class HCompare: public HBinaryOperation {
2488 public:
2489 HCompare(HValue* left, HValue* right, Token::Value token)
2490 : HBinaryOperation(left, right), token_(token) {
2491 ASSERT(Token::IsCompareOp(token));
2492 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002493 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002494 }
2495
2496 void SetInputRepresentation(Representation r);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002497
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002498 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002499 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002500 }
2501
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002502 virtual Representation RequiredInputRepresentation(int index) const {
2503 return input_representation_;
2504 }
2505 Representation GetInputRepresentation() const {
2506 return input_representation_;
2507 }
2508 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002509 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002510
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002511 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002512
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002513 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002514 return HValue::Hashcode() * 7 + token_;
2515 }
2516
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002517 DECLARE_CONCRETE_INSTRUCTION(Compare)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002518
2519 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002520 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002521 HCompare* comp = HCompare::cast(other);
2522 return token_ == comp->token();
2523 }
2524
2525 private:
2526 Representation input_representation_;
2527 Token::Value token_;
2528};
2529
2530
2531class HCompareJSObjectEq: public HBinaryOperation {
2532 public:
2533 HCompareJSObjectEq(HValue* left, HValue* right)
2534 : HBinaryOperation(left, right) {
2535 set_representation(Representation::Tagged());
2536 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002537 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002538 }
2539
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002540 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002541 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002542 }
2543
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002544 virtual Representation RequiredInputRepresentation(int index) const {
2545 return Representation::Tagged();
2546 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002547 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002548
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002549 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002550
2551 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002552 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002553};
2554
2555
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002556class HCompareSymbolEq: public HBinaryOperation {
2557 public:
2558 HCompareSymbolEq(HValue* left, HValue* right, Token::Value op)
2559 : HBinaryOperation(left, right), op_(op) {
2560 ASSERT(op == Token::EQ || op == Token::EQ_STRICT);
2561 set_representation(Representation::Tagged());
2562 SetFlag(kUseGVN);
2563 SetFlag(kDependsOnMaps);
2564 }
2565
2566 Token::Value op() const { return op_; }
2567
2568 virtual bool EmitAtUses() {
2569 return !HasSideEffects() && !HasMultipleUses();
2570 }
2571
2572 virtual Representation RequiredInputRepresentation(int index) const {
2573 return Representation::Tagged();
2574 }
2575
2576 virtual HType CalculateInferredType() { return HType::Boolean(); }
2577
2578 DECLARE_CONCRETE_INSTRUCTION(CompareSymbolEq);
2579
2580 protected:
2581 virtual bool DataEquals(HValue* other) {
2582 return op_ == HCompareSymbolEq::cast(other)->op_;
2583 }
2584
2585 private:
2586 const Token::Value op_;
2587};
2588
2589
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002590class HUnaryPredicate: public HUnaryOperation {
2591 public:
2592 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2593 set_representation(Representation::Tagged());
2594 SetFlag(kUseGVN);
2595 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002596
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002597 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002598 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002599 }
2600
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002601 virtual Representation RequiredInputRepresentation(int index) const {
2602 return Representation::Tagged();
2603 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002604 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002605};
2606
2607
2608class HIsNull: public HUnaryPredicate {
2609 public:
2610 HIsNull(HValue* value, bool is_strict)
2611 : HUnaryPredicate(value), is_strict_(is_strict) { }
2612
2613 bool is_strict() const { return is_strict_; }
2614
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002615 DECLARE_CONCRETE_INSTRUCTION(IsNull)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002616
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002617 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002618 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002619 HIsNull* b = HIsNull::cast(other);
2620 return is_strict_ == b->is_strict();
2621 }
2622
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002623 private:
2624 bool is_strict_;
2625};
2626
2627
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002628class HIsObject: public HUnaryPredicate {
2629 public:
2630 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2631
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002632 DECLARE_CONCRETE_INSTRUCTION(IsObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002633
2634 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002635 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002636};
2637
2638
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002639class HIsSmi: public HUnaryPredicate {
2640 public:
2641 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2642
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002643 DECLARE_CONCRETE_INSTRUCTION(IsSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002644
2645 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002646 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002647};
2648
2649
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002650class HIsUndetectable: public HUnaryPredicate {
2651 public:
2652 explicit HIsUndetectable(HValue* value) : HUnaryPredicate(value) { }
2653
2654 DECLARE_CONCRETE_INSTRUCTION(IsUndetectable)
2655
2656 protected:
2657 virtual bool DataEquals(HValue* other) { return true; }
2658};
2659
2660
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002661class HIsConstructCall: public HTemplateInstruction<0> {
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002662 public:
2663 HIsConstructCall() {
2664 set_representation(Representation::Tagged());
2665 SetFlag(kUseGVN);
2666 }
2667
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002668 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002669 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002670 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002671
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002672 virtual Representation RequiredInputRepresentation(int index) const {
2673 return Representation::None();
2674 }
2675
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002676 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002677
2678 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002679 virtual bool DataEquals(HValue* other) { return true; }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002680};
2681
2682
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002683class HHasInstanceType: public HUnaryPredicate {
2684 public:
2685 HHasInstanceType(HValue* value, InstanceType type)
2686 : HUnaryPredicate(value), from_(type), to_(type) { }
2687 HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2688 : HUnaryPredicate(value), from_(from), to_(to) {
2689 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2690 }
2691
2692 InstanceType from() { return from_; }
2693 InstanceType to() { return to_; }
2694
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002695 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002696
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002697 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002698
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002699 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002700 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002701 HHasInstanceType* b = HHasInstanceType::cast(other);
2702 return (from_ == b->from()) && (to_ == b->to());
2703 }
2704
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002705 private:
2706 InstanceType from_;
2707 InstanceType to_; // Inclusive range, not all combinations work.
2708};
2709
2710
2711class HHasCachedArrayIndex: public HUnaryPredicate {
2712 public:
2713 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2714
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002715 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002716
2717 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002718 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002719};
2720
2721
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002722class HGetCachedArrayIndex: public HUnaryPredicate {
2723 public:
2724 explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2725
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002726 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002727
2728 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002729 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002730};
2731
2732
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002733class HClassOfTest: public HUnaryPredicate {
2734 public:
2735 HClassOfTest(HValue* value, Handle<String> class_name)
2736 : HUnaryPredicate(value), class_name_(class_name) { }
2737
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002738 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002739
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002740 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002741
2742 Handle<String> class_name() const { return class_name_; }
2743
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002744 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002745 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002746 HClassOfTest* b = HClassOfTest::cast(other);
2747 return class_name_.is_identical_to(b->class_name_);
2748 }
2749
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002750 private:
2751 Handle<String> class_name_;
2752};
2753
2754
2755class HTypeofIs: public HUnaryPredicate {
2756 public:
2757 HTypeofIs(HValue* value, Handle<String> type_literal)
2758 : HUnaryPredicate(value), type_literal_(type_literal) { }
2759
2760 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002761 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002762
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002763 DECLARE_CONCRETE_INSTRUCTION(TypeofIs)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002764
2765 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002766 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002767 HTypeofIs* b = HTypeofIs::cast(other);
2768 return type_literal_.is_identical_to(b->type_literal_);
2769 }
2770
2771 private:
2772 Handle<String> type_literal_;
2773};
2774
2775
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002776class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002777 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002778 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2779 SetOperandAt(0, context);
2780 SetOperandAt(1, left);
2781 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002782 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002783 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002784 }
2785
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002786 HValue* context() { return OperandAt(0); }
2787 HValue* left() { return OperandAt(1); }
2788 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002789
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002790 virtual bool EmitAtUses() {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002791 return !HasSideEffects() && !HasMultipleUses();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002792 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002793
2794 virtual Representation RequiredInputRepresentation(int index) const {
2795 return Representation::Tagged();
2796 }
2797
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002798 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002799
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002800 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002801};
2802
2803
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002804class HInstanceOfKnownGlobal: public HUnaryOperation {
2805 public:
2806 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2807 : HUnaryOperation(left), function_(right) {
2808 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002809 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002810 }
2811
2812 Handle<JSFunction> function() { return function_; }
2813
2814 virtual Representation RequiredInputRepresentation(int index) const {
2815 return Representation::Tagged();
2816 }
2817
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002818 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002819
2820 private:
2821 Handle<JSFunction> function_;
2822};
2823
2824
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002825class HPower: public HBinaryOperation {
2826 public:
2827 HPower(HValue* left, HValue* right)
2828 : HBinaryOperation(left, right) {
2829 set_representation(Representation::Double());
2830 SetFlag(kUseGVN);
2831 }
2832
2833 virtual Representation RequiredInputRepresentation(int index) const {
2834 return (index == 1) ? Representation::None() : Representation::Double();
2835 }
2836
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002837 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002838
2839 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002840 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002841};
2842
2843
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002844class HAdd: public HArithmeticBinaryOperation {
2845 public:
2846 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2847 SetFlag(kCanOverflow);
2848 }
2849
2850 // Add is only commutative if two integer values are added and not if two
2851 // tagged values are added (because it might be a String concatenation).
2852 virtual bool IsCommutative() const {
2853 return !representation().IsTagged();
2854 }
2855
2856 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2857
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002858 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002859
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002860 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002861
2862 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002863 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002864
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002865 virtual Range* InferRange();
2866};
2867
2868
2869class HSub: public HArithmeticBinaryOperation {
2870 public:
2871 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2872 SetFlag(kCanOverflow);
2873 }
2874
2875 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2876
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002877 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002878
2879 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002880 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002881
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002882 virtual Range* InferRange();
2883};
2884
2885
2886class HMul: public HArithmeticBinaryOperation {
2887 public:
2888 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2889 SetFlag(kCanOverflow);
2890 }
2891
2892 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2893
2894 // Only commutative if it is certain that not two objects are multiplicated.
2895 virtual bool IsCommutative() const {
2896 return !representation().IsTagged();
2897 }
2898
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002899 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002900
2901 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002902 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002903
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002904 virtual Range* InferRange();
2905};
2906
2907
2908class HMod: public HArithmeticBinaryOperation {
2909 public:
2910 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2911 SetFlag(kCanBeDivByZero);
2912 }
2913
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002914 bool HasPowerOf2Divisor() {
2915 if (right()->IsConstant() &&
2916 HConstant::cast(right())->HasInteger32Value()) {
2917 int32_t value = HConstant::cast(right())->Integer32Value();
2918 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2919 }
2920
2921 return false;
2922 }
2923
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002924 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2925
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002926 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002927
2928 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002929 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002930
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002931 virtual Range* InferRange();
2932};
2933
2934
2935class HDiv: public HArithmeticBinaryOperation {
2936 public:
2937 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2938 SetFlag(kCanBeDivByZero);
2939 SetFlag(kCanOverflow);
2940 }
2941
2942 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2943
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002944 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002945
2946 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002947 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002948
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002949 virtual Range* InferRange();
2950};
2951
2952
2953class HBitAnd: public HBitwiseBinaryOperation {
2954 public:
2955 HBitAnd(HValue* left, HValue* right)
2956 : HBitwiseBinaryOperation(left, right) { }
2957
2958 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002959 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002960
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002961 DECLARE_CONCRETE_INSTRUCTION(BitAnd)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002962
2963 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002964 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002965
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002966 virtual Range* InferRange();
2967};
2968
2969
2970class HBitXor: public HBitwiseBinaryOperation {
2971 public:
2972 HBitXor(HValue* left, HValue* right)
2973 : HBitwiseBinaryOperation(left, right) { }
2974
2975 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002976 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002977
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002978 DECLARE_CONCRETE_INSTRUCTION(BitXor)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002979
2980 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002981 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002982};
2983
2984
2985class HBitOr: public HBitwiseBinaryOperation {
2986 public:
2987 HBitOr(HValue* left, HValue* right)
2988 : HBitwiseBinaryOperation(left, right) { }
2989
2990 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002991 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002992
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002993 DECLARE_CONCRETE_INSTRUCTION(BitOr)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002994
2995 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002996 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002997
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002998 virtual Range* InferRange();
2999};
3000
3001
3002class HShl: public HBitwiseBinaryOperation {
3003 public:
3004 HShl(HValue* left, HValue* right)
3005 : HBitwiseBinaryOperation(left, right) { }
3006
3007 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003008 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003009
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003010 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003011
3012 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003013 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003014};
3015
3016
3017class HShr: public HBitwiseBinaryOperation {
3018 public:
3019 HShr(HValue* left, HValue* right)
3020 : HBitwiseBinaryOperation(left, right) { }
3021
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003022 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003023
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003024 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003025
3026 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003027 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003028};
3029
3030
3031class HSar: public HBitwiseBinaryOperation {
3032 public:
3033 HSar(HValue* left, HValue* right)
3034 : HBitwiseBinaryOperation(left, right) { }
3035
3036 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003037 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003038
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003039 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003040
3041 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003042 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003043};
3044
3045
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003046class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003047 public:
3048 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
3049 SetFlag(kChangesOsrEntries);
3050 }
3051
3052 int ast_id() const { return ast_id_; }
3053
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003054 virtual Representation RequiredInputRepresentation(int index) const {
3055 return Representation::None();
3056 }
3057
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003058 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003059
3060 private:
3061 int ast_id_;
3062};
3063
3064
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003065class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003066 public:
3067 explicit HParameter(unsigned index) : index_(index) {
3068 set_representation(Representation::Tagged());
3069 }
3070
3071 unsigned index() const { return index_; }
3072
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003073 virtual void PrintDataTo(StringStream* stream);
3074
3075 virtual Representation RequiredInputRepresentation(int index) const {
3076 return Representation::None();
3077 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003078
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003079 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003080
3081 private:
3082 unsigned index_;
3083};
3084
3085
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003086class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003087 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003088 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
3089 : HUnaryCall(context, argument_count),
3090 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003091 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003092 }
3093
3094 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003095
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003096 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003097
3098 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
3099 transcendental_type_ = transcendental_type;
3100 }
3101 TranscendentalCache::Type transcendental_type() {
3102 return transcendental_type_;
3103 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003104
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003105 virtual void PrintDataTo(StringStream* stream);
3106
3107 virtual Representation RequiredInputRepresentation(int index) const {
3108 return Representation::Tagged();
3109 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003110
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003111 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003112
3113 private:
3114 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003115 TranscendentalCache::Type transcendental_type_;
3116};
3117
3118
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003119class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003120 public:
3121 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
3122
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003123 virtual Representation RequiredInputRepresentation(int index) const {
3124 return Representation::None();
3125 }
3126
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003127 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003128};
3129
3130
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003131class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003132 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003133 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003134 : cell_(cell), check_hole_value_(check_hole_value) {
3135 set_representation(Representation::Tagged());
3136 SetFlag(kUseGVN);
3137 SetFlag(kDependsOnGlobalVars);
3138 }
3139
3140 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
3141 bool check_hole_value() const { return check_hole_value_; }
3142
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003143 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003144
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003145 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003146 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003147 return reinterpret_cast<intptr_t>(*cell_);
3148 }
3149
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003150 virtual Representation RequiredInputRepresentation(int index) const {
3151 return Representation::None();
3152 }
3153
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003154 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003155
3156 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003157 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003158 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003159 return cell_.is_identical_to(b->cell());
3160 }
3161
3162 private:
3163 Handle<JSGlobalPropertyCell> cell_;
3164 bool check_hole_value_;
3165};
3166
3167
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003168class HLoadGlobalGeneric: public HBinaryOperation {
3169 public:
3170 HLoadGlobalGeneric(HValue* context,
3171 HValue* global_object,
3172 Handle<Object> name,
3173 bool for_typeof)
3174 : HBinaryOperation(context, global_object),
3175 name_(name),
3176 for_typeof_(for_typeof) {
3177 set_representation(Representation::Tagged());
3178 SetAllSideEffects();
3179 }
3180
3181 HValue* context() { return OperandAt(0); }
3182 HValue* global_object() { return OperandAt(1); }
3183 Handle<Object> name() const { return name_; }
3184 bool for_typeof() const { return for_typeof_; }
3185
3186 virtual void PrintDataTo(StringStream* stream);
3187
3188 virtual Representation RequiredInputRepresentation(int index) const {
3189 return Representation::Tagged();
3190 }
3191
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003192 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003193
3194 private:
3195 Handle<Object> name_;
3196 bool for_typeof_;
3197};
3198
3199
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003200class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003201 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003202 HStoreGlobalCell(HValue* value,
3203 Handle<JSGlobalPropertyCell> cell,
3204 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003205 : HUnaryOperation(value),
3206 cell_(cell),
3207 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003208 SetFlag(kChangesGlobalVars);
3209 }
3210
3211 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003212 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003213
3214 virtual Representation RequiredInputRepresentation(int index) const {
3215 return Representation::Tagged();
3216 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003217 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003218
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003219 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003220
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003221 private:
3222 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00003223 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003224};
3225
3226
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003227class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3228 public:
3229 HStoreGlobalGeneric(HValue* context,
3230 HValue* global_object,
3231 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003232 HValue* value,
3233 bool strict_mode)
3234 : name_(name),
3235 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003236 SetOperandAt(0, context);
3237 SetOperandAt(1, global_object);
3238 SetOperandAt(2, value);
3239 set_representation(Representation::Tagged());
3240 SetAllSideEffects();
3241 }
3242
3243 HValue* context() { return OperandAt(0); }
3244 HValue* global_object() { return OperandAt(1); }
3245 Handle<Object> name() const { return name_; }
3246 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003247 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003248
3249 virtual void PrintDataTo(StringStream* stream);
3250
3251 virtual Representation RequiredInputRepresentation(int index) const {
3252 return Representation::Tagged();
3253 }
3254
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003255 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003256
3257 private:
3258 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003259 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00003260};
3261
3262
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003263class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003264 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003265 HLoadContextSlot(HValue* context , int slot_index)
3266 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003267 set_representation(Representation::Tagged());
3268 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003269 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003270 }
3271
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003272 int slot_index() const { return slot_index_; }
3273
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003274 virtual Representation RequiredInputRepresentation(int index) const {
3275 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003276 }
3277
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003278 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003279
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003280 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003281
3282 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003283 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003284 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003285 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003286 }
3287
3288 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003289 int slot_index_;
3290};
3291
3292
3293static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
3294 return !value->type().IsSmi() &&
3295 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
3296}
3297
3298
3299class HStoreContextSlot: public HBinaryOperation {
3300 public:
3301 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
3302 : HBinaryOperation(context, value), slot_index_(slot_index) {
3303 SetFlag(kChangesContextSlots);
3304 }
3305
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003306 HValue* context() { return OperandAt(0); }
3307 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003308 int slot_index() const { return slot_index_; }
3309
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003310 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003311 return StoringValueNeedsWriteBarrier(value());
3312 }
3313
3314 virtual Representation RequiredInputRepresentation(int index) const {
3315 return Representation::Tagged();
3316 }
3317
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003318 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003319
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003320 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003321
3322 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003323 int slot_index_;
3324};
3325
3326
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003327class HLoadNamedField: public HUnaryOperation {
3328 public:
3329 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3330 : HUnaryOperation(object),
3331 is_in_object_(is_in_object),
3332 offset_(offset) {
3333 set_representation(Representation::Tagged());
3334 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003335 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003336 if (is_in_object) {
3337 SetFlag(kDependsOnInobjectFields);
3338 } else {
3339 SetFlag(kDependsOnBackingStoreFields);
3340 }
3341 }
3342
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003343 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003344 bool is_in_object() const { return is_in_object_; }
3345 int offset() const { return offset_; }
3346
3347 virtual Representation RequiredInputRepresentation(int index) const {
3348 return Representation::Tagged();
3349 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003350 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003351
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003352 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003353
3354 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003355 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003356 HLoadNamedField* b = HLoadNamedField::cast(other);
3357 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3358 }
3359
3360 private:
3361 bool is_in_object_;
3362 int offset_;
3363};
3364
3365
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003366class HLoadNamedFieldPolymorphic: public HUnaryOperation {
3367 public:
3368 HLoadNamedFieldPolymorphic(HValue* object,
3369 ZoneMapList* types,
3370 Handle<String> name);
3371
3372 HValue* object() { return OperandAt(0); }
3373 ZoneMapList* types() { return &types_; }
3374 Handle<String> name() { return name_; }
3375 bool need_generic() { return need_generic_; }
3376
3377 virtual Representation RequiredInputRepresentation(int index) const {
3378 return Representation::Tagged();
3379 }
3380
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003381 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003382
3383 static const int kMaxLoadPolymorphism = 4;
3384
3385 protected:
3386 virtual bool DataEquals(HValue* value);
3387
3388 private:
3389 ZoneMapList types_;
3390 Handle<String> name_;
3391 bool need_generic_;
3392};
3393
3394
3395
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003396class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003397 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003398 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
3399 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003400 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003401 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003402 }
3403
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003404 HValue* context() { return OperandAt(0); }
3405 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003406 Handle<Object> name() const { return name_; }
3407
3408 virtual Representation RequiredInputRepresentation(int index) const {
3409 return Representation::Tagged();
3410 }
3411
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003412 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003413
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003414 private:
3415 Handle<Object> name_;
3416};
3417
3418
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003419class HLoadFunctionPrototype: public HUnaryOperation {
3420 public:
3421 explicit HLoadFunctionPrototype(HValue* function)
3422 : HUnaryOperation(function) {
3423 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003424 SetFlag(kUseGVN);
3425 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003426 }
3427
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003428 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003429
3430 virtual Representation RequiredInputRepresentation(int index) const {
3431 return Representation::Tagged();
3432 }
3433
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003434 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003435
3436 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003437 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003438};
3439
3440
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003441class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003442 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003443 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003444 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003445 SetFlag(kDependsOnArrayElements);
3446 SetFlag(kUseGVN);
3447 }
3448
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003449 HValue* object() { return OperandAt(0); }
3450 HValue* key() { return OperandAt(1); }
3451
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003452 virtual Representation RequiredInputRepresentation(int index) const {
3453 // The key is supposed to be Integer32.
3454 return (index == 1) ? Representation::Integer32()
3455 : Representation::Tagged();
3456 }
3457
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003458 virtual void PrintDataTo(StringStream* stream);
3459
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003460 bool RequiresHoleCheck() const;
3461
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003462 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003463
3464 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003465 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003466};
3467
3468
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003469class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003470 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003471 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3472 HValue* key,
3473 ExternalArrayType array_type)
3474 : HBinaryOperation(external_elements, key),
3475 array_type_(array_type) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003476 if (array_type == kExternalFloatArray ||
3477 array_type == kExternalDoubleArray) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003478 set_representation(Representation::Double());
3479 } else {
3480 set_representation(Representation::Integer32());
3481 }
3482 SetFlag(kDependsOnSpecializedArrayElements);
3483 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003484 SetFlag(kDependsOnCalls);
3485 SetFlag(kUseGVN);
3486 }
3487
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003488 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003489
3490 virtual Representation RequiredInputRepresentation(int index) const {
3491 // The key is supposed to be Integer32, but the base pointer
3492 // for the element load is a naked pointer.
3493 return (index == 1) ? Representation::Integer32()
3494 : Representation::External();
3495 }
3496
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003497 HValue* external_pointer() { return OperandAt(0); }
3498 HValue* key() { return OperandAt(1); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003499 ExternalArrayType array_type() const { return array_type_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003500
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003501 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003502
3503 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003504 virtual bool DataEquals(HValue* other) {
3505 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3506 HLoadKeyedSpecializedArrayElement* cast_other =
3507 HLoadKeyedSpecializedArrayElement::cast(other);
3508 return array_type_ == cast_other->array_type();
3509 }
3510
3511 private:
3512 ExternalArrayType array_type_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003513};
3514
3515
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003516class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003517 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00003518 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003519 set_representation(Representation::Tagged());
3520 SetOperandAt(0, obj);
3521 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003522 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003523 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003524 }
3525
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003526 HValue* object() { return OperandAt(0); }
3527 HValue* key() { return OperandAt(1); }
3528 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003529
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003530 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003531
3532 virtual Representation RequiredInputRepresentation(int index) const {
3533 return Representation::Tagged();
3534 }
3535
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003536 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003537};
3538
3539
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003540class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003541 public:
3542 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003543 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003544 HValue* val,
3545 bool in_object,
3546 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003547 : HBinaryOperation(obj, val),
3548 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003549 is_in_object_(in_object),
3550 offset_(offset) {
3551 if (is_in_object_) {
3552 SetFlag(kChangesInobjectFields);
3553 } else {
3554 SetFlag(kChangesBackingStoreFields);
3555 }
3556 }
3557
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003558 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003559
3560 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003561 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003562 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003563 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003564
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003565 HValue* object() { return OperandAt(0); }
3566 HValue* value() { return OperandAt(1); }
3567
3568 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003569 bool is_in_object() const { return is_in_object_; }
3570 int offset() const { return offset_; }
3571 Handle<Map> transition() const { return transition_; }
3572 void set_transition(Handle<Map> map) { transition_ = map; }
3573
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003574 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003575 return StoringValueNeedsWriteBarrier(value());
3576 }
3577
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003578 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003579 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003580 bool is_in_object_;
3581 int offset_;
3582 Handle<Map> transition_;
3583};
3584
3585
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003586class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003587 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003588 HStoreNamedGeneric(HValue* context,
3589 HValue* object,
3590 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003591 HValue* value,
3592 bool strict_mode)
3593 : name_(name),
3594 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003595 SetOperandAt(0, object);
3596 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003597 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003598 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003599 }
3600
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003601 HValue* object() { return OperandAt(0); }
3602 HValue* value() { return OperandAt(1); }
3603 HValue* context() { return OperandAt(2); }
3604 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003605 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003606
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003607 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003608
3609 virtual Representation RequiredInputRepresentation(int index) const {
3610 return Representation::Tagged();
3611 }
3612
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003613 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003614
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003615 private:
3616 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003617 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003618};
3619
3620
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003621class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003622 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003623 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3624 SetOperandAt(0, obj);
3625 SetOperandAt(1, key);
3626 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003627 SetFlag(kChangesArrayElements);
3628 }
3629
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003630 virtual Representation RequiredInputRepresentation(int index) const {
3631 // The key is supposed to be Integer32.
3632 return (index == 1) ? Representation::Integer32()
3633 : Representation::Tagged();
3634 }
3635
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003636 HValue* object() { return OperandAt(0); }
3637 HValue* key() { return OperandAt(1); }
3638 HValue* value() { return OperandAt(2); }
3639
3640 bool NeedsWriteBarrier() {
3641 return StoringValueNeedsWriteBarrier(value());
3642 }
3643
3644 virtual void PrintDataTo(StringStream* stream);
3645
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003646 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003647};
3648
3649
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003650class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003651 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003652 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3653 HValue* key,
3654 HValue* val,
3655 ExternalArrayType array_type)
3656 : array_type_(array_type) {
3657 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003658 SetOperandAt(0, external_elements);
3659 SetOperandAt(1, key);
3660 SetOperandAt(2, val);
3661 }
3662
3663 virtual void PrintDataTo(StringStream* stream);
3664
3665 virtual Representation RequiredInputRepresentation(int index) const {
3666 if (index == 0) {
3667 return Representation::External();
3668 } else {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003669 if (index == 2 && (array_type() == kExternalFloatArray ||
3670 array_type() == kExternalDoubleArray)) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003671 return Representation::Double();
3672 } else {
3673 return Representation::Integer32();
3674 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003675 }
3676 }
3677
3678 HValue* external_pointer() { return OperandAt(0); }
3679 HValue* key() { return OperandAt(1); }
3680 HValue* value() { return OperandAt(2); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003681 ExternalArrayType array_type() const { return array_type_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003682
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003683 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3684
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003685 private:
3686 ExternalArrayType array_type_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003687};
3688
3689
3690class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003691 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003692 HStoreKeyedGeneric(HValue* context,
3693 HValue* object,
3694 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003695 HValue* value,
3696 bool strict_mode)
3697 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003698 SetOperandAt(0, object);
3699 SetOperandAt(1, key);
3700 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003701 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003702 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003703 }
3704
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003705 HValue* object() { return OperandAt(0); }
3706 HValue* key() { return OperandAt(1); }
3707 HValue* value() { return OperandAt(2); }
3708 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003709 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003710
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003711 virtual Representation RequiredInputRepresentation(int index) const {
3712 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003713 }
3714
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003715 virtual void PrintDataTo(StringStream* stream);
3716
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003717 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003718
3719 private:
3720 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003721};
3722
3723
danno@chromium.org160a7b02011-04-18 15:51:38 +00003724class HStringAdd: public HBinaryOperation {
3725 public:
3726 HStringAdd(HValue* left, HValue* right) : HBinaryOperation(left, right) {
3727 set_representation(Representation::Tagged());
3728 SetFlag(kUseGVN);
3729 SetFlag(kDependsOnMaps);
3730 }
3731
3732 virtual Representation RequiredInputRepresentation(int index) const {
3733 return Representation::Tagged();
3734 }
3735
3736 virtual HType CalculateInferredType() {
3737 return HType::String();
3738 }
3739
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003740 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00003741
3742 protected:
3743 virtual bool DataEquals(HValue* other) { return true; }
3744};
3745
3746
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003747class HStringCharCodeAt: public HBinaryOperation {
3748 public:
3749 HStringCharCodeAt(HValue* string, HValue* index)
3750 : HBinaryOperation(string, index) {
3751 set_representation(Representation::Integer32());
3752 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003753 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003754 }
3755
3756 virtual Representation RequiredInputRepresentation(int index) const {
3757 // The index is supposed to be Integer32.
3758 return (index == 1) ? Representation::Integer32()
3759 : Representation::Tagged();
3760 }
3761
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003762 HValue* string() { return OperandAt(0); }
3763 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003764
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003765 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003766
3767 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003768 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003769
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003770 virtual Range* InferRange() {
3771 return new Range(0, String::kMaxUC16CharCode);
3772 }
3773};
3774
3775
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003776class HStringCharFromCode: public HUnaryOperation {
3777 public:
3778 explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
3779 set_representation(Representation::Tagged());
3780 SetFlag(kUseGVN);
3781 }
3782
3783 virtual Representation RequiredInputRepresentation(int index) const {
3784 return Representation::Integer32();
3785 }
3786
3787 virtual bool DataEquals(HValue* other) { return true; }
3788
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003789 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003790};
3791
3792
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003793class HStringLength: public HUnaryOperation {
3794 public:
3795 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3796 set_representation(Representation::Tagged());
3797 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003798 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003799 }
3800
3801 virtual Representation RequiredInputRepresentation(int index) const {
3802 return Representation::Tagged();
3803 }
3804
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003805 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003806 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3807 return HType::Smi();
3808 }
3809
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003810 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003811
3812 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003813 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003814
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003815 virtual Range* InferRange() {
3816 return new Range(0, String::kMaxLength);
3817 }
3818};
3819
3820
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003821template <int V>
3822class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003823 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003824 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003825 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003826 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003827 }
3828
3829 int literal_index() const { return literal_index_; }
3830 int depth() const { return depth_; }
3831
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003832 private:
3833 int literal_index_;
3834 int depth_;
3835};
3836
3837
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003838class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003839 public:
3840 HArrayLiteral(Handle<FixedArray> constant_elements,
3841 int length,
3842 int literal_index,
3843 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003844 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003845 length_(length),
3846 constant_elements_(constant_elements) {}
3847
3848 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3849 int length() const { return length_; }
3850
3851 bool IsCopyOnWrite() const;
3852
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003853 virtual Representation RequiredInputRepresentation(int index) const {
3854 return Representation::None();
3855 }
3856
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003857 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003858
3859 private:
3860 int length_;
3861 Handle<FixedArray> constant_elements_;
3862};
3863
3864
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003865class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003866 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003867 HObjectLiteral(HValue* context,
3868 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003869 bool fast_elements,
3870 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003871 int depth,
3872 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003873 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003874 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003875 fast_elements_(fast_elements),
3876 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003877 SetOperandAt(0, context);
3878 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003879
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003880 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003881 Handle<FixedArray> constant_properties() const {
3882 return constant_properties_;
3883 }
3884 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003885 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003886
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003887 virtual Representation RequiredInputRepresentation(int index) const {
3888 return Representation::Tagged();
3889 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003890
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003891 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003892
3893 private:
3894 Handle<FixedArray> constant_properties_;
3895 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003896 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003897};
3898
3899
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003900class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003901 public:
3902 HRegExpLiteral(Handle<String> pattern,
3903 Handle<String> flags,
3904 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003905 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003906 pattern_(pattern),
3907 flags_(flags) { }
3908
3909 Handle<String> pattern() { return pattern_; }
3910 Handle<String> flags() { return flags_; }
3911
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003912 virtual Representation RequiredInputRepresentation(int index) const {
3913 return Representation::None();
3914 }
3915
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003916 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003917
3918 private:
3919 Handle<String> pattern_;
3920 Handle<String> flags_;
3921};
3922
3923
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003924class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003925 public:
3926 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3927 : shared_info_(shared), pretenure_(pretenure) {
3928 set_representation(Representation::Tagged());
3929 }
3930
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003931 virtual Representation RequiredInputRepresentation(int index) const {
3932 return Representation::None();
3933 }
3934
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003935 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003936
3937 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3938 bool pretenure() const { return pretenure_; }
3939
3940 private:
3941 Handle<SharedFunctionInfo> shared_info_;
3942 bool pretenure_;
3943};
3944
3945
3946class HTypeof: public HUnaryOperation {
3947 public:
3948 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
3949 set_representation(Representation::Tagged());
3950 }
3951
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003952 virtual Representation RequiredInputRepresentation(int index) const {
3953 return Representation::Tagged();
3954 }
3955
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003956 DECLARE_CONCRETE_INSTRUCTION(Typeof)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003957};
3958
3959
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003960class HToFastProperties: public HUnaryOperation {
3961 public:
3962 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
3963 // This instruction is not marked as having side effects, but
3964 // changes the map of the input operand. Use it only when creating
3965 // object literals.
3966 ASSERT(value->IsObjectLiteral());
3967 set_representation(Representation::Tagged());
3968 }
3969
3970 virtual Representation RequiredInputRepresentation(int index) const {
3971 return Representation::Tagged();
3972 }
3973
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003974 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003975};
3976
3977
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003978class HValueOf: public HUnaryOperation {
3979 public:
3980 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
3981 set_representation(Representation::Tagged());
3982 }
3983
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003984 virtual Representation RequiredInputRepresentation(int index) const {
3985 return Representation::Tagged();
3986 }
3987
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003988 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003989};
3990
3991
3992class HDeleteProperty: public HBinaryOperation {
3993 public:
3994 HDeleteProperty(HValue* obj, HValue* key)
3995 : HBinaryOperation(obj, key) {
3996 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003997 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003998 }
3999
4000 virtual Representation RequiredInputRepresentation(int index) const {
4001 return Representation::Tagged();
4002 }
4003
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004004 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004005
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004006 HValue* object() { return left(); }
4007 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004008};
4009
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004010
4011class HIn: public HTemplateInstruction<2> {
4012 public:
4013 HIn(HValue* key, HValue* object) {
4014 SetOperandAt(0, key);
4015 SetOperandAt(1, object);
4016 set_representation(Representation::Tagged());
4017 SetAllSideEffects();
4018 }
4019
4020 HValue* key() { return OperandAt(0); }
4021 HValue* object() { return OperandAt(1); }
4022
4023 virtual Representation RequiredInputRepresentation(int index) const {
4024 return Representation::Tagged();
4025 }
4026
4027 virtual HType CalculateInferredType() {
4028 return HType::Boolean();
4029 }
4030
4031 virtual void PrintDataTo(StringStream* stream);
4032
4033 DECLARE_CONCRETE_INSTRUCTION(In)
4034};
4035
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004036#undef DECLARE_INSTRUCTION
4037#undef DECLARE_CONCRETE_INSTRUCTION
4038
4039} } // namespace v8::internal
4040
4041#endif // V8_HYDROGEN_INSTRUCTIONS_H_