blob: cc7535460a07d33aec529d7241b6021dba693490 [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"
32#include "code-stubs.h"
33#include "string-stream.h"
34#include "zone.h"
35
36namespace v8 {
37namespace internal {
38
39// Forward declarations.
40class HBasicBlock;
41class HEnvironment;
42class HInstruction;
43class HLoopInformation;
44class HValue;
45class LInstruction;
46class LChunkBuilder;
47
48
kasperl@chromium.orga5551262010-12-07 12:49:48 +000049#define HYDROGEN_ALL_INSTRUCTION_LIST(V) \
50 V(ArithmeticBinaryOperation) \
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +000051 V(BinaryCall) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000052 V(BinaryOperation) \
53 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000054 V(ControlInstruction) \
55 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000056 V(Phi) \
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +000057 V(UnaryCall) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000058 V(UnaryControlInstruction) \
59 V(UnaryOperation) \
60 HYDROGEN_CONCRETE_INSTRUCTION_LIST(V)
61
62
63#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +000064 V(AbnormalExit) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000065 V(AccessArgumentsAt) \
66 V(Add) \
67 V(ApplyArguments) \
68 V(ArgumentsElements) \
69 V(ArgumentsLength) \
70 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000071 V(ArrayLiteral) \
72 V(BitAnd) \
73 V(BitNot) \
74 V(BitOr) \
75 V(BitXor) \
76 V(BlockEntry) \
77 V(BoundsCheck) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000078 V(CallConstantFunction) \
79 V(CallFunction) \
80 V(CallGlobal) \
81 V(CallKeyed) \
82 V(CallKnownGlobal) \
83 V(CallNamed) \
84 V(CallNew) \
85 V(CallRuntime) \
86 V(CallStub) \
87 V(Change) \
88 V(CheckFunction) \
89 V(CheckInstanceType) \
90 V(CheckMap) \
91 V(CheckNonSmi) \
92 V(CheckPrototypeMaps) \
93 V(CheckSmi) \
94 V(Compare) \
95 V(CompareJSObjectEq) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000096 V(CompareMap) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000097 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +000098 V(Context) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000099 V(DeleteProperty) \
100 V(Deoptimize) \
101 V(Div) \
102 V(EnterInlined) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000103 V(FixedArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000104 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000105 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000106 V(GlobalObject) \
107 V(GlobalReceiver) \
108 V(Goto) \
109 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000110 V(InstanceOfKnownGlobal) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000111 V(IsNull) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000112 V(IsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000113 V(IsSmi) \
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +0000114 V(IsConstructCall) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000115 V(HasInstanceType) \
116 V(HasCachedArrayIndex) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000117 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000118 V(ClassOfTest) \
119 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000120 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000121 V(LoadElements) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000122 V(LoadFunctionPrototype) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000123 V(LoadGlobal) \
124 V(LoadKeyedFastElement) \
125 V(LoadKeyedGeneric) \
126 V(LoadNamedField) \
127 V(LoadNamedGeneric) \
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000128 V(LoadPixelArrayElement) \
129 V(LoadPixelArrayExternalPointer) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000130 V(Mod) \
131 V(Mul) \
132 V(ObjectLiteral) \
133 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000134 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000135 V(Parameter) \
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000136 V(PixelArrayLength) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000137 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000138 V(PushArgument) \
139 V(RegExpLiteral) \
140 V(Return) \
141 V(Sar) \
142 V(Shl) \
143 V(Shr) \
144 V(Simulate) \
145 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000146 V(StoreContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000147 V(StoreGlobal) \
148 V(StoreKeyedFastElement) \
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000149 V(StorePixelArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000150 V(StoreKeyedGeneric) \
151 V(StoreNamedField) \
152 V(StoreNamedGeneric) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000153 V(StringCharCodeAt) \
154 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000155 V(Sub) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000156 V(Test) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000157 V(Throw) \
158 V(Typeof) \
159 V(TypeofIs) \
160 V(UnaryMathOperation) \
161 V(UnknownOSRValue) \
162 V(ValueOf)
163
164#define GVN_FLAG_LIST(V) \
165 V(Calls) \
166 V(InobjectFields) \
167 V(BackingStoreFields) \
168 V(ArrayElements) \
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000169 V(PixelArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000170 V(GlobalVars) \
171 V(Maps) \
172 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000173 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000174 V(OsrEntries)
175
176#define DECLARE_INSTRUCTION(type) \
177 virtual bool Is##type() const { return true; } \
178 static H##type* cast(HValue* value) { \
179 ASSERT(value->Is##type()); \
180 return reinterpret_cast<H##type*>(value); \
181 } \
182 Opcode opcode() const { return HValue::k##type; }
183
184
185#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
186 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
187 virtual const char* Mnemonic() const { return mnemonic; } \
188 DECLARE_INSTRUCTION(type)
189
190
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000191class Range: public ZoneObject {
192 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000193 Range()
194 : lower_(kMinInt),
195 upper_(kMaxInt),
196 next_(NULL),
197 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000198
199 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000200 : lower_(lower),
201 upper_(upper),
202 next_(NULL),
203 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000204
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000205 int32_t upper() const { return upper_; }
206 int32_t lower() const { return lower_; }
207 Range* next() const { return next_; }
208 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
209 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000210 Range* Copy() const { return new Range(lower_, upper_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000211 int32_t Mask() const;
212 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
213 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
214 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
215 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000216 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
217 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
218 bool IsInSmiRange() const {
219 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000220 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000221 void KeepOrder();
222 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000223
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000224 void StackUpon(Range* other) {
225 Intersect(other);
226 next_ = other;
227 }
228
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000229 void Intersect(Range* other);
230 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000231
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000232 void AddConstant(int32_t value);
233 void Sar(int32_t value);
234 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000235 bool AddAndCheckOverflow(Range* other);
236 bool SubAndCheckOverflow(Range* other);
237 bool MulAndCheckOverflow(Range* other);
238
239 private:
240 int32_t lower_;
241 int32_t upper_;
242 Range* next_;
243 bool can_be_minus_zero_;
244};
245
246
247class Representation {
248 public:
249 enum Kind {
250 kNone,
251 kTagged,
252 kDouble,
253 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000254 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000255 kNumRepresentations
256 };
257
258 Representation() : kind_(kNone) { }
259
260 static Representation None() { return Representation(kNone); }
261 static Representation Tagged() { return Representation(kTagged); }
262 static Representation Integer32() { return Representation(kInteger32); }
263 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000264 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000265
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000266 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000267 return kind_ == other.kind_;
268 }
269
270 Kind kind() const { return kind_; }
271 bool IsNone() const { return kind_ == kNone; }
272 bool IsTagged() const { return kind_ == kTagged; }
273 bool IsInteger32() const { return kind_ == kInteger32; }
274 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000275 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000276 bool IsSpecialization() const {
277 return kind_ == kInteger32 || kind_ == kDouble;
278 }
279 const char* Mnemonic() const;
280
281 private:
282 explicit Representation(Kind k) : kind_(k) { }
283
284 Kind kind_;
285};
286
287
288class HType {
289 public:
290 HType() : type_(kUninitialized) { }
291
292 static HType Tagged() { return HType(kTagged); }
293 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
294 static HType TaggedNumber() { return HType(kTaggedNumber); }
295 static HType Smi() { return HType(kSmi); }
296 static HType HeapNumber() { return HType(kHeapNumber); }
297 static HType String() { return HType(kString); }
298 static HType Boolean() { return HType(kBoolean); }
299 static HType NonPrimitive() { return HType(kNonPrimitive); }
300 static HType JSArray() { return HType(kJSArray); }
301 static HType JSObject() { return HType(kJSObject); }
302 static HType Uninitialized() { return HType(kUninitialized); }
303
304 // Return the weakest (least precise) common type.
305 HType Combine(HType other) {
306 return HType(static_cast<Type>(type_ & other.type_));
307 }
308
309 bool Equals(const HType& other) {
310 return type_ == other.type_;
311 }
312
313 bool IsSubtypeOf(const HType& other) {
314 return Combine(other).Equals(other);
315 }
316
317 bool IsTagged() {
318 ASSERT(type_ != kUninitialized);
319 return ((type_ & kTagged) == kTagged);
320 }
321
322 bool IsTaggedPrimitive() {
323 ASSERT(type_ != kUninitialized);
324 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
325 }
326
327 bool IsTaggedNumber() {
328 ASSERT(type_ != kUninitialized);
329 return ((type_ & kTaggedNumber) == kTaggedNumber);
330 }
331
332 bool IsSmi() {
333 ASSERT(type_ != kUninitialized);
334 return ((type_ & kSmi) == kSmi);
335 }
336
337 bool IsHeapNumber() {
338 ASSERT(type_ != kUninitialized);
339 return ((type_ & kHeapNumber) == kHeapNumber);
340 }
341
342 bool IsString() {
343 ASSERT(type_ != kUninitialized);
344 return ((type_ & kString) == kString);
345 }
346
347 bool IsBoolean() {
348 ASSERT(type_ != kUninitialized);
349 return ((type_ & kBoolean) == kBoolean);
350 }
351
352 bool IsNonPrimitive() {
353 ASSERT(type_ != kUninitialized);
354 return ((type_ & kNonPrimitive) == kNonPrimitive);
355 }
356
357 bool IsJSArray() {
358 ASSERT(type_ != kUninitialized);
359 return ((type_ & kJSArray) == kJSArray);
360 }
361
362 bool IsJSObject() {
363 ASSERT(type_ != kUninitialized);
364 return ((type_ & kJSObject) == kJSObject);
365 }
366
367 bool IsUninitialized() {
368 return type_ == kUninitialized;
369 }
370
371 static HType TypeFromValue(Handle<Object> value);
372
373 const char* ToString();
374 const char* ToShortString();
375
376 private:
377 enum Type {
378 kTagged = 0x1, // 0000 0000 0000 0001
379 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
380 kTaggedNumber = 0xd, // 0000 0000 0000 1101
381 kSmi = 0x1d, // 0000 0000 0001 1101
382 kHeapNumber = 0x2d, // 0000 0000 0010 1101
383 kString = 0x45, // 0000 0000 0100 0101
384 kBoolean = 0x85, // 0000 0000 1000 0101
385 kNonPrimitive = 0x101, // 0000 0001 0000 0001
386 kJSObject = 0x301, // 0000 0011 0000 0001
387 kJSArray = 0x701, // 0000 0111 1000 0001
388 kUninitialized = 0x1fff // 0001 1111 1111 1111
389 };
390
391 explicit HType(Type t) : type_(t) { }
392
393 Type type_;
394};
395
396
397class HValue: public ZoneObject {
398 public:
399 static const int kNoNumber = -1;
400
401 // There must be one corresponding kDepends flag for every kChanges flag and
402 // the order of the kChanges flags must be exactly the same as of the kDepends
403 // flags.
404 enum Flag {
405 // Declare global value numbering flags.
406 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
407 GVN_FLAG_LIST(DECLARE_DO)
408 #undef DECLARE_DO
409 kFlexibleRepresentation,
410 kUseGVN,
411 kCanOverflow,
412 kBailoutOnMinusZero,
413 kCanBeDivByZero,
414 kIsArguments,
415 kTruncatingToInt32,
416 kLastFlag = kTruncatingToInt32
417 };
418
419 STATIC_ASSERT(kLastFlag < kBitsPerInt);
420
421 static const int kChangesToDependsFlagsLeftShift = 1;
422
423 static int ChangesFlagsMask() {
424 int result = 0;
425 // Create changes mask.
426#define DECLARE_DO(type) result |= (1 << kChanges##type);
427 GVN_FLAG_LIST(DECLARE_DO)
428#undef DECLARE_DO
429 return result;
430 }
431
432 static int DependsFlagsMask() {
433 return ConvertChangesToDependsFlags(ChangesFlagsMask());
434 }
435
436 static int ConvertChangesToDependsFlags(int flags) {
437 return flags << kChangesToDependsFlagsLeftShift;
438 }
439
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000440 static HValue* cast(HValue* value) { return value; }
441
442 enum Opcode {
443 // Declare a unique enum value for each hydrogen instruction.
444 #define DECLARE_DO(type) k##type,
445 HYDROGEN_ALL_INSTRUCTION_LIST(DECLARE_DO)
446 #undef DECLARE_DO
447 kMaxInstructionClass
448 };
449
450 HValue() : block_(NULL),
451 id_(kNoNumber),
452 uses_(2),
453 type_(HType::Tagged()),
454 range_(NULL),
455 flags_(0) {}
456 virtual ~HValue() {}
457
458 HBasicBlock* block() const { return block_; }
459 void SetBlock(HBasicBlock* block);
460
461 int id() const { return id_; }
462 void set_id(int id) { id_ = id; }
463
464 const ZoneList<HValue*>* uses() const { return &uses_; }
465
466 virtual bool EmitAtUses() const { return false; }
467 Representation representation() const { return representation_; }
468 void ChangeRepresentation(Representation r) {
469 // Representation was already set and is allowed to be changed.
470 ASSERT(!representation_.IsNone());
471 ASSERT(!r.IsNone());
472 ASSERT(CheckFlag(kFlexibleRepresentation));
473 RepresentationChanged(r);
474 representation_ = r;
475 }
476
477 HType type() const { return type_; }
478 void set_type(HType type) {
479 ASSERT(uses_.length() == 0);
480 type_ = type;
481 }
482
483 // An operation needs to override this function iff:
484 // 1) it can produce an int32 output.
485 // 2) the true value of its output can potentially be minus zero.
486 // The implementation must set a flag so that it bails out in the case where
487 // it would otherwise output what should be a minus zero as an int32 zero.
488 // If the operation also exists in a form that takes int32 and outputs int32
489 // then the operation should return its input value so that we can propagate
490 // back. There are two operations that need to propagate back to more than
491 // one input. They are phi and binary add. They always return NULL and
492 // expect the caller to take care of things.
493 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
494 visited->Add(id());
495 return NULL;
496 }
497
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000498 bool IsDefinedAfter(HBasicBlock* other) const;
499
500 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000501 virtual int OperandCount() = 0;
502 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000503 void SetOperandAt(int index, HValue* value);
504
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000505 int LookupOperandIndex(int occurrence_index, HValue* op);
506 bool UsesMultipleTimes(HValue* op);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000507
508 void ReplaceAndDelete(HValue* other);
509 void ReplaceValue(HValue* other);
510 void ReplaceAtUse(HValue* use, HValue* other);
511 void ReplaceFirstAtUse(HValue* use, HValue* other, Representation r);
512 bool HasNoUses() const { return uses_.is_empty(); }
513 void ClearOperands();
514 void Delete();
515
516 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000517 void SetFlag(Flag f) { flags_ |= (1 << f); }
518 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
519 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
520
521 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
522 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
523 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000524
525 Range* range() const { return range_; }
526 bool HasRange() const { return range_ != NULL; }
527 void AddNewRange(Range* r);
528 void RemoveLastAddedRange();
529 void ComputeInitialRange();
530
531 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000532 virtual Representation RequiredInputRepresentation(int index) const = 0;
533
534 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000535 return representation();
536 }
537
538 // This gives the instruction an opportunity to replace itself with an
539 // instruction that does the same in some better way. To replace an
540 // instruction with a new one, first add the new instruction to the graph,
541 // then return it. Return NULL to have the instruction deleted.
542 virtual HValue* Canonicalize() { return this; }
543
544 // Declare virtual type testers.
545#define DECLARE_DO(type) virtual bool Is##type() const { return false; }
546 HYDROGEN_ALL_INSTRUCTION_LIST(DECLARE_DO)
547#undef DECLARE_DO
548
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000549 bool Equals(HValue* other);
550 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000551
552 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000553 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000554 void PrintNameTo(StringStream* stream);
555 static void PrintTypeTo(HType type, StringStream* stream);
556
557 virtual const char* Mnemonic() const = 0;
558 virtual Opcode opcode() const = 0;
559
560 // Updated the inferred type of this instruction and returns true if
561 // it has changed.
562 bool UpdateInferredType();
563
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000564 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000565
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000566#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000567 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000568#endif
569
570 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000571 // This function must be overridden for instructions with flag kUseGVN, to
572 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000573 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000574 UNREACHABLE();
575 return false;
576 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000577 virtual void RepresentationChanged(Representation to) { }
578 virtual Range* InferRange();
579 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000580 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000581 void clear_block() {
582 ASSERT(block_ != NULL);
583 block_ = NULL;
584 }
585
586 void set_representation(Representation r) {
587 // Representation is set-once.
588 ASSERT(representation_.IsNone() && !r.IsNone());
589 representation_ = r;
590 }
591
592 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000593 // A flag mask to mark an instruction as having arbitrary side effects.
594 static int AllSideEffects() {
595 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
596 }
597
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000598 void InternalReplaceAtUse(HValue* use, HValue* other);
599 void RegisterUse(int index, HValue* new_value);
600
601 HBasicBlock* block_;
602
603 // The id of this instruction in the hydrogen graph, assigned when first
604 // added to the graph. Reflects creation order.
605 int id_;
606
607 Representation representation_;
608 ZoneList<HValue*> uses_;
609 HType type_;
610 Range* range_;
611 int flags_;
612
613 DISALLOW_COPY_AND_ASSIGN(HValue);
614};
615
616
617class HInstruction: public HValue {
618 public:
619 HInstruction* next() const { return next_; }
620 HInstruction* previous() const { return previous_; }
621
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000622 virtual void PrintTo(StringStream* stream);
623 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000624
625 bool IsLinked() const { return block() != NULL; }
626 void Unlink();
627 void InsertBefore(HInstruction* next);
628 void InsertAfter(HInstruction* previous);
629
630 int position() const { return position_; }
631 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
632 void set_position(int position) { position_ = position; }
633
634 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
635
636#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000637 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000638#endif
639
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000640 // Returns whether this is some kind of deoptimizing check
641 // instruction.
642 virtual bool IsCheckInstruction() const { return false; }
643
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000644 virtual bool IsCall() { return false; }
645
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000646 DECLARE_INSTRUCTION(Instruction)
647
648 protected:
649 HInstruction()
650 : next_(NULL),
651 previous_(NULL),
652 position_(RelocInfo::kNoPosition) {
653 SetFlag(kDependsOnOsrEntries);
654 }
655
656 virtual void DeleteFromGraph() { Unlink(); }
657
658 private:
659 void InitializeAsFirst(HBasicBlock* block) {
660 ASSERT(!IsLinked());
661 SetBlock(block);
662 }
663
664 HInstruction* next_;
665 HInstruction* previous_;
666 int position_;
667
668 friend class HBasicBlock;
669};
670
671
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000672class HControlInstruction: public HInstruction {
673 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000674 HControlInstruction(HBasicBlock* first, HBasicBlock* second)
675 : first_successor_(first), second_successor_(second) {
676 }
677
678 HBasicBlock* FirstSuccessor() const { return first_successor_; }
679 HBasicBlock* SecondSuccessor() const { return second_successor_; }
680
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000681 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000682
683 DECLARE_INSTRUCTION(ControlInstruction)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000684
685 private:
686 HBasicBlock* first_successor_;
687 HBasicBlock* second_successor_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000688};
689
690
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000691template<int NumElements>
692class HOperandContainer {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000693 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000694 HOperandContainer() : elems_() { }
695
696 int length() { return NumElements; }
697 HValue*& operator[](int i) {
698 ASSERT(i < length());
699 return elems_[i];
700 }
701
702 private:
703 HValue* elems_[NumElements];
704};
705
706
707template<>
708class HOperandContainer<0> {
709 public:
710 int length() { return 0; }
711 HValue*& operator[](int i) {
712 UNREACHABLE();
713 static HValue* t = 0;
714 return t;
715 }
716};
717
718
719template<int V>
720class HTemplateInstruction : public HInstruction {
721 public:
722 int OperandCount() { return V; }
723 HValue* OperandAt(int i) { return inputs_[i]; }
724
725 protected:
726 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
727
728 private:
729 HOperandContainer<V> inputs_;
730};
731
732
733template<int V>
734class HTemplateControlInstruction : public HControlInstruction {
735 public:
736 HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second)
737 : HControlInstruction(first, second) { }
738 int OperandCount() { return V; }
739 HValue* OperandAt(int i) { return inputs_[i]; }
740
741 protected:
742 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
743
744 private:
745 HOperandContainer<V> inputs_;
746};
747
748
749class HBlockEntry: public HTemplateInstruction<0> {
750 public:
751 virtual Representation RequiredInputRepresentation(int index) const {
752 return Representation::None();
753 }
754
755 DECLARE_CONCRETE_INSTRUCTION(BlockEntry, "block_entry")
756};
757
758
759class HDeoptimize: public HTemplateControlInstruction<0> {
760 public:
761 HDeoptimize() : HTemplateControlInstruction<0>(NULL, NULL) { }
762
763 virtual Representation RequiredInputRepresentation(int index) const {
764 return Representation::None();
765 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000766
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000767 DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
768};
769
770
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000771class HGoto: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000772 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000773 explicit HGoto(HBasicBlock* target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000774 : HTemplateControlInstruction<0>(target, NULL),
775 include_stack_check_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000776
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000777 void set_include_stack_check(bool include_stack_check) {
778 include_stack_check_ = include_stack_check;
779 }
780 bool include_stack_check() const { return include_stack_check_; }
781
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000782 virtual Representation RequiredInputRepresentation(int index) const {
783 return Representation::None();
784 }
785
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000786 DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
787
788 private:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000789 bool include_stack_check_;
790};
791
792
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000793class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000794 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000795 explicit HUnaryControlInstruction(HValue* value,
796 HBasicBlock* true_target,
797 HBasicBlock* false_target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000798 : HTemplateControlInstruction<1>(true_target, false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000799 SetOperandAt(0, value);
800 }
801
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000802 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000803
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000804 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000805
806 DECLARE_INSTRUCTION(UnaryControlInstruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000807};
808
809
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000810class HTest: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000811 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000812 HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
813 : HUnaryControlInstruction(value, true_target, false_target) {
814 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000815 }
816
817 virtual Representation RequiredInputRepresentation(int index) const {
818 return Representation::None();
819 }
820
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000821 DECLARE_CONCRETE_INSTRUCTION(Test, "test")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000822};
823
824
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000825class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000826 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000827 HCompareMap(HValue* value,
828 Handle<Map> map,
829 HBasicBlock* true_target,
830 HBasicBlock* false_target)
831 : HUnaryControlInstruction(value, true_target, false_target),
832 map_(map) {
833 ASSERT(true_target != NULL);
834 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000835 ASSERT(!map.is_null());
836 }
837
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000838 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000839
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000840 Handle<Map> map() const { return map_; }
841
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000842 virtual Representation RequiredInputRepresentation(int index) const {
843 return Representation::Tagged();
844 }
845
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000846 DECLARE_CONCRETE_INSTRUCTION(CompareMap, "compare_map")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000847
848 private:
849 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000850};
851
852
853class HReturn: public HUnaryControlInstruction {
854 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000855 explicit HReturn(HValue* value)
856 : HUnaryControlInstruction(value, NULL, NULL) {
857 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000858
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000859 virtual Representation RequiredInputRepresentation(int index) const {
860 return Representation::Tagged();
861 }
862
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000863 DECLARE_CONCRETE_INSTRUCTION(Return, "return")
864};
865
866
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000867class HAbnormalExit: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000868 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000869 HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
870
871 virtual Representation RequiredInputRepresentation(int index) const {
872 return Representation::None();
873 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000874
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000875 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit, "abnormal_exit")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000876};
877
878
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000879class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000880 public:
881 explicit HUnaryOperation(HValue* value) {
882 SetOperandAt(0, value);
883 }
884
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000885 HValue* value() { return OperandAt(0); }
886 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000887
888 DECLARE_INSTRUCTION(UnaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000889};
890
891
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000892class HThrow: public HUnaryOperation {
893 public:
894 explicit HThrow(HValue* value) : HUnaryOperation(value) {
895 SetAllSideEffects();
896 }
897
898 virtual Representation RequiredInputRepresentation(int index) const {
899 return Representation::Tagged();
900 }
901
902 DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
903};
904
905
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000906class HChange: public HUnaryOperation {
907 public:
908 HChange(HValue* value,
909 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000910 Representation to,
911 bool is_truncating)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000912 : HUnaryOperation(value), from_(from), to_(to) {
913 ASSERT(!from.IsNone() && !to.IsNone());
914 ASSERT(!from.Equals(to));
915 set_representation(to);
916 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000917 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000918 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
919 value->range()->IsInSmiRange()) {
920 set_type(HType::Smi());
921 }
922 }
923
924 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
925
926 Representation from() const { return from_; }
927 Representation to() const { return to_; }
928 virtual Representation RequiredInputRepresentation(int index) const {
929 return from_;
930 }
931
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000932 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000933
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000934 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000935
936 DECLARE_CONCRETE_INSTRUCTION(Change,
937 CanTruncateToInt32() ? "truncate" : "change")
938
939 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000940 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000941 if (!other->IsChange()) return false;
942 HChange* change = HChange::cast(other);
943 return value() == change->value()
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000944 && to().Equals(change->to());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000945 }
946
947 private:
948 Representation from_;
949 Representation to_;
950};
951
952
953class HSimulate: public HInstruction {
954 public:
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000955 HSimulate(int ast_id, int pop_count, int environment_length)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000956 : ast_id_(ast_id),
957 pop_count_(pop_count),
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000958 environment_length_(environment_length),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000959 values_(2),
960 assigned_indexes_(2) {}
961 virtual ~HSimulate() {}
962
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000963 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000964
965 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
966 int ast_id() const { return ast_id_; }
967 void set_ast_id(int id) {
968 ASSERT(!HasAstId());
969 ast_id_ = id;
970 }
971
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000972 int environment_length() const { return environment_length_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000973 int pop_count() const { return pop_count_; }
974 const ZoneList<HValue*>* values() const { return &values_; }
975 int GetAssignedIndexAt(int index) const {
976 ASSERT(HasAssignedIndexAt(index));
977 return assigned_indexes_[index];
978 }
979 bool HasAssignedIndexAt(int index) const {
980 return assigned_indexes_[index] != kNoIndex;
981 }
982 void AddAssignedValue(int index, HValue* value) {
983 AddValue(index, value);
984 }
985 void AddPushedValue(HValue* value) {
986 AddValue(kNoIndex, value);
987 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000988 virtual int OperandCount() { return values_.length(); }
989 virtual HValue* OperandAt(int index) { return values_[index]; }
990
991 virtual Representation RequiredInputRepresentation(int index) const {
992 return Representation::None();
993 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000994
995 DECLARE_CONCRETE_INSTRUCTION(Simulate, "simulate")
996
997#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000998 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000999#endif
1000
1001 protected:
1002 virtual void InternalSetOperandAt(int index, HValue* value) {
1003 values_[index] = value;
1004 }
1005
1006 private:
1007 static const int kNoIndex = -1;
1008 void AddValue(int index, HValue* value) {
1009 assigned_indexes_.Add(index);
1010 // Resize the list of pushed values.
1011 values_.Add(NULL);
1012 // Set the operand through the base method in HValue to make sure that the
1013 // use lists are correctly updated.
1014 SetOperandAt(values_.length() - 1, value);
1015 }
1016 int ast_id_;
1017 int pop_count_;
lrn@chromium.org5d00b602011-01-05 09:51:43 +00001018 int environment_length_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001019 ZoneList<HValue*> values_;
1020 ZoneList<int> assigned_indexes_;
1021};
1022
1023
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001024class HStackCheck: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001025 public:
1026 HStackCheck() { }
1027
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001028 virtual Representation RequiredInputRepresentation(int index) const {
1029 return Representation::None();
1030 }
1031
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001032 DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack_check")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001033};
1034
1035
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001036class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001037 public:
1038 HEnterInlined(Handle<JSFunction> closure, FunctionLiteral* function)
1039 : closure_(closure), function_(function) {
1040 }
1041
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001042 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001043
1044 Handle<JSFunction> closure() const { return closure_; }
1045 FunctionLiteral* function() const { return function_; }
1046
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001047 virtual Representation RequiredInputRepresentation(int index) const {
1048 return Representation::None();
1049 }
1050
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001051 DECLARE_CONCRETE_INSTRUCTION(EnterInlined, "enter_inlined")
1052
1053 private:
1054 Handle<JSFunction> closure_;
1055 FunctionLiteral* function_;
1056};
1057
1058
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001059class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001060 public:
1061 HLeaveInlined() {}
1062
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001063 virtual Representation RequiredInputRepresentation(int index) const {
1064 return Representation::None();
1065 }
1066
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001067 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined, "leave_inlined")
1068};
1069
1070
1071class HPushArgument: public HUnaryOperation {
1072 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001073 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1074 set_representation(Representation::Tagged());
1075 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001076
1077 virtual Representation RequiredInputRepresentation(int index) const {
1078 return Representation::Tagged();
1079 }
1080
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001081 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001082
1083 DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push_argument")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001084};
1085
1086
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001087class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001088 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001089 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001090 set_representation(Representation::Tagged());
1091 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001092 }
1093
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001094 virtual Representation RequiredInputRepresentation(int index) const {
1095 return Representation::None();
1096 }
1097
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001098 DECLARE_CONCRETE_INSTRUCTION(Context, "context");
1099
1100 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001101 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001102};
1103
1104
1105class HOuterContext: public HUnaryOperation {
1106 public:
1107 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1108 set_representation(Representation::Tagged());
1109 SetFlag(kUseGVN);
1110 }
1111
1112 DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer_context");
1113
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001114 virtual Representation RequiredInputRepresentation(int index) const {
1115 return Representation::Tagged();
1116 }
1117
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001118 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001119 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001120};
1121
1122
1123class HGlobalObject: public HUnaryOperation {
1124 public:
1125 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1126 set_representation(Representation::Tagged());
1127 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001128 }
1129
1130 DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global_object")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001131
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001132 virtual Representation RequiredInputRepresentation(int index) const {
1133 return Representation::Tagged();
1134 }
1135
ager@chromium.org378b34e2011-01-28 08:04:38 +00001136 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001137 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001138};
1139
1140
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001141class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001142 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001143 explicit HGlobalReceiver(HValue* global_object)
1144 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001145 set_representation(Representation::Tagged());
1146 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001147 }
1148
1149 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global_receiver")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001150
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001151 virtual Representation RequiredInputRepresentation(int index) const {
1152 return Representation::Tagged();
1153 }
1154
ager@chromium.org378b34e2011-01-28 08:04:38 +00001155 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001156 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001157};
1158
1159
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001160template <int V>
1161class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001162 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001163 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001164 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1165 this->set_representation(Representation::Tagged());
1166 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001167 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001168
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001169 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001170
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001171 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001172
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001173 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001174
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001175 private:
1176 int argument_count_;
1177};
1178
1179
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001180class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001181 public:
1182 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001183 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001184 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001185 }
1186
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001187 virtual Representation RequiredInputRepresentation(int index) const {
1188 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001189 }
1190
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001191 virtual void PrintDataTo(StringStream* stream);
1192
1193 HValue* value() { return OperandAt(0); }
1194
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001195 DECLARE_INSTRUCTION(UnaryCall)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001196};
1197
1198
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001199class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001200 public:
1201 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001202 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001203 SetOperandAt(0, first);
1204 SetOperandAt(1, second);
1205 }
1206
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001207 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001208
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001209 virtual Representation RequiredInputRepresentation(int index) const {
1210 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001211 }
1212
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001213 HValue* first() { return OperandAt(0); }
1214 HValue* second() { return OperandAt(1); }
1215
1216 DECLARE_INSTRUCTION(BinaryCall)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001217};
1218
1219
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001220class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001221 public:
1222 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001223 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001224
1225 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001226
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001227 bool IsApplyFunction() const {
1228 return function_->code() == Builtins::builtin(Builtins::FunctionApply);
1229 }
1230
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001231 virtual void PrintDataTo(StringStream* stream);
1232
1233 virtual Representation RequiredInputRepresentation(int index) const {
1234 return Representation::None();
1235 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001236
1237 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call_constant_function")
1238
1239 private:
1240 Handle<JSFunction> function_;
1241};
1242
1243
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001244class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001245 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001246 HCallKeyed(HValue* context, HValue* key, int argument_count)
1247 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001248 }
1249
1250 virtual Representation RequiredInputRepresentation(int index) const {
1251 return Representation::Tagged();
1252 }
1253
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001254 HValue* context() { return first(); }
1255 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001256
1257 DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call_keyed")
1258};
1259
1260
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001261class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001262 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001263 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1264 : HUnaryCall(context, argument_count), name_(name) {
1265 }
1266
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001267 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001268
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001269 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001270 Handle<String> name() const { return name_; }
1271
1272 DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call_named")
1273
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001274 virtual Representation RequiredInputRepresentation(int index) const {
1275 return Representation::Tagged();
1276 }
1277
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001278 private:
1279 Handle<String> name_;
1280};
1281
1282
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001283class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001284 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001285 HCallFunction(HValue* context, int argument_count)
1286 : HUnaryCall(context, argument_count) {
1287 }
1288
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001289 HValue* context() { return value(); }
1290
1291 virtual Representation RequiredInputRepresentation(int index) const {
1292 return Representation::Tagged();
1293 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001294
1295 DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call_function")
1296};
1297
1298
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001299class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001300 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001301 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1302 : HUnaryCall(context, argument_count), name_(name) {
1303 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001304
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001305 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001306
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001307 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001308 Handle<String> name() const { return name_; }
1309
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001310 virtual Representation RequiredInputRepresentation(int index) const {
1311 return Representation::Tagged();
1312 }
1313
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001314 DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call_global")
1315
1316 private:
1317 Handle<String> name_;
1318};
1319
1320
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001321class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001322 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001323 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001324 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001325
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001326 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001327
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001328 Handle<JSFunction> target() const { return target_; }
1329
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001330 virtual Representation RequiredInputRepresentation(int index) const {
1331 return Representation::None();
1332 }
1333
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001334 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call_known_global")
1335
1336 private:
1337 Handle<JSFunction> target_;
1338};
1339
1340
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001341class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001342 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001343 HCallNew(HValue* context, HValue* constructor, int argument_count)
1344 : HBinaryCall(context, constructor, argument_count) {
1345 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001346
1347 virtual Representation RequiredInputRepresentation(int index) const {
1348 return Representation::Tagged();
1349 }
1350
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001351 HValue* context() { return first(); }
1352 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001353
1354 DECLARE_CONCRETE_INSTRUCTION(CallNew, "call_new")
1355};
1356
1357
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001358class HCallRuntime: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001359 public:
1360 HCallRuntime(Handle<String> name,
1361 Runtime::Function* c_function,
1362 int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001363 : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
1364 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001365
1366 Runtime::Function* function() const { return c_function_; }
1367 Handle<String> name() const { return name_; }
1368
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001369 virtual Representation RequiredInputRepresentation(int index) const {
1370 return Representation::None();
1371 }
1372
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001373 DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call_runtime")
1374
1375 private:
1376 Runtime::Function* c_function_;
1377 Handle<String> name_;
1378};
1379
1380
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001381class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001382 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001383 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001384 // The length of an array is stored as a tagged value in the array
1385 // object. It is guaranteed to be 32 bit integer, but it can be
1386 // represented as either a smi or heap number.
1387 set_representation(Representation::Tagged());
1388 SetFlag(kDependsOnArrayLengths);
1389 SetFlag(kUseGVN);
1390 }
1391
1392 virtual Representation RequiredInputRepresentation(int index) const {
1393 return Representation::Tagged();
1394 }
1395
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001396 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js_array_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001397
1398 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001399 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001400};
1401
1402
1403class HFixedArrayLength: public HUnaryOperation {
1404 public:
1405 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1406 set_representation(Representation::Tagged());
1407 SetFlag(kDependsOnArrayLengths);
1408 SetFlag(kUseGVN);
1409 }
1410
1411 virtual Representation RequiredInputRepresentation(int index) const {
1412 return Representation::Tagged();
1413 }
1414
1415 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed_array_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001416
1417 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001418 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001419};
1420
1421
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001422class HPixelArrayLength: public HUnaryOperation {
1423 public:
1424 explicit HPixelArrayLength(HValue* value) : HUnaryOperation(value) {
1425 set_representation(Representation::Integer32());
1426 // The result of this instruction is idempotent as long as its inputs don't
1427 // change. The length of a pixel array cannot change once set, so it's not
1428 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1429 SetFlag(kUseGVN);
1430 }
1431
1432 virtual Representation RequiredInputRepresentation(int index) const {
1433 return Representation::Tagged();
1434 }
1435
1436 DECLARE_CONCRETE_INSTRUCTION(PixelArrayLength, "pixel_array_length")
1437
1438 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001439 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001440};
1441
1442
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001443class HBitNot: public HUnaryOperation {
1444 public:
1445 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1446 set_representation(Representation::Integer32());
1447 SetFlag(kUseGVN);
1448 SetFlag(kTruncatingToInt32);
1449 }
1450
1451 virtual Representation RequiredInputRepresentation(int index) const {
1452 return Representation::Integer32();
1453 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001454 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001455
1456 DECLARE_CONCRETE_INSTRUCTION(BitNot, "bit_not")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001457
1458 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001459 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001460};
1461
1462
1463class HUnaryMathOperation: public HUnaryOperation {
1464 public:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001465 HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001466 : HUnaryOperation(value), op_(op) {
1467 switch (op) {
1468 case kMathFloor:
1469 case kMathRound:
1470 case kMathCeil:
1471 set_representation(Representation::Integer32());
1472 break;
1473 case kMathAbs:
1474 set_representation(Representation::Tagged());
1475 SetFlag(kFlexibleRepresentation);
1476 break;
1477 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001478 case kMathPowHalf:
1479 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001480 case kMathSin:
1481 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001482 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001483 break;
1484 default:
1485 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001486 }
1487 SetFlag(kUseGVN);
1488 }
1489
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001490 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001491
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001492 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001493
1494 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1495
1496 virtual Representation RequiredInputRepresentation(int index) const {
1497 switch (op_) {
1498 case kMathFloor:
1499 case kMathRound:
1500 case kMathCeil:
1501 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001502 case kMathPowHalf:
1503 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001504 case kMathSin:
1505 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001506 return Representation::Double();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001507 case kMathAbs:
1508 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001509 default:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001510 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001511 return Representation::None();
1512 }
1513 }
1514
1515 virtual HValue* Canonicalize() {
1516 // If the input is integer32 then we replace the floor instruction
1517 // with its inputs. This happens before the representation changes are
1518 // introduced.
1519 if (op() == kMathFloor) {
1520 if (value()->representation().IsInteger32()) return value();
1521 }
1522 return this;
1523 }
1524
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001525 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001526 const char* OpName() const;
1527
1528 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary_math_operation")
1529
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001530 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001531 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001532 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1533 return op_ == b->op();
1534 }
1535
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001536 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001537 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001538};
1539
1540
1541class HLoadElements: public HUnaryOperation {
1542 public:
1543 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1544 set_representation(Representation::Tagged());
1545 SetFlag(kUseGVN);
1546 SetFlag(kDependsOnMaps);
1547 }
1548
1549 virtual Representation RequiredInputRepresentation(int index) const {
1550 return Representation::Tagged();
1551 }
1552
1553 DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001554
1555 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001556 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001557};
1558
1559
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001560class HLoadPixelArrayExternalPointer: public HUnaryOperation {
1561 public:
1562 explicit HLoadPixelArrayExternalPointer(HValue* value)
1563 : HUnaryOperation(value) {
1564 set_representation(Representation::External());
1565 // The result of this instruction is idempotent as long as its inputs don't
1566 // change. The external array of a pixel array elements object cannot
1567 // change once set, so it's no necessary to introduce any additional
1568 // dependencies on top of the inputs.
1569 SetFlag(kUseGVN);
1570 }
1571
1572 virtual Representation RequiredInputRepresentation(int index) const {
1573 return Representation::Tagged();
1574 }
1575
1576 DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayExternalPointer,
1577 "load-pixel-array-external-pointer")
1578
1579 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001580 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001581};
1582
1583
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001584class HCheckMap: public HUnaryOperation {
1585 public:
1586 HCheckMap(HValue* value, Handle<Map> map)
1587 : HUnaryOperation(value), map_(map) {
1588 set_representation(Representation::Tagged());
1589 SetFlag(kUseGVN);
1590 SetFlag(kDependsOnMaps);
1591 }
1592
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001593 virtual bool IsCheckInstruction() const { return true; }
1594
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001595 virtual Representation RequiredInputRepresentation(int index) const {
1596 return Representation::Tagged();
1597 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001598 virtual void PrintDataTo(StringStream* stream);
1599 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001600
1601#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001602 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001603#endif
1604
1605 Handle<Map> map() const { return map_; }
1606
1607 DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check_map")
1608
1609 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001610 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001611 HCheckMap* b = HCheckMap::cast(other);
1612 return map_.is_identical_to(b->map());
1613 }
1614
1615 private:
1616 Handle<Map> map_;
1617};
1618
1619
1620class HCheckFunction: public HUnaryOperation {
1621 public:
1622 HCheckFunction(HValue* value, Handle<JSFunction> function)
1623 : HUnaryOperation(value), target_(function) {
1624 set_representation(Representation::Tagged());
1625 SetFlag(kUseGVN);
1626 }
1627
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001628 virtual bool IsCheckInstruction() const { return true; }
1629
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001630 virtual Representation RequiredInputRepresentation(int index) const {
1631 return Representation::Tagged();
1632 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001633 virtual void PrintDataTo(StringStream* stream);
1634 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001635
1636#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001637 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001638#endif
1639
1640 Handle<JSFunction> target() const { return target_; }
1641
1642 DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check_function")
1643
1644 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001645 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001646 HCheckFunction* b = HCheckFunction::cast(other);
1647 return target_.is_identical_to(b->target());
1648 }
1649
1650 private:
1651 Handle<JSFunction> target_;
1652};
1653
1654
1655class HCheckInstanceType: public HUnaryOperation {
1656 public:
1657 // Check that the instance type is in the range [first, last] where
1658 // both first and last are included.
1659 HCheckInstanceType(HValue* value, InstanceType first, InstanceType last)
1660 : HUnaryOperation(value), first_(first), last_(last) {
1661 ASSERT(first <= last);
1662 set_representation(Representation::Tagged());
1663 SetFlag(kUseGVN);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001664 if ((FIRST_STRING_TYPE < first && last <= LAST_STRING_TYPE) ||
1665 (FIRST_STRING_TYPE <= first && last < LAST_STRING_TYPE)) {
1666 // A particular string instance type can change because of GC or
1667 // externalization, but the value still remains a string.
1668 SetFlag(kDependsOnMaps);
1669 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001670 }
1671
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001672 virtual bool IsCheckInstruction() const { return true; }
1673
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001674 virtual Representation RequiredInputRepresentation(int index) const {
1675 return Representation::Tagged();
1676 }
1677
1678#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001679 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001680#endif
1681
1682 static HCheckInstanceType* NewIsJSObjectOrJSFunction(HValue* value);
1683
1684 InstanceType first() const { return first_; }
1685 InstanceType last() const { return last_; }
1686
1687 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check_instance_type")
1688
1689 protected:
1690 // TODO(ager): It could be nice to allow the ommision of instance
1691 // type checks if we have already performed an instance type check
1692 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001693 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001694 HCheckInstanceType* b = HCheckInstanceType::cast(other);
1695 return (first_ == b->first()) && (last_ == b->last());
1696 }
1697
1698 private:
1699 InstanceType first_;
1700 InstanceType last_;
1701};
1702
1703
1704class HCheckNonSmi: public HUnaryOperation {
1705 public:
1706 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
1707 set_representation(Representation::Tagged());
1708 SetFlag(kUseGVN);
1709 }
1710
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001711 virtual bool IsCheckInstruction() const { return true; }
1712
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001713 virtual Representation RequiredInputRepresentation(int index) const {
1714 return Representation::Tagged();
1715 }
1716
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001717 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001718
1719#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001720 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001721#endif
1722
1723 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check_non_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001724
1725 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001726 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001727};
1728
1729
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001730class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001731 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001732 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
1733 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001734 SetFlag(kUseGVN);
1735 SetFlag(kDependsOnMaps);
1736 }
1737
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001738 virtual bool IsCheckInstruction() const { return true; }
1739
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001740#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001741 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001742#endif
1743
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001744 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001745 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001746
1747 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check_prototype_maps")
1748
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001749 virtual Representation RequiredInputRepresentation(int index) const {
1750 return Representation::None();
1751 }
1752
1753 virtual intptr_t Hashcode() {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001754 ASSERT(!Heap::IsAllocationAllowed());
1755 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
1756 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
1757 return hash;
1758 }
1759
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001760 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001761 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001762 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001763 return prototype_.is_identical_to(b->prototype()) &&
1764 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001765 }
1766
1767 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001768 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001769 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001770};
1771
1772
1773class HCheckSmi: public HUnaryOperation {
1774 public:
1775 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
1776 set_representation(Representation::Tagged());
1777 SetFlag(kUseGVN);
1778 }
1779
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001780 virtual bool IsCheckInstruction() const { return true; }
1781
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001782 virtual Representation RequiredInputRepresentation(int index) const {
1783 return Representation::Tagged();
1784 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001785 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001786
1787#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001788 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001789#endif
1790
1791 DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001792
1793 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001794 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001795};
1796
1797
1798class HPhi: public HValue {
1799 public:
1800 explicit HPhi(int merged_index)
1801 : inputs_(2),
1802 merged_index_(merged_index),
1803 phi_id_(-1) {
1804 for (int i = 0; i < Representation::kNumRepresentations; i++) {
1805 non_phi_uses_[i] = 0;
1806 indirect_uses_[i] = 0;
1807 }
1808 ASSERT(merged_index >= 0);
1809 set_representation(Representation::Tagged());
1810 SetFlag(kFlexibleRepresentation);
1811 }
1812
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001813 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001814 bool double_occurred = false;
1815 bool int32_occurred = false;
1816 for (int i = 0; i < OperandCount(); ++i) {
1817 HValue* value = OperandAt(i);
1818 if (value->representation().IsDouble()) double_occurred = true;
1819 if (value->representation().IsInteger32()) int32_occurred = true;
1820 if (value->representation().IsTagged()) return Representation::Tagged();
1821 }
1822
1823 if (double_occurred) return Representation::Double();
1824 if (int32_occurred) return Representation::Integer32();
1825 return Representation::None();
1826 }
1827
1828 virtual Range* InferRange();
1829 virtual Representation RequiredInputRepresentation(int index) const {
1830 return representation();
1831 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001832 virtual HType CalculateInferredType();
1833 virtual int OperandCount() { return inputs_.length(); }
1834 virtual HValue* OperandAt(int index) { return inputs_[index]; }
1835 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001836 void AddInput(HValue* value);
1837
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00001838 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001839
1840 int merged_index() const { return merged_index_; }
1841
1842 virtual const char* Mnemonic() const { return "phi"; }
1843
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001844 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001845
1846#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001847 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001848#endif
1849
1850 DECLARE_INSTRUCTION(Phi)
1851
1852 void InitRealUses(int id);
1853 void AddNonPhiUsesFrom(HPhi* other);
1854 void AddIndirectUsesTo(int* use_count);
1855
1856 int tagged_non_phi_uses() const {
1857 return non_phi_uses_[Representation::kTagged];
1858 }
1859 int int32_non_phi_uses() const {
1860 return non_phi_uses_[Representation::kInteger32];
1861 }
1862 int double_non_phi_uses() const {
1863 return non_phi_uses_[Representation::kDouble];
1864 }
1865 int tagged_indirect_uses() const {
1866 return indirect_uses_[Representation::kTagged];
1867 }
1868 int int32_indirect_uses() const {
1869 return indirect_uses_[Representation::kInteger32];
1870 }
1871 int double_indirect_uses() const {
1872 return indirect_uses_[Representation::kDouble];
1873 }
1874 int phi_id() { return phi_id_; }
1875
1876 protected:
1877 virtual void DeleteFromGraph();
1878 virtual void InternalSetOperandAt(int index, HValue* value) {
1879 inputs_[index] = value;
1880 }
1881
1882 private:
1883 ZoneList<HValue*> inputs_;
1884 int merged_index_;
1885
1886 int non_phi_uses_[Representation::kNumRepresentations];
1887 int indirect_uses_[Representation::kNumRepresentations];
1888 int phi_id_;
1889};
1890
1891
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001892class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001893 public:
1894 HArgumentsObject() {
1895 set_representation(Representation::Tagged());
1896 SetFlag(kIsArguments);
1897 }
1898
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001899 virtual Representation RequiredInputRepresentation(int index) const {
1900 return Representation::None();
1901 }
1902
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001903 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject, "arguments-object")
1904};
1905
1906
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001907class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001908 public:
1909 HConstant(Handle<Object> handle, Representation r);
1910
1911 Handle<Object> handle() const { return handle_; }
1912
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001913 bool InOldSpace() const { return !Heap::InNewSpace(*handle_); }
1914
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001915 virtual Representation RequiredInputRepresentation(int index) const {
1916 return Representation::None();
1917 }
1918
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001919 virtual bool EmitAtUses() const { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001920 virtual void PrintDataTo(StringStream* stream);
1921 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001922 bool IsInteger() const { return handle_->IsSmi(); }
1923 HConstant* CopyToRepresentation(Representation r) const;
1924 HConstant* CopyToTruncatedInt32() const;
1925 bool HasInteger32Value() const { return has_int32_value_; }
1926 int32_t Integer32Value() const {
1927 ASSERT(HasInteger32Value());
1928 return int32_value_;
1929 }
1930 bool HasDoubleValue() const { return has_double_value_; }
1931 double DoubleValue() const {
1932 ASSERT(HasDoubleValue());
1933 return double_value_;
1934 }
1935 bool HasStringValue() const { return handle_->IsString(); }
1936
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001937 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001938 ASSERT(!Heap::allow_allocation(false));
1939 return reinterpret_cast<intptr_t>(*handle());
1940 }
1941
1942#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001943 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001944#endif
1945
1946 DECLARE_CONCRETE_INSTRUCTION(Constant, "constant")
1947
1948 protected:
1949 virtual Range* InferRange();
1950
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001951 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001952 HConstant* other_constant = HConstant::cast(other);
1953 return handle().is_identical_to(other_constant->handle());
1954 }
1955
1956 private:
1957 Handle<Object> handle_;
1958 HType constant_type_;
1959
1960 // The following two values represent the int32 and the double value of the
1961 // given constant if there is a lossless conversion between the constant
1962 // and the specific representation.
1963 bool has_int32_value_;
1964 int32_t int32_value_;
1965 bool has_double_value_;
1966 double double_value_;
1967};
1968
1969
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001970class HBinaryOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001971 public:
1972 HBinaryOperation(HValue* left, HValue* right) {
1973 ASSERT(left != NULL && right != NULL);
1974 SetOperandAt(0, left);
1975 SetOperandAt(1, right);
1976 }
1977
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001978 HValue* left() { return OperandAt(0); }
1979 HValue* right() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001980
1981 // TODO(kasperl): Move these helpers to the IA-32 Lithium
1982 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001983 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001984 if (IsCommutative() && left()->IsConstant()) return right();
1985 return left();
1986 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001987 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001988 if (IsCommutative() && left()->IsConstant()) return left();
1989 return right();
1990 }
1991
1992 virtual bool IsCommutative() const { return false; }
1993
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001994 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001995
1996 DECLARE_INSTRUCTION(BinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001997};
1998
1999
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002000class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002001 public:
2002 HApplyArguments(HValue* function,
2003 HValue* receiver,
2004 HValue* length,
2005 HValue* elements) {
2006 set_representation(Representation::Tagged());
2007 SetOperandAt(0, function);
2008 SetOperandAt(1, receiver);
2009 SetOperandAt(2, length);
2010 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002011 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002012 }
2013
2014 virtual Representation RequiredInputRepresentation(int index) const {
2015 // The length is untagged, all other inputs are tagged.
2016 return (index == 2)
2017 ? Representation::Integer32()
2018 : Representation::Tagged();
2019 }
2020
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002021 HValue* function() { return OperandAt(0); }
2022 HValue* receiver() { return OperandAt(1); }
2023 HValue* length() { return OperandAt(2); }
2024 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002025
2026 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply_arguments")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002027};
2028
2029
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002030class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002031 public:
2032 HArgumentsElements() {
2033 // The value produced by this instruction is a pointer into the stack
2034 // that looks as if it was a smi because of alignment.
2035 set_representation(Representation::Tagged());
2036 SetFlag(kUseGVN);
2037 }
2038
2039 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments_elements")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002040
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002041 virtual Representation RequiredInputRepresentation(int index) const {
2042 return Representation::None();
2043 }
2044
ager@chromium.org378b34e2011-01-28 08:04:38 +00002045 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002046 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002047};
2048
2049
2050class HArgumentsLength: public HUnaryOperation {
2051 public:
2052 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2053 set_representation(Representation::Integer32());
2054 SetFlag(kUseGVN);
2055 }
2056
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002057 virtual Representation RequiredInputRepresentation(int index) const {
2058 return Representation::Tagged();
2059 }
2060
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002061 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002062
2063 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002064 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002065};
2066
2067
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002068class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002069 public:
2070 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2071 set_representation(Representation::Tagged());
2072 SetFlag(kUseGVN);
2073 SetOperandAt(0, arguments);
2074 SetOperandAt(1, length);
2075 SetOperandAt(2, index);
2076 }
2077
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002078 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002079
2080 virtual Representation RequiredInputRepresentation(int index) const {
2081 // The arguments elements is considered tagged.
2082 return index == 0
2083 ? Representation::Tagged()
2084 : Representation::Integer32();
2085 }
2086
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002087 HValue* arguments() { return OperandAt(0); }
2088 HValue* length() { return OperandAt(1); }
2089 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002090
2091 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access_arguments_at")
2092
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002093 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002094};
2095
2096
2097class HBoundsCheck: public HBinaryOperation {
2098 public:
2099 HBoundsCheck(HValue* index, HValue* length)
2100 : HBinaryOperation(index, length) {
2101 SetFlag(kUseGVN);
2102 }
2103
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002104 virtual bool IsCheckInstruction() const { return true; }
2105
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002106 virtual Representation RequiredInputRepresentation(int index) const {
2107 return Representation::Integer32();
2108 }
2109
2110#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002111 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002112#endif
2113
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002114 HValue* index() { return left(); }
2115 HValue* length() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002116
2117 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds_check")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002118
2119 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002120 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002121};
2122
2123
2124class HBitwiseBinaryOperation: public HBinaryOperation {
2125 public:
2126 HBitwiseBinaryOperation(HValue* left, HValue* right)
2127 : HBinaryOperation(left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002128 set_representation(Representation::Tagged());
2129 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002130 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002131 }
2132
2133 virtual Representation RequiredInputRepresentation(int index) const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002134 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002135 }
2136
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002137 virtual void RepresentationChanged(Representation to) {
2138 if (!to.IsTagged()) {
2139 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002140 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002141 SetFlag(kTruncatingToInt32);
2142 SetFlag(kUseGVN);
2143 }
2144 }
2145
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002146 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002147
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002148 DECLARE_INSTRUCTION(BitwiseBinaryOperation)
2149};
2150
2151
2152class HArithmeticBinaryOperation: public HBinaryOperation {
2153 public:
2154 HArithmeticBinaryOperation(HValue* left, HValue* right)
2155 : HBinaryOperation(left, right) {
2156 set_representation(Representation::Tagged());
2157 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002158 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002159 }
2160
2161 virtual void RepresentationChanged(Representation to) {
2162 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002163 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002164 SetFlag(kUseGVN);
2165 }
2166 }
2167
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002168 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002169 virtual Representation RequiredInputRepresentation(int index) const {
2170 return representation();
2171 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002172 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002173 if (left()->representation().Equals(right()->representation())) {
2174 return left()->representation();
2175 }
2176 return HValue::InferredRepresentation();
2177 }
2178
2179 DECLARE_INSTRUCTION(ArithmeticBinaryOperation)
2180};
2181
2182
2183class HCompare: public HBinaryOperation {
2184 public:
2185 HCompare(HValue* left, HValue* right, Token::Value token)
2186 : HBinaryOperation(left, right), token_(token) {
2187 ASSERT(Token::IsCompareOp(token));
2188 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002189 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002190 }
2191
2192 void SetInputRepresentation(Representation r);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002193
2194 virtual bool EmitAtUses() const {
2195 return !HasSideEffects() && (uses()->length() <= 1);
2196 }
2197
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002198 virtual Representation RequiredInputRepresentation(int index) const {
2199 return input_representation_;
2200 }
2201 Representation GetInputRepresentation() const {
2202 return input_representation_;
2203 }
2204 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002205 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002206
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002207 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002208
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002209 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002210 return HValue::Hashcode() * 7 + token_;
2211 }
2212
2213 DECLARE_CONCRETE_INSTRUCTION(Compare, "compare")
2214
2215 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002216 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002217 HCompare* comp = HCompare::cast(other);
2218 return token_ == comp->token();
2219 }
2220
2221 private:
2222 Representation input_representation_;
2223 Token::Value token_;
2224};
2225
2226
2227class HCompareJSObjectEq: public HBinaryOperation {
2228 public:
2229 HCompareJSObjectEq(HValue* left, HValue* right)
2230 : HBinaryOperation(left, right) {
2231 set_representation(Representation::Tagged());
2232 SetFlag(kUseGVN);
2233 }
2234
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002235 virtual bool EmitAtUses() const {
2236 return !HasSideEffects() && (uses()->length() <= 1);
2237 }
2238
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002239 virtual Representation RequiredInputRepresentation(int index) const {
2240 return Representation::Tagged();
2241 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002242 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002243
2244 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq, "compare-js-object-eq")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002245
2246 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002247 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002248};
2249
2250
2251class HUnaryPredicate: public HUnaryOperation {
2252 public:
2253 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2254 set_representation(Representation::Tagged());
2255 SetFlag(kUseGVN);
2256 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002257
2258 virtual bool EmitAtUses() const {
2259 return !HasSideEffects() && (uses()->length() <= 1);
2260 }
2261
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002262 virtual Representation RequiredInputRepresentation(int index) const {
2263 return Representation::Tagged();
2264 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002265 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002266};
2267
2268
2269class HIsNull: public HUnaryPredicate {
2270 public:
2271 HIsNull(HValue* value, bool is_strict)
2272 : HUnaryPredicate(value), is_strict_(is_strict) { }
2273
2274 bool is_strict() const { return is_strict_; }
2275
2276 DECLARE_CONCRETE_INSTRUCTION(IsNull, "is_null")
2277
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002278 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002279 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002280 HIsNull* b = HIsNull::cast(other);
2281 return is_strict_ == b->is_strict();
2282 }
2283
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002284 private:
2285 bool is_strict_;
2286};
2287
2288
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002289class HIsObject: public HUnaryPredicate {
2290 public:
2291 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2292
2293 DECLARE_CONCRETE_INSTRUCTION(IsObject, "is_object")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002294
2295 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002296 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002297};
2298
2299
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002300class HIsSmi: public HUnaryPredicate {
2301 public:
2302 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2303
2304 DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002305
2306 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002307 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002308};
2309
2310
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002311class HIsConstructCall: public HTemplateInstruction<0> {
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002312 public:
2313 HIsConstructCall() {
2314 set_representation(Representation::Tagged());
2315 SetFlag(kUseGVN);
2316 }
2317
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002318 virtual bool EmitAtUses() const {
2319 return !HasSideEffects() && (uses()->length() <= 1);
2320 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002321
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002322 virtual Representation RequiredInputRepresentation(int index) const {
2323 return Representation::None();
2324 }
2325
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002326 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall, "is_construct_call")
2327
2328 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002329 virtual bool DataEquals(HValue* other) { return true; }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002330};
2331
2332
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002333class HHasInstanceType: public HUnaryPredicate {
2334 public:
2335 HHasInstanceType(HValue* value, InstanceType type)
2336 : HUnaryPredicate(value), from_(type), to_(type) { }
2337 HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2338 : HUnaryPredicate(value), from_(from), to_(to) {
2339 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2340 }
2341
2342 InstanceType from() { return from_; }
2343 InstanceType to() { return to_; }
2344
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002345 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002346
2347 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has_instance_type")
2348
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002349 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002350 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002351 HHasInstanceType* b = HHasInstanceType::cast(other);
2352 return (from_ == b->from()) && (to_ == b->to());
2353 }
2354
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002355 private:
2356 InstanceType from_;
2357 InstanceType to_; // Inclusive range, not all combinations work.
2358};
2359
2360
2361class HHasCachedArrayIndex: public HUnaryPredicate {
2362 public:
2363 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2364
2365 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has_cached_array_index")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002366
2367 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002368 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002369};
2370
2371
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002372class HGetCachedArrayIndex: public HUnaryPredicate {
2373 public:
2374 explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2375
2376 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get_cached_array_index")
2377
2378 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002379 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002380};
2381
2382
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002383class HClassOfTest: public HUnaryPredicate {
2384 public:
2385 HClassOfTest(HValue* value, Handle<String> class_name)
2386 : HUnaryPredicate(value), class_name_(class_name) { }
2387
2388 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class_of_test")
2389
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002390 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002391
2392 Handle<String> class_name() const { return class_name_; }
2393
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002394 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002395 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002396 HClassOfTest* b = HClassOfTest::cast(other);
2397 return class_name_.is_identical_to(b->class_name_);
2398 }
2399
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002400 private:
2401 Handle<String> class_name_;
2402};
2403
2404
2405class HTypeofIs: public HUnaryPredicate {
2406 public:
2407 HTypeofIs(HValue* value, Handle<String> type_literal)
2408 : HUnaryPredicate(value), type_literal_(type_literal) { }
2409
2410 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002411 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002412
2413 DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof_is")
2414
2415 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002416 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002417 HTypeofIs* b = HTypeofIs::cast(other);
2418 return type_literal_.is_identical_to(b->type_literal_);
2419 }
2420
2421 private:
2422 Handle<String> type_literal_;
2423};
2424
2425
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002426class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002427 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002428 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2429 SetOperandAt(0, context);
2430 SetOperandAt(1, left);
2431 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002432 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002433 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002434 }
2435
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002436 HValue* context() { return OperandAt(0); }
2437 HValue* left() { return OperandAt(1); }
2438 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002439
2440 virtual bool EmitAtUses() const {
2441 return !HasSideEffects() && (uses()->length() <= 1);
2442 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002443
2444 virtual Representation RequiredInputRepresentation(int index) const {
2445 return Representation::Tagged();
2446 }
2447
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002448 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002449
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002450 DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance_of")
2451};
2452
2453
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002454class HInstanceOfKnownGlobal: public HUnaryOperation {
2455 public:
2456 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2457 : HUnaryOperation(left), function_(right) {
2458 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002459 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002460 }
2461
2462 Handle<JSFunction> function() { return function_; }
2463
2464 virtual Representation RequiredInputRepresentation(int index) const {
2465 return Representation::Tagged();
2466 }
2467
2468 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
2469 "instance_of_known_global")
2470
2471 private:
2472 Handle<JSFunction> function_;
2473};
2474
2475
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002476class HPower: public HBinaryOperation {
2477 public:
2478 HPower(HValue* left, HValue* right)
2479 : HBinaryOperation(left, right) {
2480 set_representation(Representation::Double());
2481 SetFlag(kUseGVN);
2482 }
2483
2484 virtual Representation RequiredInputRepresentation(int index) const {
2485 return (index == 1) ? Representation::None() : Representation::Double();
2486 }
2487
2488 DECLARE_CONCRETE_INSTRUCTION(Power, "power")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002489
2490 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002491 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002492};
2493
2494
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002495class HAdd: public HArithmeticBinaryOperation {
2496 public:
2497 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2498 SetFlag(kCanOverflow);
2499 }
2500
2501 // Add is only commutative if two integer values are added and not if two
2502 // tagged values are added (because it might be a String concatenation).
2503 virtual bool IsCommutative() const {
2504 return !representation().IsTagged();
2505 }
2506
2507 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2508
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002509 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002510
2511 DECLARE_CONCRETE_INSTRUCTION(Add, "add")
2512
2513 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002514 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002515
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002516 virtual Range* InferRange();
2517};
2518
2519
2520class HSub: public HArithmeticBinaryOperation {
2521 public:
2522 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2523 SetFlag(kCanOverflow);
2524 }
2525
2526 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2527
2528 DECLARE_CONCRETE_INSTRUCTION(Sub, "sub")
2529
2530 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002531 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002532
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002533 virtual Range* InferRange();
2534};
2535
2536
2537class HMul: public HArithmeticBinaryOperation {
2538 public:
2539 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2540 SetFlag(kCanOverflow);
2541 }
2542
2543 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2544
2545 // Only commutative if it is certain that not two objects are multiplicated.
2546 virtual bool IsCommutative() const {
2547 return !representation().IsTagged();
2548 }
2549
2550 DECLARE_CONCRETE_INSTRUCTION(Mul, "mul")
2551
2552 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002553 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002554
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002555 virtual Range* InferRange();
2556};
2557
2558
2559class HMod: public HArithmeticBinaryOperation {
2560 public:
2561 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2562 SetFlag(kCanBeDivByZero);
2563 }
2564
2565 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2566
2567 DECLARE_CONCRETE_INSTRUCTION(Mod, "mod")
2568
2569 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002570 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002571
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002572 virtual Range* InferRange();
2573};
2574
2575
2576class HDiv: public HArithmeticBinaryOperation {
2577 public:
2578 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2579 SetFlag(kCanBeDivByZero);
2580 SetFlag(kCanOverflow);
2581 }
2582
2583 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2584
2585 DECLARE_CONCRETE_INSTRUCTION(Div, "div")
2586
2587 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002588 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002589
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002590 virtual Range* InferRange();
2591};
2592
2593
2594class HBitAnd: public HBitwiseBinaryOperation {
2595 public:
2596 HBitAnd(HValue* left, HValue* right)
2597 : HBitwiseBinaryOperation(left, right) { }
2598
2599 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002600 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002601
2602 DECLARE_CONCRETE_INSTRUCTION(BitAnd, "bit_and")
2603
2604 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002605 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002606
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002607 virtual Range* InferRange();
2608};
2609
2610
2611class HBitXor: public HBitwiseBinaryOperation {
2612 public:
2613 HBitXor(HValue* left, HValue* right)
2614 : HBitwiseBinaryOperation(left, right) { }
2615
2616 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002617 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002618
2619 DECLARE_CONCRETE_INSTRUCTION(BitXor, "bit_xor")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002620
2621 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002622 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002623};
2624
2625
2626class HBitOr: public HBitwiseBinaryOperation {
2627 public:
2628 HBitOr(HValue* left, HValue* right)
2629 : HBitwiseBinaryOperation(left, right) { }
2630
2631 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002632 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002633
2634 DECLARE_CONCRETE_INSTRUCTION(BitOr, "bit_or")
2635
2636 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002637 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002638
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002639 virtual Range* InferRange();
2640};
2641
2642
2643class HShl: public HBitwiseBinaryOperation {
2644 public:
2645 HShl(HValue* left, HValue* right)
2646 : HBitwiseBinaryOperation(left, right) { }
2647
2648 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002649 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002650
2651 DECLARE_CONCRETE_INSTRUCTION(Shl, "shl")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002652
2653 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002654 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002655};
2656
2657
2658class HShr: public HBitwiseBinaryOperation {
2659 public:
2660 HShr(HValue* left, HValue* right)
2661 : HBitwiseBinaryOperation(left, right) { }
2662
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002663 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002664
2665 DECLARE_CONCRETE_INSTRUCTION(Shr, "shr")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002666
2667 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002668 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002669};
2670
2671
2672class HSar: public HBitwiseBinaryOperation {
2673 public:
2674 HSar(HValue* left, HValue* right)
2675 : HBitwiseBinaryOperation(left, right) { }
2676
2677 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002678 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002679
2680 DECLARE_CONCRETE_INSTRUCTION(Sar, "sar")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002681
2682 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002683 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002684};
2685
2686
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002687class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002688 public:
2689 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
2690 SetFlag(kChangesOsrEntries);
2691 }
2692
2693 int ast_id() const { return ast_id_; }
2694
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002695 virtual Representation RequiredInputRepresentation(int index) const {
2696 return Representation::None();
2697 }
2698
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002699 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr_entry")
2700
2701 private:
2702 int ast_id_;
2703};
2704
2705
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002706class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002707 public:
2708 explicit HParameter(unsigned index) : index_(index) {
2709 set_representation(Representation::Tagged());
2710 }
2711
2712 unsigned index() const { return index_; }
2713
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002714 virtual void PrintDataTo(StringStream* stream);
2715
2716 virtual Representation RequiredInputRepresentation(int index) const {
2717 return Representation::None();
2718 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002719
2720 DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
2721
2722 private:
2723 unsigned index_;
2724};
2725
2726
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002727class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002728 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002729 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
2730 : HUnaryCall(context, argument_count),
2731 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002732 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002733 }
2734
2735 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002736
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002737 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002738
2739 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
2740 transcendental_type_ = transcendental_type;
2741 }
2742 TranscendentalCache::Type transcendental_type() {
2743 return transcendental_type_;
2744 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002745
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002746 virtual void PrintDataTo(StringStream* stream);
2747
2748 virtual Representation RequiredInputRepresentation(int index) const {
2749 return Representation::Tagged();
2750 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002751
2752 DECLARE_CONCRETE_INSTRUCTION(CallStub, "call_stub")
2753
2754 private:
2755 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002756 TranscendentalCache::Type transcendental_type_;
2757};
2758
2759
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002760class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002761 public:
2762 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
2763
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002764 virtual Representation RequiredInputRepresentation(int index) const {
2765 return Representation::None();
2766 }
2767
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002768 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown_osr_value")
2769};
2770
2771
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002772class HLoadGlobal: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002773 public:
2774 HLoadGlobal(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
2775 : cell_(cell), check_hole_value_(check_hole_value) {
2776 set_representation(Representation::Tagged());
2777 SetFlag(kUseGVN);
2778 SetFlag(kDependsOnGlobalVars);
2779 }
2780
2781 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
2782 bool check_hole_value() const { return check_hole_value_; }
2783
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002784 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002785
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002786 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002787 ASSERT(!Heap::allow_allocation(false));
2788 return reinterpret_cast<intptr_t>(*cell_);
2789 }
2790
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002791 virtual Representation RequiredInputRepresentation(int index) const {
2792 return Representation::None();
2793 }
2794
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002795 DECLARE_CONCRETE_INSTRUCTION(LoadGlobal, "load_global")
2796
2797 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002798 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002799 HLoadGlobal* b = HLoadGlobal::cast(other);
2800 return cell_.is_identical_to(b->cell());
2801 }
2802
2803 private:
2804 Handle<JSGlobalPropertyCell> cell_;
2805 bool check_hole_value_;
2806};
2807
2808
2809class HStoreGlobal: public HUnaryOperation {
2810 public:
ager@chromium.org378b34e2011-01-28 08:04:38 +00002811 HStoreGlobal(HValue* value,
2812 Handle<JSGlobalPropertyCell> cell,
2813 bool check_hole_value)
2814 : HUnaryOperation(value),
2815 cell_(cell),
2816 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002817 SetFlag(kChangesGlobalVars);
2818 }
2819
2820 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002821 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002822
2823 virtual Representation RequiredInputRepresentation(int index) const {
2824 return Representation::Tagged();
2825 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002826 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002827
2828 DECLARE_CONCRETE_INSTRUCTION(StoreGlobal, "store_global")
2829
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002830 private:
2831 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00002832 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002833};
2834
2835
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002836class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002837 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002838 HLoadContextSlot(HValue* context , int slot_index)
2839 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002840 set_representation(Representation::Tagged());
2841 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002842 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002843 }
2844
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002845 int slot_index() const { return slot_index_; }
2846
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002847 virtual Representation RequiredInputRepresentation(int index) const {
2848 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002849 }
2850
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002851 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002852
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002853 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load_context_slot")
2854
2855 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002856 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002857 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002858 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002859 }
2860
2861 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002862 int slot_index_;
2863};
2864
2865
2866static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
2867 return !value->type().IsSmi() &&
2868 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
2869}
2870
2871
2872class HStoreContextSlot: public HBinaryOperation {
2873 public:
2874 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
2875 : HBinaryOperation(context, value), slot_index_(slot_index) {
2876 SetFlag(kChangesContextSlots);
2877 }
2878
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002879 HValue* context() { return OperandAt(0); }
2880 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002881 int slot_index() const { return slot_index_; }
2882
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002883 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002884 return StoringValueNeedsWriteBarrier(value());
2885 }
2886
2887 virtual Representation RequiredInputRepresentation(int index) const {
2888 return Representation::Tagged();
2889 }
2890
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002891 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002892
2893 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store_context_slot")
2894
2895 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002896 int slot_index_;
2897};
2898
2899
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002900class HLoadNamedField: public HUnaryOperation {
2901 public:
2902 HLoadNamedField(HValue* object, bool is_in_object, int offset)
2903 : HUnaryOperation(object),
2904 is_in_object_(is_in_object),
2905 offset_(offset) {
2906 set_representation(Representation::Tagged());
2907 SetFlag(kUseGVN);
2908 if (is_in_object) {
2909 SetFlag(kDependsOnInobjectFields);
2910 } else {
2911 SetFlag(kDependsOnBackingStoreFields);
2912 }
2913 }
2914
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002915 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002916 bool is_in_object() const { return is_in_object_; }
2917 int offset() const { return offset_; }
2918
2919 virtual Representation RequiredInputRepresentation(int index) const {
2920 return Representation::Tagged();
2921 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002922 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002923
2924 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load_named_field")
2925
2926 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002927 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002928 HLoadNamedField* b = HLoadNamedField::cast(other);
2929 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
2930 }
2931
2932 private:
2933 bool is_in_object_;
2934 int offset_;
2935};
2936
2937
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002938class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002939 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002940 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
2941 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002942 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002943 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002944 }
2945
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002946 HValue* context() { return OperandAt(0); }
2947 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002948 Handle<Object> name() const { return name_; }
2949
2950 virtual Representation RequiredInputRepresentation(int index) const {
2951 return Representation::Tagged();
2952 }
2953
2954 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load_named_generic")
2955
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002956 private:
2957 Handle<Object> name_;
2958};
2959
2960
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002961class HLoadFunctionPrototype: public HUnaryOperation {
2962 public:
2963 explicit HLoadFunctionPrototype(HValue* function)
2964 : HUnaryOperation(function) {
2965 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002966 SetFlag(kUseGVN);
2967 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002968 }
2969
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002970 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002971
2972 virtual Representation RequiredInputRepresentation(int index) const {
2973 return Representation::Tagged();
2974 }
2975
2976 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load_function_prototype")
2977
2978 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002979 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002980};
2981
2982
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002983class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002984 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002985 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002986 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002987 SetFlag(kDependsOnArrayElements);
2988 SetFlag(kUseGVN);
2989 }
2990
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002991 HValue* object() { return OperandAt(0); }
2992 HValue* key() { return OperandAt(1); }
2993
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002994 virtual Representation RequiredInputRepresentation(int index) const {
2995 // The key is supposed to be Integer32.
2996 return (index == 1) ? Representation::Integer32()
2997 : Representation::Tagged();
2998 }
2999
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003000 virtual void PrintDataTo(StringStream* stream);
3001
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003002 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement,
3003 "load_keyed_fast_element")
ager@chromium.org378b34e2011-01-28 08:04:38 +00003004
3005 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003006 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003007};
3008
3009
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003010class HLoadPixelArrayElement: public HBinaryOperation {
3011 public:
3012 HLoadPixelArrayElement(HValue* external_elements, HValue* key)
3013 : HBinaryOperation(external_elements, key) {
3014 set_representation(Representation::Integer32());
3015 SetFlag(kDependsOnPixelArrayElements);
3016 // Native code could change the pixel array.
3017 SetFlag(kDependsOnCalls);
3018 SetFlag(kUseGVN);
3019 }
3020
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003021 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003022
3023 virtual Representation RequiredInputRepresentation(int index) const {
3024 // The key is supposed to be Integer32, but the base pointer
3025 // for the element load is a naked pointer.
3026 return (index == 1) ? Representation::Integer32()
3027 : Representation::External();
3028 }
3029
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003030 HValue* external_pointer() { return OperandAt(0); }
3031 HValue* key() { return OperandAt(1); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003032
3033 DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayElement,
3034 "load_pixel_array_element")
3035
3036 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003037 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003038};
3039
3040
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003041class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003042 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003043 HLoadKeyedGeneric(HContext* context, HValue* obj, HValue* key) {
3044 set_representation(Representation::Tagged());
3045 SetOperandAt(0, obj);
3046 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003047 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003048 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003049 }
3050
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003051 HValue* object() { return OperandAt(0); }
3052 HValue* key() { return OperandAt(1); }
3053 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003054
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003055 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003056
3057 virtual Representation RequiredInputRepresentation(int index) const {
3058 return Representation::Tagged();
3059 }
3060
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003061 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load_keyed_generic")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003062};
3063
3064
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003065class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003066 public:
3067 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003068 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003069 HValue* val,
3070 bool in_object,
3071 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003072 : HBinaryOperation(obj, val),
3073 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003074 is_in_object_(in_object),
3075 offset_(offset) {
3076 if (is_in_object_) {
3077 SetFlag(kChangesInobjectFields);
3078 } else {
3079 SetFlag(kChangesBackingStoreFields);
3080 }
3081 }
3082
3083 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store_named_field")
3084
3085 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003086 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003087 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003088 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003089
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003090 HValue* object() { return OperandAt(0); }
3091 HValue* value() { return OperandAt(1); }
3092
3093 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003094 bool is_in_object() const { return is_in_object_; }
3095 int offset() const { return offset_; }
3096 Handle<Map> transition() const { return transition_; }
3097 void set_transition(Handle<Map> map) { transition_ = map; }
3098
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003099 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003100 return StoringValueNeedsWriteBarrier(value());
3101 }
3102
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003103 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003104 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003105 bool is_in_object_;
3106 int offset_;
3107 Handle<Map> transition_;
3108};
3109
3110
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003111class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003112 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003113 HStoreNamedGeneric(HValue* context,
3114 HValue* object,
3115 Handle<String> name,
3116 HValue* value)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003117 : name_(name) {
3118 SetOperandAt(0, object);
3119 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003120 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003121 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003122 }
3123
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003124 HValue* object() { return OperandAt(0); }
3125 HValue* value() { return OperandAt(1); }
3126 HValue* context() { return OperandAt(2); }
3127 Handle<String> name() { return name_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003128
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003129 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003130
3131 virtual Representation RequiredInputRepresentation(int index) const {
3132 return Representation::Tagged();
3133 }
3134
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003135 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store_named_generic")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003136
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003137 private:
3138 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003139};
3140
3141
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003142class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003143 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003144 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3145 SetOperandAt(0, obj);
3146 SetOperandAt(1, key);
3147 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003148 SetFlag(kChangesArrayElements);
3149 }
3150
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003151 virtual Representation RequiredInputRepresentation(int index) const {
3152 // The key is supposed to be Integer32.
3153 return (index == 1) ? Representation::Integer32()
3154 : Representation::Tagged();
3155 }
3156
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003157 HValue* object() { return OperandAt(0); }
3158 HValue* key() { return OperandAt(1); }
3159 HValue* value() { return OperandAt(2); }
3160
3161 bool NeedsWriteBarrier() {
3162 return StoringValueNeedsWriteBarrier(value());
3163 }
3164
3165 virtual void PrintDataTo(StringStream* stream);
3166
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003167 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
3168 "store_keyed_fast_element")
3169};
3170
3171
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003172class HStorePixelArrayElement: public HTemplateInstruction<3> {
3173 public:
3174 HStorePixelArrayElement(HValue* external_elements, HValue* key, HValue* val) {
3175 SetFlag(kChangesPixelArrayElements);
3176 SetOperandAt(0, external_elements);
3177 SetOperandAt(1, key);
3178 SetOperandAt(2, val);
3179 }
3180
3181 virtual void PrintDataTo(StringStream* stream);
3182
3183 virtual Representation RequiredInputRepresentation(int index) const {
3184 if (index == 0) {
3185 return Representation::External();
3186 } else {
3187 return Representation::Integer32();
3188 }
3189 }
3190
3191 HValue* external_pointer() { return OperandAt(0); }
3192 HValue* key() { return OperandAt(1); }
3193 HValue* value() { return OperandAt(2); }
3194
3195 DECLARE_CONCRETE_INSTRUCTION(StorePixelArrayElement,
3196 "store_pixel_array_element")
3197};
3198
3199
3200class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003201 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003202 HStoreKeyedGeneric(HValue* context,
3203 HValue* object,
3204 HValue* key,
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003205 HValue* value) {
3206 SetOperandAt(0, object);
3207 SetOperandAt(1, key);
3208 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003209 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003210 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003211 }
3212
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003213 HValue* object() { return OperandAt(0); }
3214 HValue* key() { return OperandAt(1); }
3215 HValue* value() { return OperandAt(2); }
3216 HValue* context() { return OperandAt(3); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003217
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003218 virtual Representation RequiredInputRepresentation(int index) const {
3219 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003220 }
3221
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003222 virtual void PrintDataTo(StringStream* stream);
3223
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003224 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store_keyed_generic")
3225};
3226
3227
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003228class HStringCharCodeAt: public HBinaryOperation {
3229 public:
3230 HStringCharCodeAt(HValue* string, HValue* index)
3231 : HBinaryOperation(string, index) {
3232 set_representation(Representation::Integer32());
3233 SetFlag(kUseGVN);
3234 }
3235
3236 virtual Representation RequiredInputRepresentation(int index) const {
3237 // The index is supposed to be Integer32.
3238 return (index == 1) ? Representation::Integer32()
3239 : Representation::Tagged();
3240 }
3241
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003242 HValue* string() { return OperandAt(0); }
3243 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003244
3245 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string_char_code_at")
3246
3247 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003248 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003249
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003250 virtual Range* InferRange() {
3251 return new Range(0, String::kMaxUC16CharCode);
3252 }
3253};
3254
3255
3256class HStringLength: public HUnaryOperation {
3257 public:
3258 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3259 set_representation(Representation::Tagged());
3260 SetFlag(kUseGVN);
3261 }
3262
3263 virtual Representation RequiredInputRepresentation(int index) const {
3264 return Representation::Tagged();
3265 }
3266
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003267 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003268 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3269 return HType::Smi();
3270 }
3271
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003272 DECLARE_CONCRETE_INSTRUCTION(StringLength, "string_length")
3273
3274 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003275 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003276
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003277 virtual Range* InferRange() {
3278 return new Range(0, String::kMaxLength);
3279 }
3280};
3281
3282
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003283template <int V>
3284class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003285 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003286 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003287 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003288 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003289 }
3290
3291 int literal_index() const { return literal_index_; }
3292 int depth() const { return depth_; }
3293
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003294 private:
3295 int literal_index_;
3296 int depth_;
3297};
3298
3299
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003300class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003301 public:
3302 HArrayLiteral(Handle<FixedArray> constant_elements,
3303 int length,
3304 int literal_index,
3305 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003306 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003307 length_(length),
3308 constant_elements_(constant_elements) {}
3309
3310 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3311 int length() const { return length_; }
3312
3313 bool IsCopyOnWrite() const;
3314
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003315 virtual Representation RequiredInputRepresentation(int index) const {
3316 return Representation::None();
3317 }
3318
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003319 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array_literal")
3320
3321 private:
3322 int length_;
3323 Handle<FixedArray> constant_elements_;
3324};
3325
3326
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003327class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003328 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003329 HObjectLiteral(HValue* context,
3330 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003331 bool fast_elements,
3332 int literal_index,
3333 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003334 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003335 constant_properties_(constant_properties),
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003336 fast_elements_(fast_elements) {
3337 SetOperandAt(0, context);
3338 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003339
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003340 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003341 Handle<FixedArray> constant_properties() const {
3342 return constant_properties_;
3343 }
3344 bool fast_elements() const { return fast_elements_; }
3345
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003346 virtual Representation RequiredInputRepresentation(int index) const {
3347 return Representation::Tagged();
3348 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003349
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003350 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object_literal")
3351
3352 private:
3353 Handle<FixedArray> constant_properties_;
3354 bool fast_elements_;
3355};
3356
3357
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003358class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003359 public:
3360 HRegExpLiteral(Handle<String> pattern,
3361 Handle<String> flags,
3362 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003363 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003364 pattern_(pattern),
3365 flags_(flags) { }
3366
3367 Handle<String> pattern() { return pattern_; }
3368 Handle<String> flags() { return flags_; }
3369
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003370 virtual Representation RequiredInputRepresentation(int index) const {
3371 return Representation::None();
3372 }
3373
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003374 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp_literal")
3375
3376 private:
3377 Handle<String> pattern_;
3378 Handle<String> flags_;
3379};
3380
3381
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003382class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003383 public:
3384 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3385 : shared_info_(shared), pretenure_(pretenure) {
3386 set_representation(Representation::Tagged());
3387 }
3388
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003389 virtual Representation RequiredInputRepresentation(int index) const {
3390 return Representation::None();
3391 }
3392
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003393 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function_literal")
3394
3395 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3396 bool pretenure() const { return pretenure_; }
3397
3398 private:
3399 Handle<SharedFunctionInfo> shared_info_;
3400 bool pretenure_;
3401};
3402
3403
3404class HTypeof: public HUnaryOperation {
3405 public:
3406 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
3407 set_representation(Representation::Tagged());
3408 }
3409
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003410 virtual Representation RequiredInputRepresentation(int index) const {
3411 return Representation::Tagged();
3412 }
3413
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003414 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
3415};
3416
3417
3418class HValueOf: public HUnaryOperation {
3419 public:
3420 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
3421 set_representation(Representation::Tagged());
3422 }
3423
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003424 virtual Representation RequiredInputRepresentation(int index) const {
3425 return Representation::Tagged();
3426 }
3427
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003428 DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value_of")
3429};
3430
3431
3432class HDeleteProperty: public HBinaryOperation {
3433 public:
3434 HDeleteProperty(HValue* obj, HValue* key)
3435 : HBinaryOperation(obj, key) {
3436 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003437 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003438 }
3439
3440 virtual Representation RequiredInputRepresentation(int index) const {
3441 return Representation::Tagged();
3442 }
3443
3444 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete_property")
3445
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003446 HValue* object() { return left(); }
3447 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003448};
3449
3450#undef DECLARE_INSTRUCTION
3451#undef DECLARE_CONCRETE_INSTRUCTION
3452
3453} } // namespace v8::internal
3454
3455#endif // V8_HYDROGEN_INSTRUCTIONS_H_