| 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 |