blob: e32a09c7202a1c0396602156fef9abe82c744173 [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
kasperl@chromium.orga5551262010-12-07 12:49:48 +000033#include "code-stubs.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000034#include "small-pointer-list.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000035#include "string-stream.h"
36#include "zone.h"
37
38namespace v8 {
39namespace internal {
40
41// Forward declarations.
42class HBasicBlock;
43class HEnvironment;
44class HInstruction;
45class HLoopInformation;
46class HValue;
47class LInstruction;
48class LChunkBuilder;
49
50
kasperl@chromium.orga5551262010-12-07 12:49:48 +000051#define HYDROGEN_ALL_INSTRUCTION_LIST(V) \
52 V(ArithmeticBinaryOperation) \
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +000053 V(BinaryCall) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000054 V(BinaryOperation) \
55 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000056 V(ControlInstruction) \
57 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000058 V(Phi) \
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +000059 V(UnaryCall) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000060 V(UnaryControlInstruction) \
61 V(UnaryOperation) \
62 HYDROGEN_CONCRETE_INSTRUCTION_LIST(V)
63
64
65#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +000066 V(AbnormalExit) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000067 V(AccessArgumentsAt) \
68 V(Add) \
69 V(ApplyArguments) \
70 V(ArgumentsElements) \
71 V(ArgumentsLength) \
72 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000073 V(ArrayLiteral) \
74 V(BitAnd) \
75 V(BitNot) \
76 V(BitOr) \
77 V(BitXor) \
78 V(BlockEntry) \
79 V(BoundsCheck) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000080 V(CallConstantFunction) \
81 V(CallFunction) \
82 V(CallGlobal) \
83 V(CallKeyed) \
84 V(CallKnownGlobal) \
85 V(CallNamed) \
86 V(CallNew) \
87 V(CallRuntime) \
88 V(CallStub) \
89 V(Change) \
90 V(CheckFunction) \
91 V(CheckInstanceType) \
92 V(CheckMap) \
93 V(CheckNonSmi) \
94 V(CheckPrototypeMaps) \
95 V(CheckSmi) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +000096 V(ClassOfTest) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000097 V(Compare) \
98 V(CompareJSObjectEq) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000099 V(CompareMap) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000100 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000101 V(Context) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000102 V(DeleteProperty) \
103 V(Deoptimize) \
104 V(Div) \
105 V(EnterInlined) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000106 V(ExternalArrayLength) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000107 V(FixedArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000108 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000109 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000110 V(GlobalObject) \
111 V(GlobalReceiver) \
112 V(Goto) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000113 V(HasInstanceType) \
114 V(HasCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000115 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000116 V(InstanceOfKnownGlobal) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000117 V(InvokeFunction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000118 V(IsNull) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000119 V(IsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000120 V(IsSmi) \
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +0000121 V(IsConstructCall) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000122 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000123 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000124 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000125 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000126 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000127 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000128 V(LoadGlobalCell) \
129 V(LoadGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000130 V(LoadKeyedFastElement) \
131 V(LoadKeyedGeneric) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000132 V(LoadKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000133 V(LoadNamedField) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000134 V(LoadNamedFieldPolymorphic) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000135 V(LoadNamedGeneric) \
136 V(Mod) \
137 V(Mul) \
138 V(ObjectLiteral) \
139 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000140 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000141 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000142 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000143 V(PushArgument) \
144 V(RegExpLiteral) \
145 V(Return) \
146 V(Sar) \
147 V(Shl) \
148 V(Shr) \
149 V(Simulate) \
150 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000151 V(StoreContextSlot) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000152 V(StoreGlobalCell) \
153 V(StoreGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000154 V(StoreKeyedFastElement) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000155 V(StoreKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000156 V(StoreKeyedGeneric) \
157 V(StoreNamedField) \
158 V(StoreNamedGeneric) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000159 V(StringAdd) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000160 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000161 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000162 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000163 V(Sub) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000164 V(Test) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000165 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000166 V(ToFastProperties) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000167 V(Typeof) \
168 V(TypeofIs) \
169 V(UnaryMathOperation) \
170 V(UnknownOSRValue) \
171 V(ValueOf)
172
173#define GVN_FLAG_LIST(V) \
174 V(Calls) \
175 V(InobjectFields) \
176 V(BackingStoreFields) \
177 V(ArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000178 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000179 V(GlobalVars) \
180 V(Maps) \
181 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000182 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000183 V(OsrEntries)
184
185#define DECLARE_INSTRUCTION(type) \
186 virtual bool Is##type() const { return true; } \
187 static H##type* cast(HValue* value) { \
188 ASSERT(value->Is##type()); \
189 return reinterpret_cast<H##type*>(value); \
190 } \
191 Opcode opcode() const { return HValue::k##type; }
192
193
194#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
195 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
196 virtual const char* Mnemonic() const { return mnemonic; } \
197 DECLARE_INSTRUCTION(type)
198
199
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000200class Range: public ZoneObject {
201 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000202 Range()
203 : lower_(kMinInt),
204 upper_(kMaxInt),
205 next_(NULL),
206 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000207
208 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000209 : lower_(lower),
210 upper_(upper),
211 next_(NULL),
212 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000213
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000214 int32_t upper() const { return upper_; }
215 int32_t lower() const { return lower_; }
216 Range* next() const { return next_; }
217 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
218 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000219 Range* Copy() const { return new Range(lower_, upper_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000220 int32_t Mask() const;
221 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
222 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
223 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
224 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000225 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
226 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
227 bool IsInSmiRange() const {
228 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000229 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000230 void KeepOrder();
231 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000232
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000233 void StackUpon(Range* other) {
234 Intersect(other);
235 next_ = other;
236 }
237
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000238 void Intersect(Range* other);
239 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000240
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000241 void AddConstant(int32_t value);
242 void Sar(int32_t value);
243 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000244 bool AddAndCheckOverflow(Range* other);
245 bool SubAndCheckOverflow(Range* other);
246 bool MulAndCheckOverflow(Range* other);
247
248 private:
249 int32_t lower_;
250 int32_t upper_;
251 Range* next_;
252 bool can_be_minus_zero_;
253};
254
255
256class Representation {
257 public:
258 enum Kind {
259 kNone,
260 kTagged,
261 kDouble,
262 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000263 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000264 kNumRepresentations
265 };
266
267 Representation() : kind_(kNone) { }
268
269 static Representation None() { return Representation(kNone); }
270 static Representation Tagged() { return Representation(kTagged); }
271 static Representation Integer32() { return Representation(kInteger32); }
272 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000273 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000274
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000275 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000276 return kind_ == other.kind_;
277 }
278
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000279 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000280 bool IsNone() const { return kind_ == kNone; }
281 bool IsTagged() const { return kind_ == kTagged; }
282 bool IsInteger32() const { return kind_ == kInteger32; }
283 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000284 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000285 bool IsSpecialization() const {
286 return kind_ == kInteger32 || kind_ == kDouble;
287 }
288 const char* Mnemonic() const;
289
290 private:
291 explicit Representation(Kind k) : kind_(k) { }
292
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000293 // Make sure kind fits in int8.
294 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
295
296 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000297};
298
299
300class HType {
301 public:
302 HType() : type_(kUninitialized) { }
303
304 static HType Tagged() { return HType(kTagged); }
305 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
306 static HType TaggedNumber() { return HType(kTaggedNumber); }
307 static HType Smi() { return HType(kSmi); }
308 static HType HeapNumber() { return HType(kHeapNumber); }
309 static HType String() { return HType(kString); }
310 static HType Boolean() { return HType(kBoolean); }
311 static HType NonPrimitive() { return HType(kNonPrimitive); }
312 static HType JSArray() { return HType(kJSArray); }
313 static HType JSObject() { return HType(kJSObject); }
314 static HType Uninitialized() { return HType(kUninitialized); }
315
316 // Return the weakest (least precise) common type.
317 HType Combine(HType other) {
318 return HType(static_cast<Type>(type_ & other.type_));
319 }
320
321 bool Equals(const HType& other) {
322 return type_ == other.type_;
323 }
324
325 bool IsSubtypeOf(const HType& other) {
326 return Combine(other).Equals(other);
327 }
328
329 bool IsTagged() {
330 ASSERT(type_ != kUninitialized);
331 return ((type_ & kTagged) == kTagged);
332 }
333
334 bool IsTaggedPrimitive() {
335 ASSERT(type_ != kUninitialized);
336 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
337 }
338
339 bool IsTaggedNumber() {
340 ASSERT(type_ != kUninitialized);
341 return ((type_ & kTaggedNumber) == kTaggedNumber);
342 }
343
344 bool IsSmi() {
345 ASSERT(type_ != kUninitialized);
346 return ((type_ & kSmi) == kSmi);
347 }
348
349 bool IsHeapNumber() {
350 ASSERT(type_ != kUninitialized);
351 return ((type_ & kHeapNumber) == kHeapNumber);
352 }
353
354 bool IsString() {
355 ASSERT(type_ != kUninitialized);
356 return ((type_ & kString) == kString);
357 }
358
359 bool IsBoolean() {
360 ASSERT(type_ != kUninitialized);
361 return ((type_ & kBoolean) == kBoolean);
362 }
363
364 bool IsNonPrimitive() {
365 ASSERT(type_ != kUninitialized);
366 return ((type_ & kNonPrimitive) == kNonPrimitive);
367 }
368
369 bool IsJSArray() {
370 ASSERT(type_ != kUninitialized);
371 return ((type_ & kJSArray) == kJSArray);
372 }
373
374 bool IsJSObject() {
375 ASSERT(type_ != kUninitialized);
376 return ((type_ & kJSObject) == kJSObject);
377 }
378
379 bool IsUninitialized() {
380 return type_ == kUninitialized;
381 }
382
383 static HType TypeFromValue(Handle<Object> value);
384
385 const char* ToString();
386 const char* ToShortString();
387
388 private:
389 enum Type {
390 kTagged = 0x1, // 0000 0000 0000 0001
391 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
392 kTaggedNumber = 0xd, // 0000 0000 0000 1101
393 kSmi = 0x1d, // 0000 0000 0001 1101
394 kHeapNumber = 0x2d, // 0000 0000 0010 1101
395 kString = 0x45, // 0000 0000 0100 0101
396 kBoolean = 0x85, // 0000 0000 1000 0101
397 kNonPrimitive = 0x101, // 0000 0001 0000 0001
398 kJSObject = 0x301, // 0000 0011 0000 0001
399 kJSArray = 0x701, // 0000 0111 1000 0001
400 kUninitialized = 0x1fff // 0001 1111 1111 1111
401 };
402
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000403 // Make sure type fits in int16.
404 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
405
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000406 explicit HType(Type t) : type_(t) { }
407
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000408 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000409};
410
411
412class HValue: public ZoneObject {
413 public:
414 static const int kNoNumber = -1;
415
416 // There must be one corresponding kDepends flag for every kChanges flag and
417 // the order of the kChanges flags must be exactly the same as of the kDepends
418 // flags.
419 enum Flag {
420 // Declare global value numbering flags.
421 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
422 GVN_FLAG_LIST(DECLARE_DO)
423 #undef DECLARE_DO
424 kFlexibleRepresentation,
425 kUseGVN,
426 kCanOverflow,
427 kBailoutOnMinusZero,
428 kCanBeDivByZero,
429 kIsArguments,
430 kTruncatingToInt32,
431 kLastFlag = kTruncatingToInt32
432 };
433
434 STATIC_ASSERT(kLastFlag < kBitsPerInt);
435
436 static const int kChangesToDependsFlagsLeftShift = 1;
437
438 static int ChangesFlagsMask() {
439 int result = 0;
440 // Create changes mask.
441#define DECLARE_DO(type) result |= (1 << kChanges##type);
442 GVN_FLAG_LIST(DECLARE_DO)
443#undef DECLARE_DO
444 return result;
445 }
446
447 static int DependsFlagsMask() {
448 return ConvertChangesToDependsFlags(ChangesFlagsMask());
449 }
450
451 static int ConvertChangesToDependsFlags(int flags) {
452 return flags << kChangesToDependsFlagsLeftShift;
453 }
454
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000455 static HValue* cast(HValue* value) { return value; }
456
457 enum Opcode {
458 // Declare a unique enum value for each hydrogen instruction.
459 #define DECLARE_DO(type) k##type,
460 HYDROGEN_ALL_INSTRUCTION_LIST(DECLARE_DO)
461 #undef DECLARE_DO
462 kMaxInstructionClass
463 };
464
465 HValue() : block_(NULL),
466 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000467 type_(HType::Tagged()),
468 range_(NULL),
469 flags_(0) {}
470 virtual ~HValue() {}
471
472 HBasicBlock* block() const { return block_; }
473 void SetBlock(HBasicBlock* block);
474
475 int id() const { return id_; }
476 void set_id(int id) { id_ = id; }
477
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000478 SmallPointerList<HValue>* uses() { return &uses_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000479
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000480 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000481 Representation representation() const { return representation_; }
482 void ChangeRepresentation(Representation r) {
483 // Representation was already set and is allowed to be changed.
484 ASSERT(!representation_.IsNone());
485 ASSERT(!r.IsNone());
486 ASSERT(CheckFlag(kFlexibleRepresentation));
487 RepresentationChanged(r);
488 representation_ = r;
489 }
490
491 HType type() const { return type_; }
492 void set_type(HType type) {
493 ASSERT(uses_.length() == 0);
494 type_ = type;
495 }
496
497 // An operation needs to override this function iff:
498 // 1) it can produce an int32 output.
499 // 2) the true value of its output can potentially be minus zero.
500 // The implementation must set a flag so that it bails out in the case where
501 // it would otherwise output what should be a minus zero as an int32 zero.
502 // If the operation also exists in a form that takes int32 and outputs int32
503 // then the operation should return its input value so that we can propagate
504 // back. There are two operations that need to propagate back to more than
505 // one input. They are phi and binary add. They always return NULL and
506 // expect the caller to take care of things.
507 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
508 visited->Add(id());
509 return NULL;
510 }
511
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000512 bool IsDefinedAfter(HBasicBlock* other) const;
513
514 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000515 virtual int OperandCount() = 0;
516 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000517 void SetOperandAt(int index, HValue* value);
518
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000519 int LookupOperandIndex(int occurrence_index, HValue* op);
520 bool UsesMultipleTimes(HValue* op);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000521
522 void ReplaceAndDelete(HValue* other);
523 void ReplaceValue(HValue* other);
524 void ReplaceAtUse(HValue* use, HValue* other);
525 void ReplaceFirstAtUse(HValue* use, HValue* other, Representation r);
526 bool HasNoUses() const { return uses_.is_empty(); }
527 void ClearOperands();
528 void Delete();
529
530 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000531 void SetFlag(Flag f) { flags_ |= (1 << f); }
532 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
533 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
534
535 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
536 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
537 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000538
539 Range* range() const { return range_; }
540 bool HasRange() const { return range_ != NULL; }
541 void AddNewRange(Range* r);
542 void RemoveLastAddedRange();
543 void ComputeInitialRange();
544
545 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000546 virtual Representation RequiredInputRepresentation(int index) const = 0;
547
548 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000549 return representation();
550 }
551
552 // This gives the instruction an opportunity to replace itself with an
553 // instruction that does the same in some better way. To replace an
554 // instruction with a new one, first add the new instruction to the graph,
555 // then return it. Return NULL to have the instruction deleted.
556 virtual HValue* Canonicalize() { return this; }
557
558 // Declare virtual type testers.
559#define DECLARE_DO(type) virtual bool Is##type() const { return false; }
560 HYDROGEN_ALL_INSTRUCTION_LIST(DECLARE_DO)
561#undef DECLARE_DO
562
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000563 bool Equals(HValue* other);
564 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000565
566 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000567 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000568 void PrintNameTo(StringStream* stream);
569 static void PrintTypeTo(HType type, StringStream* stream);
570
571 virtual const char* Mnemonic() const = 0;
572 virtual Opcode opcode() const = 0;
573
574 // Updated the inferred type of this instruction and returns true if
575 // it has changed.
576 bool UpdateInferredType();
577
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000578 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000579
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000580#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000581 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000582#endif
583
584 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000585 // This function must be overridden for instructions with flag kUseGVN, to
586 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000587 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000588 UNREACHABLE();
589 return false;
590 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000591 virtual void RepresentationChanged(Representation to) { }
592 virtual Range* InferRange();
593 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000594 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000595 void clear_block() {
596 ASSERT(block_ != NULL);
597 block_ = NULL;
598 }
599
600 void set_representation(Representation r) {
601 // Representation is set-once.
602 ASSERT(representation_.IsNone() && !r.IsNone());
603 representation_ = r;
604 }
605
606 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000607 // A flag mask to mark an instruction as having arbitrary side effects.
608 static int AllSideEffects() {
609 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
610 }
611
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000612 void InternalReplaceAtUse(HValue* use, HValue* other);
613 void RegisterUse(int index, HValue* new_value);
614
615 HBasicBlock* block_;
616
617 // The id of this instruction in the hydrogen graph, assigned when first
618 // added to the graph. Reflects creation order.
619 int id_;
620
621 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000622 HType type_;
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000623 SmallPointerList<HValue> uses_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000624 Range* range_;
625 int flags_;
626
627 DISALLOW_COPY_AND_ASSIGN(HValue);
628};
629
630
631class HInstruction: public HValue {
632 public:
633 HInstruction* next() const { return next_; }
634 HInstruction* previous() const { return previous_; }
635
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000636 virtual void PrintTo(StringStream* stream);
637 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000638
639 bool IsLinked() const { return block() != NULL; }
640 void Unlink();
641 void InsertBefore(HInstruction* next);
642 void InsertAfter(HInstruction* previous);
643
644 int position() const { return position_; }
645 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
646 void set_position(int position) { position_ = position; }
647
648 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
649
650#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000651 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000652#endif
653
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000654 // Returns whether this is some kind of deoptimizing check
655 // instruction.
656 virtual bool IsCheckInstruction() const { return false; }
657
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000658 virtual bool IsCall() { return false; }
659
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000660 DECLARE_INSTRUCTION(Instruction)
661
662 protected:
663 HInstruction()
664 : next_(NULL),
665 previous_(NULL),
666 position_(RelocInfo::kNoPosition) {
667 SetFlag(kDependsOnOsrEntries);
668 }
669
670 virtual void DeleteFromGraph() { Unlink(); }
671
672 private:
673 void InitializeAsFirst(HBasicBlock* block) {
674 ASSERT(!IsLinked());
675 SetBlock(block);
676 }
677
678 HInstruction* next_;
679 HInstruction* previous_;
680 int position_;
681
682 friend class HBasicBlock;
683};
684
685
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000686class HControlInstruction: public HInstruction {
687 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000688 HControlInstruction(HBasicBlock* first, HBasicBlock* second)
689 : first_successor_(first), second_successor_(second) {
690 }
691
692 HBasicBlock* FirstSuccessor() const { return first_successor_; }
693 HBasicBlock* SecondSuccessor() const { return second_successor_; }
694
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000695 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000696
697 DECLARE_INSTRUCTION(ControlInstruction)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000698
699 private:
700 HBasicBlock* first_successor_;
701 HBasicBlock* second_successor_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000702};
703
704
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000705template<int NumElements>
706class HOperandContainer {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000707 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000708 HOperandContainer() : elems_() { }
709
710 int length() { return NumElements; }
711 HValue*& operator[](int i) {
712 ASSERT(i < length());
713 return elems_[i];
714 }
715
716 private:
717 HValue* elems_[NumElements];
718};
719
720
721template<>
722class HOperandContainer<0> {
723 public:
724 int length() { return 0; }
725 HValue*& operator[](int i) {
726 UNREACHABLE();
727 static HValue* t = 0;
728 return t;
729 }
730};
731
732
733template<int V>
734class HTemplateInstruction : public HInstruction {
735 public:
736 int OperandCount() { return V; }
737 HValue* OperandAt(int i) { return inputs_[i]; }
738
739 protected:
740 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
741
742 private:
743 HOperandContainer<V> inputs_;
744};
745
746
747template<int V>
748class HTemplateControlInstruction : public HControlInstruction {
749 public:
750 HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second)
751 : HControlInstruction(first, second) { }
752 int OperandCount() { return V; }
753 HValue* OperandAt(int i) { return inputs_[i]; }
754
755 protected:
756 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
757
758 private:
759 HOperandContainer<V> inputs_;
760};
761
762
763class HBlockEntry: public HTemplateInstruction<0> {
764 public:
765 virtual Representation RequiredInputRepresentation(int index) const {
766 return Representation::None();
767 }
768
769 DECLARE_CONCRETE_INSTRUCTION(BlockEntry, "block_entry")
770};
771
772
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000773class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000774 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000775 explicit HDeoptimize(int environment_length)
776 : HControlInstruction(NULL, NULL),
777 values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000778
779 virtual Representation RequiredInputRepresentation(int index) const {
780 return Representation::None();
781 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000782
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000783 virtual int OperandCount() { return values_.length(); }
784 virtual HValue* OperandAt(int index) { return values_[index]; }
785
786 void AddEnvironmentValue(HValue* value) {
787 values_.Add(NULL);
788 SetOperandAt(values_.length() - 1, value);
789 }
790
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000791 DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000792
793 protected:
794 virtual void InternalSetOperandAt(int index, HValue* value) {
795 values_[index] = value;
796 }
797
798 private:
799 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000800};
801
802
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000803class HGoto: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000804 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000805 explicit HGoto(HBasicBlock* target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000806 : HTemplateControlInstruction<0>(target, NULL),
807 include_stack_check_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000808
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000809 void set_include_stack_check(bool include_stack_check) {
810 include_stack_check_ = include_stack_check;
811 }
812 bool include_stack_check() const { return include_stack_check_; }
813
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000814 virtual Representation RequiredInputRepresentation(int index) const {
815 return Representation::None();
816 }
817
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000818 DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
819
820 private:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000821 bool include_stack_check_;
822};
823
824
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000825class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000826 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000827 explicit HUnaryControlInstruction(HValue* value,
828 HBasicBlock* true_target,
829 HBasicBlock* false_target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000830 : HTemplateControlInstruction<1>(true_target, false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000831 SetOperandAt(0, value);
832 }
833
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000834 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000835
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000836 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000837
838 DECLARE_INSTRUCTION(UnaryControlInstruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000839};
840
841
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000842class HTest: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000843 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000844 HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
845 : HUnaryControlInstruction(value, true_target, false_target) {
846 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000847 }
848
849 virtual Representation RequiredInputRepresentation(int index) const {
850 return Representation::None();
851 }
852
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000853 DECLARE_CONCRETE_INSTRUCTION(Test, "test")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000854};
855
856
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000857class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000858 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000859 HCompareMap(HValue* value,
860 Handle<Map> map,
861 HBasicBlock* true_target,
862 HBasicBlock* false_target)
863 : HUnaryControlInstruction(value, true_target, false_target),
864 map_(map) {
865 ASSERT(true_target != NULL);
866 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000867 ASSERT(!map.is_null());
868 }
869
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000870 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000871
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000872 Handle<Map> map() const { return map_; }
873
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000874 virtual Representation RequiredInputRepresentation(int index) const {
875 return Representation::Tagged();
876 }
877
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000878 DECLARE_CONCRETE_INSTRUCTION(CompareMap, "compare_map")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000879
880 private:
881 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000882};
883
884
885class HReturn: public HUnaryControlInstruction {
886 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000887 explicit HReturn(HValue* value)
888 : HUnaryControlInstruction(value, NULL, NULL) {
889 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000890
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000891 virtual Representation RequiredInputRepresentation(int index) const {
892 return Representation::Tagged();
893 }
894
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000895 DECLARE_CONCRETE_INSTRUCTION(Return, "return")
896};
897
898
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000899class HAbnormalExit: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000900 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000901 HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
902
903 virtual Representation RequiredInputRepresentation(int index) const {
904 return Representation::None();
905 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000906
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000907 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit, "abnormal_exit")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000908};
909
910
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000911class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000912 public:
913 explicit HUnaryOperation(HValue* value) {
914 SetOperandAt(0, value);
915 }
916
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000917 HValue* value() { return OperandAt(0); }
918 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000919
920 DECLARE_INSTRUCTION(UnaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000921};
922
923
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000924class HThrow: public HUnaryOperation {
925 public:
926 explicit HThrow(HValue* value) : HUnaryOperation(value) {
927 SetAllSideEffects();
928 }
929
930 virtual Representation RequiredInputRepresentation(int index) const {
931 return Representation::Tagged();
932 }
933
934 DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
935};
936
937
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000938class HChange: public HUnaryOperation {
939 public:
940 HChange(HValue* value,
941 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000942 Representation to,
943 bool is_truncating)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000944 : HUnaryOperation(value), from_(from) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000945 ASSERT(!from.IsNone() && !to.IsNone());
946 ASSERT(!from.Equals(to));
947 set_representation(to);
948 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000949 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000950 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
951 value->range()->IsInSmiRange()) {
952 set_type(HType::Smi());
953 }
954 }
955
956 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
957
958 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000959 Representation to() const { return representation(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000960 virtual Representation RequiredInputRepresentation(int index) const {
961 return from_;
962 }
963
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000964 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000965
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000966 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000967
968 DECLARE_CONCRETE_INSTRUCTION(Change,
969 CanTruncateToInt32() ? "truncate" : "change")
970
971 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000972 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000973 if (!other->IsChange()) return false;
974 HChange* change = HChange::cast(other);
975 return value() == change->value()
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000976 && to().Equals(change->to());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000977 }
978
979 private:
980 Representation from_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000981};
982
983
984class HSimulate: public HInstruction {
985 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000986 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000987 : ast_id_(ast_id),
988 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000989 values_(2),
990 assigned_indexes_(2) {}
991 virtual ~HSimulate() {}
992
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000993 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000994
995 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
996 int ast_id() const { return ast_id_; }
997 void set_ast_id(int id) {
998 ASSERT(!HasAstId());
999 ast_id_ = id;
1000 }
1001
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001002 int pop_count() const { return pop_count_; }
1003 const ZoneList<HValue*>* values() const { return &values_; }
1004 int GetAssignedIndexAt(int index) const {
1005 ASSERT(HasAssignedIndexAt(index));
1006 return assigned_indexes_[index];
1007 }
1008 bool HasAssignedIndexAt(int index) const {
1009 return assigned_indexes_[index] != kNoIndex;
1010 }
1011 void AddAssignedValue(int index, HValue* value) {
1012 AddValue(index, value);
1013 }
1014 void AddPushedValue(HValue* value) {
1015 AddValue(kNoIndex, value);
1016 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001017 virtual int OperandCount() { return values_.length(); }
1018 virtual HValue* OperandAt(int index) { return values_[index]; }
1019
1020 virtual Representation RequiredInputRepresentation(int index) const {
1021 return Representation::None();
1022 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001023
1024 DECLARE_CONCRETE_INSTRUCTION(Simulate, "simulate")
1025
1026#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001027 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001028#endif
1029
1030 protected:
1031 virtual void InternalSetOperandAt(int index, HValue* value) {
1032 values_[index] = value;
1033 }
1034
1035 private:
1036 static const int kNoIndex = -1;
1037 void AddValue(int index, HValue* value) {
1038 assigned_indexes_.Add(index);
1039 // Resize the list of pushed values.
1040 values_.Add(NULL);
1041 // Set the operand through the base method in HValue to make sure that the
1042 // use lists are correctly updated.
1043 SetOperandAt(values_.length() - 1, value);
1044 }
1045 int ast_id_;
1046 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001047 ZoneList<HValue*> values_;
1048 ZoneList<int> assigned_indexes_;
1049};
1050
1051
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001052class HStackCheck: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001053 public:
1054 HStackCheck() { }
1055
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001056 virtual Representation RequiredInputRepresentation(int index) const {
1057 return Representation::None();
1058 }
1059
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001060 DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack_check")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001061};
1062
1063
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001064class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001065 public:
1066 HEnterInlined(Handle<JSFunction> closure, FunctionLiteral* function)
1067 : closure_(closure), function_(function) {
1068 }
1069
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001070 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001071
1072 Handle<JSFunction> closure() const { return closure_; }
1073 FunctionLiteral* function() const { return function_; }
1074
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001075 virtual Representation RequiredInputRepresentation(int index) const {
1076 return Representation::None();
1077 }
1078
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001079 DECLARE_CONCRETE_INSTRUCTION(EnterInlined, "enter_inlined")
1080
1081 private:
1082 Handle<JSFunction> closure_;
1083 FunctionLiteral* function_;
1084};
1085
1086
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001087class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001088 public:
1089 HLeaveInlined() {}
1090
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001091 virtual Representation RequiredInputRepresentation(int index) const {
1092 return Representation::None();
1093 }
1094
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001095 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined, "leave_inlined")
1096};
1097
1098
1099class HPushArgument: public HUnaryOperation {
1100 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001101 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1102 set_representation(Representation::Tagged());
1103 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001104
1105 virtual Representation RequiredInputRepresentation(int index) const {
1106 return Representation::Tagged();
1107 }
1108
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001109 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001110
1111 DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push_argument")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001112};
1113
1114
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001115class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001116 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001117 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001118 set_representation(Representation::Tagged());
1119 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001120 }
1121
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001122 virtual Representation RequiredInputRepresentation(int index) const {
1123 return Representation::None();
1124 }
1125
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001126 DECLARE_CONCRETE_INSTRUCTION(Context, "context");
1127
1128 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001129 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001130};
1131
1132
1133class HOuterContext: public HUnaryOperation {
1134 public:
1135 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1136 set_representation(Representation::Tagged());
1137 SetFlag(kUseGVN);
1138 }
1139
1140 DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer_context");
1141
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001142 virtual Representation RequiredInputRepresentation(int index) const {
1143 return Representation::Tagged();
1144 }
1145
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001146 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001147 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001148};
1149
1150
1151class HGlobalObject: public HUnaryOperation {
1152 public:
1153 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1154 set_representation(Representation::Tagged());
1155 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001156 }
1157
1158 DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global_object")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001159
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001160 virtual Representation RequiredInputRepresentation(int index) const {
1161 return Representation::Tagged();
1162 }
1163
ager@chromium.org378b34e2011-01-28 08:04:38 +00001164 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001165 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001166};
1167
1168
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001169class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001170 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001171 explicit HGlobalReceiver(HValue* global_object)
1172 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001173 set_representation(Representation::Tagged());
1174 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001175 }
1176
1177 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global_receiver")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001178
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001179 virtual Representation RequiredInputRepresentation(int index) const {
1180 return Representation::Tagged();
1181 }
1182
ager@chromium.org378b34e2011-01-28 08:04:38 +00001183 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001184 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001185};
1186
1187
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001188template <int V>
1189class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001190 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001191 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001192 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1193 this->set_representation(Representation::Tagged());
1194 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001195 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001196
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001197 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001198
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001199 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001200
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001201 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001202
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001203 private:
1204 int argument_count_;
1205};
1206
1207
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001208class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001209 public:
1210 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001211 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001212 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001213 }
1214
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001215 virtual Representation RequiredInputRepresentation(int index) const {
1216 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001217 }
1218
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001219 virtual void PrintDataTo(StringStream* stream);
1220
1221 HValue* value() { return OperandAt(0); }
1222
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001223 DECLARE_INSTRUCTION(UnaryCall)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001224};
1225
1226
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001227class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001228 public:
1229 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001230 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001231 SetOperandAt(0, first);
1232 SetOperandAt(1, second);
1233 }
1234
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001235 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001236
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001237 virtual Representation RequiredInputRepresentation(int index) const {
1238 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001239 }
1240
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001241 HValue* first() { return OperandAt(0); }
1242 HValue* second() { return OperandAt(1); }
1243
1244 DECLARE_INSTRUCTION(BinaryCall)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001245};
1246
1247
danno@chromium.org160a7b02011-04-18 15:51:38 +00001248class HInvokeFunction: public HBinaryCall {
1249 public:
1250 HInvokeFunction(HValue* context, HValue* function, int argument_count)
1251 : HBinaryCall(context, function, argument_count) {
1252 }
1253
1254 virtual Representation RequiredInputRepresentation(int index) const {
1255 return Representation::Tagged();
1256 }
1257
1258 HValue* context() { return first(); }
1259 HValue* function() { return second(); }
1260
1261 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke_function")
1262};
1263
1264
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001265class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001266 public:
1267 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001268 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001269
1270 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001271
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001272 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001273 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001274 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001275 }
1276
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001277 virtual void PrintDataTo(StringStream* stream);
1278
1279 virtual Representation RequiredInputRepresentation(int index) const {
1280 return Representation::None();
1281 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001282
1283 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call_constant_function")
1284
1285 private:
1286 Handle<JSFunction> function_;
1287};
1288
1289
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001290class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001291 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001292 HCallKeyed(HValue* context, HValue* key, int argument_count)
1293 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001294 }
1295
1296 virtual Representation RequiredInputRepresentation(int index) const {
1297 return Representation::Tagged();
1298 }
1299
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001300 HValue* context() { return first(); }
1301 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001302
1303 DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call_keyed")
1304};
1305
1306
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001307class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001308 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001309 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1310 : HUnaryCall(context, argument_count), name_(name) {
1311 }
1312
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001313 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001314
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001315 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001316 Handle<String> name() const { return name_; }
1317
1318 DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call_named")
1319
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001320 virtual Representation RequiredInputRepresentation(int index) const {
1321 return Representation::Tagged();
1322 }
1323
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001324 private:
1325 Handle<String> name_;
1326};
1327
1328
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001329class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001330 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001331 HCallFunction(HValue* context, int argument_count)
1332 : HUnaryCall(context, argument_count) {
1333 }
1334
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001335 HValue* context() { return value(); }
1336
1337 virtual Representation RequiredInputRepresentation(int index) const {
1338 return Representation::Tagged();
1339 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001340
1341 DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call_function")
1342};
1343
1344
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001345class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001346 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001347 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1348 : HUnaryCall(context, argument_count), name_(name) {
1349 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001350
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001351 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001352
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001353 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001354 Handle<String> name() const { return name_; }
1355
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001356 virtual Representation RequiredInputRepresentation(int index) const {
1357 return Representation::Tagged();
1358 }
1359
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001360 DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call_global")
1361
1362 private:
1363 Handle<String> name_;
1364};
1365
1366
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001367class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001368 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001369 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001370 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001371
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001372 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001373
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001374 Handle<JSFunction> target() const { return target_; }
1375
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001376 virtual Representation RequiredInputRepresentation(int index) const {
1377 return Representation::None();
1378 }
1379
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001380 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call_known_global")
1381
1382 private:
1383 Handle<JSFunction> target_;
1384};
1385
1386
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001387class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001388 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001389 HCallNew(HValue* context, HValue* constructor, int argument_count)
1390 : HBinaryCall(context, constructor, argument_count) {
1391 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001392
1393 virtual Representation RequiredInputRepresentation(int index) const {
1394 return Representation::Tagged();
1395 }
1396
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001397 HValue* context() { return first(); }
1398 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001399
1400 DECLARE_CONCRETE_INSTRUCTION(CallNew, "call_new")
1401};
1402
1403
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001404class HCallRuntime: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001405 public:
1406 HCallRuntime(Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001407 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001408 int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001409 : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
1410 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001411
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001412 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001413 Handle<String> name() const { return name_; }
1414
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001415 virtual Representation RequiredInputRepresentation(int index) const {
1416 return Representation::None();
1417 }
1418
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001419 DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call_runtime")
1420
1421 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001422 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001423 Handle<String> name_;
1424};
1425
1426
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001427class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001428 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001429 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001430 // The length of an array is stored as a tagged value in the array
1431 // object. It is guaranteed to be 32 bit integer, but it can be
1432 // represented as either a smi or heap number.
1433 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001434 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001435 SetFlag(kDependsOnArrayLengths);
1436 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001437 }
1438
1439 virtual Representation RequiredInputRepresentation(int index) const {
1440 return Representation::Tagged();
1441 }
1442
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001443 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js_array_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001444
1445 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001446 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001447};
1448
1449
1450class HFixedArrayLength: public HUnaryOperation {
1451 public:
1452 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1453 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001454 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001455 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001456 }
1457
1458 virtual Representation RequiredInputRepresentation(int index) const {
1459 return Representation::Tagged();
1460 }
1461
1462 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed_array_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001463
1464 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001465 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001466};
1467
1468
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001469class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001470 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001471 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001472 set_representation(Representation::Integer32());
1473 // The result of this instruction is idempotent as long as its inputs don't
1474 // change. The length of a pixel array cannot change once set, so it's not
1475 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1476 SetFlag(kUseGVN);
1477 }
1478
1479 virtual Representation RequiredInputRepresentation(int index) const {
1480 return Representation::Tagged();
1481 }
1482
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001483 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength, "external_array_length")
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001484
1485 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001486 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001487};
1488
1489
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001490class HBitNot: public HUnaryOperation {
1491 public:
1492 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1493 set_representation(Representation::Integer32());
1494 SetFlag(kUseGVN);
1495 SetFlag(kTruncatingToInt32);
1496 }
1497
1498 virtual Representation RequiredInputRepresentation(int index) const {
1499 return Representation::Integer32();
1500 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001501 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001502
1503 DECLARE_CONCRETE_INSTRUCTION(BitNot, "bit_not")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001504
1505 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001506 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001507};
1508
1509
1510class HUnaryMathOperation: public HUnaryOperation {
1511 public:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001512 HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001513 : HUnaryOperation(value), op_(op) {
1514 switch (op) {
1515 case kMathFloor:
1516 case kMathRound:
1517 case kMathCeil:
1518 set_representation(Representation::Integer32());
1519 break;
1520 case kMathAbs:
1521 set_representation(Representation::Tagged());
1522 SetFlag(kFlexibleRepresentation);
1523 break;
1524 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001525 case kMathPowHalf:
1526 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001527 case kMathSin:
1528 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001529 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001530 break;
1531 default:
1532 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001533 }
1534 SetFlag(kUseGVN);
1535 }
1536
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001537 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001538
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001539 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001540
1541 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1542
1543 virtual Representation RequiredInputRepresentation(int index) const {
1544 switch (op_) {
1545 case kMathFloor:
1546 case kMathRound:
1547 case kMathCeil:
1548 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001549 case kMathPowHalf:
1550 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001551 case kMathSin:
1552 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001553 return Representation::Double();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001554 case kMathAbs:
1555 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001556 default:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001557 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001558 return Representation::None();
1559 }
1560 }
1561
1562 virtual HValue* Canonicalize() {
1563 // If the input is integer32 then we replace the floor instruction
1564 // with its inputs. This happens before the representation changes are
1565 // introduced.
1566 if (op() == kMathFloor) {
1567 if (value()->representation().IsInteger32()) return value();
1568 }
1569 return this;
1570 }
1571
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001572 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001573 const char* OpName() const;
1574
1575 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary_math_operation")
1576
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001577 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001578 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001579 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1580 return op_ == b->op();
1581 }
1582
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001583 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001584 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001585};
1586
1587
1588class HLoadElements: public HUnaryOperation {
1589 public:
1590 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1591 set_representation(Representation::Tagged());
1592 SetFlag(kUseGVN);
1593 SetFlag(kDependsOnMaps);
1594 }
1595
1596 virtual Representation RequiredInputRepresentation(int index) const {
1597 return Representation::Tagged();
1598 }
1599
1600 DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001601
1602 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001603 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001604};
1605
1606
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001607class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001608 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001609 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001610 : HUnaryOperation(value) {
1611 set_representation(Representation::External());
1612 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001613 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001614 // change once set, so it's no necessary to introduce any additional
1615 // dependencies on top of the inputs.
1616 SetFlag(kUseGVN);
1617 }
1618
1619 virtual Representation RequiredInputRepresentation(int index) const {
1620 return Representation::Tagged();
1621 }
1622
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001623 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer,
1624 "load-external-array-pointer")
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001625
1626 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001627 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001628};
1629
1630
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001631class HCheckMap: public HUnaryOperation {
1632 public:
1633 HCheckMap(HValue* value, Handle<Map> map)
1634 : HUnaryOperation(value), map_(map) {
1635 set_representation(Representation::Tagged());
1636 SetFlag(kUseGVN);
1637 SetFlag(kDependsOnMaps);
1638 }
1639
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001640 virtual bool IsCheckInstruction() const { return true; }
1641
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001642 virtual Representation RequiredInputRepresentation(int index) const {
1643 return Representation::Tagged();
1644 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001645 virtual void PrintDataTo(StringStream* stream);
1646 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001647
1648#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001649 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001650#endif
1651
1652 Handle<Map> map() const { return map_; }
1653
1654 DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check_map")
1655
1656 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001657 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001658 HCheckMap* b = HCheckMap::cast(other);
1659 return map_.is_identical_to(b->map());
1660 }
1661
1662 private:
1663 Handle<Map> map_;
1664};
1665
1666
1667class HCheckFunction: public HUnaryOperation {
1668 public:
1669 HCheckFunction(HValue* value, Handle<JSFunction> function)
1670 : HUnaryOperation(value), target_(function) {
1671 set_representation(Representation::Tagged());
1672 SetFlag(kUseGVN);
1673 }
1674
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001675 virtual bool IsCheckInstruction() const { return true; }
1676
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001677 virtual Representation RequiredInputRepresentation(int index) const {
1678 return Representation::Tagged();
1679 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001680 virtual void PrintDataTo(StringStream* stream);
1681 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001682
1683#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001684 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001685#endif
1686
1687 Handle<JSFunction> target() const { return target_; }
1688
1689 DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check_function")
1690
1691 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001692 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001693 HCheckFunction* b = HCheckFunction::cast(other);
1694 return target_.is_identical_to(b->target());
1695 }
1696
1697 private:
1698 Handle<JSFunction> target_;
1699};
1700
1701
1702class HCheckInstanceType: public HUnaryOperation {
1703 public:
1704 // Check that the instance type is in the range [first, last] where
1705 // both first and last are included.
1706 HCheckInstanceType(HValue* value, InstanceType first, InstanceType last)
1707 : HUnaryOperation(value), first_(first), last_(last) {
1708 ASSERT(first <= last);
1709 set_representation(Representation::Tagged());
1710 SetFlag(kUseGVN);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001711 if ((FIRST_STRING_TYPE < first && last <= LAST_STRING_TYPE) ||
1712 (FIRST_STRING_TYPE <= first && last < LAST_STRING_TYPE)) {
1713 // A particular string instance type can change because of GC or
1714 // externalization, but the value still remains a string.
1715 SetFlag(kDependsOnMaps);
1716 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001717 }
1718
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001719 virtual bool IsCheckInstruction() const { return true; }
1720
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001721 virtual Representation RequiredInputRepresentation(int index) const {
1722 return Representation::Tagged();
1723 }
1724
1725#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001726 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001727#endif
1728
danno@chromium.org160a7b02011-04-18 15:51:38 +00001729 virtual HValue* Canonicalize() {
1730 if (!value()->type().IsUninitialized() &&
1731 value()->type().IsString() &&
1732 first() == FIRST_STRING_TYPE &&
1733 last() == LAST_STRING_TYPE) {
1734 return NULL;
1735 }
1736 return this;
1737 }
1738
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001739 static HCheckInstanceType* NewIsJSObjectOrJSFunction(HValue* value);
1740
1741 InstanceType first() const { return first_; }
1742 InstanceType last() const { return last_; }
1743
1744 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check_instance_type")
1745
1746 protected:
1747 // TODO(ager): It could be nice to allow the ommision of instance
1748 // type checks if we have already performed an instance type check
1749 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001750 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001751 HCheckInstanceType* b = HCheckInstanceType::cast(other);
1752 return (first_ == b->first()) && (last_ == b->last());
1753 }
1754
1755 private:
1756 InstanceType first_;
1757 InstanceType last_;
1758};
1759
1760
1761class HCheckNonSmi: public HUnaryOperation {
1762 public:
1763 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
1764 set_representation(Representation::Tagged());
1765 SetFlag(kUseGVN);
1766 }
1767
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001768 virtual bool IsCheckInstruction() const { return true; }
1769
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001770 virtual Representation RequiredInputRepresentation(int index) const {
1771 return Representation::Tagged();
1772 }
1773
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001774 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001775
1776#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001777 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001778#endif
1779
danno@chromium.org160a7b02011-04-18 15:51:38 +00001780 virtual HValue* Canonicalize() {
1781 HType value_type = value()->type();
1782 if (!value_type.IsUninitialized() &&
1783 (value_type.IsHeapNumber() ||
1784 value_type.IsString() ||
1785 value_type.IsBoolean() ||
1786 value_type.IsNonPrimitive())) {
1787 return NULL;
1788 }
1789 return this;
1790 }
1791
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001792 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check_non_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001793
1794 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001795 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001796};
1797
1798
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001799class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001800 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001801 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
1802 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001803 SetFlag(kUseGVN);
1804 SetFlag(kDependsOnMaps);
1805 }
1806
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001807 virtual bool IsCheckInstruction() const { return true; }
1808
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001809#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001810 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001811#endif
1812
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001813 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001814 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001815
1816 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check_prototype_maps")
1817
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001818 virtual Representation RequiredInputRepresentation(int index) const {
1819 return Representation::None();
1820 }
1821
1822 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001823 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001824 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
1825 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
1826 return hash;
1827 }
1828
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001829 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001830 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001831 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001832 return prototype_.is_identical_to(b->prototype()) &&
1833 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001834 }
1835
1836 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001837 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001838 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001839};
1840
1841
1842class HCheckSmi: public HUnaryOperation {
1843 public:
1844 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
1845 set_representation(Representation::Tagged());
1846 SetFlag(kUseGVN);
1847 }
1848
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001849 virtual bool IsCheckInstruction() const { return true; }
1850
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001851 virtual Representation RequiredInputRepresentation(int index) const {
1852 return Representation::Tagged();
1853 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001854 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001855
1856#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001857 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001858#endif
1859
1860 DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001861
1862 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001863 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001864};
1865
1866
1867class HPhi: public HValue {
1868 public:
1869 explicit HPhi(int merged_index)
1870 : inputs_(2),
1871 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001872 phi_id_(-1),
1873 is_live_(false) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001874 for (int i = 0; i < Representation::kNumRepresentations; i++) {
1875 non_phi_uses_[i] = 0;
1876 indirect_uses_[i] = 0;
1877 }
1878 ASSERT(merged_index >= 0);
1879 set_representation(Representation::Tagged());
1880 SetFlag(kFlexibleRepresentation);
1881 }
1882
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001883 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001884 bool double_occurred = false;
1885 bool int32_occurred = false;
1886 for (int i = 0; i < OperandCount(); ++i) {
1887 HValue* value = OperandAt(i);
1888 if (value->representation().IsDouble()) double_occurred = true;
1889 if (value->representation().IsInteger32()) int32_occurred = true;
1890 if (value->representation().IsTagged()) return Representation::Tagged();
1891 }
1892
1893 if (double_occurred) return Representation::Double();
1894 if (int32_occurred) return Representation::Integer32();
1895 return Representation::None();
1896 }
1897
1898 virtual Range* InferRange();
1899 virtual Representation RequiredInputRepresentation(int index) const {
1900 return representation();
1901 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001902 virtual HType CalculateInferredType();
1903 virtual int OperandCount() { return inputs_.length(); }
1904 virtual HValue* OperandAt(int index) { return inputs_[index]; }
1905 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001906 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001907 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001908
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00001909 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001910
1911 int merged_index() const { return merged_index_; }
1912
1913 virtual const char* Mnemonic() const { return "phi"; }
1914
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001915 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001916
1917#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001918 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001919#endif
1920
1921 DECLARE_INSTRUCTION(Phi)
1922
1923 void InitRealUses(int id);
1924 void AddNonPhiUsesFrom(HPhi* other);
1925 void AddIndirectUsesTo(int* use_count);
1926
1927 int tagged_non_phi_uses() const {
1928 return non_phi_uses_[Representation::kTagged];
1929 }
1930 int int32_non_phi_uses() const {
1931 return non_phi_uses_[Representation::kInteger32];
1932 }
1933 int double_non_phi_uses() const {
1934 return non_phi_uses_[Representation::kDouble];
1935 }
1936 int tagged_indirect_uses() const {
1937 return indirect_uses_[Representation::kTagged];
1938 }
1939 int int32_indirect_uses() const {
1940 return indirect_uses_[Representation::kInteger32];
1941 }
1942 int double_indirect_uses() const {
1943 return indirect_uses_[Representation::kDouble];
1944 }
1945 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001946 bool is_live() { return is_live_; }
1947 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001948
1949 protected:
1950 virtual void DeleteFromGraph();
1951 virtual void InternalSetOperandAt(int index, HValue* value) {
1952 inputs_[index] = value;
1953 }
1954
1955 private:
1956 ZoneList<HValue*> inputs_;
1957 int merged_index_;
1958
1959 int non_phi_uses_[Representation::kNumRepresentations];
1960 int indirect_uses_[Representation::kNumRepresentations];
1961 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001962 bool is_live_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001963};
1964
1965
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001966class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001967 public:
1968 HArgumentsObject() {
1969 set_representation(Representation::Tagged());
1970 SetFlag(kIsArguments);
1971 }
1972
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001973 virtual Representation RequiredInputRepresentation(int index) const {
1974 return Representation::None();
1975 }
1976
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001977 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject, "arguments-object")
1978};
1979
1980
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001981class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001982 public:
1983 HConstant(Handle<Object> handle, Representation r);
1984
1985 Handle<Object> handle() const { return handle_; }
1986
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001987 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001988
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001989 virtual Representation RequiredInputRepresentation(int index) const {
1990 return Representation::None();
1991 }
1992
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001993 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001994 virtual void PrintDataTo(StringStream* stream);
1995 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001996 bool IsInteger() const { return handle_->IsSmi(); }
1997 HConstant* CopyToRepresentation(Representation r) const;
1998 HConstant* CopyToTruncatedInt32() const;
1999 bool HasInteger32Value() const { return has_int32_value_; }
2000 int32_t Integer32Value() const {
2001 ASSERT(HasInteger32Value());
2002 return int32_value_;
2003 }
2004 bool HasDoubleValue() const { return has_double_value_; }
2005 double DoubleValue() const {
2006 ASSERT(HasDoubleValue());
2007 return double_value_;
2008 }
2009 bool HasStringValue() const { return handle_->IsString(); }
2010
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002011 bool ToBoolean() const;
2012
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002013 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002014 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002015 return reinterpret_cast<intptr_t>(*handle());
2016 }
2017
2018#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002019 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002020#endif
2021
2022 DECLARE_CONCRETE_INSTRUCTION(Constant, "constant")
2023
2024 protected:
2025 virtual Range* InferRange();
2026
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002027 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002028 HConstant* other_constant = HConstant::cast(other);
2029 return handle().is_identical_to(other_constant->handle());
2030 }
2031
2032 private:
2033 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002034
2035 // The following two values represent the int32 and the double value of the
2036 // given constant if there is a lossless conversion between the constant
2037 // and the specific representation.
danno@chromium.org160a7b02011-04-18 15:51:38 +00002038 bool has_int32_value_ : 1;
2039 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002040 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002041 double double_value_;
2042};
2043
2044
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002045class HBinaryOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002046 public:
2047 HBinaryOperation(HValue* left, HValue* right) {
2048 ASSERT(left != NULL && right != NULL);
2049 SetOperandAt(0, left);
2050 SetOperandAt(1, right);
2051 }
2052
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002053 HValue* left() { return OperandAt(0); }
2054 HValue* right() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002055
2056 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2057 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002058 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002059 if (IsCommutative() && left()->IsConstant()) return right();
2060 return left();
2061 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002062 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002063 if (IsCommutative() && left()->IsConstant()) return left();
2064 return right();
2065 }
2066
2067 virtual bool IsCommutative() const { return false; }
2068
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002069 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002070
2071 DECLARE_INSTRUCTION(BinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002072};
2073
2074
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002075class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002076 public:
2077 HApplyArguments(HValue* function,
2078 HValue* receiver,
2079 HValue* length,
2080 HValue* elements) {
2081 set_representation(Representation::Tagged());
2082 SetOperandAt(0, function);
2083 SetOperandAt(1, receiver);
2084 SetOperandAt(2, length);
2085 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002086 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002087 }
2088
2089 virtual Representation RequiredInputRepresentation(int index) const {
2090 // The length is untagged, all other inputs are tagged.
2091 return (index == 2)
2092 ? Representation::Integer32()
2093 : Representation::Tagged();
2094 }
2095
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002096 HValue* function() { return OperandAt(0); }
2097 HValue* receiver() { return OperandAt(1); }
2098 HValue* length() { return OperandAt(2); }
2099 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002100
2101 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply_arguments")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002102};
2103
2104
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002105class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002106 public:
2107 HArgumentsElements() {
2108 // The value produced by this instruction is a pointer into the stack
2109 // that looks as if it was a smi because of alignment.
2110 set_representation(Representation::Tagged());
2111 SetFlag(kUseGVN);
2112 }
2113
2114 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments_elements")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002115
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002116 virtual Representation RequiredInputRepresentation(int index) const {
2117 return Representation::None();
2118 }
2119
ager@chromium.org378b34e2011-01-28 08:04:38 +00002120 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002121 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002122};
2123
2124
2125class HArgumentsLength: public HUnaryOperation {
2126 public:
2127 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2128 set_representation(Representation::Integer32());
2129 SetFlag(kUseGVN);
2130 }
2131
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002132 virtual Representation RequiredInputRepresentation(int index) const {
2133 return Representation::Tagged();
2134 }
2135
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002136 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002137
2138 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002139 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002140};
2141
2142
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002143class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002144 public:
2145 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2146 set_representation(Representation::Tagged());
2147 SetFlag(kUseGVN);
2148 SetOperandAt(0, arguments);
2149 SetOperandAt(1, length);
2150 SetOperandAt(2, index);
2151 }
2152
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002153 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002154
2155 virtual Representation RequiredInputRepresentation(int index) const {
2156 // The arguments elements is considered tagged.
2157 return index == 0
2158 ? Representation::Tagged()
2159 : Representation::Integer32();
2160 }
2161
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002162 HValue* arguments() { return OperandAt(0); }
2163 HValue* length() { return OperandAt(1); }
2164 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002165
2166 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access_arguments_at")
2167
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002168 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002169};
2170
2171
2172class HBoundsCheck: public HBinaryOperation {
2173 public:
2174 HBoundsCheck(HValue* index, HValue* length)
2175 : HBinaryOperation(index, length) {
2176 SetFlag(kUseGVN);
2177 }
2178
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002179 virtual bool IsCheckInstruction() const { return true; }
2180
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002181 virtual Representation RequiredInputRepresentation(int index) const {
2182 return Representation::Integer32();
2183 }
2184
2185#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002186 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002187#endif
2188
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002189 HValue* index() { return left(); }
2190 HValue* length() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002191
2192 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds_check")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002193
2194 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002195 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002196};
2197
2198
2199class HBitwiseBinaryOperation: public HBinaryOperation {
2200 public:
2201 HBitwiseBinaryOperation(HValue* left, HValue* right)
2202 : HBinaryOperation(left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002203 set_representation(Representation::Tagged());
2204 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002205 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002206 }
2207
2208 virtual Representation RequiredInputRepresentation(int index) const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002209 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002210 }
2211
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002212 virtual void RepresentationChanged(Representation to) {
2213 if (!to.IsTagged()) {
2214 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002215 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002216 SetFlag(kTruncatingToInt32);
2217 SetFlag(kUseGVN);
2218 }
2219 }
2220
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002221 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002222
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002223 DECLARE_INSTRUCTION(BitwiseBinaryOperation)
2224};
2225
2226
2227class HArithmeticBinaryOperation: public HBinaryOperation {
2228 public:
2229 HArithmeticBinaryOperation(HValue* left, HValue* right)
2230 : HBinaryOperation(left, right) {
2231 set_representation(Representation::Tagged());
2232 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002233 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002234 }
2235
2236 virtual void RepresentationChanged(Representation to) {
2237 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002238 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002239 SetFlag(kUseGVN);
2240 }
2241 }
2242
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002243 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002244 virtual Representation RequiredInputRepresentation(int index) const {
2245 return representation();
2246 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002247 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002248 if (left()->representation().Equals(right()->representation())) {
2249 return left()->representation();
2250 }
2251 return HValue::InferredRepresentation();
2252 }
2253
2254 DECLARE_INSTRUCTION(ArithmeticBinaryOperation)
2255};
2256
2257
2258class HCompare: public HBinaryOperation {
2259 public:
2260 HCompare(HValue* left, HValue* right, Token::Value token)
2261 : HBinaryOperation(left, right), token_(token) {
2262 ASSERT(Token::IsCompareOp(token));
2263 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002264 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002265 }
2266
2267 void SetInputRepresentation(Representation r);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002268
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002269 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002270 return !HasSideEffects() && (uses()->length() <= 1);
2271 }
2272
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002273 virtual Representation RequiredInputRepresentation(int index) const {
2274 return input_representation_;
2275 }
2276 Representation GetInputRepresentation() const {
2277 return input_representation_;
2278 }
2279 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002280 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002281
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002282 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002283
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002284 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002285 return HValue::Hashcode() * 7 + token_;
2286 }
2287
2288 DECLARE_CONCRETE_INSTRUCTION(Compare, "compare")
2289
2290 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002291 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002292 HCompare* comp = HCompare::cast(other);
2293 return token_ == comp->token();
2294 }
2295
2296 private:
2297 Representation input_representation_;
2298 Token::Value token_;
2299};
2300
2301
2302class HCompareJSObjectEq: public HBinaryOperation {
2303 public:
2304 HCompareJSObjectEq(HValue* left, HValue* right)
2305 : HBinaryOperation(left, right) {
2306 set_representation(Representation::Tagged());
2307 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002308 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002309 }
2310
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002311 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002312 return !HasSideEffects() && (uses()->length() <= 1);
2313 }
2314
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002315 virtual Representation RequiredInputRepresentation(int index) const {
2316 return Representation::Tagged();
2317 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002318 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002319
2320 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq, "compare-js-object-eq")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002321
2322 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002323 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002324};
2325
2326
2327class HUnaryPredicate: public HUnaryOperation {
2328 public:
2329 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2330 set_representation(Representation::Tagged());
2331 SetFlag(kUseGVN);
2332 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002333
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002334 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002335 return !HasSideEffects() && (uses()->length() <= 1);
2336 }
2337
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002338 virtual Representation RequiredInputRepresentation(int index) const {
2339 return Representation::Tagged();
2340 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002341 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002342};
2343
2344
2345class HIsNull: public HUnaryPredicate {
2346 public:
2347 HIsNull(HValue* value, bool is_strict)
2348 : HUnaryPredicate(value), is_strict_(is_strict) { }
2349
2350 bool is_strict() const { return is_strict_; }
2351
2352 DECLARE_CONCRETE_INSTRUCTION(IsNull, "is_null")
2353
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002354 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002355 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002356 HIsNull* b = HIsNull::cast(other);
2357 return is_strict_ == b->is_strict();
2358 }
2359
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002360 private:
2361 bool is_strict_;
2362};
2363
2364
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002365class HIsObject: public HUnaryPredicate {
2366 public:
2367 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2368
2369 DECLARE_CONCRETE_INSTRUCTION(IsObject, "is_object")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002370
2371 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002372 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002373};
2374
2375
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002376class HIsSmi: public HUnaryPredicate {
2377 public:
2378 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2379
2380 DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002381
2382 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002383 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002384};
2385
2386
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002387class HIsConstructCall: public HTemplateInstruction<0> {
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002388 public:
2389 HIsConstructCall() {
2390 set_representation(Representation::Tagged());
2391 SetFlag(kUseGVN);
2392 }
2393
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002394 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002395 return !HasSideEffects() && (uses()->length() <= 1);
2396 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002397
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002398 virtual Representation RequiredInputRepresentation(int index) const {
2399 return Representation::None();
2400 }
2401
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002402 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall, "is_construct_call")
2403
2404 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002405 virtual bool DataEquals(HValue* other) { return true; }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002406};
2407
2408
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002409class HHasInstanceType: public HUnaryPredicate {
2410 public:
2411 HHasInstanceType(HValue* value, InstanceType type)
2412 : HUnaryPredicate(value), from_(type), to_(type) { }
2413 HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2414 : HUnaryPredicate(value), from_(from), to_(to) {
2415 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2416 }
2417
2418 InstanceType from() { return from_; }
2419 InstanceType to() { return to_; }
2420
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002421 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002422
2423 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has_instance_type")
2424
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002425 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002426 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002427 HHasInstanceType* b = HHasInstanceType::cast(other);
2428 return (from_ == b->from()) && (to_ == b->to());
2429 }
2430
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002431 private:
2432 InstanceType from_;
2433 InstanceType to_; // Inclusive range, not all combinations work.
2434};
2435
2436
2437class HHasCachedArrayIndex: public HUnaryPredicate {
2438 public:
2439 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2440
2441 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has_cached_array_index")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002442
2443 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002444 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002445};
2446
2447
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002448class HGetCachedArrayIndex: public HUnaryPredicate {
2449 public:
2450 explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2451
2452 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get_cached_array_index")
2453
2454 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002455 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002456};
2457
2458
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002459class HClassOfTest: public HUnaryPredicate {
2460 public:
2461 HClassOfTest(HValue* value, Handle<String> class_name)
2462 : HUnaryPredicate(value), class_name_(class_name) { }
2463
2464 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class_of_test")
2465
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002466 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002467
2468 Handle<String> class_name() const { return class_name_; }
2469
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002470 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002471 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002472 HClassOfTest* b = HClassOfTest::cast(other);
2473 return class_name_.is_identical_to(b->class_name_);
2474 }
2475
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002476 private:
2477 Handle<String> class_name_;
2478};
2479
2480
2481class HTypeofIs: public HUnaryPredicate {
2482 public:
2483 HTypeofIs(HValue* value, Handle<String> type_literal)
2484 : HUnaryPredicate(value), type_literal_(type_literal) { }
2485
2486 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002487 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002488
2489 DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof_is")
2490
2491 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002492 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002493 HTypeofIs* b = HTypeofIs::cast(other);
2494 return type_literal_.is_identical_to(b->type_literal_);
2495 }
2496
2497 private:
2498 Handle<String> type_literal_;
2499};
2500
2501
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002502class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002503 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002504 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2505 SetOperandAt(0, context);
2506 SetOperandAt(1, left);
2507 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002508 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002509 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002510 }
2511
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002512 HValue* context() { return OperandAt(0); }
2513 HValue* left() { return OperandAt(1); }
2514 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002515
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002516 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002517 return !HasSideEffects() && (uses()->length() <= 1);
2518 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002519
2520 virtual Representation RequiredInputRepresentation(int index) const {
2521 return Representation::Tagged();
2522 }
2523
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002524 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002525
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002526 DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance_of")
2527};
2528
2529
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002530class HInstanceOfKnownGlobal: public HUnaryOperation {
2531 public:
2532 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2533 : HUnaryOperation(left), function_(right) {
2534 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002535 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002536 }
2537
2538 Handle<JSFunction> function() { return function_; }
2539
2540 virtual Representation RequiredInputRepresentation(int index) const {
2541 return Representation::Tagged();
2542 }
2543
2544 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
2545 "instance_of_known_global")
2546
2547 private:
2548 Handle<JSFunction> function_;
2549};
2550
2551
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002552class HPower: public HBinaryOperation {
2553 public:
2554 HPower(HValue* left, HValue* right)
2555 : HBinaryOperation(left, right) {
2556 set_representation(Representation::Double());
2557 SetFlag(kUseGVN);
2558 }
2559
2560 virtual Representation RequiredInputRepresentation(int index) const {
2561 return (index == 1) ? Representation::None() : Representation::Double();
2562 }
2563
2564 DECLARE_CONCRETE_INSTRUCTION(Power, "power")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002565
2566 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002567 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002568};
2569
2570
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002571class HAdd: public HArithmeticBinaryOperation {
2572 public:
2573 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2574 SetFlag(kCanOverflow);
2575 }
2576
2577 // Add is only commutative if two integer values are added and not if two
2578 // tagged values are added (because it might be a String concatenation).
2579 virtual bool IsCommutative() const {
2580 return !representation().IsTagged();
2581 }
2582
2583 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2584
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002585 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002586
2587 DECLARE_CONCRETE_INSTRUCTION(Add, "add")
2588
2589 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002590 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002591
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002592 virtual Range* InferRange();
2593};
2594
2595
2596class HSub: public HArithmeticBinaryOperation {
2597 public:
2598 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2599 SetFlag(kCanOverflow);
2600 }
2601
2602 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2603
2604 DECLARE_CONCRETE_INSTRUCTION(Sub, "sub")
2605
2606 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002607 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002608
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002609 virtual Range* InferRange();
2610};
2611
2612
2613class HMul: public HArithmeticBinaryOperation {
2614 public:
2615 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2616 SetFlag(kCanOverflow);
2617 }
2618
2619 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2620
2621 // Only commutative if it is certain that not two objects are multiplicated.
2622 virtual bool IsCommutative() const {
2623 return !representation().IsTagged();
2624 }
2625
2626 DECLARE_CONCRETE_INSTRUCTION(Mul, "mul")
2627
2628 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002629 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002630
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002631 virtual Range* InferRange();
2632};
2633
2634
2635class HMod: public HArithmeticBinaryOperation {
2636 public:
2637 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2638 SetFlag(kCanBeDivByZero);
2639 }
2640
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002641 bool HasPowerOf2Divisor() {
2642 if (right()->IsConstant() &&
2643 HConstant::cast(right())->HasInteger32Value()) {
2644 int32_t value = HConstant::cast(right())->Integer32Value();
2645 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2646 }
2647
2648 return false;
2649 }
2650
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002651 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2652
2653 DECLARE_CONCRETE_INSTRUCTION(Mod, "mod")
2654
2655 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002656 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002657
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002658 virtual Range* InferRange();
2659};
2660
2661
2662class HDiv: public HArithmeticBinaryOperation {
2663 public:
2664 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2665 SetFlag(kCanBeDivByZero);
2666 SetFlag(kCanOverflow);
2667 }
2668
2669 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2670
2671 DECLARE_CONCRETE_INSTRUCTION(Div, "div")
2672
2673 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002674 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002675
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002676 virtual Range* InferRange();
2677};
2678
2679
2680class HBitAnd: public HBitwiseBinaryOperation {
2681 public:
2682 HBitAnd(HValue* left, HValue* right)
2683 : HBitwiseBinaryOperation(left, right) { }
2684
2685 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002686 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002687
2688 DECLARE_CONCRETE_INSTRUCTION(BitAnd, "bit_and")
2689
2690 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002691 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002692
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002693 virtual Range* InferRange();
2694};
2695
2696
2697class HBitXor: public HBitwiseBinaryOperation {
2698 public:
2699 HBitXor(HValue* left, HValue* right)
2700 : HBitwiseBinaryOperation(left, right) { }
2701
2702 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002703 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002704
2705 DECLARE_CONCRETE_INSTRUCTION(BitXor, "bit_xor")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002706
2707 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002708 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002709};
2710
2711
2712class HBitOr: public HBitwiseBinaryOperation {
2713 public:
2714 HBitOr(HValue* left, HValue* right)
2715 : HBitwiseBinaryOperation(left, right) { }
2716
2717 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002718 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002719
2720 DECLARE_CONCRETE_INSTRUCTION(BitOr, "bit_or")
2721
2722 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002723 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002724
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002725 virtual Range* InferRange();
2726};
2727
2728
2729class HShl: public HBitwiseBinaryOperation {
2730 public:
2731 HShl(HValue* left, HValue* right)
2732 : HBitwiseBinaryOperation(left, right) { }
2733
2734 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002735 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002736
2737 DECLARE_CONCRETE_INSTRUCTION(Shl, "shl")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002738
2739 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002740 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002741};
2742
2743
2744class HShr: public HBitwiseBinaryOperation {
2745 public:
2746 HShr(HValue* left, HValue* right)
2747 : HBitwiseBinaryOperation(left, right) { }
2748
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002749 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002750
2751 DECLARE_CONCRETE_INSTRUCTION(Shr, "shr")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002752
2753 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002754 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002755};
2756
2757
2758class HSar: public HBitwiseBinaryOperation {
2759 public:
2760 HSar(HValue* left, HValue* right)
2761 : HBitwiseBinaryOperation(left, right) { }
2762
2763 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002764 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002765
2766 DECLARE_CONCRETE_INSTRUCTION(Sar, "sar")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002767
2768 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002769 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002770};
2771
2772
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002773class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002774 public:
2775 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
2776 SetFlag(kChangesOsrEntries);
2777 }
2778
2779 int ast_id() const { return ast_id_; }
2780
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002781 virtual Representation RequiredInputRepresentation(int index) const {
2782 return Representation::None();
2783 }
2784
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002785 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr_entry")
2786
2787 private:
2788 int ast_id_;
2789};
2790
2791
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002792class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002793 public:
2794 explicit HParameter(unsigned index) : index_(index) {
2795 set_representation(Representation::Tagged());
2796 }
2797
2798 unsigned index() const { return index_; }
2799
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002800 virtual void PrintDataTo(StringStream* stream);
2801
2802 virtual Representation RequiredInputRepresentation(int index) const {
2803 return Representation::None();
2804 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002805
2806 DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
2807
2808 private:
2809 unsigned index_;
2810};
2811
2812
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002813class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002814 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002815 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
2816 : HUnaryCall(context, argument_count),
2817 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002818 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002819 }
2820
2821 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002822
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002823 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002824
2825 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
2826 transcendental_type_ = transcendental_type;
2827 }
2828 TranscendentalCache::Type transcendental_type() {
2829 return transcendental_type_;
2830 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002831
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002832 virtual void PrintDataTo(StringStream* stream);
2833
2834 virtual Representation RequiredInputRepresentation(int index) const {
2835 return Representation::Tagged();
2836 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002837
2838 DECLARE_CONCRETE_INSTRUCTION(CallStub, "call_stub")
2839
2840 private:
2841 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002842 TranscendentalCache::Type transcendental_type_;
2843};
2844
2845
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002846class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002847 public:
2848 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
2849
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002850 virtual Representation RequiredInputRepresentation(int index) const {
2851 return Representation::None();
2852 }
2853
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002854 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown_osr_value")
2855};
2856
2857
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002858class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002859 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002860 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002861 : cell_(cell), check_hole_value_(check_hole_value) {
2862 set_representation(Representation::Tagged());
2863 SetFlag(kUseGVN);
2864 SetFlag(kDependsOnGlobalVars);
2865 }
2866
2867 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
2868 bool check_hole_value() const { return check_hole_value_; }
2869
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002870 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002871
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002872 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002873 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002874 return reinterpret_cast<intptr_t>(*cell_);
2875 }
2876
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002877 virtual Representation RequiredInputRepresentation(int index) const {
2878 return Representation::None();
2879 }
2880
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002881 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell, "load_global_cell")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002882
2883 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002884 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002885 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002886 return cell_.is_identical_to(b->cell());
2887 }
2888
2889 private:
2890 Handle<JSGlobalPropertyCell> cell_;
2891 bool check_hole_value_;
2892};
2893
2894
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002895class HLoadGlobalGeneric: public HBinaryOperation {
2896 public:
2897 HLoadGlobalGeneric(HValue* context,
2898 HValue* global_object,
2899 Handle<Object> name,
2900 bool for_typeof)
2901 : HBinaryOperation(context, global_object),
2902 name_(name),
2903 for_typeof_(for_typeof) {
2904 set_representation(Representation::Tagged());
2905 SetAllSideEffects();
2906 }
2907
2908 HValue* context() { return OperandAt(0); }
2909 HValue* global_object() { return OperandAt(1); }
2910 Handle<Object> name() const { return name_; }
2911 bool for_typeof() const { return for_typeof_; }
2912
2913 virtual void PrintDataTo(StringStream* stream);
2914
2915 virtual Representation RequiredInputRepresentation(int index) const {
2916 return Representation::Tagged();
2917 }
2918
2919 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load_global_generic")
2920
2921 private:
2922 Handle<Object> name_;
2923 bool for_typeof_;
2924};
2925
2926
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002927class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002928 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002929 HStoreGlobalCell(HValue* value,
2930 Handle<JSGlobalPropertyCell> cell,
2931 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002932 : HUnaryOperation(value),
2933 cell_(cell),
2934 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002935 SetFlag(kChangesGlobalVars);
2936 }
2937
2938 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002939 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002940
2941 virtual Representation RequiredInputRepresentation(int index) const {
2942 return Representation::Tagged();
2943 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002944 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002945
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002946 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store_global_cell")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002947
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002948 private:
2949 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00002950 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002951};
2952
2953
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002954class HStoreGlobalGeneric: public HTemplateInstruction<3> {
2955 public:
2956 HStoreGlobalGeneric(HValue* context,
2957 HValue* global_object,
2958 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002959 HValue* value,
2960 bool strict_mode)
2961 : name_(name),
2962 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002963 SetOperandAt(0, context);
2964 SetOperandAt(1, global_object);
2965 SetOperandAt(2, value);
2966 set_representation(Representation::Tagged());
2967 SetAllSideEffects();
2968 }
2969
2970 HValue* context() { return OperandAt(0); }
2971 HValue* global_object() { return OperandAt(1); }
2972 Handle<Object> name() const { return name_; }
2973 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002974 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002975
2976 virtual void PrintDataTo(StringStream* stream);
2977
2978 virtual Representation RequiredInputRepresentation(int index) const {
2979 return Representation::Tagged();
2980 }
2981
2982 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric, "store_global_generic")
2983
2984 private:
2985 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002986 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002987};
2988
2989
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002990class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002991 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002992 HLoadContextSlot(HValue* context , int slot_index)
2993 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002994 set_representation(Representation::Tagged());
2995 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002996 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002997 }
2998
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002999 int slot_index() const { return slot_index_; }
3000
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003001 virtual Representation RequiredInputRepresentation(int index) const {
3002 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003003 }
3004
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003005 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003006
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003007 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load_context_slot")
3008
3009 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003010 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003011 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003012 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003013 }
3014
3015 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003016 int slot_index_;
3017};
3018
3019
3020static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
3021 return !value->type().IsSmi() &&
3022 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
3023}
3024
3025
3026class HStoreContextSlot: public HBinaryOperation {
3027 public:
3028 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
3029 : HBinaryOperation(context, value), slot_index_(slot_index) {
3030 SetFlag(kChangesContextSlots);
3031 }
3032
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003033 HValue* context() { return OperandAt(0); }
3034 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003035 int slot_index() const { return slot_index_; }
3036
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003037 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003038 return StoringValueNeedsWriteBarrier(value());
3039 }
3040
3041 virtual Representation RequiredInputRepresentation(int index) const {
3042 return Representation::Tagged();
3043 }
3044
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003045 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003046
3047 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store_context_slot")
3048
3049 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003050 int slot_index_;
3051};
3052
3053
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003054class HLoadNamedField: public HUnaryOperation {
3055 public:
3056 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3057 : HUnaryOperation(object),
3058 is_in_object_(is_in_object),
3059 offset_(offset) {
3060 set_representation(Representation::Tagged());
3061 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003062 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003063 if (is_in_object) {
3064 SetFlag(kDependsOnInobjectFields);
3065 } else {
3066 SetFlag(kDependsOnBackingStoreFields);
3067 }
3068 }
3069
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003070 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003071 bool is_in_object() const { return is_in_object_; }
3072 int offset() const { return offset_; }
3073
3074 virtual Representation RequiredInputRepresentation(int index) const {
3075 return Representation::Tagged();
3076 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003077 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003078
3079 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load_named_field")
3080
3081 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003082 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003083 HLoadNamedField* b = HLoadNamedField::cast(other);
3084 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3085 }
3086
3087 private:
3088 bool is_in_object_;
3089 int offset_;
3090};
3091
3092
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003093class HLoadNamedFieldPolymorphic: public HUnaryOperation {
3094 public:
3095 HLoadNamedFieldPolymorphic(HValue* object,
3096 ZoneMapList* types,
3097 Handle<String> name);
3098
3099 HValue* object() { return OperandAt(0); }
3100 ZoneMapList* types() { return &types_; }
3101 Handle<String> name() { return name_; }
3102 bool need_generic() { return need_generic_; }
3103
3104 virtual Representation RequiredInputRepresentation(int index) const {
3105 return Representation::Tagged();
3106 }
3107
3108 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic,
3109 "load_named_field_polymorphic")
3110
3111 static const int kMaxLoadPolymorphism = 4;
3112
3113 protected:
3114 virtual bool DataEquals(HValue* value);
3115
3116 private:
3117 ZoneMapList types_;
3118 Handle<String> name_;
3119 bool need_generic_;
3120};
3121
3122
3123
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003124class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003125 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003126 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
3127 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003128 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003129 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003130 }
3131
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003132 HValue* context() { return OperandAt(0); }
3133 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003134 Handle<Object> name() const { return name_; }
3135
3136 virtual Representation RequiredInputRepresentation(int index) const {
3137 return Representation::Tagged();
3138 }
3139
3140 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load_named_generic")
3141
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003142 private:
3143 Handle<Object> name_;
3144};
3145
3146
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003147class HLoadFunctionPrototype: public HUnaryOperation {
3148 public:
3149 explicit HLoadFunctionPrototype(HValue* function)
3150 : HUnaryOperation(function) {
3151 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003152 SetFlag(kUseGVN);
3153 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003154 }
3155
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003156 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003157
3158 virtual Representation RequiredInputRepresentation(int index) const {
3159 return Representation::Tagged();
3160 }
3161
3162 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load_function_prototype")
3163
3164 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003165 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003166};
3167
3168
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003169class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003170 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003171 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003172 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003173 SetFlag(kDependsOnArrayElements);
3174 SetFlag(kUseGVN);
3175 }
3176
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003177 HValue* object() { return OperandAt(0); }
3178 HValue* key() { return OperandAt(1); }
3179
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003180 virtual Representation RequiredInputRepresentation(int index) const {
3181 // The key is supposed to be Integer32.
3182 return (index == 1) ? Representation::Integer32()
3183 : Representation::Tagged();
3184 }
3185
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003186 virtual void PrintDataTo(StringStream* stream);
3187
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003188 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement,
3189 "load_keyed_fast_element")
ager@chromium.org378b34e2011-01-28 08:04:38 +00003190
3191 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003192 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003193};
3194
3195
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003196class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003197 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003198 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3199 HValue* key,
3200 ExternalArrayType array_type)
3201 : HBinaryOperation(external_elements, key),
3202 array_type_(array_type) {
3203 if (array_type == kExternalFloatArray) {
3204 set_representation(Representation::Double());
3205 } else {
3206 set_representation(Representation::Integer32());
3207 }
3208 SetFlag(kDependsOnSpecializedArrayElements);
3209 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003210 SetFlag(kDependsOnCalls);
3211 SetFlag(kUseGVN);
3212 }
3213
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003214 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003215
3216 virtual Representation RequiredInputRepresentation(int index) const {
3217 // The key is supposed to be Integer32, but the base pointer
3218 // for the element load is a naked pointer.
3219 return (index == 1) ? Representation::Integer32()
3220 : Representation::External();
3221 }
3222
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003223 HValue* external_pointer() { return OperandAt(0); }
3224 HValue* key() { return OperandAt(1); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003225 ExternalArrayType array_type() const { return array_type_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003226
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003227 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement,
3228 "load_keyed_specialized_array_element")
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003229
3230 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003231 virtual bool DataEquals(HValue* other) {
3232 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3233 HLoadKeyedSpecializedArrayElement* cast_other =
3234 HLoadKeyedSpecializedArrayElement::cast(other);
3235 return array_type_ == cast_other->array_type();
3236 }
3237
3238 private:
3239 ExternalArrayType array_type_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003240};
3241
3242
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003243class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003244 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003245 HLoadKeyedGeneric(HContext* context, HValue* obj, HValue* key) {
3246 set_representation(Representation::Tagged());
3247 SetOperandAt(0, obj);
3248 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003249 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003250 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003251 }
3252
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003253 HValue* object() { return OperandAt(0); }
3254 HValue* key() { return OperandAt(1); }
3255 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003256
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003257 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003258
3259 virtual Representation RequiredInputRepresentation(int index) const {
3260 return Representation::Tagged();
3261 }
3262
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003263 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load_keyed_generic")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003264};
3265
3266
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003267class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003268 public:
3269 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003270 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003271 HValue* val,
3272 bool in_object,
3273 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003274 : HBinaryOperation(obj, val),
3275 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003276 is_in_object_(in_object),
3277 offset_(offset) {
3278 if (is_in_object_) {
3279 SetFlag(kChangesInobjectFields);
3280 } else {
3281 SetFlag(kChangesBackingStoreFields);
3282 }
3283 }
3284
3285 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store_named_field")
3286
3287 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003288 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003289 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003290 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003291
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003292 HValue* object() { return OperandAt(0); }
3293 HValue* value() { return OperandAt(1); }
3294
3295 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003296 bool is_in_object() const { return is_in_object_; }
3297 int offset() const { return offset_; }
3298 Handle<Map> transition() const { return transition_; }
3299 void set_transition(Handle<Map> map) { transition_ = map; }
3300
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003301 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003302 return StoringValueNeedsWriteBarrier(value());
3303 }
3304
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003305 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003306 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003307 bool is_in_object_;
3308 int offset_;
3309 Handle<Map> transition_;
3310};
3311
3312
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003313class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003314 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003315 HStoreNamedGeneric(HValue* context,
3316 HValue* object,
3317 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003318 HValue* value,
3319 bool strict_mode)
3320 : name_(name),
3321 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003322 SetOperandAt(0, object);
3323 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003324 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003325 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003326 }
3327
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003328 HValue* object() { return OperandAt(0); }
3329 HValue* value() { return OperandAt(1); }
3330 HValue* context() { return OperandAt(2); }
3331 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003332 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003333
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003334 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003335
3336 virtual Representation RequiredInputRepresentation(int index) const {
3337 return Representation::Tagged();
3338 }
3339
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003340 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store_named_generic")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003341
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003342 private:
3343 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003344 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003345};
3346
3347
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003348class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003349 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003350 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3351 SetOperandAt(0, obj);
3352 SetOperandAt(1, key);
3353 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003354 SetFlag(kChangesArrayElements);
3355 }
3356
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003357 virtual Representation RequiredInputRepresentation(int index) const {
3358 // The key is supposed to be Integer32.
3359 return (index == 1) ? Representation::Integer32()
3360 : Representation::Tagged();
3361 }
3362
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003363 HValue* object() { return OperandAt(0); }
3364 HValue* key() { return OperandAt(1); }
3365 HValue* value() { return OperandAt(2); }
3366
3367 bool NeedsWriteBarrier() {
3368 return StoringValueNeedsWriteBarrier(value());
3369 }
3370
3371 virtual void PrintDataTo(StringStream* stream);
3372
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003373 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
3374 "store_keyed_fast_element")
3375};
3376
3377
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003378class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003379 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003380 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3381 HValue* key,
3382 HValue* val,
3383 ExternalArrayType array_type)
3384 : array_type_(array_type) {
3385 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003386 SetOperandAt(0, external_elements);
3387 SetOperandAt(1, key);
3388 SetOperandAt(2, val);
3389 }
3390
3391 virtual void PrintDataTo(StringStream* stream);
3392
3393 virtual Representation RequiredInputRepresentation(int index) const {
3394 if (index == 0) {
3395 return Representation::External();
3396 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003397 if (index == 2 && array_type() == kExternalFloatArray) {
3398 return Representation::Double();
3399 } else {
3400 return Representation::Integer32();
3401 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003402 }
3403 }
3404
3405 HValue* external_pointer() { return OperandAt(0); }
3406 HValue* key() { return OperandAt(1); }
3407 HValue* value() { return OperandAt(2); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003408 ExternalArrayType array_type() const { return array_type_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003409
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003410 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,
3411 "store_keyed_specialized_array_element")
3412 private:
3413 ExternalArrayType array_type_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003414};
3415
3416
3417class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003418 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003419 HStoreKeyedGeneric(HValue* context,
3420 HValue* object,
3421 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003422 HValue* value,
3423 bool strict_mode)
3424 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003425 SetOperandAt(0, object);
3426 SetOperandAt(1, key);
3427 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003428 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003429 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003430 }
3431
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003432 HValue* object() { return OperandAt(0); }
3433 HValue* key() { return OperandAt(1); }
3434 HValue* value() { return OperandAt(2); }
3435 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003436 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003437
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003438 virtual Representation RequiredInputRepresentation(int index) const {
3439 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003440 }
3441
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003442 virtual void PrintDataTo(StringStream* stream);
3443
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003444 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store_keyed_generic")
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003445
3446 private:
3447 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003448};
3449
3450
danno@chromium.org160a7b02011-04-18 15:51:38 +00003451class HStringAdd: public HBinaryOperation {
3452 public:
3453 HStringAdd(HValue* left, HValue* right) : HBinaryOperation(left, right) {
3454 set_representation(Representation::Tagged());
3455 SetFlag(kUseGVN);
3456 SetFlag(kDependsOnMaps);
3457 }
3458
3459 virtual Representation RequiredInputRepresentation(int index) const {
3460 return Representation::Tagged();
3461 }
3462
3463 virtual HType CalculateInferredType() {
3464 return HType::String();
3465 }
3466
3467 DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string_add")
3468
3469 protected:
3470 virtual bool DataEquals(HValue* other) { return true; }
3471};
3472
3473
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003474class HStringCharCodeAt: public HBinaryOperation {
3475 public:
3476 HStringCharCodeAt(HValue* string, HValue* index)
3477 : HBinaryOperation(string, index) {
3478 set_representation(Representation::Integer32());
3479 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003480 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003481 }
3482
3483 virtual Representation RequiredInputRepresentation(int index) const {
3484 // The index is supposed to be Integer32.
3485 return (index == 1) ? Representation::Integer32()
3486 : Representation::Tagged();
3487 }
3488
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003489 HValue* string() { return OperandAt(0); }
3490 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003491
3492 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string_char_code_at")
3493
3494 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003495 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003496
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003497 virtual Range* InferRange() {
3498 return new Range(0, String::kMaxUC16CharCode);
3499 }
3500};
3501
3502
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003503class HStringCharFromCode: public HUnaryOperation {
3504 public:
3505 explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
3506 set_representation(Representation::Tagged());
3507 SetFlag(kUseGVN);
3508 }
3509
3510 virtual Representation RequiredInputRepresentation(int index) const {
3511 return Representation::Integer32();
3512 }
3513
3514 virtual bool DataEquals(HValue* other) { return true; }
3515
3516 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string_char_from_code")
3517};
3518
3519
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003520class HStringLength: public HUnaryOperation {
3521 public:
3522 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3523 set_representation(Representation::Tagged());
3524 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003525 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003526 }
3527
3528 virtual Representation RequiredInputRepresentation(int index) const {
3529 return Representation::Tagged();
3530 }
3531
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003532 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003533 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3534 return HType::Smi();
3535 }
3536
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003537 DECLARE_CONCRETE_INSTRUCTION(StringLength, "string_length")
3538
3539 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003540 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003541
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003542 virtual Range* InferRange() {
3543 return new Range(0, String::kMaxLength);
3544 }
3545};
3546
3547
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003548template <int V>
3549class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003550 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003551 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003552 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003553 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003554 }
3555
3556 int literal_index() const { return literal_index_; }
3557 int depth() const { return depth_; }
3558
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003559 private:
3560 int literal_index_;
3561 int depth_;
3562};
3563
3564
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003565class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003566 public:
3567 HArrayLiteral(Handle<FixedArray> constant_elements,
3568 int length,
3569 int literal_index,
3570 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003571 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003572 length_(length),
3573 constant_elements_(constant_elements) {}
3574
3575 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3576 int length() const { return length_; }
3577
3578 bool IsCopyOnWrite() const;
3579
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003580 virtual Representation RequiredInputRepresentation(int index) const {
3581 return Representation::None();
3582 }
3583
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003584 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array_literal")
3585
3586 private:
3587 int length_;
3588 Handle<FixedArray> constant_elements_;
3589};
3590
3591
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003592class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003593 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003594 HObjectLiteral(HValue* context,
3595 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003596 bool fast_elements,
3597 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003598 int depth,
3599 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003600 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003601 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003602 fast_elements_(fast_elements),
3603 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003604 SetOperandAt(0, context);
3605 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003606
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003607 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003608 Handle<FixedArray> constant_properties() const {
3609 return constant_properties_;
3610 }
3611 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003612 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003613
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003614 virtual Representation RequiredInputRepresentation(int index) const {
3615 return Representation::Tagged();
3616 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003617
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003618 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object_literal")
3619
3620 private:
3621 Handle<FixedArray> constant_properties_;
3622 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003623 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003624};
3625
3626
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003627class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003628 public:
3629 HRegExpLiteral(Handle<String> pattern,
3630 Handle<String> flags,
3631 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003632 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003633 pattern_(pattern),
3634 flags_(flags) { }
3635
3636 Handle<String> pattern() { return pattern_; }
3637 Handle<String> flags() { return flags_; }
3638
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003639 virtual Representation RequiredInputRepresentation(int index) const {
3640 return Representation::None();
3641 }
3642
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003643 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp_literal")
3644
3645 private:
3646 Handle<String> pattern_;
3647 Handle<String> flags_;
3648};
3649
3650
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003651class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003652 public:
3653 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3654 : shared_info_(shared), pretenure_(pretenure) {
3655 set_representation(Representation::Tagged());
3656 }
3657
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003658 virtual Representation RequiredInputRepresentation(int index) const {
3659 return Representation::None();
3660 }
3661
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003662 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function_literal")
3663
3664 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3665 bool pretenure() const { return pretenure_; }
3666
3667 private:
3668 Handle<SharedFunctionInfo> shared_info_;
3669 bool pretenure_;
3670};
3671
3672
3673class HTypeof: public HUnaryOperation {
3674 public:
3675 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
3676 set_representation(Representation::Tagged());
3677 }
3678
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003679 virtual Representation RequiredInputRepresentation(int index) const {
3680 return Representation::Tagged();
3681 }
3682
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003683 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
3684};
3685
3686
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003687class HToFastProperties: public HUnaryOperation {
3688 public:
3689 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
3690 // This instruction is not marked as having side effects, but
3691 // changes the map of the input operand. Use it only when creating
3692 // object literals.
3693 ASSERT(value->IsObjectLiteral());
3694 set_representation(Representation::Tagged());
3695 }
3696
3697 virtual Representation RequiredInputRepresentation(int index) const {
3698 return Representation::Tagged();
3699 }
3700
3701 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to_fast_properties")
3702};
3703
3704
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003705class HValueOf: public HUnaryOperation {
3706 public:
3707 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
3708 set_representation(Representation::Tagged());
3709 }
3710
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003711 virtual Representation RequiredInputRepresentation(int index) const {
3712 return Representation::Tagged();
3713 }
3714
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003715 DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value_of")
3716};
3717
3718
3719class HDeleteProperty: public HBinaryOperation {
3720 public:
3721 HDeleteProperty(HValue* obj, HValue* key)
3722 : HBinaryOperation(obj, key) {
3723 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003724 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003725 }
3726
3727 virtual Representation RequiredInputRepresentation(int index) const {
3728 return Representation::Tagged();
3729 }
3730
3731 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete_property")
3732
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003733 HValue* object() { return left(); }
3734 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003735};
3736
3737#undef DECLARE_INSTRUCTION
3738#undef DECLARE_CONCRETE_INSTRUCTION
3739
3740} } // namespace v8::internal
3741
3742#endif // V8_HYDROGEN_INSTRUCTIONS_H_