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 5263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5274 class HObjectAccess { | 5274 class HObjectAccess { |
5275 public: | 5275 public: |
5276 inline bool IsInobject() const { | 5276 inline bool IsInobject() const { |
5277 return portion() != kBackingStore; | 5277 return portion() != kBackingStore; |
5278 } | 5278 } |
5279 | 5279 |
5280 inline int offset() const { | 5280 inline int offset() const { |
5281 return OffsetField::decode(value_); | 5281 return OffsetField::decode(value_); |
5282 } | 5282 } |
5283 | 5283 |
5284 inline Representation representation() const { | |
5285 return Representation::FromKind(RepresentationField::decode(value_)); | |
5286 } | |
5287 | |
5284 inline Handle<String> name() const { | 5288 inline Handle<String> name() const { |
5285 return name_; | 5289 return name_; |
5286 } | 5290 } |
5287 | 5291 |
5292 inline HObjectAccess WithRepresentation(Representation representation) { | |
5293 return HObjectAccess(portion(), offset(), representation, name()); | |
5294 } | |
5295 | |
5288 static HObjectAccess ForHeapNumberValue() { | 5296 static HObjectAccess ForHeapNumberValue() { |
5289 return HObjectAccess(kDouble, HeapNumber::kValueOffset); | 5297 return HObjectAccess( |
5298 kDouble, HeapNumber::kValueOffset, Representation::Double()); | |
5290 } | 5299 } |
5291 | 5300 |
5292 static HObjectAccess ForElementsPointer() { | 5301 static HObjectAccess ForElementsPointer() { |
5293 return HObjectAccess(kElementsPointer, JSObject::kElementsOffset); | 5302 return HObjectAccess(kElementsPointer, JSObject::kElementsOffset); |
5294 } | 5303 } |
5295 | 5304 |
5296 static HObjectAccess ForArrayLength() { | 5305 static HObjectAccess ForArrayLength(bool is_fast_elements = false) { |
5297 return HObjectAccess(kArrayLengths, JSArray::kLengthOffset); | 5306 return HObjectAccess( |
5307 kArrayLengths, JSArray::kLengthOffset, is_fast_elements ? | |
5308 Representation::Smi() : Representation::Tagged()); | |
danno
2013/07/08 11:12:25
You should probably gate using ::Smi() here and be
| |
5298 } | 5309 } |
5299 | 5310 |
5300 static HObjectAccess ForFixedArrayLength() { | 5311 static HObjectAccess ForFixedArrayLength(bool is_fast_elements = false) { |
5301 return HObjectAccess(kArrayLengths, FixedArray::kLengthOffset); | 5312 return HObjectAccess( |
5313 kArrayLengths, FixedArray::kLengthOffset, is_fast_elements ? | |
5314 Representation::Smi() : Representation::Tagged()); | |
danno
2013/07/08 11:12:25
It's _always_ ::Smi() for FixedArrays, no need to
| |
5302 } | 5315 } |
5303 | 5316 |
5304 static HObjectAccess ForPropertiesPointer() { | 5317 static HObjectAccess ForPropertiesPointer() { |
5305 return HObjectAccess(kInobject, JSObject::kPropertiesOffset); | 5318 return HObjectAccess(kInobject, JSObject::kPropertiesOffset); |
5306 } | 5319 } |
5307 | 5320 |
5308 static HObjectAccess ForPrototypeOrInitialMap() { | 5321 static HObjectAccess ForPrototypeOrInitialMap() { |
5309 return HObjectAccess(kInobject, JSFunction::kPrototypeOrInitialMapOffset); | 5322 return HObjectAccess(kInobject, JSFunction::kPrototypeOrInitialMapOffset); |
5310 } | 5323 } |
5311 | 5324 |
5312 static HObjectAccess ForMap() { | 5325 static HObjectAccess ForMap() { |
5313 return HObjectAccess(kMaps, JSObject::kMapOffset); | 5326 return HObjectAccess(kMaps, JSObject::kMapOffset); |
5314 } | 5327 } |
5315 | 5328 |
5316 static HObjectAccess ForAllocationSitePayload() { | 5329 static HObjectAccess ForAllocationSitePayload() { |
5317 return HObjectAccess(kInobject, AllocationSiteInfo::kPayloadOffset); | 5330 return HObjectAccess(kInobject, AllocationSiteInfo::kPayloadOffset); |
5318 } | 5331 } |
5319 | 5332 |
5320 // Create an access to an offset in a fixed array header. | 5333 // Create an access to an offset in a fixed array header. |
5321 static HObjectAccess ForFixedArrayHeader(int offset); | 5334 static HObjectAccess ForFixedArrayHeader(int offset); |
5322 | 5335 |
5323 // Create an access to an in-object property in a JSObject. | 5336 // Create an access to an in-object property in a JSObject. |
5324 static HObjectAccess ForJSObjectOffset(int offset); | 5337 static HObjectAccess ForJSObjectOffset(int offset, |
5338 Representation representation = Representation::Tagged()); | |
5325 | 5339 |
5326 // Create an access to an in-object property in a JSArray. | 5340 // Create an access to an in-object property in a JSArray. |
5327 static HObjectAccess ForJSArrayOffset(int offset); | 5341 static HObjectAccess ForJSArrayOffset(int offset); |
5328 | 5342 |
5329 // Create an access to the backing store of an object. | 5343 // Create an access to the backing store of an object. |
5330 static HObjectAccess ForBackingStoreOffset(int offset); | 5344 static HObjectAccess ForBackingStoreOffset(int offset, |
5345 Representation representation = Representation::Tagged()); | |
5331 | 5346 |
5332 // Create an access to a resolved field (in-object or backing store). | 5347 // Create an access to a resolved field (in-object or backing store). |
5333 static HObjectAccess ForField(Handle<Map> map, | 5348 static HObjectAccess ForField(Handle<Map> map, |
5334 LookupResult *lookup, Handle<String> name = Handle<String>::null()); | 5349 LookupResult *lookup, Handle<String> name = Handle<String>::null()); |
5335 | 5350 |
5336 void PrintTo(StringStream* stream); | 5351 void PrintTo(StringStream* stream); |
5337 | 5352 |
5338 inline bool Equals(HObjectAccess that) const { | 5353 inline bool Equals(HObjectAccess that) const { |
5339 return value_ == that.value_; // portion and offset must match | 5354 return value_ == that.value_; // portion and offset must match |
5340 } | 5355 } |
5341 | 5356 |
5342 protected: | 5357 protected: |
5343 void SetGVNFlags(HValue *instr, bool is_store); | 5358 void SetGVNFlags(HValue *instr, bool is_store); |
5344 | 5359 |
5345 private: | 5360 private: |
5346 // internal use only; different parts of an object or array | 5361 // internal use only; different parts of an object or array |
5347 enum Portion { | 5362 enum Portion { |
5348 kMaps, // map of an object | 5363 kMaps, // map of an object |
5349 kArrayLengths, // the length of an array | 5364 kArrayLengths, // the length of an array |
5350 kElementsPointer, // elements pointer | 5365 kElementsPointer, // elements pointer |
5351 kBackingStore, // some field in the backing store | 5366 kBackingStore, // some field in the backing store |
5352 kDouble, // some double field | 5367 kDouble, // some double field |
5353 kInobject // some other in-object field | 5368 kInobject // some other in-object field |
5354 }; | 5369 }; |
5355 | 5370 |
5356 HObjectAccess(Portion portion, int offset, | 5371 HObjectAccess(Portion portion, int offset, |
5357 Handle<String> name = Handle<String>::null()) | 5372 Representation representation = Representation::Tagged(), |
5358 : value_(PortionField::encode(portion) | OffsetField::encode(offset)), | 5373 Handle<String> name = Handle<String>::null()) |
5374 : value_(PortionField::encode(portion) | | |
5375 RepresentationField::encode(representation.kind()) | | |
5376 OffsetField::encode(offset)), | |
5359 name_(name) { | 5377 name_(name) { |
5360 ASSERT(this->offset() == offset); // offset should decode correctly | 5378 // assert that the fields decode correctly |
5361 ASSERT(this->portion() == portion); // portion should decode correctly | 5379 ASSERT(this->offset() == offset); |
5380 ASSERT(this->portion() == portion); | |
5381 ASSERT(RepresentationField::decode(value_) == representation.kind()); | |
5362 } | 5382 } |
5363 | 5383 |
5364 class PortionField : public BitField<Portion, 0, 3> {}; | 5384 class PortionField : public BitField<Portion, 0, 3> {}; |
5365 class OffsetField : public BitField<int, 3, 29> {}; | 5385 class RepresentationField : public BitField<Representation::Kind, 3, 3> {}; |
5386 class OffsetField : public BitField<int, 6, 26> {}; | |
5366 | 5387 |
5367 uint32_t value_; // encodes both portion and offset | 5388 uint32_t value_; // encodes portion, representation, and offset |
5368 Handle<String> name_; | 5389 Handle<String> name_; |
5369 | 5390 |
5370 friend class HLoadNamedField; | 5391 friend class HLoadNamedField; |
5371 friend class HStoreNamedField; | 5392 friend class HStoreNamedField; |
5372 | 5393 |
5373 inline Portion portion() const { | 5394 inline Portion portion() const { |
5374 return PortionField::decode(value_); | 5395 return PortionField::decode(value_); |
5375 } | 5396 } |
5376 }; | 5397 }; |
5377 | 5398 |
5378 | 5399 |
5379 class HLoadNamedField: public HTemplateInstruction<2> { | 5400 class HLoadNamedField: public HTemplateInstruction<2> { |
5380 public: | 5401 public: |
5381 HLoadNamedField(HValue* object, | 5402 HLoadNamedField(HValue* object, |
5382 HObjectAccess access, | 5403 HObjectAccess access, |
5383 HValue* typecheck = NULL, | 5404 HValue* typecheck = NULL) |
5384 Representation field_representation | 5405 : access_(access) { |
5385 = Representation::Tagged()) | |
5386 : access_(access), | |
5387 field_representation_(field_representation) { | |
5388 ASSERT(object != NULL); | 5406 ASSERT(object != NULL); |
5389 SetOperandAt(0, object); | 5407 SetOperandAt(0, object); |
5390 SetOperandAt(1, typecheck != NULL ? typecheck : object); | 5408 SetOperandAt(1, typecheck != NULL ? typecheck : object); |
5391 | 5409 |
5392 if (FLAG_track_fields && field_representation.IsSmi()) { | 5410 Representation representation = access.representation(); |
5411 if (representation.IsSmi()) { | |
5393 set_type(HType::Smi()); | 5412 set_type(HType::Smi()); |
5394 set_representation(field_representation); | 5413 set_representation(representation); |
5395 } else if (FLAG_track_double_fields && field_representation.IsDouble()) { | 5414 } else if (representation.IsDouble()) { |
5396 set_representation(field_representation); | 5415 set_representation(representation); |
5397 } else if (FLAG_track_heap_object_fields && | 5416 } else if (FLAG_track_heap_object_fields && |
5398 field_representation.IsHeapObject()) { | 5417 representation.IsHeapObject()) { |
5399 set_type(HType::NonPrimitive()); | 5418 set_type(HType::NonPrimitive()); |
5400 set_representation(Representation::Tagged()); | 5419 set_representation(Representation::Tagged()); |
5401 } else { | 5420 } else { |
5402 set_representation(Representation::Tagged()); | 5421 set_representation(Representation::Tagged()); |
5403 } | 5422 } |
5404 access.SetGVNFlags(this, false); | 5423 access.SetGVNFlags(this, false); |
5405 } | 5424 } |
5406 | 5425 |
5407 HValue* object() { return OperandAt(0); } | 5426 HValue* object() { return OperandAt(0); } |
5408 HValue* typecheck() { | 5427 HValue* typecheck() { |
5409 ASSERT(HasTypeCheck()); | 5428 ASSERT(HasTypeCheck()); |
5410 return OperandAt(1); | 5429 return OperandAt(1); |
5411 } | 5430 } |
5412 | 5431 |
5413 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } | 5432 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } |
5414 HObjectAccess access() const { return access_; } | 5433 HObjectAccess access() const { return access_; } |
5415 Representation field_representation() const { return representation_; } | 5434 Representation field_representation() const { |
5435 return access_.representation(); | |
5436 } | |
5416 | 5437 |
5417 virtual bool HasEscapingOperandAt(int index) { return false; } | 5438 virtual bool HasEscapingOperandAt(int index) { return false; } |
5418 virtual Representation RequiredInputRepresentation(int index) { | 5439 virtual Representation RequiredInputRepresentation(int index) { |
5419 return Representation::Tagged(); | 5440 return Representation::Tagged(); |
5420 } | 5441 } |
5421 virtual void PrintDataTo(StringStream* stream); | 5442 virtual void PrintDataTo(StringStream* stream); |
5422 | 5443 |
5423 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) | 5444 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) |
5424 | 5445 |
5425 protected: | 5446 protected: |
5426 virtual bool DataEquals(HValue* other) { | 5447 virtual bool DataEquals(HValue* other) { |
5427 HLoadNamedField* b = HLoadNamedField::cast(other); | 5448 HLoadNamedField* b = HLoadNamedField::cast(other); |
5428 return access_.Equals(b->access_); | 5449 return access_.Equals(b->access_); |
5429 } | 5450 } |
5430 | 5451 |
5431 private: | 5452 private: |
5432 virtual bool IsDeletable() const { return true; } | 5453 virtual bool IsDeletable() const { return true; } |
5433 | 5454 |
5434 HObjectAccess access_; | 5455 HObjectAccess access_; |
5435 Representation field_representation_; | |
5436 }; | 5456 }; |
5437 | 5457 |
5438 | 5458 |
5439 class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> { | 5459 class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> { |
5440 public: | 5460 public: |
5441 HLoadNamedFieldPolymorphic(HValue* context, | 5461 HLoadNamedFieldPolymorphic(HValue* context, |
5442 HValue* object, | 5462 HValue* object, |
5443 SmallMapList* types, | 5463 SmallMapList* types, |
5444 Handle<String> name, | 5464 Handle<String> name, |
5445 Zone* zone); | 5465 Zone* zone); |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5725 virtual HValue* Canonicalize(); | 5745 virtual HValue* Canonicalize(); |
5726 | 5746 |
5727 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric) | 5747 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric) |
5728 }; | 5748 }; |
5729 | 5749 |
5730 | 5750 |
5731 class HStoreNamedField: public HTemplateInstruction<2> { | 5751 class HStoreNamedField: public HTemplateInstruction<2> { |
5732 public: | 5752 public: |
5733 HStoreNamedField(HValue* obj, | 5753 HStoreNamedField(HValue* obj, |
5734 HObjectAccess access, | 5754 HObjectAccess access, |
5735 HValue* val, | 5755 HValue* val) |
5736 Representation field_representation | |
5737 = Representation::Tagged()) | |
5738 : access_(access), | 5756 : access_(access), |
5739 field_representation_(field_representation), | |
5740 transition_(), | 5757 transition_(), |
5741 transition_unique_id_(), | 5758 transition_unique_id_(), |
5742 new_space_dominator_(NULL) { | 5759 new_space_dominator_(NULL) { |
5743 SetOperandAt(0, obj); | 5760 SetOperandAt(0, obj); |
5744 SetOperandAt(1, val); | 5761 SetOperandAt(1, val); |
5745 access.SetGVNFlags(this, true); | 5762 access.SetGVNFlags(this, true); |
5746 } | 5763 } |
5747 | 5764 |
5748 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) | 5765 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) |
5749 | 5766 |
5750 virtual bool HasEscapingOperandAt(int index) { return index == 1; } | 5767 virtual bool HasEscapingOperandAt(int index) { return index == 1; } |
5751 virtual Representation RequiredInputRepresentation(int index) { | 5768 virtual Representation RequiredInputRepresentation(int index) { |
5752 if (FLAG_track_double_fields && | 5769 if (index == 1 && field_representation().IsDouble()) { |
5753 index == 1 && field_representation_.IsDouble()) { | 5770 return field_representation(); |
5754 return field_representation_; | 5771 } else if (index == 1 && field_representation().IsSmi()) { |
5755 } else if (FLAG_track_fields && | 5772 return field_representation(); |
5756 index == 1 && field_representation_.IsSmi()) { | |
5757 return field_representation_; | |
5758 } | 5773 } |
5759 return Representation::Tagged(); | 5774 return Representation::Tagged(); |
5760 } | 5775 } |
5761 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) { | 5776 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) { |
5762 ASSERT(side_effect == kChangesNewSpacePromotion); | 5777 ASSERT(side_effect == kChangesNewSpacePromotion); |
5763 new_space_dominator_ = dominator; | 5778 new_space_dominator_ = dominator; |
5764 } | 5779 } |
5765 virtual void PrintDataTo(StringStream* stream); | 5780 virtual void PrintDataTo(StringStream* stream); |
5766 | 5781 |
5767 HValue* object() { return OperandAt(0); } | 5782 HValue* object() { return OperandAt(0); } |
5768 HValue* value() { return OperandAt(1); } | 5783 HValue* value() { return OperandAt(1); } |
5769 | 5784 |
5770 HObjectAccess access() const { return access_; } | 5785 HObjectAccess access() const { return access_; } |
5771 Handle<Map> transition() const { return transition_; } | 5786 Handle<Map> transition() const { return transition_; } |
5772 UniqueValueId transition_unique_id() const { return transition_unique_id_; } | 5787 UniqueValueId transition_unique_id() const { return transition_unique_id_; } |
5773 void SetTransition(Handle<Map> map, CompilationInfo* info) { | 5788 void SetTransition(Handle<Map> map, CompilationInfo* info) { |
5774 ASSERT(transition_.is_null()); // Only set once. | 5789 ASSERT(transition_.is_null()); // Only set once. |
5775 if (map->CanBeDeprecated()) { | 5790 if (map->CanBeDeprecated()) { |
5776 map->AddDependentCompilationInfo(DependentCode::kTransitionGroup, info); | 5791 map->AddDependentCompilationInfo(DependentCode::kTransitionGroup, info); |
5777 } | 5792 } |
5778 transition_ = map; | 5793 transition_ = map; |
5779 } | 5794 } |
5780 HValue* new_space_dominator() const { return new_space_dominator_; } | 5795 HValue* new_space_dominator() const { return new_space_dominator_; } |
5781 | 5796 |
5782 bool NeedsWriteBarrier() { | 5797 bool NeedsWriteBarrier() { |
5783 ASSERT(!(FLAG_track_double_fields && field_representation_.IsDouble()) || | 5798 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) || |
5784 transition_.is_null()); | 5799 transition_.is_null()); |
5785 return (!FLAG_track_fields || !field_representation_.IsSmi()) && | 5800 if (field_representation().IsDouble()) return false; |
5786 // If there is a transition, a new storage object needs to be allocated. | 5801 if (field_representation().IsSmi()) return false; |
5787 !(FLAG_track_double_fields && field_representation_.IsDouble()) && | 5802 return StoringValueNeedsWriteBarrier(value()) && |
5788 StoringValueNeedsWriteBarrier(value()) && | |
5789 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); | 5803 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); |
5790 } | 5804 } |
5791 | 5805 |
5792 bool NeedsWriteBarrierForMap() { | 5806 bool NeedsWriteBarrierForMap() { |
5793 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); | 5807 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); |
5794 } | 5808 } |
5795 | 5809 |
5796 virtual void FinalizeUniqueValueId() { | 5810 virtual void FinalizeUniqueValueId() { |
5797 transition_unique_id_ = UniqueValueId(transition_); | 5811 transition_unique_id_ = UniqueValueId(transition_); |
5798 } | 5812 } |
5799 | 5813 |
5800 Representation field_representation() const { | 5814 Representation field_representation() const { |
5801 return field_representation_; | 5815 return access_.representation(); |
5802 } | 5816 } |
5803 | 5817 |
5804 private: | 5818 private: |
5805 HObjectAccess access_; | 5819 HObjectAccess access_; |
5806 Representation field_representation_; | |
5807 Handle<Map> transition_; | 5820 Handle<Map> transition_; |
5808 UniqueValueId transition_unique_id_; | 5821 UniqueValueId transition_unique_id_; |
5809 HValue* new_space_dominator_; | 5822 HValue* new_space_dominator_; |
5810 }; | 5823 }; |
5811 | 5824 |
5812 | 5825 |
5813 class HStoreNamedGeneric: public HTemplateInstruction<3> { | 5826 class HStoreNamedGeneric: public HTemplateInstruction<3> { |
5814 public: | 5827 public: |
5815 HStoreNamedGeneric(HValue* context, | 5828 HStoreNamedGeneric(HValue* context, |
5816 HValue* object, | 5829 HValue* object, |
(...skipping 819 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6636 virtual bool IsDeletable() const { return true; } | 6649 virtual bool IsDeletable() const { return true; } |
6637 }; | 6650 }; |
6638 | 6651 |
6639 | 6652 |
6640 #undef DECLARE_INSTRUCTION | 6653 #undef DECLARE_INSTRUCTION |
6641 #undef DECLARE_CONCRETE_INSTRUCTION | 6654 #undef DECLARE_CONCRETE_INSTRUCTION |
6642 | 6655 |
6643 } } // namespace v8::internal | 6656 } } // namespace v8::internal |
6644 | 6657 |
6645 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6658 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |