| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 void HBasicBlock::Finish(HControlInstruction* end) { | 176 void HBasicBlock::Finish(HControlInstruction* end) { |
| 177 ASSERT(!IsFinished()); | 177 ASSERT(!IsFinished()); |
| 178 AddInstruction(end); | 178 AddInstruction(end); |
| 179 end_ = end; | 179 end_ = end; |
| 180 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { | 180 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { |
| 181 it.Current()->RegisterPredecessor(this); | 181 it.Current()->RegisterPredecessor(this); |
| 182 } | 182 } |
| 183 } | 183 } |
| 184 | 184 |
| 185 | 185 |
| 186 void HBasicBlock::Goto(HBasicBlock* block, FunctionState* state) { | 186 void HBasicBlock::Goto(HBasicBlock* block, |
| 187 FunctionState* state, |
| 188 bool add_simulate) { |
| 187 bool drop_extra = state != NULL && | 189 bool drop_extra = state != NULL && |
| 188 state->inlining_kind() == DROP_EXTRA_ON_RETURN; | 190 state->inlining_kind() == DROP_EXTRA_ON_RETURN; |
| 189 | 191 |
| 190 if (block->IsInlineReturnTarget()) { | 192 if (block->IsInlineReturnTarget()) { |
| 191 AddInstruction(new(zone()) HLeaveInlined()); | 193 AddInstruction(new(zone()) HLeaveInlined()); |
| 192 last_environment_ = last_environment()->DiscardInlined(drop_extra); | 194 last_environment_ = last_environment()->DiscardInlined(drop_extra); |
| 193 } | 195 } |
| 194 | 196 |
| 195 AddSimulate(BailoutId::None()); | 197 if (add_simulate) AddSimulate(BailoutId::None()); |
| 196 HGoto* instr = new(zone()) HGoto(block); | 198 HGoto* instr = new(zone()) HGoto(block); |
| 197 Finish(instr); | 199 Finish(instr); |
| 198 } | 200 } |
| 199 | 201 |
| 200 | 202 |
| 201 void HBasicBlock::AddLeaveInlined(HValue* return_value, | 203 void HBasicBlock::AddLeaveInlined(HValue* return_value, |
| 202 FunctionState* state) { | 204 FunctionState* state) { |
| 203 HBasicBlock* target = state->function_return(); | 205 HBasicBlock* target = state->function_return(); |
| 204 bool drop_extra = state->inlining_kind() == DROP_EXTRA_ON_RETURN; | 206 bool drop_extra = state->inlining_kind() == DROP_EXTRA_ON_RETURN; |
| 205 | 207 |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 } | 635 } |
| 634 | 636 |
| 635 | 637 |
| 636 DEFINE_GET_CONSTANT(True, true, HType::Boolean(), true) | 638 DEFINE_GET_CONSTANT(True, true, HType::Boolean(), true) |
| 637 DEFINE_GET_CONSTANT(False, false, HType::Boolean(), false) | 639 DEFINE_GET_CONSTANT(False, false, HType::Boolean(), false) |
| 638 DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false) | 640 DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false) |
| 639 | 641 |
| 640 #undef DEFINE_GET_CONSTANT | 642 #undef DEFINE_GET_CONSTANT |
| 641 | 643 |
| 642 | 644 |
| 643 HGraphBuilder::CheckBuilder::CheckBuilder(HGraphBuilder* builder, BailoutId id) | 645 HGraphBuilder::CheckBuilder::CheckBuilder(HGraphBuilder* builder) |
| 644 : builder_(builder), | 646 : builder_(builder), |
| 645 finished_(false), | 647 finished_(false) { |
| 646 id_(id) { | |
| 647 HEnvironment* env = builder->environment(); | 648 HEnvironment* env = builder->environment(); |
| 648 failure_block_ = builder->CreateBasicBlock(env->CopyWithoutHistory()); | 649 failure_block_ = builder->CreateBasicBlock(env->Copy()); |
| 649 merge_block_ = builder->CreateBasicBlock(env->CopyWithoutHistory()); | 650 merge_block_ = builder->CreateBasicBlock(env->Copy()); |
| 650 } | 651 } |
| 651 | 652 |
| 652 | 653 |
| 653 HValue* HGraphBuilder::CheckBuilder::CheckNotUndefined(HValue* value) { | 654 HValue* HGraphBuilder::CheckBuilder::CheckNotUndefined(HValue* value) { |
| 654 HEnvironment* env = builder_->environment(); | 655 HEnvironment* env = builder_->environment(); |
| 655 HIsNilAndBranch* compare = | 656 HCompareObjectEqAndBranch* compare = |
| 656 new(zone()) HIsNilAndBranch(value, kStrictEquality, kUndefinedValue); | 657 new(zone()) HCompareObjectEqAndBranch( |
| 657 HBasicBlock* success_block = | 658 value, |
| 658 builder_->CreateBasicBlock(env->CopyWithoutHistory()); | 659 builder_->graph()->GetConstantUndefined()); |
| 659 HBasicBlock* failure_block = | 660 HBasicBlock* success_block = builder_->CreateBasicBlock(env->Copy()); |
| 660 builder_->CreateBasicBlock(env->CopyWithoutHistory()); | 661 HBasicBlock* failure_block = builder_->CreateBasicBlock(env->Copy()); |
| 661 compare->SetSuccessorAt(0, failure_block); | 662 compare->SetSuccessorAt(0, failure_block); |
| 662 compare->SetSuccessorAt(1, success_block); | 663 compare->SetSuccessorAt(1, success_block); |
| 663 failure_block->Goto(failure_block_); | 664 failure_block->GotoNoSimulate(failure_block_); |
| 664 builder_->current_block()->Finish(compare); | 665 builder_->current_block()->Finish(compare); |
| 665 builder_->set_current_block(success_block); | 666 builder_->set_current_block(success_block); |
| 666 return compare; | 667 return compare; |
| 667 } | 668 } |
| 668 | 669 |
| 669 | 670 |
| 670 HValue* HGraphBuilder::CheckBuilder::CheckIntegerCompare(HValue* left, | 671 HValue* HGraphBuilder::CheckBuilder::CheckIntegerCompare(HValue* left, |
| 671 HValue* right, | 672 HValue* right, |
| 672 Token::Value op) { | 673 Token::Value op) { |
| 673 HEnvironment* env = builder_->environment(); | 674 HEnvironment* env = builder_->environment(); |
| 674 HCompareIDAndBranch* compare = | 675 HCompareIDAndBranch* compare = |
| 675 new(zone()) HCompareIDAndBranch(left, right, op); | 676 new(zone()) HCompareIDAndBranch(left, right, op); |
| 676 compare->AssumeRepresentation(Representation::Integer32()); | 677 compare->AssumeRepresentation(Representation::Integer32()); |
| 677 HBasicBlock* success_block = | 678 HBasicBlock* success_block = builder_->CreateBasicBlock(env->Copy()); |
| 678 builder_->CreateBasicBlock(env->CopyWithoutHistory()); | 679 HBasicBlock* failure_block = builder_->CreateBasicBlock(env->Copy()); |
| 679 HBasicBlock* failure_block = | |
| 680 builder_->CreateBasicBlock(env->CopyWithoutHistory()); | |
| 681 compare->SetSuccessorAt(0, success_block); | 680 compare->SetSuccessorAt(0, success_block); |
| 682 compare->SetSuccessorAt(1, failure_block); | 681 compare->SetSuccessorAt(1, failure_block); |
| 683 failure_block->Goto(failure_block_); | 682 failure_block->GotoNoSimulate(failure_block_); |
| 684 builder_->current_block()->Finish(compare); | 683 builder_->current_block()->Finish(compare); |
| 685 builder_->set_current_block(success_block); | 684 builder_->set_current_block(success_block); |
| 686 return compare; | 685 return compare; |
| 687 } | 686 } |
| 688 | 687 |
| 689 | 688 |
| 690 HValue* HGraphBuilder::CheckBuilder::CheckIntegerEq(HValue* left, | 689 HValue* HGraphBuilder::CheckBuilder::CheckIntegerEq(HValue* left, |
| 691 HValue* right) { | 690 HValue* right) { |
| 692 return CheckIntegerCompare(left, right, Token::EQ); | 691 return CheckIntegerCompare(left, right, Token::EQ); |
| 693 } | 692 } |
| 694 | 693 |
| 695 | 694 |
| 696 void HGraphBuilder::CheckBuilder::End() { | 695 void HGraphBuilder::CheckBuilder::End() { |
| 697 ASSERT(!finished_); | 696 ASSERT(!finished_); |
| 698 builder_->current_block()->Goto(merge_block_); | 697 builder_->current_block()->GotoNoSimulate(merge_block_); |
| 699 failure_block_->FinishExitWithDeoptimization(HDeoptimize::kUseAll); | 698 if (failure_block_->HasPredecessor()) { |
| 700 failure_block_->SetJoinId(id_); | 699 failure_block_->FinishExitWithDeoptimization(HDeoptimize::kUseAll); |
| 700 } |
| 701 builder_->set_current_block(merge_block_); | 701 builder_->set_current_block(merge_block_); |
| 702 merge_block_->SetJoinId(id_); | |
| 703 finished_ = true; | 702 finished_ = true; |
| 704 } | 703 } |
| 705 | 704 |
| 706 | 705 |
| 707 HConstant* HGraph::GetInvalidContext() { | 706 HConstant* HGraph::GetInvalidContext() { |
| 708 return GetConstantInt32(&constant_invalid_context_, 0xFFFFC0C7); | 707 return GetConstantInt32(&constant_invalid_context_, 0xFFFFC0C7); |
| 709 } | 708 } |
| 710 | 709 |
| 711 | 710 |
| 712 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, BailoutId id) | 711 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, int position) |
| 713 : builder_(builder), | 712 : builder_(builder), |
| 713 position_(position), |
| 714 finished_(false), | 714 finished_(false), |
| 715 did_then_(false), |
| 715 did_else_(false), | 716 did_else_(false), |
| 716 id_(id) { | 717 deopt_then_(false), |
| 718 deopt_else_(false), |
| 719 did_and_(false), |
| 720 did_or_(false), |
| 721 captured_(false), |
| 722 needs_compare_(true), |
| 723 split_edge_merge_block_(NULL) { |
| 717 HEnvironment* env = builder->environment(); | 724 HEnvironment* env = builder->environment(); |
| 718 first_true_block_ = builder->CreateBasicBlock(env->Copy()); | 725 first_true_block_ = builder->CreateBasicBlock(env->Copy()); |
| 719 last_true_block_ = NULL; | 726 last_true_block_ = NULL; |
| 720 first_false_block_ = builder->CreateBasicBlock(env->Copy()); | 727 first_false_block_ = builder->CreateBasicBlock(env->Copy()); |
| 721 } | 728 } |
| 722 | 729 |
| 723 | 730 |
| 724 HInstruction* HGraphBuilder::IfBuilder::BeginIf( | 731 HGraphBuilder::IfBuilder::IfBuilder( |
| 732 HGraphBuilder* builder, |
| 733 HIfContinuation* continuation) |
| 734 : builder_(builder), |
| 735 position_(RelocInfo::kNoPosition), |
| 736 finished_(false), |
| 737 did_then_(false), |
| 738 did_else_(false), |
| 739 deopt_then_(false), |
| 740 deopt_else_(false), |
| 741 did_and_(false), |
| 742 did_or_(false), |
| 743 captured_(false), |
| 744 needs_compare_(false), |
| 745 first_true_block_(NULL), |
| 746 first_false_block_(NULL), |
| 747 split_edge_merge_block_(NULL), |
| 748 merge_block_(NULL) { |
| 749 continuation->Continue(&first_true_block_, |
| 750 &first_false_block_, |
| 751 &position_); |
| 752 } |
| 753 |
| 754 |
| 755 HInstruction* HGraphBuilder::IfBuilder::IfCompare( |
| 725 HValue* left, | 756 HValue* left, |
| 726 HValue* right, | 757 HValue* right, |
| 727 Token::Value token, | 758 Token::Value token, |
| 728 Representation input_representation) { | 759 Representation input_representation) { |
| 729 HCompareIDAndBranch* compare = | 760 HCompareIDAndBranch* compare = |
| 730 new(zone()) HCompareIDAndBranch(left, right, token); | 761 new(zone()) HCompareIDAndBranch(left, right, token); |
| 731 compare->set_observed_input_representation(input_representation, | 762 compare->set_observed_input_representation(input_representation, |
| 732 input_representation); | 763 input_representation); |
| 733 compare->ChangeRepresentation(input_representation); | 764 compare->ChangeRepresentation(input_representation); |
| 734 compare->SetSuccessorAt(0, first_true_block_); | 765 AddCompare(compare); |
| 735 compare->SetSuccessorAt(1, first_false_block_); | |
| 736 builder_->current_block()->Finish(compare); | |
| 737 builder_->set_current_block(first_true_block_); | |
| 738 return compare; | 766 return compare; |
| 739 } | 767 } |
| 740 | 768 |
| 741 | 769 |
| 742 HInstruction* HGraphBuilder::IfBuilder::BeginIfObjectsEqual( | 770 HInstruction* HGraphBuilder::IfBuilder::IfCompareMap(HValue* left, |
| 743 HValue* left, | 771 Handle<Map> map) { |
| 744 HValue* right) { | 772 HCompareMap* compare = |
| 745 HCompareObjectEqAndBranch* compare = | 773 new(zone()) HCompareMap(left, map, |
| 746 new(zone()) HCompareObjectEqAndBranch(left, right); | 774 first_true_block_, first_false_block_); |
| 747 compare->SetSuccessorAt(0, first_true_block_); | 775 AddCompare(compare); |
| 748 compare->SetSuccessorAt(1, first_false_block_); | |
| 749 builder_->current_block()->Finish(compare); | |
| 750 builder_->set_current_block(first_true_block_); | |
| 751 return compare; | 776 return compare; |
| 752 } | 777 } |
| 753 | 778 |
| 754 | 779 |
| 755 HInstruction* HGraphBuilder::IfBuilder::BeginIfMapEquals(HValue* value, | 780 void HGraphBuilder::IfBuilder::AddCompare(HControlInstruction* compare) { |
| 756 Handle<Map> map) { | 781 if (split_edge_merge_block_ != NULL) { |
| 757 HCompareMap* compare = new(zone()) | 782 HEnvironment* env = first_false_block_->last_environment(); |
| 758 HCompareMap(value, map, first_true_block_, first_false_block_); | 783 HBasicBlock* split_edge = |
| 784 builder_->CreateBasicBlock(env->Copy()); |
| 785 if (did_or_) { |
| 786 compare->SetSuccessorAt(0, split_edge); |
| 787 compare->SetSuccessorAt(1, first_false_block_); |
| 788 } else { |
| 789 compare->SetSuccessorAt(0, first_true_block_); |
| 790 compare->SetSuccessorAt(1, split_edge); |
| 791 } |
| 792 split_edge->GotoNoSimulate(split_edge_merge_block_); |
| 793 } else { |
| 794 compare->SetSuccessorAt(0, first_true_block_); |
| 795 compare->SetSuccessorAt(1, first_false_block_); |
| 796 } |
| 759 builder_->current_block()->Finish(compare); | 797 builder_->current_block()->Finish(compare); |
| 760 builder_->set_current_block(first_true_block_); | 798 needs_compare_ = false; |
| 761 return compare; | |
| 762 } | 799 } |
| 763 | 800 |
| 764 | 801 |
| 765 void HGraphBuilder::IfBuilder::BeginElse() { | 802 void HGraphBuilder::IfBuilder::Or() { |
| 803 ASSERT(!did_and_); |
| 804 did_or_ = true; |
| 805 HEnvironment* env = first_false_block_->last_environment(); |
| 806 if (split_edge_merge_block_ == NULL) { |
| 807 split_edge_merge_block_ = |
| 808 builder_->CreateBasicBlock(env->Copy()); |
| 809 first_true_block_->GotoNoSimulate(split_edge_merge_block_); |
| 810 first_true_block_ = split_edge_merge_block_; |
| 811 } |
| 812 builder_->set_current_block(first_false_block_); |
| 813 first_false_block_ = builder_->CreateBasicBlock(env->Copy()); |
| 814 } |
| 815 |
| 816 |
| 817 void HGraphBuilder::IfBuilder::And() { |
| 818 ASSERT(!did_or_); |
| 819 did_and_ = true; |
| 820 HEnvironment* env = first_false_block_->last_environment(); |
| 821 if (split_edge_merge_block_ == NULL) { |
| 822 split_edge_merge_block_ = builder_->CreateBasicBlock(env->Copy()); |
| 823 first_false_block_->GotoNoSimulate(split_edge_merge_block_); |
| 824 first_false_block_ = split_edge_merge_block_; |
| 825 } |
| 826 builder_->set_current_block(first_true_block_); |
| 827 first_true_block_ = builder_->CreateBasicBlock(env->Copy()); |
| 828 } |
| 829 |
| 830 |
| 831 void HGraphBuilder::IfBuilder::CaptureContinuation( |
| 832 HIfContinuation* continuation) { |
| 833 ASSERT(!finished_); |
| 834 ASSERT(!captured_); |
| 835 HBasicBlock* true_block = last_true_block_ == NULL |
| 836 ? first_true_block_ |
| 837 : last_true_block_; |
| 838 HBasicBlock* false_block = |
| 839 did_else_ ? builder_->current_block() : first_false_block_; |
| 840 continuation->Capture(true_block, false_block, position_); |
| 841 captured_ = true; |
| 842 End(); |
| 843 } |
| 844 |
| 845 |
| 846 void HGraphBuilder::IfBuilder::Then() { |
| 847 ASSERT(!captured_); |
| 848 ASSERT(!finished_); |
| 849 did_then_ = true; |
| 850 if (needs_compare_) { |
| 851 // Handle if's without any expressions, they jump directly to the "else" |
| 852 // branch. |
| 853 builder_->current_block()->GotoNoSimulate(first_false_block_); |
| 854 first_true_block_ = NULL; |
| 855 } |
| 856 builder_->set_current_block(first_true_block_); |
| 857 } |
| 858 |
| 859 |
| 860 void HGraphBuilder::IfBuilder::Else() { |
| 861 ASSERT(did_then_); |
| 862 ASSERT(!captured_); |
| 863 ASSERT(!finished_); |
| 766 last_true_block_ = builder_->current_block(); | 864 last_true_block_ = builder_->current_block(); |
| 767 ASSERT(!last_true_block_->IsFinished()); | 865 ASSERT(first_true_block_ == NULL || !last_true_block_->IsFinished()); |
| 768 builder_->set_current_block(first_false_block_); | 866 builder_->set_current_block(first_false_block_); |
| 769 did_else_ = true; | 867 did_else_ = true; |
| 770 } | 868 } |
| 771 | 869 |
| 772 | 870 |
| 871 void HGraphBuilder::IfBuilder::Deopt() { |
| 872 ASSERT(!(did_then_ ^ did_else_)); |
| 873 HBasicBlock* block = builder_->current_block(); |
| 874 block->FinishExitWithDeoptimization(HDeoptimize::kUseAll); |
| 875 if (did_else_) { |
| 876 first_false_block_ = NULL; |
| 877 did_else_ = false; |
| 878 } else { |
| 879 first_true_block_ = NULL; |
| 880 } |
| 881 } |
| 882 |
| 883 |
| 773 void HGraphBuilder::IfBuilder::End() { | 884 void HGraphBuilder::IfBuilder::End() { |
| 774 ASSERT(!finished_); | 885 if (!captured_) { |
| 775 if (!did_else_) BeginElse(); | 886 ASSERT(did_then_); |
| 776 ASSERT(!last_true_block_->IsFinished()); | 887 if (!did_else_) { |
| 777 HBasicBlock* last_false_block = builder_->current_block(); | 888 last_true_block_ = builder_->current_block(); |
| 778 ASSERT(!last_false_block->IsFinished()); | 889 } |
| 779 HEnvironment* merge_env = | 890 if (first_true_block_ == NULL) { |
| 780 last_true_block_->last_environment()->CopyWithoutHistory(); | 891 // Deopt on true. Nothing to do, just continue the else block. |
| 781 merge_block_ = builder_->CreateBasicBlock(merge_env); | 892 } else if (first_false_block_ == NULL) { |
| 782 last_true_block_->Goto(merge_block_); | 893 builder_->set_current_block(last_true_block_); |
| 783 last_false_block->Goto(merge_block_); | 894 } else { |
| 784 merge_block_->SetJoinId(id_); | 895 HEnvironment* merge_env = last_true_block_->last_environment()->Copy(); |
| 785 builder_->set_current_block(merge_block_); | 896 merge_block_ = builder_->CreateBasicBlock(merge_env); |
| 897 ASSERT(!finished_); |
| 898 if (!did_else_) Else(); |
| 899 ASSERT(!last_true_block_->IsFinished()); |
| 900 HBasicBlock* last_false_block = builder_->current_block(); |
| 901 ASSERT(!last_false_block->IsFinished()); |
| 902 last_true_block_->GotoNoSimulate(merge_block_); |
| 903 last_false_block->GotoNoSimulate(merge_block_); |
| 904 builder_->set_current_block(merge_block_); |
| 905 } |
| 906 } |
| 786 finished_ = true; | 907 finished_ = true; |
| 787 } | 908 } |
| 788 | 909 |
| 789 | 910 |
| 790 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, | 911 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, |
| 791 HValue* context, | 912 HValue* context, |
| 792 LoopBuilder::Direction direction, | 913 LoopBuilder::Direction direction) |
| 793 BailoutId id) | |
| 794 : builder_(builder), | 914 : builder_(builder), |
| 795 context_(context), | 915 context_(context), |
| 796 direction_(direction), | 916 direction_(direction), |
| 797 id_(id), | |
| 798 finished_(false) { | 917 finished_(false) { |
| 799 header_block_ = builder->CreateLoopHeaderBlock(); | 918 header_block_ = builder->CreateLoopHeaderBlock(); |
| 800 body_block_ = NULL; | 919 body_block_ = NULL; |
| 801 exit_block_ = NULL; | 920 exit_block_ = NULL; |
| 802 } | 921 } |
| 803 | 922 |
| 804 | 923 |
| 805 HValue* HGraphBuilder::LoopBuilder::BeginBody( | 924 HValue* HGraphBuilder::LoopBuilder::BeginBody( |
| 806 HValue* initial, | 925 HValue* initial, |
| 807 HValue* terminating, | 926 HValue* terminating, |
| 808 Token::Value token, | 927 Token::Value token, |
| 809 Representation input_representation) { | 928 Representation input_representation) { |
| 810 HEnvironment* env = builder_->environment(); | 929 HEnvironment* env = builder_->environment(); |
| 811 phi_ = new(zone()) HPhi(env->values()->length(), zone()); | 930 phi_ = new(zone()) HPhi(env->values()->length(), zone()); |
| 812 header_block_->AddPhi(phi_); | 931 header_block_->AddPhi(phi_); |
| 813 phi_->AddInput(initial); | 932 phi_->AddInput(initial); |
| 814 phi_->ChangeRepresentation(Representation::Integer32()); | 933 phi_->ChangeRepresentation(Representation::Integer32()); |
| 815 env->Push(initial); | 934 env->Push(initial); |
| 816 builder_->current_block()->Goto(header_block_); | 935 builder_->current_block()->GotoNoSimulate(header_block_); |
| 817 | 936 |
| 818 HEnvironment* body_env = env->Copy(); | 937 HEnvironment* body_env = env->Copy(); |
| 819 HEnvironment* exit_env = env->Copy(); | 938 HEnvironment* exit_env = env->Copy(); |
| 820 body_block_ = builder_->CreateBasicBlock(body_env); | 939 body_block_ = builder_->CreateBasicBlock(body_env); |
| 821 exit_block_ = builder_->CreateBasicBlock(exit_env); | 940 exit_block_ = builder_->CreateBasicBlock(exit_env); |
| 822 // Remove the phi from the expression stack | 941 // Remove the phi from the expression stack |
| 823 body_env->Pop(); | 942 body_env->Pop(); |
| 824 | 943 |
| 825 builder_->set_current_block(header_block_); | 944 builder_->set_current_block(header_block_); |
| 826 HCompareIDAndBranch* compare = | 945 HCompareIDAndBranch* compare = |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 860 } else { | 979 } else { |
| 861 increment_ = HSub::New(zone(), context_, phi_, one); | 980 increment_ = HSub::New(zone(), context_, phi_, one); |
| 862 } | 981 } |
| 863 increment_->ClearFlag(HValue::kCanOverflow); | 982 increment_->ClearFlag(HValue::kCanOverflow); |
| 864 increment_->ChangeRepresentation(Representation::Integer32()); | 983 increment_->ChangeRepresentation(Representation::Integer32()); |
| 865 builder_->AddInstruction(increment_); | 984 builder_->AddInstruction(increment_); |
| 866 } | 985 } |
| 867 | 986 |
| 868 // Push the new increment value on the expression stack to merge into the phi. | 987 // Push the new increment value on the expression stack to merge into the phi. |
| 869 builder_->environment()->Push(increment_); | 988 builder_->environment()->Push(increment_); |
| 870 builder_->current_block()->Goto(header_block_); | 989 builder_->current_block()->GotoNoSimulate(header_block_); |
| 871 header_block_->loop_information()->RegisterBackEdge(body_block_); | 990 header_block_->loop_information()->RegisterBackEdge(body_block_); |
| 872 header_block_->SetJoinId(id_); | |
| 873 | 991 |
| 874 builder_->set_current_block(exit_block_); | 992 builder_->set_current_block(exit_block_); |
| 875 // Pop the phi from the expression stack | 993 // Pop the phi from the expression stack |
| 876 builder_->environment()->Pop(); | 994 builder_->environment()->Pop(); |
| 877 finished_ = true; | 995 finished_ = true; |
| 878 } | 996 } |
| 879 | 997 |
| 880 | 998 |
| 881 HGraph* HGraphBuilder::CreateGraph() { | 999 HGraph* HGraphBuilder::CreateGraph() { |
| 882 graph_ = new(zone()) HGraph(info_); | 1000 graph_ = new(zone()) HGraph(info_); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 897 } | 1015 } |
| 898 return instr; | 1016 return instr; |
| 899 } | 1017 } |
| 900 | 1018 |
| 901 | 1019 |
| 902 void HGraphBuilder::AddSimulate(BailoutId id, | 1020 void HGraphBuilder::AddSimulate(BailoutId id, |
| 903 RemovableSimulate removable) { | 1021 RemovableSimulate removable) { |
| 904 ASSERT(current_block() != NULL); | 1022 ASSERT(current_block() != NULL); |
| 905 ASSERT(no_side_effects_scope_count_ == 0); | 1023 ASSERT(no_side_effects_scope_count_ == 0); |
| 906 current_block()->AddSimulate(id, removable); | 1024 current_block()->AddSimulate(id, removable); |
| 907 environment()->set_ast_id(id); | |
| 908 } | 1025 } |
| 909 | 1026 |
| 910 | 1027 |
| 911 HBoundsCheck* HGraphBuilder::AddBoundsCheck(HValue* index, | 1028 HBoundsCheck* HGraphBuilder::AddBoundsCheck(HValue* index, |
| 912 HValue* length, | 1029 HValue* length, |
| 913 BoundsCheckKeyMode key_mode, | 1030 BoundsCheckKeyMode key_mode, |
| 914 Representation r) { | 1031 Representation r) { |
| 915 if (!index->type().IsSmi()) { | 1032 if (!index->type().IsSmi()) { |
| 916 index = new(graph()->zone()) HCheckSmiOrInt32(index); | 1033 index = new(graph()->zone()) HCheckSmiOrInt32(index); |
| 917 AddInstruction(HCheckSmiOrInt32::cast(index)); | 1034 AddInstruction(HCheckSmiOrInt32::cast(index)); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 948 | 1065 |
| 949 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { | 1066 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { |
| 950 HBasicBlock* header = graph()->CreateBasicBlock(); | 1067 HBasicBlock* header = graph()->CreateBasicBlock(); |
| 951 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); | 1068 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); |
| 952 header->SetInitialEnvironment(entry_env); | 1069 header->SetInitialEnvironment(entry_env); |
| 953 header->AttachLoopInformation(); | 1070 header->AttachLoopInformation(); |
| 954 return header; | 1071 return header; |
| 955 } | 1072 } |
| 956 | 1073 |
| 957 | 1074 |
| 1075 HValue* HGraphBuilder::BuildCheckNonSmi(HValue* obj) { |
| 1076 HCheckNonSmi* check = new(zone()) HCheckNonSmi(obj); |
| 1077 AddInstruction(check); |
| 1078 return check; |
| 1079 } |
| 1080 |
| 1081 |
| 1082 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, |
| 1083 Handle<Map> map) { |
| 1084 HCheckMaps* check = new(zone()) HCheckMaps(obj, map, zone()); |
| 1085 AddInstruction(check); |
| 1086 return check; |
| 1087 } |
| 1088 |
| 1089 |
| 958 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( | 1090 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( |
| 959 HValue* external_elements, | 1091 HValue* external_elements, |
| 960 HValue* checked_key, | 1092 HValue* checked_key, |
| 961 HValue* val, | 1093 HValue* val, |
| 962 HValue* dependency, | 1094 HValue* dependency, |
| 963 ElementsKind elements_kind, | 1095 ElementsKind elements_kind, |
| 964 bool is_store) { | 1096 bool is_store) { |
| 965 Zone* zone = this->zone(); | 1097 Zone* zone = this->zone(); |
| 966 if (is_store) { | 1098 if (is_store) { |
| 967 ASSERT(val != NULL); | 1099 ASSERT(val != NULL); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1042 elements_kind); | 1174 elements_kind); |
| 1043 } | 1175 } |
| 1044 | 1176 |
| 1045 | 1177 |
| 1046 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, | 1178 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, |
| 1047 HValue* elements, | 1179 HValue* elements, |
| 1048 ElementsKind kind, | 1180 ElementsKind kind, |
| 1049 HValue* length, | 1181 HValue* length, |
| 1050 HValue* key, | 1182 HValue* key, |
| 1051 bool is_js_array) { | 1183 bool is_js_array) { |
| 1052 BailoutId ast_id = environment()->ast_id(); | |
| 1053 Zone* zone = this->zone(); | 1184 Zone* zone = this->zone(); |
| 1054 IfBuilder length_checker(this, ast_id); | 1185 IfBuilder length_checker(this); |
| 1055 | 1186 |
| 1056 length_checker.BeginIf(length, key, Token::EQ); | 1187 length_checker.IfCompare(length, key, Token::EQ); |
| 1188 length_checker.Then(); |
| 1057 | 1189 |
| 1058 HValue* current_capacity = | 1190 HValue* current_capacity = |
| 1059 AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | 1191 AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
| 1060 | 1192 |
| 1061 IfBuilder capacity_checker(this, ast_id); | 1193 IfBuilder capacity_checker(this); |
| 1062 | 1194 |
| 1063 capacity_checker.BeginIf(length, current_capacity, Token::EQ); | 1195 capacity_checker.IfCompare(length, current_capacity, Token::EQ); |
| 1196 capacity_checker.Then(); |
| 1064 | 1197 |
| 1065 HValue* context = environment()->LookupContext(); | 1198 HValue* context = environment()->LookupContext(); |
| 1066 | 1199 |
| 1067 HValue* new_capacity = | 1200 HValue* new_capacity = |
| 1068 BuildNewElementsCapacity(context, current_capacity); | 1201 BuildNewElementsCapacity(context, current_capacity); |
| 1069 | 1202 |
| 1070 HValue* new_elements = BuildGrowElementsCapacity(object, elements, | 1203 HValue* new_elements = BuildGrowElementsCapacity(object, elements, |
| 1071 kind, length, | 1204 kind, length, |
| 1072 new_capacity, ast_id); | 1205 new_capacity); |
| 1073 | 1206 |
| 1074 environment()->Push(new_elements); | 1207 environment()->Push(new_elements); |
| 1075 capacity_checker.BeginElse(); | 1208 capacity_checker.Else(); |
| 1076 | 1209 |
| 1077 environment()->Push(elements); | 1210 environment()->Push(elements); |
| 1078 capacity_checker.End(); | 1211 capacity_checker.End(); |
| 1079 | 1212 |
| 1080 if (is_js_array) { | 1213 if (is_js_array) { |
| 1081 HValue* new_length = AddInstruction( | 1214 HValue* new_length = AddInstruction( |
| 1082 HAdd::New(zone, context, length, graph_->GetConstant1())); | 1215 HAdd::New(zone, context, length, graph_->GetConstant1())); |
| 1083 new_length->ChangeRepresentation(Representation::Integer32()); | 1216 new_length->ChangeRepresentation(Representation::Integer32()); |
| 1084 new_length->ClearFlag(HValue::kCanOverflow); | 1217 new_length->ClearFlag(HValue::kCanOverflow); |
| 1085 | 1218 |
| 1086 Factory* factory = isolate()->factory(); | 1219 Factory* factory = isolate()->factory(); |
| 1087 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField( | 1220 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField( |
| 1088 object, | 1221 object, |
| 1089 factory->length_field_string(), | 1222 factory->length_field_string(), |
| 1090 new_length, true, | 1223 new_length, true, |
| 1091 JSArray::kLengthOffset)); | 1224 JSArray::kLengthOffset)); |
| 1092 length_store->SetGVNFlag(kChangesArrayLengths); | 1225 length_store->SetGVNFlag(kChangesArrayLengths); |
| 1093 } | 1226 } |
| 1094 | 1227 |
| 1095 length_checker.BeginElse(); | 1228 length_checker.Else(); |
| 1096 | 1229 |
| 1097 AddBoundsCheck(key, length, ALLOW_SMI_KEY); | 1230 AddBoundsCheck(key, length, ALLOW_SMI_KEY); |
| 1098 environment()->Push(elements); | 1231 environment()->Push(elements); |
| 1099 | 1232 |
| 1100 length_checker.End(); | 1233 length_checker.End(); |
| 1101 | 1234 |
| 1102 return environment()->Pop(); | 1235 return environment()->Pop(); |
| 1103 } | 1236 } |
| 1104 | 1237 |
| 1105 | 1238 |
| 1106 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, | 1239 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, |
| 1107 HValue* elements, | 1240 HValue* elements, |
| 1108 ElementsKind kind, | 1241 ElementsKind kind, |
| 1109 HValue* length) { | 1242 HValue* length) { |
| 1110 BailoutId ast_id = environment()->ast_id(); | |
| 1111 Zone* zone = this->zone(); | 1243 Zone* zone = this->zone(); |
| 1112 Heap* heap = isolate()->heap(); | 1244 Heap* heap = isolate()->heap(); |
| 1113 | 1245 |
| 1114 IfBuilder cow_checker(this, ast_id); | 1246 IfBuilder cow_checker(this); |
| 1115 | 1247 |
| 1116 cow_checker.BeginIfMapEquals(elements, | 1248 cow_checker.IfCompareMap(elements, |
| 1117 Handle<Map>(heap->fixed_cow_array_map())); | 1249 Handle<Map>(heap->fixed_cow_array_map())); |
| 1250 cow_checker.Then(); |
| 1118 | 1251 |
| 1119 HValue* capacity = | 1252 HValue* capacity = |
| 1120 AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | 1253 AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
| 1121 | 1254 |
| 1122 HValue* new_elements = BuildGrowElementsCapacity(object, elements, | 1255 HValue* new_elements = BuildGrowElementsCapacity(object, elements, |
| 1123 kind, length, | 1256 kind, length, capacity); |
| 1124 capacity, ast_id); | |
| 1125 | 1257 |
| 1126 environment()->Push(new_elements); | 1258 environment()->Push(new_elements); |
| 1127 | 1259 |
| 1128 cow_checker.BeginElse(); | 1260 cow_checker.Else(); |
| 1129 | 1261 |
| 1130 environment()->Push(elements); | 1262 environment()->Push(elements); |
| 1131 | 1263 |
| 1132 cow_checker.End(); | 1264 cow_checker.End(); |
| 1133 | 1265 |
| 1134 return environment()->Pop(); | 1266 return environment()->Pop(); |
| 1135 } | 1267 } |
| 1136 | 1268 |
| 1137 | 1269 |
| 1138 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( | 1270 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1173 HInstruction* length = NULL; | 1305 HInstruction* length = NULL; |
| 1174 if (is_js_array) { | 1306 if (is_js_array) { |
| 1175 length = AddInstruction( | 1307 length = AddInstruction( |
| 1176 HLoadNamedField::NewArrayLength(zone, object, mapcheck, HType::Smi())); | 1308 HLoadNamedField::NewArrayLength(zone, object, mapcheck, HType::Smi())); |
| 1177 } else { | 1309 } else { |
| 1178 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | 1310 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
| 1179 } | 1311 } |
| 1180 HValue* checked_key = NULL; | 1312 HValue* checked_key = NULL; |
| 1181 if (IsExternalArrayElementsKind(elements_kind)) { | 1313 if (IsExternalArrayElementsKind(elements_kind)) { |
| 1182 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { | 1314 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { |
| 1315 NoObservableSideEffectsScope no_effects(this); |
| 1183 HLoadExternalArrayPointer* external_elements = | 1316 HLoadExternalArrayPointer* external_elements = |
| 1184 new(zone) HLoadExternalArrayPointer(elements); | 1317 new(zone) HLoadExternalArrayPointer(elements); |
| 1185 AddInstruction(external_elements); | 1318 AddInstruction(external_elements); |
| 1186 BailoutId previous_id = environment()->ast_id(); | 1319 IfBuilder length_checker(this); |
| 1187 ASSERT(!previous_id.IsNone()); | 1320 length_checker.IfCompare(key, length, Token::LT); |
| 1188 IfBuilder length_checker(this, previous_id); | 1321 length_checker.Then(); |
| 1189 length_checker.BeginIf(key, length, Token::LT); | 1322 CheckBuilder negative_checker(this); |
| 1190 CheckBuilder negative_checker(this, previous_id); | |
| 1191 HValue* bounds_check = negative_checker.CheckIntegerCompare( | 1323 HValue* bounds_check = negative_checker.CheckIntegerCompare( |
| 1192 key, graph()->GetConstant0(), Token::GTE); | 1324 key, graph()->GetConstant0(), Token::GTE); |
| 1193 negative_checker.End(); | 1325 negative_checker.End(); |
| 1194 HInstruction* result = BuildExternalArrayElementAccess( | 1326 HInstruction* result = BuildExternalArrayElementAccess( |
| 1195 external_elements, key, val, bounds_check, | 1327 external_elements, key, val, bounds_check, |
| 1196 elements_kind, is_store); | 1328 elements_kind, is_store); |
| 1197 AddInstruction(result); | 1329 AddInstruction(result); |
| 1198 length_checker.End(); | 1330 length_checker.End(); |
| 1199 return result; | 1331 return result; |
| 1200 } else { | 1332 } else { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1243 } | 1375 } |
| 1244 } | 1376 } |
| 1245 return AddInstruction( | 1377 return AddInstruction( |
| 1246 BuildFastElementAccess(elements, checked_key, val, mapcheck, | 1378 BuildFastElementAccess(elements, checked_key, val, mapcheck, |
| 1247 elements_kind, is_store, store_mode)); | 1379 elements_kind, is_store, store_mode)); |
| 1248 } | 1380 } |
| 1249 | 1381 |
| 1250 | 1382 |
| 1251 HValue* HGraphBuilder::BuildAllocateElements(HValue* context, | 1383 HValue* HGraphBuilder::BuildAllocateElements(HValue* context, |
| 1252 ElementsKind kind, | 1384 ElementsKind kind, |
| 1253 HValue* capacity, | 1385 HValue* capacity) { |
| 1254 BailoutId ast_id) { | |
| 1255 Zone* zone = this->zone(); | 1386 Zone* zone = this->zone(); |
| 1256 | 1387 |
| 1257 int elements_size = IsFastDoubleElementsKind(kind) | 1388 int elements_size = IsFastDoubleElementsKind(kind) |
| 1258 ? kDoubleSize : kPointerSize; | 1389 ? kDoubleSize : kPointerSize; |
| 1259 HConstant* elements_size_value = | 1390 HConstant* elements_size_value = |
| 1260 new(zone) HConstant(elements_size, Representation::Integer32()); | 1391 new(zone) HConstant(elements_size, Representation::Integer32()); |
| 1261 AddInstruction(elements_size_value); | 1392 AddInstruction(elements_size_value); |
| 1262 HValue* mul = AddInstruction( | 1393 HValue* mul = AddInstruction( |
| 1263 HMul::New(zone, context, capacity, elements_size_value)); | 1394 HMul::New(zone, context, capacity, elements_size_value)); |
| 1264 mul->ChangeRepresentation(Representation::Integer32()); | 1395 mul->ChangeRepresentation(Representation::Integer32()); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1308 HInstruction* store_length = | 1439 HInstruction* store_length = |
| 1309 new(zone) HStoreNamedField(elements, fixed_array_length_field_name, | 1440 new(zone) HStoreNamedField(elements, fixed_array_length_field_name, |
| 1310 capacity, true, FixedArray::kLengthOffset); | 1441 capacity, true, FixedArray::kLengthOffset); |
| 1311 AddInstruction(store_length); | 1442 AddInstruction(store_length); |
| 1312 } | 1443 } |
| 1313 | 1444 |
| 1314 | 1445 |
| 1315 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, | 1446 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, |
| 1316 ElementsKind kind, | 1447 ElementsKind kind, |
| 1317 HValue* capacity) { | 1448 HValue* capacity) { |
| 1318 BailoutId ast_id = environment()->ast_id(); | 1449 HValue* new_elements = BuildAllocateElements(context, kind, capacity); |
| 1319 HValue* new_elements = | |
| 1320 BuildAllocateElements(context, kind, capacity, ast_id); | |
| 1321 BuildInitializeElements(new_elements, kind, capacity); | 1450 BuildInitializeElements(new_elements, kind, capacity); |
| 1322 return new_elements; | 1451 return new_elements; |
| 1323 } | 1452 } |
| 1324 | 1453 |
| 1325 | 1454 |
| 1326 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, | 1455 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, |
| 1327 HValue* map) { | 1456 HValue* map) { |
| 1328 Zone* zone = this->zone(); | 1457 Zone* zone = this->zone(); |
| 1329 Factory* factory = isolate()->factory(); | 1458 Factory* factory = isolate()->factory(); |
| 1330 Handle<String> map_field_name = factory->map_field_string(); | 1459 Handle<String> map_field_name = factory->map_field_string(); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1387 AddInstruction(new(zone) | 1516 AddInstruction(new(zone) |
| 1388 HBoundsCheck(length, max_size_constant, | 1517 HBoundsCheck(length, max_size_constant, |
| 1389 DONT_ALLOW_SMI_KEY, Representation::Integer32())); | 1518 DONT_ALLOW_SMI_KEY, Representation::Integer32())); |
| 1390 } | 1519 } |
| 1391 | 1520 |
| 1392 | 1521 |
| 1393 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, | 1522 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, |
| 1394 HValue* elements, | 1523 HValue* elements, |
| 1395 ElementsKind kind, | 1524 ElementsKind kind, |
| 1396 HValue* length, | 1525 HValue* length, |
| 1397 HValue* new_capacity, | 1526 HValue* new_capacity) { |
| 1398 BailoutId ast_id) { | |
| 1399 Zone* zone = this->zone(); | 1527 Zone* zone = this->zone(); |
| 1400 HValue* context = environment()->LookupContext(); | 1528 HValue* context = environment()->LookupContext(); |
| 1401 | 1529 |
| 1402 BuildNewSpaceArrayCheck(new_capacity, kind); | 1530 BuildNewSpaceArrayCheck(new_capacity, kind); |
| 1403 | 1531 |
| 1404 HValue* new_elements = | 1532 HValue* new_elements = |
| 1405 BuildAllocateAndInitializeElements(context, kind, new_capacity); | 1533 BuildAllocateAndInitializeElements(context, kind, new_capacity); |
| 1406 | 1534 |
| 1407 BuildCopyElements(context, elements, kind, | 1535 BuildCopyElements(context, elements, kind, |
| 1408 new_elements, kind, | 1536 new_elements, kind, |
| 1409 length, new_capacity, ast_id); | 1537 length, new_capacity); |
| 1410 | 1538 |
| 1411 Factory* factory = isolate()->factory(); | 1539 Factory* factory = isolate()->factory(); |
| 1412 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField( | 1540 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField( |
| 1413 object, | 1541 object, |
| 1414 factory->elements_field_string(), | 1542 factory->elements_field_string(), |
| 1415 new_elements, true, | 1543 new_elements, true, |
| 1416 JSArray::kElementsOffset)); | 1544 JSArray::kElementsOffset)); |
| 1417 elements_store->SetGVNFlag(kChangesElementsPointer); | 1545 elements_store->SetGVNFlag(kChangesElementsPointer); |
| 1418 | 1546 |
| 1419 return new_elements; | 1547 return new_elements; |
| 1420 } | 1548 } |
| 1421 | 1549 |
| 1422 | 1550 |
| 1423 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, | 1551 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, |
| 1424 HValue* elements, | 1552 HValue* elements, |
| 1425 ElementsKind elements_kind, | 1553 ElementsKind elements_kind, |
| 1426 HValue* from, | 1554 HValue* from, |
| 1427 HValue* to, | 1555 HValue* to) { |
| 1428 BailoutId ast_id) { | |
| 1429 // Fast elements kinds need to be initialized in case statements below cause | 1556 // Fast elements kinds need to be initialized in case statements below cause |
| 1430 // a garbage collection. | 1557 // a garbage collection. |
| 1431 Factory* factory = isolate()->factory(); | 1558 Factory* factory = isolate()->factory(); |
| 1432 | 1559 |
| 1433 double nan_double = FixedDoubleArray::hole_nan_as_double(); | 1560 double nan_double = FixedDoubleArray::hole_nan_as_double(); |
| 1434 Zone* zone = this->zone(); | 1561 Zone* zone = this->zone(); |
| 1435 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) | 1562 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) |
| 1436 ? AddInstruction(new(zone) HConstant(factory->the_hole_value(), | 1563 ? AddInstruction(new(zone) HConstant(factory->the_hole_value(), |
| 1437 Representation::Tagged())) | 1564 Representation::Tagged())) |
| 1438 : AddInstruction(new(zone) HConstant(nan_double, | 1565 : AddInstruction(new(zone) HConstant(nan_double, |
| 1439 Representation::Double())); | 1566 Representation::Double())); |
| 1440 | 1567 |
| 1441 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement, ast_id); | 1568 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); |
| 1442 | 1569 |
| 1443 HValue* key = builder.BeginBody(from, to, Token::LT); | 1570 HValue* key = builder.BeginBody(from, to, Token::LT); |
| 1444 | 1571 |
| 1445 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); | 1572 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); |
| 1446 | 1573 |
| 1447 builder.EndBody(); | 1574 builder.EndBody(); |
| 1448 } | 1575 } |
| 1449 | 1576 |
| 1450 | 1577 |
| 1451 void HGraphBuilder::BuildCopyElements(HValue* context, | 1578 void HGraphBuilder::BuildCopyElements(HValue* context, |
| 1452 HValue* from_elements, | 1579 HValue* from_elements, |
| 1453 ElementsKind from_elements_kind, | 1580 ElementsKind from_elements_kind, |
| 1454 HValue* to_elements, | 1581 HValue* to_elements, |
| 1455 ElementsKind to_elements_kind, | 1582 ElementsKind to_elements_kind, |
| 1456 HValue* length, | 1583 HValue* length, |
| 1457 HValue* capacity, | 1584 HValue* capacity) { |
| 1458 BailoutId ast_id) { | |
| 1459 bool pre_fill_with_holes = | 1585 bool pre_fill_with_holes = |
| 1460 IsFastDoubleElementsKind(from_elements_kind) && | 1586 IsFastDoubleElementsKind(from_elements_kind) && |
| 1461 IsFastObjectElementsKind(to_elements_kind); | 1587 IsFastObjectElementsKind(to_elements_kind); |
| 1462 | 1588 |
| 1463 if (pre_fill_with_holes) { | 1589 if (pre_fill_with_holes) { |
| 1464 // If the copy might trigger a GC, make sure that the FixedArray is | 1590 // If the copy might trigger a GC, make sure that the FixedArray is |
| 1465 // pre-initialized with holes to make sure that it's always in a consistent | 1591 // pre-initialized with holes to make sure that it's always in a consistent |
| 1466 // state. | 1592 // state. |
| 1467 BuildFillElementsWithHole(context, to_elements, to_elements_kind, | 1593 BuildFillElementsWithHole(context, to_elements, to_elements_kind, |
| 1468 graph()->GetConstant0(), capacity, ast_id); | 1594 graph()->GetConstant0(), capacity); |
| 1469 } | 1595 } |
| 1470 | 1596 |
| 1471 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement, ast_id); | 1597 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); |
| 1472 | 1598 |
| 1473 HValue* key = builder.BeginBody(graph()->GetConstant0(), length, Token::LT); | 1599 HValue* key = builder.BeginBody(graph()->GetConstant0(), length, Token::LT); |
| 1474 | 1600 |
| 1475 HValue* element = | 1601 HValue* element = |
| 1476 AddInstruction(new(zone()) HLoadKeyed(from_elements, key, NULL, | 1602 AddInstruction(new(zone()) HLoadKeyed(from_elements, key, NULL, |
| 1477 from_elements_kind, | 1603 from_elements_kind, |
| 1478 ALLOW_RETURN_HOLE)); | 1604 ALLOW_RETURN_HOLE)); |
| 1479 | 1605 |
| 1480 AddInstruction(new(zone()) HStoreKeyed(to_elements, key, element, | 1606 AddInstruction(new(zone()) HStoreKeyed(to_elements, key, element, |
| 1481 to_elements_kind)); | 1607 to_elements_kind)); |
| 1482 | 1608 |
| 1483 builder.EndBody(); | 1609 builder.EndBody(); |
| 1484 | 1610 |
| 1485 if (!pre_fill_with_holes && length != capacity) { | 1611 if (!pre_fill_with_holes && length != capacity) { |
| 1486 // Fill unused capacity with the hole. | 1612 // Fill unused capacity with the hole. |
| 1487 BuildFillElementsWithHole(context, to_elements, to_elements_kind, | 1613 BuildFillElementsWithHole(context, to_elements, to_elements_kind, |
| 1488 key, capacity, ast_id); | 1614 key, capacity); |
| 1489 } | 1615 } |
| 1490 } | 1616 } |
| 1491 | 1617 |
| 1492 | 1618 |
| 1493 HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, | 1619 HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, |
| 1494 HValue* boilerplate, | 1620 HValue* boilerplate, |
| 1495 AllocationSiteMode mode, | 1621 AllocationSiteMode mode, |
| 1496 ElementsKind kind, | 1622 ElementsKind kind, |
| 1497 int length) { | 1623 int length) { |
| 1498 Zone* zone = this->zone(); | 1624 Zone* zone = this->zone(); |
| (...skipping 2605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4104 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); | 4230 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); |
| 4105 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); | 4231 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); |
| 4106 instr->SetSuccessorAt(0, empty_true); | 4232 instr->SetSuccessorAt(0, empty_true); |
| 4107 instr->SetSuccessorAt(1, empty_false); | 4233 instr->SetSuccessorAt(1, empty_false); |
| 4108 owner()->current_block()->Finish(instr); | 4234 owner()->current_block()->Finish(instr); |
| 4109 HBasicBlock* join = owner()->CreateJoin(empty_true, empty_false, ast_id); | 4235 HBasicBlock* join = owner()->CreateJoin(empty_true, empty_false, ast_id); |
| 4110 owner()->set_current_block(join); | 4236 owner()->set_current_block(join); |
| 4111 } | 4237 } |
| 4112 | 4238 |
| 4113 | 4239 |
| 4240 void EffectContext::ReturnContinuation(HIfContinuation* continuation, |
| 4241 BailoutId ast_id) { |
| 4242 HBasicBlock* true_branch = NULL; |
| 4243 HBasicBlock* false_branch = NULL; |
| 4244 continuation->Continue(&true_branch, &false_branch, NULL); |
| 4245 if (!continuation->IsTrueReachable()) { |
| 4246 owner()->set_current_block(false_branch); |
| 4247 } else if (!continuation->IsFalseReachable()) { |
| 4248 owner()->set_current_block(true_branch); |
| 4249 } else { |
| 4250 HBasicBlock* join = owner()->CreateJoin(true_branch, false_branch, ast_id); |
| 4251 owner()->set_current_block(join); |
| 4252 } |
| 4253 } |
| 4254 |
| 4255 |
| 4114 void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { | 4256 void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { |
| 4115 ASSERT(!instr->IsControlInstruction()); | 4257 ASSERT(!instr->IsControlInstruction()); |
| 4116 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { | 4258 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { |
| 4117 return owner()->Bailout("bad value context for arguments object value"); | 4259 return owner()->Bailout("bad value context for arguments object value"); |
| 4118 } | 4260 } |
| 4119 owner()->AddInstruction(instr); | 4261 owner()->AddInstruction(instr); |
| 4120 owner()->Push(instr); | 4262 owner()->Push(instr); |
| 4121 if (instr->HasObservableSideEffects()) { | 4263 if (instr->HasObservableSideEffects()) { |
| 4122 owner()->AddSimulate(ast_id, REMOVABLE_SIMULATE); | 4264 owner()->AddSimulate(ast_id, REMOVABLE_SIMULATE); |
| 4123 } | 4265 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 4137 owner()->set_current_block(materialize_true); | 4279 owner()->set_current_block(materialize_true); |
| 4138 owner()->Push(owner()->graph()->GetConstantTrue()); | 4280 owner()->Push(owner()->graph()->GetConstantTrue()); |
| 4139 owner()->set_current_block(materialize_false); | 4281 owner()->set_current_block(materialize_false); |
| 4140 owner()->Push(owner()->graph()->GetConstantFalse()); | 4282 owner()->Push(owner()->graph()->GetConstantFalse()); |
| 4141 HBasicBlock* join = | 4283 HBasicBlock* join = |
| 4142 owner()->CreateJoin(materialize_true, materialize_false, ast_id); | 4284 owner()->CreateJoin(materialize_true, materialize_false, ast_id); |
| 4143 owner()->set_current_block(join); | 4285 owner()->set_current_block(join); |
| 4144 } | 4286 } |
| 4145 | 4287 |
| 4146 | 4288 |
| 4289 void ValueContext::ReturnContinuation(HIfContinuation* continuation, |
| 4290 BailoutId ast_id) { |
| 4291 HBasicBlock* materialize_true = NULL; |
| 4292 HBasicBlock* materialize_false = NULL; |
| 4293 continuation->Continue(&materialize_true, &materialize_false, NULL); |
| 4294 if (continuation->IsTrueReachable()) { |
| 4295 owner()->set_current_block(materialize_true); |
| 4296 owner()->Push(owner()->graph()->GetConstantTrue()); |
| 4297 owner()->set_current_block(materialize_true); |
| 4298 } |
| 4299 if (continuation->IsFalseReachable()) { |
| 4300 owner()->set_current_block(materialize_false); |
| 4301 owner()->Push(owner()->graph()->GetConstantFalse()); |
| 4302 owner()->set_current_block(materialize_false); |
| 4303 } |
| 4304 if (continuation->TrueAndFalseReachable()) { |
| 4305 HBasicBlock* join = |
| 4306 owner()->CreateJoin(materialize_true, materialize_false, ast_id); |
| 4307 owner()->set_current_block(join); |
| 4308 } |
| 4309 } |
| 4310 |
| 4311 |
| 4147 void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { | 4312 void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { |
| 4148 ASSERT(!instr->IsControlInstruction()); | 4313 ASSERT(!instr->IsControlInstruction()); |
| 4149 HOptimizedGraphBuilder* builder = owner(); | 4314 HOptimizedGraphBuilder* builder = owner(); |
| 4150 builder->AddInstruction(instr); | 4315 builder->AddInstruction(instr); |
| 4151 // We expect a simulate after every expression with side effects, though | 4316 // We expect a simulate after every expression with side effects, though |
| 4152 // this one isn't actually needed (and wouldn't work if it were targeted). | 4317 // this one isn't actually needed (and wouldn't work if it were targeted). |
| 4153 if (instr->HasObservableSideEffects()) { | 4318 if (instr->HasObservableSideEffects()) { |
| 4154 builder->Push(instr); | 4319 builder->Push(instr); |
| 4155 builder->AddSimulate(ast_id, REMOVABLE_SIMULATE); | 4320 builder->AddSimulate(ast_id, REMOVABLE_SIMULATE); |
| 4156 builder->Pop(); | 4321 builder->Pop(); |
| 4157 } | 4322 } |
| 4158 BuildBranch(instr); | 4323 BuildBranch(instr); |
| 4159 } | 4324 } |
| 4160 | 4325 |
| 4161 | 4326 |
| 4162 void TestContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { | 4327 void TestContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { |
| 4163 ASSERT(!instr->HasObservableSideEffects()); | 4328 ASSERT(!instr->HasObservableSideEffects()); |
| 4164 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); | 4329 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); |
| 4165 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); | 4330 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); |
| 4166 instr->SetSuccessorAt(0, empty_true); | 4331 instr->SetSuccessorAt(0, empty_true); |
| 4167 instr->SetSuccessorAt(1, empty_false); | 4332 instr->SetSuccessorAt(1, empty_false); |
| 4168 owner()->current_block()->Finish(instr); | 4333 owner()->current_block()->Finish(instr); |
| 4169 empty_true->Goto(if_true(), owner()->function_state()); | 4334 empty_true->Goto(if_true(), owner()->function_state()); |
| 4170 empty_false->Goto(if_false(), owner()->function_state()); | 4335 empty_false->Goto(if_false(), owner()->function_state()); |
| 4171 owner()->set_current_block(NULL); | 4336 owner()->set_current_block(NULL); |
| 4172 } | 4337 } |
| 4173 | 4338 |
| 4174 | 4339 |
| 4340 void TestContext::ReturnContinuation(HIfContinuation* continuation, |
| 4341 BailoutId ast_id) { |
| 4342 HBasicBlock* true_branch = NULL; |
| 4343 HBasicBlock* false_branch = NULL; |
| 4344 continuation->Continue(&true_branch, &false_branch, NULL); |
| 4345 if (continuation->IsTrueReachable()) { |
| 4346 true_branch->Goto(if_true(), owner()->function_state()); |
| 4347 } |
| 4348 if (continuation->IsFalseReachable()) { |
| 4349 false_branch->Goto(if_false(), owner()->function_state()); |
| 4350 } |
| 4351 owner()->set_current_block(NULL); |
| 4352 } |
| 4353 |
| 4354 |
| 4175 void TestContext::BuildBranch(HValue* value) { | 4355 void TestContext::BuildBranch(HValue* value) { |
| 4176 // We expect the graph to be in edge-split form: there is no edge that | 4356 // We expect the graph to be in edge-split form: there is no edge that |
| 4177 // connects a branch node to a join node. We conservatively ensure that | 4357 // connects a branch node to a join node. We conservatively ensure that |
| 4178 // property by always adding an empty block on the outgoing edges of this | 4358 // property by always adding an empty block on the outgoing edges of this |
| 4179 // branch. | 4359 // branch. |
| 4180 HOptimizedGraphBuilder* builder = owner(); | 4360 HOptimizedGraphBuilder* builder = owner(); |
| 4181 if (value != NULL && value->CheckFlag(HValue::kIsArguments)) { | 4361 if (value != NULL && value->CheckFlag(HValue::kIsArguments)) { |
| 4182 builder->Bailout("arguments object value in a test context"); | 4362 builder->Bailout("arguments object value in a test context"); |
| 4183 } | 4363 } |
| 4184 if (value->IsConstant()) { | 4364 if (value->IsConstant()) { |
| (...skipping 2623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6808 CHECK_ALIVE(VisitForValue(expr->value())); | 6988 CHECK_ALIVE(VisitForValue(expr->value())); |
| 6809 HValue* value = Pop(); | 6989 HValue* value = Pop(); |
| 6810 HValue* key = Pop(); | 6990 HValue* key = Pop(); |
| 6811 HValue* object = Pop(); | 6991 HValue* object = Pop(); |
| 6812 bool has_side_effects = false; | 6992 bool has_side_effects = false; |
| 6813 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(), | 6993 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(), |
| 6814 expr->position(), | 6994 expr->position(), |
| 6815 true, // is_store | 6995 true, // is_store |
| 6816 &has_side_effects); | 6996 &has_side_effects); |
| 6817 Push(value); | 6997 Push(value); |
| 6818 ASSERT(has_side_effects); // Stores always have side effects. | |
| 6819 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 6998 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); |
| 6820 return ast_context()->ReturnValue(Pop()); | 6999 return ast_context()->ReturnValue(Pop()); |
| 6821 } | 7000 } |
| 6822 } | 7001 } |
| 6823 | 7002 |
| 6824 | 7003 |
| 6825 // Because not every expression has a position and there is not common | 7004 // Because not every expression has a position and there is not common |
| 6826 // superclass of Assignment and CountOperation, we cannot just pass the | 7005 // superclass of Assignment and CountOperation, we cannot just pass the |
| 6827 // owning expression instead of position and ast_id separately. | 7006 // owning expression instead of position and ast_id separately. |
| 6828 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( | 7007 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( |
| (...skipping 4864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11693 } | 11872 } |
| 11694 } | 11873 } |
| 11695 | 11874 |
| 11696 #ifdef DEBUG | 11875 #ifdef DEBUG |
| 11697 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11876 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 11698 if (allocator_ != NULL) allocator_->Verify(); | 11877 if (allocator_ != NULL) allocator_->Verify(); |
| 11699 #endif | 11878 #endif |
| 11700 } | 11879 } |
| 11701 | 11880 |
| 11702 } } // namespace v8::internal | 11881 } } // namespace v8::internal |
| OLD | NEW |