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 5203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5214 virtual void PrintDataTo(StringStream* stream); | 5214 virtual void PrintDataTo(StringStream* stream); |
5215 | 5215 |
5216 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot) | 5216 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot) |
5217 | 5217 |
5218 private: | 5218 private: |
5219 int slot_index_; | 5219 int slot_index_; |
5220 Mode mode_; | 5220 Mode mode_; |
5221 }; | 5221 }; |
5222 | 5222 |
5223 | 5223 |
5224 // Represents an access to a portion of an object, such as the map pointer, | |
5225 // array elements pointer, etc, but not accesses to array elements themselves. | |
5226 class HObjectAccess: public ZoneObject { | |
5227 public: | |
5228 // internal use only; different parts of an object or array | |
danno
2013/05/06 15:53:06
Can you please make the following enum protected/p
titzer
2013/05/07 17:51:03
Haha. Tried that. Can't do that because I can't ma
titzer
2013/05/07 17:54:30
Nevermind, moving it to a value object made this p
| |
5229 enum Portion { | |
5230 kMaps, // map of an object | |
5231 kArrayLengths, // the length of an array | |
5232 kElementsPointer, // elements pointer | |
5233 kBackingStore, // some field in the backing store | |
5234 kInobject // some other in-object field | |
5235 }; | |
5236 | |
5237 HObjectAccess(Portion portion, int offset, | |
danno
2013/05/06 15:53:06
This should be private.
titzer
2013/05/07 17:51:03
Wish I could do that, but I can't, for the same re
titzer
2013/05/07 17:54:30
Spoke too soon. Done.
| |
5238 Handle<String> name = Handle<String>::null()) | |
5239 : portion_(portion), offset_(offset), name_(name) { } | |
5240 | |
5241 inline bool IsInobject() { | |
danno
2013/05/06 15:53:06
Does IsInobject or offset have to be public?
titzer
2013/05/07 17:51:03
They are used in HandlePolymorphicNamedField to ch
| |
5242 return portion_ != kBackingStore; | |
5243 } | |
5244 | |
5245 inline int offset() { | |
5246 return offset_; | |
5247 } | |
5248 | |
5249 inline Handle<String> name() { | |
5250 return name_; | |
5251 } | |
5252 | |
5253 static HObjectAccess* ForElementsPointer(); | |
danno
2013/05/06 15:53:06
OK, you've convinced me. There is precidence elsew
| |
5254 static HObjectAccess* ForArrayLength(); | |
5255 static HObjectAccess* ForFixedArrayLength(); | |
5256 static HObjectAccess* ForMap(); | |
5257 | |
5258 // Create an access to a property in an object | |
5259 static HObjectAccess* ForInobjectOffset(Zone *zone, int offset, | |
5260 Handle<String> name = Handle<String>::null()); | |
5261 | |
5262 // Create a direct access for a given offset, not in an object | |
5263 static HObjectAccess* ForOffset(Zone *zone, int offset, | |
danno
2013/05/06 15:53:06
Roll ForInobjectOffset directly into this method.
| |
5264 Handle<String> name = Handle<String>::null()); | |
5265 | |
5266 // Create an access to a resolved field (in-object or backing store) | |
5267 static HObjectAccess* ForField(Zone *zone, Handle<Map> map, | |
5268 LookupResult *lookup, Handle<String> name = Handle<String>::null()); | |
5269 | |
5270 protected: | |
5271 void SetGVNFlags(HValue *instr, bool is_store); | |
5272 | |
5273 private: | |
5274 Portion portion_; | |
danno
2013/05/06 15:53:06
Please put these together into a bit field,
int po
titzer
2013/05/07 17:51:03
Done.
| |
5275 int offset_; | |
5276 Handle<String> name_; | |
5277 | |
5278 friend class HLoadNamedField; | |
5279 friend class HStoreNamedField; | |
5280 }; | |
5281 | |
5282 | |
5224 class HLoadNamedField: public HTemplateInstruction<2> { | 5283 class HLoadNamedField: public HTemplateInstruction<2> { |
5225 public: | 5284 public: |
5226 HLoadNamedField(HValue* object, bool is_in_object, | 5285 HLoadNamedField(HValue* object, HObjectAccess *access, |
5227 Representation field_representation, | 5286 HValue* typecheck = NULL) |
5228 int offset, HValue* typecheck = NULL) | 5287 : access_(access), |
5229 : is_in_object_(is_in_object), | 5288 field_representation_(Representation::Tagged()) { |
5230 field_representation_(field_representation), | |
5231 offset_(offset) { | |
5232 ASSERT(object != NULL); | 5289 ASSERT(object != NULL); |
5233 SetOperandAt(0, object); | 5290 SetOperandAt(0, object); |
5234 SetOperandAt(1, typecheck != NULL ? typecheck : object); | 5291 SetOperandAt(1, typecheck != NULL ? typecheck : object); |
5235 | 5292 |
5236 if (FLAG_track_fields && field_representation.IsSmi()) { | 5293 set_representation(Representation::Tagged()); |
5237 set_type(HType::Smi()); | 5294 access->SetGVNFlags(this, false); |
5238 set_representation(Representation::Tagged()); | |
5239 } else if (FLAG_track_double_fields && field_representation.IsDouble()) { | |
5240 set_representation(field_representation); | |
5241 } else { | |
5242 set_representation(Representation::Tagged()); | |
5243 } | |
5244 SetFlag(kUseGVN); | |
5245 SetGVNFlag(kDependsOnMaps); | |
5246 if (is_in_object) { | |
5247 SetGVNFlag(kDependsOnInobjectFields); | |
5248 } else { | |
5249 SetGVNFlag(kDependsOnBackingStoreFields); | |
5250 } | |
5251 } | |
5252 | |
5253 static HLoadNamedField* NewArrayLength(Zone* zone, HValue* object, | |
5254 HValue* typecheck, | |
5255 HType type = HType::Tagged()) { | |
5256 Representation representation = | |
5257 type.IsSmi() ? Representation::Smi() : Representation::Tagged(); | |
5258 HLoadNamedField* result = new(zone) HLoadNamedField( | |
5259 object, true, representation, JSArray::kLengthOffset, typecheck); | |
5260 result->set_type(type); | |
5261 result->SetGVNFlag(kDependsOnArrayLengths); | |
5262 result->ClearGVNFlag(kDependsOnInobjectFields); | |
5263 return result; | |
5264 } | 5295 } |
5265 | 5296 |
5266 HValue* object() { return OperandAt(0); } | 5297 HValue* object() { return OperandAt(0); } |
5267 HValue* typecheck() { | 5298 HValue* typecheck() { |
5268 ASSERT(HasTypeCheck()); | 5299 ASSERT(HasTypeCheck()); |
5269 return OperandAt(1); | 5300 return OperandAt(1); |
5270 } | 5301 } |
5271 | 5302 |
5272 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } | 5303 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } |
5273 bool is_in_object() const { return is_in_object_; } | 5304 bool is_in_object() const { return access_->IsInobject(); } |
5274 Representation field_representation() const { return representation_; } | 5305 Representation field_representation() const { return representation_; } |
5275 int offset() const { return offset_; } | 5306 int offset() const { return access_->offset(); } |
5307 | |
5308 void set_field_representation(Representation representation) { | |
5309 field_representation_ = representation; | |
5310 } | |
5276 | 5311 |
5277 virtual Representation RequiredInputRepresentation(int index) { | 5312 virtual Representation RequiredInputRepresentation(int index) { |
5278 return Representation::Tagged(); | 5313 return Representation::Tagged(); |
5279 } | 5314 } |
5280 virtual void PrintDataTo(StringStream* stream); | 5315 virtual void PrintDataTo(StringStream* stream); |
5281 | 5316 |
5282 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) | 5317 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) |
5283 | 5318 |
5284 protected: | 5319 protected: |
5285 virtual bool DataEquals(HValue* other) { | 5320 virtual bool DataEquals(HValue* other) { |
5286 HLoadNamedField* b = HLoadNamedField::cast(other); | 5321 HLoadNamedField* b = HLoadNamedField::cast(other); |
5287 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_; | 5322 return is_in_object() == b->is_in_object() && offset() == b->offset(); |
5288 } | 5323 } |
5289 | 5324 |
5290 private: | 5325 private: |
5291 virtual bool IsDeletable() const { return true; } | 5326 virtual bool IsDeletable() const { return true; } |
5292 | 5327 |
5293 bool is_in_object_; | 5328 HObjectAccess* access_; |
5294 Representation field_representation_; | 5329 Representation field_representation_; |
5295 int offset_; | |
5296 }; | 5330 }; |
5297 | 5331 |
5298 | 5332 |
5299 class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> { | 5333 class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> { |
5300 public: | 5334 public: |
5301 HLoadNamedFieldPolymorphic(HValue* context, | 5335 HLoadNamedFieldPolymorphic(HValue* context, |
5302 HValue* object, | 5336 HValue* object, |
5303 SmallMapList* types, | 5337 SmallMapList* types, |
5304 Handle<String> name, | 5338 Handle<String> name, |
5305 Zone* zone); | 5339 Zone* zone); |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5579 | 5613 |
5580 virtual HValue* Canonicalize(); | 5614 virtual HValue* Canonicalize(); |
5581 | 5615 |
5582 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric) | 5616 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric) |
5583 }; | 5617 }; |
5584 | 5618 |
5585 | 5619 |
5586 class HStoreNamedField: public HTemplateInstruction<2> { | 5620 class HStoreNamedField: public HTemplateInstruction<2> { |
5587 public: | 5621 public: |
5588 HStoreNamedField(HValue* obj, | 5622 HStoreNamedField(HValue* obj, |
5589 Handle<String> name, | 5623 HObjectAccess* access, |
5590 HValue* val, | 5624 HValue* val) |
5591 bool in_object, | 5625 : access_(access), |
5592 Representation field_representation, | 5626 field_representation_(Representation::Tagged()), |
5593 int offset) | |
5594 : name_(name), | |
5595 is_in_object_(in_object), | |
5596 field_representation_(field_representation), | |
5597 offset_(offset), | |
5598 transition_unique_id_(), | 5627 transition_unique_id_(), |
5599 new_space_dominator_(NULL) { | 5628 new_space_dominator_(NULL) { |
5600 SetOperandAt(0, obj); | 5629 SetOperandAt(0, obj); |
5601 SetOperandAt(1, val); | 5630 SetOperandAt(1, val); |
5602 SetFlag(kTrackSideEffectDominators); | 5631 access->SetGVNFlags(this, true); |
5603 SetGVNFlag(kDependsOnNewSpacePromotion); | |
5604 if (is_in_object_) { | |
5605 SetGVNFlag(kChangesInobjectFields); | |
5606 } else { | |
5607 SetGVNFlag(kChangesBackingStoreFields); | |
5608 } | |
5609 } | 5632 } |
5610 | 5633 |
5611 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) | 5634 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) |
5612 | 5635 |
5613 virtual Representation RequiredInputRepresentation(int index) { | 5636 virtual Representation RequiredInputRepresentation(int index) { |
5614 if (FLAG_track_fields && index == 1 && field_representation_.IsSmi()) { | 5637 if (FLAG_track_fields && index == 1 && field_representation_.IsSmi()) { |
5615 return Representation::Integer32(); | 5638 return Representation::Integer32(); |
5616 } | 5639 } |
5617 return Representation::Tagged(); | 5640 return Representation::Tagged(); |
5618 } | 5641 } |
5619 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) { | 5642 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) { |
5620 ASSERT(side_effect == kChangesNewSpacePromotion); | 5643 ASSERT(side_effect == kChangesNewSpacePromotion); |
5621 new_space_dominator_ = dominator; | 5644 new_space_dominator_ = dominator; |
5622 } | 5645 } |
5623 virtual void PrintDataTo(StringStream* stream); | 5646 virtual void PrintDataTo(StringStream* stream); |
5624 | 5647 |
5625 HValue* object() { return OperandAt(0); } | 5648 HValue* object() { return OperandAt(0); } |
5626 HValue* value() { return OperandAt(1); } | 5649 HValue* value() { return OperandAt(1); } |
5627 | 5650 |
5628 Handle<String> name() const { return name_; } | 5651 Handle<String> name() const { return access_->name(); } |
5629 bool is_in_object() const { return is_in_object_; } | 5652 bool is_in_object() const { return access_->IsInobject(); } |
5630 int offset() const { return offset_; } | 5653 int offset() const { return access_->offset(); } |
5631 Handle<Map> transition() const { return transition_; } | 5654 Handle<Map> transition() const { return transition_; } |
5632 UniqueValueId transition_unique_id() const { return transition_unique_id_; } | 5655 UniqueValueId transition_unique_id() const { return transition_unique_id_; } |
5633 void set_transition(Handle<Map> map) { transition_ = map; } | 5656 void set_transition(Handle<Map> map) { transition_ = map; } |
5634 HValue* new_space_dominator() const { return new_space_dominator_; } | 5657 HValue* new_space_dominator() const { return new_space_dominator_; } |
5635 | 5658 |
5636 bool NeedsWriteBarrier() { | 5659 bool NeedsWriteBarrier() { |
5637 return (!FLAG_track_fields || !field_representation_.IsSmi()) && | 5660 return (!FLAG_track_fields || !field_representation_.IsSmi()) && |
5638 StoringValueNeedsWriteBarrier(value()) && | 5661 StoringValueNeedsWriteBarrier(value()) && |
5639 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); | 5662 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); |
5640 } | 5663 } |
5641 | 5664 |
5642 bool NeedsWriteBarrierForMap() { | 5665 bool NeedsWriteBarrierForMap() { |
5643 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); | 5666 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); |
5644 } | 5667 } |
5645 | 5668 |
5646 virtual void FinalizeUniqueValueId() { | 5669 virtual void FinalizeUniqueValueId() { |
5647 transition_unique_id_ = UniqueValueId(transition_); | 5670 transition_unique_id_ = UniqueValueId(transition_); |
5648 } | 5671 } |
5649 | 5672 |
5673 void set_field_representation(Representation representation) { | |
5674 field_representation_ = representation; | |
5675 } | |
5676 | |
5650 Representation field_representation() const { | 5677 Representation field_representation() const { |
5651 return field_representation_; | 5678 return field_representation_; |
5652 } | 5679 } |
5653 | 5680 |
5654 private: | 5681 private: |
5655 Handle<String> name_; | 5682 HObjectAccess* access_; |
5656 bool is_in_object_; | |
5657 Representation field_representation_; | 5683 Representation field_representation_; |
5658 int offset_; | |
5659 Handle<Map> transition_; | 5684 Handle<Map> transition_; |
5660 UniqueValueId transition_unique_id_; | 5685 UniqueValueId transition_unique_id_; |
5661 HValue* new_space_dominator_; | 5686 HValue* new_space_dominator_; |
5662 }; | 5687 }; |
5663 | 5688 |
5664 | 5689 |
5665 class HStoreNamedGeneric: public HTemplateInstruction<3> { | 5690 class HStoreNamedGeneric: public HTemplateInstruction<3> { |
5666 public: | 5691 public: |
5667 HStoreNamedGeneric(HValue* context, | 5692 HStoreNamedGeneric(HValue* context, |
5668 HValue* object, | 5693 HValue* object, |
(...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6557 virtual bool IsDeletable() const { return true; } | 6582 virtual bool IsDeletable() const { return true; } |
6558 }; | 6583 }; |
6559 | 6584 |
6560 | 6585 |
6561 #undef DECLARE_INSTRUCTION | 6586 #undef DECLARE_INSTRUCTION |
6562 #undef DECLARE_CONCRETE_INSTRUCTION | 6587 #undef DECLARE_CONCRETE_INSTRUCTION |
6563 | 6588 |
6564 } } // namespace v8::internal | 6589 } } // namespace v8::internal |
6565 | 6590 |
6566 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6591 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |