blob: ddef8b75840ce0add324f73290ca44fc4193294b [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) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000151 V(StoreGlobal) \
152 V(StoreKeyedFastElement) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000153 V(StoreKeyedSpecializedArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000154 V(StoreKeyedGeneric) \
155 V(StoreNamedField) \
156 V(StoreNamedGeneric) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000157 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000158 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000159 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000160 V(Sub) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000161 V(Test) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000162 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000163 V(ToFastProperties) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000164 V(Typeof) \
165 V(TypeofIs) \
166 V(UnaryMathOperation) \
167 V(UnknownOSRValue) \
168 V(ValueOf)
169
170#define GVN_FLAG_LIST(V) \
171 V(Calls) \
172 V(InobjectFields) \
173 V(BackingStoreFields) \
174 V(ArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000175 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000176 V(GlobalVars) \
177 V(Maps) \
178 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000179 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000180 V(OsrEntries)
181
182#define DECLARE_INSTRUCTION(type) \
183 virtual bool Is##type() const { return true; } \
184 static H##type* cast(HValue* value) { \
185 ASSERT(value->Is##type()); \
186 return reinterpret_cast<H##type*>(value); \
187 } \
188 Opcode opcode() const { return HValue::k##type; }
189
190
191#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
192 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
193 virtual const char* Mnemonic() const { return mnemonic; } \
194 DECLARE_INSTRUCTION(type)
195
196
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000197class Range: public ZoneObject {
198 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000199 Range()
200 : lower_(kMinInt),
201 upper_(kMaxInt),
202 next_(NULL),
203 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000204
205 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000206 : lower_(lower),
207 upper_(upper),
208 next_(NULL),
209 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000210
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000211 int32_t upper() const { return upper_; }
212 int32_t lower() const { return lower_; }
213 Range* next() const { return next_; }
214 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
215 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000216 Range* Copy() const { return new Range(lower_, upper_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000217 int32_t Mask() const;
218 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
219 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
220 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
221 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000222 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
223 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
224 bool IsInSmiRange() const {
225 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000226 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000227 void KeepOrder();
228 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000229
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000230 void StackUpon(Range* other) {
231 Intersect(other);
232 next_ = other;
233 }
234
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000235 void Intersect(Range* other);
236 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000237
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000238 void AddConstant(int32_t value);
239 void Sar(int32_t value);
240 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000241 bool AddAndCheckOverflow(Range* other);
242 bool SubAndCheckOverflow(Range* other);
243 bool MulAndCheckOverflow(Range* other);
244
245 private:
246 int32_t lower_;
247 int32_t upper_;
248 Range* next_;
249 bool can_be_minus_zero_;
250};
251
252
253class Representation {
254 public:
255 enum Kind {
256 kNone,
257 kTagged,
258 kDouble,
259 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000260 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000261 kNumRepresentations
262 };
263
264 Representation() : kind_(kNone) { }
265
266 static Representation None() { return Representation(kNone); }
267 static Representation Tagged() { return Representation(kTagged); }
268 static Representation Integer32() { return Representation(kInteger32); }
269 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000270 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000271
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000272 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000273 return kind_ == other.kind_;
274 }
275
276 Kind kind() const { return kind_; }
277 bool IsNone() const { return kind_ == kNone; }
278 bool IsTagged() const { return kind_ == kTagged; }
279 bool IsInteger32() const { return kind_ == kInteger32; }
280 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000281 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000282 bool IsSpecialization() const {
283 return kind_ == kInteger32 || kind_ == kDouble;
284 }
285 const char* Mnemonic() const;
286
287 private:
288 explicit Representation(Kind k) : kind_(k) { }
289
290 Kind kind_;
291};
292
293
294class HType {
295 public:
296 HType() : type_(kUninitialized) { }
297
298 static HType Tagged() { return HType(kTagged); }
299 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
300 static HType TaggedNumber() { return HType(kTaggedNumber); }
301 static HType Smi() { return HType(kSmi); }
302 static HType HeapNumber() { return HType(kHeapNumber); }
303 static HType String() { return HType(kString); }
304 static HType Boolean() { return HType(kBoolean); }
305 static HType NonPrimitive() { return HType(kNonPrimitive); }
306 static HType JSArray() { return HType(kJSArray); }
307 static HType JSObject() { return HType(kJSObject); }
308 static HType Uninitialized() { return HType(kUninitialized); }
309
310 // Return the weakest (least precise) common type.
311 HType Combine(HType other) {
312 return HType(static_cast<Type>(type_ & other.type_));
313 }
314
315 bool Equals(const HType& other) {
316 return type_ == other.type_;
317 }
318
319 bool IsSubtypeOf(const HType& other) {
320 return Combine(other).Equals(other);
321 }
322
323 bool IsTagged() {
324 ASSERT(type_ != kUninitialized);
325 return ((type_ & kTagged) == kTagged);
326 }
327
328 bool IsTaggedPrimitive() {
329 ASSERT(type_ != kUninitialized);
330 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
331 }
332
333 bool IsTaggedNumber() {
334 ASSERT(type_ != kUninitialized);
335 return ((type_ & kTaggedNumber) == kTaggedNumber);
336 }
337
338 bool IsSmi() {
339 ASSERT(type_ != kUninitialized);
340 return ((type_ & kSmi) == kSmi);
341 }
342
343 bool IsHeapNumber() {
344 ASSERT(type_ != kUninitialized);
345 return ((type_ & kHeapNumber) == kHeapNumber);
346 }
347
348 bool IsString() {
349 ASSERT(type_ != kUninitialized);
350 return ((type_ & kString) == kString);
351 }
352
353 bool IsBoolean() {
354 ASSERT(type_ != kUninitialized);
355 return ((type_ & kBoolean) == kBoolean);
356 }
357
358 bool IsNonPrimitive() {
359 ASSERT(type_ != kUninitialized);
360 return ((type_ & kNonPrimitive) == kNonPrimitive);
361 }
362
363 bool IsJSArray() {
364 ASSERT(type_ != kUninitialized);
365 return ((type_ & kJSArray) == kJSArray);
366 }
367
368 bool IsJSObject() {
369 ASSERT(type_ != kUninitialized);
370 return ((type_ & kJSObject) == kJSObject);
371 }
372
373 bool IsUninitialized() {
374 return type_ == kUninitialized;
375 }
376
377 static HType TypeFromValue(Handle<Object> value);
378
379 const char* ToString();
380 const char* ToShortString();
381
382 private:
383 enum Type {
384 kTagged = 0x1, // 0000 0000 0000 0001
385 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
386 kTaggedNumber = 0xd, // 0000 0000 0000 1101
387 kSmi = 0x1d, // 0000 0000 0001 1101
388 kHeapNumber = 0x2d, // 0000 0000 0010 1101
389 kString = 0x45, // 0000 0000 0100 0101
390 kBoolean = 0x85, // 0000 0000 1000 0101
391 kNonPrimitive = 0x101, // 0000 0001 0000 0001
392 kJSObject = 0x301, // 0000 0011 0000 0001
393 kJSArray = 0x701, // 0000 0111 1000 0001
394 kUninitialized = 0x1fff // 0001 1111 1111 1111
395 };
396
397 explicit HType(Type t) : type_(t) { }
398
399 Type type_;
400};
401
402
403class HValue: public ZoneObject {
404 public:
405 static const int kNoNumber = -1;
406
407 // There must be one corresponding kDepends flag for every kChanges flag and
408 // the order of the kChanges flags must be exactly the same as of the kDepends
409 // flags.
410 enum Flag {
411 // Declare global value numbering flags.
412 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
413 GVN_FLAG_LIST(DECLARE_DO)
414 #undef DECLARE_DO
415 kFlexibleRepresentation,
416 kUseGVN,
417 kCanOverflow,
418 kBailoutOnMinusZero,
419 kCanBeDivByZero,
420 kIsArguments,
421 kTruncatingToInt32,
422 kLastFlag = kTruncatingToInt32
423 };
424
425 STATIC_ASSERT(kLastFlag < kBitsPerInt);
426
427 static const int kChangesToDependsFlagsLeftShift = 1;
428
429 static int ChangesFlagsMask() {
430 int result = 0;
431 // Create changes mask.
432#define DECLARE_DO(type) result |= (1 << kChanges##type);
433 GVN_FLAG_LIST(DECLARE_DO)
434#undef DECLARE_DO
435 return result;
436 }
437
438 static int DependsFlagsMask() {
439 return ConvertChangesToDependsFlags(ChangesFlagsMask());
440 }
441
442 static int ConvertChangesToDependsFlags(int flags) {
443 return flags << kChangesToDependsFlagsLeftShift;
444 }
445
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000446 static HValue* cast(HValue* value) { return value; }
447
448 enum Opcode {
449 // Declare a unique enum value for each hydrogen instruction.
450 #define DECLARE_DO(type) k##type,
451 HYDROGEN_ALL_INSTRUCTION_LIST(DECLARE_DO)
452 #undef DECLARE_DO
453 kMaxInstructionClass
454 };
455
456 HValue() : block_(NULL),
457 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000458 type_(HType::Tagged()),
459 range_(NULL),
460 flags_(0) {}
461 virtual ~HValue() {}
462
463 HBasicBlock* block() const { return block_; }
464 void SetBlock(HBasicBlock* block);
465
466 int id() const { return id_; }
467 void set_id(int id) { id_ = id; }
468
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000469 SmallPointerList<HValue>* uses() { return &uses_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000470
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000471 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000472 Representation representation() const { return representation_; }
473 void ChangeRepresentation(Representation r) {
474 // Representation was already set and is allowed to be changed.
475 ASSERT(!representation_.IsNone());
476 ASSERT(!r.IsNone());
477 ASSERT(CheckFlag(kFlexibleRepresentation));
478 RepresentationChanged(r);
479 representation_ = r;
480 }
481
482 HType type() const { return type_; }
483 void set_type(HType type) {
484 ASSERT(uses_.length() == 0);
485 type_ = type;
486 }
487
488 // An operation needs to override this function iff:
489 // 1) it can produce an int32 output.
490 // 2) the true value of its output can potentially be minus zero.
491 // The implementation must set a flag so that it bails out in the case where
492 // it would otherwise output what should be a minus zero as an int32 zero.
493 // If the operation also exists in a form that takes int32 and outputs int32
494 // then the operation should return its input value so that we can propagate
495 // back. There are two operations that need to propagate back to more than
496 // one input. They are phi and binary add. They always return NULL and
497 // expect the caller to take care of things.
498 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
499 visited->Add(id());
500 return NULL;
501 }
502
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000503 bool IsDefinedAfter(HBasicBlock* other) const;
504
505 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000506 virtual int OperandCount() = 0;
507 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000508 void SetOperandAt(int index, HValue* value);
509
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000510 int LookupOperandIndex(int occurrence_index, HValue* op);
511 bool UsesMultipleTimes(HValue* op);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000512
513 void ReplaceAndDelete(HValue* other);
514 void ReplaceValue(HValue* other);
515 void ReplaceAtUse(HValue* use, HValue* other);
516 void ReplaceFirstAtUse(HValue* use, HValue* other, Representation r);
517 bool HasNoUses() const { return uses_.is_empty(); }
518 void ClearOperands();
519 void Delete();
520
521 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000522 void SetFlag(Flag f) { flags_ |= (1 << f); }
523 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
524 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
525
526 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
527 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
528 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000529
530 Range* range() const { return range_; }
531 bool HasRange() const { return range_ != NULL; }
532 void AddNewRange(Range* r);
533 void RemoveLastAddedRange();
534 void ComputeInitialRange();
535
536 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000537 virtual Representation RequiredInputRepresentation(int index) const = 0;
538
539 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000540 return representation();
541 }
542
543 // This gives the instruction an opportunity to replace itself with an
544 // instruction that does the same in some better way. To replace an
545 // instruction with a new one, first add the new instruction to the graph,
546 // then return it. Return NULL to have the instruction deleted.
547 virtual HValue* Canonicalize() { return this; }
548
549 // Declare virtual type testers.
550#define DECLARE_DO(type) virtual bool Is##type() const { return false; }
551 HYDROGEN_ALL_INSTRUCTION_LIST(DECLARE_DO)
552#undef DECLARE_DO
553
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000554 bool Equals(HValue* other);
555 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000556
557 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000558 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000559 void PrintNameTo(StringStream* stream);
560 static void PrintTypeTo(HType type, StringStream* stream);
561
562 virtual const char* Mnemonic() const = 0;
563 virtual Opcode opcode() const = 0;
564
565 // Updated the inferred type of this instruction and returns true if
566 // it has changed.
567 bool UpdateInferredType();
568
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000569 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000570
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000571#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000572 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000573#endif
574
575 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000576 // This function must be overridden for instructions with flag kUseGVN, to
577 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000578 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000579 UNREACHABLE();
580 return false;
581 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000582 virtual void RepresentationChanged(Representation to) { }
583 virtual Range* InferRange();
584 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000585 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000586 void clear_block() {
587 ASSERT(block_ != NULL);
588 block_ = NULL;
589 }
590
591 void set_representation(Representation r) {
592 // Representation is set-once.
593 ASSERT(representation_.IsNone() && !r.IsNone());
594 representation_ = r;
595 }
596
597 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000598 // A flag mask to mark an instruction as having arbitrary side effects.
599 static int AllSideEffects() {
600 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
601 }
602
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000603 void InternalReplaceAtUse(HValue* use, HValue* other);
604 void RegisterUse(int index, HValue* new_value);
605
606 HBasicBlock* block_;
607
608 // The id of this instruction in the hydrogen graph, assigned when first
609 // added to the graph. Reflects creation order.
610 int id_;
611
612 Representation representation_;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000613 SmallPointerList<HValue> uses_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000614 HType type_;
615 Range* range_;
616 int flags_;
617
618 DISALLOW_COPY_AND_ASSIGN(HValue);
619};
620
621
622class HInstruction: public HValue {
623 public:
624 HInstruction* next() const { return next_; }
625 HInstruction* previous() const { return previous_; }
626
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000627 virtual void PrintTo(StringStream* stream);
628 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000629
630 bool IsLinked() const { return block() != NULL; }
631 void Unlink();
632 void InsertBefore(HInstruction* next);
633 void InsertAfter(HInstruction* previous);
634
635 int position() const { return position_; }
636 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
637 void set_position(int position) { position_ = position; }
638
639 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
640
641#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000642 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000643#endif
644
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000645 // Returns whether this is some kind of deoptimizing check
646 // instruction.
647 virtual bool IsCheckInstruction() const { return false; }
648
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000649 virtual bool IsCall() { return false; }
650
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000651 DECLARE_INSTRUCTION(Instruction)
652
653 protected:
654 HInstruction()
655 : next_(NULL),
656 previous_(NULL),
657 position_(RelocInfo::kNoPosition) {
658 SetFlag(kDependsOnOsrEntries);
659 }
660
661 virtual void DeleteFromGraph() { Unlink(); }
662
663 private:
664 void InitializeAsFirst(HBasicBlock* block) {
665 ASSERT(!IsLinked());
666 SetBlock(block);
667 }
668
669 HInstruction* next_;
670 HInstruction* previous_;
671 int position_;
672
673 friend class HBasicBlock;
674};
675
676
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000677class HControlInstruction: public HInstruction {
678 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000679 HControlInstruction(HBasicBlock* first, HBasicBlock* second)
680 : first_successor_(first), second_successor_(second) {
681 }
682
683 HBasicBlock* FirstSuccessor() const { return first_successor_; }
684 HBasicBlock* SecondSuccessor() const { return second_successor_; }
685
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000686 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000687
688 DECLARE_INSTRUCTION(ControlInstruction)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000689
690 private:
691 HBasicBlock* first_successor_;
692 HBasicBlock* second_successor_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000693};
694
695
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000696template<int NumElements>
697class HOperandContainer {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000698 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000699 HOperandContainer() : elems_() { }
700
701 int length() { return NumElements; }
702 HValue*& operator[](int i) {
703 ASSERT(i < length());
704 return elems_[i];
705 }
706
707 private:
708 HValue* elems_[NumElements];
709};
710
711
712template<>
713class HOperandContainer<0> {
714 public:
715 int length() { return 0; }
716 HValue*& operator[](int i) {
717 UNREACHABLE();
718 static HValue* t = 0;
719 return t;
720 }
721};
722
723
724template<int V>
725class HTemplateInstruction : public HInstruction {
726 public:
727 int OperandCount() { return V; }
728 HValue* OperandAt(int i) { return inputs_[i]; }
729
730 protected:
731 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
732
733 private:
734 HOperandContainer<V> inputs_;
735};
736
737
738template<int V>
739class HTemplateControlInstruction : public HControlInstruction {
740 public:
741 HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second)
742 : HControlInstruction(first, second) { }
743 int OperandCount() { return V; }
744 HValue* OperandAt(int i) { return inputs_[i]; }
745
746 protected:
747 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
748
749 private:
750 HOperandContainer<V> inputs_;
751};
752
753
754class HBlockEntry: public HTemplateInstruction<0> {
755 public:
756 virtual Representation RequiredInputRepresentation(int index) const {
757 return Representation::None();
758 }
759
760 DECLARE_CONCRETE_INSTRUCTION(BlockEntry, "block_entry")
761};
762
763
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000764class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000765 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000766 explicit HDeoptimize(int environment_length)
767 : HControlInstruction(NULL, NULL),
768 values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000769
770 virtual Representation RequiredInputRepresentation(int index) const {
771 return Representation::None();
772 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000773
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000774 virtual int OperandCount() { return values_.length(); }
775 virtual HValue* OperandAt(int index) { return values_[index]; }
776
777 void AddEnvironmentValue(HValue* value) {
778 values_.Add(NULL);
779 SetOperandAt(values_.length() - 1, value);
780 }
781
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000782 DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000783
784 protected:
785 virtual void InternalSetOperandAt(int index, HValue* value) {
786 values_[index] = value;
787 }
788
789 private:
790 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000791};
792
793
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000794class HGoto: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000795 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000796 explicit HGoto(HBasicBlock* target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000797 : HTemplateControlInstruction<0>(target, NULL),
798 include_stack_check_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000799
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000800 void set_include_stack_check(bool include_stack_check) {
801 include_stack_check_ = include_stack_check;
802 }
803 bool include_stack_check() const { return include_stack_check_; }
804
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000805 virtual Representation RequiredInputRepresentation(int index) const {
806 return Representation::None();
807 }
808
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000809 DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
810
811 private:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000812 bool include_stack_check_;
813};
814
815
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000816class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000817 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000818 explicit HUnaryControlInstruction(HValue* value,
819 HBasicBlock* true_target,
820 HBasicBlock* false_target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000821 : HTemplateControlInstruction<1>(true_target, false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000822 SetOperandAt(0, value);
823 }
824
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000825 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000826
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000827 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000828
829 DECLARE_INSTRUCTION(UnaryControlInstruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000830};
831
832
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000833class HTest: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000834 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000835 HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
836 : HUnaryControlInstruction(value, true_target, false_target) {
837 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000838 }
839
840 virtual Representation RequiredInputRepresentation(int index) const {
841 return Representation::None();
842 }
843
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000844 DECLARE_CONCRETE_INSTRUCTION(Test, "test")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000845};
846
847
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000848class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000849 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000850 HCompareMap(HValue* value,
851 Handle<Map> map,
852 HBasicBlock* true_target,
853 HBasicBlock* false_target)
854 : HUnaryControlInstruction(value, true_target, false_target),
855 map_(map) {
856 ASSERT(true_target != NULL);
857 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000858 ASSERT(!map.is_null());
859 }
860
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000861 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000862
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000863 Handle<Map> map() const { return map_; }
864
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000865 virtual Representation RequiredInputRepresentation(int index) const {
866 return Representation::Tagged();
867 }
868
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000869 DECLARE_CONCRETE_INSTRUCTION(CompareMap, "compare_map")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000870
871 private:
872 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000873};
874
875
876class HReturn: public HUnaryControlInstruction {
877 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000878 explicit HReturn(HValue* value)
879 : HUnaryControlInstruction(value, NULL, NULL) {
880 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000881
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000882 virtual Representation RequiredInputRepresentation(int index) const {
883 return Representation::Tagged();
884 }
885
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000886 DECLARE_CONCRETE_INSTRUCTION(Return, "return")
887};
888
889
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000890class HAbnormalExit: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000891 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000892 HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
893
894 virtual Representation RequiredInputRepresentation(int index) const {
895 return Representation::None();
896 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000897
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000898 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit, "abnormal_exit")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000899};
900
901
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000902class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000903 public:
904 explicit HUnaryOperation(HValue* value) {
905 SetOperandAt(0, value);
906 }
907
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000908 HValue* value() { return OperandAt(0); }
909 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000910
911 DECLARE_INSTRUCTION(UnaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000912};
913
914
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000915class HThrow: public HUnaryOperation {
916 public:
917 explicit HThrow(HValue* value) : HUnaryOperation(value) {
918 SetAllSideEffects();
919 }
920
921 virtual Representation RequiredInputRepresentation(int index) const {
922 return Representation::Tagged();
923 }
924
925 DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
926};
927
928
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000929class HChange: public HUnaryOperation {
930 public:
931 HChange(HValue* value,
932 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000933 Representation to,
934 bool is_truncating)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000935 : HUnaryOperation(value), from_(from), to_(to) {
936 ASSERT(!from.IsNone() && !to.IsNone());
937 ASSERT(!from.Equals(to));
938 set_representation(to);
939 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000940 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000941 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
942 value->range()->IsInSmiRange()) {
943 set_type(HType::Smi());
944 }
945 }
946
947 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
948
949 Representation from() const { return from_; }
950 Representation to() const { return to_; }
951 virtual Representation RequiredInputRepresentation(int index) const {
952 return from_;
953 }
954
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000955 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000956
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000957 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000958
959 DECLARE_CONCRETE_INSTRUCTION(Change,
960 CanTruncateToInt32() ? "truncate" : "change")
961
962 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000963 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000964 if (!other->IsChange()) return false;
965 HChange* change = HChange::cast(other);
966 return value() == change->value()
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000967 && to().Equals(change->to());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000968 }
969
970 private:
971 Representation from_;
972 Representation to_;
973};
974
975
976class HSimulate: public HInstruction {
977 public:
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000978 HSimulate(int ast_id, int pop_count, int environment_length)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000979 : ast_id_(ast_id),
980 pop_count_(pop_count),
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000981 environment_length_(environment_length),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000982 values_(2),
983 assigned_indexes_(2) {}
984 virtual ~HSimulate() {}
985
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000986 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000987
988 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
989 int ast_id() const { return ast_id_; }
990 void set_ast_id(int id) {
991 ASSERT(!HasAstId());
992 ast_id_ = id;
993 }
994
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000995 int environment_length() const { return environment_length_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000996 int pop_count() const { return pop_count_; }
997 const ZoneList<HValue*>* values() const { return &values_; }
998 int GetAssignedIndexAt(int index) const {
999 ASSERT(HasAssignedIndexAt(index));
1000 return assigned_indexes_[index];
1001 }
1002 bool HasAssignedIndexAt(int index) const {
1003 return assigned_indexes_[index] != kNoIndex;
1004 }
1005 void AddAssignedValue(int index, HValue* value) {
1006 AddValue(index, value);
1007 }
1008 void AddPushedValue(HValue* value) {
1009 AddValue(kNoIndex, value);
1010 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001011 virtual int OperandCount() { return values_.length(); }
1012 virtual HValue* OperandAt(int index) { return values_[index]; }
1013
1014 virtual Representation RequiredInputRepresentation(int index) const {
1015 return Representation::None();
1016 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001017
1018 DECLARE_CONCRETE_INSTRUCTION(Simulate, "simulate")
1019
1020#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001021 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001022#endif
1023
1024 protected:
1025 virtual void InternalSetOperandAt(int index, HValue* value) {
1026 values_[index] = value;
1027 }
1028
1029 private:
1030 static const int kNoIndex = -1;
1031 void AddValue(int index, HValue* value) {
1032 assigned_indexes_.Add(index);
1033 // Resize the list of pushed values.
1034 values_.Add(NULL);
1035 // Set the operand through the base method in HValue to make sure that the
1036 // use lists are correctly updated.
1037 SetOperandAt(values_.length() - 1, value);
1038 }
1039 int ast_id_;
1040 int pop_count_;
lrn@chromium.org5d00b602011-01-05 09:51:43 +00001041 int environment_length_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001042 ZoneList<HValue*> values_;
1043 ZoneList<int> assigned_indexes_;
1044};
1045
1046
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001047class HStackCheck: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001048 public:
1049 HStackCheck() { }
1050
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001051 virtual Representation RequiredInputRepresentation(int index) const {
1052 return Representation::None();
1053 }
1054
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001055 DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack_check")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001056};
1057
1058
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001059class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001060 public:
1061 HEnterInlined(Handle<JSFunction> closure, FunctionLiteral* function)
1062 : closure_(closure), function_(function) {
1063 }
1064
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001065 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001066
1067 Handle<JSFunction> closure() const { return closure_; }
1068 FunctionLiteral* function() const { return function_; }
1069
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001070 virtual Representation RequiredInputRepresentation(int index) const {
1071 return Representation::None();
1072 }
1073
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001074 DECLARE_CONCRETE_INSTRUCTION(EnterInlined, "enter_inlined")
1075
1076 private:
1077 Handle<JSFunction> closure_;
1078 FunctionLiteral* function_;
1079};
1080
1081
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001082class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001083 public:
1084 HLeaveInlined() {}
1085
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001086 virtual Representation RequiredInputRepresentation(int index) const {
1087 return Representation::None();
1088 }
1089
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001090 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined, "leave_inlined")
1091};
1092
1093
1094class HPushArgument: public HUnaryOperation {
1095 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001096 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1097 set_representation(Representation::Tagged());
1098 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001099
1100 virtual Representation RequiredInputRepresentation(int index) const {
1101 return Representation::Tagged();
1102 }
1103
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001104 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001105
1106 DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push_argument")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001107};
1108
1109
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001110class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001111 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001112 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001113 set_representation(Representation::Tagged());
1114 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001115 }
1116
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001117 virtual Representation RequiredInputRepresentation(int index) const {
1118 return Representation::None();
1119 }
1120
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001121 DECLARE_CONCRETE_INSTRUCTION(Context, "context");
1122
1123 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001124 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001125};
1126
1127
1128class HOuterContext: public HUnaryOperation {
1129 public:
1130 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1131 set_representation(Representation::Tagged());
1132 SetFlag(kUseGVN);
1133 }
1134
1135 DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer_context");
1136
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001137 virtual Representation RequiredInputRepresentation(int index) const {
1138 return Representation::Tagged();
1139 }
1140
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001141 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001142 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001143};
1144
1145
1146class HGlobalObject: public HUnaryOperation {
1147 public:
1148 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1149 set_representation(Representation::Tagged());
1150 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001151 }
1152
1153 DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global_object")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001154
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001155 virtual Representation RequiredInputRepresentation(int index) const {
1156 return Representation::Tagged();
1157 }
1158
ager@chromium.org378b34e2011-01-28 08:04:38 +00001159 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001160 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001161};
1162
1163
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001164class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001165 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001166 explicit HGlobalReceiver(HValue* global_object)
1167 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001168 set_representation(Representation::Tagged());
1169 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001170 }
1171
1172 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global_receiver")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001173
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001174 virtual Representation RequiredInputRepresentation(int index) const {
1175 return Representation::Tagged();
1176 }
1177
ager@chromium.org378b34e2011-01-28 08:04:38 +00001178 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001179 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001180};
1181
1182
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001183template <int V>
1184class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001185 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001186 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001187 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1188 this->set_representation(Representation::Tagged());
1189 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001190 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001191
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001192 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001193
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001194 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001195
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001196 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001197
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001198 private:
1199 int argument_count_;
1200};
1201
1202
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001203class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001204 public:
1205 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001206 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001207 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001208 }
1209
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001210 virtual Representation RequiredInputRepresentation(int index) const {
1211 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001212 }
1213
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001214 virtual void PrintDataTo(StringStream* stream);
1215
1216 HValue* value() { return OperandAt(0); }
1217
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001218 DECLARE_INSTRUCTION(UnaryCall)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001219};
1220
1221
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001222class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001223 public:
1224 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001225 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001226 SetOperandAt(0, first);
1227 SetOperandAt(1, second);
1228 }
1229
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001230 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001231
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001232 virtual Representation RequiredInputRepresentation(int index) const {
1233 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001234 }
1235
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001236 HValue* first() { return OperandAt(0); }
1237 HValue* second() { return OperandAt(1); }
1238
1239 DECLARE_INSTRUCTION(BinaryCall)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001240};
1241
1242
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001243class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001244 public:
1245 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001246 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001247
1248 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001249
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001250 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001251 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001252 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001253 }
1254
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001255 virtual void PrintDataTo(StringStream* stream);
1256
1257 virtual Representation RequiredInputRepresentation(int index) const {
1258 return Representation::None();
1259 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001260
1261 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call_constant_function")
1262
1263 private:
1264 Handle<JSFunction> function_;
1265};
1266
1267
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001268class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001269 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001270 HCallKeyed(HValue* context, HValue* key, int argument_count)
1271 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001272 }
1273
1274 virtual Representation RequiredInputRepresentation(int index) const {
1275 return Representation::Tagged();
1276 }
1277
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001278 HValue* context() { return first(); }
1279 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001280
1281 DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call_keyed")
1282};
1283
1284
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001285class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001286 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001287 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1288 : HUnaryCall(context, argument_count), name_(name) {
1289 }
1290
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001291 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001292
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001293 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001294 Handle<String> name() const { return name_; }
1295
1296 DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call_named")
1297
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001298 virtual Representation RequiredInputRepresentation(int index) const {
1299 return Representation::Tagged();
1300 }
1301
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001302 private:
1303 Handle<String> name_;
1304};
1305
1306
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001307class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001308 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001309 HCallFunction(HValue* context, int argument_count)
1310 : HUnaryCall(context, argument_count) {
1311 }
1312
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001313 HValue* context() { return value(); }
1314
1315 virtual Representation RequiredInputRepresentation(int index) const {
1316 return Representation::Tagged();
1317 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001318
1319 DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call_function")
1320};
1321
1322
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001323class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001324 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001325 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1326 : HUnaryCall(context, argument_count), name_(name) {
1327 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001328
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001329 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001330
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001331 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001332 Handle<String> name() const { return name_; }
1333
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001334 virtual Representation RequiredInputRepresentation(int index) const {
1335 return Representation::Tagged();
1336 }
1337
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001338 DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call_global")
1339
1340 private:
1341 Handle<String> name_;
1342};
1343
1344
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001345class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001346 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001347 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001348 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001349
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001350 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001351
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001352 Handle<JSFunction> target() const { return target_; }
1353
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001354 virtual Representation RequiredInputRepresentation(int index) const {
1355 return Representation::None();
1356 }
1357
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001358 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call_known_global")
1359
1360 private:
1361 Handle<JSFunction> target_;
1362};
1363
1364
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001365class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001366 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001367 HCallNew(HValue* context, HValue* constructor, int argument_count)
1368 : HBinaryCall(context, constructor, argument_count) {
1369 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001370
1371 virtual Representation RequiredInputRepresentation(int index) const {
1372 return Representation::Tagged();
1373 }
1374
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001375 HValue* context() { return first(); }
1376 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001377
1378 DECLARE_CONCRETE_INSTRUCTION(CallNew, "call_new")
1379};
1380
1381
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001382class HCallRuntime: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001383 public:
1384 HCallRuntime(Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001385 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001386 int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001387 : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
1388 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001389
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001390 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001391 Handle<String> name() const { return name_; }
1392
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001393 virtual Representation RequiredInputRepresentation(int index) const {
1394 return Representation::None();
1395 }
1396
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001397 DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call_runtime")
1398
1399 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001400 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001401 Handle<String> name_;
1402};
1403
1404
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001405class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001406 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001407 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001408 // The length of an array is stored as a tagged value in the array
1409 // object. It is guaranteed to be 32 bit integer, but it can be
1410 // represented as either a smi or heap number.
1411 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001412 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001413 SetFlag(kDependsOnArrayLengths);
1414 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001415 }
1416
1417 virtual Representation RequiredInputRepresentation(int index) const {
1418 return Representation::Tagged();
1419 }
1420
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001421 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js_array_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001422
1423 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001424 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001425};
1426
1427
1428class HFixedArrayLength: public HUnaryOperation {
1429 public:
1430 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1431 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001432 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001433 SetFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001434 }
1435
1436 virtual Representation RequiredInputRepresentation(int index) const {
1437 return Representation::Tagged();
1438 }
1439
1440 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed_array_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001441
1442 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001443 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001444};
1445
1446
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001447class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001448 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001449 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001450 set_representation(Representation::Integer32());
1451 // The result of this instruction is idempotent as long as its inputs don't
1452 // change. The length of a pixel array cannot change once set, so it's not
1453 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1454 SetFlag(kUseGVN);
1455 }
1456
1457 virtual Representation RequiredInputRepresentation(int index) const {
1458 return Representation::Tagged();
1459 }
1460
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001461 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength, "external_array_length")
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001462
1463 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001464 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001465};
1466
1467
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001468class HBitNot: public HUnaryOperation {
1469 public:
1470 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1471 set_representation(Representation::Integer32());
1472 SetFlag(kUseGVN);
1473 SetFlag(kTruncatingToInt32);
1474 }
1475
1476 virtual Representation RequiredInputRepresentation(int index) const {
1477 return Representation::Integer32();
1478 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001479 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001480
1481 DECLARE_CONCRETE_INSTRUCTION(BitNot, "bit_not")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001482
1483 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001484 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001485};
1486
1487
1488class HUnaryMathOperation: public HUnaryOperation {
1489 public:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001490 HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001491 : HUnaryOperation(value), op_(op) {
1492 switch (op) {
1493 case kMathFloor:
1494 case kMathRound:
1495 case kMathCeil:
1496 set_representation(Representation::Integer32());
1497 break;
1498 case kMathAbs:
1499 set_representation(Representation::Tagged());
1500 SetFlag(kFlexibleRepresentation);
1501 break;
1502 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001503 case kMathPowHalf:
1504 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001505 case kMathSin:
1506 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001507 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001508 break;
1509 default:
1510 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001511 }
1512 SetFlag(kUseGVN);
1513 }
1514
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001515 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001516
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001517 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001518
1519 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1520
1521 virtual Representation RequiredInputRepresentation(int index) const {
1522 switch (op_) {
1523 case kMathFloor:
1524 case kMathRound:
1525 case kMathCeil:
1526 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001527 case kMathPowHalf:
1528 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001529 case kMathSin:
1530 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001531 return Representation::Double();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001532 case kMathAbs:
1533 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001534 default:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001535 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001536 return Representation::None();
1537 }
1538 }
1539
1540 virtual HValue* Canonicalize() {
1541 // If the input is integer32 then we replace the floor instruction
1542 // with its inputs. This happens before the representation changes are
1543 // introduced.
1544 if (op() == kMathFloor) {
1545 if (value()->representation().IsInteger32()) return value();
1546 }
1547 return this;
1548 }
1549
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001550 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001551 const char* OpName() const;
1552
1553 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary_math_operation")
1554
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001555 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001556 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001557 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1558 return op_ == b->op();
1559 }
1560
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001561 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001562 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001563};
1564
1565
1566class HLoadElements: public HUnaryOperation {
1567 public:
1568 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1569 set_representation(Representation::Tagged());
1570 SetFlag(kUseGVN);
1571 SetFlag(kDependsOnMaps);
1572 }
1573
1574 virtual Representation RequiredInputRepresentation(int index) const {
1575 return Representation::Tagged();
1576 }
1577
1578 DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001579
1580 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001581 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001582};
1583
1584
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001585class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001586 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001587 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001588 : HUnaryOperation(value) {
1589 set_representation(Representation::External());
1590 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001591 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001592 // change once set, so it's no necessary to introduce any additional
1593 // dependencies on top of the inputs.
1594 SetFlag(kUseGVN);
1595 }
1596
1597 virtual Representation RequiredInputRepresentation(int index) const {
1598 return Representation::Tagged();
1599 }
1600
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001601 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer,
1602 "load-external-array-pointer")
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001603
1604 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001605 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001606};
1607
1608
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001609class HCheckMap: public HUnaryOperation {
1610 public:
1611 HCheckMap(HValue* value, Handle<Map> map)
1612 : HUnaryOperation(value), map_(map) {
1613 set_representation(Representation::Tagged());
1614 SetFlag(kUseGVN);
1615 SetFlag(kDependsOnMaps);
1616 }
1617
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001618 virtual bool IsCheckInstruction() const { return true; }
1619
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001620 virtual Representation RequiredInputRepresentation(int index) const {
1621 return Representation::Tagged();
1622 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001623 virtual void PrintDataTo(StringStream* stream);
1624 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001625
1626#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001627 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001628#endif
1629
1630 Handle<Map> map() const { return map_; }
1631
1632 DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check_map")
1633
1634 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001635 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001636 HCheckMap* b = HCheckMap::cast(other);
1637 return map_.is_identical_to(b->map());
1638 }
1639
1640 private:
1641 Handle<Map> map_;
1642};
1643
1644
1645class HCheckFunction: public HUnaryOperation {
1646 public:
1647 HCheckFunction(HValue* value, Handle<JSFunction> function)
1648 : HUnaryOperation(value), target_(function) {
1649 set_representation(Representation::Tagged());
1650 SetFlag(kUseGVN);
1651 }
1652
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001653 virtual bool IsCheckInstruction() const { return true; }
1654
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001655 virtual Representation RequiredInputRepresentation(int index) const {
1656 return Representation::Tagged();
1657 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001658 virtual void PrintDataTo(StringStream* stream);
1659 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001660
1661#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001662 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001663#endif
1664
1665 Handle<JSFunction> target() const { return target_; }
1666
1667 DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check_function")
1668
1669 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001670 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001671 HCheckFunction* b = HCheckFunction::cast(other);
1672 return target_.is_identical_to(b->target());
1673 }
1674
1675 private:
1676 Handle<JSFunction> target_;
1677};
1678
1679
1680class HCheckInstanceType: public HUnaryOperation {
1681 public:
1682 // Check that the instance type is in the range [first, last] where
1683 // both first and last are included.
1684 HCheckInstanceType(HValue* value, InstanceType first, InstanceType last)
1685 : HUnaryOperation(value), first_(first), last_(last) {
1686 ASSERT(first <= last);
1687 set_representation(Representation::Tagged());
1688 SetFlag(kUseGVN);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001689 if ((FIRST_STRING_TYPE < first && last <= LAST_STRING_TYPE) ||
1690 (FIRST_STRING_TYPE <= first && last < LAST_STRING_TYPE)) {
1691 // A particular string instance type can change because of GC or
1692 // externalization, but the value still remains a string.
1693 SetFlag(kDependsOnMaps);
1694 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001695 }
1696
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001697 virtual bool IsCheckInstruction() const { return true; }
1698
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001699 virtual Representation RequiredInputRepresentation(int index) const {
1700 return Representation::Tagged();
1701 }
1702
1703#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001704 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001705#endif
1706
1707 static HCheckInstanceType* NewIsJSObjectOrJSFunction(HValue* value);
1708
1709 InstanceType first() const { return first_; }
1710 InstanceType last() const { return last_; }
1711
1712 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check_instance_type")
1713
1714 protected:
1715 // TODO(ager): It could be nice to allow the ommision of instance
1716 // type checks if we have already performed an instance type check
1717 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001718 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001719 HCheckInstanceType* b = HCheckInstanceType::cast(other);
1720 return (first_ == b->first()) && (last_ == b->last());
1721 }
1722
1723 private:
1724 InstanceType first_;
1725 InstanceType last_;
1726};
1727
1728
1729class HCheckNonSmi: public HUnaryOperation {
1730 public:
1731 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
1732 set_representation(Representation::Tagged());
1733 SetFlag(kUseGVN);
1734 }
1735
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001736 virtual bool IsCheckInstruction() const { return true; }
1737
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001738 virtual Representation RequiredInputRepresentation(int index) const {
1739 return Representation::Tagged();
1740 }
1741
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001742 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001743
1744#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001745 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001746#endif
1747
1748 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check_non_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001749
1750 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001751 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001752};
1753
1754
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001755class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001756 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001757 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
1758 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001759 SetFlag(kUseGVN);
1760 SetFlag(kDependsOnMaps);
1761 }
1762
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001763 virtual bool IsCheckInstruction() const { return true; }
1764
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001765#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001766 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001767#endif
1768
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001769 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001770 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001771
1772 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check_prototype_maps")
1773
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001774 virtual Representation RequiredInputRepresentation(int index) const {
1775 return Representation::None();
1776 }
1777
1778 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001779 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001780 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
1781 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
1782 return hash;
1783 }
1784
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001785 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001786 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001787 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001788 return prototype_.is_identical_to(b->prototype()) &&
1789 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001790 }
1791
1792 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001793 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001794 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001795};
1796
1797
1798class HCheckSmi: public HUnaryOperation {
1799 public:
1800 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
1801 set_representation(Representation::Tagged());
1802 SetFlag(kUseGVN);
1803 }
1804
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001805 virtual bool IsCheckInstruction() const { return true; }
1806
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001807 virtual Representation RequiredInputRepresentation(int index) const {
1808 return Representation::Tagged();
1809 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001810 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001811
1812#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001813 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001814#endif
1815
1816 DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001817
1818 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001819 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001820};
1821
1822
1823class HPhi: public HValue {
1824 public:
1825 explicit HPhi(int merged_index)
1826 : inputs_(2),
1827 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001828 phi_id_(-1),
1829 is_live_(false) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001830 for (int i = 0; i < Representation::kNumRepresentations; i++) {
1831 non_phi_uses_[i] = 0;
1832 indirect_uses_[i] = 0;
1833 }
1834 ASSERT(merged_index >= 0);
1835 set_representation(Representation::Tagged());
1836 SetFlag(kFlexibleRepresentation);
1837 }
1838
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001839 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001840 bool double_occurred = false;
1841 bool int32_occurred = false;
1842 for (int i = 0; i < OperandCount(); ++i) {
1843 HValue* value = OperandAt(i);
1844 if (value->representation().IsDouble()) double_occurred = true;
1845 if (value->representation().IsInteger32()) int32_occurred = true;
1846 if (value->representation().IsTagged()) return Representation::Tagged();
1847 }
1848
1849 if (double_occurred) return Representation::Double();
1850 if (int32_occurred) return Representation::Integer32();
1851 return Representation::None();
1852 }
1853
1854 virtual Range* InferRange();
1855 virtual Representation RequiredInputRepresentation(int index) const {
1856 return representation();
1857 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001858 virtual HType CalculateInferredType();
1859 virtual int OperandCount() { return inputs_.length(); }
1860 virtual HValue* OperandAt(int index) { return inputs_[index]; }
1861 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001862 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001863 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001864
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00001865 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001866
1867 int merged_index() const { return merged_index_; }
1868
1869 virtual const char* Mnemonic() const { return "phi"; }
1870
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001871 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001872
1873#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001874 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001875#endif
1876
1877 DECLARE_INSTRUCTION(Phi)
1878
1879 void InitRealUses(int id);
1880 void AddNonPhiUsesFrom(HPhi* other);
1881 void AddIndirectUsesTo(int* use_count);
1882
1883 int tagged_non_phi_uses() const {
1884 return non_phi_uses_[Representation::kTagged];
1885 }
1886 int int32_non_phi_uses() const {
1887 return non_phi_uses_[Representation::kInteger32];
1888 }
1889 int double_non_phi_uses() const {
1890 return non_phi_uses_[Representation::kDouble];
1891 }
1892 int tagged_indirect_uses() const {
1893 return indirect_uses_[Representation::kTagged];
1894 }
1895 int int32_indirect_uses() const {
1896 return indirect_uses_[Representation::kInteger32];
1897 }
1898 int double_indirect_uses() const {
1899 return indirect_uses_[Representation::kDouble];
1900 }
1901 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001902 bool is_live() { return is_live_; }
1903 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001904
1905 protected:
1906 virtual void DeleteFromGraph();
1907 virtual void InternalSetOperandAt(int index, HValue* value) {
1908 inputs_[index] = value;
1909 }
1910
1911 private:
1912 ZoneList<HValue*> inputs_;
1913 int merged_index_;
1914
1915 int non_phi_uses_[Representation::kNumRepresentations];
1916 int indirect_uses_[Representation::kNumRepresentations];
1917 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001918 bool is_live_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001919};
1920
1921
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001922class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001923 public:
1924 HArgumentsObject() {
1925 set_representation(Representation::Tagged());
1926 SetFlag(kIsArguments);
1927 }
1928
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001929 virtual Representation RequiredInputRepresentation(int index) const {
1930 return Representation::None();
1931 }
1932
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001933 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject, "arguments-object")
1934};
1935
1936
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001937class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001938 public:
1939 HConstant(Handle<Object> handle, Representation r);
1940
1941 Handle<Object> handle() const { return handle_; }
1942
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001943 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001944
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001945 virtual Representation RequiredInputRepresentation(int index) const {
1946 return Representation::None();
1947 }
1948
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001949 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001950 virtual void PrintDataTo(StringStream* stream);
1951 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001952 bool IsInteger() const { return handle_->IsSmi(); }
1953 HConstant* CopyToRepresentation(Representation r) const;
1954 HConstant* CopyToTruncatedInt32() const;
1955 bool HasInteger32Value() const { return has_int32_value_; }
1956 int32_t Integer32Value() const {
1957 ASSERT(HasInteger32Value());
1958 return int32_value_;
1959 }
1960 bool HasDoubleValue() const { return has_double_value_; }
1961 double DoubleValue() const {
1962 ASSERT(HasDoubleValue());
1963 return double_value_;
1964 }
1965 bool HasStringValue() const { return handle_->IsString(); }
1966
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001967 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001968 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001969 return reinterpret_cast<intptr_t>(*handle());
1970 }
1971
1972#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001973 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001974#endif
1975
1976 DECLARE_CONCRETE_INSTRUCTION(Constant, "constant")
1977
1978 protected:
1979 virtual Range* InferRange();
1980
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001981 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001982 HConstant* other_constant = HConstant::cast(other);
1983 return handle().is_identical_to(other_constant->handle());
1984 }
1985
1986 private:
1987 Handle<Object> handle_;
1988 HType constant_type_;
1989
1990 // The following two values represent the int32 and the double value of the
1991 // given constant if there is a lossless conversion between the constant
1992 // and the specific representation.
1993 bool has_int32_value_;
1994 int32_t int32_value_;
1995 bool has_double_value_;
1996 double double_value_;
1997};
1998
1999
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002000class HBinaryOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002001 public:
2002 HBinaryOperation(HValue* left, HValue* right) {
2003 ASSERT(left != NULL && right != NULL);
2004 SetOperandAt(0, left);
2005 SetOperandAt(1, right);
2006 }
2007
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002008 HValue* left() { return OperandAt(0); }
2009 HValue* right() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002010
2011 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2012 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002013 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002014 if (IsCommutative() && left()->IsConstant()) return right();
2015 return left();
2016 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002017 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002018 if (IsCommutative() && left()->IsConstant()) return left();
2019 return right();
2020 }
2021
2022 virtual bool IsCommutative() const { return false; }
2023
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002024 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002025
2026 DECLARE_INSTRUCTION(BinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002027};
2028
2029
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002030class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002031 public:
2032 HApplyArguments(HValue* function,
2033 HValue* receiver,
2034 HValue* length,
2035 HValue* elements) {
2036 set_representation(Representation::Tagged());
2037 SetOperandAt(0, function);
2038 SetOperandAt(1, receiver);
2039 SetOperandAt(2, length);
2040 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002041 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002042 }
2043
2044 virtual Representation RequiredInputRepresentation(int index) const {
2045 // The length is untagged, all other inputs are tagged.
2046 return (index == 2)
2047 ? Representation::Integer32()
2048 : Representation::Tagged();
2049 }
2050
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002051 HValue* function() { return OperandAt(0); }
2052 HValue* receiver() { return OperandAt(1); }
2053 HValue* length() { return OperandAt(2); }
2054 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002055
2056 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply_arguments")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002057};
2058
2059
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002060class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002061 public:
2062 HArgumentsElements() {
2063 // The value produced by this instruction is a pointer into the stack
2064 // that looks as if it was a smi because of alignment.
2065 set_representation(Representation::Tagged());
2066 SetFlag(kUseGVN);
2067 }
2068
2069 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments_elements")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002070
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002071 virtual Representation RequiredInputRepresentation(int index) const {
2072 return Representation::None();
2073 }
2074
ager@chromium.org378b34e2011-01-28 08:04:38 +00002075 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002076 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002077};
2078
2079
2080class HArgumentsLength: public HUnaryOperation {
2081 public:
2082 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2083 set_representation(Representation::Integer32());
2084 SetFlag(kUseGVN);
2085 }
2086
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002087 virtual Representation RequiredInputRepresentation(int index) const {
2088 return Representation::Tagged();
2089 }
2090
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002091 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002092
2093 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002094 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002095};
2096
2097
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002098class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002099 public:
2100 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2101 set_representation(Representation::Tagged());
2102 SetFlag(kUseGVN);
2103 SetOperandAt(0, arguments);
2104 SetOperandAt(1, length);
2105 SetOperandAt(2, index);
2106 }
2107
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002108 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002109
2110 virtual Representation RequiredInputRepresentation(int index) const {
2111 // The arguments elements is considered tagged.
2112 return index == 0
2113 ? Representation::Tagged()
2114 : Representation::Integer32();
2115 }
2116
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002117 HValue* arguments() { return OperandAt(0); }
2118 HValue* length() { return OperandAt(1); }
2119 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002120
2121 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access_arguments_at")
2122
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002123 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002124};
2125
2126
2127class HBoundsCheck: public HBinaryOperation {
2128 public:
2129 HBoundsCheck(HValue* index, HValue* length)
2130 : HBinaryOperation(index, length) {
2131 SetFlag(kUseGVN);
2132 }
2133
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002134 virtual bool IsCheckInstruction() const { return true; }
2135
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002136 virtual Representation RequiredInputRepresentation(int index) const {
2137 return Representation::Integer32();
2138 }
2139
2140#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002141 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002142#endif
2143
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002144 HValue* index() { return left(); }
2145 HValue* length() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002146
2147 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds_check")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002148
2149 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002150 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002151};
2152
2153
2154class HBitwiseBinaryOperation: public HBinaryOperation {
2155 public:
2156 HBitwiseBinaryOperation(HValue* left, HValue* right)
2157 : HBinaryOperation(left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002158 set_representation(Representation::Tagged());
2159 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002160 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002161 }
2162
2163 virtual Representation RequiredInputRepresentation(int index) const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002164 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002165 }
2166
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002167 virtual void RepresentationChanged(Representation to) {
2168 if (!to.IsTagged()) {
2169 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002170 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002171 SetFlag(kTruncatingToInt32);
2172 SetFlag(kUseGVN);
2173 }
2174 }
2175
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002176 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002177
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002178 DECLARE_INSTRUCTION(BitwiseBinaryOperation)
2179};
2180
2181
2182class HArithmeticBinaryOperation: public HBinaryOperation {
2183 public:
2184 HArithmeticBinaryOperation(HValue* left, HValue* right)
2185 : HBinaryOperation(left, right) {
2186 set_representation(Representation::Tagged());
2187 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002188 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002189 }
2190
2191 virtual void RepresentationChanged(Representation to) {
2192 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002193 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002194 SetFlag(kUseGVN);
2195 }
2196 }
2197
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002198 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002199 virtual Representation RequiredInputRepresentation(int index) const {
2200 return representation();
2201 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002202 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002203 if (left()->representation().Equals(right()->representation())) {
2204 return left()->representation();
2205 }
2206 return HValue::InferredRepresentation();
2207 }
2208
2209 DECLARE_INSTRUCTION(ArithmeticBinaryOperation)
2210};
2211
2212
2213class HCompare: public HBinaryOperation {
2214 public:
2215 HCompare(HValue* left, HValue* right, Token::Value token)
2216 : HBinaryOperation(left, right), token_(token) {
2217 ASSERT(Token::IsCompareOp(token));
2218 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002219 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002220 }
2221
2222 void SetInputRepresentation(Representation r);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002223
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002224 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002225 return !HasSideEffects() && (uses()->length() <= 1);
2226 }
2227
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002228 virtual Representation RequiredInputRepresentation(int index) const {
2229 return input_representation_;
2230 }
2231 Representation GetInputRepresentation() const {
2232 return input_representation_;
2233 }
2234 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002235 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002236
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002237 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002238
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002239 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002240 return HValue::Hashcode() * 7 + token_;
2241 }
2242
2243 DECLARE_CONCRETE_INSTRUCTION(Compare, "compare")
2244
2245 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002246 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002247 HCompare* comp = HCompare::cast(other);
2248 return token_ == comp->token();
2249 }
2250
2251 private:
2252 Representation input_representation_;
2253 Token::Value token_;
2254};
2255
2256
2257class HCompareJSObjectEq: public HBinaryOperation {
2258 public:
2259 HCompareJSObjectEq(HValue* left, HValue* right)
2260 : HBinaryOperation(left, right) {
2261 set_representation(Representation::Tagged());
2262 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002263 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002264 }
2265
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002266 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002267 return !HasSideEffects() && (uses()->length() <= 1);
2268 }
2269
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002270 virtual Representation RequiredInputRepresentation(int index) const {
2271 return Representation::Tagged();
2272 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002273 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002274
2275 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq, "compare-js-object-eq")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002276
2277 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002278 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002279};
2280
2281
2282class HUnaryPredicate: public HUnaryOperation {
2283 public:
2284 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2285 set_representation(Representation::Tagged());
2286 SetFlag(kUseGVN);
2287 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002288
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002289 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002290 return !HasSideEffects() && (uses()->length() <= 1);
2291 }
2292
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002293 virtual Representation RequiredInputRepresentation(int index) const {
2294 return Representation::Tagged();
2295 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002296 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002297};
2298
2299
2300class HIsNull: public HUnaryPredicate {
2301 public:
2302 HIsNull(HValue* value, bool is_strict)
2303 : HUnaryPredicate(value), is_strict_(is_strict) { }
2304
2305 bool is_strict() const { return is_strict_; }
2306
2307 DECLARE_CONCRETE_INSTRUCTION(IsNull, "is_null")
2308
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002309 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002310 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002311 HIsNull* b = HIsNull::cast(other);
2312 return is_strict_ == b->is_strict();
2313 }
2314
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002315 private:
2316 bool is_strict_;
2317};
2318
2319
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002320class HIsObject: public HUnaryPredicate {
2321 public:
2322 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2323
2324 DECLARE_CONCRETE_INSTRUCTION(IsObject, "is_object")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002325
2326 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002327 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002328};
2329
2330
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002331class HIsSmi: public HUnaryPredicate {
2332 public:
2333 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2334
2335 DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002336
2337 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002338 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002339};
2340
2341
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002342class HIsConstructCall: public HTemplateInstruction<0> {
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002343 public:
2344 HIsConstructCall() {
2345 set_representation(Representation::Tagged());
2346 SetFlag(kUseGVN);
2347 }
2348
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002349 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002350 return !HasSideEffects() && (uses()->length() <= 1);
2351 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002352
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002353 virtual Representation RequiredInputRepresentation(int index) const {
2354 return Representation::None();
2355 }
2356
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002357 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall, "is_construct_call")
2358
2359 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002360 virtual bool DataEquals(HValue* other) { return true; }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002361};
2362
2363
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002364class HHasInstanceType: public HUnaryPredicate {
2365 public:
2366 HHasInstanceType(HValue* value, InstanceType type)
2367 : HUnaryPredicate(value), from_(type), to_(type) { }
2368 HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2369 : HUnaryPredicate(value), from_(from), to_(to) {
2370 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2371 }
2372
2373 InstanceType from() { return from_; }
2374 InstanceType to() { return to_; }
2375
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002376 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002377
2378 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has_instance_type")
2379
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002380 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002381 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002382 HHasInstanceType* b = HHasInstanceType::cast(other);
2383 return (from_ == b->from()) && (to_ == b->to());
2384 }
2385
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002386 private:
2387 InstanceType from_;
2388 InstanceType to_; // Inclusive range, not all combinations work.
2389};
2390
2391
2392class HHasCachedArrayIndex: public HUnaryPredicate {
2393 public:
2394 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2395
2396 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has_cached_array_index")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002397
2398 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002399 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002400};
2401
2402
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002403class HGetCachedArrayIndex: public HUnaryPredicate {
2404 public:
2405 explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2406
2407 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get_cached_array_index")
2408
2409 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002410 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002411};
2412
2413
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002414class HClassOfTest: public HUnaryPredicate {
2415 public:
2416 HClassOfTest(HValue* value, Handle<String> class_name)
2417 : HUnaryPredicate(value), class_name_(class_name) { }
2418
2419 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class_of_test")
2420
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002421 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002422
2423 Handle<String> class_name() const { return class_name_; }
2424
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002425 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002426 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002427 HClassOfTest* b = HClassOfTest::cast(other);
2428 return class_name_.is_identical_to(b->class_name_);
2429 }
2430
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002431 private:
2432 Handle<String> class_name_;
2433};
2434
2435
2436class HTypeofIs: public HUnaryPredicate {
2437 public:
2438 HTypeofIs(HValue* value, Handle<String> type_literal)
2439 : HUnaryPredicate(value), type_literal_(type_literal) { }
2440
2441 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002442 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002443
2444 DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof_is")
2445
2446 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002447 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002448 HTypeofIs* b = HTypeofIs::cast(other);
2449 return type_literal_.is_identical_to(b->type_literal_);
2450 }
2451
2452 private:
2453 Handle<String> type_literal_;
2454};
2455
2456
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002457class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002458 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002459 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2460 SetOperandAt(0, context);
2461 SetOperandAt(1, left);
2462 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002463 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002464 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002465 }
2466
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002467 HValue* context() { return OperandAt(0); }
2468 HValue* left() { return OperandAt(1); }
2469 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002470
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002471 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002472 return !HasSideEffects() && (uses()->length() <= 1);
2473 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002474
2475 virtual Representation RequiredInputRepresentation(int index) const {
2476 return Representation::Tagged();
2477 }
2478
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002479 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002480
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002481 DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance_of")
2482};
2483
2484
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002485class HInstanceOfKnownGlobal: public HUnaryOperation {
2486 public:
2487 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2488 : HUnaryOperation(left), function_(right) {
2489 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002490 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002491 }
2492
2493 Handle<JSFunction> function() { return function_; }
2494
2495 virtual Representation RequiredInputRepresentation(int index) const {
2496 return Representation::Tagged();
2497 }
2498
2499 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
2500 "instance_of_known_global")
2501
2502 private:
2503 Handle<JSFunction> function_;
2504};
2505
2506
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002507class HPower: public HBinaryOperation {
2508 public:
2509 HPower(HValue* left, HValue* right)
2510 : HBinaryOperation(left, right) {
2511 set_representation(Representation::Double());
2512 SetFlag(kUseGVN);
2513 }
2514
2515 virtual Representation RequiredInputRepresentation(int index) const {
2516 return (index == 1) ? Representation::None() : Representation::Double();
2517 }
2518
2519 DECLARE_CONCRETE_INSTRUCTION(Power, "power")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002520
2521 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002522 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002523};
2524
2525
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002526class HAdd: public HArithmeticBinaryOperation {
2527 public:
2528 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2529 SetFlag(kCanOverflow);
2530 }
2531
2532 // Add is only commutative if two integer values are added and not if two
2533 // tagged values are added (because it might be a String concatenation).
2534 virtual bool IsCommutative() const {
2535 return !representation().IsTagged();
2536 }
2537
2538 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2539
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002540 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002541
2542 DECLARE_CONCRETE_INSTRUCTION(Add, "add")
2543
2544 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002545 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002546
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002547 virtual Range* InferRange();
2548};
2549
2550
2551class HSub: public HArithmeticBinaryOperation {
2552 public:
2553 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2554 SetFlag(kCanOverflow);
2555 }
2556
2557 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2558
2559 DECLARE_CONCRETE_INSTRUCTION(Sub, "sub")
2560
2561 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002562 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002563
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002564 virtual Range* InferRange();
2565};
2566
2567
2568class HMul: public HArithmeticBinaryOperation {
2569 public:
2570 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2571 SetFlag(kCanOverflow);
2572 }
2573
2574 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2575
2576 // Only commutative if it is certain that not two objects are multiplicated.
2577 virtual bool IsCommutative() const {
2578 return !representation().IsTagged();
2579 }
2580
2581 DECLARE_CONCRETE_INSTRUCTION(Mul, "mul")
2582
2583 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002584 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002585
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002586 virtual Range* InferRange();
2587};
2588
2589
2590class HMod: public HArithmeticBinaryOperation {
2591 public:
2592 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2593 SetFlag(kCanBeDivByZero);
2594 }
2595
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002596 bool HasPowerOf2Divisor() {
2597 if (right()->IsConstant() &&
2598 HConstant::cast(right())->HasInteger32Value()) {
2599 int32_t value = HConstant::cast(right())->Integer32Value();
2600 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2601 }
2602
2603 return false;
2604 }
2605
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002606 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2607
2608 DECLARE_CONCRETE_INSTRUCTION(Mod, "mod")
2609
2610 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002611 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002612
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002613 virtual Range* InferRange();
2614};
2615
2616
2617class HDiv: public HArithmeticBinaryOperation {
2618 public:
2619 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2620 SetFlag(kCanBeDivByZero);
2621 SetFlag(kCanOverflow);
2622 }
2623
2624 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2625
2626 DECLARE_CONCRETE_INSTRUCTION(Div, "div")
2627
2628 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002629 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002630
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002631 virtual Range* InferRange();
2632};
2633
2634
2635class HBitAnd: public HBitwiseBinaryOperation {
2636 public:
2637 HBitAnd(HValue* left, HValue* right)
2638 : HBitwiseBinaryOperation(left, right) { }
2639
2640 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002641 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002642
2643 DECLARE_CONCRETE_INSTRUCTION(BitAnd, "bit_and")
2644
2645 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002646 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002647
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002648 virtual Range* InferRange();
2649};
2650
2651
2652class HBitXor: public HBitwiseBinaryOperation {
2653 public:
2654 HBitXor(HValue* left, HValue* right)
2655 : HBitwiseBinaryOperation(left, right) { }
2656
2657 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002658 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002659
2660 DECLARE_CONCRETE_INSTRUCTION(BitXor, "bit_xor")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002661
2662 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002663 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002664};
2665
2666
2667class HBitOr: public HBitwiseBinaryOperation {
2668 public:
2669 HBitOr(HValue* left, HValue* right)
2670 : HBitwiseBinaryOperation(left, right) { }
2671
2672 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002673 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002674
2675 DECLARE_CONCRETE_INSTRUCTION(BitOr, "bit_or")
2676
2677 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002678 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002679
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002680 virtual Range* InferRange();
2681};
2682
2683
2684class HShl: public HBitwiseBinaryOperation {
2685 public:
2686 HShl(HValue* left, HValue* right)
2687 : HBitwiseBinaryOperation(left, right) { }
2688
2689 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002690 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002691
2692 DECLARE_CONCRETE_INSTRUCTION(Shl, "shl")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002693
2694 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002695 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002696};
2697
2698
2699class HShr: public HBitwiseBinaryOperation {
2700 public:
2701 HShr(HValue* left, HValue* right)
2702 : HBitwiseBinaryOperation(left, right) { }
2703
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002704 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002705
2706 DECLARE_CONCRETE_INSTRUCTION(Shr, "shr")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002707
2708 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002709 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002710};
2711
2712
2713class HSar: public HBitwiseBinaryOperation {
2714 public:
2715 HSar(HValue* left, HValue* right)
2716 : HBitwiseBinaryOperation(left, right) { }
2717
2718 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002719 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002720
2721 DECLARE_CONCRETE_INSTRUCTION(Sar, "sar")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002722
2723 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002724 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002725};
2726
2727
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002728class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002729 public:
2730 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
2731 SetFlag(kChangesOsrEntries);
2732 }
2733
2734 int ast_id() const { return ast_id_; }
2735
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002736 virtual Representation RequiredInputRepresentation(int index) const {
2737 return Representation::None();
2738 }
2739
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002740 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr_entry")
2741
2742 private:
2743 int ast_id_;
2744};
2745
2746
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002747class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002748 public:
2749 explicit HParameter(unsigned index) : index_(index) {
2750 set_representation(Representation::Tagged());
2751 }
2752
2753 unsigned index() const { return index_; }
2754
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002755 virtual void PrintDataTo(StringStream* stream);
2756
2757 virtual Representation RequiredInputRepresentation(int index) const {
2758 return Representation::None();
2759 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002760
2761 DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
2762
2763 private:
2764 unsigned index_;
2765};
2766
2767
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002768class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002769 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002770 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
2771 : HUnaryCall(context, argument_count),
2772 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002773 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002774 }
2775
2776 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002777
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002778 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002779
2780 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
2781 transcendental_type_ = transcendental_type;
2782 }
2783 TranscendentalCache::Type transcendental_type() {
2784 return transcendental_type_;
2785 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002786
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002787 virtual void PrintDataTo(StringStream* stream);
2788
2789 virtual Representation RequiredInputRepresentation(int index) const {
2790 return Representation::Tagged();
2791 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002792
2793 DECLARE_CONCRETE_INSTRUCTION(CallStub, "call_stub")
2794
2795 private:
2796 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002797 TranscendentalCache::Type transcendental_type_;
2798};
2799
2800
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002801class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002802 public:
2803 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
2804
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002805 virtual Representation RequiredInputRepresentation(int index) const {
2806 return Representation::None();
2807 }
2808
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002809 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown_osr_value")
2810};
2811
2812
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002813class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002814 public:
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002815 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002816 : cell_(cell), check_hole_value_(check_hole_value) {
2817 set_representation(Representation::Tagged());
2818 SetFlag(kUseGVN);
2819 SetFlag(kDependsOnGlobalVars);
2820 }
2821
2822 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
2823 bool check_hole_value() const { return check_hole_value_; }
2824
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002825 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002826
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002827 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002828 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002829 return reinterpret_cast<intptr_t>(*cell_);
2830 }
2831
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002832 virtual Representation RequiredInputRepresentation(int index) const {
2833 return Representation::None();
2834 }
2835
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002836 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell, "load_global_cell")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002837
2838 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002839 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002840 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002841 return cell_.is_identical_to(b->cell());
2842 }
2843
2844 private:
2845 Handle<JSGlobalPropertyCell> cell_;
2846 bool check_hole_value_;
2847};
2848
2849
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002850class HLoadGlobalGeneric: public HBinaryOperation {
2851 public:
2852 HLoadGlobalGeneric(HValue* context,
2853 HValue* global_object,
2854 Handle<Object> name,
2855 bool for_typeof)
2856 : HBinaryOperation(context, global_object),
2857 name_(name),
2858 for_typeof_(for_typeof) {
2859 set_representation(Representation::Tagged());
2860 SetAllSideEffects();
2861 }
2862
2863 HValue* context() { return OperandAt(0); }
2864 HValue* global_object() { return OperandAt(1); }
2865 Handle<Object> name() const { return name_; }
2866 bool for_typeof() const { return for_typeof_; }
2867
2868 virtual void PrintDataTo(StringStream* stream);
2869
2870 virtual Representation RequiredInputRepresentation(int index) const {
2871 return Representation::Tagged();
2872 }
2873
2874 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load_global_generic")
2875
2876 private:
2877 Handle<Object> name_;
2878 bool for_typeof_;
2879};
2880
2881
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002882class HStoreGlobal: public HUnaryOperation {
2883 public:
ager@chromium.org378b34e2011-01-28 08:04:38 +00002884 HStoreGlobal(HValue* value,
2885 Handle<JSGlobalPropertyCell> cell,
2886 bool check_hole_value)
2887 : HUnaryOperation(value),
2888 cell_(cell),
2889 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002890 SetFlag(kChangesGlobalVars);
2891 }
2892
2893 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002894 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002895
2896 virtual Representation RequiredInputRepresentation(int index) const {
2897 return Representation::Tagged();
2898 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002899 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002900
2901 DECLARE_CONCRETE_INSTRUCTION(StoreGlobal, "store_global")
2902
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002903 private:
2904 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00002905 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002906};
2907
2908
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002909class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002910 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002911 HLoadContextSlot(HValue* context , int slot_index)
2912 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002913 set_representation(Representation::Tagged());
2914 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002915 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002916 }
2917
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002918 int slot_index() const { return slot_index_; }
2919
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002920 virtual Representation RequiredInputRepresentation(int index) const {
2921 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002922 }
2923
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002924 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002925
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002926 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load_context_slot")
2927
2928 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002929 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002930 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002931 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002932 }
2933
2934 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002935 int slot_index_;
2936};
2937
2938
2939static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
2940 return !value->type().IsSmi() &&
2941 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
2942}
2943
2944
2945class HStoreContextSlot: public HBinaryOperation {
2946 public:
2947 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
2948 : HBinaryOperation(context, value), slot_index_(slot_index) {
2949 SetFlag(kChangesContextSlots);
2950 }
2951
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002952 HValue* context() { return OperandAt(0); }
2953 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002954 int slot_index() const { return slot_index_; }
2955
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002956 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002957 return StoringValueNeedsWriteBarrier(value());
2958 }
2959
2960 virtual Representation RequiredInputRepresentation(int index) const {
2961 return Representation::Tagged();
2962 }
2963
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002964 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002965
2966 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store_context_slot")
2967
2968 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002969 int slot_index_;
2970};
2971
2972
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002973class HLoadNamedField: public HUnaryOperation {
2974 public:
2975 HLoadNamedField(HValue* object, bool is_in_object, int offset)
2976 : HUnaryOperation(object),
2977 is_in_object_(is_in_object),
2978 offset_(offset) {
2979 set_representation(Representation::Tagged());
2980 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002981 SetFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002982 if (is_in_object) {
2983 SetFlag(kDependsOnInobjectFields);
2984 } else {
2985 SetFlag(kDependsOnBackingStoreFields);
2986 }
2987 }
2988
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002989 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002990 bool is_in_object() const { return is_in_object_; }
2991 int offset() const { return offset_; }
2992
2993 virtual Representation RequiredInputRepresentation(int index) const {
2994 return Representation::Tagged();
2995 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002996 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002997
2998 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load_named_field")
2999
3000 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003001 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003002 HLoadNamedField* b = HLoadNamedField::cast(other);
3003 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3004 }
3005
3006 private:
3007 bool is_in_object_;
3008 int offset_;
3009};
3010
3011
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003012class HLoadNamedFieldPolymorphic: public HUnaryOperation {
3013 public:
3014 HLoadNamedFieldPolymorphic(HValue* object,
3015 ZoneMapList* types,
3016 Handle<String> name);
3017
3018 HValue* object() { return OperandAt(0); }
3019 ZoneMapList* types() { return &types_; }
3020 Handle<String> name() { return name_; }
3021 bool need_generic() { return need_generic_; }
3022
3023 virtual Representation RequiredInputRepresentation(int index) const {
3024 return Representation::Tagged();
3025 }
3026
3027 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic,
3028 "load_named_field_polymorphic")
3029
3030 static const int kMaxLoadPolymorphism = 4;
3031
3032 protected:
3033 virtual bool DataEquals(HValue* value);
3034
3035 private:
3036 ZoneMapList types_;
3037 Handle<String> name_;
3038 bool need_generic_;
3039};
3040
3041
3042
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003043class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003044 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003045 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
3046 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003047 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003048 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003049 }
3050
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003051 HValue* context() { return OperandAt(0); }
3052 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003053 Handle<Object> name() const { return name_; }
3054
3055 virtual Representation RequiredInputRepresentation(int index) const {
3056 return Representation::Tagged();
3057 }
3058
3059 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load_named_generic")
3060
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003061 private:
3062 Handle<Object> name_;
3063};
3064
3065
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003066class HLoadFunctionPrototype: public HUnaryOperation {
3067 public:
3068 explicit HLoadFunctionPrototype(HValue* function)
3069 : HUnaryOperation(function) {
3070 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003071 SetFlag(kUseGVN);
3072 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003073 }
3074
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003075 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003076
3077 virtual Representation RequiredInputRepresentation(int index) const {
3078 return Representation::Tagged();
3079 }
3080
3081 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load_function_prototype")
3082
3083 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003084 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003085};
3086
3087
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003088class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003089 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003090 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003091 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003092 SetFlag(kDependsOnArrayElements);
3093 SetFlag(kUseGVN);
3094 }
3095
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003096 HValue* object() { return OperandAt(0); }
3097 HValue* key() { return OperandAt(1); }
3098
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003099 virtual Representation RequiredInputRepresentation(int index) const {
3100 // The key is supposed to be Integer32.
3101 return (index == 1) ? Representation::Integer32()
3102 : Representation::Tagged();
3103 }
3104
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003105 virtual void PrintDataTo(StringStream* stream);
3106
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003107 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement,
3108 "load_keyed_fast_element")
ager@chromium.org378b34e2011-01-28 08:04:38 +00003109
3110 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003111 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003112};
3113
3114
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003115class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003116 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003117 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3118 HValue* key,
3119 ExternalArrayType array_type)
3120 : HBinaryOperation(external_elements, key),
3121 array_type_(array_type) {
3122 if (array_type == kExternalFloatArray) {
3123 set_representation(Representation::Double());
3124 } else {
3125 set_representation(Representation::Integer32());
3126 }
3127 SetFlag(kDependsOnSpecializedArrayElements);
3128 // Native code could change the specialized array.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003129 SetFlag(kDependsOnCalls);
3130 SetFlag(kUseGVN);
3131 }
3132
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003133 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003134
3135 virtual Representation RequiredInputRepresentation(int index) const {
3136 // The key is supposed to be Integer32, but the base pointer
3137 // for the element load is a naked pointer.
3138 return (index == 1) ? Representation::Integer32()
3139 : Representation::External();
3140 }
3141
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003142 HValue* external_pointer() { return OperandAt(0); }
3143 HValue* key() { return OperandAt(1); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003144 ExternalArrayType array_type() const { return array_type_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003145
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003146 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement,
3147 "load_keyed_specialized_array_element")
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003148
3149 protected:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003150 virtual bool DataEquals(HValue* other) {
3151 if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3152 HLoadKeyedSpecializedArrayElement* cast_other =
3153 HLoadKeyedSpecializedArrayElement::cast(other);
3154 return array_type_ == cast_other->array_type();
3155 }
3156
3157 private:
3158 ExternalArrayType array_type_;
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003159};
3160
3161
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003162class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003163 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003164 HLoadKeyedGeneric(HContext* context, HValue* obj, HValue* key) {
3165 set_representation(Representation::Tagged());
3166 SetOperandAt(0, obj);
3167 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003168 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003169 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003170 }
3171
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003172 HValue* object() { return OperandAt(0); }
3173 HValue* key() { return OperandAt(1); }
3174 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003175
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003176 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003177
3178 virtual Representation RequiredInputRepresentation(int index) const {
3179 return Representation::Tagged();
3180 }
3181
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003182 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load_keyed_generic")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003183};
3184
3185
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003186class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003187 public:
3188 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003189 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003190 HValue* val,
3191 bool in_object,
3192 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003193 : HBinaryOperation(obj, val),
3194 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003195 is_in_object_(in_object),
3196 offset_(offset) {
3197 if (is_in_object_) {
3198 SetFlag(kChangesInobjectFields);
3199 } else {
3200 SetFlag(kChangesBackingStoreFields);
3201 }
3202 }
3203
3204 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store_named_field")
3205
3206 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003207 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003208 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003209 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003210
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003211 HValue* object() { return OperandAt(0); }
3212 HValue* value() { return OperandAt(1); }
3213
3214 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003215 bool is_in_object() const { return is_in_object_; }
3216 int offset() const { return offset_; }
3217 Handle<Map> transition() const { return transition_; }
3218 void set_transition(Handle<Map> map) { transition_ = map; }
3219
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003220 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003221 return StoringValueNeedsWriteBarrier(value());
3222 }
3223
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003224 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003225 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003226 bool is_in_object_;
3227 int offset_;
3228 Handle<Map> transition_;
3229};
3230
3231
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003232class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003233 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003234 HStoreNamedGeneric(HValue* context,
3235 HValue* object,
3236 Handle<String> name,
3237 HValue* value)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003238 : name_(name) {
3239 SetOperandAt(0, object);
3240 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003241 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003242 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003243 }
3244
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003245 HValue* object() { return OperandAt(0); }
3246 HValue* value() { return OperandAt(1); }
3247 HValue* context() { return OperandAt(2); }
3248 Handle<String> name() { return name_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003249
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003250 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003251
3252 virtual Representation RequiredInputRepresentation(int index) const {
3253 return Representation::Tagged();
3254 }
3255
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003256 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store_named_generic")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003257
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003258 private:
3259 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003260};
3261
3262
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003263class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003264 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003265 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3266 SetOperandAt(0, obj);
3267 SetOperandAt(1, key);
3268 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003269 SetFlag(kChangesArrayElements);
3270 }
3271
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003272 virtual Representation RequiredInputRepresentation(int index) const {
3273 // The key is supposed to be Integer32.
3274 return (index == 1) ? Representation::Integer32()
3275 : Representation::Tagged();
3276 }
3277
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003278 HValue* object() { return OperandAt(0); }
3279 HValue* key() { return OperandAt(1); }
3280 HValue* value() { return OperandAt(2); }
3281
3282 bool NeedsWriteBarrier() {
3283 return StoringValueNeedsWriteBarrier(value());
3284 }
3285
3286 virtual void PrintDataTo(StringStream* stream);
3287
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003288 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
3289 "store_keyed_fast_element")
3290};
3291
3292
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003293class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003294 public:
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003295 HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3296 HValue* key,
3297 HValue* val,
3298 ExternalArrayType array_type)
3299 : array_type_(array_type) {
3300 SetFlag(kChangesSpecializedArrayElements);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003301 SetOperandAt(0, external_elements);
3302 SetOperandAt(1, key);
3303 SetOperandAt(2, val);
3304 }
3305
3306 virtual void PrintDataTo(StringStream* stream);
3307
3308 virtual Representation RequiredInputRepresentation(int index) const {
3309 if (index == 0) {
3310 return Representation::External();
3311 } else {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003312 if (index == 2 && array_type() == kExternalFloatArray) {
3313 return Representation::Double();
3314 } else {
3315 return Representation::Integer32();
3316 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003317 }
3318 }
3319
3320 HValue* external_pointer() { return OperandAt(0); }
3321 HValue* key() { return OperandAt(1); }
3322 HValue* value() { return OperandAt(2); }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003323 ExternalArrayType array_type() const { return array_type_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003324
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003325 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,
3326 "store_keyed_specialized_array_element")
3327 private:
3328 ExternalArrayType array_type_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003329};
3330
3331
3332class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003333 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003334 HStoreKeyedGeneric(HValue* context,
3335 HValue* object,
3336 HValue* key,
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003337 HValue* value) {
3338 SetOperandAt(0, object);
3339 SetOperandAt(1, key);
3340 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003341 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003342 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003343 }
3344
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003345 HValue* object() { return OperandAt(0); }
3346 HValue* key() { return OperandAt(1); }
3347 HValue* value() { return OperandAt(2); }
3348 HValue* context() { return OperandAt(3); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003349
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003350 virtual Representation RequiredInputRepresentation(int index) const {
3351 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003352 }
3353
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003354 virtual void PrintDataTo(StringStream* stream);
3355
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003356 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store_keyed_generic")
3357};
3358
3359
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003360class HStringCharCodeAt: public HBinaryOperation {
3361 public:
3362 HStringCharCodeAt(HValue* string, HValue* index)
3363 : HBinaryOperation(string, index) {
3364 set_representation(Representation::Integer32());
3365 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003366 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003367 }
3368
3369 virtual Representation RequiredInputRepresentation(int index) const {
3370 // The index is supposed to be Integer32.
3371 return (index == 1) ? Representation::Integer32()
3372 : Representation::Tagged();
3373 }
3374
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003375 HValue* string() { return OperandAt(0); }
3376 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003377
3378 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string_char_code_at")
3379
3380 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003381 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003382
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003383 virtual Range* InferRange() {
3384 return new Range(0, String::kMaxUC16CharCode);
3385 }
3386};
3387
3388
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003389class HStringCharFromCode: public HUnaryOperation {
3390 public:
3391 explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
3392 set_representation(Representation::Tagged());
3393 SetFlag(kUseGVN);
3394 }
3395
3396 virtual Representation RequiredInputRepresentation(int index) const {
3397 return Representation::Integer32();
3398 }
3399
3400 virtual bool DataEquals(HValue* other) { return true; }
3401
3402 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string_char_from_code")
3403};
3404
3405
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003406class HStringLength: public HUnaryOperation {
3407 public:
3408 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3409 set_representation(Representation::Tagged());
3410 SetFlag(kUseGVN);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003411 SetFlag(kDependsOnMaps);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003412 }
3413
3414 virtual Representation RequiredInputRepresentation(int index) const {
3415 return Representation::Tagged();
3416 }
3417
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003418 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003419 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3420 return HType::Smi();
3421 }
3422
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003423 DECLARE_CONCRETE_INSTRUCTION(StringLength, "string_length")
3424
3425 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003426 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003427
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003428 virtual Range* InferRange() {
3429 return new Range(0, String::kMaxLength);
3430 }
3431};
3432
3433
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003434template <int V>
3435class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003436 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003437 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003438 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003439 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003440 }
3441
3442 int literal_index() const { return literal_index_; }
3443 int depth() const { return depth_; }
3444
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003445 private:
3446 int literal_index_;
3447 int depth_;
3448};
3449
3450
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003451class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003452 public:
3453 HArrayLiteral(Handle<FixedArray> constant_elements,
3454 int length,
3455 int literal_index,
3456 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003457 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003458 length_(length),
3459 constant_elements_(constant_elements) {}
3460
3461 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3462 int length() const { return length_; }
3463
3464 bool IsCopyOnWrite() const;
3465
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003466 virtual Representation RequiredInputRepresentation(int index) const {
3467 return Representation::None();
3468 }
3469
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003470 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array_literal")
3471
3472 private:
3473 int length_;
3474 Handle<FixedArray> constant_elements_;
3475};
3476
3477
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003478class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003479 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003480 HObjectLiteral(HValue* context,
3481 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003482 bool fast_elements,
3483 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003484 int depth,
3485 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003486 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003487 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003488 fast_elements_(fast_elements),
3489 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003490 SetOperandAt(0, context);
3491 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003492
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003493 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003494 Handle<FixedArray> constant_properties() const {
3495 return constant_properties_;
3496 }
3497 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003498 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003499
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003500 virtual Representation RequiredInputRepresentation(int index) const {
3501 return Representation::Tagged();
3502 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003503
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003504 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object_literal")
3505
3506 private:
3507 Handle<FixedArray> constant_properties_;
3508 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003509 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003510};
3511
3512
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003513class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003514 public:
3515 HRegExpLiteral(Handle<String> pattern,
3516 Handle<String> flags,
3517 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003518 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003519 pattern_(pattern),
3520 flags_(flags) { }
3521
3522 Handle<String> pattern() { return pattern_; }
3523 Handle<String> flags() { return flags_; }
3524
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003525 virtual Representation RequiredInputRepresentation(int index) const {
3526 return Representation::None();
3527 }
3528
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003529 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp_literal")
3530
3531 private:
3532 Handle<String> pattern_;
3533 Handle<String> flags_;
3534};
3535
3536
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003537class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003538 public:
3539 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3540 : shared_info_(shared), pretenure_(pretenure) {
3541 set_representation(Representation::Tagged());
3542 }
3543
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003544 virtual Representation RequiredInputRepresentation(int index) const {
3545 return Representation::None();
3546 }
3547
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003548 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function_literal")
3549
3550 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3551 bool pretenure() const { return pretenure_; }
3552
3553 private:
3554 Handle<SharedFunctionInfo> shared_info_;
3555 bool pretenure_;
3556};
3557
3558
3559class HTypeof: public HUnaryOperation {
3560 public:
3561 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
3562 set_representation(Representation::Tagged());
3563 }
3564
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003565 virtual Representation RequiredInputRepresentation(int index) const {
3566 return Representation::Tagged();
3567 }
3568
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003569 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
3570};
3571
3572
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003573class HToFastProperties: public HUnaryOperation {
3574 public:
3575 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
3576 // This instruction is not marked as having side effects, but
3577 // changes the map of the input operand. Use it only when creating
3578 // object literals.
3579 ASSERT(value->IsObjectLiteral());
3580 set_representation(Representation::Tagged());
3581 }
3582
3583 virtual Representation RequiredInputRepresentation(int index) const {
3584 return Representation::Tagged();
3585 }
3586
3587 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to_fast_properties")
3588};
3589
3590
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003591class HValueOf: public HUnaryOperation {
3592 public:
3593 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
3594 set_representation(Representation::Tagged());
3595 }
3596
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003597 virtual Representation RequiredInputRepresentation(int index) const {
3598 return Representation::Tagged();
3599 }
3600
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003601 DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value_of")
3602};
3603
3604
3605class HDeleteProperty: public HBinaryOperation {
3606 public:
3607 HDeleteProperty(HValue* obj, HValue* key)
3608 : HBinaryOperation(obj, key) {
3609 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003610 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003611 }
3612
3613 virtual Representation RequiredInputRepresentation(int index) const {
3614 return Representation::Tagged();
3615 }
3616
3617 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete_property")
3618
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003619 HValue* object() { return left(); }
3620 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003621};
3622
3623#undef DECLARE_INSTRUCTION
3624#undef DECLARE_CONCRETE_INSTRUCTION
3625
3626} } // namespace v8::internal
3627
3628#endif // V8_HYDROGEN_INSTRUCTIONS_H_