| Index: src/hydrogen-instructions.h
|
| ===================================================================
|
| --- src/hydrogen-instructions.h (revision 8778)
|
| +++ src/hydrogen-instructions.h (working copy)
|
| @@ -131,6 +131,7 @@
|
| V(LoadFunctionPrototype) \
|
| V(LoadGlobalCell) \
|
| V(LoadGlobalGeneric) \
|
| + V(LoadKeyedFastDoubleElement) \
|
| V(LoadKeyedFastElement) \
|
| V(LoadKeyedGeneric) \
|
| V(LoadKeyedSpecializedArrayElement) \
|
| @@ -156,6 +157,7 @@
|
| V(StoreContextSlot) \
|
| V(StoreGlobalCell) \
|
| V(StoreGlobalGeneric) \
|
| + V(StoreKeyedFastDoubleElement) \
|
| V(StoreKeyedFastElement) \
|
| V(StoreKeyedGeneric) \
|
| V(StoreKeyedSpecializedArrayElement) \
|
| @@ -182,6 +184,7 @@
|
| V(InobjectFields) \
|
| V(BackingStoreFields) \
|
| V(ArrayElements) \
|
| + V(DoubleArrayElements) \
|
| V(SpecializedArrayElements) \
|
| V(GlobalVars) \
|
| V(Maps) \
|
| @@ -588,9 +591,9 @@
|
| // it would otherwise output what should be a minus zero as an int32 zero.
|
| // If the operation also exists in a form that takes int32 and outputs int32
|
| // then the operation should return its input value so that we can propagate
|
| - // back. There are two operations that need to propagate back to more than
|
| - // one input. They are phi and binary add. They always return NULL and
|
| - // expect the caller to take care of things.
|
| + // back. There are three operations that need to propagate back to more than
|
| + // one input. They are phi and binary div and mul. They always return NULL
|
| + // and expect the caller to take care of things.
|
| virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
|
| visited->Add(id());
|
| return NULL;
|
| @@ -931,8 +934,12 @@
|
|
|
| class HBranch: public HUnaryControlInstruction {
|
| public:
|
| - HBranch(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
|
| - : HUnaryControlInstruction(value, true_target, false_target) {
|
| + HBranch(HValue* value,
|
| + HBasicBlock* true_target,
|
| + HBasicBlock* false_target,
|
| + ToBooleanStub::Types expected_input_types = ToBooleanStub::no_types())
|
| + : HUnaryControlInstruction(value, true_target, false_target),
|
| + expected_input_types_(expected_input_types) {
|
| ASSERT(true_target != NULL && false_target != NULL);
|
| }
|
| explicit HBranch(HValue* value)
|
| @@ -943,7 +950,14 @@
|
| return Representation::None();
|
| }
|
|
|
| + ToBooleanStub::Types expected_input_types() const {
|
| + return expected_input_types_;
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(Branch)
|
| +
|
| + private:
|
| + ToBooleanStub::Types expected_input_types_;
|
| };
|
|
|
|
|
| @@ -1123,40 +1137,19 @@
|
| class HClampToUint8: public HUnaryOperation {
|
| public:
|
| explicit HClampToUint8(HValue* value)
|
| - : HUnaryOperation(value),
|
| - input_rep_(Representation::None()) {
|
| - SetFlag(kFlexibleRepresentation);
|
| - set_representation(Representation::Tagged());
|
| + : HUnaryOperation(value) {
|
| + set_representation(Representation::Integer32());
|
| SetFlag(kUseGVN);
|
| }
|
|
|
| virtual Representation RequiredInputRepresentation(int index) const {
|
| - return input_rep_;
|
| + return Representation::None();
|
| }
|
|
|
| - virtual Representation InferredRepresentation() {
|
| - // TODO(danno): Inference on input types should happen separately from
|
| - // return representation.
|
| - Representation new_rep = value()->representation();
|
| - if (input_rep_.IsNone()) {
|
| - if (!new_rep.IsNone()) {
|
| - input_rep_ = new_rep;
|
| - return Representation::Integer32();
|
| - } else {
|
| - return Representation::None();
|
| - }
|
| - } else {
|
| - return Representation::Integer32();
|
| - }
|
| - }
|
| -
|
| DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
|
|
|
| protected:
|
| virtual bool DataEquals(HValue* other) { return true; }
|
| -
|
| - private:
|
| - Representation input_rep_;
|
| };
|
|
|
|
|
| @@ -1682,12 +1675,14 @@
|
| };
|
|
|
|
|
| -class HJSArrayLength: public HUnaryOperation {
|
| +class HJSArrayLength: public HTemplateInstruction<2> {
|
| public:
|
| - explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
|
| + HJSArrayLength(HValue* value, HValue* typecheck) {
|
| // The length of an array is stored as a tagged value in the array
|
| // object. It is guaranteed to be 32 bit integer, but it can be
|
| // represented as either a smi or heap number.
|
| + SetOperandAt(0, value);
|
| + SetOperandAt(1, typecheck);
|
| set_representation(Representation::Tagged());
|
| SetFlag(kUseGVN);
|
| SetFlag(kDependsOnArrayLengths);
|
| @@ -1698,6 +1693,8 @@
|
| return Representation::Tagged();
|
| }
|
|
|
| + HValue* value() { return OperandAt(0); }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
|
|
|
| protected:
|
| @@ -1913,10 +1910,14 @@
|
| };
|
|
|
|
|
| -class HCheckMap: public HUnaryOperation {
|
| +class HCheckMap: public HTemplateInstruction<2> {
|
| public:
|
| - HCheckMap(HValue* value, Handle<Map> map)
|
| - : HUnaryOperation(value), map_(map) {
|
| + HCheckMap(HValue* value, Handle<Map> map, HValue* typecheck = NULL)
|
| + : map_(map) {
|
| + SetOperandAt(0, value);
|
| + // If callers don't depend on a typecheck, they can pass in NULL. In that
|
| + // case we use a copy of the |value| argument as a dummy value.
|
| + SetOperandAt(1, typecheck != NULL ? typecheck : value);
|
| set_representation(Representation::Tagged());
|
| SetFlag(kUseGVN);
|
| SetFlag(kDependsOnMaps);
|
| @@ -1928,10 +1929,7 @@
|
| virtual void PrintDataTo(StringStream* stream);
|
| virtual HType CalculateInferredType();
|
|
|
| -#ifdef DEBUG
|
| - virtual void Verify();
|
| -#endif
|
| -
|
| + HValue* value() { return OperandAt(0); }
|
| Handle<Map> map() const { return map_; }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(CheckMap)
|
| @@ -1999,10 +1997,6 @@
|
| return Representation::Tagged();
|
| }
|
|
|
| -#ifdef DEBUG
|
| - virtual void Verify();
|
| -#endif
|
| -
|
| virtual HValue* Canonicalize();
|
|
|
| bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
|
| @@ -2477,10 +2471,6 @@
|
| return Representation::Integer32();
|
| }
|
|
|
| -#ifdef DEBUG
|
| - virtual void Verify();
|
| -#endif
|
| -
|
| HValue* index() { return OperandAt(0); }
|
| HValue* length() { return OperandAt(1); }
|
|
|
| @@ -3082,6 +3072,7 @@
|
| HShr(HValue* context, HValue* left, HValue* right)
|
| : HBitwiseBinaryOperation(context, left, right) { }
|
|
|
| + virtual Range* InferRange();
|
| virtual HType CalculateInferredType();
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(Shr)
|
| @@ -3541,6 +3532,37 @@
|
| };
|
|
|
|
|
| +class HLoadKeyedFastDoubleElement: public HTemplateInstruction<2> {
|
| + public:
|
| + HLoadKeyedFastDoubleElement(HValue* elements, HValue* key) {
|
| + SetOperandAt(0, elements);
|
| + SetOperandAt(1, key);
|
| + set_representation(Representation::Double());
|
| + SetFlag(kDependsOnDoubleArrayElements);
|
| + SetFlag(kUseGVN);
|
| + }
|
| +
|
| + HValue* elements() { return OperandAt(0); }
|
| + HValue* key() { return OperandAt(1); }
|
| +
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + // The key is supposed to be Integer32.
|
| + return index == 0
|
| + ? Representation::Tagged()
|
| + : Representation::Integer32();
|
| + }
|
| +
|
| + virtual void PrintDataTo(StringStream* stream);
|
| +
|
| + bool RequiresHoleCheck() const;
|
| +
|
| + DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement)
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| +};
|
| +
|
| +
|
| class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> {
|
| public:
|
| HLoadKeyedSpecializedArrayElement(HValue* external_elements,
|
| @@ -3726,6 +3748,41 @@
|
| };
|
|
|
|
|
| +class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> {
|
| + public:
|
| + HStoreKeyedFastDoubleElement(HValue* elements,
|
| + HValue* key,
|
| + HValue* val) {
|
| + SetOperandAt(0, elements);
|
| + SetOperandAt(1, key);
|
| + SetOperandAt(2, val);
|
| + SetFlag(kChangesDoubleArrayElements);
|
| + }
|
| +
|
| + virtual Representation RequiredInputRepresentation(int index) const {
|
| + if (index == 1) {
|
| + return Representation::Integer32();
|
| + } else if (index == 2) {
|
| + return Representation::Double();
|
| + } else {
|
| + return Representation::Tagged();
|
| + }
|
| + }
|
| +
|
| + HValue* elements() { return OperandAt(0); }
|
| + HValue* key() { return OperandAt(1); }
|
| + HValue* value() { return OperandAt(2); }
|
| +
|
| + bool NeedsWriteBarrier() {
|
| + return StoringValueNeedsWriteBarrier(value());
|
| + }
|
| +
|
| + virtual void PrintDataTo(StringStream* stream);
|
| +
|
| + DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement)
|
| +};
|
| +
|
| +
|
| class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
|
| public:
|
| HStoreKeyedSpecializedArrayElement(HValue* external_elements,
|
|
|