blob: 053ae9ed2d8f9318a5523daec804be2568b67c10 [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
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001964 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001965 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001966 return reinterpret_cast<intptr_t>(*handle());
1967 }
1968
1969#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001970 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001971#endif
1972
1973 DECLARE_CONCRETE_INSTRUCTION(Constant, "constant")
1974
1975 protected:
1976 virtual Range* InferRange();
1977
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001978 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001979 HConstant* other_constant = HConstant::cast(other);
1980 return handle().is_identical_to(other_constant->handle());
1981 }
1982
1983 private:
1984 Handle<Object> handle_;
1985 HType constant_type_;
1986
1987 // The following two values represent the int32 and the double value of the
1988 // given constant if there is a lossless conversion between the constant
1989 // and the specific representation.
1990 bool has_int32_value_;
1991 int32_t int32_value_;
1992 bool has_double_value_;
1993 double double_value_;
1994};
1995
1996
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001997class HBinaryOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001998 public:
1999 HBinaryOperation(HValue* left, HValue* right) {
2000 ASSERT(left != NULL && right != NULL);
2001 SetOperandAt(0, left);
2002 SetOperandAt(1, right);
2003 }
2004
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002005 HValue* left() { return OperandAt(0); }
2006 HValue* right() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002007
2008 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2009 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002010 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002011 if (IsCommutative() && left()->IsConstant()) return right();
2012 return left();
2013 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002014 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002015 if (IsCommutative() && left()->IsConstant()) return left();
2016 return right();
2017 }
2018
2019 virtual bool IsCommutative() const { return false; }
2020
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002021 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002022
2023 DECLARE_INSTRUCTION(BinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002024};
2025
2026
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002027class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002028 public:
2029 HApplyArguments(HValue* function,
2030 HValue* receiver,
2031 HValue* length,
2032 HValue* elements) {
2033 set_representation(Representation::Tagged());
2034 SetOperandAt(0, function);
2035 SetOperandAt(1, receiver);
2036 SetOperandAt(2, length);
2037 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002038 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002039 }
2040
2041 virtual Representation RequiredInputRepresentation(int index) const {
2042 // The length is untagged, all other inputs are tagged.
2043 return (index == 2)
2044 ? Representation::Integer32()
2045 : Representation::Tagged();
2046 }
2047
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002048 HValue* function() { return OperandAt(0); }
2049 HValue* receiver() { return OperandAt(1); }
2050 HValue* length() { return OperandAt(2); }
2051 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002052
2053 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply_arguments")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002054};
2055
2056
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002057class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002058 public:
2059 HArgumentsElements() {
2060 // The value produced by this instruction is a pointer into the stack
2061 // that looks as if it was a smi because of alignment.
2062 set_representation(Representation::Tagged());
2063 SetFlag(kUseGVN);
2064 }
2065
2066 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments_elements")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002067
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002068 virtual Representation RequiredInputRepresentation(int index) const {
2069 return Representation::None();
2070 }
2071
ager@chromium.org378b34e2011-01-28 08:04:38 +00002072 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002073 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002074};
2075
2076
2077class HArgumentsLength: public HUnaryOperation {
2078 public:
2079 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2080 set_representation(Representation::Integer32());
2081 SetFlag(kUseGVN);
2082 }
2083
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002084 virtual Representation RequiredInputRepresentation(int index) const {
2085 return Representation::Tagged();
2086 }
2087
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002088 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002089
2090 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002091 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002092};
2093
2094
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002095class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002096 public:
2097 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2098 set_representation(Representation::Tagged());
2099 SetFlag(kUseGVN);
2100 SetOperandAt(0, arguments);
2101 SetOperandAt(1, length);
2102 SetOperandAt(2, index);
2103 }
2104
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002105 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002106
2107 virtual Representation RequiredInputRepresentation(int index) const {
2108 // The arguments elements is considered tagged.
2109 return index == 0
2110 ? Representation::Tagged()
2111 : Representation::Integer32();
2112 }
2113
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002114 HValue* arguments() { return OperandAt(0); }
2115 HValue* length() { return OperandAt(1); }
2116 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002117
2118 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access_arguments_at")
2119
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002120 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002121};
2122
2123
2124class HBoundsCheck: public HBinaryOperation {
2125 public:
2126 HBoundsCheck(HValue* index, HValue* length)
2127 : HBinaryOperation(index, length) {
2128 SetFlag(kUseGVN);
2129 }
2130
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002131 virtual bool IsCheckInstruction() const { return true; }
2132
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002133 virtual Representation RequiredInputRepresentation(int index) const {
2134 return Representation::Integer32();
2135 }
2136
2137#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002138 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002139#endif
2140
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002141 HValue* index() { return left(); }
2142 HValue* length() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002143
2144 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds_check")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002145
2146 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002147 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002148};
2149
2150
2151class HBitwiseBinaryOperation: public HBinaryOperation {
2152 public:
2153 HBitwiseBinaryOperation(HValue* left, HValue* right)
2154 : HBinaryOperation(left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002155 set_representation(Representation::Tagged());
2156 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002157 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002158 }
2159
2160 virtual Representation RequiredInputRepresentation(int index) const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002161 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002162 }
2163
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002164 virtual void RepresentationChanged(Representation to) {
2165 if (!to.IsTagged()) {
2166 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002167 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002168 SetFlag(kTruncatingToInt32);
2169 SetFlag(kUseGVN);
2170 }
2171 }
2172
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002173 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002174
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002175 DECLARE_INSTRUCTION(BitwiseBinaryOperation)
2176};
2177
2178
2179class HArithmeticBinaryOperation: public HBinaryOperation {
2180 public:
2181 HArithmeticBinaryOperation(HValue* left, HValue* right)
2182 : HBinaryOperation(left, right) {
2183 set_representation(Representation::Tagged());
2184 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002185 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002186 }
2187
2188 virtual void RepresentationChanged(Representation to) {
2189 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002190 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002191 SetFlag(kUseGVN);
2192 }
2193 }
2194
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002195 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002196 virtual Representation RequiredInputRepresentation(int index) const {
2197 return representation();
2198 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002199 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002200 if (left()->representation().Equals(right()->representation())) {
2201 return left()->representation();
2202 }
2203 return HValue::InferredRepresentation();
2204 }
2205
2206 DECLARE_INSTRUCTION(ArithmeticBinaryOperation)
2207};
2208
2209
2210class HCompare: public HBinaryOperation {
2211 public:
2212 HCompare(HValue* left, HValue* right, Token::Value token)
2213 : HBinaryOperation(left, right), token_(token) {
2214 ASSERT(Token::IsCompareOp(token));
2215 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002216 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002217 }
2218
2219 void SetInputRepresentation(Representation r);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002220
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002221 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002222 return !HasSideEffects() && (uses()->length() <= 1);
2223 }
2224
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002225 virtual Representation RequiredInputRepresentation(int index) const {
2226 return input_representation_;
2227 }
2228 Representation GetInputRepresentation() const {
2229 return input_representation_;
2230 }
2231 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002232 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002233
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002234 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002235
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002236 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002237 return HValue::Hashcode() * 7 + token_;
2238 }
2239
2240 DECLARE_CONCRETE_INSTRUCTION(Compare, "compare")
2241
2242 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002243 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002244 HCompare* comp = HCompare::cast(other);
2245 return token_ == comp->token();
2246 }
2247
2248 private:
2249 Representation input_representation_;
2250 Token::Value token_;
2251};
2252
2253
2254class HCompareJSObjectEq: public HBinaryOperation {
2255 public:
2256 HCompareJSObjectEq(HValue* left, HValue* right)
2257 : HBinaryOperation(left, right) {
2258 set_representation(Representation::Tagged());
2259 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002260 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002261 }
2262
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002263 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002264 return !HasSideEffects() && (uses()->length() <= 1);
2265 }
2266
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002267 virtual Representation RequiredInputRepresentation(int index) const {
2268 return Representation::Tagged();
2269 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002270 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002271
2272 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq, "compare-js-object-eq")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002273
2274 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002275 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002276};
2277
2278
2279class HUnaryPredicate: public HUnaryOperation {
2280 public:
2281 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2282 set_representation(Representation::Tagged());
2283 SetFlag(kUseGVN);
2284 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002285
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002286 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002287 return !HasSideEffects() && (uses()->length() <= 1);
2288 }
2289
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002290 virtual Representation RequiredInputRepresentation(int index) const {
2291 return Representation::Tagged();
2292 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002293 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002294};
2295
2296
2297class HIsNull: public HUnaryPredicate {
2298 public:
2299 HIsNull(HValue* value, bool is_strict)
2300 : HUnaryPredicate(value), is_strict_(is_strict) { }
2301
2302 bool is_strict() const { return is_strict_; }
2303
2304 DECLARE_CONCRETE_INSTRUCTION(IsNull, "is_null")
2305
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002306 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002307 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002308 HIsNull* b = HIsNull::cast(other);
2309 return is_strict_ == b->is_strict();
2310 }
2311
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002312 private:
2313 bool is_strict_;
2314};
2315
2316
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002317class HIsObject: public HUnaryPredicate {
2318 public:
2319 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2320
2321 DECLARE_CONCRETE_INSTRUCTION(IsObject, "is_object")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002322
2323 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002324 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002325};
2326
2327
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002328class HIsSmi: public HUnaryPredicate {
2329 public:
2330 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2331
2332 DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002333
2334 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002335 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002336};
2337
2338
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002339class HIsConstructCall: public HTemplateInstruction<0> {
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002340 public:
2341 HIsConstructCall() {
2342 set_representation(Representation::Tagged());
2343 SetFlag(kUseGVN);
2344 }
2345
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002346 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002347 return !HasSideEffects() && (uses()->length() <= 1);
2348 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002349
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002350 virtual Representation RequiredInputRepresentation(int index) const {
2351 return Representation::None();
2352 }
2353
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002354 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall, "is_construct_call")
2355
2356 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002357 virtual bool DataEquals(HValue* other) { return true; }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002358};
2359
2360
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002361class HHasInstanceType: public HUnaryPredicate {
2362 public:
2363 HHasInstanceType(HValue* value, InstanceType type)
2364 : HUnaryPredicate(value), from_(type), to_(type) { }
2365 HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2366 : HUnaryPredicate(value), from_(from), to_(to) {
2367 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2368 }
2369
2370 InstanceType from() { return from_; }
2371 InstanceType to() { return to_; }
2372
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002373 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002374
2375 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has_instance_type")
2376
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002377 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002378 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002379 HHasInstanceType* b = HHasInstanceType::cast(other);
2380 return (from_ == b->from()) && (to_ == b->to());
2381 }
2382
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002383 private:
2384 InstanceType from_;
2385 InstanceType to_; // Inclusive range, not all combinations work.
2386};
2387
2388
2389class HHasCachedArrayIndex: public HUnaryPredicate {
2390 public:
2391 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2392
2393 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has_cached_array_index")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002394
2395 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002396 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002397};
2398
2399
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002400class HGetCachedArrayIndex: public HUnaryPredicate {
2401 public:
2402 explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2403
2404 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get_cached_array_index")
2405
2406 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002407 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002408};
2409
2410
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002411class HClassOfTest: public HUnaryPredicate {
2412 public:
2413 HClassOfTest(HValue* value, Handle<String> class_name)
2414 : HUnaryPredicate(value), class_name_(class_name) { }
2415
2416 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class_of_test")
2417
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002418 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002419
2420 Handle<String> class_name() const { return class_name_; }
2421
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002422 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002423 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002424 HClassOfTest* b = HClassOfTest::cast(other);
2425 return class_name_.is_identical_to(b->class_name_);
2426 }
2427
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002428 private:
2429 Handle<String> class_name_;
2430};
2431
2432
2433class HTypeofIs: public HUnaryPredicate {
2434 public:
2435 HTypeofIs(HValue* value, Handle<String> type_literal)
2436 : HUnaryPredicate(value), type_literal_(type_literal) { }
2437
2438 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002439 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002440
2441 DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof_is")
2442
2443 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002444 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002445 HTypeofIs* b = HTypeofIs::cast(other);
2446 return type_literal_.is_identical_to(b->type_literal_);
2447 }
2448
2449 private:
2450 Handle<String> type_literal_;
2451};
2452
2453
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002454class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002455 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002456 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2457 SetOperandAt(0, context);
2458 SetOperandAt(1, left);
2459 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002460 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002461 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002462 }
2463
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002464 HValue* context() { return OperandAt(0); }
2465 HValue* left() { return OperandAt(1); }
2466 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002467
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002468 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002469 return !HasSideEffects() && (uses()->length() <= 1);
2470 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002471
2472 virtual Representation RequiredInputRepresentation(int index) const {
2473 return Representation::Tagged();
2474 }
2475
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002476 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002477
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002478 DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance_of")
2479};
2480
2481
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002482class HInstanceOfKnownGlobal: public HUnaryOperation {
2483 public:
2484 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2485 : HUnaryOperation(left), function_(right) {
2486 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002487 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002488 }
2489
2490 Handle<JSFunction> function() { return function_; }
2491
2492 virtual Representation RequiredInputRepresentation(int index) const {
2493 return Representation::Tagged();
2494 }
2495
2496 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
2497 "instance_of_known_global")
2498
2499 private:
2500 Handle<JSFunction> function_;
2501};
2502
2503
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002504class HPower: public HBinaryOperation {
2505 public:
2506 HPower(HValue* left, HValue* right)
2507 : HBinaryOperation(left, right) {
2508 set_representation(Representation::Double());
2509 SetFlag(kUseGVN);
2510 }
2511
2512 virtual Representation RequiredInputRepresentation(int index) const {
2513 return (index == 1) ? Representation::None() : Representation::Double();
2514 }
2515
2516 DECLARE_CONCRETE_INSTRUCTION(Power, "power")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002517
2518 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002519 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002520};
2521
2522
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002523class HAdd: public HArithmeticBinaryOperation {
2524 public:
2525 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2526 SetFlag(kCanOverflow);
2527 }
2528
2529 // Add is only commutative if two integer values are added and not if two
2530 // tagged values are added (because it might be a String concatenation).
2531 virtual bool IsCommutative() const {
2532 return !representation().IsTagged();
2533 }
2534
2535 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2536
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002537 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002538
2539 DECLARE_CONCRETE_INSTRUCTION(Add, "add")
2540
2541 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002542 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002543
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002544 virtual Range* InferRange();
2545};
2546
2547
2548class HSub: public HArithmeticBinaryOperation {
2549 public:
2550 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2551 SetFlag(kCanOverflow);
2552 }
2553
2554 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2555
2556 DECLARE_CONCRETE_INSTRUCTION(Sub, "sub")
2557
2558 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002559 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002560
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002561 virtual Range* InferRange();
2562};
2563
2564
2565class HMul: public HArithmeticBinaryOperation {
2566 public:
2567 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2568 SetFlag(kCanOverflow);
2569 }
2570
2571 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2572
2573 // Only commutative if it is certain that not two objects are multiplicated.
2574 virtual bool IsCommutative() const {
2575 return !representation().IsTagged();
2576 }
2577
2578 DECLARE_CONCRETE_INSTRUCTION(Mul, "mul")
2579
2580 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002581 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002582
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002583 virtual Range* InferRange();
2584};
2585
2586
2587class HMod: public HArithmeticBinaryOperation {
2588 public:
2589 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2590 SetFlag(kCanBeDivByZero);
2591 }
2592
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002593 bool HasPowerOf2Divisor() {
2594 if (right()->IsConstant() &&
2595 HConstant::cast(right())->HasInteger32Value()) {
2596 int32_t value = HConstant::cast(right())->Integer32Value();
2597 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2598 }
2599
2600 return false;
2601 }
2602
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002603 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2604
2605 DECLARE_CONCRETE_INSTRUCTION(Mod, "mod")
2606
2607 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002608 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002609
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002610 virtual Range* InferRange();
2611};
2612
2613
2614class HDiv: public HArithmeticBinaryOperation {
2615 public:
2616 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2617 SetFlag(kCanBeDivByZero);
2618 SetFlag(kCanOverflow);
2619 }
2620
2621 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2622
2623 DECLARE_CONCRETE_INSTRUCTION(Div, "div")
2624
2625 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002626 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002627
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002628 virtual Range* InferRange();
2629};
2630
2631
2632class HBitAnd: public HBitwiseBinaryOperation {
2633 public:
2634 HBitAnd(HValue* left, HValue* right)
2635 : HBitwiseBinaryOperation(left, right) { }
2636
2637 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002638 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002639
2640 DECLARE_CONCRETE_INSTRUCTION(BitAnd, "bit_and")
2641
2642 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002643 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002644
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002645 virtual Range* InferRange();
2646};
2647
2648
2649class HBitXor: public HBitwiseBinaryOperation {
2650 public:
2651 HBitXor(HValue* left, HValue* right)
2652 : HBitwiseBinaryOperation(left, right) { }
2653
2654 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002655 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002656
2657 DECLARE_CONCRETE_INSTRUCTION(BitXor, "bit_xor")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002658
2659 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002660 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002661};
2662
2663
2664class HBitOr: public HBitwiseBinaryOperation {
2665 public:
2666 HBitOr(HValue* left, HValue* right)
2667 : HBitwiseBinaryOperation(left, right) { }
2668
2669 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002670 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002671
2672 DECLARE_CONCRETE_INSTRUCTION(BitOr, "bit_or")
2673
2674 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002675 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002676
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002677 virtual Range* InferRange();
2678};
2679
2680
2681class HShl: public HBitwiseBinaryOperation {
2682 public:
2683 HShl(HValue* left, HValue* right)
2684 : HBitwiseBinaryOperation(left, right) { }
2685
2686 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002687 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002688
2689 DECLARE_CONCRETE_INSTRUCTION(Shl, "shl")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002690
2691 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002692 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002693};
2694
2695
2696class HShr: public HBitwiseBinaryOperation {
2697 public:
2698 HShr(HValue* left, HValue* right)
2699 : HBitwiseBinaryOperation(left, right) { }
2700
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002701 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002702
2703 DECLARE_CONCRETE_INSTRUCTION(Shr, "shr")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002704
2705 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002706 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002707};
2708
2709
2710class HSar: public HBitwiseBinaryOperation {
2711 public:
2712 HSar(HValue* left, HValue* right)
2713 : HBitwiseBinaryOperation(left, right) { }
2714
2715 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002716 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002717
2718 DECLARE_CONCRETE_INSTRUCTION(Sar, "sar")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002719
2720 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002721 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002722};
2723
2724
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002725class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002726 public:
2727 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
2728 SetFlag(kChangesOsrEntries);
2729 }
2730
2731 int ast_id() const { return ast_id_; }
2732
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002733 virtual Representation RequiredInputRepresentation(int index) const {
2734 return Representation::None();
2735 }
2736
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002737 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr_entry")
2738
2739 private:
2740 int ast_id_;
2741};
2742
2743
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002744class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002745 public:
2746 explicit HParameter(unsigned index) : index_(index) {
2747 set_representation(Representation::Tagged());
2748 }
2749
2750 unsigned index() const { return index_; }
2751
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002752 virtual void PrintDataTo(StringStream* stream);
2753
2754 virtual Representation RequiredInputRepresentation(int index) const {
2755 return Representation::None();
2756 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002757
2758 DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
2759
2760 private:
2761 unsigned index_;
2762};
2763
2764
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002765class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002766 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002767 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
2768 : HUnaryCall(context, argument_count),
2769 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002770 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002771 }
2772
2773 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002774
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002775 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002776
2777 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
2778 transcendental_type_ = transcendental_type;
2779 }
2780 TranscendentalCache::Type transcendental_type() {
2781 return transcendental_type_;
2782 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002783
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002784 virtual void PrintDataTo(StringStream* stream);
2785
2786 virtual Representation RequiredInputRepresentation(int index) const {
2787 return Representation::Tagged();
2788 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002789
2790 DECLARE_CONCRETE_INSTRUCTION(CallStub, "call_stub")
2791
2792 private:
2793 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002794 TranscendentalCache::Type transcendental_type_;
2795};
2796
2797
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002798class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002799 public:
2800 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
2801
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002802 virtual Representation RequiredInputRepresentation(int index) const {
2803 return Representation::None();
2804 }
2805
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002806 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown_osr_value")
2807};
2808
2809
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002810class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002811 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002812 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002813 : cell_(cell), check_hole_value_(check_hole_value) {
2814 set_representation(Representation::Tagged());
2815 SetFlag(kUseGVN);
2816 SetFlag(kDependsOnGlobalVars);
2817 }
2818
2819 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
2820 bool check_hole_value() const { return check_hole_value_; }
2821
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002822 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002823
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002824 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002825 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002826 return reinterpret_cast<intptr_t>(*cell_);
2827 }
2828
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002829 virtual Representation RequiredInputRepresentation(int index) const {
2830 return Representation::None();
2831 }
2832
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002833 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell, "load_global_cell")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002834
2835 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002836 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002837 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002838 return cell_.is_identical_to(b->cell());
2839 }
2840
2841 private:
2842 Handle<JSGlobalPropertyCell> cell_;
2843 bool check_hole_value_;
2844};
2845
2846
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002847class HLoadGlobalGeneric: public HBinaryOperation {
2848 public:
2849 HLoadGlobalGeneric(HValue* context,
2850 HValue* global_object,
2851 Handle<Object> name,
2852 bool for_typeof)
2853 : HBinaryOperation(context, global_object),
2854 name_(name),
2855 for_typeof_(for_typeof) {
2856 set_representation(Representation::Tagged());
2857 SetAllSideEffects();
2858 }
2859
2860 HValue* context() { return OperandAt(0); }
2861 HValue* global_object() { return OperandAt(1); }
2862 Handle<Object> name() const { return name_; }
2863 bool for_typeof() const { return for_typeof_; }
2864
2865 virtual void PrintDataTo(StringStream* stream);
2866
2867 virtual Representation RequiredInputRepresentation(int index) const {
2868 return Representation::Tagged();
2869 }
2870
2871 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load_global_generic")
2872
2873 private:
2874 Handle<Object> name_;
2875 bool for_typeof_;
2876};
2877
2878
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002879class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002880 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002881 HStoreGlobalCell(HValue* value,
2882 Handle<JSGlobalPropertyCell> cell,
2883 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002884 : HUnaryOperation(value),
2885 cell_(cell),
2886 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002887 SetFlag(kChangesGlobalVars);
2888 }
2889
2890 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002891 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002892
2893 virtual Representation RequiredInputRepresentation(int index) const {
2894 return Representation::Tagged();
2895 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002896 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002897
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002898 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store_global_cell")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002899
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002900 private:
2901 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00002902 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002903};
2904
2905
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002906class HStoreGlobalGeneric: public HTemplateInstruction<3> {
2907 public:
2908 HStoreGlobalGeneric(HValue* context,
2909 HValue* global_object,
2910 Handle<Object> name,
2911 HValue* value)
2912 : name_(name) {
2913 SetOperandAt(0, context);
2914 SetOperandAt(1, global_object);
2915 SetOperandAt(2, value);
2916 set_representation(Representation::Tagged());
2917 SetAllSideEffects();
2918 }
2919
2920 HValue* context() { return OperandAt(0); }
2921 HValue* global_object() { return OperandAt(1); }
2922 Handle<Object> name() const { return name_; }
2923 HValue* value() { return OperandAt(2); }
2924
2925 virtual void PrintDataTo(StringStream* stream);
2926
2927 virtual Representation RequiredInputRepresentation(int index) const {
2928 return Representation::Tagged();
2929 }
2930
2931 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric, "store_global_generic")
2932
2933 private:
2934 Handle<Object> name_;
2935};
2936
2937
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002938class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002939 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002940 HLoadContextSlot(HValue* context , int slot_index)
2941 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002942 set_representation(Representation::Tagged());
2943 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002944 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002945 }
2946
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002947 int slot_index() const { return slot_index_; }
2948
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002949 virtual Representation RequiredInputRepresentation(int index) const {
2950 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002951 }
2952
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002953 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002954
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002955 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load_context_slot")
2956
2957 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002958 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002959 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002960 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002961 }
2962
2963 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002964 int slot_index_;
2965};
2966
2967
2968static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
2969 return !value->type().IsSmi() &&
2970 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
2971}
2972
2973
2974class HStoreContextSlot: public HBinaryOperation {
2975 public:
2976 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
2977 : HBinaryOperation(context, value), slot_index_(slot_index) {
2978 SetFlag(kChangesContextSlots);
2979 }
2980
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002981 HValue* context() { return OperandAt(0); }
2982 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002983 int slot_index() const { return slot_index_; }
2984
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002985 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002986 return StoringValueNeedsWriteBarrier(value());
2987 }
2988
2989 virtual Representation RequiredInputRepresentation(int index) const {
2990 return Representation::Tagged();
2991 }
2992
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002993 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002994
2995 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store_context_slot")
2996
2997 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002998 int slot_index_;
2999};
3000
3001
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003002class HLoadNamedField: public HUnaryOperation {
3003 public:
3004 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3005 : HUnaryOperation(object),
3006 is_in_object_(is_in_object),
3007 offset_(offset) {
3008 set_representation(Representation::Tagged());
3009 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003010 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003011 if (is_in_object) {
3012 SetFlag(kDependsOnInobjectFields);
3013 } else {
3014 SetFlag(kDependsOnBackingStoreFields);
3015 }
3016 }
3017
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003018 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003019 bool is_in_object() const { return is_in_object_; }
3020 int offset() const { return offset_; }
3021
3022 virtual Representation RequiredInputRepresentation(int index) const {
3023 return Representation::Tagged();
3024 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003025 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003026
3027 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load_named_field")
3028
3029 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003030 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003031 HLoadNamedField* b = HLoadNamedField::cast(other);
3032 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3033 }
3034
3035 private:
3036 bool is_in_object_;
3037 int offset_;
3038};
3039
3040
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003041class HLoadNamedFieldPolymorphic: public HUnaryOperation {
3042 public:
3043 HLoadNamedFieldPolymorphic(HValue* object,
3044 ZoneMapList* types,
3045 Handle<String> name);
3046
3047 HValue* object() { return OperandAt(0); }
3048 ZoneMapList* types() { return &types_; }
3049 Handle<String> name() { return name_; }
3050 bool need_generic() { return need_generic_; }
3051
3052 virtual Representation RequiredInputRepresentation(int index) const {
3053 return Representation::Tagged();
3054 }
3055
3056 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic,
3057 "load_named_field_polymorphic")
3058
3059 static const int kMaxLoadPolymorphism = 4;
3060
3061 protected:
3062 virtual bool DataEquals(HValue* value);
3063
3064 private:
3065 ZoneMapList types_;
3066 Handle<String> name_;
3067 bool need_generic_;
3068};
3069
3070
3071
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003072class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003073 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003074 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
3075 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003076 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003077 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003078 }
3079
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003080 HValue* context() { return OperandAt(0); }
3081 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003082 Handle<Object> name() const { return name_; }
3083
3084 virtual Representation RequiredInputRepresentation(int index) const {
3085 return Representation::Tagged();
3086 }
3087
3088 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load_named_generic")
3089
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003090 private:
3091 Handle<Object> name_;
3092};
3093
3094
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003095class HLoadFunctionPrototype: public HUnaryOperation {
3096 public:
3097 explicit HLoadFunctionPrototype(HValue* function)
3098 : HUnaryOperation(function) {
3099 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003100 SetFlag(kUseGVN);
3101 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003102 }
3103
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003104 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003105
3106 virtual Representation RequiredInputRepresentation(int index) const {
3107 return Representation::Tagged();
3108 }
3109
3110 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load_function_prototype")
3111
3112 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003113 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003114};
3115
3116
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003117class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003118 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003119 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003120 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003121 SetFlag(kDependsOnArrayElements);
3122 SetFlag(kUseGVN);
3123 }
3124
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003125 HValue* object() { return OperandAt(0); }
3126 HValue* key() { return OperandAt(1); }
3127
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003128 virtual Representation RequiredInputRepresentation(int index) const {
3129 // The key is supposed to be Integer32.
3130 return (index == 1) ? Representation::Integer32()
3131 : Representation::Tagged();
3132 }
3133
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003134 virtual void PrintDataTo(StringStream* stream);
3135
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003136 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement,
3137 "load_keyed_fast_element")
ager@chromium.org378b34e2011-01-28 08:04:38 +00003138
3139 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003140 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003141};
3142
3143
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003144class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003145 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003146 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3147 HValue* key,
3148 ExternalArrayType array_type)
3149 : HBinaryOperation(external_elements, key),
3150 array_type_(array_type) {
3151 if (array_type == kExternalFloatArray) {
3152 set_representation(Representation::Double());
3153 } else {
3154 set_representation(Representation::Integer32());
3155 }
3156 SetFlag(kDependsOnSpecializedArrayElements);
3157 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003158 SetFlag(kDependsOnCalls);
3159 SetFlag(kUseGVN);
3160 }
3161
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003162 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003163
3164 virtual Representation RequiredInputRepresentation(int index) const {
3165 // The key is supposed to be Integer32, but the base pointer
3166 // for the element load is a naked pointer.
3167 return (index == 1) ? Representation::Integer32()
3168 : Representation::External();
3169 }
3170
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003171 HValue* external_pointer() { return OperandAt(0); }
3172 HValue* key() { return OperandAt(1); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003173 ExternalArrayType array_type() const { return array_type_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003174
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003175 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement,
3176 "load_keyed_specialized_array_element")
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003177
3178 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003179 virtual bool DataEquals(HValue* other) {
3180 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3181 HLoadKeyedSpecializedArrayElement* cast_other =
3182 HLoadKeyedSpecializedArrayElement::cast(other);
3183 return array_type_ == cast_other->array_type();
3184 }
3185
3186 private:
3187 ExternalArrayType array_type_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003188};
3189
3190
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003191class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003192 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003193 HLoadKeyedGeneric(HContext* context, HValue* obj, HValue* key) {
3194 set_representation(Representation::Tagged());
3195 SetOperandAt(0, obj);
3196 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003197 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003198 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003199 }
3200
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003201 HValue* object() { return OperandAt(0); }
3202 HValue* key() { return OperandAt(1); }
3203 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003204
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003205 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003206
3207 virtual Representation RequiredInputRepresentation(int index) const {
3208 return Representation::Tagged();
3209 }
3210
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003211 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load_keyed_generic")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003212};
3213
3214
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003215class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003216 public:
3217 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003218 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003219 HValue* val,
3220 bool in_object,
3221 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003222 : HBinaryOperation(obj, val),
3223 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003224 is_in_object_(in_object),
3225 offset_(offset) {
3226 if (is_in_object_) {
3227 SetFlag(kChangesInobjectFields);
3228 } else {
3229 SetFlag(kChangesBackingStoreFields);
3230 }
3231 }
3232
3233 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store_named_field")
3234
3235 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003236 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003237 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003238 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003239
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003240 HValue* object() { return OperandAt(0); }
3241 HValue* value() { return OperandAt(1); }
3242
3243 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003244 bool is_in_object() const { return is_in_object_; }
3245 int offset() const { return offset_; }
3246 Handle<Map> transition() const { return transition_; }
3247 void set_transition(Handle<Map> map) { transition_ = map; }
3248
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003249 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003250 return StoringValueNeedsWriteBarrier(value());
3251 }
3252
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003253 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003254 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003255 bool is_in_object_;
3256 int offset_;
3257 Handle<Map> transition_;
3258};
3259
3260
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003261class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003262 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003263 HStoreNamedGeneric(HValue* context,
3264 HValue* object,
3265 Handle<String> name,
3266 HValue* value)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003267 : name_(name) {
3268 SetOperandAt(0, object);
3269 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003270 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003271 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003272 }
3273
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003274 HValue* object() { return OperandAt(0); }
3275 HValue* value() { return OperandAt(1); }
3276 HValue* context() { return OperandAt(2); }
3277 Handle<String> name() { return name_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003278
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003279 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003280
3281 virtual Representation RequiredInputRepresentation(int index) const {
3282 return Representation::Tagged();
3283 }
3284
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003285 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store_named_generic")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003286
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003287 private:
3288 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003289};
3290
3291
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003292class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003293 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003294 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3295 SetOperandAt(0, obj);
3296 SetOperandAt(1, key);
3297 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003298 SetFlag(kChangesArrayElements);
3299 }
3300
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003301 virtual Representation RequiredInputRepresentation(int index) const {
3302 // The key is supposed to be Integer32.
3303 return (index == 1) ? Representation::Integer32()
3304 : Representation::Tagged();
3305 }
3306
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003307 HValue* object() { return OperandAt(0); }
3308 HValue* key() { return OperandAt(1); }
3309 HValue* value() { return OperandAt(2); }
3310
3311 bool NeedsWriteBarrier() {
3312 return StoringValueNeedsWriteBarrier(value());
3313 }
3314
3315 virtual void PrintDataTo(StringStream* stream);
3316
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003317 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
3318 "store_keyed_fast_element")
3319};
3320
3321
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003322class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003323 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003324 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3325 HValue* key,
3326 HValue* val,
3327 ExternalArrayType array_type)
3328 : array_type_(array_type) {
3329 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003330 SetOperandAt(0, external_elements);
3331 SetOperandAt(1, key);
3332 SetOperandAt(2, val);
3333 }
3334
3335 virtual void PrintDataTo(StringStream* stream);
3336
3337 virtual Representation RequiredInputRepresentation(int index) const {
3338 if (index == 0) {
3339 return Representation::External();
3340 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003341 if (index == 2 && array_type() == kExternalFloatArray) {
3342 return Representation::Double();
3343 } else {
3344 return Representation::Integer32();
3345 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003346 }
3347 }
3348
3349 HValue* external_pointer() { return OperandAt(0); }
3350 HValue* key() { return OperandAt(1); }
3351 HValue* value() { return OperandAt(2); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003352 ExternalArrayType array_type() const { return array_type_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003353
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003354 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,
3355 "store_keyed_specialized_array_element")
3356 private:
3357 ExternalArrayType array_type_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003358};
3359
3360
3361class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003362 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003363 HStoreKeyedGeneric(HValue* context,
3364 HValue* object,
3365 HValue* key,
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003366 HValue* value) {
3367 SetOperandAt(0, object);
3368 SetOperandAt(1, key);
3369 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003370 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003371 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003372 }
3373
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003374 HValue* object() { return OperandAt(0); }
3375 HValue* key() { return OperandAt(1); }
3376 HValue* value() { return OperandAt(2); }
3377 HValue* context() { return OperandAt(3); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003378
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003379 virtual Representation RequiredInputRepresentation(int index) const {
3380 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003381 }
3382
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003383 virtual void PrintDataTo(StringStream* stream);
3384
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003385 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store_keyed_generic")
3386};
3387
3388
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003389class HStringCharCodeAt: public HBinaryOperation {
3390 public:
3391 HStringCharCodeAt(HValue* string, HValue* index)
3392 : HBinaryOperation(string, index) {
3393 set_representation(Representation::Integer32());
3394 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003395 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003396 }
3397
3398 virtual Representation RequiredInputRepresentation(int index) const {
3399 // The index is supposed to be Integer32.
3400 return (index == 1) ? Representation::Integer32()
3401 : Representation::Tagged();
3402 }
3403
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003404 HValue* string() { return OperandAt(0); }
3405 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003406
3407 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string_char_code_at")
3408
3409 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003410 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003411
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003412 virtual Range* InferRange() {
3413 return new Range(0, String::kMaxUC16CharCode);
3414 }
3415};
3416
3417
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003418class HStringCharFromCode: public HUnaryOperation {
3419 public:
3420 explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
3421 set_representation(Representation::Tagged());
3422 SetFlag(kUseGVN);
3423 }
3424
3425 virtual Representation RequiredInputRepresentation(int index) const {
3426 return Representation::Integer32();
3427 }
3428
3429 virtual bool DataEquals(HValue* other) { return true; }
3430
3431 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string_char_from_code")
3432};
3433
3434
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003435class HStringLength: public HUnaryOperation {
3436 public:
3437 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3438 set_representation(Representation::Tagged());
3439 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003440 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003441 }
3442
3443 virtual Representation RequiredInputRepresentation(int index) const {
3444 return Representation::Tagged();
3445 }
3446
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003447 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003448 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3449 return HType::Smi();
3450 }
3451
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003452 DECLARE_CONCRETE_INSTRUCTION(StringLength, "string_length")
3453
3454 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003455 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003456
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003457 virtual Range* InferRange() {
3458 return new Range(0, String::kMaxLength);
3459 }
3460};
3461
3462
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003463template <int V>
3464class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003465 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003466 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003467 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003468 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003469 }
3470
3471 int literal_index() const { return literal_index_; }
3472 int depth() const { return depth_; }
3473
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003474 private:
3475 int literal_index_;
3476 int depth_;
3477};
3478
3479
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003480class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003481 public:
3482 HArrayLiteral(Handle<FixedArray> constant_elements,
3483 int length,
3484 int literal_index,
3485 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003486 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003487 length_(length),
3488 constant_elements_(constant_elements) {}
3489
3490 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3491 int length() const { return length_; }
3492
3493 bool IsCopyOnWrite() const;
3494
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003495 virtual Representation RequiredInputRepresentation(int index) const {
3496 return Representation::None();
3497 }
3498
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003499 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array_literal")
3500
3501 private:
3502 int length_;
3503 Handle<FixedArray> constant_elements_;
3504};
3505
3506
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003507class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003508 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003509 HObjectLiteral(HValue* context,
3510 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003511 bool fast_elements,
3512 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003513 int depth,
3514 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003515 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003516 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003517 fast_elements_(fast_elements),
3518 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003519 SetOperandAt(0, context);
3520 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003521
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003522 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003523 Handle<FixedArray> constant_properties() const {
3524 return constant_properties_;
3525 }
3526 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003527 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003528
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003529 virtual Representation RequiredInputRepresentation(int index) const {
3530 return Representation::Tagged();
3531 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003532
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003533 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object_literal")
3534
3535 private:
3536 Handle<FixedArray> constant_properties_;
3537 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003538 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003539};
3540
3541
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003542class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003543 public:
3544 HRegExpLiteral(Handle<String> pattern,
3545 Handle<String> flags,
3546 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003547 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003548 pattern_(pattern),
3549 flags_(flags) { }
3550
3551 Handle<String> pattern() { return pattern_; }
3552 Handle<String> flags() { return flags_; }
3553
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003554 virtual Representation RequiredInputRepresentation(int index) const {
3555 return Representation::None();
3556 }
3557
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003558 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp_literal")
3559
3560 private:
3561 Handle<String> pattern_;
3562 Handle<String> flags_;
3563};
3564
3565
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003566class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003567 public:
3568 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3569 : shared_info_(shared), pretenure_(pretenure) {
3570 set_representation(Representation::Tagged());
3571 }
3572
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003573 virtual Representation RequiredInputRepresentation(int index) const {
3574 return Representation::None();
3575 }
3576
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003577 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function_literal")
3578
3579 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3580 bool pretenure() const { return pretenure_; }
3581
3582 private:
3583 Handle<SharedFunctionInfo> shared_info_;
3584 bool pretenure_;
3585};
3586
3587
3588class HTypeof: public HUnaryOperation {
3589 public:
3590 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
3591 set_representation(Representation::Tagged());
3592 }
3593
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003594 virtual Representation RequiredInputRepresentation(int index) const {
3595 return Representation::Tagged();
3596 }
3597
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003598 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
3599};
3600
3601
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003602class HToFastProperties: public HUnaryOperation {
3603 public:
3604 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
3605 // This instruction is not marked as having side effects, but
3606 // changes the map of the input operand. Use it only when creating
3607 // object literals.
3608 ASSERT(value->IsObjectLiteral());
3609 set_representation(Representation::Tagged());
3610 }
3611
3612 virtual Representation RequiredInputRepresentation(int index) const {
3613 return Representation::Tagged();
3614 }
3615
3616 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to_fast_properties")
3617};
3618
3619
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003620class HValueOf: public HUnaryOperation {
3621 public:
3622 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
3623 set_representation(Representation::Tagged());
3624 }
3625
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003626 virtual Representation RequiredInputRepresentation(int index) const {
3627 return Representation::Tagged();
3628 }
3629
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003630 DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value_of")
3631};
3632
3633
3634class HDeleteProperty: public HBinaryOperation {
3635 public:
3636 HDeleteProperty(HValue* obj, HValue* key)
3637 : HBinaryOperation(obj, key) {
3638 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003639 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003640 }
3641
3642 virtual Representation RequiredInputRepresentation(int index) const {
3643 return Representation::Tagged();
3644 }
3645
3646 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete_property")
3647
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003648 HValue* object() { return left(); }
3649 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003650};
3651
3652#undef DECLARE_INSTRUCTION
3653#undef DECLARE_CONCRETE_INSTRUCTION
3654
3655} } // namespace v8::internal
3656
3657#endif // V8_HYDROGEN_INSTRUCTIONS_H_