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

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

Issue 324093002: ARM/ARM64: Optimise HLoadNamedField and HStoreNamedField. Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Upload the correct patch (minor diff in hydrogen.h) Created 6 years, 6 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.h ('k') | no next file » | 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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_HYDROGEN_INSTRUCTIONS_H_ 5 #ifndef V8_HYDROGEN_INSTRUCTIONS_H_
6 #define V8_HYDROGEN_INSTRUCTIONS_H_ 6 #define V8_HYDROGEN_INSTRUCTIONS_H_
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/allocation.h" 10 #include "src/allocation.h"
(...skipping 1188 matching lines...) Expand 10 before | Expand all | Expand 10 after
1199 HInstruction* previous_; 1199 HInstruction* previous_;
1200 HPositionInfo position_; 1200 HPositionInfo position_;
1201 1201
1202 friend class HBasicBlock; 1202 friend class HBasicBlock;
1203 }; 1203 };
1204 1204
1205 1205
1206 template<int V> 1206 template<int V>
1207 class HTemplateInstruction : public HInstruction { 1207 class HTemplateInstruction : public HInstruction {
1208 public: 1208 public:
1209 virtual int OperandCount() V8_FINAL V8_OVERRIDE { return V; } 1209 virtual int OperandCount() V8_OVERRIDE { return V; }
1210 virtual HValue* OperandAt(int i) const V8_FINAL V8_OVERRIDE { 1210 virtual HValue* OperandAt(int i) const V8_FINAL V8_OVERRIDE {
1211 return inputs_[i]; 1211 return inputs_[i];
1212 } 1212 }
1213 1213
1214 protected: 1214 protected:
1215 HTemplateInstruction(HType type = HType::Tagged()) : HInstruction(type) {} 1215 HTemplateInstruction(HType type = HType::Tagged()) : HInstruction(type) {}
1216 1216
1217 virtual void InternalSetOperandAt(int i, HValue* value) V8_FINAL V8_OVERRIDE { 1217 virtual void InternalSetOperandAt(int i, HValue* value) V8_FINAL V8_OVERRIDE {
1218 inputs_[i] = value; 1218 inputs_[i] = value;
1219 } 1219 }
(...skipping 4999 matching lines...) Expand 10 before | Expand all | Expand 10 after
6219 friend class HLoadNamedField; 6219 friend class HLoadNamedField;
6220 friend class HStoreNamedField; 6220 friend class HStoreNamedField;
6221 friend class SideEffectsTracker; 6221 friend class SideEffectsTracker;
6222 6222
6223 inline Portion portion() const { 6223 inline Portion portion() const {
6224 return PortionField::decode(value_); 6224 return PortionField::decode(value_);
6225 } 6225 }
6226 }; 6226 };
6227 6227
6228 6228
6229 class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> { 6229 class HLoadNamedField V8_FINAL : public HTemplateInstruction<3> {
6230 public: 6230 public:
6231 DECLARE_INSTRUCTION_FACTORY_P3(HLoadNamedField, HValue*, 6231 DECLARE_INSTRUCTION_FACTORY_P3(HLoadNamedField, HValue*,
6232 HValue*, HObjectAccess); 6232 HValue*, HObjectAccess);
6233 DECLARE_INSTRUCTION_FACTORY_P4(HLoadNamedField, HValue*,
6234 HValue*, HObjectAccess, HValue*);
6233 DECLARE_INSTRUCTION_FACTORY_P5(HLoadNamedField, HValue*, HValue*, 6235 DECLARE_INSTRUCTION_FACTORY_P5(HLoadNamedField, HValue*, HValue*,
6234 HObjectAccess, const UniqueSet<Map>*, HType); 6236 HObjectAccess, const UniqueSet<Map>*, HType);
6237 DECLARE_INSTRUCTION_FACTORY_P6(HLoadNamedField, HValue*, HValue*,
6238 HObjectAccess, const UniqueSet<Map>*, HType,
6239 HValue*);
6240
6241 virtual int OperandCount() V8_OVERRIDE {
6242 return (object_properties() != NULL) ? 3 : 2;
6243 }
6235 6244
6236 HValue* object() { return OperandAt(0); } 6245 HValue* object() { return OperandAt(0); }
6237 HValue* dependency() { 6246 HValue* dependency() {
6238 ASSERT(HasDependency()); 6247 ASSERT(HasDependency());
6239 return OperandAt(1); 6248 return OperandAt(1);
6240 } 6249 }
6241 bool HasDependency() const { return OperandAt(0) != OperandAt(1); } 6250 bool HasDependency() const { return OperandAt(0) != OperandAt(1); }
6251 HValue* object_properties() { return OperandAt(2); }
6242 HObjectAccess access() const { return access_; } 6252 HObjectAccess access() const { return access_; }
6243 Representation field_representation() const { 6253 Representation field_representation() const {
6244 return access_.representation(); 6254 return access_.representation();
6245 } 6255 }
6246 6256
6247 const UniqueSet<Map>* maps() const { return maps_; } 6257 const UniqueSet<Map>* maps() const { return maps_; }
6248 6258
6249 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } 6259 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; }
6250 virtual bool HasOutOfBoundsAccess(int size) V8_OVERRIDE { 6260 virtual bool HasOutOfBoundsAccess(int size) V8_OVERRIDE {
6251 return !access().IsInobject() || access().offset() >= size; 6261 return !access().IsInobject() || access().offset() >= size;
(...skipping 12 matching lines...) Expand all
6264 if (!CheckFlag(HValue::kCantBeReplaced)) return false; 6274 if (!CheckFlag(HValue::kCantBeReplaced)) return false;
6265 if (!type().Equals(other->type())) return false; 6275 if (!type().Equals(other->type())) return false;
6266 if (!representation().Equals(other->representation())) return false; 6276 if (!representation().Equals(other->representation())) return false;
6267 if (!other->IsLoadNamedField()) return true; 6277 if (!other->IsLoadNamedField()) return true;
6268 HLoadNamedField* that = HLoadNamedField::cast(other); 6278 HLoadNamedField* that = HLoadNamedField::cast(other);
6269 if (this->maps_ == that->maps_) return true; 6279 if (this->maps_ == that->maps_) return true;
6270 if (this->maps_ == NULL || that->maps_ == NULL) return false; 6280 if (this->maps_ == NULL || that->maps_ == NULL) return false;
6271 return this->maps_->IsSubset(that->maps_); 6281 return this->maps_->IsSubset(that->maps_);
6272 } 6282 }
6273 6283
6284 static bool PreferExtractLoadPropertiesPointer() {
6285 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64
6286 return true;
6287 #else
6288 return false;
6289 #endif
6290 }
6291 static bool NeedsPropertiesPointer(HObjectAccess access) {
6292 return !(access.IsExternalMemory() ||
6293 access.representation().IsDouble() ||
6294 access.IsInobject());
6295 }
6296
6274 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) 6297 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
6275 6298
6276 protected: 6299 protected:
6277 virtual bool DataEquals(HValue* other) V8_OVERRIDE { 6300 virtual bool DataEquals(HValue* other) V8_OVERRIDE {
6278 HLoadNamedField* that = HLoadNamedField::cast(other); 6301 HLoadNamedField* that = HLoadNamedField::cast(other);
6279 if (!this->access_.Equals(that->access_)) return false; 6302 if (!this->access_.Equals(that->access_)) return false;
6280 if (this->maps_ == that->maps_) return true; 6303 if (this->maps_ == that->maps_) return true;
6281 return (this->maps_ != NULL && 6304 return (this->maps_ != NULL &&
6282 that->maps_ != NULL && 6305 that->maps_ != NULL &&
6283 this->maps_->Equals(that->maps_)); 6306 this->maps_->Equals(that->maps_));
6284 } 6307 }
6285 6308
6286 private: 6309 private:
6287 HLoadNamedField(HValue* object, 6310 HLoadNamedField(HValue* object,
6288 HValue* dependency, 6311 HValue* dependency,
6289 HObjectAccess access) 6312 HObjectAccess access,
6313 HValue* object_properties = NULL)
6290 : access_(access), maps_(NULL) { 6314 : access_(access), maps_(NULL) {
6291 ASSERT_NOT_NULL(object); 6315 ASSERT_NOT_NULL(object);
6292 SetOperandAt(0, object); 6316 SetOperandAt(0, object);
6293 SetOperandAt(1, dependency ? dependency : object); 6317 SetOperandAt(1, dependency ? dependency : object);
6318 SetOperandAt(2, object_properties);
6294 6319
6295 Representation representation = access.representation(); 6320 Representation representation = access.representation();
6296 if (representation.IsInteger8() || 6321 if (representation.IsInteger8() ||
6297 representation.IsUInteger8() || 6322 representation.IsUInteger8() ||
6298 representation.IsInteger16() || 6323 representation.IsInteger16() ||
6299 representation.IsUInteger16()) { 6324 representation.IsUInteger16()) {
6300 set_representation(Representation::Integer32()); 6325 set_representation(Representation::Integer32());
6301 } else if (representation.IsSmi()) { 6326 } else if (representation.IsSmi()) {
6302 set_type(HType::Smi()); 6327 set_type(HType::Smi());
6303 if (SmiValuesAre32Bits()) { 6328 if (SmiValuesAre32Bits()) {
(...skipping 11 matching lines...) Expand all
6315 } else { 6340 } else {
6316 set_representation(Representation::Tagged()); 6341 set_representation(Representation::Tagged());
6317 } 6342 }
6318 access.SetGVNFlags(this, LOAD); 6343 access.SetGVNFlags(this, LOAD);
6319 } 6344 }
6320 6345
6321 HLoadNamedField(HValue* object, 6346 HLoadNamedField(HValue* object,
6322 HValue* dependency, 6347 HValue* dependency,
6323 HObjectAccess access, 6348 HObjectAccess access,
6324 const UniqueSet<Map>* maps, 6349 const UniqueSet<Map>* maps,
6325 HType type) 6350 HType type,
6326 : HTemplateInstruction<2>(type), access_(access), maps_(maps) { 6351 HValue* object_properties = NULL)
6352 : HTemplateInstruction<3>(type), access_(access), maps_(maps) {
6327 ASSERT_NOT_NULL(maps); 6353 ASSERT_NOT_NULL(maps);
6328 ASSERT_NE(0, maps->size()); 6354 ASSERT_NE(0, maps->size());
6329 6355
6330 ASSERT_NOT_NULL(object); 6356 ASSERT_NOT_NULL(object);
6331 SetOperandAt(0, object); 6357 SetOperandAt(0, object);
6332 SetOperandAt(1, dependency ? dependency : object); 6358 SetOperandAt(1, dependency ? dependency : object);
6359 SetOperandAt(2, object_properties);
6333 6360
6334 ASSERT(access.representation().IsHeapObject()); 6361 ASSERT(access.representation().IsHeapObject());
6335 ASSERT(type.IsHeapObject()); 6362 ASSERT(type.IsHeapObject());
6336 set_representation(Representation::Tagged()); 6363 set_representation(Representation::Tagged());
6337 6364
6338 access.SetGVNFlags(this, LOAD); 6365 access.SetGVNFlags(this, LOAD);
6339 } 6366 }
6340 6367
6341 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 6368 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
6342 6369
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
6650 // initialized or not. 6677 // initialized or not.
6651 enum StoreFieldOrKeyedMode { 6678 enum StoreFieldOrKeyedMode {
6652 // The entry could be either previously initialized or not. 6679 // The entry could be either previously initialized or not.
6653 INITIALIZING_STORE, 6680 INITIALIZING_STORE,
6654 // At the time of this store it is guaranteed that the entry is already 6681 // At the time of this store it is guaranteed that the entry is already
6655 // initialized. 6682 // initialized.
6656 STORE_TO_INITIALIZED_ENTRY 6683 STORE_TO_INITIALIZED_ENTRY
6657 }; 6684 };
6658 6685
6659 6686
6660 class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> { 6687 class HStoreNamedField V8_FINAL : public HTemplateInstruction<4> {
6661 public: 6688 public:
6662 DECLARE_INSTRUCTION_FACTORY_P3(HStoreNamedField, HValue*, 6689 DECLARE_INSTRUCTION_FACTORY_P3(HStoreNamedField, HValue*,
6663 HObjectAccess, HValue*); 6690 HObjectAccess, HValue*);
6664 DECLARE_INSTRUCTION_FACTORY_P4(HStoreNamedField, HValue*, 6691 DECLARE_INSTRUCTION_FACTORY_P4(HStoreNamedField, HValue*,
6665 HObjectAccess, HValue*, StoreFieldOrKeyedMode); 6692 HObjectAccess, HValue*, StoreFieldOrKeyedMode);
6693 DECLARE_INSTRUCTION_FACTORY_P5(HStoreNamedField, HValue*,
6694 HObjectAccess, HValue*, StoreFieldOrKeyedMode,
6695 HValue*);
6666 6696
6667 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) 6697 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
6668 6698
6699 virtual int OperandCount() V8_OVERRIDE {
6700 return (object_properties() != NULL) ? 4 : 3;
6701 }
6702
6669 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { 6703 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE {
6670 return index == 1; 6704 return index == 1;
6671 } 6705 }
6672 virtual bool HasOutOfBoundsAccess(int size) V8_OVERRIDE { 6706 virtual bool HasOutOfBoundsAccess(int size) V8_OVERRIDE {
6673 return !access().IsInobject() || access().offset() >= size; 6707 return !access().IsInobject() || access().offset() >= size;
6674 } 6708 }
6675 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 6709 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
6676 if (index == 0 && access().IsExternalMemory()) { 6710 if (index == 0 && access().IsExternalMemory()) {
6677 // object must be external in case of external memory access 6711 // object must be external in case of external memory access
6678 return Representation::External(); 6712 return Representation::External();
(...skipping 22 matching lines...) Expand all
6701 ASSERT(side_effect == kNewSpacePromotion); 6735 ASSERT(side_effect == kNewSpacePromotion);
6702 if (!FLAG_use_write_barrier_elimination) return false; 6736 if (!FLAG_use_write_barrier_elimination) return false;
6703 dominator_ = dominator; 6737 dominator_ = dominator;
6704 return false; 6738 return false;
6705 } 6739 }
6706 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 6740 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
6707 6741
6708 HValue* object() const { return OperandAt(0); } 6742 HValue* object() const { return OperandAt(0); }
6709 HValue* value() const { return OperandAt(1); } 6743 HValue* value() const { return OperandAt(1); }
6710 HValue* transition() const { return OperandAt(2); } 6744 HValue* transition() const { return OperandAt(2); }
6745 HValue* object_properties() { return OperandAt(3); }
6711 6746
6712 HObjectAccess access() const { return access_; } 6747 HObjectAccess access() const { return access_; }
6713 HValue* dominator() const { return dominator_; } 6748 HValue* dominator() const { return dominator_; }
6714 bool has_transition() const { return has_transition_; } 6749 bool has_transition() const { return has_transition_; }
6715 StoreFieldOrKeyedMode store_mode() const { return store_mode_; } 6750 StoreFieldOrKeyedMode store_mode() const { return store_mode_; }
6716 6751
6717 Handle<Map> transition_map() const { 6752 Handle<Map> transition_map() const {
6718 if (has_transition()) { 6753 if (has_transition()) {
6719 return Handle<Map>::cast( 6754 return Handle<Map>::cast(
6720 HConstant::cast(transition())->handle(Isolate::Current())); 6755 HConstant::cast(transition())->handle(Isolate::Current()));
(...skipping 17 matching lines...) Expand all
6738 if (field_representation().IsExternal()) return false; 6773 if (field_representation().IsExternal()) return false;
6739 return StoringValueNeedsWriteBarrier(value()) && 6774 return StoringValueNeedsWriteBarrier(value()) &&
6740 ReceiverObjectNeedsWriteBarrier(object(), value(), dominator()); 6775 ReceiverObjectNeedsWriteBarrier(object(), value(), dominator());
6741 } 6776 }
6742 6777
6743 bool NeedsWriteBarrierForMap() { 6778 bool NeedsWriteBarrierForMap() {
6744 return ReceiverObjectNeedsWriteBarrier(object(), transition(), 6779 return ReceiverObjectNeedsWriteBarrier(object(), transition(),
6745 dominator()); 6780 dominator());
6746 } 6781 }
6747 6782
6783 static bool PreferExtractLoadPropertiesPointer() {
6784 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64
6785 return true;
ulan 2014/06/12 13:39:18 Could you please port this to other architectures
6786 #else
6787 return false;
6788 #endif
6789 }
6790 static bool NeedsPropertiesPointer(HObjectAccess access) {
6791 return !(access.IsExternalMemory() ||
ulan 2014/06/12 13:39:18 This predicate should be part of HObjectAccess (if
6792 access.representation().IsDouble() ||
6793 access.IsInobject());
6794 }
6795
6748 SmiCheck SmiCheckForWriteBarrier() const { 6796 SmiCheck SmiCheckForWriteBarrier() const {
6749 if (field_representation().IsHeapObject()) return OMIT_SMI_CHECK; 6797 if (field_representation().IsHeapObject()) return OMIT_SMI_CHECK;
6750 if (value()->type().IsHeapObject()) return OMIT_SMI_CHECK; 6798 if (value()->type().IsHeapObject()) return OMIT_SMI_CHECK;
6751 return INLINE_SMI_CHECK; 6799 return INLINE_SMI_CHECK;
6752 } 6800 }
6753 6801
6754 PointersToHereCheck PointersToHereCheckForValue() const { 6802 PointersToHereCheck PointersToHereCheckForValue() const {
6755 return PointersToHereCheckForObject(value(), dominator()); 6803 return PointersToHereCheckForObject(value(), dominator());
6756 } 6804 }
6757 6805
(...skipping 15 matching lines...) Expand all
6773 // an initialized entry on 64-bit architectures (with 32-bit smis). 6821 // an initialized entry on 64-bit architectures (with 32-bit smis).
6774 return false; 6822 return false;
6775 } 6823 }
6776 return true; 6824 return true;
6777 } 6825 }
6778 6826
6779 private: 6827 private:
6780 HStoreNamedField(HValue* obj, 6828 HStoreNamedField(HValue* obj,
6781 HObjectAccess access, 6829 HObjectAccess access,
6782 HValue* val, 6830 HValue* val,
6783 StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE) 6831 StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE,
6832 HValue* obj_properties = NULL)
6784 : access_(access), 6833 : access_(access),
6785 dominator_(NULL), 6834 dominator_(NULL),
6786 has_transition_(false), 6835 has_transition_(false),
6787 store_mode_(store_mode) { 6836 store_mode_(store_mode) {
6788 // Stores to a non existing in-object property are allowed only to the 6837 // Stores to a non existing in-object property are allowed only to the
6789 // newly allocated objects (via HAllocate or HInnerAllocatedObject). 6838 // newly allocated objects (via HAllocate or HInnerAllocatedObject).
6790 ASSERT(!access.IsInobject() || access.existing_inobject_property() || 6839 ASSERT(!access.IsInobject() || access.existing_inobject_property() ||
6791 obj->IsAllocate() || obj->IsInnerAllocatedObject()); 6840 obj->IsAllocate() || obj->IsInnerAllocatedObject());
6792 SetOperandAt(0, obj); 6841 SetOperandAt(0, obj);
6793 SetOperandAt(1, val); 6842 SetOperandAt(1, val);
6794 SetOperandAt(2, obj); 6843 SetOperandAt(2, obj);
6844 SetOperandAt(3, obj_properties);
6795 access.SetGVNFlags(this, STORE); 6845 access.SetGVNFlags(this, STORE);
6796 } 6846 }
6797 6847
6798 HObjectAccess access_; 6848 HObjectAccess access_;
6799 HValue* dominator_; 6849 HValue* dominator_;
6800 bool has_transition_ : 1; 6850 bool has_transition_ : 1;
6801 StoreFieldOrKeyedMode store_mode_ : 1; 6851 StoreFieldOrKeyedMode store_mode_ : 1;
6802 }; 6852 };
6803 6853
6804 6854
(...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after
7757 }; 7807 };
7758 7808
7759 7809
7760 7810
7761 #undef DECLARE_INSTRUCTION 7811 #undef DECLARE_INSTRUCTION
7762 #undef DECLARE_CONCRETE_INSTRUCTION 7812 #undef DECLARE_CONCRETE_INSTRUCTION
7763 7813
7764 } } // namespace v8::internal 7814 } } // namespace v8::internal
7765 7815
7766 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 7816 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698