OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/double.h" | 7 #include "src/double.h" |
8 #include "src/factory.h" | 8 #include "src/factory.h" |
9 #include "src/hydrogen-infer-representation.h" | 9 #include "src/hydrogen-infer-representation.h" |
10 #include "src/property-details-inl.h" | 10 #include "src/property-details-inl.h" |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 | 518 |
519 void HValue::SetBlock(HBasicBlock* block) { | 519 void HValue::SetBlock(HBasicBlock* block) { |
520 ASSERT(block_ == NULL || block == NULL); | 520 ASSERT(block_ == NULL || block == NULL); |
521 block_ = block; | 521 block_ = block; |
522 if (id_ == kNoNumber && block != NULL) { | 522 if (id_ == kNoNumber && block != NULL) { |
523 id_ = block->graph()->GetNextValueID(this); | 523 id_ = block->graph()->GetNextValueID(this); |
524 } | 524 } |
525 } | 525 } |
526 | 526 |
527 | 527 |
528 OStream& operator<<(OStream& os, const HValue& v) { | 528 OStream& operator<<(OStream& os, const HValue& v) { return v.PrintTo(os); } |
529 // TODO(svenpanne) Temporary impedance matching, to be removed later. | 529 |
530 HeapStringAllocator allocator; | 530 |
531 StringStream stream(&allocator); | 531 OStream& operator<<(OStream& os, const TypeOf& t) { |
532 const_cast<HValue*>(&v)->PrintTo(&stream); | 532 if (t.value->representation().IsTagged() && |
533 return os << stream.ToCString().get(); | 533 !t.value->type().Equals(HType::Tagged())) |
| 534 return os; |
| 535 return os << " type:" << t.value->type(); |
534 } | 536 } |
535 | 537 |
536 | 538 |
537 void HValue::PrintTypeTo(StringStream* stream) { | 539 OStream& operator<<(OStream& os, const ChangesOf& c) { |
538 if (!representation().IsTagged() || type().Equals(HType::Tagged())) return; | 540 GVNFlagSet changes_flags = c.value->ChangesFlags(); |
539 stream->Add(" type:%s", type().ToString()); | 541 if (changes_flags.IsEmpty()) return os; |
540 } | 542 os << " changes["; |
541 | 543 if (changes_flags == c.value->AllSideEffectsFlagSet()) { |
542 | 544 os << "*"; |
543 void HValue::PrintChangesTo(StringStream* stream) { | |
544 GVNFlagSet changes_flags = ChangesFlags(); | |
545 if (changes_flags.IsEmpty()) return; | |
546 stream->Add(" changes["); | |
547 if (changes_flags == AllSideEffectsFlagSet()) { | |
548 stream->Add("*"); | |
549 } else { | 545 } else { |
550 bool add_comma = false; | 546 bool add_comma = false; |
551 #define PRINT_DO(Type) \ | 547 #define PRINT_DO(Type) \ |
552 if (changes_flags.Contains(k##Type)) { \ | 548 if (changes_flags.Contains(k##Type)) { \ |
553 if (add_comma) stream->Add(","); \ | 549 if (add_comma) os << ","; \ |
554 add_comma = true; \ | 550 add_comma = true; \ |
555 stream->Add(#Type); \ | 551 os << #Type; \ |
556 } | 552 } |
557 GVN_TRACKED_FLAG_LIST(PRINT_DO); | 553 GVN_TRACKED_FLAG_LIST(PRINT_DO); |
558 GVN_UNTRACKED_FLAG_LIST(PRINT_DO); | 554 GVN_UNTRACKED_FLAG_LIST(PRINT_DO); |
559 #undef PRINT_DO | 555 #undef PRINT_DO |
560 } | 556 } |
561 stream->Add("]"); | 557 return os << "]"; |
562 } | 558 } |
563 | 559 |
564 | 560 |
565 void HValue::PrintNameTo(StringStream* stream) { | |
566 stream->Add("%s%d", representation_.Mnemonic(), id()); | |
567 } | |
568 | |
569 | |
570 bool HValue::HasMonomorphicJSObjectType() { | 561 bool HValue::HasMonomorphicJSObjectType() { |
571 return !GetMonomorphicJSObjectMap().is_null(); | 562 return !GetMonomorphicJSObjectMap().is_null(); |
572 } | 563 } |
573 | 564 |
574 | 565 |
575 bool HValue::UpdateInferredType() { | 566 bool HValue::UpdateInferredType() { |
576 HType type = CalculateInferredType(); | 567 HType type = CalculateInferredType(); |
577 bool result = (!type.Equals(type_)); | 568 bool result = (!type.Equals(type_)); |
578 type_ = type; | 569 type_ = type; |
579 return result; | 570 return result; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 } | 608 } |
618 | 609 |
619 | 610 |
620 void HValue::ComputeInitialRange(Zone* zone) { | 611 void HValue::ComputeInitialRange(Zone* zone) { |
621 ASSERT(!HasRange()); | 612 ASSERT(!HasRange()); |
622 range_ = InferRange(zone); | 613 range_ = InferRange(zone); |
623 ASSERT(HasRange()); | 614 ASSERT(HasRange()); |
624 } | 615 } |
625 | 616 |
626 | 617 |
627 void HSourcePosition::PrintTo(FILE* out) { | 618 OStream& operator<<(OStream& os, const HSourcePosition& p) { |
628 if (IsUnknown()) { | 619 if (p.IsUnknown()) { |
629 PrintF(out, "<?>"); | 620 return os << "<?>"; |
| 621 } else if (FLAG_hydrogen_track_positions) { |
| 622 return os << "<" << p.inlining_id() << ":" << p.position() << ">"; |
630 } else { | 623 } else { |
631 if (FLAG_hydrogen_track_positions) { | 624 return os << "<0:" << p.raw() << ">"; |
632 PrintF(out, "<%d:%d>", inlining_id(), position()); | |
633 } else { | |
634 PrintF(out, "<0:%d>", raw()); | |
635 } | |
636 } | 625 } |
637 } | 626 } |
638 | 627 |
639 | 628 |
640 void HInstruction::PrintTo(StringStream* stream) { | 629 OStream& HInstruction::PrintTo(OStream& os) const { // NOLINT |
641 PrintMnemonicTo(stream); | 630 os << Mnemonic() << " "; |
642 PrintDataTo(stream); | 631 PrintDataTo(os) << ChangesOf(this) << TypeOf(this); |
643 PrintChangesTo(stream); | 632 if (CheckFlag(HValue::kHasNoObservableSideEffects)) os << " [noOSE]"; |
644 PrintTypeTo(stream); | 633 if (CheckFlag(HValue::kIsDead)) os << " [dead]"; |
645 if (CheckFlag(HValue::kHasNoObservableSideEffects)) { | 634 return os; |
646 stream->Add(" [noOSE]"); | |
647 } | |
648 if (CheckFlag(HValue::kIsDead)) { | |
649 stream->Add(" [dead]"); | |
650 } | |
651 } | 635 } |
652 | 636 |
653 | 637 |
654 void HInstruction::PrintDataTo(StringStream *stream) { | 638 OStream& HInstruction::PrintDataTo(OStream& os) const { // NOLINT |
655 for (int i = 0; i < OperandCount(); ++i) { | 639 for (int i = 0; i < OperandCount(); ++i) { |
656 if (i > 0) stream->Add(" "); | 640 if (i > 0) os << " "; |
657 OperandAt(i)->PrintNameTo(stream); | 641 os << NameOf(OperandAt(i)); |
658 } | 642 } |
| 643 return os; |
659 } | 644 } |
660 | 645 |
661 | 646 |
662 void HInstruction::PrintMnemonicTo(StringStream* stream) { | |
663 stream->Add("%s ", Mnemonic()); | |
664 } | |
665 | |
666 | |
667 void HInstruction::Unlink() { | 647 void HInstruction::Unlink() { |
668 ASSERT(IsLinked()); | 648 ASSERT(IsLinked()); |
669 ASSERT(!IsControlInstruction()); // Must never move control instructions. | 649 ASSERT(!IsControlInstruction()); // Must never move control instructions. |
670 ASSERT(!IsBlockEntry()); // Doesn't make sense to delete these. | 650 ASSERT(!IsBlockEntry()); // Doesn't make sense to delete these. |
671 ASSERT(previous_ != NULL); | 651 ASSERT(previous_ != NULL); |
672 previous_->next_ = next_; | 652 previous_->next_ = next_; |
673 if (next_ == NULL) { | 653 if (next_ == NULL) { |
674 ASSERT(block()->last() == this); | 654 ASSERT(block()->last() == this); |
675 block()->set_last(previous_); | 655 block()->set_last(previous_); |
676 } else { | 656 } else { |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
921 case HValue::kTypeof: | 901 case HValue::kTypeof: |
922 case HValue::kUnaryMathOperation: | 902 case HValue::kUnaryMathOperation: |
923 case HValue::kWrapReceiver: | 903 case HValue::kWrapReceiver: |
924 return true; | 904 return true; |
925 } | 905 } |
926 UNREACHABLE(); | 906 UNREACHABLE(); |
927 return true; | 907 return true; |
928 } | 908 } |
929 | 909 |
930 | 910 |
931 void HDummyUse::PrintDataTo(StringStream* stream) { | 911 OStream& operator<<(OStream& os, const NameOf& v) { |
932 value()->PrintNameTo(stream); | 912 return os << v.value->representation().Mnemonic() << v.value->id(); |
| 913 } |
| 914 |
| 915 OStream& HDummyUse::PrintDataTo(OStream& os) const { // NOLINT |
| 916 return os << NameOf(value()); |
933 } | 917 } |
934 | 918 |
935 | 919 |
936 void HEnvironmentMarker::PrintDataTo(StringStream* stream) { | 920 OStream& HEnvironmentMarker::PrintDataTo(OStream& os) const { // NOLINT |
937 stream->Add("%s var[%d]", kind() == BIND ? "bind" : "lookup", index()); | 921 return os << (kind() == BIND ? "bind" : "lookup") << " var[" << index() |
| 922 << "]"; |
938 } | 923 } |
939 | 924 |
940 | 925 |
941 void HUnaryCall::PrintDataTo(StringStream* stream) { | 926 OStream& HUnaryCall::PrintDataTo(OStream& os) const { // NOLINT |
942 value()->PrintNameTo(stream); | 927 return os << NameOf(value()) << " #" << argument_count(); |
943 stream->Add(" "); | |
944 stream->Add("#%d", argument_count()); | |
945 } | 928 } |
946 | 929 |
947 | 930 |
948 void HCallJSFunction::PrintDataTo(StringStream* stream) { | 931 OStream& HCallJSFunction::PrintDataTo(OStream& os) const { // NOLINT |
949 function()->PrintNameTo(stream); | 932 return os << NameOf(function()) << " #" << argument_count(); |
950 stream->Add(" "); | |
951 stream->Add("#%d", argument_count()); | |
952 } | 933 } |
953 | 934 |
954 | 935 |
955 HCallJSFunction* HCallJSFunction::New( | 936 HCallJSFunction* HCallJSFunction::New( |
956 Zone* zone, | 937 Zone* zone, |
957 HValue* context, | 938 HValue* context, |
958 HValue* function, | 939 HValue* function, |
959 int argument_count, | 940 int argument_count, |
960 bool pass_argument_count) { | 941 bool pass_argument_count) { |
961 bool has_stack_check = false; | 942 bool has_stack_check = false; |
962 if (function->IsConstant()) { | 943 if (function->IsConstant()) { |
963 HConstant* fun_const = HConstant::cast(function); | 944 HConstant* fun_const = HConstant::cast(function); |
964 Handle<JSFunction> jsfun = | 945 Handle<JSFunction> jsfun = |
965 Handle<JSFunction>::cast(fun_const->handle(zone->isolate())); | 946 Handle<JSFunction>::cast(fun_const->handle(zone->isolate())); |
966 has_stack_check = !jsfun.is_null() && | 947 has_stack_check = !jsfun.is_null() && |
967 (jsfun->code()->kind() == Code::FUNCTION || | 948 (jsfun->code()->kind() == Code::FUNCTION || |
968 jsfun->code()->kind() == Code::OPTIMIZED_FUNCTION); | 949 jsfun->code()->kind() == Code::OPTIMIZED_FUNCTION); |
969 } | 950 } |
970 | 951 |
971 return new(zone) HCallJSFunction( | 952 return new(zone) HCallJSFunction( |
972 function, argument_count, pass_argument_count, | 953 function, argument_count, pass_argument_count, |
973 has_stack_check); | 954 has_stack_check); |
974 } | 955 } |
975 | 956 |
976 | 957 |
977 | 958 OStream& HBinaryCall::PrintDataTo(OStream& os) const { // NOLINT |
978 | 959 return os << NameOf(first()) << " " << NameOf(second()) << " #" |
979 void HBinaryCall::PrintDataTo(StringStream* stream) { | 960 << argument_count(); |
980 first()->PrintNameTo(stream); | |
981 stream->Add(" "); | |
982 second()->PrintNameTo(stream); | |
983 stream->Add(" "); | |
984 stream->Add("#%d", argument_count()); | |
985 } | 961 } |
986 | 962 |
987 | 963 |
988 void HBoundsCheck::ApplyIndexChange() { | 964 void HBoundsCheck::ApplyIndexChange() { |
989 if (skip_check()) return; | 965 if (skip_check()) return; |
990 | 966 |
991 DecompositionResult decomposition; | 967 DecompositionResult decomposition; |
992 bool index_is_decomposable = index()->TryDecompose(&decomposition); | 968 bool index_is_decomposable = index()->TryDecompose(&decomposition); |
993 if (index_is_decomposable) { | 969 if (index_is_decomposable) { |
994 ASSERT(decomposition.base() == base()); | 970 ASSERT(decomposition.base() == base()); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1028 } | 1004 } |
1029 | 1005 |
1030 SetOperandAt(0, current_index); | 1006 SetOperandAt(0, current_index); |
1031 | 1007 |
1032 base_ = NULL; | 1008 base_ = NULL; |
1033 offset_ = 0; | 1009 offset_ = 0; |
1034 scale_ = 0; | 1010 scale_ = 0; |
1035 } | 1011 } |
1036 | 1012 |
1037 | 1013 |
1038 void HBoundsCheck::PrintDataTo(StringStream* stream) { | 1014 OStream& HBoundsCheck::PrintDataTo(OStream& os) const { // NOLINT |
1039 index()->PrintNameTo(stream); | 1015 os << NameOf(index()) << " " << NameOf(length()); |
1040 stream->Add(" "); | |
1041 length()->PrintNameTo(stream); | |
1042 if (base() != NULL && (offset() != 0 || scale() != 0)) { | 1016 if (base() != NULL && (offset() != 0 || scale() != 0)) { |
1043 stream->Add(" base: (("); | 1017 os << " base: (("; |
1044 if (base() != index()) { | 1018 if (base() != index()) { |
1045 index()->PrintNameTo(stream); | 1019 os << NameOf(index()); |
1046 } else { | 1020 } else { |
1047 stream->Add("index"); | 1021 os << "index"; |
1048 } | 1022 } |
1049 stream->Add(" + %d) >> %d)", offset(), scale()); | 1023 os << " + " << offset() << ") >> " << scale() << ")"; |
1050 } | 1024 } |
1051 if (skip_check()) { | 1025 if (skip_check()) os << " [DISABLED]"; |
1052 stream->Add(" [DISABLED]"); | 1026 return os; |
1053 } | |
1054 } | 1027 } |
1055 | 1028 |
1056 | 1029 |
1057 void HBoundsCheck::InferRepresentation(HInferRepresentationPhase* h_infer) { | 1030 void HBoundsCheck::InferRepresentation(HInferRepresentationPhase* h_infer) { |
1058 ASSERT(CheckFlag(kFlexibleRepresentation)); | 1031 ASSERT(CheckFlag(kFlexibleRepresentation)); |
1059 HValue* actual_index = index()->ActualValue(); | 1032 HValue* actual_index = index()->ActualValue(); |
1060 HValue* actual_length = length()->ActualValue(); | 1033 HValue* actual_length = length()->ActualValue(); |
1061 Representation index_rep = actual_index->representation(); | 1034 Representation index_rep = actual_index->representation(); |
1062 Representation length_rep = actual_length->representation(); | 1035 Representation length_rep = actual_length->representation(); |
1063 if (index_rep.IsTagged() && actual_index->type().IsSmi()) { | 1036 if (index_rep.IsTagged() && actual_index->type().IsSmi()) { |
(...skipping 22 matching lines...) Expand all Loading... |
1086 } | 1059 } |
1087 | 1060 |
1088 // In case of Smi representation, clamp result to Smi::kMaxValue. | 1061 // In case of Smi representation, clamp result to Smi::kMaxValue. |
1089 if (r.IsSmi()) result->ClampToSmi(); | 1062 if (r.IsSmi()) result->ClampToSmi(); |
1090 return result; | 1063 return result; |
1091 } | 1064 } |
1092 return HValue::InferRange(zone); | 1065 return HValue::InferRange(zone); |
1093 } | 1066 } |
1094 | 1067 |
1095 | 1068 |
1096 void HBoundsCheckBaseIndexInformation::PrintDataTo(StringStream* stream) { | 1069 OStream& HBoundsCheckBaseIndexInformation::PrintDataTo( |
1097 stream->Add("base: "); | 1070 OStream& os) const { // NOLINT |
1098 base_index()->PrintNameTo(stream); | 1071 // TODO(svenpanne) This 2nd base_index() looks wrong... |
1099 stream->Add(", check: "); | 1072 return os << "base: " << NameOf(base_index()) |
1100 base_index()->PrintNameTo(stream); | 1073 << ", check: " << NameOf(base_index()); |
1101 } | 1074 } |
1102 | 1075 |
1103 | 1076 |
1104 void HCallWithDescriptor::PrintDataTo(StringStream* stream) { | 1077 OStream& HCallWithDescriptor::PrintDataTo(OStream& os) const { // NOLINT |
1105 for (int i = 0; i < OperandCount(); i++) { | 1078 for (int i = 0; i < OperandCount(); i++) { |
1106 OperandAt(i)->PrintNameTo(stream); | 1079 os << NameOf(OperandAt(i)) << " "; |
1107 stream->Add(" "); | |
1108 } | 1080 } |
1109 stream->Add("#%d", argument_count()); | 1081 return os << "#" << argument_count(); |
1110 } | 1082 } |
1111 | 1083 |
1112 | 1084 |
1113 void HCallNewArray::PrintDataTo(StringStream* stream) { | 1085 OStream& HCallNewArray::PrintDataTo(OStream& os) const { // NOLINT |
1114 stream->Add(ElementsKindToString(elements_kind())); | 1086 os << ElementsKindToString(elements_kind()) << " "; |
1115 stream->Add(" "); | 1087 return HBinaryCall::PrintDataTo(os); |
1116 HBinaryCall::PrintDataTo(stream); | |
1117 } | 1088 } |
1118 | 1089 |
1119 | 1090 |
1120 void HCallRuntime::PrintDataTo(StringStream* stream) { | 1091 OStream& HCallRuntime::PrintDataTo(OStream& os) const { // NOLINT |
1121 stream->Add("%o ", *name()); | 1092 os << name()->ToCString().get() << " "; |
1122 if (save_doubles() == kSaveFPRegs) { | 1093 if (save_doubles() == kSaveFPRegs) os << "[save doubles] "; |
1123 stream->Add("[save doubles] "); | 1094 return os << "#" << argument_count(); |
1124 } | |
1125 stream->Add("#%d", argument_count()); | |
1126 } | 1095 } |
1127 | 1096 |
1128 | 1097 |
1129 void HClassOfTestAndBranch::PrintDataTo(StringStream* stream) { | 1098 OStream& HClassOfTestAndBranch::PrintDataTo(OStream& os) const { // NOLINT |
1130 stream->Add("class_of_test("); | 1099 return os << "class_of_test(" << NameOf(value()) << ", \"" |
1131 value()->PrintNameTo(stream); | 1100 << class_name()->ToCString().get() << "\")"; |
1132 stream->Add(", \"%o\")", *class_name()); | |
1133 } | 1101 } |
1134 | 1102 |
1135 | 1103 |
1136 void HWrapReceiver::PrintDataTo(StringStream* stream) { | 1104 OStream& HWrapReceiver::PrintDataTo(OStream& os) const { // NOLINT |
1137 receiver()->PrintNameTo(stream); | 1105 return os << NameOf(receiver()) << " " << NameOf(function()); |
1138 stream->Add(" "); | |
1139 function()->PrintNameTo(stream); | |
1140 } | 1106 } |
1141 | 1107 |
1142 | 1108 |
1143 void HAccessArgumentsAt::PrintDataTo(StringStream* stream) { | 1109 OStream& HAccessArgumentsAt::PrintDataTo(OStream& os) const { // NOLINT |
1144 arguments()->PrintNameTo(stream); | 1110 return os << NameOf(arguments()) << "[" << NameOf(index()) << "], length " |
1145 stream->Add("["); | 1111 << NameOf(length()); |
1146 index()->PrintNameTo(stream); | |
1147 stream->Add("], length "); | |
1148 length()->PrintNameTo(stream); | |
1149 } | 1112 } |
1150 | 1113 |
1151 | 1114 |
1152 void HAllocateBlockContext::PrintDataTo(StringStream* stream) { | 1115 OStream& HAllocateBlockContext::PrintDataTo(OStream& os) const { // NOLINT |
1153 context()->PrintNameTo(stream); | 1116 return os << NameOf(context()) << " " << NameOf(function()); |
1154 stream->Add(" "); | |
1155 function()->PrintNameTo(stream); | |
1156 } | 1117 } |
1157 | 1118 |
1158 | 1119 |
1159 void HControlInstruction::PrintDataTo(StringStream* stream) { | 1120 OStream& HControlInstruction::PrintDataTo(OStream& os) const { // NOLINT |
1160 stream->Add(" goto ("); | 1121 os << " goto ("; |
1161 bool first_block = true; | 1122 bool first_block = true; |
1162 for (HSuccessorIterator it(this); !it.Done(); it.Advance()) { | 1123 for (HSuccessorIterator it(this); !it.Done(); it.Advance()) { |
1163 stream->Add(first_block ? "B%d" : ", B%d", it.Current()->block_id()); | 1124 if (!first_block) os << ", "; |
| 1125 os << *it.Current(); |
1164 first_block = false; | 1126 first_block = false; |
1165 } | 1127 } |
1166 stream->Add(")"); | 1128 return os << ")"; |
1167 } | 1129 } |
1168 | 1130 |
1169 | 1131 |
1170 void HUnaryControlInstruction::PrintDataTo(StringStream* stream) { | 1132 OStream& HUnaryControlInstruction::PrintDataTo(OStream& os) const { // NOLINT |
1171 value()->PrintNameTo(stream); | 1133 os << NameOf(value()); |
1172 HControlInstruction::PrintDataTo(stream); | 1134 return HControlInstruction::PrintDataTo(os); |
1173 } | 1135 } |
1174 | 1136 |
1175 | 1137 |
1176 void HReturn::PrintDataTo(StringStream* stream) { | 1138 OStream& HReturn::PrintDataTo(OStream& os) const { // NOLINT |
1177 value()->PrintNameTo(stream); | 1139 return os << NameOf(value()) << " (pop " << NameOf(parameter_count()) |
1178 stream->Add(" (pop "); | 1140 << " values)"; |
1179 parameter_count()->PrintNameTo(stream); | |
1180 stream->Add(" values)"); | |
1181 } | 1141 } |
1182 | 1142 |
1183 | 1143 |
1184 Representation HBranch::observed_input_representation(int index) { | 1144 Representation HBranch::observed_input_representation(int index) { |
1185 static const ToBooleanStub::Types tagged_types( | 1145 static const ToBooleanStub::Types tagged_types( |
1186 ToBooleanStub::NULL_TYPE | | 1146 ToBooleanStub::NULL_TYPE | |
1187 ToBooleanStub::SPEC_OBJECT | | 1147 ToBooleanStub::SPEC_OBJECT | |
1188 ToBooleanStub::STRING | | 1148 ToBooleanStub::STRING | |
1189 ToBooleanStub::SYMBOL); | 1149 ToBooleanStub::SYMBOL); |
1190 if (expected_input_types_.ContainsAnyOf(tagged_types)) { | 1150 if (expected_input_types_.ContainsAnyOf(tagged_types)) { |
(...skipping 23 matching lines...) Expand all Loading... |
1214 *block = HConstant::cast(value)->BooleanValue() | 1174 *block = HConstant::cast(value)->BooleanValue() |
1215 ? FirstSuccessor() | 1175 ? FirstSuccessor() |
1216 : SecondSuccessor(); | 1176 : SecondSuccessor(); |
1217 return true; | 1177 return true; |
1218 } | 1178 } |
1219 *block = NULL; | 1179 *block = NULL; |
1220 return false; | 1180 return false; |
1221 } | 1181 } |
1222 | 1182 |
1223 | 1183 |
1224 void HBranch::PrintDataTo(StringStream* stream) { | 1184 OStream& HBranch::PrintDataTo(OStream& os) const { // NOLINT |
1225 HUnaryControlInstruction::PrintDataTo(stream); | 1185 return HUnaryControlInstruction::PrintDataTo(os) << " " |
1226 OStringStream os; | 1186 << expected_input_types(); |
1227 os << " " << expected_input_types(); | |
1228 stream->Add(os.c_str()); | |
1229 } | 1187 } |
1230 | 1188 |
1231 | 1189 |
1232 void HCompareMap::PrintDataTo(StringStream* stream) { | 1190 OStream& HCompareMap::PrintDataTo(OStream& os) const { // NOLINT |
1233 value()->PrintNameTo(stream); | 1191 os << NameOf(value()) << " (" << *map().handle() << ")"; |
1234 stream->Add(" (%p)", *map().handle()); | 1192 HControlInstruction::PrintDataTo(os); |
1235 HControlInstruction::PrintDataTo(stream); | |
1236 if (known_successor_index() == 0) { | 1193 if (known_successor_index() == 0) { |
1237 stream->Add(" [true]"); | 1194 os << " [true]"; |
1238 } else if (known_successor_index() == 1) { | 1195 } else if (known_successor_index() == 1) { |
1239 stream->Add(" [false]"); | 1196 os << " [false]"; |
1240 } | 1197 } |
| 1198 return os; |
1241 } | 1199 } |
1242 | 1200 |
1243 | 1201 |
1244 const char* HUnaryMathOperation::OpName() const { | 1202 const char* HUnaryMathOperation::OpName() const { |
1245 switch (op()) { | 1203 switch (op()) { |
1246 case kMathFloor: return "floor"; | 1204 case kMathFloor: return "floor"; |
1247 case kMathRound: return "round"; | 1205 case kMathRound: return "round"; |
1248 case kMathAbs: return "abs"; | 1206 case kMathAbs: return "abs"; |
1249 case kMathLog: return "log"; | 1207 case kMathLog: return "log"; |
1250 case kMathExp: return "exp"; | 1208 case kMathExp: return "exp"; |
(...skipping 25 matching lines...) Expand all Loading... |
1276 // In case of Smi representation, clamp Math.abs(Smi::kMinValue) to | 1234 // In case of Smi representation, clamp Math.abs(Smi::kMinValue) to |
1277 // Smi::kMaxValue. | 1235 // Smi::kMaxValue. |
1278 if (r.IsSmi()) result->ClampToSmi(); | 1236 if (r.IsSmi()) result->ClampToSmi(); |
1279 return result; | 1237 return result; |
1280 } | 1238 } |
1281 } | 1239 } |
1282 return HValue::InferRange(zone); | 1240 return HValue::InferRange(zone); |
1283 } | 1241 } |
1284 | 1242 |
1285 | 1243 |
1286 void HUnaryMathOperation::PrintDataTo(StringStream* stream) { | 1244 OStream& HUnaryMathOperation::PrintDataTo(OStream& os) const { // NOLINT |
1287 const char* name = OpName(); | 1245 return os << OpName() << " " << NameOf(value()); |
1288 stream->Add("%s ", name); | |
1289 value()->PrintNameTo(stream); | |
1290 } | 1246 } |
1291 | 1247 |
1292 | 1248 |
1293 void HUnaryOperation::PrintDataTo(StringStream* stream) { | 1249 OStream& HUnaryOperation::PrintDataTo(OStream& os) const { // NOLINT |
1294 value()->PrintNameTo(stream); | 1250 return os << NameOf(value()); |
1295 } | 1251 } |
1296 | 1252 |
1297 | 1253 |
1298 void HHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) { | 1254 OStream& HHasInstanceTypeAndBranch::PrintDataTo(OStream& os) const { // NOLINT |
1299 value()->PrintNameTo(stream); | 1255 os << NameOf(value()); |
1300 switch (from_) { | 1256 switch (from_) { |
1301 case FIRST_JS_RECEIVER_TYPE: | 1257 case FIRST_JS_RECEIVER_TYPE: |
1302 if (to_ == LAST_TYPE) stream->Add(" spec_object"); | 1258 if (to_ == LAST_TYPE) os << " spec_object"; |
1303 break; | 1259 break; |
1304 case JS_REGEXP_TYPE: | 1260 case JS_REGEXP_TYPE: |
1305 if (to_ == JS_REGEXP_TYPE) stream->Add(" reg_exp"); | 1261 if (to_ == JS_REGEXP_TYPE) os << " reg_exp"; |
1306 break; | 1262 break; |
1307 case JS_ARRAY_TYPE: | 1263 case JS_ARRAY_TYPE: |
1308 if (to_ == JS_ARRAY_TYPE) stream->Add(" array"); | 1264 if (to_ == JS_ARRAY_TYPE) os << " array"; |
1309 break; | 1265 break; |
1310 case JS_FUNCTION_TYPE: | 1266 case JS_FUNCTION_TYPE: |
1311 if (to_ == JS_FUNCTION_TYPE) stream->Add(" function"); | 1267 if (to_ == JS_FUNCTION_TYPE) os << " function"; |
1312 break; | 1268 break; |
1313 default: | 1269 default: |
1314 break; | 1270 break; |
1315 } | 1271 } |
| 1272 return os; |
1316 } | 1273 } |
1317 | 1274 |
1318 | 1275 |
1319 void HTypeofIsAndBranch::PrintDataTo(StringStream* stream) { | 1276 OStream& HTypeofIsAndBranch::PrintDataTo(OStream& os) const { // NOLINT |
1320 value()->PrintNameTo(stream); | 1277 os << NameOf(value()) << " == " << type_literal()->ToCString().get(); |
1321 stream->Add(" == %o", *type_literal_.handle()); | 1278 return HControlInstruction::PrintDataTo(os); |
1322 HControlInstruction::PrintDataTo(stream); | |
1323 } | 1279 } |
1324 | 1280 |
1325 | 1281 |
1326 static String* TypeOfString(HConstant* constant, Isolate* isolate) { | 1282 static String* TypeOfString(HConstant* constant, Isolate* isolate) { |
1327 Heap* heap = isolate->heap(); | 1283 Heap* heap = isolate->heap(); |
1328 if (constant->HasNumberValue()) return heap->number_string(); | 1284 if (constant->HasNumberValue()) return heap->number_string(); |
1329 if (constant->IsUndetectable()) return heap->undefined_string(); | 1285 if (constant->IsUndetectable()) return heap->undefined_string(); |
1330 if (constant->HasStringValue()) return heap->string_string(); | 1286 if (constant->HasStringValue()) return heap->string_string(); |
1331 switch (constant->GetInstanceType()) { | 1287 switch (constant->GetInstanceType()) { |
1332 case ODDBALL_TYPE: { | 1288 case ODDBALL_TYPE: { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1364 bool number_type = | 1320 bool number_type = |
1365 type_literal_.IsKnownGlobal(isolate()->heap()->number_string()); | 1321 type_literal_.IsKnownGlobal(isolate()->heap()->number_string()); |
1366 *block = number_type ? FirstSuccessor() : SecondSuccessor(); | 1322 *block = number_type ? FirstSuccessor() : SecondSuccessor(); |
1367 return true; | 1323 return true; |
1368 } | 1324 } |
1369 *block = NULL; | 1325 *block = NULL; |
1370 return false; | 1326 return false; |
1371 } | 1327 } |
1372 | 1328 |
1373 | 1329 |
1374 void HCheckMapValue::PrintDataTo(StringStream* stream) { | 1330 OStream& HCheckMapValue::PrintDataTo(OStream& os) const { // NOLINT |
1375 value()->PrintNameTo(stream); | 1331 return os << NameOf(value()) << " " << NameOf(map()); |
1376 stream->Add(" "); | |
1377 map()->PrintNameTo(stream); | |
1378 } | 1332 } |
1379 | 1333 |
1380 | 1334 |
1381 HValue* HCheckMapValue::Canonicalize() { | 1335 HValue* HCheckMapValue::Canonicalize() { |
1382 if (map()->IsConstant()) { | 1336 if (map()->IsConstant()) { |
1383 HConstant* c_map = HConstant::cast(map()); | 1337 HConstant* c_map = HConstant::cast(map()); |
1384 return HCheckMaps::CreateAndInsertAfter( | 1338 return HCheckMaps::CreateAndInsertAfter( |
1385 block()->graph()->zone(), value(), c_map->MapValue(), | 1339 block()->graph()->zone(), value(), c_map->MapValue(), |
1386 c_map->HasStableMapValue(), this); | 1340 c_map->HasStableMapValue(), this); |
1387 } | 1341 } |
1388 return this; | 1342 return this; |
1389 } | 1343 } |
1390 | 1344 |
1391 | 1345 |
1392 void HForInPrepareMap::PrintDataTo(StringStream* stream) { | 1346 OStream& HForInPrepareMap::PrintDataTo(OStream& os) const { // NOLINT |
1393 enumerable()->PrintNameTo(stream); | 1347 return os << NameOf(enumerable()); |
1394 } | 1348 } |
1395 | 1349 |
1396 | 1350 |
1397 void HForInCacheArray::PrintDataTo(StringStream* stream) { | 1351 OStream& HForInCacheArray::PrintDataTo(OStream& os) const { // NOLINT |
1398 enumerable()->PrintNameTo(stream); | 1352 return os << NameOf(enumerable()) << " " << NameOf(map()) << "[" << idx_ |
1399 stream->Add(" "); | 1353 << "]"; |
1400 map()->PrintNameTo(stream); | |
1401 stream->Add("[%d]", idx_); | |
1402 } | 1354 } |
1403 | 1355 |
1404 | 1356 |
1405 void HLoadFieldByIndex::PrintDataTo(StringStream* stream) { | 1357 OStream& HLoadFieldByIndex::PrintDataTo(OStream& os) const { // NOLINT |
1406 object()->PrintNameTo(stream); | 1358 return os << NameOf(object()) << " " << NameOf(index()); |
1407 stream->Add(" "); | |
1408 index()->PrintNameTo(stream); | |
1409 } | 1359 } |
1410 | 1360 |
1411 | 1361 |
1412 static bool MatchLeftIsOnes(HValue* l, HValue* r, HValue** negated) { | 1362 static bool MatchLeftIsOnes(HValue* l, HValue* r, HValue** negated) { |
1413 if (!l->EqualsInteger32Constant(~0)) return false; | 1363 if (!l->EqualsInteger32Constant(~0)) return false; |
1414 *negated = r; | 1364 *negated = r; |
1415 return true; | 1365 return true; |
1416 } | 1366 } |
1417 | 1367 |
1418 | 1368 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1534 | 1484 |
1535 HValue* HWrapReceiver::Canonicalize() { | 1485 HValue* HWrapReceiver::Canonicalize() { |
1536 if (HasNoUses()) return NULL; | 1486 if (HasNoUses()) return NULL; |
1537 if (receiver()->type().IsJSObject()) { | 1487 if (receiver()->type().IsJSObject()) { |
1538 return receiver(); | 1488 return receiver(); |
1539 } | 1489 } |
1540 return this; | 1490 return this; |
1541 } | 1491 } |
1542 | 1492 |
1543 | 1493 |
1544 void HTypeof::PrintDataTo(StringStream* stream) { | 1494 OStream& HTypeof::PrintDataTo(OStream& os) const { // NOLINT |
1545 value()->PrintNameTo(stream); | 1495 return os << NameOf(value()); |
1546 } | 1496 } |
1547 | 1497 |
1548 | 1498 |
1549 HInstruction* HForceRepresentation::New(Zone* zone, HValue* context, | 1499 HInstruction* HForceRepresentation::New(Zone* zone, HValue* context, |
1550 HValue* value, Representation representation) { | 1500 HValue* value, Representation representation) { |
1551 if (FLAG_fold_constants && value->IsConstant()) { | 1501 if (FLAG_fold_constants && value->IsConstant()) { |
1552 HConstant* c = HConstant::cast(value); | 1502 HConstant* c = HConstant::cast(value); |
1553 if (c->HasNumberValue()) { | 1503 if (c->HasNumberValue()) { |
1554 double double_res = c->DoubleValue(); | 1504 double double_res = c->DoubleValue(); |
1555 if (representation.IsDouble()) { | 1505 if (representation.IsDouble()) { |
1556 return HConstant::New(zone, context, double_res); | 1506 return HConstant::New(zone, context, double_res); |
1557 | 1507 |
1558 } else if (representation.CanContainDouble(double_res)) { | 1508 } else if (representation.CanContainDouble(double_res)) { |
1559 return HConstant::New(zone, context, | 1509 return HConstant::New(zone, context, |
1560 static_cast<int32_t>(double_res), | 1510 static_cast<int32_t>(double_res), |
1561 representation); | 1511 representation); |
1562 } | 1512 } |
1563 } | 1513 } |
1564 } | 1514 } |
1565 return new(zone) HForceRepresentation(value, representation); | 1515 return new(zone) HForceRepresentation(value, representation); |
1566 } | 1516 } |
1567 | 1517 |
1568 | 1518 |
1569 void HForceRepresentation::PrintDataTo(StringStream* stream) { | 1519 OStream& HForceRepresentation::PrintDataTo(OStream& os) const { // NOLINT |
1570 stream->Add("%s ", representation().Mnemonic()); | 1520 return os << representation().Mnemonic() << " " << NameOf(value()); |
1571 value()->PrintNameTo(stream); | |
1572 } | 1521 } |
1573 | 1522 |
1574 | 1523 |
1575 void HChange::PrintDataTo(StringStream* stream) { | 1524 OStream& HChange::PrintDataTo(OStream& os) const { // NOLINT |
1576 HUnaryOperation::PrintDataTo(stream); | 1525 HUnaryOperation::PrintDataTo(os); |
1577 stream->Add(" %s to %s", from().Mnemonic(), to().Mnemonic()); | 1526 os << " " << from().Mnemonic() << " to " << to().Mnemonic(); |
1578 | 1527 |
1579 if (CanTruncateToSmi()) stream->Add(" truncating-smi"); | 1528 if (CanTruncateToSmi()) os << " truncating-smi"; |
1580 if (CanTruncateToInt32()) stream->Add(" truncating-int32"); | 1529 if (CanTruncateToInt32()) os << " truncating-int32"; |
1581 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); | 1530 if (CheckFlag(kBailoutOnMinusZero)) os << " -0?"; |
1582 if (CheckFlag(kAllowUndefinedAsNaN)) stream->Add(" allow-undefined-as-nan"); | 1531 if (CheckFlag(kAllowUndefinedAsNaN)) os << " allow-undefined-as-nan"; |
| 1532 return os; |
1583 } | 1533 } |
1584 | 1534 |
1585 | 1535 |
1586 HValue* HUnaryMathOperation::Canonicalize() { | 1536 HValue* HUnaryMathOperation::Canonicalize() { |
1587 if (op() == kMathRound || op() == kMathFloor) { | 1537 if (op() == kMathRound || op() == kMathFloor) { |
1588 HValue* val = value(); | 1538 HValue* val = value(); |
1589 if (val->IsChange()) val = HChange::cast(val)->value(); | 1539 if (val->IsChange()) val = HChange::cast(val)->value(); |
1590 if (val->representation().IsSmiOrInteger32()) { | 1540 if (val->representation().IsSmiOrInteger32()) { |
1591 if (val->representation().Equals(representation())) return val; | 1541 if (val->representation().Equals(representation())) return val; |
1592 return Prepend(new(block()->zone()) HChange( | 1542 return Prepend(new(block()->zone()) HChange( |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1676 case IS_INTERNALIZED_STRING: | 1626 case IS_INTERNALIZED_STRING: |
1677 *mask = kIsNotStringMask | kIsNotInternalizedMask; | 1627 *mask = kIsNotStringMask | kIsNotInternalizedMask; |
1678 *tag = kInternalizedTag; | 1628 *tag = kInternalizedTag; |
1679 return; | 1629 return; |
1680 default: | 1630 default: |
1681 UNREACHABLE(); | 1631 UNREACHABLE(); |
1682 } | 1632 } |
1683 } | 1633 } |
1684 | 1634 |
1685 | 1635 |
1686 void HCheckMaps::PrintDataTo(StringStream* stream) { | 1636 OStream& HCheckMaps::PrintDataTo(OStream& os) const { // NOLINT |
1687 value()->PrintNameTo(stream); | 1637 os << NameOf(value()) << " [" << *maps()->at(0).handle(); |
1688 stream->Add(" [%p", *maps()->at(0).handle()); | |
1689 for (int i = 1; i < maps()->size(); ++i) { | 1638 for (int i = 1; i < maps()->size(); ++i) { |
1690 stream->Add(",%p", *maps()->at(i).handle()); | 1639 os << "," << *maps()->at(i).handle(); |
1691 } | 1640 } |
1692 stream->Add("]%s", IsStabilityCheck() ? "(stability-check)" : ""); | 1641 os << "]"; |
| 1642 if (IsStabilityCheck()) os << "(stability-check)"; |
| 1643 return os; |
1693 } | 1644 } |
1694 | 1645 |
1695 | 1646 |
1696 HValue* HCheckMaps::Canonicalize() { | 1647 HValue* HCheckMaps::Canonicalize() { |
1697 if (!IsStabilityCheck() && maps_are_stable() && value()->IsConstant()) { | 1648 if (!IsStabilityCheck() && maps_are_stable() && value()->IsConstant()) { |
1698 HConstant* c_value = HConstant::cast(value()); | 1649 HConstant* c_value = HConstant::cast(value()); |
1699 if (c_value->HasObjectMap()) { | 1650 if (c_value->HasObjectMap()) { |
1700 for (int i = 0; i < maps()->size(); ++i) { | 1651 for (int i = 0; i < maps()->size(); ++i) { |
1701 if (c_value->ObjectMap() == maps()->at(i)) { | 1652 if (c_value->ObjectMap() == maps()->at(i)) { |
1702 if (maps()->size() > 1) { | 1653 if (maps()->size() > 1) { |
1703 set_maps(new(block()->graph()->zone()) UniqueSet<Map>( | 1654 set_maps(new(block()->graph()->zone()) UniqueSet<Map>( |
1704 maps()->at(i), block()->graph()->zone())); | 1655 maps()->at(i), block()->graph()->zone())); |
1705 } | 1656 } |
1706 MarkAsStabilityCheck(); | 1657 MarkAsStabilityCheck(); |
1707 break; | 1658 break; |
1708 } | 1659 } |
1709 } | 1660 } |
1710 } | 1661 } |
1711 } | 1662 } |
1712 return this; | 1663 return this; |
1713 } | 1664 } |
1714 | 1665 |
1715 | 1666 |
1716 void HCheckValue::PrintDataTo(StringStream* stream) { | 1667 OStream& HCheckValue::PrintDataTo(OStream& os) const { // NOLINT |
1717 value()->PrintNameTo(stream); | 1668 return os << NameOf(value()) << " " << Brief(*object().handle()); |
1718 stream->Add(" "); | |
1719 object().handle()->ShortPrint(stream); | |
1720 } | 1669 } |
1721 | 1670 |
1722 | 1671 |
1723 HValue* HCheckValue::Canonicalize() { | 1672 HValue* HCheckValue::Canonicalize() { |
1724 return (value()->IsConstant() && | 1673 return (value()->IsConstant() && |
1725 HConstant::cast(value())->EqualsUnique(object_)) ? NULL : this; | 1674 HConstant::cast(value())->EqualsUnique(object_)) ? NULL : this; |
1726 } | 1675 } |
1727 | 1676 |
1728 | 1677 |
1729 const char* HCheckInstanceType::GetCheckName() { | 1678 const char* HCheckInstanceType::GetCheckName() const { |
1730 switch (check_) { | 1679 switch (check_) { |
1731 case IS_SPEC_OBJECT: return "object"; | 1680 case IS_SPEC_OBJECT: return "object"; |
1732 case IS_JS_ARRAY: return "array"; | 1681 case IS_JS_ARRAY: return "array"; |
1733 case IS_STRING: return "string"; | 1682 case IS_STRING: return "string"; |
1734 case IS_INTERNALIZED_STRING: return "internalized_string"; | 1683 case IS_INTERNALIZED_STRING: return "internalized_string"; |
1735 } | 1684 } |
1736 UNREACHABLE(); | 1685 UNREACHABLE(); |
1737 return ""; | 1686 return ""; |
1738 } | 1687 } |
1739 | 1688 |
1740 | 1689 |
1741 void HCheckInstanceType::PrintDataTo(StringStream* stream) { | 1690 OStream& HCheckInstanceType::PrintDataTo(OStream& os) const { // NOLINT |
1742 stream->Add("%s ", GetCheckName()); | 1691 os << GetCheckName() << " "; |
1743 HUnaryOperation::PrintDataTo(stream); | 1692 return HUnaryOperation::PrintDataTo(os); |
1744 } | 1693 } |
1745 | 1694 |
1746 | 1695 |
1747 void HCallStub::PrintDataTo(StringStream* stream) { | 1696 OStream& HCallStub::PrintDataTo(OStream& os) const { // NOLINT |
1748 stream->Add("%s ", | 1697 os << CodeStub::MajorName(major_key_, false) << " "; |
1749 CodeStub::MajorName(major_key_, false)); | 1698 return HUnaryCall::PrintDataTo(os); |
1750 HUnaryCall::PrintDataTo(stream); | |
1751 } | 1699 } |
1752 | 1700 |
1753 | 1701 |
1754 void HUnknownOSRValue::PrintDataTo(StringStream *stream) { | 1702 OStream& HUnknownOSRValue::PrintDataTo(OStream& os) const { // NOLINT |
1755 const char* type = "expression"; | 1703 const char* type = "expression"; |
1756 if (environment_->is_local_index(index_)) type = "local"; | 1704 if (environment_->is_local_index(index_)) type = "local"; |
1757 if (environment_->is_special_index(index_)) type = "special"; | 1705 if (environment_->is_special_index(index_)) type = "special"; |
1758 if (environment_->is_parameter_index(index_)) type = "parameter"; | 1706 if (environment_->is_parameter_index(index_)) type = "parameter"; |
1759 stream->Add("%s @ %d", type, index_); | 1707 return os << type << " @ " << index_; |
1760 } | 1708 } |
1761 | 1709 |
1762 | 1710 |
1763 void HInstanceOf::PrintDataTo(StringStream* stream) { | 1711 OStream& HInstanceOf::PrintDataTo(OStream& os) const { // NOLINT |
1764 left()->PrintNameTo(stream); | 1712 return os << NameOf(left()) << " " << NameOf(right()) << " " |
1765 stream->Add(" "); | 1713 << NameOf(context()); |
1766 right()->PrintNameTo(stream); | |
1767 stream->Add(" "); | |
1768 context()->PrintNameTo(stream); | |
1769 } | 1714 } |
1770 | 1715 |
1771 | 1716 |
1772 Range* HValue::InferRange(Zone* zone) { | 1717 Range* HValue::InferRange(Zone* zone) { |
1773 Range* result; | 1718 Range* result; |
1774 if (representation().IsSmi() || type().IsSmi()) { | 1719 if (representation().IsSmi() || type().IsSmi()) { |
1775 result = new(zone) Range(Smi::kMinValue, Smi::kMaxValue); | 1720 result = new(zone) Range(Smi::kMinValue, Smi::kMaxValue); |
1776 result->set_can_be_minus_zero(false); | 1721 result->set_can_be_minus_zero(false); |
1777 } else { | 1722 } else { |
1778 result = new(zone) Range(); | 1723 result = new(zone) Range(); |
(...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2471 } | 2416 } |
2472 } | 2417 } |
2473 | 2418 |
2474 | 2419 |
2475 void HPushArguments::AddInput(HValue* value) { | 2420 void HPushArguments::AddInput(HValue* value) { |
2476 inputs_.Add(NULL, value->block()->zone()); | 2421 inputs_.Add(NULL, value->block()->zone()); |
2477 SetOperandAt(OperandCount() - 1, value); | 2422 SetOperandAt(OperandCount() - 1, value); |
2478 } | 2423 } |
2479 | 2424 |
2480 | 2425 |
2481 void HPhi::PrintTo(StringStream* stream) { | 2426 OStream& HPhi::PrintTo(OStream& os) const { // NOLINT |
2482 stream->Add("["); | 2427 os << "["; |
2483 for (int i = 0; i < OperandCount(); ++i) { | 2428 for (int i = 0; i < OperandCount(); ++i) { |
2484 HValue* value = OperandAt(i); | 2429 os << " " << NameOf(OperandAt(i)) << " "; |
2485 stream->Add(" "); | |
2486 value->PrintNameTo(stream); | |
2487 stream->Add(" "); | |
2488 } | 2430 } |
2489 stream->Add(" uses:%d_%ds_%di_%dd_%dt", | 2431 return os << " uses:" << UseCount() << "_" |
2490 UseCount(), | 2432 << smi_non_phi_uses() + smi_indirect_uses() << "s_" |
2491 smi_non_phi_uses() + smi_indirect_uses(), | 2433 << int32_non_phi_uses() + int32_indirect_uses() << "i_" |
2492 int32_non_phi_uses() + int32_indirect_uses(), | 2434 << double_non_phi_uses() + double_indirect_uses() << "d_" |
2493 double_non_phi_uses() + double_indirect_uses(), | 2435 << tagged_non_phi_uses() + tagged_indirect_uses() << "t" |
2494 tagged_non_phi_uses() + tagged_indirect_uses()); | 2436 << TypeOf(this) << "]"; |
2495 PrintTypeTo(stream); | |
2496 stream->Add("]"); | |
2497 } | 2437 } |
2498 | 2438 |
2499 | 2439 |
2500 void HPhi::AddInput(HValue* value) { | 2440 void HPhi::AddInput(HValue* value) { |
2501 inputs_.Add(NULL, value->block()->zone()); | 2441 inputs_.Add(NULL, value->block()->zone()); |
2502 SetOperandAt(OperandCount() - 1, value); | 2442 SetOperandAt(OperandCount() - 1, value); |
2503 // Mark phis that may have 'arguments' directly or indirectly as an operand. | 2443 // Mark phis that may have 'arguments' directly or indirectly as an operand. |
2504 if (!CheckFlag(kIsArguments) && value->CheckFlag(kIsArguments)) { | 2444 if (!CheckFlag(kIsArguments) && value->CheckFlag(kIsArguments)) { |
2505 SetFlag(kIsArguments); | 2445 SetFlag(kIsArguments); |
2506 } | 2446 } |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2608 AddPushedValue(from_values->at(i)); | 2548 AddPushedValue(from_values->at(i)); |
2609 } | 2549 } |
2610 } | 2550 } |
2611 } | 2551 } |
2612 pop_count_ += from->pop_count_; | 2552 pop_count_ += from->pop_count_; |
2613 from->DeleteAndReplaceWith(NULL); | 2553 from->DeleteAndReplaceWith(NULL); |
2614 } | 2554 } |
2615 } | 2555 } |
2616 | 2556 |
2617 | 2557 |
2618 void HSimulate::PrintDataTo(StringStream* stream) { | 2558 OStream& HSimulate::PrintDataTo(OStream& os) const { // NOLINT |
2619 stream->Add("id=%d", ast_id().ToInt()); | 2559 os << "id=" << ast_id().ToInt(); |
2620 if (pop_count_ > 0) stream->Add(" pop %d", pop_count_); | 2560 if (pop_count_ > 0) os << " pop " << pop_count_; |
2621 if (values_.length() > 0) { | 2561 if (values_.length() > 0) { |
2622 if (pop_count_ > 0) stream->Add(" /"); | 2562 if (pop_count_ > 0) os << " /"; |
2623 for (int i = values_.length() - 1; i >= 0; --i) { | 2563 for (int i = values_.length() - 1; i >= 0; --i) { |
2624 if (HasAssignedIndexAt(i)) { | 2564 if (HasAssignedIndexAt(i)) { |
2625 stream->Add(" var[%d] = ", GetAssignedIndexAt(i)); | 2565 os << " var[" << GetAssignedIndexAt(i) << "] = "; |
2626 } else { | 2566 } else { |
2627 stream->Add(" push "); | 2567 os << " push "; |
2628 } | 2568 } |
2629 values_[i]->PrintNameTo(stream); | 2569 os << NameOf(values_[i]); |
2630 if (i > 0) stream->Add(","); | 2570 if (i > 0) os << ","; |
2631 } | 2571 } |
2632 } | 2572 } |
| 2573 return os; |
2633 } | 2574 } |
2634 | 2575 |
2635 | 2576 |
2636 void HSimulate::ReplayEnvironment(HEnvironment* env) { | 2577 void HSimulate::ReplayEnvironment(HEnvironment* env) { |
2637 if (done_with_replay_) return; | 2578 if (done_with_replay_) return; |
2638 ASSERT(env != NULL); | 2579 ASSERT(env != NULL); |
2639 env->set_ast_id(ast_id()); | 2580 env->set_ast_id(ast_id()); |
2640 env->Drop(pop_count()); | 2581 env->Drop(pop_count()); |
2641 for (int i = values()->length() - 1; i >= 0; --i) { | 2582 for (int i = values()->length() - 1; i >= 0; --i) { |
2642 HValue* value = values()->at(i); | 2583 HValue* value = values()->at(i); |
(...skipping 26 matching lines...) Expand all Loading... |
2669 // same capture id in the current and all outer environments. | 2610 // same capture id in the current and all outer environments. |
2670 void HCapturedObject::ReplayEnvironment(HEnvironment* env) { | 2611 void HCapturedObject::ReplayEnvironment(HEnvironment* env) { |
2671 ASSERT(env != NULL); | 2612 ASSERT(env != NULL); |
2672 while (env != NULL) { | 2613 while (env != NULL) { |
2673 ReplayEnvironmentNested(env->values(), this); | 2614 ReplayEnvironmentNested(env->values(), this); |
2674 env = env->outer(); | 2615 env = env->outer(); |
2675 } | 2616 } |
2676 } | 2617 } |
2677 | 2618 |
2678 | 2619 |
2679 void HCapturedObject::PrintDataTo(StringStream* stream) { | 2620 OStream& HCapturedObject::PrintDataTo(OStream& os) const { // NOLINT |
2680 stream->Add("#%d ", capture_id()); | 2621 os << "#" << capture_id() << " "; |
2681 HDematerializedObject::PrintDataTo(stream); | 2622 return HDematerializedObject::PrintDataTo(os); |
2682 } | 2623 } |
2683 | 2624 |
2684 | 2625 |
2685 void HEnterInlined::RegisterReturnTarget(HBasicBlock* return_target, | 2626 void HEnterInlined::RegisterReturnTarget(HBasicBlock* return_target, |
2686 Zone* zone) { | 2627 Zone* zone) { |
2687 ASSERT(return_target->IsInlineReturnTarget()); | 2628 ASSERT(return_target->IsInlineReturnTarget()); |
2688 return_targets_.Add(return_target, zone); | 2629 return_targets_.Add(return_target, zone); |
2689 } | 2630 } |
2690 | 2631 |
2691 | 2632 |
2692 void HEnterInlined::PrintDataTo(StringStream* stream) { | 2633 OStream& HEnterInlined::PrintDataTo(OStream& os) const { // NOLINT |
2693 SmartArrayPointer<char> name = function()->debug_name()->ToCString(); | 2634 return os << function()->debug_name()->ToCString().get() |
2694 stream->Add("%s, id=%d", name.get(), function()->id().ToInt()); | 2635 << ", id=" << function()->id().ToInt(); |
2695 } | 2636 } |
2696 | 2637 |
2697 | 2638 |
2698 static bool IsInteger32(double value) { | 2639 static bool IsInteger32(double value) { |
2699 double roundtrip_value = static_cast<double>(static_cast<int32_t>(value)); | 2640 double roundtrip_value = static_cast<double>(static_cast<int32_t>(value)); |
2700 return BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(value); | 2641 return BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(value); |
2701 } | 2642 } |
2702 | 2643 |
2703 | 2644 |
2704 HConstant::HConstant(Handle<Object> object, Representation r) | 2645 HConstant::HConstant(Handle<Object> object, Representation r) |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2965 new(zone) HConstant(1) : new(zone) HConstant(0); | 2906 new(zone) HConstant(1) : new(zone) HConstant(0); |
2966 } else if (handle->IsUndefined()) { | 2907 } else if (handle->IsUndefined()) { |
2967 res = new(zone) HConstant(base::OS::nan_value()); | 2908 res = new(zone) HConstant(base::OS::nan_value()); |
2968 } else if (handle->IsNull()) { | 2909 } else if (handle->IsNull()) { |
2969 res = new(zone) HConstant(0); | 2910 res = new(zone) HConstant(0); |
2970 } | 2911 } |
2971 return Maybe<HConstant*>(res != NULL, res); | 2912 return Maybe<HConstant*>(res != NULL, res); |
2972 } | 2913 } |
2973 | 2914 |
2974 | 2915 |
2975 void HConstant::PrintDataTo(StringStream* stream) { | 2916 OStream& HConstant::PrintDataTo(OStream& os) const { // NOLINT |
2976 if (has_int32_value_) { | 2917 if (has_int32_value_) { |
2977 stream->Add("%d ", int32_value_); | 2918 os << int32_value_ << " "; |
2978 } else if (has_double_value_) { | 2919 } else if (has_double_value_) { |
2979 stream->Add("%f ", FmtElm(double_value_)); | 2920 os << double_value_ << " "; |
2980 } else if (has_external_reference_value_) { | 2921 } else if (has_external_reference_value_) { |
2981 stream->Add("%p ", reinterpret_cast<void*>( | 2922 os << reinterpret_cast<void*>(external_reference_value_.address()) << " "; |
2982 external_reference_value_.address())); | |
2983 } else { | 2923 } else { |
2984 handle(Isolate::Current())->ShortPrint(stream); | 2924 // The handle() method is silently and lazily mutating the object. |
2985 stream->Add(" "); | 2925 Handle<Object> h = const_cast<HConstant*>(this)->handle(Isolate::Current()); |
2986 if (HasStableMapValue()) { | 2926 os << Brief(*h) << " "; |
2987 stream->Add("[stable-map] "); | 2927 if (HasStableMapValue()) os << "[stable-map] "; |
2988 } | 2928 if (HasObjectMap()) os << "[map " << *ObjectMap().handle() << "] "; |
2989 if (HasObjectMap()) { | |
2990 stream->Add("[map %p] ", *ObjectMap().handle()); | |
2991 } | |
2992 } | 2929 } |
2993 if (!is_not_in_new_space_) { | 2930 if (!is_not_in_new_space_) os << "[new space] "; |
2994 stream->Add("[new space] "); | 2931 return os; |
2995 } | |
2996 } | 2932 } |
2997 | 2933 |
2998 | 2934 |
2999 void HBinaryOperation::PrintDataTo(StringStream* stream) { | 2935 OStream& HBinaryOperation::PrintDataTo(OStream& os) const { // NOLINT |
3000 left()->PrintNameTo(stream); | 2936 os << NameOf(left()) << " " << NameOf(right()); |
3001 stream->Add(" "); | 2937 if (CheckFlag(kCanOverflow)) os << " !"; |
3002 right()->PrintNameTo(stream); | 2938 if (CheckFlag(kBailoutOnMinusZero)) os << " -0?"; |
3003 if (CheckFlag(kCanOverflow)) stream->Add(" !"); | 2939 return os; |
3004 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); | |
3005 } | 2940 } |
3006 | 2941 |
3007 | 2942 |
3008 void HBinaryOperation::InferRepresentation(HInferRepresentationPhase* h_infer) { | 2943 void HBinaryOperation::InferRepresentation(HInferRepresentationPhase* h_infer) { |
3009 ASSERT(CheckFlag(kFlexibleRepresentation)); | 2944 ASSERT(CheckFlag(kFlexibleRepresentation)); |
3010 Representation new_rep = RepresentationFromInputs(); | 2945 Representation new_rep = RepresentationFromInputs(); |
3011 UpdateRepresentation(new_rep, h_infer, "inputs"); | 2946 UpdateRepresentation(new_rep, h_infer, "inputs"); |
3012 | 2947 |
3013 if (representation().IsSmi() && HasNonSmiUse()) { | 2948 if (representation().IsSmi() && HasNonSmiUse()) { |
3014 UpdateRepresentation( | 2949 UpdateRepresentation( |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3217 case EXTERNAL_INT16_ELEMENTS: | 3152 case EXTERNAL_INT16_ELEMENTS: |
3218 return new(zone) Range(kMinInt16, kMaxInt16); | 3153 return new(zone) Range(kMinInt16, kMaxInt16); |
3219 case EXTERNAL_UINT16_ELEMENTS: | 3154 case EXTERNAL_UINT16_ELEMENTS: |
3220 return new(zone) Range(kMinUInt16, kMaxUInt16); | 3155 return new(zone) Range(kMinUInt16, kMaxUInt16); |
3221 default: | 3156 default: |
3222 return HValue::InferRange(zone); | 3157 return HValue::InferRange(zone); |
3223 } | 3158 } |
3224 } | 3159 } |
3225 | 3160 |
3226 | 3161 |
3227 void HCompareGeneric::PrintDataTo(StringStream* stream) { | 3162 OStream& HCompareGeneric::PrintDataTo(OStream& os) const { // NOLINT |
3228 stream->Add(Token::Name(token())); | 3163 os << Token::Name(token()) << " "; |
3229 stream->Add(" "); | 3164 return HBinaryOperation::PrintDataTo(os); |
3230 HBinaryOperation::PrintDataTo(stream); | |
3231 } | 3165 } |
3232 | 3166 |
3233 | 3167 |
3234 void HStringCompareAndBranch::PrintDataTo(StringStream* stream) { | 3168 OStream& HStringCompareAndBranch::PrintDataTo(OStream& os) const { // NOLINT |
3235 stream->Add(Token::Name(token())); | 3169 os << Token::Name(token()) << " "; |
3236 stream->Add(" "); | 3170 return HControlInstruction::PrintDataTo(os); |
3237 HControlInstruction::PrintDataTo(stream); | |
3238 } | 3171 } |
3239 | 3172 |
3240 | 3173 |
3241 void HCompareNumericAndBranch::PrintDataTo(StringStream* stream) { | 3174 OStream& HCompareNumericAndBranch::PrintDataTo(OStream& os) const { // NOLINT |
3242 stream->Add(Token::Name(token())); | 3175 os << Token::Name(token()) << " " << NameOf(left()) << " " << NameOf(right()); |
3243 stream->Add(" "); | 3176 return HControlInstruction::PrintDataTo(os); |
3244 left()->PrintNameTo(stream); | |
3245 stream->Add(" "); | |
3246 right()->PrintNameTo(stream); | |
3247 HControlInstruction::PrintDataTo(stream); | |
3248 } | 3177 } |
3249 | 3178 |
3250 | 3179 |
3251 void HCompareObjectEqAndBranch::PrintDataTo(StringStream* stream) { | 3180 OStream& HCompareObjectEqAndBranch::PrintDataTo(OStream& os) const { // NOLINT |
3252 left()->PrintNameTo(stream); | 3181 os << NameOf(left()) << " " << NameOf(right()); |
3253 stream->Add(" "); | 3182 return HControlInstruction::PrintDataTo(os); |
3254 right()->PrintNameTo(stream); | |
3255 HControlInstruction::PrintDataTo(stream); | |
3256 } | 3183 } |
3257 | 3184 |
3258 | 3185 |
3259 bool HCompareObjectEqAndBranch::KnownSuccessorBlock(HBasicBlock** block) { | 3186 bool HCompareObjectEqAndBranch::KnownSuccessorBlock(HBasicBlock** block) { |
3260 if (known_successor_index() != kNoKnownSuccessorIndex) { | 3187 if (known_successor_index() != kNoKnownSuccessorIndex) { |
3261 *block = SuccessorAt(known_successor_index()); | 3188 *block = SuccessorAt(known_successor_index()); |
3262 return true; | 3189 return true; |
3263 } | 3190 } |
3264 if (FLAG_fold_constants && left()->IsConstant() && right()->IsConstant()) { | 3191 if (FLAG_fold_constants && left()->IsConstant() && right()->IsConstant()) { |
3265 *block = HConstant::cast(left())->DataEquals(HConstant::cast(right())) | 3192 *block = HConstant::cast(left())->DataEquals(HConstant::cast(right())) |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3383 return false; | 3310 return false; |
3384 } | 3311 } |
3385 | 3312 |
3386 | 3313 |
3387 void HCompareMinusZeroAndBranch::InferRepresentation( | 3314 void HCompareMinusZeroAndBranch::InferRepresentation( |
3388 HInferRepresentationPhase* h_infer) { | 3315 HInferRepresentationPhase* h_infer) { |
3389 ChangeRepresentation(value()->representation()); | 3316 ChangeRepresentation(value()->representation()); |
3390 } | 3317 } |
3391 | 3318 |
3392 | 3319 |
3393 | 3320 OStream& HGoto::PrintDataTo(OStream& os) const { // NOLINT |
3394 void HGoto::PrintDataTo(StringStream* stream) { | 3321 return os << *SuccessorAt(0); |
3395 stream->Add("B%d", SuccessorAt(0)->block_id()); | |
3396 } | 3322 } |
3397 | 3323 |
3398 | 3324 |
3399 void HCompareNumericAndBranch::InferRepresentation( | 3325 void HCompareNumericAndBranch::InferRepresentation( |
3400 HInferRepresentationPhase* h_infer) { | 3326 HInferRepresentationPhase* h_infer) { |
3401 Representation left_rep = left()->representation(); | 3327 Representation left_rep = left()->representation(); |
3402 Representation right_rep = right()->representation(); | 3328 Representation right_rep = right()->representation(); |
3403 Representation observed_left = observed_input_representation(0); | 3329 Representation observed_left = observed_input_representation(0); |
3404 Representation observed_right = observed_input_representation(1); | 3330 Representation observed_right = observed_input_representation(1); |
3405 | 3331 |
(...skipping 22 matching lines...) Expand all Loading... |
3428 // comparisons must cause a deopt when one of their arguments is undefined. | 3354 // comparisons must cause a deopt when one of their arguments is undefined. |
3429 // See also v8:1434 | 3355 // See also v8:1434 |
3430 if (Token::IsOrderedRelationalCompareOp(token_)) { | 3356 if (Token::IsOrderedRelationalCompareOp(token_)) { |
3431 SetFlag(kAllowUndefinedAsNaN); | 3357 SetFlag(kAllowUndefinedAsNaN); |
3432 } | 3358 } |
3433 } | 3359 } |
3434 ChangeRepresentation(rep); | 3360 ChangeRepresentation(rep); |
3435 } | 3361 } |
3436 | 3362 |
3437 | 3363 |
3438 void HParameter::PrintDataTo(StringStream* stream) { | 3364 OStream& HParameter::PrintDataTo(OStream& os) const { // NOLINT |
3439 stream->Add("%u", index()); | 3365 return os << index(); |
3440 } | 3366 } |
3441 | 3367 |
3442 | 3368 |
3443 void HLoadNamedField::PrintDataTo(StringStream* stream) { | 3369 OStream& HLoadNamedField::PrintDataTo(OStream& os) const { // NOLINT |
3444 object()->PrintNameTo(stream); | 3370 os << NameOf(object()) << access_; |
3445 access_.PrintTo(stream); | |
3446 | 3371 |
3447 if (maps() != NULL) { | 3372 if (maps() != NULL) { |
3448 stream->Add(" [%p", *maps()->at(0).handle()); | 3373 os << " [" << *maps()->at(0).handle(); |
3449 for (int i = 1; i < maps()->size(); ++i) { | 3374 for (int i = 1; i < maps()->size(); ++i) { |
3450 stream->Add(",%p", *maps()->at(i).handle()); | 3375 os << "," << *maps()->at(i).handle(); |
3451 } | 3376 } |
3452 stream->Add("]"); | 3377 os << "]"; |
3453 } | 3378 } |
3454 | 3379 |
3455 if (HasDependency()) { | 3380 if (HasDependency()) os << " " << NameOf(dependency()); |
3456 stream->Add(" "); | 3381 return os; |
3457 dependency()->PrintNameTo(stream); | |
3458 } | |
3459 } | 3382 } |
3460 | 3383 |
3461 | 3384 |
3462 void HLoadNamedGeneric::PrintDataTo(StringStream* stream) { | 3385 OStream& HLoadNamedGeneric::PrintDataTo(OStream& os) const { // NOLINT |
3463 object()->PrintNameTo(stream); | 3386 Handle<String> n = Handle<String>::cast(name()); |
3464 stream->Add("."); | 3387 return os << NameOf(object()) << "." << n->ToCString().get(); |
3465 stream->Add(String::cast(*name())->ToCString().get()); | |
3466 } | 3388 } |
3467 | 3389 |
3468 | 3390 |
3469 void HLoadKeyed::PrintDataTo(StringStream* stream) { | 3391 OStream& HLoadKeyed::PrintDataTo(OStream& os) const { // NOLINT |
3470 if (!is_external()) { | 3392 if (!is_external()) { |
3471 elements()->PrintNameTo(stream); | 3393 os << NameOf(elements()); |
3472 } else { | 3394 } else { |
3473 ASSERT(elements_kind() >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND && | 3395 ASSERT(elements_kind() >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND && |
3474 elements_kind() <= LAST_EXTERNAL_ARRAY_ELEMENTS_KIND); | 3396 elements_kind() <= LAST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
3475 elements()->PrintNameTo(stream); | 3397 os << NameOf(elements()) << "." << ElementsKindToString(elements_kind()); |
3476 stream->Add("."); | |
3477 stream->Add(ElementsKindToString(elements_kind())); | |
3478 } | 3398 } |
3479 | 3399 |
3480 stream->Add("["); | 3400 os << "[" << NameOf(key()); |
3481 key()->PrintNameTo(stream); | 3401 if (IsDehoisted()) os << " + " << base_offset(); |
3482 if (IsDehoisted()) { | 3402 os << "]"; |
3483 stream->Add(" + %d]", base_offset()); | |
3484 } else { | |
3485 stream->Add("]"); | |
3486 } | |
3487 | 3403 |
3488 if (HasDependency()) { | 3404 if (HasDependency()) os << " " << NameOf(dependency()); |
3489 stream->Add(" "); | 3405 if (RequiresHoleCheck()) os << " check_hole"; |
3490 dependency()->PrintNameTo(stream); | 3406 return os; |
3491 } | |
3492 | |
3493 if (RequiresHoleCheck()) { | |
3494 stream->Add(" check_hole"); | |
3495 } | |
3496 } | 3407 } |
3497 | 3408 |
3498 | 3409 |
3499 bool HLoadKeyed::TryIncreaseBaseOffset(uint32_t increase_by_value) { | 3410 bool HLoadKeyed::TryIncreaseBaseOffset(uint32_t increase_by_value) { |
3500 // The base offset is usually simply the size of the array header, except | 3411 // The base offset is usually simply the size of the array header, except |
3501 // with dehoisting adds an addition offset due to a array index key | 3412 // with dehoisting adds an addition offset due to a array index key |
3502 // manipulation, in which case it becomes (array header size + | 3413 // manipulation, in which case it becomes (array header size + |
3503 // constant-offset-from-key * kPointerSize) | 3414 // constant-offset-from-key * kPointerSize) |
3504 uint32_t base_offset = BaseOffsetField::decode(bit_field_); | 3415 uint32_t base_offset = BaseOffsetField::decode(bit_field_); |
3505 v8::base::internal::CheckedNumeric<uint32_t> addition_result = base_offset; | 3416 v8::base::internal::CheckedNumeric<uint32_t> addition_result = base_offset; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3558 } | 3469 } |
3559 | 3470 |
3560 if (IsExternalArrayElementsKind(elements_kind())) { | 3471 if (IsExternalArrayElementsKind(elements_kind())) { |
3561 return false; | 3472 return false; |
3562 } | 3473 } |
3563 | 3474 |
3564 return !UsesMustHandleHole(); | 3475 return !UsesMustHandleHole(); |
3565 } | 3476 } |
3566 | 3477 |
3567 | 3478 |
3568 void HLoadKeyedGeneric::PrintDataTo(StringStream* stream) { | 3479 OStream& HLoadKeyedGeneric::PrintDataTo(OStream& os) const { // NOLINT |
3569 object()->PrintNameTo(stream); | 3480 return os << NameOf(object()) << "[" << NameOf(key()) << "]"; |
3570 stream->Add("["); | |
3571 key()->PrintNameTo(stream); | |
3572 stream->Add("]"); | |
3573 } | 3481 } |
3574 | 3482 |
3575 | 3483 |
3576 HValue* HLoadKeyedGeneric::Canonicalize() { | 3484 HValue* HLoadKeyedGeneric::Canonicalize() { |
3577 // Recognize generic keyed loads that use property name generated | 3485 // Recognize generic keyed loads that use property name generated |
3578 // by for-in statement as a key and rewrite them into fast property load | 3486 // by for-in statement as a key and rewrite them into fast property load |
3579 // by index. | 3487 // by index. |
3580 if (key()->IsLoadKeyed()) { | 3488 if (key()->IsLoadKeyed()) { |
3581 HLoadKeyed* key_load = HLoadKeyed::cast(key()); | 3489 HLoadKeyed* key_load = HLoadKeyed::cast(key()); |
3582 if (key_load->elements()->IsForInCacheArray()) { | 3490 if (key_load->elements()->IsForInCacheArray()) { |
(...skipping 20 matching lines...) Expand all Loading... |
3603 return Prepend(new(block()->zone()) HLoadFieldByIndex( | 3511 return Prepend(new(block()->zone()) HLoadFieldByIndex( |
3604 object(), index)); | 3512 object(), index)); |
3605 } | 3513 } |
3606 } | 3514 } |
3607 } | 3515 } |
3608 | 3516 |
3609 return this; | 3517 return this; |
3610 } | 3518 } |
3611 | 3519 |
3612 | 3520 |
3613 void HStoreNamedGeneric::PrintDataTo(StringStream* stream) { | 3521 OStream& HStoreNamedGeneric::PrintDataTo(OStream& os) const { // NOLINT |
3614 object()->PrintNameTo(stream); | 3522 Handle<String> n = Handle<String>::cast(name()); |
3615 stream->Add("."); | 3523 return os << NameOf(object()) << "." << n->ToCString().get() << " = " |
3616 ASSERT(name()->IsString()); | 3524 << NameOf(value()); |
3617 stream->Add(String::cast(*name())->ToCString().get()); | |
3618 stream->Add(" = "); | |
3619 value()->PrintNameTo(stream); | |
3620 } | 3525 } |
3621 | 3526 |
3622 | 3527 |
3623 void HStoreNamedField::PrintDataTo(StringStream* stream) { | 3528 OStream& HStoreNamedField::PrintDataTo(OStream& os) const { // NOLINT |
3624 object()->PrintNameTo(stream); | 3529 os << NameOf(object()) << access_ << " = " << NameOf(value()); |
3625 access_.PrintTo(stream); | 3530 if (NeedsWriteBarrier()) os << " (write-barrier)"; |
3626 stream->Add(" = "); | 3531 if (has_transition()) os << " (transition map " << *transition_map() << ")"; |
3627 value()->PrintNameTo(stream); | 3532 return os; |
3628 if (NeedsWriteBarrier()) { | |
3629 stream->Add(" (write-barrier)"); | |
3630 } | |
3631 if (has_transition()) { | |
3632 stream->Add(" (transition map %p)", *transition_map()); | |
3633 } | |
3634 } | 3533 } |
3635 | 3534 |
3636 | 3535 |
3637 void HStoreKeyed::PrintDataTo(StringStream* stream) { | 3536 OStream& HStoreKeyed::PrintDataTo(OStream& os) const { // NOLINT |
3638 if (!is_external()) { | 3537 if (!is_external()) { |
3639 elements()->PrintNameTo(stream); | 3538 os << NameOf(elements()); |
3640 } else { | 3539 } else { |
3641 elements()->PrintNameTo(stream); | |
3642 stream->Add("."); | |
3643 stream->Add(ElementsKindToString(elements_kind())); | |
3644 ASSERT(elements_kind() >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND && | 3540 ASSERT(elements_kind() >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND && |
3645 elements_kind() <= LAST_EXTERNAL_ARRAY_ELEMENTS_KIND); | 3541 elements_kind() <= LAST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
| 3542 os << NameOf(elements()) << "." << ElementsKindToString(elements_kind()); |
3646 } | 3543 } |
3647 | 3544 |
3648 stream->Add("["); | 3545 os << "[" << NameOf(key()); |
3649 key()->PrintNameTo(stream); | 3546 if (IsDehoisted()) os << " + " << base_offset(); |
3650 if (IsDehoisted()) { | 3547 return os << "] = " << NameOf(value()); |
3651 stream->Add(" + %d] = ", base_offset()); | |
3652 } else { | |
3653 stream->Add("] = "); | |
3654 } | |
3655 | |
3656 value()->PrintNameTo(stream); | |
3657 } | 3548 } |
3658 | 3549 |
3659 | 3550 |
3660 void HStoreKeyedGeneric::PrintDataTo(StringStream* stream) { | 3551 OStream& HStoreKeyedGeneric::PrintDataTo(OStream& os) const { // NOLINT |
3661 object()->PrintNameTo(stream); | 3552 return os << NameOf(object()) << "[" << NameOf(key()) |
3662 stream->Add("["); | 3553 << "] = " << NameOf(value()); |
3663 key()->PrintNameTo(stream); | |
3664 stream->Add("] = "); | |
3665 value()->PrintNameTo(stream); | |
3666 } | 3554 } |
3667 | 3555 |
3668 | 3556 |
3669 void HTransitionElementsKind::PrintDataTo(StringStream* stream) { | 3557 OStream& HTransitionElementsKind::PrintDataTo(OStream& os) const { // NOLINT |
3670 object()->PrintNameTo(stream); | 3558 os << NameOf(object()); |
3671 ElementsKind from_kind = original_map().handle()->elements_kind(); | 3559 ElementsKind from_kind = original_map().handle()->elements_kind(); |
3672 ElementsKind to_kind = transitioned_map().handle()->elements_kind(); | 3560 ElementsKind to_kind = transitioned_map().handle()->elements_kind(); |
3673 stream->Add(" %p [%s] -> %p [%s]", | 3561 os << " " << *original_map().handle() << " [" |
3674 *original_map().handle(), | 3562 << ElementsAccessor::ForKind(from_kind)->name() << "] -> " |
3675 ElementsAccessor::ForKind(from_kind)->name(), | 3563 << *transitioned_map().handle() << " [" |
3676 *transitioned_map().handle(), | 3564 << ElementsAccessor::ForKind(to_kind)->name() << "]"; |
3677 ElementsAccessor::ForKind(to_kind)->name()); | 3565 if (IsSimpleMapChangeTransition(from_kind, to_kind)) os << " (simple)"; |
3678 if (IsSimpleMapChangeTransition(from_kind, to_kind)) stream->Add(" (simple)"); | 3566 return os; |
3679 } | 3567 } |
3680 | 3568 |
3681 | 3569 |
3682 void HLoadGlobalCell::PrintDataTo(StringStream* stream) { | 3570 OStream& HLoadGlobalCell::PrintDataTo(OStream& os) const { // NOLINT |
3683 stream->Add("[%p]", *cell().handle()); | 3571 os << "[" << *cell().handle() << "]"; |
3684 if (!details_.IsDontDelete()) stream->Add(" (deleteable)"); | 3572 if (!details_.IsDontDelete()) os << " (deleteable)"; |
3685 if (details_.IsReadOnly()) stream->Add(" (read-only)"); | 3573 if (details_.IsReadOnly()) os << " (read-only)"; |
| 3574 return os; |
3686 } | 3575 } |
3687 | 3576 |
3688 | 3577 |
3689 bool HLoadGlobalCell::RequiresHoleCheck() const { | 3578 bool HLoadGlobalCell::RequiresHoleCheck() const { |
3690 if (details_.IsDontDelete() && !details_.IsReadOnly()) return false; | 3579 if (details_.IsDontDelete() && !details_.IsReadOnly()) return false; |
3691 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { | 3580 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { |
3692 HValue* use = it.value(); | 3581 HValue* use = it.value(); |
3693 if (!use->IsChange()) return true; | 3582 if (!use->IsChange()) return true; |
3694 } | 3583 } |
3695 return false; | 3584 return false; |
3696 } | 3585 } |
3697 | 3586 |
3698 | 3587 |
3699 void HLoadGlobalGeneric::PrintDataTo(StringStream* stream) { | 3588 OStream& HLoadGlobalGeneric::PrintDataTo(OStream& os) const { // NOLINT |
3700 stream->Add("%o ", *name()); | 3589 return os << name()->ToCString().get() << " "; |
3701 } | 3590 } |
3702 | 3591 |
3703 | 3592 |
3704 void HInnerAllocatedObject::PrintDataTo(StringStream* stream) { | 3593 OStream& HInnerAllocatedObject::PrintDataTo(OStream& os) const { // NOLINT |
3705 base_object()->PrintNameTo(stream); | 3594 os << NameOf(base_object()) << " offset "; |
3706 stream->Add(" offset "); | 3595 return offset()->PrintTo(os); |
3707 offset()->PrintTo(stream); | |
3708 } | 3596 } |
3709 | 3597 |
3710 | 3598 |
3711 void HStoreGlobalCell::PrintDataTo(StringStream* stream) { | 3599 OStream& HStoreGlobalCell::PrintDataTo(OStream& os) const { // NOLINT |
3712 stream->Add("[%p] = ", *cell().handle()); | 3600 os << "[" << *cell().handle() << "] = " << NameOf(value()); |
3713 value()->PrintNameTo(stream); | 3601 if (!details_.IsDontDelete()) os << " (deleteable)"; |
3714 if (!details_.IsDontDelete()) stream->Add(" (deleteable)"); | 3602 if (details_.IsReadOnly()) os << " (read-only)"; |
3715 if (details_.IsReadOnly()) stream->Add(" (read-only)"); | 3603 return os; |
3716 } | 3604 } |
3717 | 3605 |
3718 | 3606 |
3719 void HLoadContextSlot::PrintDataTo(StringStream* stream) { | 3607 OStream& HLoadContextSlot::PrintDataTo(OStream& os) const { // NOLINT |
3720 value()->PrintNameTo(stream); | 3608 return os << NameOf(value()) << "[" << slot_index() << "]"; |
3721 stream->Add("[%d]", slot_index()); | |
3722 } | 3609 } |
3723 | 3610 |
3724 | 3611 |
3725 void HStoreContextSlot::PrintDataTo(StringStream* stream) { | 3612 OStream& HStoreContextSlot::PrintDataTo(OStream& os) const { // NOLINT |
3726 context()->PrintNameTo(stream); | 3613 return os << NameOf(context()) << "[" << slot_index() |
3727 stream->Add("[%d] = ", slot_index()); | 3614 << "] = " << NameOf(value()); |
3728 value()->PrintNameTo(stream); | |
3729 } | 3615 } |
3730 | 3616 |
3731 | 3617 |
3732 // Implementation of type inference and type conversions. Calculates | 3618 // Implementation of type inference and type conversions. Calculates |
3733 // the inferred type of this instruction based on the input operands. | 3619 // the inferred type of this instruction based on the input operands. |
3734 | 3620 |
3735 HType HValue::CalculateInferredType() { | 3621 HType HValue::CalculateInferredType() { |
3736 return type_; | 3622 return type_; |
3737 } | 3623 } |
3738 | 3624 |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4071 HObjectAccess::ForObservableJSObjectOffset(offset); | 3957 HObjectAccess::ForObservableJSObjectOffset(offset); |
4072 HStoreNamedField* clear_next_map = | 3958 HStoreNamedField* clear_next_map = |
4073 HStoreNamedField::New(zone, context(), this, access, | 3959 HStoreNamedField::New(zone, context(), this, access, |
4074 block()->graph()->GetConstant0()); | 3960 block()->graph()->GetConstant0()); |
4075 clear_next_map->ClearAllSideEffects(); | 3961 clear_next_map->ClearAllSideEffects(); |
4076 clear_next_map->InsertAfter(this); | 3962 clear_next_map->InsertAfter(this); |
4077 } | 3963 } |
4078 } | 3964 } |
4079 | 3965 |
4080 | 3966 |
4081 void HAllocate::PrintDataTo(StringStream* stream) { | 3967 OStream& HAllocate::PrintDataTo(OStream& os) const { // NOLINT |
4082 size()->PrintNameTo(stream); | 3968 os << NameOf(size()) << " ("; |
4083 stream->Add(" ("); | 3969 if (IsNewSpaceAllocation()) os << "N"; |
4084 if (IsNewSpaceAllocation()) stream->Add("N"); | 3970 if (IsOldPointerSpaceAllocation()) os << "P"; |
4085 if (IsOldPointerSpaceAllocation()) stream->Add("P"); | 3971 if (IsOldDataSpaceAllocation()) os << "D"; |
4086 if (IsOldDataSpaceAllocation()) stream->Add("D"); | 3972 if (MustAllocateDoubleAligned()) os << "A"; |
4087 if (MustAllocateDoubleAligned()) stream->Add("A"); | 3973 if (MustPrefillWithFiller()) os << "F"; |
4088 if (MustPrefillWithFiller()) stream->Add("F"); | 3974 return os << ")"; |
4089 stream->Add(")"); | |
4090 } | 3975 } |
4091 | 3976 |
4092 | 3977 |
4093 bool HStoreKeyed::TryIncreaseBaseOffset(uint32_t increase_by_value) { | 3978 bool HStoreKeyed::TryIncreaseBaseOffset(uint32_t increase_by_value) { |
4094 // The base offset is usually simply the size of the array header, except | 3979 // The base offset is usually simply the size of the array header, except |
4095 // with dehoisting adds an addition offset due to a array index key | 3980 // with dehoisting adds an addition offset due to a array index key |
4096 // manipulation, in which case it becomes (array header size + | 3981 // manipulation, in which case it becomes (array header size + |
4097 // constant-offset-from-key * kPointerSize) | 3982 // constant-offset-from-key * kPointerSize) |
4098 v8::base::internal::CheckedNumeric<uint32_t> addition_result = base_offset_; | 3983 v8::base::internal::CheckedNumeric<uint32_t> addition_result = base_offset_; |
4099 addition_result += increase_by_value; | 3984 addition_result += increase_by_value; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4182 ASSERT(!concat.is_null()); | 4067 ASSERT(!concat.is_null()); |
4183 return HConstant::New(zone, context, concat); | 4068 return HConstant::New(zone, context, concat); |
4184 } | 4069 } |
4185 } | 4070 } |
4186 } | 4071 } |
4187 return new(zone) HStringAdd( | 4072 return new(zone) HStringAdd( |
4188 context, left, right, pretenure_flag, flags, allocation_site); | 4073 context, left, right, pretenure_flag, flags, allocation_site); |
4189 } | 4074 } |
4190 | 4075 |
4191 | 4076 |
4192 void HStringAdd::PrintDataTo(StringStream* stream) { | 4077 OStream& HStringAdd::PrintDataTo(OStream& os) const { // NOLINT |
4193 if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_BOTH) { | 4078 if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_BOTH) { |
4194 stream->Add("_CheckBoth"); | 4079 os << "_CheckBoth"; |
4195 } else if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_LEFT) { | 4080 } else if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_LEFT) { |
4196 stream->Add("_CheckLeft"); | 4081 os << "_CheckLeft"; |
4197 } else if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_RIGHT) { | 4082 } else if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_RIGHT) { |
4198 stream->Add("_CheckRight"); | 4083 os << "_CheckRight"; |
4199 } | 4084 } |
4200 HBinaryOperation::PrintDataTo(stream); | 4085 HBinaryOperation::PrintDataTo(os); |
4201 stream->Add(" ("); | 4086 os << " ("; |
4202 if (pretenure_flag() == NOT_TENURED) stream->Add("N"); | 4087 if (pretenure_flag() == NOT_TENURED) |
4203 else if (pretenure_flag() == TENURED) stream->Add("D"); | 4088 os << "N"; |
4204 stream->Add(")"); | 4089 else if (pretenure_flag() == TENURED) |
| 4090 os << "D"; |
| 4091 return os << ")"; |
4205 } | 4092 } |
4206 | 4093 |
4207 | 4094 |
4208 HInstruction* HStringCharFromCode::New( | 4095 HInstruction* HStringCharFromCode::New( |
4209 Zone* zone, HValue* context, HValue* char_code) { | 4096 Zone* zone, HValue* context, HValue* char_code) { |
4210 if (FLAG_fold_constants && char_code->IsConstant()) { | 4097 if (FLAG_fold_constants && char_code->IsConstant()) { |
4211 HConstant* c_code = HConstant::cast(char_code); | 4098 HConstant* c_code = HConstant::cast(char_code); |
4212 Isolate* isolate = zone->isolate(); | 4099 Isolate* isolate = zone->isolate(); |
4213 if (c_code->HasNumberValue()) { | 4100 if (c_code->HasNumberValue()) { |
4214 if (std::isfinite(c_code->DoubleValue())) { | 4101 if (std::isfinite(c_code->DoubleValue())) { |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4513 } | 4400 } |
4514 } | 4401 } |
4515 return new(zone) HSeqStringGetChar(encoding, string, index); | 4402 return new(zone) HSeqStringGetChar(encoding, string, index); |
4516 } | 4403 } |
4517 | 4404 |
4518 | 4405 |
4519 #undef H_CONSTANT_INT | 4406 #undef H_CONSTANT_INT |
4520 #undef H_CONSTANT_DOUBLE | 4407 #undef H_CONSTANT_DOUBLE |
4521 | 4408 |
4522 | 4409 |
4523 void HBitwise::PrintDataTo(StringStream* stream) { | 4410 OStream& HBitwise::PrintDataTo(OStream& os) const { // NOLINT |
4524 stream->Add(Token::Name(op_)); | 4411 os << Token::Name(op_) << " "; |
4525 stream->Add(" "); | 4412 return HBitwiseBinaryOperation::PrintDataTo(os); |
4526 HBitwiseBinaryOperation::PrintDataTo(stream); | |
4527 } | 4413 } |
4528 | 4414 |
4529 | 4415 |
4530 void HPhi::SimplifyConstantInputs() { | 4416 void HPhi::SimplifyConstantInputs() { |
4531 // Convert constant inputs to integers when all uses are truncating. | 4417 // Convert constant inputs to integers when all uses are truncating. |
4532 // This must happen before representation inference takes place. | 4418 // This must happen before representation inference takes place. |
4533 if (!CheckUsesForFlag(kTruncatingToInt32)) return; | 4419 if (!CheckUsesForFlag(kTruncatingToInt32)) return; |
4534 for (int i = 0; i < OperandCount(); ++i) { | 4420 for (int i = 0; i < OperandCount(); ++i) { |
4535 if (!OperandAt(i)->IsConstant()) return; | 4421 if (!OperandAt(i)->IsConstant()) return; |
4536 } | 4422 } |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4845 if (access_type == STORE) { | 4731 if (access_type == STORE) { |
4846 instr->SetChangesFlag(::v8::internal::kExternalMemory); | 4732 instr->SetChangesFlag(::v8::internal::kExternalMemory); |
4847 } else { | 4733 } else { |
4848 instr->SetDependsOnFlag(::v8::internal::kExternalMemory); | 4734 instr->SetDependsOnFlag(::v8::internal::kExternalMemory); |
4849 } | 4735 } |
4850 break; | 4736 break; |
4851 } | 4737 } |
4852 } | 4738 } |
4853 | 4739 |
4854 | 4740 |
4855 void HObjectAccess::PrintTo(StringStream* stream) const { | 4741 OStream& operator<<(OStream& os, const HObjectAccess& access) { |
4856 stream->Add("."); | 4742 os << "."; |
4857 | 4743 |
4858 switch (portion()) { | 4744 switch (access.portion()) { |
4859 case kArrayLengths: | 4745 case HObjectAccess::kArrayLengths: |
4860 case kStringLengths: | 4746 case HObjectAccess::kStringLengths: |
4861 stream->Add("%length"); | 4747 os << "%length"; |
4862 break; | 4748 break; |
4863 case kElementsPointer: | 4749 case HObjectAccess::kElementsPointer: |
4864 stream->Add("%elements"); | 4750 os << "%elements"; |
4865 break; | 4751 break; |
4866 case kMaps: | 4752 case HObjectAccess::kMaps: |
4867 stream->Add("%map"); | 4753 os << "%map"; |
4868 break; | 4754 break; |
4869 case kDouble: // fall through | 4755 case HObjectAccess::kDouble: // fall through |
4870 case kInobject: | 4756 case HObjectAccess::kInobject: |
4871 if (!name_.is_null()) { | 4757 if (!access.name().is_null()) { |
4872 stream->Add(String::cast(*name_)->ToCString().get()); | 4758 os << Handle<String>::cast(access.name())->ToCString().get(); |
4873 } | 4759 } |
4874 stream->Add("[in-object]"); | 4760 os << "[in-object]"; |
4875 break; | 4761 break; |
4876 case kBackingStore: | 4762 case HObjectAccess::kBackingStore: |
4877 if (!name_.is_null()) { | 4763 if (!access.name().is_null()) { |
4878 stream->Add(String::cast(*name_)->ToCString().get()); | 4764 os << Handle<String>::cast(access.name())->ToCString().get(); |
4879 } | 4765 } |
4880 stream->Add("[backing-store]"); | 4766 os << "[backing-store]"; |
4881 break; | 4767 break; |
4882 case kExternalMemory: | 4768 case HObjectAccess::kExternalMemory: |
4883 stream->Add("[external-memory]"); | 4769 os << "[external-memory]"; |
4884 break; | 4770 break; |
4885 } | 4771 } |
4886 | 4772 |
4887 stream->Add("@%d", offset()); | 4773 return os << "@" << access.offset(); |
4888 } | 4774 } |
4889 | 4775 |
4890 } } // namespace v8::internal | 4776 } } // namespace v8::internal |
OLD | NEW |