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