diff options
Diffstat (limited to 'deps/v8/src/hydrogen-instructions.h')
-rw-r--r-- | deps/v8/src/hydrogen-instructions.h | 1559 |
1 files changed, 890 insertions, 669 deletions
diff --git a/deps/v8/src/hydrogen-instructions.h b/deps/v8/src/hydrogen-instructions.h index 7d33141a4f..80773bf147 100644 --- a/deps/v8/src/hydrogen-instructions.h +++ b/deps/v8/src/hydrogen-instructions.h @@ -36,6 +36,7 @@ #include "deoptimizer.h" #include "small-pointer-list.h" #include "string-stream.h" +#include "unique.h" #include "v8conversions.h" #include "v8utils.h" #include "zone.h" @@ -63,6 +64,7 @@ class LChunkBuilder; #define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \ + V(AbnormalExit) \ V(AccessArgumentsAt) \ V(Add) \ V(Allocate) \ @@ -124,11 +126,9 @@ class LChunkBuilder; V(InnerAllocatedObject) \ V(InstanceOf) \ V(InstanceOfKnownGlobal) \ - V(InstanceSize) \ V(InvokeFunction) \ V(IsConstructCallAndBranch) \ V(IsObjectAndBranch) \ - V(IsNumberAndBranch) \ V(IsStringAndBranch) \ V(IsSmiAndBranch) \ V(IsUndetectableAndBranch) \ @@ -143,6 +143,7 @@ class LChunkBuilder; V(LoadKeyedGeneric) \ V(LoadNamedField) \ V(LoadNamedGeneric) \ + V(LoadRoot) \ V(MapEnumLength) \ V(MathFloorOfDiv) \ V(MathMinMax) \ @@ -305,64 +306,6 @@ class Range V8_FINAL : public ZoneObject { }; -class UniqueValueId V8_FINAL { - public: - UniqueValueId() : raw_address_(NULL) { } - - explicit UniqueValueId(Handle<Object> handle) { - ASSERT(!AllowHeapAllocation::IsAllowed()); - static const Address kEmptyHandleSentinel = reinterpret_cast<Address>(1); - if (handle.is_null()) { - raw_address_ = kEmptyHandleSentinel; - } else { - raw_address_ = reinterpret_cast<Address>(*handle); - ASSERT_NE(kEmptyHandleSentinel, raw_address_); - } - ASSERT(IsInitialized()); - } - - bool IsInitialized() const { return raw_address_ != NULL; } - - bool operator==(const UniqueValueId& other) const { - ASSERT(IsInitialized() && other.IsInitialized()); - return raw_address_ == other.raw_address_; - } - - bool operator!=(const UniqueValueId& other) const { - ASSERT(IsInitialized() && other.IsInitialized()); - return raw_address_ != other.raw_address_; - } - - intptr_t Hashcode() const { - ASSERT(IsInitialized()); - return reinterpret_cast<intptr_t>(raw_address_); - } - -#define IMMOVABLE_UNIQUE_VALUE_ID(name) \ - static UniqueValueId name(Heap* heap) { return UniqueValueId(heap->name()); } - - IMMOVABLE_UNIQUE_VALUE_ID(free_space_map) - IMMOVABLE_UNIQUE_VALUE_ID(minus_zero_value) - IMMOVABLE_UNIQUE_VALUE_ID(nan_value) - IMMOVABLE_UNIQUE_VALUE_ID(undefined_value) - IMMOVABLE_UNIQUE_VALUE_ID(null_value) - IMMOVABLE_UNIQUE_VALUE_ID(true_value) - IMMOVABLE_UNIQUE_VALUE_ID(false_value) - IMMOVABLE_UNIQUE_VALUE_ID(the_hole_value) - IMMOVABLE_UNIQUE_VALUE_ID(empty_string) - -#undef IMMOVABLE_UNIQUE_VALUE_ID - - private: - Address raw_address_; - - explicit UniqueValueId(Object* object) { - raw_address_ = reinterpret_cast<Address>(object); - ASSERT(IsInitialized()); - } -}; - - class HType V8_FINAL { public: static HType None() { return HType(kNone); } @@ -695,6 +638,8 @@ class HValue : public ZoneObject { flags_(0) {} virtual ~HValue() {} + virtual int position() const { return RelocInfo::kNoPosition; } + HBasicBlock* block() const { return block_; } void SetBlock(HBasicBlock* block); int LoopWeight() const; @@ -777,16 +722,24 @@ class HValue : public ZoneObject { return index == kNoRedefinedOperand ? NULL : OperandAt(index); } + bool CanReplaceWithDummyUses(); + + virtual int argument_delta() const { return 0; } + // A purely informative definition is an idef that will not emit code and // should therefore be removed from the graph in the RestoreActualValues // phase (so that live ranges will be shorter). virtual bool IsPurelyInformativeDefinition() { return false; } - // This method must always return the original HValue SSA definition - // (regardless of any iDef of this value). + // This method must always return the original HValue SSA definition, + // regardless of any chain of iDefs of this value. HValue* ActualValue() { - int index = RedefinedOperandIndex(); - return index == kNoRedefinedOperand ? this : OperandAt(index); + HValue* value = this; + int index; + while ((index = value->RedefinedOperandIndex()) != kNoRedefinedOperand) { + value = value->OperandAt(index); + } + return value; } bool IsInteger32Constant(); @@ -815,6 +768,9 @@ class HValue : public ZoneObject { void SetFlag(Flag f) { flags_ |= (1 << f); } void ClearFlag(Flag f) { flags_ &= ~(1 << f); } bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; } + void CopyFlag(Flag f, HValue* other) { + if (other->CheckFlag(f)) SetFlag(f); + } // Returns true if the flag specified is set for all uses, false otherwise. bool CheckUsesForFlag(Flag f) const; @@ -898,7 +854,7 @@ class HValue : public ZoneObject { virtual intptr_t Hashcode(); // Compute unique ids upfront that is safe wrt GC and concurrent compilation. - virtual void FinalizeUniqueValueId() { } + virtual void FinalizeUniqueness() { } // Printing support. virtual void PrintTo(StringStream* stream) = 0; @@ -1104,6 +1060,47 @@ class HValue : public ZoneObject { return new(zone) I(p1, p2, p3, p4, p5); \ } +#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P0(I) \ + static I* New(Zone* zone, HValue* context) { \ + return new(zone) I(context); \ + } + +#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(I, P1) \ + static I* New(Zone* zone, HValue* context, P1 p1) { \ + return new(zone) I(context, p1); \ + } + +#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(I, P1, P2) \ + static I* New(Zone* zone, HValue* context, P1 p1, P2 p2) { \ + return new(zone) I(context, p1, p2); \ + } + +#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(I, P1, P2, P3) \ + static I* New(Zone* zone, HValue* context, P1 p1, P2 p2, P3 p3) { \ + return new(zone) I(context, p1, p2, p3); \ + } + +#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(I, P1, P2, P3, P4) \ + static I* New(Zone* zone, \ + HValue* context, \ + P1 p1, \ + P2 p2, \ + P3 p3, \ + P4 p4) { \ + return new(zone) I(context, p1, p2, p3, p4); \ + } + +#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P5(I, P1, P2, P3, P4, P5) \ + static I* New(Zone* zone, \ + HValue* context, \ + P1 p1, \ + P2 p2, \ + P3 p3, \ + P4 p4, \ + P5 p5) { \ + return new(zone) I(context, p1, p2, p3, p4, p5); \ + } + class HInstruction : public HValue { public: @@ -1119,7 +1116,7 @@ class HInstruction : public HValue { void InsertAfter(HInstruction* previous); // The position is a write-once variable. - int position() const { return position_; } + virtual int position() const V8_OVERRIDE { return position_; } bool has_position() const { return position_ != RelocInfo::kNoPosition; } void set_position(int position) { ASSERT(!has_position()); @@ -1194,6 +1191,11 @@ class HControlInstruction : public HInstruction { virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; + virtual bool KnownSuccessorBlock(HBasicBlock** block) { + *block = NULL; + return false; + } + HBasicBlock* FirstSuccessor() { return SuccessorCount() > 0 ? SuccessorAt(0) : NULL; } @@ -1201,6 +1203,12 @@ class HControlInstruction : public HInstruction { return SuccessorCount() > 1 ? SuccessorAt(1) : NULL; } + void Not() { + HBasicBlock* swap = SuccessorAt(0); + SetSuccessorAt(0, SuccessorAt(1)); + SetSuccessorAt(1, swap); + } + DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction) }; @@ -1277,53 +1285,74 @@ class HDummyUse V8_FINAL : public HTemplateInstruction<1> { }; -class HDeoptimize V8_FINAL : public HTemplateInstruction<0> { +// Inserts an int3/stop break instruction for debugging purposes. +class HDebugBreak V8_FINAL : public HTemplateInstruction<0> { public: - DECLARE_INSTRUCTION_FACTORY_P2(HDeoptimize, const char*, - Deoptimizer::BailoutType); + DECLARE_INSTRUCTION_FACTORY_P0(HDebugBreak); virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { return Representation::None(); } - const char* reason() const { return reason_; } - Deoptimizer::BailoutType type() { return type_; } - - DECLARE_CONCRETE_INSTRUCTION(Deoptimize) - - private: - explicit HDeoptimize(const char* reason, Deoptimizer::BailoutType type) - : reason_(reason), type_(type) {} - - const char* reason_; - Deoptimizer::BailoutType type_; + DECLARE_CONCRETE_INSTRUCTION(DebugBreak) }; -// Inserts an int3/stop break instruction for debugging purposes. -class HDebugBreak V8_FINAL : public HTemplateInstruction<0> { +class HGoto V8_FINAL : public HTemplateControlInstruction<1, 0> { public: + explicit HGoto(HBasicBlock* target) { + SetSuccessorAt(0, target); + } + + virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE { + *block = FirstSuccessor(); + return true; + } + virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { return Representation::None(); } - DECLARE_CONCRETE_INSTRUCTION(DebugBreak) + virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; + + DECLARE_CONCRETE_INSTRUCTION(Goto) }; -class HGoto V8_FINAL : public HTemplateControlInstruction<1, 0> { +class HDeoptimize V8_FINAL : public HTemplateControlInstruction<1, 0> { public: - explicit HGoto(HBasicBlock* target) { - SetSuccessorAt(0, target); + static HInstruction* New(Zone* zone, + HValue* context, + const char* reason, + Deoptimizer::BailoutType type, + HBasicBlock* unreachable_continuation) { + return new(zone) HDeoptimize(reason, type, unreachable_continuation); + } + + virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE { + *block = NULL; + return true; } virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { return Representation::None(); } - virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; + const char* reason() const { return reason_; } + Deoptimizer::BailoutType type() { return type_; } - DECLARE_CONCRETE_INSTRUCTION(Goto) + DECLARE_CONCRETE_INSTRUCTION(Deoptimize) + + private: + explicit HDeoptimize(const char* reason, + Deoptimizer::BailoutType type, + HBasicBlock* unreachable_continuation) + : reason_(reason), type_(type) { + SetSuccessorAt(0, unreachable_continuation); + } + + const char* reason_; + Deoptimizer::BailoutType type_; }; @@ -1345,20 +1374,20 @@ class HUnaryControlInstruction : public HTemplateControlInstruction<2, 1> { class HBranch V8_FINAL : public HUnaryControlInstruction { public: - HBranch(HValue* value, - ToBooleanStub::Types expected_input_types = ToBooleanStub::Types(), - HBasicBlock* true_target = NULL, - HBasicBlock* false_target = NULL) - : HUnaryControlInstruction(value, true_target, false_target), - expected_input_types_(expected_input_types) { - SetFlag(kAllowUndefinedAsNaN); - } + DECLARE_INSTRUCTION_FACTORY_P1(HBranch, HValue*); + DECLARE_INSTRUCTION_FACTORY_P2(HBranch, HValue*, + ToBooleanStub::Types); + DECLARE_INSTRUCTION_FACTORY_P4(HBranch, HValue*, + ToBooleanStub::Types, + HBasicBlock*, HBasicBlock*); virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { return Representation::None(); } virtual Representation observed_input_representation(int index) V8_OVERRIDE; + virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE; + ToBooleanStub::Types expected_input_types() const { return expected_input_types_; } @@ -1366,24 +1395,28 @@ class HBranch V8_FINAL : public HUnaryControlInstruction { DECLARE_CONCRETE_INSTRUCTION(Branch) private: + HBranch(HValue* value, + ToBooleanStub::Types expected_input_types = ToBooleanStub::Types(), + HBasicBlock* true_target = NULL, + HBasicBlock* false_target = NULL) + : HUnaryControlInstruction(value, true_target, false_target), + expected_input_types_(expected_input_types) { + SetFlag(kAllowUndefinedAsNaN); + } + ToBooleanStub::Types expected_input_types_; }; class HCompareMap V8_FINAL : public HUnaryControlInstruction { public: - HCompareMap(HValue* value, - Handle<Map> map, - HBasicBlock* true_target = NULL, - HBasicBlock* false_target = NULL) - : HUnaryControlInstruction(value, true_target, false_target), - map_(map) { - ASSERT(!map.is_null()); - } + DECLARE_INSTRUCTION_FACTORY_P2(HCompareMap, HValue*, Handle<Map>); + DECLARE_INSTRUCTION_FACTORY_P4(HCompareMap, HValue*, Handle<Map>, + HBasicBlock*, HBasicBlock*); virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; - Handle<Map> map() const { return map_; } + Unique<Map> map() const { return map_; } virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { return Representation::Tagged(); @@ -1395,7 +1428,16 @@ class HCompareMap V8_FINAL : public HUnaryControlInstruction { virtual int RedefinedOperandIndex() { return 0; } private: - Handle<Map> map_; + HCompareMap(HValue* value, + Handle<Map> map, + HBasicBlock* true_target = NULL, + HBasicBlock* false_target = NULL) + : HUnaryControlInstruction(value, true_target, false_target), + map_(Unique<Map>(map)) { + ASSERT(!map.is_null()); + } + + Unique<Map> map_; }; @@ -1426,18 +1468,8 @@ class HContext V8_FINAL : public HTemplateInstruction<0> { class HReturn V8_FINAL : public HTemplateControlInstruction<0, 3> { public: - static HInstruction* New(Zone* zone, - HValue* context, - HValue* value, - HValue* parameter_count) { - return new(zone) HReturn(value, context, parameter_count); - } - - static HInstruction* New(Zone* zone, - HValue* context, - HValue* value) { - return new(zone) HReturn(value, context, 0); - } + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HReturn, HValue*, HValue*); + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HReturn, HValue*); virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { return Representation::Tagged(); @@ -1452,7 +1484,7 @@ class HReturn V8_FINAL : public HTemplateControlInstruction<0, 3> { DECLARE_CONCRETE_INSTRUCTION(Return) private: - HReturn(HValue* value, HValue* context, HValue* parameter_count) { + HReturn(HValue* context, HValue* value, HValue* parameter_count = 0) { SetOperandAt(0, value); SetOperandAt(1, context); SetOperandAt(2, parameter_count); @@ -1460,6 +1492,20 @@ class HReturn V8_FINAL : public HTemplateControlInstruction<0, 3> { }; +class HAbnormalExit V8_FINAL : public HTemplateControlInstruction<0, 0> { + public: + DECLARE_INSTRUCTION_FACTORY_P0(HAbnormalExit); + + virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { + return Representation::None(); + } + + DECLARE_CONCRETE_INSTRUCTION(AbnormalExit) + private: + HAbnormalExit() {} +}; + + class HUnaryOperation : public HTemplateInstruction<1> { public: HUnaryOperation(HValue* value, HType type = HType::Tagged()) @@ -1478,11 +1524,7 @@ class HUnaryOperation : public HTemplateInstruction<1> { class HThrow V8_FINAL : public HTemplateInstruction<2> { public: - static HThrow* New(Zone* zone, - HValue* context, - HValue* value) { - return new(zone) HThrow(context, value); - } + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HThrow, HValue*); virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { return Representation::Tagged(); @@ -1738,8 +1780,7 @@ class HEnvironmentMarker V8_FINAL : public HTemplateInstruction<1> { public: enum Kind { BIND, LOOKUP }; - HEnvironmentMarker(Kind kind, int index) - : kind_(kind), index_(index), next_simulate_(NULL) { } + DECLARE_INSTRUCTION_FACTORY_P2(HEnvironmentMarker, Kind, int); Kind kind() { return kind_; } int index() { return index_; } @@ -1766,6 +1807,9 @@ class HEnvironmentMarker V8_FINAL : public HTemplateInstruction<1> { DECLARE_CONCRETE_INSTRUCTION(EnvironmentMarker); private: + HEnvironmentMarker(Kind kind, int index) + : kind_(kind), index_(index), next_simulate_(NULL) { } + Kind kind_; int index_; HSimulate* next_simulate_; @@ -1783,7 +1827,7 @@ class HStackCheck V8_FINAL : public HTemplateInstruction<1> { kBackwardsBranch }; - DECLARE_INSTRUCTION_FACTORY_P2(HStackCheck, HValue*, Type); + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HStackCheck, Type); HValue* context() { return OperandAt(0); } @@ -1898,13 +1942,24 @@ class HEnterInlined V8_FINAL : public HTemplateInstruction<0> { class HLeaveInlined V8_FINAL : public HTemplateInstruction<0> { public: - HLeaveInlined() { } + HLeaveInlined(HEnterInlined* entry, + int drop_count) + : entry_(entry), + drop_count_(drop_count) { } virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { return Representation::None(); } + virtual int argument_delta() const V8_OVERRIDE { + return entry_->arguments_pushed() ? -drop_count_ : 0; + } + DECLARE_CONCRETE_INSTRUCTION(LeaveInlined) + + private: + HEnterInlined* entry_; + int drop_count_; }; @@ -1916,6 +1971,7 @@ class HPushArgument V8_FINAL : public HUnaryOperation { return Representation::Tagged(); } + virtual int argument_delta() const V8_OVERRIDE { return 1; } HValue* argument() { return OperandAt(0); } DECLARE_CONCRETE_INSTRUCTION(PushArgument) @@ -1929,10 +1985,7 @@ class HPushArgument V8_FINAL : public HUnaryOperation { class HThisFunction V8_FINAL : public HTemplateInstruction<0> { public: - HThisFunction() { - set_representation(Representation::Tagged()); - SetFlag(kUseGVN); - } + DECLARE_INSTRUCTION_FACTORY_P0(HThisFunction); virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { return Representation::None(); @@ -1944,6 +1997,11 @@ class HThisFunction V8_FINAL : public HTemplateInstruction<0> { virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } private: + HThisFunction() { + set_representation(Representation::Tagged()); + SetFlag(kUseGVN); + } + virtual bool IsDeletable() const V8_OVERRIDE { return true; } }; @@ -1973,22 +2031,9 @@ class HOuterContext V8_FINAL : public HUnaryOperation { class HDeclareGlobals V8_FINAL : public HUnaryOperation { public: - HDeclareGlobals(HValue* context, - Handle<FixedArray> pairs, - int flags) - : HUnaryOperation(context), - pairs_(pairs), - flags_(flags) { - set_representation(Representation::Tagged()); - SetAllSideEffects(); - } - - static HDeclareGlobals* New(Zone* zone, - HValue* context, - Handle<FixedArray> pairs, - int flags) { - return new(zone) HDeclareGlobals(context, pairs, flags); - } + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HDeclareGlobals, + Handle<FixedArray>, + int); HValue* context() { return OperandAt(0); } Handle<FixedArray> pairs() const { return pairs_; } @@ -2001,6 +2046,16 @@ class HDeclareGlobals V8_FINAL : public HUnaryOperation { } private: + HDeclareGlobals(HValue* context, + Handle<FixedArray> pairs, + int flags) + : HUnaryOperation(context), + pairs_(pairs), + flags_(flags) { + set_representation(Representation::Tagged()); + SetAllSideEffects(); + } + Handle<FixedArray> pairs_; int flags_; }; @@ -2008,14 +2063,7 @@ class HDeclareGlobals V8_FINAL : public HUnaryOperation { class HGlobalObject V8_FINAL : public HUnaryOperation { public: - explicit HGlobalObject(HValue* context) : HUnaryOperation(context) { - set_representation(Representation::Tagged()); - SetFlag(kUseGVN); - } - - static HGlobalObject* New(Zone* zone, HValue* context) { - return new(zone) HGlobalObject(context); - } + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P0(HGlobalObject); DECLARE_CONCRETE_INSTRUCTION(GlobalObject) @@ -2027,6 +2075,11 @@ class HGlobalObject V8_FINAL : public HUnaryOperation { virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } private: + explicit HGlobalObject(HValue* context) : HUnaryOperation(context) { + set_representation(Representation::Tagged()); + SetFlag(kUseGVN); + } + virtual bool IsDeletable() const V8_OVERRIDE { return true; } }; @@ -2068,7 +2121,13 @@ class HCall : public HTemplateInstruction<V> { return HType::Tagged(); } - virtual int argument_count() const { return argument_count_; } + virtual int argument_count() const { + return argument_count_; + } + + virtual int argument_delta() const V8_OVERRIDE { + return -argument_count(); + } virtual bool IsCall() V8_FINAL V8_OVERRIDE { return true; } @@ -2117,16 +2176,7 @@ class HBinaryCall : public HCall<2> { class HInvokeFunction V8_FINAL : public HBinaryCall { public: - HInvokeFunction(HValue* context, HValue* function, int argument_count) - : HBinaryCall(context, function, argument_count) { - } - - static HInvokeFunction* New(Zone* zone, - HValue* context, - HValue* function, - int argument_count) { - return new(zone) HInvokeFunction(context, function, argument_count); - } + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HInvokeFunction, HValue*, int); HInvokeFunction(HValue* context, HValue* function, @@ -2155,6 +2205,10 @@ class HInvokeFunction V8_FINAL : public HBinaryCall { DECLARE_CONCRETE_INSTRUCTION(InvokeFunction) private: + HInvokeFunction(HValue* context, HValue* function, int argument_count) + : HBinaryCall(context, function, argument_count) { + } + Handle<JSFunction> known_function_; int formal_parameter_count_; }; @@ -2162,10 +2216,9 @@ class HInvokeFunction V8_FINAL : public HBinaryCall { class HCallConstantFunction V8_FINAL : public HCall<0> { public: - HCallConstantFunction(Handle<JSFunction> function, int argument_count) - : HCall<0>(argument_count), - function_(function), - formal_parameter_count_(function->shared()->formal_parameter_count()) {} + DECLARE_INSTRUCTION_FACTORY_P2(HCallConstantFunction, + Handle<JSFunction>, + int); Handle<JSFunction> function() const { return function_; } int formal_parameter_count() const { return formal_parameter_count_; } @@ -2184,6 +2237,11 @@ class HCallConstantFunction V8_FINAL : public HCall<0> { DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction) private: + HCallConstantFunction(Handle<JSFunction> function, int argument_count) + : HCall<0>(argument_count), + function_(function), + formal_parameter_count_(function->shared()->formal_parameter_count()) {} + Handle<JSFunction> function_; int formal_parameter_count_; }; @@ -2191,22 +2249,23 @@ class HCallConstantFunction V8_FINAL : public HCall<0> { class HCallKeyed V8_FINAL : public HBinaryCall { public: - HCallKeyed(HValue* context, HValue* key, int argument_count) - : HBinaryCall(context, key, argument_count) { - } + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallKeyed, HValue*, int); HValue* context() { return first(); } HValue* key() { return second(); } DECLARE_CONCRETE_INSTRUCTION(CallKeyed) + + private: + HCallKeyed(HValue* context, HValue* key, int argument_count) + : HBinaryCall(context, key, argument_count) { + } }; class HCallNamed V8_FINAL : public HUnaryCall { public: - HCallNamed(HValue* context, Handle<String> name, int argument_count) - : HUnaryCall(context, argument_count), name_(name) { - } + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallNamed, Handle<String>, int); virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; @@ -2216,42 +2275,33 @@ class HCallNamed V8_FINAL : public HUnaryCall { DECLARE_CONCRETE_INSTRUCTION(CallNamed) private: + HCallNamed(HValue* context, Handle<String> name, int argument_count) + : HUnaryCall(context, argument_count), name_(name) { + } + Handle<String> name_; }; class HCallFunction V8_FINAL : public HBinaryCall { public: - HCallFunction(HValue* context, HValue* function, int argument_count) - : HBinaryCall(context, function, argument_count) { - } - - static HCallFunction* New(Zone* zone, - HValue* context, - HValue* function, - int argument_count) { - return new(zone) HCallFunction(context, function, argument_count); - } + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallFunction, HValue*, int); HValue* context() { return first(); } HValue* function() { return second(); } DECLARE_CONCRETE_INSTRUCTION(CallFunction) + + private: + HCallFunction(HValue* context, HValue* function, int argument_count) + : HBinaryCall(context, function, argument_count) { + } }; class HCallGlobal V8_FINAL : public HUnaryCall { public: - HCallGlobal(HValue* context, Handle<String> name, int argument_count) - : HUnaryCall(context, argument_count), name_(name) { - } - - static HCallGlobal* New(Zone* zone, - HValue* context, - Handle<String> name, - int argument_count) { - return new(zone) HCallGlobal(context, name, argument_count); - } + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallGlobal, Handle<String>, int); virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; @@ -2261,16 +2311,17 @@ class HCallGlobal V8_FINAL : public HUnaryCall { DECLARE_CONCRETE_INSTRUCTION(CallGlobal) private: + HCallGlobal(HValue* context, Handle<String> name, int argument_count) + : HUnaryCall(context, argument_count), name_(name) { + } + Handle<String> name_; }; class HCallKnownGlobal V8_FINAL : public HCall<0> { public: - HCallKnownGlobal(Handle<JSFunction> target, int argument_count) - : HCall<0>(argument_count), - target_(target), - formal_parameter_count_(target->shared()->formal_parameter_count()) { } + DECLARE_INSTRUCTION_FACTORY_P2(HCallKnownGlobal, Handle<JSFunction>, int); virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; @@ -2284,6 +2335,11 @@ class HCallKnownGlobal V8_FINAL : public HCall<0> { DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal) private: + HCallKnownGlobal(Handle<JSFunction> target, int argument_count) + : HCall<0>(argument_count), + target_(target), + formal_parameter_count_(target->shared()->formal_parameter_count()) { } + Handle<JSFunction> target_; int formal_parameter_count_; }; @@ -2291,23 +2347,26 @@ class HCallKnownGlobal V8_FINAL : public HCall<0> { class HCallNew V8_FINAL : public HBinaryCall { public: - HCallNew(HValue* context, HValue* constructor, int argument_count) - : HBinaryCall(context, constructor, argument_count) {} + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallNew, HValue*, int); HValue* context() { return first(); } HValue* constructor() { return second(); } DECLARE_CONCRETE_INSTRUCTION(CallNew) + + private: + HCallNew(HValue* context, HValue* constructor, int argument_count) + : HBinaryCall(context, constructor, argument_count) {} }; class HCallNewArray V8_FINAL : public HBinaryCall { public: - HCallNewArray(HValue* context, HValue* constructor, int argument_count, - Handle<Cell> type_cell, ElementsKind elements_kind) - : HBinaryCall(context, constructor, argument_count), - elements_kind_(elements_kind), - type_cell_(type_cell) {} + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HCallNewArray, + HValue*, + int, + Handle<Cell>, + ElementsKind); HValue* context() { return first(); } HValue* constructor() { return second(); } @@ -2323,6 +2382,12 @@ class HCallNewArray V8_FINAL : public HBinaryCall { DECLARE_CONCRETE_INSTRUCTION(CallNewArray) private: + HCallNewArray(HValue* context, HValue* constructor, int argument_count, + Handle<Cell> type_cell, ElementsKind elements_kind) + : HBinaryCall(context, constructor, argument_count), + elements_kind_(elements_kind), + type_cell_(type_cell) {} + ElementsKind elements_kind_; Handle<Cell> type_cell_; }; @@ -2330,19 +2395,20 @@ class HCallNewArray V8_FINAL : public HBinaryCall { class HCallRuntime V8_FINAL : public HCall<1> { public: - static HCallRuntime* New(Zone* zone, - HValue* context, - Handle<String> name, - const Runtime::Function* c_function, - int argument_count) { - return new(zone) HCallRuntime(context, name, c_function, argument_count); - } + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HCallRuntime, + Handle<String>, + const Runtime::Function*, + int); virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; HValue* context() { return OperandAt(0); } const Runtime::Function* function() const { return c_function_; } Handle<String> name() const { return name_; } + SaveFPRegsMode save_doubles() const { return save_doubles_; } + void set_save_doubles(SaveFPRegsMode save_doubles) { + save_doubles_ = save_doubles; + } virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { return Representation::Tagged(); @@ -2355,12 +2421,14 @@ class HCallRuntime V8_FINAL : public HCall<1> { Handle<String> name, const Runtime::Function* c_function, int argument_count) - : HCall<1>(argument_count), c_function_(c_function), name_(name) { + : HCall<1>(argument_count), c_function_(c_function), name_(name), + save_doubles_(kDontSaveFPRegs) { SetOperandAt(0, context); } const Runtime::Function* c_function_; Handle<String> name_; + SaveFPRegsMode save_doubles_; }; @@ -2509,6 +2577,40 @@ class HUnaryMathOperation V8_FINAL : public HTemplateInstruction<2> { }; +class HLoadRoot V8_FINAL : public HTemplateInstruction<0> { + public: + DECLARE_INSTRUCTION_FACTORY_P1(HLoadRoot, Heap::RootListIndex); + DECLARE_INSTRUCTION_FACTORY_P2(HLoadRoot, Heap::RootListIndex, HType); + + virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { + return Representation::None(); + } + + Heap::RootListIndex index() const { return index_; } + + DECLARE_CONCRETE_INSTRUCTION(LoadRoot) + + protected: + virtual bool DataEquals(HValue* other) V8_OVERRIDE { + HLoadRoot* b = HLoadRoot::cast(other); + return index_ == b->index_; + } + + private: + HLoadRoot(Heap::RootListIndex index, HType type = HType::Tagged()) + : HTemplateInstruction<0>(type), index_(index) { + SetFlag(kUseGVN); + // TODO(bmeurer): We'll need kDependsOnRoots once we add the + // corresponding HStoreRoot instruction. + SetGVNFlag(kDependsOnCalls); + } + + virtual bool IsDeletable() const V8_OVERRIDE { return true; } + + const Heap::RootListIndex index_; +}; + + class HLoadExternalArrayPointer V8_FINAL : public HUnaryOperation { public: DECLARE_INSTRUCTION_FACTORY_P1(HLoadExternalArrayPointer, HValue*); @@ -2553,7 +2655,6 @@ class HCheckMaps V8_FINAL : public HTemplateInstruction<2> { for (int i = 0; i < maps->length(); i++) { check_map->Add(maps->at(i), zone); } - check_map->map_set_.Sort(); return check_map; } @@ -2568,38 +2669,26 @@ class HCheckMaps V8_FINAL : public HTemplateInstruction<2> { virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; HValue* value() { return OperandAt(0); } - SmallMapList* map_set() { return &map_set_; } - ZoneList<UniqueValueId>* map_unique_ids() { return &map_unique_ids_; } - bool has_migration_target() { + Unique<Map> first_map() const { return map_set_.at(0); } + UniqueSet<Map> map_set() const { return map_set_; } + + bool has_migration_target() const { return has_migration_target_; } - virtual void FinalizeUniqueValueId() V8_OVERRIDE; - DECLARE_CONCRETE_INSTRUCTION(CheckMaps) protected: virtual bool DataEquals(HValue* other) V8_OVERRIDE { - ASSERT_EQ(map_set_.length(), map_unique_ids_.length()); - HCheckMaps* b = HCheckMaps::cast(other); - // Relies on the fact that map_set has been sorted before. - if (map_unique_ids_.length() != b->map_unique_ids_.length()) { - return false; - } - for (int i = 0; i < map_unique_ids_.length(); i++) { - if (map_unique_ids_.at(i) != b->map_unique_ids_.at(i)) { - return false; - } - } - return true; + return this->map_set_.Equals(&HCheckMaps::cast(other)->map_set_); } virtual int RedefinedOperandIndex() { return 0; } private: void Add(Handle<Map> map, Zone* zone) { - map_set_.Add(map, zone); + map_set_.Add(Unique<Map>(map), zone); if (!has_migration_target_ && map->is_migration_target()) { has_migration_target_ = true; SetGVNFlag(kChangesNewSpacePromotion); @@ -2609,10 +2698,9 @@ class HCheckMaps V8_FINAL : public HTemplateInstruction<2> { // Clients should use one of the static New* methods above. HCheckMaps(HValue* value, Zone *zone, HValue* typecheck) : HTemplateInstruction<2>(value->type()), - omit_(false), has_migration_target_(false), map_unique_ids_(0, zone) { + omit_(false), has_migration_target_(false) { SetOperandAt(0, value); // Use the object value for the dependency if NULL is passed. - // TODO(titzer): do GVN flags already express this dependency? SetOperandAt(1, typecheck != NULL ? typecheck : value); set_representation(Representation::Tagged()); SetFlag(kUseGVN); @@ -2621,36 +2709,33 @@ class HCheckMaps V8_FINAL : public HTemplateInstruction<2> { SetGVNFlag(kDependsOnElementsKind); } - void omit(CompilationInfo* info) { - omit_ = true; - for (int i = 0; i < map_set_.length(); i++) { - Handle<Map> map = map_set_.at(i); - if (!map->CanTransition()) continue; - map->AddDependentCompilationInfo(DependentCode::kPrototypeCheckGroup, - info); - } - } - bool omit_; bool has_migration_target_; - SmallMapList map_set_; - ZoneList<UniqueValueId> map_unique_ids_; + UniqueSet<Map> map_set_; }; class HCheckValue V8_FINAL : public HUnaryOperation { public: static HCheckValue* New(Zone* zone, HValue* context, - HValue* value, Handle<JSFunction> target) { - bool in_new_space = zone->isolate()->heap()->InNewSpace(*target); + HValue* value, Handle<JSFunction> func) { + bool in_new_space = zone->isolate()->heap()->InNewSpace(*func); + // NOTE: We create an uninitialized Unique and initialize it later. + // This is because a JSFunction can move due to GC during graph creation. + // TODO(titzer): This is a migration crutch. Replace with some kind of + // Uniqueness scope later. + Unique<JSFunction> target = Unique<JSFunction>::CreateUninitialized(func); HCheckValue* check = new(zone) HCheckValue(value, target, in_new_space); return check; } static HCheckValue* New(Zone* zone, HValue* context, - HValue* value, Handle<Map> map, UniqueValueId id) { - HCheckValue* check = new(zone) HCheckValue(value, map, false); - check->object_unique_id_ = id; - return check; + HValue* value, Unique<HeapObject> target, + bool object_in_new_space) { + return new(zone) HCheckValue(value, target, object_in_new_space); + } + + virtual void FinalizeUniqueness() V8_OVERRIDE { + object_ = Unique<HeapObject>(object_.handle()); } virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { @@ -2664,11 +2749,7 @@ class HCheckValue V8_FINAL : public HUnaryOperation { virtual void Verify() V8_OVERRIDE; #endif - virtual void FinalizeUniqueValueId() V8_OVERRIDE { - object_unique_id_ = UniqueValueId(object_); - } - - Handle<HeapObject> object() const { return object_; } + Unique<HeapObject> object() const { return object_; } bool object_in_new_space() const { return object_in_new_space_; } DECLARE_CONCRETE_INSTRUCTION(CheckValue) @@ -2676,38 +2757,35 @@ class HCheckValue V8_FINAL : public HUnaryOperation { protected: virtual bool DataEquals(HValue* other) V8_OVERRIDE { HCheckValue* b = HCheckValue::cast(other); - return object_unique_id_ == b->object_unique_id_; + return object_ == b->object_; } private: - HCheckValue(HValue* value, Handle<HeapObject> object, bool in_new_space) + HCheckValue(HValue* value, Unique<HeapObject> object, + bool object_in_new_space) : HUnaryOperation(value, value->type()), - object_(object), object_in_new_space_(in_new_space) { + object_(object), + object_in_new_space_(object_in_new_space) { set_representation(Representation::Tagged()); SetFlag(kUseGVN); } - Handle<HeapObject> object_; - UniqueValueId object_unique_id_; + Unique<HeapObject> object_; bool object_in_new_space_; }; class HCheckInstanceType V8_FINAL : public HUnaryOperation { public: - static HCheckInstanceType* NewIsSpecObject(HValue* value, Zone* zone) { - return new(zone) HCheckInstanceType(value, IS_SPEC_OBJECT); - } - static HCheckInstanceType* NewIsJSArray(HValue* value, Zone* zone) { - return new(zone) HCheckInstanceType(value, IS_JS_ARRAY); - } - static HCheckInstanceType* NewIsString(HValue* value, Zone* zone) { - return new(zone) HCheckInstanceType(value, IS_STRING); - } - static HCheckInstanceType* NewIsInternalizedString( - HValue* value, Zone* zone) { - return new(zone) HCheckInstanceType(value, IS_INTERNALIZED_STRING); - } + enum Check { + IS_SPEC_OBJECT, + IS_JS_ARRAY, + IS_STRING, + IS_INTERNALIZED_STRING, + LAST_INTERVAL_CHECK = IS_JS_ARRAY + }; + + DECLARE_INSTRUCTION_FACTORY_P2(HCheckInstanceType, HValue*, Check); virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; @@ -2735,14 +2813,6 @@ class HCheckInstanceType V8_FINAL : public HUnaryOperation { virtual int RedefinedOperandIndex() { return 0; } private: - enum Check { - IS_SPEC_OBJECT, - IS_JS_ARRAY, - IS_STRING, - IS_INTERNALIZED_STRING, - LAST_INTERVAL_CHECK = IS_JS_ARRAY - }; - const char* GetCheckName(); HCheckInstanceType(HValue* value, Check check) @@ -2784,21 +2854,6 @@ class HCheckSmi V8_FINAL : public HUnaryOperation { }; -class HIsNumberAndBranch V8_FINAL : public HUnaryControlInstruction { - public: - explicit HIsNumberAndBranch(HValue* value) - : HUnaryControlInstruction(value, NULL, NULL) { - SetFlag(kFlexibleRepresentation); - } - - virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { - return Representation::None(); - } - - DECLARE_CONCRETE_INSTRUCTION(IsNumberAndBranch) -}; - - class HCheckHeapObject V8_FINAL : public HUnaryOperation { public: DECLARE_INSTRUCTION_FACTORY_P1(HCheckHeapObject, HValue*); @@ -3090,6 +3145,8 @@ class HPhi V8_FINAL : public HValue { bool IsReceiver() const { return merged_index_ == 0; } bool HasMergedIndex() const { return merged_index_ != kInvalidMergedIndex; } + virtual int position() const V8_OVERRIDE; + int merged_index() const { return merged_index_; } InductionVariableData* induction_variable_data() { @@ -3260,6 +3317,8 @@ class HCapturedObject V8_FINAL : public HDematerializedObject { // Replay effects of this instruction on the given environment. void ReplayEnvironment(HEnvironment* env); + virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; + DECLARE_CONCRETE_INSTRUCTION(CapturedObject) private: @@ -3273,7 +3332,6 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> { DECLARE_INSTRUCTION_FACTORY_P2(HConstant, int32_t, Representation); DECLARE_INSTRUCTION_FACTORY_P1(HConstant, double); DECLARE_INSTRUCTION_FACTORY_P1(HConstant, Handle<Object>); - DECLARE_INSTRUCTION_FACTORY_P2(HConstant, Handle<Map>, UniqueValueId); DECLARE_INSTRUCTION_FACTORY_P1(HConstant, ExternalReference); static HConstant* CreateAndInsertAfter(Zone* zone, @@ -3298,16 +3356,27 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> { return new_constant; } + static HConstant* CreateAndInsertBefore(Zone* zone, + Unique<Object> unique, + bool is_not_in_new_space, + HInstruction* instruction) { + HConstant* new_constant = new(zone) HConstant(unique, + Representation::Tagged(), HType::Tagged(), false, is_not_in_new_space, + false, false); + new_constant->InsertBefore(instruction); + return new_constant; + } + Handle<Object> handle(Isolate* isolate) { - if (handle_.is_null()) { - Factory* factory = isolate->factory(); + if (object_.handle().is_null()) { // Default arguments to is_not_in_new_space depend on this heap number - // to be tenured so that it's guaranteed not be be located in new space. - handle_ = factory->NewNumber(double_value_, TENURED); + // to be tenured so that it's guaranteed not to be located in new space. + object_ = Unique<Object>::CreateUninitialized( + isolate->factory()->NewNumber(double_value_, TENURED)); } AllowDeferredHandleDereference smi_check; - ASSERT(has_int32_value_ || !handle_->IsSmi()); - return handle_; + ASSERT(has_int32_value_ || !object_.handle()->IsSmi()); + return object_.handle(); } bool HasMap(Handle<Map> map) { @@ -3341,16 +3410,18 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> { return false; } - ASSERT(!handle_.is_null()); + ASSERT(!object_.handle().is_null()); Heap* heap = isolate()->heap(); - ASSERT(unique_id_ != UniqueValueId::minus_zero_value(heap)); - ASSERT(unique_id_ != UniqueValueId::nan_value(heap)); - return unique_id_ == UniqueValueId::undefined_value(heap) || - unique_id_ == UniqueValueId::null_value(heap) || - unique_id_ == UniqueValueId::true_value(heap) || - unique_id_ == UniqueValueId::false_value(heap) || - unique_id_ == UniqueValueId::the_hole_value(heap) || - unique_id_ == UniqueValueId::empty_string(heap); + ASSERT(!object_.IsKnownGlobal(heap->minus_zero_value())); + ASSERT(!object_.IsKnownGlobal(heap->nan_value())); + return + object_.IsKnownGlobal(heap->undefined_value()) || + object_.IsKnownGlobal(heap->null_value()) || + object_.IsKnownGlobal(heap->true_value()) || + object_.IsKnownGlobal(heap->false_value()) || + object_.IsKnownGlobal(heap->the_hole_value()) || + object_.IsKnownGlobal(heap->empty_string()) || + object_.IsKnownGlobal(heap->empty_fixed_array()); } bool IsCell() const { @@ -3389,11 +3460,7 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> { if (HasDoubleValue() && FixedDoubleArray::is_the_hole_nan(double_value_)) { return true; } - Heap* heap = isolate()->heap(); - if (!handle_.is_null() && *handle_ == heap->the_hole_value()) { - return true; - } - return false; + return object_.IsKnownGlobal(isolate()->heap()->the_hole_value()); } bool HasNumberValue() const { return has_double_value_; } int32_t NumberValueAsInteger32() const { @@ -3405,12 +3472,12 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> { } bool HasStringValue() const { if (has_double_value_ || has_int32_value_) return false; - ASSERT(!handle_.is_null()); + ASSERT(!object_.handle().is_null()); return type_.IsString(); } Handle<String> StringValue() const { ASSERT(HasStringValue()); - return Handle<String>::cast(handle_); + return Handle<String>::cast(object_.handle()); } bool HasInternalizedStringValue() const { return HasStringValue() && is_internalized_string_; @@ -3434,21 +3501,20 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> { } else if (has_external_reference_value_) { return reinterpret_cast<intptr_t>(external_reference_value_.address()); } else { - ASSERT(!handle_.is_null()); - return unique_id_.Hashcode(); + ASSERT(!object_.handle().is_null()); + return object_.Hashcode(); } } - virtual void FinalizeUniqueValueId() V8_OVERRIDE { + virtual void FinalizeUniqueness() V8_OVERRIDE { if (!has_double_value_ && !has_external_reference_value_) { - ASSERT(!handle_.is_null()); - unique_id_ = UniqueValueId(handle_); + ASSERT(!object_.handle().is_null()); + object_ = Unique<Object>(object_.handle()); } } - bool UniqueValueIdsMatch(UniqueValueId other) { - return !has_double_value_ && !has_external_reference_value_ && - unique_id_ == other; + Unique<Object> GetUnique() const { + return object_; } #ifdef DEBUG @@ -3474,9 +3540,13 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> { external_reference_value_ == other_constant->external_reference_value_; } else { - ASSERT(!handle_.is_null()); - return !other_constant->handle_.is_null() && - unique_id_ == other_constant->unique_id_; + if (other_constant->has_int32_value_ || + other_constant->has_double_value_ || + other_constant->has_external_reference_value_) { + return false; + } + ASSERT(!object_.handle().is_null()); + return other_constant->object_ == object_; } } @@ -3486,33 +3556,30 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> { HConstant(int32_t value, Representation r = Representation::None(), bool is_not_in_new_space = true, - Handle<Object> optional_handle = Handle<Object>::null()); + Unique<Object> optional = Unique<Object>(Handle<Object>::null())); HConstant(double value, Representation r = Representation::None(), bool is_not_in_new_space = true, - Handle<Object> optional_handle = Handle<Object>::null()); - HConstant(Handle<Object> handle, - UniqueValueId unique_id, + Unique<Object> optional = Unique<Object>(Handle<Object>::null())); + HConstant(Unique<Object> unique, Representation r, HType type, bool is_internalized_string, bool is_not_in_new_space, bool is_cell, bool boolean_value); - HConstant(Handle<Map> handle, - UniqueValueId unique_id); + explicit HConstant(ExternalReference reference); void Initialize(Representation r); virtual bool IsDeletable() const V8_OVERRIDE { return true; } - // If this is a numerical constant, handle_ either points to to the + // If this is a numerical constant, object_ either points to the // HeapObject the constant originated from or is null. If the - // constant is non-numeric, handle_ always points to a valid + // constant is non-numeric, object_ always points to a valid // constant HeapObject. - Handle<Object> handle_; - UniqueValueId unique_id_; + Unique<Object> object_; // We store the HConstant in the most specific form safely possible. // The two flags, has_int32_value_ and has_double_value_ tell us if @@ -3649,17 +3716,8 @@ class HWrapReceiver V8_FINAL : public HTemplateInstruction<2> { class HApplyArguments V8_FINAL : public HTemplateInstruction<4> { public: - HApplyArguments(HValue* function, - HValue* receiver, - HValue* length, - HValue* elements) { - set_representation(Representation::Tagged()); - SetOperandAt(0, function); - SetOperandAt(1, receiver); - SetOperandAt(2, length); - SetOperandAt(3, elements); - SetAllSideEffects(); - } + DECLARE_INSTRUCTION_FACTORY_P4(HApplyArguments, HValue*, HValue*, HValue*, + HValue*); virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { // The length is untagged, all other inputs are tagged. @@ -3674,6 +3732,19 @@ class HApplyArguments V8_FINAL : public HTemplateInstruction<4> { HValue* elements() { return OperandAt(3); } DECLARE_CONCRETE_INSTRUCTION(ApplyArguments) + + private: + HApplyArguments(HValue* function, + HValue* receiver, + HValue* length, + HValue* elements) { + set_representation(Representation::Tagged()); + SetOperandAt(0, function); + SetOperandAt(1, receiver); + SetOperandAt(2, length); + SetOperandAt(3, elements); + SetAllSideEffects(); + } }; @@ -3731,13 +3802,7 @@ class HArgumentsLength V8_FINAL : public HUnaryOperation { class HAccessArgumentsAt V8_FINAL : public HTemplateInstruction<3> { public: - HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) { - set_representation(Representation::Tagged()); - SetFlag(kUseGVN); - SetOperandAt(0, arguments); - SetOperandAt(1, length); - SetOperandAt(2, index); - } + DECLARE_INSTRUCTION_FACTORY_P3(HAccessArgumentsAt, HValue*, HValue*, HValue*); virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; @@ -3754,6 +3819,15 @@ class HAccessArgumentsAt V8_FINAL : public HTemplateInstruction<3> { DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt) + private: + HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) { + set_representation(Representation::Tagged()); + SetFlag(kUseGVN); + SetOperandAt(0, arguments); + SetOperandAt(1, length); + SetOperandAt(2, index); + } + virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } }; @@ -3882,13 +3956,14 @@ class HBitwiseBinaryOperation : public HBinaryOperation { } virtual void RepresentationChanged(Representation to) V8_OVERRIDE { - if (!to.IsTagged()) { - ASSERT(to.IsSmiOrInteger32()); - ClearAllSideEffects(); - SetFlag(kUseGVN); - } else { + if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion); + if (to.IsTagged() && + (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) { SetAllSideEffects(); ClearFlag(kUseGVN); + } else { + ClearAllSideEffects(); + SetFlag(kUseGVN); } } @@ -3920,12 +3995,9 @@ class HBitwiseBinaryOperation : public HBinaryOperation { class HMathFloorOfDiv V8_FINAL : public HBinaryOperation { public: - static HMathFloorOfDiv* New(Zone* zone, - HValue* context, - HValue* left, - HValue* right) { - return new(zone) HMathFloorOfDiv(context, left, right); - } + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HMathFloorOfDiv, + HValue*, + HValue*); virtual HValue* EnsureAndPropagateNotMinusZero( BitVector* visited) V8_OVERRIDE; @@ -3961,7 +4033,9 @@ class HArithmeticBinaryOperation : public HBinaryOperation { } virtual void RepresentationChanged(Representation to) V8_OVERRIDE { - if (to.IsTagged()) { + if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion); + if (to.IsTagged() && + (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) { SetAllSideEffects(); ClearFlag(kUseGVN); } else { @@ -3971,7 +4045,6 @@ class HArithmeticBinaryOperation : public HBinaryOperation { } DECLARE_ABSTRACT_INSTRUCTION(ArithmeticBinaryOperation) - private: virtual bool IsDeletable() const V8_OVERRIDE { return true; } }; @@ -3979,16 +4052,8 @@ class HArithmeticBinaryOperation : public HBinaryOperation { class HCompareGeneric V8_FINAL : public HBinaryOperation { public: - HCompareGeneric(HValue* context, - HValue* left, - HValue* right, - Token::Value token) - : HBinaryOperation(context, left, right, HType::Boolean()), - token_(token) { - ASSERT(Token::IsCompareOp(token)); - set_representation(Representation::Tagged()); - SetAllSideEffects(); - } + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HCompareGeneric, HValue*, + HValue*, Token::Value); virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { return index == 0 @@ -4002,19 +4067,28 @@ class HCompareGeneric V8_FINAL : public HBinaryOperation { DECLARE_CONCRETE_INSTRUCTION(CompareGeneric) private: + HCompareGeneric(HValue* context, + HValue* left, + HValue* right, + Token::Value token) + : HBinaryOperation(context, left, right, HType::Boolean()), + token_(token) { + ASSERT(Token::IsCompareOp(token)); + set_representation(Representation::Tagged()); + SetAllSideEffects(); + } + Token::Value token_; }; class HCompareNumericAndBranch : public HTemplateControlInstruction<2, 2> { public: - HCompareNumericAndBranch(HValue* left, HValue* right, Token::Value token) - : token_(token) { - SetFlag(kFlexibleRepresentation); - ASSERT(Token::IsCompareOp(token)); - SetOperandAt(0, left); - SetOperandAt(1, right); - } + DECLARE_INSTRUCTION_FACTORY_P3(HCompareNumericAndBranch, + HValue*, HValue*, Token::Value); + DECLARE_INSTRUCTION_FACTORY_P5(HCompareNumericAndBranch, + HValue*, HValue*, Token::Value, + HBasicBlock*, HBasicBlock*); HValue* left() { return OperandAt(0); } HValue* right() { return OperandAt(1); } @@ -4040,25 +4114,30 @@ class HCompareNumericAndBranch : public HTemplateControlInstruction<2, 2> { DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch) private: + HCompareNumericAndBranch(HValue* left, + HValue* right, + Token::Value token, + HBasicBlock* true_target = NULL, + HBasicBlock* false_target = NULL) + : token_(token) { + SetFlag(kFlexibleRepresentation); + ASSERT(Token::IsCompareOp(token)); + SetOperandAt(0, left); + SetOperandAt(1, right); + SetSuccessorAt(0, true_target); + SetSuccessorAt(1, false_target); + } + Representation observed_input_representation_[2]; Token::Value token_; }; -class HCompareHoleAndBranch V8_FINAL - : public HTemplateControlInstruction<2, 1> { +class HCompareHoleAndBranch V8_FINAL : public HUnaryControlInstruction { public: - // TODO(danno): make this private when the IfBuilder properly constructs - // control flow instructions. - explicit HCompareHoleAndBranch(HValue* object) { - SetFlag(kFlexibleRepresentation); - SetFlag(kAllowUndefinedAsNaN); - SetOperandAt(0, object); - } - DECLARE_INSTRUCTION_FACTORY_P1(HCompareHoleAndBranch, HValue*); - - HValue* object() { return OperandAt(0); } + DECLARE_INSTRUCTION_FACTORY_P3(HCompareHoleAndBranch, HValue*, + HBasicBlock*, HBasicBlock*); virtual void InferRepresentation( HInferRepresentationPhase* h_infer) V8_OVERRIDE; @@ -4067,23 +4146,44 @@ class HCompareHoleAndBranch V8_FINAL return representation(); } - virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; - DECLARE_CONCRETE_INSTRUCTION(CompareHoleAndBranch) + + private: + HCompareHoleAndBranch(HValue* value, + HBasicBlock* true_target = NULL, + HBasicBlock* false_target = NULL) + : HUnaryControlInstruction(value, true_target, false_target) { + SetFlag(kFlexibleRepresentation); + SetFlag(kAllowUndefinedAsNaN); + } }; class HCompareObjectEqAndBranch : public HTemplateControlInstruction<2, 2> { public: - // TODO(danno): make this private when the IfBuilder properly constructs - // control flow instructions. HCompareObjectEqAndBranch(HValue* left, - HValue* right) { + HValue* right, + HBasicBlock* true_target = NULL, + HBasicBlock* false_target = NULL) { + // TODO(danno): make this private when the IfBuilder properly constructs + // control flow instructions. + ASSERT(!left->IsConstant() || + (!HConstant::cast(left)->HasInteger32Value() || + HConstant::cast(left)->HasSmiValue())); + ASSERT(!right->IsConstant() || + (!HConstant::cast(right)->HasInteger32Value() || + HConstant::cast(right)->HasSmiValue())); SetOperandAt(0, left); SetOperandAt(1, right); + SetSuccessorAt(0, true_target); + SetSuccessorAt(1, false_target); } DECLARE_INSTRUCTION_FACTORY_P2(HCompareObjectEqAndBranch, HValue*, HValue*); + DECLARE_INSTRUCTION_FACTORY_P4(HCompareObjectEqAndBranch, HValue*, HValue*, + HBasicBlock*, HBasicBlock*); + + virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE; HValue* left() { return OperandAt(0); } HValue* right() { return OperandAt(1); } @@ -4104,33 +4204,49 @@ class HCompareObjectEqAndBranch : public HTemplateControlInstruction<2, 2> { class HIsObjectAndBranch V8_FINAL : public HUnaryControlInstruction { public: - explicit HIsObjectAndBranch(HValue* value) - : HUnaryControlInstruction(value, NULL, NULL) { } + DECLARE_INSTRUCTION_FACTORY_P1(HIsObjectAndBranch, HValue*); + DECLARE_INSTRUCTION_FACTORY_P3(HIsObjectAndBranch, HValue*, + HBasicBlock*, HBasicBlock*); virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { return Representation::Tagged(); } DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch) + + private: + HIsObjectAndBranch(HValue* value, + HBasicBlock* true_target = NULL, + HBasicBlock* false_target = NULL) + : HUnaryControlInstruction(value, true_target, false_target) {} }; + class HIsStringAndBranch V8_FINAL : public HUnaryControlInstruction { public: - explicit HIsStringAndBranch(HValue* value) - : HUnaryControlInstruction(value, NULL, NULL) { } + DECLARE_INSTRUCTION_FACTORY_P1(HIsStringAndBranch, HValue*); + DECLARE_INSTRUCTION_FACTORY_P3(HIsStringAndBranch, HValue*, + HBasicBlock*, HBasicBlock*); virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { return Representation::Tagged(); } DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch) + + private: + HIsStringAndBranch(HValue* value, + HBasicBlock* true_target = NULL, + HBasicBlock* false_target = NULL) + : HUnaryControlInstruction(value, true_target, false_target) {} }; class HIsSmiAndBranch V8_FINAL : public HUnaryControlInstruction { public: - explicit HIsSmiAndBranch(HValue* value) - : HUnaryControlInstruction(value, NULL, NULL) { } + DECLARE_INSTRUCTION_FACTORY_P1(HIsSmiAndBranch, HValue*); + DECLARE_INSTRUCTION_FACTORY_P3(HIsSmiAndBranch, HValue*, + HBasicBlock*, HBasicBlock*); DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch) @@ -4140,36 +4256,41 @@ class HIsSmiAndBranch V8_FINAL : public HUnaryControlInstruction { protected: virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } + + private: + HIsSmiAndBranch(HValue* value, + HBasicBlock* true_target = NULL, + HBasicBlock* false_target = NULL) + : HUnaryControlInstruction(value, true_target, false_target) {} }; class HIsUndetectableAndBranch V8_FINAL : public HUnaryControlInstruction { public: - explicit HIsUndetectableAndBranch(HValue* value) - : HUnaryControlInstruction(value, NULL, NULL) { } + DECLARE_INSTRUCTION_FACTORY_P1(HIsUndetectableAndBranch, HValue*); + DECLARE_INSTRUCTION_FACTORY_P3(HIsUndetectableAndBranch, HValue*, + HBasicBlock*, HBasicBlock*); virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { return Representation::Tagged(); } DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch) + + private: + HIsUndetectableAndBranch(HValue* value, + HBasicBlock* true_target = NULL, + HBasicBlock* false_target = NULL) + : HUnaryControlInstruction(value, true_target, false_target) {} }; class HStringCompareAndBranch : public HTemplateControlInstruction<2, 3> { public: - HStringCompareAndBranch(HValue* context, - HValue* left, - HValue* right, - Token::Value token) - : token_(token) { - ASSERT(Token::IsCompareOp(token)); - SetOperandAt(0, context); - SetOperandAt(1, left); - SetOperandAt(2, right); - set_representation(Representation::Tagged()); - SetGVNFlag(kChangesNewSpacePromotion); - } + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HStringCompareAndBranch, + HValue*, + HValue*, + Token::Value); HValue* context() { return OperandAt(0); } HValue* left() { return OperandAt(1); } @@ -4189,28 +4310,43 @@ class HStringCompareAndBranch : public HTemplateControlInstruction<2, 3> { DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch) private: + HStringCompareAndBranch(HValue* context, + HValue* left, + HValue* right, + Token::Value token) + : token_(token) { + ASSERT(Token::IsCompareOp(token)); + SetOperandAt(0, context); + SetOperandAt(1, left); + SetOperandAt(2, right); + set_representation(Representation::Tagged()); + SetGVNFlag(kChangesNewSpacePromotion); + } + Token::Value token_; }; class HIsConstructCallAndBranch : public HTemplateControlInstruction<2, 0> { public: + DECLARE_INSTRUCTION_FACTORY_P0(HIsConstructCallAndBranch); + virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { return Representation::None(); } DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch) + private: + HIsConstructCallAndBranch() {} }; class HHasInstanceTypeAndBranch V8_FINAL : public HUnaryControlInstruction { public: - HHasInstanceTypeAndBranch(HValue* value, InstanceType type) - : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { } - HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to) - : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) { - ASSERT(to == LAST_TYPE); // Others not implemented yet in backend. - } + DECLARE_INSTRUCTION_FACTORY_P2( + HHasInstanceTypeAndBranch, HValue*, InstanceType); + DECLARE_INSTRUCTION_FACTORY_P3( + HHasInstanceTypeAndBranch, HValue*, InstanceType, InstanceType); InstanceType from() { return from_; } InstanceType to() { return to_; } @@ -4224,6 +4360,13 @@ class HHasInstanceTypeAndBranch V8_FINAL : public HUnaryControlInstruction { DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch) private: + HHasInstanceTypeAndBranch(HValue* value, InstanceType type) + : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { } + HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to) + : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) { + ASSERT(to == LAST_TYPE); // Others not implemented yet in backend. + } + InstanceType from_; InstanceType to_; // Inclusive range, not all combinations work. }; @@ -4231,23 +4374,22 @@ class HHasInstanceTypeAndBranch V8_FINAL : public HUnaryControlInstruction { class HHasCachedArrayIndexAndBranch V8_FINAL : public HUnaryControlInstruction { public: - explicit HHasCachedArrayIndexAndBranch(HValue* value) - : HUnaryControlInstruction(value, NULL, NULL) { } + DECLARE_INSTRUCTION_FACTORY_P1(HHasCachedArrayIndexAndBranch, HValue*); virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { return Representation::Tagged(); } DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch) + private: + explicit HHasCachedArrayIndexAndBranch(HValue* value) + : HUnaryControlInstruction(value, NULL, NULL) { } }; class HGetCachedArrayIndex V8_FINAL : public HUnaryOperation { public: - explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) { - set_representation(Representation::Tagged()); - SetFlag(kUseGVN); - } + DECLARE_INSTRUCTION_FACTORY_P1(HGetCachedArrayIndex, HValue*); virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { return Representation::Tagged(); @@ -4259,15 +4401,19 @@ class HGetCachedArrayIndex V8_FINAL : public HUnaryOperation { virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } private: + explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) { + set_representation(Representation::Tagged()); + SetFlag(kUseGVN); + } + virtual bool IsDeletable() const V8_OVERRIDE { return true; } }; class HClassOfTestAndBranch V8_FINAL : public HUnaryControlInstruction { public: - HClassOfTestAndBranch(HValue* value, Handle<String> class_name) - : HUnaryControlInstruction(value, NULL, NULL), - class_name_(class_name) { } + DECLARE_INSTRUCTION_FACTORY_P2(HClassOfTestAndBranch, HValue*, + Handle<String>); DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch) @@ -4280,15 +4426,17 @@ class HClassOfTestAndBranch V8_FINAL : public HUnaryControlInstruction { Handle<String> class_name() const { return class_name_; } private: + HClassOfTestAndBranch(HValue* value, Handle<String> class_name) + : HUnaryControlInstruction(value, NULL, NULL), + class_name_(class_name) { } + Handle<String> class_name_; }; class HTypeofIsAndBranch V8_FINAL : public HUnaryControlInstruction { public: - HTypeofIsAndBranch(HValue* value, Handle<String> type_literal) - : HUnaryControlInstruction(value, NULL, NULL), - type_literal_(type_literal) { } + DECLARE_INSTRUCTION_FACTORY_P2(HTypeofIsAndBranch, HValue*, Handle<String>); Handle<String> type_literal() { return type_literal_; } virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; @@ -4300,17 +4448,17 @@ class HTypeofIsAndBranch V8_FINAL : public HUnaryControlInstruction { } private: + HTypeofIsAndBranch(HValue* value, Handle<String> type_literal) + : HUnaryControlInstruction(value, NULL, NULL), + type_literal_(type_literal) { } + Handle<String> type_literal_; }; class HInstanceOf V8_FINAL : public HBinaryOperation { public: - HInstanceOf(HValue* context, HValue* left, HValue* right) - : HBinaryOperation(context, left, right, HType::Boolean()) { - set_representation(Representation::Tagged()); - SetAllSideEffects(); - } + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HInstanceOf, HValue*, HValue*); virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { return Representation::Tagged(); @@ -4319,20 +4467,21 @@ class HInstanceOf V8_FINAL : public HBinaryOperation { virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; DECLARE_CONCRETE_INSTRUCTION(InstanceOf) + + private: + HInstanceOf(HValue* context, HValue* left, HValue* right) + : HBinaryOperation(context, left, right, HType::Boolean()) { + set_representation(Representation::Tagged()); + SetAllSideEffects(); + } }; class HInstanceOfKnownGlobal V8_FINAL : public HTemplateInstruction<2> { public: - HInstanceOfKnownGlobal(HValue* context, - HValue* left, - Handle<JSFunction> right) - : HTemplateInstruction<2>(HType::Boolean()), function_(right) { - SetOperandAt(0, context); - SetOperandAt(1, left); - set_representation(Representation::Tagged()); - SetAllSideEffects(); - } + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HInstanceOfKnownGlobal, + HValue*, + Handle<JSFunction>); HValue* context() { return OperandAt(0); } HValue* left() { return OperandAt(1); } @@ -4345,27 +4494,17 @@ class HInstanceOfKnownGlobal V8_FINAL : public HTemplateInstruction<2> { DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal) private: - Handle<JSFunction> function_; -}; - - -// TODO(mstarzinger): This instruction should be modeled as a load of the map -// field followed by a load of the instance size field once HLoadNamedField is -// flexible enough to accommodate byte-field loads. -class HInstanceSize V8_FINAL : public HTemplateInstruction<1> { - public: - explicit HInstanceSize(HValue* object) { - SetOperandAt(0, object); - set_representation(Representation::Integer32()); - } - - HValue* object() { return OperandAt(0); } - - virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { - return Representation::Tagged(); + HInstanceOfKnownGlobal(HValue* context, + HValue* left, + Handle<JSFunction> right) + : HTemplateInstruction<2>(HType::Boolean()), function_(right) { + SetOperandAt(0, context); + SetOperandAt(1, left); + set_representation(Representation::Tagged()); + SetAllSideEffects(); } - DECLARE_CONCRETE_INSTRUCTION(InstanceSize) + Handle<JSFunction> function_; }; @@ -4410,10 +4549,7 @@ class HPower V8_FINAL : public HTemplateInstruction<2> { class HRandom V8_FINAL : public HTemplateInstruction<1> { public: - explicit HRandom(HValue* global_object) { - SetOperandAt(0, global_object); - set_representation(Representation::Double()); - } + DECLARE_INSTRUCTION_FACTORY_P1(HRandom, HValue*); HValue* global_object() { return OperandAt(0); } @@ -4424,6 +4560,11 @@ class HRandom V8_FINAL : public HTemplateInstruction<1> { DECLARE_CONCRETE_INSTRUCTION(Random) private: + explicit HRandom(HValue* global_object) { + SetOperandAt(0, global_object); + set_representation(Representation::Double()); + } + virtual bool IsDeletable() const V8_OVERRIDE { return true; } }; @@ -4459,8 +4600,19 @@ class HAdd V8_FINAL : public HArithmeticBinaryOperation { } virtual void RepresentationChanged(Representation to) V8_OVERRIDE { - if (to.IsTagged()) ClearFlag(kAllowUndefinedAsNaN); - HArithmeticBinaryOperation::RepresentationChanged(to); + if (to.IsTagged()) { + SetGVNFlag(kChangesNewSpacePromotion); + ClearFlag(kAllowUndefinedAsNaN); + } + if (to.IsTagged() && + (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved() || + left()->ToStringCanBeObserved() || right()->ToStringCanBeObserved())) { + SetAllSideEffects(); + ClearFlag(kUseGVN); + } else { + ClearAllSideEffects(); + SetFlag(kUseGVN); + } } DECLARE_CONCRETE_INSTRUCTION(Add) @@ -4522,10 +4674,12 @@ class HMul V8_FINAL : public HArithmeticBinaryOperation { HValue* right); static HInstruction* NewImul(Zone* zone, - HValue* context, - HValue* left, - HValue* right) { - HMul* mul = new(zone) HMul(context, left, right); + HValue* context, + HValue* left, + HValue* right) { + HInstruction* instr = HMul::New(zone, context, left, right); + if (!instr->IsMul()) return instr; + HMul* mul = HMul::cast(instr); // TODO(mstarzinger): Prevent bailout on minus zero for imul. mul->AssumeRepresentation(Representation::Integer32()); mul->ClearFlag(HValue::kCanOverflow); @@ -4548,6 +4702,8 @@ class HMul V8_FINAL : public HArithmeticBinaryOperation { HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); } + bool MulMinusOne(); + DECLARE_CONCRETE_INSTRUCTION(Mul) protected: @@ -4884,9 +5040,11 @@ class HSar V8_FINAL : public HBitwiseBinaryOperation { class HRor V8_FINAL : public HBitwiseBinaryOperation { public: - HRor(HValue* context, HValue* left, HValue* right) - : HBitwiseBinaryOperation(context, left, right) { - ChangeRepresentation(Representation::Integer32()); + static HInstruction* New(Zone* zone, + HValue* context, + HValue* left, + HValue* right) { + return new(zone) HRor(context, left, right); } virtual void UpdateRepresentation(Representation new_rep, @@ -4900,6 +5058,12 @@ class HRor V8_FINAL : public HBitwiseBinaryOperation { protected: virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } + + private: + HRor(HValue* context, HValue* left, HValue* right) + : HBitwiseBinaryOperation(context, left, right) { + ChangeRepresentation(Representation::Integer32()); + } }; @@ -4971,12 +5135,7 @@ class HParameter V8_FINAL : public HTemplateInstruction<0> { class HCallStub V8_FINAL : public HUnaryCall { public: - HCallStub(HValue* context, CodeStub::Major major_key, int argument_count) - : HUnaryCall(context, argument_count), - major_key_(major_key), - transcendental_type_(TranscendentalCache::kNumberOfCaches) { - } - + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallStub, CodeStub::Major, int); CodeStub::Major major_key() { return major_key_; } HValue* context() { return value(); } @@ -4993,6 +5152,12 @@ class HCallStub V8_FINAL : public HUnaryCall { DECLARE_CONCRETE_INSTRUCTION(CallStub) private: + HCallStub(HValue* context, CodeStub::Major major_key, int argument_count) + : HUnaryCall(context, argument_count), + major_key_(major_key), + transcendental_type_(TranscendentalCache::kNumberOfCaches) { + } + CodeStub::Major major_key_; TranscendentalCache::Type transcendental_type_; }; @@ -5036,24 +5201,20 @@ class HUnknownOSRValue V8_FINAL : public HTemplateInstruction<0> { class HLoadGlobalCell V8_FINAL : public HTemplateInstruction<0> { public: - HLoadGlobalCell(Handle<Cell> cell, PropertyDetails details) - : cell_(cell), details_(details), unique_id_() { - set_representation(Representation::Tagged()); - SetFlag(kUseGVN); - SetGVNFlag(kDependsOnGlobalVars); - } + DECLARE_INSTRUCTION_FACTORY_P2(HLoadGlobalCell, Handle<Cell>, + PropertyDetails); - Handle<Cell> cell() const { return cell_; } + Unique<Cell> cell() const { return cell_; } bool RequiresHoleCheck() const; virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; virtual intptr_t Hashcode() V8_OVERRIDE { - return unique_id_.Hashcode(); + return cell_.Hashcode(); } - virtual void FinalizeUniqueValueId() V8_OVERRIDE { - unique_id_ = UniqueValueId(cell_); + virtual void FinalizeUniqueness() V8_OVERRIDE { + cell_ = Unique<Cell>(cell_.handle()); } virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { @@ -5064,32 +5225,28 @@ class HLoadGlobalCell V8_FINAL : public HTemplateInstruction<0> { protected: virtual bool DataEquals(HValue* other) V8_OVERRIDE { - HLoadGlobalCell* b = HLoadGlobalCell::cast(other); - return unique_id_ == b->unique_id_; + return cell_ == HLoadGlobalCell::cast(other)->cell_; } private: + HLoadGlobalCell(Handle<Cell> cell, PropertyDetails details) + : cell_(Unique<Cell>::CreateUninitialized(cell)), details_(details) { + set_representation(Representation::Tagged()); + SetFlag(kUseGVN); + SetGVNFlag(kDependsOnGlobalVars); + } + virtual bool IsDeletable() const V8_OVERRIDE { return !RequiresHoleCheck(); } - Handle<Cell> cell_; + Unique<Cell> cell_; PropertyDetails details_; - UniqueValueId unique_id_; }; class HLoadGlobalGeneric V8_FINAL : public HTemplateInstruction<2> { public: - HLoadGlobalGeneric(HValue* context, - HValue* global_object, - Handle<Object> name, - bool for_typeof) - : name_(name), - for_typeof_(for_typeof) { - SetOperandAt(0, context); - SetOperandAt(1, global_object); - set_representation(Representation::Tagged()); - SetAllSideEffects(); - } + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HLoadGlobalGeneric, HValue*, + Handle<Object>, bool); HValue* context() { return OperandAt(0); } HValue* global_object() { return OperandAt(1); } @@ -5105,6 +5262,18 @@ class HLoadGlobalGeneric V8_FINAL : public HTemplateInstruction<2> { DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric) private: + HLoadGlobalGeneric(HValue* context, + HValue* global_object, + Handle<Object> name, + bool for_typeof) + : name_(name), + for_typeof_(for_typeof) { + SetOperandAt(0, context); + SetOperandAt(1, global_object); + set_representation(Representation::Tagged()); + SetAllSideEffects(); + } + Handle<Object> name_; bool for_typeof_; }; @@ -5344,7 +5513,7 @@ class HStoreGlobalCell V8_FINAL : public HUnaryOperation { DECLARE_INSTRUCTION_FACTORY_P3(HStoreGlobalCell, HValue*, Handle<PropertyCell>, PropertyDetails); - Handle<PropertyCell> cell() const { return cell_; } + Unique<PropertyCell> cell() const { return cell_; } bool RequiresHoleCheck() { return !details_.IsDontDelete() || details_.IsReadOnly(); } @@ -5352,6 +5521,10 @@ class HStoreGlobalCell V8_FINAL : public HUnaryOperation { return StoringValueNeedsWriteBarrier(value()); } + virtual void FinalizeUniqueness() V8_OVERRIDE { + cell_ = Unique<PropertyCell>(cell_.handle()); + } + virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { return Representation::Tagged(); } @@ -5364,12 +5537,12 @@ class HStoreGlobalCell V8_FINAL : public HUnaryOperation { Handle<PropertyCell> cell, PropertyDetails details) : HUnaryOperation(value), - cell_(cell), + cell_(Unique<PropertyCell>::CreateUninitialized(cell)), details_(details) { SetGVNFlag(kChangesGlobalVars); } - Handle<PropertyCell> cell_; + Unique<PropertyCell> cell_; PropertyDetails details_; }; @@ -5580,6 +5753,18 @@ class HObjectAccess V8_FINAL { kDouble, HeapNumber::kValueOffset, Representation::Double()); } + static HObjectAccess ForHeapNumberValueLowestBits() { + return HObjectAccess(kDouble, + HeapNumber::kValueOffset, + Representation::Integer32()); + } + + static HObjectAccess ForHeapNumberValueHighestBits() { + return HObjectAccess(kDouble, + HeapNumber::kValueOffset + kIntSize, + Representation::Integer32()); + } + static HObjectAccess ForElementsPointer() { return HObjectAccess(kElementsPointer, JSObject::kElementsOffset); } @@ -5601,12 +5786,9 @@ class HObjectAccess V8_FINAL { ? Representation::Smi() : Representation::Tagged()); } - static HObjectAccess ForAllocationSiteTransitionInfo() { - return HObjectAccess(kInobject, AllocationSite::kTransitionInfoOffset); - } - - static HObjectAccess ForAllocationSiteWeakNext() { - return HObjectAccess(kInobject, AllocationSite::kWeakNextOffset); + static HObjectAccess ForAllocationSiteOffset(int offset) { + ASSERT(offset >= HeapObject::kHeaderSize && offset < AllocationSite::kSize); + return HObjectAccess(kInobject, offset); } static HObjectAccess ForAllocationSiteList() { @@ -5669,6 +5851,12 @@ class HObjectAccess V8_FINAL { return HObjectAccess(kMaps, JSObject::kMapOffset); } + static HObjectAccess ForMapInstanceSize() { + return HObjectAccess(kInobject, + Map::kInstanceSizeOffset, + Representation::Byte()); + } + static HObjectAccess ForPropertyCellValue() { return HObjectAccess(kInobject, PropertyCell::kValueOffset); } @@ -5798,7 +5986,9 @@ class HLoadNamedField V8_FINAL : public HTemplateInstruction<1> { SetOperandAt(0, object); Representation representation = access.representation(); - if (representation.IsSmi()) { + if (representation.IsByte()) { + set_representation(Representation::Integer32()); + } else if (representation.IsSmi()) { set_type(HType::Smi()); set_representation(representation); } else if (representation.IsDouble() || @@ -5823,13 +6013,8 @@ class HLoadNamedField V8_FINAL : public HTemplateInstruction<1> { class HLoadNamedGeneric V8_FINAL : public HTemplateInstruction<2> { public: - HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name) - : name_(name) { - SetOperandAt(0, context); - SetOperandAt(1, object); - set_representation(Representation::Tagged()); - SetAllSideEffects(); - } + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HLoadNamedGeneric, HValue*, + Handle<Object>); HValue* context() { return OperandAt(0); } HValue* object() { return OperandAt(1); } @@ -5844,18 +6029,21 @@ class HLoadNamedGeneric V8_FINAL : public HTemplateInstruction<2> { DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric) private: + HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name) + : name_(name) { + SetOperandAt(0, context); + SetOperandAt(1, object); + set_representation(Representation::Tagged()); + SetAllSideEffects(); + } + Handle<Object> name_; }; class HLoadFunctionPrototype V8_FINAL : public HUnaryOperation { public: - explicit HLoadFunctionPrototype(HValue* function) - : HUnaryOperation(function) { - set_representation(Representation::Tagged()); - SetFlag(kUseGVN); - SetGVNFlag(kDependsOnCalls); - } + DECLARE_INSTRUCTION_FACTORY_P1(HLoadFunctionPrototype, HValue*); HValue* function() { return OperandAt(0); } @@ -5867,6 +6055,14 @@ class HLoadFunctionPrototype V8_FINAL : public HUnaryOperation { protected: virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } + + private: + explicit HLoadFunctionPrototype(HValue* function) + : HUnaryOperation(function) { + set_representation(Representation::Tagged()); + SetFlag(kUseGVN); + SetGVNFlag(kDependsOnCalls); + } }; class ArrayInstructionInterface { @@ -6054,14 +6250,8 @@ class HLoadKeyed V8_FINAL class HLoadKeyedGeneric V8_FINAL : public HTemplateInstruction<3> { public: - HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) { - set_representation(Representation::Tagged()); - SetOperandAt(0, obj); - SetOperandAt(1, key); - SetOperandAt(2, context); - SetAllSideEffects(); - } - + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HLoadKeyedGeneric, HValue*, + HValue*); HValue* object() { return OperandAt(0); } HValue* key() { return OperandAt(1); } HValue* context() { return OperandAt(2); } @@ -6076,6 +6266,15 @@ class HLoadKeyedGeneric V8_FINAL : public HTemplateInstruction<3> { virtual HValue* Canonicalize() V8_OVERRIDE; DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric) + + private: + HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) { + set_representation(Representation::Tagged()); + SetOperandAt(0, obj); + SetOperandAt(1, key); + SetOperandAt(2, context); + SetAllSideEffects(); + } }; @@ -6096,11 +6295,14 @@ class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> { if (index == 0 && access().IsExternalMemory()) { // object must be external in case of external memory access return Representation::External(); - } else if (index == 1 && - (field_representation().IsDouble() || - field_representation().IsSmi() || - field_representation().IsInteger32())) { - return field_representation(); + } else if (index == 1) { + if (field_representation().IsByte() || + field_representation().IsInteger32()) { + return Representation::Integer32(); + } else if (field_representation().IsDouble() || + field_representation().IsSmi()) { + return field_representation(); + } } return Representation::Tagged(); } @@ -6191,19 +6393,9 @@ class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> { class HStoreNamedGeneric V8_FINAL : public HTemplateInstruction<3> { public: - HStoreNamedGeneric(HValue* context, - HValue* object, - Handle<String> name, - HValue* value, - StrictModeFlag strict_mode_flag) - : name_(name), - strict_mode_flag_(strict_mode_flag) { - SetOperandAt(0, object); - SetOperandAt(1, value); - SetOperandAt(2, context); - SetAllSideEffects(); - } - + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HStoreNamedGeneric, HValue*, + Handle<String>, HValue*, + StrictModeFlag); HValue* object() { return OperandAt(0); } HValue* value() { return OperandAt(1); } HValue* context() { return OperandAt(2); } @@ -6219,6 +6411,19 @@ class HStoreNamedGeneric V8_FINAL : public HTemplateInstruction<3> { DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric) private: + HStoreNamedGeneric(HValue* context, + HValue* object, + Handle<String> name, + HValue* value, + StrictModeFlag strict_mode_flag) + : name_(name), + strict_mode_flag_(strict_mode_flag) { + SetOperandAt(0, object); + SetOperandAt(1, value); + SetOperandAt(2, context); + SetAllSideEffects(); + } + Handle<String> name_; StrictModeFlag strict_mode_flag_; }; @@ -6367,18 +6572,8 @@ class HStoreKeyed V8_FINAL class HStoreKeyedGeneric V8_FINAL : public HTemplateInstruction<4> { public: - HStoreKeyedGeneric(HValue* context, - HValue* object, - HValue* key, - HValue* value, - StrictModeFlag strict_mode_flag) - : strict_mode_flag_(strict_mode_flag) { - SetOperandAt(0, object); - SetOperandAt(1, key); - SetOperandAt(2, value); - SetOperandAt(3, context); - SetAllSideEffects(); - } + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HStoreKeyedGeneric, HValue*, + HValue*, HValue*, StrictModeFlag); HValue* object() { return OperandAt(0); } HValue* key() { return OperandAt(1); } @@ -6396,6 +6591,19 @@ class HStoreKeyedGeneric V8_FINAL : public HTemplateInstruction<4> { DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric) private: + HStoreKeyedGeneric(HValue* context, + HValue* object, + HValue* key, + HValue* value, + StrictModeFlag strict_mode_flag) + : strict_mode_flag_(strict_mode_flag) { + SetOperandAt(0, object); + SetOperandAt(1, key); + SetOperandAt(2, value); + SetOperandAt(3, context); + SetAllSideEffects(); + } + StrictModeFlag strict_mode_flag_; }; @@ -6417,25 +6625,20 @@ class HTransitionElementsKind V8_FINAL : public HTemplateInstruction<2> { HValue* object() { return OperandAt(0); } HValue* context() { return OperandAt(1); } - Handle<Map> original_map() { return original_map_; } - Handle<Map> transitioned_map() { return transitioned_map_; } + Unique<Map> original_map() { return original_map_; } + Unique<Map> transitioned_map() { return transitioned_map_; } ElementsKind from_kind() { return from_kind_; } ElementsKind to_kind() { return to_kind_; } virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; - virtual void FinalizeUniqueValueId() V8_OVERRIDE { - original_map_unique_id_ = UniqueValueId(original_map_); - transitioned_map_unique_id_ = UniqueValueId(transitioned_map_); - } - DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind) protected: virtual bool DataEquals(HValue* other) V8_OVERRIDE { HTransitionElementsKind* instr = HTransitionElementsKind::cast(other); - return original_map_unique_id_ == instr->original_map_unique_id_ && - transitioned_map_unique_id_ == instr->transitioned_map_unique_id_; + return original_map_ == instr->original_map_ && + transitioned_map_ == instr->transitioned_map_; } private: @@ -6443,10 +6646,8 @@ class HTransitionElementsKind V8_FINAL : public HTemplateInstruction<2> { HValue* object, Handle<Map> original_map, Handle<Map> transitioned_map) - : original_map_(original_map), - transitioned_map_(transitioned_map), - original_map_unique_id_(), - transitioned_map_unique_id_(), + : original_map_(Unique<Map>(original_map)), + transitioned_map_(Unique<Map>(transitioned_map)), from_kind_(original_map->elements_kind()), to_kind_(transitioned_map->elements_kind()) { SetOperandAt(0, object); @@ -6460,10 +6661,8 @@ class HTransitionElementsKind V8_FINAL : public HTemplateInstruction<2> { set_representation(Representation::Tagged()); } - Handle<Map> original_map_; - Handle<Map> transitioned_map_; - UniqueValueId original_map_unique_id_; - UniqueValueId transitioned_map_unique_id_; + Unique<Map> original_map_; + Unique<Map> transitioned_map_; ElementsKind from_kind_; ElementsKind to_kind_; }; @@ -6492,14 +6691,26 @@ class HStringAdd V8_FINAL : public HBinaryOperation { HStringAdd(HValue* context, HValue* left, HValue* right, StringAddFlags flags) : HBinaryOperation(context, left, right, HType::String()), flags_(flags) { set_representation(Representation::Tagged()); - SetFlag(kUseGVN); - SetGVNFlag(kDependsOnMaps); - SetGVNFlag(kChangesNewSpacePromotion); + if (MightHaveSideEffects()) { + SetAllSideEffects(); + } else { + SetFlag(kUseGVN); + SetGVNFlag(kDependsOnMaps); + SetGVNFlag(kChangesNewSpacePromotion); + } } - // No side-effects except possible allocation. - // NOTE: this instruction _does not_ call ToString() on its inputs. - virtual bool IsDeletable() const V8_OVERRIDE { return true; } + bool MightHaveSideEffects() const { + return flags_ != STRING_ADD_CHECK_NONE && + (left()->ToStringCanBeObserved() || right()->ToStringCanBeObserved()); + } + + // No side-effects except possible allocation: + // NOTE: this instruction does not call ToString() on its inputs, when flags_ + // is set to STRING_ADD_CHECK_NONE. + virtual bool IsDeletable() const V8_OVERRIDE { + return !MightHaveSideEffects(); + } const StringAddFlags flags_; }; @@ -6507,12 +6718,9 @@ class HStringAdd V8_FINAL : public HBinaryOperation { class HStringCharCodeAt V8_FINAL : public HTemplateInstruction<3> { public: - static HStringCharCodeAt* New(Zone* zone, - HValue* context, - HValue* string, - HValue* index) { - return new(zone) HStringCharCodeAt(context, string, index); - } + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HStringCharCodeAt, + HValue*, + HValue*); virtual Representation RequiredInputRepresentation(int index) { // The index is supposed to be Integer32. @@ -6616,6 +6824,24 @@ class HMaterializedLiteral : public HTemplateInstruction<V> { class HRegExpLiteral V8_FINAL : public HMaterializedLiteral<1> { public: + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HRegExpLiteral, + Handle<FixedArray>, + Handle<String>, + Handle<String>, + int); + + HValue* context() { return OperandAt(0); } + Handle<FixedArray> literals() { return literals_; } + Handle<String> pattern() { return pattern_; } + Handle<String> flags() { return flags_; } + + virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { + return Representation::Tagged(); + } + + DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral) + + private: HRegExpLiteral(HValue* context, Handle<FixedArray> literals, Handle<String> pattern, @@ -6630,18 +6856,6 @@ class HRegExpLiteral V8_FINAL : public HMaterializedLiteral<1> { set_type(HType::JSObject()); } - HValue* context() { return OperandAt(0); } - Handle<FixedArray> literals() { return literals_; } - Handle<String> pattern() { return pattern_; } - Handle<String> flags() { return flags_; } - - virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { - return Representation::Tagged(); - } - - DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral) - - private: Handle<FixedArray> literals_; Handle<String> pattern_; Handle<String> flags_; @@ -6650,20 +6864,9 @@ class HRegExpLiteral V8_FINAL : public HMaterializedLiteral<1> { class HFunctionLiteral V8_FINAL : public HTemplateInstruction<1> { public: - HFunctionLiteral(HValue* context, - Handle<SharedFunctionInfo> shared, - bool pretenure) - : HTemplateInstruction<1>(HType::JSObject()), - shared_info_(shared), - pretenure_(pretenure), - has_no_literals_(shared->num_literals() == 0), - is_generator_(shared->is_generator()), - language_mode_(shared->language_mode()) { - SetOperandAt(0, context); - set_representation(Representation::Tagged()); - SetGVNFlag(kChangesNewSpacePromotion); - } - + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HFunctionLiteral, + Handle<SharedFunctionInfo>, + bool); HValue* context() { return OperandAt(0); } virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { @@ -6679,6 +6882,20 @@ class HFunctionLiteral V8_FINAL : public HTemplateInstruction<1> { LanguageMode language_mode() const { return language_mode_; } private: + HFunctionLiteral(HValue* context, + Handle<SharedFunctionInfo> shared, + bool pretenure) + : HTemplateInstruction<1>(HType::JSObject()), + shared_info_(shared), + pretenure_(pretenure), + has_no_literals_(shared->num_literals() == 0), + is_generator_(shared->is_generator()), + language_mode_(shared->language_mode()) { + SetOperandAt(0, context); + set_representation(Representation::Tagged()); + SetGVNFlag(kChangesNewSpacePromotion); + } + virtual bool IsDeletable() const V8_OVERRIDE { return true; } Handle<SharedFunctionInfo> shared_info_; @@ -6691,11 +6908,7 @@ class HFunctionLiteral V8_FINAL : public HTemplateInstruction<1> { class HTypeof V8_FINAL : public HTemplateInstruction<2> { public: - explicit HTypeof(HValue* context, HValue* value) { - SetOperandAt(0, context); - SetOperandAt(1, value); - set_representation(Representation::Tagged()); - } + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HTypeof, HValue*); HValue* context() { return OperandAt(0); } HValue* value() { return OperandAt(1); } @@ -6709,6 +6922,12 @@ class HTypeof V8_FINAL : public HTemplateInstruction<2> { DECLARE_CONCRETE_INSTRUCTION(Typeof) private: + explicit HTypeof(HValue* context, HValue* value) { + SetOperandAt(0, context); + SetOperandAt(1, value); + set_representation(Representation::Tagged()); + } + virtual bool IsDeletable() const V8_OVERRIDE { return true; } }; @@ -6753,8 +6972,7 @@ class HToFastProperties V8_FINAL : public HUnaryOperation { ASSERT(value->IsCallRuntime()); #ifdef DEBUG const Runtime::Function* function = HCallRuntime::cast(value)->function(); - ASSERT(function->function_id == Runtime::kCreateObjectLiteral || - function->function_id == Runtime::kCreateObjectLiteralShallow); + ASSERT(function->function_id == Runtime::kCreateObjectLiteral); #endif } @@ -6764,9 +6982,7 @@ class HToFastProperties V8_FINAL : public HUnaryOperation { class HValueOf V8_FINAL : public HUnaryOperation { public: - explicit HValueOf(HValue* value) : HUnaryOperation(value) { - set_representation(Representation::Tagged()); - } + DECLARE_INSTRUCTION_FACTORY_P1(HValueOf, HValue*); virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { return Representation::Tagged(); @@ -6775,16 +6991,17 @@ class HValueOf V8_FINAL : public HUnaryOperation { DECLARE_CONCRETE_INSTRUCTION(ValueOf) private: + explicit HValueOf(HValue* value) : HUnaryOperation(value) { + set_representation(Representation::Tagged()); + } + virtual bool IsDeletable() const V8_OVERRIDE { return true; } }; class HDateField V8_FINAL : public HUnaryOperation { public: - HDateField(HValue* date, Smi* index) - : HUnaryOperation(date), index_(index) { - set_representation(Representation::Tagged()); - } + DECLARE_INSTRUCTION_FACTORY_P2(HDateField, HValue*, Smi*); Smi* index() const { return index_; } @@ -6795,21 +7012,19 @@ class HDateField V8_FINAL : public HUnaryOperation { DECLARE_CONCRETE_INSTRUCTION(DateField) private: + HDateField(HValue* date, Smi* index) + : HUnaryOperation(date), index_(index) { + set_representation(Representation::Tagged()); + } + Smi* index_; }; class HSeqStringSetChar V8_FINAL : public HTemplateInstruction<3> { public: - HSeqStringSetChar(String::Encoding encoding, - HValue* string, - HValue* index, - HValue* value) : encoding_(encoding) { - SetOperandAt(0, string); - SetOperandAt(1, index); - SetOperandAt(2, value); - set_representation(Representation::Tagged()); - } + DECLARE_INSTRUCTION_FACTORY_P4(HSeqStringSetChar, String::Encoding, + HValue*, HValue*, HValue*); String::Encoding encoding() { return encoding_; } HValue* string() { return OperandAt(0); } @@ -6824,6 +7039,16 @@ class HSeqStringSetChar V8_FINAL : public HTemplateInstruction<3> { DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar) private: + HSeqStringSetChar(String::Encoding encoding, + HValue* string, + HValue* index, + HValue* value) : encoding_(encoding) { + SetOperandAt(0, string); + SetOperandAt(1, index); + SetOperandAt(2, value); + set_representation(Representation::Tagged()); + } + String::Encoding encoding_; }; @@ -6867,11 +7092,7 @@ class HCheckMapValue V8_FINAL : public HTemplateInstruction<2> { class HForInPrepareMap V8_FINAL : public HTemplateInstruction<2> { public: - static HForInPrepareMap* New(Zone* zone, - HValue* context, - HValue* object) { - return new(zone) HForInPrepareMap(context, object); - } + DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HForInPrepareMap, HValue*); virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { return Representation::Tagged(); |