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 5303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5314 class HObjectAccess { | 5314 class HObjectAccess { |
5315 public: | 5315 public: |
5316 inline bool IsInobject() const { | 5316 inline bool IsInobject() const { |
5317 return portion() != kBackingStore; | 5317 return portion() != kBackingStore; |
5318 } | 5318 } |
5319 | 5319 |
5320 inline int offset() const { | 5320 inline int offset() const { |
5321 return OffsetField::decode(value_); | 5321 return OffsetField::decode(value_); |
5322 } | 5322 } |
5323 | 5323 |
| 5324 inline Representation representation() const { |
| 5325 return Representation::FromKind(RepresentationField::decode(value_)); |
| 5326 } |
| 5327 |
5324 inline Handle<String> name() const { | 5328 inline Handle<String> name() const { |
5325 return name_; | 5329 return name_; |
5326 } | 5330 } |
5327 | 5331 |
| 5332 inline HObjectAccess WithRepresentation(Representation representation) { |
| 5333 return HObjectAccess(portion(), offset(), representation, name()); |
| 5334 } |
| 5335 |
5328 static HObjectAccess ForHeapNumberValue() { | 5336 static HObjectAccess ForHeapNumberValue() { |
5329 return HObjectAccess(kDouble, HeapNumber::kValueOffset); | 5337 return HObjectAccess( |
| 5338 kDouble, HeapNumber::kValueOffset, Representation::Double()); |
5330 } | 5339 } |
5331 | 5340 |
5332 static HObjectAccess ForElementsPointer() { | 5341 static HObjectAccess ForElementsPointer() { |
5333 return HObjectAccess(kElementsPointer, JSObject::kElementsOffset); | 5342 return HObjectAccess(kElementsPointer, JSObject::kElementsOffset); |
5334 } | 5343 } |
5335 | 5344 |
5336 static HObjectAccess ForArrayLength() { | 5345 static HObjectAccess ForArrayLength(bool is_fast_elements = false) { |
5337 return HObjectAccess(kArrayLengths, JSArray::kLengthOffset); | 5346 return HObjectAccess( |
| 5347 kArrayLengths, JSArray::kLengthOffset, |
| 5348 is_fast_elements && FLAG_track_fields ? |
| 5349 Representation::Smi() : Representation::Tagged()); |
5338 } | 5350 } |
5339 | 5351 |
5340 static HObjectAccess ForAllocationSiteTransitionInfo() { | 5352 static HObjectAccess ForAllocationSiteTransitionInfo() { |
5341 return HObjectAccess(kInobject, AllocationSite::kTransitionInfoOffset); | 5353 return HObjectAccess(kInobject, AllocationSite::kTransitionInfoOffset); |
5342 } | 5354 } |
5343 | 5355 |
5344 static HObjectAccess ForAllocationSiteWeakNext() { | 5356 static HObjectAccess ForAllocationSiteWeakNext() { |
5345 return HObjectAccess(kInobject, AllocationSite::kWeakNextOffset); | 5357 return HObjectAccess(kInobject, AllocationSite::kWeakNextOffset); |
5346 } | 5358 } |
5347 | 5359 |
5348 static HObjectAccess ForFixedArrayLength() { | 5360 static HObjectAccess ForFixedArrayLength(bool is_fast_elements = false) { |
5349 return HObjectAccess(kArrayLengths, FixedArray::kLengthOffset); | 5361 return HObjectAccess( |
| 5362 kArrayLengths, FixedArray::kLengthOffset, |
| 5363 FLAG_track_fields ? |
| 5364 Representation::Smi() : Representation::Tagged()); |
5350 } | 5365 } |
5351 | 5366 |
5352 static HObjectAccess ForPropertiesPointer() { | 5367 static HObjectAccess ForPropertiesPointer() { |
5353 return HObjectAccess(kInobject, JSObject::kPropertiesOffset); | 5368 return HObjectAccess(kInobject, JSObject::kPropertiesOffset); |
5354 } | 5369 } |
5355 | 5370 |
5356 static HObjectAccess ForPrototypeOrInitialMap() { | 5371 static HObjectAccess ForPrototypeOrInitialMap() { |
5357 return HObjectAccess(kInobject, JSFunction::kPrototypeOrInitialMapOffset); | 5372 return HObjectAccess(kInobject, JSFunction::kPrototypeOrInitialMapOffset); |
5358 } | 5373 } |
5359 | 5374 |
(...skipping 10 matching lines...) Expand all Loading... |
5370 } | 5385 } |
5371 | 5386 |
5372 static HObjectAccess ForAllocationMementoSite() { | 5387 static HObjectAccess ForAllocationMementoSite() { |
5373 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset); | 5388 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset); |
5374 } | 5389 } |
5375 | 5390 |
5376 // Create an access to an offset in a fixed array header. | 5391 // Create an access to an offset in a fixed array header. |
5377 static HObjectAccess ForFixedArrayHeader(int offset); | 5392 static HObjectAccess ForFixedArrayHeader(int offset); |
5378 | 5393 |
5379 // Create an access to an in-object property in a JSObject. | 5394 // Create an access to an in-object property in a JSObject. |
5380 static HObjectAccess ForJSObjectOffset(int offset); | 5395 static HObjectAccess ForJSObjectOffset(int offset, |
| 5396 Representation representation = Representation::Tagged()); |
5381 | 5397 |
5382 // Create an access to an in-object property in a JSArray. | 5398 // Create an access to an in-object property in a JSArray. |
5383 static HObjectAccess ForJSArrayOffset(int offset); | 5399 static HObjectAccess ForJSArrayOffset(int offset); |
5384 | 5400 |
5385 // Create an access to the backing store of an object. | 5401 // Create an access to the backing store of an object. |
5386 static HObjectAccess ForBackingStoreOffset(int offset); | 5402 static HObjectAccess ForBackingStoreOffset(int offset, |
| 5403 Representation representation = Representation::Tagged()); |
5387 | 5404 |
5388 // Create an access to a resolved field (in-object or backing store). | 5405 // Create an access to a resolved field (in-object or backing store). |
5389 static HObjectAccess ForField(Handle<Map> map, | 5406 static HObjectAccess ForField(Handle<Map> map, |
5390 LookupResult *lookup, Handle<String> name = Handle<String>::null()); | 5407 LookupResult *lookup, Handle<String> name = Handle<String>::null()); |
5391 | 5408 |
5392 // Create an access for the payload of a Cell or JSGlobalPropertyCell. | 5409 // Create an access for the payload of a Cell or JSGlobalPropertyCell. |
5393 static HObjectAccess ForCellPayload(Isolate* isolate); | 5410 static HObjectAccess ForCellPayload(Isolate* isolate); |
5394 | 5411 |
5395 void PrintTo(StringStream* stream); | 5412 void PrintTo(StringStream* stream); |
5396 | 5413 |
5397 inline bool Equals(HObjectAccess that) const { | 5414 inline bool Equals(HObjectAccess that) const { |
5398 return value_ == that.value_; // portion and offset must match | 5415 return value_ == that.value_; // portion and offset must match |
5399 } | 5416 } |
5400 | 5417 |
5401 protected: | 5418 protected: |
5402 void SetGVNFlags(HValue *instr, bool is_store); | 5419 void SetGVNFlags(HValue *instr, bool is_store); |
5403 | 5420 |
5404 private: | 5421 private: |
5405 // internal use only; different parts of an object or array | 5422 // internal use only; different parts of an object or array |
5406 enum Portion { | 5423 enum Portion { |
5407 kMaps, // map of an object | 5424 kMaps, // map of an object |
5408 kArrayLengths, // the length of an array | 5425 kArrayLengths, // the length of an array |
5409 kElementsPointer, // elements pointer | 5426 kElementsPointer, // elements pointer |
5410 kBackingStore, // some field in the backing store | 5427 kBackingStore, // some field in the backing store |
5411 kDouble, // some double field | 5428 kDouble, // some double field |
5412 kInobject // some other in-object field | 5429 kInobject // some other in-object field |
5413 }; | 5430 }; |
5414 | 5431 |
5415 HObjectAccess(Portion portion, int offset, | 5432 HObjectAccess(Portion portion, int offset, |
5416 Handle<String> name = Handle<String>::null()) | 5433 Representation representation = Representation::Tagged(), |
5417 : value_(PortionField::encode(portion) | OffsetField::encode(offset)), | 5434 Handle<String> name = Handle<String>::null()) |
| 5435 : value_(PortionField::encode(portion) | |
| 5436 RepresentationField::encode(representation.kind()) | |
| 5437 OffsetField::encode(offset)), |
5418 name_(name) { | 5438 name_(name) { |
5419 ASSERT(this->offset() == offset); // offset should decode correctly | 5439 // assert that the fields decode correctly |
5420 ASSERT(this->portion() == portion); // portion should decode correctly | 5440 ASSERT(this->offset() == offset); |
| 5441 ASSERT(this->portion() == portion); |
| 5442 ASSERT(RepresentationField::decode(value_) == representation.kind()); |
5421 } | 5443 } |
5422 | 5444 |
5423 class PortionField : public BitField<Portion, 0, 3> {}; | 5445 class PortionField : public BitField<Portion, 0, 3> {}; |
5424 class OffsetField : public BitField<int, 3, 29> {}; | 5446 class RepresentationField : public BitField<Representation::Kind, 3, 3> {}; |
| 5447 class OffsetField : public BitField<int, 6, 26> {}; |
5425 | 5448 |
5426 uint32_t value_; // encodes both portion and offset | 5449 uint32_t value_; // encodes portion, representation, and offset |
5427 Handle<String> name_; | 5450 Handle<String> name_; |
5428 | 5451 |
5429 friend class HLoadNamedField; | 5452 friend class HLoadNamedField; |
5430 friend class HStoreNamedField; | 5453 friend class HStoreNamedField; |
5431 | 5454 |
5432 inline Portion portion() const { | 5455 inline Portion portion() const { |
5433 return PortionField::decode(value_); | 5456 return PortionField::decode(value_); |
5434 } | 5457 } |
5435 }; | 5458 }; |
5436 | 5459 |
(...skipping 27 matching lines...) Expand all Loading... |
5464 private: | 5487 private: |
5465 HObjectAccess store_field_; | 5488 HObjectAccess store_field_; |
5466 KnownList known_list_; | 5489 KnownList known_list_; |
5467 }; | 5490 }; |
5468 | 5491 |
5469 | 5492 |
5470 class HLoadNamedField: public HTemplateInstruction<2> { | 5493 class HLoadNamedField: public HTemplateInstruction<2> { |
5471 public: | 5494 public: |
5472 HLoadNamedField(HValue* object, | 5495 HLoadNamedField(HValue* object, |
5473 HObjectAccess access, | 5496 HObjectAccess access, |
5474 HValue* typecheck = NULL, | 5497 HValue* typecheck = NULL) |
5475 Representation field_representation | 5498 : access_(access) { |
5476 = Representation::Tagged()) | |
5477 : access_(access), | |
5478 field_representation_(field_representation) { | |
5479 ASSERT(object != NULL); | 5499 ASSERT(object != NULL); |
5480 SetOperandAt(0, object); | 5500 SetOperandAt(0, object); |
5481 SetOperandAt(1, typecheck != NULL ? typecheck : object); | 5501 SetOperandAt(1, typecheck != NULL ? typecheck : object); |
5482 | 5502 |
5483 if (FLAG_track_fields && field_representation.IsSmi()) { | 5503 Representation representation = access.representation(); |
| 5504 if (representation.IsSmi()) { |
5484 set_type(HType::Smi()); | 5505 set_type(HType::Smi()); |
5485 set_representation(field_representation); | 5506 set_representation(representation); |
5486 } else if (FLAG_track_double_fields && field_representation.IsDouble()) { | 5507 } else if (representation.IsDouble()) { |
5487 set_representation(field_representation); | 5508 set_representation(representation); |
5488 } else if (FLAG_track_heap_object_fields && | 5509 } else if (FLAG_track_heap_object_fields && |
5489 field_representation.IsHeapObject()) { | 5510 representation.IsHeapObject()) { |
5490 set_type(HType::NonPrimitive()); | 5511 set_type(HType::NonPrimitive()); |
5491 set_representation(Representation::Tagged()); | 5512 set_representation(Representation::Tagged()); |
5492 } else { | 5513 } else { |
5493 set_representation(Representation::Tagged()); | 5514 set_representation(Representation::Tagged()); |
5494 } | 5515 } |
5495 access.SetGVNFlags(this, false); | 5516 access.SetGVNFlags(this, false); |
5496 } | 5517 } |
5497 | 5518 |
5498 HValue* object() { return OperandAt(0); } | 5519 HValue* object() { return OperandAt(0); } |
5499 HValue* typecheck() { | 5520 HValue* typecheck() { |
5500 ASSERT(HasTypeCheck()); | 5521 ASSERT(HasTypeCheck()); |
5501 return OperandAt(1); | 5522 return OperandAt(1); |
5502 } | 5523 } |
5503 | 5524 |
5504 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } | 5525 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } |
5505 HObjectAccess access() const { return access_; } | 5526 HObjectAccess access() const { return access_; } |
5506 Representation field_representation() const { return representation_; } | 5527 Representation field_representation() const { |
| 5528 return access_.representation(); |
| 5529 } |
5507 | 5530 |
5508 virtual bool HasEscapingOperandAt(int index) { return false; } | 5531 virtual bool HasEscapingOperandAt(int index) { return false; } |
5509 virtual Representation RequiredInputRepresentation(int index) { | 5532 virtual Representation RequiredInputRepresentation(int index) { |
5510 return Representation::Tagged(); | 5533 return Representation::Tagged(); |
5511 } | 5534 } |
5512 virtual void PrintDataTo(StringStream* stream); | 5535 virtual void PrintDataTo(StringStream* stream); |
5513 | 5536 |
5514 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) | 5537 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) |
5515 | 5538 |
5516 protected: | 5539 protected: |
5517 virtual bool DataEquals(HValue* other) { | 5540 virtual bool DataEquals(HValue* other) { |
5518 HLoadNamedField* b = HLoadNamedField::cast(other); | 5541 HLoadNamedField* b = HLoadNamedField::cast(other); |
5519 return access_.Equals(b->access_); | 5542 return access_.Equals(b->access_); |
5520 } | 5543 } |
5521 | 5544 |
5522 private: | 5545 private: |
5523 virtual bool IsDeletable() const { return true; } | 5546 virtual bool IsDeletable() const { return true; } |
5524 | 5547 |
5525 HObjectAccess access_; | 5548 HObjectAccess access_; |
5526 Representation field_representation_; | |
5527 }; | 5549 }; |
5528 | 5550 |
5529 | 5551 |
5530 class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> { | 5552 class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> { |
5531 public: | 5553 public: |
5532 HLoadNamedFieldPolymorphic(HValue* context, | 5554 HLoadNamedFieldPolymorphic(HValue* context, |
5533 HValue* object, | 5555 HValue* object, |
5534 SmallMapList* types, | 5556 SmallMapList* types, |
5535 Handle<String> name, | 5557 Handle<String> name, |
5536 Zone* zone); | 5558 Zone* zone); |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5816 virtual HValue* Canonicalize(); | 5838 virtual HValue* Canonicalize(); |
5817 | 5839 |
5818 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric) | 5840 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric) |
5819 }; | 5841 }; |
5820 | 5842 |
5821 | 5843 |
5822 class HStoreNamedField: public HTemplateInstruction<2> { | 5844 class HStoreNamedField: public HTemplateInstruction<2> { |
5823 public: | 5845 public: |
5824 HStoreNamedField(HValue* obj, | 5846 HStoreNamedField(HValue* obj, |
5825 HObjectAccess access, | 5847 HObjectAccess access, |
5826 HValue* val, | 5848 HValue* val) |
5827 Representation field_representation | |
5828 = Representation::Tagged()) | |
5829 : access_(access), | 5849 : access_(access), |
5830 field_representation_(field_representation), | |
5831 transition_(), | 5850 transition_(), |
5832 transition_unique_id_(), | 5851 transition_unique_id_(), |
5833 new_space_dominator_(NULL), | 5852 new_space_dominator_(NULL), |
5834 write_barrier_mode_(UPDATE_WRITE_BARRIER) { | 5853 write_barrier_mode_(UPDATE_WRITE_BARRIER) { |
5835 SetOperandAt(0, obj); | 5854 SetOperandAt(0, obj); |
5836 SetOperandAt(1, val); | 5855 SetOperandAt(1, val); |
5837 access.SetGVNFlags(this, true); | 5856 access.SetGVNFlags(this, true); |
5838 } | 5857 } |
5839 | 5858 |
5840 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) | 5859 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) |
5841 | 5860 |
5842 virtual bool HasEscapingOperandAt(int index) { return index == 1; } | 5861 virtual bool HasEscapingOperandAt(int index) { return index == 1; } |
5843 virtual Representation RequiredInputRepresentation(int index) { | 5862 virtual Representation RequiredInputRepresentation(int index) { |
5844 if (FLAG_track_double_fields && | 5863 if (index == 1 && field_representation().IsDouble()) { |
5845 index == 1 && field_representation_.IsDouble()) { | 5864 return field_representation(); |
5846 return field_representation_; | 5865 } else if (index == 1 && field_representation().IsSmi()) { |
5847 } else if (FLAG_track_fields && | 5866 return field_representation(); |
5848 index == 1 && field_representation_.IsSmi()) { | |
5849 return field_representation_; | |
5850 } | 5867 } |
5851 return Representation::Tagged(); | 5868 return Representation::Tagged(); |
5852 } | 5869 } |
5853 virtual void HandleSideEffectDominator(GVNFlag side_effect, | 5870 virtual void HandleSideEffectDominator(GVNFlag side_effect, |
5854 HValue* dominator) { | 5871 HValue* dominator) { |
5855 ASSERT(side_effect == kChangesNewSpacePromotion); | 5872 ASSERT(side_effect == kChangesNewSpacePromotion); |
5856 new_space_dominator_ = dominator; | 5873 new_space_dominator_ = dominator; |
5857 } | 5874 } |
5858 virtual void PrintDataTo(StringStream* stream); | 5875 virtual void PrintDataTo(StringStream* stream); |
5859 | 5876 |
(...skipping 11 matching lines...) Expand all Loading... |
5871 void SetTransition(Handle<Map> map, CompilationInfo* info) { | 5888 void SetTransition(Handle<Map> map, CompilationInfo* info) { |
5872 ASSERT(transition_.is_null()); // Only set once. | 5889 ASSERT(transition_.is_null()); // Only set once. |
5873 if (map->CanBeDeprecated()) { | 5890 if (map->CanBeDeprecated()) { |
5874 map->AddDependentCompilationInfo(DependentCode::kTransitionGroup, info); | 5891 map->AddDependentCompilationInfo(DependentCode::kTransitionGroup, info); |
5875 } | 5892 } |
5876 transition_ = map; | 5893 transition_ = map; |
5877 } | 5894 } |
5878 HValue* new_space_dominator() const { return new_space_dominator_; } | 5895 HValue* new_space_dominator() const { return new_space_dominator_; } |
5879 | 5896 |
5880 bool NeedsWriteBarrier() { | 5897 bool NeedsWriteBarrier() { |
5881 ASSERT(!(FLAG_track_double_fields && field_representation_.IsDouble()) || | 5898 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) || |
5882 transition_.is_null()); | 5899 transition_.is_null()); |
5883 if (IsSkipWriteBarrier()) return false; | 5900 if (IsSkipWriteBarrier()) return false; |
5884 return (!FLAG_track_fields || !field_representation_.IsSmi()) && | 5901 if (field_representation().IsDouble()) return false; |
5885 // If there is a transition, a new storage object needs to be allocated. | 5902 if (field_representation().IsSmi()) return false; |
5886 !(FLAG_track_double_fields && field_representation_.IsDouble()) && | 5903 return StoringValueNeedsWriteBarrier(value()) && |
5887 StoringValueNeedsWriteBarrier(value()) && | |
5888 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); | 5904 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); |
5889 } | 5905 } |
5890 | 5906 |
5891 bool NeedsWriteBarrierForMap() { | 5907 bool NeedsWriteBarrierForMap() { |
5892 if (IsSkipWriteBarrier()) return false; | 5908 if (IsSkipWriteBarrier()) return false; |
5893 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); | 5909 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); |
5894 } | 5910 } |
5895 | 5911 |
5896 virtual void FinalizeUniqueValueId() { | 5912 virtual void FinalizeUniqueValueId() { |
5897 transition_unique_id_ = UniqueValueId(transition_); | 5913 transition_unique_id_ = UniqueValueId(transition_); |
5898 } | 5914 } |
5899 | 5915 |
5900 Representation field_representation() const { | 5916 Representation field_representation() const { |
5901 return field_representation_; | 5917 return access_.representation(); |
5902 } | 5918 } |
5903 | 5919 |
5904 private: | 5920 private: |
5905 HObjectAccess access_; | 5921 HObjectAccess access_; |
5906 Representation field_representation_; | |
5907 Handle<Map> transition_; | 5922 Handle<Map> transition_; |
5908 UniqueValueId transition_unique_id_; | 5923 UniqueValueId transition_unique_id_; |
5909 HValue* new_space_dominator_; | 5924 HValue* new_space_dominator_; |
5910 WriteBarrierMode write_barrier_mode_; | 5925 WriteBarrierMode write_barrier_mode_; |
5911 }; | 5926 }; |
5912 | 5927 |
5913 | 5928 |
5914 class HStoreNamedGeneric: public HTemplateInstruction<3> { | 5929 class HStoreNamedGeneric: public HTemplateInstruction<3> { |
5915 public: | 5930 public: |
5916 HStoreNamedGeneric(HValue* context, | 5931 HStoreNamedGeneric(HValue* context, |
(...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6693 virtual bool IsDeletable() const { return true; } | 6708 virtual bool IsDeletable() const { return true; } |
6694 }; | 6709 }; |
6695 | 6710 |
6696 | 6711 |
6697 #undef DECLARE_INSTRUCTION | 6712 #undef DECLARE_INSTRUCTION |
6698 #undef DECLARE_CONCRETE_INSTRUCTION | 6713 #undef DECLARE_CONCRETE_INSTRUCTION |
6699 | 6714 |
6700 } } // namespace v8::internal | 6715 } } // namespace v8::internal |
6701 | 6716 |
6702 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6717 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |