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

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

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