OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_HYDROGEN_INSTRUCTIONS_H_ | 5 #ifndef V8_HYDROGEN_INSTRUCTIONS_H_ |
6 #define V8_HYDROGEN_INSTRUCTIONS_H_ | 6 #define V8_HYDROGEN_INSTRUCTIONS_H_ |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/allocation.h" | 10 #include "src/allocation.h" |
(...skipping 1188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1199 HInstruction* previous_; | 1199 HInstruction* previous_; |
1200 HPositionInfo position_; | 1200 HPositionInfo position_; |
1201 | 1201 |
1202 friend class HBasicBlock; | 1202 friend class HBasicBlock; |
1203 }; | 1203 }; |
1204 | 1204 |
1205 | 1205 |
1206 template<int V> | 1206 template<int V> |
1207 class HTemplateInstruction : public HInstruction { | 1207 class HTemplateInstruction : public HInstruction { |
1208 public: | 1208 public: |
1209 virtual int OperandCount() V8_FINAL V8_OVERRIDE { return V; } | 1209 virtual int OperandCount() V8_OVERRIDE { return V; } |
1210 virtual HValue* OperandAt(int i) const V8_FINAL V8_OVERRIDE { | 1210 virtual HValue* OperandAt(int i) const V8_FINAL V8_OVERRIDE { |
1211 return inputs_[i]; | 1211 return inputs_[i]; |
1212 } | 1212 } |
1213 | 1213 |
1214 protected: | 1214 protected: |
1215 HTemplateInstruction(HType type = HType::Tagged()) : HInstruction(type) {} | 1215 HTemplateInstruction(HType type = HType::Tagged()) : HInstruction(type) {} |
1216 | 1216 |
1217 virtual void InternalSetOperandAt(int i, HValue* value) V8_FINAL V8_OVERRIDE { | 1217 virtual void InternalSetOperandAt(int i, HValue* value) V8_FINAL V8_OVERRIDE { |
1218 inputs_[i] = value; | 1218 inputs_[i] = value; |
1219 } | 1219 } |
(...skipping 4999 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6219 friend class HLoadNamedField; | 6219 friend class HLoadNamedField; |
6220 friend class HStoreNamedField; | 6220 friend class HStoreNamedField; |
6221 friend class SideEffectsTracker; | 6221 friend class SideEffectsTracker; |
6222 | 6222 |
6223 inline Portion portion() const { | 6223 inline Portion portion() const { |
6224 return PortionField::decode(value_); | 6224 return PortionField::decode(value_); |
6225 } | 6225 } |
6226 }; | 6226 }; |
6227 | 6227 |
6228 | 6228 |
6229 class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> { | 6229 class HLoadNamedField V8_FINAL : public HTemplateInstruction<3> { |
6230 public: | 6230 public: |
6231 DECLARE_INSTRUCTION_FACTORY_P3(HLoadNamedField, HValue*, | 6231 DECLARE_INSTRUCTION_FACTORY_P3(HLoadNamedField, HValue*, |
6232 HValue*, HObjectAccess); | 6232 HValue*, HObjectAccess); |
6233 DECLARE_INSTRUCTION_FACTORY_P4(HLoadNamedField, HValue*, | |
6234 HValue*, HObjectAccess, HValue*); | |
6233 DECLARE_INSTRUCTION_FACTORY_P5(HLoadNamedField, HValue*, HValue*, | 6235 DECLARE_INSTRUCTION_FACTORY_P5(HLoadNamedField, HValue*, HValue*, |
6234 HObjectAccess, const UniqueSet<Map>*, HType); | 6236 HObjectAccess, const UniqueSet<Map>*, HType); |
6237 DECLARE_INSTRUCTION_FACTORY_P6(HLoadNamedField, HValue*, HValue*, | |
6238 HObjectAccess, const UniqueSet<Map>*, HType, | |
6239 HValue*); | |
6240 | |
6241 virtual int OperandCount() V8_OVERRIDE { | |
6242 return (object_properties() != NULL) ? 3 : 2; | |
6243 } | |
6235 | 6244 |
6236 HValue* object() { return OperandAt(0); } | 6245 HValue* object() { return OperandAt(0); } |
6237 HValue* dependency() { | 6246 HValue* dependency() { |
6238 ASSERT(HasDependency()); | 6247 ASSERT(HasDependency()); |
6239 return OperandAt(1); | 6248 return OperandAt(1); |
6240 } | 6249 } |
6241 bool HasDependency() const { return OperandAt(0) != OperandAt(1); } | 6250 bool HasDependency() const { return OperandAt(0) != OperandAt(1); } |
6251 HValue* object_properties() { return OperandAt(2); } | |
6242 HObjectAccess access() const { return access_; } | 6252 HObjectAccess access() const { return access_; } |
6243 Representation field_representation() const { | 6253 Representation field_representation() const { |
6244 return access_.representation(); | 6254 return access_.representation(); |
6245 } | 6255 } |
6246 | 6256 |
6247 const UniqueSet<Map>* maps() const { return maps_; } | 6257 const UniqueSet<Map>* maps() const { return maps_; } |
6248 | 6258 |
6249 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } | 6259 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } |
6250 virtual bool HasOutOfBoundsAccess(int size) V8_OVERRIDE { | 6260 virtual bool HasOutOfBoundsAccess(int size) V8_OVERRIDE { |
6251 return !access().IsInobject() || access().offset() >= size; | 6261 return !access().IsInobject() || access().offset() >= size; |
(...skipping 12 matching lines...) Expand all Loading... | |
6264 if (!CheckFlag(HValue::kCantBeReplaced)) return false; | 6274 if (!CheckFlag(HValue::kCantBeReplaced)) return false; |
6265 if (!type().Equals(other->type())) return false; | 6275 if (!type().Equals(other->type())) return false; |
6266 if (!representation().Equals(other->representation())) return false; | 6276 if (!representation().Equals(other->representation())) return false; |
6267 if (!other->IsLoadNamedField()) return true; | 6277 if (!other->IsLoadNamedField()) return true; |
6268 HLoadNamedField* that = HLoadNamedField::cast(other); | 6278 HLoadNamedField* that = HLoadNamedField::cast(other); |
6269 if (this->maps_ == that->maps_) return true; | 6279 if (this->maps_ == that->maps_) return true; |
6270 if (this->maps_ == NULL || that->maps_ == NULL) return false; | 6280 if (this->maps_ == NULL || that->maps_ == NULL) return false; |
6271 return this->maps_->IsSubset(that->maps_); | 6281 return this->maps_->IsSubset(that->maps_); |
6272 } | 6282 } |
6273 | 6283 |
6284 static bool PreferExtractLoadPropertiesPointer() { | |
6285 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 | |
6286 return true; | |
6287 #else | |
6288 return false; | |
6289 #endif | |
6290 } | |
6291 static bool NeedsPropertiesPointer(HObjectAccess access) { | |
6292 return !(access.IsExternalMemory() || | |
6293 access.representation().IsDouble() || | |
6294 access.IsInobject()); | |
6295 } | |
6296 | |
6274 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) | 6297 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) |
6275 | 6298 |
6276 protected: | 6299 protected: |
6277 virtual bool DataEquals(HValue* other) V8_OVERRIDE { | 6300 virtual bool DataEquals(HValue* other) V8_OVERRIDE { |
6278 HLoadNamedField* that = HLoadNamedField::cast(other); | 6301 HLoadNamedField* that = HLoadNamedField::cast(other); |
6279 if (!this->access_.Equals(that->access_)) return false; | 6302 if (!this->access_.Equals(that->access_)) return false; |
6280 if (this->maps_ == that->maps_) return true; | 6303 if (this->maps_ == that->maps_) return true; |
6281 return (this->maps_ != NULL && | 6304 return (this->maps_ != NULL && |
6282 that->maps_ != NULL && | 6305 that->maps_ != NULL && |
6283 this->maps_->Equals(that->maps_)); | 6306 this->maps_->Equals(that->maps_)); |
6284 } | 6307 } |
6285 | 6308 |
6286 private: | 6309 private: |
6287 HLoadNamedField(HValue* object, | 6310 HLoadNamedField(HValue* object, |
6288 HValue* dependency, | 6311 HValue* dependency, |
6289 HObjectAccess access) | 6312 HObjectAccess access, |
6313 HValue* object_properties = NULL) | |
6290 : access_(access), maps_(NULL) { | 6314 : access_(access), maps_(NULL) { |
6291 ASSERT_NOT_NULL(object); | 6315 ASSERT_NOT_NULL(object); |
6292 SetOperandAt(0, object); | 6316 SetOperandAt(0, object); |
6293 SetOperandAt(1, dependency ? dependency : object); | 6317 SetOperandAt(1, dependency ? dependency : object); |
6318 SetOperandAt(2, object_properties); | |
6294 | 6319 |
6295 Representation representation = access.representation(); | 6320 Representation representation = access.representation(); |
6296 if (representation.IsInteger8() || | 6321 if (representation.IsInteger8() || |
6297 representation.IsUInteger8() || | 6322 representation.IsUInteger8() || |
6298 representation.IsInteger16() || | 6323 representation.IsInteger16() || |
6299 representation.IsUInteger16()) { | 6324 representation.IsUInteger16()) { |
6300 set_representation(Representation::Integer32()); | 6325 set_representation(Representation::Integer32()); |
6301 } else if (representation.IsSmi()) { | 6326 } else if (representation.IsSmi()) { |
6302 set_type(HType::Smi()); | 6327 set_type(HType::Smi()); |
6303 if (SmiValuesAre32Bits()) { | 6328 if (SmiValuesAre32Bits()) { |
(...skipping 11 matching lines...) Expand all Loading... | |
6315 } else { | 6340 } else { |
6316 set_representation(Representation::Tagged()); | 6341 set_representation(Representation::Tagged()); |
6317 } | 6342 } |
6318 access.SetGVNFlags(this, LOAD); | 6343 access.SetGVNFlags(this, LOAD); |
6319 } | 6344 } |
6320 | 6345 |
6321 HLoadNamedField(HValue* object, | 6346 HLoadNamedField(HValue* object, |
6322 HValue* dependency, | 6347 HValue* dependency, |
6323 HObjectAccess access, | 6348 HObjectAccess access, |
6324 const UniqueSet<Map>* maps, | 6349 const UniqueSet<Map>* maps, |
6325 HType type) | 6350 HType type, |
6326 : HTemplateInstruction<2>(type), access_(access), maps_(maps) { | 6351 HValue* object_properties = NULL) |
6352 : HTemplateInstruction<3>(type), access_(access), maps_(maps) { | |
6327 ASSERT_NOT_NULL(maps); | 6353 ASSERT_NOT_NULL(maps); |
6328 ASSERT_NE(0, maps->size()); | 6354 ASSERT_NE(0, maps->size()); |
6329 | 6355 |
6330 ASSERT_NOT_NULL(object); | 6356 ASSERT_NOT_NULL(object); |
6331 SetOperandAt(0, object); | 6357 SetOperandAt(0, object); |
6332 SetOperandAt(1, dependency ? dependency : object); | 6358 SetOperandAt(1, dependency ? dependency : object); |
6359 SetOperandAt(2, object_properties); | |
6333 | 6360 |
6334 ASSERT(access.representation().IsHeapObject()); | 6361 ASSERT(access.representation().IsHeapObject()); |
6335 ASSERT(type.IsHeapObject()); | 6362 ASSERT(type.IsHeapObject()); |
6336 set_representation(Representation::Tagged()); | 6363 set_representation(Representation::Tagged()); |
6337 | 6364 |
6338 access.SetGVNFlags(this, LOAD); | 6365 access.SetGVNFlags(this, LOAD); |
6339 } | 6366 } |
6340 | 6367 |
6341 virtual bool IsDeletable() const V8_OVERRIDE { return true; } | 6368 virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
6342 | 6369 |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6650 // initialized or not. | 6677 // initialized or not. |
6651 enum StoreFieldOrKeyedMode { | 6678 enum StoreFieldOrKeyedMode { |
6652 // The entry could be either previously initialized or not. | 6679 // The entry could be either previously initialized or not. |
6653 INITIALIZING_STORE, | 6680 INITIALIZING_STORE, |
6654 // At the time of this store it is guaranteed that the entry is already | 6681 // At the time of this store it is guaranteed that the entry is already |
6655 // initialized. | 6682 // initialized. |
6656 STORE_TO_INITIALIZED_ENTRY | 6683 STORE_TO_INITIALIZED_ENTRY |
6657 }; | 6684 }; |
6658 | 6685 |
6659 | 6686 |
6660 class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> { | 6687 class HStoreNamedField V8_FINAL : public HTemplateInstruction<4> { |
6661 public: | 6688 public: |
6662 DECLARE_INSTRUCTION_FACTORY_P3(HStoreNamedField, HValue*, | 6689 DECLARE_INSTRUCTION_FACTORY_P3(HStoreNamedField, HValue*, |
6663 HObjectAccess, HValue*); | 6690 HObjectAccess, HValue*); |
6664 DECLARE_INSTRUCTION_FACTORY_P4(HStoreNamedField, HValue*, | 6691 DECLARE_INSTRUCTION_FACTORY_P4(HStoreNamedField, HValue*, |
6665 HObjectAccess, HValue*, StoreFieldOrKeyedMode); | 6692 HObjectAccess, HValue*, StoreFieldOrKeyedMode); |
6693 DECLARE_INSTRUCTION_FACTORY_P5(HStoreNamedField, HValue*, | |
6694 HObjectAccess, HValue*, StoreFieldOrKeyedMode, | |
6695 HValue*); | |
6666 | 6696 |
6667 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) | 6697 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) |
6668 | 6698 |
6699 virtual int OperandCount() V8_OVERRIDE { | |
6700 return (object_properties() != NULL) ? 4 : 3; | |
6701 } | |
6702 | |
6669 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { | 6703 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { |
6670 return index == 1; | 6704 return index == 1; |
6671 } | 6705 } |
6672 virtual bool HasOutOfBoundsAccess(int size) V8_OVERRIDE { | 6706 virtual bool HasOutOfBoundsAccess(int size) V8_OVERRIDE { |
6673 return !access().IsInobject() || access().offset() >= size; | 6707 return !access().IsInobject() || access().offset() >= size; |
6674 } | 6708 } |
6675 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 6709 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
6676 if (index == 0 && access().IsExternalMemory()) { | 6710 if (index == 0 && access().IsExternalMemory()) { |
6677 // object must be external in case of external memory access | 6711 // object must be external in case of external memory access |
6678 return Representation::External(); | 6712 return Representation::External(); |
(...skipping 22 matching lines...) Expand all Loading... | |
6701 ASSERT(side_effect == kNewSpacePromotion); | 6735 ASSERT(side_effect == kNewSpacePromotion); |
6702 if (!FLAG_use_write_barrier_elimination) return false; | 6736 if (!FLAG_use_write_barrier_elimination) return false; |
6703 dominator_ = dominator; | 6737 dominator_ = dominator; |
6704 return false; | 6738 return false; |
6705 } | 6739 } |
6706 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 6740 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
6707 | 6741 |
6708 HValue* object() const { return OperandAt(0); } | 6742 HValue* object() const { return OperandAt(0); } |
6709 HValue* value() const { return OperandAt(1); } | 6743 HValue* value() const { return OperandAt(1); } |
6710 HValue* transition() const { return OperandAt(2); } | 6744 HValue* transition() const { return OperandAt(2); } |
6745 HValue* object_properties() { return OperandAt(3); } | |
6711 | 6746 |
6712 HObjectAccess access() const { return access_; } | 6747 HObjectAccess access() const { return access_; } |
6713 HValue* dominator() const { return dominator_; } | 6748 HValue* dominator() const { return dominator_; } |
6714 bool has_transition() const { return has_transition_; } | 6749 bool has_transition() const { return has_transition_; } |
6715 StoreFieldOrKeyedMode store_mode() const { return store_mode_; } | 6750 StoreFieldOrKeyedMode store_mode() const { return store_mode_; } |
6716 | 6751 |
6717 Handle<Map> transition_map() const { | 6752 Handle<Map> transition_map() const { |
6718 if (has_transition()) { | 6753 if (has_transition()) { |
6719 return Handle<Map>::cast( | 6754 return Handle<Map>::cast( |
6720 HConstant::cast(transition())->handle(Isolate::Current())); | 6755 HConstant::cast(transition())->handle(Isolate::Current())); |
(...skipping 17 matching lines...) Expand all Loading... | |
6738 if (field_representation().IsExternal()) return false; | 6773 if (field_representation().IsExternal()) return false; |
6739 return StoringValueNeedsWriteBarrier(value()) && | 6774 return StoringValueNeedsWriteBarrier(value()) && |
6740 ReceiverObjectNeedsWriteBarrier(object(), value(), dominator()); | 6775 ReceiverObjectNeedsWriteBarrier(object(), value(), dominator()); |
6741 } | 6776 } |
6742 | 6777 |
6743 bool NeedsWriteBarrierForMap() { | 6778 bool NeedsWriteBarrierForMap() { |
6744 return ReceiverObjectNeedsWriteBarrier(object(), transition(), | 6779 return ReceiverObjectNeedsWriteBarrier(object(), transition(), |
6745 dominator()); | 6780 dominator()); |
6746 } | 6781 } |
6747 | 6782 |
6783 static bool PreferExtractLoadPropertiesPointer() { | |
6784 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 | |
6785 return true; | |
ulan
2014/06/12 13:39:18
Could you please port this to other architectures
| |
6786 #else | |
6787 return false; | |
6788 #endif | |
6789 } | |
6790 static bool NeedsPropertiesPointer(HObjectAccess access) { | |
6791 return !(access.IsExternalMemory() || | |
ulan
2014/06/12 13:39:18
This predicate should be part of HObjectAccess (if
| |
6792 access.representation().IsDouble() || | |
6793 access.IsInobject()); | |
6794 } | |
6795 | |
6748 SmiCheck SmiCheckForWriteBarrier() const { | 6796 SmiCheck SmiCheckForWriteBarrier() const { |
6749 if (field_representation().IsHeapObject()) return OMIT_SMI_CHECK; | 6797 if (field_representation().IsHeapObject()) return OMIT_SMI_CHECK; |
6750 if (value()->type().IsHeapObject()) return OMIT_SMI_CHECK; | 6798 if (value()->type().IsHeapObject()) return OMIT_SMI_CHECK; |
6751 return INLINE_SMI_CHECK; | 6799 return INLINE_SMI_CHECK; |
6752 } | 6800 } |
6753 | 6801 |
6754 PointersToHereCheck PointersToHereCheckForValue() const { | 6802 PointersToHereCheck PointersToHereCheckForValue() const { |
6755 return PointersToHereCheckForObject(value(), dominator()); | 6803 return PointersToHereCheckForObject(value(), dominator()); |
6756 } | 6804 } |
6757 | 6805 |
(...skipping 15 matching lines...) Expand all Loading... | |
6773 // an initialized entry on 64-bit architectures (with 32-bit smis). | 6821 // an initialized entry on 64-bit architectures (with 32-bit smis). |
6774 return false; | 6822 return false; |
6775 } | 6823 } |
6776 return true; | 6824 return true; |
6777 } | 6825 } |
6778 | 6826 |
6779 private: | 6827 private: |
6780 HStoreNamedField(HValue* obj, | 6828 HStoreNamedField(HValue* obj, |
6781 HObjectAccess access, | 6829 HObjectAccess access, |
6782 HValue* val, | 6830 HValue* val, |
6783 StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE) | 6831 StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE, |
6832 HValue* obj_properties = NULL) | |
6784 : access_(access), | 6833 : access_(access), |
6785 dominator_(NULL), | 6834 dominator_(NULL), |
6786 has_transition_(false), | 6835 has_transition_(false), |
6787 store_mode_(store_mode) { | 6836 store_mode_(store_mode) { |
6788 // Stores to a non existing in-object property are allowed only to the | 6837 // Stores to a non existing in-object property are allowed only to the |
6789 // newly allocated objects (via HAllocate or HInnerAllocatedObject). | 6838 // newly allocated objects (via HAllocate or HInnerAllocatedObject). |
6790 ASSERT(!access.IsInobject() || access.existing_inobject_property() || | 6839 ASSERT(!access.IsInobject() || access.existing_inobject_property() || |
6791 obj->IsAllocate() || obj->IsInnerAllocatedObject()); | 6840 obj->IsAllocate() || obj->IsInnerAllocatedObject()); |
6792 SetOperandAt(0, obj); | 6841 SetOperandAt(0, obj); |
6793 SetOperandAt(1, val); | 6842 SetOperandAt(1, val); |
6794 SetOperandAt(2, obj); | 6843 SetOperandAt(2, obj); |
6844 SetOperandAt(3, obj_properties); | |
6795 access.SetGVNFlags(this, STORE); | 6845 access.SetGVNFlags(this, STORE); |
6796 } | 6846 } |
6797 | 6847 |
6798 HObjectAccess access_; | 6848 HObjectAccess access_; |
6799 HValue* dominator_; | 6849 HValue* dominator_; |
6800 bool has_transition_ : 1; | 6850 bool has_transition_ : 1; |
6801 StoreFieldOrKeyedMode store_mode_ : 1; | 6851 StoreFieldOrKeyedMode store_mode_ : 1; |
6802 }; | 6852 }; |
6803 | 6853 |
6804 | 6854 |
(...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7757 }; | 7807 }; |
7758 | 7808 |
7759 | 7809 |
7760 | 7810 |
7761 #undef DECLARE_INSTRUCTION | 7811 #undef DECLARE_INSTRUCTION |
7762 #undef DECLARE_CONCRETE_INSTRUCTION | 7812 #undef DECLARE_CONCRETE_INSTRUCTION |
7763 | 7813 |
7764 } } // namespace v8::internal | 7814 } } // namespace v8::internal |
7765 | 7815 |
7766 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 7816 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |