blob: 6c516f2497e01ae6e63a9cca6f241d55d2929172 [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) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +000094 V(ClassOfTest) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000095 V(Compare) \
96 V(CompareJSObjectEq) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000097 V(CompareMap) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000098 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +000099 V(Context) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000100 V(DeleteProperty) \
101 V(Deoptimize) \
102 V(Div) \
103 V(EnterInlined) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000104 V(ExternalArrayLength) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000105 V(FixedArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000106 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000107 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000108 V(GlobalObject) \
109 V(GlobalReceiver) \
110 V(Goto) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000111 V(HasInstanceType) \
112 V(HasCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000113 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000114 V(InstanceOfKnownGlobal) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000115 V(IsNull) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000116 V(IsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000117 V(IsSmi) \
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +0000118 V(IsConstructCall) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000119 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000120 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000121 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000122 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000123 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000124 V(LoadFunctionPrototype) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000125 V(LoadGlobal) \
126 V(LoadKeyedFastElement) \
127 V(LoadKeyedGeneric) \
128 V(LoadNamedField) \
129 V(LoadNamedGeneric) \
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000130 V(LoadPixelArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000131 V(Mod) \
132 V(Mul) \
133 V(ObjectLiteral) \
134 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000135 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000136 V(Parameter) \
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
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000464 ZoneList<HValue*>* uses() { return &uses_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000465
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000466 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000467 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
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001422class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001423 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001424 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001425 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
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001436 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength, "external_array_length")
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001437
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
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001560class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001561 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001562 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001563 : 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
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001576 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer,
1577 "load-external-array-pointer")
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001578
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),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001803 phi_id_(-1),
1804 is_live_(false) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001805 for (int i = 0; i < Representation::kNumRepresentations; i++) {
1806 non_phi_uses_[i] = 0;
1807 indirect_uses_[i] = 0;
1808 }
1809 ASSERT(merged_index >= 0);
1810 set_representation(Representation::Tagged());
1811 SetFlag(kFlexibleRepresentation);
1812 }
1813
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001814 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001815 bool double_occurred = false;
1816 bool int32_occurred = false;
1817 for (int i = 0; i < OperandCount(); ++i) {
1818 HValue* value = OperandAt(i);
1819 if (value->representation().IsDouble()) double_occurred = true;
1820 if (value->representation().IsInteger32()) int32_occurred = true;
1821 if (value->representation().IsTagged()) return Representation::Tagged();
1822 }
1823
1824 if (double_occurred) return Representation::Double();
1825 if (int32_occurred) return Representation::Integer32();
1826 return Representation::None();
1827 }
1828
1829 virtual Range* InferRange();
1830 virtual Representation RequiredInputRepresentation(int index) const {
1831 return representation();
1832 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001833 virtual HType CalculateInferredType();
1834 virtual int OperandCount() { return inputs_.length(); }
1835 virtual HValue* OperandAt(int index) { return inputs_[index]; }
1836 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001837 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001838 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001839
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00001840 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001841
1842 int merged_index() const { return merged_index_; }
1843
1844 virtual const char* Mnemonic() const { return "phi"; }
1845
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001846 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001847
1848#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001849 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001850#endif
1851
1852 DECLARE_INSTRUCTION(Phi)
1853
1854 void InitRealUses(int id);
1855 void AddNonPhiUsesFrom(HPhi* other);
1856 void AddIndirectUsesTo(int* use_count);
1857
1858 int tagged_non_phi_uses() const {
1859 return non_phi_uses_[Representation::kTagged];
1860 }
1861 int int32_non_phi_uses() const {
1862 return non_phi_uses_[Representation::kInteger32];
1863 }
1864 int double_non_phi_uses() const {
1865 return non_phi_uses_[Representation::kDouble];
1866 }
1867 int tagged_indirect_uses() const {
1868 return indirect_uses_[Representation::kTagged];
1869 }
1870 int int32_indirect_uses() const {
1871 return indirect_uses_[Representation::kInteger32];
1872 }
1873 int double_indirect_uses() const {
1874 return indirect_uses_[Representation::kDouble];
1875 }
1876 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001877 bool is_live() { return is_live_; }
1878 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001879
1880 protected:
1881 virtual void DeleteFromGraph();
1882 virtual void InternalSetOperandAt(int index, HValue* value) {
1883 inputs_[index] = value;
1884 }
1885
1886 private:
1887 ZoneList<HValue*> inputs_;
1888 int merged_index_;
1889
1890 int non_phi_uses_[Representation::kNumRepresentations];
1891 int indirect_uses_[Representation::kNumRepresentations];
1892 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001893 bool is_live_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001894};
1895
1896
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001897class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001898 public:
1899 HArgumentsObject() {
1900 set_representation(Representation::Tagged());
1901 SetFlag(kIsArguments);
1902 }
1903
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001904 virtual Representation RequiredInputRepresentation(int index) const {
1905 return Representation::None();
1906 }
1907
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001908 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject, "arguments-object")
1909};
1910
1911
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001912class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001913 public:
1914 HConstant(Handle<Object> handle, Representation r);
1915
1916 Handle<Object> handle() const { return handle_; }
1917
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001918 bool InOldSpace() const { return !Heap::InNewSpace(*handle_); }
1919
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001920 virtual Representation RequiredInputRepresentation(int index) const {
1921 return Representation::None();
1922 }
1923
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001924 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001925 virtual void PrintDataTo(StringStream* stream);
1926 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001927 bool IsInteger() const { return handle_->IsSmi(); }
1928 HConstant* CopyToRepresentation(Representation r) const;
1929 HConstant* CopyToTruncatedInt32() const;
1930 bool HasInteger32Value() const { return has_int32_value_; }
1931 int32_t Integer32Value() const {
1932 ASSERT(HasInteger32Value());
1933 return int32_value_;
1934 }
1935 bool HasDoubleValue() const { return has_double_value_; }
1936 double DoubleValue() const {
1937 ASSERT(HasDoubleValue());
1938 return double_value_;
1939 }
1940 bool HasStringValue() const { return handle_->IsString(); }
1941
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001942 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001943 ASSERT(!Heap::allow_allocation(false));
1944 return reinterpret_cast<intptr_t>(*handle());
1945 }
1946
1947#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001948 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001949#endif
1950
1951 DECLARE_CONCRETE_INSTRUCTION(Constant, "constant")
1952
1953 protected:
1954 virtual Range* InferRange();
1955
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001956 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001957 HConstant* other_constant = HConstant::cast(other);
1958 return handle().is_identical_to(other_constant->handle());
1959 }
1960
1961 private:
1962 Handle<Object> handle_;
1963 HType constant_type_;
1964
1965 // The following two values represent the int32 and the double value of the
1966 // given constant if there is a lossless conversion between the constant
1967 // and the specific representation.
1968 bool has_int32_value_;
1969 int32_t int32_value_;
1970 bool has_double_value_;
1971 double double_value_;
1972};
1973
1974
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001975class HBinaryOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001976 public:
1977 HBinaryOperation(HValue* left, HValue* right) {
1978 ASSERT(left != NULL && right != NULL);
1979 SetOperandAt(0, left);
1980 SetOperandAt(1, right);
1981 }
1982
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001983 HValue* left() { return OperandAt(0); }
1984 HValue* right() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001985
1986 // TODO(kasperl): Move these helpers to the IA-32 Lithium
1987 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001988 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001989 if (IsCommutative() && left()->IsConstant()) return right();
1990 return left();
1991 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001992 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001993 if (IsCommutative() && left()->IsConstant()) return left();
1994 return right();
1995 }
1996
1997 virtual bool IsCommutative() const { return false; }
1998
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001999 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002000
2001 DECLARE_INSTRUCTION(BinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002002};
2003
2004
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002005class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002006 public:
2007 HApplyArguments(HValue* function,
2008 HValue* receiver,
2009 HValue* length,
2010 HValue* elements) {
2011 set_representation(Representation::Tagged());
2012 SetOperandAt(0, function);
2013 SetOperandAt(1, receiver);
2014 SetOperandAt(2, length);
2015 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002016 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002017 }
2018
2019 virtual Representation RequiredInputRepresentation(int index) const {
2020 // The length is untagged, all other inputs are tagged.
2021 return (index == 2)
2022 ? Representation::Integer32()
2023 : Representation::Tagged();
2024 }
2025
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002026 HValue* function() { return OperandAt(0); }
2027 HValue* receiver() { return OperandAt(1); }
2028 HValue* length() { return OperandAt(2); }
2029 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002030
2031 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply_arguments")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002032};
2033
2034
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002035class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002036 public:
2037 HArgumentsElements() {
2038 // The value produced by this instruction is a pointer into the stack
2039 // that looks as if it was a smi because of alignment.
2040 set_representation(Representation::Tagged());
2041 SetFlag(kUseGVN);
2042 }
2043
2044 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments_elements")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002045
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002046 virtual Representation RequiredInputRepresentation(int index) const {
2047 return Representation::None();
2048 }
2049
ager@chromium.org378b34e2011-01-28 08:04:38 +00002050 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002051 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002052};
2053
2054
2055class HArgumentsLength: public HUnaryOperation {
2056 public:
2057 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2058 set_representation(Representation::Integer32());
2059 SetFlag(kUseGVN);
2060 }
2061
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002062 virtual Representation RequiredInputRepresentation(int index) const {
2063 return Representation::Tagged();
2064 }
2065
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002066 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002067
2068 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002069 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002070};
2071
2072
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002073class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002074 public:
2075 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2076 set_representation(Representation::Tagged());
2077 SetFlag(kUseGVN);
2078 SetOperandAt(0, arguments);
2079 SetOperandAt(1, length);
2080 SetOperandAt(2, index);
2081 }
2082
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002083 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002084
2085 virtual Representation RequiredInputRepresentation(int index) const {
2086 // The arguments elements is considered tagged.
2087 return index == 0
2088 ? Representation::Tagged()
2089 : Representation::Integer32();
2090 }
2091
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002092 HValue* arguments() { return OperandAt(0); }
2093 HValue* length() { return OperandAt(1); }
2094 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002095
2096 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access_arguments_at")
2097
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002098 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002099};
2100
2101
2102class HBoundsCheck: public HBinaryOperation {
2103 public:
2104 HBoundsCheck(HValue* index, HValue* length)
2105 : HBinaryOperation(index, length) {
2106 SetFlag(kUseGVN);
2107 }
2108
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002109 virtual bool IsCheckInstruction() const { return true; }
2110
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002111 virtual Representation RequiredInputRepresentation(int index) const {
2112 return Representation::Integer32();
2113 }
2114
2115#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002116 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002117#endif
2118
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002119 HValue* index() { return left(); }
2120 HValue* length() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002121
2122 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds_check")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002123
2124 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002125 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002126};
2127
2128
2129class HBitwiseBinaryOperation: public HBinaryOperation {
2130 public:
2131 HBitwiseBinaryOperation(HValue* left, HValue* right)
2132 : HBinaryOperation(left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002133 set_representation(Representation::Tagged());
2134 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002135 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002136 }
2137
2138 virtual Representation RequiredInputRepresentation(int index) const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002139 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002140 }
2141
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002142 virtual void RepresentationChanged(Representation to) {
2143 if (!to.IsTagged()) {
2144 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002145 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002146 SetFlag(kTruncatingToInt32);
2147 SetFlag(kUseGVN);
2148 }
2149 }
2150
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002151 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002152
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002153 DECLARE_INSTRUCTION(BitwiseBinaryOperation)
2154};
2155
2156
2157class HArithmeticBinaryOperation: public HBinaryOperation {
2158 public:
2159 HArithmeticBinaryOperation(HValue* left, HValue* right)
2160 : HBinaryOperation(left, right) {
2161 set_representation(Representation::Tagged());
2162 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002163 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002164 }
2165
2166 virtual void RepresentationChanged(Representation to) {
2167 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002168 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002169 SetFlag(kUseGVN);
2170 }
2171 }
2172
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002173 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002174 virtual Representation RequiredInputRepresentation(int index) const {
2175 return representation();
2176 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002177 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002178 if (left()->representation().Equals(right()->representation())) {
2179 return left()->representation();
2180 }
2181 return HValue::InferredRepresentation();
2182 }
2183
2184 DECLARE_INSTRUCTION(ArithmeticBinaryOperation)
2185};
2186
2187
2188class HCompare: public HBinaryOperation {
2189 public:
2190 HCompare(HValue* left, HValue* right, Token::Value token)
2191 : HBinaryOperation(left, right), token_(token) {
2192 ASSERT(Token::IsCompareOp(token));
2193 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002194 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002195 }
2196
2197 void SetInputRepresentation(Representation r);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002198
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002199 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002200 return !HasSideEffects() && (uses()->length() <= 1);
2201 }
2202
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002203 virtual Representation RequiredInputRepresentation(int index) const {
2204 return input_representation_;
2205 }
2206 Representation GetInputRepresentation() const {
2207 return input_representation_;
2208 }
2209 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002210 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002211
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002212 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002213
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002214 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002215 return HValue::Hashcode() * 7 + token_;
2216 }
2217
2218 DECLARE_CONCRETE_INSTRUCTION(Compare, "compare")
2219
2220 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002221 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002222 HCompare* comp = HCompare::cast(other);
2223 return token_ == comp->token();
2224 }
2225
2226 private:
2227 Representation input_representation_;
2228 Token::Value token_;
2229};
2230
2231
2232class HCompareJSObjectEq: public HBinaryOperation {
2233 public:
2234 HCompareJSObjectEq(HValue* left, HValue* right)
2235 : HBinaryOperation(left, right) {
2236 set_representation(Representation::Tagged());
2237 SetFlag(kUseGVN);
2238 }
2239
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002240 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002241 return !HasSideEffects() && (uses()->length() <= 1);
2242 }
2243
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002244 virtual Representation RequiredInputRepresentation(int index) const {
2245 return Representation::Tagged();
2246 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002247 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002248
2249 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq, "compare-js-object-eq")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002250
2251 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002252 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002253};
2254
2255
2256class HUnaryPredicate: public HUnaryOperation {
2257 public:
2258 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2259 set_representation(Representation::Tagged());
2260 SetFlag(kUseGVN);
2261 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002262
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002263 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002264 return !HasSideEffects() && (uses()->length() <= 1);
2265 }
2266
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002267 virtual Representation RequiredInputRepresentation(int index) const {
2268 return Representation::Tagged();
2269 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002270 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002271};
2272
2273
2274class HIsNull: public HUnaryPredicate {
2275 public:
2276 HIsNull(HValue* value, bool is_strict)
2277 : HUnaryPredicate(value), is_strict_(is_strict) { }
2278
2279 bool is_strict() const { return is_strict_; }
2280
2281 DECLARE_CONCRETE_INSTRUCTION(IsNull, "is_null")
2282
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002283 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002284 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002285 HIsNull* b = HIsNull::cast(other);
2286 return is_strict_ == b->is_strict();
2287 }
2288
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002289 private:
2290 bool is_strict_;
2291};
2292
2293
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002294class HIsObject: public HUnaryPredicate {
2295 public:
2296 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2297
2298 DECLARE_CONCRETE_INSTRUCTION(IsObject, "is_object")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002299
2300 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002301 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002302};
2303
2304
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002305class HIsSmi: public HUnaryPredicate {
2306 public:
2307 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2308
2309 DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002310
2311 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002312 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002313};
2314
2315
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002316class HIsConstructCall: public HTemplateInstruction<0> {
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002317 public:
2318 HIsConstructCall() {
2319 set_representation(Representation::Tagged());
2320 SetFlag(kUseGVN);
2321 }
2322
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002323 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002324 return !HasSideEffects() && (uses()->length() <= 1);
2325 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002326
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002327 virtual Representation RequiredInputRepresentation(int index) const {
2328 return Representation::None();
2329 }
2330
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002331 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall, "is_construct_call")
2332
2333 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002334 virtual bool DataEquals(HValue* other) { return true; }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002335};
2336
2337
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002338class HHasInstanceType: public HUnaryPredicate {
2339 public:
2340 HHasInstanceType(HValue* value, InstanceType type)
2341 : HUnaryPredicate(value), from_(type), to_(type) { }
2342 HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2343 : HUnaryPredicate(value), from_(from), to_(to) {
2344 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2345 }
2346
2347 InstanceType from() { return from_; }
2348 InstanceType to() { return to_; }
2349
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002350 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002351
2352 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has_instance_type")
2353
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002354 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002355 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002356 HHasInstanceType* b = HHasInstanceType::cast(other);
2357 return (from_ == b->from()) && (to_ == b->to());
2358 }
2359
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002360 private:
2361 InstanceType from_;
2362 InstanceType to_; // Inclusive range, not all combinations work.
2363};
2364
2365
2366class HHasCachedArrayIndex: public HUnaryPredicate {
2367 public:
2368 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2369
2370 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has_cached_array_index")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002371
2372 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002373 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002374};
2375
2376
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002377class HGetCachedArrayIndex: public HUnaryPredicate {
2378 public:
2379 explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2380
2381 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get_cached_array_index")
2382
2383 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002384 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002385};
2386
2387
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002388class HClassOfTest: public HUnaryPredicate {
2389 public:
2390 HClassOfTest(HValue* value, Handle<String> class_name)
2391 : HUnaryPredicate(value), class_name_(class_name) { }
2392
2393 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class_of_test")
2394
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002395 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002396
2397 Handle<String> class_name() const { return class_name_; }
2398
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002399 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002400 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002401 HClassOfTest* b = HClassOfTest::cast(other);
2402 return class_name_.is_identical_to(b->class_name_);
2403 }
2404
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002405 private:
2406 Handle<String> class_name_;
2407};
2408
2409
2410class HTypeofIs: public HUnaryPredicate {
2411 public:
2412 HTypeofIs(HValue* value, Handle<String> type_literal)
2413 : HUnaryPredicate(value), type_literal_(type_literal) { }
2414
2415 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002416 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002417
2418 DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof_is")
2419
2420 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002421 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002422 HTypeofIs* b = HTypeofIs::cast(other);
2423 return type_literal_.is_identical_to(b->type_literal_);
2424 }
2425
2426 private:
2427 Handle<String> type_literal_;
2428};
2429
2430
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002431class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002432 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002433 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2434 SetOperandAt(0, context);
2435 SetOperandAt(1, left);
2436 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002437 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002438 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002439 }
2440
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002441 HValue* context() { return OperandAt(0); }
2442 HValue* left() { return OperandAt(1); }
2443 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002444
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002445 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002446 return !HasSideEffects() && (uses()->length() <= 1);
2447 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002448
2449 virtual Representation RequiredInputRepresentation(int index) const {
2450 return Representation::Tagged();
2451 }
2452
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002453 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002454
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002455 DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance_of")
2456};
2457
2458
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002459class HInstanceOfKnownGlobal: public HUnaryOperation {
2460 public:
2461 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2462 : HUnaryOperation(left), function_(right) {
2463 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002464 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002465 }
2466
2467 Handle<JSFunction> function() { return function_; }
2468
2469 virtual Representation RequiredInputRepresentation(int index) const {
2470 return Representation::Tagged();
2471 }
2472
2473 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
2474 "instance_of_known_global")
2475
2476 private:
2477 Handle<JSFunction> function_;
2478};
2479
2480
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002481class HPower: public HBinaryOperation {
2482 public:
2483 HPower(HValue* left, HValue* right)
2484 : HBinaryOperation(left, right) {
2485 set_representation(Representation::Double());
2486 SetFlag(kUseGVN);
2487 }
2488
2489 virtual Representation RequiredInputRepresentation(int index) const {
2490 return (index == 1) ? Representation::None() : Representation::Double();
2491 }
2492
2493 DECLARE_CONCRETE_INSTRUCTION(Power, "power")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002494
2495 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002496 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002497};
2498
2499
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002500class HAdd: public HArithmeticBinaryOperation {
2501 public:
2502 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2503 SetFlag(kCanOverflow);
2504 }
2505
2506 // Add is only commutative if two integer values are added and not if two
2507 // tagged values are added (because it might be a String concatenation).
2508 virtual bool IsCommutative() const {
2509 return !representation().IsTagged();
2510 }
2511
2512 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2513
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002514 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002515
2516 DECLARE_CONCRETE_INSTRUCTION(Add, "add")
2517
2518 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002519 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002520
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002521 virtual Range* InferRange();
2522};
2523
2524
2525class HSub: public HArithmeticBinaryOperation {
2526 public:
2527 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2528 SetFlag(kCanOverflow);
2529 }
2530
2531 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2532
2533 DECLARE_CONCRETE_INSTRUCTION(Sub, "sub")
2534
2535 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002536 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002537
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002538 virtual Range* InferRange();
2539};
2540
2541
2542class HMul: public HArithmeticBinaryOperation {
2543 public:
2544 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2545 SetFlag(kCanOverflow);
2546 }
2547
2548 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2549
2550 // Only commutative if it is certain that not two objects are multiplicated.
2551 virtual bool IsCommutative() const {
2552 return !representation().IsTagged();
2553 }
2554
2555 DECLARE_CONCRETE_INSTRUCTION(Mul, "mul")
2556
2557 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002558 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002559
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002560 virtual Range* InferRange();
2561};
2562
2563
2564class HMod: public HArithmeticBinaryOperation {
2565 public:
2566 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2567 SetFlag(kCanBeDivByZero);
2568 }
2569
2570 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2571
2572 DECLARE_CONCRETE_INSTRUCTION(Mod, "mod")
2573
2574 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002575 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002576
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002577 virtual Range* InferRange();
2578};
2579
2580
2581class HDiv: public HArithmeticBinaryOperation {
2582 public:
2583 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2584 SetFlag(kCanBeDivByZero);
2585 SetFlag(kCanOverflow);
2586 }
2587
2588 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2589
2590 DECLARE_CONCRETE_INSTRUCTION(Div, "div")
2591
2592 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002593 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002594
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002595 virtual Range* InferRange();
2596};
2597
2598
2599class HBitAnd: public HBitwiseBinaryOperation {
2600 public:
2601 HBitAnd(HValue* left, HValue* right)
2602 : HBitwiseBinaryOperation(left, right) { }
2603
2604 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002605 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002606
2607 DECLARE_CONCRETE_INSTRUCTION(BitAnd, "bit_and")
2608
2609 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002610 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002611
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002612 virtual Range* InferRange();
2613};
2614
2615
2616class HBitXor: public HBitwiseBinaryOperation {
2617 public:
2618 HBitXor(HValue* left, HValue* right)
2619 : HBitwiseBinaryOperation(left, right) { }
2620
2621 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002622 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002623
2624 DECLARE_CONCRETE_INSTRUCTION(BitXor, "bit_xor")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002625
2626 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002627 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002628};
2629
2630
2631class HBitOr: public HBitwiseBinaryOperation {
2632 public:
2633 HBitOr(HValue* left, HValue* right)
2634 : HBitwiseBinaryOperation(left, right) { }
2635
2636 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002637 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002638
2639 DECLARE_CONCRETE_INSTRUCTION(BitOr, "bit_or")
2640
2641 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002642 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002643
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002644 virtual Range* InferRange();
2645};
2646
2647
2648class HShl: public HBitwiseBinaryOperation {
2649 public:
2650 HShl(HValue* left, HValue* right)
2651 : HBitwiseBinaryOperation(left, right) { }
2652
2653 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002654 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002655
2656 DECLARE_CONCRETE_INSTRUCTION(Shl, "shl")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002657
2658 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002659 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002660};
2661
2662
2663class HShr: public HBitwiseBinaryOperation {
2664 public:
2665 HShr(HValue* left, HValue* right)
2666 : HBitwiseBinaryOperation(left, right) { }
2667
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002668 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002669
2670 DECLARE_CONCRETE_INSTRUCTION(Shr, "shr")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002671
2672 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002673 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002674};
2675
2676
2677class HSar: public HBitwiseBinaryOperation {
2678 public:
2679 HSar(HValue* left, HValue* right)
2680 : HBitwiseBinaryOperation(left, right) { }
2681
2682 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002683 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002684
2685 DECLARE_CONCRETE_INSTRUCTION(Sar, "sar")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002686
2687 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002688 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002689};
2690
2691
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002692class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002693 public:
2694 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
2695 SetFlag(kChangesOsrEntries);
2696 }
2697
2698 int ast_id() const { return ast_id_; }
2699
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002700 virtual Representation RequiredInputRepresentation(int index) const {
2701 return Representation::None();
2702 }
2703
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002704 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr_entry")
2705
2706 private:
2707 int ast_id_;
2708};
2709
2710
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002711class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002712 public:
2713 explicit HParameter(unsigned index) : index_(index) {
2714 set_representation(Representation::Tagged());
2715 }
2716
2717 unsigned index() const { return index_; }
2718
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002719 virtual void PrintDataTo(StringStream* stream);
2720
2721 virtual Representation RequiredInputRepresentation(int index) const {
2722 return Representation::None();
2723 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002724
2725 DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
2726
2727 private:
2728 unsigned index_;
2729};
2730
2731
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002732class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002733 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002734 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
2735 : HUnaryCall(context, argument_count),
2736 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002737 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002738 }
2739
2740 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002741
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002742 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002743
2744 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
2745 transcendental_type_ = transcendental_type;
2746 }
2747 TranscendentalCache::Type transcendental_type() {
2748 return transcendental_type_;
2749 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002750
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002751 virtual void PrintDataTo(StringStream* stream);
2752
2753 virtual Representation RequiredInputRepresentation(int index) const {
2754 return Representation::Tagged();
2755 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002756
2757 DECLARE_CONCRETE_INSTRUCTION(CallStub, "call_stub")
2758
2759 private:
2760 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002761 TranscendentalCache::Type transcendental_type_;
2762};
2763
2764
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002765class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002766 public:
2767 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
2768
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002769 virtual Representation RequiredInputRepresentation(int index) const {
2770 return Representation::None();
2771 }
2772
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002773 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown_osr_value")
2774};
2775
2776
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002777class HLoadGlobal: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002778 public:
2779 HLoadGlobal(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
2780 : cell_(cell), check_hole_value_(check_hole_value) {
2781 set_representation(Representation::Tagged());
2782 SetFlag(kUseGVN);
2783 SetFlag(kDependsOnGlobalVars);
2784 }
2785
2786 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
2787 bool check_hole_value() const { return check_hole_value_; }
2788
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002789 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002790
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002791 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002792 ASSERT(!Heap::allow_allocation(false));
2793 return reinterpret_cast<intptr_t>(*cell_);
2794 }
2795
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002796 virtual Representation RequiredInputRepresentation(int index) const {
2797 return Representation::None();
2798 }
2799
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002800 DECLARE_CONCRETE_INSTRUCTION(LoadGlobal, "load_global")
2801
2802 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002803 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002804 HLoadGlobal* b = HLoadGlobal::cast(other);
2805 return cell_.is_identical_to(b->cell());
2806 }
2807
2808 private:
2809 Handle<JSGlobalPropertyCell> cell_;
2810 bool check_hole_value_;
2811};
2812
2813
2814class HStoreGlobal: public HUnaryOperation {
2815 public:
ager@chromium.org378b34e2011-01-28 08:04:38 +00002816 HStoreGlobal(HValue* value,
2817 Handle<JSGlobalPropertyCell> cell,
2818 bool check_hole_value)
2819 : HUnaryOperation(value),
2820 cell_(cell),
2821 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002822 SetFlag(kChangesGlobalVars);
2823 }
2824
2825 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002826 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002827
2828 virtual Representation RequiredInputRepresentation(int index) const {
2829 return Representation::Tagged();
2830 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002831 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002832
2833 DECLARE_CONCRETE_INSTRUCTION(StoreGlobal, "store_global")
2834
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002835 private:
2836 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00002837 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002838};
2839
2840
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002841class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002842 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002843 HLoadContextSlot(HValue* context , int slot_index)
2844 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002845 set_representation(Representation::Tagged());
2846 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002847 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002848 }
2849
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002850 int slot_index() const { return slot_index_; }
2851
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002852 virtual Representation RequiredInputRepresentation(int index) const {
2853 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002854 }
2855
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002856 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002857
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002858 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load_context_slot")
2859
2860 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002861 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002862 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002863 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002864 }
2865
2866 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002867 int slot_index_;
2868};
2869
2870
2871static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
2872 return !value->type().IsSmi() &&
2873 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
2874}
2875
2876
2877class HStoreContextSlot: public HBinaryOperation {
2878 public:
2879 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
2880 : HBinaryOperation(context, value), slot_index_(slot_index) {
2881 SetFlag(kChangesContextSlots);
2882 }
2883
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002884 HValue* context() { return OperandAt(0); }
2885 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002886 int slot_index() const { return slot_index_; }
2887
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002888 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002889 return StoringValueNeedsWriteBarrier(value());
2890 }
2891
2892 virtual Representation RequiredInputRepresentation(int index) const {
2893 return Representation::Tagged();
2894 }
2895
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002896 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002897
2898 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store_context_slot")
2899
2900 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002901 int slot_index_;
2902};
2903
2904
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002905class HLoadNamedField: public HUnaryOperation {
2906 public:
2907 HLoadNamedField(HValue* object, bool is_in_object, int offset)
2908 : HUnaryOperation(object),
2909 is_in_object_(is_in_object),
2910 offset_(offset) {
2911 set_representation(Representation::Tagged());
2912 SetFlag(kUseGVN);
2913 if (is_in_object) {
2914 SetFlag(kDependsOnInobjectFields);
2915 } else {
2916 SetFlag(kDependsOnBackingStoreFields);
2917 }
2918 }
2919
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002920 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002921 bool is_in_object() const { return is_in_object_; }
2922 int offset() const { return offset_; }
2923
2924 virtual Representation RequiredInputRepresentation(int index) const {
2925 return Representation::Tagged();
2926 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002927 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002928
2929 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load_named_field")
2930
2931 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002932 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002933 HLoadNamedField* b = HLoadNamedField::cast(other);
2934 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
2935 }
2936
2937 private:
2938 bool is_in_object_;
2939 int offset_;
2940};
2941
2942
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002943class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002944 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002945 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
2946 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002947 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002948 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002949 }
2950
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002951 HValue* context() { return OperandAt(0); }
2952 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002953 Handle<Object> name() const { return name_; }
2954
2955 virtual Representation RequiredInputRepresentation(int index) const {
2956 return Representation::Tagged();
2957 }
2958
2959 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load_named_generic")
2960
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002961 private:
2962 Handle<Object> name_;
2963};
2964
2965
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002966class HLoadFunctionPrototype: public HUnaryOperation {
2967 public:
2968 explicit HLoadFunctionPrototype(HValue* function)
2969 : HUnaryOperation(function) {
2970 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002971 SetFlag(kUseGVN);
2972 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002973 }
2974
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002975 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002976
2977 virtual Representation RequiredInputRepresentation(int index) const {
2978 return Representation::Tagged();
2979 }
2980
2981 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load_function_prototype")
2982
2983 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002984 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002985};
2986
2987
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002988class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002989 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002990 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002991 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002992 SetFlag(kDependsOnArrayElements);
2993 SetFlag(kUseGVN);
2994 }
2995
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002996 HValue* object() { return OperandAt(0); }
2997 HValue* key() { return OperandAt(1); }
2998
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002999 virtual Representation RequiredInputRepresentation(int index) const {
3000 // The key is supposed to be Integer32.
3001 return (index == 1) ? Representation::Integer32()
3002 : Representation::Tagged();
3003 }
3004
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003005 virtual void PrintDataTo(StringStream* stream);
3006
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003007 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement,
3008 "load_keyed_fast_element")
ager@chromium.org378b34e2011-01-28 08:04:38 +00003009
3010 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003011 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003012};
3013
3014
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003015class HLoadPixelArrayElement: public HBinaryOperation {
3016 public:
3017 HLoadPixelArrayElement(HValue* external_elements, HValue* key)
3018 : HBinaryOperation(external_elements, key) {
3019 set_representation(Representation::Integer32());
3020 SetFlag(kDependsOnPixelArrayElements);
3021 // Native code could change the pixel array.
3022 SetFlag(kDependsOnCalls);
3023 SetFlag(kUseGVN);
3024 }
3025
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003026 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003027
3028 virtual Representation RequiredInputRepresentation(int index) const {
3029 // The key is supposed to be Integer32, but the base pointer
3030 // for the element load is a naked pointer.
3031 return (index == 1) ? Representation::Integer32()
3032 : Representation::External();
3033 }
3034
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003035 HValue* external_pointer() { return OperandAt(0); }
3036 HValue* key() { return OperandAt(1); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003037
3038 DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayElement,
3039 "load_pixel_array_element")
3040
3041 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003042 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003043};
3044
3045
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003046class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003047 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003048 HLoadKeyedGeneric(HContext* context, HValue* obj, HValue* key) {
3049 set_representation(Representation::Tagged());
3050 SetOperandAt(0, obj);
3051 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003052 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003053 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003054 }
3055
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003056 HValue* object() { return OperandAt(0); }
3057 HValue* key() { return OperandAt(1); }
3058 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003059
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003060 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003061
3062 virtual Representation RequiredInputRepresentation(int index) const {
3063 return Representation::Tagged();
3064 }
3065
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003066 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load_keyed_generic")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003067};
3068
3069
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003070class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003071 public:
3072 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003073 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003074 HValue* val,
3075 bool in_object,
3076 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003077 : HBinaryOperation(obj, val),
3078 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003079 is_in_object_(in_object),
3080 offset_(offset) {
3081 if (is_in_object_) {
3082 SetFlag(kChangesInobjectFields);
3083 } else {
3084 SetFlag(kChangesBackingStoreFields);
3085 }
3086 }
3087
3088 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store_named_field")
3089
3090 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003091 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003092 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003093 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003094
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003095 HValue* object() { return OperandAt(0); }
3096 HValue* value() { return OperandAt(1); }
3097
3098 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003099 bool is_in_object() const { return is_in_object_; }
3100 int offset() const { return offset_; }
3101 Handle<Map> transition() const { return transition_; }
3102 void set_transition(Handle<Map> map) { transition_ = map; }
3103
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003104 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003105 return StoringValueNeedsWriteBarrier(value());
3106 }
3107
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003108 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003109 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003110 bool is_in_object_;
3111 int offset_;
3112 Handle<Map> transition_;
3113};
3114
3115
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003116class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003117 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003118 HStoreNamedGeneric(HValue* context,
3119 HValue* object,
3120 Handle<String> name,
3121 HValue* value)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003122 : name_(name) {
3123 SetOperandAt(0, object);
3124 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003125 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003126 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003127 }
3128
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003129 HValue* object() { return OperandAt(0); }
3130 HValue* value() { return OperandAt(1); }
3131 HValue* context() { return OperandAt(2); }
3132 Handle<String> name() { return name_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003133
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003134 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003135
3136 virtual Representation RequiredInputRepresentation(int index) const {
3137 return Representation::Tagged();
3138 }
3139
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003140 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store_named_generic")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003141
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003142 private:
3143 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003144};
3145
3146
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003147class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003148 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003149 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3150 SetOperandAt(0, obj);
3151 SetOperandAt(1, key);
3152 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003153 SetFlag(kChangesArrayElements);
3154 }
3155
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003156 virtual Representation RequiredInputRepresentation(int index) const {
3157 // The key is supposed to be Integer32.
3158 return (index == 1) ? Representation::Integer32()
3159 : Representation::Tagged();
3160 }
3161
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003162 HValue* object() { return OperandAt(0); }
3163 HValue* key() { return OperandAt(1); }
3164 HValue* value() { return OperandAt(2); }
3165
3166 bool NeedsWriteBarrier() {
3167 return StoringValueNeedsWriteBarrier(value());
3168 }
3169
3170 virtual void PrintDataTo(StringStream* stream);
3171
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003172 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
3173 "store_keyed_fast_element")
3174};
3175
3176
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003177class HStorePixelArrayElement: public HTemplateInstruction<3> {
3178 public:
3179 HStorePixelArrayElement(HValue* external_elements, HValue* key, HValue* val) {
3180 SetFlag(kChangesPixelArrayElements);
3181 SetOperandAt(0, external_elements);
3182 SetOperandAt(1, key);
3183 SetOperandAt(2, val);
3184 }
3185
3186 virtual void PrintDataTo(StringStream* stream);
3187
3188 virtual Representation RequiredInputRepresentation(int index) const {
3189 if (index == 0) {
3190 return Representation::External();
3191 } else {
3192 return Representation::Integer32();
3193 }
3194 }
3195
3196 HValue* external_pointer() { return OperandAt(0); }
3197 HValue* key() { return OperandAt(1); }
3198 HValue* value() { return OperandAt(2); }
3199
3200 DECLARE_CONCRETE_INSTRUCTION(StorePixelArrayElement,
3201 "store_pixel_array_element")
3202};
3203
3204
3205class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003206 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003207 HStoreKeyedGeneric(HValue* context,
3208 HValue* object,
3209 HValue* key,
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003210 HValue* value) {
3211 SetOperandAt(0, object);
3212 SetOperandAt(1, key);
3213 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003214 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003215 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003216 }
3217
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003218 HValue* object() { return OperandAt(0); }
3219 HValue* key() { return OperandAt(1); }
3220 HValue* value() { return OperandAt(2); }
3221 HValue* context() { return OperandAt(3); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003222
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003223 virtual Representation RequiredInputRepresentation(int index) const {
3224 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003225 }
3226
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003227 virtual void PrintDataTo(StringStream* stream);
3228
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003229 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store_keyed_generic")
3230};
3231
3232
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003233class HStringCharCodeAt: public HBinaryOperation {
3234 public:
3235 HStringCharCodeAt(HValue* string, HValue* index)
3236 : HBinaryOperation(string, index) {
3237 set_representation(Representation::Integer32());
3238 SetFlag(kUseGVN);
3239 }
3240
3241 virtual Representation RequiredInputRepresentation(int index) const {
3242 // The index is supposed to be Integer32.
3243 return (index == 1) ? Representation::Integer32()
3244 : Representation::Tagged();
3245 }
3246
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003247 HValue* string() { return OperandAt(0); }
3248 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003249
3250 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string_char_code_at")
3251
3252 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003253 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003254
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003255 virtual Range* InferRange() {
3256 return new Range(0, String::kMaxUC16CharCode);
3257 }
3258};
3259
3260
3261class HStringLength: public HUnaryOperation {
3262 public:
3263 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3264 set_representation(Representation::Tagged());
3265 SetFlag(kUseGVN);
3266 }
3267
3268 virtual Representation RequiredInputRepresentation(int index) const {
3269 return Representation::Tagged();
3270 }
3271
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003272 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003273 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3274 return HType::Smi();
3275 }
3276
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003277 DECLARE_CONCRETE_INSTRUCTION(StringLength, "string_length")
3278
3279 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003280 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003281
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003282 virtual Range* InferRange() {
3283 return new Range(0, String::kMaxLength);
3284 }
3285};
3286
3287
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003288template <int V>
3289class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003290 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003291 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003292 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003293 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003294 }
3295
3296 int literal_index() const { return literal_index_; }
3297 int depth() const { return depth_; }
3298
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003299 private:
3300 int literal_index_;
3301 int depth_;
3302};
3303
3304
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003305class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003306 public:
3307 HArrayLiteral(Handle<FixedArray> constant_elements,
3308 int length,
3309 int literal_index,
3310 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003311 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003312 length_(length),
3313 constant_elements_(constant_elements) {}
3314
3315 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3316 int length() const { return length_; }
3317
3318 bool IsCopyOnWrite() const;
3319
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003320 virtual Representation RequiredInputRepresentation(int index) const {
3321 return Representation::None();
3322 }
3323
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003324 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array_literal")
3325
3326 private:
3327 int length_;
3328 Handle<FixedArray> constant_elements_;
3329};
3330
3331
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003332class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003333 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003334 HObjectLiteral(HValue* context,
3335 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003336 bool fast_elements,
3337 int literal_index,
3338 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003339 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003340 constant_properties_(constant_properties),
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003341 fast_elements_(fast_elements) {
3342 SetOperandAt(0, context);
3343 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003344
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003345 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003346 Handle<FixedArray> constant_properties() const {
3347 return constant_properties_;
3348 }
3349 bool fast_elements() const { return fast_elements_; }
3350
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003351 virtual Representation RequiredInputRepresentation(int index) const {
3352 return Representation::Tagged();
3353 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003354
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003355 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object_literal")
3356
3357 private:
3358 Handle<FixedArray> constant_properties_;
3359 bool fast_elements_;
3360};
3361
3362
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003363class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003364 public:
3365 HRegExpLiteral(Handle<String> pattern,
3366 Handle<String> flags,
3367 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003368 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003369 pattern_(pattern),
3370 flags_(flags) { }
3371
3372 Handle<String> pattern() { return pattern_; }
3373 Handle<String> flags() { return flags_; }
3374
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003375 virtual Representation RequiredInputRepresentation(int index) const {
3376 return Representation::None();
3377 }
3378
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003379 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp_literal")
3380
3381 private:
3382 Handle<String> pattern_;
3383 Handle<String> flags_;
3384};
3385
3386
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003387class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003388 public:
3389 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3390 : shared_info_(shared), pretenure_(pretenure) {
3391 set_representation(Representation::Tagged());
3392 }
3393
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003394 virtual Representation RequiredInputRepresentation(int index) const {
3395 return Representation::None();
3396 }
3397
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003398 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function_literal")
3399
3400 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3401 bool pretenure() const { return pretenure_; }
3402
3403 private:
3404 Handle<SharedFunctionInfo> shared_info_;
3405 bool pretenure_;
3406};
3407
3408
3409class HTypeof: public HUnaryOperation {
3410 public:
3411 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
3412 set_representation(Representation::Tagged());
3413 }
3414
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003415 virtual Representation RequiredInputRepresentation(int index) const {
3416 return Representation::Tagged();
3417 }
3418
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003419 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
3420};
3421
3422
3423class HValueOf: public HUnaryOperation {
3424 public:
3425 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
3426 set_representation(Representation::Tagged());
3427 }
3428
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003429 virtual Representation RequiredInputRepresentation(int index) const {
3430 return Representation::Tagged();
3431 }
3432
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003433 DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value_of")
3434};
3435
3436
3437class HDeleteProperty: public HBinaryOperation {
3438 public:
3439 HDeleteProperty(HValue* obj, HValue* key)
3440 : HBinaryOperation(obj, key) {
3441 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003442 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003443 }
3444
3445 virtual Representation RequiredInputRepresentation(int index) const {
3446 return Representation::Tagged();
3447 }
3448
3449 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete_property")
3450
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003451 HValue* object() { return left(); }
3452 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003453};
3454
3455#undef DECLARE_INSTRUCTION
3456#undef DECLARE_CONCRETE_INSTRUCTION
3457
3458} } // namespace v8::internal
3459
3460#endif // V8_HYDROGEN_INSTRUCTIONS_H_