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

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

Issue 10031031: Remove write-barriers for stores to new-space objects. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Make kNumberOfTrackedSideEffects a generated value. Created 8 years, 8 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
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 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 V(UnknownOSRValue) \ 181 V(UnknownOSRValue) \
182 V(UseConst) \ 182 V(UseConst) \
183 V(ValueOf) \ 183 V(ValueOf) \
184 V(ForInPrepareMap) \ 184 V(ForInPrepareMap) \
185 V(ForInCacheArray) \ 185 V(ForInCacheArray) \
186 V(CheckMapValue) \ 186 V(CheckMapValue) \
187 V(LoadFieldByIndex) \ 187 V(LoadFieldByIndex) \
188 V(DateField) \ 188 V(DateField) \
189 V(WrapReceiver) 189 V(WrapReceiver)
190 190
191 #define GVN_FLAG_LIST(V) \ 191 #define GVN_TRACKED_FLAG_LIST(V) \
192 V(NewSpace)
193
194 #define GVN_UNTRACKED_FLAG_LIST(V) \
192 V(Calls) \ 195 V(Calls) \
193 V(InobjectFields) \ 196 V(InobjectFields) \
194 V(BackingStoreFields) \ 197 V(BackingStoreFields) \
195 V(ElementsKind) \ 198 V(ElementsKind) \
196 V(ElementsPointer) \ 199 V(ElementsPointer) \
197 V(ArrayElements) \ 200 V(ArrayElements) \
198 V(DoubleArrayElements) \ 201 V(DoubleArrayElements) \
199 V(SpecializedArrayElements) \ 202 V(SpecializedArrayElements) \
200 V(GlobalVars) \ 203 V(GlobalVars) \
201 V(Maps) \ 204 V(Maps) \
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 HUseListNode* next_; 502 HUseListNode* next_;
500 HValue* value_; 503 HValue* value_;
501 int index_; 504 int index_;
502 505
503 friend class HValue; 506 friend class HValue;
504 }; 507 };
505 508
506 509
507 // There must be one corresponding kDepends flag for every kChanges flag and 510 // There must be one corresponding kDepends flag for every kChanges flag and
508 // the order of the kChanges flags must be exactly the same as of the kDepends 511 // the order of the kChanges flags must be exactly the same as of the kDepends
509 // flags. 512 // flags. All tracked flags should appear before untracked ones.
510 enum GVNFlag { 513 enum GVNFlag {
511 // Declare global value numbering flags. 514 // Declare global value numbering flags.
512 #define DECLARE_FLAG(type) kChanges##type, kDependsOn##type, 515 #define DECLARE_FLAG(type) kChanges##type, kDependsOn##type,
513 GVN_FLAG_LIST(DECLARE_FLAG) 516 GVN_TRACKED_FLAG_LIST(DECLARE_FLAG)
517 GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
514 #undef DECLARE_FLAG 518 #undef DECLARE_FLAG
515 kAfterLastFlag, 519 kAfterLastFlag,
516 kLastFlag = kAfterLastFlag - 1 520 kLastFlag = kAfterLastFlag - 1,
521 #define COUNT_FLAG(type) + 1
522 kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG)
523 #undef COUNT_FLAG
Erik Corry 2012/04/10 12:06:52 I think it would be nice to provide functions: GV
Michael Starzinger 2012/04/11 09:53:08 Done.
517 }; 524 };
518 525
519 typedef EnumSet<GVNFlag> GVNFlagSet; 526 typedef EnumSet<GVNFlag> GVNFlagSet;
520 527
521 528
522 class HValue: public ZoneObject { 529 class HValue: public ZoneObject {
523 public: 530 public:
524 static const int kNoNumber = -1; 531 static const int kNoNumber = -1;
525 532
526 enum Flag { 533 enum Flag {
527 kFlexibleRepresentation, 534 kFlexibleRepresentation,
528 // Participate in Global Value Numbering, i.e. elimination of 535 // Participate in Global Value Numbering, i.e. elimination of
529 // unnecessary recomputations. If an instruction sets this flag, it must 536 // unnecessary recomputations. If an instruction sets this flag, it must
530 // implement DataEquals(), which will be used to determine if other 537 // implement DataEquals(), which will be used to determine if other
531 // occurrences of the instruction are indeed the same. 538 // occurrences of the instruction are indeed the same.
532 kUseGVN, 539 kUseGVN,
540 // Track instructions that are dominating side effects. If an instruction
541 // sets this flag, it must implement SetSideEffectDominator() and should
542 // indicate which side effects to track by setting GVN flags.
543 kTrackSideEffectDominators,
533 kCanOverflow, 544 kCanOverflow,
534 kBailoutOnMinusZero, 545 kBailoutOnMinusZero,
535 kCanBeDivByZero, 546 kCanBeDivByZero,
536 kDeoptimizeOnUndefined, 547 kDeoptimizeOnUndefined,
537 kIsArguments, 548 kIsArguments,
538 kTruncatingToInt32, 549 kTruncatingToInt32,
539 kIsDead, 550 kIsDead,
540 kLastFlag = kIsDead 551 kLastFlag = kIsDead
541 }; 552 };
542 553
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 void PrintChangesTo(StringStream* stream); 730 void PrintChangesTo(StringStream* stream);
720 731
721 const char* Mnemonic() const; 732 const char* Mnemonic() const;
722 733
723 // Updated the inferred type of this instruction and returns true if 734 // Updated the inferred type of this instruction and returns true if
724 // it has changed. 735 // it has changed.
725 bool UpdateInferredType(); 736 bool UpdateInferredType();
726 737
727 virtual HType CalculateInferredType(); 738 virtual HType CalculateInferredType();
728 739
740 // This function must be overridden for instructions which have the
741 // kTrackSideEffectDominators flag set, to track instructions that are
742 // dominating side effects.
743 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) {
744 UNREACHABLE();
745 }
746
729 #ifdef DEBUG 747 #ifdef DEBUG
730 virtual void Verify() = 0; 748 virtual void Verify() = 0;
731 #endif 749 #endif
732 750
733 protected: 751 protected:
734 // This function must be overridden for instructions with flag kUseGVN, to 752 // This function must be overridden for instructions with flag kUseGVN, to
735 // compare the non-Operand parts of the instruction. 753 // compare the non-Operand parts of the instruction.
736 virtual bool DataEquals(HValue* other) { 754 virtual bool DataEquals(HValue* other) {
737 UNREACHABLE(); 755 UNREACHABLE();
738 return false; 756 return false;
(...skipping 10 matching lines...) Expand all
749 void set_representation(Representation r) { 767 void set_representation(Representation r) {
750 // Representation is set-once. 768 // Representation is set-once.
751 ASSERT(representation_.IsNone() && !r.IsNone()); 769 ASSERT(representation_.IsNone() && !r.IsNone());
752 representation_ = r; 770 representation_ = r;
753 } 771 }
754 772
755 static GVNFlagSet AllDependsOnFlagSet() { 773 static GVNFlagSet AllDependsOnFlagSet() {
756 GVNFlagSet result; 774 GVNFlagSet result;
757 // Create changes mask. 775 // Create changes mask.
758 #define ADD_FLAG(type) result.Add(kDependsOn##type); 776 #define ADD_FLAG(type) result.Add(kDependsOn##type);
759 GVN_FLAG_LIST(ADD_FLAG) 777 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
778 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
760 #undef ADD_FLAG 779 #undef ADD_FLAG
761 return result; 780 return result;
762 } 781 }
763 782
764 static GVNFlagSet AllChangesFlagSet() { 783 static GVNFlagSet AllChangesFlagSet() {
765 GVNFlagSet result; 784 GVNFlagSet result;
766 // Create changes mask. 785 // Create changes mask.
767 #define ADD_FLAG(type) result.Add(kChanges##type); 786 #define ADD_FLAG(type) result.Add(kChanges##type);
768 GVN_FLAG_LIST(ADD_FLAG) 787 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
788 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
769 #undef ADD_FLAG 789 #undef ADD_FLAG
770 return result; 790 return result;
771 } 791 }
772 792
773 // A flag mask to mark an instruction as having arbitrary side effects. 793 // A flag mask to mark an instruction as having arbitrary side effects.
774 static GVNFlagSet AllSideEffectsFlagSet() { 794 static GVNFlagSet AllSideEffectsFlagSet() {
775 GVNFlagSet result = AllChangesFlagSet(); 795 GVNFlagSet result = AllChangesFlagSet();
776 result.Remove(kChangesOsrEntries); 796 result.Remove(kChangesOsrEntries);
777 return result; 797 return result;
778 } 798 }
779 799
780 // A flag mask of all side effects that can make observable changes in 800 // A flag mask of all side effects that can make observable changes in
781 // an executing program (i.e. are not safe to repeat, move or remove); 801 // an executing program (i.e. are not safe to repeat, move or remove);
782 static GVNFlagSet AllObservableSideEffectsFlagSet() { 802 static GVNFlagSet AllObservableSideEffectsFlagSet() {
783 GVNFlagSet result = AllChangesFlagSet(); 803 GVNFlagSet result = AllChangesFlagSet();
804 result.Remove(kChangesNewSpace);
Erik Corry 2012/04/10 12:06:52 The name makes it sound like any write to new spac
Michael Starzinger 2012/04/11 09:53:08 Done.
784 result.Remove(kChangesElementsKind); 805 result.Remove(kChangesElementsKind);
785 result.Remove(kChangesElementsPointer); 806 result.Remove(kChangesElementsPointer);
786 result.Remove(kChangesMaps); 807 result.Remove(kChangesMaps);
787 return result; 808 return result;
788 } 809 }
789 810
790 // Remove the matching use from the use list if present. Returns the 811 // Remove the matching use from the use list if present. Returns the
791 // removed list node or NULL. 812 // removed list node or NULL.
792 HUseListNode* RemoveUse(HValue* value, int index); 813 HUseListNode* RemoveUse(HValue* value, int index);
793 814
(...skipping 2756 matching lines...) Expand 10 before | Expand all | Expand 10 after
3550 }; 3571 };
3551 3572
3552 3573
3553 inline bool StoringValueNeedsWriteBarrier(HValue* value) { 3574 inline bool StoringValueNeedsWriteBarrier(HValue* value) {
3554 return !value->type().IsBoolean() 3575 return !value->type().IsBoolean()
3555 && !value->type().IsSmi() 3576 && !value->type().IsSmi()
3556 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable()); 3577 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable());
3557 } 3578 }
3558 3579
3559 3580
3581 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object,
3582 HValue* new_space_dominator) {
3583 return !object->IsAllocateObject() || (object != new_space_dominator);
3584 }
3585
3586
3560 class HStoreGlobalCell: public HUnaryOperation { 3587 class HStoreGlobalCell: public HUnaryOperation {
3561 public: 3588 public:
3562 HStoreGlobalCell(HValue* value, 3589 HStoreGlobalCell(HValue* value,
3563 Handle<JSGlobalPropertyCell> cell, 3590 Handle<JSGlobalPropertyCell> cell,
3564 PropertyDetails details) 3591 PropertyDetails details)
3565 : HUnaryOperation(value), 3592 : HUnaryOperation(value),
3566 cell_(cell), 3593 cell_(cell),
3567 details_(details) { 3594 details_(details) {
3568 SetGVNFlag(kChangesGlobalVars); 3595 SetGVNFlag(kChangesGlobalVars);
3569 } 3596 }
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
4016 4043
4017 class HStoreNamedField: public HTemplateInstruction<2> { 4044 class HStoreNamedField: public HTemplateInstruction<2> {
4018 public: 4045 public:
4019 HStoreNamedField(HValue* obj, 4046 HStoreNamedField(HValue* obj,
4020 Handle<String> name, 4047 Handle<String> name,
4021 HValue* val, 4048 HValue* val,
4022 bool in_object, 4049 bool in_object,
4023 int offset) 4050 int offset)
4024 : name_(name), 4051 : name_(name),
4025 is_in_object_(in_object), 4052 is_in_object_(in_object),
4026 offset_(offset) { 4053 offset_(offset) {
Erik Corry 2012/04/10 12:06:52 Should you not initialize new_space_dominator_ her
Michael Starzinger 2012/04/11 09:53:08 Done.
4027 SetOperandAt(0, obj); 4054 SetOperandAt(0, obj);
4028 SetOperandAt(1, val); 4055 SetOperandAt(1, val);
4056 SetFlag(kTrackSideEffectDominators);
4057 SetGVNFlag(kDependsOnNewSpace);
4029 if (is_in_object_) { 4058 if (is_in_object_) {
4030 SetGVNFlag(kChangesInobjectFields); 4059 SetGVNFlag(kChangesInobjectFields);
4031 } else { 4060 } else {
4032 SetGVNFlag(kChangesBackingStoreFields); 4061 SetGVNFlag(kChangesBackingStoreFields);
4033 } 4062 }
4034 } 4063 }
4035 4064
4036 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) 4065 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
4037 4066
4038 virtual Representation RequiredInputRepresentation(int index) { 4067 virtual Representation RequiredInputRepresentation(int index) {
4039 return Representation::Tagged(); 4068 return Representation::Tagged();
4040 } 4069 }
4070 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) {
4071 ASSERT(side_effect == kChangesNewSpace);
4072 new_space_dominator_ = dominator;
4073 }
4041 virtual void PrintDataTo(StringStream* stream); 4074 virtual void PrintDataTo(StringStream* stream);
4042 4075
4043 HValue* object() { return OperandAt(0); } 4076 HValue* object() { return OperandAt(0); }
4044 HValue* value() { return OperandAt(1); } 4077 HValue* value() { return OperandAt(1); }
4045 4078
4046 Handle<String> name() const { return name_; } 4079 Handle<String> name() const { return name_; }
4047 bool is_in_object() const { return is_in_object_; } 4080 bool is_in_object() const { return is_in_object_; }
4048 int offset() const { return offset_; } 4081 int offset() const { return offset_; }
4049 Handle<Map> transition() const { return transition_; } 4082 Handle<Map> transition() const { return transition_; }
4050 void set_transition(Handle<Map> map) { transition_ = map; } 4083 void set_transition(Handle<Map> map) { transition_ = map; }
4084 HValue* new_space_dominator() const { return new_space_dominator_; }
4051 4085
4052 bool NeedsWriteBarrier() { 4086 bool NeedsWriteBarrier() {
4053 return StoringValueNeedsWriteBarrier(value()); 4087 return StoringValueNeedsWriteBarrier(value()) &&
4088 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
4054 } 4089 }
4055 4090
4056 private: 4091 private:
4057 Handle<String> name_; 4092 Handle<String> name_;
4058 bool is_in_object_; 4093 bool is_in_object_;
4059 int offset_; 4094 int offset_;
4060 Handle<Map> transition_; 4095 Handle<Map> transition_;
4096 HValue* new_space_dominator_;
4061 }; 4097 };
4062 4098
4063 4099
4064 class HStoreNamedGeneric: public HTemplateInstruction<3> { 4100 class HStoreNamedGeneric: public HTemplateInstruction<3> {
4065 public: 4101 public:
4066 HStoreNamedGeneric(HValue* context, 4102 HStoreNamedGeneric(HValue* context,
4067 HValue* object, 4103 HValue* object,
4068 Handle<String> name, 4104 Handle<String> name,
4069 HValue* value, 4105 HValue* value,
4070 StrictModeFlag strict_mode_flag) 4106 StrictModeFlag strict_mode_flag)
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
4397 } 4433 }
4398 }; 4434 };
4399 4435
4400 4436
4401 class HAllocateObject: public HTemplateInstruction<1> { 4437 class HAllocateObject: public HTemplateInstruction<1> {
4402 public: 4438 public:
4403 HAllocateObject(HValue* context, Handle<JSFunction> constructor) 4439 HAllocateObject(HValue* context, Handle<JSFunction> constructor)
4404 : constructor_(constructor) { 4440 : constructor_(constructor) {
4405 SetOperandAt(0, context); 4441 SetOperandAt(0, context);
4406 set_representation(Representation::Tagged()); 4442 set_representation(Representation::Tagged());
4443 SetGVNFlag(kChangesNewSpace);
4407 } 4444 }
4408 4445
4409 // Maximum instance size for which allocations will be inlined. 4446 // Maximum instance size for which allocations will be inlined.
4410 static const int kMaxSize = 64 * kPointerSize; 4447 static const int kMaxSize = 64 * kPointerSize;
4411 4448
4412 HValue* context() { return OperandAt(0); } 4449 HValue* context() { return OperandAt(0); }
4413 Handle<JSFunction> constructor() { return constructor_; } 4450 Handle<JSFunction> constructor() { return constructor_; }
4414 4451
4415 virtual Representation RequiredInputRepresentation(int index) { 4452 virtual Representation RequiredInputRepresentation(int index) {
4416 return Representation::Tagged(); 4453 return Representation::Tagged();
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
4857 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex); 4894 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex);
4858 }; 4895 };
4859 4896
4860 4897
4861 #undef DECLARE_INSTRUCTION 4898 #undef DECLARE_INSTRUCTION
4862 #undef DECLARE_CONCRETE_INSTRUCTION 4899 #undef DECLARE_CONCRETE_INSTRUCTION
4863 4900
4864 } } // namespace v8::internal 4901 } } // namespace v8::internal
4865 4902
4866 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 4903 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« src/hydrogen.cc ('K') | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698