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

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

Issue 185653004: Experimental parser: merge to r19637 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 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-gvn.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 28 matching lines...) Expand all
39 #include "unique.h" 39 #include "unique.h"
40 #include "v8conversions.h" 40 #include "v8conversions.h"
41 #include "v8utils.h" 41 #include "v8utils.h"
42 #include "zone.h" 42 #include "zone.h"
43 43
44 namespace v8 { 44 namespace v8 {
45 namespace internal { 45 namespace internal {
46 46
47 // Forward declarations. 47 // Forward declarations.
48 class HBasicBlock; 48 class HBasicBlock;
49 class HDiv;
49 class HEnvironment; 50 class HEnvironment;
50 class HInferRepresentationPhase; 51 class HInferRepresentationPhase;
51 class HInstruction; 52 class HInstruction;
52 class HLoopInformation; 53 class HLoopInformation;
53 class HStoreNamedField; 54 class HStoreNamedField;
54 class HValue; 55 class HValue;
55 class LInstruction; 56 class LInstruction;
56 class LChunkBuilder; 57 class LChunkBuilder;
57 58
58 #define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \ 59 #define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 V(CompareObjectEqAndBranch) \ 102 V(CompareObjectEqAndBranch) \
102 V(CompareMap) \ 103 V(CompareMap) \
103 V(Constant) \ 104 V(Constant) \
104 V(Context) \ 105 V(Context) \
105 V(DateField) \ 106 V(DateField) \
106 V(DebugBreak) \ 107 V(DebugBreak) \
107 V(DeclareGlobals) \ 108 V(DeclareGlobals) \
108 V(Deoptimize) \ 109 V(Deoptimize) \
109 V(Div) \ 110 V(Div) \
110 V(DummyUse) \ 111 V(DummyUse) \
111 V(ElementsKind) \
112 V(EnterInlined) \ 112 V(EnterInlined) \
113 V(EnvironmentMarker) \ 113 V(EnvironmentMarker) \
114 V(ForceRepresentation) \ 114 V(ForceRepresentation) \
115 V(ForInCacheArray) \ 115 V(ForInCacheArray) \
116 V(ForInPrepareMap) \ 116 V(ForInPrepareMap) \
117 V(FunctionLiteral) \ 117 V(FunctionLiteral) \
118 V(GetCachedArrayIndex) \ 118 V(GetCachedArrayIndex) \
119 V(GlobalObject) \
120 V(GlobalReceiver) \
121 V(Goto) \ 119 V(Goto) \
122 V(HasCachedArrayIndexAndBranch) \ 120 V(HasCachedArrayIndexAndBranch) \
123 V(HasInstanceTypeAndBranch) \ 121 V(HasInstanceTypeAndBranch) \
124 V(InnerAllocatedObject) \ 122 V(InnerAllocatedObject) \
125 V(InstanceOf) \ 123 V(InstanceOf) \
126 V(InstanceOfKnownGlobal) \ 124 V(InstanceOfKnownGlobal) \
127 V(InvokeFunction) \ 125 V(InvokeFunction) \
128 V(IsConstructCallAndBranch) \ 126 V(IsConstructCallAndBranch) \
129 V(IsObjectAndBranch) \ 127 V(IsObjectAndBranch) \
130 V(IsStringAndBranch) \ 128 V(IsStringAndBranch) \
131 V(IsSmiAndBranch) \ 129 V(IsSmiAndBranch) \
132 V(IsUndetectableAndBranch) \ 130 V(IsUndetectableAndBranch) \
133 V(LeaveInlined) \ 131 V(LeaveInlined) \
134 V(LoadContextSlot) \ 132 V(LoadContextSlot) \
135 V(LoadExternalArrayPointer) \
136 V(LoadFieldByIndex) \ 133 V(LoadFieldByIndex) \
137 V(LoadFunctionPrototype) \ 134 V(LoadFunctionPrototype) \
138 V(LoadGlobalCell) \ 135 V(LoadGlobalCell) \
139 V(LoadGlobalGeneric) \ 136 V(LoadGlobalGeneric) \
140 V(LoadKeyed) \ 137 V(LoadKeyed) \
141 V(LoadKeyedGeneric) \ 138 V(LoadKeyedGeneric) \
142 V(LoadNamedField) \ 139 V(LoadNamedField) \
143 V(LoadNamedGeneric) \ 140 V(LoadNamedGeneric) \
144 V(LoadRoot) \ 141 V(LoadRoot) \
145 V(MapEnumLength) \ 142 V(MapEnumLength) \
146 V(MathFloorOfDiv) \ 143 V(MathFloorOfDiv) \
147 V(MathMinMax) \ 144 V(MathMinMax) \
148 V(Mod) \ 145 V(Mod) \
149 V(Mul) \ 146 V(Mul) \
150 V(OsrEntry) \ 147 V(OsrEntry) \
151 V(OuterContext) \
152 V(Parameter) \ 148 V(Parameter) \
153 V(Power) \ 149 V(Power) \
154 V(PushArgument) \ 150 V(PushArgument) \
155 V(RegExpLiteral) \ 151 V(RegExpLiteral) \
156 V(Return) \ 152 V(Return) \
157 V(Ror) \ 153 V(Ror) \
158 V(Sar) \ 154 V(Sar) \
159 V(SeqStringGetChar) \ 155 V(SeqStringGetChar) \
160 V(SeqStringSetChar) \ 156 V(SeqStringSetChar) \
161 V(Shl) \ 157 V(Shl) \
162 V(Shr) \ 158 V(Shr) \
163 V(Simulate) \ 159 V(Simulate) \
164 V(StackCheck) \ 160 V(StackCheck) \
165 V(StoreCodeEntry) \ 161 V(StoreCodeEntry) \
166 V(StoreContextSlot) \ 162 V(StoreContextSlot) \
167 V(StoreGlobalCell) \ 163 V(StoreGlobalCell) \
168 V(StoreKeyed) \ 164 V(StoreKeyed) \
169 V(StoreKeyedGeneric) \ 165 V(StoreKeyedGeneric) \
170 V(StoreNamedField) \ 166 V(StoreNamedField) \
171 V(StoreNamedGeneric) \ 167 V(StoreNamedGeneric) \
172 V(StringAdd) \ 168 V(StringAdd) \
173 V(StringCharCodeAt) \ 169 V(StringCharCodeAt) \
174 V(StringCharFromCode) \ 170 V(StringCharFromCode) \
175 V(StringCompareAndBranch) \ 171 V(StringCompareAndBranch) \
176 V(Sub) \ 172 V(Sub) \
177 V(ThisFunction) \ 173 V(ThisFunction) \
178 V(Throw) \
179 V(ToFastProperties) \ 174 V(ToFastProperties) \
180 V(TransitionElementsKind) \ 175 V(TransitionElementsKind) \
181 V(TrapAllocationMemento) \ 176 V(TrapAllocationMemento) \
182 V(Typeof) \ 177 V(Typeof) \
183 V(TypeofIsAndBranch) \ 178 V(TypeofIsAndBranch) \
184 V(UnaryMathOperation) \ 179 V(UnaryMathOperation) \
185 V(UnknownOSRValue) \ 180 V(UnknownOSRValue) \
186 V(UseConst) \ 181 V(UseConst) \
187 V(ValueOf) \
188 V(WrapReceiver) 182 V(WrapReceiver)
189 183
190 #define GVN_TRACKED_FLAG_LIST(V) \ 184 #define GVN_TRACKED_FLAG_LIST(V) \
191 V(Maps) \ 185 V(Maps) \
192 V(NewSpacePromotion) 186 V(NewSpacePromotion)
193 187
194 #define GVN_UNTRACKED_FLAG_LIST(V) \ 188 #define GVN_UNTRACKED_FLAG_LIST(V) \
195 V(ArrayElements) \ 189 V(ArrayElements) \
196 V(ArrayLengths) \ 190 V(ArrayLengths) \
197 V(StringLengths) \ 191 V(StringLengths) \
(...skipping 25 matching lines...) Expand all
223 LChunkBuilder* builder) V8_FINAL V8_OVERRIDE; \ 217 LChunkBuilder* builder) V8_FINAL V8_OVERRIDE; \
224 static H##type* cast(HValue* value) { \ 218 static H##type* cast(HValue* value) { \
225 ASSERT(value->Is##type()); \ 219 ASSERT(value->Is##type()); \
226 return reinterpret_cast<H##type*>(value); \ 220 return reinterpret_cast<H##type*>(value); \
227 } \ 221 } \
228 virtual Opcode opcode() const V8_FINAL V8_OVERRIDE { \ 222 virtual Opcode opcode() const V8_FINAL V8_OVERRIDE { \
229 return HValue::k##type; \ 223 return HValue::k##type; \
230 } 224 }
231 225
232 226
227 enum PropertyAccessType { LOAD, STORE };
228
229
233 class Range V8_FINAL : public ZoneObject { 230 class Range V8_FINAL : public ZoneObject {
234 public: 231 public:
235 Range() 232 Range()
236 : lower_(kMinInt), 233 : lower_(kMinInt),
237 upper_(kMaxInt), 234 upper_(kMaxInt),
238 next_(NULL), 235 next_(NULL),
239 can_be_minus_zero_(false) { } 236 can_be_minus_zero_(false) { }
240 237
241 Range(int32_t lower, int32_t upper) 238 Range(int32_t lower, int32_t upper)
242 : lower_(lower), 239 : lower_(lower),
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 469
473 HUseListNode* current_; 470 HUseListNode* current_;
474 HUseListNode* next_; 471 HUseListNode* next_;
475 HValue* value_; 472 HValue* value_;
476 int index_; 473 int index_;
477 474
478 friend class HValue; 475 friend class HValue;
479 }; 476 };
480 477
481 478
482 // There must be one corresponding kDepends flag for every kChanges flag and 479 // All tracked flags should appear before untracked ones.
483 // the order of the kChanges flags must be exactly the same as of the kDepends
484 // flags. All tracked flags should appear before untracked ones.
485 enum GVNFlag { 480 enum GVNFlag {
486 // Declare global value numbering flags. 481 // Declare global value numbering flags.
487 #define DECLARE_FLAG(type) kChanges##type, kDependsOn##type, 482 #define DECLARE_FLAG(Type) k##Type,
488 GVN_TRACKED_FLAG_LIST(DECLARE_FLAG) 483 GVN_TRACKED_FLAG_LIST(DECLARE_FLAG)
489 GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG) 484 GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
490 #undef DECLARE_FLAG 485 #undef DECLARE_FLAG
491 kAfterLastFlag, 486 #define COUNT_FLAG(Type) + 1
492 kLastFlag = kAfterLastFlag - 1, 487 kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG),
493 #define COUNT_FLAG(type) + 1 488 kNumberOfUntrackedSideEffects = 0 GVN_UNTRACKED_FLAG_LIST(COUNT_FLAG),
494 kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG)
495 #undef COUNT_FLAG 489 #undef COUNT_FLAG
490 kNumberOfFlags = kNumberOfTrackedSideEffects + kNumberOfUntrackedSideEffects
496 }; 491 };
497 492
498 493
494 static inline GVNFlag GVNFlagFromInt(int i) {
495 ASSERT(i >= 0);
496 ASSERT(i < kNumberOfFlags);
497 return static_cast<GVNFlag>(i);
498 }
499
500
499 class DecompositionResult V8_FINAL BASE_EMBEDDED { 501 class DecompositionResult V8_FINAL BASE_EMBEDDED {
500 public: 502 public:
501 DecompositionResult() : base_(NULL), offset_(0), scale_(0) {} 503 DecompositionResult() : base_(NULL), offset_(0), scale_(0) {}
502 504
503 HValue* base() { return base_; } 505 HValue* base() { return base_; }
504 int offset() { return offset_; } 506 int offset() { return offset_; }
505 int scale() { return scale_; } 507 int scale() { return scale_; }
506 508
507 bool Apply(HValue* other_base, int other_offset, int other_scale = 0) { 509 bool Apply(HValue* other_base, int other_offset, int other_scale = 0) {
508 if (base_ == NULL) { 510 if (base_ == NULL) {
(...skipping 25 matching lines...) Expand all
534 *a = *b; 536 *a = *b;
535 *b = c; 537 *b = c;
536 } 538 }
537 539
538 HValue* base_; 540 HValue* base_;
539 int offset_; 541 int offset_;
540 int scale_; 542 int scale_;
541 }; 543 };
542 544
543 545
544 typedef EnumSet<GVNFlag, int64_t> GVNFlagSet; 546 typedef EnumSet<GVNFlag, int32_t> GVNFlagSet;
547
548
549 // This class encapsulates encoding and decoding of sources positions from
550 // which hydrogen values originated.
551 // When FLAG_track_hydrogen_positions is set this object encodes the
552 // identifier of the inlining and absolute offset from the start of the
553 // inlined function.
554 // When the flag is not set we simply track absolute offset from the
555 // script start.
556 class HSourcePosition {
557 public:
558 HSourcePosition(const HSourcePosition& other) : value_(other.value_) { }
559
560 static HSourcePosition Unknown() {
561 return HSourcePosition(RelocInfo::kNoPosition);
562 }
563
564 bool IsUnknown() const { return value_ == RelocInfo::kNoPosition; }
565
566 int position() const { return PositionField::decode(value_); }
567 void set_position(int position) {
568 if (FLAG_hydrogen_track_positions) {
569 value_ = static_cast<int>(PositionField::update(value_, position));
570 } else {
571 value_ = position;
572 }
573 }
574
575 int inlining_id() const { return InliningIdField::decode(value_); }
576 void set_inlining_id(int inlining_id) {
577 if (FLAG_hydrogen_track_positions) {
578 value_ = static_cast<int>(InliningIdField::update(value_, inlining_id));
579 }
580 }
581
582 int raw() const { return value_; }
583
584 void PrintTo(FILE* f);
585
586 private:
587 typedef BitField<int, 0, 9> InliningIdField;
588
589 // Offset from the start of the inlined function.
590 typedef BitField<int, 9, 22> PositionField;
591
592 // On HPositionInfo can use this constructor.
593 explicit HSourcePosition(int value) : value_(value) { }
594
595 friend class HPositionInfo;
596
597 // If FLAG_hydrogen_track_positions is set contains bitfields InliningIdField
598 // and PositionField.
599 // Otherwise contains absolute offset from the script start.
600 int value_;
601 };
545 602
546 603
547 class HValue : public ZoneObject { 604 class HValue : public ZoneObject {
548 public: 605 public:
549 static const int kNoNumber = -1; 606 static const int kNoNumber = -1;
550 607
551 enum Flag { 608 enum Flag {
552 kFlexibleRepresentation, 609 kFlexibleRepresentation,
553 kCannotBeTagged, 610 kCannotBeTagged,
554 // Participate in Global Value Numbering, i.e. elimination of 611 // Participate in Global Value Numbering, i.e. elimination of
(...skipping 11 matching lines...) Expand all
566 kAllowUndefinedAsNaN, 623 kAllowUndefinedAsNaN,
567 kIsArguments, 624 kIsArguments,
568 kTruncatingToInt32, 625 kTruncatingToInt32,
569 kAllUsesTruncatingToInt32, 626 kAllUsesTruncatingToInt32,
570 kTruncatingToSmi, 627 kTruncatingToSmi,
571 kAllUsesTruncatingToSmi, 628 kAllUsesTruncatingToSmi,
572 // Set after an instruction is killed. 629 // Set after an instruction is killed.
573 kIsDead, 630 kIsDead,
574 // Instructions that are allowed to produce full range unsigned integer 631 // Instructions that are allowed to produce full range unsigned integer
575 // values are marked with kUint32 flag. If arithmetic shift or a load from 632 // values are marked with kUint32 flag. If arithmetic shift or a load from
576 // EXTERNAL_UNSIGNED_INT_ELEMENTS array is not marked with this flag 633 // EXTERNAL_UINT32_ELEMENTS array is not marked with this flag
577 // it will deoptimize if result does not fit into signed integer range. 634 // it will deoptimize if result does not fit into signed integer range.
578 // HGraph::ComputeSafeUint32Operations is responsible for setting this 635 // HGraph::ComputeSafeUint32Operations is responsible for setting this
579 // flag. 636 // flag.
580 kUint32, 637 kUint32,
581 kHasNoObservableSideEffects, 638 kHasNoObservableSideEffects,
582 // Indicates the instruction is live during dead code elimination. 639 // Indicates the instruction is live during dead code elimination.
583 kIsLive, 640 kIsLive,
584 641
585 // HEnvironmentMarkers are deleted before dead code 642 // HEnvironmentMarkers are deleted before dead code
586 // elimination takes place, so they can repurpose the kIsLive flag: 643 // elimination takes place, so they can repurpose the kIsLive flag:
587 kEndsLiveRange = kIsLive, 644 kEndsLiveRange = kIsLive,
588 645
589 // TODO(everyone): Don't forget to update this! 646 // TODO(everyone): Don't forget to update this!
590 kLastFlag = kIsLive 647 kLastFlag = kIsLive
591 }; 648 };
592 649
593 STATIC_ASSERT(kLastFlag < kBitsPerInt); 650 STATIC_ASSERT(kLastFlag < kBitsPerInt);
594 651
595 static const int kChangesToDependsFlagsLeftShift = 1;
596
597 static GVNFlag ChangesFlagFromInt(int x) {
598 return static_cast<GVNFlag>(x * 2);
599 }
600 static GVNFlag DependsOnFlagFromInt(int x) {
601 return static_cast<GVNFlag>(x * 2 + 1);
602 }
603 static GVNFlagSet ConvertChangesToDependsFlags(GVNFlagSet flags) {
604 return GVNFlagSet(flags.ToIntegral() << kChangesToDependsFlagsLeftShift);
605 }
606
607 static HValue* cast(HValue* value) { return value; } 652 static HValue* cast(HValue* value) { return value; }
608 653
609 enum Opcode { 654 enum Opcode {
610 // Declare a unique enum value for each hydrogen instruction. 655 // Declare a unique enum value for each hydrogen instruction.
611 #define DECLARE_OPCODE(type) k##type, 656 #define DECLARE_OPCODE(type) k##type,
612 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE) 657 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
613 kPhi 658 kPhi
614 #undef DECLARE_OPCODE 659 #undef DECLARE_OPCODE
615 }; 660 };
616 virtual Opcode opcode() const = 0; 661 virtual Opcode opcode() const = 0;
(...skipping 13 matching lines...) Expand all
630 675
631 HValue(HType type = HType::Tagged()) 676 HValue(HType type = HType::Tagged())
632 : block_(NULL), 677 : block_(NULL),
633 id_(kNoNumber), 678 id_(kNoNumber),
634 type_(type), 679 type_(type),
635 use_list_(NULL), 680 use_list_(NULL),
636 range_(NULL), 681 range_(NULL),
637 flags_(0) {} 682 flags_(0) {}
638 virtual ~HValue() {} 683 virtual ~HValue() {}
639 684
640 virtual int position() const { return RelocInfo::kNoPosition; } 685 virtual HSourcePosition position() const {
641 virtual int operand_position(int index) const { return position(); } 686 return HSourcePosition::Unknown();
687 }
688 virtual HSourcePosition operand_position(int index) const {
689 return position();
690 }
642 691
643 HBasicBlock* block() const { return block_; } 692 HBasicBlock* block() const { return block_; }
644 void SetBlock(HBasicBlock* block); 693 void SetBlock(HBasicBlock* block);
645 694
646 // Note: Never call this method for an unlinked value. 695 // Note: Never call this method for an unlinked value.
647 Isolate* isolate() const; 696 Isolate* isolate() const;
648 697
649 int id() const { return id_; } 698 int id() const { return id_; }
650 void set_id(int id) { id_ = id; } 699 void set_id(int id) { id_ = id; }
651 700
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 } 821 }
773 822
774 // Returns true if the flag specified is set for all uses, false otherwise. 823 // Returns true if the flag specified is set for all uses, false otherwise.
775 bool CheckUsesForFlag(Flag f) const; 824 bool CheckUsesForFlag(Flag f) const;
776 // Same as before and the first one without the flag is returned in value. 825 // Same as before and the first one without the flag is returned in value.
777 bool CheckUsesForFlag(Flag f, HValue** value) const; 826 bool CheckUsesForFlag(Flag f, HValue** value) const;
778 // Returns true if the flag specified is set for all uses, and this set 827 // Returns true if the flag specified is set for all uses, and this set
779 // of uses is non-empty. 828 // of uses is non-empty.
780 bool HasAtLeastOneUseWithFlagAndNoneWithout(Flag f) const; 829 bool HasAtLeastOneUseWithFlagAndNoneWithout(Flag f) const;
781 830
782 GVNFlagSet gvn_flags() const { return gvn_flags_; } 831 GVNFlagSet ChangesFlags() const { return changes_flags_; }
783 void SetGVNFlag(GVNFlag f) { gvn_flags_.Add(f); } 832 GVNFlagSet DependsOnFlags() const { return depends_on_flags_; }
784 void ClearGVNFlag(GVNFlag f) { gvn_flags_.Remove(f); } 833 void SetChangesFlag(GVNFlag f) { changes_flags_.Add(f); }
785 bool CheckGVNFlag(GVNFlag f) const { return gvn_flags_.Contains(f); } 834 void SetDependsOnFlag(GVNFlag f) { depends_on_flags_.Add(f); }
786 void SetAllSideEffects() { gvn_flags_.Add(AllSideEffectsFlagSet()); } 835 void ClearChangesFlag(GVNFlag f) { changes_flags_.Remove(f); }
836 void ClearDependsOnFlag(GVNFlag f) { depends_on_flags_.Remove(f); }
837 bool CheckChangesFlag(GVNFlag f) const {
838 return changes_flags_.Contains(f);
839 }
840 bool CheckDependsOnFlag(GVNFlag f) const {
841 return depends_on_flags_.Contains(f);
842 }
843 void SetAllSideEffects() { changes_flags_.Add(AllSideEffectsFlagSet()); }
787 void ClearAllSideEffects() { 844 void ClearAllSideEffects() {
788 gvn_flags_.Remove(AllSideEffectsFlagSet()); 845 changes_flags_.Remove(AllSideEffectsFlagSet());
789 } 846 }
790 bool HasSideEffects() const { 847 bool HasSideEffects() const {
791 return gvn_flags_.ContainsAnyOf(AllSideEffectsFlagSet()); 848 return changes_flags_.ContainsAnyOf(AllSideEffectsFlagSet());
792 } 849 }
793 bool HasObservableSideEffects() const { 850 bool HasObservableSideEffects() const {
794 return !CheckFlag(kHasNoObservableSideEffects) && 851 return !CheckFlag(kHasNoObservableSideEffects) &&
795 gvn_flags_.ContainsAnyOf(AllObservableSideEffectsFlagSet()); 852 changes_flags_.ContainsAnyOf(AllObservableSideEffectsFlagSet());
796 }
797
798 GVNFlagSet DependsOnFlags() const {
799 GVNFlagSet result = gvn_flags_;
800 result.Intersect(AllDependsOnFlagSet());
801 return result;
802 } 853 }
803 854
804 GVNFlagSet SideEffectFlags() const { 855 GVNFlagSet SideEffectFlags() const {
805 GVNFlagSet result = gvn_flags_; 856 GVNFlagSet result = ChangesFlags();
806 result.Intersect(AllSideEffectsFlagSet()); 857 result.Intersect(AllSideEffectsFlagSet());
807 return result; 858 return result;
808 } 859 }
809 860
810 GVNFlagSet ChangesFlags() const {
811 GVNFlagSet result = gvn_flags_;
812 result.Intersect(AllChangesFlagSet());
813 return result;
814 }
815
816 GVNFlagSet ObservableChangesFlags() const { 861 GVNFlagSet ObservableChangesFlags() const {
817 GVNFlagSet result = gvn_flags_; 862 GVNFlagSet result = ChangesFlags();
818 result.Intersect(AllChangesFlagSet());
819 result.Intersect(AllObservableSideEffectsFlagSet()); 863 result.Intersect(AllObservableSideEffectsFlagSet());
820 return result; 864 return result;
821 } 865 }
822 866
823 Range* range() const { return range_; } 867 Range* range() const { return range_; }
824 // TODO(svenpanne) We should really use the null object pattern here. 868 // TODO(svenpanne) We should really use the null object pattern here.
825 bool HasRange() const { return range_ != NULL; } 869 bool HasRange() const { return range_ != NULL; }
826 bool CanBeNegative() const { return !HasRange() || range()->CanBeNegative(); } 870 bool CanBeNegative() const { return !HasRange() || range()->CanBeNegative(); }
827 bool CanBeZero() const { return !HasRange() || range()->CanBeZero(); } 871 bool CanBeZero() const { return !HasRange() || range()->CanBeZero(); }
828 bool RangeCanInclude(int value) const { 872 bool RangeCanInclude(int value) const {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 918
875 // Updated the inferred type of this instruction and returns true if 919 // Updated the inferred type of this instruction and returns true if
876 // it has changed. 920 // it has changed.
877 bool UpdateInferredType(); 921 bool UpdateInferredType();
878 922
879 virtual HType CalculateInferredType(); 923 virtual HType CalculateInferredType();
880 924
881 // This function must be overridden for instructions which have the 925 // This function must be overridden for instructions which have the
882 // kTrackSideEffectDominators flag set, to track instructions that are 926 // kTrackSideEffectDominators flag set, to track instructions that are
883 // dominating side effects. 927 // dominating side effects.
884 virtual void HandleSideEffectDominator(GVNFlag side_effect, 928 // It returns true if it removed an instruction which had side effects.
929 virtual bool HandleSideEffectDominator(GVNFlag side_effect,
885 HValue* dominator) { 930 HValue* dominator) {
886 UNREACHABLE(); 931 UNREACHABLE();
932 return false;
887 } 933 }
888 934
889 // Check if this instruction has some reason that prevents elimination. 935 // Check if this instruction has some reason that prevents elimination.
890 bool CannotBeEliminated() const { 936 bool CannotBeEliminated() const {
891 return HasObservableSideEffects() || !IsDeletable(); 937 return HasObservableSideEffects() || !IsDeletable();
892 } 938 }
893 939
894 #ifdef DEBUG 940 #ifdef DEBUG
895 virtual void Verify() = 0; 941 virtual void Verify() = 0;
896 #endif 942 #endif
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 void clear_block() { 993 void clear_block() {
948 ASSERT(block_ != NULL); 994 ASSERT(block_ != NULL);
949 block_ = NULL; 995 block_ = NULL;
950 } 996 }
951 997
952 void set_representation(Representation r) { 998 void set_representation(Representation r) {
953 ASSERT(representation_.IsNone() && !r.IsNone()); 999 ASSERT(representation_.IsNone() && !r.IsNone());
954 representation_ = r; 1000 representation_ = r;
955 } 1001 }
956 1002
957 static GVNFlagSet AllDependsOnFlagSet() { 1003 static GVNFlagSet AllFlagSet() {
958 GVNFlagSet result; 1004 GVNFlagSet result;
959 // Create changes mask. 1005 #define ADD_FLAG(Type) result.Add(k##Type);
960 #define ADD_FLAG(type) result.Add(kDependsOn##type);
961 GVN_TRACKED_FLAG_LIST(ADD_FLAG) 1006 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
962 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG) 1007 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
963 #undef ADD_FLAG 1008 #undef ADD_FLAG
964 return result;
965 }
966
967 static GVNFlagSet AllChangesFlagSet() {
968 GVNFlagSet result;
969 // Create changes mask.
970 #define ADD_FLAG(type) result.Add(kChanges##type);
971 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
972 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
973 #undef ADD_FLAG
974 return result; 1009 return result;
975 } 1010 }
976 1011
977 // A flag mask to mark an instruction as having arbitrary side effects. 1012 // A flag mask to mark an instruction as having arbitrary side effects.
978 static GVNFlagSet AllSideEffectsFlagSet() { 1013 static GVNFlagSet AllSideEffectsFlagSet() {
979 GVNFlagSet result = AllChangesFlagSet(); 1014 GVNFlagSet result = AllFlagSet();
980 result.Remove(kChangesOsrEntries); 1015 result.Remove(kOsrEntries);
981 return result; 1016 return result;
982 } 1017 }
983 1018
984 // A flag mask of all side effects that can make observable changes in 1019 // A flag mask of all side effects that can make observable changes in
985 // an executing program (i.e. are not safe to repeat, move or remove); 1020 // an executing program (i.e. are not safe to repeat, move or remove);
986 static GVNFlagSet AllObservableSideEffectsFlagSet() { 1021 static GVNFlagSet AllObservableSideEffectsFlagSet() {
987 GVNFlagSet result = AllChangesFlagSet(); 1022 GVNFlagSet result = AllFlagSet();
988 result.Remove(kChangesNewSpacePromotion); 1023 result.Remove(kNewSpacePromotion);
989 result.Remove(kChangesElementsKind); 1024 result.Remove(kElementsKind);
990 result.Remove(kChangesElementsPointer); 1025 result.Remove(kElementsPointer);
991 result.Remove(kChangesMaps); 1026 result.Remove(kMaps);
992 return result; 1027 return result;
993 } 1028 }
994 1029
995 // Remove the matching use from the use list if present. Returns the 1030 // Remove the matching use from the use list if present. Returns the
996 // removed list node or NULL. 1031 // removed list node or NULL.
997 HUseListNode* RemoveUse(HValue* value, int index); 1032 HUseListNode* RemoveUse(HValue* value, int index);
998 1033
999 void RegisterUse(int index, HValue* new_value); 1034 void RegisterUse(int index, HValue* new_value);
1000 1035
1001 HBasicBlock* block_; 1036 HBasicBlock* block_;
1002 1037
1003 // The id of this instruction in the hydrogen graph, assigned when first 1038 // The id of this instruction in the hydrogen graph, assigned when first
1004 // added to the graph. Reflects creation order. 1039 // added to the graph. Reflects creation order.
1005 int id_; 1040 int id_;
1006 1041
1007 Representation representation_; 1042 Representation representation_;
1008 HType type_; 1043 HType type_;
1009 HUseListNode* use_list_; 1044 HUseListNode* use_list_;
1010 Range* range_; 1045 Range* range_;
1011 int flags_; 1046 int flags_;
1012 GVNFlagSet gvn_flags_; 1047 GVNFlagSet changes_flags_;
1048 GVNFlagSet depends_on_flags_;
1013 1049
1014 private: 1050 private:
1015 virtual bool IsDeletable() const { return false; } 1051 virtual bool IsDeletable() const { return false; }
1016 1052
1017 DISALLOW_COPY_AND_ASSIGN(HValue); 1053 DISALLOW_COPY_AND_ASSIGN(HValue);
1018 }; 1054 };
1019 1055
1020 1056
1021 #define DECLARE_INSTRUCTION_FACTORY_P0(I) \ 1057 #define DECLARE_INSTRUCTION_FACTORY_P0(I) \
1022 static I* New(Zone* zone, HValue* context) { \ 1058 static I* New(Zone* zone, HValue* context) { \
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1101 } 1137 }
1102 1138
1103 1139
1104 // A helper class to represent per-operand position information attached to 1140 // A helper class to represent per-operand position information attached to
1105 // the HInstruction in the compact form. Uses tagging to distinguish between 1141 // the HInstruction in the compact form. Uses tagging to distinguish between
1106 // case when only instruction's position is available and case when operands' 1142 // case when only instruction's position is available and case when operands'
1107 // positions are also available. 1143 // positions are also available.
1108 // In the first case it contains intruction's position as a tagged value. 1144 // In the first case it contains intruction's position as a tagged value.
1109 // In the second case it points to an array which contains instruction's 1145 // In the second case it points to an array which contains instruction's
1110 // position and operands' positions. 1146 // position and operands' positions.
1111 // TODO(vegorov): what we really want to track here is a combination of
1112 // source position and a script id because cross script inlining can easily
1113 // result in optimized functions composed of several scripts.
1114 class HPositionInfo { 1147 class HPositionInfo {
1115 public: 1148 public:
1116 explicit HPositionInfo(int pos) : data_(TagPosition(pos)) { } 1149 explicit HPositionInfo(int pos) : data_(TagPosition(pos)) { }
1117 1150
1118 int position() const { 1151 HSourcePosition position() const {
1119 if (has_operand_positions()) { 1152 if (has_operand_positions()) {
1120 return static_cast<int>(operand_positions()[kInstructionPosIndex]); 1153 return operand_positions()[kInstructionPosIndex];
1121 } 1154 }
1122 return static_cast<int>(UntagPosition(data_)); 1155 return HSourcePosition(static_cast<int>(UntagPosition(data_)));
1123 } 1156 }
1124 1157
1125 void set_position(int pos) { 1158 void set_position(HSourcePosition pos) {
1126 if (has_operand_positions()) { 1159 if (has_operand_positions()) {
1127 operand_positions()[kInstructionPosIndex] = pos; 1160 operand_positions()[kInstructionPosIndex] = pos;
1128 } else { 1161 } else {
1129 data_ = TagPosition(pos); 1162 data_ = TagPosition(pos.raw());
1130 } 1163 }
1131 } 1164 }
1132 1165
1133 void ensure_storage_for_operand_positions(Zone* zone, int operand_count) { 1166 void ensure_storage_for_operand_positions(Zone* zone, int operand_count) {
1134 if (has_operand_positions()) { 1167 if (has_operand_positions()) {
1135 return; 1168 return;
1136 } 1169 }
1137 1170
1138 const int length = kFirstOperandPosIndex + operand_count; 1171 const int length = kFirstOperandPosIndex + operand_count;
1139 intptr_t* positions = 1172 HSourcePosition* positions =
1140 zone->NewArray<intptr_t>(length); 1173 zone->NewArray<HSourcePosition>(length);
1141 for (int i = 0; i < length; i++) { 1174 for (int i = 0; i < length; i++) {
1142 positions[i] = RelocInfo::kNoPosition; 1175 positions[i] = HSourcePosition::Unknown();
1143 } 1176 }
1144 1177
1145 const int pos = position(); 1178 const HSourcePosition pos = position();
1146 data_ = reinterpret_cast<intptr_t>(positions); 1179 data_ = reinterpret_cast<intptr_t>(positions);
1147 set_position(pos); 1180 set_position(pos);
1148 1181
1149 ASSERT(has_operand_positions()); 1182 ASSERT(has_operand_positions());
1150 } 1183 }
1151 1184
1152 int operand_position(int idx) const { 1185 HSourcePosition operand_position(int idx) const {
1153 if (!has_operand_positions()) { 1186 if (!has_operand_positions()) {
1154 return position(); 1187 return position();
1155 } 1188 }
1156 return static_cast<int>(*operand_position_slot(idx)); 1189 return *operand_position_slot(idx);
1157 } 1190 }
1158 1191
1159 void set_operand_position(int idx, int pos) { 1192 void set_operand_position(int idx, HSourcePosition pos) {
1160 *operand_position_slot(idx) = pos; 1193 *operand_position_slot(idx) = pos;
1161 } 1194 }
1162 1195
1163 private: 1196 private:
1164 static const intptr_t kInstructionPosIndex = 0; 1197 static const intptr_t kInstructionPosIndex = 0;
1165 static const intptr_t kFirstOperandPosIndex = 1; 1198 static const intptr_t kFirstOperandPosIndex = 1;
1166 1199
1167 intptr_t* operand_position_slot(int idx) const { 1200 HSourcePosition* operand_position_slot(int idx) const {
1168 ASSERT(has_operand_positions()); 1201 ASSERT(has_operand_positions());
1169 return &(operand_positions()[kFirstOperandPosIndex + idx]); 1202 return &(operand_positions()[kFirstOperandPosIndex + idx]);
1170 } 1203 }
1171 1204
1172 bool has_operand_positions() const { 1205 bool has_operand_positions() const {
1173 return !IsTaggedPosition(data_); 1206 return !IsTaggedPosition(data_);
1174 } 1207 }
1175 1208
1176 intptr_t* operand_positions() const { 1209 HSourcePosition* operand_positions() const {
1177 ASSERT(has_operand_positions()); 1210 ASSERT(has_operand_positions());
1178 return reinterpret_cast<intptr_t*>(data_); 1211 return reinterpret_cast<HSourcePosition*>(data_);
1179 } 1212 }
1180 1213
1181 static const intptr_t kPositionTag = 1; 1214 static const intptr_t kPositionTag = 1;
1182 static const intptr_t kPositionShift = 1; 1215 static const intptr_t kPositionShift = 1;
1183 static bool IsTaggedPosition(intptr_t val) { 1216 static bool IsTaggedPosition(intptr_t val) {
1184 return (val & kPositionTag) != 0; 1217 return (val & kPositionTag) != 0;
1185 } 1218 }
1186 static intptr_t UntagPosition(intptr_t val) { 1219 static intptr_t UntagPosition(intptr_t val) {
1187 ASSERT(IsTaggedPosition(val)); 1220 ASSERT(IsTaggedPosition(val));
1188 return val >> kPositionShift; 1221 return val >> kPositionShift;
(...skipping 11 matching lines...) Expand all
1200 class HInstruction : public HValue { 1233 class HInstruction : public HValue {
1201 public: 1234 public:
1202 HInstruction* next() const { return next_; } 1235 HInstruction* next() const { return next_; }
1203 HInstruction* previous() const { return previous_; } 1236 HInstruction* previous() const { return previous_; }
1204 1237
1205 virtual void PrintTo(StringStream* stream) V8_OVERRIDE; 1238 virtual void PrintTo(StringStream* stream) V8_OVERRIDE;
1206 virtual void PrintDataTo(StringStream* stream); 1239 virtual void PrintDataTo(StringStream* stream);
1207 1240
1208 bool IsLinked() const { return block() != NULL; } 1241 bool IsLinked() const { return block() != NULL; }
1209 void Unlink(); 1242 void Unlink();
1243
1210 void InsertBefore(HInstruction* next); 1244 void InsertBefore(HInstruction* next);
1245
1246 template<class T> T* Prepend(T* instr) {
1247 instr->InsertBefore(this);
1248 return instr;
1249 }
1250
1211 void InsertAfter(HInstruction* previous); 1251 void InsertAfter(HInstruction* previous);
1212 1252
1253 template<class T> T* Append(T* instr) {
1254 instr->InsertAfter(this);
1255 return instr;
1256 }
1257
1213 // The position is a write-once variable. 1258 // The position is a write-once variable.
1214 virtual int position() const V8_OVERRIDE { 1259 virtual HSourcePosition position() const V8_OVERRIDE {
1215 return position_.position(); 1260 return HSourcePosition(position_.position());
1216 } 1261 }
1217 bool has_position() const { 1262 bool has_position() const {
1218 return position_.position() != RelocInfo::kNoPosition; 1263 return !position().IsUnknown();
1219 } 1264 }
1220 void set_position(int position) { 1265 void set_position(HSourcePosition position) {
1221 ASSERT(!has_position()); 1266 ASSERT(!has_position());
1222 ASSERT(position != RelocInfo::kNoPosition); 1267 ASSERT(!position.IsUnknown());
1223 position_.set_position(position); 1268 position_.set_position(position);
1224 } 1269 }
1225 1270
1226 virtual int operand_position(int index) const V8_OVERRIDE { 1271 virtual HSourcePosition operand_position(int index) const V8_OVERRIDE {
1227 const int pos = position_.operand_position(index); 1272 const HSourcePosition pos = position_.operand_position(index);
1228 return (pos != RelocInfo::kNoPosition) ? pos : position(); 1273 return pos.IsUnknown() ? position() : pos;
1229 } 1274 }
1230 void set_operand_position(Zone* zone, int index, int pos) { 1275 void set_operand_position(Zone* zone, int index, HSourcePosition pos) {
1231 ASSERT(0 <= index && index < OperandCount()); 1276 ASSERT(0 <= index && index < OperandCount());
1232 position_.ensure_storage_for_operand_positions(zone, OperandCount()); 1277 position_.ensure_storage_for_operand_positions(zone, OperandCount());
1233 position_.set_operand_position(index, pos); 1278 position_.set_operand_position(index, pos);
1234 } 1279 }
1235 1280
1236 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); } 1281 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
1237 1282
1238 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0; 1283 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
1239 1284
1240 #ifdef DEBUG 1285 #ifdef DEBUG
1241 virtual void Verify() V8_OVERRIDE; 1286 virtual void Verify() V8_OVERRIDE;
1242 #endif 1287 #endif
1243 1288
1244 virtual bool HasStackCheck() { return false; } 1289 virtual bool HasStackCheck() { return false; }
1245 1290
1246 DECLARE_ABSTRACT_INSTRUCTION(Instruction) 1291 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
1247 1292
1248 protected: 1293 protected:
1249 HInstruction(HType type = HType::Tagged()) 1294 HInstruction(HType type = HType::Tagged())
1250 : HValue(type), 1295 : HValue(type),
1251 next_(NULL), 1296 next_(NULL),
1252 previous_(NULL), 1297 previous_(NULL),
1253 position_(RelocInfo::kNoPosition) { 1298 position_(RelocInfo::kNoPosition) {
1254 SetGVNFlag(kDependsOnOsrEntries); 1299 SetDependsOnFlag(kOsrEntries);
1255 } 1300 }
1256 1301
1257 virtual void DeleteFromGraph() V8_OVERRIDE { Unlink(); } 1302 virtual void DeleteFromGraph() V8_OVERRIDE { Unlink(); }
1258 1303
1259 private: 1304 private:
1260 void InitializeAsFirst(HBasicBlock* block) { 1305 void InitializeAsFirst(HBasicBlock* block) {
1261 ASSERT(!IsLinked()); 1306 ASSERT(!IsLinked());
1262 SetBlock(block); 1307 SetBlock(block);
1263 } 1308 }
1264 1309
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 ToBooleanStub::Types expected_input_types_; 1561 ToBooleanStub::Types expected_input_types_;
1517 }; 1562 };
1518 1563
1519 1564
1520 class HCompareMap V8_FINAL : public HUnaryControlInstruction { 1565 class HCompareMap V8_FINAL : public HUnaryControlInstruction {
1521 public: 1566 public:
1522 DECLARE_INSTRUCTION_FACTORY_P2(HCompareMap, HValue*, Handle<Map>); 1567 DECLARE_INSTRUCTION_FACTORY_P2(HCompareMap, HValue*, Handle<Map>);
1523 DECLARE_INSTRUCTION_FACTORY_P4(HCompareMap, HValue*, Handle<Map>, 1568 DECLARE_INSTRUCTION_FACTORY_P4(HCompareMap, HValue*, Handle<Map>,
1524 HBasicBlock*, HBasicBlock*); 1569 HBasicBlock*, HBasicBlock*);
1525 1570
1571 virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE {
1572 if (known_successor_index() != kNoKnownSuccessorIndex) {
1573 *block = SuccessorAt(known_successor_index());
1574 return true;
1575 }
1576 *block = NULL;
1577 return false;
1578 }
1579
1526 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 1580 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1527 1581
1582 static const int kNoKnownSuccessorIndex = -1;
1583 int known_successor_index() const { return known_successor_index_; }
1584 void set_known_successor_index(int known_successor_index) {
1585 known_successor_index_ = known_successor_index;
1586 }
1587
1528 Unique<Map> map() const { return map_; } 1588 Unique<Map> map() const { return map_; }
1529 1589
1530 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 1590 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
1531 return Representation::Tagged(); 1591 return Representation::Tagged();
1532 } 1592 }
1533 1593
1534 DECLARE_CONCRETE_INSTRUCTION(CompareMap) 1594 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
1535 1595
1536 protected: 1596 protected:
1537 virtual int RedefinedOperandIndex() { return 0; } 1597 virtual int RedefinedOperandIndex() { return 0; }
1538 1598
1539 private: 1599 private:
1540 HCompareMap(HValue* value, 1600 HCompareMap(HValue* value,
1541 Handle<Map> map, 1601 Handle<Map> map,
1542 HBasicBlock* true_target = NULL, 1602 HBasicBlock* true_target = NULL,
1543 HBasicBlock* false_target = NULL) 1603 HBasicBlock* false_target = NULL)
1544 : HUnaryControlInstruction(value, true_target, false_target), 1604 : HUnaryControlInstruction(value, true_target, false_target),
1545 map_(Unique<Map>(map)) { 1605 known_successor_index_(kNoKnownSuccessorIndex), map_(Unique<Map>(map)) {
1546 ASSERT(!map.is_null()); 1606 ASSERT(!map.is_null());
1607 set_representation(Representation::Tagged());
1547 } 1608 }
1548 1609
1610 int known_successor_index_;
1549 Unique<Map> map_; 1611 Unique<Map> map_;
1550 }; 1612 };
1551 1613
1552 1614
1553 class HContext V8_FINAL : public HTemplateInstruction<0> { 1615 class HContext V8_FINAL : public HTemplateInstruction<0> {
1554 public: 1616 public:
1555 static HContext* New(Zone* zone) { 1617 static HContext* New(Zone* zone) {
1556 return new(zone) HContext(); 1618 return new(zone) HContext();
1557 } 1619 }
1558 1620
(...skipping 15 matching lines...) Expand all
1574 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 1636 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
1575 }; 1637 };
1576 1638
1577 1639
1578 class HReturn V8_FINAL : public HTemplateControlInstruction<0, 3> { 1640 class HReturn V8_FINAL : public HTemplateControlInstruction<0, 3> {
1579 public: 1641 public:
1580 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HReturn, HValue*, HValue*); 1642 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HReturn, HValue*, HValue*);
1581 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HReturn, HValue*); 1643 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HReturn, HValue*);
1582 1644
1583 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 1645 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
1646 // TODO(titzer): require an Int32 input for faster returns.
1647 if (index == 2) return Representation::Smi();
1584 return Representation::Tagged(); 1648 return Representation::Tagged();
1585 } 1649 }
1586 1650
1587 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 1651 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1588 1652
1589 HValue* value() { return OperandAt(0); } 1653 HValue* value() { return OperandAt(0); }
1590 HValue* context() { return OperandAt(1); } 1654 HValue* context() { return OperandAt(1); }
1591 HValue* parameter_count() { return OperandAt(2); } 1655 HValue* parameter_count() { return OperandAt(2); }
1592 1656
1593 DECLARE_CONCRETE_INSTRUCTION(Return) 1657 DECLARE_CONCRETE_INSTRUCTION(Return)
(...skipping 30 matching lines...) Expand all
1624 1688
1625 static HUnaryOperation* cast(HValue* value) { 1689 static HUnaryOperation* cast(HValue* value) {
1626 return reinterpret_cast<HUnaryOperation*>(value); 1690 return reinterpret_cast<HUnaryOperation*>(value);
1627 } 1691 }
1628 1692
1629 HValue* value() const { return OperandAt(0); } 1693 HValue* value() const { return OperandAt(0); }
1630 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 1694 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1631 }; 1695 };
1632 1696
1633 1697
1634 class HThrow V8_FINAL : public HTemplateInstruction<2> {
1635 public:
1636 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HThrow, HValue*);
1637
1638 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
1639 return Representation::Tagged();
1640 }
1641
1642 HValue* context() { return OperandAt(0); }
1643 HValue* value() { return OperandAt(1); }
1644
1645 DECLARE_CONCRETE_INSTRUCTION(Throw)
1646
1647 private:
1648 HThrow(HValue* context, HValue* value) {
1649 SetOperandAt(0, context);
1650 SetOperandAt(1, value);
1651 SetAllSideEffects();
1652 }
1653 };
1654
1655
1656 class HUseConst V8_FINAL : public HUnaryOperation { 1698 class HUseConst V8_FINAL : public HUnaryOperation {
1657 public: 1699 public:
1658 DECLARE_INSTRUCTION_FACTORY_P1(HUseConst, HValue*); 1700 DECLARE_INSTRUCTION_FACTORY_P1(HUseConst, HValue*);
1659 1701
1660 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 1702 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
1661 return Representation::None(); 1703 return Representation::None();
1662 } 1704 }
1663 1705
1664 DECLARE_CONCRETE_INSTRUCTION(UseConst) 1706 DECLARE_CONCRETE_INSTRUCTION(UseConst)
1665 1707
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1708 SetFlag(kUseGVN); 1750 SetFlag(kUseGVN);
1709 if (is_truncating_to_smi) { 1751 if (is_truncating_to_smi) {
1710 SetFlag(kTruncatingToSmi); 1752 SetFlag(kTruncatingToSmi);
1711 SetFlag(kTruncatingToInt32); 1753 SetFlag(kTruncatingToInt32);
1712 } 1754 }
1713 if (is_truncating_to_int32) SetFlag(kTruncatingToInt32); 1755 if (is_truncating_to_int32) SetFlag(kTruncatingToInt32);
1714 if (value->representation().IsSmi() || value->type().IsSmi()) { 1756 if (value->representation().IsSmi() || value->type().IsSmi()) {
1715 set_type(HType::Smi()); 1757 set_type(HType::Smi());
1716 } else { 1758 } else {
1717 set_type(HType::TaggedNumber()); 1759 set_type(HType::TaggedNumber());
1718 if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion); 1760 if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion);
1719 } 1761 }
1720 } 1762 }
1721 1763
1722 bool can_convert_undefined_to_nan() { 1764 bool can_convert_undefined_to_nan() {
1723 return CheckUsesForFlag(kAllowUndefinedAsNaN); 1765 return CheckUsesForFlag(kAllowUndefinedAsNaN);
1724 } 1766 }
1725 1767
1726 virtual HValue* EnsureAndPropagateNotMinusZero( 1768 virtual HValue* EnsureAndPropagateNotMinusZero(
1727 BitVector* visited) V8_OVERRIDE; 1769 BitVector* visited) V8_OVERRIDE;
1728 virtual HType CalculateInferredType() V8_OVERRIDE; 1770 virtual HType CalculateInferredType() V8_OVERRIDE;
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
1954 } 1996 }
1955 1997
1956 bool is_function_entry() { return type_ == kFunctionEntry; } 1998 bool is_function_entry() { return type_ == kFunctionEntry; }
1957 bool is_backwards_branch() { return type_ == kBackwardsBranch; } 1999 bool is_backwards_branch() { return type_ == kBackwardsBranch; }
1958 2000
1959 DECLARE_CONCRETE_INSTRUCTION(StackCheck) 2001 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
1960 2002
1961 private: 2003 private:
1962 HStackCheck(HValue* context, Type type) : type_(type) { 2004 HStackCheck(HValue* context, Type type) : type_(type) {
1963 SetOperandAt(0, context); 2005 SetOperandAt(0, context);
1964 SetGVNFlag(kChangesNewSpacePromotion); 2006 SetChangesFlag(kNewSpacePromotion);
1965 } 2007 }
1966 2008
1967 Type type_; 2009 Type type_;
1968 }; 2010 };
1969 2011
1970 2012
1971 enum InliningKind { 2013 enum InliningKind {
1972 NORMAL_RETURN, // Normal function/method call and return. 2014 NORMAL_RETURN, // Drop the function from the environment on return.
1973 DROP_EXTRA_ON_RETURN, // Drop an extra value from the environment on return.
1974 CONSTRUCT_CALL_RETURN, // Either use allocated receiver or return value. 2015 CONSTRUCT_CALL_RETURN, // Either use allocated receiver or return value.
1975 GETTER_CALL_RETURN, // Returning from a getter, need to restore context. 2016 GETTER_CALL_RETURN, // Returning from a getter, need to restore context.
1976 SETTER_CALL_RETURN // Use the RHS of the assignment as the return value. 2017 SETTER_CALL_RETURN // Use the RHS of the assignment as the return value.
1977 }; 2018 };
1978 2019
1979 2020
1980 class HArgumentsObject; 2021 class HArgumentsObject;
1981 2022
1982 2023
1983 class HEnterInlined V8_FINAL : public HTemplateInstruction<0> { 2024 class HEnterInlined V8_FINAL : public HTemplateInstruction<0> {
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
2104 private: 2145 private:
2105 HThisFunction() { 2146 HThisFunction() {
2106 set_representation(Representation::Tagged()); 2147 set_representation(Representation::Tagged());
2107 SetFlag(kUseGVN); 2148 SetFlag(kUseGVN);
2108 } 2149 }
2109 2150
2110 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 2151 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
2111 }; 2152 };
2112 2153
2113 2154
2114 class HOuterContext V8_FINAL : public HUnaryOperation {
2115 public:
2116 DECLARE_INSTRUCTION_FACTORY_P1(HOuterContext, HValue*);
2117
2118 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
2119
2120 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
2121 return Representation::Tagged();
2122 }
2123
2124 protected:
2125 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
2126
2127 private:
2128 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
2129 set_representation(Representation::Tagged());
2130 SetFlag(kUseGVN);
2131 }
2132
2133 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
2134 };
2135
2136
2137 class HDeclareGlobals V8_FINAL : public HUnaryOperation { 2155 class HDeclareGlobals V8_FINAL : public HUnaryOperation {
2138 public: 2156 public:
2139 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HDeclareGlobals, 2157 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HDeclareGlobals,
2140 Handle<FixedArray>, 2158 Handle<FixedArray>,
2141 int); 2159 int);
2142 2160
2143 HValue* context() { return OperandAt(0); } 2161 HValue* context() { return OperandAt(0); }
2144 Handle<FixedArray> pairs() const { return pairs_; } 2162 Handle<FixedArray> pairs() const { return pairs_; }
2145 int flags() const { return flags_; } 2163 int flags() const { return flags_; }
2146 2164
(...skipping 12 matching lines...) Expand all
2159 flags_(flags) { 2177 flags_(flags) {
2160 set_representation(Representation::Tagged()); 2178 set_representation(Representation::Tagged());
2161 SetAllSideEffects(); 2179 SetAllSideEffects();
2162 } 2180 }
2163 2181
2164 Handle<FixedArray> pairs_; 2182 Handle<FixedArray> pairs_;
2165 int flags_; 2183 int flags_;
2166 }; 2184 };
2167 2185
2168 2186
2169 class HGlobalObject V8_FINAL : public HUnaryOperation {
2170 public:
2171 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P0(HGlobalObject);
2172
2173 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
2174
2175 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
2176 return Representation::Tagged();
2177 }
2178
2179 protected:
2180 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
2181
2182 private:
2183 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
2184 set_representation(Representation::Tagged());
2185 SetFlag(kUseGVN);
2186 }
2187
2188 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
2189 };
2190
2191
2192 class HGlobalReceiver V8_FINAL : public HUnaryOperation {
2193 public:
2194 DECLARE_INSTRUCTION_FACTORY_P1(HGlobalReceiver, HValue*);
2195
2196 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
2197
2198 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
2199 return Representation::Tagged();
2200 }
2201
2202 protected:
2203 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
2204
2205 private:
2206 explicit HGlobalReceiver(HValue* global_object)
2207 : HUnaryOperation(global_object) {
2208 set_representation(Representation::Tagged());
2209 SetFlag(kUseGVN);
2210 }
2211
2212 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
2213 };
2214
2215
2216 template <int V> 2187 template <int V>
2217 class HCall : public HTemplateInstruction<V> { 2188 class HCall : public HTemplateInstruction<V> {
2218 public: 2189 public:
2219 // The argument count includes the receiver. 2190 // The argument count includes the receiver.
2220 explicit HCall<V>(int argument_count) : argument_count_(argument_count) { 2191 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
2221 this->set_representation(Representation::Tagged()); 2192 this->set_representation(Representation::Tagged());
2222 this->SetAllSideEffects(); 2193 this->SetAllSideEffects();
2223 } 2194 }
2224 2195
2225 virtual HType CalculateInferredType() V8_FINAL V8_OVERRIDE { 2196 virtual HType CalculateInferredType() V8_FINAL V8_OVERRIDE {
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
2450 : HBinaryCall(context, function, argument_count), 2421 : HBinaryCall(context, function, argument_count),
2451 has_stack_check_(false) { 2422 has_stack_check_(false) {
2452 } 2423 }
2453 2424
2454 Handle<JSFunction> known_function_; 2425 Handle<JSFunction> known_function_;
2455 int formal_parameter_count_; 2426 int formal_parameter_count_;
2456 bool has_stack_check_; 2427 bool has_stack_check_;
2457 }; 2428 };
2458 2429
2459 2430
2460 enum CallMode {
2461 NORMAL_CALL,
2462 TAIL_CALL,
2463 NORMAL_CONTEXTUAL_CALL
2464 };
2465
2466
2467 class HCallFunction V8_FINAL : public HBinaryCall { 2431 class HCallFunction V8_FINAL : public HBinaryCall {
2468 public: 2432 public:
2469 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallFunction, HValue*, int); 2433 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallFunction, HValue*, int);
2470 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3( 2434 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(
2471 HCallFunction, HValue*, int, CallMode); 2435 HCallFunction, HValue*, int, CallFunctionFlags);
2472 2436
2473 bool IsTailCall() const { return call_mode_ == TAIL_CALL; }
2474 bool IsContextualCall() const { return call_mode_ == NORMAL_CONTEXTUAL_CALL; }
2475 HValue* context() { return first(); } 2437 HValue* context() { return first(); }
2476 HValue* function() { return second(); } 2438 HValue* function() { return second(); }
2439 CallFunctionFlags function_flags() const { return function_flags_; }
2477 2440
2478 DECLARE_CONCRETE_INSTRUCTION(CallFunction) 2441 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
2479 2442
2480 virtual int argument_delta() const V8_OVERRIDE { 2443 virtual int argument_delta() const V8_OVERRIDE { return -argument_count(); }
2481 if (IsTailCall()) return 0;
2482 return -argument_count();
2483 }
2484 2444
2485 private: 2445 private:
2486 HCallFunction(HValue* context, 2446 HCallFunction(HValue* context,
2487 HValue* function, 2447 HValue* function,
2488 int argument_count, 2448 int argument_count,
2489 CallMode mode = NORMAL_CALL) 2449 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS)
2490 : HBinaryCall(context, function, argument_count), call_mode_(mode) { 2450 : HBinaryCall(context, function, argument_count), function_flags_(flags) {
2491 } 2451 }
2492 CallMode call_mode_; 2452 CallFunctionFlags function_flags_;
2493 }; 2453 };
2494 2454
2495 2455
2496 class HCallNew V8_FINAL : public HBinaryCall { 2456 class HCallNew V8_FINAL : public HBinaryCall {
2497 public: 2457 public:
2498 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallNew, HValue*, int); 2458 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallNew, HValue*, int);
2499 2459
2500 HValue* context() { return first(); } 2460 HValue* context() { return first(); }
2501 HValue* constructor() { return second(); } 2461 HValue* constructor() { return second(); }
2502 2462
2503 DECLARE_CONCRETE_INSTRUCTION(CallNew) 2463 DECLARE_CONCRETE_INSTRUCTION(CallNew)
2504 2464
2505 private: 2465 private:
2506 HCallNew(HValue* context, HValue* constructor, int argument_count) 2466 HCallNew(HValue* context, HValue* constructor, int argument_count)
2507 : HBinaryCall(context, constructor, argument_count) {} 2467 : HBinaryCall(context, constructor, argument_count) {}
2508 }; 2468 };
2509 2469
2510 2470
2511 class HCallNewArray V8_FINAL : public HBinaryCall { 2471 class HCallNewArray V8_FINAL : public HBinaryCall {
2512 public: 2472 public:
2513 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HCallNewArray, 2473 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HCallNewArray,
2514 HValue*, 2474 HValue*,
2515 int, 2475 int,
2516 Handle<Cell>,
2517 ElementsKind); 2476 ElementsKind);
2518 2477
2519 HValue* context() { return first(); } 2478 HValue* context() { return first(); }
2520 HValue* constructor() { return second(); } 2479 HValue* constructor() { return second(); }
2521 2480
2522 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 2481 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2523 2482
2524 Handle<Cell> property_cell() const {
2525 return type_cell_;
2526 }
2527
2528 ElementsKind elements_kind() const { return elements_kind_; } 2483 ElementsKind elements_kind() const { return elements_kind_; }
2529 2484
2530 DECLARE_CONCRETE_INSTRUCTION(CallNewArray) 2485 DECLARE_CONCRETE_INSTRUCTION(CallNewArray)
2531 2486
2532 private: 2487 private:
2533 HCallNewArray(HValue* context, HValue* constructor, int argument_count, 2488 HCallNewArray(HValue* context, HValue* constructor, int argument_count,
2534 Handle<Cell> type_cell, ElementsKind elements_kind) 2489 ElementsKind elements_kind)
2535 : HBinaryCall(context, constructor, argument_count), 2490 : HBinaryCall(context, constructor, argument_count),
2536 elements_kind_(elements_kind), 2491 elements_kind_(elements_kind) {}
2537 type_cell_(type_cell) {}
2538 2492
2539 ElementsKind elements_kind_; 2493 ElementsKind elements_kind_;
2540 Handle<Cell> type_cell_;
2541 }; 2494 };
2542 2495
2543 2496
2544 class HCallRuntime V8_FINAL : public HCall<1> { 2497 class HCallRuntime V8_FINAL : public HCall<1> {
2545 public: 2498 public:
2546 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HCallRuntime, 2499 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HCallRuntime,
2547 Handle<String>, 2500 Handle<String>,
2548 const Runtime::Function*, 2501 const Runtime::Function*,
2549 int); 2502 int);
2550 2503
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2591 DECLARE_CONCRETE_INSTRUCTION(MapEnumLength) 2544 DECLARE_CONCRETE_INSTRUCTION(MapEnumLength)
2592 2545
2593 protected: 2546 protected:
2594 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } 2547 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
2595 2548
2596 private: 2549 private:
2597 explicit HMapEnumLength(HValue* value) 2550 explicit HMapEnumLength(HValue* value)
2598 : HUnaryOperation(value, HType::Smi()) { 2551 : HUnaryOperation(value, HType::Smi()) {
2599 set_representation(Representation::Smi()); 2552 set_representation(Representation::Smi());
2600 SetFlag(kUseGVN); 2553 SetFlag(kUseGVN);
2601 SetGVNFlag(kDependsOnMaps); 2554 SetDependsOnFlag(kMaps);
2602 } 2555 }
2603 2556
2604 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 2557 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
2605 }; 2558 };
2606 2559
2607 2560
2608 class HElementsKind V8_FINAL : public HUnaryOperation {
2609 public:
2610 explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
2611 set_representation(Representation::Integer32());
2612 SetFlag(kUseGVN);
2613 SetGVNFlag(kDependsOnElementsKind);
2614 }
2615
2616 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
2617 return Representation::Tagged();
2618 }
2619
2620 DECLARE_CONCRETE_INSTRUCTION(ElementsKind)
2621
2622 protected:
2623 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
2624
2625 private:
2626 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
2627 };
2628
2629
2630 class HUnaryMathOperation V8_FINAL : public HTemplateInstruction<2> { 2561 class HUnaryMathOperation V8_FINAL : public HTemplateInstruction<2> {
2631 public: 2562 public:
2632 static HInstruction* New(Zone* zone, 2563 static HInstruction* New(Zone* zone,
2633 HValue* context, 2564 HValue* context,
2634 HValue* value, 2565 HValue* value,
2635 BuiltinFunctionId op); 2566 BuiltinFunctionId op);
2636 2567
2637 HValue* context() { return OperandAt(0); } 2568 HValue* context() { return OperandAt(0); }
2638 HValue* value() { return OperandAt(1); } 2569 HValue* value() { return OperandAt(1); }
2639 2570
2640 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 2571 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2641 2572
2642 virtual HValue* EnsureAndPropagateNotMinusZero( 2573 virtual HValue* EnsureAndPropagateNotMinusZero(
2643 BitVector* visited) V8_OVERRIDE; 2574 BitVector* visited) V8_OVERRIDE;
2644 2575
2645 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 2576 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
2646 if (index == 0) { 2577 if (index == 0) {
2647 return Representation::Tagged(); 2578 return Representation::Tagged();
2648 } else { 2579 } else {
2649 switch (op_) { 2580 switch (op_) {
2650 case kMathFloor: 2581 case kMathFloor:
2651 case kMathRound: 2582 case kMathRound:
2652 case kMathSqrt: 2583 case kMathSqrt:
2653 case kMathPowHalf: 2584 case kMathPowHalf:
2654 case kMathLog: 2585 case kMathLog:
2655 case kMathExp: 2586 case kMathExp:
2656 return Representation::Double(); 2587 return Representation::Double();
2657 case kMathAbs: 2588 case kMathAbs:
2658 return representation(); 2589 return representation();
2590 case kMathClz32:
2591 return Representation::Integer32();
2659 default: 2592 default:
2660 UNREACHABLE(); 2593 UNREACHABLE();
2661 return Representation::None(); 2594 return Representation::None();
2662 } 2595 }
2663 } 2596 }
2664 } 2597 }
2665 2598
2666 virtual Range* InferRange(Zone* zone) V8_OVERRIDE; 2599 virtual Range* InferRange(Zone* zone) V8_OVERRIDE;
2667 2600
2668 virtual HValue* Canonicalize() V8_OVERRIDE; 2601 virtual HValue* Canonicalize() V8_OVERRIDE;
(...skipping 11 matching lines...) Expand all
2680 } 2613 }
2681 2614
2682 private: 2615 private:
2683 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op) 2616 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
2684 : HTemplateInstruction<2>(HType::TaggedNumber()), op_(op) { 2617 : HTemplateInstruction<2>(HType::TaggedNumber()), op_(op) {
2685 SetOperandAt(0, context); 2618 SetOperandAt(0, context);
2686 SetOperandAt(1, value); 2619 SetOperandAt(1, value);
2687 switch (op) { 2620 switch (op) {
2688 case kMathFloor: 2621 case kMathFloor:
2689 case kMathRound: 2622 case kMathRound:
2623 case kMathClz32:
2690 set_representation(Representation::Integer32()); 2624 set_representation(Representation::Integer32());
2691 break; 2625 break;
2692 case kMathAbs: 2626 case kMathAbs:
2693 // Not setting representation here: it is None intentionally. 2627 // Not setting representation here: it is None intentionally.
2694 SetFlag(kFlexibleRepresentation); 2628 SetFlag(kFlexibleRepresentation);
2695 // TODO(svenpanne) This flag is actually only needed if representation() 2629 // TODO(svenpanne) This flag is actually only needed if representation()
2696 // is tagged, and not when it is an unboxed double or unboxed integer. 2630 // is tagged, and not when it is an unboxed double or unboxed integer.
2697 SetGVNFlag(kChangesNewSpacePromotion); 2631 SetChangesFlag(kNewSpacePromotion);
2698 break; 2632 break;
2699 case kMathLog: 2633 case kMathLog:
2700 case kMathExp: 2634 case kMathExp:
2701 case kMathSqrt: 2635 case kMathSqrt:
2702 case kMathPowHalf: 2636 case kMathPowHalf:
2703 set_representation(Representation::Double()); 2637 set_representation(Representation::Double());
2704 break; 2638 break;
2705 default: 2639 default:
2706 UNREACHABLE(); 2640 UNREACHABLE();
2707 } 2641 }
2708 SetFlag(kUseGVN); 2642 SetFlag(kUseGVN);
2709 SetFlag(kAllowUndefinedAsNaN); 2643 SetFlag(kAllowUndefinedAsNaN);
2710 } 2644 }
2711 2645
2712 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 2646 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
2713 2647
2648 HValue* SimplifiedDividendForMathFloorOfDiv(HDiv* hdiv);
2649 HValue* SimplifiedDivisorForMathFloorOfDiv(HDiv* hdiv);
2650
2714 BuiltinFunctionId op_; 2651 BuiltinFunctionId op_;
2715 }; 2652 };
2716 2653
2717 2654
2718 class HLoadRoot V8_FINAL : public HTemplateInstruction<0> { 2655 class HLoadRoot V8_FINAL : public HTemplateInstruction<0> {
2719 public: 2656 public:
2720 DECLARE_INSTRUCTION_FACTORY_P1(HLoadRoot, Heap::RootListIndex); 2657 DECLARE_INSTRUCTION_FACTORY_P1(HLoadRoot, Heap::RootListIndex);
2721 DECLARE_INSTRUCTION_FACTORY_P2(HLoadRoot, Heap::RootListIndex, HType); 2658 DECLARE_INSTRUCTION_FACTORY_P2(HLoadRoot, Heap::RootListIndex, HType);
2722 2659
2723 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 2660 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
2724 return Representation::None(); 2661 return Representation::None();
2725 } 2662 }
2726 2663
2727 Heap::RootListIndex index() const { return index_; } 2664 Heap::RootListIndex index() const { return index_; }
2728 2665
2729 DECLARE_CONCRETE_INSTRUCTION(LoadRoot) 2666 DECLARE_CONCRETE_INSTRUCTION(LoadRoot)
2730 2667
2731 protected: 2668 protected:
2732 virtual bool DataEquals(HValue* other) V8_OVERRIDE { 2669 virtual bool DataEquals(HValue* other) V8_OVERRIDE {
2733 HLoadRoot* b = HLoadRoot::cast(other); 2670 HLoadRoot* b = HLoadRoot::cast(other);
2734 return index_ == b->index_; 2671 return index_ == b->index_;
2735 } 2672 }
2736 2673
2737 private: 2674 private:
2738 HLoadRoot(Heap::RootListIndex index, HType type = HType::Tagged()) 2675 HLoadRoot(Heap::RootListIndex index, HType type = HType::Tagged())
2739 : HTemplateInstruction<0>(type), index_(index) { 2676 : HTemplateInstruction<0>(type), index_(index) {
2740 SetFlag(kUseGVN); 2677 SetFlag(kUseGVN);
2741 // TODO(bmeurer): We'll need kDependsOnRoots once we add the 2678 // TODO(bmeurer): We'll need kDependsOnRoots once we add the
2742 // corresponding HStoreRoot instruction. 2679 // corresponding HStoreRoot instruction.
2743 SetGVNFlag(kDependsOnCalls); 2680 SetDependsOnFlag(kCalls);
2744 } 2681 }
2745 2682
2746 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 2683 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
2747 2684
2748 const Heap::RootListIndex index_; 2685 const Heap::RootListIndex index_;
2749 }; 2686 };
2750 2687
2751 2688
2752 class HLoadExternalArrayPointer V8_FINAL : public HUnaryOperation {
2753 public:
2754 DECLARE_INSTRUCTION_FACTORY_P1(HLoadExternalArrayPointer, HValue*);
2755
2756 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
2757 return Representation::Tagged();
2758 }
2759
2760 virtual HType CalculateInferredType() V8_OVERRIDE {
2761 return HType::None();
2762 }
2763
2764 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
2765
2766 protected:
2767 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
2768
2769 private:
2770 explicit HLoadExternalArrayPointer(HValue* value)
2771 : HUnaryOperation(value) {
2772 set_representation(Representation::External());
2773 // The result of this instruction is idempotent as long as its inputs don't
2774 // change. The external array of a specialized array elements object cannot
2775 // change once set, so it's no necessary to introduce any additional
2776 // dependencies on top of the inputs.
2777 SetFlag(kUseGVN);
2778 }
2779
2780 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
2781 };
2782
2783
2784 class HCheckMaps V8_FINAL : public HTemplateInstruction<2> { 2689 class HCheckMaps V8_FINAL : public HTemplateInstruction<2> {
2785 public: 2690 public:
2786 static HCheckMaps* New(Zone* zone, HValue* context, HValue* value, 2691 static HCheckMaps* New(Zone* zone, HValue* context, HValue* value,
2787 Handle<Map> map, CompilationInfo* info, 2692 Handle<Map> map, CompilationInfo* info,
2788 HValue *typecheck = NULL); 2693 HValue* typecheck = NULL);
2789 static HCheckMaps* New(Zone* zone, HValue* context, 2694 static HCheckMaps* New(Zone* zone, HValue* context,
2790 HValue* value, SmallMapList* maps, 2695 HValue* value, SmallMapList* maps,
2791 HValue *typecheck = NULL) { 2696 HValue* typecheck = NULL) {
2792 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck); 2697 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck);
2793 for (int i = 0; i < maps->length(); i++) { 2698 for (int i = 0; i < maps->length(); i++) {
2794 check_map->Add(maps->at(i), zone); 2699 check_map->Add(maps->at(i), zone);
2795 } 2700 }
2796 return check_map; 2701 return check_map;
2797 } 2702 }
2798 2703
2799 bool CanOmitMapChecks() { return omit_; } 2704 bool CanOmitMapChecks() { return omit_; }
2800 2705
2801 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } 2706 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; }
2802 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 2707 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
2803 return Representation::Tagged(); 2708 return Representation::Tagged();
2804 } 2709 }
2805 virtual void HandleSideEffectDominator(GVNFlag side_effect, 2710 virtual bool HandleSideEffectDominator(GVNFlag side_effect,
2806 HValue* dominator) V8_OVERRIDE; 2711 HValue* dominator) V8_OVERRIDE;
2807 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 2712 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2808 2713
2809 HValue* value() { return OperandAt(0); } 2714 HValue* value() { return OperandAt(0); }
2715 HValue* typecheck() { return OperandAt(1); }
2810 2716
2811 Unique<Map> first_map() const { return map_set_.at(0); } 2717 Unique<Map> first_map() const { return map_set_.at(0); }
2812 UniqueSet<Map> map_set() const { return map_set_; } 2718 UniqueSet<Map> map_set() const { return map_set_; }
2813 2719
2720 void set_map_set(UniqueSet<Map>* maps, Zone *zone) {
2721 map_set_.Clear();
2722 for (int i = 0; i < maps->size(); i++) {
2723 map_set_.Add(maps->at(i), zone);
2724 }
2725 }
2726
2814 bool has_migration_target() const { 2727 bool has_migration_target() const {
2815 return has_migration_target_; 2728 return has_migration_target_;
2816 } 2729 }
2817 2730
2818 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) 2731 DECLARE_CONCRETE_INSTRUCTION(CheckMaps)
2819 2732
2820 protected: 2733 protected:
2821 virtual bool DataEquals(HValue* other) V8_OVERRIDE { 2734 virtual bool DataEquals(HValue* other) V8_OVERRIDE {
2822 return this->map_set_.Equals(&HCheckMaps::cast(other)->map_set_); 2735 return this->map_set_.Equals(&HCheckMaps::cast(other)->map_set_);
2823 } 2736 }
2824 2737
2825 virtual int RedefinedOperandIndex() { return 0; } 2738 virtual int RedefinedOperandIndex() { return 0; }
2826 2739
2827 private: 2740 private:
2828 void Add(Handle<Map> map, Zone* zone) { 2741 void Add(Handle<Map> map, Zone* zone) {
2829 map_set_.Add(Unique<Map>(map), zone); 2742 map_set_.Add(Unique<Map>(map), zone);
2743 SetDependsOnFlag(kMaps);
2744 SetDependsOnFlag(kElementsKind);
2745
2830 if (!has_migration_target_ && map->is_migration_target()) { 2746 if (!has_migration_target_ && map->is_migration_target()) {
2831 has_migration_target_ = true; 2747 has_migration_target_ = true;
2832 SetGVNFlag(kChangesNewSpacePromotion); 2748 SetChangesFlag(kNewSpacePromotion);
2833 } 2749 }
2834 } 2750 }
2835 2751
2836 // Clients should use one of the static New* methods above. 2752 // Clients should use one of the static New* methods above.
2837 HCheckMaps(HValue* value, Zone *zone, HValue* typecheck) 2753 HCheckMaps(HValue* value, Zone *zone, HValue* typecheck)
2838 : HTemplateInstruction<2>(value->type()), 2754 : HTemplateInstruction<2>(value->type()),
2839 omit_(false), has_migration_target_(false) { 2755 omit_(false), has_migration_target_(false) {
2840 SetOperandAt(0, value); 2756 SetOperandAt(0, value);
2841 // Use the object value for the dependency if NULL is passed. 2757 // Use the object value for the dependency if NULL is passed.
2842 SetOperandAt(1, typecheck != NULL ? typecheck : value); 2758 SetOperandAt(1, typecheck != NULL ? typecheck : value);
2843 set_representation(Representation::Tagged()); 2759 set_representation(Representation::Tagged());
2844 SetFlag(kUseGVN); 2760 SetFlag(kUseGVN);
2845 SetFlag(kTrackSideEffectDominators); 2761 SetFlag(kTrackSideEffectDominators);
2846 SetGVNFlag(kDependsOnMaps);
2847 SetGVNFlag(kDependsOnElementsKind);
2848 } 2762 }
2849 2763
2850 bool omit_; 2764 bool omit_;
2851 bool has_migration_target_; 2765 bool has_migration_target_;
2852 UniqueSet<Map> map_set_; 2766 UniqueSet<Map> map_set_;
2853 }; 2767 };
2854 2768
2855 2769
2856 class HCheckValue V8_FINAL : public HUnaryOperation { 2770 class HCheckValue V8_FINAL : public HUnaryOperation {
2857 public: 2771 public:
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
3276 virtual HValue* OperandAt(int index) const V8_OVERRIDE { 3190 virtual HValue* OperandAt(int index) const V8_OVERRIDE {
3277 return inputs_[index]; 3191 return inputs_[index];
3278 } 3192 }
3279 HValue* GetRedundantReplacement(); 3193 HValue* GetRedundantReplacement();
3280 void AddInput(HValue* value); 3194 void AddInput(HValue* value);
3281 bool HasRealUses(); 3195 bool HasRealUses();
3282 3196
3283 bool IsReceiver() const { return merged_index_ == 0; } 3197 bool IsReceiver() const { return merged_index_ == 0; }
3284 bool HasMergedIndex() const { return merged_index_ != kInvalidMergedIndex; } 3198 bool HasMergedIndex() const { return merged_index_ != kInvalidMergedIndex; }
3285 3199
3286 virtual int position() const V8_OVERRIDE; 3200 virtual HSourcePosition position() const V8_OVERRIDE;
3287 3201
3288 int merged_index() const { return merged_index_; } 3202 int merged_index() const { return merged_index_; }
3289 3203
3290 InductionVariableData* induction_variable_data() { 3204 InductionVariableData* induction_variable_data() {
3291 return induction_variable_data_; 3205 return induction_variable_data_;
3292 } 3206 }
3293 bool IsInductionVariable() { 3207 bool IsInductionVariable() {
3294 return induction_variable_data_ != NULL; 3208 return induction_variable_data_ != NULL;
3295 } 3209 }
3296 bool IsLimitedInductionVariable() { 3210 bool IsLimitedInductionVariable() {
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
3441 const ZoneList<HValue*>* values() const { return &values_; } 3355 const ZoneList<HValue*>* values() const { return &values_; }
3442 int length() const { return values_.length(); } 3356 int length() const { return values_.length(); }
3443 int capture_id() const { return capture_id_; } 3357 int capture_id() const { return capture_id_; }
3444 3358
3445 // Shortcut for the map value of this captured object. 3359 // Shortcut for the map value of this captured object.
3446 HValue* map_value() const { return values()->first(); } 3360 HValue* map_value() const { return values()->first(); }
3447 3361
3448 void ReuseSideEffectsFromStore(HInstruction* store) { 3362 void ReuseSideEffectsFromStore(HInstruction* store) {
3449 ASSERT(store->HasObservableSideEffects()); 3363 ASSERT(store->HasObservableSideEffects());
3450 ASSERT(store->IsStoreNamedField()); 3364 ASSERT(store->IsStoreNamedField());
3451 gvn_flags_.Add(store->gvn_flags()); 3365 changes_flags_.Add(store->ChangesFlags());
3452 } 3366 }
3453 3367
3454 // Replay effects of this instruction on the given environment. 3368 // Replay effects of this instruction on the given environment.
3455 void ReplayEnvironment(HEnvironment* env); 3369 void ReplayEnvironment(HEnvironment* env);
3456 3370
3457 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 3371 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
3458 3372
3459 DECLARE_CONCRETE_INSTRUCTION(CapturedObject) 3373 DECLARE_CONCRETE_INSTRUCTION(CapturedObject)
3460 3374
3461 private: 3375 private:
(...skipping 12 matching lines...) Expand all
3474 DECLARE_INSTRUCTION_FACTORY_P2(HConstant, int32_t, Representation); 3388 DECLARE_INSTRUCTION_FACTORY_P2(HConstant, int32_t, Representation);
3475 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, double); 3389 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, double);
3476 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, Handle<Object>); 3390 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, Handle<Object>);
3477 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, ExternalReference); 3391 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, ExternalReference);
3478 3392
3479 static HConstant* CreateAndInsertAfter(Zone* zone, 3393 static HConstant* CreateAndInsertAfter(Zone* zone,
3480 HValue* context, 3394 HValue* context,
3481 int32_t value, 3395 int32_t value,
3482 Representation representation, 3396 Representation representation,
3483 HInstruction* instruction) { 3397 HInstruction* instruction) {
3484 HConstant* new_constant = 3398 return instruction->Append(HConstant::New(
3485 HConstant::New(zone, context, value, representation); 3399 zone, context, value, representation));
3486 new_constant->InsertAfter(instruction);
3487 return new_constant;
3488 } 3400 }
3489 3401
3490 static HConstant* CreateAndInsertBefore(Zone* zone, 3402 static HConstant* CreateAndInsertBefore(Zone* zone,
3491 HValue* context, 3403 HValue* context,
3492 int32_t value, 3404 int32_t value,
3493 Representation representation, 3405 Representation representation,
3494 HInstruction* instruction) { 3406 HInstruction* instruction) {
3495 HConstant* new_constant = 3407 return instruction->Prepend(HConstant::New(
3496 HConstant::New(zone, context, value, representation); 3408 zone, context, value, representation));
3497 new_constant->InsertBefore(instruction);
3498 return new_constant;
3499 } 3409 }
3500 3410
3501 static HConstant* CreateAndInsertBefore(Zone* zone, 3411 static HConstant* CreateAndInsertBefore(Zone* zone,
3502 Unique<Object> unique, 3412 Unique<Object> unique,
3503 bool is_not_in_new_space, 3413 bool is_not_in_new_space,
3504 HInstruction* instruction) { 3414 HInstruction* instruction) {
3505 HConstant* new_constant = new(zone) HConstant(unique, 3415 return instruction->Prepend(new(zone) HConstant(
3506 Representation::Tagged(), HType::Tagged(), false, is_not_in_new_space, 3416 unique, Representation::Tagged(), HType::Tagged(), false,
3507 false, false); 3417 is_not_in_new_space, false, false));
3508 new_constant->InsertBefore(instruction);
3509 return new_constant;
3510 } 3418 }
3511 3419
3512 Handle<Object> handle(Isolate* isolate) { 3420 Handle<Object> handle(Isolate* isolate) {
3513 if (object_.handle().is_null()) { 3421 if (object_.handle().is_null()) {
3514 // Default arguments to is_not_in_new_space depend on this heap number 3422 // Default arguments to is_not_in_new_space depend on this heap number
3515 // to be tenured so that it's guaranteed not to be located in new space. 3423 // to be tenured so that it's guaranteed not to be located in new space.
3516 object_ = Unique<Object>::CreateUninitialized( 3424 object_ = Unique<Object>::CreateUninitialized(
3517 isolate->factory()->NewNumber(double_value_, TENURED)); 3425 isolate->factory()->NewNumber(double_value_, TENURED));
3518 } 3426 }
3519 AllowDeferredHandleDereference smi_check; 3427 AllowDeferredHandleDereference smi_check;
(...skipping 11 matching lines...) Expand all
3531 return has_double_value_ && 3439 return has_double_value_ &&
3532 (BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) || 3440 (BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) ||
3533 FixedDoubleArray::is_the_hole_nan(double_value_) || 3441 FixedDoubleArray::is_the_hole_nan(double_value_) ||
3534 std::isnan(double_value_)); 3442 std::isnan(double_value_));
3535 } 3443 }
3536 3444
3537 bool NotInNewSpace() const { 3445 bool NotInNewSpace() const {
3538 return is_not_in_new_space_; 3446 return is_not_in_new_space_;
3539 } 3447 }
3540 3448
3541 bool ImmortalImmovable() const { 3449 bool ImmortalImmovable() const;
3542 if (has_int32_value_) {
3543 return false;
3544 }
3545 if (has_double_value_) {
3546 if (IsSpecialDouble()) {
3547 return true;
3548 }
3549 return false;
3550 }
3551 if (has_external_reference_value_) {
3552 return false;
3553 }
3554
3555 ASSERT(!object_.handle().is_null());
3556 Heap* heap = isolate()->heap();
3557 ASSERT(!object_.IsKnownGlobal(heap->minus_zero_value()));
3558 ASSERT(!object_.IsKnownGlobal(heap->nan_value()));
3559 return
3560 object_.IsKnownGlobal(heap->undefined_value()) ||
3561 object_.IsKnownGlobal(heap->null_value()) ||
3562 object_.IsKnownGlobal(heap->true_value()) ||
3563 object_.IsKnownGlobal(heap->false_value()) ||
3564 object_.IsKnownGlobal(heap->the_hole_value()) ||
3565 object_.IsKnownGlobal(heap->empty_string()) ||
3566 object_.IsKnownGlobal(heap->empty_fixed_array());
3567 }
3568 3450
3569 bool IsCell() const { 3451 bool IsCell() const {
3570 return is_cell_; 3452 return is_cell_;
3571 } 3453 }
3572 3454
3573 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 3455 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
3574 return Representation::None(); 3456 return Representation::None();
3575 } 3457 }
3576 3458
3577 virtual Representation KnownOptimalRepresentation() V8_OVERRIDE { 3459 virtual Representation KnownOptimalRepresentation() V8_OVERRIDE {
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
3813 3695
3814 virtual bool IsCommutative() const { return false; } 3696 virtual bool IsCommutative() const { return false; }
3815 3697
3816 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 3698 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
3817 3699
3818 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 3700 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
3819 if (index == 0) return Representation::Tagged(); 3701 if (index == 0) return Representation::Tagged();
3820 return representation(); 3702 return representation();
3821 } 3703 }
3822 3704
3823 void SetOperandPositions(Zone* zone, int left_pos, int right_pos) { 3705 void SetOperandPositions(Zone* zone,
3706 HSourcePosition left_pos,
3707 HSourcePosition right_pos) {
3824 set_operand_position(zone, 1, left_pos); 3708 set_operand_position(zone, 1, left_pos);
3825 set_operand_position(zone, 2, right_pos); 3709 set_operand_position(zone, 2, right_pos);
3826 } 3710 }
3827 3711
3828 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation) 3712 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation)
3829 3713
3830 private: 3714 private:
3831 bool IgnoreObservedOutputRepresentation(Representation current_rep); 3715 bool IgnoreObservedOutputRepresentation(Representation current_rep);
3832 3716
3833 Representation observed_input_representation_[2]; 3717 Representation observed_input_representation_[2];
3834 Representation observed_output_representation_; 3718 Representation observed_output_representation_;
3835 }; 3719 };
3836 3720
3837 3721
3838 class HWrapReceiver V8_FINAL : public HTemplateInstruction<2> { 3722 class HWrapReceiver V8_FINAL : public HTemplateInstruction<2> {
3839 public: 3723 public:
3840 DECLARE_INSTRUCTION_FACTORY_P2(HWrapReceiver, HValue*, HValue*); 3724 DECLARE_INSTRUCTION_FACTORY_P2(HWrapReceiver, HValue*, HValue*);
3841 3725
3726 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
3727
3842 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 3728 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
3843 return Representation::Tagged(); 3729 return Representation::Tagged();
3844 } 3730 }
3845 3731
3846 HValue* receiver() { return OperandAt(0); } 3732 HValue* receiver() { return OperandAt(0); }
3847 HValue* function() { return OperandAt(1); } 3733 HValue* function() { return OperandAt(1); }
3848 3734
3849 virtual HValue* Canonicalize() V8_OVERRIDE; 3735 virtual HValue* Canonicalize() V8_OVERRIDE;
3850 3736
3851 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 3737 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
3738 bool known_function() const { return known_function_; }
3852 3739
3853 DECLARE_CONCRETE_INSTRUCTION(WrapReceiver) 3740 DECLARE_CONCRETE_INSTRUCTION(WrapReceiver)
3854 3741
3855 private: 3742 private:
3856 HWrapReceiver(HValue* receiver, HValue* function) { 3743 HWrapReceiver(HValue* receiver, HValue* function) {
3744 known_function_ = function->IsConstant() &&
3745 HConstant::cast(function)->handle(function->isolate())->IsJSFunction();
3857 set_representation(Representation::Tagged()); 3746 set_representation(Representation::Tagged());
3858 SetOperandAt(0, receiver); 3747 SetOperandAt(0, receiver);
3859 SetOperandAt(1, function); 3748 SetOperandAt(1, function);
3749 SetFlag(kUseGVN);
3860 } 3750 }
3751
3752 bool known_function_;
3861 }; 3753 };
3862 3754
3863 3755
3864 class HApplyArguments V8_FINAL : public HTemplateInstruction<4> { 3756 class HApplyArguments V8_FINAL : public HTemplateInstruction<4> {
3865 public: 3757 public:
3866 DECLARE_INSTRUCTION_FACTORY_P4(HApplyArguments, HValue*, HValue*, HValue*, 3758 DECLARE_INSTRUCTION_FACTORY_P4(HApplyArguments, HValue*, HValue*, HValue*,
3867 HValue*); 3759 HValue*);
3868 3760
3869 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 3761 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
3870 // The length is untagged, all other inputs are tagged. 3762 // The length is untagged, all other inputs are tagged.
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
4098 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right, 3990 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right,
4099 HType type = HType::Tagged()) 3991 HType type = HType::Tagged())
4100 : HBinaryOperation(context, left, right, type) { 3992 : HBinaryOperation(context, left, right, type) {
4101 SetFlag(kFlexibleRepresentation); 3993 SetFlag(kFlexibleRepresentation);
4102 SetFlag(kTruncatingToInt32); 3994 SetFlag(kTruncatingToInt32);
4103 SetFlag(kAllowUndefinedAsNaN); 3995 SetFlag(kAllowUndefinedAsNaN);
4104 SetAllSideEffects(); 3996 SetAllSideEffects();
4105 } 3997 }
4106 3998
4107 virtual void RepresentationChanged(Representation to) V8_OVERRIDE { 3999 virtual void RepresentationChanged(Representation to) V8_OVERRIDE {
4108 if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion); 4000 if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion);
4109 if (to.IsTagged() && 4001 if (to.IsTagged() &&
4110 (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) { 4002 (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) {
4111 SetAllSideEffects(); 4003 SetAllSideEffects();
4112 ClearFlag(kUseGVN); 4004 ClearFlag(kUseGVN);
4113 } else { 4005 } else {
4114 ClearAllSideEffects(); 4006 ClearAllSideEffects();
4115 SetFlag(kUseGVN); 4007 SetFlag(kUseGVN);
4116 } 4008 }
4117 } 4009 }
4118 4010
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
4175 class HArithmeticBinaryOperation : public HBinaryOperation { 4067 class HArithmeticBinaryOperation : public HBinaryOperation {
4176 public: 4068 public:
4177 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right) 4069 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right)
4178 : HBinaryOperation(context, left, right, HType::TaggedNumber()) { 4070 : HBinaryOperation(context, left, right, HType::TaggedNumber()) {
4179 SetAllSideEffects(); 4071 SetAllSideEffects();
4180 SetFlag(kFlexibleRepresentation); 4072 SetFlag(kFlexibleRepresentation);
4181 SetFlag(kAllowUndefinedAsNaN); 4073 SetFlag(kAllowUndefinedAsNaN);
4182 } 4074 }
4183 4075
4184 virtual void RepresentationChanged(Representation to) V8_OVERRIDE { 4076 virtual void RepresentationChanged(Representation to) V8_OVERRIDE {
4185 if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion); 4077 if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion);
4186 if (to.IsTagged() && 4078 if (to.IsTagged() &&
4187 (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) { 4079 (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) {
4188 SetAllSideEffects(); 4080 SetAllSideEffects();
4189 ClearFlag(kUseGVN); 4081 ClearFlag(kUseGVN);
4190 } else { 4082 } else {
4191 ClearAllSideEffects(); 4083 ClearAllSideEffects();
4192 SetFlag(kUseGVN); 4084 SetFlag(kUseGVN);
4193 } 4085 }
4194 } 4086 }
4195 4087
4088 bool RightIsPowerOf2() {
4089 if (!right()->IsInteger32Constant()) return false;
4090 int32_t value = right()->GetInteger32Constant();
4091 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
4092 }
4093
4196 DECLARE_ABSTRACT_INSTRUCTION(ArithmeticBinaryOperation) 4094 DECLARE_ABSTRACT_INSTRUCTION(ArithmeticBinaryOperation)
4095
4197 private: 4096 private:
4198 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 4097 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
4199 }; 4098 };
4200 4099
4201 4100
4202 class HCompareGeneric V8_FINAL : public HBinaryOperation { 4101 class HCompareGeneric V8_FINAL : public HBinaryOperation {
4203 public: 4102 public:
4204 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HCompareGeneric, HValue*, 4103 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HCompareGeneric, HValue*,
4205 HValue*, Token::Value); 4104 HValue*, Token::Value);
4206 4105
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
4253 HInferRepresentationPhase* h_infer) V8_OVERRIDE; 4152 HInferRepresentationPhase* h_infer) V8_OVERRIDE;
4254 4153
4255 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 4154 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
4256 return representation(); 4155 return representation();
4257 } 4156 }
4258 virtual Representation observed_input_representation(int index) V8_OVERRIDE { 4157 virtual Representation observed_input_representation(int index) V8_OVERRIDE {
4259 return observed_input_representation_[index]; 4158 return observed_input_representation_[index];
4260 } 4159 }
4261 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 4160 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
4262 4161
4263 void SetOperandPositions(Zone* zone, int left_pos, int right_pos) { 4162 void SetOperandPositions(Zone* zone,
4163 HSourcePosition left_pos,
4164 HSourcePosition right_pos) {
4264 set_operand_position(zone, 0, left_pos); 4165 set_operand_position(zone, 0, left_pos);
4265 set_operand_position(zone, 1, right_pos); 4166 set_operand_position(zone, 1, right_pos);
4266 } 4167 }
4267 4168
4268 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch) 4169 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch)
4269 4170
4270 private: 4171 private:
4271 HCompareNumericAndBranch(HValue* left, 4172 HCompareNumericAndBranch(HValue* left,
4272 HValue* right, 4173 HValue* right,
4273 Token::Value token, 4174 Token::Value token,
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
4403 DECLARE_INSTRUCTION_FACTORY_P1(HIsStringAndBranch, HValue*); 4304 DECLARE_INSTRUCTION_FACTORY_P1(HIsStringAndBranch, HValue*);
4404 DECLARE_INSTRUCTION_FACTORY_P3(HIsStringAndBranch, HValue*, 4305 DECLARE_INSTRUCTION_FACTORY_P3(HIsStringAndBranch, HValue*,
4405 HBasicBlock*, HBasicBlock*); 4306 HBasicBlock*, HBasicBlock*);
4406 4307
4407 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 4308 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
4408 return Representation::Tagged(); 4309 return Representation::Tagged();
4409 } 4310 }
4410 4311
4411 DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch) 4312 DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch)
4412 4313
4314 protected:
4315 virtual int RedefinedOperandIndex() { return 0; }
4316
4413 private: 4317 private:
4414 HIsStringAndBranch(HValue* value, 4318 HIsStringAndBranch(HValue* value,
4415 HBasicBlock* true_target = NULL, 4319 HBasicBlock* true_target = NULL,
4416 HBasicBlock* false_target = NULL) 4320 HBasicBlock* false_target = NULL)
4417 : HUnaryControlInstruction(value, true_target, false_target) {} 4321 : HUnaryControlInstruction(value, true_target, false_target) {}
4418 }; 4322 };
4419 4323
4420 4324
4421 class HIsSmiAndBranch V8_FINAL : public HUnaryControlInstruction { 4325 class HIsSmiAndBranch V8_FINAL : public HUnaryControlInstruction {
4422 public: 4326 public:
4423 DECLARE_INSTRUCTION_FACTORY_P1(HIsSmiAndBranch, HValue*); 4327 DECLARE_INSTRUCTION_FACTORY_P1(HIsSmiAndBranch, HValue*);
4424 DECLARE_INSTRUCTION_FACTORY_P3(HIsSmiAndBranch, HValue*, 4328 DECLARE_INSTRUCTION_FACTORY_P3(HIsSmiAndBranch, HValue*,
4425 HBasicBlock*, HBasicBlock*); 4329 HBasicBlock*, HBasicBlock*);
4426 4330
4427 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch) 4331 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
4428 4332
4429 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 4333 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
4430 return Representation::Tagged(); 4334 return Representation::Tagged();
4431 } 4335 }
4432 4336
4433 protected: 4337 protected:
4434 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } 4338 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
4339 virtual int RedefinedOperandIndex() { return 0; }
4435 4340
4436 private: 4341 private:
4437 HIsSmiAndBranch(HValue* value, 4342 HIsSmiAndBranch(HValue* value,
4438 HBasicBlock* true_target = NULL, 4343 HBasicBlock* true_target = NULL,
4439 HBasicBlock* false_target = NULL) 4344 HBasicBlock* false_target = NULL)
4440 : HUnaryControlInstruction(value, true_target, false_target) {} 4345 : HUnaryControlInstruction(value, true_target, false_target) {}
4441 }; 4346 };
4442 4347
4443 4348
4444 class HIsUndetectableAndBranch V8_FINAL : public HUnaryControlInstruction { 4349 class HIsUndetectableAndBranch V8_FINAL : public HUnaryControlInstruction {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
4489 HStringCompareAndBranch(HValue* context, 4394 HStringCompareAndBranch(HValue* context,
4490 HValue* left, 4395 HValue* left,
4491 HValue* right, 4396 HValue* right,
4492 Token::Value token) 4397 Token::Value token)
4493 : token_(token) { 4398 : token_(token) {
4494 ASSERT(Token::IsCompareOp(token)); 4399 ASSERT(Token::IsCompareOp(token));
4495 SetOperandAt(0, context); 4400 SetOperandAt(0, context);
4496 SetOperandAt(1, left); 4401 SetOperandAt(1, left);
4497 SetOperandAt(2, right); 4402 SetOperandAt(2, right);
4498 set_representation(Representation::Tagged()); 4403 set_representation(Representation::Tagged());
4499 SetGVNFlag(kChangesNewSpacePromotion); 4404 SetChangesFlag(kNewSpacePromotion);
4500 } 4405 }
4501 4406
4502 Token::Value token_; 4407 Token::Value token_;
4503 }; 4408 };
4504 4409
4505 4410
4506 class HIsConstructCallAndBranch : public HTemplateControlInstruction<2, 0> { 4411 class HIsConstructCallAndBranch : public HTemplateControlInstruction<2, 0> {
4507 public: 4412 public:
4508 DECLARE_INSTRUCTION_FACTORY_P0(HIsConstructCallAndBranch); 4413 DECLARE_INSTRUCTION_FACTORY_P0(HIsConstructCallAndBranch);
4509 4414
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
4714 4619
4715 protected: 4620 protected:
4716 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } 4621 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
4717 4622
4718 private: 4623 private:
4719 HPower(HValue* left, HValue* right) { 4624 HPower(HValue* left, HValue* right) {
4720 SetOperandAt(0, left); 4625 SetOperandAt(0, left);
4721 SetOperandAt(1, right); 4626 SetOperandAt(1, right);
4722 set_representation(Representation::Double()); 4627 set_representation(Representation::Double());
4723 SetFlag(kUseGVN); 4628 SetFlag(kUseGVN);
4724 SetGVNFlag(kChangesNewSpacePromotion); 4629 SetChangesFlag(kNewSpacePromotion);
4725 } 4630 }
4726 4631
4727 virtual bool IsDeletable() const V8_OVERRIDE { 4632 virtual bool IsDeletable() const V8_OVERRIDE {
4728 return !right()->representation().IsTagged(); 4633 return !right()->representation().IsTagged();
4729 } 4634 }
4730 }; 4635 };
4731 4636
4732 4637
4733 class HAdd V8_FINAL : public HArithmeticBinaryOperation { 4638 class HAdd V8_FINAL : public HArithmeticBinaryOperation {
4734 public: 4639 public:
(...skipping 21 matching lines...) Expand all
4756 } else if (right()->IsInteger32Constant()) { 4661 } else if (right()->IsInteger32Constant()) {
4757 decomposition->Apply(left(), right()->GetInteger32Constant()); 4662 decomposition->Apply(left(), right()->GetInteger32Constant());
4758 return true; 4663 return true;
4759 } else { 4664 } else {
4760 return false; 4665 return false;
4761 } 4666 }
4762 } 4667 }
4763 4668
4764 virtual void RepresentationChanged(Representation to) V8_OVERRIDE { 4669 virtual void RepresentationChanged(Representation to) V8_OVERRIDE {
4765 if (to.IsTagged()) { 4670 if (to.IsTagged()) {
4766 SetGVNFlag(kChangesNewSpacePromotion); 4671 SetChangesFlag(kNewSpacePromotion);
4767 ClearFlag(kAllowUndefinedAsNaN); 4672 ClearFlag(kAllowUndefinedAsNaN);
4768 } 4673 }
4769 if (to.IsTagged() && 4674 if (to.IsTagged() &&
4770 (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved() || 4675 (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved() ||
4771 left()->ToStringCanBeObserved() || right()->ToStringCanBeObserved())) { 4676 left()->ToStringCanBeObserved() || right()->ToStringCanBeObserved())) {
4772 SetAllSideEffects(); 4677 SetAllSideEffects();
4773 ClearFlag(kUseGVN); 4678 ClearFlag(kUseGVN);
4774 } else { 4679 } else {
4775 ClearAllSideEffects(); 4680 ClearAllSideEffects();
4776 SetFlag(kUseGVN); 4681 SetFlag(kUseGVN);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
4885 }; 4790 };
4886 4791
4887 4792
4888 class HMod V8_FINAL : public HArithmeticBinaryOperation { 4793 class HMod V8_FINAL : public HArithmeticBinaryOperation {
4889 public: 4794 public:
4890 static HInstruction* New(Zone* zone, 4795 static HInstruction* New(Zone* zone,
4891 HValue* context, 4796 HValue* context,
4892 HValue* left, 4797 HValue* left,
4893 HValue* right); 4798 HValue* right);
4894 4799
4895 bool HasPowerOf2Divisor() {
4896 if (right()->IsConstant() &&
4897 HConstant::cast(right())->HasInteger32Value()) {
4898 int32_t value = HConstant::cast(right())->Integer32Value();
4899 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
4900 }
4901
4902 return false;
4903 }
4904
4905 virtual HValue* EnsureAndPropagateNotMinusZero( 4800 virtual HValue* EnsureAndPropagateNotMinusZero(
4906 BitVector* visited) V8_OVERRIDE; 4801 BitVector* visited) V8_OVERRIDE;
4907 4802
4908 virtual HValue* Canonicalize() V8_OVERRIDE; 4803 virtual HValue* Canonicalize() V8_OVERRIDE;
4909 4804
4910 virtual void UpdateRepresentation(Representation new_rep, 4805 virtual void UpdateRepresentation(Representation new_rep,
4911 HInferRepresentationPhase* h_infer, 4806 HInferRepresentationPhase* h_infer,
4912 const char* reason) V8_OVERRIDE { 4807 const char* reason) V8_OVERRIDE {
4913 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); 4808 if (new_rep.IsSmi()) new_rep = Representation::Integer32();
4914 HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); 4809 HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
(...skipping 16 matching lines...) Expand all
4931 }; 4826 };
4932 4827
4933 4828
4934 class HDiv V8_FINAL : public HArithmeticBinaryOperation { 4829 class HDiv V8_FINAL : public HArithmeticBinaryOperation {
4935 public: 4830 public:
4936 static HInstruction* New(Zone* zone, 4831 static HInstruction* New(Zone* zone,
4937 HValue* context, 4832 HValue* context,
4938 HValue* left, 4833 HValue* left,
4939 HValue* right); 4834 HValue* right);
4940 4835
4941 bool HasPowerOf2Divisor() {
4942 if (right()->IsInteger32Constant()) {
4943 int32_t value = right()->GetInteger32Constant();
4944 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
4945 }
4946
4947 return false;
4948 }
4949
4950 virtual HValue* EnsureAndPropagateNotMinusZero( 4836 virtual HValue* EnsureAndPropagateNotMinusZero(
4951 BitVector* visited) V8_OVERRIDE; 4837 BitVector* visited) V8_OVERRIDE;
4952 4838
4953 virtual HValue* Canonicalize() V8_OVERRIDE; 4839 virtual HValue* Canonicalize() V8_OVERRIDE;
4954 4840
4955 virtual void UpdateRepresentation(Representation new_rep, 4841 virtual void UpdateRepresentation(Representation new_rep,
4956 HInferRepresentationPhase* h_infer, 4842 HInferRepresentationPhase* h_infer,
4957 const char* reason) V8_OVERRIDE { 4843 const char* reason) V8_OVERRIDE {
4958 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); 4844 if (new_rep.IsSmi()) new_rep = Representation::Integer32();
4959 HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); 4845 HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
5232 BailoutId ast_id() const { return ast_id_; } 5118 BailoutId ast_id() const { return ast_id_; }
5233 5119
5234 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 5120 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
5235 return Representation::None(); 5121 return Representation::None();
5236 } 5122 }
5237 5123
5238 DECLARE_CONCRETE_INSTRUCTION(OsrEntry) 5124 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
5239 5125
5240 private: 5126 private:
5241 explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) { 5127 explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) {
5242 SetGVNFlag(kChangesOsrEntries); 5128 SetChangesFlag(kOsrEntries);
5243 SetGVNFlag(kChangesNewSpacePromotion); 5129 SetChangesFlag(kNewSpacePromotion);
5244 } 5130 }
5245 5131
5246 BailoutId ast_id_; 5132 BailoutId ast_id_;
5247 }; 5133 };
5248 5134
5249 5135
5250 class HParameter V8_FINAL : public HTemplateInstruction<0> { 5136 class HParameter V8_FINAL : public HTemplateInstruction<0> {
5251 public: 5137 public:
5252 enum ParameterKind { 5138 enum ParameterKind {
5253 STACK_PARAMETER, 5139 STACK_PARAMETER,
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
5375 protected: 5261 protected:
5376 virtual bool DataEquals(HValue* other) V8_OVERRIDE { 5262 virtual bool DataEquals(HValue* other) V8_OVERRIDE {
5377 return cell_ == HLoadGlobalCell::cast(other)->cell_; 5263 return cell_ == HLoadGlobalCell::cast(other)->cell_;
5378 } 5264 }
5379 5265
5380 private: 5266 private:
5381 HLoadGlobalCell(Handle<Cell> cell, PropertyDetails details) 5267 HLoadGlobalCell(Handle<Cell> cell, PropertyDetails details)
5382 : cell_(Unique<Cell>::CreateUninitialized(cell)), details_(details) { 5268 : cell_(Unique<Cell>::CreateUninitialized(cell)), details_(details) {
5383 set_representation(Representation::Tagged()); 5269 set_representation(Representation::Tagged());
5384 SetFlag(kUseGVN); 5270 SetFlag(kUseGVN);
5385 SetGVNFlag(kDependsOnGlobalVars); 5271 SetDependsOnFlag(kGlobalVars);
5386 } 5272 }
5387 5273
5388 virtual bool IsDeletable() const V8_OVERRIDE { return !RequiresHoleCheck(); } 5274 virtual bool IsDeletable() const V8_OVERRIDE { return !RequiresHoleCheck(); }
5389 5275
5390 Unique<Cell> cell_; 5276 Unique<Cell> cell_;
5391 PropertyDetails details_; 5277 PropertyDetails details_;
5392 }; 5278 };
5393 5279
5394 5280
5395 class HLoadGlobalGeneric V8_FINAL : public HTemplateInstruction<2> { 5281 class HLoadGlobalGeneric V8_FINAL : public HTemplateInstruction<2> {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
5495 } 5381 }
5496 5382
5497 bool MustClearNextMapWord() const { 5383 bool MustClearNextMapWord() const {
5498 return (flags_ & CLEAR_NEXT_MAP_WORD) != 0; 5384 return (flags_ & CLEAR_NEXT_MAP_WORD) != 0;
5499 } 5385 }
5500 5386
5501 void MakeDoubleAligned() { 5387 void MakeDoubleAligned() {
5502 flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATE_DOUBLE_ALIGNED); 5388 flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATE_DOUBLE_ALIGNED);
5503 } 5389 }
5504 5390
5505 virtual void HandleSideEffectDominator(GVNFlag side_effect, 5391 virtual bool HandleSideEffectDominator(GVNFlag side_effect,
5506 HValue* dominator) V8_OVERRIDE; 5392 HValue* dominator) V8_OVERRIDE;
5507 5393
5508 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 5394 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
5509 5395
5510 DECLARE_CONCRETE_INSTRUCTION(Allocate) 5396 DECLARE_CONCRETE_INSTRUCTION(Allocate)
5511 5397
5512 private: 5398 private:
5513 enum Flags { 5399 enum Flags {
5514 ALLOCATE_IN_NEW_SPACE = 1 << 0, 5400 ALLOCATE_IN_NEW_SPACE = 1 << 0,
5515 ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1, 5401 ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1,
(...skipping 11 matching lines...) Expand all
5527 Handle<AllocationSite> allocation_site = 5413 Handle<AllocationSite> allocation_site =
5528 Handle<AllocationSite>::null()) 5414 Handle<AllocationSite>::null())
5529 : HTemplateInstruction<2>(type), 5415 : HTemplateInstruction<2>(type),
5530 flags_(ComputeFlags(pretenure_flag, instance_type)), 5416 flags_(ComputeFlags(pretenure_flag, instance_type)),
5531 dominating_allocate_(NULL), 5417 dominating_allocate_(NULL),
5532 filler_free_space_size_(NULL) { 5418 filler_free_space_size_(NULL) {
5533 SetOperandAt(0, context); 5419 SetOperandAt(0, context);
5534 SetOperandAt(1, size); 5420 SetOperandAt(1, size);
5535 set_representation(Representation::Tagged()); 5421 set_representation(Representation::Tagged());
5536 SetFlag(kTrackSideEffectDominators); 5422 SetFlag(kTrackSideEffectDominators);
5537 SetGVNFlag(kChangesNewSpacePromotion); 5423 SetChangesFlag(kNewSpacePromotion);
5538 SetGVNFlag(kDependsOnNewSpacePromotion); 5424 SetDependsOnFlag(kNewSpacePromotion);
5539 5425
5540 if (FLAG_trace_pretenuring) { 5426 if (FLAG_trace_pretenuring) {
5541 PrintF("HAllocate with AllocationSite %p %s\n", 5427 PrintF("HAllocate with AllocationSite %p %s\n",
5542 allocation_site.is_null() 5428 allocation_site.is_null()
5543 ? static_cast<void*>(NULL) 5429 ? static_cast<void*>(NULL)
5544 : static_cast<void*>(*allocation_site), 5430 : static_cast<void*>(*allocation_site),
5545 pretenure_flag == TENURED ? "tenured" : "not tenured"); 5431 pretenure_flag == TENURED ? "tenured" : "not tenured");
5546 } 5432 }
5547 } 5433 }
5548 5434
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
5726 5612
5727 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell) 5613 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
5728 5614
5729 private: 5615 private:
5730 HStoreGlobalCell(HValue* value, 5616 HStoreGlobalCell(HValue* value,
5731 Handle<PropertyCell> cell, 5617 Handle<PropertyCell> cell,
5732 PropertyDetails details) 5618 PropertyDetails details)
5733 : HUnaryOperation(value), 5619 : HUnaryOperation(value),
5734 cell_(Unique<PropertyCell>::CreateUninitialized(cell)), 5620 cell_(Unique<PropertyCell>::CreateUninitialized(cell)),
5735 details_(details) { 5621 details_(details) {
5736 SetGVNFlag(kChangesGlobalVars); 5622 SetChangesFlag(kGlobalVars);
5737 } 5623 }
5738 5624
5739 Unique<PropertyCell> cell_; 5625 Unique<PropertyCell> cell_;
5740 PropertyDetails details_; 5626 PropertyDetails details_;
5741 }; 5627 };
5742 5628
5743 5629
5744 class HLoadContextSlot V8_FINAL : public HUnaryOperation { 5630 class HLoadContextSlot V8_FINAL : public HUnaryOperation {
5745 public: 5631 public:
5746 enum Mode { 5632 enum Mode {
(...skipping 18 matching lines...) Expand all
5765 mode_ = kCheckDeoptimize; 5651 mode_ = kCheckDeoptimize;
5766 break; 5652 break;
5767 case CONST: 5653 case CONST:
5768 mode_ = kCheckReturnUndefined; 5654 mode_ = kCheckReturnUndefined;
5769 break; 5655 break;
5770 default: 5656 default:
5771 mode_ = kNoCheck; 5657 mode_ = kNoCheck;
5772 } 5658 }
5773 set_representation(Representation::Tagged()); 5659 set_representation(Representation::Tagged());
5774 SetFlag(kUseGVN); 5660 SetFlag(kUseGVN);
5775 SetGVNFlag(kDependsOnContextSlots); 5661 SetDependsOnFlag(kContextSlots);
5776 } 5662 }
5777 5663
5778 int slot_index() const { return slot_index_; } 5664 int slot_index() const { return slot_index_; }
5779 Mode mode() const { return mode_; } 5665 Mode mode() const { return mode_; }
5780 5666
5781 bool DeoptimizesOnHole() { 5667 bool DeoptimizesOnHole() {
5782 return mode_ == kCheckDeoptimize; 5668 return mode_ == kCheckDeoptimize;
5783 } 5669 }
5784 5670
5785 bool RequiresHoleCheck() const { 5671 bool RequiresHoleCheck() const {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
5849 5735
5850 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 5736 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
5851 5737
5852 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot) 5738 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
5853 5739
5854 private: 5740 private:
5855 HStoreContextSlot(HValue* context, int slot_index, Mode mode, HValue* value) 5741 HStoreContextSlot(HValue* context, int slot_index, Mode mode, HValue* value)
5856 : slot_index_(slot_index), mode_(mode) { 5742 : slot_index_(slot_index), mode_(mode) {
5857 SetOperandAt(0, context); 5743 SetOperandAt(0, context);
5858 SetOperandAt(1, value); 5744 SetOperandAt(1, value);
5859 SetGVNFlag(kChangesContextSlots); 5745 SetChangesFlag(kContextSlots);
5860 } 5746 }
5861 5747
5862 int slot_index_; 5748 int slot_index_;
5863 Mode mode_; 5749 Mode mode_;
5864 }; 5750 };
5865 5751
5866 5752
5867 // Represents an access to a portion of an object, such as the map pointer, 5753 // Represents an access to a portion of an object, such as the map pointer,
5868 // array elements pointer, etc, but not accesses to array elements themselves. 5754 // array elements pointer, etc, but not accesses to array elements themselves.
5869 class HObjectAccess V8_FINAL { 5755 class HObjectAccess V8_FINAL {
(...skipping 19 matching lines...) Expand all
5889 } 5775 }
5890 5776
5891 inline Handle<String> name() const { 5777 inline Handle<String> name() const {
5892 return name_; 5778 return name_;
5893 } 5779 }
5894 5780
5895 inline bool immutable() const { 5781 inline bool immutable() const {
5896 return ImmutableField::decode(value_); 5782 return ImmutableField::decode(value_);
5897 } 5783 }
5898 5784
5785 // Returns true if access is being made to an in-object property that
5786 // was already added to the object.
5787 inline bool existing_inobject_property() const {
5788 return ExistingInobjectPropertyField::decode(value_);
5789 }
5790
5899 inline HObjectAccess WithRepresentation(Representation representation) { 5791 inline HObjectAccess WithRepresentation(Representation representation) {
5900 return HObjectAccess(portion(), offset(), representation, name()); 5792 return HObjectAccess(portion(), offset(), representation, name(),
5793 immutable(), existing_inobject_property());
5901 } 5794 }
5902 5795
5903 static HObjectAccess ForHeapNumberValue() { 5796 static HObjectAccess ForHeapNumberValue() {
5904 return HObjectAccess( 5797 return HObjectAccess(
5905 kDouble, HeapNumber::kValueOffset, Representation::Double()); 5798 kDouble, HeapNumber::kValueOffset, Representation::Double());
5906 } 5799 }
5907 5800
5908 static HObjectAccess ForHeapNumberValueLowestBits() { 5801 static HObjectAccess ForHeapNumberValueLowestBits() {
5909 return HObjectAccess(kDouble, 5802 return HObjectAccess(kDouble,
5910 HeapNumber::kValueOffset, 5803 HeapNumber::kValueOffset,
(...skipping 23 matching lines...) Expand all
5934 kArrayLengths, 5827 kArrayLengths,
5935 JSArray::kLengthOffset, 5828 JSArray::kLengthOffset,
5936 IsFastElementsKind(elements_kind) && 5829 IsFastElementsKind(elements_kind) &&
5937 FLAG_track_fields 5830 FLAG_track_fields
5938 ? Representation::Smi() : Representation::Tagged()); 5831 ? Representation::Smi() : Representation::Tagged());
5939 } 5832 }
5940 5833
5941 static HObjectAccess ForAllocationSiteOffset(int offset); 5834 static HObjectAccess ForAllocationSiteOffset(int offset);
5942 5835
5943 static HObjectAccess ForAllocationSiteList() { 5836 static HObjectAccess ForAllocationSiteList() {
5944 return HObjectAccess(kExternalMemory, 0, Representation::Tagged()); 5837 return HObjectAccess(kExternalMemory, 0, Representation::Tagged(),
5838 Handle<String>::null(), false, false);
5945 } 5839 }
5946 5840
5947 static HObjectAccess ForFixedArrayLength() { 5841 static HObjectAccess ForFixedArrayLength() {
5948 return HObjectAccess( 5842 return HObjectAccess(
5949 kArrayLengths, 5843 kArrayLengths,
5950 FixedArray::kLengthOffset, 5844 FixedArray::kLengthOffset,
5951 FLAG_track_fields ? Representation::Smi() : Representation::Tagged()); 5845 FLAG_track_fields ? Representation::Smi() : Representation::Tagged());
5952 } 5846 }
5953 5847
5954 static HObjectAccess ForStringHashField() { 5848 static HObjectAccess ForStringHashField() {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
6036 5930
6037 static HObjectAccess ForCellValue() { 5931 static HObjectAccess ForCellValue() {
6038 return HObjectAccess(kInobject, Cell::kValueOffset); 5932 return HObjectAccess(kInobject, Cell::kValueOffset);
6039 } 5933 }
6040 5934
6041 static HObjectAccess ForAllocationMementoSite() { 5935 static HObjectAccess ForAllocationMementoSite() {
6042 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset); 5936 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset);
6043 } 5937 }
6044 5938
6045 static HObjectAccess ForCounter() { 5939 static HObjectAccess ForCounter() {
6046 return HObjectAccess(kExternalMemory, 0, Representation::Integer32()); 5940 return HObjectAccess(kExternalMemory, 0, Representation::Integer32(),
5941 Handle<String>::null(), false, false);
6047 } 5942 }
6048 5943
6049 // Create an access to an offset in a fixed array header. 5944 // Create an access to an offset in a fixed array header.
6050 static HObjectAccess ForFixedArrayHeader(int offset); 5945 static HObjectAccess ForFixedArrayHeader(int offset);
6051 5946
6052 // Create an access to an in-object property in a JSObject. 5947 // Create an access to an in-object property in a JSObject.
6053 static HObjectAccess ForJSObjectOffset(int offset, 5948 // This kind of access must be used when the object |map| is known and
5949 // in-object properties are being accessed. Accesses of the in-object
5950 // properties can have different semantics depending on whether corresponding
5951 // property was added to the map or not.
5952 static HObjectAccess ForMapAndOffset(Handle<Map> map, int offset,
6054 Representation representation = Representation::Tagged()); 5953 Representation representation = Representation::Tagged());
6055 5954
5955 // Create an access to an in-object property in a JSObject.
5956 // This kind of access can be used for accessing object header fields or
5957 // in-object properties if the map of the object is not known.
5958 static HObjectAccess ForObservableJSObjectOffset(int offset,
5959 Representation representation = Representation::Tagged()) {
5960 return ForMapAndOffset(Handle<Map>::null(), offset, representation);
5961 }
5962
6056 // Create an access to an in-object property in a JSArray. 5963 // Create an access to an in-object property in a JSArray.
6057 static HObjectAccess ForJSArrayOffset(int offset); 5964 static HObjectAccess ForJSArrayOffset(int offset);
6058 5965
6059 static HObjectAccess ForContextSlot(int index); 5966 static HObjectAccess ForContextSlot(int index);
6060 5967
6061 // Create an access to the backing store of an object. 5968 // Create an access to the backing store of an object.
6062 static HObjectAccess ForBackingStoreOffset(int offset, 5969 static HObjectAccess ForBackingStoreOffset(int offset,
6063 Representation representation = Representation::Tagged()); 5970 Representation representation = Representation::Tagged());
6064 5971
6065 // Create an access to a resolved field (in-object or backing store). 5972 // Create an access to a resolved field (in-object or backing store).
6066 static HObjectAccess ForField(Handle<Map> map, 5973 static HObjectAccess ForField(Handle<Map> map,
6067 LookupResult *lookup, Handle<String> name = Handle<String>::null()); 5974 LookupResult *lookup, Handle<String> name = Handle<String>::null());
6068 5975
6069 // Create an access for the payload of a Cell or JSGlobalPropertyCell. 5976 // Create an access for the payload of a Cell or JSGlobalPropertyCell.
6070 static HObjectAccess ForCellPayload(Isolate* isolate); 5977 static HObjectAccess ForCellPayload(Isolate* isolate);
6071 5978
6072 static HObjectAccess ForJSTypedArrayLength() { 5979 static HObjectAccess ForJSTypedArrayLength() {
6073 return HObjectAccess::ForJSObjectOffset(JSTypedArray::kLengthOffset); 5980 return HObjectAccess::ForObservableJSObjectOffset(
5981 JSTypedArray::kLengthOffset);
6074 } 5982 }
6075 5983
6076 static HObjectAccess ForJSArrayBufferBackingStore() { 5984 static HObjectAccess ForJSArrayBufferBackingStore() {
6077 return HObjectAccess::ForJSObjectOffset( 5985 return HObjectAccess::ForObservableJSObjectOffset(
6078 JSArrayBuffer::kBackingStoreOffset, Representation::External()); 5986 JSArrayBuffer::kBackingStoreOffset, Representation::External());
6079 } 5987 }
6080 5988
6081 static HObjectAccess ForExternalArrayExternalPointer() { 5989 static HObjectAccess ForExternalArrayExternalPointer() {
6082 return HObjectAccess::ForJSObjectOffset( 5990 return HObjectAccess::ForObservableJSObjectOffset(
6083 ExternalArray::kExternalPointerOffset, Representation::External()); 5991 ExternalArray::kExternalPointerOffset, Representation::External());
6084 } 5992 }
6085 5993
6086 static HObjectAccess ForJSArrayBufferViewWeakNext() { 5994 static HObjectAccess ForJSArrayBufferViewWeakNext() {
6087 return HObjectAccess::ForJSObjectOffset(JSArrayBufferView::kWeakNextOffset); 5995 return HObjectAccess::ForObservableJSObjectOffset(
5996 JSArrayBufferView::kWeakNextOffset);
6088 } 5997 }
6089 5998
6090 static HObjectAccess ForJSArrayBufferWeakFirstView() { 5999 static HObjectAccess ForJSArrayBufferWeakFirstView() {
6091 return HObjectAccess::ForJSObjectOffset( 6000 return HObjectAccess::ForObservableJSObjectOffset(
6092 JSArrayBuffer::kWeakFirstViewOffset); 6001 JSArrayBuffer::kWeakFirstViewOffset);
6093 } 6002 }
6094 6003
6095 static HObjectAccess ForJSArrayBufferViewBuffer() { 6004 static HObjectAccess ForJSArrayBufferViewBuffer() {
6096 return HObjectAccess::ForJSObjectOffset(JSArrayBufferView::kBufferOffset); 6005 return HObjectAccess::ForObservableJSObjectOffset(
6006 JSArrayBufferView::kBufferOffset);
6097 } 6007 }
6098 6008
6099 static HObjectAccess ForJSArrayBufferViewByteOffset() { 6009 static HObjectAccess ForJSArrayBufferViewByteOffset() {
6100 return HObjectAccess::ForJSObjectOffset( 6010 return HObjectAccess::ForObservableJSObjectOffset(
6101 JSArrayBufferView::kByteOffsetOffset); 6011 JSArrayBufferView::kByteOffsetOffset);
6102 } 6012 }
6103 6013
6104 static HObjectAccess ForJSArrayBufferViewByteLength() { 6014 static HObjectAccess ForJSArrayBufferViewByteLength() {
6105 return HObjectAccess::ForJSObjectOffset( 6015 return HObjectAccess::ForObservableJSObjectOffset(
6106 JSArrayBufferView::kByteLengthOffset); 6016 JSArrayBufferView::kByteLengthOffset);
6107 } 6017 }
6108 6018
6109 void PrintTo(StringStream* stream); 6019 static HObjectAccess ForGlobalObjectNativeContext() {
6020 return HObjectAccess(kInobject, GlobalObject::kNativeContextOffset);
6021 }
6022
6023 void PrintTo(StringStream* stream) const;
6110 6024
6111 inline bool Equals(HObjectAccess that) const { 6025 inline bool Equals(HObjectAccess that) const {
6112 return value_ == that.value_; // portion and offset must match 6026 return value_ == that.value_; // portion and offset must match
6113 } 6027 }
6114 6028
6115 protected: 6029 protected:
6116 void SetGVNFlags(HValue *instr, bool is_store); 6030 void SetGVNFlags(HValue *instr, PropertyAccessType access_type);
6117 6031
6118 private: 6032 private:
6119 // internal use only; different parts of an object or array 6033 // internal use only; different parts of an object or array
6120 enum Portion { 6034 enum Portion {
6121 kMaps, // map of an object 6035 kMaps, // map of an object
6122 kArrayLengths, // the length of an array 6036 kArrayLengths, // the length of an array
6123 kStringLengths, // the length of a string 6037 kStringLengths, // the length of a string
6124 kElementsPointer, // elements pointer 6038 kElementsPointer, // elements pointer
6125 kBackingStore, // some field in the backing store 6039 kBackingStore, // some field in the backing store
6126 kDouble, // some double field 6040 kDouble, // some double field
6127 kInobject, // some other in-object field 6041 kInobject, // some other in-object field
6128 kExternalMemory // some field in external memory 6042 kExternalMemory // some field in external memory
6129 }; 6043 };
6130 6044
6045 HObjectAccess() : value_(0) {}
6046
6131 HObjectAccess(Portion portion, int offset, 6047 HObjectAccess(Portion portion, int offset,
6132 Representation representation = Representation::Tagged(), 6048 Representation representation = Representation::Tagged(),
6133 Handle<String> name = Handle<String>::null(), 6049 Handle<String> name = Handle<String>::null(),
6134 bool immutable = false) 6050 bool immutable = false,
6051 bool existing_inobject_property = true)
6135 : value_(PortionField::encode(portion) | 6052 : value_(PortionField::encode(portion) |
6136 RepresentationField::encode(representation.kind()) | 6053 RepresentationField::encode(representation.kind()) |
6137 ImmutableField::encode(immutable ? 1 : 0) | 6054 ImmutableField::encode(immutable ? 1 : 0) |
6055 ExistingInobjectPropertyField::encode(
6056 existing_inobject_property ? 1 : 0) |
6138 OffsetField::encode(offset)), 6057 OffsetField::encode(offset)),
6139 name_(name) { 6058 name_(name) {
6140 // assert that the fields decode correctly 6059 // assert that the fields decode correctly
6141 ASSERT(this->offset() == offset); 6060 ASSERT(this->offset() == offset);
6142 ASSERT(this->portion() == portion); 6061 ASSERT(this->portion() == portion);
6143 ASSERT(this->immutable() == immutable); 6062 ASSERT(this->immutable() == immutable);
6063 ASSERT(this->existing_inobject_property() == existing_inobject_property);
6144 ASSERT(RepresentationField::decode(value_) == representation.kind()); 6064 ASSERT(RepresentationField::decode(value_) == representation.kind());
6065 ASSERT(!this->existing_inobject_property() || IsInobject());
6145 } 6066 }
6146 6067
6147 class PortionField : public BitField<Portion, 0, 3> {}; 6068 class PortionField : public BitField<Portion, 0, 3> {};
6148 class RepresentationField : public BitField<Representation::Kind, 3, 4> {}; 6069 class RepresentationField : public BitField<Representation::Kind, 3, 4> {};
6149 class ImmutableField : public BitField<bool, 7, 1> {}; 6070 class ImmutableField : public BitField<bool, 7, 1> {};
6150 class OffsetField : public BitField<int, 8, 24> {}; 6071 class ExistingInobjectPropertyField : public BitField<bool, 8, 1> {};
6072 class OffsetField : public BitField<int, 9, 23> {};
6151 6073
6152 uint32_t value_; // encodes portion, representation, immutable, and offset 6074 uint32_t value_; // encodes portion, representation, immutable, and offset
6153 Handle<String> name_; 6075 Handle<String> name_;
6154 6076
6155 friend class HLoadNamedField; 6077 friend class HLoadNamedField;
6156 friend class HStoreNamedField; 6078 friend class HStoreNamedField;
6079 friend class SideEffectsTracker;
6157 6080
6158 inline Portion portion() const { 6081 inline Portion portion() const {
6159 return PortionField::decode(value_); 6082 return PortionField::decode(value_);
6160 } 6083 }
6161 }; 6084 };
6162 6085
6163 6086
6164 class HLoadNamedField V8_FINAL : public HTemplateInstruction<1> { 6087 class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> {
6165 public: 6088 public:
6166 DECLARE_INSTRUCTION_FACTORY_P2(HLoadNamedField, HValue*, HObjectAccess); 6089 DECLARE_INSTRUCTION_FACTORY_P3(HLoadNamedField, HValue*, HValue*,
6090 HObjectAccess);
6167 6091
6168 HValue* object() { return OperandAt(0); } 6092 HValue* object() { return OperandAt(0); }
6169 bool HasTypeCheck() { return object()->IsCheckMaps(); } 6093 HValue* dependency() {
6094 ASSERT(HasDependency());
6095 return OperandAt(1);
6096 }
6097 bool HasDependency() const { return OperandAt(0) != OperandAt(1); }
6170 HObjectAccess access() const { return access_; } 6098 HObjectAccess access() const { return access_; }
6171 Representation field_representation() const { 6099 Representation field_representation() const {
6172 return access_.representation(); 6100 return access_.representation();
6173 } 6101 }
6174 6102
6175 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } 6103 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; }
6176 virtual bool HasOutOfBoundsAccess(int size) V8_OVERRIDE { 6104 virtual bool HasOutOfBoundsAccess(int size) V8_OVERRIDE {
6177 return !access().IsInobject() || access().offset() >= size; 6105 return !access().IsInobject() || access().offset() >= size;
6178 } 6106 }
6179 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 6107 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
6180 if (index == 0 && access().IsExternalMemory()) { 6108 if (index == 0 && access().IsExternalMemory()) {
6181 // object must be external in case of external memory access 6109 // object must be external in case of external memory access
6182 return Representation::External(); 6110 return Representation::External();
6183 } 6111 }
6184 return Representation::Tagged(); 6112 return Representation::Tagged();
6185 } 6113 }
6186 virtual Range* InferRange(Zone* zone) V8_OVERRIDE; 6114 virtual Range* InferRange(Zone* zone) V8_OVERRIDE;
6187 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 6115 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
6188 6116
6189 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) 6117 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
6190 6118
6191 protected: 6119 protected:
6192 virtual bool DataEquals(HValue* other) V8_OVERRIDE { 6120 virtual bool DataEquals(HValue* other) V8_OVERRIDE {
6193 HLoadNamedField* b = HLoadNamedField::cast(other); 6121 HLoadNamedField* b = HLoadNamedField::cast(other);
6194 return access_.Equals(b->access_); 6122 return access_.Equals(b->access_);
6195 } 6123 }
6196 6124
6197 private: 6125 private:
6198 HLoadNamedField(HValue* object, HObjectAccess access) : access_(access) { 6126 HLoadNamedField(HValue* object,
6127 HValue* dependency,
6128 HObjectAccess access) : access_(access) {
6199 ASSERT(object != NULL); 6129 ASSERT(object != NULL);
6200 SetOperandAt(0, object); 6130 SetOperandAt(0, object);
6131 SetOperandAt(1, dependency != NULL ? dependency : object);
6201 6132
6202 Representation representation = access.representation(); 6133 Representation representation = access.representation();
6203 if (representation.IsInteger8() || 6134 if (representation.IsInteger8() ||
6204 representation.IsUInteger8() || 6135 representation.IsUInteger8() ||
6205 representation.IsInteger16() || 6136 representation.IsInteger16() ||
6206 representation.IsUInteger16()) { 6137 representation.IsUInteger16()) {
6207 set_representation(Representation::Integer32()); 6138 set_representation(Representation::Integer32());
6208 } else if (representation.IsSmi()) { 6139 } else if (representation.IsSmi()) {
6209 set_type(HType::Smi()); 6140 set_type(HType::Smi());
6210 if (SmiValuesAre32Bits()) { 6141 if (SmiValuesAre32Bits()) {
6211 set_representation(Representation::Integer32()); 6142 set_representation(Representation::Integer32());
6212 } else { 6143 } else {
6213 set_representation(representation); 6144 set_representation(representation);
6214 } 6145 }
6215 } else if (representation.IsDouble() || 6146 } else if (representation.IsDouble() ||
6216 representation.IsExternal() || 6147 representation.IsExternal() ||
6217 representation.IsInteger32()) { 6148 representation.IsInteger32()) {
6218 set_representation(representation); 6149 set_representation(representation);
6219 } else if (FLAG_track_heap_object_fields && 6150 } else if (FLAG_track_heap_object_fields &&
6220 representation.IsHeapObject()) { 6151 representation.IsHeapObject()) {
6221 set_type(HType::NonPrimitive()); 6152 set_type(HType::NonPrimitive());
6222 set_representation(Representation::Tagged()); 6153 set_representation(Representation::Tagged());
6223 } else { 6154 } else {
6224 set_representation(Representation::Tagged()); 6155 set_representation(Representation::Tagged());
6225 } 6156 }
6226 access.SetGVNFlags(this, false); 6157 access.SetGVNFlags(this, LOAD);
6227 } 6158 }
6228 6159
6229 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 6160 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
6230 6161
6231 HObjectAccess access_; 6162 HObjectAccess access_;
6232 }; 6163 };
6233 6164
6234 6165
6235 class HLoadNamedGeneric V8_FINAL : public HTemplateInstruction<2> { 6166 class HLoadNamedGeneric V8_FINAL : public HTemplateInstruction<2> {
6236 public: 6167 public:
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
6275 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype) 6206 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
6276 6207
6277 protected: 6208 protected:
6278 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } 6209 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
6279 6210
6280 private: 6211 private:
6281 explicit HLoadFunctionPrototype(HValue* function) 6212 explicit HLoadFunctionPrototype(HValue* function)
6282 : HUnaryOperation(function) { 6213 : HUnaryOperation(function) {
6283 set_representation(Representation::Tagged()); 6214 set_representation(Representation::Tagged());
6284 SetFlag(kUseGVN); 6215 SetFlag(kUseGVN);
6285 SetGVNFlag(kDependsOnCalls); 6216 SetDependsOnFlag(kCalls);
6286 } 6217 }
6287 }; 6218 };
6288 6219
6289 class ArrayInstructionInterface { 6220 class ArrayInstructionInterface {
6290 public: 6221 public:
6291 virtual HValue* GetKey() = 0; 6222 virtual HValue* GetKey() = 0;
6292 virtual void SetKey(HValue* key) = 0; 6223 virtual void SetKey(HValue* key) = 0;
6293 virtual void SetIndexOffset(uint32_t index_offset) = 0; 6224 virtual void SetIndexOffset(uint32_t index_offset) = 0;
6294 virtual int MaxIndexOffsetBits() = 0; 6225 virtual int MaxIndexOffsetBits() = 0;
6295 virtual bool IsDehoisted() = 0; 6226 virtual bool IsDehoisted() = 0;
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
6420 set_type(HType::Smi()); 6351 set_type(HType::Smi());
6421 if (SmiValuesAre32Bits() && !RequiresHoleCheck()) { 6352 if (SmiValuesAre32Bits() && !RequiresHoleCheck()) {
6422 set_representation(Representation::Integer32()); 6353 set_representation(Representation::Integer32());
6423 } else { 6354 } else {
6424 set_representation(Representation::Smi()); 6355 set_representation(Representation::Smi());
6425 } 6356 }
6426 } else { 6357 } else {
6427 set_representation(Representation::Tagged()); 6358 set_representation(Representation::Tagged());
6428 } 6359 }
6429 6360
6430 SetGVNFlag(kDependsOnArrayElements); 6361 SetDependsOnFlag(kArrayElements);
6431 } else { 6362 } else {
6432 set_representation(Representation::Double()); 6363 set_representation(Representation::Double());
6433 SetGVNFlag(kDependsOnDoubleArrayElements); 6364 SetDependsOnFlag(kDoubleArrayElements);
6434 } 6365 }
6435 } else { 6366 } else {
6436 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 6367 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
6437 elements_kind == EXTERNAL_DOUBLE_ELEMENTS || 6368 elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
6438 elements_kind == FLOAT32_ELEMENTS || 6369 elements_kind == FLOAT32_ELEMENTS ||
6439 elements_kind == FLOAT64_ELEMENTS) { 6370 elements_kind == FLOAT64_ELEMENTS) {
6440 set_representation(Representation::Double()); 6371 set_representation(Representation::Double());
6441 } else { 6372 } else {
6442 set_representation(Representation::Integer32()); 6373 set_representation(Representation::Integer32());
6443 } 6374 }
6444 6375
6445 if (is_external()) { 6376 if (is_external()) {
6446 SetGVNFlag(kDependsOnExternalMemory); 6377 SetDependsOnFlag(kExternalMemory);
6447 } else if (is_fixed_typed_array()) { 6378 } else if (is_fixed_typed_array()) {
6448 SetGVNFlag(kDependsOnTypedArrayElements); 6379 SetDependsOnFlag(kTypedArrayElements);
6449 } else { 6380 } else {
6450 UNREACHABLE(); 6381 UNREACHABLE();
6451 } 6382 }
6452 // Native code could change the specialized array. 6383 // Native code could change the specialized array.
6453 SetGVNFlag(kDependsOnCalls); 6384 SetDependsOnFlag(kCalls);
6454 } 6385 }
6455 6386
6456 SetFlag(kUseGVN); 6387 SetFlag(kUseGVN);
6457 } 6388 }
6458 6389
6459 virtual bool IsDeletable() const V8_OVERRIDE { 6390 virtual bool IsDeletable() const V8_OVERRIDE {
6460 return !RequiresHoleCheck(); 6391 return !RequiresHoleCheck();
6461 } 6392 }
6462 6393
6463 // Establish some checks around our packed fields 6394 // Establish some checks around our packed fields
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
6518 SetOperandAt(1, key); 6449 SetOperandAt(1, key);
6519 SetOperandAt(2, context); 6450 SetOperandAt(2, context);
6520 SetAllSideEffects(); 6451 SetAllSideEffects();
6521 } 6452 }
6522 }; 6453 };
6523 6454
6524 6455
6525 // Indicates whether the store is a store to an entry that was previously 6456 // Indicates whether the store is a store to an entry that was previously
6526 // initialized or not. 6457 // initialized or not.
6527 enum StoreFieldOrKeyedMode { 6458 enum StoreFieldOrKeyedMode {
6459 // The entry could be either previously initialized or not.
6528 INITIALIZING_STORE, 6460 INITIALIZING_STORE,
6461 // At the time of this store it is guaranteed that the entry is already
6462 // initialized.
6529 STORE_TO_INITIALIZED_ENTRY 6463 STORE_TO_INITIALIZED_ENTRY
6530 }; 6464 };
6531 6465
6532 6466
6533 class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> { 6467 class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> {
6534 public: 6468 public:
6535 DECLARE_INSTRUCTION_FACTORY_P3(HStoreNamedField, HValue*, 6469 DECLARE_INSTRUCTION_FACTORY_P3(HStoreNamedField, HValue*,
6536 HObjectAccess, HValue*); 6470 HObjectAccess, HValue*);
6537 DECLARE_INSTRUCTION_FACTORY_P4(HStoreNamedField, HValue*, 6471 DECLARE_INSTRUCTION_FACTORY_P4(HStoreNamedField, HValue*,
6538 HObjectAccess, HValue*, StoreFieldOrKeyedMode); 6472 HObjectAccess, HValue*, StoreFieldOrKeyedMode);
(...skipping 23 matching lines...) Expand all
6562 if (SmiValuesAre32Bits() && store_mode_ == STORE_TO_INITIALIZED_ENTRY) { 6496 if (SmiValuesAre32Bits() && store_mode_ == STORE_TO_INITIALIZED_ENTRY) {
6563 return Representation::Integer32(); 6497 return Representation::Integer32();
6564 } 6498 }
6565 return field_representation(); 6499 return field_representation();
6566 } else if (field_representation().IsExternal()) { 6500 } else if (field_representation().IsExternal()) {
6567 return Representation::External(); 6501 return Representation::External();
6568 } 6502 }
6569 } 6503 }
6570 return Representation::Tagged(); 6504 return Representation::Tagged();
6571 } 6505 }
6572 virtual void HandleSideEffectDominator(GVNFlag side_effect, 6506 virtual bool HandleSideEffectDominator(GVNFlag side_effect,
6573 HValue* dominator) V8_OVERRIDE { 6507 HValue* dominator) V8_OVERRIDE {
6574 ASSERT(side_effect == kChangesNewSpacePromotion); 6508 ASSERT(side_effect == kNewSpacePromotion);
6509 if (!FLAG_use_write_barrier_elimination) return false;
6575 new_space_dominator_ = dominator; 6510 new_space_dominator_ = dominator;
6511 return false;
6576 } 6512 }
6577 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 6513 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
6578 6514
6579 void SkipWriteBarrier() { write_barrier_mode_ = SKIP_WRITE_BARRIER; } 6515 void SkipWriteBarrier() { write_barrier_mode_ = SKIP_WRITE_BARRIER; }
6580 bool IsSkipWriteBarrier() const { 6516 bool IsSkipWriteBarrier() const {
6581 return write_barrier_mode_ == SKIP_WRITE_BARRIER; 6517 return write_barrier_mode_ == SKIP_WRITE_BARRIER;
6582 } 6518 }
6583 6519
6584 HValue* object() const { return OperandAt(0); } 6520 HValue* object() const { return OperandAt(0); }
6585 HValue* value() const { return OperandAt(1); } 6521 HValue* value() const { return OperandAt(1); }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
6639 private: 6575 private:
6640 HStoreNamedField(HValue* obj, 6576 HStoreNamedField(HValue* obj,
6641 HObjectAccess access, 6577 HObjectAccess access,
6642 HValue* val, 6578 HValue* val,
6643 StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE) 6579 StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE)
6644 : access_(access), 6580 : access_(access),
6645 new_space_dominator_(NULL), 6581 new_space_dominator_(NULL),
6646 write_barrier_mode_(UPDATE_WRITE_BARRIER), 6582 write_barrier_mode_(UPDATE_WRITE_BARRIER),
6647 has_transition_(false), 6583 has_transition_(false),
6648 store_mode_(store_mode) { 6584 store_mode_(store_mode) {
6585 // Stores to a non existing in-object property are allowed only to the
6586 // newly allocated objects (via HAllocate or HInnerAllocatedObject).
6587 ASSERT(!access.IsInobject() || access.existing_inobject_property() ||
6588 obj->IsAllocate() || obj->IsInnerAllocatedObject());
6649 SetOperandAt(0, obj); 6589 SetOperandAt(0, obj);
6650 SetOperandAt(1, val); 6590 SetOperandAt(1, val);
6651 SetOperandAt(2, obj); 6591 SetOperandAt(2, obj);
6652 access.SetGVNFlags(this, true); 6592 access.SetGVNFlags(this, STORE);
6653 } 6593 }
6654 6594
6655 HObjectAccess access_; 6595 HObjectAccess access_;
6656 HValue* new_space_dominator_; 6596 HValue* new_space_dominator_;
6657 WriteBarrierMode write_barrier_mode_ : 1; 6597 WriteBarrierMode write_barrier_mode_ : 1;
6658 bool has_transition_ : 1; 6598 bool has_transition_ : 1;
6659 StoreFieldOrKeyedMode store_mode_ : 1; 6599 StoreFieldOrKeyedMode store_mode_ : 1;
6660 }; 6600 };
6661 6601
6662 6602
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
6788 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } 6728 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
6789 bool IsUninitialized() { return is_uninitialized_; } 6729 bool IsUninitialized() { return is_uninitialized_; }
6790 void SetUninitialized(bool is_uninitialized) { 6730 void SetUninitialized(bool is_uninitialized) {
6791 is_uninitialized_ = is_uninitialized; 6731 is_uninitialized_ = is_uninitialized;
6792 } 6732 }
6793 6733
6794 bool IsConstantHoleStore() { 6734 bool IsConstantHoleStore() {
6795 return value()->IsConstant() && HConstant::cast(value())->IsTheHole(); 6735 return value()->IsConstant() && HConstant::cast(value())->IsTheHole();
6796 } 6736 }
6797 6737
6798 virtual void HandleSideEffectDominator(GVNFlag side_effect, 6738 virtual bool HandleSideEffectDominator(GVNFlag side_effect,
6799 HValue* dominator) V8_OVERRIDE { 6739 HValue* dominator) V8_OVERRIDE {
6800 ASSERT(side_effect == kChangesNewSpacePromotion); 6740 ASSERT(side_effect == kNewSpacePromotion);
6801 new_space_dominator_ = dominator; 6741 new_space_dominator_ = dominator;
6742 return false;
6802 } 6743 }
6803 6744
6804 HValue* new_space_dominator() const { return new_space_dominator_; } 6745 HValue* new_space_dominator() const { return new_space_dominator_; }
6805 6746
6806 bool NeedsWriteBarrier() { 6747 bool NeedsWriteBarrier() {
6807 if (value_is_smi()) { 6748 if (value_is_smi()) {
6808 return false; 6749 return false;
6809 } else { 6750 } else {
6810 return StoringValueNeedsWriteBarrier(value()) && 6751 return StoringValueNeedsWriteBarrier(value()) &&
6811 ReceiverObjectNeedsWriteBarrier(elements(), value(), 6752 ReceiverObjectNeedsWriteBarrier(elements(), value(),
(...skipping 19 matching lines...) Expand all
6831 new_space_dominator_(NULL) { 6772 new_space_dominator_(NULL) {
6832 SetOperandAt(0, obj); 6773 SetOperandAt(0, obj);
6833 SetOperandAt(1, key); 6774 SetOperandAt(1, key);
6834 SetOperandAt(2, val); 6775 SetOperandAt(2, val);
6835 6776
6836 ASSERT(store_mode != STORE_TO_INITIALIZED_ENTRY || 6777 ASSERT(store_mode != STORE_TO_INITIALIZED_ENTRY ||
6837 elements_kind == FAST_SMI_ELEMENTS); 6778 elements_kind == FAST_SMI_ELEMENTS);
6838 6779
6839 if (IsFastObjectElementsKind(elements_kind)) { 6780 if (IsFastObjectElementsKind(elements_kind)) {
6840 SetFlag(kTrackSideEffectDominators); 6781 SetFlag(kTrackSideEffectDominators);
6841 SetGVNFlag(kDependsOnNewSpacePromotion); 6782 SetDependsOnFlag(kNewSpacePromotion);
6842 } 6783 }
6843 if (is_external()) { 6784 if (is_external()) {
6844 SetGVNFlag(kChangesExternalMemory); 6785 SetChangesFlag(kExternalMemory);
6845 SetFlag(kAllowUndefinedAsNaN); 6786 SetFlag(kAllowUndefinedAsNaN);
6846 } else if (IsFastDoubleElementsKind(elements_kind)) { 6787 } else if (IsFastDoubleElementsKind(elements_kind)) {
6847 SetGVNFlag(kChangesDoubleArrayElements); 6788 SetChangesFlag(kDoubleArrayElements);
6848 } else if (IsFastSmiElementsKind(elements_kind)) { 6789 } else if (IsFastSmiElementsKind(elements_kind)) {
6849 SetGVNFlag(kChangesArrayElements); 6790 SetChangesFlag(kArrayElements);
6850 } else if (is_fixed_typed_array()) { 6791 } else if (is_fixed_typed_array()) {
6851 SetGVNFlag(kChangesTypedArrayElements); 6792 SetChangesFlag(kTypedArrayElements);
6852 SetFlag(kAllowUndefinedAsNaN); 6793 SetFlag(kAllowUndefinedAsNaN);
6853 } else { 6794 } else {
6854 SetGVNFlag(kChangesArrayElements); 6795 SetChangesFlag(kArrayElements);
6855 } 6796 }
6856 6797
6857 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. 6798 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating.
6858 if ((elements_kind >= EXTERNAL_BYTE_ELEMENTS && 6799 if ((elements_kind >= EXTERNAL_INT8_ELEMENTS &&
6859 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) || 6800 elements_kind <= EXTERNAL_UINT32_ELEMENTS) ||
6860 (elements_kind >= UINT8_ELEMENTS && 6801 (elements_kind >= UINT8_ELEMENTS &&
6861 elements_kind <= INT32_ELEMENTS)) { 6802 elements_kind <= INT32_ELEMENTS)) {
6862 SetFlag(kTruncatingToInt32); 6803 SetFlag(kTruncatingToInt32);
6863 } 6804 }
6864 } 6805 }
6865 6806
6866 ElementsKind elements_kind_; 6807 ElementsKind elements_kind_;
6867 uint32_t index_offset_; 6808 uint32_t index_offset_;
6868 bool is_dehoisted_ : 1; 6809 bool is_dehoisted_ : 1;
6869 bool is_uninitialized_ : 1; 6810 bool is_uninitialized_ : 1;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
6948 HValue* object, 6889 HValue* object,
6949 Handle<Map> original_map, 6890 Handle<Map> original_map,
6950 Handle<Map> transitioned_map) 6891 Handle<Map> transitioned_map)
6951 : original_map_(Unique<Map>(original_map)), 6892 : original_map_(Unique<Map>(original_map)),
6952 transitioned_map_(Unique<Map>(transitioned_map)), 6893 transitioned_map_(Unique<Map>(transitioned_map)),
6953 from_kind_(original_map->elements_kind()), 6894 from_kind_(original_map->elements_kind()),
6954 to_kind_(transitioned_map->elements_kind()) { 6895 to_kind_(transitioned_map->elements_kind()) {
6955 SetOperandAt(0, object); 6896 SetOperandAt(0, object);
6956 SetOperandAt(1, context); 6897 SetOperandAt(1, context);
6957 SetFlag(kUseGVN); 6898 SetFlag(kUseGVN);
6958 SetGVNFlag(kChangesElementsKind); 6899 SetChangesFlag(kElementsKind);
6959 if (!IsSimpleMapChangeTransition(from_kind_, to_kind_)) { 6900 if (!IsSimpleMapChangeTransition(from_kind_, to_kind_)) {
6960 SetGVNFlag(kChangesElementsPointer); 6901 SetChangesFlag(kElementsPointer);
6961 SetGVNFlag(kChangesNewSpacePromotion); 6902 SetChangesFlag(kNewSpacePromotion);
6962 } 6903 }
6963 set_representation(Representation::Tagged()); 6904 set_representation(Representation::Tagged());
6964 } 6905 }
6965 6906
6966 Unique<Map> original_map_; 6907 Unique<Map> original_map_;
6967 Unique<Map> transitioned_map_; 6908 Unique<Map> transitioned_map_;
6968 ElementsKind from_kind_; 6909 ElementsKind from_kind_;
6969 ElementsKind to_kind_; 6910 ElementsKind to_kind_;
6970 }; 6911 };
6971 6912
(...skipping 30 matching lines...) Expand all
7002 HStringAdd(HValue* context, 6943 HStringAdd(HValue* context,
7003 HValue* left, 6944 HValue* left,
7004 HValue* right, 6945 HValue* right,
7005 PretenureFlag pretenure_flag, 6946 PretenureFlag pretenure_flag,
7006 StringAddFlags flags, 6947 StringAddFlags flags,
7007 Handle<AllocationSite> allocation_site) 6948 Handle<AllocationSite> allocation_site)
7008 : HBinaryOperation(context, left, right, HType::String()), 6949 : HBinaryOperation(context, left, right, HType::String()),
7009 flags_(flags), pretenure_flag_(pretenure_flag) { 6950 flags_(flags), pretenure_flag_(pretenure_flag) {
7010 set_representation(Representation::Tagged()); 6951 set_representation(Representation::Tagged());
7011 SetFlag(kUseGVN); 6952 SetFlag(kUseGVN);
7012 SetGVNFlag(kDependsOnMaps); 6953 SetDependsOnFlag(kMaps);
7013 SetGVNFlag(kChangesNewSpacePromotion); 6954 SetChangesFlag(kNewSpacePromotion);
7014 if (FLAG_trace_pretenuring) { 6955 if (FLAG_trace_pretenuring) {
7015 PrintF("HStringAdd with AllocationSite %p %s\n", 6956 PrintF("HStringAdd with AllocationSite %p %s\n",
7016 allocation_site.is_null() 6957 allocation_site.is_null()
7017 ? static_cast<void*>(NULL) 6958 ? static_cast<void*>(NULL)
7018 : static_cast<void*>(*allocation_site), 6959 : static_cast<void*>(*allocation_site),
7019 pretenure_flag == TENURED ? "tenured" : "not tenured"); 6960 pretenure_flag == TENURED ? "tenured" : "not tenured");
7020 } 6961 }
7021 } 6962 }
7022 6963
7023 // No side-effects except possible allocation: 6964 // No side-effects except possible allocation:
(...skipping 30 matching lines...) Expand all
7054 return new(zone) Range(0, String::kMaxUtf16CodeUnit); 6995 return new(zone) Range(0, String::kMaxUtf16CodeUnit);
7055 } 6996 }
7056 6997
7057 private: 6998 private:
7058 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { 6999 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
7059 SetOperandAt(0, context); 7000 SetOperandAt(0, context);
7060 SetOperandAt(1, string); 7001 SetOperandAt(1, string);
7061 SetOperandAt(2, index); 7002 SetOperandAt(2, index);
7062 set_representation(Representation::Integer32()); 7003 set_representation(Representation::Integer32());
7063 SetFlag(kUseGVN); 7004 SetFlag(kUseGVN);
7064 SetGVNFlag(kDependsOnMaps); 7005 SetDependsOnFlag(kMaps);
7065 SetGVNFlag(kDependsOnStringChars); 7006 SetDependsOnFlag(kStringChars);
7066 SetGVNFlag(kChangesNewSpacePromotion); 7007 SetChangesFlag(kNewSpacePromotion);
7067 } 7008 }
7068 7009
7069 // No side effects: runtime function assumes string + number inputs. 7010 // No side effects: runtime function assumes string + number inputs.
7070 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 7011 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
7071 }; 7012 };
7072 7013
7073 7014
7074 class HStringCharFromCode V8_FINAL : public HTemplateInstruction<2> { 7015 class HStringCharFromCode V8_FINAL : public HTemplateInstruction<2> {
7075 public: 7016 public:
7076 static HInstruction* New(Zone* zone, 7017 static HInstruction* New(Zone* zone,
(...skipping 13 matching lines...) Expand all
7090 7031
7091 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode) 7032 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
7092 7033
7093 private: 7034 private:
7094 HStringCharFromCode(HValue* context, HValue* char_code) 7035 HStringCharFromCode(HValue* context, HValue* char_code)
7095 : HTemplateInstruction<2>(HType::String()) { 7036 : HTemplateInstruction<2>(HType::String()) {
7096 SetOperandAt(0, context); 7037 SetOperandAt(0, context);
7097 SetOperandAt(1, char_code); 7038 SetOperandAt(1, char_code);
7098 set_representation(Representation::Tagged()); 7039 set_representation(Representation::Tagged());
7099 SetFlag(kUseGVN); 7040 SetFlag(kUseGVN);
7100 SetGVNFlag(kChangesNewSpacePromotion); 7041 SetChangesFlag(kNewSpacePromotion);
7101 } 7042 }
7102 7043
7103 virtual bool IsDeletable() const V8_OVERRIDE { 7044 virtual bool IsDeletable() const V8_OVERRIDE {
7104 return !value()->ToNumberCanBeObserved(); 7045 return !value()->ToNumberCanBeObserved();
7105 } 7046 }
7106 }; 7047 };
7107 7048
7108 7049
7109 template <int V> 7050 template <int V>
7110 class HMaterializedLiteral : public HTemplateInstruction<V> { 7051 class HMaterializedLiteral : public HTemplateInstruction<V> {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
7199 Handle<SharedFunctionInfo> shared, 7140 Handle<SharedFunctionInfo> shared,
7200 bool pretenure) 7141 bool pretenure)
7201 : HTemplateInstruction<1>(HType::JSObject()), 7142 : HTemplateInstruction<1>(HType::JSObject()),
7202 shared_info_(shared), 7143 shared_info_(shared),
7203 pretenure_(pretenure), 7144 pretenure_(pretenure),
7204 has_no_literals_(shared->num_literals() == 0), 7145 has_no_literals_(shared->num_literals() == 0),
7205 is_generator_(shared->is_generator()), 7146 is_generator_(shared->is_generator()),
7206 language_mode_(shared->language_mode()) { 7147 language_mode_(shared->language_mode()) {
7207 SetOperandAt(0, context); 7148 SetOperandAt(0, context);
7208 set_representation(Representation::Tagged()); 7149 set_representation(Representation::Tagged());
7209 SetGVNFlag(kChangesNewSpacePromotion); 7150 SetChangesFlag(kNewSpacePromotion);
7210 } 7151 }
7211 7152
7212 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 7153 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
7213 7154
7214 Handle<SharedFunctionInfo> shared_info_; 7155 Handle<SharedFunctionInfo> shared_info_;
7215 bool pretenure_ : 1; 7156 bool pretenure_ : 1;
7216 bool has_no_literals_ : 1; 7157 bool has_no_literals_ : 1;
7217 bool is_generator_ : 1; 7158 bool is_generator_ : 1;
7218 LanguageMode language_mode_; 7159 LanguageMode language_mode_;
7219 }; 7160 };
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
7270 7211
7271 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 7212 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
7272 return Representation::Tagged(); 7213 return Representation::Tagged();
7273 } 7214 }
7274 7215
7275 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties) 7216 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
7276 7217
7277 private: 7218 private:
7278 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) { 7219 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
7279 set_representation(Representation::Tagged()); 7220 set_representation(Representation::Tagged());
7280 SetGVNFlag(kChangesNewSpacePromotion); 7221 SetChangesFlag(kNewSpacePromotion);
7281 7222
7282 // This instruction is not marked as kChangesMaps, but does 7223 // This instruction is not marked as kChangesMaps, but does
7283 // change the map of the input operand. Use it only when creating 7224 // change the map of the input operand. Use it only when creating
7284 // object literals via a runtime call. 7225 // object literals via a runtime call.
7285 ASSERT(value->IsCallRuntime()); 7226 ASSERT(value->IsCallRuntime());
7286 #ifdef DEBUG 7227 #ifdef DEBUG
7287 const Runtime::Function* function = HCallRuntime::cast(value)->function(); 7228 const Runtime::Function* function = HCallRuntime::cast(value)->function();
7288 ASSERT(function->function_id == Runtime::kCreateObjectLiteral); 7229 ASSERT(function->function_id == Runtime::kCreateObjectLiteral);
7289 #endif 7230 #endif
7290 } 7231 }
7291 7232
7292 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 7233 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
7293 }; 7234 };
7294 7235
7295 7236
7296 class HValueOf V8_FINAL : public HUnaryOperation {
7297 public:
7298 DECLARE_INSTRUCTION_FACTORY_P1(HValueOf, HValue*);
7299
7300 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
7301 return Representation::Tagged();
7302 }
7303
7304 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
7305
7306 private:
7307 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
7308 set_representation(Representation::Tagged());
7309 }
7310
7311 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
7312 };
7313
7314
7315 class HDateField V8_FINAL : public HUnaryOperation { 7237 class HDateField V8_FINAL : public HUnaryOperation {
7316 public: 7238 public:
7317 DECLARE_INSTRUCTION_FACTORY_P2(HDateField, HValue*, Smi*); 7239 DECLARE_INSTRUCTION_FACTORY_P2(HDateField, HValue*, Smi*);
7318 7240
7319 Smi* index() const { return index_; } 7241 Smi* index() const { return index_; }
7320 7242
7321 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 7243 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
7322 return Representation::Tagged(); 7244 return Representation::Tagged();
7323 } 7245 }
7324 7246
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
7368 } 7290 }
7369 7291
7370 private: 7292 private:
7371 HSeqStringGetChar(String::Encoding encoding, 7293 HSeqStringGetChar(String::Encoding encoding,
7372 HValue* string, 7294 HValue* string,
7373 HValue* index) : encoding_(encoding) { 7295 HValue* index) : encoding_(encoding) {
7374 SetOperandAt(0, string); 7296 SetOperandAt(0, string);
7375 SetOperandAt(1, index); 7297 SetOperandAt(1, index);
7376 set_representation(Representation::Integer32()); 7298 set_representation(Representation::Integer32());
7377 SetFlag(kUseGVN); 7299 SetFlag(kUseGVN);
7378 SetGVNFlag(kDependsOnStringChars); 7300 SetDependsOnFlag(kStringChars);
7379 } 7301 }
7380 7302
7381 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 7303 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
7382 7304
7383 String::Encoding encoding_; 7305 String::Encoding encoding_;
7384 }; 7306 };
7385 7307
7386 7308
7387 class HSeqStringSetChar V8_FINAL : public HTemplateInstruction<4> { 7309 class HSeqStringSetChar V8_FINAL : public HTemplateInstruction<4> {
7388 public: 7310 public:
(...skipping 18 matching lines...) Expand all
7407 HSeqStringSetChar(HValue* context, 7329 HSeqStringSetChar(HValue* context,
7408 String::Encoding encoding, 7330 String::Encoding encoding,
7409 HValue* string, 7331 HValue* string,
7410 HValue* index, 7332 HValue* index,
7411 HValue* value) : encoding_(encoding) { 7333 HValue* value) : encoding_(encoding) {
7412 SetOperandAt(0, context); 7334 SetOperandAt(0, context);
7413 SetOperandAt(1, string); 7335 SetOperandAt(1, string);
7414 SetOperandAt(2, index); 7336 SetOperandAt(2, index);
7415 SetOperandAt(3, value); 7337 SetOperandAt(3, value);
7416 set_representation(Representation::Tagged()); 7338 set_representation(Representation::Tagged());
7417 SetGVNFlag(kChangesStringChars); 7339 SetChangesFlag(kStringChars);
7418 } 7340 }
7419 7341
7420 String::Encoding encoding_; 7342 String::Encoding encoding_;
7421 }; 7343 };
7422 7344
7423 7345
7424 class HCheckMapValue V8_FINAL : public HTemplateInstruction<2> { 7346 class HCheckMapValue V8_FINAL : public HTemplateInstruction<2> {
7425 public: 7347 public:
7426 DECLARE_INSTRUCTION_FACTORY_P2(HCheckMapValue, HValue*, HValue*); 7348 DECLARE_INSTRUCTION_FACTORY_P2(HCheckMapValue, HValue*, HValue*);
7427 7349
(...skipping 19 matching lines...) Expand all
7447 return true; 7369 return true;
7448 } 7370 }
7449 7371
7450 private: 7372 private:
7451 HCheckMapValue(HValue* value, 7373 HCheckMapValue(HValue* value,
7452 HValue* map) { 7374 HValue* map) {
7453 SetOperandAt(0, value); 7375 SetOperandAt(0, value);
7454 SetOperandAt(1, map); 7376 SetOperandAt(1, map);
7455 set_representation(Representation::Tagged()); 7377 set_representation(Representation::Tagged());
7456 SetFlag(kUseGVN); 7378 SetFlag(kUseGVN);
7457 SetGVNFlag(kDependsOnMaps); 7379 SetDependsOnFlag(kMaps);
7458 SetGVNFlag(kDependsOnElementsKind); 7380 SetDependsOnFlag(kElementsKind);
7459 } 7381 }
7460 }; 7382 };
7461 7383
7462 7384
7463 class HForInPrepareMap V8_FINAL : public HTemplateInstruction<2> { 7385 class HForInPrepareMap V8_FINAL : public HTemplateInstruction<2> {
7464 public: 7386 public:
7465 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HForInPrepareMap, HValue*); 7387 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HForInPrepareMap, HValue*);
7466 7388
7467 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 7389 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
7468 return Representation::Tagged(); 7390 return Representation::Tagged();
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
7560 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 7482 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
7561 }; 7483 };
7562 7484
7563 7485
7564 #undef DECLARE_INSTRUCTION 7486 #undef DECLARE_INSTRUCTION
7565 #undef DECLARE_CONCRETE_INSTRUCTION 7487 #undef DECLARE_CONCRETE_INSTRUCTION
7566 7488
7567 } } // namespace v8::internal 7489 } } // namespace v8::internal
7568 7490
7569 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 7491 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« no previous file with comments | « src/hydrogen-gvn.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698