blob: c7365531b3f2af656a4c30d19788cccd12642d11 [file] [log] [blame]
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001// Copyright 2011 the V8 project authors. All rights reserved.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_HYDROGEN_INSTRUCTIONS_H_
29#define V8_HYDROGEN_INSTRUCTIONS_H_
30
31#include "v8.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000032
kasperl@chromium.orga5551262010-12-07 12:49:48 +000033#include "code-stubs.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000034#include "small-pointer-list.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000035#include "string-stream.h"
36#include "zone.h"
37
38namespace v8 {
39namespace internal {
40
41// Forward declarations.
42class HBasicBlock;
43class HEnvironment;
44class HInstruction;
45class HLoopInformation;
46class HValue;
47class LInstruction;
48class LChunkBuilder;
49
50
kasperl@chromium.orga5551262010-12-07 12:49:48 +000051#define HYDROGEN_ALL_INSTRUCTION_LIST(V) \
52 V(ArithmeticBinaryOperation) \
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +000053 V(BinaryCall) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000054 V(BinaryOperation) \
55 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000056 V(ControlInstruction) \
57 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000058 V(Phi) \
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +000059 V(UnaryCall) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000060 V(UnaryControlInstruction) \
61 V(UnaryOperation) \
62 HYDROGEN_CONCRETE_INSTRUCTION_LIST(V)
63
64
65#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +000066 V(AbnormalExit) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000067 V(AccessArgumentsAt) \
68 V(Add) \
69 V(ApplyArguments) \
70 V(ArgumentsElements) \
71 V(ArgumentsLength) \
72 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000073 V(ArrayLiteral) \
74 V(BitAnd) \
75 V(BitNot) \
76 V(BitOr) \
77 V(BitXor) \
78 V(BlockEntry) \
79 V(BoundsCheck) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000080 V(CallConstantFunction) \
81 V(CallFunction) \
82 V(CallGlobal) \
83 V(CallKeyed) \
84 V(CallKnownGlobal) \
85 V(CallNamed) \
86 V(CallNew) \
87 V(CallRuntime) \
88 V(CallStub) \
89 V(Change) \
90 V(CheckFunction) \
91 V(CheckInstanceType) \
92 V(CheckMap) \
93 V(CheckNonSmi) \
94 V(CheckPrototypeMaps) \
95 V(CheckSmi) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +000096 V(ClassOfTest) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000097 V(Compare) \
98 V(CompareJSObjectEq) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000099 V(CompareMap) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000100 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000101 V(Context) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000102 V(DeleteProperty) \
103 V(Deoptimize) \
104 V(Div) \
105 V(EnterInlined) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000106 V(ExternalArrayLength) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000107 V(FixedArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000108 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000109 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000110 V(GlobalObject) \
111 V(GlobalReceiver) \
112 V(Goto) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000113 V(HasInstanceType) \
114 V(HasCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000115 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000116 V(InstanceOfKnownGlobal) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000117 V(IsNull) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000118 V(IsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000119 V(IsSmi) \
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +0000120 V(IsConstructCall) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000121 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000122 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000123 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000124 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000125 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000126 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000127 V(LoadGlobalCell) \
128 V(LoadGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000129 V(LoadKeyedFastElement) \
130 V(LoadKeyedGeneric) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000131 V(LoadKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000132 V(LoadNamedField) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000133 V(LoadNamedFieldPolymorphic) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000134 V(LoadNamedGeneric) \
135 V(Mod) \
136 V(Mul) \
137 V(ObjectLiteral) \
138 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000139 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000140 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000141 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000142 V(PushArgument) \
143 V(RegExpLiteral) \
144 V(Return) \
145 V(Sar) \
146 V(Shl) \
147 V(Shr) \
148 V(Simulate) \
149 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000150 V(StoreContextSlot) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000151 V(StoreGlobalCell) \
152 V(StoreGlobalGeneric) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000153 V(StoreKeyedFastElement) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000154 V(StoreKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000155 V(StoreKeyedGeneric) \
156 V(StoreNamedField) \
157 V(StoreNamedGeneric) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000158 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000159 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000160 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000161 V(Sub) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000162 V(Test) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000163 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000164 V(ToFastProperties) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000165 V(Typeof) \
166 V(TypeofIs) \
167 V(UnaryMathOperation) \
168 V(UnknownOSRValue) \
169 V(ValueOf)
170
171#define GVN_FLAG_LIST(V) \
172 V(Calls) \
173 V(InobjectFields) \
174 V(BackingStoreFields) \
175 V(ArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000176 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000177 V(GlobalVars) \
178 V(Maps) \
179 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000180 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000181 V(OsrEntries)
182
183#define DECLARE_INSTRUCTION(type) \
184 virtual bool Is##type() const { return true; } \
185 static H##type* cast(HValue* value) { \
186 ASSERT(value->Is##type()); \
187 return reinterpret_cast<H##type*>(value); \
188 } \
189 Opcode opcode() const { return HValue::k##type; }
190
191
192#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
193 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
194 virtual const char* Mnemonic() const { return mnemonic; } \
195 DECLARE_INSTRUCTION(type)
196
197
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000198class Range: public ZoneObject {
199 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000200 Range()
201 : lower_(kMinInt),
202 upper_(kMaxInt),
203 next_(NULL),
204 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000205
206 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000207 : lower_(lower),
208 upper_(upper),
209 next_(NULL),
210 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000211
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000212 int32_t upper() const { return upper_; }
213 int32_t lower() const { return lower_; }
214 Range* next() const { return next_; }
215 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
216 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000217 Range* Copy() const { return new Range(lower_, upper_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000218 int32_t Mask() const;
219 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
220 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
221 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
222 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000223 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
224 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
225 bool IsInSmiRange() const {
226 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000227 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000228 void KeepOrder();
229 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000230
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000231 void StackUpon(Range* other) {
232 Intersect(other);
233 next_ = other;
234 }
235
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000236 void Intersect(Range* other);
237 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000238
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000239 void AddConstant(int32_t value);
240 void Sar(int32_t value);
241 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000242 bool AddAndCheckOverflow(Range* other);
243 bool SubAndCheckOverflow(Range* other);
244 bool MulAndCheckOverflow(Range* other);
245
246 private:
247 int32_t lower_;
248 int32_t upper_;
249 Range* next_;
250 bool can_be_minus_zero_;
251};
252
253
254class Representation {
255 public:
256 enum Kind {
257 kNone,
258 kTagged,
259 kDouble,
260 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000261 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000262 kNumRepresentations
263 };
264
265 Representation() : kind_(kNone) { }
266
267 static Representation None() { return Representation(kNone); }
268 static Representation Tagged() { return Representation(kTagged); }
269 static Representation Integer32() { return Representation(kInteger32); }
270 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000271 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000272
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000273 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000274 return kind_ == other.kind_;
275 }
276
277 Kind kind() const { return kind_; }
278 bool IsNone() const { return kind_ == kNone; }
279 bool IsTagged() const { return kind_ == kTagged; }
280 bool IsInteger32() const { return kind_ == kInteger32; }
281 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000282 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000283 bool IsSpecialization() const {
284 return kind_ == kInteger32 || kind_ == kDouble;
285 }
286 const char* Mnemonic() const;
287
288 private:
289 explicit Representation(Kind k) : kind_(k) { }
290
291 Kind kind_;
292};
293
294
295class HType {
296 public:
297 HType() : type_(kUninitialized) { }
298
299 static HType Tagged() { return HType(kTagged); }
300 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
301 static HType TaggedNumber() { return HType(kTaggedNumber); }
302 static HType Smi() { return HType(kSmi); }
303 static HType HeapNumber() { return HType(kHeapNumber); }
304 static HType String() { return HType(kString); }
305 static HType Boolean() { return HType(kBoolean); }
306 static HType NonPrimitive() { return HType(kNonPrimitive); }
307 static HType JSArray() { return HType(kJSArray); }
308 static HType JSObject() { return HType(kJSObject); }
309 static HType Uninitialized() { return HType(kUninitialized); }
310
311 // Return the weakest (least precise) common type.
312 HType Combine(HType other) {
313 return HType(static_cast<Type>(type_ & other.type_));
314 }
315
316 bool Equals(const HType& other) {
317 return type_ == other.type_;
318 }
319
320 bool IsSubtypeOf(const HType& other) {
321 return Combine(other).Equals(other);
322 }
323
324 bool IsTagged() {
325 ASSERT(type_ != kUninitialized);
326 return ((type_ & kTagged) == kTagged);
327 }
328
329 bool IsTaggedPrimitive() {
330 ASSERT(type_ != kUninitialized);
331 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
332 }
333
334 bool IsTaggedNumber() {
335 ASSERT(type_ != kUninitialized);
336 return ((type_ & kTaggedNumber) == kTaggedNumber);
337 }
338
339 bool IsSmi() {
340 ASSERT(type_ != kUninitialized);
341 return ((type_ & kSmi) == kSmi);
342 }
343
344 bool IsHeapNumber() {
345 ASSERT(type_ != kUninitialized);
346 return ((type_ & kHeapNumber) == kHeapNumber);
347 }
348
349 bool IsString() {
350 ASSERT(type_ != kUninitialized);
351 return ((type_ & kString) == kString);
352 }
353
354 bool IsBoolean() {
355 ASSERT(type_ != kUninitialized);
356 return ((type_ & kBoolean) == kBoolean);
357 }
358
359 bool IsNonPrimitive() {
360 ASSERT(type_ != kUninitialized);
361 return ((type_ & kNonPrimitive) == kNonPrimitive);
362 }
363
364 bool IsJSArray() {
365 ASSERT(type_ != kUninitialized);
366 return ((type_ & kJSArray) == kJSArray);
367 }
368
369 bool IsJSObject() {
370 ASSERT(type_ != kUninitialized);
371 return ((type_ & kJSObject) == kJSObject);
372 }
373
374 bool IsUninitialized() {
375 return type_ == kUninitialized;
376 }
377
378 static HType TypeFromValue(Handle<Object> value);
379
380 const char* ToString();
381 const char* ToShortString();
382
383 private:
384 enum Type {
385 kTagged = 0x1, // 0000 0000 0000 0001
386 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
387 kTaggedNumber = 0xd, // 0000 0000 0000 1101
388 kSmi = 0x1d, // 0000 0000 0001 1101
389 kHeapNumber = 0x2d, // 0000 0000 0010 1101
390 kString = 0x45, // 0000 0000 0100 0101
391 kBoolean = 0x85, // 0000 0000 1000 0101
392 kNonPrimitive = 0x101, // 0000 0001 0000 0001
393 kJSObject = 0x301, // 0000 0011 0000 0001
394 kJSArray = 0x701, // 0000 0111 1000 0001
395 kUninitialized = 0x1fff // 0001 1111 1111 1111
396 };
397
398 explicit HType(Type t) : type_(t) { }
399
400 Type type_;
401};
402
403
404class HValue: public ZoneObject {
405 public:
406 static const int kNoNumber = -1;
407
408 // There must be one corresponding kDepends flag for every kChanges flag and
409 // the order of the kChanges flags must be exactly the same as of the kDepends
410 // flags.
411 enum Flag {
412 // Declare global value numbering flags.
413 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
414 GVN_FLAG_LIST(DECLARE_DO)
415 #undef DECLARE_DO
416 kFlexibleRepresentation,
417 kUseGVN,
418 kCanOverflow,
419 kBailoutOnMinusZero,
420 kCanBeDivByZero,
421 kIsArguments,
422 kTruncatingToInt32,
423 kLastFlag = kTruncatingToInt32
424 };
425
426 STATIC_ASSERT(kLastFlag < kBitsPerInt);
427
428 static const int kChangesToDependsFlagsLeftShift = 1;
429
430 static int ChangesFlagsMask() {
431 int result = 0;
432 // Create changes mask.
433#define DECLARE_DO(type) result |= (1 << kChanges##type);
434 GVN_FLAG_LIST(DECLARE_DO)
435#undef DECLARE_DO
436 return result;
437 }
438
439 static int DependsFlagsMask() {
440 return ConvertChangesToDependsFlags(ChangesFlagsMask());
441 }
442
443 static int ConvertChangesToDependsFlags(int flags) {
444 return flags << kChangesToDependsFlagsLeftShift;
445 }
446
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000447 static HValue* cast(HValue* value) { return value; }
448
449 enum Opcode {
450 // Declare a unique enum value for each hydrogen instruction.
451 #define DECLARE_DO(type) k##type,
452 HYDROGEN_ALL_INSTRUCTION_LIST(DECLARE_DO)
453 #undef DECLARE_DO
454 kMaxInstructionClass
455 };
456
457 HValue() : block_(NULL),
458 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000459 type_(HType::Tagged()),
460 range_(NULL),
461 flags_(0) {}
462 virtual ~HValue() {}
463
464 HBasicBlock* block() const { return block_; }
465 void SetBlock(HBasicBlock* block);
466
467 int id() const { return id_; }
468 void set_id(int id) { id_ = id; }
469
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000470 SmallPointerList<HValue>* uses() { return &uses_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000471
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000472 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000473 Representation representation() const { return representation_; }
474 void ChangeRepresentation(Representation r) {
475 // Representation was already set and is allowed to be changed.
476 ASSERT(!representation_.IsNone());
477 ASSERT(!r.IsNone());
478 ASSERT(CheckFlag(kFlexibleRepresentation));
479 RepresentationChanged(r);
480 representation_ = r;
481 }
482
483 HType type() const { return type_; }
484 void set_type(HType type) {
485 ASSERT(uses_.length() == 0);
486 type_ = type;
487 }
488
489 // An operation needs to override this function iff:
490 // 1) it can produce an int32 output.
491 // 2) the true value of its output can potentially be minus zero.
492 // The implementation must set a flag so that it bails out in the case where
493 // it would otherwise output what should be a minus zero as an int32 zero.
494 // If the operation also exists in a form that takes int32 and outputs int32
495 // then the operation should return its input value so that we can propagate
496 // back. There are two operations that need to propagate back to more than
497 // one input. They are phi and binary add. They always return NULL and
498 // expect the caller to take care of things.
499 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
500 visited->Add(id());
501 return NULL;
502 }
503
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000504 bool IsDefinedAfter(HBasicBlock* other) const;
505
506 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000507 virtual int OperandCount() = 0;
508 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000509 void SetOperandAt(int index, HValue* value);
510
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000511 int LookupOperandIndex(int occurrence_index, HValue* op);
512 bool UsesMultipleTimes(HValue* op);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000513
514 void ReplaceAndDelete(HValue* other);
515 void ReplaceValue(HValue* other);
516 void ReplaceAtUse(HValue* use, HValue* other);
517 void ReplaceFirstAtUse(HValue* use, HValue* other, Representation r);
518 bool HasNoUses() const { return uses_.is_empty(); }
519 void ClearOperands();
520 void Delete();
521
522 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000523 void SetFlag(Flag f) { flags_ |= (1 << f); }
524 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
525 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
526
527 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
528 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
529 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000530
531 Range* range() const { return range_; }
532 bool HasRange() const { return range_ != NULL; }
533 void AddNewRange(Range* r);
534 void RemoveLastAddedRange();
535 void ComputeInitialRange();
536
537 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000538 virtual Representation RequiredInputRepresentation(int index) const = 0;
539
540 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000541 return representation();
542 }
543
544 // This gives the instruction an opportunity to replace itself with an
545 // instruction that does the same in some better way. To replace an
546 // instruction with a new one, first add the new instruction to the graph,
547 // then return it. Return NULL to have the instruction deleted.
548 virtual HValue* Canonicalize() { return this; }
549
550 // Declare virtual type testers.
551#define DECLARE_DO(type) virtual bool Is##type() const { return false; }
552 HYDROGEN_ALL_INSTRUCTION_LIST(DECLARE_DO)
553#undef DECLARE_DO
554
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000555 bool Equals(HValue* other);
556 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000557
558 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000559 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000560 void PrintNameTo(StringStream* stream);
561 static void PrintTypeTo(HType type, StringStream* stream);
562
563 virtual const char* Mnemonic() const = 0;
564 virtual Opcode opcode() const = 0;
565
566 // Updated the inferred type of this instruction and returns true if
567 // it has changed.
568 bool UpdateInferredType();
569
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000570 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000571
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000572#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000573 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000574#endif
575
576 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000577 // This function must be overridden for instructions with flag kUseGVN, to
578 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000579 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000580 UNREACHABLE();
581 return false;
582 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000583 virtual void RepresentationChanged(Representation to) { }
584 virtual Range* InferRange();
585 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000586 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000587 void clear_block() {
588 ASSERT(block_ != NULL);
589 block_ = NULL;
590 }
591
592 void set_representation(Representation r) {
593 // Representation is set-once.
594 ASSERT(representation_.IsNone() && !r.IsNone());
595 representation_ = r;
596 }
597
598 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000599 // A flag mask to mark an instruction as having arbitrary side effects.
600 static int AllSideEffects() {
601 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
602 }
603
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000604 void InternalReplaceAtUse(HValue* use, HValue* other);
605 void RegisterUse(int index, HValue* new_value);
606
607 HBasicBlock* block_;
608
609 // The id of this instruction in the hydrogen graph, assigned when first
610 // added to the graph. Reflects creation order.
611 int id_;
612
613 Representation representation_;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000614 SmallPointerList<HValue> uses_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000615 HType type_;
616 Range* range_;
617 int flags_;
618
619 DISALLOW_COPY_AND_ASSIGN(HValue);
620};
621
622
623class HInstruction: public HValue {
624 public:
625 HInstruction* next() const { return next_; }
626 HInstruction* previous() const { return previous_; }
627
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000628 virtual void PrintTo(StringStream* stream);
629 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000630
631 bool IsLinked() const { return block() != NULL; }
632 void Unlink();
633 void InsertBefore(HInstruction* next);
634 void InsertAfter(HInstruction* previous);
635
636 int position() const { return position_; }
637 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
638 void set_position(int position) { position_ = position; }
639
640 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
641
642#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000643 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000644#endif
645
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000646 // Returns whether this is some kind of deoptimizing check
647 // instruction.
648 virtual bool IsCheckInstruction() const { return false; }
649
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000650 virtual bool IsCall() { return false; }
651
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000652 DECLARE_INSTRUCTION(Instruction)
653
654 protected:
655 HInstruction()
656 : next_(NULL),
657 previous_(NULL),
658 position_(RelocInfo::kNoPosition) {
659 SetFlag(kDependsOnOsrEntries);
660 }
661
662 virtual void DeleteFromGraph() { Unlink(); }
663
664 private:
665 void InitializeAsFirst(HBasicBlock* block) {
666 ASSERT(!IsLinked());
667 SetBlock(block);
668 }
669
670 HInstruction* next_;
671 HInstruction* previous_;
672 int position_;
673
674 friend class HBasicBlock;
675};
676
677
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000678class HControlInstruction: public HInstruction {
679 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000680 HControlInstruction(HBasicBlock* first, HBasicBlock* second)
681 : first_successor_(first), second_successor_(second) {
682 }
683
684 HBasicBlock* FirstSuccessor() const { return first_successor_; }
685 HBasicBlock* SecondSuccessor() const { return second_successor_; }
686
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000687 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000688
689 DECLARE_INSTRUCTION(ControlInstruction)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000690
691 private:
692 HBasicBlock* first_successor_;
693 HBasicBlock* second_successor_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000694};
695
696
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000697template<int NumElements>
698class HOperandContainer {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000699 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000700 HOperandContainer() : elems_() { }
701
702 int length() { return NumElements; }
703 HValue*& operator[](int i) {
704 ASSERT(i < length());
705 return elems_[i];
706 }
707
708 private:
709 HValue* elems_[NumElements];
710};
711
712
713template<>
714class HOperandContainer<0> {
715 public:
716 int length() { return 0; }
717 HValue*& operator[](int i) {
718 UNREACHABLE();
719 static HValue* t = 0;
720 return t;
721 }
722};
723
724
725template<int V>
726class HTemplateInstruction : public HInstruction {
727 public:
728 int OperandCount() { return V; }
729 HValue* OperandAt(int i) { return inputs_[i]; }
730
731 protected:
732 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
733
734 private:
735 HOperandContainer<V> inputs_;
736};
737
738
739template<int V>
740class HTemplateControlInstruction : public HControlInstruction {
741 public:
742 HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second)
743 : HControlInstruction(first, second) { }
744 int OperandCount() { return V; }
745 HValue* OperandAt(int i) { return inputs_[i]; }
746
747 protected:
748 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
749
750 private:
751 HOperandContainer<V> inputs_;
752};
753
754
755class HBlockEntry: public HTemplateInstruction<0> {
756 public:
757 virtual Representation RequiredInputRepresentation(int index) const {
758 return Representation::None();
759 }
760
761 DECLARE_CONCRETE_INSTRUCTION(BlockEntry, "block_entry")
762};
763
764
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000765class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000766 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000767 explicit HDeoptimize(int environment_length)
768 : HControlInstruction(NULL, NULL),
769 values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000770
771 virtual Representation RequiredInputRepresentation(int index) const {
772 return Representation::None();
773 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000774
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000775 virtual int OperandCount() { return values_.length(); }
776 virtual HValue* OperandAt(int index) { return values_[index]; }
777
778 void AddEnvironmentValue(HValue* value) {
779 values_.Add(NULL);
780 SetOperandAt(values_.length() - 1, value);
781 }
782
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000783 DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000784
785 protected:
786 virtual void InternalSetOperandAt(int index, HValue* value) {
787 values_[index] = value;
788 }
789
790 private:
791 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000792};
793
794
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000795class HGoto: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000796 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000797 explicit HGoto(HBasicBlock* target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000798 : HTemplateControlInstruction<0>(target, NULL),
799 include_stack_check_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000800
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000801 void set_include_stack_check(bool include_stack_check) {
802 include_stack_check_ = include_stack_check;
803 }
804 bool include_stack_check() const { return include_stack_check_; }
805
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000806 virtual Representation RequiredInputRepresentation(int index) const {
807 return Representation::None();
808 }
809
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000810 DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
811
812 private:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000813 bool include_stack_check_;
814};
815
816
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000817class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000818 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000819 explicit HUnaryControlInstruction(HValue* value,
820 HBasicBlock* true_target,
821 HBasicBlock* false_target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000822 : HTemplateControlInstruction<1>(true_target, false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000823 SetOperandAt(0, value);
824 }
825
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000826 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000827
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000828 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000829
830 DECLARE_INSTRUCTION(UnaryControlInstruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000831};
832
833
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000834class HTest: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000835 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000836 HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
837 : HUnaryControlInstruction(value, true_target, false_target) {
838 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000839 }
840
841 virtual Representation RequiredInputRepresentation(int index) const {
842 return Representation::None();
843 }
844
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000845 DECLARE_CONCRETE_INSTRUCTION(Test, "test")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000846};
847
848
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000849class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000850 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000851 HCompareMap(HValue* value,
852 Handle<Map> map,
853 HBasicBlock* true_target,
854 HBasicBlock* false_target)
855 : HUnaryControlInstruction(value, true_target, false_target),
856 map_(map) {
857 ASSERT(true_target != NULL);
858 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000859 ASSERT(!map.is_null());
860 }
861
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000862 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000863
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000864 Handle<Map> map() const { return map_; }
865
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000866 virtual Representation RequiredInputRepresentation(int index) const {
867 return Representation::Tagged();
868 }
869
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000870 DECLARE_CONCRETE_INSTRUCTION(CompareMap, "compare_map")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000871
872 private:
873 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000874};
875
876
877class HReturn: public HUnaryControlInstruction {
878 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000879 explicit HReturn(HValue* value)
880 : HUnaryControlInstruction(value, NULL, NULL) {
881 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000882
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000883 virtual Representation RequiredInputRepresentation(int index) const {
884 return Representation::Tagged();
885 }
886
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000887 DECLARE_CONCRETE_INSTRUCTION(Return, "return")
888};
889
890
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000891class HAbnormalExit: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000892 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000893 HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
894
895 virtual Representation RequiredInputRepresentation(int index) const {
896 return Representation::None();
897 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000898
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000899 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit, "abnormal_exit")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000900};
901
902
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000903class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000904 public:
905 explicit HUnaryOperation(HValue* value) {
906 SetOperandAt(0, value);
907 }
908
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000909 HValue* value() { return OperandAt(0); }
910 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000911
912 DECLARE_INSTRUCTION(UnaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000913};
914
915
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000916class HThrow: public HUnaryOperation {
917 public:
918 explicit HThrow(HValue* value) : HUnaryOperation(value) {
919 SetAllSideEffects();
920 }
921
922 virtual Representation RequiredInputRepresentation(int index) const {
923 return Representation::Tagged();
924 }
925
926 DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
927};
928
929
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000930class HChange: public HUnaryOperation {
931 public:
932 HChange(HValue* value,
933 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000934 Representation to,
935 bool is_truncating)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000936 : HUnaryOperation(value), from_(from) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000937 ASSERT(!from.IsNone() && !to.IsNone());
938 ASSERT(!from.Equals(to));
939 set_representation(to);
940 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000941 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000942 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
943 value->range()->IsInSmiRange()) {
944 set_type(HType::Smi());
945 }
946 }
947
948 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
949
950 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000951 Representation to() const { return representation(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000952 virtual Representation RequiredInputRepresentation(int index) const {
953 return from_;
954 }
955
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000956 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000957
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000958 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000959
960 DECLARE_CONCRETE_INSTRUCTION(Change,
961 CanTruncateToInt32() ? "truncate" : "change")
962
963 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000964 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000965 if (!other->IsChange()) return false;
966 HChange* change = HChange::cast(other);
967 return value() == change->value()
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000968 && to().Equals(change->to());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000969 }
970
971 private:
972 Representation from_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000973};
974
975
976class HSimulate: public HInstruction {
977 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000978 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000979 : ast_id_(ast_id),
980 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000981 values_(2),
982 assigned_indexes_(2) {}
983 virtual ~HSimulate() {}
984
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000985 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000986
987 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
988 int ast_id() const { return ast_id_; }
989 void set_ast_id(int id) {
990 ASSERT(!HasAstId());
991 ast_id_ = id;
992 }
993
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000994 int pop_count() const { return pop_count_; }
995 const ZoneList<HValue*>* values() const { return &values_; }
996 int GetAssignedIndexAt(int index) const {
997 ASSERT(HasAssignedIndexAt(index));
998 return assigned_indexes_[index];
999 }
1000 bool HasAssignedIndexAt(int index) const {
1001 return assigned_indexes_[index] != kNoIndex;
1002 }
1003 void AddAssignedValue(int index, HValue* value) {
1004 AddValue(index, value);
1005 }
1006 void AddPushedValue(HValue* value) {
1007 AddValue(kNoIndex, value);
1008 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001009 virtual int OperandCount() { return values_.length(); }
1010 virtual HValue* OperandAt(int index) { return values_[index]; }
1011
1012 virtual Representation RequiredInputRepresentation(int index) const {
1013 return Representation::None();
1014 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001015
1016 DECLARE_CONCRETE_INSTRUCTION(Simulate, "simulate")
1017
1018#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001019 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001020#endif
1021
1022 protected:
1023 virtual void InternalSetOperandAt(int index, HValue* value) {
1024 values_[index] = value;
1025 }
1026
1027 private:
1028 static const int kNoIndex = -1;
1029 void AddValue(int index, HValue* value) {
1030 assigned_indexes_.Add(index);
1031 // Resize the list of pushed values.
1032 values_.Add(NULL);
1033 // Set the operand through the base method in HValue to make sure that the
1034 // use lists are correctly updated.
1035 SetOperandAt(values_.length() - 1, value);
1036 }
1037 int ast_id_;
1038 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001039 ZoneList<HValue*> values_;
1040 ZoneList<int> assigned_indexes_;
1041};
1042
1043
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001044class HStackCheck: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001045 public:
1046 HStackCheck() { }
1047
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001048 virtual Representation RequiredInputRepresentation(int index) const {
1049 return Representation::None();
1050 }
1051
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001052 DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack_check")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001053};
1054
1055
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001056class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001057 public:
1058 HEnterInlined(Handle<JSFunction> closure, FunctionLiteral* function)
1059 : closure_(closure), function_(function) {
1060 }
1061
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001062 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001063
1064 Handle<JSFunction> closure() const { return closure_; }
1065 FunctionLiteral* function() const { return function_; }
1066
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001067 virtual Representation RequiredInputRepresentation(int index) const {
1068 return Representation::None();
1069 }
1070
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001071 DECLARE_CONCRETE_INSTRUCTION(EnterInlined, "enter_inlined")
1072
1073 private:
1074 Handle<JSFunction> closure_;
1075 FunctionLiteral* function_;
1076};
1077
1078
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001079class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001080 public:
1081 HLeaveInlined() {}
1082
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001083 virtual Representation RequiredInputRepresentation(int index) const {
1084 return Representation::None();
1085 }
1086
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001087 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined, "leave_inlined")
1088};
1089
1090
1091class HPushArgument: public HUnaryOperation {
1092 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001093 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1094 set_representation(Representation::Tagged());
1095 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001096
1097 virtual Representation RequiredInputRepresentation(int index) const {
1098 return Representation::Tagged();
1099 }
1100
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001101 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001102
1103 DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push_argument")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001104};
1105
1106
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001107class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001108 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001109 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001110 set_representation(Representation::Tagged());
1111 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001112 }
1113
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001114 virtual Representation RequiredInputRepresentation(int index) const {
1115 return Representation::None();
1116 }
1117
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001118 DECLARE_CONCRETE_INSTRUCTION(Context, "context");
1119
1120 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001121 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001122};
1123
1124
1125class HOuterContext: public HUnaryOperation {
1126 public:
1127 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1128 set_representation(Representation::Tagged());
1129 SetFlag(kUseGVN);
1130 }
1131
1132 DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer_context");
1133
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001134 virtual Representation RequiredInputRepresentation(int index) const {
1135 return Representation::Tagged();
1136 }
1137
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001138 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001139 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001140};
1141
1142
1143class HGlobalObject: public HUnaryOperation {
1144 public:
1145 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1146 set_representation(Representation::Tagged());
1147 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001148 }
1149
1150 DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global_object")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001151
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001152 virtual Representation RequiredInputRepresentation(int index) const {
1153 return Representation::Tagged();
1154 }
1155
ager@chromium.org378b34e2011-01-28 08:04:38 +00001156 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001157 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001158};
1159
1160
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001161class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001162 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001163 explicit HGlobalReceiver(HValue* global_object)
1164 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001165 set_representation(Representation::Tagged());
1166 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001167 }
1168
1169 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global_receiver")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001170
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001171 virtual Representation RequiredInputRepresentation(int index) const {
1172 return Representation::Tagged();
1173 }
1174
ager@chromium.org378b34e2011-01-28 08:04:38 +00001175 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001176 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001177};
1178
1179
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001180template <int V>
1181class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001182 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001183 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001184 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1185 this->set_representation(Representation::Tagged());
1186 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001187 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001188
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001189 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001190
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001191 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001192
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001193 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001194
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001195 private:
1196 int argument_count_;
1197};
1198
1199
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001200class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001201 public:
1202 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001203 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001204 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001205 }
1206
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001207 virtual Representation RequiredInputRepresentation(int index) const {
1208 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001209 }
1210
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001211 virtual void PrintDataTo(StringStream* stream);
1212
1213 HValue* value() { return OperandAt(0); }
1214
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001215 DECLARE_INSTRUCTION(UnaryCall)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001216};
1217
1218
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001219class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001220 public:
1221 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001222 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001223 SetOperandAt(0, first);
1224 SetOperandAt(1, second);
1225 }
1226
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001227 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001228
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001229 virtual Representation RequiredInputRepresentation(int index) const {
1230 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001231 }
1232
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001233 HValue* first() { return OperandAt(0); }
1234 HValue* second() { return OperandAt(1); }
1235
1236 DECLARE_INSTRUCTION(BinaryCall)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001237};
1238
1239
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001240class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001241 public:
1242 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001243 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001244
1245 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001246
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001247 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001248 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001249 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001250 }
1251
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001252 virtual void PrintDataTo(StringStream* stream);
1253
1254 virtual Representation RequiredInputRepresentation(int index) const {
1255 return Representation::None();
1256 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001257
1258 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call_constant_function")
1259
1260 private:
1261 Handle<JSFunction> function_;
1262};
1263
1264
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001265class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001266 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001267 HCallKeyed(HValue* context, HValue* key, int argument_count)
1268 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001269 }
1270
1271 virtual Representation RequiredInputRepresentation(int index) const {
1272 return Representation::Tagged();
1273 }
1274
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001275 HValue* context() { return first(); }
1276 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001277
1278 DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call_keyed")
1279};
1280
1281
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001282class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001283 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001284 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1285 : HUnaryCall(context, argument_count), name_(name) {
1286 }
1287
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001288 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001289
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001290 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001291 Handle<String> name() const { return name_; }
1292
1293 DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call_named")
1294
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001295 virtual Representation RequiredInputRepresentation(int index) const {
1296 return Representation::Tagged();
1297 }
1298
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001299 private:
1300 Handle<String> name_;
1301};
1302
1303
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001304class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001305 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001306 HCallFunction(HValue* context, int argument_count)
1307 : HUnaryCall(context, argument_count) {
1308 }
1309
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001310 HValue* context() { return value(); }
1311
1312 virtual Representation RequiredInputRepresentation(int index) const {
1313 return Representation::Tagged();
1314 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001315
1316 DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call_function")
1317};
1318
1319
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001320class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001321 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001322 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1323 : HUnaryCall(context, argument_count), name_(name) {
1324 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001325
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001326 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001327
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001328 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001329 Handle<String> name() const { return name_; }
1330
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001331 virtual Representation RequiredInputRepresentation(int index) const {
1332 return Representation::Tagged();
1333 }
1334
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001335 DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call_global")
1336
1337 private:
1338 Handle<String> name_;
1339};
1340
1341
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001342class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001343 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001344 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001345 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001346
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001347 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001348
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001349 Handle<JSFunction> target() const { return target_; }
1350
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001351 virtual Representation RequiredInputRepresentation(int index) const {
1352 return Representation::None();
1353 }
1354
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001355 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call_known_global")
1356
1357 private:
1358 Handle<JSFunction> target_;
1359};
1360
1361
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001362class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001363 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001364 HCallNew(HValue* context, HValue* constructor, int argument_count)
1365 : HBinaryCall(context, constructor, argument_count) {
1366 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001367
1368 virtual Representation RequiredInputRepresentation(int index) const {
1369 return Representation::Tagged();
1370 }
1371
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001372 HValue* context() { return first(); }
1373 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001374
1375 DECLARE_CONCRETE_INSTRUCTION(CallNew, "call_new")
1376};
1377
1378
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001379class HCallRuntime: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001380 public:
1381 HCallRuntime(Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001382 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001383 int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001384 : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
1385 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001386
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001387 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001388 Handle<String> name() const { return name_; }
1389
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001390 virtual Representation RequiredInputRepresentation(int index) const {
1391 return Representation::None();
1392 }
1393
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001394 DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call_runtime")
1395
1396 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001397 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001398 Handle<String> name_;
1399};
1400
1401
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001402class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001403 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001404 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001405 // The length of an array is stored as a tagged value in the array
1406 // object. It is guaranteed to be 32 bit integer, but it can be
1407 // represented as either a smi or heap number.
1408 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001409 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001410 SetFlag(kDependsOnArrayLengths);
1411 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001412 }
1413
1414 virtual Representation RequiredInputRepresentation(int index) const {
1415 return Representation::Tagged();
1416 }
1417
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001418 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js_array_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001419
1420 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001421 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001422};
1423
1424
1425class HFixedArrayLength: public HUnaryOperation {
1426 public:
1427 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1428 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001429 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001430 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001431 }
1432
1433 virtual Representation RequiredInputRepresentation(int index) const {
1434 return Representation::Tagged();
1435 }
1436
1437 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed_array_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001438
1439 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001440 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001441};
1442
1443
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001444class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001445 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001446 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001447 set_representation(Representation::Integer32());
1448 // The result of this instruction is idempotent as long as its inputs don't
1449 // change. The length of a pixel array cannot change once set, so it's not
1450 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1451 SetFlag(kUseGVN);
1452 }
1453
1454 virtual Representation RequiredInputRepresentation(int index) const {
1455 return Representation::Tagged();
1456 }
1457
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001458 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength, "external_array_length")
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001459
1460 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001461 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001462};
1463
1464
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001465class HBitNot: public HUnaryOperation {
1466 public:
1467 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1468 set_representation(Representation::Integer32());
1469 SetFlag(kUseGVN);
1470 SetFlag(kTruncatingToInt32);
1471 }
1472
1473 virtual Representation RequiredInputRepresentation(int index) const {
1474 return Representation::Integer32();
1475 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001476 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001477
1478 DECLARE_CONCRETE_INSTRUCTION(BitNot, "bit_not")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001479
1480 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001481 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001482};
1483
1484
1485class HUnaryMathOperation: public HUnaryOperation {
1486 public:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001487 HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001488 : HUnaryOperation(value), op_(op) {
1489 switch (op) {
1490 case kMathFloor:
1491 case kMathRound:
1492 case kMathCeil:
1493 set_representation(Representation::Integer32());
1494 break;
1495 case kMathAbs:
1496 set_representation(Representation::Tagged());
1497 SetFlag(kFlexibleRepresentation);
1498 break;
1499 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001500 case kMathPowHalf:
1501 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001502 case kMathSin:
1503 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001504 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001505 break;
1506 default:
1507 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001508 }
1509 SetFlag(kUseGVN);
1510 }
1511
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001512 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001513
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001514 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001515
1516 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1517
1518 virtual Representation RequiredInputRepresentation(int index) const {
1519 switch (op_) {
1520 case kMathFloor:
1521 case kMathRound:
1522 case kMathCeil:
1523 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001524 case kMathPowHalf:
1525 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001526 case kMathSin:
1527 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001528 return Representation::Double();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001529 case kMathAbs:
1530 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001531 default:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001532 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001533 return Representation::None();
1534 }
1535 }
1536
1537 virtual HValue* Canonicalize() {
1538 // If the input is integer32 then we replace the floor instruction
1539 // with its inputs. This happens before the representation changes are
1540 // introduced.
1541 if (op() == kMathFloor) {
1542 if (value()->representation().IsInteger32()) return value();
1543 }
1544 return this;
1545 }
1546
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001547 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001548 const char* OpName() const;
1549
1550 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary_math_operation")
1551
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001552 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001553 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001554 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1555 return op_ == b->op();
1556 }
1557
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001558 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001559 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001560};
1561
1562
1563class HLoadElements: public HUnaryOperation {
1564 public:
1565 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1566 set_representation(Representation::Tagged());
1567 SetFlag(kUseGVN);
1568 SetFlag(kDependsOnMaps);
1569 }
1570
1571 virtual Representation RequiredInputRepresentation(int index) const {
1572 return Representation::Tagged();
1573 }
1574
1575 DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001576
1577 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001578 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001579};
1580
1581
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001582class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001583 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001584 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001585 : HUnaryOperation(value) {
1586 set_representation(Representation::External());
1587 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001588 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001589 // change once set, so it's no necessary to introduce any additional
1590 // dependencies on top of the inputs.
1591 SetFlag(kUseGVN);
1592 }
1593
1594 virtual Representation RequiredInputRepresentation(int index) const {
1595 return Representation::Tagged();
1596 }
1597
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001598 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer,
1599 "load-external-array-pointer")
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001600
1601 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001602 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001603};
1604
1605
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001606class HCheckMap: public HUnaryOperation {
1607 public:
1608 HCheckMap(HValue* value, Handle<Map> map)
1609 : HUnaryOperation(value), map_(map) {
1610 set_representation(Representation::Tagged());
1611 SetFlag(kUseGVN);
1612 SetFlag(kDependsOnMaps);
1613 }
1614
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001615 virtual bool IsCheckInstruction() const { return true; }
1616
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001617 virtual Representation RequiredInputRepresentation(int index) const {
1618 return Representation::Tagged();
1619 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001620 virtual void PrintDataTo(StringStream* stream);
1621 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001622
1623#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001624 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001625#endif
1626
1627 Handle<Map> map() const { return map_; }
1628
1629 DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check_map")
1630
1631 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001632 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001633 HCheckMap* b = HCheckMap::cast(other);
1634 return map_.is_identical_to(b->map());
1635 }
1636
1637 private:
1638 Handle<Map> map_;
1639};
1640
1641
1642class HCheckFunction: public HUnaryOperation {
1643 public:
1644 HCheckFunction(HValue* value, Handle<JSFunction> function)
1645 : HUnaryOperation(value), target_(function) {
1646 set_representation(Representation::Tagged());
1647 SetFlag(kUseGVN);
1648 }
1649
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001650 virtual bool IsCheckInstruction() const { return true; }
1651
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001652 virtual Representation RequiredInputRepresentation(int index) const {
1653 return Representation::Tagged();
1654 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001655 virtual void PrintDataTo(StringStream* stream);
1656 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001657
1658#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001659 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001660#endif
1661
1662 Handle<JSFunction> target() const { return target_; }
1663
1664 DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check_function")
1665
1666 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001667 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001668 HCheckFunction* b = HCheckFunction::cast(other);
1669 return target_.is_identical_to(b->target());
1670 }
1671
1672 private:
1673 Handle<JSFunction> target_;
1674};
1675
1676
1677class HCheckInstanceType: public HUnaryOperation {
1678 public:
1679 // Check that the instance type is in the range [first, last] where
1680 // both first and last are included.
1681 HCheckInstanceType(HValue* value, InstanceType first, InstanceType last)
1682 : HUnaryOperation(value), first_(first), last_(last) {
1683 ASSERT(first <= last);
1684 set_representation(Representation::Tagged());
1685 SetFlag(kUseGVN);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001686 if ((FIRST_STRING_TYPE < first && last <= LAST_STRING_TYPE) ||
1687 (FIRST_STRING_TYPE <= first && last < LAST_STRING_TYPE)) {
1688 // A particular string instance type can change because of GC or
1689 // externalization, but the value still remains a string.
1690 SetFlag(kDependsOnMaps);
1691 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001692 }
1693
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001694 virtual bool IsCheckInstruction() const { return true; }
1695
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001696 virtual Representation RequiredInputRepresentation(int index) const {
1697 return Representation::Tagged();
1698 }
1699
1700#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001701 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001702#endif
1703
1704 static HCheckInstanceType* NewIsJSObjectOrJSFunction(HValue* value);
1705
1706 InstanceType first() const { return first_; }
1707 InstanceType last() const { return last_; }
1708
1709 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check_instance_type")
1710
1711 protected:
1712 // TODO(ager): It could be nice to allow the ommision of instance
1713 // type checks if we have already performed an instance type check
1714 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001715 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001716 HCheckInstanceType* b = HCheckInstanceType::cast(other);
1717 return (first_ == b->first()) && (last_ == b->last());
1718 }
1719
1720 private:
1721 InstanceType first_;
1722 InstanceType last_;
1723};
1724
1725
1726class HCheckNonSmi: public HUnaryOperation {
1727 public:
1728 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
1729 set_representation(Representation::Tagged());
1730 SetFlag(kUseGVN);
1731 }
1732
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001733 virtual bool IsCheckInstruction() const { return true; }
1734
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001735 virtual Representation RequiredInputRepresentation(int index) const {
1736 return Representation::Tagged();
1737 }
1738
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001739 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001740
1741#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001742 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001743#endif
1744
1745 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check_non_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001746
1747 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001748 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001749};
1750
1751
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001752class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001753 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001754 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
1755 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001756 SetFlag(kUseGVN);
1757 SetFlag(kDependsOnMaps);
1758 }
1759
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001760 virtual bool IsCheckInstruction() const { return true; }
1761
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001762#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001763 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001764#endif
1765
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001766 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001767 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001768
1769 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check_prototype_maps")
1770
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001771 virtual Representation RequiredInputRepresentation(int index) const {
1772 return Representation::None();
1773 }
1774
1775 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001776 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001777 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
1778 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
1779 return hash;
1780 }
1781
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001782 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001783 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001784 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001785 return prototype_.is_identical_to(b->prototype()) &&
1786 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001787 }
1788
1789 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001790 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001791 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001792};
1793
1794
1795class HCheckSmi: public HUnaryOperation {
1796 public:
1797 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
1798 set_representation(Representation::Tagged());
1799 SetFlag(kUseGVN);
1800 }
1801
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001802 virtual bool IsCheckInstruction() const { return true; }
1803
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001804 virtual Representation RequiredInputRepresentation(int index) const {
1805 return Representation::Tagged();
1806 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001807 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001808
1809#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001810 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001811#endif
1812
1813 DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001814
1815 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001816 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001817};
1818
1819
1820class HPhi: public HValue {
1821 public:
1822 explicit HPhi(int merged_index)
1823 : inputs_(2),
1824 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001825 phi_id_(-1),
1826 is_live_(false) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001827 for (int i = 0; i < Representation::kNumRepresentations; i++) {
1828 non_phi_uses_[i] = 0;
1829 indirect_uses_[i] = 0;
1830 }
1831 ASSERT(merged_index >= 0);
1832 set_representation(Representation::Tagged());
1833 SetFlag(kFlexibleRepresentation);
1834 }
1835
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001836 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001837 bool double_occurred = false;
1838 bool int32_occurred = false;
1839 for (int i = 0; i < OperandCount(); ++i) {
1840 HValue* value = OperandAt(i);
1841 if (value->representation().IsDouble()) double_occurred = true;
1842 if (value->representation().IsInteger32()) int32_occurred = true;
1843 if (value->representation().IsTagged()) return Representation::Tagged();
1844 }
1845
1846 if (double_occurred) return Representation::Double();
1847 if (int32_occurred) return Representation::Integer32();
1848 return Representation::None();
1849 }
1850
1851 virtual Range* InferRange();
1852 virtual Representation RequiredInputRepresentation(int index) const {
1853 return representation();
1854 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001855 virtual HType CalculateInferredType();
1856 virtual int OperandCount() { return inputs_.length(); }
1857 virtual HValue* OperandAt(int index) { return inputs_[index]; }
1858 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001859 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001860 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001861
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00001862 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001863
1864 int merged_index() const { return merged_index_; }
1865
1866 virtual const char* Mnemonic() const { return "phi"; }
1867
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001868 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001869
1870#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001871 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001872#endif
1873
1874 DECLARE_INSTRUCTION(Phi)
1875
1876 void InitRealUses(int id);
1877 void AddNonPhiUsesFrom(HPhi* other);
1878 void AddIndirectUsesTo(int* use_count);
1879
1880 int tagged_non_phi_uses() const {
1881 return non_phi_uses_[Representation::kTagged];
1882 }
1883 int int32_non_phi_uses() const {
1884 return non_phi_uses_[Representation::kInteger32];
1885 }
1886 int double_non_phi_uses() const {
1887 return non_phi_uses_[Representation::kDouble];
1888 }
1889 int tagged_indirect_uses() const {
1890 return indirect_uses_[Representation::kTagged];
1891 }
1892 int int32_indirect_uses() const {
1893 return indirect_uses_[Representation::kInteger32];
1894 }
1895 int double_indirect_uses() const {
1896 return indirect_uses_[Representation::kDouble];
1897 }
1898 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001899 bool is_live() { return is_live_; }
1900 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001901
1902 protected:
1903 virtual void DeleteFromGraph();
1904 virtual void InternalSetOperandAt(int index, HValue* value) {
1905 inputs_[index] = value;
1906 }
1907
1908 private:
1909 ZoneList<HValue*> inputs_;
1910 int merged_index_;
1911
1912 int non_phi_uses_[Representation::kNumRepresentations];
1913 int indirect_uses_[Representation::kNumRepresentations];
1914 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001915 bool is_live_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001916};
1917
1918
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001919class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001920 public:
1921 HArgumentsObject() {
1922 set_representation(Representation::Tagged());
1923 SetFlag(kIsArguments);
1924 }
1925
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001926 virtual Representation RequiredInputRepresentation(int index) const {
1927 return Representation::None();
1928 }
1929
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001930 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject, "arguments-object")
1931};
1932
1933
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001934class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001935 public:
1936 HConstant(Handle<Object> handle, Representation r);
1937
1938 Handle<Object> handle() const { return handle_; }
1939
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001940 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001941
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001942 virtual Representation RequiredInputRepresentation(int index) const {
1943 return Representation::None();
1944 }
1945
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001946 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001947 virtual void PrintDataTo(StringStream* stream);
1948 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001949 bool IsInteger() const { return handle_->IsSmi(); }
1950 HConstant* CopyToRepresentation(Representation r) const;
1951 HConstant* CopyToTruncatedInt32() const;
1952 bool HasInteger32Value() const { return has_int32_value_; }
1953 int32_t Integer32Value() const {
1954 ASSERT(HasInteger32Value());
1955 return int32_value_;
1956 }
1957 bool HasDoubleValue() const { return has_double_value_; }
1958 double DoubleValue() const {
1959 ASSERT(HasDoubleValue());
1960 return double_value_;
1961 }
1962 bool HasStringValue() const { return handle_->IsString(); }
1963
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001964 bool ToBoolean() const;
1965
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001966 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001967 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001968 return reinterpret_cast<intptr_t>(*handle());
1969 }
1970
1971#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001972 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001973#endif
1974
1975 DECLARE_CONCRETE_INSTRUCTION(Constant, "constant")
1976
1977 protected:
1978 virtual Range* InferRange();
1979
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001980 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001981 HConstant* other_constant = HConstant::cast(other);
1982 return handle().is_identical_to(other_constant->handle());
1983 }
1984
1985 private:
1986 Handle<Object> handle_;
1987 HType constant_type_;
1988
1989 // The following two values represent the int32 and the double value of the
1990 // given constant if there is a lossless conversion between the constant
1991 // and the specific representation.
1992 bool has_int32_value_;
1993 int32_t int32_value_;
1994 bool has_double_value_;
1995 double double_value_;
1996};
1997
1998
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001999class HBinaryOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002000 public:
2001 HBinaryOperation(HValue* left, HValue* right) {
2002 ASSERT(left != NULL && right != NULL);
2003 SetOperandAt(0, left);
2004 SetOperandAt(1, right);
2005 }
2006
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002007 HValue* left() { return OperandAt(0); }
2008 HValue* right() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002009
2010 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2011 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002012 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002013 if (IsCommutative() && left()->IsConstant()) return right();
2014 return left();
2015 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002016 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002017 if (IsCommutative() && left()->IsConstant()) return left();
2018 return right();
2019 }
2020
2021 virtual bool IsCommutative() const { return false; }
2022
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002023 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002024
2025 DECLARE_INSTRUCTION(BinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002026};
2027
2028
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002029class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002030 public:
2031 HApplyArguments(HValue* function,
2032 HValue* receiver,
2033 HValue* length,
2034 HValue* elements) {
2035 set_representation(Representation::Tagged());
2036 SetOperandAt(0, function);
2037 SetOperandAt(1, receiver);
2038 SetOperandAt(2, length);
2039 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002040 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002041 }
2042
2043 virtual Representation RequiredInputRepresentation(int index) const {
2044 // The length is untagged, all other inputs are tagged.
2045 return (index == 2)
2046 ? Representation::Integer32()
2047 : Representation::Tagged();
2048 }
2049
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002050 HValue* function() { return OperandAt(0); }
2051 HValue* receiver() { return OperandAt(1); }
2052 HValue* length() { return OperandAt(2); }
2053 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002054
2055 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply_arguments")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002056};
2057
2058
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002059class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002060 public:
2061 HArgumentsElements() {
2062 // The value produced by this instruction is a pointer into the stack
2063 // that looks as if it was a smi because of alignment.
2064 set_representation(Representation::Tagged());
2065 SetFlag(kUseGVN);
2066 }
2067
2068 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments_elements")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002069
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002070 virtual Representation RequiredInputRepresentation(int index) const {
2071 return Representation::None();
2072 }
2073
ager@chromium.org378b34e2011-01-28 08:04:38 +00002074 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002075 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002076};
2077
2078
2079class HArgumentsLength: public HUnaryOperation {
2080 public:
2081 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2082 set_representation(Representation::Integer32());
2083 SetFlag(kUseGVN);
2084 }
2085
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002086 virtual Representation RequiredInputRepresentation(int index) const {
2087 return Representation::Tagged();
2088 }
2089
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002090 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002091
2092 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002093 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002094};
2095
2096
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002097class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002098 public:
2099 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2100 set_representation(Representation::Tagged());
2101 SetFlag(kUseGVN);
2102 SetOperandAt(0, arguments);
2103 SetOperandAt(1, length);
2104 SetOperandAt(2, index);
2105 }
2106
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002107 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002108
2109 virtual Representation RequiredInputRepresentation(int index) const {
2110 // The arguments elements is considered tagged.
2111 return index == 0
2112 ? Representation::Tagged()
2113 : Representation::Integer32();
2114 }
2115
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002116 HValue* arguments() { return OperandAt(0); }
2117 HValue* length() { return OperandAt(1); }
2118 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002119
2120 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access_arguments_at")
2121
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002122 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002123};
2124
2125
2126class HBoundsCheck: public HBinaryOperation {
2127 public:
2128 HBoundsCheck(HValue* index, HValue* length)
2129 : HBinaryOperation(index, length) {
2130 SetFlag(kUseGVN);
2131 }
2132
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002133 virtual bool IsCheckInstruction() const { return true; }
2134
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002135 virtual Representation RequiredInputRepresentation(int index) const {
2136 return Representation::Integer32();
2137 }
2138
2139#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002140 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002141#endif
2142
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002143 HValue* index() { return left(); }
2144 HValue* length() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002145
2146 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds_check")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002147
2148 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002149 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002150};
2151
2152
2153class HBitwiseBinaryOperation: public HBinaryOperation {
2154 public:
2155 HBitwiseBinaryOperation(HValue* left, HValue* right)
2156 : HBinaryOperation(left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002157 set_representation(Representation::Tagged());
2158 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002159 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002160 }
2161
2162 virtual Representation RequiredInputRepresentation(int index) const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002163 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002164 }
2165
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002166 virtual void RepresentationChanged(Representation to) {
2167 if (!to.IsTagged()) {
2168 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002169 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002170 SetFlag(kTruncatingToInt32);
2171 SetFlag(kUseGVN);
2172 }
2173 }
2174
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002175 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002176
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002177 DECLARE_INSTRUCTION(BitwiseBinaryOperation)
2178};
2179
2180
2181class HArithmeticBinaryOperation: public HBinaryOperation {
2182 public:
2183 HArithmeticBinaryOperation(HValue* left, HValue* right)
2184 : HBinaryOperation(left, right) {
2185 set_representation(Representation::Tagged());
2186 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002187 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002188 }
2189
2190 virtual void RepresentationChanged(Representation to) {
2191 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002192 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002193 SetFlag(kUseGVN);
2194 }
2195 }
2196
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002197 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002198 virtual Representation RequiredInputRepresentation(int index) const {
2199 return representation();
2200 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002201 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002202 if (left()->representation().Equals(right()->representation())) {
2203 return left()->representation();
2204 }
2205 return HValue::InferredRepresentation();
2206 }
2207
2208 DECLARE_INSTRUCTION(ArithmeticBinaryOperation)
2209};
2210
2211
2212class HCompare: public HBinaryOperation {
2213 public:
2214 HCompare(HValue* left, HValue* right, Token::Value token)
2215 : HBinaryOperation(left, right), token_(token) {
2216 ASSERT(Token::IsCompareOp(token));
2217 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002218 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002219 }
2220
2221 void SetInputRepresentation(Representation r);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002222
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002223 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002224 return !HasSideEffects() && (uses()->length() <= 1);
2225 }
2226
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002227 virtual Representation RequiredInputRepresentation(int index) const {
2228 return input_representation_;
2229 }
2230 Representation GetInputRepresentation() const {
2231 return input_representation_;
2232 }
2233 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002234 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002235
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002236 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002237
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002238 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002239 return HValue::Hashcode() * 7 + token_;
2240 }
2241
2242 DECLARE_CONCRETE_INSTRUCTION(Compare, "compare")
2243
2244 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002245 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002246 HCompare* comp = HCompare::cast(other);
2247 return token_ == comp->token();
2248 }
2249
2250 private:
2251 Representation input_representation_;
2252 Token::Value token_;
2253};
2254
2255
2256class HCompareJSObjectEq: public HBinaryOperation {
2257 public:
2258 HCompareJSObjectEq(HValue* left, HValue* right)
2259 : HBinaryOperation(left, right) {
2260 set_representation(Representation::Tagged());
2261 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002262 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002263 }
2264
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002265 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002266 return !HasSideEffects() && (uses()->length() <= 1);
2267 }
2268
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002269 virtual Representation RequiredInputRepresentation(int index) const {
2270 return Representation::Tagged();
2271 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002272 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002273
2274 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq, "compare-js-object-eq")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002275
2276 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002277 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002278};
2279
2280
2281class HUnaryPredicate: public HUnaryOperation {
2282 public:
2283 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2284 set_representation(Representation::Tagged());
2285 SetFlag(kUseGVN);
2286 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002287
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002288 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002289 return !HasSideEffects() && (uses()->length() <= 1);
2290 }
2291
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002292 virtual Representation RequiredInputRepresentation(int index) const {
2293 return Representation::Tagged();
2294 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002295 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002296};
2297
2298
2299class HIsNull: public HUnaryPredicate {
2300 public:
2301 HIsNull(HValue* value, bool is_strict)
2302 : HUnaryPredicate(value), is_strict_(is_strict) { }
2303
2304 bool is_strict() const { return is_strict_; }
2305
2306 DECLARE_CONCRETE_INSTRUCTION(IsNull, "is_null")
2307
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002308 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002309 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002310 HIsNull* b = HIsNull::cast(other);
2311 return is_strict_ == b->is_strict();
2312 }
2313
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002314 private:
2315 bool is_strict_;
2316};
2317
2318
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002319class HIsObject: public HUnaryPredicate {
2320 public:
2321 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2322
2323 DECLARE_CONCRETE_INSTRUCTION(IsObject, "is_object")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002324
2325 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002326 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002327};
2328
2329
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002330class HIsSmi: public HUnaryPredicate {
2331 public:
2332 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2333
2334 DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002335
2336 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002337 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002338};
2339
2340
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002341class HIsConstructCall: public HTemplateInstruction<0> {
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002342 public:
2343 HIsConstructCall() {
2344 set_representation(Representation::Tagged());
2345 SetFlag(kUseGVN);
2346 }
2347
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002348 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002349 return !HasSideEffects() && (uses()->length() <= 1);
2350 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002351
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002352 virtual Representation RequiredInputRepresentation(int index) const {
2353 return Representation::None();
2354 }
2355
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002356 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall, "is_construct_call")
2357
2358 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002359 virtual bool DataEquals(HValue* other) { return true; }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002360};
2361
2362
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002363class HHasInstanceType: public HUnaryPredicate {
2364 public:
2365 HHasInstanceType(HValue* value, InstanceType type)
2366 : HUnaryPredicate(value), from_(type), to_(type) { }
2367 HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2368 : HUnaryPredicate(value), from_(from), to_(to) {
2369 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2370 }
2371
2372 InstanceType from() { return from_; }
2373 InstanceType to() { return to_; }
2374
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002375 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002376
2377 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has_instance_type")
2378
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002379 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002380 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002381 HHasInstanceType* b = HHasInstanceType::cast(other);
2382 return (from_ == b->from()) && (to_ == b->to());
2383 }
2384
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002385 private:
2386 InstanceType from_;
2387 InstanceType to_; // Inclusive range, not all combinations work.
2388};
2389
2390
2391class HHasCachedArrayIndex: public HUnaryPredicate {
2392 public:
2393 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2394
2395 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has_cached_array_index")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002396
2397 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002398 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002399};
2400
2401
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002402class HGetCachedArrayIndex: public HUnaryPredicate {
2403 public:
2404 explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2405
2406 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get_cached_array_index")
2407
2408 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002409 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002410};
2411
2412
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002413class HClassOfTest: public HUnaryPredicate {
2414 public:
2415 HClassOfTest(HValue* value, Handle<String> class_name)
2416 : HUnaryPredicate(value), class_name_(class_name) { }
2417
2418 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class_of_test")
2419
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002420 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002421
2422 Handle<String> class_name() const { return class_name_; }
2423
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002424 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002425 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002426 HClassOfTest* b = HClassOfTest::cast(other);
2427 return class_name_.is_identical_to(b->class_name_);
2428 }
2429
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002430 private:
2431 Handle<String> class_name_;
2432};
2433
2434
2435class HTypeofIs: public HUnaryPredicate {
2436 public:
2437 HTypeofIs(HValue* value, Handle<String> type_literal)
2438 : HUnaryPredicate(value), type_literal_(type_literal) { }
2439
2440 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002441 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002442
2443 DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof_is")
2444
2445 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002446 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002447 HTypeofIs* b = HTypeofIs::cast(other);
2448 return type_literal_.is_identical_to(b->type_literal_);
2449 }
2450
2451 private:
2452 Handle<String> type_literal_;
2453};
2454
2455
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002456class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002457 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002458 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2459 SetOperandAt(0, context);
2460 SetOperandAt(1, left);
2461 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002462 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002463 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002464 }
2465
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002466 HValue* context() { return OperandAt(0); }
2467 HValue* left() { return OperandAt(1); }
2468 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002469
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002470 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002471 return !HasSideEffects() && (uses()->length() <= 1);
2472 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002473
2474 virtual Representation RequiredInputRepresentation(int index) const {
2475 return Representation::Tagged();
2476 }
2477
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002478 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002479
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002480 DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance_of")
2481};
2482
2483
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002484class HInstanceOfKnownGlobal: public HUnaryOperation {
2485 public:
2486 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2487 : HUnaryOperation(left), function_(right) {
2488 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002489 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002490 }
2491
2492 Handle<JSFunction> function() { return function_; }
2493
2494 virtual Representation RequiredInputRepresentation(int index) const {
2495 return Representation::Tagged();
2496 }
2497
2498 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
2499 "instance_of_known_global")
2500
2501 private:
2502 Handle<JSFunction> function_;
2503};
2504
2505
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002506class HPower: public HBinaryOperation {
2507 public:
2508 HPower(HValue* left, HValue* right)
2509 : HBinaryOperation(left, right) {
2510 set_representation(Representation::Double());
2511 SetFlag(kUseGVN);
2512 }
2513
2514 virtual Representation RequiredInputRepresentation(int index) const {
2515 return (index == 1) ? Representation::None() : Representation::Double();
2516 }
2517
2518 DECLARE_CONCRETE_INSTRUCTION(Power, "power")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002519
2520 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002521 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002522};
2523
2524
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002525class HAdd: public HArithmeticBinaryOperation {
2526 public:
2527 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2528 SetFlag(kCanOverflow);
2529 }
2530
2531 // Add is only commutative if two integer values are added and not if two
2532 // tagged values are added (because it might be a String concatenation).
2533 virtual bool IsCommutative() const {
2534 return !representation().IsTagged();
2535 }
2536
2537 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2538
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002539 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002540
2541 DECLARE_CONCRETE_INSTRUCTION(Add, "add")
2542
2543 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002544 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002545
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002546 virtual Range* InferRange();
2547};
2548
2549
2550class HSub: public HArithmeticBinaryOperation {
2551 public:
2552 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2553 SetFlag(kCanOverflow);
2554 }
2555
2556 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2557
2558 DECLARE_CONCRETE_INSTRUCTION(Sub, "sub")
2559
2560 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002561 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002562
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002563 virtual Range* InferRange();
2564};
2565
2566
2567class HMul: public HArithmeticBinaryOperation {
2568 public:
2569 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2570 SetFlag(kCanOverflow);
2571 }
2572
2573 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2574
2575 // Only commutative if it is certain that not two objects are multiplicated.
2576 virtual bool IsCommutative() const {
2577 return !representation().IsTagged();
2578 }
2579
2580 DECLARE_CONCRETE_INSTRUCTION(Mul, "mul")
2581
2582 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002583 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002584
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002585 virtual Range* InferRange();
2586};
2587
2588
2589class HMod: public HArithmeticBinaryOperation {
2590 public:
2591 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2592 SetFlag(kCanBeDivByZero);
2593 }
2594
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002595 bool HasPowerOf2Divisor() {
2596 if (right()->IsConstant() &&
2597 HConstant::cast(right())->HasInteger32Value()) {
2598 int32_t value = HConstant::cast(right())->Integer32Value();
2599 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2600 }
2601
2602 return false;
2603 }
2604
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002605 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2606
2607 DECLARE_CONCRETE_INSTRUCTION(Mod, "mod")
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 HDiv: public HArithmeticBinaryOperation {
2617 public:
2618 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2619 SetFlag(kCanBeDivByZero);
2620 SetFlag(kCanOverflow);
2621 }
2622
2623 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2624
2625 DECLARE_CONCRETE_INSTRUCTION(Div, "div")
2626
2627 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002628 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002629
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002630 virtual Range* InferRange();
2631};
2632
2633
2634class HBitAnd: public HBitwiseBinaryOperation {
2635 public:
2636 HBitAnd(HValue* left, HValue* right)
2637 : HBitwiseBinaryOperation(left, right) { }
2638
2639 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002640 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002641
2642 DECLARE_CONCRETE_INSTRUCTION(BitAnd, "bit_and")
2643
2644 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002645 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002646
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002647 virtual Range* InferRange();
2648};
2649
2650
2651class HBitXor: public HBitwiseBinaryOperation {
2652 public:
2653 HBitXor(HValue* left, HValue* right)
2654 : HBitwiseBinaryOperation(left, right) { }
2655
2656 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002657 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002658
2659 DECLARE_CONCRETE_INSTRUCTION(BitXor, "bit_xor")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002660
2661 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002662 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002663};
2664
2665
2666class HBitOr: public HBitwiseBinaryOperation {
2667 public:
2668 HBitOr(HValue* left, HValue* right)
2669 : HBitwiseBinaryOperation(left, right) { }
2670
2671 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002672 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002673
2674 DECLARE_CONCRETE_INSTRUCTION(BitOr, "bit_or")
2675
2676 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002677 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002678
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002679 virtual Range* InferRange();
2680};
2681
2682
2683class HShl: public HBitwiseBinaryOperation {
2684 public:
2685 HShl(HValue* left, HValue* right)
2686 : HBitwiseBinaryOperation(left, right) { }
2687
2688 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002689 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002690
2691 DECLARE_CONCRETE_INSTRUCTION(Shl, "shl")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002692
2693 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002694 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002695};
2696
2697
2698class HShr: public HBitwiseBinaryOperation {
2699 public:
2700 HShr(HValue* left, HValue* right)
2701 : HBitwiseBinaryOperation(left, right) { }
2702
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002703 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002704
2705 DECLARE_CONCRETE_INSTRUCTION(Shr, "shr")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002706
2707 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002708 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002709};
2710
2711
2712class HSar: public HBitwiseBinaryOperation {
2713 public:
2714 HSar(HValue* left, HValue* right)
2715 : HBitwiseBinaryOperation(left, right) { }
2716
2717 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002718 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002719
2720 DECLARE_CONCRETE_INSTRUCTION(Sar, "sar")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002721
2722 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002723 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002724};
2725
2726
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002727class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002728 public:
2729 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
2730 SetFlag(kChangesOsrEntries);
2731 }
2732
2733 int ast_id() const { return ast_id_; }
2734
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002735 virtual Representation RequiredInputRepresentation(int index) const {
2736 return Representation::None();
2737 }
2738
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002739 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr_entry")
2740
2741 private:
2742 int ast_id_;
2743};
2744
2745
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002746class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002747 public:
2748 explicit HParameter(unsigned index) : index_(index) {
2749 set_representation(Representation::Tagged());
2750 }
2751
2752 unsigned index() const { return index_; }
2753
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002754 virtual void PrintDataTo(StringStream* stream);
2755
2756 virtual Representation RequiredInputRepresentation(int index) const {
2757 return Representation::None();
2758 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002759
2760 DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
2761
2762 private:
2763 unsigned index_;
2764};
2765
2766
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002767class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002768 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002769 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
2770 : HUnaryCall(context, argument_count),
2771 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002772 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002773 }
2774
2775 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002776
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002777 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002778
2779 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
2780 transcendental_type_ = transcendental_type;
2781 }
2782 TranscendentalCache::Type transcendental_type() {
2783 return transcendental_type_;
2784 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002785
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002786 virtual void PrintDataTo(StringStream* stream);
2787
2788 virtual Representation RequiredInputRepresentation(int index) const {
2789 return Representation::Tagged();
2790 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002791
2792 DECLARE_CONCRETE_INSTRUCTION(CallStub, "call_stub")
2793
2794 private:
2795 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002796 TranscendentalCache::Type transcendental_type_;
2797};
2798
2799
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002800class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002801 public:
2802 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
2803
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002804 virtual Representation RequiredInputRepresentation(int index) const {
2805 return Representation::None();
2806 }
2807
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002808 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown_osr_value")
2809};
2810
2811
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002812class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002813 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002814 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002815 : cell_(cell), check_hole_value_(check_hole_value) {
2816 set_representation(Representation::Tagged());
2817 SetFlag(kUseGVN);
2818 SetFlag(kDependsOnGlobalVars);
2819 }
2820
2821 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
2822 bool check_hole_value() const { return check_hole_value_; }
2823
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002824 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002825
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002826 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002827 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002828 return reinterpret_cast<intptr_t>(*cell_);
2829 }
2830
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002831 virtual Representation RequiredInputRepresentation(int index) const {
2832 return Representation::None();
2833 }
2834
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002835 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell, "load_global_cell")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002836
2837 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002838 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002839 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002840 return cell_.is_identical_to(b->cell());
2841 }
2842
2843 private:
2844 Handle<JSGlobalPropertyCell> cell_;
2845 bool check_hole_value_;
2846};
2847
2848
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002849class HLoadGlobalGeneric: public HBinaryOperation {
2850 public:
2851 HLoadGlobalGeneric(HValue* context,
2852 HValue* global_object,
2853 Handle<Object> name,
2854 bool for_typeof)
2855 : HBinaryOperation(context, global_object),
2856 name_(name),
2857 for_typeof_(for_typeof) {
2858 set_representation(Representation::Tagged());
2859 SetAllSideEffects();
2860 }
2861
2862 HValue* context() { return OperandAt(0); }
2863 HValue* global_object() { return OperandAt(1); }
2864 Handle<Object> name() const { return name_; }
2865 bool for_typeof() const { return for_typeof_; }
2866
2867 virtual void PrintDataTo(StringStream* stream);
2868
2869 virtual Representation RequiredInputRepresentation(int index) const {
2870 return Representation::Tagged();
2871 }
2872
2873 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load_global_generic")
2874
2875 private:
2876 Handle<Object> name_;
2877 bool for_typeof_;
2878};
2879
2880
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002881class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002882 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002883 HStoreGlobalCell(HValue* value,
2884 Handle<JSGlobalPropertyCell> cell,
2885 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002886 : HUnaryOperation(value),
2887 cell_(cell),
2888 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002889 SetFlag(kChangesGlobalVars);
2890 }
2891
2892 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002893 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002894
2895 virtual Representation RequiredInputRepresentation(int index) const {
2896 return Representation::Tagged();
2897 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002898 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002899
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002900 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store_global_cell")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002901
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002902 private:
2903 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00002904 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002905};
2906
2907
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002908class HStoreGlobalGeneric: public HTemplateInstruction<3> {
2909 public:
2910 HStoreGlobalGeneric(HValue* context,
2911 HValue* global_object,
2912 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002913 HValue* value,
2914 bool strict_mode)
2915 : name_(name),
2916 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002917 SetOperandAt(0, context);
2918 SetOperandAt(1, global_object);
2919 SetOperandAt(2, value);
2920 set_representation(Representation::Tagged());
2921 SetAllSideEffects();
2922 }
2923
2924 HValue* context() { return OperandAt(0); }
2925 HValue* global_object() { return OperandAt(1); }
2926 Handle<Object> name() const { return name_; }
2927 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002928 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002929
2930 virtual void PrintDataTo(StringStream* stream);
2931
2932 virtual Representation RequiredInputRepresentation(int index) const {
2933 return Representation::Tagged();
2934 }
2935
2936 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric, "store_global_generic")
2937
2938 private:
2939 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002940 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002941};
2942
2943
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002944class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002945 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002946 HLoadContextSlot(HValue* context , int slot_index)
2947 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002948 set_representation(Representation::Tagged());
2949 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002950 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002951 }
2952
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002953 int slot_index() const { return slot_index_; }
2954
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002955 virtual Representation RequiredInputRepresentation(int index) const {
2956 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002957 }
2958
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002959 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002960
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002961 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load_context_slot")
2962
2963 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002964 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002965 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002966 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002967 }
2968
2969 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002970 int slot_index_;
2971};
2972
2973
2974static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
2975 return !value->type().IsSmi() &&
2976 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
2977}
2978
2979
2980class HStoreContextSlot: public HBinaryOperation {
2981 public:
2982 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
2983 : HBinaryOperation(context, value), slot_index_(slot_index) {
2984 SetFlag(kChangesContextSlots);
2985 }
2986
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002987 HValue* context() { return OperandAt(0); }
2988 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002989 int slot_index() const { return slot_index_; }
2990
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002991 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002992 return StoringValueNeedsWriteBarrier(value());
2993 }
2994
2995 virtual Representation RequiredInputRepresentation(int index) const {
2996 return Representation::Tagged();
2997 }
2998
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002999 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003000
3001 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store_context_slot")
3002
3003 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003004 int slot_index_;
3005};
3006
3007
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003008class HLoadNamedField: public HUnaryOperation {
3009 public:
3010 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3011 : HUnaryOperation(object),
3012 is_in_object_(is_in_object),
3013 offset_(offset) {
3014 set_representation(Representation::Tagged());
3015 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003016 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003017 if (is_in_object) {
3018 SetFlag(kDependsOnInobjectFields);
3019 } else {
3020 SetFlag(kDependsOnBackingStoreFields);
3021 }
3022 }
3023
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003024 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003025 bool is_in_object() const { return is_in_object_; }
3026 int offset() const { return offset_; }
3027
3028 virtual Representation RequiredInputRepresentation(int index) const {
3029 return Representation::Tagged();
3030 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003031 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003032
3033 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load_named_field")
3034
3035 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003036 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003037 HLoadNamedField* b = HLoadNamedField::cast(other);
3038 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3039 }
3040
3041 private:
3042 bool is_in_object_;
3043 int offset_;
3044};
3045
3046
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003047class HLoadNamedFieldPolymorphic: public HUnaryOperation {
3048 public:
3049 HLoadNamedFieldPolymorphic(HValue* object,
3050 ZoneMapList* types,
3051 Handle<String> name);
3052
3053 HValue* object() { return OperandAt(0); }
3054 ZoneMapList* types() { return &types_; }
3055 Handle<String> name() { return name_; }
3056 bool need_generic() { return need_generic_; }
3057
3058 virtual Representation RequiredInputRepresentation(int index) const {
3059 return Representation::Tagged();
3060 }
3061
3062 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic,
3063 "load_named_field_polymorphic")
3064
3065 static const int kMaxLoadPolymorphism = 4;
3066
3067 protected:
3068 virtual bool DataEquals(HValue* value);
3069
3070 private:
3071 ZoneMapList types_;
3072 Handle<String> name_;
3073 bool need_generic_;
3074};
3075
3076
3077
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003078class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003079 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003080 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
3081 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003082 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003083 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003084 }
3085
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003086 HValue* context() { return OperandAt(0); }
3087 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003088 Handle<Object> name() const { return name_; }
3089
3090 virtual Representation RequiredInputRepresentation(int index) const {
3091 return Representation::Tagged();
3092 }
3093
3094 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load_named_generic")
3095
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003096 private:
3097 Handle<Object> name_;
3098};
3099
3100
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003101class HLoadFunctionPrototype: public HUnaryOperation {
3102 public:
3103 explicit HLoadFunctionPrototype(HValue* function)
3104 : HUnaryOperation(function) {
3105 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003106 SetFlag(kUseGVN);
3107 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003108 }
3109
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003110 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003111
3112 virtual Representation RequiredInputRepresentation(int index) const {
3113 return Representation::Tagged();
3114 }
3115
3116 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load_function_prototype")
3117
3118 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003119 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003120};
3121
3122
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003123class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003124 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003125 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003126 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003127 SetFlag(kDependsOnArrayElements);
3128 SetFlag(kUseGVN);
3129 }
3130
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003131 HValue* object() { return OperandAt(0); }
3132 HValue* key() { return OperandAt(1); }
3133
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003134 virtual Representation RequiredInputRepresentation(int index) const {
3135 // The key is supposed to be Integer32.
3136 return (index == 1) ? Representation::Integer32()
3137 : Representation::Tagged();
3138 }
3139
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003140 virtual void PrintDataTo(StringStream* stream);
3141
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003142 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement,
3143 "load_keyed_fast_element")
ager@chromium.org378b34e2011-01-28 08:04:38 +00003144
3145 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003146 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003147};
3148
3149
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003150class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003151 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003152 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3153 HValue* key,
3154 ExternalArrayType array_type)
3155 : HBinaryOperation(external_elements, key),
3156 array_type_(array_type) {
3157 if (array_type == kExternalFloatArray) {
3158 set_representation(Representation::Double());
3159 } else {
3160 set_representation(Representation::Integer32());
3161 }
3162 SetFlag(kDependsOnSpecializedArrayElements);
3163 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003164 SetFlag(kDependsOnCalls);
3165 SetFlag(kUseGVN);
3166 }
3167
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003168 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003169
3170 virtual Representation RequiredInputRepresentation(int index) const {
3171 // The key is supposed to be Integer32, but the base pointer
3172 // for the element load is a naked pointer.
3173 return (index == 1) ? Representation::Integer32()
3174 : Representation::External();
3175 }
3176
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003177 HValue* external_pointer() { return OperandAt(0); }
3178 HValue* key() { return OperandAt(1); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003179 ExternalArrayType array_type() const { return array_type_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003180
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003181 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement,
3182 "load_keyed_specialized_array_element")
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003183
3184 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003185 virtual bool DataEquals(HValue* other) {
3186 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3187 HLoadKeyedSpecializedArrayElement* cast_other =
3188 HLoadKeyedSpecializedArrayElement::cast(other);
3189 return array_type_ == cast_other->array_type();
3190 }
3191
3192 private:
3193 ExternalArrayType array_type_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003194};
3195
3196
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003197class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003198 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003199 HLoadKeyedGeneric(HContext* context, HValue* obj, HValue* key) {
3200 set_representation(Representation::Tagged());
3201 SetOperandAt(0, obj);
3202 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003203 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003204 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003205 }
3206
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003207 HValue* object() { return OperandAt(0); }
3208 HValue* key() { return OperandAt(1); }
3209 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003210
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003211 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003212
3213 virtual Representation RequiredInputRepresentation(int index) const {
3214 return Representation::Tagged();
3215 }
3216
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003217 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load_keyed_generic")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003218};
3219
3220
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003221class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003222 public:
3223 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003224 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003225 HValue* val,
3226 bool in_object,
3227 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003228 : HBinaryOperation(obj, val),
3229 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003230 is_in_object_(in_object),
3231 offset_(offset) {
3232 if (is_in_object_) {
3233 SetFlag(kChangesInobjectFields);
3234 } else {
3235 SetFlag(kChangesBackingStoreFields);
3236 }
3237 }
3238
3239 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store_named_field")
3240
3241 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003242 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003243 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003244 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003245
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003246 HValue* object() { return OperandAt(0); }
3247 HValue* value() { return OperandAt(1); }
3248
3249 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003250 bool is_in_object() const { return is_in_object_; }
3251 int offset() const { return offset_; }
3252 Handle<Map> transition() const { return transition_; }
3253 void set_transition(Handle<Map> map) { transition_ = map; }
3254
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003255 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003256 return StoringValueNeedsWriteBarrier(value());
3257 }
3258
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003259 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003260 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003261 bool is_in_object_;
3262 int offset_;
3263 Handle<Map> transition_;
3264};
3265
3266
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003267class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003268 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003269 HStoreNamedGeneric(HValue* context,
3270 HValue* object,
3271 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003272 HValue* value,
3273 bool strict_mode)
3274 : name_(name),
3275 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003276 SetOperandAt(0, object);
3277 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003278 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003279 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003280 }
3281
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003282 HValue* object() { return OperandAt(0); }
3283 HValue* value() { return OperandAt(1); }
3284 HValue* context() { return OperandAt(2); }
3285 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003286 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003287
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003288 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003289
3290 virtual Representation RequiredInputRepresentation(int index) const {
3291 return Representation::Tagged();
3292 }
3293
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003294 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store_named_generic")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003295
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003296 private:
3297 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003298 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003299};
3300
3301
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003302class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003303 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003304 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3305 SetOperandAt(0, obj);
3306 SetOperandAt(1, key);
3307 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003308 SetFlag(kChangesArrayElements);
3309 }
3310
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003311 virtual Representation RequiredInputRepresentation(int index) const {
3312 // The key is supposed to be Integer32.
3313 return (index == 1) ? Representation::Integer32()
3314 : Representation::Tagged();
3315 }
3316
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003317 HValue* object() { return OperandAt(0); }
3318 HValue* key() { return OperandAt(1); }
3319 HValue* value() { return OperandAt(2); }
3320
3321 bool NeedsWriteBarrier() {
3322 return StoringValueNeedsWriteBarrier(value());
3323 }
3324
3325 virtual void PrintDataTo(StringStream* stream);
3326
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003327 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
3328 "store_keyed_fast_element")
3329};
3330
3331
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003332class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003333 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003334 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3335 HValue* key,
3336 HValue* val,
3337 ExternalArrayType array_type)
3338 : array_type_(array_type) {
3339 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003340 SetOperandAt(0, external_elements);
3341 SetOperandAt(1, key);
3342 SetOperandAt(2, val);
3343 }
3344
3345 virtual void PrintDataTo(StringStream* stream);
3346
3347 virtual Representation RequiredInputRepresentation(int index) const {
3348 if (index == 0) {
3349 return Representation::External();
3350 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003351 if (index == 2 && array_type() == kExternalFloatArray) {
3352 return Representation::Double();
3353 } else {
3354 return Representation::Integer32();
3355 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003356 }
3357 }
3358
3359 HValue* external_pointer() { return OperandAt(0); }
3360 HValue* key() { return OperandAt(1); }
3361 HValue* value() { return OperandAt(2); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003362 ExternalArrayType array_type() const { return array_type_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003363
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003364 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,
3365 "store_keyed_specialized_array_element")
3366 private:
3367 ExternalArrayType array_type_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003368};
3369
3370
3371class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003372 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003373 HStoreKeyedGeneric(HValue* context,
3374 HValue* object,
3375 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003376 HValue* value,
3377 bool strict_mode)
3378 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003379 SetOperandAt(0, object);
3380 SetOperandAt(1, key);
3381 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003382 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003383 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003384 }
3385
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003386 HValue* object() { return OperandAt(0); }
3387 HValue* key() { return OperandAt(1); }
3388 HValue* value() { return OperandAt(2); }
3389 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003390 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003391
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003392 virtual Representation RequiredInputRepresentation(int index) const {
3393 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003394 }
3395
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003396 virtual void PrintDataTo(StringStream* stream);
3397
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003398 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store_keyed_generic")
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003399
3400 private:
3401 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003402};
3403
3404
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003405class HStringCharCodeAt: public HBinaryOperation {
3406 public:
3407 HStringCharCodeAt(HValue* string, HValue* index)
3408 : HBinaryOperation(string, index) {
3409 set_representation(Representation::Integer32());
3410 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003411 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003412 }
3413
3414 virtual Representation RequiredInputRepresentation(int index) const {
3415 // The index is supposed to be Integer32.
3416 return (index == 1) ? Representation::Integer32()
3417 : Representation::Tagged();
3418 }
3419
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003420 HValue* string() { return OperandAt(0); }
3421 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003422
3423 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string_char_code_at")
3424
3425 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003426 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003427
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003428 virtual Range* InferRange() {
3429 return new Range(0, String::kMaxUC16CharCode);
3430 }
3431};
3432
3433
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003434class HStringCharFromCode: public HUnaryOperation {
3435 public:
3436 explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
3437 set_representation(Representation::Tagged());
3438 SetFlag(kUseGVN);
3439 }
3440
3441 virtual Representation RequiredInputRepresentation(int index) const {
3442 return Representation::Integer32();
3443 }
3444
3445 virtual bool DataEquals(HValue* other) { return true; }
3446
3447 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string_char_from_code")
3448};
3449
3450
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003451class HStringLength: public HUnaryOperation {
3452 public:
3453 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3454 set_representation(Representation::Tagged());
3455 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003456 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003457 }
3458
3459 virtual Representation RequiredInputRepresentation(int index) const {
3460 return Representation::Tagged();
3461 }
3462
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003463 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003464 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3465 return HType::Smi();
3466 }
3467
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003468 DECLARE_CONCRETE_INSTRUCTION(StringLength, "string_length")
3469
3470 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003471 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003472
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003473 virtual Range* InferRange() {
3474 return new Range(0, String::kMaxLength);
3475 }
3476};
3477
3478
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003479template <int V>
3480class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003481 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003482 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003483 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003484 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003485 }
3486
3487 int literal_index() const { return literal_index_; }
3488 int depth() const { return depth_; }
3489
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003490 private:
3491 int literal_index_;
3492 int depth_;
3493};
3494
3495
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003496class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003497 public:
3498 HArrayLiteral(Handle<FixedArray> constant_elements,
3499 int length,
3500 int literal_index,
3501 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003502 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003503 length_(length),
3504 constant_elements_(constant_elements) {}
3505
3506 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3507 int length() const { return length_; }
3508
3509 bool IsCopyOnWrite() const;
3510
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003511 virtual Representation RequiredInputRepresentation(int index) const {
3512 return Representation::None();
3513 }
3514
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003515 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array_literal")
3516
3517 private:
3518 int length_;
3519 Handle<FixedArray> constant_elements_;
3520};
3521
3522
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003523class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003524 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003525 HObjectLiteral(HValue* context,
3526 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003527 bool fast_elements,
3528 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003529 int depth,
3530 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003531 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003532 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003533 fast_elements_(fast_elements),
3534 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003535 SetOperandAt(0, context);
3536 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003537
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003538 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003539 Handle<FixedArray> constant_properties() const {
3540 return constant_properties_;
3541 }
3542 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003543 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003544
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003545 virtual Representation RequiredInputRepresentation(int index) const {
3546 return Representation::Tagged();
3547 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003548
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003549 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object_literal")
3550
3551 private:
3552 Handle<FixedArray> constant_properties_;
3553 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003554 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003555};
3556
3557
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003558class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003559 public:
3560 HRegExpLiteral(Handle<String> pattern,
3561 Handle<String> flags,
3562 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003563 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003564 pattern_(pattern),
3565 flags_(flags) { }
3566
3567 Handle<String> pattern() { return pattern_; }
3568 Handle<String> flags() { return flags_; }
3569
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003570 virtual Representation RequiredInputRepresentation(int index) const {
3571 return Representation::None();
3572 }
3573
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003574 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp_literal")
3575
3576 private:
3577 Handle<String> pattern_;
3578 Handle<String> flags_;
3579};
3580
3581
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003582class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003583 public:
3584 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3585 : shared_info_(shared), pretenure_(pretenure) {
3586 set_representation(Representation::Tagged());
3587 }
3588
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003589 virtual Representation RequiredInputRepresentation(int index) const {
3590 return Representation::None();
3591 }
3592
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003593 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function_literal")
3594
3595 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3596 bool pretenure() const { return pretenure_; }
3597
3598 private:
3599 Handle<SharedFunctionInfo> shared_info_;
3600 bool pretenure_;
3601};
3602
3603
3604class HTypeof: public HUnaryOperation {
3605 public:
3606 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
3607 set_representation(Representation::Tagged());
3608 }
3609
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003610 virtual Representation RequiredInputRepresentation(int index) const {
3611 return Representation::Tagged();
3612 }
3613
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003614 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
3615};
3616
3617
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003618class HToFastProperties: public HUnaryOperation {
3619 public:
3620 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
3621 // This instruction is not marked as having side effects, but
3622 // changes the map of the input operand. Use it only when creating
3623 // object literals.
3624 ASSERT(value->IsObjectLiteral());
3625 set_representation(Representation::Tagged());
3626 }
3627
3628 virtual Representation RequiredInputRepresentation(int index) const {
3629 return Representation::Tagged();
3630 }
3631
3632 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to_fast_properties")
3633};
3634
3635
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003636class HValueOf: public HUnaryOperation {
3637 public:
3638 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
3639 set_representation(Representation::Tagged());
3640 }
3641
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003642 virtual Representation RequiredInputRepresentation(int index) const {
3643 return Representation::Tagged();
3644 }
3645
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003646 DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value_of")
3647};
3648
3649
3650class HDeleteProperty: public HBinaryOperation {
3651 public:
3652 HDeleteProperty(HValue* obj, HValue* key)
3653 : HBinaryOperation(obj, key) {
3654 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003655 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003656 }
3657
3658 virtual Representation RequiredInputRepresentation(int index) const {
3659 return Representation::Tagged();
3660 }
3661
3662 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete_property")
3663
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003664 HValue* object() { return left(); }
3665 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003666};
3667
3668#undef DECLARE_INSTRUCTION
3669#undef DECLARE_CONCRETE_INSTRUCTION
3670
3671} } // namespace v8::internal
3672
3673#endif // V8_HYDROGEN_INSTRUCTIONS_H_