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 2351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2362 protected: | 2362 protected: |
2363 virtual bool DataEquals(HValue* other) { return true; } | 2363 virtual bool DataEquals(HValue* other) { return true; } |
2364 | 2364 |
2365 private: | 2365 private: |
2366 virtual bool IsDeletable() const { return true; } | 2366 virtual bool IsDeletable() const { return true; } |
2367 }; | 2367 }; |
2368 | 2368 |
2369 | 2369 |
2370 class HUnaryMathOperation: public HTemplateInstruction<2> { | 2370 class HUnaryMathOperation: public HTemplateInstruction<2> { |
2371 public: | 2371 public: |
2372 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op) | 2372 static HInstruction* New(Zone* zone, |
2373 : op_(op) { | 2373 HValue* context, |
2374 SetOperandAt(0, context); | 2374 HValue* value, |
2375 SetOperandAt(1, value); | 2375 BuiltinFunctionId op); |
2376 switch (op) { | |
2377 case kMathFloor: | |
2378 case kMathRound: | |
2379 case kMathCeil: | |
2380 set_representation(Representation::Integer32()); | |
2381 break; | |
2382 case kMathAbs: | |
2383 // Not setting representation here: it is None intentionally. | |
2384 SetFlag(kFlexibleRepresentation); | |
2385 SetGVNFlag(kChangesNewSpacePromotion); | |
2386 break; | |
2387 case kMathSqrt: | |
2388 case kMathPowHalf: | |
2389 case kMathLog: | |
2390 case kMathSin: | |
2391 case kMathCos: | |
2392 case kMathTan: | |
2393 set_representation(Representation::Double()); | |
2394 SetGVNFlag(kChangesNewSpacePromotion); | |
2395 break; | |
2396 case kMathExp: | |
2397 set_representation(Representation::Double()); | |
2398 break; | |
2399 default: | |
2400 UNREACHABLE(); | |
2401 } | |
2402 SetFlag(kUseGVN); | |
2403 } | |
2404 | 2376 |
2405 HValue* context() { return OperandAt(0); } | 2377 HValue* context() { return OperandAt(0); } |
2406 HValue* value() { return OperandAt(1); } | 2378 HValue* value() { return OperandAt(1); } |
2407 | 2379 |
2408 virtual void PrintDataTo(StringStream* stream); | 2380 virtual void PrintDataTo(StringStream* stream); |
2409 | 2381 |
2410 virtual HType CalculateInferredType(); | 2382 virtual HType CalculateInferredType(); |
2411 | 2383 |
2412 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 2384 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
2413 | 2385 |
2414 virtual Representation RequiredInputRepresentation(int index) { | 2386 virtual Representation RequiredInputRepresentation(int index) { |
2415 if (index == 0) { | 2387 if (index == 0) { |
2416 return Representation::Tagged(); | 2388 return Representation::Tagged(); |
2417 } else { | 2389 } else { |
2418 switch (op_) { | 2390 switch (op_) { |
2419 case kMathFloor: | 2391 case kMathFloor: |
2420 case kMathRound: | 2392 case kMathRound: |
2421 case kMathCeil: | |
2422 case kMathSqrt: | 2393 case kMathSqrt: |
2423 case kMathPowHalf: | 2394 case kMathPowHalf: |
2424 case kMathLog: | 2395 case kMathLog: |
2425 case kMathExp: | 2396 case kMathExp: |
2426 case kMathSin: | 2397 case kMathSin: |
2427 case kMathCos: | 2398 case kMathCos: |
2428 case kMathTan: | 2399 case kMathTan: |
2429 return Representation::Double(); | 2400 return Representation::Double(); |
2430 case kMathAbs: | 2401 case kMathAbs: |
2431 return representation(); | 2402 return representation(); |
(...skipping 11 matching lines...) Expand all Loading... |
2443 | 2414 |
2444 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation) | 2415 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation) |
2445 | 2416 |
2446 protected: | 2417 protected: |
2447 virtual bool DataEquals(HValue* other) { | 2418 virtual bool DataEquals(HValue* other) { |
2448 HUnaryMathOperation* b = HUnaryMathOperation::cast(other); | 2419 HUnaryMathOperation* b = HUnaryMathOperation::cast(other); |
2449 return op_ == b->op(); | 2420 return op_ == b->op(); |
2450 } | 2421 } |
2451 | 2422 |
2452 private: | 2423 private: |
| 2424 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op) |
| 2425 : op_(op) { |
| 2426 SetOperandAt(0, context); |
| 2427 SetOperandAt(1, value); |
| 2428 switch (op) { |
| 2429 case kMathFloor: |
| 2430 case kMathRound: |
| 2431 case kMathCeil: |
| 2432 set_representation(Representation::Integer32()); |
| 2433 break; |
| 2434 case kMathAbs: |
| 2435 // Not setting representation here: it is None intentionally. |
| 2436 SetFlag(kFlexibleRepresentation); |
| 2437 SetGVNFlag(kChangesNewSpacePromotion); |
| 2438 break; |
| 2439 case kMathSqrt: |
| 2440 case kMathPowHalf: |
| 2441 case kMathLog: |
| 2442 case kMathSin: |
| 2443 case kMathCos: |
| 2444 case kMathTan: |
| 2445 set_representation(Representation::Double()); |
| 2446 SetGVNFlag(kChangesNewSpacePromotion); |
| 2447 break; |
| 2448 case kMathExp: |
| 2449 set_representation(Representation::Double()); |
| 2450 break; |
| 2451 default: |
| 2452 UNREACHABLE(); |
| 2453 } |
| 2454 SetFlag(kUseGVN); |
| 2455 } |
| 2456 |
2453 virtual bool IsDeletable() const { return true; } | 2457 virtual bool IsDeletable() const { return true; } |
2454 | 2458 |
2455 BuiltinFunctionId op_; | 2459 BuiltinFunctionId op_; |
2456 }; | 2460 }; |
2457 | 2461 |
2458 | 2462 |
2459 class HLoadElements: public HTemplateInstruction<2> { | 2463 class HLoadElements: public HTemplateInstruction<2> { |
2460 public: | 2464 public: |
2461 HLoadElements(HValue* value, HValue* typecheck) { | 2465 HLoadElements(HValue* value, HValue* typecheck) { |
2462 SetOperandAt(0, value); | 2466 SetOperandAt(0, value); |
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3057 return double_value_; | 3061 return double_value_; |
3058 } | 3062 } |
3059 bool HasNumberValue() const { return has_double_value_; } | 3063 bool HasNumberValue() const { return has_double_value_; } |
3060 int32_t NumberValueAsInteger32() const { | 3064 int32_t NumberValueAsInteger32() const { |
3061 ASSERT(HasNumberValue()); | 3065 ASSERT(HasNumberValue()); |
3062 // Irrespective of whether a numeric HConstant can be safely | 3066 // Irrespective of whether a numeric HConstant can be safely |
3063 // represented as an int32, we store the (in some cases lossy) | 3067 // represented as an int32, we store the (in some cases lossy) |
3064 // representation of the number in int32_value_. | 3068 // representation of the number in int32_value_. |
3065 return int32_value_; | 3069 return int32_value_; |
3066 } | 3070 } |
| 3071 bool HasStringValue() const { |
| 3072 if (has_double_value_ || has_int32_value_) return false; |
| 3073 ASSERT(!handle_.is_null()); |
| 3074 return handle_->IsString(); |
| 3075 } |
| 3076 Handle<String> StringValue() const { |
| 3077 ASSERT(HasStringValue()); |
| 3078 return Handle<String>::cast(handle_); |
| 3079 } |
3067 | 3080 |
3068 bool ToBoolean(); | 3081 bool ToBoolean(); |
3069 | 3082 |
3070 bool IsUint32() { | 3083 bool IsUint32() { |
3071 return HasInteger32Value() && (Integer32Value() >= 0); | 3084 return HasInteger32Value() && (Integer32Value() >= 0); |
3072 } | 3085 } |
3073 | 3086 |
3074 virtual intptr_t Hashcode() { | 3087 virtual intptr_t Hashcode() { |
3075 ASSERT_ALLOCATION_DISABLED; | 3088 ASSERT_ALLOCATION_DISABLED; |
3076 intptr_t hash; | 3089 intptr_t hash; |
(...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3877 | 3890 |
3878 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal) | 3891 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal) |
3879 | 3892 |
3880 private: | 3893 private: |
3881 Handle<JSFunction> function_; | 3894 Handle<JSFunction> function_; |
3882 }; | 3895 }; |
3883 | 3896 |
3884 | 3897 |
3885 class HPower: public HTemplateInstruction<2> { | 3898 class HPower: public HTemplateInstruction<2> { |
3886 public: | 3899 public: |
3887 HPower(HValue* left, HValue* right) { | 3900 static HInstruction* New(Zone* zone, HValue* left, HValue* right); |
3888 SetOperandAt(0, left); | |
3889 SetOperandAt(1, right); | |
3890 set_representation(Representation::Double()); | |
3891 SetFlag(kUseGVN); | |
3892 SetGVNFlag(kChangesNewSpacePromotion); | |
3893 } | |
3894 | 3901 |
3895 HValue* left() { return OperandAt(0); } | 3902 HValue* left() { return OperandAt(0); } |
3896 HValue* right() const { return OperandAt(1); } | 3903 HValue* right() const { return OperandAt(1); } |
3897 | 3904 |
3898 virtual Representation RequiredInputRepresentation(int index) { | 3905 virtual Representation RequiredInputRepresentation(int index) { |
3899 return index == 0 | 3906 return index == 0 |
3900 ? Representation::Double() | 3907 ? Representation::Double() |
3901 : Representation::None(); | 3908 : Representation::None(); |
3902 } | 3909 } |
3903 virtual Representation observed_input_representation(int index) { | 3910 virtual Representation observed_input_representation(int index) { |
3904 return RequiredInputRepresentation(index); | 3911 return RequiredInputRepresentation(index); |
3905 } | 3912 } |
3906 | 3913 |
3907 DECLARE_CONCRETE_INSTRUCTION(Power) | 3914 DECLARE_CONCRETE_INSTRUCTION(Power) |
3908 | 3915 |
3909 protected: | 3916 protected: |
3910 virtual bool DataEquals(HValue* other) { return true; } | 3917 virtual bool DataEquals(HValue* other) { return true; } |
3911 | 3918 |
3912 private: | 3919 private: |
| 3920 HPower(HValue* left, HValue* right) { |
| 3921 SetOperandAt(0, left); |
| 3922 SetOperandAt(1, right); |
| 3923 set_representation(Representation::Double()); |
| 3924 SetFlag(kUseGVN); |
| 3925 SetGVNFlag(kChangesNewSpacePromotion); |
| 3926 } |
| 3927 |
3913 virtual bool IsDeletable() const { | 3928 virtual bool IsDeletable() const { |
3914 return !right()->representation().IsTagged(); | 3929 return !right()->representation().IsTagged(); |
3915 } | 3930 } |
3916 }; | 3931 }; |
3917 | 3932 |
3918 | 3933 |
3919 class HRandom: public HTemplateInstruction<1> { | 3934 class HRandom: public HTemplateInstruction<1> { |
3920 public: | 3935 public: |
3921 explicit HRandom(HValue* global_object) { | 3936 explicit HRandom(HValue* global_object) { |
3922 SetOperandAt(0, global_object); | 3937 SetOperandAt(0, global_object); |
3923 set_representation(Representation::Double()); | 3938 set_representation(Representation::Double()); |
3924 } | 3939 } |
3925 | 3940 |
3926 HValue* global_object() { return OperandAt(0); } | 3941 HValue* global_object() { return OperandAt(0); } |
3927 | 3942 |
3928 virtual Representation RequiredInputRepresentation(int index) { | 3943 virtual Representation RequiredInputRepresentation(int index) { |
3929 return Representation::Tagged(); | 3944 return Representation::Tagged(); |
3930 } | 3945 } |
3931 | 3946 |
3932 DECLARE_CONCRETE_INSTRUCTION(Random) | 3947 DECLARE_CONCRETE_INSTRUCTION(Random) |
3933 | 3948 |
3934 private: | 3949 private: |
3935 virtual bool IsDeletable() const { return true; } | 3950 virtual bool IsDeletable() const { return true; } |
3936 }; | 3951 }; |
3937 | 3952 |
3938 | 3953 |
3939 class HAdd: public HArithmeticBinaryOperation { | 3954 class HAdd: public HArithmeticBinaryOperation { |
3940 public: | 3955 public: |
3941 HAdd(HValue* context, HValue* left, HValue* right) | 3956 static HInstruction* New(Zone* zone, |
3942 : HArithmeticBinaryOperation(context, left, right) { | 3957 HValue* context, |
3943 SetFlag(kCanOverflow); | 3958 HValue* left, |
3944 } | 3959 HValue* right); |
3945 | 3960 |
3946 // Add is only commutative if two integer values are added and not if two | 3961 // Add is only commutative if two integer values are added and not if two |
3947 // tagged values are added (because it might be a String concatenation). | 3962 // tagged values are added (because it might be a String concatenation). |
3948 virtual bool IsCommutative() const { | 3963 virtual bool IsCommutative() const { |
3949 return !representation().IsTagged(); | 3964 return !representation().IsTagged(); |
3950 } | 3965 } |
3951 | 3966 |
3952 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 3967 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
3953 | 3968 |
3954 static HInstruction* NewHAdd(Zone* zone, | |
3955 HValue* context, | |
3956 HValue* left, | |
3957 HValue* right); | |
3958 | |
3959 virtual HType CalculateInferredType(); | 3969 virtual HType CalculateInferredType(); |
3960 | 3970 |
3961 virtual HValue* Canonicalize(); | 3971 virtual HValue* Canonicalize(); |
3962 | 3972 |
3963 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) { | 3973 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) { |
3964 HValue* base = NULL; | 3974 HValue* base = NULL; |
3965 int32_t offset = 0; | 3975 int32_t offset = 0; |
3966 if (left()->IsInteger32Constant()) { | 3976 if (left()->IsInteger32Constant()) { |
3967 base = right(); | 3977 base = right(); |
3968 offset = left()->GetInteger32Constant(); | 3978 offset = left()->GetInteger32Constant(); |
3969 } else if (right()->IsInteger32Constant()) { | 3979 } else if (right()->IsInteger32Constant()) { |
3970 base = left(); | 3980 base = left(); |
3971 offset = right()->GetInteger32Constant(); | 3981 offset = right()->GetInteger32Constant(); |
3972 } else { | 3982 } else { |
3973 return false; | 3983 return false; |
3974 } | 3984 } |
3975 | 3985 |
3976 return relation.IsExtendable(offset) | 3986 return relation.IsExtendable(offset) |
3977 ? base->IsRelationTrue(relation, other) : false; | 3987 ? base->IsRelationTrue(relation, other) : false; |
3978 } | 3988 } |
3979 | 3989 |
3980 DECLARE_CONCRETE_INSTRUCTION(Add) | 3990 DECLARE_CONCRETE_INSTRUCTION(Add) |
3981 | 3991 |
3982 protected: | 3992 protected: |
3983 virtual bool DataEquals(HValue* other) { return true; } | 3993 virtual bool DataEquals(HValue* other) { return true; } |
3984 | 3994 |
3985 virtual Range* InferRange(Zone* zone); | 3995 virtual Range* InferRange(Zone* zone); |
| 3996 |
| 3997 private: |
| 3998 HAdd(HValue* context, HValue* left, HValue* right) |
| 3999 : HArithmeticBinaryOperation(context, left, right) { |
| 4000 SetFlag(kCanOverflow); |
| 4001 } |
3986 }; | 4002 }; |
3987 | 4003 |
3988 | 4004 |
3989 class HSub: public HArithmeticBinaryOperation { | 4005 class HSub: public HArithmeticBinaryOperation { |
3990 public: | 4006 public: |
3991 HSub(HValue* context, HValue* left, HValue* right) | 4007 static HInstruction* New(Zone* zone, |
3992 : HArithmeticBinaryOperation(context, left, right) { | 4008 HValue* context, |
3993 SetFlag(kCanOverflow); | 4009 HValue* left, |
3994 } | 4010 HValue* right); |
3995 | 4011 |
3996 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 4012 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
3997 | 4013 |
3998 virtual HValue* Canonicalize(); | 4014 virtual HValue* Canonicalize(); |
3999 | 4015 |
4000 static HInstruction* NewHSub(Zone* zone, | |
4001 HValue* context, | |
4002 HValue* left, | |
4003 HValue* right); | |
4004 | |
4005 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) { | 4016 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) { |
4006 if (right()->IsInteger32Constant()) { | 4017 if (right()->IsInteger32Constant()) { |
4007 HValue* base = left(); | 4018 HValue* base = left(); |
4008 int32_t offset = right()->GetInteger32Constant(); | 4019 int32_t offset = right()->GetInteger32Constant(); |
4009 return relation.IsExtendable(-offset) | 4020 return relation.IsExtendable(-offset) |
4010 ? base->IsRelationTrue(relation, other) : false; | 4021 ? base->IsRelationTrue(relation, other) : false; |
4011 } else { | 4022 } else { |
4012 return false; | 4023 return false; |
4013 } | 4024 } |
4014 } | 4025 } |
4015 | 4026 |
4016 DECLARE_CONCRETE_INSTRUCTION(Sub) | 4027 DECLARE_CONCRETE_INSTRUCTION(Sub) |
4017 | 4028 |
4018 protected: | 4029 protected: |
4019 virtual bool DataEquals(HValue* other) { return true; } | 4030 virtual bool DataEquals(HValue* other) { return true; } |
4020 | 4031 |
4021 virtual Range* InferRange(Zone* zone); | 4032 virtual Range* InferRange(Zone* zone); |
| 4033 |
| 4034 private: |
| 4035 HSub(HValue* context, HValue* left, HValue* right) |
| 4036 : HArithmeticBinaryOperation(context, left, right) { |
| 4037 SetFlag(kCanOverflow); |
| 4038 } |
4022 }; | 4039 }; |
4023 | 4040 |
4024 | 4041 |
4025 class HMul: public HArithmeticBinaryOperation { | 4042 class HMul: public HArithmeticBinaryOperation { |
4026 public: | 4043 public: |
4027 HMul(HValue* context, HValue* left, HValue* right) | 4044 static HInstruction* New(Zone* zone, |
4028 : HArithmeticBinaryOperation(context, left, right) { | 4045 HValue* context, |
4029 SetFlag(kCanOverflow); | 4046 HValue* left, |
4030 } | 4047 HValue* right); |
4031 | 4048 |
4032 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 4049 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
4033 | 4050 |
4034 // Only commutative if it is certain that not two objects are multiplicated. | 4051 // Only commutative if it is certain that not two objects are multiplicated. |
4035 virtual bool IsCommutative() const { | 4052 virtual bool IsCommutative() const { |
4036 return !representation().IsTagged(); | 4053 return !representation().IsTagged(); |
4037 } | 4054 } |
4038 | 4055 |
4039 static HInstruction* NewHMul(Zone* zone, | |
4040 HValue* context, | |
4041 HValue* left, | |
4042 HValue* right); | |
4043 | |
4044 DECLARE_CONCRETE_INSTRUCTION(Mul) | 4056 DECLARE_CONCRETE_INSTRUCTION(Mul) |
4045 | 4057 |
4046 protected: | 4058 protected: |
4047 virtual bool DataEquals(HValue* other) { return true; } | 4059 virtual bool DataEquals(HValue* other) { return true; } |
4048 | 4060 |
4049 virtual Range* InferRange(Zone* zone); | 4061 virtual Range* InferRange(Zone* zone); |
| 4062 |
| 4063 private: |
| 4064 HMul(HValue* context, HValue* left, HValue* right) |
| 4065 : HArithmeticBinaryOperation(context, left, right) { |
| 4066 SetFlag(kCanOverflow); |
| 4067 } |
4050 }; | 4068 }; |
4051 | 4069 |
4052 | 4070 |
4053 class HMod: public HArithmeticBinaryOperation { | 4071 class HMod: public HArithmeticBinaryOperation { |
4054 public: | 4072 public: |
4055 HMod(HValue* context, HValue* left, HValue* right) | 4073 static HInstruction* New(Zone* zone, |
4056 : HArithmeticBinaryOperation(context, left, right) { | 4074 HValue* context, |
4057 SetFlag(kCanBeDivByZero); | 4075 HValue* left, |
4058 } | 4076 HValue* right); |
4059 | 4077 |
4060 bool HasPowerOf2Divisor() { | 4078 bool HasPowerOf2Divisor() { |
4061 if (right()->IsConstant() && | 4079 if (right()->IsConstant() && |
4062 HConstant::cast(right())->HasInteger32Value()) { | 4080 HConstant::cast(right())->HasInteger32Value()) { |
4063 int32_t value = HConstant::cast(right())->Integer32Value(); | 4081 int32_t value = HConstant::cast(right())->Integer32Value(); |
4064 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value)); | 4082 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value)); |
4065 } | 4083 } |
4066 | 4084 |
4067 return false; | 4085 return false; |
4068 } | 4086 } |
4069 | 4087 |
4070 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 4088 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
4071 | 4089 |
4072 static HInstruction* NewHMod(Zone* zone, | |
4073 HValue* context, | |
4074 HValue* left, | |
4075 HValue* right); | |
4076 | |
4077 DECLARE_CONCRETE_INSTRUCTION(Mod) | 4090 DECLARE_CONCRETE_INSTRUCTION(Mod) |
4078 | 4091 |
4079 protected: | 4092 protected: |
4080 virtual bool DataEquals(HValue* other) { return true; } | 4093 virtual bool DataEquals(HValue* other) { return true; } |
4081 | 4094 |
4082 virtual Range* InferRange(Zone* zone); | 4095 virtual Range* InferRange(Zone* zone); |
| 4096 |
| 4097 private: |
| 4098 HMod(HValue* context, HValue* left, HValue* right) |
| 4099 : HArithmeticBinaryOperation(context, left, right) { |
| 4100 SetFlag(kCanBeDivByZero); |
| 4101 } |
4083 }; | 4102 }; |
4084 | 4103 |
4085 | 4104 |
4086 class HDiv: public HArithmeticBinaryOperation { | 4105 class HDiv: public HArithmeticBinaryOperation { |
4087 public: | 4106 public: |
4088 HDiv(HValue* context, HValue* left, HValue* right) | 4107 static HInstruction* New(Zone* zone, |
4089 : HArithmeticBinaryOperation(context, left, right) { | 4108 HValue* context, |
4090 SetFlag(kCanBeDivByZero); | 4109 HValue* left, |
4091 SetFlag(kCanOverflow); | 4110 HValue* right); |
4092 } | |
4093 | 4111 |
4094 bool HasPowerOf2Divisor() { | 4112 bool HasPowerOf2Divisor() { |
4095 if (right()->IsConstant() && | 4113 if (right()->IsConstant() && |
4096 HConstant::cast(right())->HasInteger32Value()) { | 4114 HConstant::cast(right())->HasInteger32Value()) { |
4097 int32_t value = HConstant::cast(right())->Integer32Value(); | 4115 int32_t value = HConstant::cast(right())->Integer32Value(); |
4098 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value)); | 4116 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value)); |
4099 } | 4117 } |
4100 | 4118 |
4101 return false; | 4119 return false; |
4102 } | 4120 } |
4103 | 4121 |
4104 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 4122 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
4105 | 4123 |
4106 static HInstruction* NewHDiv(Zone* zone, | |
4107 HValue* context, | |
4108 HValue* left, | |
4109 HValue* right); | |
4110 | |
4111 DECLARE_CONCRETE_INSTRUCTION(Div) | 4124 DECLARE_CONCRETE_INSTRUCTION(Div) |
4112 | 4125 |
4113 protected: | 4126 protected: |
4114 virtual bool DataEquals(HValue* other) { return true; } | 4127 virtual bool DataEquals(HValue* other) { return true; } |
4115 | 4128 |
4116 virtual Range* InferRange(Zone* zone); | 4129 virtual Range* InferRange(Zone* zone); |
| 4130 |
| 4131 private: |
| 4132 HDiv(HValue* context, HValue* left, HValue* right) |
| 4133 : HArithmeticBinaryOperation(context, left, right) { |
| 4134 SetFlag(kCanBeDivByZero); |
| 4135 SetFlag(kCanOverflow); |
| 4136 } |
4117 }; | 4137 }; |
4118 | 4138 |
4119 | 4139 |
4120 class HMathMinMax: public HArithmeticBinaryOperation { | 4140 class HMathMinMax: public HArithmeticBinaryOperation { |
4121 public: | 4141 public: |
4122 enum Operation { kMathMin, kMathMax }; | 4142 enum Operation { kMathMin, kMathMax }; |
4123 | 4143 |
4124 HMathMinMax(HValue* context, HValue* left, HValue* right, Operation op) | 4144 static HInstruction* New(Zone* zone, |
4125 : HArithmeticBinaryOperation(context, left, right), | 4145 HValue* context, |
4126 operation_(op) { } | 4146 HValue* left, |
| 4147 HValue* right, |
| 4148 Operation op); |
4127 | 4149 |
4128 virtual Representation RequiredInputRepresentation(int index) { | 4150 virtual Representation RequiredInputRepresentation(int index) { |
4129 return index == 0 ? Representation::Tagged() | 4151 return index == 0 ? Representation::Tagged() |
4130 : representation(); | 4152 : representation(); |
4131 } | 4153 } |
4132 | 4154 |
4133 virtual Representation observed_input_representation(int index) { | 4155 virtual Representation observed_input_representation(int index) { |
4134 return RequiredInputRepresentation(index); | 4156 return RequiredInputRepresentation(index); |
4135 } | 4157 } |
4136 | 4158 |
(...skipping 17 matching lines...) Expand all Loading... |
4154 | 4176 |
4155 protected: | 4177 protected: |
4156 virtual bool DataEquals(HValue* other) { | 4178 virtual bool DataEquals(HValue* other) { |
4157 return other->IsMathMinMax() && | 4179 return other->IsMathMinMax() && |
4158 HMathMinMax::cast(other)->operation_ == operation_; | 4180 HMathMinMax::cast(other)->operation_ == operation_; |
4159 } | 4181 } |
4160 | 4182 |
4161 virtual Range* InferRange(Zone* zone); | 4183 virtual Range* InferRange(Zone* zone); |
4162 | 4184 |
4163 private: | 4185 private: |
| 4186 HMathMinMax(HValue* context, HValue* left, HValue* right, Operation op) |
| 4187 : HArithmeticBinaryOperation(context, left, right), |
| 4188 operation_(op) { } |
| 4189 |
4164 Operation operation_; | 4190 Operation operation_; |
4165 }; | 4191 }; |
4166 | 4192 |
4167 | 4193 |
4168 class HBitwise: public HBitwiseBinaryOperation { | 4194 class HBitwise: public HBitwiseBinaryOperation { |
4169 public: | 4195 public: |
4170 HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right) | 4196 static HInstruction* New(Zone* zone, |
4171 : HBitwiseBinaryOperation(context, left, right), op_(op) { | 4197 Token::Value op, |
4172 ASSERT(op == Token::BIT_AND || | 4198 HValue* context, |
4173 op == Token::BIT_OR || | 4199 HValue* left, |
4174 op == Token::BIT_XOR); | 4200 HValue* right); |
4175 } | |
4176 | 4201 |
4177 Token::Value op() const { return op_; } | 4202 Token::Value op() const { return op_; } |
4178 | 4203 |
4179 virtual bool IsCommutative() const { return true; } | 4204 virtual bool IsCommutative() const { return true; } |
4180 | 4205 |
4181 virtual HValue* Canonicalize(); | 4206 virtual HValue* Canonicalize(); |
4182 | 4207 |
4183 static HInstruction* NewHBitwise(Zone* zone, | |
4184 Token::Value op, | |
4185 HValue* context, | |
4186 HValue* left, | |
4187 HValue* right); | |
4188 | |
4189 virtual void PrintDataTo(StringStream* stream); | 4208 virtual void PrintDataTo(StringStream* stream); |
4190 | 4209 |
4191 DECLARE_CONCRETE_INSTRUCTION(Bitwise) | 4210 DECLARE_CONCRETE_INSTRUCTION(Bitwise) |
4192 | 4211 |
4193 protected: | 4212 protected: |
4194 virtual bool DataEquals(HValue* other) { | 4213 virtual bool DataEquals(HValue* other) { |
4195 return op() == HBitwise::cast(other)->op(); | 4214 return op() == HBitwise::cast(other)->op(); |
4196 } | 4215 } |
4197 | 4216 |
4198 virtual Range* InferRange(Zone* zone); | 4217 virtual Range* InferRange(Zone* zone); |
4199 | 4218 |
4200 private: | 4219 private: |
| 4220 HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right) |
| 4221 : HBitwiseBinaryOperation(context, left, right), op_(op) { |
| 4222 ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR); |
| 4223 } |
| 4224 |
4201 Token::Value op_; | 4225 Token::Value op_; |
4202 }; | 4226 }; |
4203 | 4227 |
4204 | 4228 |
4205 class HShl: public HBitwiseBinaryOperation { | 4229 class HShl: public HBitwiseBinaryOperation { |
4206 public: | 4230 public: |
4207 HShl(HValue* context, HValue* left, HValue* right) | 4231 static HInstruction* New(Zone* zone, |
4208 : HBitwiseBinaryOperation(context, left, right) { } | 4232 HValue* context, |
| 4233 HValue* left, |
| 4234 HValue* right); |
4209 | 4235 |
4210 virtual Range* InferRange(Zone* zone); | 4236 virtual Range* InferRange(Zone* zone); |
4211 | 4237 |
4212 static HInstruction* NewHShl(Zone* zone, | |
4213 HValue* context, | |
4214 HValue* left, | |
4215 HValue* right); | |
4216 | |
4217 DECLARE_CONCRETE_INSTRUCTION(Shl) | 4238 DECLARE_CONCRETE_INSTRUCTION(Shl) |
4218 | 4239 |
4219 protected: | 4240 protected: |
4220 virtual bool DataEquals(HValue* other) { return true; } | 4241 virtual bool DataEquals(HValue* other) { return true; } |
| 4242 |
| 4243 private: |
| 4244 HShl(HValue* context, HValue* left, HValue* right) |
| 4245 : HBitwiseBinaryOperation(context, left, right) { } |
4221 }; | 4246 }; |
4222 | 4247 |
4223 | 4248 |
4224 class HShr: public HBitwiseBinaryOperation { | 4249 class HShr: public HBitwiseBinaryOperation { |
4225 public: | 4250 public: |
4226 HShr(HValue* context, HValue* left, HValue* right) | 4251 static HInstruction* New(Zone* zone, |
4227 : HBitwiseBinaryOperation(context, left, right) { } | 4252 HValue* context, |
| 4253 HValue* left, |
| 4254 HValue* right); |
4228 | 4255 |
4229 virtual Range* InferRange(Zone* zone); | 4256 virtual Range* InferRange(Zone* zone); |
4230 | 4257 |
4231 static HInstruction* NewHShr(Zone* zone, | |
4232 HValue* context, | |
4233 HValue* left, | |
4234 HValue* right); | |
4235 | |
4236 DECLARE_CONCRETE_INSTRUCTION(Shr) | 4258 DECLARE_CONCRETE_INSTRUCTION(Shr) |
4237 | 4259 |
4238 protected: | 4260 protected: |
4239 virtual bool DataEquals(HValue* other) { return true; } | 4261 virtual bool DataEquals(HValue* other) { return true; } |
| 4262 |
| 4263 private: |
| 4264 HShr(HValue* context, HValue* left, HValue* right) |
| 4265 : HBitwiseBinaryOperation(context, left, right) { } |
4240 }; | 4266 }; |
4241 | 4267 |
4242 | 4268 |
4243 class HSar: public HBitwiseBinaryOperation { | 4269 class HSar: public HBitwiseBinaryOperation { |
4244 public: | 4270 public: |
4245 HSar(HValue* context, HValue* left, HValue* right) | 4271 static HInstruction* New(Zone* zone, |
4246 : HBitwiseBinaryOperation(context, left, right) { } | 4272 HValue* context, |
| 4273 HValue* left, |
| 4274 HValue* right); |
4247 | 4275 |
4248 virtual Range* InferRange(Zone* zone); | 4276 virtual Range* InferRange(Zone* zone); |
4249 | 4277 |
4250 static HInstruction* NewHSar(Zone* zone, | |
4251 HValue* context, | |
4252 HValue* left, | |
4253 HValue* right); | |
4254 | |
4255 DECLARE_CONCRETE_INSTRUCTION(Sar) | 4278 DECLARE_CONCRETE_INSTRUCTION(Sar) |
4256 | 4279 |
4257 protected: | 4280 protected: |
4258 virtual bool DataEquals(HValue* other) { return true; } | 4281 virtual bool DataEquals(HValue* other) { return true; } |
| 4282 |
| 4283 private: |
| 4284 HSar(HValue* context, HValue* left, HValue* right) |
| 4285 : HBitwiseBinaryOperation(context, left, right) { } |
4259 }; | 4286 }; |
4260 | 4287 |
4261 | 4288 |
4262 class HRor: public HBitwiseBinaryOperation { | 4289 class HRor: public HBitwiseBinaryOperation { |
4263 public: | 4290 public: |
4264 HRor(HValue* context, HValue* left, HValue* right) | 4291 HRor(HValue* context, HValue* left, HValue* right) |
4265 : HBitwiseBinaryOperation(context, left, right) { | 4292 : HBitwiseBinaryOperation(context, left, right) { |
4266 ChangeRepresentation(Representation::Integer32()); | 4293 ChangeRepresentation(Representation::Integer32()); |
4267 } | 4294 } |
4268 | 4295 |
4269 static HInstruction* NewHRor(Zone* zone, | |
4270 HValue* context, | |
4271 HValue* left, | |
4272 HValue* right); | |
4273 | |
4274 DECLARE_CONCRETE_INSTRUCTION(Ror) | 4296 DECLARE_CONCRETE_INSTRUCTION(Ror) |
4275 | 4297 |
4276 protected: | 4298 protected: |
4277 virtual bool DataEquals(HValue* other) { return true; } | 4299 virtual bool DataEquals(HValue* other) { return true; } |
4278 }; | 4300 }; |
4279 | 4301 |
4280 | 4302 |
4281 class HOsrEntry: public HTemplateInstruction<0> { | 4303 class HOsrEntry: public HTemplateInstruction<0> { |
4282 public: | 4304 public: |
4283 explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) { | 4305 explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) { |
(...skipping 1103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5387 private: | 5409 private: |
5388 Handle<Map> original_map_; | 5410 Handle<Map> original_map_; |
5389 Handle<Map> transitioned_map_; | 5411 Handle<Map> transitioned_map_; |
5390 ElementsKind from_kind_; | 5412 ElementsKind from_kind_; |
5391 ElementsKind to_kind_; | 5413 ElementsKind to_kind_; |
5392 }; | 5414 }; |
5393 | 5415 |
5394 | 5416 |
5395 class HStringAdd: public HBinaryOperation { | 5417 class HStringAdd: public HBinaryOperation { |
5396 public: | 5418 public: |
5397 HStringAdd(HValue* context, HValue* left, HValue* right) | 5419 static HInstruction* New(Zone* zone, |
5398 : HBinaryOperation(context, left, right) { | 5420 HValue* context, |
5399 set_representation(Representation::Tagged()); | 5421 HValue* left, |
5400 SetFlag(kUseGVN); | 5422 HValue* right); |
5401 SetGVNFlag(kDependsOnMaps); | |
5402 SetGVNFlag(kChangesNewSpacePromotion); | |
5403 } | |
5404 | 5423 |
5405 virtual Representation RequiredInputRepresentation(int index) { | 5424 virtual Representation RequiredInputRepresentation(int index) { |
5406 return Representation::Tagged(); | 5425 return Representation::Tagged(); |
5407 } | 5426 } |
5408 | 5427 |
5409 virtual HType CalculateInferredType() { | 5428 virtual HType CalculateInferredType() { |
5410 return HType::String(); | 5429 return HType::String(); |
5411 } | 5430 } |
5412 | 5431 |
5413 DECLARE_CONCRETE_INSTRUCTION(StringAdd) | 5432 DECLARE_CONCRETE_INSTRUCTION(StringAdd) |
5414 | 5433 |
5415 protected: | 5434 protected: |
5416 virtual bool DataEquals(HValue* other) { return true; } | 5435 virtual bool DataEquals(HValue* other) { return true; } |
5417 | 5436 |
| 5437 |
| 5438 private: |
| 5439 HStringAdd(HValue* context, HValue* left, HValue* right) |
| 5440 : HBinaryOperation(context, left, right) { |
| 5441 set_representation(Representation::Tagged()); |
| 5442 SetFlag(kUseGVN); |
| 5443 SetGVNFlag(kDependsOnMaps); |
| 5444 SetGVNFlag(kChangesNewSpacePromotion); |
| 5445 } |
| 5446 |
5418 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. | 5447 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. |
5419 // private: | |
5420 // virtual bool IsDeletable() const { return true; } | 5448 // virtual bool IsDeletable() const { return true; } |
5421 }; | 5449 }; |
5422 | 5450 |
5423 | 5451 |
5424 class HStringCharCodeAt: public HTemplateInstruction<3> { | 5452 class HStringCharCodeAt: public HTemplateInstruction<3> { |
5425 public: | 5453 public: |
5426 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { | 5454 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { |
5427 SetOperandAt(0, context); | 5455 SetOperandAt(0, context); |
5428 SetOperandAt(1, string); | 5456 SetOperandAt(1, string); |
5429 SetOperandAt(2, index); | 5457 SetOperandAt(2, index); |
(...skipping 24 matching lines...) Expand all Loading... |
5454 } | 5482 } |
5455 | 5483 |
5456 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. | 5484 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. |
5457 // private: | 5485 // private: |
5458 // virtual bool IsDeletable() const { return true; } | 5486 // virtual bool IsDeletable() const { return true; } |
5459 }; | 5487 }; |
5460 | 5488 |
5461 | 5489 |
5462 class HStringCharFromCode: public HTemplateInstruction<2> { | 5490 class HStringCharFromCode: public HTemplateInstruction<2> { |
5463 public: | 5491 public: |
5464 HStringCharFromCode(HValue* context, HValue* char_code) { | 5492 static HInstruction* New(Zone* zone, |
5465 SetOperandAt(0, context); | 5493 HValue* context, |
5466 SetOperandAt(1, char_code); | 5494 HValue* char_code); |
5467 set_representation(Representation::Tagged()); | |
5468 SetFlag(kUseGVN); | |
5469 SetGVNFlag(kChangesNewSpacePromotion); | |
5470 } | |
5471 | 5495 |
5472 virtual Representation RequiredInputRepresentation(int index) { | 5496 virtual Representation RequiredInputRepresentation(int index) { |
5473 return index == 0 | 5497 return index == 0 |
5474 ? Representation::Tagged() | 5498 ? Representation::Tagged() |
5475 : Representation::Integer32(); | 5499 : Representation::Integer32(); |
5476 } | 5500 } |
5477 virtual HType CalculateInferredType(); | 5501 virtual HType CalculateInferredType(); |
5478 | 5502 |
5479 HValue* context() { return OperandAt(0); } | 5503 HValue* context() { return OperandAt(0); } |
5480 HValue* value() { return OperandAt(1); } | 5504 HValue* value() { return OperandAt(1); } |
5481 | 5505 |
5482 virtual bool DataEquals(HValue* other) { return true; } | 5506 virtual bool DataEquals(HValue* other) { return true; } |
5483 | 5507 |
5484 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode) | 5508 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode) |
5485 | 5509 |
| 5510 private: |
| 5511 HStringCharFromCode(HValue* context, HValue* char_code) { |
| 5512 SetOperandAt(0, context); |
| 5513 SetOperandAt(1, char_code); |
| 5514 set_representation(Representation::Tagged()); |
| 5515 SetFlag(kUseGVN); |
| 5516 SetGVNFlag(kChangesNewSpacePromotion); |
| 5517 } |
| 5518 |
5486 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. | 5519 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. |
5487 // private: | 5520 // virtual bool IsDeletable() const { return true; } |
5488 // virtual bool IsDeletable() const { return true; } | |
5489 }; | 5521 }; |
5490 | 5522 |
5491 | 5523 |
5492 class HStringLength: public HUnaryOperation { | 5524 class HStringLength: public HUnaryOperation { |
5493 public: | 5525 public: |
5494 explicit HStringLength(HValue* string) : HUnaryOperation(string) { | 5526 static HInstruction* New(Zone* zone, HValue* string); |
5495 set_representation(Representation::Tagged()); | |
5496 SetFlag(kUseGVN); | |
5497 SetGVNFlag(kDependsOnMaps); | |
5498 } | |
5499 | 5527 |
5500 virtual Representation RequiredInputRepresentation(int index) { | 5528 virtual Representation RequiredInputRepresentation(int index) { |
5501 return Representation::Tagged(); | 5529 return Representation::Tagged(); |
5502 } | 5530 } |
5503 | 5531 |
5504 virtual HType CalculateInferredType() { | 5532 virtual HType CalculateInferredType() { |
5505 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); | 5533 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); |
5506 return HType::Smi(); | 5534 return HType::Smi(); |
5507 } | 5535 } |
5508 | 5536 |
5509 DECLARE_CONCRETE_INSTRUCTION(StringLength) | 5537 DECLARE_CONCRETE_INSTRUCTION(StringLength) |
5510 | 5538 |
5511 protected: | 5539 protected: |
5512 virtual bool DataEquals(HValue* other) { return true; } | 5540 virtual bool DataEquals(HValue* other) { return true; } |
5513 | 5541 |
5514 virtual Range* InferRange(Zone* zone) { | 5542 virtual Range* InferRange(Zone* zone) { |
5515 return new(zone) Range(0, String::kMaxLength); | 5543 return new(zone) Range(0, String::kMaxLength); |
5516 } | 5544 } |
5517 | 5545 |
5518 private: | 5546 private: |
| 5547 explicit HStringLength(HValue* string) : HUnaryOperation(string) { |
| 5548 set_representation(Representation::Tagged()); |
| 5549 SetFlag(kUseGVN); |
| 5550 SetGVNFlag(kDependsOnMaps); |
| 5551 } |
| 5552 |
5519 virtual bool IsDeletable() const { return true; } | 5553 virtual bool IsDeletable() const { return true; } |
5520 }; | 5554 }; |
5521 | 5555 |
5522 | 5556 |
5523 template <int V> | 5557 template <int V> |
5524 class HMaterializedLiteral: public HTemplateInstruction<V> { | 5558 class HMaterializedLiteral: public HTemplateInstruction<V> { |
5525 public: | 5559 public: |
5526 HMaterializedLiteral<V>(int index, int depth, AllocationSiteMode mode) | 5560 HMaterializedLiteral<V>(int index, int depth, AllocationSiteMode mode) |
5527 : literal_index_(index), depth_(depth), allocation_site_mode_(mode) { | 5561 : literal_index_(index), depth_(depth), allocation_site_mode_(mode) { |
5528 this->set_representation(Representation::Tagged()); | 5562 this->set_representation(Representation::Tagged()); |
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6032 virtual bool IsDeletable() const { return true; } | 6066 virtual bool IsDeletable() const { return true; } |
6033 }; | 6067 }; |
6034 | 6068 |
6035 | 6069 |
6036 #undef DECLARE_INSTRUCTION | 6070 #undef DECLARE_INSTRUCTION |
6037 #undef DECLARE_CONCRETE_INSTRUCTION | 6071 #undef DECLARE_CONCRETE_INSTRUCTION |
6038 | 6072 |
6039 } } // namespace v8::internal | 6073 } } // namespace v8::internal |
6040 | 6074 |
6041 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6075 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |