OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 class LArgument; | 48 class LArgument; |
49 class LChunk; | 49 class LChunk; |
50 class LConstantOperand; | 50 class LConstantOperand; |
51 class LGap; | 51 class LGap; |
52 class LInstruction; | 52 class LInstruction; |
53 class LParallelMove; | 53 class LParallelMove; |
54 class LPointerMap; | 54 class LPointerMap; |
55 class LStackSlot; | 55 class LStackSlot; |
56 class LRegister; | 56 class LRegister; |
57 | 57 |
58 | |
59 // This class represents a single point of a LOperand's lifetime. | 58 // This class represents a single point of a LOperand's lifetime. |
60 // For each lithium instruction there are exactly two lifetime positions: | 59 // For each lithium instruction there are exactly two lifetime positions: |
61 // the beginning and the end of the instruction. Lifetime positions for | 60 // the beginning and the end of the instruction. Lifetime positions for |
62 // different lithium instructions are disjoint. | 61 // different lithium instructions are disjoint. |
63 class LifetimePosition { | 62 class LifetimePosition { |
64 public: | 63 public: |
65 // Return the lifetime position that corresponds to the beginning of | 64 // Return the lifetime position that corresponds to the beginning of |
66 // the instruction with the given index. | 65 // the instruction with the given index. |
67 static LifetimePosition FromInstructionIndex(int index) { | 66 static LifetimePosition FromInstructionIndex(int index) { |
68 return LifetimePosition(index * kStep); | 67 return LifetimePosition(index * kStep); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 } | 114 } |
116 | 115 |
117 // Constructs the lifetime position which does not correspond to any | 116 // Constructs the lifetime position which does not correspond to any |
118 // instruction. | 117 // instruction. |
119 LifetimePosition() : value_(-1) {} | 118 LifetimePosition() : value_(-1) {} |
120 | 119 |
121 // Returns true if this lifetime positions corrensponds to some | 120 // Returns true if this lifetime positions corrensponds to some |
122 // instruction. | 121 // instruction. |
123 bool IsValid() const { return value_ != -1; } | 122 bool IsValid() const { return value_ != -1; } |
124 | 123 |
125 static inline LifetimePosition Invalid() { return LifetimePosition(); } | 124 static LifetimePosition Invalid() { return LifetimePosition(); } |
126 | |
127 static inline LifetimePosition MaxPosition() { | |
128 // We have to use this kind of getter instead of static member due to | |
129 // crash bug in GDB. | |
130 return LifetimePosition(kMaxInt); | |
131 } | |
132 | 125 |
133 private: | 126 private: |
134 static const int kStep = 2; | 127 static const int kStep = 2; |
135 | 128 |
136 // Code relies on kStep being a power of two. | 129 // Code relies on kStep being a power of two. |
137 STATIC_ASSERT(IS_POWER_OF_TWO(kStep)); | 130 STATIC_ASSERT(IS_POWER_OF_TWO(kStep)); |
138 | 131 |
139 explicit LifetimePosition(int value) : value_(value) { } | 132 explicit LifetimePosition(int value) : value_(value) { } |
140 | 133 |
141 int value_; | 134 int value_; |
142 }; | 135 }; |
143 | 136 |
144 | 137 |
145 enum RegisterKind { | |
146 NONE, | |
147 GENERAL_REGISTERS, | |
148 DOUBLE_REGISTERS | |
149 }; | |
150 | |
151 | |
152 class LOperand: public ZoneObject { | 138 class LOperand: public ZoneObject { |
153 public: | 139 public: |
154 enum Kind { | 140 enum Kind { |
155 INVALID, | 141 INVALID, |
156 UNALLOCATED, | 142 UNALLOCATED, |
157 CONSTANT_OPERAND, | 143 CONSTANT_OPERAND, |
158 STACK_SLOT, | 144 STACK_SLOT, |
159 DOUBLE_STACK_SLOT, | 145 DOUBLE_STACK_SLOT, |
160 REGISTER, | 146 REGISTER, |
161 DOUBLE_REGISTER, | 147 DOUBLE_REGISTER, |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 | 587 |
602 // Representation of SSA values' live ranges as a collection of (continuous) | 588 // Representation of SSA values' live ranges as a collection of (continuous) |
603 // intervals over the instruction ordering. | 589 // intervals over the instruction ordering. |
604 class LiveRange: public ZoneObject { | 590 class LiveRange: public ZoneObject { |
605 public: | 591 public: |
606 static const int kInvalidAssignment = 0x7fffffff; | 592 static const int kInvalidAssignment = 0x7fffffff; |
607 | 593 |
608 explicit LiveRange(int id) | 594 explicit LiveRange(int id) |
609 : id_(id), | 595 : id_(id), |
610 spilled_(false), | 596 spilled_(false), |
| 597 assigned_double_(false), |
611 assigned_register_(kInvalidAssignment), | 598 assigned_register_(kInvalidAssignment), |
612 assigned_register_kind_(NONE), | |
613 last_interval_(NULL), | 599 last_interval_(NULL), |
614 first_interval_(NULL), | 600 first_interval_(NULL), |
615 first_pos_(NULL), | 601 first_pos_(NULL), |
616 parent_(NULL), | 602 parent_(NULL), |
617 next_(NULL), | 603 next_(NULL), |
618 current_interval_(NULL), | 604 current_interval_(NULL), |
619 last_processed_use_(NULL), | 605 last_processed_use_(NULL), |
620 spill_start_index_(kMaxInt) { | 606 spill_start_index_(kMaxInt) { |
621 spill_operand_ = new LUnallocated(LUnallocated::IGNORE); | 607 spill_operand_ = new LUnallocated(LUnallocated::IGNORE); |
622 } | 608 } |
623 | 609 |
624 UseInterval* first_interval() const { return first_interval_; } | 610 UseInterval* first_interval() const { return first_interval_; } |
625 UsePosition* first_pos() const { return first_pos_; } | 611 UsePosition* first_pos() const { return first_pos_; } |
626 LiveRange* parent() const { return parent_; } | 612 LiveRange* parent() const { return parent_; } |
627 LiveRange* TopLevel() { return (parent_ == NULL) ? this : parent_; } | 613 LiveRange* TopLevel() { return (parent_ == NULL) ? this : parent_; } |
628 LiveRange* next() const { return next_; } | 614 LiveRange* next() const { return next_; } |
629 bool IsChild() const { return parent() != NULL; } | 615 bool IsChild() const { return parent() != NULL; } |
630 bool IsParent() const { return parent() == NULL; } | 616 bool IsParent() const { return parent() == NULL; } |
631 int id() const { return id_; } | 617 int id() const { return id_; } |
632 bool IsFixed() const { return id_ < 0; } | 618 bool IsFixed() const { return id_ < 0; } |
633 bool IsEmpty() const { return first_interval() == NULL; } | 619 bool IsEmpty() const { return first_interval() == NULL; } |
634 LOperand* CreateAssignedOperand(); | 620 LOperand* CreateAssignedOperand(); |
635 int assigned_register() const { return assigned_register_; } | 621 int assigned_register() const { return assigned_register_; } |
636 int spill_start_index() const { return spill_start_index_; } | 622 int spill_start_index() const { return spill_start_index_; } |
637 void set_assigned_register(int reg, RegisterKind register_kind) { | 623 void set_assigned_register(int reg, bool double_reg) { |
638 ASSERT(!HasRegisterAssigned() && !IsSpilled()); | 624 ASSERT(!HasRegisterAssigned() && !IsSpilled()); |
639 assigned_register_ = reg; | 625 assigned_register_ = reg; |
640 assigned_register_kind_ = register_kind; | 626 assigned_double_ = double_reg; |
641 ConvertOperands(); | 627 ConvertOperands(); |
642 } | 628 } |
643 void MakeSpilled() { | 629 void MakeSpilled() { |
644 ASSERT(!IsSpilled()); | 630 ASSERT(!IsSpilled()); |
645 ASSERT(TopLevel()->HasAllocatedSpillOperand()); | 631 ASSERT(TopLevel()->HasAllocatedSpillOperand()); |
646 spilled_ = true; | 632 spilled_ = true; |
647 assigned_register_ = kInvalidAssignment; | 633 assigned_register_ = kInvalidAssignment; |
648 ConvertOperands(); | 634 ConvertOperands(); |
649 } | 635 } |
650 | 636 |
651 // Returns use position in this live range that follows both start | 637 // Returns use position in this live range that follows both start |
652 // and last processed use position. | 638 // and last processed use position. |
653 // Modifies internal state of live range! | 639 // Modifies internal state of live range! |
654 UsePosition* NextUsePosition(LifetimePosition start); | 640 UsePosition* NextUsePosition(LifetimePosition start); |
655 | 641 |
656 // Returns use position for which register is required in this live | 642 // Returns use position for which register is required in this live |
657 // range and which follows both start and last processed use position | 643 // range and which follows both start and last processed use position |
658 // Modifies internal state of live range! | 644 // Modifies internal state of live range! |
659 UsePosition* NextRegisterPosition(LifetimePosition start); | 645 UsePosition* NextRegisterPosition(LifetimePosition start); |
660 | 646 |
661 // Returns use position for which register is beneficial in this live | 647 // Returns use position for which register is beneficial in this live |
662 // range and which follows both start and last processed use position | 648 // range and which follows both start and last processed use position |
663 // Modifies internal state of live range! | 649 // Modifies internal state of live range! |
664 UsePosition* NextUsePositionRegisterIsBeneficial(LifetimePosition start); | 650 UsePosition* NextUsePositionRegisterIsBeneficial(LifetimePosition start); |
665 | 651 |
666 // Can this live range be spilled at this position. | 652 // Can this live range be spilled at this position. |
667 bool CanBeSpilled(LifetimePosition pos); | 653 bool CanBeSpilled(LifetimePosition pos); |
668 | 654 |
669 // Split this live range at the given position which must follow the start of | |
670 // the range. | |
671 // All uses following the given position will be moved from this | |
672 // live range to the result live range. | |
673 void SplitAt(LifetimePosition position, LiveRange* result); | 655 void SplitAt(LifetimePosition position, LiveRange* result); |
674 | 656 |
675 bool IsDouble() const { return assigned_register_kind_ == DOUBLE_REGISTERS; } | 657 bool IsDouble() const { return assigned_double_; } |
676 bool HasRegisterAssigned() const { | 658 bool HasRegisterAssigned() const { |
677 return assigned_register_ != kInvalidAssignment; | 659 return assigned_register_ != kInvalidAssignment; |
678 } | 660 } |
679 bool IsSpilled() const { return spilled_; } | 661 bool IsSpilled() const { return spilled_; } |
680 UsePosition* FirstPosWithHint() const; | 662 UsePosition* FirstPosWithHint() const; |
681 | 663 |
682 LOperand* FirstHint() const { | 664 LOperand* FirstHint() const { |
683 UsePosition* pos = FirstPosWithHint(); | 665 UsePosition* pos = FirstPosWithHint(); |
684 if (pos != NULL) return pos->hint(); | 666 if (pos != NULL) return pos->hint(); |
685 return NULL; | 667 return NULL; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
732 #endif | 714 #endif |
733 | 715 |
734 private: | 716 private: |
735 void ConvertOperands(); | 717 void ConvertOperands(); |
736 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const; | 718 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const; |
737 void AdvanceLastProcessedMarker(UseInterval* to_start_of, | 719 void AdvanceLastProcessedMarker(UseInterval* to_start_of, |
738 LifetimePosition but_not_past) const; | 720 LifetimePosition but_not_past) const; |
739 | 721 |
740 int id_; | 722 int id_; |
741 bool spilled_; | 723 bool spilled_; |
| 724 bool assigned_double_; |
742 int assigned_register_; | 725 int assigned_register_; |
743 RegisterKind assigned_register_kind_; | |
744 UseInterval* last_interval_; | 726 UseInterval* last_interval_; |
745 UseInterval* first_interval_; | 727 UseInterval* first_interval_; |
746 UsePosition* first_pos_; | 728 UsePosition* first_pos_; |
747 LiveRange* parent_; | 729 LiveRange* parent_; |
748 LiveRange* next_; | 730 LiveRange* next_; |
749 // This is used as a cache, it doesn't affect correctness. | 731 // This is used as a cache, it doesn't affect correctness. |
750 mutable UseInterval* current_interval_; | 732 mutable UseInterval* current_interval_; |
751 UsePosition* last_processed_use_; | 733 UsePosition* last_processed_use_; |
752 LOperand* spill_operand_; | 734 LOperand* spill_operand_; |
753 int spill_start_index_; | 735 int spill_start_index_; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 void RecordDefinition(HInstruction* instr, LUnallocated* operand); | 767 void RecordDefinition(HInstruction* instr, LUnallocated* operand); |
786 // Record a temporary operand. | 768 // Record a temporary operand. |
787 void RecordTemporary(LUnallocated* operand); | 769 void RecordTemporary(LUnallocated* operand); |
788 | 770 |
789 // Marks the current instruction as a call. | 771 // Marks the current instruction as a call. |
790 void MarkAsCall(); | 772 void MarkAsCall(); |
791 | 773 |
792 // Checks whether the value of a given virtual register is tagged. | 774 // Checks whether the value of a given virtual register is tagged. |
793 bool HasTaggedValue(int virtual_register) const; | 775 bool HasTaggedValue(int virtual_register) const; |
794 | 776 |
795 // Returns the register kind required by the given virtual register. | 777 // Checks whether the value of a given virtual register is a double. |
796 RegisterKind RequiredRegisterKind(int virtual_register) const; | 778 bool HasDoubleValue(int virtual_register) const; |
797 | 779 |
798 // Begin a new instruction. | 780 // Begin a new instruction. |
799 void BeginInstruction(); | 781 void BeginInstruction(); |
800 | 782 |
801 // Summarize the current instruction. | 783 // Summarize the current instruction. |
802 void SummarizeInstruction(int index); | 784 void SummarizeInstruction(int index); |
803 | 785 |
804 // Summarize the current instruction. | 786 // Summarize the current instruction. |
805 void OmitInstruction(); | 787 void OmitInstruction(); |
806 | 788 |
(...skipping 18 matching lines...) Expand all Loading... |
825 ASSERT(!has_osr_entry_); | 807 ASSERT(!has_osr_entry_); |
826 // Simply set a flag to find and process instruction later. | 808 // Simply set a flag to find and process instruction later. |
827 has_osr_entry_ = true; | 809 has_osr_entry_ = true; |
828 } | 810 } |
829 | 811 |
830 #ifdef DEBUG | 812 #ifdef DEBUG |
831 void Verify() const; | 813 void Verify() const; |
832 #endif | 814 #endif |
833 | 815 |
834 private: | 816 private: |
| 817 enum OperationMode { |
| 818 NONE, |
| 819 CPU_REGISTERS, |
| 820 XMM_REGISTERS |
| 821 }; |
| 822 |
835 void MeetRegisterConstraints(); | 823 void MeetRegisterConstraints(); |
836 void ResolvePhis(); | 824 void ResolvePhis(); |
837 void BuildLiveRanges(); | 825 void BuildLiveRanges(); |
838 void AllocateGeneralRegisters(); | 826 void AllocateGeneralRegisters(); |
839 void AllocateDoubleRegisters(); | 827 void AllocateDoubleRegisters(); |
840 void ConnectRanges(); | 828 void ConnectRanges(); |
841 void ResolveControlFlow(); | 829 void ResolveControlFlow(); |
842 void PopulatePointerMaps(); | 830 void PopulatePointerMaps(); |
843 void ProcessOsrEntry(); | 831 void ProcessOsrEntry(); |
844 void AllocateRegisters(); | 832 void AllocateRegisters(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
876 void ActiveToHandled(LiveRange* range); | 864 void ActiveToHandled(LiveRange* range); |
877 void ActiveToInactive(LiveRange* range); | 865 void ActiveToInactive(LiveRange* range); |
878 void InactiveToHandled(LiveRange* range); | 866 void InactiveToHandled(LiveRange* range); |
879 void InactiveToActive(LiveRange* range); | 867 void InactiveToActive(LiveRange* range); |
880 void FreeSpillSlot(LiveRange* range); | 868 void FreeSpillSlot(LiveRange* range); |
881 LOperand* TryReuseSpillSlot(LiveRange* range); | 869 LOperand* TryReuseSpillSlot(LiveRange* range); |
882 | 870 |
883 // Helper methods for allocating registers. | 871 // Helper methods for allocating registers. |
884 bool TryAllocateFreeReg(LiveRange* range); | 872 bool TryAllocateFreeReg(LiveRange* range); |
885 void AllocateBlockedReg(LiveRange* range); | 873 void AllocateBlockedReg(LiveRange* range); |
886 | 874 void SplitAndSpillIntersecting(LiveRange* range); |
887 // Live range splitting helpers. | |
888 | |
889 // Split the given range at the given position. | |
890 // If range starts at or after the given position then the | |
891 // original range is returned. | |
892 // Otherwise returns the live range that starts at pos and contains | |
893 // all uses from the original range that follow pos. Uses at pos will | |
894 // still be owned by the original range after splitting. | |
895 LiveRange* SplitAt(LiveRange* range, LifetimePosition pos); | |
896 | |
897 // Split the given range in a position from the interval [start, end]. | |
898 LiveRange* SplitBetween(LiveRange* range, | |
899 LifetimePosition start, | |
900 LifetimePosition end); | |
901 | |
902 // Find a lifetime position in the interval [start, end] which | |
903 // is optimal for splitting: it is either header of the outermost | |
904 // loop covered by this interval or the latest possible position. | |
905 LifetimePosition FindOptimalSplitPos(LifetimePosition start, | 875 LifetimePosition FindOptimalSplitPos(LifetimePosition start, |
906 LifetimePosition end); | 876 LifetimePosition end); |
907 | 877 LiveRange* Split(LiveRange* range, |
908 // Spill the given life range after position pos. | 878 LifetimePosition start, |
909 void SpillAfter(LiveRange* range, LifetimePosition pos); | 879 LifetimePosition end); |
910 | 880 LiveRange* Split(LiveRange* range, LifetimePosition split_pos); |
911 // Spill the given life range after position start and up to position end. | 881 void SplitAndSpill(LiveRange* range, |
912 void SpillBetween(LiveRange* range, | 882 LifetimePosition start, |
913 LifetimePosition start, | 883 LifetimePosition end); |
914 LifetimePosition end); | 884 void SplitAndSpill(LiveRange* range, LifetimePosition at); |
915 | |
916 void SplitAndSpillIntersecting(LiveRange* range); | |
917 | |
918 void Spill(LiveRange* range); | 885 void Spill(LiveRange* range); |
919 bool IsBlockBoundary(LifetimePosition pos); | 886 bool IsBlockBoundary(LifetimePosition pos); |
920 void AddGapMove(int pos, LiveRange* prev, LiveRange* next); | 887 void AddGapMove(int pos, LiveRange* prev, LiveRange* next); |
921 | 888 |
922 // Helper methods for resolving control flow. | 889 // Helper methods for resolving control flow. |
923 void ResolveControlFlow(LiveRange* range, | 890 void ResolveControlFlow(LiveRange* range, |
924 HBasicBlock* block, | 891 HBasicBlock* block, |
925 HBasicBlock* pred); | 892 HBasicBlock* pred); |
926 | 893 |
927 // Return parallel move that should be used to connect ranges split at the | 894 // Return parallel move that should be used to connect ranges split at the |
(...skipping 12 matching lines...) Expand all Loading... |
940 // Helper methods for the fixed registers. | 907 // Helper methods for the fixed registers. |
941 int RegisterCount() const; | 908 int RegisterCount() const; |
942 static int FixedLiveRangeID(int index) { return -index - 1; } | 909 static int FixedLiveRangeID(int index) { return -index - 1; } |
943 static int FixedDoubleLiveRangeID(int index); | 910 static int FixedDoubleLiveRangeID(int index); |
944 LiveRange* FixedLiveRangeFor(int index); | 911 LiveRange* FixedLiveRangeFor(int index); |
945 LiveRange* FixedDoubleLiveRangeFor(int index); | 912 LiveRange* FixedDoubleLiveRangeFor(int index); |
946 LiveRange* LiveRangeFor(int index); | 913 LiveRange* LiveRangeFor(int index); |
947 HPhi* LookupPhi(LOperand* operand) const; | 914 HPhi* LookupPhi(LOperand* operand) const; |
948 LGap* GetLastGap(HBasicBlock* block) const; | 915 LGap* GetLastGap(HBasicBlock* block) const; |
949 | 916 |
950 const char* RegisterName(int allocation_index); | |
951 | |
952 LChunk* chunk_; | 917 LChunk* chunk_; |
953 ZoneList<InstructionSummary*> summaries_; | 918 ZoneList<InstructionSummary*> summaries_; |
954 InstructionSummary* next_summary_; | 919 InstructionSummary* next_summary_; |
955 | 920 |
956 ZoneList<InstructionSummary*> summary_stack_; | 921 ZoneList<InstructionSummary*> summary_stack_; |
957 | 922 |
958 // During liveness analysis keep a mapping from block id to live_in sets | 923 // During liveness analysis keep a mapping from block id to live_in sets |
959 // for blocks already analyzed. | 924 // for blocks already analyzed. |
960 ZoneList<BitVector*> live_in_sets_; | 925 ZoneList<BitVector*> live_in_sets_; |
961 | 926 |
962 // Liveness analysis results. | 927 // Liveness analysis results. |
963 ZoneList<LiveRange*> live_ranges_; | 928 ZoneList<LiveRange*> live_ranges_; |
964 | 929 |
965 // Lists of live ranges | 930 // Lists of live ranges |
966 ZoneList<LiveRange*> fixed_live_ranges_; | 931 ZoneList<LiveRange*> fixed_live_ranges_; |
967 ZoneList<LiveRange*> fixed_double_live_ranges_; | 932 ZoneList<LiveRange*> fixed_double_live_ranges_; |
968 ZoneList<LiveRange*> unhandled_live_ranges_; | 933 ZoneList<LiveRange*> unhandled_live_ranges_; |
969 ZoneList<LiveRange*> active_live_ranges_; | 934 ZoneList<LiveRange*> active_live_ranges_; |
970 ZoneList<LiveRange*> inactive_live_ranges_; | 935 ZoneList<LiveRange*> inactive_live_ranges_; |
971 ZoneList<LiveRange*> reusable_slots_; | 936 ZoneList<LiveRange*> reusable_slots_; |
972 | 937 |
973 // Next virtual register number to be assigned to temporaries. | 938 // Next virtual register number to be assigned to temporaries. |
974 int next_virtual_register_; | 939 int next_virtual_register_; |
975 | 940 |
976 RegisterKind mode_; | 941 OperationMode mode_; |
977 int num_registers_; | 942 int num_registers_; |
978 | 943 |
979 HGraph* graph_; | 944 HGraph* graph_; |
980 | 945 |
981 bool has_osr_entry_; | 946 bool has_osr_entry_; |
982 | 947 |
983 DISALLOW_COPY_AND_ASSIGN(LAllocator); | 948 DISALLOW_COPY_AND_ASSIGN(LAllocator); |
984 }; | 949 }; |
985 | 950 |
986 | 951 |
987 } } // namespace v8::internal | 952 } } // namespace v8::internal |
988 | 953 |
989 #endif // V8_LITHIUM_ALLOCATOR_H_ | 954 #endif // V8_LITHIUM_ALLOCATOR_H_ |
OLD | NEW |