OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
598 phi->Verify(); | 598 phi->Verify(); |
599 } | 599 } |
600 | 600 |
601 // Check that all join blocks have predecessors that end with an | 601 // Check that all join blocks have predecessors that end with an |
602 // unconditional goto and agree on their environment node id. | 602 // unconditional goto and agree on their environment node id. |
603 if (block->predecessors()->length() >= 2) { | 603 if (block->predecessors()->length() >= 2) { |
604 BailoutId id = | 604 BailoutId id = |
605 block->predecessors()->first()->last_environment()->ast_id(); | 605 block->predecessors()->first()->last_environment()->ast_id(); |
606 for (int k = 0; k < block->predecessors()->length(); k++) { | 606 for (int k = 0; k < block->predecessors()->length(); k++) { |
607 HBasicBlock* predecessor = block->predecessors()->at(k); | 607 HBasicBlock* predecessor = block->predecessors()->at(k); |
608 ASSERT(predecessor->end()->IsGoto()); | 608 ASSERT(predecessor->end()->IsGoto() || |
| 609 predecessor->end()->IsDeoptimize()); |
609 ASSERT(predecessor->last_environment()->ast_id() == id); | 610 ASSERT(predecessor->last_environment()->ast_id() == id); |
610 } | 611 } |
611 } | 612 } |
612 } | 613 } |
613 | 614 |
614 // Check special property of first block to have no predecessors. | 615 // Check special property of first block to have no predecessors. |
615 ASSERT(blocks_.at(0)->predecessors()->is_empty()); | 616 ASSERT(blocks_.at(0)->predecessors()->is_empty()); |
616 | 617 |
617 if (do_full_verify) { | 618 if (do_full_verify) { |
618 // Check that the graph is fully connected. | 619 // Check that the graph is fully connected. |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 if (IsConstantFalse(constant)) return true; | 739 if (IsConstantFalse(constant)) return true; |
739 if (IsConstantHole(constant)) return true; | 740 if (IsConstantHole(constant)) return true; |
740 if (IsConstantNull(constant)) return true; | 741 if (IsConstantNull(constant)) return true; |
741 return false; | 742 return false; |
742 } | 743 } |
743 | 744 |
744 | 745 |
745 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder) | 746 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder) |
746 : builder_(builder), | 747 : builder_(builder), |
747 finished_(false), | 748 finished_(false), |
748 deopt_then_(false), | |
749 deopt_else_(false), | |
750 did_then_(false), | 749 did_then_(false), |
751 did_else_(false), | 750 did_else_(false), |
| 751 did_else_if_(false), |
752 did_and_(false), | 752 did_and_(false), |
753 did_or_(false), | 753 did_or_(false), |
754 captured_(false), | 754 captured_(false), |
755 needs_compare_(true), | 755 needs_compare_(true), |
| 756 pending_merge_block_(false), |
756 split_edge_merge_block_(NULL), | 757 split_edge_merge_block_(NULL), |
757 merge_block_(NULL) { | 758 merge_at_join_blocks_(NULL), |
| 759 normal_merge_at_join_block_count_(0), |
| 760 deopt_merge_at_join_block_count_(0) { |
758 HEnvironment* env = builder->environment(); | 761 HEnvironment* env = builder->environment(); |
759 first_true_block_ = builder->CreateBasicBlock(env->Copy()); | 762 first_true_block_ = builder->CreateBasicBlock(env->Copy()); |
760 last_true_block_ = NULL; | |
761 first_false_block_ = builder->CreateBasicBlock(env->Copy()); | 763 first_false_block_ = builder->CreateBasicBlock(env->Copy()); |
762 } | 764 } |
763 | 765 |
764 | 766 |
765 HGraphBuilder::IfBuilder::IfBuilder( | 767 HGraphBuilder::IfBuilder::IfBuilder( |
766 HGraphBuilder* builder, | 768 HGraphBuilder* builder, |
767 HIfContinuation* continuation) | 769 HIfContinuation* continuation) |
768 : builder_(builder), | 770 : builder_(builder), |
769 finished_(false), | 771 finished_(false), |
770 deopt_then_(false), | |
771 deopt_else_(false), | |
772 did_then_(false), | 772 did_then_(false), |
773 did_else_(false), | 773 did_else_(false), |
| 774 did_else_if_(false), |
774 did_and_(false), | 775 did_and_(false), |
775 did_or_(false), | 776 did_or_(false), |
776 captured_(false), | 777 captured_(false), |
777 needs_compare_(false), | 778 needs_compare_(false), |
| 779 pending_merge_block_(false), |
778 first_true_block_(NULL), | 780 first_true_block_(NULL), |
779 last_true_block_(NULL), | |
780 first_false_block_(NULL), | 781 first_false_block_(NULL), |
781 split_edge_merge_block_(NULL), | 782 split_edge_merge_block_(NULL), |
782 merge_block_(NULL) { | 783 merge_at_join_blocks_(NULL), |
| 784 normal_merge_at_join_block_count_(0), |
| 785 deopt_merge_at_join_block_count_(0) { |
783 continuation->Continue(&first_true_block_, | 786 continuation->Continue(&first_true_block_, |
784 &first_false_block_); | 787 &first_false_block_); |
785 } | 788 } |
786 | 789 |
787 | 790 |
788 HControlInstruction* HGraphBuilder::IfBuilder::AddCompare( | 791 HControlInstruction* HGraphBuilder::IfBuilder::AddCompare( |
789 HControlInstruction* compare) { | 792 HControlInstruction* compare) { |
| 793 ASSERT(did_then_ == did_else_); |
| 794 if (did_else_) { |
| 795 // Handle if-then-elseif |
| 796 did_else_if_ = true; |
| 797 did_else_ = false; |
| 798 did_then_ = false; |
| 799 did_and_ = false; |
| 800 did_or_ = false; |
| 801 pending_merge_block_ = false; |
| 802 split_edge_merge_block_ = NULL; |
| 803 HEnvironment* env = builder_->environment(); |
| 804 first_true_block_ = builder_->CreateBasicBlock(env->Copy()); |
| 805 first_false_block_ = builder_->CreateBasicBlock(env->Copy()); |
| 806 } |
790 if (split_edge_merge_block_ != NULL) { | 807 if (split_edge_merge_block_ != NULL) { |
791 HEnvironment* env = first_false_block_->last_environment(); | 808 HEnvironment* env = first_false_block_->last_environment(); |
792 HBasicBlock* split_edge = | 809 HBasicBlock* split_edge = |
793 builder_->CreateBasicBlock(env->Copy()); | 810 builder_->CreateBasicBlock(env->Copy()); |
794 if (did_or_) { | 811 if (did_or_) { |
795 compare->SetSuccessorAt(0, split_edge); | 812 compare->SetSuccessorAt(0, split_edge); |
796 compare->SetSuccessorAt(1, first_false_block_); | 813 compare->SetSuccessorAt(1, first_false_block_); |
797 } else { | 814 } else { |
798 compare->SetSuccessorAt(0, first_true_block_); | 815 compare->SetSuccessorAt(0, first_true_block_); |
799 compare->SetSuccessorAt(1, split_edge); | 816 compare->SetSuccessorAt(1, split_edge); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
835 builder_->GotoNoSimulate(first_false_block_, split_edge_merge_block_); | 852 builder_->GotoNoSimulate(first_false_block_, split_edge_merge_block_); |
836 first_false_block_ = split_edge_merge_block_; | 853 first_false_block_ = split_edge_merge_block_; |
837 } | 854 } |
838 builder_->set_current_block(first_true_block_); | 855 builder_->set_current_block(first_true_block_); |
839 first_true_block_ = builder_->CreateBasicBlock(env->Copy()); | 856 first_true_block_ = builder_->CreateBasicBlock(env->Copy()); |
840 } | 857 } |
841 | 858 |
842 | 859 |
843 void HGraphBuilder::IfBuilder::CaptureContinuation( | 860 void HGraphBuilder::IfBuilder::CaptureContinuation( |
844 HIfContinuation* continuation) { | 861 HIfContinuation* continuation) { |
| 862 ASSERT(!did_else_if_); |
845 ASSERT(!finished_); | 863 ASSERT(!finished_); |
846 ASSERT(!captured_); | 864 ASSERT(!captured_); |
847 HBasicBlock* true_block = last_true_block_ == NULL | 865 |
848 ? first_true_block_ | 866 HBasicBlock* true_block = NULL; |
849 : last_true_block_; | 867 HBasicBlock* false_block = NULL; |
850 HBasicBlock* false_block = did_else_ && (first_false_block_ != NULL) | 868 Finish(&true_block, &false_block); |
851 ? builder_->current_block() | 869 ASSERT(true_block != NULL); |
852 : first_false_block_; | 870 ASSERT(false_block != NULL); |
853 continuation->Capture(true_block, false_block); | 871 continuation->Capture(true_block, false_block); |
854 captured_ = true; | 872 captured_ = true; |
| 873 builder_->set_current_block(NULL); |
855 End(); | 874 End(); |
856 } | 875 } |
857 | 876 |
858 | 877 |
859 void HGraphBuilder::IfBuilder::JoinContinuation(HIfContinuation* continuation) { | 878 void HGraphBuilder::IfBuilder::JoinContinuation(HIfContinuation* continuation) { |
| 879 ASSERT(!did_else_if_); |
860 ASSERT(!finished_); | 880 ASSERT(!finished_); |
861 ASSERT(!captured_); | 881 ASSERT(!captured_); |
862 ASSERT(did_then_); | 882 HBasicBlock* true_block = NULL; |
863 if (!did_else_) Else(); | 883 HBasicBlock* false_block = NULL; |
864 HBasicBlock* true_block = last_true_block_ == NULL | 884 Finish(&true_block, &false_block); |
865 ? first_true_block_ | 885 merge_at_join_blocks_ = NULL; |
866 : last_true_block_; | |
867 HBasicBlock* false_block = builder_->current_block(); | |
868 if (true_block != NULL && !true_block->IsFinished()) { | 886 if (true_block != NULL && !true_block->IsFinished()) { |
869 ASSERT(continuation->IsTrueReachable()); | 887 ASSERT(continuation->IsTrueReachable()); |
870 builder_->GotoNoSimulate(true_block, continuation->true_branch()); | 888 builder_->GotoNoSimulate(true_block, continuation->true_branch()); |
871 } | 889 } |
872 if (false_block != NULL && !false_block->IsFinished()) { | 890 if (false_block != NULL && !false_block->IsFinished()) { |
873 ASSERT(continuation->IsFalseReachable()); | 891 ASSERT(continuation->IsFalseReachable()); |
874 builder_->GotoNoSimulate(false_block, continuation->false_branch()); | 892 builder_->GotoNoSimulate(false_block, continuation->false_branch()); |
875 } | 893 } |
876 captured_ = true; | 894 captured_ = true; |
877 End(); | 895 End(); |
(...skipping 10 matching lines...) Expand all Loading... |
888 // so that the graph builder visits it and sees any live range extending | 906 // so that the graph builder visits it and sees any live range extending |
889 // constructs within it. | 907 // constructs within it. |
890 HConstant* constant_false = builder_->graph()->GetConstantFalse(); | 908 HConstant* constant_false = builder_->graph()->GetConstantFalse(); |
891 ToBooleanStub::Types boolean_type = ToBooleanStub::Types(); | 909 ToBooleanStub::Types boolean_type = ToBooleanStub::Types(); |
892 boolean_type.Add(ToBooleanStub::BOOLEAN); | 910 boolean_type.Add(ToBooleanStub::BOOLEAN); |
893 HBranch* branch = builder()->New<HBranch>( | 911 HBranch* branch = builder()->New<HBranch>( |
894 constant_false, boolean_type, first_true_block_, first_false_block_); | 912 constant_false, boolean_type, first_true_block_, first_false_block_); |
895 builder_->FinishCurrentBlock(branch); | 913 builder_->FinishCurrentBlock(branch); |
896 } | 914 } |
897 builder_->set_current_block(first_true_block_); | 915 builder_->set_current_block(first_true_block_); |
| 916 pending_merge_block_ = true; |
898 } | 917 } |
899 | 918 |
900 | 919 |
901 void HGraphBuilder::IfBuilder::Else() { | 920 void HGraphBuilder::IfBuilder::Else() { |
902 ASSERT(did_then_); | 921 ASSERT(did_then_); |
903 ASSERT(!captured_); | 922 ASSERT(!captured_); |
904 ASSERT(!finished_); | 923 ASSERT(!finished_); |
905 last_true_block_ = builder_->current_block(); | 924 AddMergeAtJoinBlock(false); |
906 builder_->set_current_block(first_false_block_); | 925 builder_->set_current_block(first_false_block_); |
| 926 pending_merge_block_ = true; |
907 did_else_ = true; | 927 did_else_ = true; |
908 } | 928 } |
909 | 929 |
910 | 930 |
911 void HGraphBuilder::IfBuilder::Deopt(const char* reason) { | 931 void HGraphBuilder::IfBuilder::Deopt(const char* reason) { |
912 ASSERT(did_then_); | 932 ASSERT(did_then_); |
913 if (did_else_) { | |
914 deopt_else_ = true; | |
915 } else { | |
916 deopt_then_ = true; | |
917 } | |
918 builder_->Add<HDeoptimize>(reason, Deoptimizer::EAGER); | 933 builder_->Add<HDeoptimize>(reason, Deoptimizer::EAGER); |
| 934 AddMergeAtJoinBlock(true); |
919 } | 935 } |
920 | 936 |
921 | 937 |
922 void HGraphBuilder::IfBuilder::Return(HValue* value) { | 938 void HGraphBuilder::IfBuilder::Return(HValue* value) { |
923 HValue* parameter_count = builder_->graph()->GetConstantMinus1(); | 939 HValue* parameter_count = builder_->graph()->GetConstantMinus1(); |
924 builder_->FinishExitCurrentBlock( | 940 builder_->FinishExitCurrentBlock( |
925 builder_->New<HReturn>(value, parameter_count)); | 941 builder_->New<HReturn>(value, parameter_count)); |
926 if (did_else_) { | 942 AddMergeAtJoinBlock(false); |
927 first_false_block_ = NULL; | |
928 } else { | |
929 first_true_block_ = NULL; | |
930 } | |
931 } | 943 } |
932 | 944 |
933 | 945 |
934 void HGraphBuilder::IfBuilder::End() { | 946 void HGraphBuilder::IfBuilder::AddMergeAtJoinBlock(bool deopt) { |
935 if (!captured_) { | 947 if (!pending_merge_block_) return; |
936 ASSERT(did_then_); | 948 HBasicBlock* block = builder_->current_block(); |
937 if (!did_else_) { | 949 ASSERT(block == NULL || !block->IsFinished()); |
938 last_true_block_ = builder_->current_block(); | 950 MergeAtJoinBlock* record = |
| 951 new(builder_->zone()) MergeAtJoinBlock(block, deopt, |
| 952 merge_at_join_blocks_); |
| 953 merge_at_join_blocks_ = record; |
| 954 if (block != NULL) { |
| 955 ASSERT(block->end() == NULL); |
| 956 if (deopt) { |
| 957 normal_merge_at_join_block_count_++; |
| 958 } else { |
| 959 deopt_merge_at_join_block_count_++; |
939 } | 960 } |
940 if (last_true_block_ == NULL || last_true_block_->IsFinished()) { | 961 } |
941 ASSERT(did_else_); | 962 builder_->set_current_block(NULL); |
942 // Return on true. Nothing to do, just continue the false block. | 963 pending_merge_block_ = false; |
943 } else if (first_false_block_ == NULL || | 964 } |
944 (did_else_ && builder_->current_block()->IsFinished())) { | 965 |
945 // Deopt on false. Nothing to do except switching to the true block. | 966 |
946 builder_->set_current_block(last_true_block_); | 967 void HGraphBuilder::IfBuilder::Finish() { |
947 } else { | 968 ASSERT(!finished_); |
948 merge_block_ = builder_->graph()->CreateBasicBlock(); | 969 if (!did_then_) { |
949 ASSERT(!finished_); | 970 Then(); |
950 if (!did_else_) Else(); | 971 } |
951 ASSERT(!last_true_block_->IsFinished()); | 972 AddMergeAtJoinBlock(false); |
952 HBasicBlock* last_false_block = builder_->current_block(); | 973 if (!did_else_) { |
953 ASSERT(!last_false_block->IsFinished()); | 974 Else(); |
954 if (deopt_then_) { | 975 AddMergeAtJoinBlock(false); |
955 builder_->GotoNoSimulate(last_false_block, merge_block_); | |
956 builder_->PadEnvironmentForContinuation(last_true_block_, | |
957 merge_block_); | |
958 builder_->GotoNoSimulate(last_true_block_, merge_block_); | |
959 } else { | |
960 builder_->GotoNoSimulate(last_true_block_, merge_block_); | |
961 if (deopt_else_) { | |
962 builder_->PadEnvironmentForContinuation(last_false_block, | |
963 merge_block_); | |
964 } | |
965 builder_->GotoNoSimulate(last_false_block, merge_block_); | |
966 } | |
967 builder_->set_current_block(merge_block_); | |
968 } | |
969 } | 976 } |
970 finished_ = true; | 977 finished_ = true; |
971 } | 978 } |
972 | 979 |
973 | 980 |
| 981 void HGraphBuilder::IfBuilder::Finish(HBasicBlock** then_continuation, |
| 982 HBasicBlock** else_continuation) { |
| 983 Finish(); |
| 984 |
| 985 MergeAtJoinBlock* else_record = merge_at_join_blocks_; |
| 986 if (else_continuation != NULL) { |
| 987 *else_continuation = else_record->block_; |
| 988 } |
| 989 MergeAtJoinBlock* then_record = else_record->next_; |
| 990 if (then_continuation != NULL) { |
| 991 *then_continuation = then_record->block_; |
| 992 } |
| 993 ASSERT(then_record->next_ == NULL); |
| 994 } |
| 995 |
| 996 |
| 997 void HGraphBuilder::IfBuilder::End() { |
| 998 if (captured_) return; |
| 999 Finish(); |
| 1000 |
| 1001 int total_merged_blocks = normal_merge_at_join_block_count_ + |
| 1002 deopt_merge_at_join_block_count_; |
| 1003 ASSERT(total_merged_blocks >= 1); |
| 1004 HBasicBlock* merge_block = total_merged_blocks == 1 |
| 1005 ? NULL : builder_->graph()->CreateBasicBlock(); |
| 1006 |
| 1007 // Merge non-deopt blocks first to ensure environment has right size for |
| 1008 // padding. |
| 1009 MergeAtJoinBlock* current = merge_at_join_blocks_; |
| 1010 while (current != NULL) { |
| 1011 if (!current->deopt_ && current->block_ != NULL) { |
| 1012 // If there is only one block that makes it through to the end of the |
| 1013 // if, then just set it as the current block and continue rather then |
| 1014 // creating an unnecessary merge block. |
| 1015 if (total_merged_blocks == 1) { |
| 1016 builder_->set_current_block(current->block_); |
| 1017 return; |
| 1018 } |
| 1019 builder_->GotoNoSimulate(current->block_, merge_block); |
| 1020 } |
| 1021 current = current->next_; |
| 1022 } |
| 1023 |
| 1024 // Merge deopt blocks, padding when necessary. |
| 1025 current = merge_at_join_blocks_; |
| 1026 while (current != NULL) { |
| 1027 if (current->deopt_ && current->block_ != NULL) { |
| 1028 builder_->PadEnvironmentForContinuation(current->block_, |
| 1029 merge_block); |
| 1030 builder_->GotoNoSimulate(current->block_, merge_block); |
| 1031 } |
| 1032 current = current->next_; |
| 1033 } |
| 1034 builder_->set_current_block(merge_block); |
| 1035 } |
| 1036 |
| 1037 |
974 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, | 1038 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, |
975 HValue* context, | 1039 HValue* context, |
976 LoopBuilder::Direction direction) | 1040 LoopBuilder::Direction direction) |
977 : builder_(builder), | 1041 : builder_(builder), |
978 context_(context), | 1042 context_(context), |
979 direction_(direction), | 1043 direction_(direction), |
980 finished_(false) { | 1044 finished_(false) { |
981 header_block_ = builder->CreateLoopHeaderBlock(); | 1045 header_block_ = builder->CreateLoopHeaderBlock(); |
982 body_block_ = NULL; | 1046 body_block_ = NULL; |
983 exit_block_ = NULL; | 1047 exit_block_ = NULL; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1044 | 1108 |
1045 void HGraphBuilder::LoopBuilder::Break() { | 1109 void HGraphBuilder::LoopBuilder::Break() { |
1046 if (exit_trampoline_block_ == NULL) { | 1110 if (exit_trampoline_block_ == NULL) { |
1047 // Its the first time we saw a break. | 1111 // Its the first time we saw a break. |
1048 HEnvironment* env = exit_block_->last_environment()->Copy(); | 1112 HEnvironment* env = exit_block_->last_environment()->Copy(); |
1049 exit_trampoline_block_ = builder_->CreateBasicBlock(env); | 1113 exit_trampoline_block_ = builder_->CreateBasicBlock(env); |
1050 builder_->GotoNoSimulate(exit_block_, exit_trampoline_block_); | 1114 builder_->GotoNoSimulate(exit_block_, exit_trampoline_block_); |
1051 } | 1115 } |
1052 | 1116 |
1053 builder_->GotoNoSimulate(exit_trampoline_block_); | 1117 builder_->GotoNoSimulate(exit_trampoline_block_); |
| 1118 builder_->set_current_block(NULL); |
1054 } | 1119 } |
1055 | 1120 |
1056 | 1121 |
1057 void HGraphBuilder::LoopBuilder::EndBody() { | 1122 void HGraphBuilder::LoopBuilder::EndBody() { |
1058 ASSERT(!finished_); | 1123 ASSERT(!finished_); |
1059 | 1124 |
1060 if (direction_ == kPostIncrement || direction_ == kPostDecrement) { | 1125 if (direction_ == kPostIncrement || direction_ == kPostDecrement) { |
1061 if (direction_ == kPostIncrement) { | 1126 if (direction_ == kPostIncrement) { |
1062 increment_ = HAdd::New(zone(), context_, phi_, increment_amount_); | 1127 increment_ = HAdd::New(zone(), context_, phi_, increment_amount_); |
1063 } else { | 1128 } else { |
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1852 IfBuilder length_checker(this); | 1917 IfBuilder length_checker(this); |
1853 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); | 1918 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); |
1854 length_checker.Then(); | 1919 length_checker.Then(); |
1855 IfBuilder negative_checker(this); | 1920 IfBuilder negative_checker(this); |
1856 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( | 1921 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( |
1857 key, graph()->GetConstant0(), Token::GTE); | 1922 key, graph()->GetConstant0(), Token::GTE); |
1858 negative_checker.Then(); | 1923 negative_checker.Then(); |
1859 HInstruction* result = AddElementAccess( | 1924 HInstruction* result = AddElementAccess( |
1860 external_elements, key, val, bounds_check, elements_kind, is_store); | 1925 external_elements, key, val, bounds_check, elements_kind, is_store); |
1861 negative_checker.ElseDeopt("Negative key encountered"); | 1926 negative_checker.ElseDeopt("Negative key encountered"); |
| 1927 negative_checker.End(); |
1862 length_checker.End(); | 1928 length_checker.End(); |
1863 return result; | 1929 return result; |
1864 } else { | 1930 } else { |
1865 ASSERT(store_mode == STANDARD_STORE); | 1931 ASSERT(store_mode == STANDARD_STORE); |
1866 checked_key = Add<HBoundsCheck>(key, length); | 1932 checked_key = Add<HBoundsCheck>(key, length); |
1867 HLoadExternalArrayPointer* external_elements = | 1933 HLoadExternalArrayPointer* external_elements = |
1868 Add<HLoadExternalArrayPointer>(elements); | 1934 Add<HLoadExternalArrayPointer>(elements); |
1869 return AddElementAccess( | 1935 return AddElementAccess( |
1870 external_elements, checked_key, val, | 1936 external_elements, checked_key, val, |
1871 checked_object, elements_kind, is_store); | 1937 checked_object, elements_kind, is_store); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1933 if_builder.Then(); | 1999 if_builder.Then(); |
1934 const int initial_capacity = JSArray::kPreallocatedArrayElements; | 2000 const int initial_capacity = JSArray::kPreallocatedArrayElements; |
1935 HConstant* initial_capacity_node = Add<HConstant>(initial_capacity); | 2001 HConstant* initial_capacity_node = Add<HConstant>(initial_capacity); |
1936 Push(initial_capacity_node); // capacity | 2002 Push(initial_capacity_node); // capacity |
1937 Push(constant_zero); // length | 2003 Push(constant_zero); // length |
1938 if_builder.Else(); | 2004 if_builder.Else(); |
1939 if (!(top_info()->IsStub()) && | 2005 if (!(top_info()->IsStub()) && |
1940 IsFastPackedElementsKind(array_builder->kind())) { | 2006 IsFastPackedElementsKind(array_builder->kind())) { |
1941 // We'll come back later with better (holey) feedback. | 2007 // We'll come back later with better (holey) feedback. |
1942 if_builder.Deopt("Holey array despite packed elements_kind feedback"); | 2008 if_builder.Deopt("Holey array despite packed elements_kind feedback"); |
| 2009 } else { |
| 2010 Push(checked_length); // capacity |
| 2011 Push(checked_length); // length |
1943 } | 2012 } |
1944 Push(checked_length); // capacity | |
1945 Push(checked_length); // length | |
1946 if_builder.End(); | 2013 if_builder.End(); |
1947 | 2014 |
1948 // Figure out total size | 2015 // Figure out total size |
1949 HValue* length = Pop(); | 2016 HValue* length = Pop(); |
1950 HValue* capacity = Pop(); | 2017 HValue* capacity = Pop(); |
1951 return array_builder->AllocateArray(capacity, length); | 2018 return array_builder->AllocateArray(capacity, length); |
1952 } | 2019 } |
1953 | 2020 |
1954 HValue* HGraphBuilder::BuildAllocateElements(ElementsKind kind, | 2021 HValue* HGraphBuilder::BuildAllocateElements(ElementsKind kind, |
1955 HValue* capacity) { | 2022 HValue* capacity) { |
(...skipping 8376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10332 if (ShouldProduceTraceOutput()) { | 10399 if (ShouldProduceTraceOutput()) { |
10333 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10400 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
10334 } | 10401 } |
10335 | 10402 |
10336 #ifdef DEBUG | 10403 #ifdef DEBUG |
10337 graph_->Verify(false); // No full verify. | 10404 graph_->Verify(false); // No full verify. |
10338 #endif | 10405 #endif |
10339 } | 10406 } |
10340 | 10407 |
10341 } } // namespace v8::internal | 10408 } } // namespace v8::internal |
OLD | NEW |