blob: a623775f2f8aa68dddb9fbd3c93703321bfde43f [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
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000277 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000278 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
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000291 // Make sure kind fits in int8.
292 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
293
294 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000295};
296
297
298class HType {
299 public:
300 HType() : type_(kUninitialized) { }
301
302 static HType Tagged() { return HType(kTagged); }
303 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
304 static HType TaggedNumber() { return HType(kTaggedNumber); }
305 static HType Smi() { return HType(kSmi); }
306 static HType HeapNumber() { return HType(kHeapNumber); }
307 static HType String() { return HType(kString); }
308 static HType Boolean() { return HType(kBoolean); }
309 static HType NonPrimitive() { return HType(kNonPrimitive); }
310 static HType JSArray() { return HType(kJSArray); }
311 static HType JSObject() { return HType(kJSObject); }
312 static HType Uninitialized() { return HType(kUninitialized); }
313
314 // Return the weakest (least precise) common type.
315 HType Combine(HType other) {
316 return HType(static_cast<Type>(type_ & other.type_));
317 }
318
319 bool Equals(const HType& other) {
320 return type_ == other.type_;
321 }
322
323 bool IsSubtypeOf(const HType& other) {
324 return Combine(other).Equals(other);
325 }
326
327 bool IsTagged() {
328 ASSERT(type_ != kUninitialized);
329 return ((type_ & kTagged) == kTagged);
330 }
331
332 bool IsTaggedPrimitive() {
333 ASSERT(type_ != kUninitialized);
334 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
335 }
336
337 bool IsTaggedNumber() {
338 ASSERT(type_ != kUninitialized);
339 return ((type_ & kTaggedNumber) == kTaggedNumber);
340 }
341
342 bool IsSmi() {
343 ASSERT(type_ != kUninitialized);
344 return ((type_ & kSmi) == kSmi);
345 }
346
347 bool IsHeapNumber() {
348 ASSERT(type_ != kUninitialized);
349 return ((type_ & kHeapNumber) == kHeapNumber);
350 }
351
352 bool IsString() {
353 ASSERT(type_ != kUninitialized);
354 return ((type_ & kString) == kString);
355 }
356
357 bool IsBoolean() {
358 ASSERT(type_ != kUninitialized);
359 return ((type_ & kBoolean) == kBoolean);
360 }
361
362 bool IsNonPrimitive() {
363 ASSERT(type_ != kUninitialized);
364 return ((type_ & kNonPrimitive) == kNonPrimitive);
365 }
366
367 bool IsJSArray() {
368 ASSERT(type_ != kUninitialized);
369 return ((type_ & kJSArray) == kJSArray);
370 }
371
372 bool IsJSObject() {
373 ASSERT(type_ != kUninitialized);
374 return ((type_ & kJSObject) == kJSObject);
375 }
376
377 bool IsUninitialized() {
378 return type_ == kUninitialized;
379 }
380
381 static HType TypeFromValue(Handle<Object> value);
382
383 const char* ToString();
384 const char* ToShortString();
385
386 private:
387 enum Type {
388 kTagged = 0x1, // 0000 0000 0000 0001
389 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
390 kTaggedNumber = 0xd, // 0000 0000 0000 1101
391 kSmi = 0x1d, // 0000 0000 0001 1101
392 kHeapNumber = 0x2d, // 0000 0000 0010 1101
393 kString = 0x45, // 0000 0000 0100 0101
394 kBoolean = 0x85, // 0000 0000 1000 0101
395 kNonPrimitive = 0x101, // 0000 0001 0000 0001
396 kJSObject = 0x301, // 0000 0011 0000 0001
397 kJSArray = 0x701, // 0000 0111 1000 0001
398 kUninitialized = 0x1fff // 0001 1111 1111 1111
399 };
400
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000401 // Make sure type fits in int16.
402 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
403
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000404 explicit HType(Type t) : type_(t) { }
405
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000406 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000407};
408
409
410class HValue: public ZoneObject {
411 public:
412 static const int kNoNumber = -1;
413
414 // There must be one corresponding kDepends flag for every kChanges flag and
415 // the order of the kChanges flags must be exactly the same as of the kDepends
416 // flags.
417 enum Flag {
418 // Declare global value numbering flags.
419 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
420 GVN_FLAG_LIST(DECLARE_DO)
421 #undef DECLARE_DO
422 kFlexibleRepresentation,
423 kUseGVN,
424 kCanOverflow,
425 kBailoutOnMinusZero,
426 kCanBeDivByZero,
427 kIsArguments,
428 kTruncatingToInt32,
429 kLastFlag = kTruncatingToInt32
430 };
431
432 STATIC_ASSERT(kLastFlag < kBitsPerInt);
433
434 static const int kChangesToDependsFlagsLeftShift = 1;
435
436 static int ChangesFlagsMask() {
437 int result = 0;
438 // Create changes mask.
439#define DECLARE_DO(type) result |= (1 << kChanges##type);
440 GVN_FLAG_LIST(DECLARE_DO)
441#undef DECLARE_DO
442 return result;
443 }
444
445 static int DependsFlagsMask() {
446 return ConvertChangesToDependsFlags(ChangesFlagsMask());
447 }
448
449 static int ConvertChangesToDependsFlags(int flags) {
450 return flags << kChangesToDependsFlagsLeftShift;
451 }
452
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000453 static HValue* cast(HValue* value) { return value; }
454
455 enum Opcode {
456 // Declare a unique enum value for each hydrogen instruction.
457 #define DECLARE_DO(type) k##type,
458 HYDROGEN_ALL_INSTRUCTION_LIST(DECLARE_DO)
459 #undef DECLARE_DO
460 kMaxInstructionClass
461 };
462
463 HValue() : block_(NULL),
464 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000465 type_(HType::Tagged()),
466 range_(NULL),
467 flags_(0) {}
468 virtual ~HValue() {}
469
470 HBasicBlock* block() const { return block_; }
471 void SetBlock(HBasicBlock* block);
472
473 int id() const { return id_; }
474 void set_id(int id) { id_ = id; }
475
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000476 SmallPointerList<HValue>* uses() { return &uses_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000477
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000478 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000479 Representation representation() const { return representation_; }
480 void ChangeRepresentation(Representation r) {
481 // Representation was already set and is allowed to be changed.
482 ASSERT(!representation_.IsNone());
483 ASSERT(!r.IsNone());
484 ASSERT(CheckFlag(kFlexibleRepresentation));
485 RepresentationChanged(r);
486 representation_ = r;
487 }
488
489 HType type() const { return type_; }
490 void set_type(HType type) {
491 ASSERT(uses_.length() == 0);
492 type_ = type;
493 }
494
495 // An operation needs to override this function iff:
496 // 1) it can produce an int32 output.
497 // 2) the true value of its output can potentially be minus zero.
498 // The implementation must set a flag so that it bails out in the case where
499 // it would otherwise output what should be a minus zero as an int32 zero.
500 // If the operation also exists in a form that takes int32 and outputs int32
501 // then the operation should return its input value so that we can propagate
502 // back. There are two operations that need to propagate back to more than
503 // one input. They are phi and binary add. They always return NULL and
504 // expect the caller to take care of things.
505 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
506 visited->Add(id());
507 return NULL;
508 }
509
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000510 bool IsDefinedAfter(HBasicBlock* other) const;
511
512 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000513 virtual int OperandCount() = 0;
514 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000515 void SetOperandAt(int index, HValue* value);
516
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000517 int LookupOperandIndex(int occurrence_index, HValue* op);
518 bool UsesMultipleTimes(HValue* op);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000519
520 void ReplaceAndDelete(HValue* other);
521 void ReplaceValue(HValue* other);
522 void ReplaceAtUse(HValue* use, HValue* other);
523 void ReplaceFirstAtUse(HValue* use, HValue* other, Representation r);
524 bool HasNoUses() const { return uses_.is_empty(); }
525 void ClearOperands();
526 void Delete();
527
528 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000529 void SetFlag(Flag f) { flags_ |= (1 << f); }
530 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
531 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
532
533 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
534 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
535 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000536
537 Range* range() const { return range_; }
538 bool HasRange() const { return range_ != NULL; }
539 void AddNewRange(Range* r);
540 void RemoveLastAddedRange();
541 void ComputeInitialRange();
542
543 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000544 virtual Representation RequiredInputRepresentation(int index) const = 0;
545
546 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000547 return representation();
548 }
549
550 // This gives the instruction an opportunity to replace itself with an
551 // instruction that does the same in some better way. To replace an
552 // instruction with a new one, first add the new instruction to the graph,
553 // then return it. Return NULL to have the instruction deleted.
554 virtual HValue* Canonicalize() { return this; }
555
556 // Declare virtual type testers.
557#define DECLARE_DO(type) virtual bool Is##type() const { return false; }
558 HYDROGEN_ALL_INSTRUCTION_LIST(DECLARE_DO)
559#undef DECLARE_DO
560
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000561 bool Equals(HValue* other);
562 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000563
564 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000565 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000566 void PrintNameTo(StringStream* stream);
567 static void PrintTypeTo(HType type, StringStream* stream);
568
569 virtual const char* Mnemonic() const = 0;
570 virtual Opcode opcode() const = 0;
571
572 // Updated the inferred type of this instruction and returns true if
573 // it has changed.
574 bool UpdateInferredType();
575
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000576 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000577
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000578#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000579 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000580#endif
581
582 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000583 // This function must be overridden for instructions with flag kUseGVN, to
584 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000585 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000586 UNREACHABLE();
587 return false;
588 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000589 virtual void RepresentationChanged(Representation to) { }
590 virtual Range* InferRange();
591 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000592 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000593 void clear_block() {
594 ASSERT(block_ != NULL);
595 block_ = NULL;
596 }
597
598 void set_representation(Representation r) {
599 // Representation is set-once.
600 ASSERT(representation_.IsNone() && !r.IsNone());
601 representation_ = r;
602 }
603
604 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000605 // A flag mask to mark an instruction as having arbitrary side effects.
606 static int AllSideEffects() {
607 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
608 }
609
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000610 void InternalReplaceAtUse(HValue* use, HValue* other);
611 void RegisterUse(int index, HValue* new_value);
612
613 HBasicBlock* block_;
614
615 // The id of this instruction in the hydrogen graph, assigned when first
616 // added to the graph. Reflects creation order.
617 int id_;
618
619 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000620 HType type_;
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000621 SmallPointerList<HValue> uses_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000622 Range* range_;
623 int flags_;
624
625 DISALLOW_COPY_AND_ASSIGN(HValue);
626};
627
628
629class HInstruction: public HValue {
630 public:
631 HInstruction* next() const { return next_; }
632 HInstruction* previous() const { return previous_; }
633
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000634 virtual void PrintTo(StringStream* stream);
635 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000636
637 bool IsLinked() const { return block() != NULL; }
638 void Unlink();
639 void InsertBefore(HInstruction* next);
640 void InsertAfter(HInstruction* previous);
641
642 int position() const { return position_; }
643 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
644 void set_position(int position) { position_ = position; }
645
646 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
647
648#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000649 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000650#endif
651
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000652 // Returns whether this is some kind of deoptimizing check
653 // instruction.
654 virtual bool IsCheckInstruction() const { return false; }
655
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000656 virtual bool IsCall() { return false; }
657
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000658 DECLARE_INSTRUCTION(Instruction)
659
660 protected:
661 HInstruction()
662 : next_(NULL),
663 previous_(NULL),
664 position_(RelocInfo::kNoPosition) {
665 SetFlag(kDependsOnOsrEntries);
666 }
667
668 virtual void DeleteFromGraph() { Unlink(); }
669
670 private:
671 void InitializeAsFirst(HBasicBlock* block) {
672 ASSERT(!IsLinked());
673 SetBlock(block);
674 }
675
676 HInstruction* next_;
677 HInstruction* previous_;
678 int position_;
679
680 friend class HBasicBlock;
681};
682
683
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000684class HControlInstruction: public HInstruction {
685 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000686 HControlInstruction(HBasicBlock* first, HBasicBlock* second)
687 : first_successor_(first), second_successor_(second) {
688 }
689
690 HBasicBlock* FirstSuccessor() const { return first_successor_; }
691 HBasicBlock* SecondSuccessor() const { return second_successor_; }
692
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000693 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000694
695 DECLARE_INSTRUCTION(ControlInstruction)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000696
697 private:
698 HBasicBlock* first_successor_;
699 HBasicBlock* second_successor_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000700};
701
702
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000703template<int NumElements>
704class HOperandContainer {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000705 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000706 HOperandContainer() : elems_() { }
707
708 int length() { return NumElements; }
709 HValue*& operator[](int i) {
710 ASSERT(i < length());
711 return elems_[i];
712 }
713
714 private:
715 HValue* elems_[NumElements];
716};
717
718
719template<>
720class HOperandContainer<0> {
721 public:
722 int length() { return 0; }
723 HValue*& operator[](int i) {
724 UNREACHABLE();
725 static HValue* t = 0;
726 return t;
727 }
728};
729
730
731template<int V>
732class HTemplateInstruction : public HInstruction {
733 public:
734 int OperandCount() { return V; }
735 HValue* OperandAt(int i) { return inputs_[i]; }
736
737 protected:
738 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
739
740 private:
741 HOperandContainer<V> inputs_;
742};
743
744
745template<int V>
746class HTemplateControlInstruction : public HControlInstruction {
747 public:
748 HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second)
749 : HControlInstruction(first, second) { }
750 int OperandCount() { return V; }
751 HValue* OperandAt(int i) { return inputs_[i]; }
752
753 protected:
754 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
755
756 private:
757 HOperandContainer<V> inputs_;
758};
759
760
761class HBlockEntry: public HTemplateInstruction<0> {
762 public:
763 virtual Representation RequiredInputRepresentation(int index) const {
764 return Representation::None();
765 }
766
767 DECLARE_CONCRETE_INSTRUCTION(BlockEntry, "block_entry")
768};
769
770
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000771class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000772 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000773 explicit HDeoptimize(int environment_length)
774 : HControlInstruction(NULL, NULL),
775 values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000776
777 virtual Representation RequiredInputRepresentation(int index) const {
778 return Representation::None();
779 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000780
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000781 virtual int OperandCount() { return values_.length(); }
782 virtual HValue* OperandAt(int index) { return values_[index]; }
783
784 void AddEnvironmentValue(HValue* value) {
785 values_.Add(NULL);
786 SetOperandAt(values_.length() - 1, value);
787 }
788
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000789 DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000790
791 protected:
792 virtual void InternalSetOperandAt(int index, HValue* value) {
793 values_[index] = value;
794 }
795
796 private:
797 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000798};
799
800
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000801class HGoto: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000802 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000803 explicit HGoto(HBasicBlock* target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000804 : HTemplateControlInstruction<0>(target, NULL),
805 include_stack_check_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000806
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000807 void set_include_stack_check(bool include_stack_check) {
808 include_stack_check_ = include_stack_check;
809 }
810 bool include_stack_check() const { return include_stack_check_; }
811
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000812 virtual Representation RequiredInputRepresentation(int index) const {
813 return Representation::None();
814 }
815
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000816 DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
817
818 private:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000819 bool include_stack_check_;
820};
821
822
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000823class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000824 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000825 explicit HUnaryControlInstruction(HValue* value,
826 HBasicBlock* true_target,
827 HBasicBlock* false_target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000828 : HTemplateControlInstruction<1>(true_target, false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000829 SetOperandAt(0, value);
830 }
831
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000832 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000833
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000834 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000835
836 DECLARE_INSTRUCTION(UnaryControlInstruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000837};
838
839
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000840class HTest: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000841 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000842 HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
843 : HUnaryControlInstruction(value, true_target, false_target) {
844 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000845 }
846
847 virtual Representation RequiredInputRepresentation(int index) const {
848 return Representation::None();
849 }
850
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000851 DECLARE_CONCRETE_INSTRUCTION(Test, "test")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000852};
853
854
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000855class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000856 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000857 HCompareMap(HValue* value,
858 Handle<Map> map,
859 HBasicBlock* true_target,
860 HBasicBlock* false_target)
861 : HUnaryControlInstruction(value, true_target, false_target),
862 map_(map) {
863 ASSERT(true_target != NULL);
864 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000865 ASSERT(!map.is_null());
866 }
867
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000868 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000869
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000870 Handle<Map> map() const { return map_; }
871
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000872 virtual Representation RequiredInputRepresentation(int index) const {
873 return Representation::Tagged();
874 }
875
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000876 DECLARE_CONCRETE_INSTRUCTION(CompareMap, "compare_map")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000877
878 private:
879 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000880};
881
882
883class HReturn: public HUnaryControlInstruction {
884 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000885 explicit HReturn(HValue* value)
886 : HUnaryControlInstruction(value, NULL, NULL) {
887 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000888
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000889 virtual Representation RequiredInputRepresentation(int index) const {
890 return Representation::Tagged();
891 }
892
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000893 DECLARE_CONCRETE_INSTRUCTION(Return, "return")
894};
895
896
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000897class HAbnormalExit: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000898 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000899 HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
900
901 virtual Representation RequiredInputRepresentation(int index) const {
902 return Representation::None();
903 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000904
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000905 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit, "abnormal_exit")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000906};
907
908
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000909class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000910 public:
911 explicit HUnaryOperation(HValue* value) {
912 SetOperandAt(0, value);
913 }
914
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000915 HValue* value() { return OperandAt(0); }
916 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000917
918 DECLARE_INSTRUCTION(UnaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000919};
920
921
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000922class HThrow: public HUnaryOperation {
923 public:
924 explicit HThrow(HValue* value) : HUnaryOperation(value) {
925 SetAllSideEffects();
926 }
927
928 virtual Representation RequiredInputRepresentation(int index) const {
929 return Representation::Tagged();
930 }
931
932 DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
933};
934
935
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000936class HChange: public HUnaryOperation {
937 public:
938 HChange(HValue* value,
939 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000940 Representation to,
941 bool is_truncating)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000942 : HUnaryOperation(value), from_(from) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000943 ASSERT(!from.IsNone() && !to.IsNone());
944 ASSERT(!from.Equals(to));
945 set_representation(to);
946 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000947 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000948 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
949 value->range()->IsInSmiRange()) {
950 set_type(HType::Smi());
951 }
952 }
953
954 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
955
956 Representation from() const { return from_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000957 Representation to() const { return representation(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000958 virtual Representation RequiredInputRepresentation(int index) const {
959 return from_;
960 }
961
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000962 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000963
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000964 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000965
966 DECLARE_CONCRETE_INSTRUCTION(Change,
967 CanTruncateToInt32() ? "truncate" : "change")
968
969 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000970 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000971 if (!other->IsChange()) return false;
972 HChange* change = HChange::cast(other);
973 return value() == change->value()
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000974 && to().Equals(change->to());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000975 }
976
977 private:
978 Representation from_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000979};
980
981
982class HSimulate: public HInstruction {
983 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000984 HSimulate(int ast_id, int pop_count)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000985 : ast_id_(ast_id),
986 pop_count_(pop_count),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000987 values_(2),
988 assigned_indexes_(2) {}
989 virtual ~HSimulate() {}
990
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000991 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000992
993 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
994 int ast_id() const { return ast_id_; }
995 void set_ast_id(int id) {
996 ASSERT(!HasAstId());
997 ast_id_ = id;
998 }
999
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001000 int pop_count() const { return pop_count_; }
1001 const ZoneList<HValue*>* values() const { return &values_; }
1002 int GetAssignedIndexAt(int index) const {
1003 ASSERT(HasAssignedIndexAt(index));
1004 return assigned_indexes_[index];
1005 }
1006 bool HasAssignedIndexAt(int index) const {
1007 return assigned_indexes_[index] != kNoIndex;
1008 }
1009 void AddAssignedValue(int index, HValue* value) {
1010 AddValue(index, value);
1011 }
1012 void AddPushedValue(HValue* value) {
1013 AddValue(kNoIndex, value);
1014 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001015 virtual int OperandCount() { return values_.length(); }
1016 virtual HValue* OperandAt(int index) { return values_[index]; }
1017
1018 virtual Representation RequiredInputRepresentation(int index) const {
1019 return Representation::None();
1020 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001021
1022 DECLARE_CONCRETE_INSTRUCTION(Simulate, "simulate")
1023
1024#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001025 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001026#endif
1027
1028 protected:
1029 virtual void InternalSetOperandAt(int index, HValue* value) {
1030 values_[index] = value;
1031 }
1032
1033 private:
1034 static const int kNoIndex = -1;
1035 void AddValue(int index, HValue* value) {
1036 assigned_indexes_.Add(index);
1037 // Resize the list of pushed values.
1038 values_.Add(NULL);
1039 // Set the operand through the base method in HValue to make sure that the
1040 // use lists are correctly updated.
1041 SetOperandAt(values_.length() - 1, value);
1042 }
1043 int ast_id_;
1044 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001045 ZoneList<HValue*> values_;
1046 ZoneList<int> assigned_indexes_;
1047};
1048
1049
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001050class HStackCheck: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001051 public:
1052 HStackCheck() { }
1053
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001054 virtual Representation RequiredInputRepresentation(int index) const {
1055 return Representation::None();
1056 }
1057
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001058 DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack_check")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001059};
1060
1061
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001062class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001063 public:
1064 HEnterInlined(Handle<JSFunction> closure, FunctionLiteral* function)
1065 : closure_(closure), function_(function) {
1066 }
1067
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001068 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001069
1070 Handle<JSFunction> closure() const { return closure_; }
1071 FunctionLiteral* function() const { return function_; }
1072
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001073 virtual Representation RequiredInputRepresentation(int index) const {
1074 return Representation::None();
1075 }
1076
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001077 DECLARE_CONCRETE_INSTRUCTION(EnterInlined, "enter_inlined")
1078
1079 private:
1080 Handle<JSFunction> closure_;
1081 FunctionLiteral* function_;
1082};
1083
1084
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001085class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001086 public:
1087 HLeaveInlined() {}
1088
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001089 virtual Representation RequiredInputRepresentation(int index) const {
1090 return Representation::None();
1091 }
1092
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001093 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined, "leave_inlined")
1094};
1095
1096
1097class HPushArgument: public HUnaryOperation {
1098 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001099 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1100 set_representation(Representation::Tagged());
1101 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001102
1103 virtual Representation RequiredInputRepresentation(int index) const {
1104 return Representation::Tagged();
1105 }
1106
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001107 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001108
1109 DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push_argument")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001110};
1111
1112
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001113class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001114 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001115 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001116 set_representation(Representation::Tagged());
1117 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001118 }
1119
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001120 virtual Representation RequiredInputRepresentation(int index) const {
1121 return Representation::None();
1122 }
1123
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001124 DECLARE_CONCRETE_INSTRUCTION(Context, "context");
1125
1126 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001127 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001128};
1129
1130
1131class HOuterContext: public HUnaryOperation {
1132 public:
1133 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1134 set_representation(Representation::Tagged());
1135 SetFlag(kUseGVN);
1136 }
1137
1138 DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer_context");
1139
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001140 virtual Representation RequiredInputRepresentation(int index) const {
1141 return Representation::Tagged();
1142 }
1143
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001144 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001145 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001146};
1147
1148
1149class HGlobalObject: public HUnaryOperation {
1150 public:
1151 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1152 set_representation(Representation::Tagged());
1153 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001154 }
1155
1156 DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global_object")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001157
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001158 virtual Representation RequiredInputRepresentation(int index) const {
1159 return Representation::Tagged();
1160 }
1161
ager@chromium.org378b34e2011-01-28 08:04:38 +00001162 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001163 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001164};
1165
1166
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001167class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001168 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001169 explicit HGlobalReceiver(HValue* global_object)
1170 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001171 set_representation(Representation::Tagged());
1172 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001173 }
1174
1175 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global_receiver")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001176
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001177 virtual Representation RequiredInputRepresentation(int index) const {
1178 return Representation::Tagged();
1179 }
1180
ager@chromium.org378b34e2011-01-28 08:04:38 +00001181 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001182 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001183};
1184
1185
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001186template <int V>
1187class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001188 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001189 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001190 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1191 this->set_representation(Representation::Tagged());
1192 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001193 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001194
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001195 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001196
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001197 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001198
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001199 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001200
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001201 private:
1202 int argument_count_;
1203};
1204
1205
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001206class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001207 public:
1208 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001209 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001210 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001211 }
1212
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001213 virtual Representation RequiredInputRepresentation(int index) const {
1214 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001215 }
1216
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001217 virtual void PrintDataTo(StringStream* stream);
1218
1219 HValue* value() { return OperandAt(0); }
1220
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001221 DECLARE_INSTRUCTION(UnaryCall)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001222};
1223
1224
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001225class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001226 public:
1227 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001228 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001229 SetOperandAt(0, first);
1230 SetOperandAt(1, second);
1231 }
1232
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001233 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001234
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001235 virtual Representation RequiredInputRepresentation(int index) const {
1236 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001237 }
1238
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001239 HValue* first() { return OperandAt(0); }
1240 HValue* second() { return OperandAt(1); }
1241
1242 DECLARE_INSTRUCTION(BinaryCall)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001243};
1244
1245
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001246class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001247 public:
1248 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001249 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001250
1251 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001252
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001253 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001254 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001255 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001256 }
1257
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001258 virtual void PrintDataTo(StringStream* stream);
1259
1260 virtual Representation RequiredInputRepresentation(int index) const {
1261 return Representation::None();
1262 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001263
1264 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call_constant_function")
1265
1266 private:
1267 Handle<JSFunction> function_;
1268};
1269
1270
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001271class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001272 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001273 HCallKeyed(HValue* context, HValue* key, int argument_count)
1274 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001275 }
1276
1277 virtual Representation RequiredInputRepresentation(int index) const {
1278 return Representation::Tagged();
1279 }
1280
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001281 HValue* context() { return first(); }
1282 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001283
1284 DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call_keyed")
1285};
1286
1287
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001288class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001289 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001290 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1291 : HUnaryCall(context, argument_count), name_(name) {
1292 }
1293
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001294 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001295
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001296 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001297 Handle<String> name() const { return name_; }
1298
1299 DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call_named")
1300
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001301 virtual Representation RequiredInputRepresentation(int index) const {
1302 return Representation::Tagged();
1303 }
1304
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001305 private:
1306 Handle<String> name_;
1307};
1308
1309
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001310class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001311 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001312 HCallFunction(HValue* context, int argument_count)
1313 : HUnaryCall(context, argument_count) {
1314 }
1315
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001316 HValue* context() { return value(); }
1317
1318 virtual Representation RequiredInputRepresentation(int index) const {
1319 return Representation::Tagged();
1320 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001321
1322 DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call_function")
1323};
1324
1325
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001326class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001327 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001328 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1329 : HUnaryCall(context, argument_count), name_(name) {
1330 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001331
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001332 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001333
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001334 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001335 Handle<String> name() const { return name_; }
1336
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001337 virtual Representation RequiredInputRepresentation(int index) const {
1338 return Representation::Tagged();
1339 }
1340
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001341 DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call_global")
1342
1343 private:
1344 Handle<String> name_;
1345};
1346
1347
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001348class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001349 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001350 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001351 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001352
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001353 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001354
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001355 Handle<JSFunction> target() const { return target_; }
1356
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001357 virtual Representation RequiredInputRepresentation(int index) const {
1358 return Representation::None();
1359 }
1360
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001361 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call_known_global")
1362
1363 private:
1364 Handle<JSFunction> target_;
1365};
1366
1367
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001368class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001369 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001370 HCallNew(HValue* context, HValue* constructor, int argument_count)
1371 : HBinaryCall(context, constructor, argument_count) {
1372 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001373
1374 virtual Representation RequiredInputRepresentation(int index) const {
1375 return Representation::Tagged();
1376 }
1377
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001378 HValue* context() { return first(); }
1379 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001380
1381 DECLARE_CONCRETE_INSTRUCTION(CallNew, "call_new")
1382};
1383
1384
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001385class HCallRuntime: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001386 public:
1387 HCallRuntime(Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001388 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001389 int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001390 : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
1391 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001392
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001393 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001394 Handle<String> name() const { return name_; }
1395
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001396 virtual Representation RequiredInputRepresentation(int index) const {
1397 return Representation::None();
1398 }
1399
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001400 DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call_runtime")
1401
1402 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001403 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001404 Handle<String> name_;
1405};
1406
1407
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001408class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001409 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001410 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001411 // The length of an array is stored as a tagged value in the array
1412 // object. It is guaranteed to be 32 bit integer, but it can be
1413 // represented as either a smi or heap number.
1414 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001415 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001416 SetFlag(kDependsOnArrayLengths);
1417 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001418 }
1419
1420 virtual Representation RequiredInputRepresentation(int index) const {
1421 return Representation::Tagged();
1422 }
1423
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001424 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js_array_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001425
1426 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001427 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001428};
1429
1430
1431class HFixedArrayLength: public HUnaryOperation {
1432 public:
1433 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1434 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001435 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001436 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001437 }
1438
1439 virtual Representation RequiredInputRepresentation(int index) const {
1440 return Representation::Tagged();
1441 }
1442
1443 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed_array_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001444
1445 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001446 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001447};
1448
1449
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001450class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001451 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001452 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001453 set_representation(Representation::Integer32());
1454 // The result of this instruction is idempotent as long as its inputs don't
1455 // change. The length of a pixel array cannot change once set, so it's not
1456 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1457 SetFlag(kUseGVN);
1458 }
1459
1460 virtual Representation RequiredInputRepresentation(int index) const {
1461 return Representation::Tagged();
1462 }
1463
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001464 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength, "external_array_length")
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001465
1466 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001467 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001468};
1469
1470
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001471class HBitNot: public HUnaryOperation {
1472 public:
1473 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1474 set_representation(Representation::Integer32());
1475 SetFlag(kUseGVN);
1476 SetFlag(kTruncatingToInt32);
1477 }
1478
1479 virtual Representation RequiredInputRepresentation(int index) const {
1480 return Representation::Integer32();
1481 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001482 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001483
1484 DECLARE_CONCRETE_INSTRUCTION(BitNot, "bit_not")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001485
1486 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001487 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001488};
1489
1490
1491class HUnaryMathOperation: public HUnaryOperation {
1492 public:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001493 HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001494 : HUnaryOperation(value), op_(op) {
1495 switch (op) {
1496 case kMathFloor:
1497 case kMathRound:
1498 case kMathCeil:
1499 set_representation(Representation::Integer32());
1500 break;
1501 case kMathAbs:
1502 set_representation(Representation::Tagged());
1503 SetFlag(kFlexibleRepresentation);
1504 break;
1505 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001506 case kMathPowHalf:
1507 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001508 case kMathSin:
1509 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001510 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001511 break;
1512 default:
1513 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001514 }
1515 SetFlag(kUseGVN);
1516 }
1517
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001518 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001519
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001520 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001521
1522 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1523
1524 virtual Representation RequiredInputRepresentation(int index) const {
1525 switch (op_) {
1526 case kMathFloor:
1527 case kMathRound:
1528 case kMathCeil:
1529 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001530 case kMathPowHalf:
1531 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001532 case kMathSin:
1533 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001534 return Representation::Double();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001535 case kMathAbs:
1536 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001537 default:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001538 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001539 return Representation::None();
1540 }
1541 }
1542
1543 virtual HValue* Canonicalize() {
1544 // If the input is integer32 then we replace the floor instruction
1545 // with its inputs. This happens before the representation changes are
1546 // introduced.
1547 if (op() == kMathFloor) {
1548 if (value()->representation().IsInteger32()) return value();
1549 }
1550 return this;
1551 }
1552
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001553 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001554 const char* OpName() const;
1555
1556 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary_math_operation")
1557
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001558 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001559 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001560 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1561 return op_ == b->op();
1562 }
1563
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001564 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001565 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001566};
1567
1568
1569class HLoadElements: public HUnaryOperation {
1570 public:
1571 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1572 set_representation(Representation::Tagged());
1573 SetFlag(kUseGVN);
1574 SetFlag(kDependsOnMaps);
1575 }
1576
1577 virtual Representation RequiredInputRepresentation(int index) const {
1578 return Representation::Tagged();
1579 }
1580
1581 DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001582
1583 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001584 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001585};
1586
1587
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001588class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001589 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001590 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001591 : HUnaryOperation(value) {
1592 set_representation(Representation::External());
1593 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001594 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001595 // change once set, so it's no necessary to introduce any additional
1596 // dependencies on top of the inputs.
1597 SetFlag(kUseGVN);
1598 }
1599
1600 virtual Representation RequiredInputRepresentation(int index) const {
1601 return Representation::Tagged();
1602 }
1603
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001604 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer,
1605 "load-external-array-pointer")
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001606
1607 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001608 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001609};
1610
1611
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001612class HCheckMap: public HUnaryOperation {
1613 public:
1614 HCheckMap(HValue* value, Handle<Map> map)
1615 : HUnaryOperation(value), map_(map) {
1616 set_representation(Representation::Tagged());
1617 SetFlag(kUseGVN);
1618 SetFlag(kDependsOnMaps);
1619 }
1620
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001621 virtual bool IsCheckInstruction() const { return true; }
1622
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001623 virtual Representation RequiredInputRepresentation(int index) const {
1624 return Representation::Tagged();
1625 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001626 virtual void PrintDataTo(StringStream* stream);
1627 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001628
1629#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001630 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001631#endif
1632
1633 Handle<Map> map() const { return map_; }
1634
1635 DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check_map")
1636
1637 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001638 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001639 HCheckMap* b = HCheckMap::cast(other);
1640 return map_.is_identical_to(b->map());
1641 }
1642
1643 private:
1644 Handle<Map> map_;
1645};
1646
1647
1648class HCheckFunction: public HUnaryOperation {
1649 public:
1650 HCheckFunction(HValue* value, Handle<JSFunction> function)
1651 : HUnaryOperation(value), target_(function) {
1652 set_representation(Representation::Tagged());
1653 SetFlag(kUseGVN);
1654 }
1655
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001656 virtual bool IsCheckInstruction() const { return true; }
1657
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001658 virtual Representation RequiredInputRepresentation(int index) const {
1659 return Representation::Tagged();
1660 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001661 virtual void PrintDataTo(StringStream* stream);
1662 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001663
1664#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001665 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001666#endif
1667
1668 Handle<JSFunction> target() const { return target_; }
1669
1670 DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check_function")
1671
1672 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001673 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001674 HCheckFunction* b = HCheckFunction::cast(other);
1675 return target_.is_identical_to(b->target());
1676 }
1677
1678 private:
1679 Handle<JSFunction> target_;
1680};
1681
1682
1683class HCheckInstanceType: public HUnaryOperation {
1684 public:
1685 // Check that the instance type is in the range [first, last] where
1686 // both first and last are included.
1687 HCheckInstanceType(HValue* value, InstanceType first, InstanceType last)
1688 : HUnaryOperation(value), first_(first), last_(last) {
1689 ASSERT(first <= last);
1690 set_representation(Representation::Tagged());
1691 SetFlag(kUseGVN);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001692 if ((FIRST_STRING_TYPE < first && last <= LAST_STRING_TYPE) ||
1693 (FIRST_STRING_TYPE <= first && last < LAST_STRING_TYPE)) {
1694 // A particular string instance type can change because of GC or
1695 // externalization, but the value still remains a string.
1696 SetFlag(kDependsOnMaps);
1697 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001698 }
1699
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001700 virtual bool IsCheckInstruction() const { return true; }
1701
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001702 virtual Representation RequiredInputRepresentation(int index) const {
1703 return Representation::Tagged();
1704 }
1705
1706#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001707 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001708#endif
1709
1710 static HCheckInstanceType* NewIsJSObjectOrJSFunction(HValue* value);
1711
1712 InstanceType first() const { return first_; }
1713 InstanceType last() const { return last_; }
1714
1715 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check_instance_type")
1716
1717 protected:
1718 // TODO(ager): It could be nice to allow the ommision of instance
1719 // type checks if we have already performed an instance type check
1720 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001721 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001722 HCheckInstanceType* b = HCheckInstanceType::cast(other);
1723 return (first_ == b->first()) && (last_ == b->last());
1724 }
1725
1726 private:
1727 InstanceType first_;
1728 InstanceType last_;
1729};
1730
1731
1732class HCheckNonSmi: public HUnaryOperation {
1733 public:
1734 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
1735 set_representation(Representation::Tagged());
1736 SetFlag(kUseGVN);
1737 }
1738
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001739 virtual bool IsCheckInstruction() const { return true; }
1740
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001741 virtual Representation RequiredInputRepresentation(int index) const {
1742 return Representation::Tagged();
1743 }
1744
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001745 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001746
1747#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001748 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001749#endif
1750
1751 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check_non_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001752
1753 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001754 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001755};
1756
1757
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001758class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001759 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001760 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
1761 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001762 SetFlag(kUseGVN);
1763 SetFlag(kDependsOnMaps);
1764 }
1765
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001766 virtual bool IsCheckInstruction() const { return true; }
1767
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001768#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001769 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001770#endif
1771
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001772 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001773 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001774
1775 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check_prototype_maps")
1776
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001777 virtual Representation RequiredInputRepresentation(int index) const {
1778 return Representation::None();
1779 }
1780
1781 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001782 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001783 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
1784 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
1785 return hash;
1786 }
1787
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001788 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001789 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001790 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001791 return prototype_.is_identical_to(b->prototype()) &&
1792 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001793 }
1794
1795 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001796 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001797 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001798};
1799
1800
1801class HCheckSmi: public HUnaryOperation {
1802 public:
1803 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
1804 set_representation(Representation::Tagged());
1805 SetFlag(kUseGVN);
1806 }
1807
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001808 virtual bool IsCheckInstruction() const { return true; }
1809
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001810 virtual Representation RequiredInputRepresentation(int index) const {
1811 return Representation::Tagged();
1812 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001813 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001814
1815#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001816 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001817#endif
1818
1819 DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001820
1821 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001822 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001823};
1824
1825
1826class HPhi: public HValue {
1827 public:
1828 explicit HPhi(int merged_index)
1829 : inputs_(2),
1830 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001831 phi_id_(-1),
1832 is_live_(false) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001833 for (int i = 0; i < Representation::kNumRepresentations; i++) {
1834 non_phi_uses_[i] = 0;
1835 indirect_uses_[i] = 0;
1836 }
1837 ASSERT(merged_index >= 0);
1838 set_representation(Representation::Tagged());
1839 SetFlag(kFlexibleRepresentation);
1840 }
1841
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001842 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001843 bool double_occurred = false;
1844 bool int32_occurred = false;
1845 for (int i = 0; i < OperandCount(); ++i) {
1846 HValue* value = OperandAt(i);
1847 if (value->representation().IsDouble()) double_occurred = true;
1848 if (value->representation().IsInteger32()) int32_occurred = true;
1849 if (value->representation().IsTagged()) return Representation::Tagged();
1850 }
1851
1852 if (double_occurred) return Representation::Double();
1853 if (int32_occurred) return Representation::Integer32();
1854 return Representation::None();
1855 }
1856
1857 virtual Range* InferRange();
1858 virtual Representation RequiredInputRepresentation(int index) const {
1859 return representation();
1860 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001861 virtual HType CalculateInferredType();
1862 virtual int OperandCount() { return inputs_.length(); }
1863 virtual HValue* OperandAt(int index) { return inputs_[index]; }
1864 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001865 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001866 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001867
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00001868 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001869
1870 int merged_index() const { return merged_index_; }
1871
1872 virtual const char* Mnemonic() const { return "phi"; }
1873
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001874 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001875
1876#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001877 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001878#endif
1879
1880 DECLARE_INSTRUCTION(Phi)
1881
1882 void InitRealUses(int id);
1883 void AddNonPhiUsesFrom(HPhi* other);
1884 void AddIndirectUsesTo(int* use_count);
1885
1886 int tagged_non_phi_uses() const {
1887 return non_phi_uses_[Representation::kTagged];
1888 }
1889 int int32_non_phi_uses() const {
1890 return non_phi_uses_[Representation::kInteger32];
1891 }
1892 int double_non_phi_uses() const {
1893 return non_phi_uses_[Representation::kDouble];
1894 }
1895 int tagged_indirect_uses() const {
1896 return indirect_uses_[Representation::kTagged];
1897 }
1898 int int32_indirect_uses() const {
1899 return indirect_uses_[Representation::kInteger32];
1900 }
1901 int double_indirect_uses() const {
1902 return indirect_uses_[Representation::kDouble];
1903 }
1904 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001905 bool is_live() { return is_live_; }
1906 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001907
1908 protected:
1909 virtual void DeleteFromGraph();
1910 virtual void InternalSetOperandAt(int index, HValue* value) {
1911 inputs_[index] = value;
1912 }
1913
1914 private:
1915 ZoneList<HValue*> inputs_;
1916 int merged_index_;
1917
1918 int non_phi_uses_[Representation::kNumRepresentations];
1919 int indirect_uses_[Representation::kNumRepresentations];
1920 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001921 bool is_live_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001922};
1923
1924
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001925class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001926 public:
1927 HArgumentsObject() {
1928 set_representation(Representation::Tagged());
1929 SetFlag(kIsArguments);
1930 }
1931
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001932 virtual Representation RequiredInputRepresentation(int index) const {
1933 return Representation::None();
1934 }
1935
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001936 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject, "arguments-object")
1937};
1938
1939
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001940class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001941 public:
1942 HConstant(Handle<Object> handle, Representation r);
1943
1944 Handle<Object> handle() const { return handle_; }
1945
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001946 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001947
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001948 virtual Representation RequiredInputRepresentation(int index) const {
1949 return Representation::None();
1950 }
1951
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001952 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001953 virtual void PrintDataTo(StringStream* stream);
1954 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001955 bool IsInteger() const { return handle_->IsSmi(); }
1956 HConstant* CopyToRepresentation(Representation r) const;
1957 HConstant* CopyToTruncatedInt32() const;
1958 bool HasInteger32Value() const { return has_int32_value_; }
1959 int32_t Integer32Value() const {
1960 ASSERT(HasInteger32Value());
1961 return int32_value_;
1962 }
1963 bool HasDoubleValue() const { return has_double_value_; }
1964 double DoubleValue() const {
1965 ASSERT(HasDoubleValue());
1966 return double_value_;
1967 }
1968 bool HasStringValue() const { return handle_->IsString(); }
1969
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001970 bool ToBoolean() const;
1971
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001972 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001973 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001974 return reinterpret_cast<intptr_t>(*handle());
1975 }
1976
1977#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001978 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001979#endif
1980
1981 DECLARE_CONCRETE_INSTRUCTION(Constant, "constant")
1982
1983 protected:
1984 virtual Range* InferRange();
1985
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001986 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001987 HConstant* other_constant = HConstant::cast(other);
1988 return handle().is_identical_to(other_constant->handle());
1989 }
1990
1991 private:
1992 Handle<Object> handle_;
1993 HType constant_type_;
1994
1995 // The following two values represent the int32 and the double value of the
1996 // given constant if there is a lossless conversion between the constant
1997 // and the specific representation.
1998 bool has_int32_value_;
1999 int32_t int32_value_;
2000 bool has_double_value_;
2001 double double_value_;
2002};
2003
2004
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002005class HBinaryOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002006 public:
2007 HBinaryOperation(HValue* left, HValue* right) {
2008 ASSERT(left != NULL && right != NULL);
2009 SetOperandAt(0, left);
2010 SetOperandAt(1, right);
2011 }
2012
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002013 HValue* left() { return OperandAt(0); }
2014 HValue* right() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002015
2016 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2017 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002018 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002019 if (IsCommutative() && left()->IsConstant()) return right();
2020 return left();
2021 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002022 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002023 if (IsCommutative() && left()->IsConstant()) return left();
2024 return right();
2025 }
2026
2027 virtual bool IsCommutative() const { return false; }
2028
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002029 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002030
2031 DECLARE_INSTRUCTION(BinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002032};
2033
2034
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002035class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002036 public:
2037 HApplyArguments(HValue* function,
2038 HValue* receiver,
2039 HValue* length,
2040 HValue* elements) {
2041 set_representation(Representation::Tagged());
2042 SetOperandAt(0, function);
2043 SetOperandAt(1, receiver);
2044 SetOperandAt(2, length);
2045 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002046 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002047 }
2048
2049 virtual Representation RequiredInputRepresentation(int index) const {
2050 // The length is untagged, all other inputs are tagged.
2051 return (index == 2)
2052 ? Representation::Integer32()
2053 : Representation::Tagged();
2054 }
2055
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002056 HValue* function() { return OperandAt(0); }
2057 HValue* receiver() { return OperandAt(1); }
2058 HValue* length() { return OperandAt(2); }
2059 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002060
2061 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply_arguments")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002062};
2063
2064
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002065class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002066 public:
2067 HArgumentsElements() {
2068 // The value produced by this instruction is a pointer into the stack
2069 // that looks as if it was a smi because of alignment.
2070 set_representation(Representation::Tagged());
2071 SetFlag(kUseGVN);
2072 }
2073
2074 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments_elements")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002075
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002076 virtual Representation RequiredInputRepresentation(int index) const {
2077 return Representation::None();
2078 }
2079
ager@chromium.org378b34e2011-01-28 08:04:38 +00002080 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002081 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002082};
2083
2084
2085class HArgumentsLength: public HUnaryOperation {
2086 public:
2087 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2088 set_representation(Representation::Integer32());
2089 SetFlag(kUseGVN);
2090 }
2091
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002092 virtual Representation RequiredInputRepresentation(int index) const {
2093 return Representation::Tagged();
2094 }
2095
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002096 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002097
2098 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002099 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002100};
2101
2102
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002103class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002104 public:
2105 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2106 set_representation(Representation::Tagged());
2107 SetFlag(kUseGVN);
2108 SetOperandAt(0, arguments);
2109 SetOperandAt(1, length);
2110 SetOperandAt(2, index);
2111 }
2112
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002113 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002114
2115 virtual Representation RequiredInputRepresentation(int index) const {
2116 // The arguments elements is considered tagged.
2117 return index == 0
2118 ? Representation::Tagged()
2119 : Representation::Integer32();
2120 }
2121
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002122 HValue* arguments() { return OperandAt(0); }
2123 HValue* length() { return OperandAt(1); }
2124 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002125
2126 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access_arguments_at")
2127
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002128 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002129};
2130
2131
2132class HBoundsCheck: public HBinaryOperation {
2133 public:
2134 HBoundsCheck(HValue* index, HValue* length)
2135 : HBinaryOperation(index, length) {
2136 SetFlag(kUseGVN);
2137 }
2138
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002139 virtual bool IsCheckInstruction() const { return true; }
2140
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002141 virtual Representation RequiredInputRepresentation(int index) const {
2142 return Representation::Integer32();
2143 }
2144
2145#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002146 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002147#endif
2148
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002149 HValue* index() { return left(); }
2150 HValue* length() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002151
2152 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds_check")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002153
2154 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002155 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002156};
2157
2158
2159class HBitwiseBinaryOperation: public HBinaryOperation {
2160 public:
2161 HBitwiseBinaryOperation(HValue* left, HValue* right)
2162 : HBinaryOperation(left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002163 set_representation(Representation::Tagged());
2164 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002165 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002166 }
2167
2168 virtual Representation RequiredInputRepresentation(int index) const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002169 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002170 }
2171
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002172 virtual void RepresentationChanged(Representation to) {
2173 if (!to.IsTagged()) {
2174 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002175 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002176 SetFlag(kTruncatingToInt32);
2177 SetFlag(kUseGVN);
2178 }
2179 }
2180
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002181 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002182
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002183 DECLARE_INSTRUCTION(BitwiseBinaryOperation)
2184};
2185
2186
2187class HArithmeticBinaryOperation: public HBinaryOperation {
2188 public:
2189 HArithmeticBinaryOperation(HValue* left, HValue* right)
2190 : HBinaryOperation(left, right) {
2191 set_representation(Representation::Tagged());
2192 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002193 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002194 }
2195
2196 virtual void RepresentationChanged(Representation to) {
2197 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002198 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002199 SetFlag(kUseGVN);
2200 }
2201 }
2202
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002203 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002204 virtual Representation RequiredInputRepresentation(int index) const {
2205 return representation();
2206 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002207 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002208 if (left()->representation().Equals(right()->representation())) {
2209 return left()->representation();
2210 }
2211 return HValue::InferredRepresentation();
2212 }
2213
2214 DECLARE_INSTRUCTION(ArithmeticBinaryOperation)
2215};
2216
2217
2218class HCompare: public HBinaryOperation {
2219 public:
2220 HCompare(HValue* left, HValue* right, Token::Value token)
2221 : HBinaryOperation(left, right), token_(token) {
2222 ASSERT(Token::IsCompareOp(token));
2223 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002224 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002225 }
2226
2227 void SetInputRepresentation(Representation r);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002228
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002229 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002230 return !HasSideEffects() && (uses()->length() <= 1);
2231 }
2232
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002233 virtual Representation RequiredInputRepresentation(int index) const {
2234 return input_representation_;
2235 }
2236 Representation GetInputRepresentation() const {
2237 return input_representation_;
2238 }
2239 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002240 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002241
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002242 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002243
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002244 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002245 return HValue::Hashcode() * 7 + token_;
2246 }
2247
2248 DECLARE_CONCRETE_INSTRUCTION(Compare, "compare")
2249
2250 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002251 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002252 HCompare* comp = HCompare::cast(other);
2253 return token_ == comp->token();
2254 }
2255
2256 private:
2257 Representation input_representation_;
2258 Token::Value token_;
2259};
2260
2261
2262class HCompareJSObjectEq: public HBinaryOperation {
2263 public:
2264 HCompareJSObjectEq(HValue* left, HValue* right)
2265 : HBinaryOperation(left, right) {
2266 set_representation(Representation::Tagged());
2267 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002268 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002269 }
2270
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002271 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002272 return !HasSideEffects() && (uses()->length() <= 1);
2273 }
2274
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002275 virtual Representation RequiredInputRepresentation(int index) const {
2276 return Representation::Tagged();
2277 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002278 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002279
2280 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq, "compare-js-object-eq")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002281
2282 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002283 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002284};
2285
2286
2287class HUnaryPredicate: public HUnaryOperation {
2288 public:
2289 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2290 set_representation(Representation::Tagged());
2291 SetFlag(kUseGVN);
2292 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002293
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002294 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002295 return !HasSideEffects() && (uses()->length() <= 1);
2296 }
2297
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002298 virtual Representation RequiredInputRepresentation(int index) const {
2299 return Representation::Tagged();
2300 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002301 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002302};
2303
2304
2305class HIsNull: public HUnaryPredicate {
2306 public:
2307 HIsNull(HValue* value, bool is_strict)
2308 : HUnaryPredicate(value), is_strict_(is_strict) { }
2309
2310 bool is_strict() const { return is_strict_; }
2311
2312 DECLARE_CONCRETE_INSTRUCTION(IsNull, "is_null")
2313
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002314 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002315 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002316 HIsNull* b = HIsNull::cast(other);
2317 return is_strict_ == b->is_strict();
2318 }
2319
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002320 private:
2321 bool is_strict_;
2322};
2323
2324
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002325class HIsObject: public HUnaryPredicate {
2326 public:
2327 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2328
2329 DECLARE_CONCRETE_INSTRUCTION(IsObject, "is_object")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002330
2331 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002332 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002333};
2334
2335
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002336class HIsSmi: public HUnaryPredicate {
2337 public:
2338 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2339
2340 DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002341
2342 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002343 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002344};
2345
2346
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002347class HIsConstructCall: public HTemplateInstruction<0> {
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002348 public:
2349 HIsConstructCall() {
2350 set_representation(Representation::Tagged());
2351 SetFlag(kUseGVN);
2352 }
2353
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002354 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002355 return !HasSideEffects() && (uses()->length() <= 1);
2356 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002357
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002358 virtual Representation RequiredInputRepresentation(int index) const {
2359 return Representation::None();
2360 }
2361
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002362 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall, "is_construct_call")
2363
2364 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002365 virtual bool DataEquals(HValue* other) { return true; }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002366};
2367
2368
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002369class HHasInstanceType: public HUnaryPredicate {
2370 public:
2371 HHasInstanceType(HValue* value, InstanceType type)
2372 : HUnaryPredicate(value), from_(type), to_(type) { }
2373 HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2374 : HUnaryPredicate(value), from_(from), to_(to) {
2375 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2376 }
2377
2378 InstanceType from() { return from_; }
2379 InstanceType to() { return to_; }
2380
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002381 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002382
2383 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has_instance_type")
2384
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002385 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002386 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002387 HHasInstanceType* b = HHasInstanceType::cast(other);
2388 return (from_ == b->from()) && (to_ == b->to());
2389 }
2390
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002391 private:
2392 InstanceType from_;
2393 InstanceType to_; // Inclusive range, not all combinations work.
2394};
2395
2396
2397class HHasCachedArrayIndex: public HUnaryPredicate {
2398 public:
2399 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2400
2401 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has_cached_array_index")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002402
2403 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002404 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002405};
2406
2407
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002408class HGetCachedArrayIndex: public HUnaryPredicate {
2409 public:
2410 explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2411
2412 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get_cached_array_index")
2413
2414 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002415 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002416};
2417
2418
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002419class HClassOfTest: public HUnaryPredicate {
2420 public:
2421 HClassOfTest(HValue* value, Handle<String> class_name)
2422 : HUnaryPredicate(value), class_name_(class_name) { }
2423
2424 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class_of_test")
2425
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002426 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002427
2428 Handle<String> class_name() const { return class_name_; }
2429
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002430 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002431 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002432 HClassOfTest* b = HClassOfTest::cast(other);
2433 return class_name_.is_identical_to(b->class_name_);
2434 }
2435
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002436 private:
2437 Handle<String> class_name_;
2438};
2439
2440
2441class HTypeofIs: public HUnaryPredicate {
2442 public:
2443 HTypeofIs(HValue* value, Handle<String> type_literal)
2444 : HUnaryPredicate(value), type_literal_(type_literal) { }
2445
2446 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002447 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002448
2449 DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof_is")
2450
2451 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002452 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002453 HTypeofIs* b = HTypeofIs::cast(other);
2454 return type_literal_.is_identical_to(b->type_literal_);
2455 }
2456
2457 private:
2458 Handle<String> type_literal_;
2459};
2460
2461
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002462class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002463 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002464 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2465 SetOperandAt(0, context);
2466 SetOperandAt(1, left);
2467 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002468 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002469 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002470 }
2471
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002472 HValue* context() { return OperandAt(0); }
2473 HValue* left() { return OperandAt(1); }
2474 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002475
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002476 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002477 return !HasSideEffects() && (uses()->length() <= 1);
2478 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002479
2480 virtual Representation RequiredInputRepresentation(int index) const {
2481 return Representation::Tagged();
2482 }
2483
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002484 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002485
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002486 DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance_of")
2487};
2488
2489
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002490class HInstanceOfKnownGlobal: public HUnaryOperation {
2491 public:
2492 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2493 : HUnaryOperation(left), function_(right) {
2494 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002495 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002496 }
2497
2498 Handle<JSFunction> function() { return function_; }
2499
2500 virtual Representation RequiredInputRepresentation(int index) const {
2501 return Representation::Tagged();
2502 }
2503
2504 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
2505 "instance_of_known_global")
2506
2507 private:
2508 Handle<JSFunction> function_;
2509};
2510
2511
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002512class HPower: public HBinaryOperation {
2513 public:
2514 HPower(HValue* left, HValue* right)
2515 : HBinaryOperation(left, right) {
2516 set_representation(Representation::Double());
2517 SetFlag(kUseGVN);
2518 }
2519
2520 virtual Representation RequiredInputRepresentation(int index) const {
2521 return (index == 1) ? Representation::None() : Representation::Double();
2522 }
2523
2524 DECLARE_CONCRETE_INSTRUCTION(Power, "power")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002525
2526 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002527 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002528};
2529
2530
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002531class HAdd: public HArithmeticBinaryOperation {
2532 public:
2533 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2534 SetFlag(kCanOverflow);
2535 }
2536
2537 // Add is only commutative if two integer values are added and not if two
2538 // tagged values are added (because it might be a String concatenation).
2539 virtual bool IsCommutative() const {
2540 return !representation().IsTagged();
2541 }
2542
2543 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2544
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002545 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002546
2547 DECLARE_CONCRETE_INSTRUCTION(Add, "add")
2548
2549 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002550 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002551
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002552 virtual Range* InferRange();
2553};
2554
2555
2556class HSub: public HArithmeticBinaryOperation {
2557 public:
2558 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2559 SetFlag(kCanOverflow);
2560 }
2561
2562 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2563
2564 DECLARE_CONCRETE_INSTRUCTION(Sub, "sub")
2565
2566 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002567 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002568
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002569 virtual Range* InferRange();
2570};
2571
2572
2573class HMul: public HArithmeticBinaryOperation {
2574 public:
2575 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2576 SetFlag(kCanOverflow);
2577 }
2578
2579 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2580
2581 // Only commutative if it is certain that not two objects are multiplicated.
2582 virtual bool IsCommutative() const {
2583 return !representation().IsTagged();
2584 }
2585
2586 DECLARE_CONCRETE_INSTRUCTION(Mul, "mul")
2587
2588 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002589 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002590
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002591 virtual Range* InferRange();
2592};
2593
2594
2595class HMod: public HArithmeticBinaryOperation {
2596 public:
2597 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2598 SetFlag(kCanBeDivByZero);
2599 }
2600
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002601 bool HasPowerOf2Divisor() {
2602 if (right()->IsConstant() &&
2603 HConstant::cast(right())->HasInteger32Value()) {
2604 int32_t value = HConstant::cast(right())->Integer32Value();
2605 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2606 }
2607
2608 return false;
2609 }
2610
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002611 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2612
2613 DECLARE_CONCRETE_INSTRUCTION(Mod, "mod")
2614
2615 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002616 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002617
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002618 virtual Range* InferRange();
2619};
2620
2621
2622class HDiv: public HArithmeticBinaryOperation {
2623 public:
2624 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2625 SetFlag(kCanBeDivByZero);
2626 SetFlag(kCanOverflow);
2627 }
2628
2629 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2630
2631 DECLARE_CONCRETE_INSTRUCTION(Div, "div")
2632
2633 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002634 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002635
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002636 virtual Range* InferRange();
2637};
2638
2639
2640class HBitAnd: public HBitwiseBinaryOperation {
2641 public:
2642 HBitAnd(HValue* left, HValue* right)
2643 : HBitwiseBinaryOperation(left, right) { }
2644
2645 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002646 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002647
2648 DECLARE_CONCRETE_INSTRUCTION(BitAnd, "bit_and")
2649
2650 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002651 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002652
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002653 virtual Range* InferRange();
2654};
2655
2656
2657class HBitXor: public HBitwiseBinaryOperation {
2658 public:
2659 HBitXor(HValue* left, HValue* right)
2660 : HBitwiseBinaryOperation(left, right) { }
2661
2662 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002663 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002664
2665 DECLARE_CONCRETE_INSTRUCTION(BitXor, "bit_xor")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002666
2667 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002668 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002669};
2670
2671
2672class HBitOr: public HBitwiseBinaryOperation {
2673 public:
2674 HBitOr(HValue* left, HValue* right)
2675 : HBitwiseBinaryOperation(left, right) { }
2676
2677 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002678 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002679
2680 DECLARE_CONCRETE_INSTRUCTION(BitOr, "bit_or")
2681
2682 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002683 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002684
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002685 virtual Range* InferRange();
2686};
2687
2688
2689class HShl: public HBitwiseBinaryOperation {
2690 public:
2691 HShl(HValue* left, HValue* right)
2692 : HBitwiseBinaryOperation(left, right) { }
2693
2694 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002695 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002696
2697 DECLARE_CONCRETE_INSTRUCTION(Shl, "shl")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002698
2699 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002700 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002701};
2702
2703
2704class HShr: public HBitwiseBinaryOperation {
2705 public:
2706 HShr(HValue* left, HValue* right)
2707 : HBitwiseBinaryOperation(left, right) { }
2708
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002709 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002710
2711 DECLARE_CONCRETE_INSTRUCTION(Shr, "shr")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002712
2713 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002714 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002715};
2716
2717
2718class HSar: public HBitwiseBinaryOperation {
2719 public:
2720 HSar(HValue* left, HValue* right)
2721 : HBitwiseBinaryOperation(left, right) { }
2722
2723 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002724 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002725
2726 DECLARE_CONCRETE_INSTRUCTION(Sar, "sar")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002727
2728 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002729 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002730};
2731
2732
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002733class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002734 public:
2735 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
2736 SetFlag(kChangesOsrEntries);
2737 }
2738
2739 int ast_id() const { return ast_id_; }
2740
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002741 virtual Representation RequiredInputRepresentation(int index) const {
2742 return Representation::None();
2743 }
2744
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002745 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr_entry")
2746
2747 private:
2748 int ast_id_;
2749};
2750
2751
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002752class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002753 public:
2754 explicit HParameter(unsigned index) : index_(index) {
2755 set_representation(Representation::Tagged());
2756 }
2757
2758 unsigned index() const { return index_; }
2759
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002760 virtual void PrintDataTo(StringStream* stream);
2761
2762 virtual Representation RequiredInputRepresentation(int index) const {
2763 return Representation::None();
2764 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002765
2766 DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
2767
2768 private:
2769 unsigned index_;
2770};
2771
2772
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002773class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002774 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002775 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
2776 : HUnaryCall(context, argument_count),
2777 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002778 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002779 }
2780
2781 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002782
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002783 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002784
2785 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
2786 transcendental_type_ = transcendental_type;
2787 }
2788 TranscendentalCache::Type transcendental_type() {
2789 return transcendental_type_;
2790 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002791
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002792 virtual void PrintDataTo(StringStream* stream);
2793
2794 virtual Representation RequiredInputRepresentation(int index) const {
2795 return Representation::Tagged();
2796 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002797
2798 DECLARE_CONCRETE_INSTRUCTION(CallStub, "call_stub")
2799
2800 private:
2801 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002802 TranscendentalCache::Type transcendental_type_;
2803};
2804
2805
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002806class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002807 public:
2808 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
2809
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002810 virtual Representation RequiredInputRepresentation(int index) const {
2811 return Representation::None();
2812 }
2813
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002814 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown_osr_value")
2815};
2816
2817
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002818class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002819 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002820 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002821 : cell_(cell), check_hole_value_(check_hole_value) {
2822 set_representation(Representation::Tagged());
2823 SetFlag(kUseGVN);
2824 SetFlag(kDependsOnGlobalVars);
2825 }
2826
2827 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
2828 bool check_hole_value() const { return check_hole_value_; }
2829
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002830 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002831
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002832 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002833 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002834 return reinterpret_cast<intptr_t>(*cell_);
2835 }
2836
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002837 virtual Representation RequiredInputRepresentation(int index) const {
2838 return Representation::None();
2839 }
2840
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002841 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell, "load_global_cell")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002842
2843 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002844 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002845 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002846 return cell_.is_identical_to(b->cell());
2847 }
2848
2849 private:
2850 Handle<JSGlobalPropertyCell> cell_;
2851 bool check_hole_value_;
2852};
2853
2854
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002855class HLoadGlobalGeneric: public HBinaryOperation {
2856 public:
2857 HLoadGlobalGeneric(HValue* context,
2858 HValue* global_object,
2859 Handle<Object> name,
2860 bool for_typeof)
2861 : HBinaryOperation(context, global_object),
2862 name_(name),
2863 for_typeof_(for_typeof) {
2864 set_representation(Representation::Tagged());
2865 SetAllSideEffects();
2866 }
2867
2868 HValue* context() { return OperandAt(0); }
2869 HValue* global_object() { return OperandAt(1); }
2870 Handle<Object> name() const { return name_; }
2871 bool for_typeof() const { return for_typeof_; }
2872
2873 virtual void PrintDataTo(StringStream* stream);
2874
2875 virtual Representation RequiredInputRepresentation(int index) const {
2876 return Representation::Tagged();
2877 }
2878
2879 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load_global_generic")
2880
2881 private:
2882 Handle<Object> name_;
2883 bool for_typeof_;
2884};
2885
2886
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002887class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002888 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002889 HStoreGlobalCell(HValue* value,
2890 Handle<JSGlobalPropertyCell> cell,
2891 bool check_hole_value)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002892 : HUnaryOperation(value),
2893 cell_(cell),
2894 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002895 SetFlag(kChangesGlobalVars);
2896 }
2897
2898 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002899 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002900
2901 virtual Representation RequiredInputRepresentation(int index) const {
2902 return Representation::Tagged();
2903 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002904 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002905
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002906 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store_global_cell")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002907
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002908 private:
2909 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00002910 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002911};
2912
2913
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002914class HStoreGlobalGeneric: public HTemplateInstruction<3> {
2915 public:
2916 HStoreGlobalGeneric(HValue* context,
2917 HValue* global_object,
2918 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002919 HValue* value,
2920 bool strict_mode)
2921 : name_(name),
2922 strict_mode_(strict_mode) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002923 SetOperandAt(0, context);
2924 SetOperandAt(1, global_object);
2925 SetOperandAt(2, value);
2926 set_representation(Representation::Tagged());
2927 SetAllSideEffects();
2928 }
2929
2930 HValue* context() { return OperandAt(0); }
2931 HValue* global_object() { return OperandAt(1); }
2932 Handle<Object> name() const { return name_; }
2933 HValue* value() { return OperandAt(2); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002934 bool strict_mode() { return strict_mode_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002935
2936 virtual void PrintDataTo(StringStream* stream);
2937
2938 virtual Representation RequiredInputRepresentation(int index) const {
2939 return Representation::Tagged();
2940 }
2941
2942 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric, "store_global_generic")
2943
2944 private:
2945 Handle<Object> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002946 bool strict_mode_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00002947};
2948
2949
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002950class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002951 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002952 HLoadContextSlot(HValue* context , int slot_index)
2953 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002954 set_representation(Representation::Tagged());
2955 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002956 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002957 }
2958
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002959 int slot_index() const { return slot_index_; }
2960
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002961 virtual Representation RequiredInputRepresentation(int index) const {
2962 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002963 }
2964
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002965 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002966
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002967 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load_context_slot")
2968
2969 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002970 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002971 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002972 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002973 }
2974
2975 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002976 int slot_index_;
2977};
2978
2979
2980static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
2981 return !value->type().IsSmi() &&
2982 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
2983}
2984
2985
2986class HStoreContextSlot: public HBinaryOperation {
2987 public:
2988 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
2989 : HBinaryOperation(context, value), slot_index_(slot_index) {
2990 SetFlag(kChangesContextSlots);
2991 }
2992
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002993 HValue* context() { return OperandAt(0); }
2994 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002995 int slot_index() const { return slot_index_; }
2996
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002997 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002998 return StoringValueNeedsWriteBarrier(value());
2999 }
3000
3001 virtual Representation RequiredInputRepresentation(int index) const {
3002 return Representation::Tagged();
3003 }
3004
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003005 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003006
3007 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store_context_slot")
3008
3009 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003010 int slot_index_;
3011};
3012
3013
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003014class HLoadNamedField: public HUnaryOperation {
3015 public:
3016 HLoadNamedField(HValue* object, bool is_in_object, int offset)
3017 : HUnaryOperation(object),
3018 is_in_object_(is_in_object),
3019 offset_(offset) {
3020 set_representation(Representation::Tagged());
3021 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003022 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003023 if (is_in_object) {
3024 SetFlag(kDependsOnInobjectFields);
3025 } else {
3026 SetFlag(kDependsOnBackingStoreFields);
3027 }
3028 }
3029
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003030 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003031 bool is_in_object() const { return is_in_object_; }
3032 int offset() const { return offset_; }
3033
3034 virtual Representation RequiredInputRepresentation(int index) const {
3035 return Representation::Tagged();
3036 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003037 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003038
3039 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load_named_field")
3040
3041 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003042 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003043 HLoadNamedField* b = HLoadNamedField::cast(other);
3044 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3045 }
3046
3047 private:
3048 bool is_in_object_;
3049 int offset_;
3050};
3051
3052
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003053class HLoadNamedFieldPolymorphic: public HUnaryOperation {
3054 public:
3055 HLoadNamedFieldPolymorphic(HValue* object,
3056 ZoneMapList* types,
3057 Handle<String> name);
3058
3059 HValue* object() { return OperandAt(0); }
3060 ZoneMapList* types() { return &types_; }
3061 Handle<String> name() { return name_; }
3062 bool need_generic() { return need_generic_; }
3063
3064 virtual Representation RequiredInputRepresentation(int index) const {
3065 return Representation::Tagged();
3066 }
3067
3068 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic,
3069 "load_named_field_polymorphic")
3070
3071 static const int kMaxLoadPolymorphism = 4;
3072
3073 protected:
3074 virtual bool DataEquals(HValue* value);
3075
3076 private:
3077 ZoneMapList types_;
3078 Handle<String> name_;
3079 bool need_generic_;
3080};
3081
3082
3083
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003084class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003085 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003086 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
3087 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003088 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003089 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003090 }
3091
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003092 HValue* context() { return OperandAt(0); }
3093 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003094 Handle<Object> name() const { return name_; }
3095
3096 virtual Representation RequiredInputRepresentation(int index) const {
3097 return Representation::Tagged();
3098 }
3099
3100 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load_named_generic")
3101
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003102 private:
3103 Handle<Object> name_;
3104};
3105
3106
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003107class HLoadFunctionPrototype: public HUnaryOperation {
3108 public:
3109 explicit HLoadFunctionPrototype(HValue* function)
3110 : HUnaryOperation(function) {
3111 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003112 SetFlag(kUseGVN);
3113 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003114 }
3115
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003116 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003117
3118 virtual Representation RequiredInputRepresentation(int index) const {
3119 return Representation::Tagged();
3120 }
3121
3122 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load_function_prototype")
3123
3124 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003125 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003126};
3127
3128
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003129class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003130 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003131 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003132 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003133 SetFlag(kDependsOnArrayElements);
3134 SetFlag(kUseGVN);
3135 }
3136
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003137 HValue* object() { return OperandAt(0); }
3138 HValue* key() { return OperandAt(1); }
3139
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003140 virtual Representation RequiredInputRepresentation(int index) const {
3141 // The key is supposed to be Integer32.
3142 return (index == 1) ? Representation::Integer32()
3143 : Representation::Tagged();
3144 }
3145
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003146 virtual void PrintDataTo(StringStream* stream);
3147
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003148 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement,
3149 "load_keyed_fast_element")
ager@chromium.org378b34e2011-01-28 08:04:38 +00003150
3151 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003152 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003153};
3154
3155
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003156class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003157 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003158 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3159 HValue* key,
3160 ExternalArrayType array_type)
3161 : HBinaryOperation(external_elements, key),
3162 array_type_(array_type) {
3163 if (array_type == kExternalFloatArray) {
3164 set_representation(Representation::Double());
3165 } else {
3166 set_representation(Representation::Integer32());
3167 }
3168 SetFlag(kDependsOnSpecializedArrayElements);
3169 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003170 SetFlag(kDependsOnCalls);
3171 SetFlag(kUseGVN);
3172 }
3173
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003174 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003175
3176 virtual Representation RequiredInputRepresentation(int index) const {
3177 // The key is supposed to be Integer32, but the base pointer
3178 // for the element load is a naked pointer.
3179 return (index == 1) ? Representation::Integer32()
3180 : Representation::External();
3181 }
3182
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003183 HValue* external_pointer() { return OperandAt(0); }
3184 HValue* key() { return OperandAt(1); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003185 ExternalArrayType array_type() const { return array_type_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003186
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003187 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement,
3188 "load_keyed_specialized_array_element")
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003189
3190 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003191 virtual bool DataEquals(HValue* other) {
3192 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3193 HLoadKeyedSpecializedArrayElement* cast_other =
3194 HLoadKeyedSpecializedArrayElement::cast(other);
3195 return array_type_ == cast_other->array_type();
3196 }
3197
3198 private:
3199 ExternalArrayType array_type_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003200};
3201
3202
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003203class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003204 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003205 HLoadKeyedGeneric(HContext* context, HValue* obj, HValue* key) {
3206 set_representation(Representation::Tagged());
3207 SetOperandAt(0, obj);
3208 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003209 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003210 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003211 }
3212
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003213 HValue* object() { return OperandAt(0); }
3214 HValue* key() { return OperandAt(1); }
3215 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003216
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003217 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003218
3219 virtual Representation RequiredInputRepresentation(int index) const {
3220 return Representation::Tagged();
3221 }
3222
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003223 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load_keyed_generic")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003224};
3225
3226
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003227class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003228 public:
3229 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003230 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003231 HValue* val,
3232 bool in_object,
3233 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003234 : HBinaryOperation(obj, val),
3235 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003236 is_in_object_(in_object),
3237 offset_(offset) {
3238 if (is_in_object_) {
3239 SetFlag(kChangesInobjectFields);
3240 } else {
3241 SetFlag(kChangesBackingStoreFields);
3242 }
3243 }
3244
3245 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store_named_field")
3246
3247 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003248 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003249 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003250 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003251
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003252 HValue* object() { return OperandAt(0); }
3253 HValue* value() { return OperandAt(1); }
3254
3255 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003256 bool is_in_object() const { return is_in_object_; }
3257 int offset() const { return offset_; }
3258 Handle<Map> transition() const { return transition_; }
3259 void set_transition(Handle<Map> map) { transition_ = map; }
3260
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003261 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003262 return StoringValueNeedsWriteBarrier(value());
3263 }
3264
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003265 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003266 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003267 bool is_in_object_;
3268 int offset_;
3269 Handle<Map> transition_;
3270};
3271
3272
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003273class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003274 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003275 HStoreNamedGeneric(HValue* context,
3276 HValue* object,
3277 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003278 HValue* value,
3279 bool strict_mode)
3280 : name_(name),
3281 strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003282 SetOperandAt(0, object);
3283 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003284 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003285 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003286 }
3287
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003288 HValue* object() { return OperandAt(0); }
3289 HValue* value() { return OperandAt(1); }
3290 HValue* context() { return OperandAt(2); }
3291 Handle<String> name() { return name_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003292 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003293
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003294 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003295
3296 virtual Representation RequiredInputRepresentation(int index) const {
3297 return Representation::Tagged();
3298 }
3299
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003300 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store_named_generic")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003301
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003302 private:
3303 Handle<String> name_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003304 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003305};
3306
3307
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003308class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003309 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003310 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3311 SetOperandAt(0, obj);
3312 SetOperandAt(1, key);
3313 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003314 SetFlag(kChangesArrayElements);
3315 }
3316
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003317 virtual Representation RequiredInputRepresentation(int index) const {
3318 // The key is supposed to be Integer32.
3319 return (index == 1) ? Representation::Integer32()
3320 : Representation::Tagged();
3321 }
3322
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003323 HValue* object() { return OperandAt(0); }
3324 HValue* key() { return OperandAt(1); }
3325 HValue* value() { return OperandAt(2); }
3326
3327 bool NeedsWriteBarrier() {
3328 return StoringValueNeedsWriteBarrier(value());
3329 }
3330
3331 virtual void PrintDataTo(StringStream* stream);
3332
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003333 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
3334 "store_keyed_fast_element")
3335};
3336
3337
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003338class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003339 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003340 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3341 HValue* key,
3342 HValue* val,
3343 ExternalArrayType array_type)
3344 : array_type_(array_type) {
3345 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003346 SetOperandAt(0, external_elements);
3347 SetOperandAt(1, key);
3348 SetOperandAt(2, val);
3349 }
3350
3351 virtual void PrintDataTo(StringStream* stream);
3352
3353 virtual Representation RequiredInputRepresentation(int index) const {
3354 if (index == 0) {
3355 return Representation::External();
3356 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003357 if (index == 2 && array_type() == kExternalFloatArray) {
3358 return Representation::Double();
3359 } else {
3360 return Representation::Integer32();
3361 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003362 }
3363 }
3364
3365 HValue* external_pointer() { return OperandAt(0); }
3366 HValue* key() { return OperandAt(1); }
3367 HValue* value() { return OperandAt(2); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003368 ExternalArrayType array_type() const { return array_type_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003369
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003370 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,
3371 "store_keyed_specialized_array_element")
3372 private:
3373 ExternalArrayType array_type_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003374};
3375
3376
3377class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003378 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003379 HStoreKeyedGeneric(HValue* context,
3380 HValue* object,
3381 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003382 HValue* value,
3383 bool strict_mode)
3384 : strict_mode_(strict_mode) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003385 SetOperandAt(0, object);
3386 SetOperandAt(1, key);
3387 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003388 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003389 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003390 }
3391
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003392 HValue* object() { return OperandAt(0); }
3393 HValue* key() { return OperandAt(1); }
3394 HValue* value() { return OperandAt(2); }
3395 HValue* context() { return OperandAt(3); }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003396 bool strict_mode() { return strict_mode_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003397
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003398 virtual Representation RequiredInputRepresentation(int index) const {
3399 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003400 }
3401
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003402 virtual void PrintDataTo(StringStream* stream);
3403
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003404 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store_keyed_generic")
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003405
3406 private:
3407 bool strict_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003408};
3409
3410
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003411class HStringCharCodeAt: public HBinaryOperation {
3412 public:
3413 HStringCharCodeAt(HValue* string, HValue* index)
3414 : HBinaryOperation(string, index) {
3415 set_representation(Representation::Integer32());
3416 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003417 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003418 }
3419
3420 virtual Representation RequiredInputRepresentation(int index) const {
3421 // The index is supposed to be Integer32.
3422 return (index == 1) ? Representation::Integer32()
3423 : Representation::Tagged();
3424 }
3425
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003426 HValue* string() { return OperandAt(0); }
3427 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003428
3429 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string_char_code_at")
3430
3431 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003432 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003433
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003434 virtual Range* InferRange() {
3435 return new Range(0, String::kMaxUC16CharCode);
3436 }
3437};
3438
3439
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003440class HStringCharFromCode: public HUnaryOperation {
3441 public:
3442 explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
3443 set_representation(Representation::Tagged());
3444 SetFlag(kUseGVN);
3445 }
3446
3447 virtual Representation RequiredInputRepresentation(int index) const {
3448 return Representation::Integer32();
3449 }
3450
3451 virtual bool DataEquals(HValue* other) { return true; }
3452
3453 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string_char_from_code")
3454};
3455
3456
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003457class HStringLength: public HUnaryOperation {
3458 public:
3459 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3460 set_representation(Representation::Tagged());
3461 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003462 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003463 }
3464
3465 virtual Representation RequiredInputRepresentation(int index) const {
3466 return Representation::Tagged();
3467 }
3468
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003469 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003470 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3471 return HType::Smi();
3472 }
3473
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003474 DECLARE_CONCRETE_INSTRUCTION(StringLength, "string_length")
3475
3476 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003477 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003478
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003479 virtual Range* InferRange() {
3480 return new Range(0, String::kMaxLength);
3481 }
3482};
3483
3484
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003485template <int V>
3486class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003487 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003488 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003489 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003490 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003491 }
3492
3493 int literal_index() const { return literal_index_; }
3494 int depth() const { return depth_; }
3495
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003496 private:
3497 int literal_index_;
3498 int depth_;
3499};
3500
3501
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003502class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003503 public:
3504 HArrayLiteral(Handle<FixedArray> constant_elements,
3505 int length,
3506 int literal_index,
3507 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003508 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003509 length_(length),
3510 constant_elements_(constant_elements) {}
3511
3512 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3513 int length() const { return length_; }
3514
3515 bool IsCopyOnWrite() const;
3516
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003517 virtual Representation RequiredInputRepresentation(int index) const {
3518 return Representation::None();
3519 }
3520
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003521 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array_literal")
3522
3523 private:
3524 int length_;
3525 Handle<FixedArray> constant_elements_;
3526};
3527
3528
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003529class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003530 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003531 HObjectLiteral(HValue* context,
3532 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003533 bool fast_elements,
3534 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003535 int depth,
3536 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003537 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003538 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003539 fast_elements_(fast_elements),
3540 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003541 SetOperandAt(0, context);
3542 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003543
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003544 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003545 Handle<FixedArray> constant_properties() const {
3546 return constant_properties_;
3547 }
3548 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003549 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003550
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003551 virtual Representation RequiredInputRepresentation(int index) const {
3552 return Representation::Tagged();
3553 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003554
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003555 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object_literal")
3556
3557 private:
3558 Handle<FixedArray> constant_properties_;
3559 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003560 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003561};
3562
3563
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003564class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003565 public:
3566 HRegExpLiteral(Handle<String> pattern,
3567 Handle<String> flags,
3568 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003569 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003570 pattern_(pattern),
3571 flags_(flags) { }
3572
3573 Handle<String> pattern() { return pattern_; }
3574 Handle<String> flags() { return flags_; }
3575
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003576 virtual Representation RequiredInputRepresentation(int index) const {
3577 return Representation::None();
3578 }
3579
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003580 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp_literal")
3581
3582 private:
3583 Handle<String> pattern_;
3584 Handle<String> flags_;
3585};
3586
3587
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003588class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003589 public:
3590 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3591 : shared_info_(shared), pretenure_(pretenure) {
3592 set_representation(Representation::Tagged());
3593 }
3594
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003595 virtual Representation RequiredInputRepresentation(int index) const {
3596 return Representation::None();
3597 }
3598
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003599 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function_literal")
3600
3601 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3602 bool pretenure() const { return pretenure_; }
3603
3604 private:
3605 Handle<SharedFunctionInfo> shared_info_;
3606 bool pretenure_;
3607};
3608
3609
3610class HTypeof: public HUnaryOperation {
3611 public:
3612 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
3613 set_representation(Representation::Tagged());
3614 }
3615
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003616 virtual Representation RequiredInputRepresentation(int index) const {
3617 return Representation::Tagged();
3618 }
3619
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003620 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
3621};
3622
3623
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003624class HToFastProperties: public HUnaryOperation {
3625 public:
3626 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
3627 // This instruction is not marked as having side effects, but
3628 // changes the map of the input operand. Use it only when creating
3629 // object literals.
3630 ASSERT(value->IsObjectLiteral());
3631 set_representation(Representation::Tagged());
3632 }
3633
3634 virtual Representation RequiredInputRepresentation(int index) const {
3635 return Representation::Tagged();
3636 }
3637
3638 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to_fast_properties")
3639};
3640
3641
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003642class HValueOf: public HUnaryOperation {
3643 public:
3644 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
3645 set_representation(Representation::Tagged());
3646 }
3647
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003648 virtual Representation RequiredInputRepresentation(int index) const {
3649 return Representation::Tagged();
3650 }
3651
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003652 DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value_of")
3653};
3654
3655
3656class HDeleteProperty: public HBinaryOperation {
3657 public:
3658 HDeleteProperty(HValue* obj, HValue* key)
3659 : HBinaryOperation(obj, key) {
3660 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003661 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003662 }
3663
3664 virtual Representation RequiredInputRepresentation(int index) const {
3665 return Representation::Tagged();
3666 }
3667
3668 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete_property")
3669
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003670 HValue* object() { return left(); }
3671 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003672};
3673
3674#undef DECLARE_INSTRUCTION
3675#undef DECLARE_CONCRETE_INSTRUCTION
3676
3677} } // namespace v8::internal
3678
3679#endif // V8_HYDROGEN_INSTRUCTIONS_H_