Chromium Code Reviews| 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 5183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5194 virtual void PrintDataTo(StringStream* stream); | 5194 virtual void PrintDataTo(StringStream* stream); |
| 5195 | 5195 |
| 5196 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot) | 5196 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot) |
| 5197 | 5197 |
| 5198 private: | 5198 private: |
| 5199 int slot_index_; | 5199 int slot_index_; |
| 5200 Mode mode_; | 5200 Mode mode_; |
| 5201 }; | 5201 }; |
| 5202 | 5202 |
| 5203 | 5203 |
| 5204 // Represents an access to a portion of an object, such as the map pointer, | |
| 5205 // array elements pointer, etc, but not accesses to array elements themselves. | |
| 5206 class HObjectAccess { | |
| 5207 public: | |
| 5208 inline bool IsInobject() const { | |
| 5209 return portion_ != kBackingStore; | |
| 5210 } | |
| 5211 | |
| 5212 inline int offset() const { | |
| 5213 return offset_; | |
| 5214 } | |
| 5215 | |
| 5216 inline Handle<String> name() const { | |
| 5217 return name_; | |
| 5218 } | |
| 5219 | |
| 5220 static HObjectAccess ForHeapNumberValue() { | |
| 5221 return HObjectAccess(kInobject, HeapNumber::kValueOffset); | |
| 5222 } | |
| 5223 | |
| 5224 static HObjectAccess ForElementsPointer() { | |
| 5225 return HObjectAccess(kElementsPointer, JSObject::kElementsOffset); | |
| 5226 } | |
| 5227 | |
| 5228 static HObjectAccess ForArrayLength() { | |
| 5229 return HObjectAccess(kArrayLengths, JSArray::kLengthOffset); | |
| 5230 } | |
| 5231 | |
| 5232 static HObjectAccess ForFixedArrayLength() { | |
| 5233 return HObjectAccess(kArrayLengths, FixedArray::kLengthOffset); | |
| 5234 } | |
| 5235 | |
| 5236 static HObjectAccess ForPropertiesPointer() { | |
| 5237 return HObjectAccess(kInobject, JSObject::kPropertiesOffset); | |
| 5238 } | |
| 5239 | |
| 5240 static HObjectAccess ForMap() { | |
| 5241 return HObjectAccess(kMaps, JSObject::kMapOffset); | |
| 5242 } | |
| 5243 | |
| 5244 static HObjectAccess ForAllocationSitePayload() { | |
| 5245 return HObjectAccess(kInobject, AllocationSiteInfo::kPayloadOffset); | |
| 5246 } | |
| 5247 | |
| 5248 // Create an access to an offset in a fixed array header. | |
| 5249 static HObjectAccess ForFixedArrayHeader(int offset); | |
| 5250 | |
| 5251 // Create an access to an in-object property in a JSObject. | |
| 5252 static HObjectAccess ForJSObjectOffset(int offset); | |
| 5253 | |
| 5254 // Create an access to an in-object property in a JSArray. | |
| 5255 static HObjectAccess ForJSArrayOffset(int offset); | |
| 5256 | |
| 5257 // Create an access to the backing store of an object. | |
| 5258 static HObjectAccess ForBackingStoreOffset(int offset); | |
| 5259 | |
| 5260 // Create an access to a resolved field (in-object or backing store). | |
| 5261 static HObjectAccess ForField(Handle<Map> map, | |
| 5262 LookupResult *lookup, Handle<String> name = Handle<String>::null()); | |
| 5263 | |
| 5264 void PrintTo(StringStream* stream); | |
| 5265 | |
| 5266 protected: | |
| 5267 void SetGVNFlags(HValue *instr, bool is_store); | |
| 5268 | |
| 5269 private: | |
| 5270 // internal use only; different parts of an object or array | |
| 5271 enum Portion { | |
| 5272 kMaps, // map of an object | |
| 5273 kArrayLengths, // the length of an array | |
| 5274 kElementsPointer, // elements pointer | |
| 5275 kBackingStore, // some field in the backing store | |
| 5276 kInobject // some other in-object field | |
| 5277 }; | |
| 5278 | |
| 5279 HObjectAccess(Portion portion, int offset, | |
| 5280 Handle<String> name = Handle<String>::null()) | |
| 5281 : portion_(portion), offset_(offset), name_(name) { | |
| 5282 ASSERT(offset_ == offset); // offset must fit | |
| 5283 ASSERT(portion_ == portion); // portion must fit | |
| 5284 } | |
| 5285 | |
| 5286 unsigned portion_ : 3; | |
|
danno
2013/05/14 14:41:58
Can't you just make this "Portion" instead of unsi
| |
| 5287 unsigned offset_ : 29; | |
| 5288 Handle<String> name_; | |
| 5289 | |
| 5290 friend class HLoadNamedField; | |
| 5291 friend class HStoreNamedField; | |
| 5292 }; | |
| 5293 | |
| 5294 | |
| 5204 class HLoadNamedField: public HTemplateInstruction<2> { | 5295 class HLoadNamedField: public HTemplateInstruction<2> { |
| 5205 public: | 5296 public: |
| 5206 HLoadNamedField(HValue* object, bool is_in_object, | 5297 HLoadNamedField(HValue* object, |
| 5207 Representation field_representation, | 5298 HObjectAccess access, |
| 5208 int offset, HValue* typecheck = NULL) | 5299 HValue* typecheck = NULL, |
| 5209 : is_in_object_(is_in_object), | 5300 Representation field_representation |
| 5210 field_representation_(field_representation), | 5301 = Representation::Tagged()) |
| 5211 offset_(offset) { | 5302 : access_(access), |
| 5303 field_representation_(field_representation) { | |
| 5212 ASSERT(object != NULL); | 5304 ASSERT(object != NULL); |
| 5213 SetOperandAt(0, object); | 5305 SetOperandAt(0, object); |
| 5214 SetOperandAt(1, typecheck != NULL ? typecheck : object); | 5306 SetOperandAt(1, typecheck != NULL ? typecheck : object); |
| 5215 | 5307 |
| 5216 if (FLAG_track_fields && field_representation.IsSmi()) { | 5308 if (FLAG_track_fields && field_representation.IsSmi()) { |
| 5217 set_type(HType::Smi()); | 5309 set_type(HType::Smi()); |
| 5218 set_representation(Representation::Tagged()); | 5310 set_representation(Representation::Tagged()); |
| 5219 } else if (FLAG_track_double_fields && field_representation.IsDouble()) { | 5311 } else if (FLAG_track_double_fields && field_representation.IsDouble()) { |
| 5220 set_representation(field_representation); | 5312 set_representation(field_representation); |
| 5313 SetGVNFlag(kDependsOnDoubleFields); | |
|
danno
2013/05/14 14:41:58
Yikes! Don't you want to only set this inside SetG
| |
| 5221 } else { | 5314 } else { |
| 5222 set_representation(Representation::Tagged()); | 5315 set_representation(Representation::Tagged()); |
| 5223 } | 5316 } |
| 5224 SetFlag(kUseGVN); | 5317 access.SetGVNFlags(this, false); |
| 5225 if (FLAG_track_double_fields && representation().IsDouble()) { | |
| 5226 ASSERT(is_in_object); | |
| 5227 ASSERT(offset == HeapNumber::kValueOffset); | |
| 5228 SetGVNFlag(kDependsOnDoubleFields); | |
| 5229 } else if (is_in_object) { | |
| 5230 SetGVNFlag(kDependsOnInobjectFields); | |
| 5231 SetGVNFlag(kDependsOnMaps); | |
| 5232 } else { | |
| 5233 SetGVNFlag(kDependsOnBackingStoreFields); | |
| 5234 SetGVNFlag(kDependsOnMaps); | |
| 5235 } | |
| 5236 } | |
| 5237 | |
| 5238 static HLoadNamedField* NewArrayLength(Zone* zone, HValue* object, | |
| 5239 HValue* typecheck, | |
| 5240 HType type = HType::Tagged()) { | |
| 5241 Representation representation = | |
| 5242 type.IsSmi() ? Representation::Smi() : Representation::Tagged(); | |
| 5243 HLoadNamedField* result = new(zone) HLoadNamedField( | |
| 5244 object, true, representation, JSArray::kLengthOffset, typecheck); | |
| 5245 result->set_type(type); | |
| 5246 result->SetGVNFlag(kDependsOnArrayLengths); | |
| 5247 result->ClearGVNFlag(kDependsOnInobjectFields); | |
| 5248 return result; | |
| 5249 } | 5318 } |
| 5250 | 5319 |
| 5251 HValue* object() { return OperandAt(0); } | 5320 HValue* object() { return OperandAt(0); } |
| 5252 HValue* typecheck() { | 5321 HValue* typecheck() { |
| 5253 ASSERT(HasTypeCheck()); | 5322 ASSERT(HasTypeCheck()); |
| 5254 return OperandAt(1); | 5323 return OperandAt(1); |
| 5255 } | 5324 } |
| 5256 | 5325 |
| 5257 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } | 5326 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } |
| 5258 bool is_in_object() const { return is_in_object_; } | 5327 HObjectAccess access() const { return access_; } |
| 5328 bool is_in_object() const { return access_.IsInobject(); } | |
| 5259 Representation field_representation() const { return representation_; } | 5329 Representation field_representation() const { return representation_; } |
| 5260 int offset() const { return offset_; } | 5330 int offset() const { return access_.offset(); } |
| 5261 | 5331 |
| 5262 virtual Representation RequiredInputRepresentation(int index) { | 5332 virtual Representation RequiredInputRepresentation(int index) { |
| 5263 return Representation::Tagged(); | 5333 return Representation::Tagged(); |
| 5264 } | 5334 } |
| 5265 virtual void PrintDataTo(StringStream* stream); | 5335 virtual void PrintDataTo(StringStream* stream); |
| 5266 | 5336 |
| 5267 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) | 5337 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) |
| 5268 | 5338 |
| 5269 protected: | 5339 protected: |
| 5270 virtual bool DataEquals(HValue* other) { | 5340 virtual bool DataEquals(HValue* other) { |
| 5271 HLoadNamedField* b = HLoadNamedField::cast(other); | 5341 HLoadNamedField* b = HLoadNamedField::cast(other); |
| 5272 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_; | 5342 return is_in_object() == b->is_in_object() && offset() == b->offset(); |
| 5273 } | 5343 } |
| 5274 | 5344 |
| 5275 private: | 5345 private: |
| 5276 virtual bool IsDeletable() const { return true; } | 5346 virtual bool IsDeletable() const { return true; } |
| 5277 | 5347 |
| 5278 bool is_in_object_; | 5348 HObjectAccess access_; |
| 5279 Representation field_representation_; | 5349 Representation field_representation_; |
| 5280 int offset_; | |
| 5281 }; | 5350 }; |
| 5282 | 5351 |
| 5283 | 5352 |
| 5284 class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> { | 5353 class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> { |
| 5285 public: | 5354 public: |
| 5286 HLoadNamedFieldPolymorphic(HValue* context, | 5355 HLoadNamedFieldPolymorphic(HValue* context, |
| 5287 HValue* object, | 5356 HValue* object, |
| 5288 SmallMapList* types, | 5357 SmallMapList* types, |
| 5289 Handle<String> name, | 5358 Handle<String> name, |
| 5290 Zone* zone); | 5359 Zone* zone); |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5564 | 5633 |
| 5565 virtual HValue* Canonicalize(); | 5634 virtual HValue* Canonicalize(); |
| 5566 | 5635 |
| 5567 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric) | 5636 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric) |
| 5568 }; | 5637 }; |
| 5569 | 5638 |
| 5570 | 5639 |
| 5571 class HStoreNamedField: public HTemplateInstruction<2> { | 5640 class HStoreNamedField: public HTemplateInstruction<2> { |
| 5572 public: | 5641 public: |
| 5573 HStoreNamedField(HValue* obj, | 5642 HStoreNamedField(HValue* obj, |
| 5574 Handle<Name> name, | 5643 HObjectAccess access, |
| 5575 HValue* val, | 5644 HValue* val, |
| 5576 bool in_object, | 5645 Representation field_representation |
| 5577 Representation field_representation, | 5646 = Representation::Tagged()) |
| 5578 int offset) | 5647 : access_(access), |
| 5579 : name_(name), | |
| 5580 is_in_object_(in_object), | |
| 5581 field_representation_(field_representation), | 5648 field_representation_(field_representation), |
| 5582 offset_(offset), | |
| 5583 transition_unique_id_(), | 5649 transition_unique_id_(), |
| 5584 new_space_dominator_(NULL) { | 5650 new_space_dominator_(NULL) { |
| 5585 SetOperandAt(0, obj); | 5651 SetOperandAt(0, obj); |
| 5586 SetOperandAt(1, val); | 5652 SetOperandAt(1, val); |
| 5587 SetFlag(kTrackSideEffectDominators); | 5653 access.SetGVNFlags(this, true); |
| 5588 if (FLAG_track_double_fields && field_representation.IsDouble()) { | 5654 if (FLAG_track_double_fields && field_representation.IsDouble()) { |
| 5589 SetGVNFlag(kChangesDoubleFields); | 5655 SetGVNFlag(kChangesDoubleFields); |
| 5590 } else if (is_in_object_) { | |
| 5591 SetGVNFlag(kChangesInobjectFields); | |
| 5592 SetGVNFlag(kDependsOnNewSpacePromotion); | |
| 5593 } else { | |
| 5594 SetGVNFlag(kChangesBackingStoreFields); | |
| 5595 SetGVNFlag(kDependsOnNewSpacePromotion); | |
| 5596 } | 5656 } |
| 5597 } | 5657 } |
| 5598 | 5658 |
| 5599 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) | 5659 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) |
| 5600 | 5660 |
| 5601 virtual Representation RequiredInputRepresentation(int index) { | 5661 virtual Representation RequiredInputRepresentation(int index) { |
| 5602 if (FLAG_track_double_fields && | 5662 if (FLAG_track_double_fields && |
| 5603 index == 1 && field_representation_.IsDouble()) { | 5663 index == 1 && field_representation_.IsDouble()) { |
| 5604 return field_representation_; | 5664 return field_representation_; |
| 5605 } else if (FLAG_track_fields && | 5665 } else if (FLAG_track_fields && |
| 5606 index == 1 && field_representation_.IsSmi()) { | 5666 index == 1 && field_representation_.IsSmi()) { |
| 5607 return Representation::Integer32(); | 5667 return Representation::Integer32(); |
| 5608 } | 5668 } |
| 5609 return Representation::Tagged(); | 5669 return Representation::Tagged(); |
| 5610 } | 5670 } |
| 5611 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) { | 5671 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) { |
| 5612 ASSERT(side_effect == kChangesNewSpacePromotion); | 5672 ASSERT(side_effect == kChangesNewSpacePromotion); |
| 5613 new_space_dominator_ = dominator; | 5673 new_space_dominator_ = dominator; |
| 5614 } | 5674 } |
| 5615 virtual void PrintDataTo(StringStream* stream); | 5675 virtual void PrintDataTo(StringStream* stream); |
| 5616 | 5676 |
| 5617 HValue* object() { return OperandAt(0); } | 5677 HValue* object() { return OperandAt(0); } |
| 5618 HValue* value() { return OperandAt(1); } | 5678 HValue* value() { return OperandAt(1); } |
| 5619 | 5679 |
| 5620 Handle<Name> name() const { return name_; } | 5680 HObjectAccess access() const { return access_; } |
| 5621 bool is_in_object() const { return is_in_object_; } | 5681 Handle<String> name() const { return access_.name(); } |
| 5622 int offset() const { return offset_; } | 5682 bool is_in_object() const { return access_.IsInobject(); } |
| 5683 int offset() const { return access_.offset(); } | |
| 5623 Handle<Map> transition() const { return transition_; } | 5684 Handle<Map> transition() const { return transition_; } |
| 5624 UniqueValueId transition_unique_id() const { return transition_unique_id_; } | 5685 UniqueValueId transition_unique_id() const { return transition_unique_id_; } |
| 5625 void set_transition(Handle<Map> map) { transition_ = map; } | 5686 void set_transition(Handle<Map> map) { transition_ = map; } |
| 5626 HValue* new_space_dominator() const { return new_space_dominator_; } | 5687 HValue* new_space_dominator() const { return new_space_dominator_; } |
| 5627 | 5688 |
| 5628 bool NeedsWriteBarrier() { | 5689 bool NeedsWriteBarrier() { |
| 5629 ASSERT(!(FLAG_track_double_fields && field_representation_.IsDouble()) || | 5690 ASSERT(!(FLAG_track_double_fields && field_representation_.IsDouble()) || |
| 5630 transition_.is_null()); | 5691 transition_.is_null()); |
| 5631 return (!FLAG_track_fields || !field_representation_.IsSmi()) && | 5692 return (!FLAG_track_fields || !field_representation_.IsSmi()) && |
| 5632 // If there is a transition, a new storage object needs to be allocated. | 5693 // If there is a transition, a new storage object needs to be allocated. |
| 5633 !(FLAG_track_double_fields && field_representation_.IsDouble()) && | 5694 !(FLAG_track_double_fields && field_representation_.IsDouble()) && |
| 5634 StoringValueNeedsWriteBarrier(value()) && | 5695 StoringValueNeedsWriteBarrier(value()) && |
| 5635 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); | 5696 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); |
| 5636 } | 5697 } |
| 5637 | 5698 |
| 5638 bool NeedsWriteBarrierForMap() { | 5699 bool NeedsWriteBarrierForMap() { |
| 5639 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); | 5700 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); |
| 5640 } | 5701 } |
| 5641 | 5702 |
| 5642 virtual void FinalizeUniqueValueId() { | 5703 virtual void FinalizeUniqueValueId() { |
| 5643 transition_unique_id_ = UniqueValueId(transition_); | 5704 transition_unique_id_ = UniqueValueId(transition_); |
| 5644 } | 5705 } |
| 5645 | 5706 |
| 5646 Representation field_representation() const { | 5707 Representation field_representation() const { |
| 5647 return field_representation_; | 5708 return field_representation_; |
| 5648 } | 5709 } |
| 5649 | 5710 |
| 5650 private: | 5711 private: |
| 5651 Handle<Name> name_; | 5712 HObjectAccess access_; |
| 5652 bool is_in_object_; | |
| 5653 Representation field_representation_; | 5713 Representation field_representation_; |
| 5654 int offset_; | |
| 5655 Handle<Map> transition_; | 5714 Handle<Map> transition_; |
| 5656 UniqueValueId transition_unique_id_; | 5715 UniqueValueId transition_unique_id_; |
| 5657 HValue* new_space_dominator_; | 5716 HValue* new_space_dominator_; |
| 5658 }; | 5717 }; |
| 5659 | 5718 |
| 5660 | 5719 |
| 5661 class HStoreNamedGeneric: public HTemplateInstruction<3> { | 5720 class HStoreNamedGeneric: public HTemplateInstruction<3> { |
| 5662 public: | 5721 public: |
| 5663 HStoreNamedGeneric(HValue* context, | 5722 HStoreNamedGeneric(HValue* context, |
| 5664 HValue* object, | 5723 HValue* object, |
| (...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6462 virtual bool IsDeletable() const { return true; } | 6521 virtual bool IsDeletable() const { return true; } |
| 6463 }; | 6522 }; |
| 6464 | 6523 |
| 6465 | 6524 |
| 6466 #undef DECLARE_INSTRUCTION | 6525 #undef DECLARE_INSTRUCTION |
| 6467 #undef DECLARE_CONCRETE_INSTRUCTION | 6526 #undef DECLARE_CONCRETE_INSTRUCTION |
| 6468 | 6527 |
| 6469 } } // namespace v8::internal | 6528 } } // namespace v8::internal |
| 6470 | 6529 |
| 6471 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6530 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |