Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Side by Side Diff: src/hydrogen-instructions.cc

Issue 6881003: Prevent deopt when assigning double values to typed arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixes to make ia32 tests run Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE) 52 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE)
53 #undef DEFINE_COMPILE 53 #undef DEFINE_COMPILE
54 54
55 55
56 const char* Representation::Mnemonic() const { 56 const char* Representation::Mnemonic() const {
57 switch (kind_) { 57 switch (kind_) {
58 case kNone: return "v"; 58 case kNone: return "v";
59 case kTagged: return "t"; 59 case kTagged: return "t";
60 case kDouble: return "d"; 60 case kDouble: return "d";
61 case kInteger32: return "i"; 61 case kInteger32: return "i";
62 case kTruncatedInteger32: return "ti";
63 case kClampedRoundedUInteger8: return "cri";
62 case kExternal: return "x"; 64 case kExternal: return "x";
63 case kNumRepresentations: 65 case kNumRepresentations:
64 UNREACHABLE(); 66 UNREACHABLE();
65 return NULL; 67 return NULL;
66 } 68 }
67 UNREACHABLE(); 69 UNREACHABLE();
68 return NULL; 70 return NULL;
69 } 71 }
70 72
71 73
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 void HTypeofIs::PrintDataTo(StringStream* stream) { 722 void HTypeofIs::PrintDataTo(StringStream* stream) {
721 value()->PrintNameTo(stream); 723 value()->PrintNameTo(stream);
722 stream->Add(" == "); 724 stream->Add(" == ");
723 stream->Add(type_literal_->ToAsciiVector()); 725 stream->Add(type_literal_->ToAsciiVector());
724 } 726 }
725 727
726 728
727 void HChange::PrintDataTo(StringStream* stream) { 729 void HChange::PrintDataTo(StringStream* stream) {
728 HUnaryOperation::PrintDataTo(stream); 730 HUnaryOperation::PrintDataTo(stream);
729 stream->Add(" %s to %s", from_.Mnemonic(), to().Mnemonic()); 731 stream->Add(" %s to %s", from_.Mnemonic(), to().Mnemonic());
730
731 if (CanTruncateToInt32()) stream->Add(" truncating-int32");
732 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); 732 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?");
733 } 733 }
734 734
735 735
736 HCheckInstanceType* HCheckInstanceType::NewIsJSObjectOrJSFunction( 736 HCheckInstanceType* HCheckInstanceType::NewIsJSObjectOrJSFunction(
737 HValue* value) { 737 HValue* value) {
738 STATIC_ASSERT((LAST_JS_OBJECT_TYPE + 1) == JS_FUNCTION_TYPE); 738 STATIC_ASSERT((LAST_JS_OBJECT_TYPE + 1) == JS_FUNCTION_TYPE);
739 return new HCheckInstanceType(value, FIRST_JS_OBJECT_TYPE, JS_FUNCTION_TYPE); 739 return new HCheckInstanceType(value, FIRST_JS_OBJECT_TYPE, JS_FUNCTION_TYPE);
740 } 740 }
741 741
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 if (has_int32_value_) { 789 if (has_int32_value_) {
790 Range* result = new Range(int32_value_, int32_value_); 790 Range* result = new Range(int32_value_, int32_value_);
791 result->set_can_be_minus_zero(false); 791 result->set_can_be_minus_zero(false);
792 return result; 792 return result;
793 } 793 }
794 return HValue::InferRange(); 794 return HValue::InferRange();
795 } 795 }
796 796
797 797
798 Range* HPhi::InferRange() { 798 Range* HPhi::InferRange() {
799 if (representation().IsInteger32()) { 799 if (representation().IsInteger()) {
800 if (block()->IsLoopHeader()) { 800 if (block()->IsLoopHeader()) {
801 Range* range = new Range(kMinInt, kMaxInt); 801 Range* range = representation().IsClampedRoundedInteger8()
802 ? new Range(0, 255)
803 : new Range(kMinInt, kMaxInt);
802 return range; 804 return range;
803 } else { 805 } else {
804 Range* range = OperandAt(0)->range()->Copy(); 806 Range* range = OperandAt(0)->range()->Copy();
805 for (int i = 1; i < OperandCount(); ++i) { 807 for (int i = 1; i < OperandCount(); ++i) {
806 range->Union(OperandAt(i)->range()); 808 range->Union(OperandAt(i)->range());
807 } 809 }
808 return range; 810 return range;
809 } 811 }
810 } else { 812 } else {
811 return HValue::InferRange(); 813 return HValue::InferRange();
812 } 814 }
813 } 815 }
814 816
815 817
816 Range* HAdd::InferRange() { 818 Range* HAdd::InferRange() {
817 if (representation().IsInteger32()) { 819 if (representation().IsInteger()) {
818 Range* a = left()->range(); 820 Range* a = left()->range();
819 Range* b = right()->range(); 821 Range* b = right()->range();
820 Range* res = a->Copy(); 822 Range* res = a->Copy();
821 if (!res->AddAndCheckOverflow(b)) { 823 if (!res->AddAndCheckOverflow(b)) {
822 ClearFlag(kCanOverflow); 824 ClearFlag(kCanOverflow);
823 } 825 }
824 bool m0 = a->CanBeMinusZero() && b->CanBeMinusZero(); 826 bool m0 = a->CanBeMinusZero() && b->CanBeMinusZero();
825 res->set_can_be_minus_zero(m0); 827 res->set_can_be_minus_zero(m0);
826 return res; 828 return res;
827 } else { 829 } else {
828 return HValue::InferRange(); 830 return HValue::InferRange();
829 } 831 }
830 } 832 }
831 833
832 834
833 Range* HSub::InferRange() { 835 Range* HSub::InferRange() {
834 if (representation().IsInteger32()) { 836 if (representation().IsInteger()) {
835 Range* a = left()->range(); 837 Range* a = left()->range();
836 Range* b = right()->range(); 838 Range* b = right()->range();
837 Range* res = a->Copy(); 839 Range* res = a->Copy();
838 if (!res->SubAndCheckOverflow(b)) { 840 if (!res->SubAndCheckOverflow(b)) {
839 ClearFlag(kCanOverflow); 841 ClearFlag(kCanOverflow);
840 } 842 }
841 res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero()); 843 res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero());
842 return res; 844 return res;
843 } else { 845 } else {
844 return HValue::InferRange(); 846 return HValue::InferRange();
845 } 847 }
846 } 848 }
847 849
848 850
849 Range* HMul::InferRange() { 851 Range* HMul::InferRange() {
850 if (representation().IsInteger32()) { 852 if (representation().IsInteger()) {
851 Range* a = left()->range(); 853 Range* a = left()->range();
852 Range* b = right()->range(); 854 Range* b = right()->range();
853 Range* res = a->Copy(); 855 Range* res = a->Copy();
854 if (!res->MulAndCheckOverflow(b)) { 856 if (!res->MulAndCheckOverflow(b)) {
855 ClearFlag(kCanOverflow); 857 ClearFlag(kCanOverflow);
856 } 858 }
857 bool m0 = (a->CanBeZero() && b->CanBeNegative()) || 859 bool m0 = (a->CanBeZero() && b->CanBeNegative()) ||
858 (a->CanBeNegative() && b->CanBeZero()); 860 (a->CanBeNegative() && b->CanBeZero());
859 res->set_can_be_minus_zero(m0); 861 res->set_can_be_minus_zero(m0);
860 return res; 862 return res;
861 } else { 863 } else {
862 return HValue::InferRange(); 864 return HValue::InferRange();
863 } 865 }
864 } 866 }
865 867
866 868
867 Range* HDiv::InferRange() { 869 Range* HDiv::InferRange() {
868 if (representation().IsInteger32()) { 870 if (representation().IsInteger()) {
869 Range* result = new Range(); 871 Range* result = new Range();
870 if (left()->range()->CanBeMinusZero()) { 872 if (left()->range()->CanBeMinusZero()) {
871 result->set_can_be_minus_zero(true); 873 result->set_can_be_minus_zero(true);
872 } 874 }
873 875
874 if (left()->range()->CanBeZero() && right()->range()->CanBeNegative()) { 876 if (left()->range()->CanBeZero() && right()->range()->CanBeNegative()) {
875 result->set_can_be_minus_zero(true); 877 result->set_can_be_minus_zero(true);
876 } 878 }
877 879
878 if (right()->range()->Includes(-1) && left()->range()->Includes(kMinInt)) { 880 if (right()->range()->Includes(-1) && left()->range()->Includes(kMinInt)) {
879 SetFlag(HValue::kCanOverflow); 881 SetFlag(HValue::kCanOverflow);
880 } 882 }
881 883
882 if (!right()->range()->CanBeZero()) { 884 if (!right()->range()->CanBeZero()) {
883 ClearFlag(HValue::kCanBeDivByZero); 885 ClearFlag(HValue::kCanBeDivByZero);
884 } 886 }
885 return result; 887 return result;
886 } else { 888 } else {
887 return HValue::InferRange(); 889 return HValue::InferRange();
888 } 890 }
889 } 891 }
890 892
891 893
892 Range* HMod::InferRange() { 894 Range* HMod::InferRange() {
893 if (representation().IsInteger32()) { 895 if (representation().IsInteger()) {
894 Range* a = left()->range(); 896 Range* a = left()->range();
895 Range* result = new Range(); 897 Range* result = new Range();
896 if (a->CanBeMinusZero() || a->CanBeNegative()) { 898 if (a->CanBeMinusZero() || a->CanBeNegative()) {
897 result->set_can_be_minus_zero(true); 899 result->set_can_be_minus_zero(true);
898 } 900 }
899 if (!right()->range()->CanBeZero()) { 901 if (!right()->range()->CanBeZero()) {
900 ClearFlag(HValue::kCanBeDivByZero); 902 ClearFlag(HValue::kCanBeDivByZero);
901 } 903 }
902 return result; 904 return result;
903 } else { 905 } else {
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1028 double roundtrip_value = static_cast<double>(static_cast<int32_t>(n)); 1030 double roundtrip_value = static_cast<double>(static_cast<int32_t>(n));
1029 has_int32_value_ = BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(n); 1031 has_int32_value_ = BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(n);
1030 if (has_int32_value_) int32_value_ = static_cast<int32_t>(n); 1032 if (has_int32_value_) int32_value_ = static_cast<int32_t>(n);
1031 double_value_ = n; 1033 double_value_ = n;
1032 has_double_value_ = true; 1034 has_double_value_ = true;
1033 } 1035 }
1034 } 1036 }
1035 1037
1036 1038
1037 HConstant* HConstant::CopyToRepresentation(Representation r) const { 1039 HConstant* HConstant::CopyToRepresentation(Representation r) const {
1038 if (r.IsInteger32() && !has_int32_value_) return NULL; 1040 if (r.IsInteger() && !has_int32_value_) return NULL;
1041 if (r.IsClampedRoundedInteger8() &&
1042 (int32_value_ > 255 || int32_value_ < 0)) return NULL;
1039 if (r.IsDouble() && !has_double_value_) return NULL; 1043 if (r.IsDouble() && !has_double_value_) return NULL;
1040 return new HConstant(handle_, r); 1044 return new HConstant(handle_, r);
1041 } 1045 }
1042 1046
1043 1047
1044 HConstant* HConstant::CopyToTruncatedInt32() const { 1048 HConstant* HConstant::CopyToTruncatedInt32() const {
1045 if (!has_double_value_) return NULL; 1049 if (!has_double_value_) return NULL;
1046 int32_t truncated = NumberToInt32(*handle_); 1050 int32_t truncated = NumberToInt32(*handle_);
1047 return new HConstant(FACTORY->NewNumberFromInt(truncated), 1051 return new HConstant(FACTORY->NewNumberFromInt(truncated),
1048 Representation::Integer32()); 1052 Representation::TruncatedInteger32());
1049 } 1053 }
1050 1054
1051 1055
1056 HConstant* HConstant::CopyToClampedRoundedUInt8() const {
1057 if (!has_double_value_) return NULL;
1058 int32_t clamped_rounded = NumberToClampedUInt8(*handle_);
1059 return new HConstant(FACTORY->NewNumberFromInt(clamped_rounded),
1060 Representation::ClampedRoundedUInteger8());
1061 }
1062
1063
1052 bool HConstant::ToBoolean() const { 1064 bool HConstant::ToBoolean() const {
1053 // Converts the constant's boolean value according to 1065 // Converts the constant's boolean value according to
1054 // ECMAScript section 9.2 ToBoolean conversion. 1066 // ECMAScript section 9.2 ToBoolean conversion.
1055 if (HasInteger32Value()) return Integer32Value() != 0; 1067 if (HasInteger32Value()) return Integer32Value() != 0;
1056 if (HasDoubleValue()) { 1068 if (HasDoubleValue()) {
1057 double v = DoubleValue(); 1069 double v = DoubleValue();
1058 return v != 0 && !isnan(v); 1070 return v != 0 && !isnan(v);
1059 } 1071 }
1060 if (handle()->IsTrue()) return true; 1072 if (handle()->IsTrue()) return true;
1061 if (handle()->IsFalse()) return false; 1073 if (handle()->IsFalse()) return false;
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
1504 1516
1505 1517
1506 HType HSar::CalculateInferredType() { 1518 HType HSar::CalculateInferredType() {
1507 return HType::TaggedNumber(); 1519 return HType::TaggedNumber();
1508 } 1520 }
1509 1521
1510 1522
1511 HValue* HUnaryMathOperation::EnsureAndPropagateNotMinusZero( 1523 HValue* HUnaryMathOperation::EnsureAndPropagateNotMinusZero(
1512 BitVector* visited) { 1524 BitVector* visited) {
1513 visited->Add(id()); 1525 visited->Add(id());
1514 if (representation().IsInteger32() && 1526 if (representation().IsInteger() &&
1515 !value()->representation().IsInteger32()) { 1527 !value()->representation().IsInteger()) {
1516 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { 1528 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) {
1517 SetFlag(kBailoutOnMinusZero); 1529 SetFlag(kBailoutOnMinusZero);
1518 } 1530 }
1519 } 1531 }
1520 if (RequiredInputRepresentation(0).IsInteger32() && 1532 if (RequiredInputRepresentation(0).IsInteger() &&
1521 representation().IsInteger32()) { 1533 representation().IsInteger()) {
1522 return value(); 1534 return value();
1523 } 1535 }
1524 return NULL; 1536 return NULL;
1525 } 1537 }
1526 1538
1527 1539
1528 1540
1529 HValue* HChange::EnsureAndPropagateNotMinusZero(BitVector* visited) { 1541 HValue* HChange::EnsureAndPropagateNotMinusZero(BitVector* visited) {
1530 visited->Add(id()); 1542 visited->Add(id());
1531 if (from().IsInteger32()) return NULL; 1543 if (from().IsInteger()) return NULL;
1532 if (CanTruncateToInt32()) return NULL; 1544 if (to().IsTruncatedInteger32() || to().IsClampedRoundedInteger8()) {
1545 return NULL;
1546 }
1533 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { 1547 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) {
1534 SetFlag(kBailoutOnMinusZero); 1548 SetFlag(kBailoutOnMinusZero);
1535 } 1549 }
1536 ASSERT(!from().IsInteger32() || !to().IsInteger32()); 1550 ASSERT(!from().IsInteger() || !to().IsInteger());
1537 return NULL; 1551 return NULL;
1538 } 1552 }
1539 1553
1540 1554
1541 HValue* HMod::EnsureAndPropagateNotMinusZero(BitVector* visited) { 1555 HValue* HMod::EnsureAndPropagateNotMinusZero(BitVector* visited) {
1542 visited->Add(id()); 1556 visited->Add(id());
1543 if (range() == NULL || range()->CanBeMinusZero()) { 1557 if (range() == NULL || range()->CanBeMinusZero()) {
1544 SetFlag(kBailoutOnMinusZero); 1558 SetFlag(kBailoutOnMinusZero);
1545 return left(); 1559 return left();
1546 } 1560 }
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1646 1660
1647 1661
1648 void HCheckPrototypeMaps::Verify() { 1662 void HCheckPrototypeMaps::Verify() {
1649 HInstruction::Verify(); 1663 HInstruction::Verify();
1650 ASSERT(HasNoUses()); 1664 ASSERT(HasNoUses());
1651 } 1665 }
1652 1666
1653 #endif 1667 #endif
1654 1668
1655 } } // namespace v8::internal 1669 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698