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

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

Issue 181453002: Reset trunk to 3.24.35.4 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 6 years, 10 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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 LChunkBuilder* builder) V8_FINAL V8_OVERRIDE; \ 217 LChunkBuilder* builder) V8_FINAL V8_OVERRIDE; \
218 static H##type* cast(HValue* value) { \ 218 static H##type* cast(HValue* value) { \
219 ASSERT(value->Is##type()); \ 219 ASSERT(value->Is##type()); \
220 return reinterpret_cast<H##type*>(value); \ 220 return reinterpret_cast<H##type*>(value); \
221 } \ 221 } \
222 virtual Opcode opcode() const V8_FINAL V8_OVERRIDE { \ 222 virtual Opcode opcode() const V8_FINAL V8_OVERRIDE { \
223 return HValue::k##type; \ 223 return HValue::k##type; \
224 } 224 }
225 225
226 226
227 enum PropertyAccessType { LOAD, STORE };
228
229
230 class Range V8_FINAL : public ZoneObject { 227 class Range V8_FINAL : public ZoneObject {
231 public: 228 public:
232 Range() 229 Range()
233 : lower_(kMinInt), 230 : lower_(kMinInt),
234 upper_(kMaxInt), 231 upper_(kMaxInt),
235 next_(NULL), 232 next_(NULL),
236 can_be_minus_zero_(false) { } 233 can_be_minus_zero_(false) { }
237 234
238 Range(int32_t lower, int32_t upper) 235 Range(int32_t lower, int32_t upper)
239 : lower_(lower), 236 : lower_(lower),
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 466
470 HUseListNode* current_; 467 HUseListNode* current_;
471 HUseListNode* next_; 468 HUseListNode* next_;
472 HValue* value_; 469 HValue* value_;
473 int index_; 470 int index_;
474 471
475 friend class HValue; 472 friend class HValue;
476 }; 473 };
477 474
478 475
479 // All tracked flags should appear before untracked ones. 476 // There must be one corresponding kDepends flag for every kChanges flag and
477 // the order of the kChanges flags must be exactly the same as of the kDepends
478 // flags. All tracked flags should appear before untracked ones.
480 enum GVNFlag { 479 enum GVNFlag {
481 // Declare global value numbering flags. 480 // Declare global value numbering flags.
482 #define DECLARE_FLAG(Type) k##Type, 481 #define DECLARE_FLAG(type) kChanges##type, kDependsOn##type,
483 GVN_TRACKED_FLAG_LIST(DECLARE_FLAG) 482 GVN_TRACKED_FLAG_LIST(DECLARE_FLAG)
484 GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG) 483 GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
485 #undef DECLARE_FLAG 484 #undef DECLARE_FLAG
486 #define COUNT_FLAG(Type) + 1 485 kNumberOfFlags,
487 kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG), 486 #define COUNT_FLAG(type) + 1
488 kNumberOfUntrackedSideEffects = 0 GVN_UNTRACKED_FLAG_LIST(COUNT_FLAG), 487 kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG)
489 #undef COUNT_FLAG 488 #undef COUNT_FLAG
490 kNumberOfFlags = kNumberOfTrackedSideEffects + kNumberOfUntrackedSideEffects
491 }; 489 };
492 490
493 491
494 static inline GVNFlag GVNFlagFromInt(int i) {
495 ASSERT(i >= 0);
496 ASSERT(i < kNumberOfFlags);
497 return static_cast<GVNFlag>(i);
498 }
499
500
501 class DecompositionResult V8_FINAL BASE_EMBEDDED { 492 class DecompositionResult V8_FINAL BASE_EMBEDDED {
502 public: 493 public:
503 DecompositionResult() : base_(NULL), offset_(0), scale_(0) {} 494 DecompositionResult() : base_(NULL), offset_(0), scale_(0) {}
504 495
505 HValue* base() { return base_; } 496 HValue* base() { return base_; }
506 int offset() { return offset_; } 497 int offset() { return offset_; }
507 int scale() { return scale_; } 498 int scale() { return scale_; }
508 499
509 bool Apply(HValue* other_base, int other_offset, int other_scale = 0) { 500 bool Apply(HValue* other_base, int other_offset, int other_scale = 0) {
510 if (base_ == NULL) { 501 if (base_ == NULL) {
(...skipping 25 matching lines...) Expand all
536 *a = *b; 527 *a = *b;
537 *b = c; 528 *b = c;
538 } 529 }
539 530
540 HValue* base_; 531 HValue* base_;
541 int offset_; 532 int offset_;
542 int scale_; 533 int scale_;
543 }; 534 };
544 535
545 536
546 typedef EnumSet<GVNFlag, int32_t> GVNFlagSet; 537 typedef EnumSet<GVNFlag, int64_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 };
602 538
603 539
604 class HValue : public ZoneObject { 540 class HValue : public ZoneObject {
605 public: 541 public:
606 static const int kNoNumber = -1; 542 static const int kNoNumber = -1;
607 543
608 enum Flag { 544 enum Flag {
609 kFlexibleRepresentation, 545 kFlexibleRepresentation,
610 kCannotBeTagged, 546 kCannotBeTagged,
611 // Participate in Global Value Numbering, i.e. elimination of 547 // Participate in Global Value Numbering, i.e. elimination of
(...skipping 30 matching lines...) Expand all
642 // HEnvironmentMarkers are deleted before dead code 578 // HEnvironmentMarkers are deleted before dead code
643 // elimination takes place, so they can repurpose the kIsLive flag: 579 // elimination takes place, so they can repurpose the kIsLive flag:
644 kEndsLiveRange = kIsLive, 580 kEndsLiveRange = kIsLive,
645 581
646 // TODO(everyone): Don't forget to update this! 582 // TODO(everyone): Don't forget to update this!
647 kLastFlag = kIsLive 583 kLastFlag = kIsLive
648 }; 584 };
649 585
650 STATIC_ASSERT(kLastFlag < kBitsPerInt); 586 STATIC_ASSERT(kLastFlag < kBitsPerInt);
651 587
588 static const int kChangesToDependsFlagsLeftShift = 1;
589
590 static GVNFlag ChangesFlagFromInt(int x) {
591 return static_cast<GVNFlag>(x * 2);
592 }
593 static GVNFlag DependsOnFlagFromInt(int x) {
594 return static_cast<GVNFlag>(x * 2 + 1);
595 }
596 static GVNFlagSet ConvertChangesToDependsFlags(GVNFlagSet flags) {
597 return GVNFlagSet(flags.ToIntegral() << kChangesToDependsFlagsLeftShift);
598 }
599
652 static HValue* cast(HValue* value) { return value; } 600 static HValue* cast(HValue* value) { return value; }
653 601
654 enum Opcode { 602 enum Opcode {
655 // Declare a unique enum value for each hydrogen instruction. 603 // Declare a unique enum value for each hydrogen instruction.
656 #define DECLARE_OPCODE(type) k##type, 604 #define DECLARE_OPCODE(type) k##type,
657 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE) 605 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
658 kPhi 606 kPhi
659 #undef DECLARE_OPCODE 607 #undef DECLARE_OPCODE
660 }; 608 };
661 virtual Opcode opcode() const = 0; 609 virtual Opcode opcode() const = 0;
(...skipping 13 matching lines...) Expand all
675 623
676 HValue(HType type = HType::Tagged()) 624 HValue(HType type = HType::Tagged())
677 : block_(NULL), 625 : block_(NULL),
678 id_(kNoNumber), 626 id_(kNoNumber),
679 type_(type), 627 type_(type),
680 use_list_(NULL), 628 use_list_(NULL),
681 range_(NULL), 629 range_(NULL),
682 flags_(0) {} 630 flags_(0) {}
683 virtual ~HValue() {} 631 virtual ~HValue() {}
684 632
685 virtual HSourcePosition position() const { 633 virtual int position() const { return RelocInfo::kNoPosition; }
686 return HSourcePosition::Unknown(); 634 virtual int operand_position(int index) const { return position(); }
687 }
688 virtual HSourcePosition operand_position(int index) const {
689 return position();
690 }
691 635
692 HBasicBlock* block() const { return block_; } 636 HBasicBlock* block() const { return block_; }
693 void SetBlock(HBasicBlock* block); 637 void SetBlock(HBasicBlock* block);
694 638
695 // Note: Never call this method for an unlinked value. 639 // Note: Never call this method for an unlinked value.
696 Isolate* isolate() const; 640 Isolate* isolate() const;
697 641
698 int id() const { return id_; } 642 int id() const { return id_; }
699 void set_id(int id) { id_ = id; } 643 void set_id(int id) { id_ = id; }
700 644
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 } 765 }
822 766
823 // Returns true if the flag specified is set for all uses, false otherwise. 767 // Returns true if the flag specified is set for all uses, false otherwise.
824 bool CheckUsesForFlag(Flag f) const; 768 bool CheckUsesForFlag(Flag f) const;
825 // Same as before and the first one without the flag is returned in value. 769 // Same as before and the first one without the flag is returned in value.
826 bool CheckUsesForFlag(Flag f, HValue** value) const; 770 bool CheckUsesForFlag(Flag f, HValue** value) const;
827 // Returns true if the flag specified is set for all uses, and this set 771 // Returns true if the flag specified is set for all uses, and this set
828 // of uses is non-empty. 772 // of uses is non-empty.
829 bool HasAtLeastOneUseWithFlagAndNoneWithout(Flag f) const; 773 bool HasAtLeastOneUseWithFlagAndNoneWithout(Flag f) const;
830 774
831 GVNFlagSet ChangesFlags() const { return changes_flags_; } 775 GVNFlagSet gvn_flags() const { return gvn_flags_; }
832 GVNFlagSet DependsOnFlags() const { return depends_on_flags_; } 776 void SetGVNFlag(GVNFlag f) { gvn_flags_.Add(f); }
833 void SetChangesFlag(GVNFlag f) { changes_flags_.Add(f); } 777 void ClearGVNFlag(GVNFlag f) { gvn_flags_.Remove(f); }
834 void SetDependsOnFlag(GVNFlag f) { depends_on_flags_.Add(f); } 778 bool CheckGVNFlag(GVNFlag f) const { return gvn_flags_.Contains(f); }
835 void ClearChangesFlag(GVNFlag f) { changes_flags_.Remove(f); } 779 void SetAllSideEffects() { gvn_flags_.Add(AllSideEffectsFlagSet()); }
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()); }
844 void ClearAllSideEffects() { 780 void ClearAllSideEffects() {
845 changes_flags_.Remove(AllSideEffectsFlagSet()); 781 gvn_flags_.Remove(AllSideEffectsFlagSet());
846 } 782 }
847 bool HasSideEffects() const { 783 bool HasSideEffects() const {
848 return changes_flags_.ContainsAnyOf(AllSideEffectsFlagSet()); 784 return gvn_flags_.ContainsAnyOf(AllSideEffectsFlagSet());
849 } 785 }
850 bool HasObservableSideEffects() const { 786 bool HasObservableSideEffects() const {
851 return !CheckFlag(kHasNoObservableSideEffects) && 787 return !CheckFlag(kHasNoObservableSideEffects) &&
852 changes_flags_.ContainsAnyOf(AllObservableSideEffectsFlagSet()); 788 gvn_flags_.ContainsAnyOf(AllObservableSideEffectsFlagSet());
789 }
790
791 GVNFlagSet DependsOnFlags() const {
792 GVNFlagSet result = gvn_flags_;
793 result.Intersect(AllDependsOnFlagSet());
794 return result;
853 } 795 }
854 796
855 GVNFlagSet SideEffectFlags() const { 797 GVNFlagSet SideEffectFlags() const {
856 GVNFlagSet result = ChangesFlags(); 798 GVNFlagSet result = gvn_flags_;
857 result.Intersect(AllSideEffectsFlagSet()); 799 result.Intersect(AllSideEffectsFlagSet());
858 return result; 800 return result;
859 } 801 }
860 802
803 GVNFlagSet ChangesFlags() const {
804 GVNFlagSet result = gvn_flags_;
805 result.Intersect(AllChangesFlagSet());
806 return result;
807 }
808
861 GVNFlagSet ObservableChangesFlags() const { 809 GVNFlagSet ObservableChangesFlags() const {
862 GVNFlagSet result = ChangesFlags(); 810 GVNFlagSet result = gvn_flags_;
811 result.Intersect(AllChangesFlagSet());
863 result.Intersect(AllObservableSideEffectsFlagSet()); 812 result.Intersect(AllObservableSideEffectsFlagSet());
864 return result; 813 return result;
865 } 814 }
866 815
867 Range* range() const { return range_; } 816 Range* range() const { return range_; }
868 // TODO(svenpanne) We should really use the null object pattern here. 817 // TODO(svenpanne) We should really use the null object pattern here.
869 bool HasRange() const { return range_ != NULL; } 818 bool HasRange() const { return range_ != NULL; }
870 bool CanBeNegative() const { return !HasRange() || range()->CanBeNegative(); } 819 bool CanBeNegative() const { return !HasRange() || range()->CanBeNegative(); }
871 bool CanBeZero() const { return !HasRange() || range()->CanBeZero(); } 820 bool CanBeZero() const { return !HasRange() || range()->CanBeZero(); }
872 bool RangeCanInclude(int value) const { 821 bool RangeCanInclude(int value) const {
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 void clear_block() { 942 void clear_block() {
994 ASSERT(block_ != NULL); 943 ASSERT(block_ != NULL);
995 block_ = NULL; 944 block_ = NULL;
996 } 945 }
997 946
998 void set_representation(Representation r) { 947 void set_representation(Representation r) {
999 ASSERT(representation_.IsNone() && !r.IsNone()); 948 ASSERT(representation_.IsNone() && !r.IsNone());
1000 representation_ = r; 949 representation_ = r;
1001 } 950 }
1002 951
1003 static GVNFlagSet AllFlagSet() { 952 static GVNFlagSet AllDependsOnFlagSet() {
1004 GVNFlagSet result; 953 GVNFlagSet result;
1005 #define ADD_FLAG(Type) result.Add(k##Type); 954 // Create changes mask.
955 #define ADD_FLAG(type) result.Add(kDependsOn##type);
1006 GVN_TRACKED_FLAG_LIST(ADD_FLAG) 956 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
1007 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG) 957 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
1008 #undef ADD_FLAG 958 #undef ADD_FLAG
959 return result;
960 }
961
962 static GVNFlagSet AllChangesFlagSet() {
963 GVNFlagSet result;
964 // Create changes mask.
965 #define ADD_FLAG(type) result.Add(kChanges##type);
966 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
967 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
968 #undef ADD_FLAG
1009 return result; 969 return result;
1010 } 970 }
1011 971
1012 // A flag mask to mark an instruction as having arbitrary side effects. 972 // A flag mask to mark an instruction as having arbitrary side effects.
1013 static GVNFlagSet AllSideEffectsFlagSet() { 973 static GVNFlagSet AllSideEffectsFlagSet() {
1014 GVNFlagSet result = AllFlagSet(); 974 GVNFlagSet result = AllChangesFlagSet();
1015 result.Remove(kOsrEntries); 975 result.Remove(kChangesOsrEntries);
1016 return result; 976 return result;
1017 } 977 }
1018 978
1019 // A flag mask of all side effects that can make observable changes in 979 // A flag mask of all side effects that can make observable changes in
1020 // an executing program (i.e. are not safe to repeat, move or remove); 980 // an executing program (i.e. are not safe to repeat, move or remove);
1021 static GVNFlagSet AllObservableSideEffectsFlagSet() { 981 static GVNFlagSet AllObservableSideEffectsFlagSet() {
1022 GVNFlagSet result = AllFlagSet(); 982 GVNFlagSet result = AllChangesFlagSet();
1023 result.Remove(kNewSpacePromotion); 983 result.Remove(kChangesNewSpacePromotion);
1024 result.Remove(kElementsKind); 984 result.Remove(kChangesElementsKind);
1025 result.Remove(kElementsPointer); 985 result.Remove(kChangesElementsPointer);
1026 result.Remove(kMaps); 986 result.Remove(kChangesMaps);
1027 return result; 987 return result;
1028 } 988 }
1029 989
1030 // Remove the matching use from the use list if present. Returns the 990 // Remove the matching use from the use list if present. Returns the
1031 // removed list node or NULL. 991 // removed list node or NULL.
1032 HUseListNode* RemoveUse(HValue* value, int index); 992 HUseListNode* RemoveUse(HValue* value, int index);
1033 993
1034 void RegisterUse(int index, HValue* new_value); 994 void RegisterUse(int index, HValue* new_value);
1035 995
1036 HBasicBlock* block_; 996 HBasicBlock* block_;
1037 997
1038 // The id of this instruction in the hydrogen graph, assigned when first 998 // The id of this instruction in the hydrogen graph, assigned when first
1039 // added to the graph. Reflects creation order. 999 // added to the graph. Reflects creation order.
1040 int id_; 1000 int id_;
1041 1001
1042 Representation representation_; 1002 Representation representation_;
1043 HType type_; 1003 HType type_;
1044 HUseListNode* use_list_; 1004 HUseListNode* use_list_;
1045 Range* range_; 1005 Range* range_;
1046 int flags_; 1006 int flags_;
1047 GVNFlagSet changes_flags_; 1007 GVNFlagSet gvn_flags_;
1048 GVNFlagSet depends_on_flags_;
1049 1008
1050 private: 1009 private:
1051 virtual bool IsDeletable() const { return false; } 1010 virtual bool IsDeletable() const { return false; }
1052 1011
1053 DISALLOW_COPY_AND_ASSIGN(HValue); 1012 DISALLOW_COPY_AND_ASSIGN(HValue);
1054 }; 1013 };
1055 1014
1056 1015
1057 #define DECLARE_INSTRUCTION_FACTORY_P0(I) \ 1016 #define DECLARE_INSTRUCTION_FACTORY_P0(I) \
1058 static I* New(Zone* zone, HValue* context) { \ 1017 static I* New(Zone* zone, HValue* context) { \
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1137 } 1096 }
1138 1097
1139 1098
1140 // A helper class to represent per-operand position information attached to 1099 // A helper class to represent per-operand position information attached to
1141 // the HInstruction in the compact form. Uses tagging to distinguish between 1100 // the HInstruction in the compact form. Uses tagging to distinguish between
1142 // case when only instruction's position is available and case when operands' 1101 // case when only instruction's position is available and case when operands'
1143 // positions are also available. 1102 // positions are also available.
1144 // In the first case it contains intruction's position as a tagged value. 1103 // In the first case it contains intruction's position as a tagged value.
1145 // In the second case it points to an array which contains instruction's 1104 // In the second case it points to an array which contains instruction's
1146 // position and operands' positions. 1105 // position and operands' positions.
1106 // TODO(vegorov): what we really want to track here is a combination of
1107 // source position and a script id because cross script inlining can easily
1108 // result in optimized functions composed of several scripts.
1147 class HPositionInfo { 1109 class HPositionInfo {
1148 public: 1110 public:
1149 explicit HPositionInfo(int pos) : data_(TagPosition(pos)) { } 1111 explicit HPositionInfo(int pos) : data_(TagPosition(pos)) { }
1150 1112
1151 HSourcePosition position() const { 1113 int position() const {
1152 if (has_operand_positions()) { 1114 if (has_operand_positions()) {
1153 return operand_positions()[kInstructionPosIndex]; 1115 return static_cast<int>(operand_positions()[kInstructionPosIndex]);
1154 } 1116 }
1155 return HSourcePosition(static_cast<int>(UntagPosition(data_))); 1117 return static_cast<int>(UntagPosition(data_));
1156 } 1118 }
1157 1119
1158 void set_position(HSourcePosition pos) { 1120 void set_position(int pos) {
1159 if (has_operand_positions()) { 1121 if (has_operand_positions()) {
1160 operand_positions()[kInstructionPosIndex] = pos; 1122 operand_positions()[kInstructionPosIndex] = pos;
1161 } else { 1123 } else {
1162 data_ = TagPosition(pos.raw()); 1124 data_ = TagPosition(pos);
1163 } 1125 }
1164 } 1126 }
1165 1127
1166 void ensure_storage_for_operand_positions(Zone* zone, int operand_count) { 1128 void ensure_storage_for_operand_positions(Zone* zone, int operand_count) {
1167 if (has_operand_positions()) { 1129 if (has_operand_positions()) {
1168 return; 1130 return;
1169 } 1131 }
1170 1132
1171 const int length = kFirstOperandPosIndex + operand_count; 1133 const int length = kFirstOperandPosIndex + operand_count;
1172 HSourcePosition* positions = 1134 intptr_t* positions =
1173 zone->NewArray<HSourcePosition>(length); 1135 zone->NewArray<intptr_t>(length);
1174 for (int i = 0; i < length; i++) { 1136 for (int i = 0; i < length; i++) {
1175 positions[i] = HSourcePosition::Unknown(); 1137 positions[i] = RelocInfo::kNoPosition;
1176 } 1138 }
1177 1139
1178 const HSourcePosition pos = position(); 1140 const int pos = position();
1179 data_ = reinterpret_cast<intptr_t>(positions); 1141 data_ = reinterpret_cast<intptr_t>(positions);
1180 set_position(pos); 1142 set_position(pos);
1181 1143
1182 ASSERT(has_operand_positions()); 1144 ASSERT(has_operand_positions());
1183 } 1145 }
1184 1146
1185 HSourcePosition operand_position(int idx) const { 1147 int operand_position(int idx) const {
1186 if (!has_operand_positions()) { 1148 if (!has_operand_positions()) {
1187 return position(); 1149 return position();
1188 } 1150 }
1189 return *operand_position_slot(idx); 1151 return static_cast<int>(*operand_position_slot(idx));
1190 } 1152 }
1191 1153
1192 void set_operand_position(int idx, HSourcePosition pos) { 1154 void set_operand_position(int idx, int pos) {
1193 *operand_position_slot(idx) = pos; 1155 *operand_position_slot(idx) = pos;
1194 } 1156 }
1195 1157
1196 private: 1158 private:
1197 static const intptr_t kInstructionPosIndex = 0; 1159 static const intptr_t kInstructionPosIndex = 0;
1198 static const intptr_t kFirstOperandPosIndex = 1; 1160 static const intptr_t kFirstOperandPosIndex = 1;
1199 1161
1200 HSourcePosition* operand_position_slot(int idx) const { 1162 intptr_t* operand_position_slot(int idx) const {
1201 ASSERT(has_operand_positions()); 1163 ASSERT(has_operand_positions());
1202 return &(operand_positions()[kFirstOperandPosIndex + idx]); 1164 return &(operand_positions()[kFirstOperandPosIndex + idx]);
1203 } 1165 }
1204 1166
1205 bool has_operand_positions() const { 1167 bool has_operand_positions() const {
1206 return !IsTaggedPosition(data_); 1168 return !IsTaggedPosition(data_);
1207 } 1169 }
1208 1170
1209 HSourcePosition* operand_positions() const { 1171 intptr_t* operand_positions() const {
1210 ASSERT(has_operand_positions()); 1172 ASSERT(has_operand_positions());
1211 return reinterpret_cast<HSourcePosition*>(data_); 1173 return reinterpret_cast<intptr_t*>(data_);
1212 } 1174 }
1213 1175
1214 static const intptr_t kPositionTag = 1; 1176 static const intptr_t kPositionTag = 1;
1215 static const intptr_t kPositionShift = 1; 1177 static const intptr_t kPositionShift = 1;
1216 static bool IsTaggedPosition(intptr_t val) { 1178 static bool IsTaggedPosition(intptr_t val) {
1217 return (val & kPositionTag) != 0; 1179 return (val & kPositionTag) != 0;
1218 } 1180 }
1219 static intptr_t UntagPosition(intptr_t val) { 1181 static intptr_t UntagPosition(intptr_t val) {
1220 ASSERT(IsTaggedPosition(val)); 1182 ASSERT(IsTaggedPosition(val));
1221 return val >> kPositionShift; 1183 return val >> kPositionShift;
(...skipping 27 matching lines...) Expand all
1249 } 1211 }
1250 1212
1251 void InsertAfter(HInstruction* previous); 1213 void InsertAfter(HInstruction* previous);
1252 1214
1253 template<class T> T* Append(T* instr) { 1215 template<class T> T* Append(T* instr) {
1254 instr->InsertAfter(this); 1216 instr->InsertAfter(this);
1255 return instr; 1217 return instr;
1256 } 1218 }
1257 1219
1258 // The position is a write-once variable. 1220 // The position is a write-once variable.
1259 virtual HSourcePosition position() const V8_OVERRIDE { 1221 virtual int position() const V8_OVERRIDE {
1260 return HSourcePosition(position_.position()); 1222 return position_.position();
1261 } 1223 }
1262 bool has_position() const { 1224 bool has_position() const {
1263 return !position().IsUnknown(); 1225 return position_.position() != RelocInfo::kNoPosition;
1264 } 1226 }
1265 void set_position(HSourcePosition position) { 1227 void set_position(int position) {
1266 ASSERT(!has_position()); 1228 ASSERT(!has_position());
1267 ASSERT(!position.IsUnknown()); 1229 ASSERT(position != RelocInfo::kNoPosition);
1268 position_.set_position(position); 1230 position_.set_position(position);
1269 } 1231 }
1270 1232
1271 virtual HSourcePosition operand_position(int index) const V8_OVERRIDE { 1233 virtual int operand_position(int index) const V8_OVERRIDE {
1272 const HSourcePosition pos = position_.operand_position(index); 1234 const int pos = position_.operand_position(index);
1273 return pos.IsUnknown() ? position() : pos; 1235 return (pos != RelocInfo::kNoPosition) ? pos : position();
1274 } 1236 }
1275 void set_operand_position(Zone* zone, int index, HSourcePosition pos) { 1237 void set_operand_position(Zone* zone, int index, int pos) {
1276 ASSERT(0 <= index && index < OperandCount()); 1238 ASSERT(0 <= index && index < OperandCount());
1277 position_.ensure_storage_for_operand_positions(zone, OperandCount()); 1239 position_.ensure_storage_for_operand_positions(zone, OperandCount());
1278 position_.set_operand_position(index, pos); 1240 position_.set_operand_position(index, pos);
1279 } 1241 }
1280 1242
1281 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); } 1243 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
1282 1244
1283 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0; 1245 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
1284 1246
1285 #ifdef DEBUG 1247 #ifdef DEBUG
1286 virtual void Verify() V8_OVERRIDE; 1248 virtual void Verify() V8_OVERRIDE;
1287 #endif 1249 #endif
1288 1250
1289 virtual bool HasStackCheck() { return false; } 1251 virtual bool HasStackCheck() { return false; }
1290 1252
1291 DECLARE_ABSTRACT_INSTRUCTION(Instruction) 1253 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
1292 1254
1293 protected: 1255 protected:
1294 HInstruction(HType type = HType::Tagged()) 1256 HInstruction(HType type = HType::Tagged())
1295 : HValue(type), 1257 : HValue(type),
1296 next_(NULL), 1258 next_(NULL),
1297 previous_(NULL), 1259 previous_(NULL),
1298 position_(RelocInfo::kNoPosition) { 1260 position_(RelocInfo::kNoPosition) {
1299 SetDependsOnFlag(kOsrEntries); 1261 SetGVNFlag(kDependsOnOsrEntries);
1300 } 1262 }
1301 1263
1302 virtual void DeleteFromGraph() V8_OVERRIDE { Unlink(); } 1264 virtual void DeleteFromGraph() V8_OVERRIDE { Unlink(); }
1303 1265
1304 private: 1266 private:
1305 void InitializeAsFirst(HBasicBlock* block) { 1267 void InitializeAsFirst(HBasicBlock* block) {
1306 ASSERT(!IsLinked()); 1268 ASSERT(!IsLinked());
1307 SetBlock(block); 1269 SetBlock(block);
1308 } 1270 }
1309 1271
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
1557 expected_input_types_(expected_input_types) { 1519 expected_input_types_(expected_input_types) {
1558 SetFlag(kAllowUndefinedAsNaN); 1520 SetFlag(kAllowUndefinedAsNaN);
1559 } 1521 }
1560 1522
1561 ToBooleanStub::Types expected_input_types_; 1523 ToBooleanStub::Types expected_input_types_;
1562 }; 1524 };
1563 1525
1564 1526
1565 class HCompareMap V8_FINAL : public HUnaryControlInstruction { 1527 class HCompareMap V8_FINAL : public HUnaryControlInstruction {
1566 public: 1528 public:
1567 DECLARE_INSTRUCTION_FACTORY_P3(HCompareMap, HValue*, Handle<Map>, 1529 DECLARE_INSTRUCTION_FACTORY_P2(HCompareMap, HValue*, Handle<Map>);
1568 CompilationInfo*); 1530 DECLARE_INSTRUCTION_FACTORY_P4(HCompareMap, HValue*, Handle<Map>,
1569 DECLARE_INSTRUCTION_FACTORY_P5(HCompareMap, HValue*, Handle<Map>,
1570 CompilationInfo*,
1571 HBasicBlock*, HBasicBlock*); 1531 HBasicBlock*, HBasicBlock*);
1572 1532
1573 virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE { 1533 virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE {
1574 if (known_successor_index() != kNoKnownSuccessorIndex) { 1534 if (known_successor_index() != kNoKnownSuccessorIndex) {
1575 *block = SuccessorAt(known_successor_index()); 1535 *block = SuccessorAt(known_successor_index());
1576 return true; 1536 return true;
1577 } 1537 }
1578 *block = NULL; 1538 *block = NULL;
1579 return false; 1539 return false;
1580 } 1540 }
1581 1541
1582 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 1542 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
1583 1543
1584 static const int kNoKnownSuccessorIndex = -1; 1544 static const int kNoKnownSuccessorIndex = -1;
1585 int known_successor_index() const { return known_successor_index_; } 1545 int known_successor_index() const { return known_successor_index_; }
1586 void set_known_successor_index(int known_successor_index) { 1546 void set_known_successor_index(int known_successor_index) {
1587 known_successor_index_ = known_successor_index; 1547 known_successor_index_ = known_successor_index;
1588 } 1548 }
1589 1549
1590 Unique<Map> map() const { return map_; } 1550 Unique<Map> map() const { return map_; }
1591 1551
1592 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 1552 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
1593 return Representation::Tagged(); 1553 return Representation::Tagged();
1594 } 1554 }
1595 1555
1596 bool is_stable() const {
1597 return is_stable_;
1598 }
1599
1600 DECLARE_CONCRETE_INSTRUCTION(CompareMap) 1556 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
1601 1557
1602 protected: 1558 protected:
1603 virtual int RedefinedOperandIndex() { return 0; } 1559 virtual int RedefinedOperandIndex() { return 0; }
1604 1560
1605 private: 1561 private:
1606 HCompareMap(HValue* value, 1562 HCompareMap(HValue* value,
1607 Handle<Map> map, 1563 Handle<Map> map,
1608 CompilationInfo* info,
1609 HBasicBlock* true_target = NULL, 1564 HBasicBlock* true_target = NULL,
1610 HBasicBlock* false_target = NULL) 1565 HBasicBlock* false_target = NULL)
1611 : HUnaryControlInstruction(value, true_target, false_target), 1566 : HUnaryControlInstruction(value, true_target, false_target),
1612 known_successor_index_(kNoKnownSuccessorIndex), map_(Unique<Map>(map)) { 1567 known_successor_index_(kNoKnownSuccessorIndex), map_(Unique<Map>(map)) {
1613 ASSERT(!map.is_null()); 1568 ASSERT(!map.is_null());
1614 is_stable_ = map->is_stable();
1615
1616 if (is_stable_) {
1617 map->AddDependentCompilationInfo(
1618 DependentCode::kPrototypeCheckGroup, info);
1619 }
1620 } 1569 }
1621 1570
1622 int known_successor_index_; 1571 int known_successor_index_;
1623 bool is_stable_;
1624 Unique<Map> map_; 1572 Unique<Map> map_;
1625 }; 1573 };
1626 1574
1627 1575
1628 class HContext V8_FINAL : public HTemplateInstruction<0> { 1576 class HContext V8_FINAL : public HTemplateInstruction<0> {
1629 public: 1577 public:
1630 static HContext* New(Zone* zone) { 1578 static HContext* New(Zone* zone) {
1631 return new(zone) HContext(); 1579 return new(zone) HContext();
1632 } 1580 }
1633 1581
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1763 SetFlag(kUseGVN); 1711 SetFlag(kUseGVN);
1764 if (is_truncating_to_smi) { 1712 if (is_truncating_to_smi) {
1765 SetFlag(kTruncatingToSmi); 1713 SetFlag(kTruncatingToSmi);
1766 SetFlag(kTruncatingToInt32); 1714 SetFlag(kTruncatingToInt32);
1767 } 1715 }
1768 if (is_truncating_to_int32) SetFlag(kTruncatingToInt32); 1716 if (is_truncating_to_int32) SetFlag(kTruncatingToInt32);
1769 if (value->representation().IsSmi() || value->type().IsSmi()) { 1717 if (value->representation().IsSmi() || value->type().IsSmi()) {
1770 set_type(HType::Smi()); 1718 set_type(HType::Smi());
1771 } else { 1719 } else {
1772 set_type(HType::TaggedNumber()); 1720 set_type(HType::TaggedNumber());
1773 if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion); 1721 if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion);
1774 } 1722 }
1775 } 1723 }
1776 1724
1777 bool can_convert_undefined_to_nan() { 1725 bool can_convert_undefined_to_nan() {
1778 return CheckUsesForFlag(kAllowUndefinedAsNaN); 1726 return CheckUsesForFlag(kAllowUndefinedAsNaN);
1779 } 1727 }
1780 1728
1781 virtual HValue* EnsureAndPropagateNotMinusZero( 1729 virtual HValue* EnsureAndPropagateNotMinusZero(
1782 BitVector* visited) V8_OVERRIDE; 1730 BitVector* visited) V8_OVERRIDE;
1783 virtual HType CalculateInferredType() V8_OVERRIDE; 1731 virtual HType CalculateInferredType() V8_OVERRIDE;
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
2009 } 1957 }
2010 1958
2011 bool is_function_entry() { return type_ == kFunctionEntry; } 1959 bool is_function_entry() { return type_ == kFunctionEntry; }
2012 bool is_backwards_branch() { return type_ == kBackwardsBranch; } 1960 bool is_backwards_branch() { return type_ == kBackwardsBranch; }
2013 1961
2014 DECLARE_CONCRETE_INSTRUCTION(StackCheck) 1962 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
2015 1963
2016 private: 1964 private:
2017 HStackCheck(HValue* context, Type type) : type_(type) { 1965 HStackCheck(HValue* context, Type type) : type_(type) {
2018 SetOperandAt(0, context); 1966 SetOperandAt(0, context);
2019 SetChangesFlag(kNewSpacePromotion); 1967 SetGVNFlag(kChangesNewSpacePromotion);
2020 } 1968 }
2021 1969
2022 Type type_; 1970 Type type_;
2023 }; 1971 };
2024 1972
2025 1973
2026 enum InliningKind { 1974 enum InliningKind {
2027 NORMAL_RETURN, // Drop the function from the environment on return. 1975 NORMAL_RETURN, // Drop the function from the environment on return.
2028 CONSTRUCT_CALL_RETURN, // Either use allocated receiver or return value. 1976 CONSTRUCT_CALL_RETURN, // Either use allocated receiver or return value.
2029 GETTER_CALL_RETURN, // Returning from a getter, need to restore context. 1977 GETTER_CALL_RETURN, // Returning from a getter, need to restore context.
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after
2557 DECLARE_CONCRETE_INSTRUCTION(MapEnumLength) 2505 DECLARE_CONCRETE_INSTRUCTION(MapEnumLength)
2558 2506
2559 protected: 2507 protected:
2560 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } 2508 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
2561 2509
2562 private: 2510 private:
2563 explicit HMapEnumLength(HValue* value) 2511 explicit HMapEnumLength(HValue* value)
2564 : HUnaryOperation(value, HType::Smi()) { 2512 : HUnaryOperation(value, HType::Smi()) {
2565 set_representation(Representation::Smi()); 2513 set_representation(Representation::Smi());
2566 SetFlag(kUseGVN); 2514 SetFlag(kUseGVN);
2567 SetDependsOnFlag(kMaps); 2515 SetGVNFlag(kDependsOnMaps);
2568 } 2516 }
2569 2517
2570 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 2518 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
2571 }; 2519 };
2572 2520
2573 2521
2574 class HUnaryMathOperation V8_FINAL : public HTemplateInstruction<2> { 2522 class HUnaryMathOperation V8_FINAL : public HTemplateInstruction<2> {
2575 public: 2523 public:
2576 static HInstruction* New(Zone* zone, 2524 static HInstruction* New(Zone* zone,
2577 HValue* context, 2525 HValue* context,
(...skipping 15 matching lines...) Expand all
2593 switch (op_) { 2541 switch (op_) {
2594 case kMathFloor: 2542 case kMathFloor:
2595 case kMathRound: 2543 case kMathRound:
2596 case kMathSqrt: 2544 case kMathSqrt:
2597 case kMathPowHalf: 2545 case kMathPowHalf:
2598 case kMathLog: 2546 case kMathLog:
2599 case kMathExp: 2547 case kMathExp:
2600 return Representation::Double(); 2548 return Representation::Double();
2601 case kMathAbs: 2549 case kMathAbs:
2602 return representation(); 2550 return representation();
2603 case kMathClz32:
2604 return Representation::Integer32();
2605 default: 2551 default:
2606 UNREACHABLE(); 2552 UNREACHABLE();
2607 return Representation::None(); 2553 return Representation::None();
2608 } 2554 }
2609 } 2555 }
2610 } 2556 }
2611 2557
2612 virtual Range* InferRange(Zone* zone) V8_OVERRIDE; 2558 virtual Range* InferRange(Zone* zone) V8_OVERRIDE;
2613 2559
2614 virtual HValue* Canonicalize() V8_OVERRIDE; 2560 virtual HValue* Canonicalize() V8_OVERRIDE;
(...skipping 11 matching lines...) Expand all
2626 } 2572 }
2627 2573
2628 private: 2574 private:
2629 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op) 2575 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
2630 : HTemplateInstruction<2>(HType::TaggedNumber()), op_(op) { 2576 : HTemplateInstruction<2>(HType::TaggedNumber()), op_(op) {
2631 SetOperandAt(0, context); 2577 SetOperandAt(0, context);
2632 SetOperandAt(1, value); 2578 SetOperandAt(1, value);
2633 switch (op) { 2579 switch (op) {
2634 case kMathFloor: 2580 case kMathFloor:
2635 case kMathRound: 2581 case kMathRound:
2636 case kMathClz32:
2637 set_representation(Representation::Integer32()); 2582 set_representation(Representation::Integer32());
2638 break; 2583 break;
2639 case kMathAbs: 2584 case kMathAbs:
2640 // Not setting representation here: it is None intentionally. 2585 // Not setting representation here: it is None intentionally.
2641 SetFlag(kFlexibleRepresentation); 2586 SetFlag(kFlexibleRepresentation);
2642 // TODO(svenpanne) This flag is actually only needed if representation() 2587 // TODO(svenpanne) This flag is actually only needed if representation()
2643 // is tagged, and not when it is an unboxed double or unboxed integer. 2588 // is tagged, and not when it is an unboxed double or unboxed integer.
2644 SetChangesFlag(kNewSpacePromotion); 2589 SetGVNFlag(kChangesNewSpacePromotion);
2645 break; 2590 break;
2646 case kMathLog: 2591 case kMathLog:
2647 case kMathExp: 2592 case kMathExp:
2648 case kMathSqrt: 2593 case kMathSqrt:
2649 case kMathPowHalf: 2594 case kMathPowHalf:
2650 set_representation(Representation::Double()); 2595 set_representation(Representation::Double());
2651 break; 2596 break;
2652 default: 2597 default:
2653 UNREACHABLE(); 2598 UNREACHABLE();
2654 } 2599 }
(...skipping 28 matching lines...) Expand all
2683 HLoadRoot* b = HLoadRoot::cast(other); 2628 HLoadRoot* b = HLoadRoot::cast(other);
2684 return index_ == b->index_; 2629 return index_ == b->index_;
2685 } 2630 }
2686 2631
2687 private: 2632 private:
2688 HLoadRoot(Heap::RootListIndex index, HType type = HType::Tagged()) 2633 HLoadRoot(Heap::RootListIndex index, HType type = HType::Tagged())
2689 : HTemplateInstruction<0>(type), index_(index) { 2634 : HTemplateInstruction<0>(type), index_(index) {
2690 SetFlag(kUseGVN); 2635 SetFlag(kUseGVN);
2691 // TODO(bmeurer): We'll need kDependsOnRoots once we add the 2636 // TODO(bmeurer): We'll need kDependsOnRoots once we add the
2692 // corresponding HStoreRoot instruction. 2637 // corresponding HStoreRoot instruction.
2693 SetDependsOnFlag(kCalls); 2638 SetGVNFlag(kDependsOnCalls);
2694 } 2639 }
2695 2640
2696 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 2641 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
2697 2642
2698 const Heap::RootListIndex index_; 2643 const Heap::RootListIndex index_;
2699 }; 2644 };
2700 2645
2701 2646
2702 class HCheckMaps V8_FINAL : public HTemplateInstruction<2> { 2647 class HCheckMaps V8_FINAL : public HTemplateInstruction<2> {
2703 public: 2648 public:
2704 static HCheckMaps* New(Zone* zone, HValue* context, HValue* value, 2649 static HCheckMaps* New(Zone* zone, HValue* context, HValue* value,
2705 Handle<Map> map, CompilationInfo* info, 2650 Handle<Map> map, CompilationInfo* info,
2706 HValue* typecheck = NULL); 2651 HValue *typecheck = NULL);
2707 static HCheckMaps* New(Zone* zone, HValue* context, 2652 static HCheckMaps* New(Zone* zone, HValue* context,
2708 HValue* value, SmallMapList* maps, 2653 HValue* value, SmallMapList* maps,
2709 CompilationInfo* info, 2654 HValue *typecheck = NULL) {
2710 HValue* typecheck = NULL) {
2711 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck); 2655 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck);
2712 for (int i = 0; i < maps->length(); i++) { 2656 for (int i = 0; i < maps->length(); i++) {
2713 check_map->Add(maps->at(i), info, zone); 2657 check_map->Add(maps->at(i), zone);
2714 } 2658 }
2715 return check_map; 2659 return check_map;
2716 } 2660 }
2717 2661
2718 bool CanOmitMapChecks() { return omit_; } 2662 bool CanOmitMapChecks() { return omit_; }
2719 2663
2720 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } 2664 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; }
2721 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 2665 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
2722 return Representation::Tagged(); 2666 return Representation::Tagged();
2723 } 2667 }
2724 virtual bool HandleSideEffectDominator(GVNFlag side_effect, 2668 virtual bool HandleSideEffectDominator(GVNFlag side_effect,
2725 HValue* dominator) V8_OVERRIDE; 2669 HValue* dominator) V8_OVERRIDE;
2726 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 2670 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2727 2671
2728 HValue* value() { return OperandAt(0); } 2672 HValue* value() { return OperandAt(0); }
2729 HValue* typecheck() { return OperandAt(1); }
2730 2673
2731 Unique<Map> first_map() const { return map_set_.at(0); } 2674 Unique<Map> first_map() const { return map_set_.at(0); }
2732 UniqueSet<Map> map_set() const { return map_set_; } 2675 UniqueSet<Map> map_set() const { return map_set_; }
2733 2676
2734 void set_map_set(UniqueSet<Map>* maps, Zone *zone) {
2735 map_set_.Clear();
2736 for (int i = 0; i < maps->size(); i++) {
2737 map_set_.Add(maps->at(i), zone);
2738 }
2739 }
2740
2741 bool has_migration_target() const { 2677 bool has_migration_target() const {
2742 return has_migration_target_; 2678 return has_migration_target_;
2743 } 2679 }
2744 2680
2745 bool is_stable() const {
2746 return is_stable_;
2747 }
2748
2749 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) 2681 DECLARE_CONCRETE_INSTRUCTION(CheckMaps)
2750 2682
2751 protected: 2683 protected:
2752 virtual bool DataEquals(HValue* other) V8_OVERRIDE { 2684 virtual bool DataEquals(HValue* other) V8_OVERRIDE {
2753 return this->map_set_.Equals(&HCheckMaps::cast(other)->map_set_); 2685 return this->map_set_.Equals(&HCheckMaps::cast(other)->map_set_);
2754 } 2686 }
2755 2687
2756 virtual int RedefinedOperandIndex() { return 0; } 2688 virtual int RedefinedOperandIndex() { return 0; }
2757 2689
2758 private: 2690 private:
2759 void Add(Handle<Map> map, CompilationInfo* info, Zone* zone) { 2691 void Add(Handle<Map> map, Zone* zone) {
2760 map_set_.Add(Unique<Map>(map), zone); 2692 map_set_.Add(Unique<Map>(map), zone);
2761 is_stable_ = is_stable_ && map->is_stable();
2762 if (is_stable_) {
2763 map->AddDependentCompilationInfo(
2764 DependentCode::kPrototypeCheckGroup, info);
2765 } else {
2766 SetDependsOnFlag(kMaps);
2767 SetDependsOnFlag(kElementsKind);
2768 }
2769
2770 if (!has_migration_target_ && map->is_migration_target()) { 2693 if (!has_migration_target_ && map->is_migration_target()) {
2771 has_migration_target_ = true; 2694 has_migration_target_ = true;
2772 SetChangesFlag(kNewSpacePromotion); 2695 SetGVNFlag(kChangesNewSpacePromotion);
2773 } 2696 }
2774 } 2697 }
2775 2698
2776 // Clients should use one of the static New* methods above. 2699 // Clients should use one of the static New* methods above.
2777 HCheckMaps(HValue* value, Zone *zone, HValue* typecheck) 2700 HCheckMaps(HValue* value, Zone *zone, HValue* typecheck)
2778 : HTemplateInstruction<2>(value->type()), 2701 : HTemplateInstruction<2>(value->type()),
2779 omit_(false), has_migration_target_(false), is_stable_(true) { 2702 omit_(false), has_migration_target_(false) {
2780 SetOperandAt(0, value); 2703 SetOperandAt(0, value);
2781 // Use the object value for the dependency if NULL is passed. 2704 // Use the object value for the dependency if NULL is passed.
2782 SetOperandAt(1, typecheck != NULL ? typecheck : value); 2705 SetOperandAt(1, typecheck != NULL ? typecheck : value);
2783 set_representation(Representation::Tagged()); 2706 set_representation(Representation::Tagged());
2784 SetFlag(kUseGVN); 2707 SetFlag(kUseGVN);
2785 SetFlag(kTrackSideEffectDominators); 2708 SetFlag(kTrackSideEffectDominators);
2709 SetGVNFlag(kDependsOnMaps);
2710 SetGVNFlag(kDependsOnElementsKind);
2786 } 2711 }
2787 2712
2788 bool omit_; 2713 bool omit_;
2789 bool has_migration_target_; 2714 bool has_migration_target_;
2790 bool is_stable_;
2791 UniqueSet<Map> map_set_; 2715 UniqueSet<Map> map_set_;
2792 }; 2716 };
2793 2717
2794 2718
2795 class HCheckValue V8_FINAL : public HUnaryOperation { 2719 class HCheckValue V8_FINAL : public HUnaryOperation {
2796 public: 2720 public:
2797 static HCheckValue* New(Zone* zone, HValue* context, 2721 static HCheckValue* New(Zone* zone, HValue* context,
2798 HValue* value, Handle<JSFunction> func) { 2722 HValue* value, Handle<JSFunction> func) {
2799 bool in_new_space = zone->isolate()->heap()->InNewSpace(*func); 2723 bool in_new_space = zone->isolate()->heap()->InNewSpace(*func);
2800 // NOTE: We create an uninitialized Unique and initialize it later. 2724 // NOTE: We create an uninitialized Unique and initialize it later.
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
3215 virtual HValue* OperandAt(int index) const V8_OVERRIDE { 3139 virtual HValue* OperandAt(int index) const V8_OVERRIDE {
3216 return inputs_[index]; 3140 return inputs_[index];
3217 } 3141 }
3218 HValue* GetRedundantReplacement(); 3142 HValue* GetRedundantReplacement();
3219 void AddInput(HValue* value); 3143 void AddInput(HValue* value);
3220 bool HasRealUses(); 3144 bool HasRealUses();
3221 3145
3222 bool IsReceiver() const { return merged_index_ == 0; } 3146 bool IsReceiver() const { return merged_index_ == 0; }
3223 bool HasMergedIndex() const { return merged_index_ != kInvalidMergedIndex; } 3147 bool HasMergedIndex() const { return merged_index_ != kInvalidMergedIndex; }
3224 3148
3225 virtual HSourcePosition position() const V8_OVERRIDE; 3149 virtual int position() const V8_OVERRIDE;
3226 3150
3227 int merged_index() const { return merged_index_; } 3151 int merged_index() const { return merged_index_; }
3228 3152
3229 InductionVariableData* induction_variable_data() { 3153 InductionVariableData* induction_variable_data() {
3230 return induction_variable_data_; 3154 return induction_variable_data_;
3231 } 3155 }
3232 bool IsInductionVariable() { 3156 bool IsInductionVariable() {
3233 return induction_variable_data_ != NULL; 3157 return induction_variable_data_ != NULL;
3234 } 3158 }
3235 bool IsLimitedInductionVariable() { 3159 bool IsLimitedInductionVariable() {
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
3380 const ZoneList<HValue*>* values() const { return &values_; } 3304 const ZoneList<HValue*>* values() const { return &values_; }
3381 int length() const { return values_.length(); } 3305 int length() const { return values_.length(); }
3382 int capture_id() const { return capture_id_; } 3306 int capture_id() const { return capture_id_; }
3383 3307
3384 // Shortcut for the map value of this captured object. 3308 // Shortcut for the map value of this captured object.
3385 HValue* map_value() const { return values()->first(); } 3309 HValue* map_value() const { return values()->first(); }
3386 3310
3387 void ReuseSideEffectsFromStore(HInstruction* store) { 3311 void ReuseSideEffectsFromStore(HInstruction* store) {
3388 ASSERT(store->HasObservableSideEffects()); 3312 ASSERT(store->HasObservableSideEffects());
3389 ASSERT(store->IsStoreNamedField()); 3313 ASSERT(store->IsStoreNamedField());
3390 changes_flags_.Add(store->ChangesFlags()); 3314 gvn_flags_.Add(store->gvn_flags());
3391 } 3315 }
3392 3316
3393 // Replay effects of this instruction on the given environment. 3317 // Replay effects of this instruction on the given environment.
3394 void ReplayEnvironment(HEnvironment* env); 3318 void ReplayEnvironment(HEnvironment* env);
3395 3319
3396 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 3320 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
3397 3321
3398 DECLARE_CONCRETE_INSTRUCTION(CapturedObject) 3322 DECLARE_CONCRETE_INSTRUCTION(CapturedObject)
3399 3323
3400 private: 3324 private:
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
3720 3644
3721 virtual bool IsCommutative() const { return false; } 3645 virtual bool IsCommutative() const { return false; }
3722 3646
3723 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 3647 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
3724 3648
3725 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 3649 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
3726 if (index == 0) return Representation::Tagged(); 3650 if (index == 0) return Representation::Tagged();
3727 return representation(); 3651 return representation();
3728 } 3652 }
3729 3653
3730 void SetOperandPositions(Zone* zone, 3654 void SetOperandPositions(Zone* zone, int left_pos, int right_pos) {
3731 HSourcePosition left_pos,
3732 HSourcePosition right_pos) {
3733 set_operand_position(zone, 1, left_pos); 3655 set_operand_position(zone, 1, left_pos);
3734 set_operand_position(zone, 2, right_pos); 3656 set_operand_position(zone, 2, right_pos);
3735 } 3657 }
3736 3658
3737 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation) 3659 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation)
3738 3660
3739 private: 3661 private:
3740 bool IgnoreObservedOutputRepresentation(Representation current_rep); 3662 bool IgnoreObservedOutputRepresentation(Representation current_rep);
3741 3663
3742 Representation observed_input_representation_[2]; 3664 Representation observed_input_representation_[2];
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
4015 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right, 3937 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right,
4016 HType type = HType::Tagged()) 3938 HType type = HType::Tagged())
4017 : HBinaryOperation(context, left, right, type) { 3939 : HBinaryOperation(context, left, right, type) {
4018 SetFlag(kFlexibleRepresentation); 3940 SetFlag(kFlexibleRepresentation);
4019 SetFlag(kTruncatingToInt32); 3941 SetFlag(kTruncatingToInt32);
4020 SetFlag(kAllowUndefinedAsNaN); 3942 SetFlag(kAllowUndefinedAsNaN);
4021 SetAllSideEffects(); 3943 SetAllSideEffects();
4022 } 3944 }
4023 3945
4024 virtual void RepresentationChanged(Representation to) V8_OVERRIDE { 3946 virtual void RepresentationChanged(Representation to) V8_OVERRIDE {
4025 if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion); 3947 if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion);
4026 if (to.IsTagged() && 3948 if (to.IsTagged() &&
4027 (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) { 3949 (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) {
4028 SetAllSideEffects(); 3950 SetAllSideEffects();
4029 ClearFlag(kUseGVN); 3951 ClearFlag(kUseGVN);
4030 } else { 3952 } else {
4031 ClearAllSideEffects(); 3953 ClearAllSideEffects();
4032 SetFlag(kUseGVN); 3954 SetFlag(kUseGVN);
4033 } 3955 }
4034 } 3956 }
4035 3957
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
4092 class HArithmeticBinaryOperation : public HBinaryOperation { 4014 class HArithmeticBinaryOperation : public HBinaryOperation {
4093 public: 4015 public:
4094 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right) 4016 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right)
4095 : HBinaryOperation(context, left, right, HType::TaggedNumber()) { 4017 : HBinaryOperation(context, left, right, HType::TaggedNumber()) {
4096 SetAllSideEffects(); 4018 SetAllSideEffects();
4097 SetFlag(kFlexibleRepresentation); 4019 SetFlag(kFlexibleRepresentation);
4098 SetFlag(kAllowUndefinedAsNaN); 4020 SetFlag(kAllowUndefinedAsNaN);
4099 } 4021 }
4100 4022
4101 virtual void RepresentationChanged(Representation to) V8_OVERRIDE { 4023 virtual void RepresentationChanged(Representation to) V8_OVERRIDE {
4102 if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion); 4024 if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion);
4103 if (to.IsTagged() && 4025 if (to.IsTagged() &&
4104 (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) { 4026 (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) {
4105 SetAllSideEffects(); 4027 SetAllSideEffects();
4106 ClearFlag(kUseGVN); 4028 ClearFlag(kUseGVN);
4107 } else { 4029 } else {
4108 ClearAllSideEffects(); 4030 ClearAllSideEffects();
4109 SetFlag(kUseGVN); 4031 SetFlag(kUseGVN);
4110 } 4032 }
4111 } 4033 }
4112 4034
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
4177 HInferRepresentationPhase* h_infer) V8_OVERRIDE; 4099 HInferRepresentationPhase* h_infer) V8_OVERRIDE;
4178 4100
4179 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 4101 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
4180 return representation(); 4102 return representation();
4181 } 4103 }
4182 virtual Representation observed_input_representation(int index) V8_OVERRIDE { 4104 virtual Representation observed_input_representation(int index) V8_OVERRIDE {
4183 return observed_input_representation_[index]; 4105 return observed_input_representation_[index];
4184 } 4106 }
4185 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 4107 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
4186 4108
4187 void SetOperandPositions(Zone* zone, 4109 void SetOperandPositions(Zone* zone, int left_pos, int right_pos) {
4188 HSourcePosition left_pos,
4189 HSourcePosition right_pos) {
4190 set_operand_position(zone, 0, left_pos); 4110 set_operand_position(zone, 0, left_pos);
4191 set_operand_position(zone, 1, right_pos); 4111 set_operand_position(zone, 1, right_pos);
4192 } 4112 }
4193 4113
4194 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch) 4114 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch)
4195 4115
4196 private: 4116 private:
4197 HCompareNumericAndBranch(HValue* left, 4117 HCompareNumericAndBranch(HValue* left,
4198 HValue* right, 4118 HValue* right,
4199 Token::Value token, 4119 Token::Value token,
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
4419 HStringCompareAndBranch(HValue* context, 4339 HStringCompareAndBranch(HValue* context,
4420 HValue* left, 4340 HValue* left,
4421 HValue* right, 4341 HValue* right,
4422 Token::Value token) 4342 Token::Value token)
4423 : token_(token) { 4343 : token_(token) {
4424 ASSERT(Token::IsCompareOp(token)); 4344 ASSERT(Token::IsCompareOp(token));
4425 SetOperandAt(0, context); 4345 SetOperandAt(0, context);
4426 SetOperandAt(1, left); 4346 SetOperandAt(1, left);
4427 SetOperandAt(2, right); 4347 SetOperandAt(2, right);
4428 set_representation(Representation::Tagged()); 4348 set_representation(Representation::Tagged());
4429 SetChangesFlag(kNewSpacePromotion); 4349 SetGVNFlag(kChangesNewSpacePromotion);
4430 } 4350 }
4431 4351
4432 Token::Value token_; 4352 Token::Value token_;
4433 }; 4353 };
4434 4354
4435 4355
4436 class HIsConstructCallAndBranch : public HTemplateControlInstruction<2, 0> { 4356 class HIsConstructCallAndBranch : public HTemplateControlInstruction<2, 0> {
4437 public: 4357 public:
4438 DECLARE_INSTRUCTION_FACTORY_P0(HIsConstructCallAndBranch); 4358 DECLARE_INSTRUCTION_FACTORY_P0(HIsConstructCallAndBranch);
4439 4359
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
4644 4564
4645 protected: 4565 protected:
4646 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } 4566 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
4647 4567
4648 private: 4568 private:
4649 HPower(HValue* left, HValue* right) { 4569 HPower(HValue* left, HValue* right) {
4650 SetOperandAt(0, left); 4570 SetOperandAt(0, left);
4651 SetOperandAt(1, right); 4571 SetOperandAt(1, right);
4652 set_representation(Representation::Double()); 4572 set_representation(Representation::Double());
4653 SetFlag(kUseGVN); 4573 SetFlag(kUseGVN);
4654 SetChangesFlag(kNewSpacePromotion); 4574 SetGVNFlag(kChangesNewSpacePromotion);
4655 } 4575 }
4656 4576
4657 virtual bool IsDeletable() const V8_OVERRIDE { 4577 virtual bool IsDeletable() const V8_OVERRIDE {
4658 return !right()->representation().IsTagged(); 4578 return !right()->representation().IsTagged();
4659 } 4579 }
4660 }; 4580 };
4661 4581
4662 4582
4663 class HAdd V8_FINAL : public HArithmeticBinaryOperation { 4583 class HAdd V8_FINAL : public HArithmeticBinaryOperation {
4664 public: 4584 public:
(...skipping 21 matching lines...) Expand all
4686 } else if (right()->IsInteger32Constant()) { 4606 } else if (right()->IsInteger32Constant()) {
4687 decomposition->Apply(left(), right()->GetInteger32Constant()); 4607 decomposition->Apply(left(), right()->GetInteger32Constant());
4688 return true; 4608 return true;
4689 } else { 4609 } else {
4690 return false; 4610 return false;
4691 } 4611 }
4692 } 4612 }
4693 4613
4694 virtual void RepresentationChanged(Representation to) V8_OVERRIDE { 4614 virtual void RepresentationChanged(Representation to) V8_OVERRIDE {
4695 if (to.IsTagged()) { 4615 if (to.IsTagged()) {
4696 SetChangesFlag(kNewSpacePromotion); 4616 SetGVNFlag(kChangesNewSpacePromotion);
4697 ClearFlag(kAllowUndefinedAsNaN); 4617 ClearFlag(kAllowUndefinedAsNaN);
4698 } 4618 }
4699 if (to.IsTagged() && 4619 if (to.IsTagged() &&
4700 (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved() || 4620 (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved() ||
4701 left()->ToStringCanBeObserved() || right()->ToStringCanBeObserved())) { 4621 left()->ToStringCanBeObserved() || right()->ToStringCanBeObserved())) {
4702 SetAllSideEffects(); 4622 SetAllSideEffects();
4703 ClearFlag(kUseGVN); 4623 ClearFlag(kUseGVN);
4704 } else { 4624 } else {
4705 ClearAllSideEffects(); 4625 ClearAllSideEffects();
4706 SetFlag(kUseGVN); 4626 SetFlag(kUseGVN);
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after
5143 BailoutId ast_id() const { return ast_id_; } 5063 BailoutId ast_id() const { return ast_id_; }
5144 5064
5145 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 5065 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
5146 return Representation::None(); 5066 return Representation::None();
5147 } 5067 }
5148 5068
5149 DECLARE_CONCRETE_INSTRUCTION(OsrEntry) 5069 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
5150 5070
5151 private: 5071 private:
5152 explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) { 5072 explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) {
5153 SetChangesFlag(kOsrEntries); 5073 SetGVNFlag(kChangesOsrEntries);
5154 SetChangesFlag(kNewSpacePromotion); 5074 SetGVNFlag(kChangesNewSpacePromotion);
5155 } 5075 }
5156 5076
5157 BailoutId ast_id_; 5077 BailoutId ast_id_;
5158 }; 5078 };
5159 5079
5160 5080
5161 class HParameter V8_FINAL : public HTemplateInstruction<0> { 5081 class HParameter V8_FINAL : public HTemplateInstruction<0> {
5162 public: 5082 public:
5163 enum ParameterKind { 5083 enum ParameterKind {
5164 STACK_PARAMETER, 5084 STACK_PARAMETER,
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
5286 protected: 5206 protected:
5287 virtual bool DataEquals(HValue* other) V8_OVERRIDE { 5207 virtual bool DataEquals(HValue* other) V8_OVERRIDE {
5288 return cell_ == HLoadGlobalCell::cast(other)->cell_; 5208 return cell_ == HLoadGlobalCell::cast(other)->cell_;
5289 } 5209 }
5290 5210
5291 private: 5211 private:
5292 HLoadGlobalCell(Handle<Cell> cell, PropertyDetails details) 5212 HLoadGlobalCell(Handle<Cell> cell, PropertyDetails details)
5293 : cell_(Unique<Cell>::CreateUninitialized(cell)), details_(details) { 5213 : cell_(Unique<Cell>::CreateUninitialized(cell)), details_(details) {
5294 set_representation(Representation::Tagged()); 5214 set_representation(Representation::Tagged());
5295 SetFlag(kUseGVN); 5215 SetFlag(kUseGVN);
5296 SetDependsOnFlag(kGlobalVars); 5216 SetGVNFlag(kDependsOnGlobalVars);
5297 } 5217 }
5298 5218
5299 virtual bool IsDeletable() const V8_OVERRIDE { return !RequiresHoleCheck(); } 5219 virtual bool IsDeletable() const V8_OVERRIDE { return !RequiresHoleCheck(); }
5300 5220
5301 Unique<Cell> cell_; 5221 Unique<Cell> cell_;
5302 PropertyDetails details_; 5222 PropertyDetails details_;
5303 }; 5223 };
5304 5224
5305 5225
5306 class HLoadGlobalGeneric V8_FINAL : public HTemplateInstruction<2> { 5226 class HLoadGlobalGeneric V8_FINAL : public HTemplateInstruction<2> {
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
5438 Handle<AllocationSite> allocation_site = 5358 Handle<AllocationSite> allocation_site =
5439 Handle<AllocationSite>::null()) 5359 Handle<AllocationSite>::null())
5440 : HTemplateInstruction<2>(type), 5360 : HTemplateInstruction<2>(type),
5441 flags_(ComputeFlags(pretenure_flag, instance_type)), 5361 flags_(ComputeFlags(pretenure_flag, instance_type)),
5442 dominating_allocate_(NULL), 5362 dominating_allocate_(NULL),
5443 filler_free_space_size_(NULL) { 5363 filler_free_space_size_(NULL) {
5444 SetOperandAt(0, context); 5364 SetOperandAt(0, context);
5445 SetOperandAt(1, size); 5365 SetOperandAt(1, size);
5446 set_representation(Representation::Tagged()); 5366 set_representation(Representation::Tagged());
5447 SetFlag(kTrackSideEffectDominators); 5367 SetFlag(kTrackSideEffectDominators);
5448 SetChangesFlag(kNewSpacePromotion); 5368 SetGVNFlag(kChangesNewSpacePromotion);
5449 SetDependsOnFlag(kNewSpacePromotion); 5369 SetGVNFlag(kDependsOnNewSpacePromotion);
5450 5370
5451 if (FLAG_trace_pretenuring) { 5371 if (FLAG_trace_pretenuring) {
5452 PrintF("HAllocate with AllocationSite %p %s\n", 5372 PrintF("HAllocate with AllocationSite %p %s\n",
5453 allocation_site.is_null() 5373 allocation_site.is_null()
5454 ? static_cast<void*>(NULL) 5374 ? static_cast<void*>(NULL)
5455 : static_cast<void*>(*allocation_site), 5375 : static_cast<void*>(*allocation_site),
5456 pretenure_flag == TENURED ? "tenured" : "not tenured"); 5376 pretenure_flag == TENURED ? "tenured" : "not tenured");
5457 } 5377 }
5458 } 5378 }
5459 5379
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
5637 5557
5638 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell) 5558 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
5639 5559
5640 private: 5560 private:
5641 HStoreGlobalCell(HValue* value, 5561 HStoreGlobalCell(HValue* value,
5642 Handle<PropertyCell> cell, 5562 Handle<PropertyCell> cell,
5643 PropertyDetails details) 5563 PropertyDetails details)
5644 : HUnaryOperation(value), 5564 : HUnaryOperation(value),
5645 cell_(Unique<PropertyCell>::CreateUninitialized(cell)), 5565 cell_(Unique<PropertyCell>::CreateUninitialized(cell)),
5646 details_(details) { 5566 details_(details) {
5647 SetChangesFlag(kGlobalVars); 5567 SetGVNFlag(kChangesGlobalVars);
5648 } 5568 }
5649 5569
5650 Unique<PropertyCell> cell_; 5570 Unique<PropertyCell> cell_;
5651 PropertyDetails details_; 5571 PropertyDetails details_;
5652 }; 5572 };
5653 5573
5654 5574
5655 class HLoadContextSlot V8_FINAL : public HUnaryOperation { 5575 class HLoadContextSlot V8_FINAL : public HUnaryOperation {
5656 public: 5576 public:
5657 enum Mode { 5577 enum Mode {
(...skipping 18 matching lines...) Expand all
5676 mode_ = kCheckDeoptimize; 5596 mode_ = kCheckDeoptimize;
5677 break; 5597 break;
5678 case CONST: 5598 case CONST:
5679 mode_ = kCheckReturnUndefined; 5599 mode_ = kCheckReturnUndefined;
5680 break; 5600 break;
5681 default: 5601 default:
5682 mode_ = kNoCheck; 5602 mode_ = kNoCheck;
5683 } 5603 }
5684 set_representation(Representation::Tagged()); 5604 set_representation(Representation::Tagged());
5685 SetFlag(kUseGVN); 5605 SetFlag(kUseGVN);
5686 SetDependsOnFlag(kContextSlots); 5606 SetGVNFlag(kDependsOnContextSlots);
5687 } 5607 }
5688 5608
5689 int slot_index() const { return slot_index_; } 5609 int slot_index() const { return slot_index_; }
5690 Mode mode() const { return mode_; } 5610 Mode mode() const { return mode_; }
5691 5611
5692 bool DeoptimizesOnHole() { 5612 bool DeoptimizesOnHole() {
5693 return mode_ == kCheckDeoptimize; 5613 return mode_ == kCheckDeoptimize;
5694 } 5614 }
5695 5615
5696 bool RequiresHoleCheck() const { 5616 bool RequiresHoleCheck() const {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
5760 5680
5761 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 5681 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
5762 5682
5763 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot) 5683 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
5764 5684
5765 private: 5685 private:
5766 HStoreContextSlot(HValue* context, int slot_index, Mode mode, HValue* value) 5686 HStoreContextSlot(HValue* context, int slot_index, Mode mode, HValue* value)
5767 : slot_index_(slot_index), mode_(mode) { 5687 : slot_index_(slot_index), mode_(mode) {
5768 SetOperandAt(0, context); 5688 SetOperandAt(0, context);
5769 SetOperandAt(1, value); 5689 SetOperandAt(1, value);
5770 SetChangesFlag(kContextSlots); 5690 SetGVNFlag(kChangesContextSlots);
5771 } 5691 }
5772 5692
5773 int slot_index_; 5693 int slot_index_;
5774 Mode mode_; 5694 Mode mode_;
5775 }; 5695 };
5776 5696
5777 5697
5778 // Represents an access to a portion of an object, such as the map pointer, 5698 // Represents an access to a portion of an object, such as the map pointer,
5779 // array elements pointer, etc, but not accesses to array elements themselves. 5699 // array elements pointer, etc, but not accesses to array elements themselves.
5780 class HObjectAccess V8_FINAL { 5700 class HObjectAccess V8_FINAL {
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
6038 5958
6039 static HObjectAccess ForJSArrayBufferViewByteLength() { 5959 static HObjectAccess ForJSArrayBufferViewByteLength() {
6040 return HObjectAccess::ForObservableJSObjectOffset( 5960 return HObjectAccess::ForObservableJSObjectOffset(
6041 JSArrayBufferView::kByteLengthOffset); 5961 JSArrayBufferView::kByteLengthOffset);
6042 } 5962 }
6043 5963
6044 static HObjectAccess ForGlobalObjectNativeContext() { 5964 static HObjectAccess ForGlobalObjectNativeContext() {
6045 return HObjectAccess(kInobject, GlobalObject::kNativeContextOffset); 5965 return HObjectAccess(kInobject, GlobalObject::kNativeContextOffset);
6046 } 5966 }
6047 5967
6048 void PrintTo(StringStream* stream) const; 5968 void PrintTo(StringStream* stream);
6049 5969
6050 inline bool Equals(HObjectAccess that) const { 5970 inline bool Equals(HObjectAccess that) const {
6051 return value_ == that.value_; // portion and offset must match 5971 return value_ == that.value_; // portion and offset must match
6052 } 5972 }
6053 5973
6054 protected: 5974 protected:
6055 void SetGVNFlags(HValue *instr, PropertyAccessType access_type); 5975 void SetGVNFlags(HValue *instr, bool is_store);
6056 5976
6057 private: 5977 private:
6058 // internal use only; different parts of an object or array 5978 // internal use only; different parts of an object or array
6059 enum Portion { 5979 enum Portion {
6060 kMaps, // map of an object 5980 kMaps, // map of an object
6061 kArrayLengths, // the length of an array 5981 kArrayLengths, // the length of an array
6062 kStringLengths, // the length of a string 5982 kStringLengths, // the length of a string
6063 kElementsPointer, // elements pointer 5983 kElementsPointer, // elements pointer
6064 kBackingStore, // some field in the backing store 5984 kBackingStore, // some field in the backing store
6065 kDouble, // some double field 5985 kDouble, // some double field
6066 kInobject, // some other in-object field 5986 kInobject, // some other in-object field
6067 kExternalMemory // some field in external memory 5987 kExternalMemory // some field in external memory
6068 }; 5988 };
6069 5989
6070 HObjectAccess() : value_(0) {}
6071
6072 HObjectAccess(Portion portion, int offset, 5990 HObjectAccess(Portion portion, int offset,
6073 Representation representation = Representation::Tagged(), 5991 Representation representation = Representation::Tagged(),
6074 Handle<String> name = Handle<String>::null(), 5992 Handle<String> name = Handle<String>::null(),
6075 bool immutable = false, 5993 bool immutable = false,
6076 bool existing_inobject_property = true) 5994 bool existing_inobject_property = true)
6077 : value_(PortionField::encode(portion) | 5995 : value_(PortionField::encode(portion) |
6078 RepresentationField::encode(representation.kind()) | 5996 RepresentationField::encode(representation.kind()) |
6079 ImmutableField::encode(immutable ? 1 : 0) | 5997 ImmutableField::encode(immutable ? 1 : 0) |
6080 ExistingInobjectPropertyField::encode( 5998 ExistingInobjectPropertyField::encode(
6081 existing_inobject_property ? 1 : 0) | 5999 existing_inobject_property ? 1 : 0) |
(...skipping 12 matching lines...) Expand all
6094 class RepresentationField : public BitField<Representation::Kind, 3, 4> {}; 6012 class RepresentationField : public BitField<Representation::Kind, 3, 4> {};
6095 class ImmutableField : public BitField<bool, 7, 1> {}; 6013 class ImmutableField : public BitField<bool, 7, 1> {};
6096 class ExistingInobjectPropertyField : public BitField<bool, 8, 1> {}; 6014 class ExistingInobjectPropertyField : public BitField<bool, 8, 1> {};
6097 class OffsetField : public BitField<int, 9, 23> {}; 6015 class OffsetField : public BitField<int, 9, 23> {};
6098 6016
6099 uint32_t value_; // encodes portion, representation, immutable, and offset 6017 uint32_t value_; // encodes portion, representation, immutable, and offset
6100 Handle<String> name_; 6018 Handle<String> name_;
6101 6019
6102 friend class HLoadNamedField; 6020 friend class HLoadNamedField;
6103 friend class HStoreNamedField; 6021 friend class HStoreNamedField;
6104 friend class SideEffectsTracker;
6105 6022
6106 inline Portion portion() const { 6023 inline Portion portion() const {
6107 return PortionField::decode(value_); 6024 return PortionField::decode(value_);
6108 } 6025 }
6109 }; 6026 };
6110 6027
6111 6028
6112 class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> { 6029 class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> {
6113 public: 6030 public:
6114 DECLARE_INSTRUCTION_FACTORY_P3(HLoadNamedField, HValue*, HValue*, 6031 DECLARE_INSTRUCTION_FACTORY_P3(HLoadNamedField, HValue*, HValue*,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
6172 representation.IsExternal() || 6089 representation.IsExternal() ||
6173 representation.IsInteger32()) { 6090 representation.IsInteger32()) {
6174 set_representation(representation); 6091 set_representation(representation);
6175 } else if (FLAG_track_heap_object_fields && 6092 } else if (FLAG_track_heap_object_fields &&
6176 representation.IsHeapObject()) { 6093 representation.IsHeapObject()) {
6177 set_type(HType::NonPrimitive()); 6094 set_type(HType::NonPrimitive());
6178 set_representation(Representation::Tagged()); 6095 set_representation(Representation::Tagged());
6179 } else { 6096 } else {
6180 set_representation(Representation::Tagged()); 6097 set_representation(Representation::Tagged());
6181 } 6098 }
6182 access.SetGVNFlags(this, LOAD); 6099 access.SetGVNFlags(this, false);
6183 } 6100 }
6184 6101
6185 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 6102 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
6186 6103
6187 HObjectAccess access_; 6104 HObjectAccess access_;
6188 }; 6105 };
6189 6106
6190 6107
6191 class HLoadNamedGeneric V8_FINAL : public HTemplateInstruction<2> { 6108 class HLoadNamedGeneric V8_FINAL : public HTemplateInstruction<2> {
6192 public: 6109 public:
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
6231 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype) 6148 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
6232 6149
6233 protected: 6150 protected:
6234 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } 6151 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
6235 6152
6236 private: 6153 private:
6237 explicit HLoadFunctionPrototype(HValue* function) 6154 explicit HLoadFunctionPrototype(HValue* function)
6238 : HUnaryOperation(function) { 6155 : HUnaryOperation(function) {
6239 set_representation(Representation::Tagged()); 6156 set_representation(Representation::Tagged());
6240 SetFlag(kUseGVN); 6157 SetFlag(kUseGVN);
6241 SetDependsOnFlag(kCalls); 6158 SetGVNFlag(kDependsOnCalls);
6242 } 6159 }
6243 }; 6160 };
6244 6161
6245 class ArrayInstructionInterface { 6162 class ArrayInstructionInterface {
6246 public: 6163 public:
6247 virtual HValue* GetKey() = 0; 6164 virtual HValue* GetKey() = 0;
6248 virtual void SetKey(HValue* key) = 0; 6165 virtual void SetKey(HValue* key) = 0;
6249 virtual void SetIndexOffset(uint32_t index_offset) = 0; 6166 virtual void SetIndexOffset(uint32_t index_offset) = 0;
6250 virtual int MaxIndexOffsetBits() = 0; 6167 virtual int MaxIndexOffsetBits() = 0;
6251 virtual bool IsDehoisted() = 0; 6168 virtual bool IsDehoisted() = 0;
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
6376 set_type(HType::Smi()); 6293 set_type(HType::Smi());
6377 if (SmiValuesAre32Bits() && !RequiresHoleCheck()) { 6294 if (SmiValuesAre32Bits() && !RequiresHoleCheck()) {
6378 set_representation(Representation::Integer32()); 6295 set_representation(Representation::Integer32());
6379 } else { 6296 } else {
6380 set_representation(Representation::Smi()); 6297 set_representation(Representation::Smi());
6381 } 6298 }
6382 } else { 6299 } else {
6383 set_representation(Representation::Tagged()); 6300 set_representation(Representation::Tagged());
6384 } 6301 }
6385 6302
6386 SetDependsOnFlag(kArrayElements); 6303 SetGVNFlag(kDependsOnArrayElements);
6387 } else { 6304 } else {
6388 set_representation(Representation::Double()); 6305 set_representation(Representation::Double());
6389 SetDependsOnFlag(kDoubleArrayElements); 6306 SetGVNFlag(kDependsOnDoubleArrayElements);
6390 } 6307 }
6391 } else { 6308 } else {
6392 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || 6309 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
6393 elements_kind == EXTERNAL_FLOAT64_ELEMENTS || 6310 elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
6394 elements_kind == FLOAT32_ELEMENTS || 6311 elements_kind == FLOAT32_ELEMENTS ||
6395 elements_kind == FLOAT64_ELEMENTS) { 6312 elements_kind == FLOAT64_ELEMENTS) {
6396 set_representation(Representation::Double()); 6313 set_representation(Representation::Double());
6397 } else { 6314 } else {
6398 set_representation(Representation::Integer32()); 6315 set_representation(Representation::Integer32());
6399 } 6316 }
6400 6317
6401 if (is_external()) { 6318 if (is_external()) {
6402 SetDependsOnFlag(kExternalMemory); 6319 SetGVNFlag(kDependsOnExternalMemory);
6403 } else if (is_fixed_typed_array()) { 6320 } else if (is_fixed_typed_array()) {
6404 SetDependsOnFlag(kTypedArrayElements); 6321 SetGVNFlag(kDependsOnTypedArrayElements);
6405 } else { 6322 } else {
6406 UNREACHABLE(); 6323 UNREACHABLE();
6407 } 6324 }
6408 // Native code could change the specialized array. 6325 // Native code could change the specialized array.
6409 SetDependsOnFlag(kCalls); 6326 SetGVNFlag(kDependsOnCalls);
6410 } 6327 }
6411 6328
6412 SetFlag(kUseGVN); 6329 SetFlag(kUseGVN);
6413 } 6330 }
6414 6331
6415 virtual bool IsDeletable() const V8_OVERRIDE { 6332 virtual bool IsDeletable() const V8_OVERRIDE {
6416 return !RequiresHoleCheck(); 6333 return !RequiresHoleCheck();
6417 } 6334 }
6418 6335
6419 // Establish some checks around our packed fields 6336 // Establish some checks around our packed fields
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
6523 } 6440 }
6524 return field_representation(); 6441 return field_representation();
6525 } else if (field_representation().IsExternal()) { 6442 } else if (field_representation().IsExternal()) {
6526 return Representation::External(); 6443 return Representation::External();
6527 } 6444 }
6528 } 6445 }
6529 return Representation::Tagged(); 6446 return Representation::Tagged();
6530 } 6447 }
6531 virtual bool HandleSideEffectDominator(GVNFlag side_effect, 6448 virtual bool HandleSideEffectDominator(GVNFlag side_effect,
6532 HValue* dominator) V8_OVERRIDE { 6449 HValue* dominator) V8_OVERRIDE {
6533 ASSERT(side_effect == kNewSpacePromotion); 6450 ASSERT(side_effect == kChangesNewSpacePromotion);
6534 if (!FLAG_use_write_barrier_elimination) return false;
6535 new_space_dominator_ = dominator; 6451 new_space_dominator_ = dominator;
6536 return false; 6452 return false;
6537 } 6453 }
6538 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 6454 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
6539 6455
6540 void SkipWriteBarrier() { write_barrier_mode_ = SKIP_WRITE_BARRIER; } 6456 void SkipWriteBarrier() { write_barrier_mode_ = SKIP_WRITE_BARRIER; }
6541 bool IsSkipWriteBarrier() const { 6457 bool IsSkipWriteBarrier() const {
6542 return write_barrier_mode_ == SKIP_WRITE_BARRIER; 6458 return write_barrier_mode_ == SKIP_WRITE_BARRIER;
6543 } 6459 }
6544 6460
(...skipping 16 matching lines...) Expand all
6561 } 6477 }
6562 6478
6563 void SetTransition(HConstant* map_constant, CompilationInfo* info) { 6479 void SetTransition(HConstant* map_constant, CompilationInfo* info) {
6564 ASSERT(!has_transition()); // Only set once. 6480 ASSERT(!has_transition()); // Only set once.
6565 Handle<Map> map = Handle<Map>::cast(map_constant->handle(info->isolate())); 6481 Handle<Map> map = Handle<Map>::cast(map_constant->handle(info->isolate()));
6566 if (map->CanBeDeprecated()) { 6482 if (map->CanBeDeprecated()) {
6567 map->AddDependentCompilationInfo(DependentCode::kTransitionGroup, info); 6483 map->AddDependentCompilationInfo(DependentCode::kTransitionGroup, info);
6568 } 6484 }
6569 SetOperandAt(2, map_constant); 6485 SetOperandAt(2, map_constant);
6570 has_transition_ = true; 6486 has_transition_ = true;
6571 is_stable_ = map->is_stable();
6572
6573 if (is_stable_) {
6574 map->AddDependentCompilationInfo(
6575 DependentCode::kPrototypeCheckGroup, info);
6576 }
6577 }
6578
6579 bool is_stable() const {
6580 return is_stable_;
6581 } 6487 }
6582 6488
6583 bool NeedsWriteBarrier() { 6489 bool NeedsWriteBarrier() {
6584 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) || 6490 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) ||
6585 !has_transition()); 6491 !has_transition());
6586 if (IsSkipWriteBarrier()) return false; 6492 if (IsSkipWriteBarrier()) return false;
6587 if (field_representation().IsDouble()) return false; 6493 if (field_representation().IsDouble()) return false;
6588 if (field_representation().IsSmi()) return false; 6494 if (field_representation().IsSmi()) return false;
6589 if (field_representation().IsInteger32()) return false; 6495 if (field_representation().IsInteger32()) return false;
6590 if (field_representation().IsExternal()) return false; 6496 if (field_representation().IsExternal()) return false;
(...skipping 18 matching lines...) Expand all
6609 6515
6610 private: 6516 private:
6611 HStoreNamedField(HValue* obj, 6517 HStoreNamedField(HValue* obj,
6612 HObjectAccess access, 6518 HObjectAccess access,
6613 HValue* val, 6519 HValue* val,
6614 StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE) 6520 StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE)
6615 : access_(access), 6521 : access_(access),
6616 new_space_dominator_(NULL), 6522 new_space_dominator_(NULL),
6617 write_barrier_mode_(UPDATE_WRITE_BARRIER), 6523 write_barrier_mode_(UPDATE_WRITE_BARRIER),
6618 has_transition_(false), 6524 has_transition_(false),
6619 is_stable_(false),
6620 store_mode_(store_mode) { 6525 store_mode_(store_mode) {
6526 if (!FLAG_smi_x64_store_opt) store_mode_ = INITIALIZING_STORE;
6621 // Stores to a non existing in-object property are allowed only to the 6527 // Stores to a non existing in-object property are allowed only to the
6622 // newly allocated objects (via HAllocate or HInnerAllocatedObject). 6528 // newly allocated objects (via HAllocate or HInnerAllocatedObject).
6623 ASSERT(!access.IsInobject() || access.existing_inobject_property() || 6529 ASSERT(!access.IsInobject() || access.existing_inobject_property() ||
6624 obj->IsAllocate() || obj->IsInnerAllocatedObject()); 6530 obj->IsAllocate() || obj->IsInnerAllocatedObject());
6625 SetOperandAt(0, obj); 6531 SetOperandAt(0, obj);
6626 SetOperandAt(1, val); 6532 SetOperandAt(1, val);
6627 SetOperandAt(2, obj); 6533 SetOperandAt(2, obj);
6628 access.SetGVNFlags(this, STORE); 6534 access.SetGVNFlags(this, true);
6629 } 6535 }
6630 6536
6631 HObjectAccess access_; 6537 HObjectAccess access_;
6632 HValue* new_space_dominator_; 6538 HValue* new_space_dominator_;
6633 WriteBarrierMode write_barrier_mode_ : 1; 6539 WriteBarrierMode write_barrier_mode_ : 1;
6634 bool has_transition_ : 1; 6540 bool has_transition_ : 1;
6635 bool is_stable_ : 1;
6636 StoreFieldOrKeyedMode store_mode_ : 1; 6541 StoreFieldOrKeyedMode store_mode_ : 1;
6637 }; 6542 };
6638 6543
6639 6544
6640 class HStoreNamedGeneric V8_FINAL : public HTemplateInstruction<3> { 6545 class HStoreNamedGeneric V8_FINAL : public HTemplateInstruction<3> {
6641 public: 6546 public:
6642 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HStoreNamedGeneric, HValue*, 6547 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HStoreNamedGeneric, HValue*,
6643 Handle<String>, HValue*, 6548 Handle<String>, HValue*,
6644 StrictModeFlag); 6549 StrictModeFlag);
6645 HValue* object() { return OperandAt(0); } 6550 HValue* object() { return OperandAt(0); }
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
6767 void SetUninitialized(bool is_uninitialized) { 6672 void SetUninitialized(bool is_uninitialized) {
6768 is_uninitialized_ = is_uninitialized; 6673 is_uninitialized_ = is_uninitialized;
6769 } 6674 }
6770 6675
6771 bool IsConstantHoleStore() { 6676 bool IsConstantHoleStore() {
6772 return value()->IsConstant() && HConstant::cast(value())->IsTheHole(); 6677 return value()->IsConstant() && HConstant::cast(value())->IsTheHole();
6773 } 6678 }
6774 6679
6775 virtual bool HandleSideEffectDominator(GVNFlag side_effect, 6680 virtual bool HandleSideEffectDominator(GVNFlag side_effect,
6776 HValue* dominator) V8_OVERRIDE { 6681 HValue* dominator) V8_OVERRIDE {
6777 ASSERT(side_effect == kNewSpacePromotion); 6682 ASSERT(side_effect == kChangesNewSpacePromotion);
6778 new_space_dominator_ = dominator; 6683 new_space_dominator_ = dominator;
6779 return false; 6684 return false;
6780 } 6685 }
6781 6686
6782 HValue* new_space_dominator() const { return new_space_dominator_; } 6687 HValue* new_space_dominator() const { return new_space_dominator_; }
6783 6688
6784 bool NeedsWriteBarrier() { 6689 bool NeedsWriteBarrier() {
6785 if (value_is_smi()) { 6690 if (value_is_smi()) {
6786 return false; 6691 return false;
6787 } else { 6692 } else {
(...skipping 12 matching lines...) Expand all
6800 private: 6705 private:
6801 HStoreKeyed(HValue* obj, HValue* key, HValue* val, 6706 HStoreKeyed(HValue* obj, HValue* key, HValue* val,
6802 ElementsKind elements_kind, 6707 ElementsKind elements_kind,
6803 StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE) 6708 StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE)
6804 : elements_kind_(elements_kind), 6709 : elements_kind_(elements_kind),
6805 index_offset_(0), 6710 index_offset_(0),
6806 is_dehoisted_(false), 6711 is_dehoisted_(false),
6807 is_uninitialized_(false), 6712 is_uninitialized_(false),
6808 store_mode_(store_mode), 6713 store_mode_(store_mode),
6809 new_space_dominator_(NULL) { 6714 new_space_dominator_(NULL) {
6715 if (!FLAG_smi_x64_store_opt) store_mode_ = INITIALIZING_STORE;
6810 SetOperandAt(0, obj); 6716 SetOperandAt(0, obj);
6811 SetOperandAt(1, key); 6717 SetOperandAt(1, key);
6812 SetOperandAt(2, val); 6718 SetOperandAt(2, val);
6813 6719
6814 ASSERT(store_mode != STORE_TO_INITIALIZED_ENTRY || 6720 ASSERT(store_mode != STORE_TO_INITIALIZED_ENTRY ||
6815 elements_kind == FAST_SMI_ELEMENTS); 6721 elements_kind == FAST_SMI_ELEMENTS);
6816 6722
6817 if (IsFastObjectElementsKind(elements_kind)) { 6723 if (IsFastObjectElementsKind(elements_kind)) {
6818 SetFlag(kTrackSideEffectDominators); 6724 SetFlag(kTrackSideEffectDominators);
6819 SetDependsOnFlag(kNewSpacePromotion); 6725 SetGVNFlag(kDependsOnNewSpacePromotion);
6820 } 6726 }
6821 if (is_external()) { 6727 if (is_external()) {
6822 SetChangesFlag(kExternalMemory); 6728 SetGVNFlag(kChangesExternalMemory);
6823 SetFlag(kAllowUndefinedAsNaN); 6729 SetFlag(kAllowUndefinedAsNaN);
6824 } else if (IsFastDoubleElementsKind(elements_kind)) { 6730 } else if (IsFastDoubleElementsKind(elements_kind)) {
6825 SetChangesFlag(kDoubleArrayElements); 6731 SetGVNFlag(kChangesDoubleArrayElements);
6826 } else if (IsFastSmiElementsKind(elements_kind)) { 6732 } else if (IsFastSmiElementsKind(elements_kind)) {
6827 SetChangesFlag(kArrayElements); 6733 SetGVNFlag(kChangesArrayElements);
6828 } else if (is_fixed_typed_array()) { 6734 } else if (is_fixed_typed_array()) {
6829 SetChangesFlag(kTypedArrayElements); 6735 SetGVNFlag(kChangesTypedArrayElements);
6830 SetFlag(kAllowUndefinedAsNaN); 6736 SetFlag(kAllowUndefinedAsNaN);
6831 } else { 6737 } else {
6832 SetChangesFlag(kArrayElements); 6738 SetGVNFlag(kChangesArrayElements);
6833 } 6739 }
6834 6740
6835 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. 6741 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating.
6836 if ((elements_kind >= EXTERNAL_INT8_ELEMENTS && 6742 if ((elements_kind >= EXTERNAL_INT8_ELEMENTS &&
6837 elements_kind <= EXTERNAL_UINT32_ELEMENTS) || 6743 elements_kind <= EXTERNAL_UINT32_ELEMENTS) ||
6838 (elements_kind >= UINT8_ELEMENTS && 6744 (elements_kind >= UINT8_ELEMENTS &&
6839 elements_kind <= INT32_ELEMENTS)) { 6745 elements_kind <= INT32_ELEMENTS)) {
6840 SetFlag(kTruncatingToInt32); 6746 SetFlag(kTruncatingToInt32);
6841 } 6747 }
6842 } 6748 }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
6926 HValue* object, 6832 HValue* object,
6927 Handle<Map> original_map, 6833 Handle<Map> original_map,
6928 Handle<Map> transitioned_map) 6834 Handle<Map> transitioned_map)
6929 : original_map_(Unique<Map>(original_map)), 6835 : original_map_(Unique<Map>(original_map)),
6930 transitioned_map_(Unique<Map>(transitioned_map)), 6836 transitioned_map_(Unique<Map>(transitioned_map)),
6931 from_kind_(original_map->elements_kind()), 6837 from_kind_(original_map->elements_kind()),
6932 to_kind_(transitioned_map->elements_kind()) { 6838 to_kind_(transitioned_map->elements_kind()) {
6933 SetOperandAt(0, object); 6839 SetOperandAt(0, object);
6934 SetOperandAt(1, context); 6840 SetOperandAt(1, context);
6935 SetFlag(kUseGVN); 6841 SetFlag(kUseGVN);
6936 SetChangesFlag(kElementsKind); 6842 SetGVNFlag(kChangesElementsKind);
6937 if (!IsSimpleMapChangeTransition(from_kind_, to_kind_)) { 6843 if (!IsSimpleMapChangeTransition(from_kind_, to_kind_)) {
6938 SetChangesFlag(kElementsPointer); 6844 SetGVNFlag(kChangesElementsPointer);
6939 SetChangesFlag(kNewSpacePromotion); 6845 SetGVNFlag(kChangesNewSpacePromotion);
6940 } 6846 }
6941 set_representation(Representation::Tagged()); 6847 set_representation(Representation::Tagged());
6942 } 6848 }
6943 6849
6944 Unique<Map> original_map_; 6850 Unique<Map> original_map_;
6945 Unique<Map> transitioned_map_; 6851 Unique<Map> transitioned_map_;
6946 ElementsKind from_kind_; 6852 ElementsKind from_kind_;
6947 ElementsKind to_kind_; 6853 ElementsKind to_kind_;
6948 }; 6854 };
6949 6855
(...skipping 30 matching lines...) Expand all
6980 HStringAdd(HValue* context, 6886 HStringAdd(HValue* context,
6981 HValue* left, 6887 HValue* left,
6982 HValue* right, 6888 HValue* right,
6983 PretenureFlag pretenure_flag, 6889 PretenureFlag pretenure_flag,
6984 StringAddFlags flags, 6890 StringAddFlags flags,
6985 Handle<AllocationSite> allocation_site) 6891 Handle<AllocationSite> allocation_site)
6986 : HBinaryOperation(context, left, right, HType::String()), 6892 : HBinaryOperation(context, left, right, HType::String()),
6987 flags_(flags), pretenure_flag_(pretenure_flag) { 6893 flags_(flags), pretenure_flag_(pretenure_flag) {
6988 set_representation(Representation::Tagged()); 6894 set_representation(Representation::Tagged());
6989 SetFlag(kUseGVN); 6895 SetFlag(kUseGVN);
6990 SetDependsOnFlag(kMaps); 6896 SetGVNFlag(kDependsOnMaps);
6991 SetChangesFlag(kNewSpacePromotion); 6897 SetGVNFlag(kChangesNewSpacePromotion);
6992 if (FLAG_trace_pretenuring) { 6898 if (FLAG_trace_pretenuring) {
6993 PrintF("HStringAdd with AllocationSite %p %s\n", 6899 PrintF("HStringAdd with AllocationSite %p %s\n",
6994 allocation_site.is_null() 6900 allocation_site.is_null()
6995 ? static_cast<void*>(NULL) 6901 ? static_cast<void*>(NULL)
6996 : static_cast<void*>(*allocation_site), 6902 : static_cast<void*>(*allocation_site),
6997 pretenure_flag == TENURED ? "tenured" : "not tenured"); 6903 pretenure_flag == TENURED ? "tenured" : "not tenured");
6998 } 6904 }
6999 } 6905 }
7000 6906
7001 // No side-effects except possible allocation: 6907 // No side-effects except possible allocation:
(...skipping 30 matching lines...) Expand all
7032 return new(zone) Range(0, String::kMaxUtf16CodeUnit); 6938 return new(zone) Range(0, String::kMaxUtf16CodeUnit);
7033 } 6939 }
7034 6940
7035 private: 6941 private:
7036 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { 6942 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
7037 SetOperandAt(0, context); 6943 SetOperandAt(0, context);
7038 SetOperandAt(1, string); 6944 SetOperandAt(1, string);
7039 SetOperandAt(2, index); 6945 SetOperandAt(2, index);
7040 set_representation(Representation::Integer32()); 6946 set_representation(Representation::Integer32());
7041 SetFlag(kUseGVN); 6947 SetFlag(kUseGVN);
7042 SetDependsOnFlag(kMaps); 6948 SetGVNFlag(kDependsOnMaps);
7043 SetDependsOnFlag(kStringChars); 6949 SetGVNFlag(kDependsOnStringChars);
7044 SetChangesFlag(kNewSpacePromotion); 6950 SetGVNFlag(kChangesNewSpacePromotion);
7045 } 6951 }
7046 6952
7047 // No side effects: runtime function assumes string + number inputs. 6953 // No side effects: runtime function assumes string + number inputs.
7048 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 6954 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
7049 }; 6955 };
7050 6956
7051 6957
7052 class HStringCharFromCode V8_FINAL : public HTemplateInstruction<2> { 6958 class HStringCharFromCode V8_FINAL : public HTemplateInstruction<2> {
7053 public: 6959 public:
7054 static HInstruction* New(Zone* zone, 6960 static HInstruction* New(Zone* zone,
(...skipping 13 matching lines...) Expand all
7068 6974
7069 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode) 6975 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
7070 6976
7071 private: 6977 private:
7072 HStringCharFromCode(HValue* context, HValue* char_code) 6978 HStringCharFromCode(HValue* context, HValue* char_code)
7073 : HTemplateInstruction<2>(HType::String()) { 6979 : HTemplateInstruction<2>(HType::String()) {
7074 SetOperandAt(0, context); 6980 SetOperandAt(0, context);
7075 SetOperandAt(1, char_code); 6981 SetOperandAt(1, char_code);
7076 set_representation(Representation::Tagged()); 6982 set_representation(Representation::Tagged());
7077 SetFlag(kUseGVN); 6983 SetFlag(kUseGVN);
7078 SetChangesFlag(kNewSpacePromotion); 6984 SetGVNFlag(kChangesNewSpacePromotion);
7079 } 6985 }
7080 6986
7081 virtual bool IsDeletable() const V8_OVERRIDE { 6987 virtual bool IsDeletable() const V8_OVERRIDE {
7082 return !value()->ToNumberCanBeObserved(); 6988 return !value()->ToNumberCanBeObserved();
7083 } 6989 }
7084 }; 6990 };
7085 6991
7086 6992
7087 template <int V> 6993 template <int V>
7088 class HMaterializedLiteral : public HTemplateInstruction<V> { 6994 class HMaterializedLiteral : public HTemplateInstruction<V> {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
7177 Handle<SharedFunctionInfo> shared, 7083 Handle<SharedFunctionInfo> shared,
7178 bool pretenure) 7084 bool pretenure)
7179 : HTemplateInstruction<1>(HType::JSObject()), 7085 : HTemplateInstruction<1>(HType::JSObject()),
7180 shared_info_(shared), 7086 shared_info_(shared),
7181 pretenure_(pretenure), 7087 pretenure_(pretenure),
7182 has_no_literals_(shared->num_literals() == 0), 7088 has_no_literals_(shared->num_literals() == 0),
7183 is_generator_(shared->is_generator()), 7089 is_generator_(shared->is_generator()),
7184 language_mode_(shared->language_mode()) { 7090 language_mode_(shared->language_mode()) {
7185 SetOperandAt(0, context); 7091 SetOperandAt(0, context);
7186 set_representation(Representation::Tagged()); 7092 set_representation(Representation::Tagged());
7187 SetChangesFlag(kNewSpacePromotion); 7093 SetGVNFlag(kChangesNewSpacePromotion);
7188 } 7094 }
7189 7095
7190 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 7096 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
7191 7097
7192 Handle<SharedFunctionInfo> shared_info_; 7098 Handle<SharedFunctionInfo> shared_info_;
7193 bool pretenure_ : 1; 7099 bool pretenure_ : 1;
7194 bool has_no_literals_ : 1; 7100 bool has_no_literals_ : 1;
7195 bool is_generator_ : 1; 7101 bool is_generator_ : 1;
7196 LanguageMode language_mode_; 7102 LanguageMode language_mode_;
7197 }; 7103 };
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
7248 7154
7249 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 7155 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
7250 return Representation::Tagged(); 7156 return Representation::Tagged();
7251 } 7157 }
7252 7158
7253 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties) 7159 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
7254 7160
7255 private: 7161 private:
7256 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) { 7162 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
7257 set_representation(Representation::Tagged()); 7163 set_representation(Representation::Tagged());
7258 SetChangesFlag(kNewSpacePromotion); 7164 SetGVNFlag(kChangesNewSpacePromotion);
7259 7165
7260 // This instruction is not marked as kChangesMaps, but does 7166 // This instruction is not marked as kChangesMaps, but does
7261 // change the map of the input operand. Use it only when creating 7167 // change the map of the input operand. Use it only when creating
7262 // object literals via a runtime call. 7168 // object literals via a runtime call.
7263 ASSERT(value->IsCallRuntime()); 7169 ASSERT(value->IsCallRuntime());
7264 #ifdef DEBUG 7170 #ifdef DEBUG
7265 const Runtime::Function* function = HCallRuntime::cast(value)->function(); 7171 const Runtime::Function* function = HCallRuntime::cast(value)->function();
7266 ASSERT(function->function_id == Runtime::kCreateObjectLiteral); 7172 ASSERT(function->function_id == Runtime::kCreateObjectLiteral);
7267 #endif 7173 #endif
7268 } 7174 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
7327 } 7233 }
7328 7234
7329 private: 7235 private:
7330 HSeqStringGetChar(String::Encoding encoding, 7236 HSeqStringGetChar(String::Encoding encoding,
7331 HValue* string, 7237 HValue* string,
7332 HValue* index) : encoding_(encoding) { 7238 HValue* index) : encoding_(encoding) {
7333 SetOperandAt(0, string); 7239 SetOperandAt(0, string);
7334 SetOperandAt(1, index); 7240 SetOperandAt(1, index);
7335 set_representation(Representation::Integer32()); 7241 set_representation(Representation::Integer32());
7336 SetFlag(kUseGVN); 7242 SetFlag(kUseGVN);
7337 SetDependsOnFlag(kStringChars); 7243 SetGVNFlag(kDependsOnStringChars);
7338 } 7244 }
7339 7245
7340 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 7246 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
7341 7247
7342 String::Encoding encoding_; 7248 String::Encoding encoding_;
7343 }; 7249 };
7344 7250
7345 7251
7346 class HSeqStringSetChar V8_FINAL : public HTemplateInstruction<4> { 7252 class HSeqStringSetChar V8_FINAL : public HTemplateInstruction<4> {
7347 public: 7253 public:
(...skipping 18 matching lines...) Expand all
7366 HSeqStringSetChar(HValue* context, 7272 HSeqStringSetChar(HValue* context,
7367 String::Encoding encoding, 7273 String::Encoding encoding,
7368 HValue* string, 7274 HValue* string,
7369 HValue* index, 7275 HValue* index,
7370 HValue* value) : encoding_(encoding) { 7276 HValue* value) : encoding_(encoding) {
7371 SetOperandAt(0, context); 7277 SetOperandAt(0, context);
7372 SetOperandAt(1, string); 7278 SetOperandAt(1, string);
7373 SetOperandAt(2, index); 7279 SetOperandAt(2, index);
7374 SetOperandAt(3, value); 7280 SetOperandAt(3, value);
7375 set_representation(Representation::Tagged()); 7281 set_representation(Representation::Tagged());
7376 SetChangesFlag(kStringChars); 7282 SetGVNFlag(kChangesStringChars);
7377 } 7283 }
7378 7284
7379 String::Encoding encoding_; 7285 String::Encoding encoding_;
7380 }; 7286 };
7381 7287
7382 7288
7383 class HCheckMapValue V8_FINAL : public HTemplateInstruction<2> { 7289 class HCheckMapValue V8_FINAL : public HTemplateInstruction<2> {
7384 public: 7290 public:
7385 DECLARE_INSTRUCTION_FACTORY_P2(HCheckMapValue, HValue*, HValue*); 7291 DECLARE_INSTRUCTION_FACTORY_P2(HCheckMapValue, HValue*, HValue*);
7386 7292
(...skipping 19 matching lines...) Expand all
7406 return true; 7312 return true;
7407 } 7313 }
7408 7314
7409 private: 7315 private:
7410 HCheckMapValue(HValue* value, 7316 HCheckMapValue(HValue* value,
7411 HValue* map) { 7317 HValue* map) {
7412 SetOperandAt(0, value); 7318 SetOperandAt(0, value);
7413 SetOperandAt(1, map); 7319 SetOperandAt(1, map);
7414 set_representation(Representation::Tagged()); 7320 set_representation(Representation::Tagged());
7415 SetFlag(kUseGVN); 7321 SetFlag(kUseGVN);
7416 SetDependsOnFlag(kMaps); 7322 SetGVNFlag(kDependsOnMaps);
7417 SetDependsOnFlag(kElementsKind); 7323 SetGVNFlag(kDependsOnElementsKind);
7418 } 7324 }
7419 }; 7325 };
7420 7326
7421 7327
7422 class HForInPrepareMap V8_FINAL : public HTemplateInstruction<2> { 7328 class HForInPrepareMap V8_FINAL : public HTemplateInstruction<2> {
7423 public: 7329 public:
7424 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HForInPrepareMap, HValue*); 7330 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HForInPrepareMap, HValue*);
7425 7331
7426 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 7332 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
7427 return Representation::Tagged(); 7333 return Representation::Tagged();
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
7519 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 7425 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
7520 }; 7426 };
7521 7427
7522 7428
7523 #undef DECLARE_INSTRUCTION 7429 #undef DECLARE_INSTRUCTION
7524 #undef DECLARE_CONCRETE_INSTRUCTION 7430 #undef DECLARE_CONCRETE_INSTRUCTION
7525 7431
7526 } } // namespace v8::internal 7432 } } // namespace v8::internal
7527 7433
7528 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 7434 #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