Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(215)

Side by Side Diff: src/hydrogen-instructions.h

Issue 6697023: Merge 6800:7180 from the bleeding edge branch to the experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 class HValue; 44 class HValue;
45 class LInstruction; 45 class LInstruction;
46 class LChunkBuilder; 46 class LChunkBuilder;
47 47
48 48
49 #define HYDROGEN_ALL_INSTRUCTION_LIST(V) \ 49 #define HYDROGEN_ALL_INSTRUCTION_LIST(V) \
50 V(ArithmeticBinaryOperation) \ 50 V(ArithmeticBinaryOperation) \
51 V(BinaryCall) \ 51 V(BinaryCall) \
52 V(BinaryOperation) \ 52 V(BinaryOperation) \
53 V(BitwiseBinaryOperation) \ 53 V(BitwiseBinaryOperation) \
54 V(Call) \
55 V(ControlInstruction) \ 54 V(ControlInstruction) \
56 V(Instruction) \ 55 V(Instruction) \
57 V(LoadKeyed) \
58 V(MaterializedLiteral) \
59 V(Phi) \ 56 V(Phi) \
60 V(StoreKeyed) \
61 V(StoreNamed) \
62 V(UnaryCall) \ 57 V(UnaryCall) \
63 V(UnaryControlInstruction) \ 58 V(UnaryControlInstruction) \
64 V(UnaryOperation) \ 59 V(UnaryOperation) \
65 HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) 60 HYDROGEN_CONCRETE_INSTRUCTION_LIST(V)
66 61
67 62
68 #define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \ 63 #define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
69 V(AbnormalExit) \ 64 V(AbnormalExit) \
70 V(AccessArgumentsAt) \ 65 V(AccessArgumentsAt) \
71 V(Add) \ 66 V(Add) \
(...skipping 17 matching lines...) Expand all
89 V(CallNew) \ 84 V(CallNew) \
90 V(CallRuntime) \ 85 V(CallRuntime) \
91 V(CallStub) \ 86 V(CallStub) \
92 V(Change) \ 87 V(Change) \
93 V(CheckFunction) \ 88 V(CheckFunction) \
94 V(CheckInstanceType) \ 89 V(CheckInstanceType) \
95 V(CheckMap) \ 90 V(CheckMap) \
96 V(CheckNonSmi) \ 91 V(CheckNonSmi) \
97 V(CheckPrototypeMaps) \ 92 V(CheckPrototypeMaps) \
98 V(CheckSmi) \ 93 V(CheckSmi) \
94 V(ClassOfTest) \
99 V(Compare) \ 95 V(Compare) \
100 V(CompareJSObjectEq) \ 96 V(CompareJSObjectEq) \
101 V(CompareMap) \ 97 V(CompareMap) \
102 V(Constant) \ 98 V(Constant) \
103 V(Context) \ 99 V(Context) \
104 V(DeleteProperty) \ 100 V(DeleteProperty) \
105 V(Deoptimize) \ 101 V(Deoptimize) \
106 V(Div) \ 102 V(Div) \
107 V(EnterInlined) \ 103 V(EnterInlined) \
104 V(ExternalArrayLength) \
108 V(FixedArrayLength) \ 105 V(FixedArrayLength) \
109 V(FunctionLiteral) \ 106 V(FunctionLiteral) \
107 V(GetCachedArrayIndex) \
110 V(GlobalObject) \ 108 V(GlobalObject) \
111 V(GlobalReceiver) \ 109 V(GlobalReceiver) \
112 V(Goto) \ 110 V(Goto) \
111 V(HasInstanceType) \
112 V(HasCachedArrayIndex) \
113 V(InstanceOf) \ 113 V(InstanceOf) \
114 V(InstanceOfKnownGlobal) \ 114 V(InstanceOfKnownGlobal) \
115 V(IsNull) \ 115 V(IsNull) \
116 V(IsObject) \ 116 V(IsObject) \
117 V(IsSmi) \ 117 V(IsSmi) \
118 V(IsConstructCall) \ 118 V(IsConstructCall) \
119 V(HasInstanceType) \
120 V(HasCachedArrayIndex) \
121 V(JSArrayLength) \ 119 V(JSArrayLength) \
122 V(ClassOfTest) \
123 V(LeaveInlined) \ 120 V(LeaveInlined) \
124 V(LoadContextSlot) \ 121 V(LoadContextSlot) \
125 V(LoadElements) \ 122 V(LoadElements) \
123 V(LoadExternalArrayPointer) \
126 V(LoadFunctionPrototype) \ 124 V(LoadFunctionPrototype) \
127 V(LoadGlobal) \ 125 V(LoadGlobal) \
128 V(LoadKeyedFastElement) \ 126 V(LoadKeyedFastElement) \
129 V(LoadKeyedGeneric) \ 127 V(LoadKeyedGeneric) \
130 V(LoadNamedField) \ 128 V(LoadNamedField) \
131 V(LoadNamedGeneric) \ 129 V(LoadNamedGeneric) \
132 V(LoadPixelArrayElement) \ 130 V(LoadPixelArrayElement) \
133 V(LoadPixelArrayExternalPointer) \
134 V(Mod) \ 131 V(Mod) \
135 V(Mul) \ 132 V(Mul) \
136 V(ObjectLiteral) \ 133 V(ObjectLiteral) \
137 V(OsrEntry) \ 134 V(OsrEntry) \
138 V(OuterContext) \ 135 V(OuterContext) \
139 V(Parameter) \ 136 V(Parameter) \
140 V(PixelArrayLength) \
141 V(Power) \ 137 V(Power) \
142 V(PushArgument) \ 138 V(PushArgument) \
143 V(RegExpLiteral) \ 139 V(RegExpLiteral) \
144 V(Return) \ 140 V(Return) \
145 V(Sar) \ 141 V(Sar) \
146 V(Shl) \ 142 V(Shl) \
147 V(Shr) \ 143 V(Shr) \
148 V(Simulate) \ 144 V(Simulate) \
149 V(StackCheck) \ 145 V(StackCheck) \
150 V(StoreContextSlot) \ 146 V(StoreContextSlot) \
151 V(StoreGlobal) \ 147 V(StoreGlobal) \
152 V(StoreKeyedFastElement) \ 148 V(StoreKeyedFastElement) \
149 V(StorePixelArrayElement) \
153 V(StoreKeyedGeneric) \ 150 V(StoreKeyedGeneric) \
154 V(StoreNamedField) \ 151 V(StoreNamedField) \
155 V(StoreNamedGeneric) \ 152 V(StoreNamedGeneric) \
156 V(StringCharCodeAt) \ 153 V(StringCharCodeAt) \
154 V(StringCharFromCode) \
157 V(StringLength) \ 155 V(StringLength) \
158 V(Sub) \ 156 V(Sub) \
159 V(Test) \ 157 V(Test) \
160 V(Throw) \ 158 V(Throw) \
161 V(Typeof) \ 159 V(Typeof) \
162 V(TypeofIs) \ 160 V(TypeofIs) \
163 V(UnaryMathOperation) \ 161 V(UnaryMathOperation) \
164 V(UnknownOSRValue) \ 162 V(UnknownOSRValue) \
165 V(ValueOf) 163 V(ValueOf)
166 164
(...skipping 17 matching lines...) Expand all
184 } \ 182 } \
185 Opcode opcode() const { return HValue::k##type; } 183 Opcode opcode() const { return HValue::k##type; }
186 184
187 185
188 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \ 186 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
189 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \ 187 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
190 virtual const char* Mnemonic() const { return mnemonic; } \ 188 virtual const char* Mnemonic() const { return mnemonic; } \
191 DECLARE_INSTRUCTION(type) 189 DECLARE_INSTRUCTION(type)
192 190
193 191
194
195 template<int kSize>
196 class HOperandVector : public EmbeddedVector<HValue*, kSize> {
197 public:
198 HOperandVector() : EmbeddedVector<HValue*, kSize>(NULL) { }
199 };
200
201
202 class Range: public ZoneObject { 192 class Range: public ZoneObject {
203 public: 193 public:
204 Range() : lower_(kMinInt), 194 Range()
205 upper_(kMaxInt), 195 : lower_(kMinInt),
206 next_(NULL), 196 upper_(kMaxInt),
207 can_be_minus_zero_(false) { } 197 next_(NULL),
198 can_be_minus_zero_(false) { }
208 199
209 Range(int32_t lower, int32_t upper) 200 Range(int32_t lower, int32_t upper)
210 : lower_(lower), upper_(upper), next_(NULL), can_be_minus_zero_(false) { } 201 : lower_(lower),
202 upper_(upper),
203 next_(NULL),
204 can_be_minus_zero_(false) { }
211 205
206 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); }
211 Range* Copy() const { return new Range(lower_, upper_); }
212 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; }
217 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
218 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
212 bool IsInSmiRange() const { 219 bool IsInSmiRange() const {
213 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue; 220 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
214 } 221 }
215 void KeepOrder(); 222 void KeepOrder();
216 void Verify() const; 223 void Verify() const;
217 int32_t upper() const { return upper_; }
218 int32_t lower() const { return lower_; }
219 Range* next() const { return next_; }
220 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
221 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
222 void ClearLower() { lower_ = kMinInt; }
223 void ClearUpper() { upper_ = kMaxInt; }
224 Range* Copy() const { return new Range(lower_, upper_); }
225 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
226 int32_t Mask() const;
227 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
228 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
229 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
230 bool CanBeNegative() const { return lower_ < 0; }
231 bool Includes(int value) const {
232 return lower_ <= value && upper_ >= value;
233 }
234
235 void Sar(int32_t value) {
236 int32_t bits = value & 0x1F;
237 lower_ = lower_ >> bits;
238 upper_ = upper_ >> bits;
239 set_can_be_minus_zero(false);
240 }
241
242 void Shl(int32_t value) {
243 int32_t bits = value & 0x1F;
244 int old_lower = lower_;
245 int old_upper = upper_;
246 lower_ = lower_ << bits;
247 upper_ = upper_ << bits;
248 if (old_lower != lower_ >> bits || old_upper != upper_ >> bits) {
249 upper_ = kMaxInt;
250 lower_ = kMinInt;
251 }
252 set_can_be_minus_zero(false);
253 }
254
255 // Adds a constant to the lower and upper bound of the range.
256 void AddConstant(int32_t value);
257 224
258 void StackUpon(Range* other) { 225 void StackUpon(Range* other) {
259 Intersect(other); 226 Intersect(other);
260 next_ = other; 227 next_ = other;
261 } 228 }
262 229
263 void Intersect(Range* other) { 230 void Intersect(Range* other);
264 upper_ = Min(upper_, other->upper_); 231 void Union(Range* other);
265 lower_ = Max(lower_, other->lower_);
266 bool b = CanBeMinusZero() && other->CanBeMinusZero();
267 set_can_be_minus_zero(b);
268 }
269 232
270 void Union(Range* other) { 233 void AddConstant(int32_t value);
271 upper_ = Max(upper_, other->upper_); 234 void Sar(int32_t value);
272 lower_ = Min(lower_, other->lower_); 235 void Shl(int32_t value);
273 bool b = CanBeMinusZero() || other->CanBeMinusZero();
274 set_can_be_minus_zero(b);
275 }
276
277 // Compute a new result range and return true, if the operation
278 // can overflow.
279 bool AddAndCheckOverflow(Range* other); 236 bool AddAndCheckOverflow(Range* other);
280 bool SubAndCheckOverflow(Range* other); 237 bool SubAndCheckOverflow(Range* other);
281 bool MulAndCheckOverflow(Range* other); 238 bool MulAndCheckOverflow(Range* other);
282 239
283 private: 240 private:
284 int32_t lower_; 241 int32_t lower_;
285 int32_t upper_; 242 int32_t upper_;
286 Range* next_; 243 Range* next_;
287 bool can_be_minus_zero_; 244 bool can_be_minus_zero_;
288 }; 245 };
(...skipping 11 matching lines...) Expand all
300 }; 257 };
301 258
302 Representation() : kind_(kNone) { } 259 Representation() : kind_(kNone) { }
303 260
304 static Representation None() { return Representation(kNone); } 261 static Representation None() { return Representation(kNone); }
305 static Representation Tagged() { return Representation(kTagged); } 262 static Representation Tagged() { return Representation(kTagged); }
306 static Representation Integer32() { return Representation(kInteger32); } 263 static Representation Integer32() { return Representation(kInteger32); }
307 static Representation Double() { return Representation(kDouble); } 264 static Representation Double() { return Representation(kDouble); }
308 static Representation External() { return Representation(kExternal); } 265 static Representation External() { return Representation(kExternal); }
309 266
310 bool Equals(const Representation& other) const { 267 bool Equals(const Representation& other) {
311 return kind_ == other.kind_; 268 return kind_ == other.kind_;
312 } 269 }
313 270
314 Kind kind() const { return kind_; } 271 Kind kind() const { return kind_; }
315 bool IsNone() const { return kind_ == kNone; } 272 bool IsNone() const { return kind_ == kNone; }
316 bool IsTagged() const { return kind_ == kTagged; } 273 bool IsTagged() const { return kind_ == kTagged; }
317 bool IsInteger32() const { return kind_ == kInteger32; } 274 bool IsInteger32() const { return kind_ == kInteger32; }
318 bool IsDouble() const { return kind_ == kDouble; } 275 bool IsDouble() const { return kind_ == kDouble; }
319 bool IsExternal() const { return kind_ == kExternal; } 276 bool IsExternal() const { return kind_ == kExternal; }
320 bool IsSpecialization() const { 277 bool IsSpecialization() const {
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 range_(NULL), 455 range_(NULL),
499 flags_(0) {} 456 flags_(0) {}
500 virtual ~HValue() {} 457 virtual ~HValue() {}
501 458
502 HBasicBlock* block() const { return block_; } 459 HBasicBlock* block() const { return block_; }
503 void SetBlock(HBasicBlock* block); 460 void SetBlock(HBasicBlock* block);
504 461
505 int id() const { return id_; } 462 int id() const { return id_; }
506 void set_id(int id) { id_ = id; } 463 void set_id(int id) { id_ = id; }
507 464
508 const ZoneList<HValue*>* uses() const { return &uses_; } 465 ZoneList<HValue*>* uses() { return &uses_; }
509 466
510 virtual bool EmitAtUses() const { return false; } 467 virtual bool EmitAtUses() { return false; }
511 Representation representation() const { return representation_; } 468 Representation representation() const { return representation_; }
512 void ChangeRepresentation(Representation r) { 469 void ChangeRepresentation(Representation r) {
513 // Representation was already set and is allowed to be changed. 470 // Representation was already set and is allowed to be changed.
514 ASSERT(!representation_.IsNone()); 471 ASSERT(!representation_.IsNone());
515 ASSERT(!r.IsNone()); 472 ASSERT(!r.IsNone());
516 ASSERT(CheckFlag(kFlexibleRepresentation)); 473 ASSERT(CheckFlag(kFlexibleRepresentation));
517 RepresentationChanged(r); 474 RepresentationChanged(r);
518 representation_ = r; 475 representation_ = r;
519 } 476 }
520 477
(...skipping 14 matching lines...) Expand all
535 // one input. They are phi and binary add. They always return NULL and 492 // one input. They are phi and binary add. They always return NULL and
536 // expect the caller to take care of things. 493 // expect the caller to take care of things.
537 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) { 494 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
538 visited->Add(id()); 495 visited->Add(id());
539 return NULL; 496 return NULL;
540 } 497 }
541 498
542 bool IsDefinedAfter(HBasicBlock* other) const; 499 bool IsDefinedAfter(HBasicBlock* other) const;
543 500
544 // Operands. 501 // Operands.
545 virtual int OperandCount() const { return 0; } 502 virtual int OperandCount() = 0;
546 virtual HValue* OperandAt(int index) const { 503 virtual HValue* OperandAt(int index) = 0;
547 UNREACHABLE();
548 return NULL;
549 }
550 void SetOperandAt(int index, HValue* value); 504 void SetOperandAt(int index, HValue* value);
551 505
552 int LookupOperandIndex(int occurrence_index, HValue* op) const; 506 int LookupOperandIndex(int occurrence_index, HValue* op);
553 bool UsesMultipleTimes(HValue* op) const; 507 bool UsesMultipleTimes(HValue* op);
554 508
555 void ReplaceAndDelete(HValue* other); 509 void ReplaceAndDelete(HValue* other);
556 void ReplaceValue(HValue* other); 510 void ReplaceValue(HValue* other);
557 void ReplaceAtUse(HValue* use, HValue* other); 511 void ReplaceAtUse(HValue* use, HValue* other);
558 void ReplaceFirstAtUse(HValue* use, HValue* other, Representation r); 512 void ReplaceFirstAtUse(HValue* use, HValue* other, Representation r);
559 bool HasNoUses() const { return uses_.is_empty(); } 513 bool HasNoUses() const { return uses_.is_empty(); }
560 void ClearOperands(); 514 void ClearOperands();
561 void Delete(); 515 void Delete();
562 516
563 int flags() const { return flags_; } 517 int flags() const { return flags_; }
564 void SetFlag(Flag f) { flags_ |= (1 << f); } 518 void SetFlag(Flag f) { flags_ |= (1 << f); }
565 void ClearFlag(Flag f) { flags_ &= ~(1 << f); } 519 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
566 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; } 520 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
567 521
568 void SetAllSideEffects() { flags_ |= AllSideEffects(); } 522 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
569 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); } 523 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
570 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; } 524 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
571 525
572 Range* range() const { return range_; } 526 Range* range() const { return range_; }
573 bool HasRange() const { return range_ != NULL; } 527 bool HasRange() const { return range_ != NULL; }
574 void AddNewRange(Range* r); 528 void AddNewRange(Range* r);
575 void RemoveLastAddedRange(); 529 void RemoveLastAddedRange();
576 void ComputeInitialRange(); 530 void ComputeInitialRange();
577 531
578 // Representation helpers. 532 // Representation helpers.
579 virtual Representation RequiredInputRepresentation(int index) const { 533 virtual Representation RequiredInputRepresentation(int index) const = 0;
580 return Representation::None(); 534
581 } 535 virtual Representation InferredRepresentation() {
582 virtual Representation InferredRepresentation() const {
583 return representation(); 536 return representation();
584 } 537 }
585 538
586 // This gives the instruction an opportunity to replace itself with an 539 // This gives the instruction an opportunity to replace itself with an
587 // instruction that does the same in some better way. To replace an 540 // instruction that does the same in some better way. To replace an
588 // instruction with a new one, first add the new instruction to the graph, 541 // instruction with a new one, first add the new instruction to the graph,
589 // then return it. Return NULL to have the instruction deleted. 542 // then return it. Return NULL to have the instruction deleted.
590 virtual HValue* Canonicalize() { return this; } 543 virtual HValue* Canonicalize() { return this; }
591 544
592 // Declare virtual type testers. 545 // Declare virtual type testers.
593 #define DECLARE_DO(type) virtual bool Is##type() const { return false; } 546 #define DECLARE_DO(type) virtual bool Is##type() const { return false; }
594 HYDROGEN_ALL_INSTRUCTION_LIST(DECLARE_DO) 547 HYDROGEN_ALL_INSTRUCTION_LIST(DECLARE_DO)
595 #undef DECLARE_DO 548 #undef DECLARE_DO
596 549
597 bool Equals(HValue* other) const; 550 bool Equals(HValue* other);
598 virtual intptr_t Hashcode() const; 551 virtual intptr_t Hashcode();
599 552
600 // Printing support. 553 // Printing support.
601 virtual void PrintTo(StringStream* stream) const = 0; 554 virtual void PrintTo(StringStream* stream) = 0;
602 void PrintNameTo(StringStream* stream); 555 void PrintNameTo(StringStream* stream);
603 static void PrintTypeTo(HType type, StringStream* stream); 556 static void PrintTypeTo(HType type, StringStream* stream);
604 557
605 virtual const char* Mnemonic() const = 0; 558 virtual const char* Mnemonic() const = 0;
606 virtual Opcode opcode() const = 0; 559 virtual Opcode opcode() const = 0;
607 560
608 // Updated the inferred type of this instruction and returns true if 561 // Updated the inferred type of this instruction and returns true if
609 // it has changed. 562 // it has changed.
610 bool UpdateInferredType(); 563 bool UpdateInferredType();
611 564
612 virtual HType CalculateInferredType() const; 565 virtual HType CalculateInferredType();
613 566
614 #ifdef DEBUG 567 #ifdef DEBUG
615 virtual void Verify() = 0; 568 virtual void Verify() = 0;
616 #endif 569 #endif
617 570
618 protected: 571 protected:
619 // This function must be overridden for instructions with flag kUseGVN, to 572 // This function must be overridden for instructions with flag kUseGVN, to
620 // compare the non-Operand parts of the instruction. 573 // compare the non-Operand parts of the instruction.
621 virtual bool DataEquals(HValue* other) const { 574 virtual bool DataEquals(HValue* other) {
622 UNREACHABLE(); 575 UNREACHABLE();
623 return false; 576 return false;
624 } 577 }
625 virtual void RepresentationChanged(Representation to) { } 578 virtual void RepresentationChanged(Representation to) { }
626 virtual Range* InferRange(); 579 virtual Range* InferRange();
627 virtual void DeleteFromGraph() = 0; 580 virtual void DeleteFromGraph() = 0;
628 virtual void InternalSetOperandAt(int index, HValue* value) { UNREACHABLE(); } 581 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
629 void clear_block() { 582 void clear_block() {
630 ASSERT(block_ != NULL); 583 ASSERT(block_ != NULL);
631 block_ = NULL; 584 block_ = NULL;
632 } 585 }
633 586
634 void set_representation(Representation r) { 587 void set_representation(Representation r) {
635 // Representation is set-once. 588 // Representation is set-once.
636 ASSERT(representation_.IsNone() && !r.IsNone()); 589 ASSERT(representation_.IsNone() && !r.IsNone());
637 representation_ = r; 590 representation_ = r;
638 } 591 }
(...skipping 21 matching lines...) Expand all
660 613
661 DISALLOW_COPY_AND_ASSIGN(HValue); 614 DISALLOW_COPY_AND_ASSIGN(HValue);
662 }; 615 };
663 616
664 617
665 class HInstruction: public HValue { 618 class HInstruction: public HValue {
666 public: 619 public:
667 HInstruction* next() const { return next_; } 620 HInstruction* next() const { return next_; }
668 HInstruction* previous() const { return previous_; } 621 HInstruction* previous() const { return previous_; }
669 622
670 void PrintTo(StringStream* stream) const; 623 virtual void PrintTo(StringStream* stream);
671 virtual void PrintDataTo(StringStream* stream) const {} 624 virtual void PrintDataTo(StringStream* stream) { }
672 625
673 bool IsLinked() const { return block() != NULL; } 626 bool IsLinked() const { return block() != NULL; }
674 void Unlink(); 627 void Unlink();
675 void InsertBefore(HInstruction* next); 628 void InsertBefore(HInstruction* next);
676 void InsertAfter(HInstruction* previous); 629 void InsertAfter(HInstruction* previous);
677 630
678 int position() const { return position_; } 631 int position() const { return position_; }
679 bool has_position() const { return position_ != RelocInfo::kNoPosition; } 632 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
680 void set_position(int position) { position_ = position; } 633 void set_position(int position) { position_ = position; }
681 634
682 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0; 635 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
683 636
684 #ifdef DEBUG 637 #ifdef DEBUG
685 virtual void Verify(); 638 virtual void Verify();
686 #endif 639 #endif
687 640
688 // Returns whether this is some kind of deoptimizing check 641 // Returns whether this is some kind of deoptimizing check
689 // instruction. 642 // instruction.
690 virtual bool IsCheckInstruction() const { return false; } 643 virtual bool IsCheckInstruction() const { return false; }
691 644
645 virtual bool IsCall() { return false; }
646
692 DECLARE_INSTRUCTION(Instruction) 647 DECLARE_INSTRUCTION(Instruction)
693 648
694 protected: 649 protected:
695 HInstruction() 650 HInstruction()
696 : next_(NULL), 651 : next_(NULL),
697 previous_(NULL), 652 previous_(NULL),
698 position_(RelocInfo::kNoPosition) { 653 position_(RelocInfo::kNoPosition) {
699 SetFlag(kDependsOnOsrEntries); 654 SetFlag(kDependsOnOsrEntries);
700 } 655 }
701 656
702 virtual void DeleteFromGraph() { Unlink(); } 657 virtual void DeleteFromGraph() { Unlink(); }
703 658
704 private: 659 private:
705 void InitializeAsFirst(HBasicBlock* block) { 660 void InitializeAsFirst(HBasicBlock* block) {
706 ASSERT(!IsLinked()); 661 ASSERT(!IsLinked());
707 SetBlock(block); 662 SetBlock(block);
708 } 663 }
709 664
710 HInstruction* next_; 665 HInstruction* next_;
711 HInstruction* previous_; 666 HInstruction* previous_;
712 int position_; 667 int position_;
713 668
714 friend class HBasicBlock; 669 friend class HBasicBlock;
715 }; 670 };
716 671
717 672
718 class HBlockEntry: public HInstruction {
719 public:
720 DECLARE_CONCRETE_INSTRUCTION(BlockEntry, "block_entry")
721 };
722
723
724 class HControlInstruction: public HInstruction { 673 class HControlInstruction: public HInstruction {
725 public: 674 public:
726 HControlInstruction(HBasicBlock* first, HBasicBlock* second) 675 HControlInstruction(HBasicBlock* first, HBasicBlock* second)
727 : first_successor_(first), second_successor_(second) { 676 : first_successor_(first), second_successor_(second) {
728 } 677 }
729 678
730 HBasicBlock* FirstSuccessor() const { return first_successor_; } 679 HBasicBlock* FirstSuccessor() const { return first_successor_; }
731 HBasicBlock* SecondSuccessor() const { return second_successor_; } 680 HBasicBlock* SecondSuccessor() const { return second_successor_; }
732 681
733 virtual void PrintDataTo(StringStream* stream) const; 682 virtual void PrintDataTo(StringStream* stream);
734 683
735 DECLARE_INSTRUCTION(ControlInstruction) 684 DECLARE_INSTRUCTION(ControlInstruction)
736 685
737 private: 686 private:
738 HBasicBlock* first_successor_; 687 HBasicBlock* first_successor_;
739 HBasicBlock* second_successor_; 688 HBasicBlock* second_successor_;
740 }; 689 };
741 690
742 691
743 class HDeoptimize: public HControlInstruction { 692 template<int NumElements>
693 class HOperandContainer {
744 public: 694 public:
745 HDeoptimize() : HControlInstruction(NULL, NULL) { } 695 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
708 template<>
709 class 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
720 template<int V>
721 class 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
734 template<int V>
735 class 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
750 class 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
760 class 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 }
746 767
747 DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize") 768 DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
748 }; 769 };
749 770
750 771
751 class HGoto: public HControlInstruction { 772 class HGoto: public HTemplateControlInstruction<0> {
752 public: 773 public:
753 explicit HGoto(HBasicBlock* target) 774 explicit HGoto(HBasicBlock* target)
754 : HControlInstruction(target, NULL), include_stack_check_(false) { 775 : HTemplateControlInstruction<0>(target, NULL),
755 } 776 include_stack_check_(false) { }
756 777
757 void set_include_stack_check(bool include_stack_check) { 778 void set_include_stack_check(bool include_stack_check) {
758 include_stack_check_ = include_stack_check; 779 include_stack_check_ = include_stack_check;
759 } 780 }
760 bool include_stack_check() const { return include_stack_check_; } 781 bool include_stack_check() const { return include_stack_check_; }
761 782
783 virtual Representation RequiredInputRepresentation(int index) const {
784 return Representation::None();
785 }
786
762 DECLARE_CONCRETE_INSTRUCTION(Goto, "goto") 787 DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
763 788
764 private: 789 private:
765 bool include_stack_check_; 790 bool include_stack_check_;
766 }; 791 };
767 792
768 793
769 class HUnaryControlInstruction: public HControlInstruction { 794 class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
770 public: 795 public:
771 explicit HUnaryControlInstruction(HValue* value, 796 explicit HUnaryControlInstruction(HValue* value,
772 HBasicBlock* true_target, 797 HBasicBlock* true_target,
773 HBasicBlock* false_target) 798 HBasicBlock* false_target)
774 : HControlInstruction(true_target, false_target) { 799 : HTemplateControlInstruction<1>(true_target, false_target) {
775 SetOperandAt(0, value); 800 SetOperandAt(0, value);
776 } 801 }
777 802
778 virtual Representation RequiredInputRepresentation(int index) const { 803 virtual void PrintDataTo(StringStream* stream);
779 return Representation::Tagged();
780 }
781 804
782 virtual void PrintDataTo(StringStream* stream) const; 805 HValue* value() { return OperandAt(0); }
783
784 HValue* value() const { return OperandAt(0); }
785 virtual int OperandCount() const { return 1; }
786 virtual HValue* OperandAt(int index) const { return operands_[index]; }
787 806
788 DECLARE_INSTRUCTION(UnaryControlInstruction) 807 DECLARE_INSTRUCTION(UnaryControlInstruction)
789
790 protected:
791 virtual void InternalSetOperandAt(int index, HValue* value) {
792 operands_[index] = value;
793 }
794
795 private:
796 HOperandVector<1> operands_;
797 }; 808 };
798 809
799 810
800 class HTest: public HUnaryControlInstruction { 811 class HTest: public HUnaryControlInstruction {
801 public: 812 public:
802 HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target) 813 HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
803 : HUnaryControlInstruction(value, true_target, false_target) { 814 : HUnaryControlInstruction(value, true_target, false_target) {
804 ASSERT(true_target != NULL && false_target != NULL); 815 ASSERT(true_target != NULL && false_target != NULL);
805 } 816 }
806 817
(...skipping 11 matching lines...) Expand all
818 Handle<Map> map, 829 Handle<Map> map,
819 HBasicBlock* true_target, 830 HBasicBlock* true_target,
820 HBasicBlock* false_target) 831 HBasicBlock* false_target)
821 : HUnaryControlInstruction(value, true_target, false_target), 832 : HUnaryControlInstruction(value, true_target, false_target),
822 map_(map) { 833 map_(map) {
823 ASSERT(true_target != NULL); 834 ASSERT(true_target != NULL);
824 ASSERT(false_target != NULL); 835 ASSERT(false_target != NULL);
825 ASSERT(!map.is_null()); 836 ASSERT(!map.is_null());
826 } 837 }
827 838
828 virtual void PrintDataTo(StringStream* stream) const; 839 virtual void PrintDataTo(StringStream* stream);
829 840
830 Handle<Map> map() const { return map_; } 841 Handle<Map> map() const { return map_; }
831 842
843 virtual Representation RequiredInputRepresentation(int index) const {
844 return Representation::Tagged();
845 }
846
832 DECLARE_CONCRETE_INSTRUCTION(CompareMap, "compare_map") 847 DECLARE_CONCRETE_INSTRUCTION(CompareMap, "compare_map")
833 848
834 private: 849 private:
835 Handle<Map> map_; 850 Handle<Map> map_;
836 }; 851 };
837 852
838 853
839 class HReturn: public HUnaryControlInstruction { 854 class HReturn: public HUnaryControlInstruction {
840 public: 855 public:
841 explicit HReturn(HValue* value) 856 explicit HReturn(HValue* value)
842 : HUnaryControlInstruction(value, NULL, NULL) { 857 : HUnaryControlInstruction(value, NULL, NULL) {
843 } 858 }
844 859
860 virtual Representation RequiredInputRepresentation(int index) const {
861 return Representation::Tagged();
862 }
863
845 DECLARE_CONCRETE_INSTRUCTION(Return, "return") 864 DECLARE_CONCRETE_INSTRUCTION(Return, "return")
846 }; 865 };
847 866
848 867
849 class HAbnormalExit: public HControlInstruction { 868 class HAbnormalExit: public HTemplateControlInstruction<0> {
850 public: 869 public:
851 HAbnormalExit() : HControlInstruction(NULL, NULL) { } 870 HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
871
872 virtual Representation RequiredInputRepresentation(int index) const {
873 return Representation::None();
874 }
852 875
853 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit, "abnormal_exit") 876 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit, "abnormal_exit")
854 }; 877 };
855 878
856 879
857 class HUnaryOperation: public HInstruction { 880 class HUnaryOperation: public HTemplateInstruction<1> {
858 public: 881 public:
859 explicit HUnaryOperation(HValue* value) { 882 explicit HUnaryOperation(HValue* value) {
860 SetOperandAt(0, value); 883 SetOperandAt(0, value);
861 } 884 }
862 885
863 HValue* value() const { return OperandAt(0); } 886 HValue* value() { return OperandAt(0); }
864 virtual void PrintDataTo(StringStream* stream) const; 887 virtual void PrintDataTo(StringStream* stream);
865 virtual int OperandCount() const { return 1; }
866 virtual HValue* OperandAt(int index) const { return operands_[index]; }
867 888
868 DECLARE_INSTRUCTION(UnaryOperation) 889 DECLARE_INSTRUCTION(UnaryOperation)
869
870 protected:
871 virtual void InternalSetOperandAt(int index, HValue* value) {
872 operands_[index] = value;
873 }
874
875 private:
876 HOperandVector<1> operands_;
877 }; 890 };
878 891
879 892
880 class HThrow: public HUnaryOperation { 893 class HThrow: public HUnaryOperation {
881 public: 894 public:
882 explicit HThrow(HValue* value) : HUnaryOperation(value) { 895 explicit HThrow(HValue* value) : HUnaryOperation(value) {
883 SetAllSideEffects(); 896 SetAllSideEffects();
884 } 897 }
885 898
886 virtual Representation RequiredInputRepresentation(int index) const { 899 virtual Representation RequiredInputRepresentation(int index) const {
887 return Representation::Tagged(); 900 return Representation::Tagged();
888 } 901 }
889 902
890 DECLARE_CONCRETE_INSTRUCTION(Throw, "throw") 903 DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
891 }; 904 };
892 905
893 906
894 class HChange: public HUnaryOperation { 907 class HChange: public HUnaryOperation {
895 public: 908 public:
896 HChange(HValue* value, 909 HChange(HValue* value,
897 Representation from, 910 Representation from,
898 Representation to) 911 Representation to,
912 bool is_truncating)
899 : HUnaryOperation(value), from_(from), to_(to) { 913 : HUnaryOperation(value), from_(from), to_(to) {
900 ASSERT(!from.IsNone() && !to.IsNone()); 914 ASSERT(!from.IsNone() && !to.IsNone());
901 ASSERT(!from.Equals(to)); 915 ASSERT(!from.Equals(to));
902 set_representation(to); 916 set_representation(to);
903 SetFlag(kUseGVN); 917 SetFlag(kUseGVN);
904 918 if (is_truncating) SetFlag(kTruncatingToInt32);
905 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL && 919 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
906 value->range()->IsInSmiRange()) { 920 value->range()->IsInSmiRange()) {
907 set_type(HType::Smi()); 921 set_type(HType::Smi());
908 } 922 }
909 } 923 }
910 924
911 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 925 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
912 926
913 Representation from() const { return from_; } 927 Representation from() const { return from_; }
914 Representation to() const { return to_; } 928 Representation to() const { return to_; }
915 virtual Representation RequiredInputRepresentation(int index) const { 929 virtual Representation RequiredInputRepresentation(int index) const {
916 return from_; 930 return from_;
917 } 931 }
918 932
919 bool CanTruncateToInt32() const { 933 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
920 for (int i = 0; i < uses()->length(); ++i) {
921 if (!uses()->at(i)->CheckFlag(HValue::kTruncatingToInt32)) return false;
922 }
923 return true;
924 }
925 934
926 virtual void PrintDataTo(StringStream* stream) const; 935 virtual void PrintDataTo(StringStream* stream);
927 936
928 DECLARE_CONCRETE_INSTRUCTION(Change, 937 DECLARE_CONCRETE_INSTRUCTION(Change,
929 CanTruncateToInt32() ? "truncate" : "change") 938 CanTruncateToInt32() ? "truncate" : "change")
930 939
931 protected: 940 protected:
932 virtual bool DataEquals(HValue* other) const { 941 virtual bool DataEquals(HValue* other) {
933 if (!other->IsChange()) return false; 942 if (!other->IsChange()) return false;
934 HChange* change = HChange::cast(other); 943 HChange* change = HChange::cast(other);
935 return value() == change->value() 944 return value() == change->value()
936 && to().Equals(change->to()) 945 && to().Equals(change->to());
937 && CanTruncateToInt32() == change->CanTruncateToInt32();
938 } 946 }
939 947
940 private: 948 private:
941 Representation from_; 949 Representation from_;
942 Representation to_; 950 Representation to_;
943 }; 951 };
944 952
945 953
946 class HSimulate: public HInstruction { 954 class HSimulate: public HInstruction {
947 public: 955 public:
948 HSimulate(int ast_id, int pop_count, int environment_length) 956 HSimulate(int ast_id, int pop_count, int environment_length)
949 : ast_id_(ast_id), 957 : ast_id_(ast_id),
950 pop_count_(pop_count), 958 pop_count_(pop_count),
951 environment_length_(environment_length), 959 environment_length_(environment_length),
952 values_(2), 960 values_(2),
953 assigned_indexes_(2) {} 961 assigned_indexes_(2) {}
954 virtual ~HSimulate() {} 962 virtual ~HSimulate() {}
955 963
956 virtual void PrintDataTo(StringStream* stream) const; 964 virtual void PrintDataTo(StringStream* stream);
957 965
958 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; } 966 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
959 int ast_id() const { return ast_id_; } 967 int ast_id() const { return ast_id_; }
960 void set_ast_id(int id) { 968 void set_ast_id(int id) {
961 ASSERT(!HasAstId()); 969 ASSERT(!HasAstId());
962 ast_id_ = id; 970 ast_id_ = id;
963 } 971 }
964 972
965 int environment_length() const { return environment_length_; } 973 int environment_length() const { return environment_length_; }
966 int pop_count() const { return pop_count_; } 974 int pop_count() const { return pop_count_; }
967 const ZoneList<HValue*>* values() const { return &values_; } 975 const ZoneList<HValue*>* values() const { return &values_; }
968 int GetAssignedIndexAt(int index) const { 976 int GetAssignedIndexAt(int index) const {
969 ASSERT(HasAssignedIndexAt(index)); 977 ASSERT(HasAssignedIndexAt(index));
970 return assigned_indexes_[index]; 978 return assigned_indexes_[index];
971 } 979 }
972 bool HasAssignedIndexAt(int index) const { 980 bool HasAssignedIndexAt(int index) const {
973 return assigned_indexes_[index] != kNoIndex; 981 return assigned_indexes_[index] != kNoIndex;
974 } 982 }
975 void AddAssignedValue(int index, HValue* value) { 983 void AddAssignedValue(int index, HValue* value) {
976 AddValue(index, value); 984 AddValue(index, value);
977 } 985 }
978 void AddPushedValue(HValue* value) { 986 void AddPushedValue(HValue* value) {
979 AddValue(kNoIndex, value); 987 AddValue(kNoIndex, value);
980 } 988 }
981 virtual int OperandCount() const { return values_.length(); } 989 virtual int OperandCount() { return values_.length(); }
982 virtual HValue* OperandAt(int index) const { return values_[index]; } 990 virtual HValue* OperandAt(int index) { return values_[index]; }
991
992 virtual Representation RequiredInputRepresentation(int index) const {
993 return Representation::None();
994 }
983 995
984 DECLARE_CONCRETE_INSTRUCTION(Simulate, "simulate") 996 DECLARE_CONCRETE_INSTRUCTION(Simulate, "simulate")
985 997
986 #ifdef DEBUG 998 #ifdef DEBUG
987 virtual void Verify(); 999 virtual void Verify();
988 #endif 1000 #endif
989 1001
990 protected: 1002 protected:
991 virtual void InternalSetOperandAt(int index, HValue* value) { 1003 virtual void InternalSetOperandAt(int index, HValue* value) {
992 values_[index] = value; 1004 values_[index] = value;
(...skipping 10 matching lines...) Expand all
1003 SetOperandAt(values_.length() - 1, value); 1015 SetOperandAt(values_.length() - 1, value);
1004 } 1016 }
1005 int ast_id_; 1017 int ast_id_;
1006 int pop_count_; 1018 int pop_count_;
1007 int environment_length_; 1019 int environment_length_;
1008 ZoneList<HValue*> values_; 1020 ZoneList<HValue*> values_;
1009 ZoneList<int> assigned_indexes_; 1021 ZoneList<int> assigned_indexes_;
1010 }; 1022 };
1011 1023
1012 1024
1013 class HStackCheck: public HInstruction { 1025 class HStackCheck: public HTemplateInstruction<0> {
1014 public: 1026 public:
1015 HStackCheck() { } 1027 HStackCheck() { }
1016 1028
1029 virtual Representation RequiredInputRepresentation(int index) const {
1030 return Representation::None();
1031 }
1032
1017 DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack_check") 1033 DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack_check")
1018 }; 1034 };
1019 1035
1020 1036
1021 class HEnterInlined: public HInstruction { 1037 class HEnterInlined: public HTemplateInstruction<0> {
1022 public: 1038 public:
1023 HEnterInlined(Handle<JSFunction> closure, FunctionLiteral* function) 1039 HEnterInlined(Handle<JSFunction> closure, FunctionLiteral* function)
1024 : closure_(closure), function_(function) { 1040 : closure_(closure), function_(function) {
1025 } 1041 }
1026 1042
1027 virtual void PrintDataTo(StringStream* stream) const; 1043 virtual void PrintDataTo(StringStream* stream);
1028 1044
1029 Handle<JSFunction> closure() const { return closure_; } 1045 Handle<JSFunction> closure() const { return closure_; }
1030 FunctionLiteral* function() const { return function_; } 1046 FunctionLiteral* function() const { return function_; }
1031 1047
1048 virtual Representation RequiredInputRepresentation(int index) const {
1049 return Representation::None();
1050 }
1051
1032 DECLARE_CONCRETE_INSTRUCTION(EnterInlined, "enter_inlined") 1052 DECLARE_CONCRETE_INSTRUCTION(EnterInlined, "enter_inlined")
1033 1053
1034 private: 1054 private:
1035 Handle<JSFunction> closure_; 1055 Handle<JSFunction> closure_;
1036 FunctionLiteral* function_; 1056 FunctionLiteral* function_;
1037 }; 1057 };
1038 1058
1039 1059
1040 class HLeaveInlined: public HInstruction { 1060 class HLeaveInlined: public HTemplateInstruction<0> {
1041 public: 1061 public:
1042 HLeaveInlined() {} 1062 HLeaveInlined() {}
1043 1063
1064 virtual Representation RequiredInputRepresentation(int index) const {
1065 return Representation::None();
1066 }
1067
1044 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined, "leave_inlined") 1068 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined, "leave_inlined")
1045 }; 1069 };
1046 1070
1047 1071
1048 class HPushArgument: public HUnaryOperation { 1072 class HPushArgument: public HUnaryOperation {
1049 public: 1073 public:
1050 explicit HPushArgument(HValue* value) : HUnaryOperation(value) { } 1074 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1075 set_representation(Representation::Tagged());
1076 }
1051 1077
1052 virtual Representation RequiredInputRepresentation(int index) const { 1078 virtual Representation RequiredInputRepresentation(int index) const {
1053 return Representation::Tagged(); 1079 return Representation::Tagged();
1054 } 1080 }
1055 1081
1056 HValue* argument() const { return OperandAt(0); } 1082 HValue* argument() { return OperandAt(0); }
1057 1083
1058 DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push_argument") 1084 DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push_argument")
1059 }; 1085 };
1060 1086
1061 1087
1062 class HContext: public HInstruction { 1088 class HContext: public HTemplateInstruction<0> {
1063 public: 1089 public:
1064 HContext() { 1090 HContext() {
1065 set_representation(Representation::Tagged()); 1091 set_representation(Representation::Tagged());
1066 SetFlag(kUseGVN); 1092 SetFlag(kUseGVN);
1067 } 1093 }
1068 1094
1095 virtual Representation RequiredInputRepresentation(int index) const {
1096 return Representation::None();
1097 }
1098
1069 DECLARE_CONCRETE_INSTRUCTION(Context, "context"); 1099 DECLARE_CONCRETE_INSTRUCTION(Context, "context");
1070 1100
1071 protected: 1101 protected:
1072 virtual bool DataEquals(HValue* other) const { return true; } 1102 virtual bool DataEquals(HValue* other) { return true; }
1073 }; 1103 };
1074 1104
1075 1105
1076 class HOuterContext: public HUnaryOperation { 1106 class HOuterContext: public HUnaryOperation {
1077 public: 1107 public:
1078 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) { 1108 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1079 set_representation(Representation::Tagged()); 1109 set_representation(Representation::Tagged());
1080 SetFlag(kUseGVN); 1110 SetFlag(kUseGVN);
1081 } 1111 }
1082 1112
1083 DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer_context"); 1113 DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer_context");
1084 1114
1115 virtual Representation RequiredInputRepresentation(int index) const {
1116 return Representation::Tagged();
1117 }
1118
1085 protected: 1119 protected:
1086 virtual bool DataEquals(HValue* other) const { return true; } 1120 virtual bool DataEquals(HValue* other) { return true; }
1087 }; 1121 };
1088 1122
1089 1123
1090 class HGlobalObject: public HUnaryOperation { 1124 class HGlobalObject: public HUnaryOperation {
1091 public: 1125 public:
1092 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) { 1126 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1093 set_representation(Representation::Tagged()); 1127 set_representation(Representation::Tagged());
1094 SetFlag(kUseGVN); 1128 SetFlag(kUseGVN);
1095 } 1129 }
1096 1130
1097 DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global_object") 1131 DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global_object")
1098 1132
1133 virtual Representation RequiredInputRepresentation(int index) const {
1134 return Representation::Tagged();
1135 }
1136
1099 protected: 1137 protected:
1100 virtual bool DataEquals(HValue* other) const { return true; } 1138 virtual bool DataEquals(HValue* other) { return true; }
1101 }; 1139 };
1102 1140
1103 1141
1104 class HGlobalReceiver: public HUnaryOperation { 1142 class HGlobalReceiver: public HUnaryOperation {
1105 public: 1143 public:
1106 explicit HGlobalReceiver(HValue* global_object) 1144 explicit HGlobalReceiver(HValue* global_object)
1107 : HUnaryOperation(global_object) { 1145 : HUnaryOperation(global_object) {
1108 set_representation(Representation::Tagged()); 1146 set_representation(Representation::Tagged());
1109 SetFlag(kUseGVN); 1147 SetFlag(kUseGVN);
1110 } 1148 }
1111 1149
1112 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global_receiver") 1150 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global_receiver")
1113 1151
1152 virtual Representation RequiredInputRepresentation(int index) const {
1153 return Representation::Tagged();
1154 }
1155
1114 protected: 1156 protected:
1115 virtual bool DataEquals(HValue* other) const { return true; } 1157 virtual bool DataEquals(HValue* other) { return true; }
1116 }; 1158 };
1117 1159
1118 1160
1119 class HCall: public HInstruction { 1161 template <int V>
1162 class HCall: public HTemplateInstruction<V> {
1120 public: 1163 public:
1121 // The argument count includes the receiver. 1164 // The argument count includes the receiver.
1122 explicit HCall(int argument_count) : argument_count_(argument_count) { 1165 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1123 set_representation(Representation::Tagged()); 1166 this->set_representation(Representation::Tagged());
1124 SetAllSideEffects(); 1167 this->SetAllSideEffects();
1125 } 1168 }
1126 1169
1127 virtual HType CalculateInferredType() const { return HType::Tagged(); } 1170 virtual HType CalculateInferredType() { return HType::Tagged(); }
1128 1171
1129 virtual int argument_count() const { return argument_count_; } 1172 virtual int argument_count() const { return argument_count_; }
1130 1173
1131 virtual void PrintDataTo(StringStream* stream) const; 1174 virtual bool IsCall() { return true; }
1132
1133 DECLARE_INSTRUCTION(Call)
1134 1175
1135 private: 1176 private:
1136 int argument_count_; 1177 int argument_count_;
1137 }; 1178 };
1138 1179
1139 1180
1140 class HUnaryCall: public HCall { 1181 class HUnaryCall: public HCall<1> {
1141 public: 1182 public:
1142 HUnaryCall(HValue* value, int argument_count) 1183 HUnaryCall(HValue* value, int argument_count)
1143 : HCall(argument_count), value_(NULL) { 1184 : HCall<1>(argument_count) {
1144 SetOperandAt(0, value); 1185 SetOperandAt(0, value);
1145 } 1186 }
1146 1187
1147 virtual void PrintDataTo(StringStream* stream) const; 1188 virtual Representation RequiredInputRepresentation(int index) const {
1148 1189 return Representation::Tagged();
1149 HValue* value() const { return value_; }
1150
1151 virtual int OperandCount() const { return 1; }
1152 virtual HValue* OperandAt(int index) const {
1153 ASSERT(index == 0);
1154 return value_;
1155 } 1190 }
1156 1191
1192 virtual void PrintDataTo(StringStream* stream);
1193
1194 HValue* value() { return OperandAt(0); }
1195
1157 DECLARE_INSTRUCTION(UnaryCall) 1196 DECLARE_INSTRUCTION(UnaryCall)
1158
1159 protected:
1160 virtual void InternalSetOperandAt(int index, HValue* value) {
1161 ASSERT(index == 0);
1162 value_ = value;
1163 }
1164
1165 private:
1166 HValue* value_;
1167 }; 1197 };
1168 1198
1169 1199
1170 class HBinaryCall: public HCall { 1200 class HBinaryCall: public HCall<2> {
1171 public: 1201 public:
1172 HBinaryCall(HValue* first, HValue* second, int argument_count) 1202 HBinaryCall(HValue* first, HValue* second, int argument_count)
1173 : HCall(argument_count) { 1203 : HCall<2>(argument_count) {
1174 SetOperandAt(0, first); 1204 SetOperandAt(0, first);
1175 SetOperandAt(1, second); 1205 SetOperandAt(1, second);
1176 } 1206 }
1177 1207
1178 virtual void PrintDataTo(StringStream* stream) const; 1208 virtual void PrintDataTo(StringStream* stream);
1179 1209
1180 HValue* first() const { return operands_[0]; } 1210 virtual Representation RequiredInputRepresentation(int index) const {
1181 HValue* second() const { return operands_[1]; } 1211 return Representation::Tagged();
1212 }
1182 1213
1183 virtual int OperandCount() const { return 2; } 1214 HValue* first() { return OperandAt(0); }
1184 virtual HValue* OperandAt(int index) const { return operands_[index]; } 1215 HValue* second() { return OperandAt(1); }
1185 1216
1186 DECLARE_INSTRUCTION(BinaryCall) 1217 DECLARE_INSTRUCTION(BinaryCall)
1187
1188 protected:
1189 virtual void InternalSetOperandAt(int index, HValue* value) {
1190 operands_[index] = value;
1191 }
1192
1193 private:
1194 HOperandVector<2> operands_;
1195 }; 1218 };
1196 1219
1197 1220
1198 class HCallConstantFunction: public HCall { 1221 class HCallConstantFunction: public HCall<0> {
1199 public: 1222 public:
1200 HCallConstantFunction(Handle<JSFunction> function, int argument_count) 1223 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
1201 : HCall(argument_count), function_(function) { } 1224 : HCall<0>(argument_count), function_(function) { }
1202 1225
1203 Handle<JSFunction> function() const { return function_; } 1226 Handle<JSFunction> function() const { return function_; }
1204 1227
1205 bool IsApplyFunction() const { 1228 bool IsApplyFunction() const {
1206 return function_->code() == Builtins::builtin(Builtins::FunctionApply); 1229 return function_->code() == Builtins::builtin(Builtins::FunctionApply);
1207 } 1230 }
1208 1231
1209 virtual void PrintDataTo(StringStream* stream) const; 1232 virtual void PrintDataTo(StringStream* stream);
1233
1234 virtual Representation RequiredInputRepresentation(int index) const {
1235 return Representation::None();
1236 }
1210 1237
1211 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call_constant_function") 1238 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call_constant_function")
1212 1239
1213 private: 1240 private:
1214 Handle<JSFunction> function_; 1241 Handle<JSFunction> function_;
1215 }; 1242 };
1216 1243
1217 1244
1218 class HCallKeyed: public HBinaryCall { 1245 class HCallKeyed: public HBinaryCall {
1219 public: 1246 public:
1220 HCallKeyed(HValue* context, HValue* key, int argument_count) 1247 HCallKeyed(HValue* context, HValue* key, int argument_count)
1221 : HBinaryCall(context, key, argument_count) { 1248 : HBinaryCall(context, key, argument_count) {
1222 } 1249 }
1223 1250
1224 virtual Representation RequiredInputRepresentation(int index) const { 1251 virtual Representation RequiredInputRepresentation(int index) const {
1225 return Representation::Tagged(); 1252 return Representation::Tagged();
1226 } 1253 }
1227 1254
1228 HValue* context() const { return first(); } 1255 HValue* context() { return first(); }
1229 HValue* key() const { return second(); } 1256 HValue* key() { return second(); }
1230 1257
1231 DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call_keyed") 1258 DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call_keyed")
1232 }; 1259 };
1233 1260
1234 1261
1235 class HCallNamed: public HUnaryCall { 1262 class HCallNamed: public HUnaryCall {
1236 public: 1263 public:
1237 HCallNamed(HValue* context, Handle<String> name, int argument_count) 1264 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1238 : HUnaryCall(context, argument_count), name_(name) { 1265 : HUnaryCall(context, argument_count), name_(name) {
1239 } 1266 }
1240 1267
1241 virtual void PrintDataTo(StringStream* stream) const; 1268 virtual void PrintDataTo(StringStream* stream);
1242 1269
1243 HValue* context() const { return value(); } 1270 HValue* context() { return value(); }
1244 Handle<String> name() const { return name_; } 1271 Handle<String> name() const { return name_; }
1245 1272
1246 DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call_named") 1273 DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call_named")
1247 1274
1275 virtual Representation RequiredInputRepresentation(int index) const {
1276 return Representation::Tagged();
1277 }
1278
1248 private: 1279 private:
1249 Handle<String> name_; 1280 Handle<String> name_;
1250 }; 1281 };
1251 1282
1252 1283
1253 class HCallFunction: public HUnaryCall { 1284 class HCallFunction: public HUnaryCall {
1254 public: 1285 public:
1255 HCallFunction(HValue* context, int argument_count) 1286 HCallFunction(HValue* context, int argument_count)
1256 : HUnaryCall(context, argument_count) { 1287 : HUnaryCall(context, argument_count) {
1257 } 1288 }
1258 1289
1259 HValue* context() const { return value(); } 1290 HValue* context() { return value(); }
1291
1292 virtual Representation RequiredInputRepresentation(int index) const {
1293 return Representation::Tagged();
1294 }
1260 1295
1261 DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call_function") 1296 DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call_function")
1262 }; 1297 };
1263 1298
1264 1299
1265 class HCallGlobal: public HUnaryCall { 1300 class HCallGlobal: public HUnaryCall {
1266 public: 1301 public:
1267 HCallGlobal(HValue* context, Handle<String> name, int argument_count) 1302 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1268 : HUnaryCall(context, argument_count), name_(name) { 1303 : HUnaryCall(context, argument_count), name_(name) {
1269 } 1304 }
1270 1305
1271 virtual void PrintDataTo(StringStream* stream) const; 1306 virtual void PrintDataTo(StringStream* stream);
1272 1307
1273 HValue* context() const { return value(); } 1308 HValue* context() { return value(); }
1274 Handle<String> name() const { return name_; } 1309 Handle<String> name() const { return name_; }
1275 1310
1311 virtual Representation RequiredInputRepresentation(int index) const {
1312 return Representation::Tagged();
1313 }
1314
1276 DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call_global") 1315 DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call_global")
1277 1316
1278 private: 1317 private:
1279 Handle<String> name_; 1318 Handle<String> name_;
1280 }; 1319 };
1281 1320
1282 1321
1283 class HCallKnownGlobal: public HCall { 1322 class HCallKnownGlobal: public HCall<0> {
1284 public: 1323 public:
1285 HCallKnownGlobal(Handle<JSFunction> target, int argument_count) 1324 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
1286 : HCall(argument_count), target_(target) { } 1325 : HCall<0>(argument_count), target_(target) { }
1287 1326
1288 virtual void PrintDataTo(StringStream* stream) const; 1327 virtual void PrintDataTo(StringStream* stream);
1289 1328
1290 Handle<JSFunction> target() const { return target_; } 1329 Handle<JSFunction> target() const { return target_; }
1291 1330
1331 virtual Representation RequiredInputRepresentation(int index) const {
1332 return Representation::None();
1333 }
1334
1292 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call_known_global") 1335 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call_known_global")
1293 1336
1294 private: 1337 private:
1295 Handle<JSFunction> target_; 1338 Handle<JSFunction> target_;
1296 }; 1339 };
1297 1340
1298 1341
1299 class HCallNew: public HBinaryCall { 1342 class HCallNew: public HBinaryCall {
1300 public: 1343 public:
1301 HCallNew(HValue* context, HValue* constructor, int argument_count) 1344 HCallNew(HValue* context, HValue* constructor, int argument_count)
1302 : HBinaryCall(context, constructor, argument_count) { 1345 : HBinaryCall(context, constructor, argument_count) {
1303 } 1346 }
1304 1347
1305 virtual Representation RequiredInputRepresentation(int index) const { 1348 virtual Representation RequiredInputRepresentation(int index) const {
1306 return Representation::Tagged(); 1349 return Representation::Tagged();
1307 } 1350 }
1308 1351
1309 HValue* context() const { return first(); } 1352 HValue* context() { return first(); }
1310 HValue* constructor() const { return second(); } 1353 HValue* constructor() { return second(); }
1311 1354
1312 DECLARE_CONCRETE_INSTRUCTION(CallNew, "call_new") 1355 DECLARE_CONCRETE_INSTRUCTION(CallNew, "call_new")
1313 }; 1356 };
1314 1357
1315 1358
1316 class HCallRuntime: public HCall { 1359 class HCallRuntime: public HCall<0> {
1317 public: 1360 public:
1318 HCallRuntime(Handle<String> name, 1361 HCallRuntime(Handle<String> name,
1319 Runtime::Function* c_function, 1362 Runtime::Function* c_function,
1320 int argument_count) 1363 int argument_count)
1321 : HCall(argument_count), c_function_(c_function), name_(name) { } 1364 : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
1322 virtual void PrintDataTo(StringStream* stream) const; 1365 virtual void PrintDataTo(StringStream* stream);
1323 1366
1324 Runtime::Function* function() const { return c_function_; } 1367 Runtime::Function* function() const { return c_function_; }
1325 Handle<String> name() const { return name_; } 1368 Handle<String> name() const { return name_; }
1326 1369
1370 virtual Representation RequiredInputRepresentation(int index) const {
1371 return Representation::None();
1372 }
1373
1327 DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call_runtime") 1374 DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call_runtime")
1328 1375
1329 private: 1376 private:
1330 Runtime::Function* c_function_; 1377 Runtime::Function* c_function_;
1331 Handle<String> name_; 1378 Handle<String> name_;
1332 }; 1379 };
1333 1380
1334 1381
1335 class HJSArrayLength: public HUnaryOperation { 1382 class HJSArrayLength: public HUnaryOperation {
1336 public: 1383 public:
1337 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) { 1384 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
1338 // The length of an array is stored as a tagged value in the array 1385 // The length of an array is stored as a tagged value in the array
1339 // object. It is guaranteed to be 32 bit integer, but it can be 1386 // object. It is guaranteed to be 32 bit integer, but it can be
1340 // represented as either a smi or heap number. 1387 // represented as either a smi or heap number.
1341 set_representation(Representation::Tagged()); 1388 set_representation(Representation::Tagged());
1342 SetFlag(kDependsOnArrayLengths); 1389 SetFlag(kDependsOnArrayLengths);
1343 SetFlag(kUseGVN); 1390 SetFlag(kUseGVN);
1344 } 1391 }
1345 1392
1346 virtual Representation RequiredInputRepresentation(int index) const { 1393 virtual Representation RequiredInputRepresentation(int index) const {
1347 return Representation::Tagged(); 1394 return Representation::Tagged();
1348 } 1395 }
1349 1396
1350 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js_array_length") 1397 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js_array_length")
1351 1398
1352 protected: 1399 protected:
1353 virtual bool DataEquals(HValue* other) const { return true; } 1400 virtual bool DataEquals(HValue* other) { return true; }
1354 }; 1401 };
1355 1402
1356 1403
1357 class HFixedArrayLength: public HUnaryOperation { 1404 class HFixedArrayLength: public HUnaryOperation {
1358 public: 1405 public:
1359 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) { 1406 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1360 set_representation(Representation::Tagged()); 1407 set_representation(Representation::Tagged());
1361 SetFlag(kDependsOnArrayLengths); 1408 SetFlag(kDependsOnArrayLengths);
1362 SetFlag(kUseGVN); 1409 SetFlag(kUseGVN);
1363 } 1410 }
1364 1411
1365 virtual Representation RequiredInputRepresentation(int index) const { 1412 virtual Representation RequiredInputRepresentation(int index) const {
1366 return Representation::Tagged(); 1413 return Representation::Tagged();
1367 } 1414 }
1368 1415
1369 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed_array_length") 1416 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed_array_length")
1370 1417
1371 protected: 1418 protected:
1372 virtual bool DataEquals(HValue* other) const { return true; } 1419 virtual bool DataEquals(HValue* other) { return true; }
1373 }; 1420 };
1374 1421
1375 1422
1376 class HPixelArrayLength: public HUnaryOperation { 1423 class HExternalArrayLength: public HUnaryOperation {
1377 public: 1424 public:
1378 explicit HPixelArrayLength(HValue* value) : HUnaryOperation(value) { 1425 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
1379 set_representation(Representation::Integer32()); 1426 set_representation(Representation::Integer32());
1380 // The result of this instruction is idempotent as long as its inputs don't 1427 // The result of this instruction is idempotent as long as its inputs don't
1381 // change. The length of a pixel array cannot change once set, so it's not 1428 // change. The length of a pixel array cannot change once set, so it's not
1382 // necessary to introduce a kDependsOnArrayLengths or any other dependency. 1429 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1383 SetFlag(kUseGVN); 1430 SetFlag(kUseGVN);
1384 } 1431 }
1385 1432
1386 virtual Representation RequiredInputRepresentation(int index) const { 1433 virtual Representation RequiredInputRepresentation(int index) const {
1387 return Representation::Tagged(); 1434 return Representation::Tagged();
1388 } 1435 }
1389 1436
1390 DECLARE_CONCRETE_INSTRUCTION(PixelArrayLength, "pixel_array_length") 1437 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength, "external_array_length")
1391 1438
1392 protected: 1439 protected:
1393 virtual bool DataEquals(HValue* other) const { return true; } 1440 virtual bool DataEquals(HValue* other) { return true; }
1394 }; 1441 };
1395 1442
1396 1443
1397 class HBitNot: public HUnaryOperation { 1444 class HBitNot: public HUnaryOperation {
1398 public: 1445 public:
1399 explicit HBitNot(HValue* value) : HUnaryOperation(value) { 1446 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1400 set_representation(Representation::Integer32()); 1447 set_representation(Representation::Integer32());
1401 SetFlag(kUseGVN); 1448 SetFlag(kUseGVN);
1402 SetFlag(kTruncatingToInt32); 1449 SetFlag(kTruncatingToInt32);
1403 } 1450 }
1404 1451
1405 virtual Representation RequiredInputRepresentation(int index) const { 1452 virtual Representation RequiredInputRepresentation(int index) const {
1406 return Representation::Integer32(); 1453 return Representation::Integer32();
1407 } 1454 }
1408 virtual HType CalculateInferredType() const; 1455 virtual HType CalculateInferredType();
1409 1456
1410 DECLARE_CONCRETE_INSTRUCTION(BitNot, "bit_not") 1457 DECLARE_CONCRETE_INSTRUCTION(BitNot, "bit_not")
1411 1458
1412 protected: 1459 protected:
1413 virtual bool DataEquals(HValue* other) const { return true; } 1460 virtual bool DataEquals(HValue* other) { return true; }
1414 }; 1461 };
1415 1462
1416 1463
1417 class HUnaryMathOperation: public HUnaryOperation { 1464 class HUnaryMathOperation: public HUnaryOperation {
1418 public: 1465 public:
1419 HUnaryMathOperation(HValue* value, BuiltinFunctionId op) 1466 HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
1420 : HUnaryOperation(value), op_(op) { 1467 : HUnaryOperation(value), op_(op) {
1421 switch (op) { 1468 switch (op) {
1422 case kMathFloor: 1469 case kMathFloor:
1423 case kMathRound: 1470 case kMathRound:
(...skipping 10 matching lines...) Expand all
1434 case kMathSin: 1481 case kMathSin:
1435 case kMathCos: 1482 case kMathCos:
1436 set_representation(Representation::Double()); 1483 set_representation(Representation::Double());
1437 break; 1484 break;
1438 default: 1485 default:
1439 UNREACHABLE(); 1486 UNREACHABLE();
1440 } 1487 }
1441 SetFlag(kUseGVN); 1488 SetFlag(kUseGVN);
1442 } 1489 }
1443 1490
1444 virtual void PrintDataTo(StringStream* stream) const; 1491 virtual void PrintDataTo(StringStream* stream);
1445 1492
1446 virtual HType CalculateInferredType() const; 1493 virtual HType CalculateInferredType();
1447 1494
1448 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 1495 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1449 1496
1450 virtual Representation RequiredInputRepresentation(int index) const { 1497 virtual Representation RequiredInputRepresentation(int index) const {
1451 switch (op_) { 1498 switch (op_) {
1452 case kMathFloor: 1499 case kMathFloor:
1453 case kMathRound: 1500 case kMathRound:
1454 case kMathCeil: 1501 case kMathCeil:
1455 case kMathSqrt: 1502 case kMathSqrt:
1456 case kMathPowHalf: 1503 case kMathPowHalf:
1457 case kMathLog: 1504 case kMathLog:
1458 case kMathSin: 1505 case kMathSin:
1459 case kMathCos: 1506 case kMathCos:
1460 return Representation::Double(); 1507 return Representation::Double();
1461 break;
1462 case kMathAbs: 1508 case kMathAbs:
1463 return representation(); 1509 return representation();
1464 break;
1465 default: 1510 default:
1511 UNREACHABLE();
1466 return Representation::None(); 1512 return Representation::None();
1467 } 1513 }
1468 } 1514 }
1469 1515
1470 virtual HValue* Canonicalize() { 1516 virtual HValue* Canonicalize() {
1471 // If the input is integer32 then we replace the floor instruction 1517 // If the input is integer32 then we replace the floor instruction
1472 // with its inputs. This happens before the representation changes are 1518 // with its inputs. This happens before the representation changes are
1473 // introduced. 1519 // introduced.
1474 if (op() == kMathFloor) { 1520 if (op() == kMathFloor) {
1475 if (value()->representation().IsInteger32()) return value(); 1521 if (value()->representation().IsInteger32()) return value();
1476 } 1522 }
1477 return this; 1523 return this;
1478 } 1524 }
1479 1525
1480 BuiltinFunctionId op() const { return op_; } 1526 BuiltinFunctionId op() const { return op_; }
1481 const char* OpName() const; 1527 const char* OpName() const;
1482 1528
1483 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary_math_operation") 1529 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary_math_operation")
1484 1530
1485 protected: 1531 protected:
1486 virtual bool DataEquals(HValue* other) const { 1532 virtual bool DataEquals(HValue* other) {
1487 HUnaryMathOperation* b = HUnaryMathOperation::cast(other); 1533 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1488 return op_ == b->op(); 1534 return op_ == b->op();
1489 } 1535 }
1490 1536
1491 private: 1537 private:
1492 BuiltinFunctionId op_; 1538 BuiltinFunctionId op_;
1493 }; 1539 };
1494 1540
1495 1541
1496 class HLoadElements: public HUnaryOperation { 1542 class HLoadElements: public HUnaryOperation {
1497 public: 1543 public:
1498 explicit HLoadElements(HValue* value) : HUnaryOperation(value) { 1544 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1499 set_representation(Representation::Tagged()); 1545 set_representation(Representation::Tagged());
1500 SetFlag(kUseGVN); 1546 SetFlag(kUseGVN);
1501 SetFlag(kDependsOnMaps); 1547 SetFlag(kDependsOnMaps);
1502 } 1548 }
1503 1549
1504 virtual Representation RequiredInputRepresentation(int index) const { 1550 virtual Representation RequiredInputRepresentation(int index) const {
1505 return Representation::Tagged(); 1551 return Representation::Tagged();
1506 } 1552 }
1507 1553
1508 DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements") 1554 DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
1509 1555
1510 protected: 1556 protected:
1511 virtual bool DataEquals(HValue* other) const { return true; } 1557 virtual bool DataEquals(HValue* other) { return true; }
1512 }; 1558 };
1513 1559
1514 1560
1515 class HLoadPixelArrayExternalPointer: public HUnaryOperation { 1561 class HLoadExternalArrayPointer: public HUnaryOperation {
1516 public: 1562 public:
1517 explicit HLoadPixelArrayExternalPointer(HValue* value) 1563 explicit HLoadExternalArrayPointer(HValue* value)
1518 : HUnaryOperation(value) { 1564 : HUnaryOperation(value) {
1519 set_representation(Representation::External()); 1565 set_representation(Representation::External());
1520 // The result of this instruction is idempotent as long as its inputs don't 1566 // The result of this instruction is idempotent as long as its inputs don't
1521 // change. The external array of a pixel array elements object cannot 1567 // change. The external array of a pixel array elements object cannot
1522 // change once set, so it's no necessary to introduce any additional 1568 // change once set, so it's no necessary to introduce any additional
1523 // dependencies on top of the inputs. 1569 // dependencies on top of the inputs.
1524 SetFlag(kUseGVN); 1570 SetFlag(kUseGVN);
1525 } 1571 }
1526 1572
1527 virtual Representation RequiredInputRepresentation(int index) const { 1573 virtual Representation RequiredInputRepresentation(int index) const {
1528 return Representation::Tagged(); 1574 return Representation::Tagged();
1529 } 1575 }
1530 1576
1531 DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayExternalPointer, 1577 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer,
1532 "load-pixel-array-external-pointer") 1578 "load-external-array-pointer")
1533 1579
1534 protected: 1580 protected:
1535 virtual bool DataEquals(HValue* other) const { return true; } 1581 virtual bool DataEquals(HValue* other) { return true; }
1536 }; 1582 };
1537 1583
1538 1584
1539 class HCheckMap: public HUnaryOperation { 1585 class HCheckMap: public HUnaryOperation {
1540 public: 1586 public:
1541 HCheckMap(HValue* value, Handle<Map> map) 1587 HCheckMap(HValue* value, Handle<Map> map)
1542 : HUnaryOperation(value), map_(map) { 1588 : HUnaryOperation(value), map_(map) {
1543 set_representation(Representation::Tagged()); 1589 set_representation(Representation::Tagged());
1544 SetFlag(kUseGVN); 1590 SetFlag(kUseGVN);
1545 SetFlag(kDependsOnMaps); 1591 SetFlag(kDependsOnMaps);
1546 } 1592 }
1547 1593
1548 virtual bool IsCheckInstruction() const { return true; } 1594 virtual bool IsCheckInstruction() const { return true; }
1549 1595
1550 virtual Representation RequiredInputRepresentation(int index) const { 1596 virtual Representation RequiredInputRepresentation(int index) const {
1551 return Representation::Tagged(); 1597 return Representation::Tagged();
1552 } 1598 }
1553 virtual void PrintDataTo(StringStream* stream) const; 1599 virtual void PrintDataTo(StringStream* stream);
1554 virtual HType CalculateInferredType() const; 1600 virtual HType CalculateInferredType();
1555 1601
1556 #ifdef DEBUG 1602 #ifdef DEBUG
1557 virtual void Verify(); 1603 virtual void Verify();
1558 #endif 1604 #endif
1559 1605
1560 Handle<Map> map() const { return map_; } 1606 Handle<Map> map() const { return map_; }
1561 1607
1562 DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check_map") 1608 DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check_map")
1563 1609
1564 protected: 1610 protected:
1565 virtual bool DataEquals(HValue* other) const { 1611 virtual bool DataEquals(HValue* other) {
1566 HCheckMap* b = HCheckMap::cast(other); 1612 HCheckMap* b = HCheckMap::cast(other);
1567 return map_.is_identical_to(b->map()); 1613 return map_.is_identical_to(b->map());
1568 } 1614 }
1569 1615
1570 private: 1616 private:
1571 Handle<Map> map_; 1617 Handle<Map> map_;
1572 }; 1618 };
1573 1619
1574 1620
1575 class HCheckFunction: public HUnaryOperation { 1621 class HCheckFunction: public HUnaryOperation {
1576 public: 1622 public:
1577 HCheckFunction(HValue* value, Handle<JSFunction> function) 1623 HCheckFunction(HValue* value, Handle<JSFunction> function)
1578 : HUnaryOperation(value), target_(function) { 1624 : HUnaryOperation(value), target_(function) {
1579 set_representation(Representation::Tagged()); 1625 set_representation(Representation::Tagged());
1580 SetFlag(kUseGVN); 1626 SetFlag(kUseGVN);
1581 } 1627 }
1582 1628
1583 virtual bool IsCheckInstruction() const { return true; } 1629 virtual bool IsCheckInstruction() const { return true; }
1584 1630
1585 virtual Representation RequiredInputRepresentation(int index) const { 1631 virtual Representation RequiredInputRepresentation(int index) const {
1586 return Representation::Tagged(); 1632 return Representation::Tagged();
1587 } 1633 }
1588 virtual void PrintDataTo(StringStream* stream) const; 1634 virtual void PrintDataTo(StringStream* stream);
1589 virtual HType CalculateInferredType() const; 1635 virtual HType CalculateInferredType();
1590 1636
1591 #ifdef DEBUG 1637 #ifdef DEBUG
1592 virtual void Verify(); 1638 virtual void Verify();
1593 #endif 1639 #endif
1594 1640
1595 Handle<JSFunction> target() const { return target_; } 1641 Handle<JSFunction> target() const { return target_; }
1596 1642
1597 DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check_function") 1643 DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check_function")
1598 1644
1599 protected: 1645 protected:
1600 virtual bool DataEquals(HValue* other) const { 1646 virtual bool DataEquals(HValue* other) {
1601 HCheckFunction* b = HCheckFunction::cast(other); 1647 HCheckFunction* b = HCheckFunction::cast(other);
1602 return target_.is_identical_to(b->target()); 1648 return target_.is_identical_to(b->target());
1603 } 1649 }
1604 1650
1605 private: 1651 private:
1606 Handle<JSFunction> target_; 1652 Handle<JSFunction> target_;
1607 }; 1653 };
1608 1654
1609 1655
1610 class HCheckInstanceType: public HUnaryOperation { 1656 class HCheckInstanceType: public HUnaryOperation {
(...skipping 27 matching lines...) Expand all
1638 1684
1639 InstanceType first() const { return first_; } 1685 InstanceType first() const { return first_; }
1640 InstanceType last() const { return last_; } 1686 InstanceType last() const { return last_; }
1641 1687
1642 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check_instance_type") 1688 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check_instance_type")
1643 1689
1644 protected: 1690 protected:
1645 // TODO(ager): It could be nice to allow the ommision of instance 1691 // TODO(ager): It could be nice to allow the ommision of instance
1646 // type checks if we have already performed an instance type check 1692 // type checks if we have already performed an instance type check
1647 // with a larger range. 1693 // with a larger range.
1648 virtual bool DataEquals(HValue* other) const { 1694 virtual bool DataEquals(HValue* other) {
1649 HCheckInstanceType* b = HCheckInstanceType::cast(other); 1695 HCheckInstanceType* b = HCheckInstanceType::cast(other);
1650 return (first_ == b->first()) && (last_ == b->last()); 1696 return (first_ == b->first()) && (last_ == b->last());
1651 } 1697 }
1652 1698
1653 private: 1699 private:
1654 InstanceType first_; 1700 InstanceType first_;
1655 InstanceType last_; 1701 InstanceType last_;
1656 }; 1702 };
1657 1703
1658 1704
1659 class HCheckNonSmi: public HUnaryOperation { 1705 class HCheckNonSmi: public HUnaryOperation {
1660 public: 1706 public:
1661 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) { 1707 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
1662 set_representation(Representation::Tagged()); 1708 set_representation(Representation::Tagged());
1663 SetFlag(kUseGVN); 1709 SetFlag(kUseGVN);
1664 } 1710 }
1665 1711
1666 virtual bool IsCheckInstruction() const { return true; } 1712 virtual bool IsCheckInstruction() const { return true; }
1667 1713
1668 virtual Representation RequiredInputRepresentation(int index) const { 1714 virtual Representation RequiredInputRepresentation(int index) const {
1669 return Representation::Tagged(); 1715 return Representation::Tagged();
1670 } 1716 }
1671 1717
1672 virtual HType CalculateInferredType() const; 1718 virtual HType CalculateInferredType();
1673 1719
1674 #ifdef DEBUG 1720 #ifdef DEBUG
1675 virtual void Verify(); 1721 virtual void Verify();
1676 #endif 1722 #endif
1677 1723
1678 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check_non_smi") 1724 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check_non_smi")
1679 1725
1680 protected: 1726 protected:
1681 virtual bool DataEquals(HValue* other) const { return true; } 1727 virtual bool DataEquals(HValue* other) { return true; }
1682 }; 1728 };
1683 1729
1684 1730
1685 class HCheckPrototypeMaps: public HInstruction { 1731 class HCheckPrototypeMaps: public HTemplateInstruction<0> {
1686 public: 1732 public:
1687 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder) 1733 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
1688 : prototype_(prototype), holder_(holder) { 1734 : prototype_(prototype), holder_(holder) {
1689 SetFlag(kUseGVN); 1735 SetFlag(kUseGVN);
1690 SetFlag(kDependsOnMaps); 1736 SetFlag(kDependsOnMaps);
1691 } 1737 }
1692 1738
1693 virtual bool IsCheckInstruction() const { return true; } 1739 virtual bool IsCheckInstruction() const { return true; }
1694 1740
1695 #ifdef DEBUG 1741 #ifdef DEBUG
1696 virtual void Verify(); 1742 virtual void Verify();
1697 #endif 1743 #endif
1698 1744
1699 Handle<JSObject> prototype() const { return prototype_; } 1745 Handle<JSObject> prototype() const { return prototype_; }
1700 Handle<JSObject> holder() const { return holder_; } 1746 Handle<JSObject> holder() const { return holder_; }
1701 1747
1702 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check_prototype_maps") 1748 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check_prototype_maps")
1703 1749
1704 virtual intptr_t Hashcode() const { 1750 virtual Representation RequiredInputRepresentation(int index) const {
1751 return Representation::None();
1752 }
1753
1754 virtual intptr_t Hashcode() {
1705 ASSERT(!Heap::IsAllocationAllowed()); 1755 ASSERT(!Heap::IsAllocationAllowed());
1706 intptr_t hash = reinterpret_cast<intptr_t>(*prototype()); 1756 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
1707 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder()); 1757 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
1708 return hash; 1758 return hash;
1709 } 1759 }
1710 1760
1711 protected: 1761 protected:
1712 virtual bool DataEquals(HValue* other) const { 1762 virtual bool DataEquals(HValue* other) {
1713 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other); 1763 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
1714 return prototype_.is_identical_to(b->prototype()) && 1764 return prototype_.is_identical_to(b->prototype()) &&
1715 holder_.is_identical_to(b->holder()); 1765 holder_.is_identical_to(b->holder());
1716 } 1766 }
1717 1767
1718 private: 1768 private:
1719 Handle<JSObject> prototype_; 1769 Handle<JSObject> prototype_;
1720 Handle<JSObject> holder_; 1770 Handle<JSObject> holder_;
1721 }; 1771 };
1722 1772
1723 1773
1724 class HCheckSmi: public HUnaryOperation { 1774 class HCheckSmi: public HUnaryOperation {
1725 public: 1775 public:
1726 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) { 1776 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
1727 set_representation(Representation::Tagged()); 1777 set_representation(Representation::Tagged());
1728 SetFlag(kUseGVN); 1778 SetFlag(kUseGVN);
1729 } 1779 }
1730 1780
1731 virtual bool IsCheckInstruction() const { return true; } 1781 virtual bool IsCheckInstruction() const { return true; }
1732 1782
1733 virtual Representation RequiredInputRepresentation(int index) const { 1783 virtual Representation RequiredInputRepresentation(int index) const {
1734 return Representation::Tagged(); 1784 return Representation::Tagged();
1735 } 1785 }
1736 virtual HType CalculateInferredType() const; 1786 virtual HType CalculateInferredType();
1737 1787
1738 #ifdef DEBUG 1788 #ifdef DEBUG
1739 virtual void Verify(); 1789 virtual void Verify();
1740 #endif 1790 #endif
1741 1791
1742 DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check_smi") 1792 DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check_smi")
1743 1793
1744 protected: 1794 protected:
1745 virtual bool DataEquals(HValue* other) const { return true; } 1795 virtual bool DataEquals(HValue* other) { return true; }
1746 }; 1796 };
1747 1797
1748 1798
1749 class HPhi: public HValue { 1799 class HPhi: public HValue {
1750 public: 1800 public:
1751 explicit HPhi(int merged_index) 1801 explicit HPhi(int merged_index)
1752 : inputs_(2), 1802 : inputs_(2),
1753 merged_index_(merged_index), 1803 merged_index_(merged_index),
1754 phi_id_(-1) { 1804 phi_id_(-1),
1805 is_live_(false) {
1755 for (int i = 0; i < Representation::kNumRepresentations; i++) { 1806 for (int i = 0; i < Representation::kNumRepresentations; i++) {
1756 non_phi_uses_[i] = 0; 1807 non_phi_uses_[i] = 0;
1757 indirect_uses_[i] = 0; 1808 indirect_uses_[i] = 0;
1758 } 1809 }
1759 ASSERT(merged_index >= 0); 1810 ASSERT(merged_index >= 0);
1760 set_representation(Representation::Tagged()); 1811 set_representation(Representation::Tagged());
1761 SetFlag(kFlexibleRepresentation); 1812 SetFlag(kFlexibleRepresentation);
1762 } 1813 }
1763 1814
1764 virtual Representation InferredRepresentation() const { 1815 virtual Representation InferredRepresentation() {
1765 bool double_occurred = false; 1816 bool double_occurred = false;
1766 bool int32_occurred = false; 1817 bool int32_occurred = false;
1767 for (int i = 0; i < OperandCount(); ++i) { 1818 for (int i = 0; i < OperandCount(); ++i) {
1768 HValue* value = OperandAt(i); 1819 HValue* value = OperandAt(i);
1769 if (value->representation().IsDouble()) double_occurred = true; 1820 if (value->representation().IsDouble()) double_occurred = true;
1770 if (value->representation().IsInteger32()) int32_occurred = true; 1821 if (value->representation().IsInteger32()) int32_occurred = true;
1771 if (value->representation().IsTagged()) return Representation::Tagged(); 1822 if (value->representation().IsTagged()) return Representation::Tagged();
1772 } 1823 }
1773 1824
1774 if (double_occurred) return Representation::Double(); 1825 if (double_occurred) return Representation::Double();
1775 if (int32_occurred) return Representation::Integer32(); 1826 if (int32_occurred) return Representation::Integer32();
1776 return Representation::None(); 1827 return Representation::None();
1777 } 1828 }
1778 1829
1779 virtual Range* InferRange(); 1830 virtual Range* InferRange();
1780 virtual Representation RequiredInputRepresentation(int index) const { 1831 virtual Representation RequiredInputRepresentation(int index) const {
1781 return representation(); 1832 return representation();
1782 } 1833 }
1783 virtual HType CalculateInferredType() const; 1834 virtual HType CalculateInferredType();
1784 virtual int OperandCount() const { return inputs_.length(); } 1835 virtual int OperandCount() { return inputs_.length(); }
1785 virtual HValue* OperandAt(int index) const { return inputs_[index]; } 1836 virtual HValue* OperandAt(int index) { return inputs_[index]; }
1786 HValue* GetRedundantReplacement() const; 1837 HValue* GetRedundantReplacement();
1787 void AddInput(HValue* value); 1838 void AddInput(HValue* value);
1839 bool HasRealUses();
1788 1840
1789 bool IsReceiver() { return merged_index_ == 0; } 1841 bool IsReceiver() { return merged_index_ == 0; }
1790 1842
1791 int merged_index() const { return merged_index_; } 1843 int merged_index() const { return merged_index_; }
1792 1844
1793 virtual const char* Mnemonic() const { return "phi"; } 1845 virtual const char* Mnemonic() const { return "phi"; }
1794 1846
1795 virtual void PrintTo(StringStream* stream) const; 1847 virtual void PrintTo(StringStream* stream);
1796 1848
1797 #ifdef DEBUG 1849 #ifdef DEBUG
1798 virtual void Verify(); 1850 virtual void Verify();
1799 #endif 1851 #endif
1800 1852
1801 DECLARE_INSTRUCTION(Phi) 1853 DECLARE_INSTRUCTION(Phi)
1802 1854
1803 void InitRealUses(int id); 1855 void InitRealUses(int id);
1804 void AddNonPhiUsesFrom(HPhi* other); 1856 void AddNonPhiUsesFrom(HPhi* other);
1805 void AddIndirectUsesTo(int* use_count); 1857 void AddIndirectUsesTo(int* use_count);
(...skipping 10 matching lines...) Expand all
1816 int tagged_indirect_uses() const { 1868 int tagged_indirect_uses() const {
1817 return indirect_uses_[Representation::kTagged]; 1869 return indirect_uses_[Representation::kTagged];
1818 } 1870 }
1819 int int32_indirect_uses() const { 1871 int int32_indirect_uses() const {
1820 return indirect_uses_[Representation::kInteger32]; 1872 return indirect_uses_[Representation::kInteger32];
1821 } 1873 }
1822 int double_indirect_uses() const { 1874 int double_indirect_uses() const {
1823 return indirect_uses_[Representation::kDouble]; 1875 return indirect_uses_[Representation::kDouble];
1824 } 1876 }
1825 int phi_id() { return phi_id_; } 1877 int phi_id() { return phi_id_; }
1878 bool is_live() { return is_live_; }
1879 void set_is_live(bool b) { is_live_ = b; }
1826 1880
1827 protected: 1881 protected:
1828 virtual void DeleteFromGraph(); 1882 virtual void DeleteFromGraph();
1829 virtual void InternalSetOperandAt(int index, HValue* value) { 1883 virtual void InternalSetOperandAt(int index, HValue* value) {
1830 inputs_[index] = value; 1884 inputs_[index] = value;
1831 } 1885 }
1832 1886
1833 private: 1887 private:
1834 ZoneList<HValue*> inputs_; 1888 ZoneList<HValue*> inputs_;
1835 int merged_index_; 1889 int merged_index_;
1836 1890
1837 int non_phi_uses_[Representation::kNumRepresentations]; 1891 int non_phi_uses_[Representation::kNumRepresentations];
1838 int indirect_uses_[Representation::kNumRepresentations]; 1892 int indirect_uses_[Representation::kNumRepresentations];
1839 int phi_id_; 1893 int phi_id_;
1894 bool is_live_;
1840 }; 1895 };
1841 1896
1842 1897
1843 class HArgumentsObject: public HInstruction { 1898 class HArgumentsObject: public HTemplateInstruction<0> {
1844 public: 1899 public:
1845 HArgumentsObject() { 1900 HArgumentsObject() {
1846 set_representation(Representation::Tagged()); 1901 set_representation(Representation::Tagged());
1847 SetFlag(kIsArguments); 1902 SetFlag(kIsArguments);
1848 } 1903 }
1849 1904
1905 virtual Representation RequiredInputRepresentation(int index) const {
1906 return Representation::None();
1907 }
1908
1850 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject, "arguments-object") 1909 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject, "arguments-object")
1851 }; 1910 };
1852 1911
1853 1912
1854 class HConstant: public HInstruction { 1913 class HConstant: public HTemplateInstruction<0> {
1855 public: 1914 public:
1856 HConstant(Handle<Object> handle, Representation r); 1915 HConstant(Handle<Object> handle, Representation r);
1857 1916
1858 Handle<Object> handle() const { return handle_; } 1917 Handle<Object> handle() const { return handle_; }
1859 1918
1860 bool InOldSpace() const { return !Heap::InNewSpace(*handle_); } 1919 bool InOldSpace() const { return !Heap::InNewSpace(*handle_); }
1861 1920
1862 virtual bool EmitAtUses() const { return !representation().IsDouble(); } 1921 virtual Representation RequiredInputRepresentation(int index) const {
1863 virtual void PrintDataTo(StringStream* stream) const; 1922 return Representation::None();
1864 virtual HType CalculateInferredType() const; 1923 }
1924
1925 virtual bool EmitAtUses() { return !representation().IsDouble(); }
1926 virtual void PrintDataTo(StringStream* stream);
1927 virtual HType CalculateInferredType();
1865 bool IsInteger() const { return handle_->IsSmi(); } 1928 bool IsInteger() const { return handle_->IsSmi(); }
1866 HConstant* CopyToRepresentation(Representation r) const; 1929 HConstant* CopyToRepresentation(Representation r) const;
1867 HConstant* CopyToTruncatedInt32() const; 1930 HConstant* CopyToTruncatedInt32() const;
1868 bool HasInteger32Value() const { return has_int32_value_; } 1931 bool HasInteger32Value() const { return has_int32_value_; }
1869 int32_t Integer32Value() const { 1932 int32_t Integer32Value() const {
1870 ASSERT(HasInteger32Value()); 1933 ASSERT(HasInteger32Value());
1871 return int32_value_; 1934 return int32_value_;
1872 } 1935 }
1873 bool HasDoubleValue() const { return has_double_value_; } 1936 bool HasDoubleValue() const { return has_double_value_; }
1874 double DoubleValue() const { 1937 double DoubleValue() const {
1875 ASSERT(HasDoubleValue()); 1938 ASSERT(HasDoubleValue());
1876 return double_value_; 1939 return double_value_;
1877 } 1940 }
1878 bool HasStringValue() const { return handle_->IsString(); } 1941 bool HasStringValue() const { return handle_->IsString(); }
1879 1942
1880 virtual intptr_t Hashcode() const { 1943 virtual intptr_t Hashcode() {
1881 ASSERT(!Heap::allow_allocation(false)); 1944 ASSERT(!Heap::allow_allocation(false));
1882 return reinterpret_cast<intptr_t>(*handle()); 1945 return reinterpret_cast<intptr_t>(*handle());
1883 } 1946 }
1884 1947
1885 #ifdef DEBUG 1948 #ifdef DEBUG
1886 virtual void Verify() { } 1949 virtual void Verify() { }
1887 #endif 1950 #endif
1888 1951
1889 DECLARE_CONCRETE_INSTRUCTION(Constant, "constant") 1952 DECLARE_CONCRETE_INSTRUCTION(Constant, "constant")
1890 1953
1891 protected: 1954 protected:
1892 virtual Range* InferRange(); 1955 virtual Range* InferRange();
1893 1956
1894 virtual bool DataEquals(HValue* other) const { 1957 virtual bool DataEquals(HValue* other) {
1895 HConstant* other_constant = HConstant::cast(other); 1958 HConstant* other_constant = HConstant::cast(other);
1896 return handle().is_identical_to(other_constant->handle()); 1959 return handle().is_identical_to(other_constant->handle());
1897 } 1960 }
1898 1961
1899 private: 1962 private:
1900 Handle<Object> handle_; 1963 Handle<Object> handle_;
1901 HType constant_type_; 1964 HType constant_type_;
1902 1965
1903 // The following two values represent the int32 and the double value of the 1966 // The following two values represent the int32 and the double value of the
1904 // given constant if there is a lossless conversion between the constant 1967 // given constant if there is a lossless conversion between the constant
1905 // and the specific representation. 1968 // and the specific representation.
1906 bool has_int32_value_; 1969 bool has_int32_value_;
1907 int32_t int32_value_; 1970 int32_t int32_value_;
1908 bool has_double_value_; 1971 bool has_double_value_;
1909 double double_value_; 1972 double double_value_;
1910 }; 1973 };
1911 1974
1912 1975
1913 class HBinaryOperation: public HInstruction { 1976 class HBinaryOperation: public HTemplateInstruction<2> {
1914 public: 1977 public:
1915 HBinaryOperation(HValue* left, HValue* right) { 1978 HBinaryOperation(HValue* left, HValue* right) {
1916 ASSERT(left != NULL && right != NULL); 1979 ASSERT(left != NULL && right != NULL);
1917 SetOperandAt(0, left); 1980 SetOperandAt(0, left);
1918 SetOperandAt(1, right); 1981 SetOperandAt(1, right);
1919 } 1982 }
1920 1983
1921 HValue* left() const { return OperandAt(0); } 1984 HValue* left() { return OperandAt(0); }
1922 HValue* right() const { return OperandAt(1); } 1985 HValue* right() { return OperandAt(1); }
1923 1986
1924 // TODO(kasperl): Move these helpers to the IA-32 Lithium 1987 // TODO(kasperl): Move these helpers to the IA-32 Lithium
1925 // instruction sequence builder. 1988 // instruction sequence builder.
1926 HValue* LeastConstantOperand() const { 1989 HValue* LeastConstantOperand() {
1927 if (IsCommutative() && left()->IsConstant()) return right(); 1990 if (IsCommutative() && left()->IsConstant()) return right();
1928 return left(); 1991 return left();
1929 } 1992 }
1930 HValue* MostConstantOperand() const { 1993 HValue* MostConstantOperand() {
1931 if (IsCommutative() && left()->IsConstant()) return left(); 1994 if (IsCommutative() && left()->IsConstant()) return left();
1932 return right(); 1995 return right();
1933 } 1996 }
1934 1997
1935 virtual bool IsCommutative() const { return false; } 1998 virtual bool IsCommutative() const { return false; }
1936 1999
1937 virtual void PrintDataTo(StringStream* stream) const; 2000 virtual void PrintDataTo(StringStream* stream);
1938 virtual int OperandCount() const { return operands_.length(); }
1939 virtual HValue* OperandAt(int index) const { return operands_[index]; }
1940 2001
1941 DECLARE_INSTRUCTION(BinaryOperation) 2002 DECLARE_INSTRUCTION(BinaryOperation)
1942
1943 protected:
1944 virtual void InternalSetOperandAt(int index, HValue* value) {
1945 operands_[index] = value;
1946 }
1947
1948 HOperandVector<2> operands_;
1949 }; 2003 };
1950 2004
1951 2005
1952 class HApplyArguments: public HInstruction { 2006 class HApplyArguments: public HTemplateInstruction<4> {
1953 public: 2007 public:
1954 HApplyArguments(HValue* function, 2008 HApplyArguments(HValue* function,
1955 HValue* receiver, 2009 HValue* receiver,
1956 HValue* length, 2010 HValue* length,
1957 HValue* elements) { 2011 HValue* elements) {
1958 set_representation(Representation::Tagged()); 2012 set_representation(Representation::Tagged());
1959 SetOperandAt(0, function); 2013 SetOperandAt(0, function);
1960 SetOperandAt(1, receiver); 2014 SetOperandAt(1, receiver);
1961 SetOperandAt(2, length); 2015 SetOperandAt(2, length);
1962 SetOperandAt(3, elements); 2016 SetOperandAt(3, elements);
1963 SetAllSideEffects(); 2017 SetAllSideEffects();
1964 } 2018 }
1965 2019
1966 virtual Representation RequiredInputRepresentation(int index) const { 2020 virtual Representation RequiredInputRepresentation(int index) const {
1967 // The length is untagged, all other inputs are tagged. 2021 // The length is untagged, all other inputs are tagged.
1968 return (index == 2) 2022 return (index == 2)
1969 ? Representation::Integer32() 2023 ? Representation::Integer32()
1970 : Representation::Tagged(); 2024 : Representation::Tagged();
1971 } 2025 }
1972 2026
1973 HValue* function() const { return OperandAt(0); } 2027 HValue* function() { return OperandAt(0); }
1974 HValue* receiver() const { return OperandAt(1); } 2028 HValue* receiver() { return OperandAt(1); }
1975 HValue* length() const { return OperandAt(2); } 2029 HValue* length() { return OperandAt(2); }
1976 HValue* elements() const { return OperandAt(3); } 2030 HValue* elements() { return OperandAt(3); }
1977
1978 virtual int OperandCount() const { return operands_.length(); }
1979 virtual HValue* OperandAt(int index) const { return operands_[index]; }
1980 2031
1981 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply_arguments") 2032 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply_arguments")
1982
1983 protected:
1984 virtual void InternalSetOperandAt(int index, HValue* value) {
1985 operands_[index] = value;
1986 }
1987
1988 private:
1989 HOperandVector<4> operands_;
1990 }; 2033 };
1991 2034
1992 2035
1993 class HArgumentsElements: public HInstruction { 2036 class HArgumentsElements: public HTemplateInstruction<0> {
1994 public: 2037 public:
1995 HArgumentsElements() { 2038 HArgumentsElements() {
1996 // The value produced by this instruction is a pointer into the stack 2039 // The value produced by this instruction is a pointer into the stack
1997 // that looks as if it was a smi because of alignment. 2040 // that looks as if it was a smi because of alignment.
1998 set_representation(Representation::Tagged()); 2041 set_representation(Representation::Tagged());
1999 SetFlag(kUseGVN); 2042 SetFlag(kUseGVN);
2000 } 2043 }
2001 2044
2002 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments_elements") 2045 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments_elements")
2003 2046
2047 virtual Representation RequiredInputRepresentation(int index) const {
2048 return Representation::None();
2049 }
2050
2004 protected: 2051 protected:
2005 virtual bool DataEquals(HValue* other) const { return true; } 2052 virtual bool DataEquals(HValue* other) { return true; }
2006 }; 2053 };
2007 2054
2008 2055
2009 class HArgumentsLength: public HUnaryOperation { 2056 class HArgumentsLength: public HUnaryOperation {
2010 public: 2057 public:
2011 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) { 2058 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2012 set_representation(Representation::Integer32()); 2059 set_representation(Representation::Integer32());
2013 SetFlag(kUseGVN); 2060 SetFlag(kUseGVN);
2014 } 2061 }
2015 2062
2063 virtual Representation RequiredInputRepresentation(int index) const {
2064 return Representation::Tagged();
2065 }
2066
2016 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments_length") 2067 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments_length")
2017 2068
2018 protected: 2069 protected:
2019 virtual bool DataEquals(HValue* other) const { return true; } 2070 virtual bool DataEquals(HValue* other) { return true; }
2020 }; 2071 };
2021 2072
2022 2073
2023 class HAccessArgumentsAt: public HInstruction { 2074 class HAccessArgumentsAt: public HTemplateInstruction<3> {
2024 public: 2075 public:
2025 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) { 2076 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2026 set_representation(Representation::Tagged()); 2077 set_representation(Representation::Tagged());
2027 SetFlag(kUseGVN); 2078 SetFlag(kUseGVN);
2028 SetOperandAt(0, arguments); 2079 SetOperandAt(0, arguments);
2029 SetOperandAt(1, length); 2080 SetOperandAt(1, length);
2030 SetOperandAt(2, index); 2081 SetOperandAt(2, index);
2031 } 2082 }
2032 2083
2033 virtual void PrintDataTo(StringStream* stream) const; 2084 virtual void PrintDataTo(StringStream* stream);
2034 2085
2035 virtual Representation RequiredInputRepresentation(int index) const { 2086 virtual Representation RequiredInputRepresentation(int index) const {
2036 // The arguments elements is considered tagged. 2087 // The arguments elements is considered tagged.
2037 return index == 0 2088 return index == 0
2038 ? Representation::Tagged() 2089 ? Representation::Tagged()
2039 : Representation::Integer32(); 2090 : Representation::Integer32();
2040 } 2091 }
2041 2092
2042 HValue* arguments() const { return operands_[0]; } 2093 HValue* arguments() { return OperandAt(0); }
2043 HValue* length() const { return operands_[1]; } 2094 HValue* length() { return OperandAt(1); }
2044 HValue* index() const { return operands_[2]; } 2095 HValue* index() { return OperandAt(2); }
2045
2046 virtual int OperandCount() const { return operands_.length(); }
2047 virtual HValue* OperandAt(int index) const { return operands_[index]; }
2048 2096
2049 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access_arguments_at") 2097 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access_arguments_at")
2050 2098
2051 protected: 2099 virtual bool DataEquals(HValue* other) { return true; }
2052 virtual void InternalSetOperandAt(int index, HValue* value) {
2053 operands_[index] = value;
2054 }
2055
2056 virtual bool DataEquals(HValue* other) const { return true; }
2057
2058 private:
2059 HOperandVector<3> operands_;
2060 }; 2100 };
2061 2101
2062 2102
2063 class HBoundsCheck: public HBinaryOperation { 2103 class HBoundsCheck: public HBinaryOperation {
2064 public: 2104 public:
2065 HBoundsCheck(HValue* index, HValue* length) 2105 HBoundsCheck(HValue* index, HValue* length)
2066 : HBinaryOperation(index, length) { 2106 : HBinaryOperation(index, length) {
2067 SetFlag(kUseGVN); 2107 SetFlag(kUseGVN);
2068 } 2108 }
2069 2109
2070 virtual bool IsCheckInstruction() const { return true; } 2110 virtual bool IsCheckInstruction() const { return true; }
2071 2111
2072 virtual Representation RequiredInputRepresentation(int index) const { 2112 virtual Representation RequiredInputRepresentation(int index) const {
2073 return Representation::Integer32(); 2113 return Representation::Integer32();
2074 } 2114 }
2075 2115
2076 #ifdef DEBUG 2116 #ifdef DEBUG
2077 virtual void Verify(); 2117 virtual void Verify();
2078 #endif 2118 #endif
2079 2119
2080 HValue* index() const { return left(); } 2120 HValue* index() { return left(); }
2081 HValue* length() const { return right(); } 2121 HValue* length() { return right(); }
2082 2122
2083 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds_check") 2123 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds_check")
2084 2124
2085 protected: 2125 protected:
2086 virtual bool DataEquals(HValue* other) const { return true; } 2126 virtual bool DataEquals(HValue* other) { return true; }
2087 }; 2127 };
2088 2128
2089 2129
2090 class HBitwiseBinaryOperation: public HBinaryOperation { 2130 class HBitwiseBinaryOperation: public HBinaryOperation {
2091 public: 2131 public:
2092 HBitwiseBinaryOperation(HValue* left, HValue* right) 2132 HBitwiseBinaryOperation(HValue* left, HValue* right)
2093 : HBinaryOperation(left, right) { 2133 : HBinaryOperation(left, right) {
2094 set_representation(Representation::Tagged()); 2134 set_representation(Representation::Tagged());
2095 SetFlag(kFlexibleRepresentation); 2135 SetFlag(kFlexibleRepresentation);
2096 SetAllSideEffects(); 2136 SetAllSideEffects();
2097 } 2137 }
2098 2138
2099 virtual Representation RequiredInputRepresentation(int index) const { 2139 virtual Representation RequiredInputRepresentation(int index) const {
2100 return representation(); 2140 return representation();
2101 } 2141 }
2102 2142
2103 virtual void RepresentationChanged(Representation to) { 2143 virtual void RepresentationChanged(Representation to) {
2104 if (!to.IsTagged()) { 2144 if (!to.IsTagged()) {
2105 ASSERT(to.IsInteger32()); 2145 ASSERT(to.IsInteger32());
2106 ClearAllSideEffects(); 2146 ClearAllSideEffects();
2107 SetFlag(kTruncatingToInt32); 2147 SetFlag(kTruncatingToInt32);
2108 SetFlag(kUseGVN); 2148 SetFlag(kUseGVN);
2109 } 2149 }
2110 } 2150 }
2111 2151
2112 HType CalculateInferredType() const; 2152 virtual HType CalculateInferredType();
2113 2153
2114 DECLARE_INSTRUCTION(BitwiseBinaryOperation) 2154 DECLARE_INSTRUCTION(BitwiseBinaryOperation)
2115 }; 2155 };
2116 2156
2117 2157
2118 class HArithmeticBinaryOperation: public HBinaryOperation { 2158 class HArithmeticBinaryOperation: public HBinaryOperation {
2119 public: 2159 public:
2120 HArithmeticBinaryOperation(HValue* left, HValue* right) 2160 HArithmeticBinaryOperation(HValue* left, HValue* right)
2121 : HBinaryOperation(left, right) { 2161 : HBinaryOperation(left, right) {
2122 set_representation(Representation::Tagged()); 2162 set_representation(Representation::Tagged());
2123 SetFlag(kFlexibleRepresentation); 2163 SetFlag(kFlexibleRepresentation);
2124 SetAllSideEffects(); 2164 SetAllSideEffects();
2125 } 2165 }
2126 2166
2127 virtual void RepresentationChanged(Representation to) { 2167 virtual void RepresentationChanged(Representation to) {
2128 if (!to.IsTagged()) { 2168 if (!to.IsTagged()) {
2129 ClearAllSideEffects(); 2169 ClearAllSideEffects();
2130 SetFlag(kUseGVN); 2170 SetFlag(kUseGVN);
2131 } 2171 }
2132 } 2172 }
2133 2173
2134 virtual HType CalculateInferredType() const; 2174 virtual HType CalculateInferredType();
2135 virtual Representation RequiredInputRepresentation(int index) const { 2175 virtual Representation RequiredInputRepresentation(int index) const {
2136 return representation(); 2176 return representation();
2137 } 2177 }
2138 virtual Representation InferredRepresentation() const { 2178 virtual Representation InferredRepresentation() {
2139 if (left()->representation().Equals(right()->representation())) { 2179 if (left()->representation().Equals(right()->representation())) {
2140 return left()->representation(); 2180 return left()->representation();
2141 } 2181 }
2142 return HValue::InferredRepresentation(); 2182 return HValue::InferredRepresentation();
2143 } 2183 }
2144 2184
2145 DECLARE_INSTRUCTION(ArithmeticBinaryOperation) 2185 DECLARE_INSTRUCTION(ArithmeticBinaryOperation)
2146 }; 2186 };
2147 2187
2148 2188
2149 class HCompare: public HBinaryOperation { 2189 class HCompare: public HBinaryOperation {
2150 public: 2190 public:
2151 HCompare(HValue* left, HValue* right, Token::Value token) 2191 HCompare(HValue* left, HValue* right, Token::Value token)
2152 : HBinaryOperation(left, right), token_(token) { 2192 : HBinaryOperation(left, right), token_(token) {
2153 ASSERT(Token::IsCompareOp(token)); 2193 ASSERT(Token::IsCompareOp(token));
2154 set_representation(Representation::Tagged()); 2194 set_representation(Representation::Tagged());
2155 SetAllSideEffects(); 2195 SetAllSideEffects();
2156 } 2196 }
2157 2197
2158 void SetInputRepresentation(Representation r); 2198 void SetInputRepresentation(Representation r);
2159 2199
2160 virtual bool EmitAtUses() const { 2200 virtual bool EmitAtUses() {
2161 return !HasSideEffects() && (uses()->length() <= 1); 2201 return !HasSideEffects() && (uses()->length() <= 1);
2162 } 2202 }
2163 2203
2164 virtual Representation RequiredInputRepresentation(int index) const { 2204 virtual Representation RequiredInputRepresentation(int index) const {
2165 return input_representation_; 2205 return input_representation_;
2166 } 2206 }
2167 Representation GetInputRepresentation() const { 2207 Representation GetInputRepresentation() const {
2168 return input_representation_; 2208 return input_representation_;
2169 } 2209 }
2170 Token::Value token() const { return token_; } 2210 Token::Value token() const { return token_; }
2171 virtual void PrintDataTo(StringStream* stream) const; 2211 virtual void PrintDataTo(StringStream* stream);
2172 2212
2173 virtual HType CalculateInferredType() const; 2213 virtual HType CalculateInferredType();
2174 2214
2175 virtual intptr_t Hashcode() const { 2215 virtual intptr_t Hashcode() {
2176 return HValue::Hashcode() * 7 + token_; 2216 return HValue::Hashcode() * 7 + token_;
2177 } 2217 }
2178 2218
2179 DECLARE_CONCRETE_INSTRUCTION(Compare, "compare") 2219 DECLARE_CONCRETE_INSTRUCTION(Compare, "compare")
2180 2220
2181 protected: 2221 protected:
2182 virtual bool DataEquals(HValue* other) const { 2222 virtual bool DataEquals(HValue* other) {
2183 HCompare* comp = HCompare::cast(other); 2223 HCompare* comp = HCompare::cast(other);
2184 return token_ == comp->token(); 2224 return token_ == comp->token();
2185 } 2225 }
2186 2226
2187 private: 2227 private:
2188 Representation input_representation_; 2228 Representation input_representation_;
2189 Token::Value token_; 2229 Token::Value token_;
2190 }; 2230 };
2191 2231
2192 2232
2193 class HCompareJSObjectEq: public HBinaryOperation { 2233 class HCompareJSObjectEq: public HBinaryOperation {
2194 public: 2234 public:
2195 HCompareJSObjectEq(HValue* left, HValue* right) 2235 HCompareJSObjectEq(HValue* left, HValue* right)
2196 : HBinaryOperation(left, right) { 2236 : HBinaryOperation(left, right) {
2197 set_representation(Representation::Tagged()); 2237 set_representation(Representation::Tagged());
2198 SetFlag(kUseGVN); 2238 SetFlag(kUseGVN);
2199 } 2239 }
2200 2240
2201 virtual bool EmitAtUses() const { 2241 virtual bool EmitAtUses() {
2202 return !HasSideEffects() && (uses()->length() <= 1); 2242 return !HasSideEffects() && (uses()->length() <= 1);
2203 } 2243 }
2204 2244
2205 virtual Representation RequiredInputRepresentation(int index) const { 2245 virtual Representation RequiredInputRepresentation(int index) const {
2206 return Representation::Tagged(); 2246 return Representation::Tagged();
2207 } 2247 }
2208 virtual HType CalculateInferredType() const; 2248 virtual HType CalculateInferredType();
2209 2249
2210 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq, "compare-js-object-eq") 2250 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq, "compare-js-object-eq")
2211 2251
2212 protected: 2252 protected:
2213 virtual bool DataEquals(HValue* other) const { return true; } 2253 virtual bool DataEquals(HValue* other) { return true; }
2214 }; 2254 };
2215 2255
2216 2256
2217 class HUnaryPredicate: public HUnaryOperation { 2257 class HUnaryPredicate: public HUnaryOperation {
2218 public: 2258 public:
2219 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) { 2259 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2220 set_representation(Representation::Tagged()); 2260 set_representation(Representation::Tagged());
2221 SetFlag(kUseGVN); 2261 SetFlag(kUseGVN);
2222 } 2262 }
2223 2263
2224 virtual bool EmitAtUses() const { 2264 virtual bool EmitAtUses() {
2225 return !HasSideEffects() && (uses()->length() <= 1); 2265 return !HasSideEffects() && (uses()->length() <= 1);
2226 } 2266 }
2227 2267
2228 virtual Representation RequiredInputRepresentation(int index) const { 2268 virtual Representation RequiredInputRepresentation(int index) const {
2229 return Representation::Tagged(); 2269 return Representation::Tagged();
2230 } 2270 }
2231 virtual HType CalculateInferredType() const; 2271 virtual HType CalculateInferredType();
2232 }; 2272 };
2233 2273
2234 2274
2235 class HIsNull: public HUnaryPredicate { 2275 class HIsNull: public HUnaryPredicate {
2236 public: 2276 public:
2237 HIsNull(HValue* value, bool is_strict) 2277 HIsNull(HValue* value, bool is_strict)
2238 : HUnaryPredicate(value), is_strict_(is_strict) { } 2278 : HUnaryPredicate(value), is_strict_(is_strict) { }
2239 2279
2240 bool is_strict() const { return is_strict_; } 2280 bool is_strict() const { return is_strict_; }
2241 2281
2242 DECLARE_CONCRETE_INSTRUCTION(IsNull, "is_null") 2282 DECLARE_CONCRETE_INSTRUCTION(IsNull, "is_null")
2243 2283
2244 protected: 2284 protected:
2245 virtual bool DataEquals(HValue* other) const { 2285 virtual bool DataEquals(HValue* other) {
2246 HIsNull* b = HIsNull::cast(other); 2286 HIsNull* b = HIsNull::cast(other);
2247 return is_strict_ == b->is_strict(); 2287 return is_strict_ == b->is_strict();
2248 } 2288 }
2249 2289
2250 private: 2290 private:
2251 bool is_strict_; 2291 bool is_strict_;
2252 }; 2292 };
2253 2293
2254 2294
2255 class HIsObject: public HUnaryPredicate { 2295 class HIsObject: public HUnaryPredicate {
2256 public: 2296 public:
2257 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { } 2297 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2258 2298
2259 DECLARE_CONCRETE_INSTRUCTION(IsObject, "is_object") 2299 DECLARE_CONCRETE_INSTRUCTION(IsObject, "is_object")
2260 2300
2261 protected: 2301 protected:
2262 virtual bool DataEquals(HValue* other) const { return true; } 2302 virtual bool DataEquals(HValue* other) { return true; }
2263 }; 2303 };
2264 2304
2265 2305
2266 class HIsSmi: public HUnaryPredicate { 2306 class HIsSmi: public HUnaryPredicate {
2267 public: 2307 public:
2268 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { } 2308 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2269 2309
2270 DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is_smi") 2310 DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is_smi")
2271 2311
2272 protected: 2312 protected:
2273 virtual bool DataEquals(HValue* other) const { return true; } 2313 virtual bool DataEquals(HValue* other) { return true; }
2274 }; 2314 };
2275 2315
2276 2316
2277 class HIsConstructCall: public HInstruction { 2317 class HIsConstructCall: public HTemplateInstruction<0> {
2278 public: 2318 public:
2279 HIsConstructCall() { 2319 HIsConstructCall() {
2280 set_representation(Representation::Tagged()); 2320 set_representation(Representation::Tagged());
2281 SetFlag(kUseGVN); 2321 SetFlag(kUseGVN);
2282 } 2322 }
2283 2323
2284 virtual bool EmitAtUses() const { 2324 virtual bool EmitAtUses() {
2285 return !HasSideEffects() && (uses()->length() <= 1); 2325 return !HasSideEffects() && (uses()->length() <= 1);
2286 } 2326 }
2287 2327
2328 virtual Representation RequiredInputRepresentation(int index) const {
2329 return Representation::None();
2330 }
2331
2288 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall, "is_construct_call") 2332 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall, "is_construct_call")
2289 2333
2290 protected: 2334 protected:
2291 virtual bool DataEquals(HValue* other) const { return true; } 2335 virtual bool DataEquals(HValue* other) { return true; }
2292 }; 2336 };
2293 2337
2294 2338
2295 class HHasInstanceType: public HUnaryPredicate { 2339 class HHasInstanceType: public HUnaryPredicate {
2296 public: 2340 public:
2297 HHasInstanceType(HValue* value, InstanceType type) 2341 HHasInstanceType(HValue* value, InstanceType type)
2298 : HUnaryPredicate(value), from_(type), to_(type) { } 2342 : HUnaryPredicate(value), from_(type), to_(type) { }
2299 HHasInstanceType(HValue* value, InstanceType from, InstanceType to) 2343 HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2300 : HUnaryPredicate(value), from_(from), to_(to) { 2344 : HUnaryPredicate(value), from_(from), to_(to) {
2301 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend. 2345 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2302 } 2346 }
2303 2347
2304 InstanceType from() { return from_; } 2348 InstanceType from() { return from_; }
2305 InstanceType to() { return to_; } 2349 InstanceType to() { return to_; }
2306 2350
2307 virtual void PrintDataTo(StringStream* stream) const; 2351 virtual void PrintDataTo(StringStream* stream);
2308 2352
2309 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has_instance_type") 2353 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has_instance_type")
2310 2354
2311 protected: 2355 protected:
2312 virtual bool DataEquals(HValue* other) const { 2356 virtual bool DataEquals(HValue* other) {
2313 HHasInstanceType* b = HHasInstanceType::cast(other); 2357 HHasInstanceType* b = HHasInstanceType::cast(other);
2314 return (from_ == b->from()) && (to_ == b->to()); 2358 return (from_ == b->from()) && (to_ == b->to());
2315 } 2359 }
2316 2360
2317 private: 2361 private:
2318 InstanceType from_; 2362 InstanceType from_;
2319 InstanceType to_; // Inclusive range, not all combinations work. 2363 InstanceType to_; // Inclusive range, not all combinations work.
2320 }; 2364 };
2321 2365
2322 2366
2323 class HHasCachedArrayIndex: public HUnaryPredicate { 2367 class HHasCachedArrayIndex: public HUnaryPredicate {
2324 public: 2368 public:
2325 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { } 2369 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2326 2370
2327 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has_cached_array_index") 2371 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has_cached_array_index")
2328 2372
2329 protected: 2373 protected:
2330 virtual bool DataEquals(HValue* other) const { return true; } 2374 virtual bool DataEquals(HValue* other) { return true; }
2375 };
2376
2377
2378 class 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:
2385 virtual bool DataEquals(HValue* other) { return true; }
2331 }; 2386 };
2332 2387
2333 2388
2334 class HClassOfTest: public HUnaryPredicate { 2389 class HClassOfTest: public HUnaryPredicate {
2335 public: 2390 public:
2336 HClassOfTest(HValue* value, Handle<String> class_name) 2391 HClassOfTest(HValue* value, Handle<String> class_name)
2337 : HUnaryPredicate(value), class_name_(class_name) { } 2392 : HUnaryPredicate(value), class_name_(class_name) { }
2338 2393
2339 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class_of_test") 2394 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class_of_test")
2340 2395
2341 virtual void PrintDataTo(StringStream* stream) const; 2396 virtual void PrintDataTo(StringStream* stream);
2342 2397
2343 Handle<String> class_name() const { return class_name_; } 2398 Handle<String> class_name() const { return class_name_; }
2344 2399
2345 protected: 2400 protected:
2346 virtual bool DataEquals(HValue* other) const { 2401 virtual bool DataEquals(HValue* other) {
2347 HClassOfTest* b = HClassOfTest::cast(other); 2402 HClassOfTest* b = HClassOfTest::cast(other);
2348 return class_name_.is_identical_to(b->class_name_); 2403 return class_name_.is_identical_to(b->class_name_);
2349 } 2404 }
2350 2405
2351 private: 2406 private:
2352 Handle<String> class_name_; 2407 Handle<String> class_name_;
2353 }; 2408 };
2354 2409
2355 2410
2356 class HTypeofIs: public HUnaryPredicate { 2411 class HTypeofIs: public HUnaryPredicate {
2357 public: 2412 public:
2358 HTypeofIs(HValue* value, Handle<String> type_literal) 2413 HTypeofIs(HValue* value, Handle<String> type_literal)
2359 : HUnaryPredicate(value), type_literal_(type_literal) { } 2414 : HUnaryPredicate(value), type_literal_(type_literal) { }
2360 2415
2361 Handle<String> type_literal() { return type_literal_; } 2416 Handle<String> type_literal() { return type_literal_; }
2362 virtual void PrintDataTo(StringStream* stream) const; 2417 virtual void PrintDataTo(StringStream* stream);
2363 2418
2364 DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof_is") 2419 DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof_is")
2365 2420
2366 protected: 2421 protected:
2367 virtual bool DataEquals(HValue* other) const { 2422 virtual bool DataEquals(HValue* other) {
2368 HTypeofIs* b = HTypeofIs::cast(other); 2423 HTypeofIs* b = HTypeofIs::cast(other);
2369 return type_literal_.is_identical_to(b->type_literal_); 2424 return type_literal_.is_identical_to(b->type_literal_);
2370 } 2425 }
2371 2426
2372 private: 2427 private:
2373 Handle<String> type_literal_; 2428 Handle<String> type_literal_;
2374 }; 2429 };
2375 2430
2376 2431
2377 class HInstanceOf: public HInstruction { 2432 class HInstanceOf: public HTemplateInstruction<3> {
2378 public: 2433 public:
2379 HInstanceOf(HValue* context, HValue* left, HValue* right) { 2434 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2380 SetOperandAt(0, context); 2435 SetOperandAt(0, context);
2381 SetOperandAt(1, left); 2436 SetOperandAt(1, left);
2382 SetOperandAt(2, right); 2437 SetOperandAt(2, right);
2383 set_representation(Representation::Tagged()); 2438 set_representation(Representation::Tagged());
2384 SetAllSideEffects(); 2439 SetAllSideEffects();
2385 } 2440 }
2386 2441
2387 HValue* context() const { return operands_[0]; } 2442 HValue* context() { return OperandAt(0); }
2388 HValue* left() const { return operands_[1]; } 2443 HValue* left() { return OperandAt(1); }
2389 HValue* right() const { return operands_[2]; } 2444 HValue* right() { return OperandAt(2); }
2390 2445
2391 virtual bool EmitAtUses() const { 2446 virtual bool EmitAtUses() {
2392 return !HasSideEffects() && (uses()->length() <= 1); 2447 return !HasSideEffects() && (uses()->length() <= 1);
2393 } 2448 }
2394 2449
2395 virtual Representation RequiredInputRepresentation(int index) const { 2450 virtual Representation RequiredInputRepresentation(int index) const {
2396 return Representation::Tagged(); 2451 return Representation::Tagged();
2397 } 2452 }
2398 2453
2399 virtual void PrintDataTo(StringStream* stream) const; 2454 virtual void PrintDataTo(StringStream* stream);
2400
2401 virtual int OperandCount() const { return 3; }
2402 virtual HValue* OperandAt(int index) const { return operands_[index]; }
2403 2455
2404 DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance_of") 2456 DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance_of")
2405
2406 protected:
2407 virtual void InternalSetOperandAt(int index, HValue* value) {
2408 operands_[index] = value;
2409 }
2410
2411 private:
2412 HOperandVector<3> operands_;
2413 }; 2457 };
2414 2458
2415 2459
2416 class HInstanceOfKnownGlobal: public HUnaryOperation { 2460 class HInstanceOfKnownGlobal: public HUnaryOperation {
2417 public: 2461 public:
2418 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right) 2462 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2419 : HUnaryOperation(left), function_(right) { 2463 : HUnaryOperation(left), function_(right) {
2420 set_representation(Representation::Tagged()); 2464 set_representation(Representation::Tagged());
2421 SetAllSideEffects(); 2465 SetAllSideEffects();
2422 } 2466 }
(...skipping 20 matching lines...) Expand all
2443 SetFlag(kUseGVN); 2487 SetFlag(kUseGVN);
2444 } 2488 }
2445 2489
2446 virtual Representation RequiredInputRepresentation(int index) const { 2490 virtual Representation RequiredInputRepresentation(int index) const {
2447 return (index == 1) ? Representation::None() : Representation::Double(); 2491 return (index == 1) ? Representation::None() : Representation::Double();
2448 } 2492 }
2449 2493
2450 DECLARE_CONCRETE_INSTRUCTION(Power, "power") 2494 DECLARE_CONCRETE_INSTRUCTION(Power, "power")
2451 2495
2452 protected: 2496 protected:
2453 virtual bool DataEquals(HValue* other) const { return true; } 2497 virtual bool DataEquals(HValue* other) { return true; }
2454 }; 2498 };
2455 2499
2456 2500
2457 class HAdd: public HArithmeticBinaryOperation { 2501 class HAdd: public HArithmeticBinaryOperation {
2458 public: 2502 public:
2459 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) { 2503 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2460 SetFlag(kCanOverflow); 2504 SetFlag(kCanOverflow);
2461 } 2505 }
2462 2506
2463 // Add is only commutative if two integer values are added and not if two 2507 // Add is only commutative if two integer values are added and not if two
2464 // tagged values are added (because it might be a String concatenation). 2508 // tagged values are added (because it might be a String concatenation).
2465 virtual bool IsCommutative() const { 2509 virtual bool IsCommutative() const {
2466 return !representation().IsTagged(); 2510 return !representation().IsTagged();
2467 } 2511 }
2468 2512
2469 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 2513 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2470 2514
2471 virtual HType CalculateInferredType() const; 2515 virtual HType CalculateInferredType();
2472 2516
2473 DECLARE_CONCRETE_INSTRUCTION(Add, "add") 2517 DECLARE_CONCRETE_INSTRUCTION(Add, "add")
2474 2518
2475 protected: 2519 protected:
2476 virtual bool DataEquals(HValue* other) const { return true; } 2520 virtual bool DataEquals(HValue* other) { return true; }
2477 2521
2478 virtual Range* InferRange(); 2522 virtual Range* InferRange();
2479 }; 2523 };
2480 2524
2481 2525
2482 class HSub: public HArithmeticBinaryOperation { 2526 class HSub: public HArithmeticBinaryOperation {
2483 public: 2527 public:
2484 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) { 2528 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2485 SetFlag(kCanOverflow); 2529 SetFlag(kCanOverflow);
2486 } 2530 }
2487 2531
2488 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 2532 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2489 2533
2490 DECLARE_CONCRETE_INSTRUCTION(Sub, "sub") 2534 DECLARE_CONCRETE_INSTRUCTION(Sub, "sub")
2491 2535
2492 protected: 2536 protected:
2493 virtual bool DataEquals(HValue* other) const { return true; } 2537 virtual bool DataEquals(HValue* other) { return true; }
2494 2538
2495 virtual Range* InferRange(); 2539 virtual Range* InferRange();
2496 }; 2540 };
2497 2541
2498 2542
2499 class HMul: public HArithmeticBinaryOperation { 2543 class HMul: public HArithmeticBinaryOperation {
2500 public: 2544 public:
2501 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) { 2545 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2502 SetFlag(kCanOverflow); 2546 SetFlag(kCanOverflow);
2503 } 2547 }
2504 2548
2505 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 2549 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2506 2550
2507 // Only commutative if it is certain that not two objects are multiplicated. 2551 // Only commutative if it is certain that not two objects are multiplicated.
2508 virtual bool IsCommutative() const { 2552 virtual bool IsCommutative() const {
2509 return !representation().IsTagged(); 2553 return !representation().IsTagged();
2510 } 2554 }
2511 2555
2512 DECLARE_CONCRETE_INSTRUCTION(Mul, "mul") 2556 DECLARE_CONCRETE_INSTRUCTION(Mul, "mul")
2513 2557
2514 protected: 2558 protected:
2515 virtual bool DataEquals(HValue* other) const { return true; } 2559 virtual bool DataEquals(HValue* other) { return true; }
2516 2560
2517 virtual Range* InferRange(); 2561 virtual Range* InferRange();
2518 }; 2562 };
2519 2563
2520 2564
2521 class HMod: public HArithmeticBinaryOperation { 2565 class HMod: public HArithmeticBinaryOperation {
2522 public: 2566 public:
2523 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) { 2567 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2524 SetFlag(kCanBeDivByZero); 2568 SetFlag(kCanBeDivByZero);
2525 } 2569 }
2526 2570
2571 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
2527 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 2581 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2528 2582
2529 DECLARE_CONCRETE_INSTRUCTION(Mod, "mod") 2583 DECLARE_CONCRETE_INSTRUCTION(Mod, "mod")
2530 2584
2531 protected: 2585 protected:
2532 virtual bool DataEquals(HValue* other) const { return true; } 2586 virtual bool DataEquals(HValue* other) { return true; }
2533 2587
2534 virtual Range* InferRange(); 2588 virtual Range* InferRange();
2535 }; 2589 };
2536 2590
2537 2591
2538 class HDiv: public HArithmeticBinaryOperation { 2592 class HDiv: public HArithmeticBinaryOperation {
2539 public: 2593 public:
2540 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) { 2594 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2541 SetFlag(kCanBeDivByZero); 2595 SetFlag(kCanBeDivByZero);
2542 SetFlag(kCanOverflow); 2596 SetFlag(kCanOverflow);
2543 } 2597 }
2544 2598
2545 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 2599 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2546 2600
2547 DECLARE_CONCRETE_INSTRUCTION(Div, "div") 2601 DECLARE_CONCRETE_INSTRUCTION(Div, "div")
2548 2602
2549 protected: 2603 protected:
2550 virtual bool DataEquals(HValue* other) const { return true; } 2604 virtual bool DataEquals(HValue* other) { return true; }
2551 2605
2552 virtual Range* InferRange(); 2606 virtual Range* InferRange();
2553 }; 2607 };
2554 2608
2555 2609
2556 class HBitAnd: public HBitwiseBinaryOperation { 2610 class HBitAnd: public HBitwiseBinaryOperation {
2557 public: 2611 public:
2558 HBitAnd(HValue* left, HValue* right) 2612 HBitAnd(HValue* left, HValue* right)
2559 : HBitwiseBinaryOperation(left, right) { } 2613 : HBitwiseBinaryOperation(left, right) { }
2560 2614
2561 virtual bool IsCommutative() const { return true; } 2615 virtual bool IsCommutative() const { return true; }
2562 virtual HType CalculateInferredType() const; 2616 virtual HType CalculateInferredType();
2563 2617
2564 DECLARE_CONCRETE_INSTRUCTION(BitAnd, "bit_and") 2618 DECLARE_CONCRETE_INSTRUCTION(BitAnd, "bit_and")
2565 2619
2566 protected: 2620 protected:
2567 virtual bool DataEquals(HValue* other) const { return true; } 2621 virtual bool DataEquals(HValue* other) { return true; }
2568 2622
2569 virtual Range* InferRange(); 2623 virtual Range* InferRange();
2570 }; 2624 };
2571 2625
2572 2626
2573 class HBitXor: public HBitwiseBinaryOperation { 2627 class HBitXor: public HBitwiseBinaryOperation {
2574 public: 2628 public:
2575 HBitXor(HValue* left, HValue* right) 2629 HBitXor(HValue* left, HValue* right)
2576 : HBitwiseBinaryOperation(left, right) { } 2630 : HBitwiseBinaryOperation(left, right) { }
2577 2631
2578 virtual bool IsCommutative() const { return true; } 2632 virtual bool IsCommutative() const { return true; }
2579 virtual HType CalculateInferredType() const; 2633 virtual HType CalculateInferredType();
2580 2634
2581 DECLARE_CONCRETE_INSTRUCTION(BitXor, "bit_xor") 2635 DECLARE_CONCRETE_INSTRUCTION(BitXor, "bit_xor")
2582 2636
2583 protected: 2637 protected:
2584 virtual bool DataEquals(HValue* other) const { return true; } 2638 virtual bool DataEquals(HValue* other) { return true; }
2585 }; 2639 };
2586 2640
2587 2641
2588 class HBitOr: public HBitwiseBinaryOperation { 2642 class HBitOr: public HBitwiseBinaryOperation {
2589 public: 2643 public:
2590 HBitOr(HValue* left, HValue* right) 2644 HBitOr(HValue* left, HValue* right)
2591 : HBitwiseBinaryOperation(left, right) { } 2645 : HBitwiseBinaryOperation(left, right) { }
2592 2646
2593 virtual bool IsCommutative() const { return true; } 2647 virtual bool IsCommutative() const { return true; }
2594 virtual HType CalculateInferredType() const; 2648 virtual HType CalculateInferredType();
2595 2649
2596 DECLARE_CONCRETE_INSTRUCTION(BitOr, "bit_or") 2650 DECLARE_CONCRETE_INSTRUCTION(BitOr, "bit_or")
2597 2651
2598 protected: 2652 protected:
2599 virtual bool DataEquals(HValue* other) const { return true; } 2653 virtual bool DataEquals(HValue* other) { return true; }
2600 2654
2601 virtual Range* InferRange(); 2655 virtual Range* InferRange();
2602 }; 2656 };
2603 2657
2604 2658
2605 class HShl: public HBitwiseBinaryOperation { 2659 class HShl: public HBitwiseBinaryOperation {
2606 public: 2660 public:
2607 HShl(HValue* left, HValue* right) 2661 HShl(HValue* left, HValue* right)
2608 : HBitwiseBinaryOperation(left, right) { } 2662 : HBitwiseBinaryOperation(left, right) { }
2609 2663
2610 virtual Range* InferRange(); 2664 virtual Range* InferRange();
2611 virtual HType CalculateInferredType() const; 2665 virtual HType CalculateInferredType();
2612 2666
2613 DECLARE_CONCRETE_INSTRUCTION(Shl, "shl") 2667 DECLARE_CONCRETE_INSTRUCTION(Shl, "shl")
2614 2668
2615 protected: 2669 protected:
2616 virtual bool DataEquals(HValue* other) const { return true; } 2670 virtual bool DataEquals(HValue* other) { return true; }
2617 }; 2671 };
2618 2672
2619 2673
2620 class HShr: public HBitwiseBinaryOperation { 2674 class HShr: public HBitwiseBinaryOperation {
2621 public: 2675 public:
2622 HShr(HValue* left, HValue* right) 2676 HShr(HValue* left, HValue* right)
2623 : HBitwiseBinaryOperation(left, right) { } 2677 : HBitwiseBinaryOperation(left, right) { }
2624 2678
2625 virtual HType CalculateInferredType() const; 2679 virtual HType CalculateInferredType();
2626 2680
2627 DECLARE_CONCRETE_INSTRUCTION(Shr, "shr") 2681 DECLARE_CONCRETE_INSTRUCTION(Shr, "shr")
2628 2682
2629 protected: 2683 protected:
2630 virtual bool DataEquals(HValue* other) const { return true; } 2684 virtual bool DataEquals(HValue* other) { return true; }
2631 }; 2685 };
2632 2686
2633 2687
2634 class HSar: public HBitwiseBinaryOperation { 2688 class HSar: public HBitwiseBinaryOperation {
2635 public: 2689 public:
2636 HSar(HValue* left, HValue* right) 2690 HSar(HValue* left, HValue* right)
2637 : HBitwiseBinaryOperation(left, right) { } 2691 : HBitwiseBinaryOperation(left, right) { }
2638 2692
2639 virtual Range* InferRange(); 2693 virtual Range* InferRange();
2640 virtual HType CalculateInferredType() const; 2694 virtual HType CalculateInferredType();
2641 2695
2642 DECLARE_CONCRETE_INSTRUCTION(Sar, "sar") 2696 DECLARE_CONCRETE_INSTRUCTION(Sar, "sar")
2643 2697
2644 protected: 2698 protected:
2645 virtual bool DataEquals(HValue* other) const { return true; } 2699 virtual bool DataEquals(HValue* other) { return true; }
2646 }; 2700 };
2647 2701
2648 2702
2649 class HOsrEntry: public HInstruction { 2703 class HOsrEntry: public HTemplateInstruction<0> {
2650 public: 2704 public:
2651 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) { 2705 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
2652 SetFlag(kChangesOsrEntries); 2706 SetFlag(kChangesOsrEntries);
2653 } 2707 }
2654 2708
2655 int ast_id() const { return ast_id_; } 2709 int ast_id() const { return ast_id_; }
2656 2710
2711 virtual Representation RequiredInputRepresentation(int index) const {
2712 return Representation::None();
2713 }
2714
2657 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr_entry") 2715 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr_entry")
2658 2716
2659 private: 2717 private:
2660 int ast_id_; 2718 int ast_id_;
2661 }; 2719 };
2662 2720
2663 2721
2664 class HParameter: public HInstruction { 2722 class HParameter: public HTemplateInstruction<0> {
2665 public: 2723 public:
2666 explicit HParameter(unsigned index) : index_(index) { 2724 explicit HParameter(unsigned index) : index_(index) {
2667 set_representation(Representation::Tagged()); 2725 set_representation(Representation::Tagged());
2668 } 2726 }
2669 2727
2670 unsigned index() const { return index_; } 2728 unsigned index() const { return index_; }
2671 2729
2672 virtual void PrintDataTo(StringStream* stream) const; 2730 virtual void PrintDataTo(StringStream* stream);
2731
2732 virtual Representation RequiredInputRepresentation(int index) const {
2733 return Representation::None();
2734 }
2673 2735
2674 DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter") 2736 DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
2675 2737
2676 private: 2738 private:
2677 unsigned index_; 2739 unsigned index_;
2678 }; 2740 };
2679 2741
2680 2742
2681 class HCallStub: public HUnaryCall { 2743 class HCallStub: public HUnaryCall {
2682 public: 2744 public:
2683 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count) 2745 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
2684 : HUnaryCall(context, argument_count), 2746 : HUnaryCall(context, argument_count),
2685 major_key_(major_key), 2747 major_key_(major_key),
2686 transcendental_type_(TranscendentalCache::kNumberOfCaches) { 2748 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
2687 } 2749 }
2688 2750
2689 CodeStub::Major major_key() { return major_key_; } 2751 CodeStub::Major major_key() { return major_key_; }
2690 2752
2691 HValue* context() const { return value(); } 2753 HValue* context() { return value(); }
2692 2754
2693 void set_transcendental_type(TranscendentalCache::Type transcendental_type) { 2755 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
2694 transcendental_type_ = transcendental_type; 2756 transcendental_type_ = transcendental_type;
2695 } 2757 }
2696 TranscendentalCache::Type transcendental_type() { 2758 TranscendentalCache::Type transcendental_type() {
2697 return transcendental_type_; 2759 return transcendental_type_;
2698 } 2760 }
2699 2761
2700 virtual void PrintDataTo(StringStream* stream) const; 2762 virtual void PrintDataTo(StringStream* stream);
2763
2764 virtual Representation RequiredInputRepresentation(int index) const {
2765 return Representation::Tagged();
2766 }
2701 2767
2702 DECLARE_CONCRETE_INSTRUCTION(CallStub, "call_stub") 2768 DECLARE_CONCRETE_INSTRUCTION(CallStub, "call_stub")
2703 2769
2704 private: 2770 private:
2705 CodeStub::Major major_key_; 2771 CodeStub::Major major_key_;
2706 TranscendentalCache::Type transcendental_type_; 2772 TranscendentalCache::Type transcendental_type_;
2707 }; 2773 };
2708 2774
2709 2775
2710 class HUnknownOSRValue: public HInstruction { 2776 class HUnknownOSRValue: public HTemplateInstruction<0> {
2711 public: 2777 public:
2712 HUnknownOSRValue() { set_representation(Representation::Tagged()); } 2778 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
2713 2779
2780 virtual Representation RequiredInputRepresentation(int index) const {
2781 return Representation::None();
2782 }
2783
2714 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown_osr_value") 2784 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown_osr_value")
2715 }; 2785 };
2716 2786
2717 2787
2718 class HLoadGlobal: public HInstruction { 2788 class HLoadGlobal: public HTemplateInstruction<0> {
2719 public: 2789 public:
2720 HLoadGlobal(Handle<JSGlobalPropertyCell> cell, bool check_hole_value) 2790 HLoadGlobal(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
2721 : cell_(cell), check_hole_value_(check_hole_value) { 2791 : cell_(cell), check_hole_value_(check_hole_value) {
2722 set_representation(Representation::Tagged()); 2792 set_representation(Representation::Tagged());
2723 SetFlag(kUseGVN); 2793 SetFlag(kUseGVN);
2724 SetFlag(kDependsOnGlobalVars); 2794 SetFlag(kDependsOnGlobalVars);
2725 } 2795 }
2726 2796
2727 Handle<JSGlobalPropertyCell> cell() const { return cell_; } 2797 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
2728 bool check_hole_value() const { return check_hole_value_; } 2798 bool check_hole_value() const { return check_hole_value_; }
2729 2799
2730 virtual Representation RequiredInputRepresentation(int index) const { 2800 virtual void PrintDataTo(StringStream* stream);
2731 return Representation::Tagged();
2732 }
2733 virtual void PrintDataTo(StringStream* stream) const;
2734 2801
2735 virtual intptr_t Hashcode() const { 2802 virtual intptr_t Hashcode() {
2736 ASSERT(!Heap::allow_allocation(false)); 2803 ASSERT(!Heap::allow_allocation(false));
2737 return reinterpret_cast<intptr_t>(*cell_); 2804 return reinterpret_cast<intptr_t>(*cell_);
2738 } 2805 }
2739 2806
2807 virtual Representation RequiredInputRepresentation(int index) const {
2808 return Representation::None();
2809 }
2810
2740 DECLARE_CONCRETE_INSTRUCTION(LoadGlobal, "load_global") 2811 DECLARE_CONCRETE_INSTRUCTION(LoadGlobal, "load_global")
2741 2812
2742 protected: 2813 protected:
2743 virtual bool DataEquals(HValue* other) const { 2814 virtual bool DataEquals(HValue* other) {
2744 HLoadGlobal* b = HLoadGlobal::cast(other); 2815 HLoadGlobal* b = HLoadGlobal::cast(other);
2745 return cell_.is_identical_to(b->cell()); 2816 return cell_.is_identical_to(b->cell());
2746 } 2817 }
2747 2818
2748 private: 2819 private:
2749 Handle<JSGlobalPropertyCell> cell_; 2820 Handle<JSGlobalPropertyCell> cell_;
2750 bool check_hole_value_; 2821 bool check_hole_value_;
2751 }; 2822 };
2752 2823
2753 2824
2754 class HStoreGlobal: public HUnaryOperation { 2825 class HStoreGlobal: public HUnaryOperation {
2755 public: 2826 public:
2756 HStoreGlobal(HValue* value, 2827 HStoreGlobal(HValue* value,
2757 Handle<JSGlobalPropertyCell> cell, 2828 Handle<JSGlobalPropertyCell> cell,
2758 bool check_hole_value) 2829 bool check_hole_value)
2759 : HUnaryOperation(value), 2830 : HUnaryOperation(value),
2760 cell_(cell), 2831 cell_(cell),
2761 check_hole_value_(check_hole_value) { 2832 check_hole_value_(check_hole_value) {
2762 SetFlag(kChangesGlobalVars); 2833 SetFlag(kChangesGlobalVars);
2763 } 2834 }
2764 2835
2765 Handle<JSGlobalPropertyCell> cell() const { return cell_; } 2836 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
2766 bool check_hole_value() const { return check_hole_value_; } 2837 bool check_hole_value() const { return check_hole_value_; }
2767 2838
2768 virtual Representation RequiredInputRepresentation(int index) const { 2839 virtual Representation RequiredInputRepresentation(int index) const {
2769 return Representation::Tagged(); 2840 return Representation::Tagged();
2770 } 2841 }
2771 virtual void PrintDataTo(StringStream* stream) const; 2842 virtual void PrintDataTo(StringStream* stream);
2772 2843
2773 DECLARE_CONCRETE_INSTRUCTION(StoreGlobal, "store_global") 2844 DECLARE_CONCRETE_INSTRUCTION(StoreGlobal, "store_global")
2774 2845
2775 private: 2846 private:
2776 Handle<JSGlobalPropertyCell> cell_; 2847 Handle<JSGlobalPropertyCell> cell_;
2777 bool check_hole_value_; 2848 bool check_hole_value_;
2778 }; 2849 };
2779 2850
2780 2851
2781 class HLoadContextSlot: public HUnaryOperation { 2852 class HLoadContextSlot: public HUnaryOperation {
2782 public: 2853 public:
2783 HLoadContextSlot(HValue* context , int slot_index) 2854 HLoadContextSlot(HValue* context , int slot_index)
2784 : HUnaryOperation(context), slot_index_(slot_index) { 2855 : HUnaryOperation(context), slot_index_(slot_index) {
2785 set_representation(Representation::Tagged()); 2856 set_representation(Representation::Tagged());
2786 SetFlag(kUseGVN); 2857 SetFlag(kUseGVN);
2787 SetFlag(kDependsOnContextSlots); 2858 SetFlag(kDependsOnContextSlots);
2788 } 2859 }
2789 2860
2790 int slot_index() const { return slot_index_; } 2861 int slot_index() const { return slot_index_; }
2791 2862
2792 virtual Representation RequiredInputRepresentation(int index) const { 2863 virtual Representation RequiredInputRepresentation(int index) const {
2793 return Representation::Tagged(); 2864 return Representation::Tagged();
2794 } 2865 }
2795 2866
2796 virtual void PrintDataTo(StringStream* stream) const; 2867 virtual void PrintDataTo(StringStream* stream);
2797 2868
2798 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load_context_slot") 2869 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load_context_slot")
2799 2870
2800 protected: 2871 protected:
2801 virtual bool DataEquals(HValue* other) const { 2872 virtual bool DataEquals(HValue* other) {
2802 HLoadContextSlot* b = HLoadContextSlot::cast(other); 2873 HLoadContextSlot* b = HLoadContextSlot::cast(other);
2803 return (slot_index() == b->slot_index()); 2874 return (slot_index() == b->slot_index());
2804 } 2875 }
2805 2876
2806 private: 2877 private:
2807 int slot_index_; 2878 int slot_index_;
2808 }; 2879 };
2809 2880
2810 2881
2811 static inline bool StoringValueNeedsWriteBarrier(HValue* value) { 2882 static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
2812 return !value->type().IsSmi() && 2883 return !value->type().IsSmi() &&
2813 !(value->IsConstant() && HConstant::cast(value)->InOldSpace()); 2884 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
2814 } 2885 }
2815 2886
2816 2887
2817 class HStoreContextSlot: public HBinaryOperation { 2888 class HStoreContextSlot: public HBinaryOperation {
2818 public: 2889 public:
2819 HStoreContextSlot(HValue* context, int slot_index, HValue* value) 2890 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
2820 : HBinaryOperation(context, value), slot_index_(slot_index) { 2891 : HBinaryOperation(context, value), slot_index_(slot_index) {
2821 SetFlag(kChangesContextSlots); 2892 SetFlag(kChangesContextSlots);
2822 } 2893 }
2823 2894
2824 HValue* context() const { return OperandAt(0); } 2895 HValue* context() { return OperandAt(0); }
2825 HValue* value() const { return OperandAt(1); } 2896 HValue* value() { return OperandAt(1); }
2826 int slot_index() const { return slot_index_; } 2897 int slot_index() const { return slot_index_; }
2827 2898
2828 bool NeedsWriteBarrier() const { 2899 bool NeedsWriteBarrier() {
2829 return StoringValueNeedsWriteBarrier(value()); 2900 return StoringValueNeedsWriteBarrier(value());
2830 } 2901 }
2831 2902
2832 virtual Representation RequiredInputRepresentation(int index) const { 2903 virtual Representation RequiredInputRepresentation(int index) const {
2833 return Representation::Tagged(); 2904 return Representation::Tagged();
2834 } 2905 }
2835 2906
2836 virtual void PrintDataTo(StringStream* stream) const; 2907 virtual void PrintDataTo(StringStream* stream);
2837 2908
2838 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store_context_slot") 2909 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store_context_slot")
2839 2910
2840 private: 2911 private:
2841 int slot_index_; 2912 int slot_index_;
2842 }; 2913 };
2843 2914
2844 2915
2845 class HLoadNamedField: public HUnaryOperation { 2916 class HLoadNamedField: public HUnaryOperation {
2846 public: 2917 public:
2847 HLoadNamedField(HValue* object, bool is_in_object, int offset) 2918 HLoadNamedField(HValue* object, bool is_in_object, int offset)
2848 : HUnaryOperation(object), 2919 : HUnaryOperation(object),
2849 is_in_object_(is_in_object), 2920 is_in_object_(is_in_object),
2850 offset_(offset) { 2921 offset_(offset) {
2851 set_representation(Representation::Tagged()); 2922 set_representation(Representation::Tagged());
2852 SetFlag(kUseGVN); 2923 SetFlag(kUseGVN);
2853 if (is_in_object) { 2924 if (is_in_object) {
2854 SetFlag(kDependsOnInobjectFields); 2925 SetFlag(kDependsOnInobjectFields);
2855 } else { 2926 } else {
2856 SetFlag(kDependsOnBackingStoreFields); 2927 SetFlag(kDependsOnBackingStoreFields);
2857 } 2928 }
2858 } 2929 }
2859 2930
2860 HValue* object() const { return OperandAt(0); } 2931 HValue* object() { return OperandAt(0); }
2861 bool is_in_object() const { return is_in_object_; } 2932 bool is_in_object() const { return is_in_object_; }
2862 int offset() const { return offset_; } 2933 int offset() const { return offset_; }
2863 2934
2864 virtual Representation RequiredInputRepresentation(int index) const { 2935 virtual Representation RequiredInputRepresentation(int index) const {
2865 return Representation::Tagged(); 2936 return Representation::Tagged();
2866 } 2937 }
2867 virtual void PrintDataTo(StringStream* stream) const; 2938 virtual void PrintDataTo(StringStream* stream);
2868 2939
2869 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load_named_field") 2940 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load_named_field")
2870 2941
2871 protected: 2942 protected:
2872 virtual bool DataEquals(HValue* other) const { 2943 virtual bool DataEquals(HValue* other) {
2873 HLoadNamedField* b = HLoadNamedField::cast(other); 2944 HLoadNamedField* b = HLoadNamedField::cast(other);
2874 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_; 2945 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
2875 } 2946 }
2876 2947
2877 private: 2948 private:
2878 bool is_in_object_; 2949 bool is_in_object_;
2879 int offset_; 2950 int offset_;
2880 }; 2951 };
2881 2952
2882 2953
2883 class HLoadNamedGeneric: public HBinaryOperation { 2954 class HLoadNamedGeneric: public HBinaryOperation {
2884 public: 2955 public:
2885 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name) 2956 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
2886 : HBinaryOperation(context, object), name_(name) { 2957 : HBinaryOperation(context, object), name_(name) {
2887 set_representation(Representation::Tagged()); 2958 set_representation(Representation::Tagged());
2888 SetAllSideEffects(); 2959 SetAllSideEffects();
2889 } 2960 }
2890 2961
2891 HValue* context() const { return OperandAt(0); } 2962 HValue* context() { return OperandAt(0); }
2892 HValue* object() const { return OperandAt(1); } 2963 HValue* object() { return OperandAt(1); }
2893 Handle<Object> name() const { return name_; } 2964 Handle<Object> name() const { return name_; }
2894 2965
2895 virtual Representation RequiredInputRepresentation(int index) const { 2966 virtual Representation RequiredInputRepresentation(int index) const {
2896 return Representation::Tagged(); 2967 return Representation::Tagged();
2897 } 2968 }
2898 2969
2899 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load_named_generic") 2970 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load_named_generic")
2900 2971
2901 private: 2972 private:
2902 Handle<Object> name_; 2973 Handle<Object> name_;
2903 }; 2974 };
2904 2975
2905 2976
2906 class HLoadFunctionPrototype: public HUnaryOperation { 2977 class HLoadFunctionPrototype: public HUnaryOperation {
2907 public: 2978 public:
2908 explicit HLoadFunctionPrototype(HValue* function) 2979 explicit HLoadFunctionPrototype(HValue* function)
2909 : HUnaryOperation(function) { 2980 : HUnaryOperation(function) {
2910 set_representation(Representation::Tagged()); 2981 set_representation(Representation::Tagged());
2911 SetFlag(kUseGVN); 2982 SetFlag(kUseGVN);
2912 SetFlag(kDependsOnCalls); 2983 SetFlag(kDependsOnCalls);
2913 } 2984 }
2914 2985
2915 HValue* function() const { return OperandAt(0); } 2986 HValue* function() { return OperandAt(0); }
2916 2987
2917 virtual Representation RequiredInputRepresentation(int index) const { 2988 virtual Representation RequiredInputRepresentation(int index) const {
2918 return Representation::Tagged(); 2989 return Representation::Tagged();
2919 } 2990 }
2920 2991
2921 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load_function_prototype") 2992 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load_function_prototype")
2922 2993
2923 protected: 2994 protected:
2924 virtual bool DataEquals(HValue* other) const { return true; } 2995 virtual bool DataEquals(HValue* other) { return true; }
2925 }; 2996 };
2926 2997
2927 2998
2928 class HLoadKeyed: public HBinaryOperation { 2999 class HLoadKeyedFastElement: public HBinaryOperation {
2929 public: 3000 public:
2930 HLoadKeyed(HValue* obj, HValue* key) : HBinaryOperation(obj, key) { 3001 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
2931 set_representation(Representation::Tagged()); 3002 set_representation(Representation::Tagged());
2932 }
2933
2934 virtual void PrintDataTo(StringStream* stream) const;
2935
2936 virtual Representation RequiredInputRepresentation(int index) const {
2937 return Representation::Tagged();
2938 }
2939 HValue* object() const { return OperandAt(0); }
2940 HValue* key() const { return OperandAt(1); }
2941
2942 DECLARE_INSTRUCTION(LoadKeyed)
2943 };
2944
2945
2946 class HLoadKeyedFastElement: public HLoadKeyed {
2947 public:
2948 HLoadKeyedFastElement(HValue* obj, HValue* key) : HLoadKeyed(obj, key) {
2949 SetFlag(kDependsOnArrayElements); 3003 SetFlag(kDependsOnArrayElements);
2950 SetFlag(kUseGVN); 3004 SetFlag(kUseGVN);
2951 } 3005 }
2952 3006
3007 HValue* object() { return OperandAt(0); }
3008 HValue* key() { return OperandAt(1); }
3009
2953 virtual Representation RequiredInputRepresentation(int index) const { 3010 virtual Representation RequiredInputRepresentation(int index) const {
2954 // The key is supposed to be Integer32. 3011 // The key is supposed to be Integer32.
2955 return (index == 1) ? Representation::Integer32() 3012 return (index == 1) ? Representation::Integer32()
2956 : Representation::Tagged(); 3013 : Representation::Tagged();
2957 } 3014 }
2958 3015
3016 virtual void PrintDataTo(StringStream* stream);
3017
2959 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement, 3018 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement,
2960 "load_keyed_fast_element") 3019 "load_keyed_fast_element")
2961 3020
2962 protected: 3021 protected:
2963 virtual bool DataEquals(HValue* other) const { return true; } 3022 virtual bool DataEquals(HValue* other) { return true; }
2964 }; 3023 };
2965 3024
2966 3025
2967 class HLoadPixelArrayElement: public HBinaryOperation { 3026 class HLoadPixelArrayElement: public HBinaryOperation {
2968 public: 3027 public:
2969 HLoadPixelArrayElement(HValue* external_elements, HValue* key) 3028 HLoadPixelArrayElement(HValue* external_elements, HValue* key)
2970 : HBinaryOperation(external_elements, key) { 3029 : HBinaryOperation(external_elements, key) {
2971 set_representation(Representation::Integer32()); 3030 set_representation(Representation::Integer32());
2972 SetFlag(kDependsOnPixelArrayElements); 3031 SetFlag(kDependsOnPixelArrayElements);
2973 // Native code could change the pixel array. 3032 // Native code could change the pixel array.
2974 SetFlag(kDependsOnCalls); 3033 SetFlag(kDependsOnCalls);
2975 SetFlag(kUseGVN); 3034 SetFlag(kUseGVN);
2976 } 3035 }
2977 3036
2978 virtual void PrintDataTo(StringStream* stream) const; 3037 virtual void PrintDataTo(StringStream* stream);
2979 3038
2980 virtual Representation RequiredInputRepresentation(int index) const { 3039 virtual Representation RequiredInputRepresentation(int index) const {
2981 // The key is supposed to be Integer32, but the base pointer 3040 // The key is supposed to be Integer32, but the base pointer
2982 // for the element load is a naked pointer. 3041 // for the element load is a naked pointer.
2983 return (index == 1) ? Representation::Integer32() 3042 return (index == 1) ? Representation::Integer32()
2984 : Representation::External(); 3043 : Representation::External();
2985 } 3044 }
2986 3045
2987 HValue* external_pointer() const { return OperandAt(0); } 3046 HValue* external_pointer() { return OperandAt(0); }
2988 HValue* key() const { return OperandAt(1); } 3047 HValue* key() { return OperandAt(1); }
2989 3048
2990 DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayElement, 3049 DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayElement,
2991 "load_pixel_array_element") 3050 "load_pixel_array_element")
2992 3051
2993 protected: 3052 protected:
2994 virtual bool DataEquals(HValue* other) const { return true; } 3053 virtual bool DataEquals(HValue* other) { return true; }
2995 }; 3054 };
2996 3055
2997 3056
2998 class HLoadKeyedGeneric: public HLoadKeyed { 3057 class HLoadKeyedGeneric: public HTemplateInstruction<3> {
2999 public: 3058 public:
3000 HLoadKeyedGeneric(HContext* context, HValue* obj, HValue* key) 3059 HLoadKeyedGeneric(HContext* context, HValue* obj, HValue* key) {
3001 : HLoadKeyed(obj, key), context_(NULL) { 3060 set_representation(Representation::Tagged());
3061 SetOperandAt(0, obj);
3062 SetOperandAt(1, key);
3002 SetOperandAt(2, context); 3063 SetOperandAt(2, context);
3003 SetAllSideEffects(); 3064 SetAllSideEffects();
3004 } 3065 }
3005 3066
3006 HValue* context() const { return context_; } 3067 HValue* object() { return OperandAt(0); }
3007 HValue* object() const { return operands_[0]; } 3068 HValue* key() { return OperandAt(1); }
3008 HValue* key() const { return operands_[1]; } 3069 HValue* context() { return OperandAt(2); }
3009 3070
3010 virtual int OperandCount() const { return 3; } 3071 virtual void PrintDataTo(StringStream* stream);
3011 virtual HValue* OperandAt(int index) const {
3012 return (index < 2) ? operands_[index] : context_;
3013 }
3014
3015 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load_keyed_generic")
3016
3017 protected:
3018 virtual void InternalSetOperandAt(int index, HValue* value);
3019
3020 private:
3021 HValue* context_;
3022 };
3023
3024
3025 class HStoreNamed: public HBinaryOperation {
3026 public:
3027 HStoreNamed(HValue* obj, Handle<String> name, HValue* val)
3028 : HBinaryOperation(obj, val), name_(name) {
3029 }
3030 3072
3031 virtual Representation RequiredInputRepresentation(int index) const { 3073 virtual Representation RequiredInputRepresentation(int index) const {
3032 return Representation::Tagged(); 3074 return Representation::Tagged();
3033 } 3075 }
3034 3076
3035 virtual void PrintDataTo(StringStream* stream) const; 3077 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load_keyed_generic")
3036
3037 HValue* object() const { return OperandAt(0); }
3038 Handle<String> name() const { return name_; }
3039 HValue* value() const { return OperandAt(1); }
3040 void set_value(HValue* value) { SetOperandAt(1, value); }
3041
3042 DECLARE_INSTRUCTION(StoreNamed)
3043
3044 private:
3045 Handle<String> name_;
3046 }; 3078 };
3047 3079
3048 3080
3049 class HStoreNamedField: public HStoreNamed { 3081 class HStoreNamedField: public HBinaryOperation {
3050 public: 3082 public:
3051 HStoreNamedField(HValue* obj, 3083 HStoreNamedField(HValue* obj,
3052 Handle<String> name, 3084 Handle<String> name,
3053 HValue* val, 3085 HValue* val,
3054 bool in_object, 3086 bool in_object,
3055 int offset) 3087 int offset)
3056 : HStoreNamed(obj, name, val), 3088 : HBinaryOperation(obj, val),
3089 name_(name),
3057 is_in_object_(in_object), 3090 is_in_object_(in_object),
3058 offset_(offset) { 3091 offset_(offset) {
3059 if (is_in_object_) { 3092 if (is_in_object_) {
3060 SetFlag(kChangesInobjectFields); 3093 SetFlag(kChangesInobjectFields);
3061 } else { 3094 } else {
3062 SetFlag(kChangesBackingStoreFields); 3095 SetFlag(kChangesBackingStoreFields);
3063 } 3096 }
3064 } 3097 }
3065 3098
3066 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store_named_field") 3099 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store_named_field")
3067 3100
3068 virtual Representation RequiredInputRepresentation(int index) const { 3101 virtual Representation RequiredInputRepresentation(int index) const {
3069 return Representation::Tagged(); 3102 return Representation::Tagged();
3070 } 3103 }
3071 virtual void PrintDataTo(StringStream* stream) const; 3104 virtual void PrintDataTo(StringStream* stream);
3072 3105
3106 HValue* object() { return OperandAt(0); }
3107 HValue* value() { return OperandAt(1); }
3108
3109 Handle<String> name() const { return name_; }
3073 bool is_in_object() const { return is_in_object_; } 3110 bool is_in_object() const { return is_in_object_; }
3074 int offset() const { return offset_; } 3111 int offset() const { return offset_; }
3075 Handle<Map> transition() const { return transition_; } 3112 Handle<Map> transition() const { return transition_; }
3076 void set_transition(Handle<Map> map) { transition_ = map; } 3113 void set_transition(Handle<Map> map) { transition_ = map; }
3077 3114
3078 bool NeedsWriteBarrier() const { 3115 bool NeedsWriteBarrier() {
3079 return StoringValueNeedsWriteBarrier(value()); 3116 return StoringValueNeedsWriteBarrier(value());
3080 } 3117 }
3081 3118
3082 private: 3119 private:
3120 Handle<String> name_;
3083 bool is_in_object_; 3121 bool is_in_object_;
3084 int offset_; 3122 int offset_;
3085 Handle<Map> transition_; 3123 Handle<Map> transition_;
3086 }; 3124 };
3087 3125
3088 3126
3089 class HStoreNamedGeneric: public HStoreNamed { 3127 class HStoreNamedGeneric: public HTemplateInstruction<3> {
3090 public: 3128 public:
3091 HStoreNamedGeneric(HValue* context, 3129 HStoreNamedGeneric(HValue* context,
3092 HValue* object, 3130 HValue* object,
3093 Handle<String> name, 3131 Handle<String> name,
3094 HValue* value) 3132 HValue* value)
3095 : HStoreNamed(object, name, value), context_(NULL) { 3133 : name_(name) {
3134 SetOperandAt(0, object);
3135 SetOperandAt(1, value);
3096 SetOperandAt(2, context); 3136 SetOperandAt(2, context);
3097 SetAllSideEffects(); 3137 SetAllSideEffects();
3098 } 3138 }
3099 3139
3100 HValue* context() const { return context_; } 3140 HValue* object() { return OperandAt(0); }
3101 HValue* object() const { return operands_[0]; } 3141 HValue* value() { return OperandAt(1); }
3102 HValue* value() const { return operands_[1]; } 3142 HValue* context() { return OperandAt(2); }
3143 Handle<String> name() { return name_; }
3103 3144
3104 virtual int OperandCount() const { return 3; } 3145 virtual void PrintDataTo(StringStream* stream);
3105
3106 virtual HValue* OperandAt(int index) const {
3107 return (index < 2) ? operands_[index] : context_;
3108 }
3109
3110 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store_named_generic")
3111
3112 protected:
3113 virtual void InternalSetOperandAt(int index, HValue* value);
3114
3115 private:
3116 HValue* context_;
3117 };
3118
3119
3120 class HStoreKeyed: public HInstruction {
3121 public:
3122 HStoreKeyed(HValue* obj, HValue* key, HValue* val) {
3123 SetOperandAt(0, obj);
3124 SetOperandAt(1, key);
3125 SetOperandAt(2, val);
3126 }
3127
3128 virtual void PrintDataTo(StringStream* stream) const;
3129 virtual int OperandCount() const { return operands_.length(); }
3130 virtual HValue* OperandAt(int index) const { return operands_[index]; }
3131 3146
3132 virtual Representation RequiredInputRepresentation(int index) const { 3147 virtual Representation RequiredInputRepresentation(int index) const {
3133 return Representation::Tagged(); 3148 return Representation::Tagged();
3134 } 3149 }
3135 3150
3136 HValue* object() const { return OperandAt(0); } 3151 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store_named_generic")
3137 HValue* key() const { return OperandAt(1); }
3138 HValue* value() const { return OperandAt(2); }
3139 3152
3140 bool NeedsWriteBarrier() const { 3153 private:
3141 return StoringValueNeedsWriteBarrier(value()); 3154 Handle<String> name_;
3142 }
3143
3144 DECLARE_INSTRUCTION(StoreKeyed)
3145
3146 protected:
3147 virtual void InternalSetOperandAt(int index, HValue* value) {
3148 operands_[index] = value;
3149 }
3150
3151 HOperandVector<3> operands_;
3152 }; 3155 };
3153 3156
3154 3157
3155 class HStoreKeyedFastElement: public HStoreKeyed { 3158 class HStoreKeyedFastElement: public HTemplateInstruction<3> {
3156 public: 3159 public:
3157 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) 3160 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3158 : HStoreKeyed(obj, key, val) { 3161 SetOperandAt(0, obj);
3162 SetOperandAt(1, key);
3163 SetOperandAt(2, val);
3159 SetFlag(kChangesArrayElements); 3164 SetFlag(kChangesArrayElements);
3160 } 3165 }
3161 3166
3162 virtual Representation RequiredInputRepresentation(int index) const { 3167 virtual Representation RequiredInputRepresentation(int index) const {
3163 // The key is supposed to be Integer32. 3168 // The key is supposed to be Integer32.
3164 return (index == 1) ? Representation::Integer32() 3169 return (index == 1) ? Representation::Integer32()
3165 : Representation::Tagged(); 3170 : Representation::Tagged();
3166 } 3171 }
3167 3172
3173 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
3168 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement, 3183 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
3169 "store_keyed_fast_element") 3184 "store_keyed_fast_element")
3170 }; 3185 };
3171 3186
3172 3187
3173 class HStoreKeyedGeneric: public HStoreKeyed { 3188 class 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
3216 class HStoreKeyedGeneric: public HTemplateInstruction<4> {
3174 public: 3217 public:
3175 HStoreKeyedGeneric(HValue* context, 3218 HStoreKeyedGeneric(HValue* context,
3176 HValue* object, 3219 HValue* object,
3177 HValue* key, 3220 HValue* key,
3178 HValue* value) 3221 HValue* value) {
3179 : HStoreKeyed(object, key, value), context_(NULL) { 3222 SetOperandAt(0, object);
3223 SetOperandAt(1, key);
3224 SetOperandAt(2, value);
3180 SetOperandAt(3, context); 3225 SetOperandAt(3, context);
3181 SetAllSideEffects(); 3226 SetAllSideEffects();
3182 } 3227 }
3183 3228
3184 HValue* context() const { return context_; } 3229 HValue* object() { return OperandAt(0); }
3185 HValue* object() const { return operands_[0]; } 3230 HValue* key() { return OperandAt(1); }
3186 HValue* key() const { return operands_[1]; } 3231 HValue* value() { return OperandAt(2); }
3187 HValue* value() const { return operands_[2]; } 3232 HValue* context() { return OperandAt(3); }
3188 3233
3189 virtual int OperandCount() const { return 4; } 3234 virtual Representation RequiredInputRepresentation(int index) const {
3190 3235 return Representation::Tagged();
3191 virtual HValue* OperandAt(int index) const {
3192 return (index < 3) ? operands_[index] : context_;
3193 } 3236 }
3194 3237
3238 virtual void PrintDataTo(StringStream* stream);
3239
3195 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store_keyed_generic") 3240 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store_keyed_generic")
3196
3197 protected:
3198 virtual void InternalSetOperandAt(int index, HValue* value);
3199
3200 private:
3201 HValue* context_;
3202 }; 3241 };
3203 3242
3204 3243
3205 class HStringCharCodeAt: public HBinaryOperation { 3244 class HStringCharCodeAt: public HBinaryOperation {
3206 public: 3245 public:
3207 HStringCharCodeAt(HValue* string, HValue* index) 3246 HStringCharCodeAt(HValue* string, HValue* index)
3208 : HBinaryOperation(string, index) { 3247 : HBinaryOperation(string, index) {
3209 set_representation(Representation::Integer32()); 3248 set_representation(Representation::Integer32());
3210 SetFlag(kUseGVN); 3249 SetFlag(kUseGVN);
3211 } 3250 }
3212 3251
3213 virtual Representation RequiredInputRepresentation(int index) const { 3252 virtual Representation RequiredInputRepresentation(int index) const {
3214 // The index is supposed to be Integer32. 3253 // The index is supposed to be Integer32.
3215 return (index == 1) ? Representation::Integer32() 3254 return (index == 1) ? Representation::Integer32()
3216 : Representation::Tagged(); 3255 : Representation::Tagged();
3217 } 3256 }
3218 3257
3219 HValue* string() const { return OperandAt(0); } 3258 HValue* string() { return OperandAt(0); }
3220 HValue* index() const { return OperandAt(1); } 3259 HValue* index() { return OperandAt(1); }
3221 3260
3222 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string_char_code_at") 3261 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string_char_code_at")
3223 3262
3224 protected: 3263 protected:
3225 virtual bool DataEquals(HValue* other) const { return true; } 3264 virtual bool DataEquals(HValue* other) { return true; }
3226 3265
3227 virtual Range* InferRange() { 3266 virtual Range* InferRange() {
3228 return new Range(0, String::kMaxUC16CharCode); 3267 return new Range(0, String::kMaxUC16CharCode);
3229 } 3268 }
3230 }; 3269 };
3231 3270
3232 3271
3272 class 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
3233 class HStringLength: public HUnaryOperation { 3289 class HStringLength: public HUnaryOperation {
3234 public: 3290 public:
3235 explicit HStringLength(HValue* string) : HUnaryOperation(string) { 3291 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3236 set_representation(Representation::Tagged()); 3292 set_representation(Representation::Tagged());
3237 SetFlag(kUseGVN); 3293 SetFlag(kUseGVN);
3238 } 3294 }
3239 3295
3240 virtual Representation RequiredInputRepresentation(int index) const { 3296 virtual Representation RequiredInputRepresentation(int index) const {
3241 return Representation::Tagged(); 3297 return Representation::Tagged();
3242 } 3298 }
3243 3299
3244 virtual HType CalculateInferredType() const { 3300 virtual HType CalculateInferredType() {
3245 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); 3301 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3246 return HType::Smi(); 3302 return HType::Smi();
3247 } 3303 }
3248 3304
3249 DECLARE_CONCRETE_INSTRUCTION(StringLength, "string_length") 3305 DECLARE_CONCRETE_INSTRUCTION(StringLength, "string_length")
3250 3306
3251 protected: 3307 protected:
3252 virtual bool DataEquals(HValue* other) const { return true; } 3308 virtual bool DataEquals(HValue* other) { return true; }
3253 3309
3254 virtual Range* InferRange() { 3310 virtual Range* InferRange() {
3255 return new Range(0, String::kMaxLength); 3311 return new Range(0, String::kMaxLength);
3256 } 3312 }
3257 }; 3313 };
3258 3314
3259 3315
3260 class HMaterializedLiteral: public HInstruction { 3316 template <int V>
3317 class HMaterializedLiteral: public HTemplateInstruction<V> {
3261 public: 3318 public:
3262 HMaterializedLiteral(int index, int depth) 3319 HMaterializedLiteral<V>(int index, int depth)
3263 : literal_index_(index), depth_(depth) { 3320 : literal_index_(index), depth_(depth) {
3264 set_representation(Representation::Tagged()); 3321 this->set_representation(Representation::Tagged());
3265 } 3322 }
3266 3323
3267 int literal_index() const { return literal_index_; } 3324 int literal_index() const { return literal_index_; }
3268 int depth() const { return depth_; } 3325 int depth() const { return depth_; }
3269 3326
3270 DECLARE_INSTRUCTION(MaterializedLiteral)
3271
3272 private: 3327 private:
3273 int literal_index_; 3328 int literal_index_;
3274 int depth_; 3329 int depth_;
3275 }; 3330 };
3276 3331
3277 3332
3278 class HArrayLiteral: public HMaterializedLiteral { 3333 class HArrayLiteral: public HMaterializedLiteral<0> {
3279 public: 3334 public:
3280 HArrayLiteral(Handle<FixedArray> constant_elements, 3335 HArrayLiteral(Handle<FixedArray> constant_elements,
3281 int length, 3336 int length,
3282 int literal_index, 3337 int literal_index,
3283 int depth) 3338 int depth)
3284 : HMaterializedLiteral(literal_index, depth), 3339 : HMaterializedLiteral<0>(literal_index, depth),
3285 length_(length), 3340 length_(length),
3286 constant_elements_(constant_elements) {} 3341 constant_elements_(constant_elements) {}
3287 3342
3288 Handle<FixedArray> constant_elements() const { return constant_elements_; } 3343 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3289 int length() const { return length_; } 3344 int length() const { return length_; }
3290 3345
3291 bool IsCopyOnWrite() const; 3346 bool IsCopyOnWrite() const;
3292 3347
3348 virtual Representation RequiredInputRepresentation(int index) const {
3349 return Representation::None();
3350 }
3351
3293 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array_literal") 3352 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array_literal")
3294 3353
3295 private: 3354 private:
3296 int length_; 3355 int length_;
3297 Handle<FixedArray> constant_elements_; 3356 Handle<FixedArray> constant_elements_;
3298 }; 3357 };
3299 3358
3300 3359
3301 class HObjectLiteral: public HMaterializedLiteral { 3360 class HObjectLiteral: public HMaterializedLiteral<1> {
3302 public: 3361 public:
3303 HObjectLiteral(HValue* context, 3362 HObjectLiteral(HValue* context,
3304 Handle<FixedArray> constant_properties, 3363 Handle<FixedArray> constant_properties,
3305 bool fast_elements, 3364 bool fast_elements,
3306 int literal_index, 3365 int literal_index,
3307 int depth) 3366 int depth)
3308 : HMaterializedLiteral(literal_index, depth), 3367 : HMaterializedLiteral<1>(literal_index, depth),
3309 context_(NULL),
3310 constant_properties_(constant_properties), 3368 constant_properties_(constant_properties),
3311 fast_elements_(fast_elements) { 3369 fast_elements_(fast_elements) {
3312 SetOperandAt(0, context); 3370 SetOperandAt(0, context);
3313 } 3371 }
3314 3372
3315 HValue* context() const { return context_; } 3373 HValue* context() { return OperandAt(0); }
3316 Handle<FixedArray> constant_properties() const { 3374 Handle<FixedArray> constant_properties() const {
3317 return constant_properties_; 3375 return constant_properties_;
3318 } 3376 }
3319 bool fast_elements() const { return fast_elements_; } 3377 bool fast_elements() const { return fast_elements_; }
3320 3378
3321 virtual int OperandCount() const { return 1; } 3379 virtual Representation RequiredInputRepresentation(int index) const {
3322 virtual HValue* OperandAt(int index) const { return context_; } 3380 return Representation::Tagged();
3381 }
3323 3382
3324 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object_literal") 3383 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object_literal")
3325 3384
3326 protected:
3327 virtual void InternalSetOperandAt(int index, HValue* value) {
3328 context_ = value;
3329 }
3330
3331 private: 3385 private:
3332 HValue* context_;
3333 Handle<FixedArray> constant_properties_; 3386 Handle<FixedArray> constant_properties_;
3334 bool fast_elements_; 3387 bool fast_elements_;
3335 }; 3388 };
3336 3389
3337 3390
3338 class HRegExpLiteral: public HMaterializedLiteral { 3391 class HRegExpLiteral: public HMaterializedLiteral<0> {
3339 public: 3392 public:
3340 HRegExpLiteral(Handle<String> pattern, 3393 HRegExpLiteral(Handle<String> pattern,
3341 Handle<String> flags, 3394 Handle<String> flags,
3342 int literal_index) 3395 int literal_index)
3343 : HMaterializedLiteral(literal_index, 0), 3396 : HMaterializedLiteral<0>(literal_index, 0),
3344 pattern_(pattern), 3397 pattern_(pattern),
3345 flags_(flags) { } 3398 flags_(flags) { }
3346 3399
3347 Handle<String> pattern() { return pattern_; } 3400 Handle<String> pattern() { return pattern_; }
3348 Handle<String> flags() { return flags_; } 3401 Handle<String> flags() { return flags_; }
3349 3402
3403 virtual Representation RequiredInputRepresentation(int index) const {
3404 return Representation::None();
3405 }
3406
3350 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp_literal") 3407 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp_literal")
3351 3408
3352 private: 3409 private:
3353 Handle<String> pattern_; 3410 Handle<String> pattern_;
3354 Handle<String> flags_; 3411 Handle<String> flags_;
3355 }; 3412 };
3356 3413
3357 3414
3358 class HFunctionLiteral: public HInstruction { 3415 class HFunctionLiteral: public HTemplateInstruction<0> {
3359 public: 3416 public:
3360 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure) 3417 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3361 : shared_info_(shared), pretenure_(pretenure) { 3418 : shared_info_(shared), pretenure_(pretenure) {
3362 set_representation(Representation::Tagged()); 3419 set_representation(Representation::Tagged());
3363 } 3420 }
3364 3421
3422 virtual Representation RequiredInputRepresentation(int index) const {
3423 return Representation::None();
3424 }
3425
3365 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function_literal") 3426 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function_literal")
3366 3427
3367 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; } 3428 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3368 bool pretenure() const { return pretenure_; } 3429 bool pretenure() const { return pretenure_; }
3369 3430
3370 private: 3431 private:
3371 Handle<SharedFunctionInfo> shared_info_; 3432 Handle<SharedFunctionInfo> shared_info_;
3372 bool pretenure_; 3433 bool pretenure_;
3373 }; 3434 };
3374 3435
(...skipping 11 matching lines...) Expand all
3386 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof") 3447 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
3387 }; 3448 };
3388 3449
3389 3450
3390 class HValueOf: public HUnaryOperation { 3451 class HValueOf: public HUnaryOperation {
3391 public: 3452 public:
3392 explicit HValueOf(HValue* value) : HUnaryOperation(value) { 3453 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
3393 set_representation(Representation::Tagged()); 3454 set_representation(Representation::Tagged());
3394 } 3455 }
3395 3456
3457 virtual Representation RequiredInputRepresentation(int index) const {
3458 return Representation::Tagged();
3459 }
3460
3396 DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value_of") 3461 DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value_of")
3397 }; 3462 };
3398 3463
3399 3464
3400 class HDeleteProperty: public HBinaryOperation { 3465 class HDeleteProperty: public HBinaryOperation {
3401 public: 3466 public:
3402 HDeleteProperty(HValue* obj, HValue* key) 3467 HDeleteProperty(HValue* obj, HValue* key)
3403 : HBinaryOperation(obj, key) { 3468 : HBinaryOperation(obj, key) {
3404 set_representation(Representation::Tagged()); 3469 set_representation(Representation::Tagged());
3405 SetAllSideEffects(); 3470 SetAllSideEffects();
3406 } 3471 }
3407 3472
3408 virtual Representation RequiredInputRepresentation(int index) const { 3473 virtual Representation RequiredInputRepresentation(int index) const {
3409 return Representation::Tagged(); 3474 return Representation::Tagged();
3410 } 3475 }
3411 3476
3412 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete_property") 3477 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete_property")
3413 3478
3414 HValue* object() const { return left(); } 3479 HValue* object() { return left(); }
3415 HValue* key() const { return right(); } 3480 HValue* key() { return right(); }
3416 }; 3481 };
3417 3482
3418 #undef DECLARE_INSTRUCTION 3483 #undef DECLARE_INSTRUCTION
3419 #undef DECLARE_CONCRETE_INSTRUCTION 3484 #undef DECLARE_CONCRETE_INSTRUCTION
3420 3485
3421 } } // namespace v8::internal 3486 } } // namespace v8::internal
3422 3487
3423 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 3488 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698