Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(224)

Side by Side Diff: src/hydrogen-instructions.h

Issue 14284010: Introduce HObjectAccess, which is used by LoadNamedField and StoreNamedField to denote what parts (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Use BitField utility instead of C-language bitfield for portion and offset in HObjectAccess. Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 V(WrapReceiver) 196 V(WrapReceiver)
197 197
198 #define GVN_TRACKED_FLAG_LIST(V) \ 198 #define GVN_TRACKED_FLAG_LIST(V) \
199 V(Maps) \ 199 V(Maps) \
200 V(NewSpacePromotion) 200 V(NewSpacePromotion)
201 201
202 #define GVN_UNTRACKED_FLAG_LIST(V) \ 202 #define GVN_UNTRACKED_FLAG_LIST(V) \
203 V(Calls) \ 203 V(Calls) \
204 V(InobjectFields) \ 204 V(InobjectFields) \
205 V(BackingStoreFields) \ 205 V(BackingStoreFields) \
206 V(DoubleFields) \
207 V(ElementsKind) \ 206 V(ElementsKind) \
208 V(ElementsPointer) \ 207 V(ElementsPointer) \
209 V(ArrayElements) \ 208 V(ArrayElements) \
210 V(DoubleArrayElements) \ 209 V(DoubleArrayElements) \
211 V(SpecializedArrayElements) \ 210 V(SpecializedArrayElements) \
212 V(GlobalVars) \ 211 V(GlobalVars) \
213 V(ArrayLengths) \ 212 V(ArrayLengths) \
214 V(ContextSlots) \ 213 V(ContextSlots) \
215 V(OsrEntries) 214 V(OsrEntries)
216 215
(...skipping 4959 matching lines...) Expand 10 before | Expand all | Expand 10 after
5176 virtual void PrintDataTo(StringStream* stream); 5175 virtual void PrintDataTo(StringStream* stream);
5177 5176
5178 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot) 5177 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
5179 5178
5180 private: 5179 private:
5181 int slot_index_; 5180 int slot_index_;
5182 Mode mode_; 5181 Mode mode_;
5183 }; 5182 };
5184 5183
5185 5184
5185 // Represents an access to a portion of an object, such as the map pointer,
5186 // array elements pointer, etc, but not accesses to array elements themselves.
5187 class HObjectAccess {
5188 public:
5189 inline bool IsInobject() const {
5190 return portion() != kBackingStore;
5191 }
5192
5193 inline int offset() const {
5194 return OffsetField::decode(value_);
5195 }
5196
5197 inline Handle<String> name() const {
5198 return name_;
5199 }
5200
5201 static HObjectAccess ForHeapNumberValue() {
5202 return HObjectAccess(kInobject, HeapNumber::kValueOffset);
5203 }
5204
5205 static HObjectAccess ForElementsPointer() {
5206 return HObjectAccess(kElementsPointer, JSObject::kElementsOffset);
5207 }
5208
5209 static HObjectAccess ForArrayLength() {
5210 return HObjectAccess(kArrayLengths, JSArray::kLengthOffset);
5211 }
5212
5213 static HObjectAccess ForFixedArrayLength() {
5214 return HObjectAccess(kArrayLengths, FixedArray::kLengthOffset);
5215 }
5216
5217 static HObjectAccess ForPropertiesPointer() {
5218 return HObjectAccess(kInobject, JSObject::kPropertiesOffset);
5219 }
5220
5221 static HObjectAccess ForMap() {
5222 return HObjectAccess(kMaps, JSObject::kMapOffset);
5223 }
5224
5225 static HObjectAccess ForAllocationSitePayload() {
5226 return HObjectAccess(kInobject, AllocationSiteInfo::kPayloadOffset);
5227 }
5228
5229 // Create an access to an offset in a fixed array header.
5230 static HObjectAccess ForFixedArrayHeader(int offset);
5231
5232 // Create an access to an in-object property in a JSObject.
5233 static HObjectAccess ForJSObjectOffset(int offset);
5234
5235 // Create an access to an in-object property in a JSArray.
5236 static HObjectAccess ForJSArrayOffset(int offset);
5237
5238 // Create an access to the backing store of an object.
5239 static HObjectAccess ForBackingStoreOffset(int offset);
5240
5241 // Create an access to a resolved field (in-object or backing store).
5242 static HObjectAccess ForField(Handle<Map> map,
5243 LookupResult *lookup, Handle<String> name = Handle<String>::null());
5244
5245 void PrintTo(StringStream* stream);
5246
5247 protected:
5248 void SetGVNFlags(HValue *instr, bool is_store);
5249
5250 private:
5251 // internal use only; different parts of an object or array
5252 enum Portion {
5253 kMaps, // map of an object
5254 kArrayLengths, // the length of an array
5255 kElementsPointer, // elements pointer
5256 kBackingStore, // some field in the backing store
5257 kInobject // some other in-object field
5258 };
5259
5260 HObjectAccess(Portion portion, int offset,
5261 Handle<String> name = Handle<String>::null())
5262 : value_(PortionField::encode(portion) | OffsetField::encode(offset)),
5263 name_(name) {
5264 ASSERT(this->offset() == offset); // offset should decode correctly
5265 ASSERT(this->portion() == portion); // portion should decode correctly
5266 }
5267
5268 class PortionField : public BitField<Portion, 0, 3> {};
5269 class OffsetField : public BitField<int, 3, 29> {};
5270
5271 uint32_t value_; // encodes both portion and offset
5272 Handle<String> name_;
5273
5274 friend class HLoadNamedField;
5275 friend class HStoreNamedField;
5276
5277 inline Portion portion() const {
5278 return PortionField::decode(value_);
5279 }
5280 };
5281
5282
5186 class HLoadNamedField: public HTemplateInstruction<2> { 5283 class HLoadNamedField: public HTemplateInstruction<2> {
5187 public: 5284 public:
5188 HLoadNamedField(HValue* object, bool is_in_object, 5285 HLoadNamedField(HValue* object,
5189 Representation field_representation, 5286 HObjectAccess access,
5190 int offset, HValue* typecheck = NULL) 5287 HValue* typecheck = NULL,
5191 : is_in_object_(is_in_object), 5288 Representation field_representation
5192 field_representation_(field_representation), 5289 = Representation::Tagged())
5193 offset_(offset) { 5290 : access_(access),
5291 field_representation_(field_representation) {
5194 ASSERT(object != NULL); 5292 ASSERT(object != NULL);
5195 SetOperandAt(0, object); 5293 SetOperandAt(0, object);
5196 SetOperandAt(1, typecheck != NULL ? typecheck : object); 5294 SetOperandAt(1, typecheck != NULL ? typecheck : object);
5197 5295
5198 if (FLAG_track_fields && field_representation.IsSmi()) { 5296 if (FLAG_track_fields && field_representation.IsSmi()) {
5199 set_type(HType::Smi()); 5297 set_type(HType::Smi());
5200 set_representation(Representation::Tagged()); 5298 set_representation(Representation::Tagged());
5201 } else if (FLAG_track_double_fields && field_representation.IsDouble()) { 5299 } else if (FLAG_track_double_fields && field_representation.IsDouble()) {
5202 set_representation(field_representation); 5300 set_representation(field_representation);
5203 } else if (FLAG_track_heap_object_fields && 5301 } else if (FLAG_track_heap_object_fields &&
5204 field_representation.IsHeapObject()) { 5302 field_representation.IsHeapObject()) {
5205 set_type(HType::NonPrimitive()); 5303 set_type(HType::NonPrimitive());
5206 set_representation(Representation::Tagged()); 5304 set_representation(Representation::Tagged());
5207 } else { 5305 } else {
5208 set_representation(Representation::Tagged()); 5306 set_representation(Representation::Tagged());
5209 } 5307 }
5210 SetFlag(kUseGVN); 5308 access.SetGVNFlags(this, false);
5211 if (FLAG_track_double_fields && representation().IsDouble()) {
5212 ASSERT(is_in_object);
5213 ASSERT(offset == HeapNumber::kValueOffset);
5214 SetGVNFlag(kDependsOnDoubleFields);
5215 } else if (is_in_object) {
5216 SetGVNFlag(kDependsOnInobjectFields);
5217 SetGVNFlag(kDependsOnMaps);
5218 } else {
5219 SetGVNFlag(kDependsOnBackingStoreFields);
5220 SetGVNFlag(kDependsOnMaps);
5221 }
5222 }
5223
5224 static HLoadNamedField* NewArrayLength(Zone* zone, HValue* object,
5225 HValue* typecheck,
5226 HType type = HType::Tagged()) {
5227 Representation representation =
5228 type.IsSmi() ? Representation::Smi() : Representation::Tagged();
5229 HLoadNamedField* result = new(zone) HLoadNamedField(
5230 object, true, representation, JSArray::kLengthOffset, typecheck);
5231 result->set_type(type);
5232 result->SetGVNFlag(kDependsOnArrayLengths);
5233 result->ClearGVNFlag(kDependsOnInobjectFields);
5234 return result;
5235 } 5309 }
5236 5310
5237 HValue* object() { return OperandAt(0); } 5311 HValue* object() { return OperandAt(0); }
5238 HValue* typecheck() { 5312 HValue* typecheck() {
5239 ASSERT(HasTypeCheck()); 5313 ASSERT(HasTypeCheck());
5240 return OperandAt(1); 5314 return OperandAt(1);
5241 } 5315 }
5242 5316
5243 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } 5317 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
5244 bool is_in_object() const { return is_in_object_; } 5318 HObjectAccess access() const { return access_; }
5319 bool is_in_object() const { return access_.IsInobject(); }
5245 Representation field_representation() const { return representation_; } 5320 Representation field_representation() const { return representation_; }
5246 int offset() const { return offset_; } 5321 int offset() const { return access_.offset(); }
5247 5322
5248 virtual Representation RequiredInputRepresentation(int index) { 5323 virtual Representation RequiredInputRepresentation(int index) {
5249 return Representation::Tagged(); 5324 return Representation::Tagged();
5250 } 5325 }
5251 virtual void PrintDataTo(StringStream* stream); 5326 virtual void PrintDataTo(StringStream* stream);
5252 5327
5253 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) 5328 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
5254 5329
5255 protected: 5330 protected:
5256 virtual bool DataEquals(HValue* other) { 5331 virtual bool DataEquals(HValue* other) {
5257 HLoadNamedField* b = HLoadNamedField::cast(other); 5332 HLoadNamedField* b = HLoadNamedField::cast(other);
5258 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_; 5333 return is_in_object() == b->is_in_object() && offset() == b->offset();
5259 } 5334 }
5260 5335
5261 private: 5336 private:
5262 virtual bool IsDeletable() const { return true; } 5337 virtual bool IsDeletable() const { return true; }
5263 5338
5264 bool is_in_object_; 5339 HObjectAccess access_;
5265 Representation field_representation_; 5340 Representation field_representation_;
5266 int offset_;
5267 }; 5341 };
5268 5342
5269 5343
5270 class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> { 5344 class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
5271 public: 5345 public:
5272 HLoadNamedFieldPolymorphic(HValue* context, 5346 HLoadNamedFieldPolymorphic(HValue* context,
5273 HValue* object, 5347 HValue* object,
5274 SmallMapList* types, 5348 SmallMapList* types,
5275 Handle<String> name, 5349 Handle<String> name,
5276 Zone* zone); 5350 Zone* zone);
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
5551 5625
5552 virtual HValue* Canonicalize(); 5626 virtual HValue* Canonicalize();
5553 5627
5554 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric) 5628 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
5555 }; 5629 };
5556 5630
5557 5631
5558 class HStoreNamedField: public HTemplateInstruction<2> { 5632 class HStoreNamedField: public HTemplateInstruction<2> {
5559 public: 5633 public:
5560 HStoreNamedField(HValue* obj, 5634 HStoreNamedField(HValue* obj,
5561 Handle<Name> name, 5635 HObjectAccess access,
5562 HValue* val, 5636 HValue* val,
5563 bool in_object, 5637 Representation field_representation
5564 Representation field_representation, 5638 = Representation::Tagged())
5565 int offset) 5639 : access_(access),
5566 : name_(name),
5567 is_in_object_(in_object),
5568 field_representation_(field_representation), 5640 field_representation_(field_representation),
5569 offset_(offset),
5570 transition_unique_id_(), 5641 transition_unique_id_(),
5571 new_space_dominator_(NULL) { 5642 new_space_dominator_(NULL) {
5572 SetOperandAt(0, obj); 5643 SetOperandAt(0, obj);
5573 SetOperandAt(1, val); 5644 SetOperandAt(1, val);
5574 SetFlag(kTrackSideEffectDominators); 5645 access.SetGVNFlags(this, true);
5575 if (FLAG_track_double_fields && field_representation.IsDouble()) {
5576 SetGVNFlag(kChangesDoubleFields);
5577 } else if (is_in_object_) {
5578 SetGVNFlag(kChangesInobjectFields);
5579 SetGVNFlag(kDependsOnNewSpacePromotion);
5580 } else {
5581 SetGVNFlag(kChangesBackingStoreFields);
5582 SetGVNFlag(kDependsOnNewSpacePromotion);
5583 }
5584 } 5646 }
5585 5647
5586 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) 5648 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
5587 5649
5588 virtual Representation RequiredInputRepresentation(int index) { 5650 virtual Representation RequiredInputRepresentation(int index) {
5589 if (FLAG_track_double_fields && 5651 if (FLAG_track_double_fields &&
5590 index == 1 && field_representation_.IsDouble()) { 5652 index == 1 && field_representation_.IsDouble()) {
5591 return field_representation_; 5653 return field_representation_;
5592 } else if (FLAG_track_fields && 5654 } else if (FLAG_track_fields &&
5593 index == 1 && field_representation_.IsSmi()) { 5655 index == 1 && field_representation_.IsSmi()) {
5594 return Representation::Integer32(); 5656 return Representation::Integer32();
5595 } 5657 }
5596 return Representation::Tagged(); 5658 return Representation::Tagged();
5597 } 5659 }
5598 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) { 5660 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) {
5599 ASSERT(side_effect == kChangesNewSpacePromotion); 5661 ASSERT(side_effect == kChangesNewSpacePromotion);
5600 new_space_dominator_ = dominator; 5662 new_space_dominator_ = dominator;
5601 } 5663 }
5602 virtual void PrintDataTo(StringStream* stream); 5664 virtual void PrintDataTo(StringStream* stream);
5603 5665
5604 HValue* object() { return OperandAt(0); } 5666 HValue* object() { return OperandAt(0); }
5605 HValue* value() { return OperandAt(1); } 5667 HValue* value() { return OperandAt(1); }
5606 5668
5607 Handle<Name> name() const { return name_; } 5669 HObjectAccess access() const { return access_; }
5608 bool is_in_object() const { return is_in_object_; } 5670 Handle<String> name() const { return access_.name(); }
5609 int offset() const { return offset_; } 5671 bool is_in_object() const { return access_.IsInobject(); }
5672 int offset() const { return access_.offset(); }
5610 Handle<Map> transition() const { return transition_; } 5673 Handle<Map> transition() const { return transition_; }
5611 UniqueValueId transition_unique_id() const { return transition_unique_id_; } 5674 UniqueValueId transition_unique_id() const { return transition_unique_id_; }
5612 void set_transition(Handle<Map> map) { transition_ = map; } 5675 void set_transition(Handle<Map> map) { transition_ = map; }
5613 HValue* new_space_dominator() const { return new_space_dominator_; } 5676 HValue* new_space_dominator() const { return new_space_dominator_; }
5614 5677
5615 bool NeedsWriteBarrier() { 5678 bool NeedsWriteBarrier() {
5616 ASSERT(!(FLAG_track_double_fields && field_representation_.IsDouble()) || 5679 ASSERT(!(FLAG_track_double_fields && field_representation_.IsDouble()) ||
5617 transition_.is_null()); 5680 transition_.is_null());
5618 return (!FLAG_track_fields || !field_representation_.IsSmi()) && 5681 return (!FLAG_track_fields || !field_representation_.IsSmi()) &&
5619 // If there is a transition, a new storage object needs to be allocated. 5682 // If there is a transition, a new storage object needs to be allocated.
5620 !(FLAG_track_double_fields && field_representation_.IsDouble()) && 5683 !(FLAG_track_double_fields && field_representation_.IsDouble()) &&
5621 StoringValueNeedsWriteBarrier(value()) && 5684 StoringValueNeedsWriteBarrier(value()) &&
5622 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); 5685 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
5623 } 5686 }
5624 5687
5625 bool NeedsWriteBarrierForMap() { 5688 bool NeedsWriteBarrierForMap() {
5626 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); 5689 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
5627 } 5690 }
5628 5691
5629 virtual void FinalizeUniqueValueId() { 5692 virtual void FinalizeUniqueValueId() {
5630 transition_unique_id_ = UniqueValueId(transition_); 5693 transition_unique_id_ = UniqueValueId(transition_);
5631 } 5694 }
5632 5695
5633 Representation field_representation() const { 5696 Representation field_representation() const {
5634 return field_representation_; 5697 return field_representation_;
5635 } 5698 }
5636 5699
5637 private: 5700 private:
5638 Handle<Name> name_; 5701 HObjectAccess access_;
5639 bool is_in_object_;
5640 Representation field_representation_; 5702 Representation field_representation_;
5641 int offset_;
5642 Handle<Map> transition_; 5703 Handle<Map> transition_;
5643 UniqueValueId transition_unique_id_; 5704 UniqueValueId transition_unique_id_;
5644 HValue* new_space_dominator_; 5705 HValue* new_space_dominator_;
5645 }; 5706 };
5646 5707
5647 5708
5648 class HStoreNamedGeneric: public HTemplateInstruction<3> { 5709 class HStoreNamedGeneric: public HTemplateInstruction<3> {
5649 public: 5710 public:
5650 HStoreNamedGeneric(HValue* context, 5711 HStoreNamedGeneric(HValue* context,
5651 HValue* object, 5712 HValue* object,
(...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after
6449 virtual bool IsDeletable() const { return true; } 6510 virtual bool IsDeletable() const { return true; }
6450 }; 6511 };
6451 6512
6452 6513
6453 #undef DECLARE_INSTRUCTION 6514 #undef DECLARE_INSTRUCTION
6454 #undef DECLARE_CONCRETE_INSTRUCTION 6515 #undef DECLARE_CONCRETE_INSTRUCTION
6455 6516
6456 } } // namespace v8::internal 6517 } } // namespace v8::internal
6457 6518
6458 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 6519 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698