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

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: Addressed comments by Erik Corry. 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
« 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 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(NewSpacePromotion)
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
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
543 STATIC_ASSERT(kLastFlag < kBitsPerInt); 554 STATIC_ASSERT(kLastFlag < kBitsPerInt);
544 555
545 static const int kChangesToDependsFlagsLeftShift = 1; 556 static const int kChangesToDependsFlagsLeftShift = 1;
546 557
558 static GVNFlag ChangesFlagFromInt(int x) {
559 return static_cast<GVNFlag>(x * 2);
560 }
561 static GVNFlag DependsOnFlagFromInt(int x) {
562 return static_cast<GVNFlag>(x * 2 + 1);
563 }
547 static GVNFlagSet ConvertChangesToDependsFlags(GVNFlagSet flags) { 564 static GVNFlagSet ConvertChangesToDependsFlags(GVNFlagSet flags) {
548 return GVNFlagSet(flags.ToIntegral() << kChangesToDependsFlagsLeftShift); 565 return GVNFlagSet(flags.ToIntegral() << kChangesToDependsFlagsLeftShift);
549 } 566 }
550 567
551 static HValue* cast(HValue* value) { return value; } 568 static HValue* cast(HValue* value) { return value; }
552 569
553 enum Opcode { 570 enum Opcode {
554 // Declare a unique enum value for each hydrogen instruction. 571 // Declare a unique enum value for each hydrogen instruction.
555 #define DECLARE_OPCODE(type) k##type, 572 #define DECLARE_OPCODE(type) k##type,
556 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE) 573 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 void PrintChangesTo(StringStream* stream); 736 void PrintChangesTo(StringStream* stream);
720 737
721 const char* Mnemonic() const; 738 const char* Mnemonic() const;
722 739
723 // Updated the inferred type of this instruction and returns true if 740 // Updated the inferred type of this instruction and returns true if
724 // it has changed. 741 // it has changed.
725 bool UpdateInferredType(); 742 bool UpdateInferredType();
726 743
727 virtual HType CalculateInferredType(); 744 virtual HType CalculateInferredType();
728 745
746 // This function must be overridden for instructions which have the
747 // kTrackSideEffectDominators flag set, to track instructions that are
748 // dominating side effects.
749 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) {
750 UNREACHABLE();
751 }
752
729 #ifdef DEBUG 753 #ifdef DEBUG
730 virtual void Verify() = 0; 754 virtual void Verify() = 0;
731 #endif 755 #endif
732 756
733 protected: 757 protected:
734 // This function must be overridden for instructions with flag kUseGVN, to 758 // This function must be overridden for instructions with flag kUseGVN, to
735 // compare the non-Operand parts of the instruction. 759 // compare the non-Operand parts of the instruction.
736 virtual bool DataEquals(HValue* other) { 760 virtual bool DataEquals(HValue* other) {
737 UNREACHABLE(); 761 UNREACHABLE();
738 return false; 762 return false;
(...skipping 10 matching lines...) Expand all
749 void set_representation(Representation r) { 773 void set_representation(Representation r) {
750 // Representation is set-once. 774 // Representation is set-once.
751 ASSERT(representation_.IsNone() && !r.IsNone()); 775 ASSERT(representation_.IsNone() && !r.IsNone());
752 representation_ = r; 776 representation_ = r;
753 } 777 }
754 778
755 static GVNFlagSet AllDependsOnFlagSet() { 779 static GVNFlagSet AllDependsOnFlagSet() {
756 GVNFlagSet result; 780 GVNFlagSet result;
757 // Create changes mask. 781 // Create changes mask.
758 #define ADD_FLAG(type) result.Add(kDependsOn##type); 782 #define ADD_FLAG(type) result.Add(kDependsOn##type);
759 GVN_FLAG_LIST(ADD_FLAG) 783 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
784 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
760 #undef ADD_FLAG 785 #undef ADD_FLAG
761 return result; 786 return result;
762 } 787 }
763 788
764 static GVNFlagSet AllChangesFlagSet() { 789 static GVNFlagSet AllChangesFlagSet() {
765 GVNFlagSet result; 790 GVNFlagSet result;
766 // Create changes mask. 791 // Create changes mask.
767 #define ADD_FLAG(type) result.Add(kChanges##type); 792 #define ADD_FLAG(type) result.Add(kChanges##type);
768 GVN_FLAG_LIST(ADD_FLAG) 793 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
794 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
769 #undef ADD_FLAG 795 #undef ADD_FLAG
770 return result; 796 return result;
771 } 797 }
772 798
773 // A flag mask to mark an instruction as having arbitrary side effects. 799 // A flag mask to mark an instruction as having arbitrary side effects.
774 static GVNFlagSet AllSideEffectsFlagSet() { 800 static GVNFlagSet AllSideEffectsFlagSet() {
775 GVNFlagSet result = AllChangesFlagSet(); 801 GVNFlagSet result = AllChangesFlagSet();
776 result.Remove(kChangesOsrEntries); 802 result.Remove(kChangesOsrEntries);
777 return result; 803 return result;
778 } 804 }
779 805
780 // A flag mask of all side effects that can make observable changes in 806 // 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); 807 // an executing program (i.e. are not safe to repeat, move or remove);
782 static GVNFlagSet AllObservableSideEffectsFlagSet() { 808 static GVNFlagSet AllObservableSideEffectsFlagSet() {
783 GVNFlagSet result = AllChangesFlagSet(); 809 GVNFlagSet result = AllChangesFlagSet();
810 result.Remove(kChangesNewSpacePromotion);
784 result.Remove(kChangesElementsKind); 811 result.Remove(kChangesElementsKind);
785 result.Remove(kChangesElementsPointer); 812 result.Remove(kChangesElementsPointer);
786 result.Remove(kChangesMaps); 813 result.Remove(kChangesMaps);
787 return result; 814 return result;
788 } 815 }
789 816
790 // Remove the matching use from the use list if present. Returns the 817 // Remove the matching use from the use list if present. Returns the
791 // removed list node or NULL. 818 // removed list node or NULL.
792 HUseListNode* RemoveUse(HValue* value, int index); 819 HUseListNode* RemoveUse(HValue* value, int index);
793 820
(...skipping 2756 matching lines...) Expand 10 before | Expand all | Expand 10 after
3550 }; 3577 };
3551 3578
3552 3579
3553 inline bool StoringValueNeedsWriteBarrier(HValue* value) { 3580 inline bool StoringValueNeedsWriteBarrier(HValue* value) {
3554 return !value->type().IsBoolean() 3581 return !value->type().IsBoolean()
3555 && !value->type().IsSmi() 3582 && !value->type().IsSmi()
3556 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable()); 3583 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable());
3557 } 3584 }
3558 3585
3559 3586
3587 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object,
3588 HValue* new_space_dominator) {
3589 return !object->IsAllocateObject() || (object != new_space_dominator);
3590 }
3591
3592
3560 class HStoreGlobalCell: public HUnaryOperation { 3593 class HStoreGlobalCell: public HUnaryOperation {
3561 public: 3594 public:
3562 HStoreGlobalCell(HValue* value, 3595 HStoreGlobalCell(HValue* value,
3563 Handle<JSGlobalPropertyCell> cell, 3596 Handle<JSGlobalPropertyCell> cell,
3564 PropertyDetails details) 3597 PropertyDetails details)
3565 : HUnaryOperation(value), 3598 : HUnaryOperation(value),
3566 cell_(cell), 3599 cell_(cell),
3567 details_(details) { 3600 details_(details) {
3568 SetGVNFlag(kChangesGlobalVars); 3601 SetGVNFlag(kChangesGlobalVars);
3569 } 3602 }
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
4016 4049
4017 class HStoreNamedField: public HTemplateInstruction<2> { 4050 class HStoreNamedField: public HTemplateInstruction<2> {
4018 public: 4051 public:
4019 HStoreNamedField(HValue* obj, 4052 HStoreNamedField(HValue* obj,
4020 Handle<String> name, 4053 Handle<String> name,
4021 HValue* val, 4054 HValue* val,
4022 bool in_object, 4055 bool in_object,
4023 int offset) 4056 int offset)
4024 : name_(name), 4057 : name_(name),
4025 is_in_object_(in_object), 4058 is_in_object_(in_object),
4026 offset_(offset) { 4059 offset_(offset),
4060 new_space_dominator_(NULL) {
4027 SetOperandAt(0, obj); 4061 SetOperandAt(0, obj);
4028 SetOperandAt(1, val); 4062 SetOperandAt(1, val);
4063 SetFlag(kTrackSideEffectDominators);
4064 SetGVNFlag(kDependsOnNewSpacePromotion);
4029 if (is_in_object_) { 4065 if (is_in_object_) {
4030 SetGVNFlag(kChangesInobjectFields); 4066 SetGVNFlag(kChangesInobjectFields);
4031 } else { 4067 } else {
4032 SetGVNFlag(kChangesBackingStoreFields); 4068 SetGVNFlag(kChangesBackingStoreFields);
4033 } 4069 }
4034 } 4070 }
4035 4071
4036 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) 4072 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
4037 4073
4038 virtual Representation RequiredInputRepresentation(int index) { 4074 virtual Representation RequiredInputRepresentation(int index) {
4039 return Representation::Tagged(); 4075 return Representation::Tagged();
4040 } 4076 }
4077 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) {
4078 ASSERT(side_effect == kChangesNewSpacePromotion);
4079 new_space_dominator_ = dominator;
4080 }
4041 virtual void PrintDataTo(StringStream* stream); 4081 virtual void PrintDataTo(StringStream* stream);
4042 4082
4043 HValue* object() { return OperandAt(0); } 4083 HValue* object() { return OperandAt(0); }
4044 HValue* value() { return OperandAt(1); } 4084 HValue* value() { return OperandAt(1); }
4045 4085
4046 Handle<String> name() const { return name_; } 4086 Handle<String> name() const { return name_; }
4047 bool is_in_object() const { return is_in_object_; } 4087 bool is_in_object() const { return is_in_object_; }
4048 int offset() const { return offset_; } 4088 int offset() const { return offset_; }
4049 Handle<Map> transition() const { return transition_; } 4089 Handle<Map> transition() const { return transition_; }
4050 void set_transition(Handle<Map> map) { transition_ = map; } 4090 void set_transition(Handle<Map> map) { transition_ = map; }
4091 HValue* new_space_dominator() const { return new_space_dominator_; }
4051 4092
4052 bool NeedsWriteBarrier() { 4093 bool NeedsWriteBarrier() {
4053 return StoringValueNeedsWriteBarrier(value()); 4094 return StoringValueNeedsWriteBarrier(value()) &&
4095 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
4054 } 4096 }
4055 4097
4056 private: 4098 private:
4057 Handle<String> name_; 4099 Handle<String> name_;
4058 bool is_in_object_; 4100 bool is_in_object_;
4059 int offset_; 4101 int offset_;
4060 Handle<Map> transition_; 4102 Handle<Map> transition_;
4103 HValue* new_space_dominator_;
4061 }; 4104 };
4062 4105
4063 4106
4064 class HStoreNamedGeneric: public HTemplateInstruction<3> { 4107 class HStoreNamedGeneric: public HTemplateInstruction<3> {
4065 public: 4108 public:
4066 HStoreNamedGeneric(HValue* context, 4109 HStoreNamedGeneric(HValue* context,
4067 HValue* object, 4110 HValue* object,
4068 Handle<String> name, 4111 Handle<String> name,
4069 HValue* value, 4112 HValue* value,
4070 StrictModeFlag strict_mode_flag) 4113 StrictModeFlag strict_mode_flag)
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
4397 } 4440 }
4398 }; 4441 };
4399 4442
4400 4443
4401 class HAllocateObject: public HTemplateInstruction<1> { 4444 class HAllocateObject: public HTemplateInstruction<1> {
4402 public: 4445 public:
4403 HAllocateObject(HValue* context, Handle<JSFunction> constructor) 4446 HAllocateObject(HValue* context, Handle<JSFunction> constructor)
4404 : constructor_(constructor) { 4447 : constructor_(constructor) {
4405 SetOperandAt(0, context); 4448 SetOperandAt(0, context);
4406 set_representation(Representation::Tagged()); 4449 set_representation(Representation::Tagged());
4450 SetGVNFlag(kChangesNewSpacePromotion);
4407 } 4451 }
4408 4452
4409 // Maximum instance size for which allocations will be inlined. 4453 // Maximum instance size for which allocations will be inlined.
4410 static const int kMaxSize = 64 * kPointerSize; 4454 static const int kMaxSize = 64 * kPointerSize;
4411 4455
4412 HValue* context() { return OperandAt(0); } 4456 HValue* context() { return OperandAt(0); }
4413 Handle<JSFunction> constructor() { return constructor_; } 4457 Handle<JSFunction> constructor() { return constructor_; }
4414 4458
4415 virtual Representation RequiredInputRepresentation(int index) { 4459 virtual Representation RequiredInputRepresentation(int index) {
4416 return Representation::Tagged(); 4460 return Representation::Tagged();
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
4857 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex); 4901 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex);
4858 }; 4902 };
4859 4903
4860 4904
4861 #undef DECLARE_INSTRUCTION 4905 #undef DECLARE_INSTRUCTION
4862 #undef DECLARE_CONCRETE_INSTRUCTION 4906 #undef DECLARE_CONCRETE_INSTRUCTION
4863 4907
4864 } } // namespace v8::internal 4908 } } // namespace v8::internal
4865 4909
4866 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 4910 #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