| Index: src/hydrogen-instructions.h
|
| ===================================================================
|
| --- src/hydrogen-instructions.h (revision 6955)
|
| +++ src/hydrogen-instructions.h (working copy)
|
| @@ -1,4 +1,4 @@
|
| -// Copyright 2010 the V8 project authors. All rights reserved.
|
| +// Copyright 2011 the V8 project authors. All rights reserved.
|
| // Redistribution and use in source and binary forms, with or without
|
| // modification, are permitted provided that the following conditions are
|
| // met:
|
| @@ -46,109 +46,6 @@
|
| class LChunkBuilder;
|
|
|
|
|
| -// Type hierarchy:
|
| -//
|
| -// HValue
|
| -// HInstruction
|
| -// HAccessArgumentsAt
|
| -// HApplyArguments
|
| -// HArgumentsElements
|
| -// HArgumentsLength
|
| -// HArgumentsObject
|
| -// HBinaryOperation
|
| -// HArithmeticBinaryOperation
|
| -// HAdd
|
| -// HDiv
|
| -// HMod
|
| -// HMul
|
| -// HSub
|
| -// HBitwiseBinaryOperation
|
| -// HBitAnd
|
| -// HBitOr
|
| -// HBitXor
|
| -// HSar
|
| -// HShl
|
| -// HShr
|
| -// HBoundsCheck
|
| -// HCompare
|
| -// HCompareJSObjectEq
|
| -// HInstanceOf
|
| -// HInstanceOfKnownGlobal
|
| -// HLoadKeyed
|
| -// HLoadKeyedFastElement
|
| -// HLoadKeyedGeneric
|
| -// HPower
|
| -// HStoreNamed
|
| -// HStoreNamedField
|
| -// HStoreNamedGeneric
|
| -// HBlockEntry
|
| -// HCall
|
| -// HCallConstantFunction
|
| -// HCallFunction
|
| -// HCallGlobal
|
| -// HCallKeyed
|
| -// HCallKnownGlobal
|
| -// HCallNamed
|
| -// HCallNew
|
| -// HCallRuntime
|
| -// HCallStub
|
| -// HCheckPrototypeMaps
|
| -// HConstant
|
| -// HControlInstruction
|
| -// HDeoptimize
|
| -// HGoto
|
| -// HUnaryControlInstruction
|
| -// HBranch
|
| -// HCompareMapAndBranch
|
| -// HReturn
|
| -// HThrow
|
| -// HEnterInlined
|
| -// HFunctionLiteral
|
| -// HGlobalObject
|
| -// HGlobalReceiver
|
| -// HLeaveInlined
|
| -// HLoadGlobal
|
| -// HMaterializedLiteral
|
| -// HArrayLiteral
|
| -// HObjectLiteral
|
| -// HRegExpLiteral
|
| -// HOsrEntry
|
| -// HParameter
|
| -// HSimulate
|
| -// HStackCheck
|
| -// HStoreKeyed
|
| -// HStoreKeyedFastElement
|
| -// HStoreKeyedGeneric
|
| -// HUnaryOperation
|
| -// HBitNot
|
| -// HChange
|
| -// HCheckFunction
|
| -// HCheckInstanceType
|
| -// HCheckMap
|
| -// HCheckNonSmi
|
| -// HCheckSmi
|
| -// HDeleteProperty
|
| -// HFixedArrayLength
|
| -// HJSArrayLength
|
| -// HLoadElements
|
| -// HTypeofIs
|
| -// HLoadNamedField
|
| -// HLoadNamedGeneric
|
| -// HLoadFunctionPrototype
|
| -// HPushArgument
|
| -// HTypeof
|
| -// HUnaryMathOperation
|
| -// HUnaryPredicate
|
| -// HClassOfTest
|
| -// HHasCachedArrayIndex
|
| -// HHasInstanceType
|
| -// HIsNull
|
| -// HIsObject
|
| -// HIsSmi
|
| -// HValueOf
|
| -// HUnknownOSRValue
|
| -// HPhi
|
| -
|
| #define HYDROGEN_ALL_INSTRUCTION_LIST(V) \
|
| V(ArithmeticBinaryOperation) \
|
| V(BinaryOperation) \
|
| @@ -180,7 +77,6 @@
|
| V(BitXor) \
|
| V(BlockEntry) \
|
| V(BoundsCheck) \
|
| - V(Branch) \
|
| V(CallConstantFunction) \
|
| V(CallFunction) \
|
| V(CallGlobal) \
|
| @@ -199,7 +95,7 @@
|
| V(CheckSmi) \
|
| V(Compare) \
|
| V(CompareJSObjectEq) \
|
| - V(CompareMapAndBranch) \
|
| + V(CompareMap) \
|
| V(Constant) \
|
| V(DeleteProperty) \
|
| V(Deoptimize) \
|
| @@ -220,13 +116,14 @@
|
| V(JSArrayLength) \
|
| V(ClassOfTest) \
|
| V(LeaveInlined) \
|
| + V(LoadContextSlot) \
|
| V(LoadElements) \
|
| + V(LoadFunctionPrototype) \
|
| V(LoadGlobal) \
|
| V(LoadKeyedFastElement) \
|
| V(LoadKeyedGeneric) \
|
| V(LoadNamedField) \
|
| V(LoadNamedGeneric) \
|
| - V(LoadFunctionPrototype) \
|
| V(Mod) \
|
| V(Mul) \
|
| V(ObjectLiteral) \
|
| @@ -246,7 +143,10 @@
|
| V(StoreKeyedGeneric) \
|
| V(StoreNamedField) \
|
| V(StoreNamedGeneric) \
|
| + V(StringCharCodeAt) \
|
| + V(StringLength) \
|
| V(Sub) \
|
| + V(Test) \
|
| V(Throw) \
|
| V(Typeof) \
|
| V(TypeofIs) \
|
| @@ -262,7 +162,6 @@
|
| V(GlobalVars) \
|
| V(Maps) \
|
| V(ArrayLengths) \
|
| - V(FunctionPrototypes) \
|
| V(OsrEntries)
|
|
|
| #define DECLARE_INSTRUCTION(type) \
|
| @@ -567,11 +466,6 @@
|
| return flags << kChangesToDependsFlagsLeftShift;
|
| }
|
|
|
| - // A flag mask to mark an instruction as having arbitrary side effects.
|
| - static int AllSideEffects() {
|
| - return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
|
| - }
|
| -
|
| static HValue* cast(HValue* value) { return value; }
|
|
|
| enum Opcode {
|
| @@ -630,9 +524,6 @@
|
| return NULL;
|
| }
|
|
|
| - bool HasSideEffects() const {
|
| - return (flags_ & AllSideEffects()) != 0;
|
| - }
|
| bool IsDefinedAfter(HBasicBlock* other) const;
|
|
|
| // Operands.
|
| @@ -655,13 +546,14 @@
|
| void Delete();
|
|
|
| int flags() const { return flags_; }
|
| - void SetFlagMask(int mask) { flags_ |= mask; }
|
| - void SetFlag(Flag f) { SetFlagMask(1 << f); }
|
| - void ClearFlagMask(int mask) { flags_ &= ~mask; }
|
| - void ClearFlag(Flag f) { ClearFlagMask(1 << f); }
|
| - bool CheckFlag(Flag f) const { return CheckFlagMask(1 << f); }
|
| - bool CheckFlagMask(int mask) const { return (flags_ & mask) != 0; }
|
| + 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 SetAllSideEffects() { flags_ |= AllSideEffects(); }
|
| + void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
|
| + bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
|
| +
|
| Range* range() const { return range_; }
|
| bool HasRange() const { return range_ != NULL; }
|
| void AddNewRange(Range* r);
|
| @@ -708,11 +600,16 @@
|
| void InsertInputConversion(HInstruction* previous, int index, HType type);
|
|
|
| #ifdef DEBUG
|
| - virtual void Verify() const = 0;
|
| + virtual void Verify() = 0;
|
| #endif
|
|
|
| protected:
|
| - virtual bool DataEquals(HValue* other) const { return true; }
|
| + // This function must be overridden for instructions with flag kUseGVN, to
|
| + // compare the non-Operand parts of the instruction.
|
| + virtual bool DataEquals(HValue* other) const {
|
| + UNREACHABLE();
|
| + return false;
|
| + }
|
| virtual void RepresentationChanged(Representation to) { }
|
| virtual Range* InferRange();
|
| virtual void DeleteFromGraph() = 0;
|
| @@ -729,6 +626,11 @@
|
| }
|
|
|
| private:
|
| + // A flag mask to mark an instruction as having arbitrary side effects.
|
| + static int AllSideEffects() {
|
| + return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
|
| + }
|
| +
|
| void InternalReplaceAtUse(HValue* use, HValue* other);
|
| void RegisterUse(int index, HValue* new_value);
|
|
|
| @@ -768,9 +670,13 @@
|
| virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
|
|
|
| #ifdef DEBUG
|
| - virtual void Verify() const;
|
| + virtual void Verify();
|
| #endif
|
|
|
| + // Returns whether this is some kind of deoptimizing check
|
| + // instruction.
|
| + virtual bool IsCheckInstruction() const { return false; }
|
| +
|
| DECLARE_INSTRUCTION(Instruction)
|
|
|
| protected:
|
| @@ -805,44 +711,55 @@
|
|
|
| class HControlInstruction: public HInstruction {
|
| public:
|
| - virtual HBasicBlock* FirstSuccessor() const { return NULL; }
|
| - virtual HBasicBlock* SecondSuccessor() const { return NULL; }
|
| + HControlInstruction(HBasicBlock* first, HBasicBlock* second)
|
| + : first_successor_(first), second_successor_(second) {
|
| + }
|
|
|
| + HBasicBlock* FirstSuccessor() const { return first_successor_; }
|
| + HBasicBlock* SecondSuccessor() const { return second_successor_; }
|
| +
|
| + virtual void PrintDataTo(StringStream* stream) const;
|
| +
|
| DECLARE_INSTRUCTION(ControlInstruction)
|
| +
|
| + private:
|
| + HBasicBlock* first_successor_;
|
| + HBasicBlock* second_successor_;
|
| };
|
|
|
|
|
| class HDeoptimize: public HControlInstruction {
|
| public:
|
| + HDeoptimize() : HControlInstruction(NULL, NULL) { }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
|
| };
|
|
|
|
|
| class HGoto: public HControlInstruction {
|
| public:
|
| - explicit HGoto(HBasicBlock* destination)
|
| - : destination_(destination),
|
| - include_stack_check_(false) {}
|
| + explicit HGoto(HBasicBlock* target)
|
| + : HControlInstruction(target, NULL), include_stack_check_(false) {
|
| + }
|
|
|
| - virtual HBasicBlock* FirstSuccessor() const { return destination_; }
|
| void set_include_stack_check(bool include_stack_check) {
|
| include_stack_check_ = include_stack_check;
|
| }
|
| bool include_stack_check() const { return include_stack_check_; }
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| -
|
| DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
|
|
|
| private:
|
| - HBasicBlock* destination_;
|
| bool include_stack_check_;
|
| };
|
|
|
|
|
| class HUnaryControlInstruction: public HControlInstruction {
|
| public:
|
| - explicit HUnaryControlInstruction(HValue* value) {
|
| + explicit HUnaryControlInstruction(HValue* value,
|
| + HBasicBlock* true_target,
|
| + HBasicBlock* false_target)
|
| + : HControlInstruction(true_target, false_target) {
|
| SetOperandAt(0, value);
|
| }
|
|
|
| @@ -850,6 +767,8 @@
|
| return Representation::Tagged();
|
| }
|
|
|
| + virtual void PrintDataTo(StringStream* stream) const;
|
| +
|
| HValue* value() const { return OperandAt(0); }
|
| virtual int OperandCount() const { return 1; }
|
| virtual HValue* OperandAt(int index) const { return operands_[index]; }
|
| @@ -866,84 +785,60 @@
|
| };
|
|
|
|
|
| -class HBranch: public HUnaryControlInstruction {
|
| +class HTest: public HUnaryControlInstruction {
|
| public:
|
| - HBranch(HBasicBlock* true_destination,
|
| - HBasicBlock* false_destination,
|
| - HValue* boolean_value)
|
| - : HUnaryControlInstruction(boolean_value),
|
| - true_destination_(true_destination),
|
| - false_destination_(false_destination) {
|
| - ASSERT(true_destination != NULL && false_destination != NULL);
|
| + HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
|
| + : HUnaryControlInstruction(value, true_target, false_target) {
|
| + ASSERT(true_target != NULL && false_target != NULL);
|
| }
|
|
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return Representation::None();
|
| }
|
|
|
| - virtual HBasicBlock* FirstSuccessor() const { return true_destination_; }
|
| - virtual HBasicBlock* SecondSuccessor() const { return false_destination_; }
|
| -
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| -
|
| - DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
|
| -
|
| - private:
|
| - HBasicBlock* true_destination_;
|
| - HBasicBlock* false_destination_;
|
| + DECLARE_CONCRETE_INSTRUCTION(Test, "test")
|
| };
|
|
|
|
|
| -class HCompareMapAndBranch: public HUnaryControlInstruction {
|
| +class HCompareMap: public HUnaryControlInstruction {
|
| public:
|
| - HCompareMapAndBranch(HValue* result,
|
| - Handle<Map> map,
|
| - HBasicBlock* true_destination,
|
| - HBasicBlock* false_destination)
|
| - : HUnaryControlInstruction(result),
|
| - map_(map),
|
| - true_destination_(true_destination),
|
| - false_destination_(false_destination) {
|
| - ASSERT(true_destination != NULL);
|
| - ASSERT(false_destination != NULL);
|
| + HCompareMap(HValue* value,
|
| + Handle<Map> map,
|
| + HBasicBlock* true_target,
|
| + HBasicBlock* false_target)
|
| + : HUnaryControlInstruction(value, true_target, false_target),
|
| + map_(map) {
|
| + ASSERT(true_target != NULL);
|
| + ASSERT(false_target != NULL);
|
| ASSERT(!map.is_null());
|
| }
|
|
|
| - virtual HBasicBlock* FirstSuccessor() const { return true_destination_; }
|
| - virtual HBasicBlock* SecondSuccessor() const { return false_destination_; }
|
| -
|
| - HBasicBlock* true_destination() const { return true_destination_; }
|
| - HBasicBlock* false_destination() const { return false_destination_; }
|
| -
|
| virtual void PrintDataTo(StringStream* stream) const;
|
|
|
| Handle<Map> map() const { return map_; }
|
|
|
| - DECLARE_CONCRETE_INSTRUCTION(CompareMapAndBranch, "compare_map_and_branch")
|
| + DECLARE_CONCRETE_INSTRUCTION(CompareMap, "compare_map")
|
|
|
| private:
|
| Handle<Map> map_;
|
| - HBasicBlock* true_destination_;
|
| - HBasicBlock* false_destination_;
|
| };
|
|
|
|
|
| class HReturn: public HUnaryControlInstruction {
|
| public:
|
| - explicit HReturn(HValue* result) : HUnaryControlInstruction(result) { }
|
| + explicit HReturn(HValue* value)
|
| + : HUnaryControlInstruction(value, NULL, NULL) {
|
| + }
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| -
|
| DECLARE_CONCRETE_INSTRUCTION(Return, "return")
|
| };
|
|
|
|
|
| class HThrow: public HUnaryControlInstruction {
|
| public:
|
| - explicit HThrow(HValue* value) : HUnaryControlInstruction(value) { }
|
| + explicit HThrow(HValue* value)
|
| + : HUnaryControlInstruction(value, NULL, NULL) { }
|
|
|
| - virtual void PrintDataTo(StringStream* stream) const;
|
| -
|
| DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
|
| };
|
|
|
| @@ -1064,7 +959,7 @@
|
| DECLARE_CONCRETE_INSTRUCTION(Simulate, "simulate")
|
|
|
| #ifdef DEBUG
|
| - virtual void Verify() const;
|
| + virtual void Verify();
|
| #endif
|
|
|
| protected:
|
| @@ -1160,6 +1055,9 @@
|
| }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global_object")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| };
|
|
|
|
|
| @@ -1172,6 +1070,9 @@
|
| }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global_receiver")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| };
|
|
|
|
|
| @@ -1363,6 +1264,9 @@
|
| }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js_array_length")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| };
|
|
|
|
|
| @@ -1379,6 +1283,9 @@
|
| }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed_array_length")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| };
|
|
|
|
|
| @@ -1396,6 +1303,9 @@
|
| virtual HType CalculateInferredType() const;
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(BitNot, "bit_not")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| };
|
|
|
|
|
| @@ -1491,6 +1401,9 @@
|
| }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| };
|
|
|
|
|
| @@ -1503,6 +1416,8 @@
|
| SetFlag(kDependsOnMaps);
|
| }
|
|
|
| + virtual bool IsCheckInstruction() const { return true; }
|
| +
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return Representation::Tagged();
|
| }
|
| @@ -1510,7 +1425,7 @@
|
| virtual HType CalculateInferredType() const;
|
|
|
| #ifdef DEBUG
|
| - virtual void Verify() const;
|
| + virtual void Verify();
|
| #endif
|
|
|
| Handle<Map> map() const { return map_; }
|
| @@ -1536,6 +1451,8 @@
|
| SetFlag(kUseGVN);
|
| }
|
|
|
| + virtual bool IsCheckInstruction() const { return true; }
|
| +
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return Representation::Tagged();
|
| }
|
| @@ -1543,7 +1460,7 @@
|
| virtual HType CalculateInferredType() const;
|
|
|
| #ifdef DEBUG
|
| - virtual void Verify() const;
|
| + virtual void Verify();
|
| #endif
|
|
|
| Handle<JSFunction> target() const { return target_; }
|
| @@ -1570,14 +1487,22 @@
|
| ASSERT(first <= last);
|
| set_representation(Representation::Tagged());
|
| SetFlag(kUseGVN);
|
| + if ((FIRST_STRING_TYPE < first && last <= LAST_STRING_TYPE) ||
|
| + (FIRST_STRING_TYPE <= first && last < LAST_STRING_TYPE)) {
|
| + // A particular string instance type can change because of GC or
|
| + // externalization, but the value still remains a string.
|
| + SetFlag(kDependsOnMaps);
|
| + }
|
| }
|
|
|
| + virtual bool IsCheckInstruction() const { return true; }
|
| +
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return Representation::Tagged();
|
| }
|
|
|
| #ifdef DEBUG
|
| - virtual void Verify() const;
|
| + virtual void Verify();
|
| #endif
|
|
|
| static HCheckInstanceType* NewIsJSObjectOrJSFunction(HValue* value);
|
| @@ -1609,6 +1534,8 @@
|
| SetFlag(kUseGVN);
|
| }
|
|
|
| + virtual bool IsCheckInstruction() const { return true; }
|
| +
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return Representation::Tagged();
|
| }
|
| @@ -1616,10 +1543,13 @@
|
| virtual HType CalculateInferredType() const;
|
|
|
| #ifdef DEBUG
|
| - virtual void Verify() const;
|
| + virtual void Verify();
|
| #endif
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check_non_smi")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| };
|
|
|
|
|
| @@ -1631,8 +1561,10 @@
|
| SetFlag(kDependsOnMaps);
|
| }
|
|
|
| + virtual bool IsCheckInstruction() const { return true; }
|
| +
|
| #ifdef DEBUG
|
| - virtual void Verify() const;
|
| + virtual void Verify();
|
| #endif
|
|
|
| Handle<JSObject> prototype() const { return prototype_; }
|
| @@ -1667,16 +1599,21 @@
|
| SetFlag(kUseGVN);
|
| }
|
|
|
| + virtual bool IsCheckInstruction() const { return true; }
|
| +
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return Representation::Tagged();
|
| }
|
| virtual HType CalculateInferredType() const;
|
|
|
| #ifdef DEBUG
|
| - virtual void Verify() const;
|
| + virtual void Verify();
|
| #endif
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check_smi")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| };
|
|
|
|
|
| @@ -1729,7 +1666,7 @@
|
| virtual void PrintTo(StringStream* stream) const;
|
|
|
| #ifdef DEBUG
|
| - virtual void Verify() const;
|
| + virtual void Verify();
|
| #endif
|
|
|
| DECLARE_INSTRUCTION(Phi)
|
| @@ -1817,7 +1754,7 @@
|
| }
|
|
|
| #ifdef DEBUG
|
| - virtual void Verify() const { }
|
| + virtual void Verify() { }
|
| #endif
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(Constant, "constant")
|
| @@ -1936,6 +1873,9 @@
|
| }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments_elements")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| };
|
|
|
|
|
| @@ -1947,6 +1887,9 @@
|
| }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments_length")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| };
|
|
|
|
|
| @@ -1983,6 +1926,8 @@
|
| operands_[index] = value;
|
| }
|
|
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| +
|
| private:
|
| HOperandVector<3> operands_;
|
| };
|
| @@ -1995,18 +1940,23 @@
|
| SetFlag(kUseGVN);
|
| }
|
|
|
| + virtual bool IsCheckInstruction() const { return true; }
|
| +
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| return Representation::Integer32();
|
| }
|
|
|
| #ifdef DEBUG
|
| - virtual void Verify() const;
|
| + virtual void Verify();
|
| #endif
|
|
|
| HValue* index() const { return left(); }
|
| HValue* length() const { return right(); }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds_check")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| };
|
|
|
|
|
| @@ -2014,16 +1964,26 @@
|
| public:
|
| HBitwiseBinaryOperation(HValue* left, HValue* right)
|
| : HBinaryOperation(left, right) {
|
| - // Default to truncating, Integer32, UseGVN.
|
| - set_representation(Representation::Integer32());
|
| - SetFlag(kTruncatingToInt32);
|
| - SetFlag(kUseGVN);
|
| + set_representation(Representation::Tagged());
|
| + SetFlag(kFlexibleRepresentation);
|
| + SetAllSideEffects();
|
| }
|
|
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| - return Representation::Integer32();
|
| + return representation();
|
| }
|
|
|
| + virtual void RepresentationChanged(Representation to) {
|
| + if (!to.IsTagged()) {
|
| + ASSERT(to.IsInteger32());
|
| + ClearAllSideEffects();
|
| + SetFlag(kTruncatingToInt32);
|
| + SetFlag(kUseGVN);
|
| + }
|
| + }
|
| +
|
| + HType CalculateInferredType() const;
|
| +
|
| DECLARE_INSTRUCTION(BitwiseBinaryOperation)
|
| };
|
|
|
| @@ -2034,12 +1994,12 @@
|
| : HBinaryOperation(left, right) {
|
| set_representation(Representation::Tagged());
|
| SetFlag(kFlexibleRepresentation);
|
| - SetFlagMask(AllSideEffects());
|
| + SetAllSideEffects();
|
| }
|
|
|
| virtual void RepresentationChanged(Representation to) {
|
| if (!to.IsTagged()) {
|
| - ClearFlagMask(AllSideEffects());
|
| + ClearAllSideEffects();
|
| SetFlag(kUseGVN);
|
| }
|
| }
|
| @@ -2065,7 +2025,7 @@
|
| : HBinaryOperation(left, right), token_(token) {
|
| ASSERT(Token::IsCompareOp(token));
|
| set_representation(Representation::Tagged());
|
| - SetFlagMask(AllSideEffects());
|
| + SetAllSideEffects();
|
| }
|
|
|
| void SetInputRepresentation(Representation r);
|
| @@ -2114,6 +2074,9 @@
|
| virtual HType CalculateInferredType() const;
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq, "compare-js-object-eq")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| };
|
|
|
|
|
| @@ -2156,6 +2119,9 @@
|
| explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(IsObject, "is_object")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| };
|
|
|
|
|
| @@ -2164,6 +2130,9 @@
|
| explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is_smi")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| };
|
|
|
|
|
| @@ -2200,6 +2169,9 @@
|
| explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has_cached_array_index")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| };
|
|
|
|
|
| @@ -2250,7 +2222,7 @@
|
| public:
|
| HInstanceOf(HValue* left, HValue* right) : HBinaryOperation(left, right) {
|
| set_representation(Representation::Tagged());
|
| - SetFlagMask(AllSideEffects());
|
| + SetAllSideEffects();
|
| }
|
|
|
| virtual bool EmitAtUses() const { return uses()->length() <= 1; }
|
| @@ -2268,7 +2240,7 @@
|
| HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
|
| : HUnaryOperation(left), function_(right) {
|
| set_representation(Representation::Tagged());
|
| - SetFlagMask(AllSideEffects());
|
| + SetAllSideEffects();
|
| }
|
|
|
| Handle<JSFunction> function() { return function_; }
|
| @@ -2298,6 +2270,9 @@
|
| }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(Power, "power")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| };
|
|
|
|
|
| @@ -2320,6 +2295,8 @@
|
| DECLARE_CONCRETE_INSTRUCTION(Add, "add")
|
|
|
| protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| +
|
| virtual Range* InferRange();
|
| };
|
|
|
| @@ -2335,6 +2312,8 @@
|
| DECLARE_CONCRETE_INSTRUCTION(Sub, "sub")
|
|
|
| protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| +
|
| virtual Range* InferRange();
|
| };
|
|
|
| @@ -2355,6 +2334,8 @@
|
| DECLARE_CONCRETE_INSTRUCTION(Mul, "mul")
|
|
|
| protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| +
|
| virtual Range* InferRange();
|
| };
|
|
|
| @@ -2370,6 +2351,8 @@
|
| DECLARE_CONCRETE_INSTRUCTION(Mod, "mod")
|
|
|
| protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| +
|
| virtual Range* InferRange();
|
| };
|
|
|
| @@ -2386,6 +2369,8 @@
|
| DECLARE_CONCRETE_INSTRUCTION(Div, "div")
|
|
|
| protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| +
|
| virtual Range* InferRange();
|
| };
|
|
|
| @@ -2401,6 +2386,8 @@
|
| DECLARE_CONCRETE_INSTRUCTION(BitAnd, "bit_and")
|
|
|
| protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| +
|
| virtual Range* InferRange();
|
| };
|
|
|
| @@ -2414,6 +2401,9 @@
|
| virtual HType CalculateInferredType() const;
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(BitXor, "bit_xor")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| };
|
|
|
|
|
| @@ -2428,6 +2418,8 @@
|
| DECLARE_CONCRETE_INSTRUCTION(BitOr, "bit_or")
|
|
|
| protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| +
|
| virtual Range* InferRange();
|
| };
|
|
|
| @@ -2441,6 +2433,9 @@
|
| virtual HType CalculateInferredType() const;
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(Shl, "shl")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| };
|
|
|
|
|
| @@ -2452,6 +2447,9 @@
|
| virtual HType CalculateInferredType() const;
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(Shr, "shr")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| };
|
|
|
|
|
| @@ -2464,6 +2462,9 @@
|
| virtual HType CalculateInferredType() const;
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(Sar, "sar")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| };
|
|
|
|
|
| @@ -2506,7 +2507,7 @@
|
| argument_count_(argument_count),
|
| transcendental_type_(TranscendentalCache::kNumberOfCaches) {
|
| set_representation(Representation::Tagged());
|
| - SetFlagMask(AllSideEffects());
|
| + SetAllSideEffects();
|
| }
|
|
|
| CodeStub::Major major_key() { return major_key_; }
|
| @@ -2589,14 +2590,41 @@
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(StoreGlobal, "store_global")
|
|
|
| + private:
|
| + Handle<JSGlobalPropertyCell> cell_;
|
| +};
|
| +
|
| +
|
| +class HLoadContextSlot: public HInstruction {
|
| + public:
|
| + HLoadContextSlot(int context_chain_length , int slot_index)
|
| + : context_chain_length_(context_chain_length), slot_index_(slot_index) {
|
| + set_representation(Representation::Tagged());
|
| + SetFlag(kUseGVN);
|
| + SetFlag(kDependsOnCalls);
|
| + }
|
| +
|
| + int context_chain_length() const { return context_chain_length_; }
|
| + int slot_index() const { return slot_index_; }
|
| +
|
| + virtual void PrintDataTo(StringStream* stream) const;
|
| +
|
| + virtual intptr_t Hashcode() const {
|
| + return context_chain_length() * 29 + slot_index();
|
| + }
|
| +
|
| + DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load_context_slot")
|
| +
|
| protected:
|
| virtual bool DataEquals(HValue* other) const {
|
| - HStoreGlobal* b = HStoreGlobal::cast(other);
|
| - return cell_.is_identical_to(b->cell());
|
| + HLoadContextSlot* b = HLoadContextSlot::cast(other);
|
| + return (context_chain_length() == b->context_chain_length())
|
| + && (slot_index() == b->slot_index());
|
| }
|
|
|
| private:
|
| - Handle<JSGlobalPropertyCell> cell_;
|
| + int context_chain_length_;
|
| + int slot_index_;
|
| };
|
|
|
|
|
| @@ -2643,7 +2671,7 @@
|
| HLoadNamedGeneric(HValue* object, Handle<Object> name)
|
| : HUnaryOperation(object), name_(name) {
|
| set_representation(Representation::Tagged());
|
| - SetFlagMask(AllSideEffects());
|
| + SetAllSideEffects();
|
| }
|
|
|
| HValue* object() const { return OperandAt(0); }
|
| @@ -2655,12 +2683,6 @@
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load_named_generic")
|
|
|
| - protected:
|
| - virtual bool DataEquals(HValue* other) const {
|
| - HLoadNamedGeneric* b = HLoadNamedGeneric::cast(other);
|
| - return name_.is_identical_to(b->name_);
|
| - }
|
| -
|
| private:
|
| Handle<Object> name_;
|
| };
|
| @@ -2671,7 +2693,8 @@
|
| explicit HLoadFunctionPrototype(HValue* function)
|
| : HUnaryOperation(function) {
|
| set_representation(Representation::Tagged());
|
| - SetFlagMask(kDependsOnFunctionPrototypes);
|
| + SetFlag(kUseGVN);
|
| + SetFlag(kDependsOnCalls);
|
| }
|
|
|
| HValue* function() const { return OperandAt(0); }
|
| @@ -2720,13 +2743,16 @@
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement,
|
| "load_keyed_fast_element")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| };
|
|
|
|
|
| class HLoadKeyedGeneric: public HLoadKeyed {
|
| public:
|
| HLoadKeyedGeneric(HValue* obj, HValue* key) : HLoadKeyed(obj, key) {
|
| - SetFlagMask(AllSideEffects());
|
| + SetAllSideEffects();
|
| }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load_keyed_generic")
|
| @@ -2762,12 +2788,6 @@
|
|
|
| DECLARE_INSTRUCTION(StoreNamed)
|
|
|
| - protected:
|
| - virtual bool DataEquals(HValue* other) const {
|
| - HStoreNamed* b = HStoreNamed::cast(other);
|
| - return name_.is_identical_to(b->name_);
|
| - }
|
| -
|
| private:
|
| Handle<Object> name_;
|
| };
|
| @@ -2813,7 +2833,7 @@
|
| public:
|
| HStoreNamedGeneric(HValue* obj, Handle<Object> name, HValue* val)
|
| : HStoreNamed(obj, name, val) {
|
| - SetFlagMask(AllSideEffects());
|
| + SetAllSideEffects();
|
| }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store_named_generic")
|
| @@ -2878,13 +2898,68 @@
|
| public:
|
| HStoreKeyedGeneric(HValue* obj, HValue* key, HValue* val)
|
| : HStoreKeyed(obj, key, val) {
|
| - SetFlagMask(AllSideEffects());
|
| + SetAllSideEffects();
|
| }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store_keyed_generic")
|
| };
|
|
|
|
|
| +class HStringCharCodeAt: public HBinaryOperation {
|
| + public:
|
| + HStringCharCodeAt(HValue* string, HValue* index)
|
| + : HBinaryOperation(string, index) {
|
| + set_representation(Representation::Integer32());
|
| + SetFlag(kUseGVN);
|
| + }
|
| +
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + // The index is supposed to be Integer32.
|
| + return (index == 1) ? Representation::Integer32()
|
| + : Representation::Tagged();
|
| + }
|
| +
|
| + HValue* string() const { return OperandAt(0); }
|
| + HValue* index() const { return OperandAt(1); }
|
| +
|
| + DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string_char_code_at")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| +
|
| + virtual Range* InferRange() {
|
| + return new Range(0, String::kMaxUC16CharCode);
|
| + }
|
| +};
|
| +
|
| +
|
| +class HStringLength: public HUnaryOperation {
|
| + public:
|
| + explicit HStringLength(HValue* string) : HUnaryOperation(string) {
|
| + set_representation(Representation::Tagged());
|
| + SetFlag(kUseGVN);
|
| + }
|
| +
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + return Representation::Tagged();
|
| + }
|
| +
|
| + virtual HType CalculateInferredType() const {
|
| + STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
|
| + return HType::Smi();
|
| + }
|
| +
|
| + DECLARE_CONCRETE_INSTRUCTION(StringLength, "string_length")
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) const { return true; }
|
| +
|
| + virtual Range* InferRange() {
|
| + return new Range(0, String::kMaxLength);
|
| + }
|
| +};
|
| +
|
| +
|
| class HMaterializedLiteral: public HInstruction {
|
| public:
|
| HMaterializedLiteral(int index, int depth)
|
| @@ -3012,7 +3087,7 @@
|
| HDeleteProperty(HValue* obj, HValue* key)
|
| : HBinaryOperation(obj, key) {
|
| set_representation(Representation::Tagged());
|
| - SetFlagMask(AllSideEffects());
|
| + SetAllSideEffects();
|
| }
|
|
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
|
|