| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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_ |
| OLD | NEW |