| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 V(BitwiseBinaryOperation) \ | 59 V(BitwiseBinaryOperation) \ |
| 60 V(ControlInstruction) \ | 60 V(ControlInstruction) \ |
| 61 V(Instruction) \ | 61 V(Instruction) \ |
| 62 | 62 |
| 63 | 63 |
| 64 #define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \ | 64 #define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \ |
| 65 V(AbnormalExit) \ | 65 V(AbnormalExit) \ |
| 66 V(AccessArgumentsAt) \ | 66 V(AccessArgumentsAt) \ |
| 67 V(Add) \ | 67 V(Add) \ |
| 68 V(Allocate) \ | 68 V(Allocate) \ |
| 69 V(AllocateObject) \ |
| 69 V(ApplyArguments) \ | 70 V(ApplyArguments) \ |
| 70 V(ArgumentsElements) \ | 71 V(ArgumentsElements) \ |
| 71 V(ArgumentsLength) \ | 72 V(ArgumentsLength) \ |
| 72 V(ArgumentsObject) \ | 73 V(ArgumentsObject) \ |
| 73 V(Bitwise) \ | 74 V(Bitwise) \ |
| 74 V(BitNot) \ | 75 V(BitNot) \ |
| 75 V(BlockEntry) \ | 76 V(BlockEntry) \ |
| 76 V(BoundsCheck) \ | 77 V(BoundsCheck) \ |
| 77 V(BoundsCheckBaseIndexInformation) \ | 78 V(BoundsCheckBaseIndexInformation) \ |
| 78 V(Branch) \ | 79 V(Branch) \ |
| 79 V(CallConstantFunction) \ | 80 V(CallConstantFunction) \ |
| 80 V(CallFunction) \ | 81 V(CallFunction) \ |
| 81 V(CallGlobal) \ | 82 V(CallGlobal) \ |
| 82 V(CallKeyed) \ | 83 V(CallKeyed) \ |
| 83 V(CallKnownGlobal) \ | 84 V(CallKnownGlobal) \ |
| 84 V(CallNamed) \ | 85 V(CallNamed) \ |
| 85 V(CallNew) \ | 86 V(CallNew) \ |
| 86 V(CallNewArray) \ | 87 V(CallNewArray) \ |
| 87 V(CallRuntime) \ | 88 V(CallRuntime) \ |
| 88 V(CallStub) \ | 89 V(CallStub) \ |
| 89 V(Change) \ | 90 V(Change) \ |
| 90 V(CheckFunction) \ | 91 V(CheckFunction) \ |
| 92 V(CheckHeapObject) \ |
| 91 V(CheckInstanceType) \ | 93 V(CheckInstanceType) \ |
| 92 V(CheckMaps) \ | 94 V(CheckMaps) \ |
| 93 V(CheckNonSmi) \ | |
| 94 V(CheckPrototypeMaps) \ | 95 V(CheckPrototypeMaps) \ |
| 95 V(ClampToUint8) \ | 96 V(ClampToUint8) \ |
| 96 V(ClassOfTestAndBranch) \ | 97 V(ClassOfTestAndBranch) \ |
| 97 V(CompareIDAndBranch) \ | 98 V(CompareIDAndBranch) \ |
| 98 V(CompareGeneric) \ | 99 V(CompareGeneric) \ |
| 99 V(CompareObjectEqAndBranch) \ | 100 V(CompareObjectEqAndBranch) \ |
| 100 V(CompareMap) \ | 101 V(CompareMap) \ |
| 101 V(CompareConstantEqAndBranch) \ | 102 V(CompareConstantEqAndBranch) \ |
| 102 V(Constant) \ | 103 V(Constant) \ |
| 103 V(Context) \ | 104 V(Context) \ |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 ASSERT(type_ != kUninitialized); | 427 ASSERT(type_ != kUninitialized); |
| 427 return ((type_ & kJSObject) == kJSObject); | 428 return ((type_ & kJSObject) == kJSObject); |
| 428 } | 429 } |
| 429 | 430 |
| 430 bool IsUninitialized() const { | 431 bool IsUninitialized() const { |
| 431 return type_ == kUninitialized; | 432 return type_ == kUninitialized; |
| 432 } | 433 } |
| 433 | 434 |
| 434 bool IsHeapObject() const { | 435 bool IsHeapObject() const { |
| 435 ASSERT(type_ != kUninitialized); | 436 ASSERT(type_ != kUninitialized); |
| 436 return IsHeapNumber() || IsString() || IsNonPrimitive(); | 437 return IsHeapNumber() || IsString() || IsBoolean() || IsNonPrimitive(); |
| 437 } | 438 } |
| 438 | 439 |
| 439 static HType TypeFromValue(Handle<Object> value); | 440 static HType TypeFromValue(Handle<Object> value); |
| 440 | 441 |
| 441 const char* ToString(); | 442 const char* ToString(); |
| 442 | 443 |
| 443 private: | 444 private: |
| 444 enum Type { | 445 enum Type { |
| 445 kTagged = 0x1, // 0000 0000 0000 0001 | 446 kTagged = 0x1, // 0000 0000 0000 0001 |
| 446 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101 | 447 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101 |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 776 | 777 |
| 777 typedef EnumSet<GVNFlag> GVNFlagSet; | 778 typedef EnumSet<GVNFlag> GVNFlagSet; |
| 778 | 779 |
| 779 | 780 |
| 780 class HValue: public ZoneObject { | 781 class HValue: public ZoneObject { |
| 781 public: | 782 public: |
| 782 static const int kNoNumber = -1; | 783 static const int kNoNumber = -1; |
| 783 | 784 |
| 784 enum Flag { | 785 enum Flag { |
| 785 kFlexibleRepresentation, | 786 kFlexibleRepresentation, |
| 787 kCannotBeTagged, |
| 786 // Participate in Global Value Numbering, i.e. elimination of | 788 // Participate in Global Value Numbering, i.e. elimination of |
| 787 // unnecessary recomputations. If an instruction sets this flag, it must | 789 // unnecessary recomputations. If an instruction sets this flag, it must |
| 788 // implement DataEquals(), which will be used to determine if other | 790 // implement DataEquals(), which will be used to determine if other |
| 789 // occurrences of the instruction are indeed the same. | 791 // occurrences of the instruction are indeed the same. |
| 790 kUseGVN, | 792 kUseGVN, |
| 791 // Track instructions that are dominating side effects. If an instruction | 793 // Track instructions that are dominating side effects. If an instruction |
| 792 // sets this flag, it must implement SetSideEffectDominator() and should | 794 // sets this flag, it must implement SetSideEffectDominator() and should |
| 793 // indicate which side effects to track by setting GVN flags. | 795 // indicate which side effects to track by setting GVN flags. |
| 794 kTrackSideEffectDominators, | 796 kTrackSideEffectDominators, |
| 795 kCanOverflow, | 797 kCanOverflow, |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 | 883 |
| 882 int id() const { return id_; } | 884 int id() const { return id_; } |
| 883 void set_id(int id) { id_ = id; } | 885 void set_id(int id) { id_ = id; } |
| 884 | 886 |
| 885 HUseIterator uses() const { return HUseIterator(use_list_); } | 887 HUseIterator uses() const { return HUseIterator(use_list_); } |
| 886 | 888 |
| 887 virtual bool EmitAtUses() { return false; } | 889 virtual bool EmitAtUses() { return false; } |
| 888 Representation representation() const { return representation_; } | 890 Representation representation() const { return representation_; } |
| 889 void ChangeRepresentation(Representation r) { | 891 void ChangeRepresentation(Representation r) { |
| 890 ASSERT(CheckFlag(kFlexibleRepresentation)); | 892 ASSERT(CheckFlag(kFlexibleRepresentation)); |
| 893 ASSERT(!CheckFlag(kCannotBeTagged) || !r.IsTagged()); |
| 891 RepresentationChanged(r); | 894 RepresentationChanged(r); |
| 892 representation_ = r; | 895 representation_ = r; |
| 893 if (r.IsTagged()) { | 896 if (r.IsTagged()) { |
| 894 // Tagged is the bottom of the lattice, don't go any further. | 897 // Tagged is the bottom of the lattice, don't go any further. |
| 895 ClearFlag(kFlexibleRepresentation); | 898 ClearFlag(kFlexibleRepresentation); |
| 896 } | 899 } |
| 897 } | 900 } |
| 898 virtual void AssumeRepresentation(Representation r); | 901 virtual void AssumeRepresentation(Representation r); |
| 899 | 902 |
| 900 virtual Representation KnownOptimalRepresentation() { | 903 virtual Representation KnownOptimalRepresentation() { |
| 901 Representation r = representation(); | 904 Representation r = representation(); |
| 902 if (r.IsTagged()) { | 905 if (r.IsTagged()) { |
| 903 HType t = type(); | 906 HType t = type(); |
| 904 if (t.IsSmi()) return Representation::Smi(); | 907 if (t.IsSmi()) return Representation::Smi(); |
| 905 if (t.IsHeapNumber()) return Representation::Double(); | 908 if (t.IsHeapNumber()) return Representation::Double(); |
| 906 if (t.IsHeapObject()) return r; | 909 if (t.IsHeapObject()) return r; |
| 907 return Representation::None(); | 910 return Representation::None(); |
| 908 } | 911 } |
| 909 return r; | 912 return r; |
| 910 } | 913 } |
| 911 | 914 |
| 912 HType type() const { return type_; } | 915 HType type() const { return type_; } |
| 913 void set_type(HType new_type) { | 916 void set_type(HType new_type) { |
| 914 ASSERT(new_type.IsSubtypeOf(type_)); | 917 ASSERT(new_type.IsSubtypeOf(type_)); |
| 915 type_ = new_type; | 918 type_ = new_type; |
| 916 } | 919 } |
| 917 | 920 |
| 921 bool IsHeapObject() { |
| 922 return representation_.IsHeapObject() || type_.IsHeapObject(); |
| 923 } |
| 924 |
| 918 // An operation needs to override this function iff: | 925 // An operation needs to override this function iff: |
| 919 // 1) it can produce an int32 output. | 926 // 1) it can produce an int32 output. |
| 920 // 2) the true value of its output can potentially be minus zero. | 927 // 2) the true value of its output can potentially be minus zero. |
| 921 // The implementation must set a flag so that it bails out in the case where | 928 // The implementation must set a flag so that it bails out in the case where |
| 922 // it would otherwise output what should be a minus zero as an int32 zero. | 929 // it would otherwise output what should be a minus zero as an int32 zero. |
| 923 // If the operation also exists in a form that takes int32 and outputs int32 | 930 // If the operation also exists in a form that takes int32 and outputs int32 |
| 924 // then the operation should return its input value so that we can propagate | 931 // then the operation should return its input value so that we can propagate |
| 925 // back. There are three operations that need to propagate back to more than | 932 // back. There are three operations that need to propagate back to more than |
| 926 // one input. They are phi and binary div and mul. They always return NULL | 933 // one input. They are phi and binary div and mul. They always return NULL |
| 927 // and expect the caller to take care of things. | 934 // and expect the caller to take care of things. |
| (...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1589 | 1596 |
| 1590 HValue* value() { return OperandAt(0); } | 1597 HValue* value() { return OperandAt(0); } |
| 1591 }; | 1598 }; |
| 1592 | 1599 |
| 1593 | 1600 |
| 1594 class HBranch: public HUnaryControlInstruction { | 1601 class HBranch: public HUnaryControlInstruction { |
| 1595 public: | 1602 public: |
| 1596 HBranch(HValue* value, | 1603 HBranch(HValue* value, |
| 1597 HBasicBlock* true_target, | 1604 HBasicBlock* true_target, |
| 1598 HBasicBlock* false_target, | 1605 HBasicBlock* false_target, |
| 1599 ToBooleanStub::Types expected_input_types = ToBooleanStub::no_types()) | 1606 ToBooleanStub::Types expected_input_types = ToBooleanStub::Types()) |
| 1600 : HUnaryControlInstruction(value, true_target, false_target), | 1607 : HUnaryControlInstruction(value, true_target, false_target), |
| 1601 expected_input_types_(expected_input_types) { | 1608 expected_input_types_(expected_input_types) { |
| 1602 ASSERT(true_target != NULL && false_target != NULL); | 1609 ASSERT(true_target != NULL && false_target != NULL); |
| 1610 SetFlag(kAllowUndefinedAsNaN); |
| 1603 } | 1611 } |
| 1604 explicit HBranch(HValue* value) | 1612 explicit HBranch(HValue* value) |
| 1605 : HUnaryControlInstruction(value, NULL, NULL) { } | 1613 : HUnaryControlInstruction(value, NULL, NULL) { |
| 1614 SetFlag(kAllowUndefinedAsNaN); |
| 1615 } |
| 1606 HBranch(HValue* value, ToBooleanStub::Types expected_input_types) | 1616 HBranch(HValue* value, ToBooleanStub::Types expected_input_types) |
| 1607 : HUnaryControlInstruction(value, NULL, NULL), | 1617 : HUnaryControlInstruction(value, NULL, NULL), |
| 1608 expected_input_types_(expected_input_types) { } | 1618 expected_input_types_(expected_input_types) { |
| 1609 | 1619 SetFlag(kAllowUndefinedAsNaN); |
| 1620 } |
| 1610 | 1621 |
| 1611 virtual Representation RequiredInputRepresentation(int index) { | 1622 virtual Representation RequiredInputRepresentation(int index) { |
| 1612 return Representation::None(); | 1623 return Representation::None(); |
| 1613 } | 1624 } |
| 1614 virtual Representation observed_input_representation(int index); | 1625 virtual Representation observed_input_representation(int index); |
| 1615 | 1626 |
| 1616 ToBooleanStub::Types expected_input_types() const { | 1627 ToBooleanStub::Types expected_input_types() const { |
| 1617 return expected_input_types_; | 1628 return expected_input_types_; |
| 1618 } | 1629 } |
| 1619 | 1630 |
| (...skipping 1314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2934 HCheckInstanceType(HValue* value, Check check) | 2945 HCheckInstanceType(HValue* value, Check check) |
| 2935 : HUnaryOperation(value), check_(check) { | 2946 : HUnaryOperation(value), check_(check) { |
| 2936 set_representation(Representation::Tagged()); | 2947 set_representation(Representation::Tagged()); |
| 2937 SetFlag(kUseGVN); | 2948 SetFlag(kUseGVN); |
| 2938 } | 2949 } |
| 2939 | 2950 |
| 2940 const Check check_; | 2951 const Check check_; |
| 2941 }; | 2952 }; |
| 2942 | 2953 |
| 2943 | 2954 |
| 2944 class HCheckNonSmi: public HUnaryOperation { | 2955 class HCheckHeapObject: public HUnaryOperation { |
| 2945 public: | 2956 public: |
| 2946 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) { | 2957 explicit HCheckHeapObject(HValue* value) : HUnaryOperation(value) { |
| 2947 set_representation(Representation::Tagged()); | 2958 set_representation(Representation::Tagged()); |
| 2948 SetFlag(kUseGVN); | 2959 SetFlag(kUseGVN); |
| 2949 } | 2960 } |
| 2950 | 2961 |
| 2951 virtual Representation RequiredInputRepresentation(int index) { | 2962 virtual Representation RequiredInputRepresentation(int index) { |
| 2952 return Representation::Tagged(); | 2963 return Representation::Tagged(); |
| 2953 } | 2964 } |
| 2954 | 2965 |
| 2955 virtual HType CalculateInferredType(); | 2966 virtual HType CalculateInferredType(); |
| 2956 | 2967 |
| 2957 #ifdef DEBUG | 2968 #ifdef DEBUG |
| 2958 virtual void Verify(); | 2969 virtual void Verify(); |
| 2959 #endif | 2970 #endif |
| 2960 | 2971 |
| 2961 virtual HValue* Canonicalize() { | 2972 virtual HValue* Canonicalize() { |
| 2962 HType value_type = value()->type(); | 2973 HType value_type = value()->type(); |
| 2963 if (!value_type.IsUninitialized() && | 2974 if (!value_type.IsUninitialized() && value_type.IsHeapObject()) { |
| 2964 (value_type.IsHeapNumber() || | |
| 2965 value_type.IsString() || | |
| 2966 value_type.IsBoolean() || | |
| 2967 value_type.IsNonPrimitive())) { | |
| 2968 return NULL; | 2975 return NULL; |
| 2969 } | 2976 } |
| 2970 return this; | 2977 return this; |
| 2971 } | 2978 } |
| 2972 | 2979 |
| 2973 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi) | 2980 DECLARE_CONCRETE_INSTRUCTION(CheckHeapObject) |
| 2974 | 2981 |
| 2975 protected: | 2982 protected: |
| 2976 virtual bool DataEquals(HValue* other) { return true; } | 2983 virtual bool DataEquals(HValue* other) { return true; } |
| 2977 }; | 2984 }; |
| 2978 | 2985 |
| 2979 | 2986 |
| 2980 class HCheckPrototypeMaps: public HTemplateInstruction<0> { | 2987 class HCheckPrototypeMaps: public HTemplateInstruction<0> { |
| 2981 public: | 2988 public: |
| 2982 HCheckPrototypeMaps(Handle<JSObject> prototype, | 2989 HCheckPrototypeMaps(Handle<JSObject> prototype, |
| 2983 Handle<JSObject> holder, | 2990 Handle<JSObject> holder, |
| (...skipping 1470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4454 } | 4461 } |
| 4455 }; | 4462 }; |
| 4456 | 4463 |
| 4457 | 4464 |
| 4458 class HMod: public HArithmeticBinaryOperation { | 4465 class HMod: public HArithmeticBinaryOperation { |
| 4459 public: | 4466 public: |
| 4460 static HInstruction* New(Zone* zone, | 4467 static HInstruction* New(Zone* zone, |
| 4461 HValue* context, | 4468 HValue* context, |
| 4462 HValue* left, | 4469 HValue* left, |
| 4463 HValue* right, | 4470 HValue* right, |
| 4464 bool has_fixed_right_arg, | 4471 Maybe<int> fixed_right_arg); |
| 4465 int fixed_right_arg_value); | |
| 4466 | 4472 |
| 4467 bool has_fixed_right_arg() const { return has_fixed_right_arg_; } | 4473 Maybe<int> fixed_right_arg() const { return fixed_right_arg_; } |
| 4468 int fixed_right_arg_value() const { return fixed_right_arg_value_; } | |
| 4469 | 4474 |
| 4470 bool HasPowerOf2Divisor() { | 4475 bool HasPowerOf2Divisor() { |
| 4471 if (right()->IsConstant() && | 4476 if (right()->IsConstant() && |
| 4472 HConstant::cast(right())->HasInteger32Value()) { | 4477 HConstant::cast(right())->HasInteger32Value()) { |
| 4473 int32_t value = HConstant::cast(right())->Integer32Value(); | 4478 int32_t value = HConstant::cast(right())->Integer32Value(); |
| 4474 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value)); | 4479 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value)); |
| 4475 } | 4480 } |
| 4476 | 4481 |
| 4477 return false; | 4482 return false; |
| 4478 } | 4483 } |
| 4479 | 4484 |
| 4480 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 4485 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
| 4481 | 4486 |
| 4482 virtual HValue* Canonicalize(); | 4487 virtual HValue* Canonicalize(); |
| 4483 | 4488 |
| 4484 DECLARE_CONCRETE_INSTRUCTION(Mod) | 4489 DECLARE_CONCRETE_INSTRUCTION(Mod) |
| 4485 | 4490 |
| 4486 protected: | 4491 protected: |
| 4487 virtual bool DataEquals(HValue* other) { return true; } | 4492 virtual bool DataEquals(HValue* other) { return true; } |
| 4488 | 4493 |
| 4489 virtual Range* InferRange(Zone* zone); | 4494 virtual Range* InferRange(Zone* zone); |
| 4490 | 4495 |
| 4491 private: | 4496 private: |
| 4492 HMod(HValue* context, | 4497 HMod(HValue* context, |
| 4493 HValue* left, | 4498 HValue* left, |
| 4494 HValue* right, | 4499 HValue* right, |
| 4495 bool has_fixed_right_arg, | 4500 Maybe<int> fixed_right_arg) |
| 4496 int fixed_right_arg_value) | |
| 4497 : HArithmeticBinaryOperation(context, left, right), | 4501 : HArithmeticBinaryOperation(context, left, right), |
| 4498 has_fixed_right_arg_(has_fixed_right_arg), | 4502 fixed_right_arg_(fixed_right_arg) { |
| 4499 fixed_right_arg_value_(fixed_right_arg_value) { | |
| 4500 SetFlag(kCanBeDivByZero); | 4503 SetFlag(kCanBeDivByZero); |
| 4501 SetFlag(kCanOverflow); | 4504 SetFlag(kCanOverflow); |
| 4502 } | 4505 } |
| 4503 | 4506 |
| 4504 const bool has_fixed_right_arg_; | 4507 const Maybe<int> fixed_right_arg_; |
| 4505 const int fixed_right_arg_value_; | |
| 4506 }; | 4508 }; |
| 4507 | 4509 |
| 4508 | 4510 |
| 4509 class HDiv: public HArithmeticBinaryOperation { | 4511 class HDiv: public HArithmeticBinaryOperation { |
| 4510 public: | 4512 public: |
| 4511 static HInstruction* New(Zone* zone, | 4513 static HInstruction* New(Zone* zone, |
| 4512 HValue* context, | 4514 HValue* context, |
| 4513 HValue* left, | 4515 HValue* left, |
| 4514 HValue* right); | 4516 HValue* right); |
| 4515 | 4517 |
| (...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4920 } | 4922 } |
| 4921 | 4923 |
| 4922 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric) | 4924 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric) |
| 4923 | 4925 |
| 4924 private: | 4926 private: |
| 4925 Handle<Object> name_; | 4927 Handle<Object> name_; |
| 4926 bool for_typeof_; | 4928 bool for_typeof_; |
| 4927 }; | 4929 }; |
| 4928 | 4930 |
| 4929 | 4931 |
| 4932 class HAllocateObject: public HTemplateInstruction<1> { |
| 4933 public: |
| 4934 HAllocateObject(HValue* context, Handle<JSFunction> constructor) |
| 4935 : constructor_(constructor) { |
| 4936 SetOperandAt(0, context); |
| 4937 set_representation(Representation::Tagged()); |
| 4938 SetGVNFlag(kChangesNewSpacePromotion); |
| 4939 constructor_initial_map_ = constructor->has_initial_map() |
| 4940 ? Handle<Map>(constructor->initial_map()) |
| 4941 : Handle<Map>::null(); |
| 4942 // If slack tracking finished, the instance size and property counts |
| 4943 // remain unchanged so that we can allocate memory for the object. |
| 4944 ASSERT(!constructor->shared()->IsInobjectSlackTrackingInProgress()); |
| 4945 } |
| 4946 |
| 4947 // Maximum instance size for which allocations will be inlined. |
| 4948 static const int kMaxSize = 64 * kPointerSize; |
| 4949 |
| 4950 HValue* context() { return OperandAt(0); } |
| 4951 Handle<JSFunction> constructor() { return constructor_; } |
| 4952 Handle<Map> constructor_initial_map() { return constructor_initial_map_; } |
| 4953 |
| 4954 virtual Representation RequiredInputRepresentation(int index) { |
| 4955 return Representation::Tagged(); |
| 4956 } |
| 4957 virtual Handle<Map> GetMonomorphicJSObjectMap() { |
| 4958 ASSERT(!constructor_initial_map_.is_null()); |
| 4959 return constructor_initial_map_; |
| 4960 } |
| 4961 virtual HType CalculateInferredType(); |
| 4962 |
| 4963 DECLARE_CONCRETE_INSTRUCTION(AllocateObject) |
| 4964 |
| 4965 private: |
| 4966 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. |
| 4967 // virtual bool IsDeletable() const { return true; } |
| 4968 |
| 4969 Handle<JSFunction> constructor_; |
| 4970 Handle<Map> constructor_initial_map_; |
| 4971 }; |
| 4972 |
| 4973 |
| 4930 class HAllocate: public HTemplateInstruction<2> { | 4974 class HAllocate: public HTemplateInstruction<2> { |
| 4931 public: | 4975 public: |
| 4932 enum Flags { | 4976 enum Flags { |
| 4933 CAN_ALLOCATE_IN_NEW_SPACE = 1 << 0, | 4977 CAN_ALLOCATE_IN_NEW_SPACE = 1 << 0, |
| 4934 CAN_ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1, | 4978 CAN_ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1, |
| 4935 CAN_ALLOCATE_IN_OLD_POINTER_SPACE = 1 << 2, | 4979 CAN_ALLOCATE_IN_OLD_POINTER_SPACE = 1 << 2, |
| 4936 ALLOCATE_DOUBLE_ALIGNED = 1 << 3 | 4980 ALLOCATE_DOUBLE_ALIGNED = 1 << 3 |
| 4937 }; | 4981 }; |
| 4938 | 4982 |
| 4939 HAllocate(HValue* context, HValue* size, HType type, Flags flags) | 4983 HAllocate(HValue* context, HValue* size, HType type, Flags flags) |
| 4940 : type_(type), | 4984 : type_(type), |
| 4941 flags_(flags) { | 4985 flags_(flags) { |
| 4942 SetOperandAt(0, context); | 4986 SetOperandAt(0, context); |
| 4943 SetOperandAt(1, size); | 4987 SetOperandAt(1, size); |
| 4944 set_representation(Representation::Tagged()); | 4988 set_representation(Representation::Tagged()); |
| 4945 SetGVNFlag(kChangesNewSpacePromotion); | 4989 SetGVNFlag(kChangesNewSpacePromotion); |
| 4946 } | 4990 } |
| 4947 | 4991 |
| 4948 // Maximum instance size for which allocations will be inlined. | |
| 4949 static const int kMaxInlineSize = 64 * kPointerSize; | |
| 4950 | |
| 4951 static Flags DefaultFlags() { | 4992 static Flags DefaultFlags() { |
| 4952 return CAN_ALLOCATE_IN_NEW_SPACE; | 4993 return CAN_ALLOCATE_IN_NEW_SPACE; |
| 4953 } | 4994 } |
| 4954 | 4995 |
| 4955 static Flags DefaultFlags(ElementsKind kind) { | 4996 static Flags DefaultFlags(ElementsKind kind) { |
| 4956 Flags flags = CAN_ALLOCATE_IN_NEW_SPACE; | 4997 Flags flags = CAN_ALLOCATE_IN_NEW_SPACE; |
| 4957 if (IsFastDoubleElementsKind(kind)) { | 4998 if (IsFastDoubleElementsKind(kind)) { |
| 4958 flags = static_cast<HAllocate::Flags>( | 4999 flags = static_cast<HAllocate::Flags>( |
| 4959 flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED); | 5000 flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED); |
| 4960 } | 5001 } |
| 4961 return flags; | 5002 return flags; |
| 4962 } | 5003 } |
| 4963 | 5004 |
| 4964 HValue* context() { return OperandAt(0); } | 5005 HValue* context() { return OperandAt(0); } |
| 4965 HValue* size() { return OperandAt(1); } | 5006 HValue* size() { return OperandAt(1); } |
| 4966 | 5007 |
| 4967 virtual Representation RequiredInputRepresentation(int index) { | 5008 virtual Representation RequiredInputRepresentation(int index) { |
| 4968 if (index == 0) { | 5009 if (index == 0) { |
| 4969 return Representation::Tagged(); | 5010 return Representation::Tagged(); |
| 4970 } else { | 5011 } else { |
| 4971 return Representation::Integer32(); | 5012 return Representation::Integer32(); |
| 4972 } | 5013 } |
| 4973 } | 5014 } |
| 4974 | 5015 |
| 4975 virtual Handle<Map> GetMonomorphicJSObjectMap() { | |
| 4976 return known_initial_map_; | |
| 4977 } | |
| 4978 | |
| 4979 void set_known_initial_map(Handle<Map> known_initial_map) { | |
| 4980 known_initial_map_ = known_initial_map; | |
| 4981 } | |
| 4982 | |
| 4983 virtual HType CalculateInferredType(); | 5016 virtual HType CalculateInferredType(); |
| 4984 | 5017 |
| 4985 bool CanAllocateInNewSpace() const { | 5018 bool CanAllocateInNewSpace() const { |
| 4986 return (flags_ & CAN_ALLOCATE_IN_NEW_SPACE) != 0; | 5019 return (flags_ & CAN_ALLOCATE_IN_NEW_SPACE) != 0; |
| 4987 } | 5020 } |
| 4988 | 5021 |
| 4989 bool CanAllocateInOldDataSpace() const { | 5022 bool CanAllocateInOldDataSpace() const { |
| 4990 return (flags_ & CAN_ALLOCATE_IN_OLD_DATA_SPACE) != 0; | 5023 return (flags_ & CAN_ALLOCATE_IN_OLD_DATA_SPACE) != 0; |
| 4991 } | 5024 } |
| 4992 | 5025 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 5007 return (flags_ & ALLOCATE_DOUBLE_ALIGNED) != 0; | 5040 return (flags_ & ALLOCATE_DOUBLE_ALIGNED) != 0; |
| 5008 } | 5041 } |
| 5009 | 5042 |
| 5010 virtual void PrintDataTo(StringStream* stream); | 5043 virtual void PrintDataTo(StringStream* stream); |
| 5011 | 5044 |
| 5012 DECLARE_CONCRETE_INSTRUCTION(Allocate) | 5045 DECLARE_CONCRETE_INSTRUCTION(Allocate) |
| 5013 | 5046 |
| 5014 private: | 5047 private: |
| 5015 HType type_; | 5048 HType type_; |
| 5016 Flags flags_; | 5049 Flags flags_; |
| 5017 Handle<Map> known_initial_map_; | |
| 5018 }; | 5050 }; |
| 5019 | 5051 |
| 5020 | 5052 |
| 5021 class HInnerAllocatedObject: public HTemplateInstruction<1> { | 5053 class HInnerAllocatedObject: public HTemplateInstruction<1> { |
| 5022 public: | 5054 public: |
| 5023 HInnerAllocatedObject(HValue* value, int offset) | 5055 HInnerAllocatedObject(HValue* value, int offset) |
| 5024 : offset_(offset) { | 5056 : offset_(offset) { |
| 5025 ASSERT(value->IsAllocate()); | 5057 ASSERT(value->IsAllocate()); |
| 5026 SetOperandAt(0, value); | 5058 SetOperandAt(0, value); |
| 5027 set_representation(Representation::Tagged()); | 5059 set_representation(Representation::Tagged()); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 5051 | 5083 |
| 5052 | 5084 |
| 5053 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, | 5085 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, |
| 5054 HValue* new_space_dominator) { | 5086 HValue* new_space_dominator) { |
| 5055 if (object->IsInnerAllocatedObject()) { | 5087 if (object->IsInnerAllocatedObject()) { |
| 5056 return ReceiverObjectNeedsWriteBarrier( | 5088 return ReceiverObjectNeedsWriteBarrier( |
| 5057 HInnerAllocatedObject::cast(object)->base_object(), | 5089 HInnerAllocatedObject::cast(object)->base_object(), |
| 5058 new_space_dominator); | 5090 new_space_dominator); |
| 5059 } | 5091 } |
| 5060 if (object != new_space_dominator) return true; | 5092 if (object != new_space_dominator) return true; |
| 5093 if (object->IsAllocateObject()) return false; |
| 5061 if (object->IsAllocate()) { | 5094 if (object->IsAllocate()) { |
| 5062 return !HAllocate::cast(object)->GuaranteedInNewSpace(); | 5095 return !HAllocate::cast(object)->GuaranteedInNewSpace(); |
| 5063 } | 5096 } |
| 5064 return true; | 5097 return true; |
| 5065 } | 5098 } |
| 5066 | 5099 |
| 5067 | 5100 |
| 5068 class HStoreGlobalCell: public HUnaryOperation { | 5101 class HStoreGlobalCell: public HUnaryOperation { |
| 5069 public: | 5102 public: |
| 5070 HStoreGlobalCell(HValue* value, | 5103 HStoreGlobalCell(HValue* value, |
| (...skipping 1537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6608 virtual bool IsDeletable() const { return true; } | 6641 virtual bool IsDeletable() const { return true; } |
| 6609 }; | 6642 }; |
| 6610 | 6643 |
| 6611 | 6644 |
| 6612 #undef DECLARE_INSTRUCTION | 6645 #undef DECLARE_INSTRUCTION |
| 6613 #undef DECLARE_CONCRETE_INSTRUCTION | 6646 #undef DECLARE_CONCRETE_INSTRUCTION |
| 6614 | 6647 |
| 6615 } } // namespace v8::internal | 6648 } } // namespace v8::internal |
| 6616 | 6649 |
| 6617 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6650 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |