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 1124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1135 | 1135 |
1136 bool TryGuaranteeRange(HValue* upper_bound); | 1136 bool TryGuaranteeRange(HValue* upper_bound); |
1137 virtual bool TryDecompose(DecompositionResult* decomposition) { | 1137 virtual bool TryDecompose(DecompositionResult* decomposition) { |
1138 if (RedefinedOperand() != NULL) { | 1138 if (RedefinedOperand() != NULL) { |
1139 return RedefinedOperand()->TryDecompose(decomposition); | 1139 return RedefinedOperand()->TryDecompose(decomposition); |
1140 } else { | 1140 } else { |
1141 return false; | 1141 return false; |
1142 } | 1142 } |
1143 } | 1143 } |
1144 | 1144 |
1145 // Returns true conservatively if the program might be able to observe a | |
1146 // ToString() operation on this value. | |
1147 bool ToStringCanBeObserved() const { | |
1148 return !type().IsString() && representation().IsTagged(); | |
1149 } | |
1150 | |
1151 // Returns true conservatively if the program might be able to observe a | |
1152 // ToNumber() operation on this value. | |
1153 bool ToNumberCanBeObserved() const { | |
1154 return !type().IsString() && representation().IsTagged(); | |
Michael Starzinger
2013/07/25 14:43:18
This predicate looks broken. Shouldn't that be typ
| |
1155 } | |
1156 | |
1145 protected: | 1157 protected: |
1146 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context); | 1158 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context); |
1147 | 1159 |
1148 enum RangeGuaranteeDirection { | 1160 enum RangeGuaranteeDirection { |
1149 DIRECTION_NONE = 0, | 1161 DIRECTION_NONE = 0, |
1150 DIRECTION_UPPER = 1, | 1162 DIRECTION_UPPER = 1, |
1151 DIRECTION_LOWER = 2, | 1163 DIRECTION_LOWER = 2, |
1152 DIRECTION_BOTH = DIRECTION_UPPER | DIRECTION_LOWER | 1164 DIRECTION_BOTH = DIRECTION_UPPER | DIRECTION_LOWER |
1153 }; | 1165 }; |
1154 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {} | 1166 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {} |
(...skipping 2509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3664 HBinaryOperation(HValue* context, HValue* left, HValue* right) | 3676 HBinaryOperation(HValue* context, HValue* left, HValue* right) |
3665 : observed_output_representation_(Representation::None()) { | 3677 : observed_output_representation_(Representation::None()) { |
3666 ASSERT(left != NULL && right != NULL); | 3678 ASSERT(left != NULL && right != NULL); |
3667 SetOperandAt(0, context); | 3679 SetOperandAt(0, context); |
3668 SetOperandAt(1, left); | 3680 SetOperandAt(1, left); |
3669 SetOperandAt(2, right); | 3681 SetOperandAt(2, right); |
3670 observed_input_representation_[0] = Representation::None(); | 3682 observed_input_representation_[0] = Representation::None(); |
3671 observed_input_representation_[1] = Representation::None(); | 3683 observed_input_representation_[1] = Representation::None(); |
3672 } | 3684 } |
3673 | 3685 |
3674 HValue* context() { return OperandAt(0); } | 3686 HValue* context() const { return OperandAt(0); } |
3675 HValue* left() { return OperandAt(1); } | 3687 HValue* left() const { return OperandAt(1); } |
3676 HValue* right() { return OperandAt(2); } | 3688 HValue* right() const { return OperandAt(2); } |
3677 | 3689 |
3678 // True if switching left and right operands likely generates better code. | 3690 // True if switching left and right operands likely generates better code. |
3679 bool AreOperandsBetterSwitched() { | 3691 bool AreOperandsBetterSwitched() { |
3680 if (!IsCommutative()) return false; | 3692 if (!IsCommutative()) return false; |
3681 | 3693 |
3682 // Constant operands are better off on the right, they can be inlined in | 3694 // Constant operands are better off on the right, they can be inlined in |
3683 // many situations on most platforms. | 3695 // many situations on most platforms. |
3684 if (left()->IsConstant()) return true; | 3696 if (left()->IsConstant()) return true; |
3685 if (right()->IsConstant()) return false; | 3697 if (right()->IsConstant()) return false; |
3686 | 3698 |
(...skipping 2702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6389 | 6401 |
6390 private: | 6402 private: |
6391 HStringAdd(HValue* context, HValue* left, HValue* right, StringAddFlags flags) | 6403 HStringAdd(HValue* context, HValue* left, HValue* right, StringAddFlags flags) |
6392 : HBinaryOperation(context, left, right), flags_(flags) { | 6404 : HBinaryOperation(context, left, right), flags_(flags) { |
6393 set_representation(Representation::Tagged()); | 6405 set_representation(Representation::Tagged()); |
6394 SetFlag(kUseGVN); | 6406 SetFlag(kUseGVN); |
6395 SetGVNFlag(kDependsOnMaps); | 6407 SetGVNFlag(kDependsOnMaps); |
6396 SetGVNFlag(kChangesNewSpacePromotion); | 6408 SetGVNFlag(kChangesNewSpacePromotion); |
6397 } | 6409 } |
6398 | 6410 |
6399 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. | 6411 virtual bool IsDeletable() const { |
6400 // virtual bool IsDeletable() const { return true; } | 6412 if (flags_ == STRING_ADD_CHECK_NONE) return true; |
6413 return !left()->ToStringCanBeObserved() | |
6414 && !right()->ToStringCanBeObserved(); | |
6415 } | |
6401 | 6416 |
6402 const StringAddFlags flags_; | 6417 const StringAddFlags flags_; |
6403 }; | 6418 }; |
6404 | 6419 |
6405 | 6420 |
6406 class HStringCharCodeAt: public HTemplateInstruction<3> { | 6421 class HStringCharCodeAt: public HTemplateInstruction<3> { |
6407 public: | 6422 public: |
6408 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { | 6423 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { |
6409 SetOperandAt(0, context); | 6424 SetOperandAt(0, context); |
6410 SetOperandAt(1, string); | 6425 SetOperandAt(1, string); |
6411 SetOperandAt(2, index); | 6426 SetOperandAt(2, index); |
6412 set_representation(Representation::Integer32()); | 6427 set_representation(Representation::Integer32()); |
6413 SetFlag(kUseGVN); | 6428 SetFlag(kUseGVN); |
6414 SetGVNFlag(kDependsOnMaps); | 6429 SetGVNFlag(kDependsOnMaps); |
6415 SetGVNFlag(kChangesNewSpacePromotion); | 6430 SetGVNFlag(kChangesNewSpacePromotion); |
6416 } | 6431 } |
6417 | 6432 |
6418 virtual Representation RequiredInputRepresentation(int index) { | 6433 virtual Representation RequiredInputRepresentation(int index) { |
6419 // The index is supposed to be Integer32. | 6434 // The index is supposed to be Integer32. |
6420 return index == 2 | 6435 return index == 2 |
6421 ? Representation::Integer32() | 6436 ? Representation::Integer32() |
6422 : Representation::Tagged(); | 6437 : Representation::Tagged(); |
6423 } | 6438 } |
6424 | 6439 |
6425 HValue* context() { return OperandAt(0); } | 6440 HValue* context() const { return OperandAt(0); } |
6426 HValue* string() { return OperandAt(1); } | 6441 HValue* string() const { return OperandAt(1); } |
6427 HValue* index() { return OperandAt(2); } | 6442 HValue* index() const { return OperandAt(2); } |
6428 | 6443 |
6429 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt) | 6444 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt) |
6430 | 6445 |
6431 protected: | 6446 protected: |
6432 virtual bool DataEquals(HValue* other) { return true; } | 6447 virtual bool DataEquals(HValue* other) { return true; } |
6433 | 6448 |
6434 virtual Range* InferRange(Zone* zone) { | 6449 virtual Range* InferRange(Zone* zone) { |
6435 return new(zone) Range(0, String::kMaxUtf16CodeUnit); | 6450 return new(zone) Range(0, String::kMaxUtf16CodeUnit); |
6436 } | 6451 } |
6437 | 6452 |
6438 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. | 6453 private: |
6439 // private: | 6454 virtual bool IsDeletable() const { |
6440 // virtual bool IsDeletable() const { return true; } | 6455 // NOTE: we assume this instruction is dominated by a string typecheck. |
6456 return !index()->ToNumberCanBeObserved(); | |
6457 } | |
6441 }; | 6458 }; |
6442 | 6459 |
6443 | 6460 |
6444 class HStringCharFromCode: public HTemplateInstruction<2> { | 6461 class HStringCharFromCode: public HTemplateInstruction<2> { |
6445 public: | 6462 public: |
6446 static HInstruction* New(Zone* zone, | 6463 static HInstruction* New(Zone* zone, |
6447 HValue* context, | 6464 HValue* context, |
6448 HValue* char_code); | 6465 HValue* char_code); |
6449 | 6466 |
6450 virtual Representation RequiredInputRepresentation(int index) { | 6467 virtual Representation RequiredInputRepresentation(int index) { |
6451 return index == 0 | 6468 return index == 0 |
6452 ? Representation::Tagged() | 6469 ? Representation::Tagged() |
6453 : Representation::Integer32(); | 6470 : Representation::Integer32(); |
6454 } | 6471 } |
6455 virtual HType CalculateInferredType(); | 6472 virtual HType CalculateInferredType() { return HType::String(); } |
6456 | 6473 |
6457 HValue* context() { return OperandAt(0); } | 6474 HValue* context() const { return OperandAt(0); } |
6458 HValue* value() { return OperandAt(1); } | 6475 HValue* value() const { return OperandAt(1); } |
6459 | 6476 |
6460 virtual bool DataEquals(HValue* other) { return true; } | 6477 virtual bool DataEquals(HValue* other) { return true; } |
6461 | 6478 |
6462 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode) | 6479 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode) |
6463 | 6480 |
6481 virtual bool IsDeletable() const { | |
Michael Starzinger
2013/07/25 14:43:18
nit: This should be private, please move it back d
titzer
2013/07/25 15:32:55
Done.
| |
6482 return !value()->ToNumberCanBeObserved(); | |
6483 } | |
6484 | |
6464 private: | 6485 private: |
6465 HStringCharFromCode(HValue* context, HValue* char_code) { | 6486 HStringCharFromCode(HValue* context, HValue* char_code) { |
6466 SetOperandAt(0, context); | 6487 SetOperandAt(0, context); |
6467 SetOperandAt(1, char_code); | 6488 SetOperandAt(1, char_code); |
6468 set_representation(Representation::Tagged()); | 6489 set_representation(Representation::Tagged()); |
6469 SetFlag(kUseGVN); | 6490 SetFlag(kUseGVN); |
6470 SetGVNFlag(kChangesNewSpacePromotion); | 6491 SetGVNFlag(kChangesNewSpacePromotion); |
6471 } | 6492 } |
6472 | |
6473 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. | |
6474 // virtual bool IsDeletable() const { return true; } | |
6475 }; | 6493 }; |
6476 | 6494 |
6477 | 6495 |
6478 class HStringLength: public HUnaryOperation { | 6496 class HStringLength: public HUnaryOperation { |
6479 public: | 6497 public: |
6480 static HInstruction* New(Zone* zone, HValue* string); | 6498 static HInstruction* New(Zone* zone, HValue* string); |
6481 | 6499 |
6482 virtual Representation RequiredInputRepresentation(int index) { | 6500 virtual Representation RequiredInputRepresentation(int index) { |
6483 return Representation::Tagged(); | 6501 return Representation::Tagged(); |
6484 } | 6502 } |
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6873 virtual bool IsDeletable() const { return true; } | 6891 virtual bool IsDeletable() const { return true; } |
6874 }; | 6892 }; |
6875 | 6893 |
6876 | 6894 |
6877 #undef DECLARE_INSTRUCTION | 6895 #undef DECLARE_INSTRUCTION |
6878 #undef DECLARE_CONCRETE_INSTRUCTION | 6896 #undef DECLARE_CONCRETE_INSTRUCTION |
6879 | 6897 |
6880 } } // namespace v8::internal | 6898 } } // namespace v8::internal |
6881 | 6899 |
6882 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6900 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |