| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 LChunkBuilder* builder) V8_FINAL V8_OVERRIDE; \ | 217 LChunkBuilder* builder) V8_FINAL V8_OVERRIDE; \ |
| 218 static H##type* cast(HValue* value) { \ | 218 static H##type* cast(HValue* value) { \ |
| 219 ASSERT(value->Is##type()); \ | 219 ASSERT(value->Is##type()); \ |
| 220 return reinterpret_cast<H##type*>(value); \ | 220 return reinterpret_cast<H##type*>(value); \ |
| 221 } \ | 221 } \ |
| 222 virtual Opcode opcode() const V8_FINAL V8_OVERRIDE { \ | 222 virtual Opcode opcode() const V8_FINAL V8_OVERRIDE { \ |
| 223 return HValue::k##type; \ | 223 return HValue::k##type; \ |
| 224 } | 224 } |
| 225 | 225 |
| 226 | 226 |
| 227 enum PropertyAccessType { LOAD, STORE }; |
| 228 |
| 229 |
| 227 class Range V8_FINAL : public ZoneObject { | 230 class Range V8_FINAL : public ZoneObject { |
| 228 public: | 231 public: |
| 229 Range() | 232 Range() |
| 230 : lower_(kMinInt), | 233 : lower_(kMinInt), |
| 231 upper_(kMaxInt), | 234 upper_(kMaxInt), |
| 232 next_(NULL), | 235 next_(NULL), |
| 233 can_be_minus_zero_(false) { } | 236 can_be_minus_zero_(false) { } |
| 234 | 237 |
| 235 Range(int32_t lower, int32_t upper) | 238 Range(int32_t lower, int32_t upper) |
| 236 : lower_(lower), | 239 : lower_(lower), |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 | 478 |
| 476 // There must be one corresponding kDepends flag for every kChanges flag and | 479 // There must be one corresponding kDepends flag for every kChanges flag and |
| 477 // the order of the kChanges flags must be exactly the same as of the kDepends | 480 // the order of the kChanges flags must be exactly the same as of the kDepends |
| 478 // flags. All tracked flags should appear before untracked ones. | 481 // flags. All tracked flags should appear before untracked ones. |
| 479 enum GVNFlag { | 482 enum GVNFlag { |
| 480 // Declare global value numbering flags. | 483 // Declare global value numbering flags. |
| 481 #define DECLARE_FLAG(type) kChanges##type, kDependsOn##type, | 484 #define DECLARE_FLAG(type) kChanges##type, kDependsOn##type, |
| 482 GVN_TRACKED_FLAG_LIST(DECLARE_FLAG) | 485 GVN_TRACKED_FLAG_LIST(DECLARE_FLAG) |
| 483 GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG) | 486 GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG) |
| 484 #undef DECLARE_FLAG | 487 #undef DECLARE_FLAG |
| 485 kAfterLastFlag, | 488 kNumberOfFlags, |
| 486 kLastFlag = kAfterLastFlag - 1, | |
| 487 #define COUNT_FLAG(type) + 1 | 489 #define COUNT_FLAG(type) + 1 |
| 488 kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG) | 490 kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG) |
| 489 #undef COUNT_FLAG | 491 #undef COUNT_FLAG |
| 490 }; | 492 }; |
| 491 | 493 |
| 492 | 494 |
| 493 class DecompositionResult V8_FINAL BASE_EMBEDDED { | 495 class DecompositionResult V8_FINAL BASE_EMBEDDED { |
| 494 public: | 496 public: |
| 495 DecompositionResult() : base_(NULL), offset_(0), scale_(0) {} | 497 DecompositionResult() : base_(NULL), offset_(0), scale_(0) {} |
| 496 | 498 |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 868 | 870 |
| 869 // Updated the inferred type of this instruction and returns true if | 871 // Updated the inferred type of this instruction and returns true if |
| 870 // it has changed. | 872 // it has changed. |
| 871 bool UpdateInferredType(); | 873 bool UpdateInferredType(); |
| 872 | 874 |
| 873 virtual HType CalculateInferredType(); | 875 virtual HType CalculateInferredType(); |
| 874 | 876 |
| 875 // This function must be overridden for instructions which have the | 877 // This function must be overridden for instructions which have the |
| 876 // kTrackSideEffectDominators flag set, to track instructions that are | 878 // kTrackSideEffectDominators flag set, to track instructions that are |
| 877 // dominating side effects. | 879 // dominating side effects. |
| 878 virtual void HandleSideEffectDominator(GVNFlag side_effect, | 880 // It returns true if it removed an instruction which had side effects. |
| 881 virtual bool HandleSideEffectDominator(GVNFlag side_effect, |
| 879 HValue* dominator) { | 882 HValue* dominator) { |
| 880 UNREACHABLE(); | 883 UNREACHABLE(); |
| 884 return false; |
| 881 } | 885 } |
| 882 | 886 |
| 883 // Check if this instruction has some reason that prevents elimination. | 887 // Check if this instruction has some reason that prevents elimination. |
| 884 bool CannotBeEliminated() const { | 888 bool CannotBeEliminated() const { |
| 885 return HasObservableSideEffects() || !IsDeletable(); | 889 return HasObservableSideEffects() || !IsDeletable(); |
| 886 } | 890 } |
| 887 | 891 |
| 888 #ifdef DEBUG | 892 #ifdef DEBUG |
| 889 virtual void Verify() = 0; | 893 virtual void Verify() = 0; |
| 890 #endif | 894 #endif |
| (...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1522 ToBooleanStub::Types expected_input_types_; | 1526 ToBooleanStub::Types expected_input_types_; |
| 1523 }; | 1527 }; |
| 1524 | 1528 |
| 1525 | 1529 |
| 1526 class HCompareMap V8_FINAL : public HUnaryControlInstruction { | 1530 class HCompareMap V8_FINAL : public HUnaryControlInstruction { |
| 1527 public: | 1531 public: |
| 1528 DECLARE_INSTRUCTION_FACTORY_P2(HCompareMap, HValue*, Handle<Map>); | 1532 DECLARE_INSTRUCTION_FACTORY_P2(HCompareMap, HValue*, Handle<Map>); |
| 1529 DECLARE_INSTRUCTION_FACTORY_P4(HCompareMap, HValue*, Handle<Map>, | 1533 DECLARE_INSTRUCTION_FACTORY_P4(HCompareMap, HValue*, Handle<Map>, |
| 1530 HBasicBlock*, HBasicBlock*); | 1534 HBasicBlock*, HBasicBlock*); |
| 1531 | 1535 |
| 1536 virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE { |
| 1537 if (known_successor_index() != kNoKnownSuccessorIndex) { |
| 1538 *block = SuccessorAt(known_successor_index()); |
| 1539 return true; |
| 1540 } |
| 1541 *block = NULL; |
| 1542 return false; |
| 1543 } |
| 1544 |
| 1532 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 1545 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 1533 | 1546 |
| 1547 static const int kNoKnownSuccessorIndex = -1; |
| 1548 int known_successor_index() const { return known_successor_index_; } |
| 1549 void set_known_successor_index(int known_successor_index) { |
| 1550 known_successor_index_ = known_successor_index; |
| 1551 } |
| 1552 |
| 1534 Unique<Map> map() const { return map_; } | 1553 Unique<Map> map() const { return map_; } |
| 1535 | 1554 |
| 1536 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 1555 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 1537 return Representation::Tagged(); | 1556 return Representation::Tagged(); |
| 1538 } | 1557 } |
| 1539 | 1558 |
| 1540 DECLARE_CONCRETE_INSTRUCTION(CompareMap) | 1559 DECLARE_CONCRETE_INSTRUCTION(CompareMap) |
| 1541 | 1560 |
| 1542 protected: | 1561 protected: |
| 1543 virtual int RedefinedOperandIndex() { return 0; } | 1562 virtual int RedefinedOperandIndex() { return 0; } |
| 1544 | 1563 |
| 1545 private: | 1564 private: |
| 1546 HCompareMap(HValue* value, | 1565 HCompareMap(HValue* value, |
| 1547 Handle<Map> map, | 1566 Handle<Map> map, |
| 1548 HBasicBlock* true_target = NULL, | 1567 HBasicBlock* true_target = NULL, |
| 1549 HBasicBlock* false_target = NULL) | 1568 HBasicBlock* false_target = NULL) |
| 1550 : HUnaryControlInstruction(value, true_target, false_target), | 1569 : HUnaryControlInstruction(value, true_target, false_target), |
| 1551 map_(Unique<Map>(map)) { | 1570 known_successor_index_(kNoKnownSuccessorIndex), map_(Unique<Map>(map)) { |
| 1552 ASSERT(!map.is_null()); | 1571 ASSERT(!map.is_null()); |
| 1553 } | 1572 } |
| 1554 | 1573 |
| 1574 int known_successor_index_; |
| 1555 Unique<Map> map_; | 1575 Unique<Map> map_; |
| 1556 }; | 1576 }; |
| 1557 | 1577 |
| 1558 | 1578 |
| 1559 class HContext V8_FINAL : public HTemplateInstruction<0> { | 1579 class HContext V8_FINAL : public HTemplateInstruction<0> { |
| 1560 public: | 1580 public: |
| 1561 static HContext* New(Zone* zone) { | 1581 static HContext* New(Zone* zone) { |
| 1562 return new(zone) HContext(); | 1582 return new(zone) HContext(); |
| 1563 } | 1583 } |
| 1564 | 1584 |
| (...skipping 1059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2624 virtual bool IsDeletable() const V8_OVERRIDE { return true; } | 2644 virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
| 2625 | 2645 |
| 2626 const Heap::RootListIndex index_; | 2646 const Heap::RootListIndex index_; |
| 2627 }; | 2647 }; |
| 2628 | 2648 |
| 2629 | 2649 |
| 2630 class HCheckMaps V8_FINAL : public HTemplateInstruction<2> { | 2650 class HCheckMaps V8_FINAL : public HTemplateInstruction<2> { |
| 2631 public: | 2651 public: |
| 2632 static HCheckMaps* New(Zone* zone, HValue* context, HValue* value, | 2652 static HCheckMaps* New(Zone* zone, HValue* context, HValue* value, |
| 2633 Handle<Map> map, CompilationInfo* info, | 2653 Handle<Map> map, CompilationInfo* info, |
| 2634 HValue *typecheck = NULL); | 2654 HValue* typecheck = NULL); |
| 2635 static HCheckMaps* New(Zone* zone, HValue* context, | 2655 static HCheckMaps* New(Zone* zone, HValue* context, |
| 2636 HValue* value, SmallMapList* maps, | 2656 HValue* value, SmallMapList* maps, |
| 2637 HValue *typecheck = NULL) { | 2657 HValue* typecheck = NULL) { |
| 2638 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck); | 2658 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck); |
| 2639 for (int i = 0; i < maps->length(); i++) { | 2659 for (int i = 0; i < maps->length(); i++) { |
| 2640 check_map->Add(maps->at(i), zone); | 2660 check_map->Add(maps->at(i), zone); |
| 2641 } | 2661 } |
| 2642 return check_map; | 2662 return check_map; |
| 2643 } | 2663 } |
| 2644 | 2664 |
| 2645 bool CanOmitMapChecks() { return omit_; } | 2665 bool CanOmitMapChecks() { return omit_; } |
| 2646 | 2666 |
| 2647 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } | 2667 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } |
| 2648 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 2668 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 2649 return Representation::Tagged(); | 2669 return Representation::Tagged(); |
| 2650 } | 2670 } |
| 2651 virtual void HandleSideEffectDominator(GVNFlag side_effect, | 2671 virtual bool HandleSideEffectDominator(GVNFlag side_effect, |
| 2652 HValue* dominator) V8_OVERRIDE; | 2672 HValue* dominator) V8_OVERRIDE; |
| 2653 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 2673 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 2654 | 2674 |
| 2655 HValue* value() { return OperandAt(0); } | 2675 HValue* value() { return OperandAt(0); } |
| 2676 HValue* typecheck() { return OperandAt(1); } |
| 2656 | 2677 |
| 2657 Unique<Map> first_map() const { return map_set_.at(0); } | 2678 Unique<Map> first_map() const { return map_set_.at(0); } |
| 2658 UniqueSet<Map> map_set() const { return map_set_; } | 2679 UniqueSet<Map> map_set() const { return map_set_; } |
| 2659 | 2680 |
| 2681 void set_map_set(UniqueSet<Map>* maps, Zone *zone) { |
| 2682 map_set_.Clear(); |
| 2683 for (int i = 0; i < maps->size(); i++) { |
| 2684 map_set_.Add(maps->at(i), zone); |
| 2685 } |
| 2686 } |
| 2687 |
| 2660 bool has_migration_target() const { | 2688 bool has_migration_target() const { |
| 2661 return has_migration_target_; | 2689 return has_migration_target_; |
| 2662 } | 2690 } |
| 2663 | 2691 |
| 2664 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) | 2692 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) |
| 2665 | 2693 |
| 2666 protected: | 2694 protected: |
| 2667 virtual bool DataEquals(HValue* other) V8_OVERRIDE { | 2695 virtual bool DataEquals(HValue* other) V8_OVERRIDE { |
| 2668 return this->map_set_.Equals(&HCheckMaps::cast(other)->map_set_); | 2696 return this->map_set_.Equals(&HCheckMaps::cast(other)->map_set_); |
| 2669 } | 2697 } |
| (...skipping 2639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5309 } | 5337 } |
| 5310 | 5338 |
| 5311 bool MustClearNextMapWord() const { | 5339 bool MustClearNextMapWord() const { |
| 5312 return (flags_ & CLEAR_NEXT_MAP_WORD) != 0; | 5340 return (flags_ & CLEAR_NEXT_MAP_WORD) != 0; |
| 5313 } | 5341 } |
| 5314 | 5342 |
| 5315 void MakeDoubleAligned() { | 5343 void MakeDoubleAligned() { |
| 5316 flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATE_DOUBLE_ALIGNED); | 5344 flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATE_DOUBLE_ALIGNED); |
| 5317 } | 5345 } |
| 5318 | 5346 |
| 5319 virtual void HandleSideEffectDominator(GVNFlag side_effect, | 5347 virtual bool HandleSideEffectDominator(GVNFlag side_effect, |
| 5320 HValue* dominator) V8_OVERRIDE; | 5348 HValue* dominator) V8_OVERRIDE; |
| 5321 | 5349 |
| 5322 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 5350 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 5323 | 5351 |
| 5324 DECLARE_CONCRETE_INSTRUCTION(Allocate) | 5352 DECLARE_CONCRETE_INSTRUCTION(Allocate) |
| 5325 | 5353 |
| 5326 private: | 5354 private: |
| 5327 enum Flags { | 5355 enum Flags { |
| 5328 ALLOCATE_IN_NEW_SPACE = 1 << 0, | 5356 ALLOCATE_IN_NEW_SPACE = 1 << 0, |
| 5329 ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1, | 5357 ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1, |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5703 } | 5731 } |
| 5704 | 5732 |
| 5705 inline Handle<String> name() const { | 5733 inline Handle<String> name() const { |
| 5706 return name_; | 5734 return name_; |
| 5707 } | 5735 } |
| 5708 | 5736 |
| 5709 inline bool immutable() const { | 5737 inline bool immutable() const { |
| 5710 return ImmutableField::decode(value_); | 5738 return ImmutableField::decode(value_); |
| 5711 } | 5739 } |
| 5712 | 5740 |
| 5741 // Returns true if access is being made to an in-object property that |
| 5742 // was already added to the object. |
| 5743 inline bool existing_inobject_property() const { |
| 5744 return ExistingInobjectPropertyField::decode(value_); |
| 5745 } |
| 5746 |
| 5713 inline HObjectAccess WithRepresentation(Representation representation) { | 5747 inline HObjectAccess WithRepresentation(Representation representation) { |
| 5714 return HObjectAccess(portion(), offset(), representation, name()); | 5748 return HObjectAccess(portion(), offset(), representation, name(), |
| 5749 immutable(), existing_inobject_property()); |
| 5715 } | 5750 } |
| 5716 | 5751 |
| 5717 static HObjectAccess ForHeapNumberValue() { | 5752 static HObjectAccess ForHeapNumberValue() { |
| 5718 return HObjectAccess( | 5753 return HObjectAccess( |
| 5719 kDouble, HeapNumber::kValueOffset, Representation::Double()); | 5754 kDouble, HeapNumber::kValueOffset, Representation::Double()); |
| 5720 } | 5755 } |
| 5721 | 5756 |
| 5722 static HObjectAccess ForHeapNumberValueLowestBits() { | 5757 static HObjectAccess ForHeapNumberValueLowestBits() { |
| 5723 return HObjectAccess(kDouble, | 5758 return HObjectAccess(kDouble, |
| 5724 HeapNumber::kValueOffset, | 5759 HeapNumber::kValueOffset, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 5748 kArrayLengths, | 5783 kArrayLengths, |
| 5749 JSArray::kLengthOffset, | 5784 JSArray::kLengthOffset, |
| 5750 IsFastElementsKind(elements_kind) && | 5785 IsFastElementsKind(elements_kind) && |
| 5751 FLAG_track_fields | 5786 FLAG_track_fields |
| 5752 ? Representation::Smi() : Representation::Tagged()); | 5787 ? Representation::Smi() : Representation::Tagged()); |
| 5753 } | 5788 } |
| 5754 | 5789 |
| 5755 static HObjectAccess ForAllocationSiteOffset(int offset); | 5790 static HObjectAccess ForAllocationSiteOffset(int offset); |
| 5756 | 5791 |
| 5757 static HObjectAccess ForAllocationSiteList() { | 5792 static HObjectAccess ForAllocationSiteList() { |
| 5758 return HObjectAccess(kExternalMemory, 0, Representation::Tagged()); | 5793 return HObjectAccess(kExternalMemory, 0, Representation::Tagged(), |
| 5794 Handle<String>::null(), false, false); |
| 5759 } | 5795 } |
| 5760 | 5796 |
| 5761 static HObjectAccess ForFixedArrayLength() { | 5797 static HObjectAccess ForFixedArrayLength() { |
| 5762 return HObjectAccess( | 5798 return HObjectAccess( |
| 5763 kArrayLengths, | 5799 kArrayLengths, |
| 5764 FixedArray::kLengthOffset, | 5800 FixedArray::kLengthOffset, |
| 5765 FLAG_track_fields ? Representation::Smi() : Representation::Tagged()); | 5801 FLAG_track_fields ? Representation::Smi() : Representation::Tagged()); |
| 5766 } | 5802 } |
| 5767 | 5803 |
| 5768 static HObjectAccess ForStringHashField() { | 5804 static HObjectAccess ForStringHashField() { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5850 | 5886 |
| 5851 static HObjectAccess ForCellValue() { | 5887 static HObjectAccess ForCellValue() { |
| 5852 return HObjectAccess(kInobject, Cell::kValueOffset); | 5888 return HObjectAccess(kInobject, Cell::kValueOffset); |
| 5853 } | 5889 } |
| 5854 | 5890 |
| 5855 static HObjectAccess ForAllocationMementoSite() { | 5891 static HObjectAccess ForAllocationMementoSite() { |
| 5856 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset); | 5892 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset); |
| 5857 } | 5893 } |
| 5858 | 5894 |
| 5859 static HObjectAccess ForCounter() { | 5895 static HObjectAccess ForCounter() { |
| 5860 return HObjectAccess(kExternalMemory, 0, Representation::Integer32()); | 5896 return HObjectAccess(kExternalMemory, 0, Representation::Integer32(), |
| 5897 Handle<String>::null(), false, false); |
| 5861 } | 5898 } |
| 5862 | 5899 |
| 5863 // Create an access to an offset in a fixed array header. | 5900 // Create an access to an offset in a fixed array header. |
| 5864 static HObjectAccess ForFixedArrayHeader(int offset); | 5901 static HObjectAccess ForFixedArrayHeader(int offset); |
| 5865 | 5902 |
| 5866 // Create an access to an in-object property in a JSObject. | 5903 // Create an access to an in-object property in a JSObject. |
| 5867 static HObjectAccess ForJSObjectOffset(int offset, | 5904 // This kind of access must be used when the object |map| is known and |
| 5905 // in-object properties are being accessed. Accesses of the in-object |
| 5906 // properties can have different semantics depending on whether corresponding |
| 5907 // property was added to the map or not. |
| 5908 static HObjectAccess ForMapAndOffset(Handle<Map> map, int offset, |
| 5868 Representation representation = Representation::Tagged()); | 5909 Representation representation = Representation::Tagged()); |
| 5869 | 5910 |
| 5911 // Create an access to an in-object property in a JSObject. |
| 5912 // This kind of access can be used for accessing object header fields or |
| 5913 // in-object properties if the map of the object is not known. |
| 5914 static HObjectAccess ForObservableJSObjectOffset(int offset, |
| 5915 Representation representation = Representation::Tagged()) { |
| 5916 return ForMapAndOffset(Handle<Map>::null(), offset, representation); |
| 5917 } |
| 5918 |
| 5870 // Create an access to an in-object property in a JSArray. | 5919 // Create an access to an in-object property in a JSArray. |
| 5871 static HObjectAccess ForJSArrayOffset(int offset); | 5920 static HObjectAccess ForJSArrayOffset(int offset); |
| 5872 | 5921 |
| 5873 static HObjectAccess ForContextSlot(int index); | 5922 static HObjectAccess ForContextSlot(int index); |
| 5874 | 5923 |
| 5875 // Create an access to the backing store of an object. | 5924 // Create an access to the backing store of an object. |
| 5876 static HObjectAccess ForBackingStoreOffset(int offset, | 5925 static HObjectAccess ForBackingStoreOffset(int offset, |
| 5877 Representation representation = Representation::Tagged()); | 5926 Representation representation = Representation::Tagged()); |
| 5878 | 5927 |
| 5879 // Create an access to a resolved field (in-object or backing store). | 5928 // Create an access to a resolved field (in-object or backing store). |
| 5880 static HObjectAccess ForField(Handle<Map> map, | 5929 static HObjectAccess ForField(Handle<Map> map, |
| 5881 LookupResult *lookup, Handle<String> name = Handle<String>::null()); | 5930 LookupResult *lookup, Handle<String> name = Handle<String>::null()); |
| 5882 | 5931 |
| 5883 // Create an access for the payload of a Cell or JSGlobalPropertyCell. | 5932 // Create an access for the payload of a Cell or JSGlobalPropertyCell. |
| 5884 static HObjectAccess ForCellPayload(Isolate* isolate); | 5933 static HObjectAccess ForCellPayload(Isolate* isolate); |
| 5885 | 5934 |
| 5886 static HObjectAccess ForJSTypedArrayLength() { | 5935 static HObjectAccess ForJSTypedArrayLength() { |
| 5887 return HObjectAccess::ForJSObjectOffset(JSTypedArray::kLengthOffset); | 5936 return HObjectAccess::ForObservableJSObjectOffset( |
| 5937 JSTypedArray::kLengthOffset); |
| 5888 } | 5938 } |
| 5889 | 5939 |
| 5890 static HObjectAccess ForJSArrayBufferBackingStore() { | 5940 static HObjectAccess ForJSArrayBufferBackingStore() { |
| 5891 return HObjectAccess::ForJSObjectOffset( | 5941 return HObjectAccess::ForObservableJSObjectOffset( |
| 5892 JSArrayBuffer::kBackingStoreOffset, Representation::External()); | 5942 JSArrayBuffer::kBackingStoreOffset, Representation::External()); |
| 5893 } | 5943 } |
| 5894 | 5944 |
| 5895 static HObjectAccess ForExternalArrayExternalPointer() { | 5945 static HObjectAccess ForExternalArrayExternalPointer() { |
| 5896 return HObjectAccess::ForJSObjectOffset( | 5946 return HObjectAccess::ForObservableJSObjectOffset( |
| 5897 ExternalArray::kExternalPointerOffset, Representation::External()); | 5947 ExternalArray::kExternalPointerOffset, Representation::External()); |
| 5898 } | 5948 } |
| 5899 | 5949 |
| 5900 static HObjectAccess ForJSArrayBufferViewWeakNext() { | 5950 static HObjectAccess ForJSArrayBufferViewWeakNext() { |
| 5901 return HObjectAccess::ForJSObjectOffset(JSArrayBufferView::kWeakNextOffset); | 5951 return HObjectAccess::ForObservableJSObjectOffset( |
| 5952 JSArrayBufferView::kWeakNextOffset); |
| 5902 } | 5953 } |
| 5903 | 5954 |
| 5904 static HObjectAccess ForJSArrayBufferWeakFirstView() { | 5955 static HObjectAccess ForJSArrayBufferWeakFirstView() { |
| 5905 return HObjectAccess::ForJSObjectOffset( | 5956 return HObjectAccess::ForObservableJSObjectOffset( |
| 5906 JSArrayBuffer::kWeakFirstViewOffset); | 5957 JSArrayBuffer::kWeakFirstViewOffset); |
| 5907 } | 5958 } |
| 5908 | 5959 |
| 5909 static HObjectAccess ForJSArrayBufferViewBuffer() { | 5960 static HObjectAccess ForJSArrayBufferViewBuffer() { |
| 5910 return HObjectAccess::ForJSObjectOffset(JSArrayBufferView::kBufferOffset); | 5961 return HObjectAccess::ForObservableJSObjectOffset( |
| 5962 JSArrayBufferView::kBufferOffset); |
| 5911 } | 5963 } |
| 5912 | 5964 |
| 5913 static HObjectAccess ForJSArrayBufferViewByteOffset() { | 5965 static HObjectAccess ForJSArrayBufferViewByteOffset() { |
| 5914 return HObjectAccess::ForJSObjectOffset( | 5966 return HObjectAccess::ForObservableJSObjectOffset( |
| 5915 JSArrayBufferView::kByteOffsetOffset); | 5967 JSArrayBufferView::kByteOffsetOffset); |
| 5916 } | 5968 } |
| 5917 | 5969 |
| 5918 static HObjectAccess ForJSArrayBufferViewByteLength() { | 5970 static HObjectAccess ForJSArrayBufferViewByteLength() { |
| 5919 return HObjectAccess::ForJSObjectOffset( | 5971 return HObjectAccess::ForObservableJSObjectOffset( |
| 5920 JSArrayBufferView::kByteLengthOffset); | 5972 JSArrayBufferView::kByteLengthOffset); |
| 5921 } | 5973 } |
| 5922 | 5974 |
| 5923 static HObjectAccess ForGlobalObjectNativeContext() { | 5975 static HObjectAccess ForGlobalObjectNativeContext() { |
| 5924 return HObjectAccess(kInobject, GlobalObject::kNativeContextOffset); | 5976 return HObjectAccess(kInobject, GlobalObject::kNativeContextOffset); |
| 5925 } | 5977 } |
| 5926 | 5978 |
| 5927 void PrintTo(StringStream* stream); | 5979 void PrintTo(StringStream* stream); |
| 5928 | 5980 |
| 5929 inline bool Equals(HObjectAccess that) const { | 5981 inline bool Equals(HObjectAccess that) const { |
| 5930 return value_ == that.value_; // portion and offset must match | 5982 return value_ == that.value_; // portion and offset must match |
| 5931 } | 5983 } |
| 5932 | 5984 |
| 5933 protected: | 5985 protected: |
| 5934 void SetGVNFlags(HValue *instr, bool is_store); | 5986 void SetGVNFlags(HValue *instr, PropertyAccessType access_type); |
| 5935 | 5987 |
| 5936 private: | 5988 private: |
| 5937 // internal use only; different parts of an object or array | 5989 // internal use only; different parts of an object or array |
| 5938 enum Portion { | 5990 enum Portion { |
| 5939 kMaps, // map of an object | 5991 kMaps, // map of an object |
| 5940 kArrayLengths, // the length of an array | 5992 kArrayLengths, // the length of an array |
| 5941 kStringLengths, // the length of a string | 5993 kStringLengths, // the length of a string |
| 5942 kElementsPointer, // elements pointer | 5994 kElementsPointer, // elements pointer |
| 5943 kBackingStore, // some field in the backing store | 5995 kBackingStore, // some field in the backing store |
| 5944 kDouble, // some double field | 5996 kDouble, // some double field |
| 5945 kInobject, // some other in-object field | 5997 kInobject, // some other in-object field |
| 5946 kExternalMemory // some field in external memory | 5998 kExternalMemory // some field in external memory |
| 5947 }; | 5999 }; |
| 5948 | 6000 |
| 5949 HObjectAccess(Portion portion, int offset, | 6001 HObjectAccess(Portion portion, int offset, |
| 5950 Representation representation = Representation::Tagged(), | 6002 Representation representation = Representation::Tagged(), |
| 5951 Handle<String> name = Handle<String>::null(), | 6003 Handle<String> name = Handle<String>::null(), |
| 5952 bool immutable = false) | 6004 bool immutable = false, |
| 6005 bool existing_inobject_property = true) |
| 5953 : value_(PortionField::encode(portion) | | 6006 : value_(PortionField::encode(portion) | |
| 5954 RepresentationField::encode(representation.kind()) | | 6007 RepresentationField::encode(representation.kind()) | |
| 5955 ImmutableField::encode(immutable ? 1 : 0) | | 6008 ImmutableField::encode(immutable ? 1 : 0) | |
| 6009 ExistingInobjectPropertyField::encode( |
| 6010 existing_inobject_property ? 1 : 0) | |
| 5956 OffsetField::encode(offset)), | 6011 OffsetField::encode(offset)), |
| 5957 name_(name) { | 6012 name_(name) { |
| 5958 // assert that the fields decode correctly | 6013 // assert that the fields decode correctly |
| 5959 ASSERT(this->offset() == offset); | 6014 ASSERT(this->offset() == offset); |
| 5960 ASSERT(this->portion() == portion); | 6015 ASSERT(this->portion() == portion); |
| 5961 ASSERT(this->immutable() == immutable); | 6016 ASSERT(this->immutable() == immutable); |
| 6017 ASSERT(this->existing_inobject_property() == existing_inobject_property); |
| 5962 ASSERT(RepresentationField::decode(value_) == representation.kind()); | 6018 ASSERT(RepresentationField::decode(value_) == representation.kind()); |
| 6019 ASSERT(!this->existing_inobject_property() || IsInobject()); |
| 5963 } | 6020 } |
| 5964 | 6021 |
| 5965 class PortionField : public BitField<Portion, 0, 3> {}; | 6022 class PortionField : public BitField<Portion, 0, 3> {}; |
| 5966 class RepresentationField : public BitField<Representation::Kind, 3, 4> {}; | 6023 class RepresentationField : public BitField<Representation::Kind, 3, 4> {}; |
| 5967 class ImmutableField : public BitField<bool, 7, 1> {}; | 6024 class ImmutableField : public BitField<bool, 7, 1> {}; |
| 5968 class OffsetField : public BitField<int, 8, 24> {}; | 6025 class ExistingInobjectPropertyField : public BitField<bool, 8, 1> {}; |
| 6026 class OffsetField : public BitField<int, 9, 23> {}; |
| 5969 | 6027 |
| 5970 uint32_t value_; // encodes portion, representation, immutable, and offset | 6028 uint32_t value_; // encodes portion, representation, immutable, and offset |
| 5971 Handle<String> name_; | 6029 Handle<String> name_; |
| 5972 | 6030 |
| 5973 friend class HLoadNamedField; | 6031 friend class HLoadNamedField; |
| 5974 friend class HStoreNamedField; | 6032 friend class HStoreNamedField; |
| 5975 | 6033 |
| 5976 inline Portion portion() const { | 6034 inline Portion portion() const { |
| 5977 return PortionField::decode(value_); | 6035 return PortionField::decode(value_); |
| 5978 } | 6036 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6042 representation.IsExternal() || | 6100 representation.IsExternal() || |
| 6043 representation.IsInteger32()) { | 6101 representation.IsInteger32()) { |
| 6044 set_representation(representation); | 6102 set_representation(representation); |
| 6045 } else if (FLAG_track_heap_object_fields && | 6103 } else if (FLAG_track_heap_object_fields && |
| 6046 representation.IsHeapObject()) { | 6104 representation.IsHeapObject()) { |
| 6047 set_type(HType::NonPrimitive()); | 6105 set_type(HType::NonPrimitive()); |
| 6048 set_representation(Representation::Tagged()); | 6106 set_representation(Representation::Tagged()); |
| 6049 } else { | 6107 } else { |
| 6050 set_representation(Representation::Tagged()); | 6108 set_representation(Representation::Tagged()); |
| 6051 } | 6109 } |
| 6052 access.SetGVNFlags(this, false); | 6110 access.SetGVNFlags(this, LOAD); |
| 6053 } | 6111 } |
| 6054 | 6112 |
| 6055 virtual bool IsDeletable() const V8_OVERRIDE { return true; } | 6113 virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
| 6056 | 6114 |
| 6057 HObjectAccess access_; | 6115 HObjectAccess access_; |
| 6058 }; | 6116 }; |
| 6059 | 6117 |
| 6060 | 6118 |
| 6061 class HLoadNamedGeneric V8_FINAL : public HTemplateInstruction<2> { | 6119 class HLoadNamedGeneric V8_FINAL : public HTemplateInstruction<2> { |
| 6062 public: | 6120 public: |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6344 SetOperandAt(1, key); | 6402 SetOperandAt(1, key); |
| 6345 SetOperandAt(2, context); | 6403 SetOperandAt(2, context); |
| 6346 SetAllSideEffects(); | 6404 SetAllSideEffects(); |
| 6347 } | 6405 } |
| 6348 }; | 6406 }; |
| 6349 | 6407 |
| 6350 | 6408 |
| 6351 // Indicates whether the store is a store to an entry that was previously | 6409 // Indicates whether the store is a store to an entry that was previously |
| 6352 // initialized or not. | 6410 // initialized or not. |
| 6353 enum StoreFieldOrKeyedMode { | 6411 enum StoreFieldOrKeyedMode { |
| 6354 // This is a store of either an undefined value to a field or a hole/NaN to | |
| 6355 // an entry of a newly allocated object. | |
| 6356 PREINITIALIZING_STORE, | |
| 6357 // The entry could be either previously initialized or not. | 6412 // The entry could be either previously initialized or not. |
| 6358 INITIALIZING_STORE, | 6413 INITIALIZING_STORE, |
| 6359 // At the time of this store it is guaranteed that the entry is already | 6414 // At the time of this store it is guaranteed that the entry is already |
| 6360 // initialized. | 6415 // initialized. |
| 6361 STORE_TO_INITIALIZED_ENTRY | 6416 STORE_TO_INITIALIZED_ENTRY |
| 6362 }; | 6417 }; |
| 6363 | 6418 |
| 6364 | 6419 |
| 6365 class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> { | 6420 class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> { |
| 6366 public: | 6421 public: |
| 6422 DECLARE_INSTRUCTION_FACTORY_P3(HStoreNamedField, HValue*, |
| 6423 HObjectAccess, HValue*); |
| 6367 DECLARE_INSTRUCTION_FACTORY_P4(HStoreNamedField, HValue*, | 6424 DECLARE_INSTRUCTION_FACTORY_P4(HStoreNamedField, HValue*, |
| 6368 HObjectAccess, HValue*, StoreFieldOrKeyedMode); | 6425 HObjectAccess, HValue*, StoreFieldOrKeyedMode); |
| 6369 | 6426 |
| 6370 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) | 6427 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) |
| 6371 | 6428 |
| 6372 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { | 6429 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { |
| 6373 return index == 1; | 6430 return index == 1; |
| 6374 } | 6431 } |
| 6375 virtual bool HasOutOfBoundsAccess(int size) V8_OVERRIDE { | 6432 virtual bool HasOutOfBoundsAccess(int size) V8_OVERRIDE { |
| 6376 return !access().IsInobject() || access().offset() >= size; | 6433 return !access().IsInobject() || access().offset() >= size; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 6392 if (SmiValuesAre32Bits() && store_mode_ == STORE_TO_INITIALIZED_ENTRY) { | 6449 if (SmiValuesAre32Bits() && store_mode_ == STORE_TO_INITIALIZED_ENTRY) { |
| 6393 return Representation::Integer32(); | 6450 return Representation::Integer32(); |
| 6394 } | 6451 } |
| 6395 return field_representation(); | 6452 return field_representation(); |
| 6396 } else if (field_representation().IsExternal()) { | 6453 } else if (field_representation().IsExternal()) { |
| 6397 return Representation::External(); | 6454 return Representation::External(); |
| 6398 } | 6455 } |
| 6399 } | 6456 } |
| 6400 return Representation::Tagged(); | 6457 return Representation::Tagged(); |
| 6401 } | 6458 } |
| 6402 virtual void HandleSideEffectDominator(GVNFlag side_effect, | 6459 virtual bool HandleSideEffectDominator(GVNFlag side_effect, |
| 6403 HValue* dominator) V8_OVERRIDE { | 6460 HValue* dominator) V8_OVERRIDE { |
| 6404 ASSERT(side_effect == kChangesNewSpacePromotion); | 6461 ASSERT(side_effect == kChangesNewSpacePromotion); |
| 6405 new_space_dominator_ = dominator; | 6462 new_space_dominator_ = dominator; |
| 6463 return false; |
| 6406 } | 6464 } |
| 6407 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 6465 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 6408 | 6466 |
| 6409 void SkipWriteBarrier() { write_barrier_mode_ = SKIP_WRITE_BARRIER; } | 6467 void SkipWriteBarrier() { write_barrier_mode_ = SKIP_WRITE_BARRIER; } |
| 6410 bool IsSkipWriteBarrier() const { | 6468 bool IsSkipWriteBarrier() const { |
| 6411 return write_barrier_mode_ == SKIP_WRITE_BARRIER; | 6469 return write_barrier_mode_ == SKIP_WRITE_BARRIER; |
| 6412 } | 6470 } |
| 6413 | 6471 |
| 6414 HValue* object() const { return OperandAt(0); } | 6472 HValue* object() const { return OperandAt(0); } |
| 6415 HValue* value() const { return OperandAt(1); } | 6473 HValue* value() const { return OperandAt(1); } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6463 } | 6521 } |
| 6464 | 6522 |
| 6465 void UpdateValue(HValue* value) { | 6523 void UpdateValue(HValue* value) { |
| 6466 SetOperandAt(1, value); | 6524 SetOperandAt(1, value); |
| 6467 } | 6525 } |
| 6468 | 6526 |
| 6469 private: | 6527 private: |
| 6470 HStoreNamedField(HValue* obj, | 6528 HStoreNamedField(HValue* obj, |
| 6471 HObjectAccess access, | 6529 HObjectAccess access, |
| 6472 HValue* val, | 6530 HValue* val, |
| 6473 StoreFieldOrKeyedMode store_mode) | 6531 StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE) |
| 6474 : access_(access), | 6532 : access_(access), |
| 6475 new_space_dominator_(NULL), | 6533 new_space_dominator_(NULL), |
| 6476 write_barrier_mode_(UPDATE_WRITE_BARRIER), | 6534 write_barrier_mode_(UPDATE_WRITE_BARRIER), |
| 6477 has_transition_(false), | 6535 has_transition_(false), |
| 6478 store_mode_(store_mode) { | 6536 store_mode_(store_mode) { |
| 6479 // PREINITIALIZING_STORE is only used to mark stores that initialize a | 6537 if (!FLAG_smi_x64_store_opt) store_mode_ = INITIALIZING_STORE; |
| 6480 // memory region resulting from HAllocate (possibly through an | 6538 // Stores to a non existing in-object property are allowed only to the |
| 6481 // HInnerAllocatedObject). | 6539 // newly allocated objects (via HAllocate or HInnerAllocatedObject). |
| 6482 ASSERT(store_mode != PREINITIALIZING_STORE || | 6540 ASSERT(!access.IsInobject() || access.existing_inobject_property() || |
| 6483 obj->IsAllocate() || obj->IsInnerAllocatedObject()); | 6541 obj->IsAllocate() || obj->IsInnerAllocatedObject()); |
| 6484 SetOperandAt(0, obj); | 6542 SetOperandAt(0, obj); |
| 6485 SetOperandAt(1, val); | 6543 SetOperandAt(1, val); |
| 6486 SetOperandAt(2, obj); | 6544 SetOperandAt(2, obj); |
| 6487 access.SetGVNFlags(this, true); | 6545 access.SetGVNFlags(this, STORE); |
| 6488 } | 6546 } |
| 6489 | 6547 |
| 6490 HObjectAccess access_; | 6548 HObjectAccess access_; |
| 6491 HValue* new_space_dominator_; | 6549 HValue* new_space_dominator_; |
| 6492 WriteBarrierMode write_barrier_mode_ : 1; | 6550 WriteBarrierMode write_barrier_mode_ : 1; |
| 6493 bool has_transition_ : 1; | 6551 bool has_transition_ : 1; |
| 6494 StoreFieldOrKeyedMode store_mode_ : 2; | 6552 StoreFieldOrKeyedMode store_mode_ : 1; |
| 6495 }; | 6553 }; |
| 6496 | 6554 |
| 6497 | 6555 |
| 6498 class HStoreNamedGeneric V8_FINAL : public HTemplateInstruction<3> { | 6556 class HStoreNamedGeneric V8_FINAL : public HTemplateInstruction<3> { |
| 6499 public: | 6557 public: |
| 6500 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HStoreNamedGeneric, HValue*, | 6558 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HStoreNamedGeneric, HValue*, |
| 6501 Handle<String>, HValue*, | 6559 Handle<String>, HValue*, |
| 6502 StrictModeFlag); | 6560 StrictModeFlag); |
| 6503 HValue* object() { return OperandAt(0); } | 6561 HValue* object() { return OperandAt(0); } |
| 6504 HValue* value() { return OperandAt(1); } | 6562 HValue* value() { return OperandAt(1); } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 6529 } | 6587 } |
| 6530 | 6588 |
| 6531 Handle<String> name_; | 6589 Handle<String> name_; |
| 6532 StrictModeFlag strict_mode_flag_; | 6590 StrictModeFlag strict_mode_flag_; |
| 6533 }; | 6591 }; |
| 6534 | 6592 |
| 6535 | 6593 |
| 6536 class HStoreKeyed V8_FINAL | 6594 class HStoreKeyed V8_FINAL |
| 6537 : public HTemplateInstruction<3>, public ArrayInstructionInterface { | 6595 : public HTemplateInstruction<3>, public ArrayInstructionInterface { |
| 6538 public: | 6596 public: |
| 6597 DECLARE_INSTRUCTION_FACTORY_P4(HStoreKeyed, HValue*, HValue*, HValue*, |
| 6598 ElementsKind); |
| 6539 DECLARE_INSTRUCTION_FACTORY_P5(HStoreKeyed, HValue*, HValue*, HValue*, | 6599 DECLARE_INSTRUCTION_FACTORY_P5(HStoreKeyed, HValue*, HValue*, HValue*, |
| 6540 ElementsKind, StoreFieldOrKeyedMode); | 6600 ElementsKind, StoreFieldOrKeyedMode); |
| 6541 | 6601 |
| 6542 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 6602 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 6543 // kind_fast: tagged[int32] = tagged | 6603 // kind_fast: tagged[int32] = tagged |
| 6544 // kind_double: tagged[int32] = double | 6604 // kind_double: tagged[int32] = double |
| 6545 // kind_smi : tagged[int32] = smi | 6605 // kind_smi : tagged[int32] = smi |
| 6546 // kind_fixed_typed_array: tagged[int32] = (double | int32) | 6606 // kind_fixed_typed_array: tagged[int32] = (double | int32) |
| 6547 // kind_external: external[int32] = (double | int32) | 6607 // kind_external: external[int32] = (double | int32) |
| 6548 if (index == 0) { | 6608 if (index == 0) { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6621 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | 6681 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } |
| 6622 bool IsUninitialized() { return is_uninitialized_; } | 6682 bool IsUninitialized() { return is_uninitialized_; } |
| 6623 void SetUninitialized(bool is_uninitialized) { | 6683 void SetUninitialized(bool is_uninitialized) { |
| 6624 is_uninitialized_ = is_uninitialized; | 6684 is_uninitialized_ = is_uninitialized; |
| 6625 } | 6685 } |
| 6626 | 6686 |
| 6627 bool IsConstantHoleStore() { | 6687 bool IsConstantHoleStore() { |
| 6628 return value()->IsConstant() && HConstant::cast(value())->IsTheHole(); | 6688 return value()->IsConstant() && HConstant::cast(value())->IsTheHole(); |
| 6629 } | 6689 } |
| 6630 | 6690 |
| 6631 virtual void HandleSideEffectDominator(GVNFlag side_effect, | 6691 virtual bool HandleSideEffectDominator(GVNFlag side_effect, |
| 6632 HValue* dominator) V8_OVERRIDE { | 6692 HValue* dominator) V8_OVERRIDE { |
| 6633 ASSERT(side_effect == kChangesNewSpacePromotion); | 6693 ASSERT(side_effect == kChangesNewSpacePromotion); |
| 6634 new_space_dominator_ = dominator; | 6694 new_space_dominator_ = dominator; |
| 6695 return false; |
| 6635 } | 6696 } |
| 6636 | 6697 |
| 6637 HValue* new_space_dominator() const { return new_space_dominator_; } | 6698 HValue* new_space_dominator() const { return new_space_dominator_; } |
| 6638 | 6699 |
| 6639 bool NeedsWriteBarrier() { | 6700 bool NeedsWriteBarrier() { |
| 6640 if (value_is_smi()) { | 6701 if (value_is_smi()) { |
| 6641 return false; | 6702 return false; |
| 6642 } else { | 6703 } else { |
| 6643 return StoringValueNeedsWriteBarrier(value()) && | 6704 return StoringValueNeedsWriteBarrier(value()) && |
| 6644 ReceiverObjectNeedsWriteBarrier(elements(), value(), | 6705 ReceiverObjectNeedsWriteBarrier(elements(), value(), |
| 6645 new_space_dominator()); | 6706 new_space_dominator()); |
| 6646 } | 6707 } |
| 6647 } | 6708 } |
| 6648 | 6709 |
| 6649 bool NeedsCanonicalization(); | 6710 bool NeedsCanonicalization(); |
| 6650 | 6711 |
| 6651 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 6712 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 6652 | 6713 |
| 6653 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) | 6714 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) |
| 6654 | 6715 |
| 6655 private: | 6716 private: |
| 6656 HStoreKeyed(HValue* obj, HValue* key, HValue* val, | 6717 HStoreKeyed(HValue* obj, HValue* key, HValue* val, |
| 6657 ElementsKind elements_kind, | 6718 ElementsKind elements_kind, |
| 6658 StoreFieldOrKeyedMode store_mode) | 6719 StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE) |
| 6659 : elements_kind_(elements_kind), | 6720 : elements_kind_(elements_kind), |
| 6660 index_offset_(0), | 6721 index_offset_(0), |
| 6661 is_dehoisted_(false), | 6722 is_dehoisted_(false), |
| 6662 is_uninitialized_(false), | 6723 is_uninitialized_(false), |
| 6663 store_mode_(store_mode), | 6724 store_mode_(store_mode), |
| 6664 new_space_dominator_(NULL) { | 6725 new_space_dominator_(NULL) { |
| 6726 if (!FLAG_smi_x64_store_opt) store_mode_ = INITIALIZING_STORE; |
| 6665 SetOperandAt(0, obj); | 6727 SetOperandAt(0, obj); |
| 6666 SetOperandAt(1, key); | 6728 SetOperandAt(1, key); |
| 6667 SetOperandAt(2, val); | 6729 SetOperandAt(2, val); |
| 6668 | 6730 |
| 6669 // PREINITIALIZING_STORE is only used to mark stores that initialize a | |
| 6670 // memory region resulting from HAllocate (possibly through an | |
| 6671 // HInnerAllocatedObject). | |
| 6672 ASSERT(store_mode != PREINITIALIZING_STORE || | |
| 6673 obj->IsAllocate() || obj->IsInnerAllocatedObject()); | |
| 6674 | |
| 6675 ASSERT(store_mode != STORE_TO_INITIALIZED_ENTRY || | 6731 ASSERT(store_mode != STORE_TO_INITIALIZED_ENTRY || |
| 6676 elements_kind == FAST_SMI_ELEMENTS); | 6732 elements_kind == FAST_SMI_ELEMENTS); |
| 6677 | 6733 |
| 6678 if (IsFastObjectElementsKind(elements_kind)) { | 6734 if (IsFastObjectElementsKind(elements_kind)) { |
| 6679 SetFlag(kTrackSideEffectDominators); | 6735 SetFlag(kTrackSideEffectDominators); |
| 6680 SetGVNFlag(kDependsOnNewSpacePromotion); | 6736 SetGVNFlag(kDependsOnNewSpacePromotion); |
| 6681 } | 6737 } |
| 6682 if (is_external()) { | 6738 if (is_external()) { |
| 6683 SetGVNFlag(kChangesExternalMemory); | 6739 SetGVNFlag(kChangesExternalMemory); |
| 6684 SetFlag(kAllowUndefinedAsNaN); | 6740 SetFlag(kAllowUndefinedAsNaN); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 6699 (elements_kind >= UINT8_ELEMENTS && | 6755 (elements_kind >= UINT8_ELEMENTS && |
| 6700 elements_kind <= INT32_ELEMENTS)) { | 6756 elements_kind <= INT32_ELEMENTS)) { |
| 6701 SetFlag(kTruncatingToInt32); | 6757 SetFlag(kTruncatingToInt32); |
| 6702 } | 6758 } |
| 6703 } | 6759 } |
| 6704 | 6760 |
| 6705 ElementsKind elements_kind_; | 6761 ElementsKind elements_kind_; |
| 6706 uint32_t index_offset_; | 6762 uint32_t index_offset_; |
| 6707 bool is_dehoisted_ : 1; | 6763 bool is_dehoisted_ : 1; |
| 6708 bool is_uninitialized_ : 1; | 6764 bool is_uninitialized_ : 1; |
| 6709 StoreFieldOrKeyedMode store_mode_: 2; | 6765 StoreFieldOrKeyedMode store_mode_: 1; |
| 6710 HValue* new_space_dominator_; | 6766 HValue* new_space_dominator_; |
| 6711 }; | 6767 }; |
| 6712 | 6768 |
| 6713 | 6769 |
| 6714 class HStoreKeyedGeneric V8_FINAL : public HTemplateInstruction<4> { | 6770 class HStoreKeyedGeneric V8_FINAL : public HTemplateInstruction<4> { |
| 6715 public: | 6771 public: |
| 6716 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HStoreKeyedGeneric, HValue*, | 6772 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HStoreKeyedGeneric, HValue*, |
| 6717 HValue*, HValue*, StrictModeFlag); | 6773 HValue*, HValue*, StrictModeFlag); |
| 6718 | 6774 |
| 6719 HValue* object() { return OperandAt(0); } | 6775 HValue* object() { return OperandAt(0); } |
| (...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7380 virtual bool IsDeletable() const V8_OVERRIDE { return true; } | 7436 virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
| 7381 }; | 7437 }; |
| 7382 | 7438 |
| 7383 | 7439 |
| 7384 #undef DECLARE_INSTRUCTION | 7440 #undef DECLARE_INSTRUCTION |
| 7385 #undef DECLARE_CONCRETE_INSTRUCTION | 7441 #undef DECLARE_CONCRETE_INSTRUCTION |
| 7386 | 7442 |
| 7387 } } // namespace v8::internal | 7443 } } // namespace v8::internal |
| 7388 | 7444 |
| 7389 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 7445 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |