blob: fc376bd17be52cf5653a78f51c4246356e44e0d8 [file] [log] [blame]
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001// Copyright 2011 the V8 project authors. All rights reserved.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_HYDROGEN_INSTRUCTIONS_H_
29#define V8_HYDROGEN_INSTRUCTIONS_H_
30
31#include "v8.h"
32#include "code-stubs.h"
33#include "string-stream.h"
34#include "zone.h"
35
36namespace v8 {
37namespace internal {
38
39// Forward declarations.
40class HBasicBlock;
41class HEnvironment;
42class HInstruction;
43class HLoopInformation;
44class HValue;
45class LInstruction;
46class LChunkBuilder;
47
48
kasperl@chromium.orga5551262010-12-07 12:49:48 +000049#define HYDROGEN_ALL_INSTRUCTION_LIST(V) \
50 V(ArithmeticBinaryOperation) \
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +000051 V(BinaryCall) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000052 V(BinaryOperation) \
53 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000054 V(ControlInstruction) \
55 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000056 V(Phi) \
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +000057 V(UnaryCall) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000058 V(UnaryControlInstruction) \
59 V(UnaryOperation) \
60 HYDROGEN_CONCRETE_INSTRUCTION_LIST(V)
61
62
63#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +000064 V(AbnormalExit) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000065 V(AccessArgumentsAt) \
66 V(Add) \
67 V(ApplyArguments) \
68 V(ArgumentsElements) \
69 V(ArgumentsLength) \
70 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000071 V(ArrayLiteral) \
72 V(BitAnd) \
73 V(BitNot) \
74 V(BitOr) \
75 V(BitXor) \
76 V(BlockEntry) \
77 V(BoundsCheck) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000078 V(CallConstantFunction) \
79 V(CallFunction) \
80 V(CallGlobal) \
81 V(CallKeyed) \
82 V(CallKnownGlobal) \
83 V(CallNamed) \
84 V(CallNew) \
85 V(CallRuntime) \
86 V(CallStub) \
87 V(Change) \
88 V(CheckFunction) \
89 V(CheckInstanceType) \
90 V(CheckMap) \
91 V(CheckNonSmi) \
92 V(CheckPrototypeMaps) \
93 V(CheckSmi) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +000094 V(ClassOfTest) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000095 V(Compare) \
96 V(CompareJSObjectEq) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000097 V(CompareMap) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000098 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +000099 V(Context) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000100 V(DeleteProperty) \
101 V(Deoptimize) \
102 V(Div) \
103 V(EnterInlined) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000104 V(ExternalArrayLength) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000105 V(FixedArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000106 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000107 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000108 V(GlobalObject) \
109 V(GlobalReceiver) \
110 V(Goto) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000111 V(HasInstanceType) \
112 V(HasCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000113 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000114 V(InstanceOfKnownGlobal) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000115 V(IsNull) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000116 V(IsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000117 V(IsSmi) \
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +0000118 V(IsConstructCall) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000119 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000120 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000121 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000122 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000123 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000124 V(LoadFunctionPrototype) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000125 V(LoadGlobal) \
126 V(LoadKeyedFastElement) \
127 V(LoadKeyedGeneric) \
128 V(LoadNamedField) \
129 V(LoadNamedGeneric) \
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000130 V(LoadPixelArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000131 V(Mod) \
132 V(Mul) \
133 V(ObjectLiteral) \
134 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000135 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000136 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000137 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000138 V(PushArgument) \
139 V(RegExpLiteral) \
140 V(Return) \
141 V(Sar) \
142 V(Shl) \
143 V(Shr) \
144 V(Simulate) \
145 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000146 V(StoreContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000147 V(StoreGlobal) \
148 V(StoreKeyedFastElement) \
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000149 V(StorePixelArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000150 V(StoreKeyedGeneric) \
151 V(StoreNamedField) \
152 V(StoreNamedGeneric) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000153 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000154 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000155 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000156 V(Sub) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000157 V(Test) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000158 V(Throw) \
159 V(Typeof) \
160 V(TypeofIs) \
161 V(UnaryMathOperation) \
162 V(UnknownOSRValue) \
163 V(ValueOf)
164
165#define GVN_FLAG_LIST(V) \
166 V(Calls) \
167 V(InobjectFields) \
168 V(BackingStoreFields) \
169 V(ArrayElements) \
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000170 V(PixelArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000171 V(GlobalVars) \
172 V(Maps) \
173 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000174 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000175 V(OsrEntries)
176
177#define DECLARE_INSTRUCTION(type) \
178 virtual bool Is##type() const { return true; } \
179 static H##type* cast(HValue* value) { \
180 ASSERT(value->Is##type()); \
181 return reinterpret_cast<H##type*>(value); \
182 } \
183 Opcode opcode() const { return HValue::k##type; }
184
185
186#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
187 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
188 virtual const char* Mnemonic() const { return mnemonic; } \
189 DECLARE_INSTRUCTION(type)
190
191
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000192class Range: public ZoneObject {
193 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000194 Range()
195 : lower_(kMinInt),
196 upper_(kMaxInt),
197 next_(NULL),
198 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000199
200 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000201 : lower_(lower),
202 upper_(upper),
203 next_(NULL),
204 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000205
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000206 int32_t upper() const { return upper_; }
207 int32_t lower() const { return lower_; }
208 Range* next() const { return next_; }
209 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
210 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000211 Range* Copy() const { return new Range(lower_, upper_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000212 int32_t Mask() const;
213 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
214 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
215 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
216 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000217 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
218 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
219 bool IsInSmiRange() const {
220 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000221 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000222 void KeepOrder();
223 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000224
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000225 void StackUpon(Range* other) {
226 Intersect(other);
227 next_ = other;
228 }
229
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000230 void Intersect(Range* other);
231 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000232
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000233 void AddConstant(int32_t value);
234 void Sar(int32_t value);
235 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000236 bool AddAndCheckOverflow(Range* other);
237 bool SubAndCheckOverflow(Range* other);
238 bool MulAndCheckOverflow(Range* other);
239
240 private:
241 int32_t lower_;
242 int32_t upper_;
243 Range* next_;
244 bool can_be_minus_zero_;
245};
246
247
248class Representation {
249 public:
250 enum Kind {
251 kNone,
252 kTagged,
253 kDouble,
254 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000255 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000256 kNumRepresentations
257 };
258
259 Representation() : kind_(kNone) { }
260
261 static Representation None() { return Representation(kNone); }
262 static Representation Tagged() { return Representation(kTagged); }
263 static Representation Integer32() { return Representation(kInteger32); }
264 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000265 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000266
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000267 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000268 return kind_ == other.kind_;
269 }
270
271 Kind kind() const { return kind_; }
272 bool IsNone() const { return kind_ == kNone; }
273 bool IsTagged() const { return kind_ == kTagged; }
274 bool IsInteger32() const { return kind_ == kInteger32; }
275 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000276 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000277 bool IsSpecialization() const {
278 return kind_ == kInteger32 || kind_ == kDouble;
279 }
280 const char* Mnemonic() const;
281
282 private:
283 explicit Representation(Kind k) : kind_(k) { }
284
285 Kind kind_;
286};
287
288
289class HType {
290 public:
291 HType() : type_(kUninitialized) { }
292
293 static HType Tagged() { return HType(kTagged); }
294 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
295 static HType TaggedNumber() { return HType(kTaggedNumber); }
296 static HType Smi() { return HType(kSmi); }
297 static HType HeapNumber() { return HType(kHeapNumber); }
298 static HType String() { return HType(kString); }
299 static HType Boolean() { return HType(kBoolean); }
300 static HType NonPrimitive() { return HType(kNonPrimitive); }
301 static HType JSArray() { return HType(kJSArray); }
302 static HType JSObject() { return HType(kJSObject); }
303 static HType Uninitialized() { return HType(kUninitialized); }
304
305 // Return the weakest (least precise) common type.
306 HType Combine(HType other) {
307 return HType(static_cast<Type>(type_ & other.type_));
308 }
309
310 bool Equals(const HType& other) {
311 return type_ == other.type_;
312 }
313
314 bool IsSubtypeOf(const HType& other) {
315 return Combine(other).Equals(other);
316 }
317
318 bool IsTagged() {
319 ASSERT(type_ != kUninitialized);
320 return ((type_ & kTagged) == kTagged);
321 }
322
323 bool IsTaggedPrimitive() {
324 ASSERT(type_ != kUninitialized);
325 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
326 }
327
328 bool IsTaggedNumber() {
329 ASSERT(type_ != kUninitialized);
330 return ((type_ & kTaggedNumber) == kTaggedNumber);
331 }
332
333 bool IsSmi() {
334 ASSERT(type_ != kUninitialized);
335 return ((type_ & kSmi) == kSmi);
336 }
337
338 bool IsHeapNumber() {
339 ASSERT(type_ != kUninitialized);
340 return ((type_ & kHeapNumber) == kHeapNumber);
341 }
342
343 bool IsString() {
344 ASSERT(type_ != kUninitialized);
345 return ((type_ & kString) == kString);
346 }
347
348 bool IsBoolean() {
349 ASSERT(type_ != kUninitialized);
350 return ((type_ & kBoolean) == kBoolean);
351 }
352
353 bool IsNonPrimitive() {
354 ASSERT(type_ != kUninitialized);
355 return ((type_ & kNonPrimitive) == kNonPrimitive);
356 }
357
358 bool IsJSArray() {
359 ASSERT(type_ != kUninitialized);
360 return ((type_ & kJSArray) == kJSArray);
361 }
362
363 bool IsJSObject() {
364 ASSERT(type_ != kUninitialized);
365 return ((type_ & kJSObject) == kJSObject);
366 }
367
368 bool IsUninitialized() {
369 return type_ == kUninitialized;
370 }
371
372 static HType TypeFromValue(Handle<Object> value);
373
374 const char* ToString();
375 const char* ToShortString();
376
377 private:
378 enum Type {
379 kTagged = 0x1, // 0000 0000 0000 0001
380 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
381 kTaggedNumber = 0xd, // 0000 0000 0000 1101
382 kSmi = 0x1d, // 0000 0000 0001 1101
383 kHeapNumber = 0x2d, // 0000 0000 0010 1101
384 kString = 0x45, // 0000 0000 0100 0101
385 kBoolean = 0x85, // 0000 0000 1000 0101
386 kNonPrimitive = 0x101, // 0000 0001 0000 0001
387 kJSObject = 0x301, // 0000 0011 0000 0001
388 kJSArray = 0x701, // 0000 0111 1000 0001
389 kUninitialized = 0x1fff // 0001 1111 1111 1111
390 };
391
392 explicit HType(Type t) : type_(t) { }
393
394 Type type_;
395};
396
397
398class HValue: public ZoneObject {
399 public:
400 static const int kNoNumber = -1;
401
402 // There must be one corresponding kDepends flag for every kChanges flag and
403 // the order of the kChanges flags must be exactly the same as of the kDepends
404 // flags.
405 enum Flag {
406 // Declare global value numbering flags.
407 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
408 GVN_FLAG_LIST(DECLARE_DO)
409 #undef DECLARE_DO
410 kFlexibleRepresentation,
411 kUseGVN,
412 kCanOverflow,
413 kBailoutOnMinusZero,
414 kCanBeDivByZero,
415 kIsArguments,
416 kTruncatingToInt32,
417 kLastFlag = kTruncatingToInt32
418 };
419
420 STATIC_ASSERT(kLastFlag < kBitsPerInt);
421
422 static const int kChangesToDependsFlagsLeftShift = 1;
423
424 static int ChangesFlagsMask() {
425 int result = 0;
426 // Create changes mask.
427#define DECLARE_DO(type) result |= (1 << kChanges##type);
428 GVN_FLAG_LIST(DECLARE_DO)
429#undef DECLARE_DO
430 return result;
431 }
432
433 static int DependsFlagsMask() {
434 return ConvertChangesToDependsFlags(ChangesFlagsMask());
435 }
436
437 static int ConvertChangesToDependsFlags(int flags) {
438 return flags << kChangesToDependsFlagsLeftShift;
439 }
440
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000441 static HValue* cast(HValue* value) { return value; }
442
443 enum Opcode {
444 // Declare a unique enum value for each hydrogen instruction.
445 #define DECLARE_DO(type) k##type,
446 HYDROGEN_ALL_INSTRUCTION_LIST(DECLARE_DO)
447 #undef DECLARE_DO
448 kMaxInstructionClass
449 };
450
451 HValue() : block_(NULL),
452 id_(kNoNumber),
453 uses_(2),
454 type_(HType::Tagged()),
455 range_(NULL),
456 flags_(0) {}
457 virtual ~HValue() {}
458
459 HBasicBlock* block() const { return block_; }
460 void SetBlock(HBasicBlock* block);
461
462 int id() const { return id_; }
463 void set_id(int id) { id_ = id; }
464
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000465 ZoneList<HValue*>* uses() { return &uses_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000466
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000467 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000468 Representation representation() const { return representation_; }
469 void ChangeRepresentation(Representation r) {
470 // Representation was already set and is allowed to be changed.
471 ASSERT(!representation_.IsNone());
472 ASSERT(!r.IsNone());
473 ASSERT(CheckFlag(kFlexibleRepresentation));
474 RepresentationChanged(r);
475 representation_ = r;
476 }
477
478 HType type() const { return type_; }
479 void set_type(HType type) {
480 ASSERT(uses_.length() == 0);
481 type_ = type;
482 }
483
484 // An operation needs to override this function iff:
485 // 1) it can produce an int32 output.
486 // 2) the true value of its output can potentially be minus zero.
487 // The implementation must set a flag so that it bails out in the case where
488 // it would otherwise output what should be a minus zero as an int32 zero.
489 // If the operation also exists in a form that takes int32 and outputs int32
490 // then the operation should return its input value so that we can propagate
491 // back. There are two operations that need to propagate back to more than
492 // one input. They are phi and binary add. They always return NULL and
493 // expect the caller to take care of things.
494 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
495 visited->Add(id());
496 return NULL;
497 }
498
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000499 bool IsDefinedAfter(HBasicBlock* other) const;
500
501 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000502 virtual int OperandCount() = 0;
503 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000504 void SetOperandAt(int index, HValue* value);
505
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000506 int LookupOperandIndex(int occurrence_index, HValue* op);
507 bool UsesMultipleTimes(HValue* op);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000508
509 void ReplaceAndDelete(HValue* other);
510 void ReplaceValue(HValue* other);
511 void ReplaceAtUse(HValue* use, HValue* other);
512 void ReplaceFirstAtUse(HValue* use, HValue* other, Representation r);
513 bool HasNoUses() const { return uses_.is_empty(); }
514 void ClearOperands();
515 void Delete();
516
517 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000518 void SetFlag(Flag f) { flags_ |= (1 << f); }
519 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
520 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
521
522 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
523 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
524 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000525
526 Range* range() const { return range_; }
527 bool HasRange() const { return range_ != NULL; }
528 void AddNewRange(Range* r);
529 void RemoveLastAddedRange();
530 void ComputeInitialRange();
531
532 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000533 virtual Representation RequiredInputRepresentation(int index) const = 0;
534
535 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000536 return representation();
537 }
538
539 // This gives the instruction an opportunity to replace itself with an
540 // instruction that does the same in some better way. To replace an
541 // instruction with a new one, first add the new instruction to the graph,
542 // then return it. Return NULL to have the instruction deleted.
543 virtual HValue* Canonicalize() { return this; }
544
545 // Declare virtual type testers.
546#define DECLARE_DO(type) virtual bool Is##type() const { return false; }
547 HYDROGEN_ALL_INSTRUCTION_LIST(DECLARE_DO)
548#undef DECLARE_DO
549
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000550 bool Equals(HValue* other);
551 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000552
553 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000554 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000555 void PrintNameTo(StringStream* stream);
556 static void PrintTypeTo(HType type, StringStream* stream);
557
558 virtual const char* Mnemonic() const = 0;
559 virtual Opcode opcode() const = 0;
560
561 // Updated the inferred type of this instruction and returns true if
562 // it has changed.
563 bool UpdateInferredType();
564
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000565 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000566
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000567#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000568 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000569#endif
570
571 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000572 // This function must be overridden for instructions with flag kUseGVN, to
573 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000574 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000575 UNREACHABLE();
576 return false;
577 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000578 virtual void RepresentationChanged(Representation to) { }
579 virtual Range* InferRange();
580 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000581 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000582 void clear_block() {
583 ASSERT(block_ != NULL);
584 block_ = NULL;
585 }
586
587 void set_representation(Representation r) {
588 // Representation is set-once.
589 ASSERT(representation_.IsNone() && !r.IsNone());
590 representation_ = r;
591 }
592
593 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000594 // A flag mask to mark an instruction as having arbitrary side effects.
595 static int AllSideEffects() {
596 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
597 }
598
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000599 void InternalReplaceAtUse(HValue* use, HValue* other);
600 void RegisterUse(int index, HValue* new_value);
601
602 HBasicBlock* block_;
603
604 // The id of this instruction in the hydrogen graph, assigned when first
605 // added to the graph. Reflects creation order.
606 int id_;
607
608 Representation representation_;
609 ZoneList<HValue*> uses_;
610 HType type_;
611 Range* range_;
612 int flags_;
613
614 DISALLOW_COPY_AND_ASSIGN(HValue);
615};
616
617
618class HInstruction: public HValue {
619 public:
620 HInstruction* next() const { return next_; }
621 HInstruction* previous() const { return previous_; }
622
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000623 virtual void PrintTo(StringStream* stream);
624 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000625
626 bool IsLinked() const { return block() != NULL; }
627 void Unlink();
628 void InsertBefore(HInstruction* next);
629 void InsertAfter(HInstruction* previous);
630
631 int position() const { return position_; }
632 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
633 void set_position(int position) { position_ = position; }
634
635 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
636
637#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000638 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000639#endif
640
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000641 // Returns whether this is some kind of deoptimizing check
642 // instruction.
643 virtual bool IsCheckInstruction() const { return false; }
644
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000645 virtual bool IsCall() { return false; }
646
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000647 DECLARE_INSTRUCTION(Instruction)
648
649 protected:
650 HInstruction()
651 : next_(NULL),
652 previous_(NULL),
653 position_(RelocInfo::kNoPosition) {
654 SetFlag(kDependsOnOsrEntries);
655 }
656
657 virtual void DeleteFromGraph() { Unlink(); }
658
659 private:
660 void InitializeAsFirst(HBasicBlock* block) {
661 ASSERT(!IsLinked());
662 SetBlock(block);
663 }
664
665 HInstruction* next_;
666 HInstruction* previous_;
667 int position_;
668
669 friend class HBasicBlock;
670};
671
672
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000673class HControlInstruction: public HInstruction {
674 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000675 HControlInstruction(HBasicBlock* first, HBasicBlock* second)
676 : first_successor_(first), second_successor_(second) {
677 }
678
679 HBasicBlock* FirstSuccessor() const { return first_successor_; }
680 HBasicBlock* SecondSuccessor() const { return second_successor_; }
681
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000682 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000683
684 DECLARE_INSTRUCTION(ControlInstruction)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000685
686 private:
687 HBasicBlock* first_successor_;
688 HBasicBlock* second_successor_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000689};
690
691
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000692template<int NumElements>
693class HOperandContainer {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000694 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000695 HOperandContainer() : elems_() { }
696
697 int length() { return NumElements; }
698 HValue*& operator[](int i) {
699 ASSERT(i < length());
700 return elems_[i];
701 }
702
703 private:
704 HValue* elems_[NumElements];
705};
706
707
708template<>
709class HOperandContainer<0> {
710 public:
711 int length() { return 0; }
712 HValue*& operator[](int i) {
713 UNREACHABLE();
714 static HValue* t = 0;
715 return t;
716 }
717};
718
719
720template<int V>
721class HTemplateInstruction : public HInstruction {
722 public:
723 int OperandCount() { return V; }
724 HValue* OperandAt(int i) { return inputs_[i]; }
725
726 protected:
727 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
728
729 private:
730 HOperandContainer<V> inputs_;
731};
732
733
734template<int V>
735class HTemplateControlInstruction : public HControlInstruction {
736 public:
737 HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second)
738 : HControlInstruction(first, second) { }
739 int OperandCount() { return V; }
740 HValue* OperandAt(int i) { return inputs_[i]; }
741
742 protected:
743 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
744
745 private:
746 HOperandContainer<V> inputs_;
747};
748
749
750class HBlockEntry: public HTemplateInstruction<0> {
751 public:
752 virtual Representation RequiredInputRepresentation(int index) const {
753 return Representation::None();
754 }
755
756 DECLARE_CONCRETE_INSTRUCTION(BlockEntry, "block_entry")
757};
758
759
760class HDeoptimize: public HTemplateControlInstruction<0> {
761 public:
762 HDeoptimize() : HTemplateControlInstruction<0>(NULL, NULL) { }
763
764 virtual Representation RequiredInputRepresentation(int index) const {
765 return Representation::None();
766 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000767
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000768 DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
769};
770
771
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000772class HGoto: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000773 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000774 explicit HGoto(HBasicBlock* target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000775 : HTemplateControlInstruction<0>(target, NULL),
776 include_stack_check_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000777
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000778 void set_include_stack_check(bool include_stack_check) {
779 include_stack_check_ = include_stack_check;
780 }
781 bool include_stack_check() const { return include_stack_check_; }
782
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000783 virtual Representation RequiredInputRepresentation(int index) const {
784 return Representation::None();
785 }
786
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000787 DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
788
789 private:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000790 bool include_stack_check_;
791};
792
793
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000794class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000795 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000796 explicit HUnaryControlInstruction(HValue* value,
797 HBasicBlock* true_target,
798 HBasicBlock* false_target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000799 : HTemplateControlInstruction<1>(true_target, false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000800 SetOperandAt(0, value);
801 }
802
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000803 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000804
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000805 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000806
807 DECLARE_INSTRUCTION(UnaryControlInstruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000808};
809
810
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000811class HTest: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000812 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000813 HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
814 : HUnaryControlInstruction(value, true_target, false_target) {
815 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000816 }
817
818 virtual Representation RequiredInputRepresentation(int index) const {
819 return Representation::None();
820 }
821
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000822 DECLARE_CONCRETE_INSTRUCTION(Test, "test")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000823};
824
825
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000826class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000827 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000828 HCompareMap(HValue* value,
829 Handle<Map> map,
830 HBasicBlock* true_target,
831 HBasicBlock* false_target)
832 : HUnaryControlInstruction(value, true_target, false_target),
833 map_(map) {
834 ASSERT(true_target != NULL);
835 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000836 ASSERT(!map.is_null());
837 }
838
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000839 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000840
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000841 Handle<Map> map() const { return map_; }
842
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000843 virtual Representation RequiredInputRepresentation(int index) const {
844 return Representation::Tagged();
845 }
846
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000847 DECLARE_CONCRETE_INSTRUCTION(CompareMap, "compare_map")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000848
849 private:
850 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000851};
852
853
854class HReturn: public HUnaryControlInstruction {
855 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000856 explicit HReturn(HValue* value)
857 : HUnaryControlInstruction(value, NULL, NULL) {
858 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000859
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000860 virtual Representation RequiredInputRepresentation(int index) const {
861 return Representation::Tagged();
862 }
863
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000864 DECLARE_CONCRETE_INSTRUCTION(Return, "return")
865};
866
867
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000868class HAbnormalExit: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000869 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000870 HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
871
872 virtual Representation RequiredInputRepresentation(int index) const {
873 return Representation::None();
874 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000875
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000876 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit, "abnormal_exit")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000877};
878
879
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000880class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000881 public:
882 explicit HUnaryOperation(HValue* value) {
883 SetOperandAt(0, value);
884 }
885
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000886 HValue* value() { return OperandAt(0); }
887 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000888
889 DECLARE_INSTRUCTION(UnaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000890};
891
892
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000893class HThrow: public HUnaryOperation {
894 public:
895 explicit HThrow(HValue* value) : HUnaryOperation(value) {
896 SetAllSideEffects();
897 }
898
899 virtual Representation RequiredInputRepresentation(int index) const {
900 return Representation::Tagged();
901 }
902
903 DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
904};
905
906
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000907class HChange: public HUnaryOperation {
908 public:
909 HChange(HValue* value,
910 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000911 Representation to,
912 bool is_truncating)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000913 : HUnaryOperation(value), from_(from), to_(to) {
914 ASSERT(!from.IsNone() && !to.IsNone());
915 ASSERT(!from.Equals(to));
916 set_representation(to);
917 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000918 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000919 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
920 value->range()->IsInSmiRange()) {
921 set_type(HType::Smi());
922 }
923 }
924
925 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
926
927 Representation from() const { return from_; }
928 Representation to() const { return to_; }
929 virtual Representation RequiredInputRepresentation(int index) const {
930 return from_;
931 }
932
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000933 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000934
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000935 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000936
937 DECLARE_CONCRETE_INSTRUCTION(Change,
938 CanTruncateToInt32() ? "truncate" : "change")
939
940 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000941 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000942 if (!other->IsChange()) return false;
943 HChange* change = HChange::cast(other);
944 return value() == change->value()
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000945 && to().Equals(change->to());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000946 }
947
948 private:
949 Representation from_;
950 Representation to_;
951};
952
953
954class HSimulate: public HInstruction {
955 public:
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000956 HSimulate(int ast_id, int pop_count, int environment_length)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000957 : ast_id_(ast_id),
958 pop_count_(pop_count),
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000959 environment_length_(environment_length),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000960 values_(2),
961 assigned_indexes_(2) {}
962 virtual ~HSimulate() {}
963
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000964 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000965
966 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
967 int ast_id() const { return ast_id_; }
968 void set_ast_id(int id) {
969 ASSERT(!HasAstId());
970 ast_id_ = id;
971 }
972
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000973 int environment_length() const { return environment_length_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000974 int pop_count() const { return pop_count_; }
975 const ZoneList<HValue*>* values() const { return &values_; }
976 int GetAssignedIndexAt(int index) const {
977 ASSERT(HasAssignedIndexAt(index));
978 return assigned_indexes_[index];
979 }
980 bool HasAssignedIndexAt(int index) const {
981 return assigned_indexes_[index] != kNoIndex;
982 }
983 void AddAssignedValue(int index, HValue* value) {
984 AddValue(index, value);
985 }
986 void AddPushedValue(HValue* value) {
987 AddValue(kNoIndex, value);
988 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000989 virtual int OperandCount() { return values_.length(); }
990 virtual HValue* OperandAt(int index) { return values_[index]; }
991
992 virtual Representation RequiredInputRepresentation(int index) const {
993 return Representation::None();
994 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000995
996 DECLARE_CONCRETE_INSTRUCTION(Simulate, "simulate")
997
998#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000999 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001000#endif
1001
1002 protected:
1003 virtual void InternalSetOperandAt(int index, HValue* value) {
1004 values_[index] = value;
1005 }
1006
1007 private:
1008 static const int kNoIndex = -1;
1009 void AddValue(int index, HValue* value) {
1010 assigned_indexes_.Add(index);
1011 // Resize the list of pushed values.
1012 values_.Add(NULL);
1013 // Set the operand through the base method in HValue to make sure that the
1014 // use lists are correctly updated.
1015 SetOperandAt(values_.length() - 1, value);
1016 }
1017 int ast_id_;
1018 int pop_count_;
lrn@chromium.org5d00b602011-01-05 09:51:43 +00001019 int environment_length_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001020 ZoneList<HValue*> values_;
1021 ZoneList<int> assigned_indexes_;
1022};
1023
1024
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001025class HStackCheck: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001026 public:
1027 HStackCheck() { }
1028
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001029 virtual Representation RequiredInputRepresentation(int index) const {
1030 return Representation::None();
1031 }
1032
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001033 DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack_check")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001034};
1035
1036
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001037class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001038 public:
1039 HEnterInlined(Handle<JSFunction> closure, FunctionLiteral* function)
1040 : closure_(closure), function_(function) {
1041 }
1042
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001043 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001044
1045 Handle<JSFunction> closure() const { return closure_; }
1046 FunctionLiteral* function() const { return function_; }
1047
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001048 virtual Representation RequiredInputRepresentation(int index) const {
1049 return Representation::None();
1050 }
1051
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001052 DECLARE_CONCRETE_INSTRUCTION(EnterInlined, "enter_inlined")
1053
1054 private:
1055 Handle<JSFunction> closure_;
1056 FunctionLiteral* function_;
1057};
1058
1059
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001060class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001061 public:
1062 HLeaveInlined() {}
1063
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001064 virtual Representation RequiredInputRepresentation(int index) const {
1065 return Representation::None();
1066 }
1067
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001068 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined, "leave_inlined")
1069};
1070
1071
1072class HPushArgument: public HUnaryOperation {
1073 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001074 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1075 set_representation(Representation::Tagged());
1076 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001077
1078 virtual Representation RequiredInputRepresentation(int index) const {
1079 return Representation::Tagged();
1080 }
1081
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001082 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001083
1084 DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push_argument")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001085};
1086
1087
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001088class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001089 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001090 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001091 set_representation(Representation::Tagged());
1092 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001093 }
1094
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001095 virtual Representation RequiredInputRepresentation(int index) const {
1096 return Representation::None();
1097 }
1098
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001099 DECLARE_CONCRETE_INSTRUCTION(Context, "context");
1100
1101 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001102 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001103};
1104
1105
1106class HOuterContext: public HUnaryOperation {
1107 public:
1108 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1109 set_representation(Representation::Tagged());
1110 SetFlag(kUseGVN);
1111 }
1112
1113 DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer_context");
1114
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001115 virtual Representation RequiredInputRepresentation(int index) const {
1116 return Representation::Tagged();
1117 }
1118
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001119 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001120 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001121};
1122
1123
1124class HGlobalObject: public HUnaryOperation {
1125 public:
1126 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1127 set_representation(Representation::Tagged());
1128 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001129 }
1130
1131 DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global_object")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001132
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001133 virtual Representation RequiredInputRepresentation(int index) const {
1134 return Representation::Tagged();
1135 }
1136
ager@chromium.org378b34e2011-01-28 08:04:38 +00001137 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001138 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001139};
1140
1141
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001142class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001143 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001144 explicit HGlobalReceiver(HValue* global_object)
1145 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001146 set_representation(Representation::Tagged());
1147 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001148 }
1149
1150 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global_receiver")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001151
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001152 virtual Representation RequiredInputRepresentation(int index) const {
1153 return Representation::Tagged();
1154 }
1155
ager@chromium.org378b34e2011-01-28 08:04:38 +00001156 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001157 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001158};
1159
1160
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001161template <int V>
1162class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001163 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001164 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001165 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1166 this->set_representation(Representation::Tagged());
1167 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001168 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001169
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001170 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001171
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001172 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001173
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001174 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001175
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001176 private:
1177 int argument_count_;
1178};
1179
1180
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001181class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001182 public:
1183 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001184 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001185 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001186 }
1187
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001188 virtual Representation RequiredInputRepresentation(int index) const {
1189 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001190 }
1191
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001192 virtual void PrintDataTo(StringStream* stream);
1193
1194 HValue* value() { return OperandAt(0); }
1195
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001196 DECLARE_INSTRUCTION(UnaryCall)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001197};
1198
1199
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001200class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001201 public:
1202 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001203 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001204 SetOperandAt(0, first);
1205 SetOperandAt(1, second);
1206 }
1207
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001208 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001209
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 HValue* first() { return OperandAt(0); }
1215 HValue* second() { return OperandAt(1); }
1216
1217 DECLARE_INSTRUCTION(BinaryCall)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001218};
1219
1220
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001221class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001222 public:
1223 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001224 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001225
1226 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001227
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001228 bool IsApplyFunction() const {
1229 return function_->code() == Builtins::builtin(Builtins::FunctionApply);
1230 }
1231
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001232 virtual void PrintDataTo(StringStream* stream);
1233
1234 virtual Representation RequiredInputRepresentation(int index) const {
1235 return Representation::None();
1236 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001237
1238 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call_constant_function")
1239
1240 private:
1241 Handle<JSFunction> function_;
1242};
1243
1244
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001245class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001246 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001247 HCallKeyed(HValue* context, HValue* key, int argument_count)
1248 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001249 }
1250
1251 virtual Representation RequiredInputRepresentation(int index) const {
1252 return Representation::Tagged();
1253 }
1254
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001255 HValue* context() { return first(); }
1256 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001257
1258 DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call_keyed")
1259};
1260
1261
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001262class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001263 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001264 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1265 : HUnaryCall(context, argument_count), name_(name) {
1266 }
1267
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001268 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001269
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001270 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001271 Handle<String> name() const { return name_; }
1272
1273 DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call_named")
1274
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001275 virtual Representation RequiredInputRepresentation(int index) const {
1276 return Representation::Tagged();
1277 }
1278
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001279 private:
1280 Handle<String> name_;
1281};
1282
1283
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001284class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001285 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001286 HCallFunction(HValue* context, int argument_count)
1287 : HUnaryCall(context, argument_count) {
1288 }
1289
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001290 HValue* context() { return value(); }
1291
1292 virtual Representation RequiredInputRepresentation(int index) const {
1293 return Representation::Tagged();
1294 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001295
1296 DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call_function")
1297};
1298
1299
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001300class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001301 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001302 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1303 : HUnaryCall(context, argument_count), name_(name) {
1304 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001305
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001306 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001307
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001308 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001309 Handle<String> name() const { return name_; }
1310
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001311 virtual Representation RequiredInputRepresentation(int index) const {
1312 return Representation::Tagged();
1313 }
1314
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001315 DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call_global")
1316
1317 private:
1318 Handle<String> name_;
1319};
1320
1321
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001322class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001323 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001324 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001325 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001326
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001327 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001328
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001329 Handle<JSFunction> target() const { return target_; }
1330
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001331 virtual Representation RequiredInputRepresentation(int index) const {
1332 return Representation::None();
1333 }
1334
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001335 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call_known_global")
1336
1337 private:
1338 Handle<JSFunction> target_;
1339};
1340
1341
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001342class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001343 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001344 HCallNew(HValue* context, HValue* constructor, int argument_count)
1345 : HBinaryCall(context, constructor, argument_count) {
1346 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001347
1348 virtual Representation RequiredInputRepresentation(int index) const {
1349 return Representation::Tagged();
1350 }
1351
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001352 HValue* context() { return first(); }
1353 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001354
1355 DECLARE_CONCRETE_INSTRUCTION(CallNew, "call_new")
1356};
1357
1358
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001359class HCallRuntime: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001360 public:
1361 HCallRuntime(Handle<String> name,
1362 Runtime::Function* c_function,
1363 int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001364 : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
1365 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001366
1367 Runtime::Function* function() const { return c_function_; }
1368 Handle<String> name() const { return name_; }
1369
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001370 virtual Representation RequiredInputRepresentation(int index) const {
1371 return Representation::None();
1372 }
1373
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001374 DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call_runtime")
1375
1376 private:
1377 Runtime::Function* c_function_;
1378 Handle<String> name_;
1379};
1380
1381
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001382class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001383 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001384 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001385 // The length of an array is stored as a tagged value in the array
1386 // object. It is guaranteed to be 32 bit integer, but it can be
1387 // represented as either a smi or heap number.
1388 set_representation(Representation::Tagged());
1389 SetFlag(kDependsOnArrayLengths);
1390 SetFlag(kUseGVN);
1391 }
1392
1393 virtual Representation RequiredInputRepresentation(int index) const {
1394 return Representation::Tagged();
1395 }
1396
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001397 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js_array_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001398
1399 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001400 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001401};
1402
1403
1404class HFixedArrayLength: public HUnaryOperation {
1405 public:
1406 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1407 set_representation(Representation::Tagged());
1408 SetFlag(kDependsOnArrayLengths);
1409 SetFlag(kUseGVN);
1410 }
1411
1412 virtual Representation RequiredInputRepresentation(int index) const {
1413 return Representation::Tagged();
1414 }
1415
1416 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed_array_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001417
1418 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001419 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001420};
1421
1422
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001423class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001424 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001425 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001426 set_representation(Representation::Integer32());
1427 // The result of this instruction is idempotent as long as its inputs don't
1428 // change. The length of a pixel array cannot change once set, so it's not
1429 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1430 SetFlag(kUseGVN);
1431 }
1432
1433 virtual Representation RequiredInputRepresentation(int index) const {
1434 return Representation::Tagged();
1435 }
1436
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001437 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength, "external_array_length")
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001438
1439 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001440 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001441};
1442
1443
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001444class HBitNot: public HUnaryOperation {
1445 public:
1446 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1447 set_representation(Representation::Integer32());
1448 SetFlag(kUseGVN);
1449 SetFlag(kTruncatingToInt32);
1450 }
1451
1452 virtual Representation RequiredInputRepresentation(int index) const {
1453 return Representation::Integer32();
1454 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001455 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001456
1457 DECLARE_CONCRETE_INSTRUCTION(BitNot, "bit_not")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001458
1459 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001460 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001461};
1462
1463
1464class HUnaryMathOperation: public HUnaryOperation {
1465 public:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001466 HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001467 : HUnaryOperation(value), op_(op) {
1468 switch (op) {
1469 case kMathFloor:
1470 case kMathRound:
1471 case kMathCeil:
1472 set_representation(Representation::Integer32());
1473 break;
1474 case kMathAbs:
1475 set_representation(Representation::Tagged());
1476 SetFlag(kFlexibleRepresentation);
1477 break;
1478 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001479 case kMathPowHalf:
1480 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001481 case kMathSin:
1482 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001483 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001484 break;
1485 default:
1486 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001487 }
1488 SetFlag(kUseGVN);
1489 }
1490
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001491 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001492
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001493 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001494
1495 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1496
1497 virtual Representation RequiredInputRepresentation(int index) const {
1498 switch (op_) {
1499 case kMathFloor:
1500 case kMathRound:
1501 case kMathCeil:
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 return Representation::Double();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001508 case kMathAbs:
1509 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001510 default:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001511 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001512 return Representation::None();
1513 }
1514 }
1515
1516 virtual HValue* Canonicalize() {
1517 // If the input is integer32 then we replace the floor instruction
1518 // with its inputs. This happens before the representation changes are
1519 // introduced.
1520 if (op() == kMathFloor) {
1521 if (value()->representation().IsInteger32()) return value();
1522 }
1523 return this;
1524 }
1525
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001526 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001527 const char* OpName() const;
1528
1529 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary_math_operation")
1530
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001531 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001532 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001533 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1534 return op_ == b->op();
1535 }
1536
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001537 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001538 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001539};
1540
1541
1542class HLoadElements: public HUnaryOperation {
1543 public:
1544 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1545 set_representation(Representation::Tagged());
1546 SetFlag(kUseGVN);
1547 SetFlag(kDependsOnMaps);
1548 }
1549
1550 virtual Representation RequiredInputRepresentation(int index) const {
1551 return Representation::Tagged();
1552 }
1553
1554 DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001555
1556 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001557 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001558};
1559
1560
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001561class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001562 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001563 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001564 : HUnaryOperation(value) {
1565 set_representation(Representation::External());
1566 // The result of this instruction is idempotent as long as its inputs don't
1567 // change. The external array of a pixel array elements object cannot
1568 // change once set, so it's no necessary to introduce any additional
1569 // dependencies on top of the inputs.
1570 SetFlag(kUseGVN);
1571 }
1572
1573 virtual Representation RequiredInputRepresentation(int index) const {
1574 return Representation::Tagged();
1575 }
1576
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001577 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer,
1578 "load-external-array-pointer")
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001579
1580 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001581 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001582};
1583
1584
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001585class HCheckMap: public HUnaryOperation {
1586 public:
1587 HCheckMap(HValue* value, Handle<Map> map)
1588 : HUnaryOperation(value), map_(map) {
1589 set_representation(Representation::Tagged());
1590 SetFlag(kUseGVN);
1591 SetFlag(kDependsOnMaps);
1592 }
1593
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001594 virtual bool IsCheckInstruction() const { return true; }
1595
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001596 virtual Representation RequiredInputRepresentation(int index) const {
1597 return Representation::Tagged();
1598 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001599 virtual void PrintDataTo(StringStream* stream);
1600 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001601
1602#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001603 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001604#endif
1605
1606 Handle<Map> map() const { return map_; }
1607
1608 DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check_map")
1609
1610 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001611 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001612 HCheckMap* b = HCheckMap::cast(other);
1613 return map_.is_identical_to(b->map());
1614 }
1615
1616 private:
1617 Handle<Map> map_;
1618};
1619
1620
1621class HCheckFunction: public HUnaryOperation {
1622 public:
1623 HCheckFunction(HValue* value, Handle<JSFunction> function)
1624 : HUnaryOperation(value), target_(function) {
1625 set_representation(Representation::Tagged());
1626 SetFlag(kUseGVN);
1627 }
1628
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001629 virtual bool IsCheckInstruction() const { return true; }
1630
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001631 virtual Representation RequiredInputRepresentation(int index) const {
1632 return Representation::Tagged();
1633 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001634 virtual void PrintDataTo(StringStream* stream);
1635 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001636
1637#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001638 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001639#endif
1640
1641 Handle<JSFunction> target() const { return target_; }
1642
1643 DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check_function")
1644
1645 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001646 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001647 HCheckFunction* b = HCheckFunction::cast(other);
1648 return target_.is_identical_to(b->target());
1649 }
1650
1651 private:
1652 Handle<JSFunction> target_;
1653};
1654
1655
1656class HCheckInstanceType: public HUnaryOperation {
1657 public:
1658 // Check that the instance type is in the range [first, last] where
1659 // both first and last are included.
1660 HCheckInstanceType(HValue* value, InstanceType first, InstanceType last)
1661 : HUnaryOperation(value), first_(first), last_(last) {
1662 ASSERT(first <= last);
1663 set_representation(Representation::Tagged());
1664 SetFlag(kUseGVN);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001665 if ((FIRST_STRING_TYPE < first && last <= LAST_STRING_TYPE) ||
1666 (FIRST_STRING_TYPE <= first && last < LAST_STRING_TYPE)) {
1667 // A particular string instance type can change because of GC or
1668 // externalization, but the value still remains a string.
1669 SetFlag(kDependsOnMaps);
1670 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001671 }
1672
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001673 virtual bool IsCheckInstruction() const { return true; }
1674
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001675 virtual Representation RequiredInputRepresentation(int index) const {
1676 return Representation::Tagged();
1677 }
1678
1679#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001680 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001681#endif
1682
1683 static HCheckInstanceType* NewIsJSObjectOrJSFunction(HValue* value);
1684
1685 InstanceType first() const { return first_; }
1686 InstanceType last() const { return last_; }
1687
1688 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check_instance_type")
1689
1690 protected:
1691 // TODO(ager): It could be nice to allow the ommision of instance
1692 // type checks if we have already performed an instance type check
1693 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001694 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001695 HCheckInstanceType* b = HCheckInstanceType::cast(other);
1696 return (first_ == b->first()) && (last_ == b->last());
1697 }
1698
1699 private:
1700 InstanceType first_;
1701 InstanceType last_;
1702};
1703
1704
1705class HCheckNonSmi: public HUnaryOperation {
1706 public:
1707 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
1708 set_representation(Representation::Tagged());
1709 SetFlag(kUseGVN);
1710 }
1711
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001712 virtual bool IsCheckInstruction() const { return true; }
1713
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001714 virtual Representation RequiredInputRepresentation(int index) const {
1715 return Representation::Tagged();
1716 }
1717
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001718 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001719
1720#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001721 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001722#endif
1723
1724 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check_non_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001725
1726 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001727 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001728};
1729
1730
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001731class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001732 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001733 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
1734 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001735 SetFlag(kUseGVN);
1736 SetFlag(kDependsOnMaps);
1737 }
1738
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001739 virtual bool IsCheckInstruction() const { return true; }
1740
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001741#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001742 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001743#endif
1744
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001745 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001746 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001747
1748 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check_prototype_maps")
1749
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001750 virtual Representation RequiredInputRepresentation(int index) const {
1751 return Representation::None();
1752 }
1753
1754 virtual intptr_t Hashcode() {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001755 ASSERT(!Heap::IsAllocationAllowed());
1756 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
1757 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
1758 return hash;
1759 }
1760
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001761 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001762 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001763 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001764 return prototype_.is_identical_to(b->prototype()) &&
1765 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001766 }
1767
1768 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001769 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001770 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001771};
1772
1773
1774class HCheckSmi: public HUnaryOperation {
1775 public:
1776 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
1777 set_representation(Representation::Tagged());
1778 SetFlag(kUseGVN);
1779 }
1780
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001781 virtual bool IsCheckInstruction() const { return true; }
1782
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001783 virtual Representation RequiredInputRepresentation(int index) const {
1784 return Representation::Tagged();
1785 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001786 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001787
1788#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001789 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001790#endif
1791
1792 DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001793
1794 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001795 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001796};
1797
1798
1799class HPhi: public HValue {
1800 public:
1801 explicit HPhi(int merged_index)
1802 : inputs_(2),
1803 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001804 phi_id_(-1),
1805 is_live_(false) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001806 for (int i = 0; i < Representation::kNumRepresentations; i++) {
1807 non_phi_uses_[i] = 0;
1808 indirect_uses_[i] = 0;
1809 }
1810 ASSERT(merged_index >= 0);
1811 set_representation(Representation::Tagged());
1812 SetFlag(kFlexibleRepresentation);
1813 }
1814
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001815 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001816 bool double_occurred = false;
1817 bool int32_occurred = false;
1818 for (int i = 0; i < OperandCount(); ++i) {
1819 HValue* value = OperandAt(i);
1820 if (value->representation().IsDouble()) double_occurred = true;
1821 if (value->representation().IsInteger32()) int32_occurred = true;
1822 if (value->representation().IsTagged()) return Representation::Tagged();
1823 }
1824
1825 if (double_occurred) return Representation::Double();
1826 if (int32_occurred) return Representation::Integer32();
1827 return Representation::None();
1828 }
1829
1830 virtual Range* InferRange();
1831 virtual Representation RequiredInputRepresentation(int index) const {
1832 return representation();
1833 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001834 virtual HType CalculateInferredType();
1835 virtual int OperandCount() { return inputs_.length(); }
1836 virtual HValue* OperandAt(int index) { return inputs_[index]; }
1837 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001838 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001839 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001840
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00001841 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001842
1843 int merged_index() const { return merged_index_; }
1844
1845 virtual const char* Mnemonic() const { return "phi"; }
1846
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001847 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001848
1849#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001850 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001851#endif
1852
1853 DECLARE_INSTRUCTION(Phi)
1854
1855 void InitRealUses(int id);
1856 void AddNonPhiUsesFrom(HPhi* other);
1857 void AddIndirectUsesTo(int* use_count);
1858
1859 int tagged_non_phi_uses() const {
1860 return non_phi_uses_[Representation::kTagged];
1861 }
1862 int int32_non_phi_uses() const {
1863 return non_phi_uses_[Representation::kInteger32];
1864 }
1865 int double_non_phi_uses() const {
1866 return non_phi_uses_[Representation::kDouble];
1867 }
1868 int tagged_indirect_uses() const {
1869 return indirect_uses_[Representation::kTagged];
1870 }
1871 int int32_indirect_uses() const {
1872 return indirect_uses_[Representation::kInteger32];
1873 }
1874 int double_indirect_uses() const {
1875 return indirect_uses_[Representation::kDouble];
1876 }
1877 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001878 bool is_live() { return is_live_; }
1879 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001880
1881 protected:
1882 virtual void DeleteFromGraph();
1883 virtual void InternalSetOperandAt(int index, HValue* value) {
1884 inputs_[index] = value;
1885 }
1886
1887 private:
1888 ZoneList<HValue*> inputs_;
1889 int merged_index_;
1890
1891 int non_phi_uses_[Representation::kNumRepresentations];
1892 int indirect_uses_[Representation::kNumRepresentations];
1893 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001894 bool is_live_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001895};
1896
1897
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001898class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001899 public:
1900 HArgumentsObject() {
1901 set_representation(Representation::Tagged());
1902 SetFlag(kIsArguments);
1903 }
1904
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001905 virtual Representation RequiredInputRepresentation(int index) const {
1906 return Representation::None();
1907 }
1908
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001909 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject, "arguments-object")
1910};
1911
1912
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001913class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001914 public:
1915 HConstant(Handle<Object> handle, Representation r);
1916
1917 Handle<Object> handle() const { return handle_; }
1918
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001919 bool InOldSpace() const { return !Heap::InNewSpace(*handle_); }
1920
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001921 virtual Representation RequiredInputRepresentation(int index) const {
1922 return Representation::None();
1923 }
1924
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001925 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001926 virtual void PrintDataTo(StringStream* stream);
1927 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001928 bool IsInteger() const { return handle_->IsSmi(); }
1929 HConstant* CopyToRepresentation(Representation r) const;
1930 HConstant* CopyToTruncatedInt32() const;
1931 bool HasInteger32Value() const { return has_int32_value_; }
1932 int32_t Integer32Value() const {
1933 ASSERT(HasInteger32Value());
1934 return int32_value_;
1935 }
1936 bool HasDoubleValue() const { return has_double_value_; }
1937 double DoubleValue() const {
1938 ASSERT(HasDoubleValue());
1939 return double_value_;
1940 }
1941 bool HasStringValue() const { return handle_->IsString(); }
1942
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001943 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001944 ASSERT(!Heap::allow_allocation(false));
1945 return reinterpret_cast<intptr_t>(*handle());
1946 }
1947
1948#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001949 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001950#endif
1951
1952 DECLARE_CONCRETE_INSTRUCTION(Constant, "constant")
1953
1954 protected:
1955 virtual Range* InferRange();
1956
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001957 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001958 HConstant* other_constant = HConstant::cast(other);
1959 return handle().is_identical_to(other_constant->handle());
1960 }
1961
1962 private:
1963 Handle<Object> handle_;
1964 HType constant_type_;
1965
1966 // The following two values represent the int32 and the double value of the
1967 // given constant if there is a lossless conversion between the constant
1968 // and the specific representation.
1969 bool has_int32_value_;
1970 int32_t int32_value_;
1971 bool has_double_value_;
1972 double double_value_;
1973};
1974
1975
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001976class HBinaryOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001977 public:
1978 HBinaryOperation(HValue* left, HValue* right) {
1979 ASSERT(left != NULL && right != NULL);
1980 SetOperandAt(0, left);
1981 SetOperandAt(1, right);
1982 }
1983
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001984 HValue* left() { return OperandAt(0); }
1985 HValue* right() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001986
1987 // TODO(kasperl): Move these helpers to the IA-32 Lithium
1988 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001989 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001990 if (IsCommutative() && left()->IsConstant()) return right();
1991 return left();
1992 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001993 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001994 if (IsCommutative() && left()->IsConstant()) return left();
1995 return right();
1996 }
1997
1998 virtual bool IsCommutative() const { return false; }
1999
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002000 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002001
2002 DECLARE_INSTRUCTION(BinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002003};
2004
2005
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002006class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002007 public:
2008 HApplyArguments(HValue* function,
2009 HValue* receiver,
2010 HValue* length,
2011 HValue* elements) {
2012 set_representation(Representation::Tagged());
2013 SetOperandAt(0, function);
2014 SetOperandAt(1, receiver);
2015 SetOperandAt(2, length);
2016 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002017 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002018 }
2019
2020 virtual Representation RequiredInputRepresentation(int index) const {
2021 // The length is untagged, all other inputs are tagged.
2022 return (index == 2)
2023 ? Representation::Integer32()
2024 : Representation::Tagged();
2025 }
2026
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002027 HValue* function() { return OperandAt(0); }
2028 HValue* receiver() { return OperandAt(1); }
2029 HValue* length() { return OperandAt(2); }
2030 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002031
2032 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply_arguments")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002033};
2034
2035
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002036class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002037 public:
2038 HArgumentsElements() {
2039 // The value produced by this instruction is a pointer into the stack
2040 // that looks as if it was a smi because of alignment.
2041 set_representation(Representation::Tagged());
2042 SetFlag(kUseGVN);
2043 }
2044
2045 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments_elements")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002046
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002047 virtual Representation RequiredInputRepresentation(int index) const {
2048 return Representation::None();
2049 }
2050
ager@chromium.org378b34e2011-01-28 08:04:38 +00002051 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002052 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002053};
2054
2055
2056class HArgumentsLength: public HUnaryOperation {
2057 public:
2058 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2059 set_representation(Representation::Integer32());
2060 SetFlag(kUseGVN);
2061 }
2062
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002063 virtual Representation RequiredInputRepresentation(int index) const {
2064 return Representation::Tagged();
2065 }
2066
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002067 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002068
2069 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002070 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002071};
2072
2073
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002074class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002075 public:
2076 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2077 set_representation(Representation::Tagged());
2078 SetFlag(kUseGVN);
2079 SetOperandAt(0, arguments);
2080 SetOperandAt(1, length);
2081 SetOperandAt(2, index);
2082 }
2083
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002084 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002085
2086 virtual Representation RequiredInputRepresentation(int index) const {
2087 // The arguments elements is considered tagged.
2088 return index == 0
2089 ? Representation::Tagged()
2090 : Representation::Integer32();
2091 }
2092
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002093 HValue* arguments() { return OperandAt(0); }
2094 HValue* length() { return OperandAt(1); }
2095 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002096
2097 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access_arguments_at")
2098
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002099 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002100};
2101
2102
2103class HBoundsCheck: public HBinaryOperation {
2104 public:
2105 HBoundsCheck(HValue* index, HValue* length)
2106 : HBinaryOperation(index, length) {
2107 SetFlag(kUseGVN);
2108 }
2109
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002110 virtual bool IsCheckInstruction() const { return true; }
2111
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002112 virtual Representation RequiredInputRepresentation(int index) const {
2113 return Representation::Integer32();
2114 }
2115
2116#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002117 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002118#endif
2119
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002120 HValue* index() { return left(); }
2121 HValue* length() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002122
2123 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds_check")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002124
2125 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002126 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002127};
2128
2129
2130class HBitwiseBinaryOperation: public HBinaryOperation {
2131 public:
2132 HBitwiseBinaryOperation(HValue* left, HValue* right)
2133 : HBinaryOperation(left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002134 set_representation(Representation::Tagged());
2135 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002136 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002137 }
2138
2139 virtual Representation RequiredInputRepresentation(int index) const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002140 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002141 }
2142
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002143 virtual void RepresentationChanged(Representation to) {
2144 if (!to.IsTagged()) {
2145 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002146 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002147 SetFlag(kTruncatingToInt32);
2148 SetFlag(kUseGVN);
2149 }
2150 }
2151
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002152 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002153
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002154 DECLARE_INSTRUCTION(BitwiseBinaryOperation)
2155};
2156
2157
2158class HArithmeticBinaryOperation: public HBinaryOperation {
2159 public:
2160 HArithmeticBinaryOperation(HValue* left, HValue* right)
2161 : HBinaryOperation(left, right) {
2162 set_representation(Representation::Tagged());
2163 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002164 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002165 }
2166
2167 virtual void RepresentationChanged(Representation to) {
2168 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002169 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002170 SetFlag(kUseGVN);
2171 }
2172 }
2173
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002174 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002175 virtual Representation RequiredInputRepresentation(int index) const {
2176 return representation();
2177 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002178 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002179 if (left()->representation().Equals(right()->representation())) {
2180 return left()->representation();
2181 }
2182 return HValue::InferredRepresentation();
2183 }
2184
2185 DECLARE_INSTRUCTION(ArithmeticBinaryOperation)
2186};
2187
2188
2189class HCompare: public HBinaryOperation {
2190 public:
2191 HCompare(HValue* left, HValue* right, Token::Value token)
2192 : HBinaryOperation(left, right), token_(token) {
2193 ASSERT(Token::IsCompareOp(token));
2194 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002195 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002196 }
2197
2198 void SetInputRepresentation(Representation r);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002199
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002200 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002201 return !HasSideEffects() && (uses()->length() <= 1);
2202 }
2203
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002204 virtual Representation RequiredInputRepresentation(int index) const {
2205 return input_representation_;
2206 }
2207 Representation GetInputRepresentation() const {
2208 return input_representation_;
2209 }
2210 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002211 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002212
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002213 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002214
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002215 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002216 return HValue::Hashcode() * 7 + token_;
2217 }
2218
2219 DECLARE_CONCRETE_INSTRUCTION(Compare, "compare")
2220
2221 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002222 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002223 HCompare* comp = HCompare::cast(other);
2224 return token_ == comp->token();
2225 }
2226
2227 private:
2228 Representation input_representation_;
2229 Token::Value token_;
2230};
2231
2232
2233class HCompareJSObjectEq: public HBinaryOperation {
2234 public:
2235 HCompareJSObjectEq(HValue* left, HValue* right)
2236 : HBinaryOperation(left, right) {
2237 set_representation(Representation::Tagged());
2238 SetFlag(kUseGVN);
2239 }
2240
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002241 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002242 return !HasSideEffects() && (uses()->length() <= 1);
2243 }
2244
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002245 virtual Representation RequiredInputRepresentation(int index) const {
2246 return Representation::Tagged();
2247 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002248 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002249
2250 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq, "compare-js-object-eq")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002251
2252 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002253 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002254};
2255
2256
2257class HUnaryPredicate: public HUnaryOperation {
2258 public:
2259 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2260 set_representation(Representation::Tagged());
2261 SetFlag(kUseGVN);
2262 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002263
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002264 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002265 return !HasSideEffects() && (uses()->length() <= 1);
2266 }
2267
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002268 virtual Representation RequiredInputRepresentation(int index) const {
2269 return Representation::Tagged();
2270 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002271 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002272};
2273
2274
2275class HIsNull: public HUnaryPredicate {
2276 public:
2277 HIsNull(HValue* value, bool is_strict)
2278 : HUnaryPredicate(value), is_strict_(is_strict) { }
2279
2280 bool is_strict() const { return is_strict_; }
2281
2282 DECLARE_CONCRETE_INSTRUCTION(IsNull, "is_null")
2283
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002284 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002285 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002286 HIsNull* b = HIsNull::cast(other);
2287 return is_strict_ == b->is_strict();
2288 }
2289
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002290 private:
2291 bool is_strict_;
2292};
2293
2294
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002295class HIsObject: public HUnaryPredicate {
2296 public:
2297 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2298
2299 DECLARE_CONCRETE_INSTRUCTION(IsObject, "is_object")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002300
2301 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002302 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002303};
2304
2305
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002306class HIsSmi: public HUnaryPredicate {
2307 public:
2308 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2309
2310 DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002311
2312 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002313 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002314};
2315
2316
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002317class HIsConstructCall: public HTemplateInstruction<0> {
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002318 public:
2319 HIsConstructCall() {
2320 set_representation(Representation::Tagged());
2321 SetFlag(kUseGVN);
2322 }
2323
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002324 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002325 return !HasSideEffects() && (uses()->length() <= 1);
2326 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002327
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002328 virtual Representation RequiredInputRepresentation(int index) const {
2329 return Representation::None();
2330 }
2331
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002332 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall, "is_construct_call")
2333
2334 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002335 virtual bool DataEquals(HValue* other) { return true; }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002336};
2337
2338
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002339class HHasInstanceType: public HUnaryPredicate {
2340 public:
2341 HHasInstanceType(HValue* value, InstanceType type)
2342 : HUnaryPredicate(value), from_(type), to_(type) { }
2343 HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2344 : HUnaryPredicate(value), from_(from), to_(to) {
2345 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2346 }
2347
2348 InstanceType from() { return from_; }
2349 InstanceType to() { return to_; }
2350
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002351 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002352
2353 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has_instance_type")
2354
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002355 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002356 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002357 HHasInstanceType* b = HHasInstanceType::cast(other);
2358 return (from_ == b->from()) && (to_ == b->to());
2359 }
2360
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002361 private:
2362 InstanceType from_;
2363 InstanceType to_; // Inclusive range, not all combinations work.
2364};
2365
2366
2367class HHasCachedArrayIndex: public HUnaryPredicate {
2368 public:
2369 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2370
2371 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has_cached_array_index")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002372
2373 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002374 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002375};
2376
2377
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002378class HGetCachedArrayIndex: public HUnaryPredicate {
2379 public:
2380 explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2381
2382 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get_cached_array_index")
2383
2384 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002385 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002386};
2387
2388
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002389class HClassOfTest: public HUnaryPredicate {
2390 public:
2391 HClassOfTest(HValue* value, Handle<String> class_name)
2392 : HUnaryPredicate(value), class_name_(class_name) { }
2393
2394 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class_of_test")
2395
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002396 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002397
2398 Handle<String> class_name() const { return class_name_; }
2399
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002400 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002401 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002402 HClassOfTest* b = HClassOfTest::cast(other);
2403 return class_name_.is_identical_to(b->class_name_);
2404 }
2405
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002406 private:
2407 Handle<String> class_name_;
2408};
2409
2410
2411class HTypeofIs: public HUnaryPredicate {
2412 public:
2413 HTypeofIs(HValue* value, Handle<String> type_literal)
2414 : HUnaryPredicate(value), type_literal_(type_literal) { }
2415
2416 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002417 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002418
2419 DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof_is")
2420
2421 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002422 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002423 HTypeofIs* b = HTypeofIs::cast(other);
2424 return type_literal_.is_identical_to(b->type_literal_);
2425 }
2426
2427 private:
2428 Handle<String> type_literal_;
2429};
2430
2431
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002432class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002433 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002434 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2435 SetOperandAt(0, context);
2436 SetOperandAt(1, left);
2437 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002438 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002439 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002440 }
2441
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002442 HValue* context() { return OperandAt(0); }
2443 HValue* left() { return OperandAt(1); }
2444 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002445
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002446 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002447 return !HasSideEffects() && (uses()->length() <= 1);
2448 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002449
2450 virtual Representation RequiredInputRepresentation(int index) const {
2451 return Representation::Tagged();
2452 }
2453
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002454 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002455
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002456 DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance_of")
2457};
2458
2459
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002460class HInstanceOfKnownGlobal: public HUnaryOperation {
2461 public:
2462 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2463 : HUnaryOperation(left), function_(right) {
2464 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002465 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002466 }
2467
2468 Handle<JSFunction> function() { return function_; }
2469
2470 virtual Representation RequiredInputRepresentation(int index) const {
2471 return Representation::Tagged();
2472 }
2473
2474 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
2475 "instance_of_known_global")
2476
2477 private:
2478 Handle<JSFunction> function_;
2479};
2480
2481
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002482class HPower: public HBinaryOperation {
2483 public:
2484 HPower(HValue* left, HValue* right)
2485 : HBinaryOperation(left, right) {
2486 set_representation(Representation::Double());
2487 SetFlag(kUseGVN);
2488 }
2489
2490 virtual Representation RequiredInputRepresentation(int index) const {
2491 return (index == 1) ? Representation::None() : Representation::Double();
2492 }
2493
2494 DECLARE_CONCRETE_INSTRUCTION(Power, "power")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002495
2496 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002497 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002498};
2499
2500
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002501class HAdd: public HArithmeticBinaryOperation {
2502 public:
2503 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2504 SetFlag(kCanOverflow);
2505 }
2506
2507 // Add is only commutative if two integer values are added and not if two
2508 // tagged values are added (because it might be a String concatenation).
2509 virtual bool IsCommutative() const {
2510 return !representation().IsTagged();
2511 }
2512
2513 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2514
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002515 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002516
2517 DECLARE_CONCRETE_INSTRUCTION(Add, "add")
2518
2519 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002520 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002521
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002522 virtual Range* InferRange();
2523};
2524
2525
2526class HSub: public HArithmeticBinaryOperation {
2527 public:
2528 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2529 SetFlag(kCanOverflow);
2530 }
2531
2532 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2533
2534 DECLARE_CONCRETE_INSTRUCTION(Sub, "sub")
2535
2536 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002537 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002538
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002539 virtual Range* InferRange();
2540};
2541
2542
2543class HMul: public HArithmeticBinaryOperation {
2544 public:
2545 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2546 SetFlag(kCanOverflow);
2547 }
2548
2549 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2550
2551 // Only commutative if it is certain that not two objects are multiplicated.
2552 virtual bool IsCommutative() const {
2553 return !representation().IsTagged();
2554 }
2555
2556 DECLARE_CONCRETE_INSTRUCTION(Mul, "mul")
2557
2558 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002559 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002560
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002561 virtual Range* InferRange();
2562};
2563
2564
2565class HMod: public HArithmeticBinaryOperation {
2566 public:
2567 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2568 SetFlag(kCanBeDivByZero);
2569 }
2570
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002571 bool HasPowerOf2Divisor() {
2572 if (right()->IsConstant() &&
2573 HConstant::cast(right())->HasInteger32Value()) {
2574 int32_t value = HConstant::cast(right())->Integer32Value();
2575 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2576 }
2577
2578 return false;
2579 }
2580
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002581 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2582
2583 DECLARE_CONCRETE_INSTRUCTION(Mod, "mod")
2584
2585 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002586 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002587
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002588 virtual Range* InferRange();
2589};
2590
2591
2592class HDiv: public HArithmeticBinaryOperation {
2593 public:
2594 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2595 SetFlag(kCanBeDivByZero);
2596 SetFlag(kCanOverflow);
2597 }
2598
2599 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2600
2601 DECLARE_CONCRETE_INSTRUCTION(Div, "div")
2602
2603 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002604 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002605
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002606 virtual Range* InferRange();
2607};
2608
2609
2610class HBitAnd: public HBitwiseBinaryOperation {
2611 public:
2612 HBitAnd(HValue* left, HValue* right)
2613 : HBitwiseBinaryOperation(left, right) { }
2614
2615 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002616 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002617
2618 DECLARE_CONCRETE_INSTRUCTION(BitAnd, "bit_and")
2619
2620 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002621 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002622
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002623 virtual Range* InferRange();
2624};
2625
2626
2627class HBitXor: public HBitwiseBinaryOperation {
2628 public:
2629 HBitXor(HValue* left, HValue* right)
2630 : HBitwiseBinaryOperation(left, right) { }
2631
2632 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002633 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002634
2635 DECLARE_CONCRETE_INSTRUCTION(BitXor, "bit_xor")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002636
2637 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002638 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002639};
2640
2641
2642class HBitOr: public HBitwiseBinaryOperation {
2643 public:
2644 HBitOr(HValue* left, HValue* right)
2645 : HBitwiseBinaryOperation(left, right) { }
2646
2647 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002648 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002649
2650 DECLARE_CONCRETE_INSTRUCTION(BitOr, "bit_or")
2651
2652 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002653 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002654
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002655 virtual Range* InferRange();
2656};
2657
2658
2659class HShl: public HBitwiseBinaryOperation {
2660 public:
2661 HShl(HValue* left, HValue* right)
2662 : HBitwiseBinaryOperation(left, right) { }
2663
2664 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002665 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002666
2667 DECLARE_CONCRETE_INSTRUCTION(Shl, "shl")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002668
2669 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002670 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002671};
2672
2673
2674class HShr: public HBitwiseBinaryOperation {
2675 public:
2676 HShr(HValue* left, HValue* right)
2677 : HBitwiseBinaryOperation(left, right) { }
2678
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002679 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002680
2681 DECLARE_CONCRETE_INSTRUCTION(Shr, "shr")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002682
2683 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002684 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002685};
2686
2687
2688class HSar: public HBitwiseBinaryOperation {
2689 public:
2690 HSar(HValue* left, HValue* right)
2691 : HBitwiseBinaryOperation(left, right) { }
2692
2693 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002694 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002695
2696 DECLARE_CONCRETE_INSTRUCTION(Sar, "sar")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002697
2698 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002699 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002700};
2701
2702
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002703class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002704 public:
2705 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
2706 SetFlag(kChangesOsrEntries);
2707 }
2708
2709 int ast_id() const { return ast_id_; }
2710
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002711 virtual Representation RequiredInputRepresentation(int index) const {
2712 return Representation::None();
2713 }
2714
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002715 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr_entry")
2716
2717 private:
2718 int ast_id_;
2719};
2720
2721
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002722class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002723 public:
2724 explicit HParameter(unsigned index) : index_(index) {
2725 set_representation(Representation::Tagged());
2726 }
2727
2728 unsigned index() const { return index_; }
2729
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002730 virtual void PrintDataTo(StringStream* stream);
2731
2732 virtual Representation RequiredInputRepresentation(int index) const {
2733 return Representation::None();
2734 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002735
2736 DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
2737
2738 private:
2739 unsigned index_;
2740};
2741
2742
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002743class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002744 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002745 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
2746 : HUnaryCall(context, argument_count),
2747 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002748 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002749 }
2750
2751 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002752
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002753 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002754
2755 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
2756 transcendental_type_ = transcendental_type;
2757 }
2758 TranscendentalCache::Type transcendental_type() {
2759 return transcendental_type_;
2760 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002761
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002762 virtual void PrintDataTo(StringStream* stream);
2763
2764 virtual Representation RequiredInputRepresentation(int index) const {
2765 return Representation::Tagged();
2766 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002767
2768 DECLARE_CONCRETE_INSTRUCTION(CallStub, "call_stub")
2769
2770 private:
2771 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002772 TranscendentalCache::Type transcendental_type_;
2773};
2774
2775
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002776class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002777 public:
2778 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
2779
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002780 virtual Representation RequiredInputRepresentation(int index) const {
2781 return Representation::None();
2782 }
2783
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002784 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown_osr_value")
2785};
2786
2787
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002788class HLoadGlobal: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002789 public:
2790 HLoadGlobal(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
2791 : cell_(cell), check_hole_value_(check_hole_value) {
2792 set_representation(Representation::Tagged());
2793 SetFlag(kUseGVN);
2794 SetFlag(kDependsOnGlobalVars);
2795 }
2796
2797 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
2798 bool check_hole_value() const { return check_hole_value_; }
2799
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002800 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002801
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002802 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002803 ASSERT(!Heap::allow_allocation(false));
2804 return reinterpret_cast<intptr_t>(*cell_);
2805 }
2806
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002807 virtual Representation RequiredInputRepresentation(int index) const {
2808 return Representation::None();
2809 }
2810
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002811 DECLARE_CONCRETE_INSTRUCTION(LoadGlobal, "load_global")
2812
2813 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002814 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002815 HLoadGlobal* b = HLoadGlobal::cast(other);
2816 return cell_.is_identical_to(b->cell());
2817 }
2818
2819 private:
2820 Handle<JSGlobalPropertyCell> cell_;
2821 bool check_hole_value_;
2822};
2823
2824
2825class HStoreGlobal: public HUnaryOperation {
2826 public:
ager@chromium.org378b34e2011-01-28 08:04:38 +00002827 HStoreGlobal(HValue* value,
2828 Handle<JSGlobalPropertyCell> cell,
2829 bool check_hole_value)
2830 : HUnaryOperation(value),
2831 cell_(cell),
2832 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002833 SetFlag(kChangesGlobalVars);
2834 }
2835
2836 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002837 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002838
2839 virtual Representation RequiredInputRepresentation(int index) const {
2840 return Representation::Tagged();
2841 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002842 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002843
2844 DECLARE_CONCRETE_INSTRUCTION(StoreGlobal, "store_global")
2845
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002846 private:
2847 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00002848 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002849};
2850
2851
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002852class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002853 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002854 HLoadContextSlot(HValue* context , int slot_index)
2855 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002856 set_representation(Representation::Tagged());
2857 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002858 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002859 }
2860
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002861 int slot_index() const { return slot_index_; }
2862
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002863 virtual Representation RequiredInputRepresentation(int index) const {
2864 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002865 }
2866
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002867 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002868
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002869 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load_context_slot")
2870
2871 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002872 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002873 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002874 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002875 }
2876
2877 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002878 int slot_index_;
2879};
2880
2881
2882static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
2883 return !value->type().IsSmi() &&
2884 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
2885}
2886
2887
2888class HStoreContextSlot: public HBinaryOperation {
2889 public:
2890 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
2891 : HBinaryOperation(context, value), slot_index_(slot_index) {
2892 SetFlag(kChangesContextSlots);
2893 }
2894
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002895 HValue* context() { return OperandAt(0); }
2896 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002897 int slot_index() const { return slot_index_; }
2898
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002899 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002900 return StoringValueNeedsWriteBarrier(value());
2901 }
2902
2903 virtual Representation RequiredInputRepresentation(int index) const {
2904 return Representation::Tagged();
2905 }
2906
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002907 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002908
2909 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store_context_slot")
2910
2911 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002912 int slot_index_;
2913};
2914
2915
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002916class HLoadNamedField: public HUnaryOperation {
2917 public:
2918 HLoadNamedField(HValue* object, bool is_in_object, int offset)
2919 : HUnaryOperation(object),
2920 is_in_object_(is_in_object),
2921 offset_(offset) {
2922 set_representation(Representation::Tagged());
2923 SetFlag(kUseGVN);
2924 if (is_in_object) {
2925 SetFlag(kDependsOnInobjectFields);
2926 } else {
2927 SetFlag(kDependsOnBackingStoreFields);
2928 }
2929 }
2930
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002931 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002932 bool is_in_object() const { return is_in_object_; }
2933 int offset() const { return offset_; }
2934
2935 virtual Representation RequiredInputRepresentation(int index) const {
2936 return Representation::Tagged();
2937 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002938 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002939
2940 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load_named_field")
2941
2942 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002943 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002944 HLoadNamedField* b = HLoadNamedField::cast(other);
2945 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
2946 }
2947
2948 private:
2949 bool is_in_object_;
2950 int offset_;
2951};
2952
2953
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002954class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002955 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002956 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
2957 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002958 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002959 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002960 }
2961
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002962 HValue* context() { return OperandAt(0); }
2963 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002964 Handle<Object> name() const { return name_; }
2965
2966 virtual Representation RequiredInputRepresentation(int index) const {
2967 return Representation::Tagged();
2968 }
2969
2970 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load_named_generic")
2971
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002972 private:
2973 Handle<Object> name_;
2974};
2975
2976
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002977class HLoadFunctionPrototype: public HUnaryOperation {
2978 public:
2979 explicit HLoadFunctionPrototype(HValue* function)
2980 : HUnaryOperation(function) {
2981 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002982 SetFlag(kUseGVN);
2983 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002984 }
2985
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002986 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002987
2988 virtual Representation RequiredInputRepresentation(int index) const {
2989 return Representation::Tagged();
2990 }
2991
2992 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load_function_prototype")
2993
2994 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002995 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002996};
2997
2998
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002999class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003000 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003001 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003002 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003003 SetFlag(kDependsOnArrayElements);
3004 SetFlag(kUseGVN);
3005 }
3006
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003007 HValue* object() { return OperandAt(0); }
3008 HValue* key() { return OperandAt(1); }
3009
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003010 virtual Representation RequiredInputRepresentation(int index) const {
3011 // The key is supposed to be Integer32.
3012 return (index == 1) ? Representation::Integer32()
3013 : Representation::Tagged();
3014 }
3015
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003016 virtual void PrintDataTo(StringStream* stream);
3017
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003018 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement,
3019 "load_keyed_fast_element")
ager@chromium.org378b34e2011-01-28 08:04:38 +00003020
3021 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003022 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003023};
3024
3025
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003026class HLoadPixelArrayElement: public HBinaryOperation {
3027 public:
3028 HLoadPixelArrayElement(HValue* external_elements, HValue* key)
3029 : HBinaryOperation(external_elements, key) {
3030 set_representation(Representation::Integer32());
3031 SetFlag(kDependsOnPixelArrayElements);
3032 // Native code could change the pixel array.
3033 SetFlag(kDependsOnCalls);
3034 SetFlag(kUseGVN);
3035 }
3036
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003037 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003038
3039 virtual Representation RequiredInputRepresentation(int index) const {
3040 // The key is supposed to be Integer32, but the base pointer
3041 // for the element load is a naked pointer.
3042 return (index == 1) ? Representation::Integer32()
3043 : Representation::External();
3044 }
3045
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003046 HValue* external_pointer() { return OperandAt(0); }
3047 HValue* key() { return OperandAt(1); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003048
3049 DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayElement,
3050 "load_pixel_array_element")
3051
3052 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003053 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003054};
3055
3056
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003057class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003058 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003059 HLoadKeyedGeneric(HContext* context, HValue* obj, HValue* key) {
3060 set_representation(Representation::Tagged());
3061 SetOperandAt(0, obj);
3062 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003063 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003064 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003065 }
3066
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003067 HValue* object() { return OperandAt(0); }
3068 HValue* key() { return OperandAt(1); }
3069 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003070
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003071 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003072
3073 virtual Representation RequiredInputRepresentation(int index) const {
3074 return Representation::Tagged();
3075 }
3076
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003077 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load_keyed_generic")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003078};
3079
3080
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003081class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003082 public:
3083 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003084 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003085 HValue* val,
3086 bool in_object,
3087 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003088 : HBinaryOperation(obj, val),
3089 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003090 is_in_object_(in_object),
3091 offset_(offset) {
3092 if (is_in_object_) {
3093 SetFlag(kChangesInobjectFields);
3094 } else {
3095 SetFlag(kChangesBackingStoreFields);
3096 }
3097 }
3098
3099 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store_named_field")
3100
3101 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003102 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003103 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003104 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003105
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003106 HValue* object() { return OperandAt(0); }
3107 HValue* value() { return OperandAt(1); }
3108
3109 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003110 bool is_in_object() const { return is_in_object_; }
3111 int offset() const { return offset_; }
3112 Handle<Map> transition() const { return transition_; }
3113 void set_transition(Handle<Map> map) { transition_ = map; }
3114
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003115 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003116 return StoringValueNeedsWriteBarrier(value());
3117 }
3118
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003119 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003120 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003121 bool is_in_object_;
3122 int offset_;
3123 Handle<Map> transition_;
3124};
3125
3126
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003127class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003128 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003129 HStoreNamedGeneric(HValue* context,
3130 HValue* object,
3131 Handle<String> name,
3132 HValue* value)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003133 : name_(name) {
3134 SetOperandAt(0, object);
3135 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003136 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003137 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003138 }
3139
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003140 HValue* object() { return OperandAt(0); }
3141 HValue* value() { return OperandAt(1); }
3142 HValue* context() { return OperandAt(2); }
3143 Handle<String> name() { return name_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003144
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003145 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003146
3147 virtual Representation RequiredInputRepresentation(int index) const {
3148 return Representation::Tagged();
3149 }
3150
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003151 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store_named_generic")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003152
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003153 private:
3154 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003155};
3156
3157
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003158class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003159 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003160 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3161 SetOperandAt(0, obj);
3162 SetOperandAt(1, key);
3163 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003164 SetFlag(kChangesArrayElements);
3165 }
3166
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003167 virtual Representation RequiredInputRepresentation(int index) const {
3168 // The key is supposed to be Integer32.
3169 return (index == 1) ? Representation::Integer32()
3170 : Representation::Tagged();
3171 }
3172
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003173 HValue* object() { return OperandAt(0); }
3174 HValue* key() { return OperandAt(1); }
3175 HValue* value() { return OperandAt(2); }
3176
3177 bool NeedsWriteBarrier() {
3178 return StoringValueNeedsWriteBarrier(value());
3179 }
3180
3181 virtual void PrintDataTo(StringStream* stream);
3182
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003183 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
3184 "store_keyed_fast_element")
3185};
3186
3187
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003188class HStorePixelArrayElement: public HTemplateInstruction<3> {
3189 public:
3190 HStorePixelArrayElement(HValue* external_elements, HValue* key, HValue* val) {
3191 SetFlag(kChangesPixelArrayElements);
3192 SetOperandAt(0, external_elements);
3193 SetOperandAt(1, key);
3194 SetOperandAt(2, val);
3195 }
3196
3197 virtual void PrintDataTo(StringStream* stream);
3198
3199 virtual Representation RequiredInputRepresentation(int index) const {
3200 if (index == 0) {
3201 return Representation::External();
3202 } else {
3203 return Representation::Integer32();
3204 }
3205 }
3206
3207 HValue* external_pointer() { return OperandAt(0); }
3208 HValue* key() { return OperandAt(1); }
3209 HValue* value() { return OperandAt(2); }
3210
3211 DECLARE_CONCRETE_INSTRUCTION(StorePixelArrayElement,
3212 "store_pixel_array_element")
3213};
3214
3215
3216class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003217 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003218 HStoreKeyedGeneric(HValue* context,
3219 HValue* object,
3220 HValue* key,
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003221 HValue* value) {
3222 SetOperandAt(0, object);
3223 SetOperandAt(1, key);
3224 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003225 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003226 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003227 }
3228
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003229 HValue* object() { return OperandAt(0); }
3230 HValue* key() { return OperandAt(1); }
3231 HValue* value() { return OperandAt(2); }
3232 HValue* context() { return OperandAt(3); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003233
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003234 virtual Representation RequiredInputRepresentation(int index) const {
3235 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003236 }
3237
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003238 virtual void PrintDataTo(StringStream* stream);
3239
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003240 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store_keyed_generic")
3241};
3242
3243
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003244class HStringCharCodeAt: public HBinaryOperation {
3245 public:
3246 HStringCharCodeAt(HValue* string, HValue* index)
3247 : HBinaryOperation(string, index) {
3248 set_representation(Representation::Integer32());
3249 SetFlag(kUseGVN);
3250 }
3251
3252 virtual Representation RequiredInputRepresentation(int index) const {
3253 // The index is supposed to be Integer32.
3254 return (index == 1) ? Representation::Integer32()
3255 : Representation::Tagged();
3256 }
3257
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003258 HValue* string() { return OperandAt(0); }
3259 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003260
3261 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string_char_code_at")
3262
3263 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003264 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003265
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003266 virtual Range* InferRange() {
3267 return new Range(0, String::kMaxUC16CharCode);
3268 }
3269};
3270
3271
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003272class HStringCharFromCode: public HUnaryOperation {
3273 public:
3274 explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
3275 set_representation(Representation::Tagged());
3276 SetFlag(kUseGVN);
3277 }
3278
3279 virtual Representation RequiredInputRepresentation(int index) const {
3280 return Representation::Integer32();
3281 }
3282
3283 virtual bool DataEquals(HValue* other) { return true; }
3284
3285 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string_char_from_code")
3286};
3287
3288
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003289class HStringLength: public HUnaryOperation {
3290 public:
3291 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3292 set_representation(Representation::Tagged());
3293 SetFlag(kUseGVN);
3294 }
3295
3296 virtual Representation RequiredInputRepresentation(int index) const {
3297 return Representation::Tagged();
3298 }
3299
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003300 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003301 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3302 return HType::Smi();
3303 }
3304
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003305 DECLARE_CONCRETE_INSTRUCTION(StringLength, "string_length")
3306
3307 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003308 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003309
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003310 virtual Range* InferRange() {
3311 return new Range(0, String::kMaxLength);
3312 }
3313};
3314
3315
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003316template <int V>
3317class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003318 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003319 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003320 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003321 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003322 }
3323
3324 int literal_index() const { return literal_index_; }
3325 int depth() const { return depth_; }
3326
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003327 private:
3328 int literal_index_;
3329 int depth_;
3330};
3331
3332
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003333class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003334 public:
3335 HArrayLiteral(Handle<FixedArray> constant_elements,
3336 int length,
3337 int literal_index,
3338 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003339 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003340 length_(length),
3341 constant_elements_(constant_elements) {}
3342
3343 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3344 int length() const { return length_; }
3345
3346 bool IsCopyOnWrite() const;
3347
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003348 virtual Representation RequiredInputRepresentation(int index) const {
3349 return Representation::None();
3350 }
3351
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003352 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array_literal")
3353
3354 private:
3355 int length_;
3356 Handle<FixedArray> constant_elements_;
3357};
3358
3359
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003360class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003361 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003362 HObjectLiteral(HValue* context,
3363 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003364 bool fast_elements,
3365 int literal_index,
3366 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003367 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003368 constant_properties_(constant_properties),
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003369 fast_elements_(fast_elements) {
3370 SetOperandAt(0, context);
3371 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003372
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003373 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003374 Handle<FixedArray> constant_properties() const {
3375 return constant_properties_;
3376 }
3377 bool fast_elements() const { return fast_elements_; }
3378
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003379 virtual Representation RequiredInputRepresentation(int index) const {
3380 return Representation::Tagged();
3381 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003382
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003383 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object_literal")
3384
3385 private:
3386 Handle<FixedArray> constant_properties_;
3387 bool fast_elements_;
3388};
3389
3390
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003391class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003392 public:
3393 HRegExpLiteral(Handle<String> pattern,
3394 Handle<String> flags,
3395 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003396 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003397 pattern_(pattern),
3398 flags_(flags) { }
3399
3400 Handle<String> pattern() { return pattern_; }
3401 Handle<String> flags() { return flags_; }
3402
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003403 virtual Representation RequiredInputRepresentation(int index) const {
3404 return Representation::None();
3405 }
3406
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003407 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp_literal")
3408
3409 private:
3410 Handle<String> pattern_;
3411 Handle<String> flags_;
3412};
3413
3414
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003415class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003416 public:
3417 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3418 : shared_info_(shared), pretenure_(pretenure) {
3419 set_representation(Representation::Tagged());
3420 }
3421
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003422 virtual Representation RequiredInputRepresentation(int index) const {
3423 return Representation::None();
3424 }
3425
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003426 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function_literal")
3427
3428 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3429 bool pretenure() const { return pretenure_; }
3430
3431 private:
3432 Handle<SharedFunctionInfo> shared_info_;
3433 bool pretenure_;
3434};
3435
3436
3437class HTypeof: public HUnaryOperation {
3438 public:
3439 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
3440 set_representation(Representation::Tagged());
3441 }
3442
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003443 virtual Representation RequiredInputRepresentation(int index) const {
3444 return Representation::Tagged();
3445 }
3446
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003447 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
3448};
3449
3450
3451class HValueOf: public HUnaryOperation {
3452 public:
3453 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
3454 set_representation(Representation::Tagged());
3455 }
3456
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003457 virtual Representation RequiredInputRepresentation(int index) const {
3458 return Representation::Tagged();
3459 }
3460
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003461 DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value_of")
3462};
3463
3464
3465class HDeleteProperty: public HBinaryOperation {
3466 public:
3467 HDeleteProperty(HValue* obj, HValue* key)
3468 : HBinaryOperation(obj, key) {
3469 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003470 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003471 }
3472
3473 virtual Representation RequiredInputRepresentation(int index) const {
3474 return Representation::Tagged();
3475 }
3476
3477 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete_property")
3478
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003479 HValue* object() { return left(); }
3480 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003481};
3482
3483#undef DECLARE_INSTRUCTION
3484#undef DECLARE_CONCRETE_INSTRUCTION
3485
3486} } // namespace v8::internal
3487
3488#endif // V8_HYDROGEN_INSTRUCTIONS_H_