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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 | 131 |
132 return instr; | 132 return instr; |
133 } | 133 } |
134 | 134 |
135 | 135 |
136 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id, | 136 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id, |
137 RemovableSimulate removable) { | 137 RemovableSimulate removable) { |
138 ASSERT(HasEnvironment()); | 138 ASSERT(HasEnvironment()); |
139 HEnvironment* environment = last_environment(); | 139 HEnvironment* environment = last_environment(); |
140 ASSERT(ast_id.IsNone() || | 140 ASSERT(ast_id.IsNone() || |
| 141 ast_id == BailoutId::StubEntry() || |
141 environment->closure()->shared()->VerifyBailoutId(ast_id)); | 142 environment->closure()->shared()->VerifyBailoutId(ast_id)); |
142 | 143 |
143 int push_count = environment->push_count(); | 144 int push_count = environment->push_count(); |
144 int pop_count = environment->pop_count(); | 145 int pop_count = environment->pop_count(); |
145 | 146 |
146 HSimulate* instr = | 147 HSimulate* instr = |
147 new(zone()) HSimulate(ast_id, pop_count, zone(), removable); | 148 new(zone()) HSimulate(ast_id, pop_count, zone(), removable); |
148 // Order of pushed values: newest (top of stack) first. This allows | 149 // Order of pushed values: newest (top of stack) first. This allows |
149 // HSimulate::MergeInto() to easily append additional pushed values | 150 // HSimulate::MergeInto() to easily append additional pushed values |
150 // that are older (from further down the stack). | 151 // that are older (from further down the stack). |
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 HConstant* HGraph::GetConstantFalse() { | 615 HConstant* HGraph::GetConstantFalse() { |
615 return GetConstant(&constant_false_, isolate()->factory()->false_value()); | 616 return GetConstant(&constant_false_, isolate()->factory()->false_value()); |
616 } | 617 } |
617 | 618 |
618 | 619 |
619 HConstant* HGraph::GetConstantHole() { | 620 HConstant* HGraph::GetConstantHole() { |
620 return GetConstant(&constant_hole_, isolate()->factory()->the_hole_value()); | 621 return GetConstant(&constant_hole_, isolate()->factory()->the_hole_value()); |
621 } | 622 } |
622 | 623 |
623 | 624 |
624 HGraphBuilder::HGraphBuilder(CompilationInfo* info, | 625 HGraph* HGraphBuilder::CreateGraph() { |
625 TypeFeedbackOracle* oracle) | 626 graph_ = new(zone()) HGraph(info_); |
626 : function_state_(NULL), | 627 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info_); |
| 628 HPhase phase("H_Block building"); |
| 629 set_current_block(graph()->entry_block()); |
| 630 if (!BuildGraph()) return NULL; |
| 631 return graph_; |
| 632 } |
| 633 |
| 634 |
| 635 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { |
| 636 ASSERT(current_block() != NULL); |
| 637 current_block()->AddInstruction(instr); |
| 638 return instr; |
| 639 } |
| 640 |
| 641 |
| 642 void HGraphBuilder::AddSimulate(BailoutId id, |
| 643 RemovableSimulate removable) { |
| 644 ASSERT(current_block() != NULL); |
| 645 current_block()->AddSimulate(id, removable); |
| 646 } |
| 647 |
| 648 |
| 649 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( |
| 650 HValue* external_elements, |
| 651 HValue* checked_key, |
| 652 HValue* val, |
| 653 HValue* dependency, |
| 654 ElementsKind elements_kind, |
| 655 bool is_store) { |
| 656 Zone* zone = this->zone(); |
| 657 if (is_store) { |
| 658 ASSERT(val != NULL); |
| 659 switch (elements_kind) { |
| 660 case EXTERNAL_PIXEL_ELEMENTS: { |
| 661 val = AddInstruction(new(zone) HClampToUint8(val)); |
| 662 break; |
| 663 } |
| 664 case EXTERNAL_BYTE_ELEMENTS: |
| 665 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 666 case EXTERNAL_SHORT_ELEMENTS: |
| 667 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 668 case EXTERNAL_INT_ELEMENTS: |
| 669 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { |
| 670 break; |
| 671 } |
| 672 case EXTERNAL_FLOAT_ELEMENTS: |
| 673 case EXTERNAL_DOUBLE_ELEMENTS: |
| 674 break; |
| 675 case FAST_SMI_ELEMENTS: |
| 676 case FAST_ELEMENTS: |
| 677 case FAST_DOUBLE_ELEMENTS: |
| 678 case FAST_HOLEY_SMI_ELEMENTS: |
| 679 case FAST_HOLEY_ELEMENTS: |
| 680 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 681 case DICTIONARY_ELEMENTS: |
| 682 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 683 UNREACHABLE(); |
| 684 break; |
| 685 } |
| 686 return new(zone) HStoreKeyed(external_elements, checked_key, |
| 687 val, elements_kind); |
| 688 } else { |
| 689 ASSERT(val == NULL); |
| 690 HLoadKeyed* load = |
| 691 new(zone) HLoadKeyed( |
| 692 external_elements, checked_key, dependency, elements_kind); |
| 693 if (FLAG_opt_safe_uint32_operations && |
| 694 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { |
| 695 graph()->RecordUint32Instruction(load); |
| 696 } |
| 697 return load; |
| 698 } |
| 699 } |
| 700 |
| 701 |
| 702 HInstruction* HGraphBuilder::BuildFastElementAccess( |
| 703 HValue* elements, |
| 704 HValue* checked_key, |
| 705 HValue* val, |
| 706 HValue* load_dependency, |
| 707 ElementsKind elements_kind, |
| 708 bool is_store) { |
| 709 Zone* zone = this->zone(); |
| 710 if (is_store) { |
| 711 ASSERT(val != NULL); |
| 712 switch (elements_kind) { |
| 713 case FAST_SMI_ELEMENTS: |
| 714 case FAST_HOLEY_SMI_ELEMENTS: |
| 715 // Smi-only arrays need a smi check. |
| 716 AddInstruction(new(zone) HCheckSmi(val)); |
| 717 // Fall through. |
| 718 case FAST_ELEMENTS: |
| 719 case FAST_HOLEY_ELEMENTS: |
| 720 case FAST_DOUBLE_ELEMENTS: |
| 721 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 722 return new(zone) HStoreKeyed(elements, checked_key, val, elements_kind); |
| 723 default: |
| 724 UNREACHABLE(); |
| 725 return NULL; |
| 726 } |
| 727 } |
| 728 // It's an element load (!is_store). |
| 729 return new(zone) HLoadKeyed(elements, |
| 730 checked_key, |
| 731 load_dependency, |
| 732 elements_kind); |
| 733 } |
| 734 |
| 735 |
| 736 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
| 737 HValue* object, |
| 738 HValue* key, |
| 739 HValue* val, |
| 740 HCheckMaps* mapcheck, |
| 741 bool is_js_array, |
| 742 ElementsKind elements_kind, |
| 743 bool is_store) { |
| 744 Zone* zone = this->zone(); |
| 745 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency |
| 746 // on a HElementsTransition instruction. The flag can also be removed if the |
| 747 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further |
| 748 // ElementsKind transitions. Finally, the dependency can be removed for stores |
| 749 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the |
| 750 // generated store code. |
| 751 if ((elements_kind == FAST_HOLEY_ELEMENTS) || |
| 752 (elements_kind == FAST_ELEMENTS && is_store)) { |
| 753 if (mapcheck != NULL) { |
| 754 mapcheck->ClearGVNFlag(kDependsOnElementsKind); |
| 755 } |
| 756 } |
| 757 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); |
| 758 bool fast_elements = IsFastObjectElementsKind(elements_kind); |
| 759 HInstruction* elements = |
| 760 AddInstruction(new(zone) HLoadElements(object, mapcheck)); |
| 761 if (is_store && (fast_elements || fast_smi_only_elements)) { |
| 762 HCheckMaps* check_cow_map = new(zone) HCheckMaps( |
| 763 elements, Isolate::Current()->factory()->fixed_array_map(), zone); |
| 764 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
| 765 AddInstruction(check_cow_map); |
| 766 } |
| 767 HInstruction* length = NULL; |
| 768 HInstruction* checked_key = NULL; |
| 769 if (IsExternalArrayElementsKind(elements_kind)) { |
| 770 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
| 771 checked_key = AddInstruction(new(zone) HBoundsCheck(key, length, |
| 772 ALLOW_SMI_KEY)); |
| 773 HLoadExternalArrayPointer* external_elements = |
| 774 new(zone) HLoadExternalArrayPointer(elements); |
| 775 AddInstruction(external_elements); |
| 776 return BuildExternalArrayElementAccess( |
| 777 external_elements, checked_key, val, mapcheck, |
| 778 elements_kind, is_store); |
| 779 } |
| 780 ASSERT(fast_smi_only_elements || |
| 781 fast_elements || |
| 782 IsFastDoubleElementsKind(elements_kind)); |
| 783 if (is_js_array) { |
| 784 length = AddInstruction(new(zone) HJSArrayLength(object, mapcheck, |
| 785 HType::Smi())); |
| 786 } else { |
| 787 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
| 788 } |
| 789 checked_key = AddInstruction(new(zone) HBoundsCheck(key, length, |
| 790 ALLOW_SMI_KEY)); |
| 791 return BuildFastElementAccess(elements, checked_key, val, mapcheck, |
| 792 elements_kind, is_store); |
| 793 } |
| 794 |
| 795 |
| 796 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, |
| 797 TypeFeedbackOracle* oracle) |
| 798 : HGraphBuilder(info), |
| 799 function_state_(NULL), |
627 initial_function_state_(this, info, oracle, NORMAL_RETURN), | 800 initial_function_state_(this, info, oracle, NORMAL_RETURN), |
628 ast_context_(NULL), | 801 ast_context_(NULL), |
629 break_scope_(NULL), | 802 break_scope_(NULL), |
630 graph_(NULL), | |
631 current_block_(NULL), | |
632 inlined_count_(0), | 803 inlined_count_(0), |
633 globals_(10, info->zone()), | 804 globals_(10, info->zone()), |
634 zone_(info->zone()), | |
635 inline_bailout_(false) { | 805 inline_bailout_(false) { |
636 // This is not initialized in the initializer list because the | 806 // This is not initialized in the initializer list because the |
637 // constructor for the initial state relies on function_state_ == NULL | 807 // constructor for the initial state relies on function_state_ == NULL |
638 // to know it's the initial state. | 808 // to know it's the initial state. |
639 function_state_= &initial_function_state_; | 809 function_state_= &initial_function_state_; |
640 } | 810 InitializeAstVisitor(); |
641 | 811 } |
642 HBasicBlock* HGraphBuilder::CreateJoin(HBasicBlock* first, | 812 |
643 HBasicBlock* second, | 813 |
644 BailoutId join_id) { | 814 HBasicBlock* HOptimizedGraphBuilder::CreateJoin(HBasicBlock* first, |
| 815 HBasicBlock* second, |
| 816 BailoutId join_id) { |
645 if (first == NULL) { | 817 if (first == NULL) { |
646 return second; | 818 return second; |
647 } else if (second == NULL) { | 819 } else if (second == NULL) { |
648 return first; | 820 return first; |
649 } else { | 821 } else { |
650 HBasicBlock* join_block = graph_->CreateBasicBlock(); | 822 HBasicBlock* join_block = graph()->CreateBasicBlock(); |
651 first->Goto(join_block); | 823 first->Goto(join_block); |
652 second->Goto(join_block); | 824 second->Goto(join_block); |
653 join_block->SetJoinId(join_id); | 825 join_block->SetJoinId(join_id); |
654 return join_block; | 826 return join_block; |
655 } | 827 } |
656 } | 828 } |
657 | 829 |
658 | 830 |
659 HBasicBlock* HGraphBuilder::JoinContinue(IterationStatement* statement, | 831 HBasicBlock* HOptimizedGraphBuilder::JoinContinue(IterationStatement* statement, |
660 HBasicBlock* exit_block, | 832 HBasicBlock* exit_block, |
661 HBasicBlock* continue_block) { | 833 HBasicBlock* continue_block) { |
662 if (continue_block != NULL) { | 834 if (continue_block != NULL) { |
663 if (exit_block != NULL) exit_block->Goto(continue_block); | 835 if (exit_block != NULL) exit_block->Goto(continue_block); |
664 continue_block->SetJoinId(statement->ContinueId()); | 836 continue_block->SetJoinId(statement->ContinueId()); |
665 return continue_block; | 837 return continue_block; |
666 } | 838 } |
667 return exit_block; | 839 return exit_block; |
668 } | 840 } |
669 | 841 |
670 | 842 |
671 HBasicBlock* HGraphBuilder::CreateLoop(IterationStatement* statement, | 843 HBasicBlock* HOptimizedGraphBuilder::CreateLoop(IterationStatement* statement, |
672 HBasicBlock* loop_entry, | 844 HBasicBlock* loop_entry, |
673 HBasicBlock* body_exit, | 845 HBasicBlock* body_exit, |
674 HBasicBlock* loop_successor, | 846 HBasicBlock* loop_successor, |
675 HBasicBlock* break_block) { | 847 HBasicBlock* break_block) { |
676 if (body_exit != NULL) body_exit->Goto(loop_entry); | 848 if (body_exit != NULL) body_exit->Goto(loop_entry); |
677 loop_entry->PostProcessLoopHeader(statement); | 849 loop_entry->PostProcessLoopHeader(statement); |
678 if (break_block != NULL) { | 850 if (break_block != NULL) { |
679 if (loop_successor != NULL) loop_successor->Goto(break_block); | 851 if (loop_successor != NULL) loop_successor->Goto(break_block); |
680 break_block->SetJoinId(statement->ExitId()); | 852 break_block->SetJoinId(statement->ExitId()); |
681 return break_block; | 853 return break_block; |
682 } | 854 } |
683 return loop_successor; | 855 return loop_successor; |
684 } | 856 } |
685 | 857 |
(...skipping 10 matching lines...) Expand all Loading... |
696 entry_block_(NULL), | 868 entry_block_(NULL), |
697 blocks_(8, info->zone()), | 869 blocks_(8, info->zone()), |
698 values_(16, info->zone()), | 870 values_(16, info->zone()), |
699 phi_list_(NULL), | 871 phi_list_(NULL), |
700 uint32_instructions_(NULL), | 872 uint32_instructions_(NULL), |
701 info_(info), | 873 info_(info), |
702 zone_(info->zone()), | 874 zone_(info->zone()), |
703 is_recursive_(false), | 875 is_recursive_(false), |
704 use_optimistic_licm_(false), | 876 use_optimistic_licm_(false), |
705 type_change_checksum_(0) { | 877 type_change_checksum_(0) { |
706 start_environment_ = | 878 if (info->IsStub()) { |
707 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); | 879 start_environment_ = |
| 880 new(zone_) HEnvironment(zone_); |
| 881 } else { |
| 882 start_environment_ = |
| 883 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); |
| 884 } |
708 start_environment_->set_ast_id(BailoutId::FunctionEntry()); | 885 start_environment_->set_ast_id(BailoutId::FunctionEntry()); |
709 entry_block_ = CreateBasicBlock(); | 886 entry_block_ = CreateBasicBlock(); |
710 entry_block_->SetInitialEnvironment(start_environment_); | 887 entry_block_->SetInitialEnvironment(start_environment_); |
711 } | 888 } |
712 | 889 |
713 | 890 |
714 HBasicBlock* HGraph::CreateBasicBlock() { | 891 HBasicBlock* HGraph::CreateBasicBlock() { |
715 HBasicBlock* result = new(zone()) HBasicBlock(this); | 892 HBasicBlock* result = new(zone()) HBasicBlock(this); |
716 blocks_.Add(result, zone()); | 893 blocks_.Add(result, zone()); |
717 return result; | 894 return result; |
(...skipping 2168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2886 visited.Clear(); | 3063 visited.Clear(); |
2887 } | 3064 } |
2888 } | 3065 } |
2889 } | 3066 } |
2890 } | 3067 } |
2891 } | 3068 } |
2892 | 3069 |
2893 | 3070 |
2894 // Implementation of utility class to encapsulate the translation state for | 3071 // Implementation of utility class to encapsulate the translation state for |
2895 // a (possibly inlined) function. | 3072 // a (possibly inlined) function. |
2896 FunctionState::FunctionState(HGraphBuilder* owner, | 3073 FunctionState::FunctionState(HOptimizedGraphBuilder* owner, |
2897 CompilationInfo* info, | 3074 CompilationInfo* info, |
2898 TypeFeedbackOracle* oracle, | 3075 TypeFeedbackOracle* oracle, |
2899 InliningKind inlining_kind) | 3076 InliningKind inlining_kind) |
2900 : owner_(owner), | 3077 : owner_(owner), |
2901 compilation_info_(info), | 3078 compilation_info_(info), |
2902 oracle_(oracle), | 3079 oracle_(oracle), |
2903 call_context_(NULL), | 3080 call_context_(NULL), |
2904 inlining_kind_(inlining_kind), | 3081 inlining_kind_(inlining_kind), |
2905 function_return_(NULL), | 3082 function_return_(NULL), |
2906 test_context_(NULL), | 3083 test_context_(NULL), |
(...skipping 28 matching lines...) Expand all Loading... |
2935 | 3112 |
2936 | 3113 |
2937 FunctionState::~FunctionState() { | 3114 FunctionState::~FunctionState() { |
2938 delete test_context_; | 3115 delete test_context_; |
2939 owner_->set_function_state(outer_); | 3116 owner_->set_function_state(outer_); |
2940 } | 3117 } |
2941 | 3118 |
2942 | 3119 |
2943 // Implementation of utility classes to represent an expression's context in | 3120 // Implementation of utility classes to represent an expression's context in |
2944 // the AST. | 3121 // the AST. |
2945 AstContext::AstContext(HGraphBuilder* owner, Expression::Context kind) | 3122 AstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind) |
2946 : owner_(owner), | 3123 : owner_(owner), |
2947 kind_(kind), | 3124 kind_(kind), |
2948 outer_(owner->ast_context()), | 3125 outer_(owner->ast_context()), |
2949 for_typeof_(false) { | 3126 for_typeof_(false) { |
2950 owner->set_ast_context(this); // Push. | 3127 owner->set_ast_context(this); // Push. |
2951 #ifdef DEBUG | 3128 #ifdef DEBUG |
2952 ASSERT(owner->environment()->frame_type() == JS_FUNCTION); | 3129 ASSERT(owner->environment()->frame_type() == JS_FUNCTION); |
2953 original_length_ = owner->environment()->length(); | 3130 original_length_ = owner->environment()->length(); |
2954 #endif | 3131 #endif |
2955 } | 3132 } |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3046 owner()->set_current_block(materialize_false); | 3223 owner()->set_current_block(materialize_false); |
3047 owner()->Push(owner()->graph()->GetConstantFalse()); | 3224 owner()->Push(owner()->graph()->GetConstantFalse()); |
3048 HBasicBlock* join = | 3225 HBasicBlock* join = |
3049 owner()->CreateJoin(materialize_true, materialize_false, ast_id); | 3226 owner()->CreateJoin(materialize_true, materialize_false, ast_id); |
3050 owner()->set_current_block(join); | 3227 owner()->set_current_block(join); |
3051 } | 3228 } |
3052 | 3229 |
3053 | 3230 |
3054 void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { | 3231 void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { |
3055 ASSERT(!instr->IsControlInstruction()); | 3232 ASSERT(!instr->IsControlInstruction()); |
3056 HGraphBuilder* builder = owner(); | 3233 HOptimizedGraphBuilder* builder = owner(); |
3057 builder->AddInstruction(instr); | 3234 builder->AddInstruction(instr); |
3058 // We expect a simulate after every expression with side effects, though | 3235 // We expect a simulate after every expression with side effects, though |
3059 // this one isn't actually needed (and wouldn't work if it were targeted). | 3236 // this one isn't actually needed (and wouldn't work if it were targeted). |
3060 if (instr->HasObservableSideEffects()) { | 3237 if (instr->HasObservableSideEffects()) { |
3061 builder->Push(instr); | 3238 builder->Push(instr); |
3062 builder->AddSimulate(ast_id, REMOVABLE_SIMULATE); | 3239 builder->AddSimulate(ast_id, REMOVABLE_SIMULATE); |
3063 builder->Pop(); | 3240 builder->Pop(); |
3064 } | 3241 } |
3065 BuildBranch(instr); | 3242 BuildBranch(instr); |
3066 } | 3243 } |
(...skipping 10 matching lines...) Expand all Loading... |
3077 empty_false->Goto(if_false(), owner()->function_state()); | 3254 empty_false->Goto(if_false(), owner()->function_state()); |
3078 owner()->set_current_block(NULL); | 3255 owner()->set_current_block(NULL); |
3079 } | 3256 } |
3080 | 3257 |
3081 | 3258 |
3082 void TestContext::BuildBranch(HValue* value) { | 3259 void TestContext::BuildBranch(HValue* value) { |
3083 // We expect the graph to be in edge-split form: there is no edge that | 3260 // We expect the graph to be in edge-split form: there is no edge that |
3084 // connects a branch node to a join node. We conservatively ensure that | 3261 // connects a branch node to a join node. We conservatively ensure that |
3085 // property by always adding an empty block on the outgoing edges of this | 3262 // property by always adding an empty block on the outgoing edges of this |
3086 // branch. | 3263 // branch. |
3087 HGraphBuilder* builder = owner(); | 3264 HOptimizedGraphBuilder* builder = owner(); |
3088 if (value != NULL && value->CheckFlag(HValue::kIsArguments)) { | 3265 if (value != NULL && value->CheckFlag(HValue::kIsArguments)) { |
3089 builder->Bailout("arguments object value in a test context"); | 3266 builder->Bailout("arguments object value in a test context"); |
3090 } | 3267 } |
3091 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); | 3268 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); |
3092 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); | 3269 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); |
3093 TypeFeedbackId test_id = condition()->test_id(); | 3270 TypeFeedbackId test_id = condition()->test_id(); |
3094 ToBooleanStub::Types expected(oracle()->ToBooleanTypes(test_id)); | 3271 ToBooleanStub::Types expected(oracle()->ToBooleanTypes(test_id)); |
3095 HBranch* test = new(zone()) HBranch(value, empty_true, empty_false, expected); | 3272 HBranch* test = new(zone()) HBranch(value, empty_true, empty_false, expected); |
3096 builder->current_block()->Finish(test); | 3273 builder->current_block()->Finish(test); |
3097 | 3274 |
3098 empty_true->Goto(if_true(), owner()->function_state()); | 3275 empty_true->Goto(if_true(), owner()->function_state()); |
3099 empty_false->Goto(if_false(), owner()->function_state()); | 3276 empty_false->Goto(if_false(), owner()->function_state()); |
3100 builder->set_current_block(NULL); | 3277 builder->set_current_block(NULL); |
3101 } | 3278 } |
3102 | 3279 |
3103 | 3280 |
3104 // HGraphBuilder infrastructure for bailing out and checking bailouts. | 3281 // HOptimizedGraphBuilder infrastructure for bailing out and checking bailouts. |
3105 #define CHECK_BAILOUT(call) \ | 3282 #define CHECK_BAILOUT(call) \ |
3106 do { \ | 3283 do { \ |
3107 call; \ | 3284 call; \ |
3108 if (HasStackOverflow()) return; \ | 3285 if (HasStackOverflow()) return; \ |
3109 } while (false) | 3286 } while (false) |
3110 | 3287 |
3111 | 3288 |
3112 #define CHECK_ALIVE(call) \ | 3289 #define CHECK_ALIVE(call) \ |
3113 do { \ | 3290 do { \ |
3114 call; \ | 3291 call; \ |
3115 if (HasStackOverflow() || current_block() == NULL) return; \ | 3292 if (HasStackOverflow() || current_block() == NULL) return; \ |
3116 } while (false) | 3293 } while (false) |
3117 | 3294 |
3118 | 3295 |
3119 void HGraphBuilder::Bailout(const char* reason) { | 3296 void HOptimizedGraphBuilder::Bailout(const char* reason) { |
3120 info()->set_bailout_reason(reason); | 3297 info()->set_bailout_reason(reason); |
3121 SetStackOverflow(); | 3298 SetStackOverflow(); |
3122 } | 3299 } |
3123 | 3300 |
3124 | 3301 |
3125 void HGraphBuilder::VisitForEffect(Expression* expr) { | 3302 void HOptimizedGraphBuilder::VisitForEffect(Expression* expr) { |
3126 EffectContext for_effect(this); | 3303 EffectContext for_effect(this); |
3127 Visit(expr); | 3304 Visit(expr); |
3128 } | 3305 } |
3129 | 3306 |
3130 | 3307 |
3131 void HGraphBuilder::VisitForValue(Expression* expr, ArgumentsAllowedFlag flag) { | 3308 void HOptimizedGraphBuilder::VisitForValue(Expression* expr, |
| 3309 ArgumentsAllowedFlag flag) { |
3132 ValueContext for_value(this, flag); | 3310 ValueContext for_value(this, flag); |
3133 Visit(expr); | 3311 Visit(expr); |
3134 } | 3312 } |
3135 | 3313 |
3136 | 3314 |
3137 void HGraphBuilder::VisitForTypeOf(Expression* expr) { | 3315 void HOptimizedGraphBuilder::VisitForTypeOf(Expression* expr) { |
3138 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); | 3316 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); |
3139 for_value.set_for_typeof(true); | 3317 for_value.set_for_typeof(true); |
3140 Visit(expr); | 3318 Visit(expr); |
3141 } | 3319 } |
3142 | 3320 |
3143 | 3321 |
3144 | 3322 |
3145 void HGraphBuilder::VisitForControl(Expression* expr, | 3323 void HOptimizedGraphBuilder::VisitForControl(Expression* expr, |
3146 HBasicBlock* true_block, | 3324 HBasicBlock* true_block, |
3147 HBasicBlock* false_block) { | 3325 HBasicBlock* false_block) { |
3148 TestContext for_test(this, expr, oracle(), true_block, false_block); | 3326 TestContext for_test(this, expr, oracle(), true_block, false_block); |
3149 Visit(expr); | 3327 Visit(expr); |
3150 } | 3328 } |
3151 | 3329 |
3152 | 3330 |
3153 void HGraphBuilder::VisitArgument(Expression* expr) { | 3331 void HOptimizedGraphBuilder::VisitArgument(Expression* expr) { |
3154 CHECK_ALIVE(VisitForValue(expr)); | 3332 CHECK_ALIVE(VisitForValue(expr)); |
3155 Push(AddInstruction(new(zone()) HPushArgument(Pop()))); | 3333 Push(AddInstruction(new(zone()) HPushArgument(Pop()))); |
3156 } | 3334 } |
3157 | 3335 |
3158 | 3336 |
3159 void HGraphBuilder::VisitArgumentList(ZoneList<Expression*>* arguments) { | 3337 void HOptimizedGraphBuilder::VisitArgumentList( |
| 3338 ZoneList<Expression*>* arguments) { |
3160 for (int i = 0; i < arguments->length(); i++) { | 3339 for (int i = 0; i < arguments->length(); i++) { |
3161 CHECK_ALIVE(VisitArgument(arguments->at(i))); | 3340 CHECK_ALIVE(VisitArgument(arguments->at(i))); |
3162 } | 3341 } |
3163 } | 3342 } |
3164 | 3343 |
3165 | 3344 |
3166 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) { | 3345 void HOptimizedGraphBuilder::VisitExpressions( |
| 3346 ZoneList<Expression*>* exprs) { |
3167 for (int i = 0; i < exprs->length(); ++i) { | 3347 for (int i = 0; i < exprs->length(); ++i) { |
3168 CHECK_ALIVE(VisitForValue(exprs->at(i))); | 3348 CHECK_ALIVE(VisitForValue(exprs->at(i))); |
3169 } | 3349 } |
3170 } | 3350 } |
3171 | 3351 |
3172 | 3352 |
3173 HGraph* HGraphBuilder::CreateGraph() { | 3353 bool HOptimizedGraphBuilder::BuildGraph() { |
3174 graph_ = new(zone()) HGraph(info()); | 3354 Scope* scope = info()->scope(); |
3175 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info()); | 3355 if (scope->HasIllegalRedeclaration()) { |
| 3356 Bailout("function with illegal redeclaration"); |
| 3357 return false; |
| 3358 } |
| 3359 if (scope->calls_eval()) { |
| 3360 Bailout("function calls eval"); |
| 3361 return false; |
| 3362 } |
| 3363 SetUpScope(scope); |
3176 | 3364 |
3177 { | 3365 // Add an edge to the body entry. This is warty: the graph's start |
3178 HPhase phase("H_Block building"); | 3366 // environment will be used by the Lithium translation as the initial |
3179 current_block_ = graph()->entry_block(); | 3367 // environment on graph entry, but it has now been mutated by the |
| 3368 // Hydrogen translation of the instructions in the start block. This |
| 3369 // environment uses values which have not been defined yet. These |
| 3370 // Hydrogen instructions will then be replayed by the Lithium |
| 3371 // translation, so they cannot have an environment effect. The edge to |
| 3372 // the body's entry block (along with some special logic for the start |
| 3373 // block in HInstruction::InsertAfter) seals the start block from |
| 3374 // getting unwanted instructions inserted. |
| 3375 // |
| 3376 // TODO(kmillikin): Fix this. Stop mutating the initial environment. |
| 3377 // Make the Hydrogen instructions in the initial block into Hydrogen |
| 3378 // values (but not instructions), present in the initial environment and |
| 3379 // not replayed by the Lithium translation. |
| 3380 HEnvironment* initial_env = environment()->CopyWithoutHistory(); |
| 3381 HBasicBlock* body_entry = CreateBasicBlock(initial_env); |
| 3382 current_block()->Goto(body_entry); |
| 3383 body_entry->SetJoinId(BailoutId::FunctionEntry()); |
| 3384 set_current_block(body_entry); |
3180 | 3385 |
3181 Scope* scope = info()->scope(); | 3386 // Handle implicit declaration of the function name in named function |
3182 if (scope->HasIllegalRedeclaration()) { | 3387 // expressions before other declarations. |
3183 Bailout("function with illegal redeclaration"); | 3388 if (scope->is_function_scope() && scope->function() != NULL) { |
3184 return NULL; | 3389 VisitVariableDeclaration(scope->function()); |
3185 } | 3390 } |
3186 if (scope->calls_eval()) { | 3391 VisitDeclarations(scope->declarations()); |
3187 Bailout("function calls eval"); | 3392 AddSimulate(BailoutId::Declarations()); |
3188 return NULL; | |
3189 } | |
3190 SetUpScope(scope); | |
3191 | 3393 |
3192 // Add an edge to the body entry. This is warty: the graph's start | 3394 HValue* context = environment()->LookupContext(); |
3193 // environment will be used by the Lithium translation as the initial | 3395 AddInstruction( |
3194 // environment on graph entry, but it has now been mutated by the | 3396 new(zone()) HStackCheck(context, HStackCheck::kFunctionEntry)); |
3195 // Hydrogen translation of the instructions in the start block. This | |
3196 // environment uses values which have not been defined yet. These | |
3197 // Hydrogen instructions will then be replayed by the Lithium | |
3198 // translation, so they cannot have an environment effect. The edge to | |
3199 // the body's entry block (along with some special logic for the start | |
3200 // block in HInstruction::InsertAfter) seals the start block from | |
3201 // getting unwanted instructions inserted. | |
3202 // | |
3203 // TODO(kmillikin): Fix this. Stop mutating the initial environment. | |
3204 // Make the Hydrogen instructions in the initial block into Hydrogen | |
3205 // values (but not instructions), present in the initial environment and | |
3206 // not replayed by the Lithium translation. | |
3207 HEnvironment* initial_env = environment()->CopyWithoutHistory(); | |
3208 HBasicBlock* body_entry = CreateBasicBlock(initial_env); | |
3209 current_block()->Goto(body_entry); | |
3210 body_entry->SetJoinId(BailoutId::FunctionEntry()); | |
3211 set_current_block(body_entry); | |
3212 | 3397 |
3213 // Handle implicit declaration of the function name in named function | 3398 VisitStatements(info()->function()->body()); |
3214 // expressions before other declarations. | 3399 if (HasStackOverflow()) return false; |
3215 if (scope->is_function_scope() && scope->function() != NULL) { | |
3216 VisitVariableDeclaration(scope->function()); | |
3217 } | |
3218 VisitDeclarations(scope->declarations()); | |
3219 AddSimulate(BailoutId::Declarations()); | |
3220 | 3400 |
3221 HValue* context = environment()->LookupContext(); | 3401 if (current_block() != NULL) { |
3222 AddInstruction( | 3402 HReturn* instr = new(zone()) HReturn(graph()->GetConstantUndefined()); |
3223 new(zone()) HStackCheck(context, HStackCheck::kFunctionEntry)); | 3403 current_block()->FinishExit(instr); |
3224 | 3404 set_current_block(NULL); |
3225 VisitStatements(info()->function()->body()); | |
3226 if (HasStackOverflow()) return NULL; | |
3227 | |
3228 if (current_block() != NULL) { | |
3229 HReturn* instr = new(zone()) HReturn(graph()->GetConstantUndefined()); | |
3230 current_block()->FinishExit(instr); | |
3231 set_current_block(NULL); | |
3232 } | |
3233 | |
3234 // If the checksum of the number of type info changes is the same as the | |
3235 // last time this function was compiled, then this recompile is likely not | |
3236 // due to missing/inadequate type feedback, but rather too aggressive | |
3237 // optimization. Disable optimistic LICM in that case. | |
3238 Handle<Code> unoptimized_code(info()->shared_info()->code()); | |
3239 ASSERT(unoptimized_code->kind() == Code::FUNCTION); | |
3240 Handle<TypeFeedbackInfo> type_info( | |
3241 TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info())); | |
3242 int checksum = type_info->own_type_change_checksum(); | |
3243 int composite_checksum = graph()->update_type_change_checksum(checksum); | |
3244 graph()->set_use_optimistic_licm( | |
3245 !type_info->matches_inlined_type_change_checksum(composite_checksum)); | |
3246 type_info->set_inlined_type_change_checksum(composite_checksum); | |
3247 } | 3405 } |
3248 | 3406 |
3249 return graph(); | 3407 // If the checksum of the number of type info changes is the same as the |
| 3408 // last time this function was compiled, then this recompile is likely not |
| 3409 // due to missing/inadequate type feedback, but rather too aggressive |
| 3410 // optimization. Disable optimistic LICM in that case. |
| 3411 Handle<Code> unoptimized_code(info()->shared_info()->code()); |
| 3412 ASSERT(unoptimized_code->kind() == Code::FUNCTION); |
| 3413 Handle<TypeFeedbackInfo> type_info( |
| 3414 TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info())); |
| 3415 int checksum = type_info->own_type_change_checksum(); |
| 3416 int composite_checksum = graph()->update_type_change_checksum(checksum); |
| 3417 graph()->set_use_optimistic_licm( |
| 3418 !type_info->matches_inlined_type_change_checksum(composite_checksum)); |
| 3419 type_info->set_inlined_type_change_checksum(composite_checksum); |
| 3420 |
| 3421 return true; |
3250 } | 3422 } |
3251 | 3423 |
| 3424 |
3252 bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) { | 3425 bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) { |
3253 *bailout_reason = SmartArrayPointer<char>(); | 3426 *bailout_reason = SmartArrayPointer<char>(); |
3254 OrderBlocks(); | 3427 OrderBlocks(); |
3255 AssignDominators(); | 3428 AssignDominators(); |
3256 | 3429 |
3257 #ifdef DEBUG | 3430 #ifdef DEBUG |
3258 // Do a full verify after building the graph and computing dominators. | 3431 // Do a full verify after building the graph and computing dominators. |
3259 Verify(true); | 3432 Verify(true); |
3260 #endif | 3433 #endif |
3261 | 3434 |
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3765 } | 3938 } |
3766 instr->DeleteAndReplaceWith(NULL); | 3939 instr->DeleteAndReplaceWith(NULL); |
3767 for (int i = 0; i < instr->OperandCount(); ++i) { | 3940 for (int i = 0; i < instr->OperandCount(); ++i) { |
3768 HValue* operand = instr->OperandAt(i); | 3941 HValue* operand = instr->OperandAt(i); |
3769 if (operand->IsDead()) worklist.Add(HInstruction::cast(operand), zone()); | 3942 if (operand->IsDead()) worklist.Add(HInstruction::cast(operand), zone()); |
3770 } | 3943 } |
3771 } | 3944 } |
3772 } | 3945 } |
3773 | 3946 |
3774 | 3947 |
3775 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { | 3948 void HOptimizedGraphBuilder::AddPhi(HPhi* instr) { |
3776 ASSERT(current_block() != NULL); | |
3777 current_block()->AddInstruction(instr); | |
3778 return instr; | |
3779 } | |
3780 | |
3781 | |
3782 void HGraphBuilder::AddSimulate(BailoutId ast_id, RemovableSimulate removable) { | |
3783 ASSERT(current_block() != NULL); | |
3784 current_block()->AddSimulate(ast_id, removable); | |
3785 } | |
3786 | |
3787 | |
3788 void HGraphBuilder::AddPhi(HPhi* instr) { | |
3789 ASSERT(current_block() != NULL); | 3949 ASSERT(current_block() != NULL); |
3790 current_block()->AddPhi(instr); | 3950 current_block()->AddPhi(instr); |
3791 } | 3951 } |
3792 | 3952 |
3793 | 3953 |
3794 void HGraphBuilder::PushAndAdd(HInstruction* instr) { | 3954 void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) { |
3795 Push(instr); | 3955 Push(instr); |
3796 AddInstruction(instr); | 3956 AddInstruction(instr); |
3797 } | 3957 } |
3798 | 3958 |
3799 | 3959 |
3800 template <class Instruction> | 3960 template <class Instruction> |
3801 HInstruction* HGraphBuilder::PreProcessCall(Instruction* call) { | 3961 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { |
3802 int count = call->argument_count(); | 3962 int count = call->argument_count(); |
3803 ZoneList<HValue*> arguments(count, zone()); | 3963 ZoneList<HValue*> arguments(count, zone()); |
3804 for (int i = 0; i < count; ++i) { | 3964 for (int i = 0; i < count; ++i) { |
3805 arguments.Add(Pop(), zone()); | 3965 arguments.Add(Pop(), zone()); |
3806 } | 3966 } |
3807 | 3967 |
3808 while (!arguments.is_empty()) { | 3968 while (!arguments.is_empty()) { |
3809 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); | 3969 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); |
3810 } | 3970 } |
3811 return call; | 3971 return call; |
3812 } | 3972 } |
3813 | 3973 |
3814 | 3974 |
3815 void HGraphBuilder::SetUpScope(Scope* scope) { | 3975 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) { |
3816 HConstant* undefined_constant = new(zone()) HConstant( | 3976 HConstant* undefined_constant = new(zone()) HConstant( |
3817 isolate()->factory()->undefined_value(), Representation::Tagged()); | 3977 isolate()->factory()->undefined_value(), Representation::Tagged()); |
3818 AddInstruction(undefined_constant); | 3978 AddInstruction(undefined_constant); |
3819 graph_->set_undefined_constant(undefined_constant); | 3979 graph()->set_undefined_constant(undefined_constant); |
3820 | 3980 |
3821 HArgumentsObject* object = new(zone()) HArgumentsObject; | 3981 HArgumentsObject* object = new(zone()) HArgumentsObject; |
3822 AddInstruction(object); | 3982 AddInstruction(object); |
3823 graph()->SetArgumentsObject(object); | 3983 graph()->SetArgumentsObject(object); |
3824 | 3984 |
3825 // Set the initial values of parameters including "this". "This" has | 3985 // Set the initial values of parameters including "this". "This" has |
3826 // parameter index 0. | 3986 // parameter index 0. |
3827 ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count()); | 3987 ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count()); |
3828 | 3988 |
3829 for (int i = 0; i < environment()->parameter_count(); ++i) { | 3989 for (int i = 0; i < environment()->parameter_count(); ++i) { |
(...skipping 18 matching lines...) Expand all Loading... |
3848 if (!scope->arguments()->IsStackAllocated()) { | 4008 if (!scope->arguments()->IsStackAllocated()) { |
3849 return Bailout("context-allocated arguments"); | 4009 return Bailout("context-allocated arguments"); |
3850 } | 4010 } |
3851 | 4011 |
3852 environment()->Bind(scope->arguments(), | 4012 environment()->Bind(scope->arguments(), |
3853 graph()->GetArgumentsObject()); | 4013 graph()->GetArgumentsObject()); |
3854 } | 4014 } |
3855 } | 4015 } |
3856 | 4016 |
3857 | 4017 |
3858 void HGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) { | 4018 void HOptimizedGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) { |
3859 for (int i = 0; i < statements->length(); i++) { | 4019 for (int i = 0; i < statements->length(); i++) { |
3860 CHECK_ALIVE(Visit(statements->at(i))); | 4020 CHECK_ALIVE(Visit(statements->at(i))); |
3861 } | 4021 } |
3862 } | 4022 } |
3863 | 4023 |
3864 | 4024 |
3865 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { | 4025 HBasicBlock* HOptimizedGraphBuilder::CreateBasicBlock(HEnvironment* env) { |
3866 HBasicBlock* b = graph()->CreateBasicBlock(); | 4026 HBasicBlock* b = graph()->CreateBasicBlock(); |
3867 b->SetInitialEnvironment(env); | 4027 b->SetInitialEnvironment(env); |
3868 return b; | 4028 return b; |
3869 } | 4029 } |
3870 | 4030 |
3871 | 4031 |
3872 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { | 4032 HBasicBlock* HOptimizedGraphBuilder::CreateLoopHeaderBlock() { |
3873 HBasicBlock* header = graph()->CreateBasicBlock(); | 4033 HBasicBlock* header = graph()->CreateBasicBlock(); |
3874 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); | 4034 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); |
3875 header->SetInitialEnvironment(entry_env); | 4035 header->SetInitialEnvironment(entry_env); |
3876 header->AttachLoopInformation(); | 4036 header->AttachLoopInformation(); |
3877 return header; | 4037 return header; |
3878 } | 4038 } |
3879 | 4039 |
3880 | 4040 |
3881 void HGraphBuilder::VisitBlock(Block* stmt) { | 4041 void HOptimizedGraphBuilder::VisitBlock(Block* stmt) { |
3882 ASSERT(!HasStackOverflow()); | 4042 ASSERT(!HasStackOverflow()); |
3883 ASSERT(current_block() != NULL); | 4043 ASSERT(current_block() != NULL); |
3884 ASSERT(current_block()->HasPredecessor()); | 4044 ASSERT(current_block()->HasPredecessor()); |
3885 if (stmt->scope() != NULL) { | 4045 if (stmt->scope() != NULL) { |
3886 return Bailout("ScopedBlock"); | 4046 return Bailout("ScopedBlock"); |
3887 } | 4047 } |
3888 BreakAndContinueInfo break_info(stmt); | 4048 BreakAndContinueInfo break_info(stmt); |
3889 { BreakAndContinueScope push(&break_info, this); | 4049 { BreakAndContinueScope push(&break_info, this); |
3890 CHECK_BAILOUT(VisitStatements(stmt->statements())); | 4050 CHECK_BAILOUT(VisitStatements(stmt->statements())); |
3891 } | 4051 } |
3892 HBasicBlock* break_block = break_info.break_block(); | 4052 HBasicBlock* break_block = break_info.break_block(); |
3893 if (break_block != NULL) { | 4053 if (break_block != NULL) { |
3894 if (current_block() != NULL) current_block()->Goto(break_block); | 4054 if (current_block() != NULL) current_block()->Goto(break_block); |
3895 break_block->SetJoinId(stmt->ExitId()); | 4055 break_block->SetJoinId(stmt->ExitId()); |
3896 set_current_block(break_block); | 4056 set_current_block(break_block); |
3897 } | 4057 } |
3898 } | 4058 } |
3899 | 4059 |
3900 | 4060 |
3901 void HGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) { | 4061 void HOptimizedGraphBuilder::VisitExpressionStatement( |
| 4062 ExpressionStatement* stmt) { |
3902 ASSERT(!HasStackOverflow()); | 4063 ASSERT(!HasStackOverflow()); |
3903 ASSERT(current_block() != NULL); | 4064 ASSERT(current_block() != NULL); |
3904 ASSERT(current_block()->HasPredecessor()); | 4065 ASSERT(current_block()->HasPredecessor()); |
3905 VisitForEffect(stmt->expression()); | 4066 VisitForEffect(stmt->expression()); |
3906 } | 4067 } |
3907 | 4068 |
3908 | 4069 |
3909 void HGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) { | 4070 void HOptimizedGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) { |
3910 ASSERT(!HasStackOverflow()); | 4071 ASSERT(!HasStackOverflow()); |
3911 ASSERT(current_block() != NULL); | 4072 ASSERT(current_block() != NULL); |
3912 ASSERT(current_block()->HasPredecessor()); | 4073 ASSERT(current_block()->HasPredecessor()); |
3913 } | 4074 } |
3914 | 4075 |
3915 | 4076 |
3916 void HGraphBuilder::VisitIfStatement(IfStatement* stmt) { | 4077 void HOptimizedGraphBuilder::VisitIfStatement(IfStatement* stmt) { |
3917 ASSERT(!HasStackOverflow()); | 4078 ASSERT(!HasStackOverflow()); |
3918 ASSERT(current_block() != NULL); | 4079 ASSERT(current_block() != NULL); |
3919 ASSERT(current_block()->HasPredecessor()); | 4080 ASSERT(current_block()->HasPredecessor()); |
3920 if (stmt->condition()->ToBooleanIsTrue()) { | 4081 if (stmt->condition()->ToBooleanIsTrue()) { |
3921 AddSimulate(stmt->ThenId()); | 4082 AddSimulate(stmt->ThenId()); |
3922 Visit(stmt->then_statement()); | 4083 Visit(stmt->then_statement()); |
3923 } else if (stmt->condition()->ToBooleanIsFalse()) { | 4084 } else if (stmt->condition()->ToBooleanIsFalse()) { |
3924 AddSimulate(stmt->ElseId()); | 4085 AddSimulate(stmt->ElseId()); |
3925 Visit(stmt->else_statement()); | 4086 Visit(stmt->else_statement()); |
3926 } else { | 4087 } else { |
(...skipping 18 matching lines...) Expand all Loading... |
3945 } else { | 4106 } else { |
3946 cond_false = NULL; | 4107 cond_false = NULL; |
3947 } | 4108 } |
3948 | 4109 |
3949 HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->IfId()); | 4110 HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->IfId()); |
3950 set_current_block(join); | 4111 set_current_block(join); |
3951 } | 4112 } |
3952 } | 4113 } |
3953 | 4114 |
3954 | 4115 |
3955 HBasicBlock* HGraphBuilder::BreakAndContinueScope::Get( | 4116 HBasicBlock* HOptimizedGraphBuilder::BreakAndContinueScope::Get( |
3956 BreakableStatement* stmt, | 4117 BreakableStatement* stmt, |
3957 BreakType type, | 4118 BreakType type, |
3958 int* drop_extra) { | 4119 int* drop_extra) { |
3959 *drop_extra = 0; | 4120 *drop_extra = 0; |
3960 BreakAndContinueScope* current = this; | 4121 BreakAndContinueScope* current = this; |
3961 while (current != NULL && current->info()->target() != stmt) { | 4122 while (current != NULL && current->info()->target() != stmt) { |
3962 *drop_extra += current->info()->drop_extra(); | 4123 *drop_extra += current->info()->drop_extra(); |
3963 current = current->next(); | 4124 current = current->next(); |
3964 } | 4125 } |
3965 ASSERT(current != NULL); // Always found (unless stack is malformed). | 4126 ASSERT(current != NULL); // Always found (unless stack is malformed). |
(...skipping 18 matching lines...) Expand all Loading... |
3984 block = current->owner()->graph()->CreateBasicBlock(); | 4145 block = current->owner()->graph()->CreateBasicBlock(); |
3985 current->info()->set_continue_block(block); | 4146 current->info()->set_continue_block(block); |
3986 } | 4147 } |
3987 break; | 4148 break; |
3988 } | 4149 } |
3989 | 4150 |
3990 return block; | 4151 return block; |
3991 } | 4152 } |
3992 | 4153 |
3993 | 4154 |
3994 void HGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) { | 4155 void HOptimizedGraphBuilder::VisitContinueStatement( |
| 4156 ContinueStatement* stmt) { |
3995 ASSERT(!HasStackOverflow()); | 4157 ASSERT(!HasStackOverflow()); |
3996 ASSERT(current_block() != NULL); | 4158 ASSERT(current_block() != NULL); |
3997 ASSERT(current_block()->HasPredecessor()); | 4159 ASSERT(current_block()->HasPredecessor()); |
3998 int drop_extra = 0; | 4160 int drop_extra = 0; |
3999 HBasicBlock* continue_block = break_scope()->Get(stmt->target(), | 4161 HBasicBlock* continue_block = break_scope()->Get(stmt->target(), |
4000 CONTINUE, | 4162 CONTINUE, |
4001 &drop_extra); | 4163 &drop_extra); |
4002 Drop(drop_extra); | 4164 Drop(drop_extra); |
4003 current_block()->Goto(continue_block); | 4165 current_block()->Goto(continue_block); |
4004 set_current_block(NULL); | 4166 set_current_block(NULL); |
4005 } | 4167 } |
4006 | 4168 |
4007 | 4169 |
4008 void HGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { | 4170 void HOptimizedGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { |
4009 ASSERT(!HasStackOverflow()); | 4171 ASSERT(!HasStackOverflow()); |
4010 ASSERT(current_block() != NULL); | 4172 ASSERT(current_block() != NULL); |
4011 ASSERT(current_block()->HasPredecessor()); | 4173 ASSERT(current_block()->HasPredecessor()); |
4012 int drop_extra = 0; | 4174 int drop_extra = 0; |
4013 HBasicBlock* break_block = break_scope()->Get(stmt->target(), | 4175 HBasicBlock* break_block = break_scope()->Get(stmt->target(), |
4014 BREAK, | 4176 BREAK, |
4015 &drop_extra); | 4177 &drop_extra); |
4016 Drop(drop_extra); | 4178 Drop(drop_extra); |
4017 current_block()->Goto(break_block); | 4179 current_block()->Goto(break_block); |
4018 set_current_block(NULL); | 4180 set_current_block(NULL); |
4019 } | 4181 } |
4020 | 4182 |
4021 | 4183 |
4022 void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { | 4184 void HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { |
4023 ASSERT(!HasStackOverflow()); | 4185 ASSERT(!HasStackOverflow()); |
4024 ASSERT(current_block() != NULL); | 4186 ASSERT(current_block() != NULL); |
4025 ASSERT(current_block()->HasPredecessor()); | 4187 ASSERT(current_block()->HasPredecessor()); |
4026 FunctionState* state = function_state(); | 4188 FunctionState* state = function_state(); |
4027 AstContext* context = call_context(); | 4189 AstContext* context = call_context(); |
4028 if (context == NULL) { | 4190 if (context == NULL) { |
4029 // Not an inlined return, so an actual one. | 4191 // Not an inlined return, so an actual one. |
4030 CHECK_ALIVE(VisitForValue(stmt->expression())); | 4192 CHECK_ALIVE(VisitForValue(stmt->expression())); |
4031 HValue* result = environment()->Pop(); | 4193 HValue* result = environment()->Pop(); |
4032 current_block()->FinishExit(new(zone()) HReturn(result)); | 4194 current_block()->FinishExit(new(zone()) HReturn(result)); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4084 } else { | 4246 } else { |
4085 ASSERT(context->IsValue()); | 4247 ASSERT(context->IsValue()); |
4086 CHECK_ALIVE(VisitForValue(stmt->expression())); | 4248 CHECK_ALIVE(VisitForValue(stmt->expression())); |
4087 current_block()->AddLeaveInlined(Pop(), state); | 4249 current_block()->AddLeaveInlined(Pop(), state); |
4088 } | 4250 } |
4089 } | 4251 } |
4090 set_current_block(NULL); | 4252 set_current_block(NULL); |
4091 } | 4253 } |
4092 | 4254 |
4093 | 4255 |
4094 void HGraphBuilder::VisitWithStatement(WithStatement* stmt) { | 4256 void HOptimizedGraphBuilder::VisitWithStatement(WithStatement* stmt) { |
4095 ASSERT(!HasStackOverflow()); | 4257 ASSERT(!HasStackOverflow()); |
4096 ASSERT(current_block() != NULL); | 4258 ASSERT(current_block() != NULL); |
4097 ASSERT(current_block()->HasPredecessor()); | 4259 ASSERT(current_block()->HasPredecessor()); |
4098 return Bailout("WithStatement"); | 4260 return Bailout("WithStatement"); |
4099 } | 4261 } |
4100 | 4262 |
4101 | 4263 |
4102 void HGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { | 4264 void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { |
4103 ASSERT(!HasStackOverflow()); | 4265 ASSERT(!HasStackOverflow()); |
4104 ASSERT(current_block() != NULL); | 4266 ASSERT(current_block() != NULL); |
4105 ASSERT(current_block()->HasPredecessor()); | 4267 ASSERT(current_block()->HasPredecessor()); |
4106 // We only optimize switch statements with smi-literal smi comparisons, | 4268 // We only optimize switch statements with smi-literal smi comparisons, |
4107 // with a bounded number of clauses. | 4269 // with a bounded number of clauses. |
4108 const int kCaseClauseLimit = 128; | 4270 const int kCaseClauseLimit = 128; |
4109 ZoneList<CaseClause*>* clauses = stmt->cases(); | 4271 ZoneList<CaseClause*>* clauses = stmt->cases(); |
4110 int clause_count = clauses->length(); | 4272 int clause_count = clauses->length(); |
4111 if (clause_count > kCaseClauseLimit) { | 4273 if (clause_count > kCaseClauseLimit) { |
4112 return Bailout("SwitchStatement: too many clauses"); | 4274 return Bailout("SwitchStatement: too many clauses"); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4278 stmt->ExitId())); | 4440 stmt->ExitId())); |
4279 } else { | 4441 } else { |
4280 if (fall_through_block != NULL) fall_through_block->Goto(break_block); | 4442 if (fall_through_block != NULL) fall_through_block->Goto(break_block); |
4281 if (last_block != NULL) last_block->Goto(break_block); | 4443 if (last_block != NULL) last_block->Goto(break_block); |
4282 break_block->SetJoinId(stmt->ExitId()); | 4444 break_block->SetJoinId(stmt->ExitId()); |
4283 set_current_block(break_block); | 4445 set_current_block(break_block); |
4284 } | 4446 } |
4285 } | 4447 } |
4286 | 4448 |
4287 | 4449 |
4288 bool HGraphBuilder::HasOsrEntryAt(IterationStatement* statement) { | 4450 bool HOptimizedGraphBuilder::HasOsrEntryAt(IterationStatement* statement) { |
4289 return statement->OsrEntryId() == info()->osr_ast_id(); | 4451 return statement->OsrEntryId() == info()->osr_ast_id(); |
4290 } | 4452 } |
4291 | 4453 |
4292 | 4454 |
4293 bool HGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) { | 4455 bool HOptimizedGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) { |
4294 if (!HasOsrEntryAt(statement)) return false; | 4456 if (!HasOsrEntryAt(statement)) return false; |
4295 | 4457 |
4296 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock(); | 4458 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock(); |
4297 HBasicBlock* osr_entry = graph()->CreateBasicBlock(); | 4459 HBasicBlock* osr_entry = graph()->CreateBasicBlock(); |
4298 HValue* true_value = graph()->GetConstantTrue(); | 4460 HValue* true_value = graph()->GetConstantTrue(); |
4299 HBranch* test = new(zone()) HBranch(true_value, non_osr_entry, osr_entry); | 4461 HBranch* test = new(zone()) HBranch(true_value, non_osr_entry, osr_entry); |
4300 current_block()->Finish(test); | 4462 current_block()->Finish(test); |
4301 | 4463 |
4302 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); | 4464 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); |
4303 non_osr_entry->Goto(loop_predecessor); | 4465 non_osr_entry->Goto(loop_predecessor); |
(...skipping 29 matching lines...) Expand all Loading... |
4333 HContext* context = new(zone()) HContext; | 4495 HContext* context = new(zone()) HContext; |
4334 AddInstruction(context); | 4496 AddInstruction(context); |
4335 environment()->BindContext(context); | 4497 environment()->BindContext(context); |
4336 current_block()->Goto(loop_predecessor); | 4498 current_block()->Goto(loop_predecessor); |
4337 loop_predecessor->SetJoinId(statement->EntryId()); | 4499 loop_predecessor->SetJoinId(statement->EntryId()); |
4338 set_current_block(loop_predecessor); | 4500 set_current_block(loop_predecessor); |
4339 return true; | 4501 return true; |
4340 } | 4502 } |
4341 | 4503 |
4342 | 4504 |
4343 void HGraphBuilder::VisitLoopBody(IterationStatement* stmt, | 4505 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, |
4344 HBasicBlock* loop_entry, | 4506 HBasicBlock* loop_entry, |
4345 BreakAndContinueInfo* break_info) { | 4507 BreakAndContinueInfo* break_info) { |
4346 BreakAndContinueScope push(break_info, this); | 4508 BreakAndContinueScope push(break_info, this); |
4347 AddSimulate(stmt->StackCheckId()); | 4509 AddSimulate(stmt->StackCheckId()); |
4348 HValue* context = environment()->LookupContext(); | 4510 HValue* context = environment()->LookupContext(); |
4349 HStackCheck* stack_check = | 4511 HStackCheck* stack_check = |
4350 new(zone()) HStackCheck(context, HStackCheck::kBackwardsBranch); | 4512 new(zone()) HStackCheck(context, HStackCheck::kBackwardsBranch); |
4351 AddInstruction(stack_check); | 4513 AddInstruction(stack_check); |
4352 ASSERT(loop_entry->IsLoopHeader()); | 4514 ASSERT(loop_entry->IsLoopHeader()); |
4353 loop_entry->loop_information()->set_stack_check(stack_check); | 4515 loop_entry->loop_information()->set_stack_check(stack_check); |
4354 CHECK_BAILOUT(Visit(stmt->body())); | 4516 CHECK_BAILOUT(Visit(stmt->body())); |
4355 } | 4517 } |
4356 | 4518 |
4357 | 4519 |
4358 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { | 4520 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { |
4359 ASSERT(!HasStackOverflow()); | 4521 ASSERT(!HasStackOverflow()); |
4360 ASSERT(current_block() != NULL); | 4522 ASSERT(current_block() != NULL); |
4361 ASSERT(current_block()->HasPredecessor()); | 4523 ASSERT(current_block()->HasPredecessor()); |
4362 ASSERT(current_block() != NULL); | 4524 ASSERT(current_block() != NULL); |
4363 bool osr_entry = PreProcessOsrEntry(stmt); | 4525 bool osr_entry = PreProcessOsrEntry(stmt); |
4364 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); | 4526 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
4365 current_block()->Goto(loop_entry); | 4527 current_block()->Goto(loop_entry); |
4366 set_current_block(loop_entry); | 4528 set_current_block(loop_entry); |
4367 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); | 4529 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
4368 | 4530 |
(...skipping 22 matching lines...) Expand all Loading... |
4391 } | 4553 } |
4392 HBasicBlock* loop_exit = CreateLoop(stmt, | 4554 HBasicBlock* loop_exit = CreateLoop(stmt, |
4393 loop_entry, | 4555 loop_entry, |
4394 body_exit, | 4556 body_exit, |
4395 loop_successor, | 4557 loop_successor, |
4396 break_info.break_block()); | 4558 break_info.break_block()); |
4397 set_current_block(loop_exit); | 4559 set_current_block(loop_exit); |
4398 } | 4560 } |
4399 | 4561 |
4400 | 4562 |
4401 void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { | 4563 void HOptimizedGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { |
4402 ASSERT(!HasStackOverflow()); | 4564 ASSERT(!HasStackOverflow()); |
4403 ASSERT(current_block() != NULL); | 4565 ASSERT(current_block() != NULL); |
4404 ASSERT(current_block()->HasPredecessor()); | 4566 ASSERT(current_block()->HasPredecessor()); |
4405 ASSERT(current_block() != NULL); | 4567 ASSERT(current_block() != NULL); |
4406 bool osr_entry = PreProcessOsrEntry(stmt); | 4568 bool osr_entry = PreProcessOsrEntry(stmt); |
4407 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); | 4569 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
4408 current_block()->Goto(loop_entry); | 4570 current_block()->Goto(loop_entry); |
4409 set_current_block(loop_entry); | 4571 set_current_block(loop_entry); |
4410 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); | 4572 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
4411 | 4573 |
(...skipping 23 matching lines...) Expand all Loading... |
4435 JoinContinue(stmt, current_block(), break_info.continue_block()); | 4597 JoinContinue(stmt, current_block(), break_info.continue_block()); |
4436 HBasicBlock* loop_exit = CreateLoop(stmt, | 4598 HBasicBlock* loop_exit = CreateLoop(stmt, |
4437 loop_entry, | 4599 loop_entry, |
4438 body_exit, | 4600 body_exit, |
4439 loop_successor, | 4601 loop_successor, |
4440 break_info.break_block()); | 4602 break_info.break_block()); |
4441 set_current_block(loop_exit); | 4603 set_current_block(loop_exit); |
4442 } | 4604 } |
4443 | 4605 |
4444 | 4606 |
4445 void HGraphBuilder::VisitForStatement(ForStatement* stmt) { | 4607 void HOptimizedGraphBuilder::VisitForStatement(ForStatement* stmt) { |
4446 ASSERT(!HasStackOverflow()); | 4608 ASSERT(!HasStackOverflow()); |
4447 ASSERT(current_block() != NULL); | 4609 ASSERT(current_block() != NULL); |
4448 ASSERT(current_block()->HasPredecessor()); | 4610 ASSERT(current_block()->HasPredecessor()); |
4449 if (stmt->init() != NULL) { | 4611 if (stmt->init() != NULL) { |
4450 CHECK_ALIVE(Visit(stmt->init())); | 4612 CHECK_ALIVE(Visit(stmt->init())); |
4451 } | 4613 } |
4452 ASSERT(current_block() != NULL); | 4614 ASSERT(current_block() != NULL); |
4453 bool osr_entry = PreProcessOsrEntry(stmt); | 4615 bool osr_entry = PreProcessOsrEntry(stmt); |
4454 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); | 4616 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
4455 current_block()->Goto(loop_entry); | 4617 current_block()->Goto(loop_entry); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4487 | 4649 |
4488 HBasicBlock* loop_exit = CreateLoop(stmt, | 4650 HBasicBlock* loop_exit = CreateLoop(stmt, |
4489 loop_entry, | 4651 loop_entry, |
4490 body_exit, | 4652 body_exit, |
4491 loop_successor, | 4653 loop_successor, |
4492 break_info.break_block()); | 4654 break_info.break_block()); |
4493 set_current_block(loop_exit); | 4655 set_current_block(loop_exit); |
4494 } | 4656 } |
4495 | 4657 |
4496 | 4658 |
4497 void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) { | 4659 void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) { |
4498 ASSERT(!HasStackOverflow()); | 4660 ASSERT(!HasStackOverflow()); |
4499 ASSERT(current_block() != NULL); | 4661 ASSERT(current_block() != NULL); |
4500 ASSERT(current_block()->HasPredecessor()); | 4662 ASSERT(current_block()->HasPredecessor()); |
4501 | 4663 |
4502 if (!FLAG_optimize_for_in) { | 4664 if (!FLAG_optimize_for_in) { |
4503 return Bailout("ForInStatement optimization is disabled"); | 4665 return Bailout("ForInStatement optimization is disabled"); |
4504 } | 4666 } |
4505 | 4667 |
4506 if (!oracle()->IsForInFastCase(stmt)) { | 4668 if (!oracle()->IsForInFastCase(stmt)) { |
4507 return Bailout("ForInStatement is not fast case"); | 4669 return Bailout("ForInStatement is not fast case"); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4608 HBasicBlock* loop_exit = CreateLoop(stmt, | 4770 HBasicBlock* loop_exit = CreateLoop(stmt, |
4609 loop_entry, | 4771 loop_entry, |
4610 body_exit, | 4772 body_exit, |
4611 loop_successor, | 4773 loop_successor, |
4612 break_info.break_block()); | 4774 break_info.break_block()); |
4613 | 4775 |
4614 set_current_block(loop_exit); | 4776 set_current_block(loop_exit); |
4615 } | 4777 } |
4616 | 4778 |
4617 | 4779 |
4618 void HGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { | 4780 void HOptimizedGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { |
4619 ASSERT(!HasStackOverflow()); | 4781 ASSERT(!HasStackOverflow()); |
4620 ASSERT(current_block() != NULL); | 4782 ASSERT(current_block() != NULL); |
4621 ASSERT(current_block()->HasPredecessor()); | 4783 ASSERT(current_block()->HasPredecessor()); |
4622 return Bailout("TryCatchStatement"); | 4784 return Bailout("TryCatchStatement"); |
4623 } | 4785 } |
4624 | 4786 |
4625 | 4787 |
4626 void HGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) { | 4788 void HOptimizedGraphBuilder::VisitTryFinallyStatement( |
| 4789 TryFinallyStatement* stmt) { |
4627 ASSERT(!HasStackOverflow()); | 4790 ASSERT(!HasStackOverflow()); |
4628 ASSERT(current_block() != NULL); | 4791 ASSERT(current_block() != NULL); |
4629 ASSERT(current_block()->HasPredecessor()); | 4792 ASSERT(current_block()->HasPredecessor()); |
4630 return Bailout("TryFinallyStatement"); | 4793 return Bailout("TryFinallyStatement"); |
4631 } | 4794 } |
4632 | 4795 |
4633 | 4796 |
4634 void HGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { | 4797 void HOptimizedGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { |
4635 ASSERT(!HasStackOverflow()); | 4798 ASSERT(!HasStackOverflow()); |
4636 ASSERT(current_block() != NULL); | 4799 ASSERT(current_block() != NULL); |
4637 ASSERT(current_block()->HasPredecessor()); | 4800 ASSERT(current_block()->HasPredecessor()); |
4638 return Bailout("DebuggerStatement"); | 4801 return Bailout("DebuggerStatement"); |
4639 } | 4802 } |
4640 | 4803 |
4641 | 4804 |
4642 static Handle<SharedFunctionInfo> SearchSharedFunctionInfo( | 4805 static Handle<SharedFunctionInfo> SearchSharedFunctionInfo( |
4643 Code* unoptimized_code, FunctionLiteral* expr) { | 4806 Code* unoptimized_code, FunctionLiteral* expr) { |
4644 int start_position = expr->start_position(); | 4807 int start_position = expr->start_position(); |
4645 RelocIterator it(unoptimized_code); | 4808 RelocIterator it(unoptimized_code); |
4646 for (;!it.done(); it.next()) { | 4809 for (;!it.done(); it.next()) { |
4647 RelocInfo* rinfo = it.rinfo(); | 4810 RelocInfo* rinfo = it.rinfo(); |
4648 if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue; | 4811 if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue; |
4649 Object* obj = rinfo->target_object(); | 4812 Object* obj = rinfo->target_object(); |
4650 if (obj->IsSharedFunctionInfo()) { | 4813 if (obj->IsSharedFunctionInfo()) { |
4651 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); | 4814 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); |
4652 if (shared->start_position() == start_position) { | 4815 if (shared->start_position() == start_position) { |
4653 return Handle<SharedFunctionInfo>(shared); | 4816 return Handle<SharedFunctionInfo>(shared); |
4654 } | 4817 } |
4655 } | 4818 } |
4656 } | 4819 } |
4657 | 4820 |
4658 return Handle<SharedFunctionInfo>(); | 4821 return Handle<SharedFunctionInfo>(); |
4659 } | 4822 } |
4660 | 4823 |
4661 | 4824 |
4662 void HGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { | 4825 void HOptimizedGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { |
4663 ASSERT(!HasStackOverflow()); | 4826 ASSERT(!HasStackOverflow()); |
4664 ASSERT(current_block() != NULL); | 4827 ASSERT(current_block() != NULL); |
4665 ASSERT(current_block()->HasPredecessor()); | 4828 ASSERT(current_block()->HasPredecessor()); |
4666 Handle<SharedFunctionInfo> shared_info = | 4829 Handle<SharedFunctionInfo> shared_info = |
4667 SearchSharedFunctionInfo(info()->shared_info()->code(), | 4830 SearchSharedFunctionInfo(info()->shared_info()->code(), |
4668 expr); | 4831 expr); |
4669 if (shared_info.is_null()) { | 4832 if (shared_info.is_null()) { |
4670 shared_info = Compiler::BuildFunctionInfo(expr, info()->script()); | 4833 shared_info = Compiler::BuildFunctionInfo(expr, info()->script()); |
4671 } | 4834 } |
4672 // We also have a stack overflow if the recursive compilation did. | 4835 // We also have a stack overflow if the recursive compilation did. |
4673 if (HasStackOverflow()) return; | 4836 if (HasStackOverflow()) return; |
4674 HValue* context = environment()->LookupContext(); | 4837 HValue* context = environment()->LookupContext(); |
4675 HFunctionLiteral* instr = | 4838 HFunctionLiteral* instr = |
4676 new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure()); | 4839 new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure()); |
4677 return ast_context()->ReturnInstruction(instr, expr->id()); | 4840 return ast_context()->ReturnInstruction(instr, expr->id()); |
4678 } | 4841 } |
4679 | 4842 |
4680 | 4843 |
4681 void HGraphBuilder::VisitSharedFunctionInfoLiteral( | 4844 void HOptimizedGraphBuilder::VisitSharedFunctionInfoLiteral( |
4682 SharedFunctionInfoLiteral* expr) { | 4845 SharedFunctionInfoLiteral* expr) { |
4683 ASSERT(!HasStackOverflow()); | 4846 ASSERT(!HasStackOverflow()); |
4684 ASSERT(current_block() != NULL); | 4847 ASSERT(current_block() != NULL); |
4685 ASSERT(current_block()->HasPredecessor()); | 4848 ASSERT(current_block()->HasPredecessor()); |
4686 return Bailout("SharedFunctionInfoLiteral"); | 4849 return Bailout("SharedFunctionInfoLiteral"); |
4687 } | 4850 } |
4688 | 4851 |
4689 | 4852 |
4690 void HGraphBuilder::VisitConditional(Conditional* expr) { | 4853 void HOptimizedGraphBuilder::VisitConditional(Conditional* expr) { |
4691 ASSERT(!HasStackOverflow()); | 4854 ASSERT(!HasStackOverflow()); |
4692 ASSERT(current_block() != NULL); | 4855 ASSERT(current_block() != NULL); |
4693 ASSERT(current_block()->HasPredecessor()); | 4856 ASSERT(current_block()->HasPredecessor()); |
4694 HBasicBlock* cond_true = graph()->CreateBasicBlock(); | 4857 HBasicBlock* cond_true = graph()->CreateBasicBlock(); |
4695 HBasicBlock* cond_false = graph()->CreateBasicBlock(); | 4858 HBasicBlock* cond_false = graph()->CreateBasicBlock(); |
4696 CHECK_BAILOUT(VisitForControl(expr->condition(), cond_true, cond_false)); | 4859 CHECK_BAILOUT(VisitForControl(expr->condition(), cond_true, cond_false)); |
4697 | 4860 |
4698 // Visit the true and false subexpressions in the same AST context as the | 4861 // Visit the true and false subexpressions in the same AST context as the |
4699 // whole expression. | 4862 // whole expression. |
4700 if (cond_true->HasPredecessor()) { | 4863 if (cond_true->HasPredecessor()) { |
(...skipping 17 matching lines...) Expand all Loading... |
4718 if (!ast_context()->IsTest()) { | 4881 if (!ast_context()->IsTest()) { |
4719 HBasicBlock* join = CreateJoin(cond_true, cond_false, expr->id()); | 4882 HBasicBlock* join = CreateJoin(cond_true, cond_false, expr->id()); |
4720 set_current_block(join); | 4883 set_current_block(join); |
4721 if (join != NULL && !ast_context()->IsEffect()) { | 4884 if (join != NULL && !ast_context()->IsEffect()) { |
4722 return ast_context()->ReturnValue(Pop()); | 4885 return ast_context()->ReturnValue(Pop()); |
4723 } | 4886 } |
4724 } | 4887 } |
4725 } | 4888 } |
4726 | 4889 |
4727 | 4890 |
4728 HGraphBuilder::GlobalPropertyAccess HGraphBuilder::LookupGlobalProperty( | 4891 HOptimizedGraphBuilder::GlobalPropertyAccess |
4729 Variable* var, LookupResult* lookup, bool is_store) { | 4892 HOptimizedGraphBuilder::LookupGlobalProperty( |
| 4893 Variable* var, LookupResult* lookup, bool is_store) { |
4730 if (var->is_this() || !info()->has_global_object()) { | 4894 if (var->is_this() || !info()->has_global_object()) { |
4731 return kUseGeneric; | 4895 return kUseGeneric; |
4732 } | 4896 } |
4733 Handle<GlobalObject> global(info()->global_object()); | 4897 Handle<GlobalObject> global(info()->global_object()); |
4734 global->Lookup(*var->name(), lookup); | 4898 global->Lookup(*var->name(), lookup); |
4735 if (!lookup->IsNormal() || | 4899 if (!lookup->IsNormal() || |
4736 (is_store && lookup->IsReadOnly()) || | 4900 (is_store && lookup->IsReadOnly()) || |
4737 lookup->holder() != *global) { | 4901 lookup->holder() != *global) { |
4738 return kUseGeneric; | 4902 return kUseGeneric; |
4739 } | 4903 } |
4740 | 4904 |
4741 return kUseCell; | 4905 return kUseCell; |
4742 } | 4906 } |
4743 | 4907 |
4744 | 4908 |
4745 HValue* HGraphBuilder::BuildContextChainWalk(Variable* var) { | 4909 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { |
4746 ASSERT(var->IsContextSlot()); | 4910 ASSERT(var->IsContextSlot()); |
4747 HValue* context = environment()->LookupContext(); | 4911 HValue* context = environment()->LookupContext(); |
4748 int length = info()->scope()->ContextChainLength(var->scope()); | 4912 int length = info()->scope()->ContextChainLength(var->scope()); |
4749 while (length-- > 0) { | 4913 while (length-- > 0) { |
4750 HInstruction* context_instruction = new(zone()) HOuterContext(context); | 4914 HInstruction* context_instruction = new(zone()) HOuterContext(context); |
4751 AddInstruction(context_instruction); | 4915 AddInstruction(context_instruction); |
4752 context = context_instruction; | 4916 context = context_instruction; |
4753 } | 4917 } |
4754 return context; | 4918 return context; |
4755 } | 4919 } |
4756 | 4920 |
4757 | 4921 |
4758 void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) { | 4922 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
4759 ASSERT(!HasStackOverflow()); | 4923 ASSERT(!HasStackOverflow()); |
4760 ASSERT(current_block() != NULL); | 4924 ASSERT(current_block() != NULL); |
4761 ASSERT(current_block()->HasPredecessor()); | 4925 ASSERT(current_block()->HasPredecessor()); |
4762 Variable* variable = expr->var(); | 4926 Variable* variable = expr->var(); |
4763 switch (variable->location()) { | 4927 switch (variable->location()) { |
4764 case Variable::UNALLOCATED: { | 4928 case Variable::UNALLOCATED: { |
4765 if (IsLexicalVariableMode(variable->mode())) { | 4929 if (IsLexicalVariableMode(variable->mode())) { |
4766 // TODO(rossberg): should this be an ASSERT? | 4930 // TODO(rossberg): should this be an ASSERT? |
4767 return Bailout("reference to global lexical variable"); | 4931 return Bailout("reference to global lexical variable"); |
4768 } | 4932 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4821 HLoadContextSlot* instr = new(zone()) HLoadContextSlot(context, variable); | 4985 HLoadContextSlot* instr = new(zone()) HLoadContextSlot(context, variable); |
4822 return ast_context()->ReturnInstruction(instr, expr->id()); | 4986 return ast_context()->ReturnInstruction(instr, expr->id()); |
4823 } | 4987 } |
4824 | 4988 |
4825 case Variable::LOOKUP: | 4989 case Variable::LOOKUP: |
4826 return Bailout("reference to a variable which requires dynamic lookup"); | 4990 return Bailout("reference to a variable which requires dynamic lookup"); |
4827 } | 4991 } |
4828 } | 4992 } |
4829 | 4993 |
4830 | 4994 |
4831 void HGraphBuilder::VisitLiteral(Literal* expr) { | 4995 void HOptimizedGraphBuilder::VisitLiteral(Literal* expr) { |
4832 ASSERT(!HasStackOverflow()); | 4996 ASSERT(!HasStackOverflow()); |
4833 ASSERT(current_block() != NULL); | 4997 ASSERT(current_block() != NULL); |
4834 ASSERT(current_block()->HasPredecessor()); | 4998 ASSERT(current_block()->HasPredecessor()); |
4835 HConstant* instr = | 4999 HConstant* instr = |
4836 new(zone()) HConstant(expr->handle(), Representation::None()); | 5000 new(zone()) HConstant(expr->handle(), Representation::None()); |
4837 return ast_context()->ReturnInstruction(instr, expr->id()); | 5001 return ast_context()->ReturnInstruction(instr, expr->id()); |
4838 } | 5002 } |
4839 | 5003 |
4840 | 5004 |
4841 void HGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { | 5005 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { |
4842 ASSERT(!HasStackOverflow()); | 5006 ASSERT(!HasStackOverflow()); |
4843 ASSERT(current_block() != NULL); | 5007 ASSERT(current_block() != NULL); |
4844 ASSERT(current_block()->HasPredecessor()); | 5008 ASSERT(current_block()->HasPredecessor()); |
4845 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); | 5009 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); |
4846 Handle<FixedArray> literals(closure->literals()); | 5010 Handle<FixedArray> literals(closure->literals()); |
4847 HValue* context = environment()->LookupContext(); | 5011 HValue* context = environment()->LookupContext(); |
4848 | 5012 |
4849 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context, | 5013 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context, |
4850 literals, | 5014 literals, |
4851 expr->pattern(), | 5015 expr->pattern(), |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4990 } | 5154 } |
4991 } | 5155 } |
4992 } | 5156 } |
4993 } | 5157 } |
4994 | 5158 |
4995 *total_size += boilerplate->map()->instance_size(); | 5159 *total_size += boilerplate->map()->instance_size(); |
4996 return true; | 5160 return true; |
4997 } | 5161 } |
4998 | 5162 |
4999 | 5163 |
5000 void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { | 5164 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
5001 ASSERT(!HasStackOverflow()); | 5165 ASSERT(!HasStackOverflow()); |
5002 ASSERT(current_block() != NULL); | 5166 ASSERT(current_block() != NULL); |
5003 ASSERT(current_block()->HasPredecessor()); | 5167 ASSERT(current_block()->HasPredecessor()); |
5004 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); | 5168 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); |
5005 HValue* context = environment()->LookupContext(); | 5169 HValue* context = environment()->LookupContext(); |
5006 HInstruction* literal; | 5170 HInstruction* literal; |
5007 | 5171 |
5008 // Check whether to use fast or slow deep-copying for boilerplate. | 5172 // Check whether to use fast or slow deep-copying for boilerplate. |
5009 int total_size = 0; | 5173 int total_size = 0; |
5010 int max_properties = HFastLiteral::kMaxLiteralProperties; | 5174 int max_properties = HFastLiteral::kMaxLiteralProperties; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5095 // (e.g. because of code motion). | 5259 // (e.g. because of code motion). |
5096 HToFastProperties* result = new(zone()) HToFastProperties(Pop()); | 5260 HToFastProperties* result = new(zone()) HToFastProperties(Pop()); |
5097 AddInstruction(result); | 5261 AddInstruction(result); |
5098 return ast_context()->ReturnValue(result); | 5262 return ast_context()->ReturnValue(result); |
5099 } else { | 5263 } else { |
5100 return ast_context()->ReturnValue(Pop()); | 5264 return ast_context()->ReturnValue(Pop()); |
5101 } | 5265 } |
5102 } | 5266 } |
5103 | 5267 |
5104 | 5268 |
5105 void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { | 5269 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
5106 ASSERT(!HasStackOverflow()); | 5270 ASSERT(!HasStackOverflow()); |
5107 ASSERT(current_block() != NULL); | 5271 ASSERT(current_block() != NULL); |
5108 ASSERT(current_block()->HasPredecessor()); | 5272 ASSERT(current_block()->HasPredecessor()); |
5109 ZoneList<Expression*>* subexprs = expr->values(); | 5273 ZoneList<Expression*>* subexprs = expr->values(); |
5110 int length = subexprs->length(); | 5274 int length = subexprs->length(); |
5111 HValue* context = environment()->LookupContext(); | 5275 HValue* context = environment()->LookupContext(); |
5112 HInstruction* literal; | 5276 HInstruction* literal; |
5113 | 5277 |
5114 Handle<FixedArray> literals(environment()->closure()->literals()); | 5278 Handle<FixedArray> literals(environment()->closure()->literals()); |
5115 Handle<Object> raw_boilerplate(literals->get(expr->literal_index())); | 5279 Handle<Object> raw_boilerplate(literals->get(expr->literal_index())); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5229 ASSERT(lookup->IsField() || lookup->IsTransitionToField(*type)); | 5393 ASSERT(lookup->IsField() || lookup->IsTransitionToField(*type)); |
5230 if (lookup->IsField()) { | 5394 if (lookup->IsField()) { |
5231 return lookup->GetLocalFieldIndexFromMap(*type); | 5395 return lookup->GetLocalFieldIndexFromMap(*type); |
5232 } else { | 5396 } else { |
5233 Map* transition = lookup->GetTransitionMapFromMap(*type); | 5397 Map* transition = lookup->GetTransitionMapFromMap(*type); |
5234 return transition->PropertyIndexFor(*name) - type->inobject_properties(); | 5398 return transition->PropertyIndexFor(*name) - type->inobject_properties(); |
5235 } | 5399 } |
5236 } | 5400 } |
5237 | 5401 |
5238 | 5402 |
5239 void HGraphBuilder::AddCheckMapsWithTransitions(HValue* object, | 5403 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object, |
5240 Handle<Map> map) { | 5404 Handle<Map> map) { |
5241 AddInstruction(new(zone()) HCheckNonSmi(object)); | 5405 AddInstruction(new(zone()) HCheckNonSmi(object)); |
5242 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); | 5406 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); |
5243 } | 5407 } |
5244 | 5408 |
5245 | 5409 |
5246 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, | 5410 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( |
5247 Handle<String> name, | 5411 HValue* object, |
5248 HValue* value, | 5412 Handle<String> name, |
5249 Handle<Map> map, | 5413 HValue* value, |
5250 LookupResult* lookup) { | 5414 Handle<Map> map, |
| 5415 LookupResult* lookup) { |
5251 ASSERT(lookup->IsFound()); | 5416 ASSERT(lookup->IsFound()); |
5252 // If the property does not exist yet, we have to check that it wasn't made | 5417 // If the property does not exist yet, we have to check that it wasn't made |
5253 // readonly or turned into a setter by some meanwhile modifications on the | 5418 // readonly or turned into a setter by some meanwhile modifications on the |
5254 // prototype chain. | 5419 // prototype chain. |
5255 if (!lookup->IsProperty() && map->prototype()->IsJSReceiver()) { | 5420 if (!lookup->IsProperty() && map->prototype()->IsJSReceiver()) { |
5256 Object* proto = map->prototype(); | 5421 Object* proto = map->prototype(); |
5257 // First check that the prototype chain isn't affected already. | 5422 // First check that the prototype chain isn't affected already. |
5258 LookupResult proto_result(isolate()); | 5423 LookupResult proto_result(isolate()); |
5259 proto->Lookup(*name, &proto_result); | 5424 proto->Lookup(*name, &proto_result); |
5260 if (proto_result.IsProperty()) { | 5425 if (proto_result.IsProperty()) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5292 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); | 5457 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); |
5293 instr->set_transition(transition); | 5458 instr->set_transition(transition); |
5294 // TODO(fschneider): Record the new map type of the object in the IR to | 5459 // TODO(fschneider): Record the new map type of the object in the IR to |
5295 // enable elimination of redundant checks after the transition store. | 5460 // enable elimination of redundant checks after the transition store. |
5296 instr->SetGVNFlag(kChangesMaps); | 5461 instr->SetGVNFlag(kChangesMaps); |
5297 } | 5462 } |
5298 return instr; | 5463 return instr; |
5299 } | 5464 } |
5300 | 5465 |
5301 | 5466 |
5302 HInstruction* HGraphBuilder::BuildStoreNamedGeneric(HValue* object, | 5467 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedGeneric( |
5303 Handle<String> name, | 5468 HValue* object, |
5304 HValue* value) { | 5469 Handle<String> name, |
| 5470 HValue* value) { |
5305 HValue* context = environment()->LookupContext(); | 5471 HValue* context = environment()->LookupContext(); |
5306 return new(zone()) HStoreNamedGeneric( | 5472 return new(zone()) HStoreNamedGeneric( |
5307 context, | 5473 context, |
5308 object, | 5474 object, |
5309 name, | 5475 name, |
5310 value, | 5476 value, |
5311 function_strict_mode_flag()); | 5477 function_strict_mode_flag()); |
5312 } | 5478 } |
5313 | 5479 |
5314 | 5480 |
5315 HInstruction* HGraphBuilder::BuildCallSetter(HValue* object, | 5481 HInstruction* HOptimizedGraphBuilder::BuildCallSetter( |
5316 HValue* value, | 5482 HValue* object, |
5317 Handle<Map> map, | 5483 HValue* value, |
5318 Handle<JSFunction> setter, | 5484 Handle<Map> map, |
5319 Handle<JSObject> holder) { | 5485 Handle<JSFunction> setter, |
| 5486 Handle<JSObject> holder) { |
5320 AddCheckConstantFunction(holder, object, map); | 5487 AddCheckConstantFunction(holder, object, map); |
5321 AddInstruction(new(zone()) HPushArgument(object)); | 5488 AddInstruction(new(zone()) HPushArgument(object)); |
5322 AddInstruction(new(zone()) HPushArgument(value)); | 5489 AddInstruction(new(zone()) HPushArgument(value)); |
5323 return new(zone()) HCallConstantFunction(setter, 2); | 5490 return new(zone()) HCallConstantFunction(setter, 2); |
5324 } | 5491 } |
5325 | 5492 |
5326 | 5493 |
5327 HInstruction* HGraphBuilder::BuildStoreNamedMonomorphic(HValue* object, | 5494 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedMonomorphic( |
5328 Handle<String> name, | 5495 HValue* object, |
5329 HValue* value, | 5496 Handle<String> name, |
5330 Handle<Map> map) { | 5497 HValue* value, |
| 5498 Handle<Map> map) { |
5331 // Handle a store to a known field. | 5499 // Handle a store to a known field. |
5332 LookupResult lookup(isolate()); | 5500 LookupResult lookup(isolate()); |
5333 if (ComputeLoadStoreField(map, name, &lookup, true)) { | 5501 if (ComputeLoadStoreField(map, name, &lookup, true)) { |
5334 AddCheckMapsWithTransitions(object, map); | 5502 AddCheckMapsWithTransitions(object, map); |
5335 return BuildStoreNamedField(object, name, value, map, &lookup); | 5503 return BuildStoreNamedField(object, name, value, map, &lookup); |
5336 } | 5504 } |
5337 | 5505 |
5338 // No luck, do a generic store. | 5506 // No luck, do a generic store. |
5339 return BuildStoreNamedGeneric(object, name, value); | 5507 return BuildStoreNamedGeneric(object, name, value); |
5340 } | 5508 } |
5341 | 5509 |
5342 | 5510 |
5343 void HGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, | 5511 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( |
5344 HValue* object, | 5512 Property* expr, |
5345 SmallMapList* types, | 5513 HValue* object, |
5346 Handle<String> name) { | 5514 SmallMapList* types, |
| 5515 Handle<String> name) { |
5347 int count = 0; | 5516 int count = 0; |
5348 int previous_field_offset = 0; | 5517 int previous_field_offset = 0; |
5349 bool previous_field_is_in_object = false; | 5518 bool previous_field_is_in_object = false; |
5350 bool is_monomorphic_field = true; | 5519 bool is_monomorphic_field = true; |
5351 Handle<Map> map; | 5520 Handle<Map> map; |
5352 LookupResult lookup(isolate()); | 5521 LookupResult lookup(isolate()); |
5353 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { | 5522 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { |
5354 map = types->at(i); | 5523 map = types->at(i); |
5355 if (ComputeLoadStoreField(map, name, &lookup, false)) { | 5524 if (ComputeLoadStoreField(map, name, &lookup, false)) { |
5356 int index = ComputeLoadStoreFieldIndex(map, name, &lookup); | 5525 int index = ComputeLoadStoreFieldIndex(map, name, &lookup); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5388 types, | 5557 types, |
5389 name, | 5558 name, |
5390 zone()); | 5559 zone()); |
5391 } | 5560 } |
5392 | 5561 |
5393 instr->set_position(expr->position()); | 5562 instr->set_position(expr->position()); |
5394 return ast_context()->ReturnInstruction(instr, expr->id()); | 5563 return ast_context()->ReturnInstruction(instr, expr->id()); |
5395 } | 5564 } |
5396 | 5565 |
5397 | 5566 |
5398 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, | 5567 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( |
5399 HValue* object, | 5568 Assignment* expr, |
5400 HValue* value, | 5569 HValue* object, |
5401 SmallMapList* types, | 5570 HValue* value, |
5402 Handle<String> name) { | 5571 SmallMapList* types, |
| 5572 Handle<String> name) { |
5403 // TODO(ager): We should recognize when the prototype chains for different | 5573 // TODO(ager): We should recognize when the prototype chains for different |
5404 // maps are identical. In that case we can avoid repeatedly generating the | 5574 // maps are identical. In that case we can avoid repeatedly generating the |
5405 // same prototype map checks. | 5575 // same prototype map checks. |
5406 int count = 0; | 5576 int count = 0; |
5407 HBasicBlock* join = NULL; | 5577 HBasicBlock* join = NULL; |
5408 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { | 5578 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { |
5409 Handle<Map> map = types->at(i); | 5579 Handle<Map> map = types->at(i); |
5410 LookupResult lookup(isolate()); | 5580 LookupResult lookup(isolate()); |
5411 if (ComputeLoadStoreField(map, name, &lookup, true)) { | 5581 if (ComputeLoadStoreField(map, name, &lookup, true)) { |
5412 if (count == 0) { | 5582 if (count == 0) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5464 } | 5634 } |
5465 } | 5635 } |
5466 | 5636 |
5467 ASSERT(join != NULL); | 5637 ASSERT(join != NULL); |
5468 join->SetJoinId(expr->id()); | 5638 join->SetJoinId(expr->id()); |
5469 set_current_block(join); | 5639 set_current_block(join); |
5470 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); | 5640 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); |
5471 } | 5641 } |
5472 | 5642 |
5473 | 5643 |
5474 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { | 5644 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { |
5475 Property* prop = expr->target()->AsProperty(); | 5645 Property* prop = expr->target()->AsProperty(); |
5476 ASSERT(prop != NULL); | 5646 ASSERT(prop != NULL); |
5477 expr->RecordTypeFeedback(oracle(), zone()); | 5647 expr->RecordTypeFeedback(oracle(), zone()); |
5478 CHECK_ALIVE(VisitForValue(prop->obj())); | 5648 CHECK_ALIVE(VisitForValue(prop->obj())); |
5479 | 5649 |
5480 if (prop->key()->IsPropertyName()) { | 5650 if (prop->key()->IsPropertyName()) { |
5481 // Named store. | 5651 // Named store. |
5482 CHECK_ALIVE(VisitForValue(expr->value())); | 5652 CHECK_ALIVE(VisitForValue(expr->value())); |
5483 HValue* value = environment()->ExpressionStackAt(0); | 5653 HValue* value = environment()->ExpressionStackAt(0); |
5484 HValue* object = environment()->ExpressionStackAt(1); | 5654 HValue* object = environment()->ExpressionStackAt(1); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5547 ASSERT(has_side_effects); // Stores always have side effects. | 5717 ASSERT(has_side_effects); // Stores always have side effects. |
5548 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 5718 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); |
5549 return ast_context()->ReturnValue(Pop()); | 5719 return ast_context()->ReturnValue(Pop()); |
5550 } | 5720 } |
5551 } | 5721 } |
5552 | 5722 |
5553 | 5723 |
5554 // Because not every expression has a position and there is not common | 5724 // Because not every expression has a position and there is not common |
5555 // superclass of Assignment and CountOperation, we cannot just pass the | 5725 // superclass of Assignment and CountOperation, we cannot just pass the |
5556 // owning expression instead of position and ast_id separately. | 5726 // owning expression instead of position and ast_id separately. |
5557 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, | 5727 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( |
5558 HValue* value, | 5728 Variable* var, |
5559 int position, | 5729 HValue* value, |
5560 BailoutId ast_id) { | 5730 int position, |
| 5731 BailoutId ast_id) { |
5561 LookupResult lookup(isolate()); | 5732 LookupResult lookup(isolate()); |
5562 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); | 5733 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); |
5563 if (type == kUseCell) { | 5734 if (type == kUseCell) { |
5564 Handle<GlobalObject> global(info()->global_object()); | 5735 Handle<GlobalObject> global(info()->global_object()); |
5565 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); | 5736 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); |
5566 HInstruction* instr = | 5737 HInstruction* instr = |
5567 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); | 5738 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); |
5568 instr->set_position(position); | 5739 instr->set_position(position); |
5569 AddInstruction(instr); | 5740 AddInstruction(instr); |
5570 if (instr->HasObservableSideEffects()) { | 5741 if (instr->HasObservableSideEffects()) { |
(...skipping 10 matching lines...) Expand all Loading... |
5581 value, | 5752 value, |
5582 function_strict_mode_flag()); | 5753 function_strict_mode_flag()); |
5583 instr->set_position(position); | 5754 instr->set_position(position); |
5584 AddInstruction(instr); | 5755 AddInstruction(instr); |
5585 ASSERT(instr->HasObservableSideEffects()); | 5756 ASSERT(instr->HasObservableSideEffects()); |
5586 AddSimulate(ast_id, REMOVABLE_SIMULATE); | 5757 AddSimulate(ast_id, REMOVABLE_SIMULATE); |
5587 } | 5758 } |
5588 } | 5759 } |
5589 | 5760 |
5590 | 5761 |
5591 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { | 5762 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
5592 Expression* target = expr->target(); | 5763 Expression* target = expr->target(); |
5593 VariableProxy* proxy = target->AsVariableProxy(); | 5764 VariableProxy* proxy = target->AsVariableProxy(); |
5594 Property* prop = target->AsProperty(); | 5765 Property* prop = target->AsProperty(); |
5595 ASSERT(proxy == NULL || prop == NULL); | 5766 ASSERT(proxy == NULL || prop == NULL); |
5596 | 5767 |
5597 // We have a second position recorded in the FullCodeGenerator to have | 5768 // We have a second position recorded in the FullCodeGenerator to have |
5598 // type feedback for the binary operation. | 5769 // type feedback for the binary operation. |
5599 BinaryOperation* operation = expr->binary_operation(); | 5770 BinaryOperation* operation = expr->binary_operation(); |
5600 | 5771 |
5601 if (proxy != NULL) { | 5772 if (proxy != NULL) { |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5778 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 5949 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); |
5779 return ast_context()->ReturnValue(Pop()); | 5950 return ast_context()->ReturnValue(Pop()); |
5780 } | 5951 } |
5781 | 5952 |
5782 } else { | 5953 } else { |
5783 return Bailout("invalid lhs in compound assignment"); | 5954 return Bailout("invalid lhs in compound assignment"); |
5784 } | 5955 } |
5785 } | 5956 } |
5786 | 5957 |
5787 | 5958 |
5788 void HGraphBuilder::VisitAssignment(Assignment* expr) { | 5959 void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { |
5789 ASSERT(!HasStackOverflow()); | 5960 ASSERT(!HasStackOverflow()); |
5790 ASSERT(current_block() != NULL); | 5961 ASSERT(current_block() != NULL); |
5791 ASSERT(current_block()->HasPredecessor()); | 5962 ASSERT(current_block()->HasPredecessor()); |
5792 VariableProxy* proxy = expr->target()->AsVariableProxy(); | 5963 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
5793 Property* prop = expr->target()->AsProperty(); | 5964 Property* prop = expr->target()->AsProperty(); |
5794 ASSERT(proxy == NULL || prop == NULL); | 5965 ASSERT(proxy == NULL || prop == NULL); |
5795 | 5966 |
5796 if (expr->is_compound()) { | 5967 if (expr->is_compound()) { |
5797 HandleCompoundAssignment(expr); | 5968 HandleCompoundAssignment(expr); |
5798 return; | 5969 return; |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5905 | 6076 |
5906 case Variable::LOOKUP: | 6077 case Variable::LOOKUP: |
5907 return Bailout("assignment to LOOKUP variable"); | 6078 return Bailout("assignment to LOOKUP variable"); |
5908 } | 6079 } |
5909 } else { | 6080 } else { |
5910 return Bailout("invalid left-hand side in assignment"); | 6081 return Bailout("invalid left-hand side in assignment"); |
5911 } | 6082 } |
5912 } | 6083 } |
5913 | 6084 |
5914 | 6085 |
5915 void HGraphBuilder::VisitThrow(Throw* expr) { | 6086 void HOptimizedGraphBuilder::VisitThrow(Throw* expr) { |
5916 ASSERT(!HasStackOverflow()); | 6087 ASSERT(!HasStackOverflow()); |
5917 ASSERT(current_block() != NULL); | 6088 ASSERT(current_block() != NULL); |
5918 ASSERT(current_block()->HasPredecessor()); | 6089 ASSERT(current_block()->HasPredecessor()); |
5919 // We don't optimize functions with invalid left-hand sides in | 6090 // We don't optimize functions with invalid left-hand sides in |
5920 // assignments, count operations, or for-in. Consequently throw can | 6091 // assignments, count operations, or for-in. Consequently throw can |
5921 // currently only occur in an effect context. | 6092 // currently only occur in an effect context. |
5922 ASSERT(ast_context()->IsEffect()); | 6093 ASSERT(ast_context()->IsEffect()); |
5923 CHECK_ALIVE(VisitForValue(expr->exception())); | 6094 CHECK_ALIVE(VisitForValue(expr->exception())); |
5924 | 6095 |
5925 HValue* context = environment()->LookupContext(); | 6096 HValue* context = environment()->LookupContext(); |
5926 HValue* value = environment()->Pop(); | 6097 HValue* value = environment()->Pop(); |
5927 HThrow* instr = new(zone()) HThrow(context, value); | 6098 HThrow* instr = new(zone()) HThrow(context, value); |
5928 instr->set_position(expr->position()); | 6099 instr->set_position(expr->position()); |
5929 AddInstruction(instr); | 6100 AddInstruction(instr); |
5930 AddSimulate(expr->id()); | 6101 AddSimulate(expr->id()); |
5931 current_block()->FinishExit(new(zone()) HAbnormalExit); | 6102 current_block()->FinishExit(new(zone()) HAbnormalExit); |
5932 set_current_block(NULL); | 6103 set_current_block(NULL); |
5933 } | 6104 } |
5934 | 6105 |
5935 | 6106 |
5936 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, | 6107 HLoadNamedField* HOptimizedGraphBuilder::BuildLoadNamedField( |
5937 Handle<Map> map, | 6108 HValue* object, |
5938 LookupResult* lookup) { | 6109 Handle<Map> map, |
| 6110 LookupResult* lookup) { |
5939 int index = lookup->GetLocalFieldIndexFromMap(*map); | 6111 int index = lookup->GetLocalFieldIndexFromMap(*map); |
5940 if (index < 0) { | 6112 if (index < 0) { |
5941 // Negative property indices are in-object properties, indexed | 6113 // Negative property indices are in-object properties, indexed |
5942 // from the end of the fixed part of the object. | 6114 // from the end of the fixed part of the object. |
5943 int offset = (index * kPointerSize) + map->instance_size(); | 6115 int offset = (index * kPointerSize) + map->instance_size(); |
5944 return new(zone()) HLoadNamedField(object, true, offset); | 6116 return new(zone()) HLoadNamedField(object, true, offset); |
5945 } else { | 6117 } else { |
5946 // Non-negative property indices are in the properties array. | 6118 // Non-negative property indices are in the properties array. |
5947 int offset = (index * kPointerSize) + FixedArray::kHeaderSize; | 6119 int offset = (index * kPointerSize) + FixedArray::kHeaderSize; |
5948 return new(zone()) HLoadNamedField(object, false, offset); | 6120 return new(zone()) HLoadNamedField(object, false, offset); |
5949 } | 6121 } |
5950 } | 6122 } |
5951 | 6123 |
5952 | 6124 |
5953 HInstruction* HGraphBuilder::BuildLoadNamedGeneric(HValue* object, | 6125 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( |
5954 Handle<String> name, | 6126 HValue* object, |
5955 Property* expr) { | 6127 Handle<String> name, |
| 6128 Property* expr) { |
5956 if (expr->IsUninitialized() && !FLAG_always_opt) { | 6129 if (expr->IsUninitialized() && !FLAG_always_opt) { |
5957 AddInstruction(new(zone()) HSoftDeoptimize); | 6130 AddInstruction(new(zone()) HSoftDeoptimize); |
5958 current_block()->MarkAsDeoptimizing(); | 6131 current_block()->MarkAsDeoptimizing(); |
5959 } | 6132 } |
5960 HValue* context = environment()->LookupContext(); | 6133 HValue* context = environment()->LookupContext(); |
5961 return new(zone()) HLoadNamedGeneric(context, object, name); | 6134 return new(zone()) HLoadNamedGeneric(context, object, name); |
5962 } | 6135 } |
5963 | 6136 |
5964 | 6137 |
5965 HInstruction* HGraphBuilder::BuildCallGetter(HValue* object, | 6138 HInstruction* HOptimizedGraphBuilder::BuildCallGetter( |
5966 Handle<Map> map, | 6139 HValue* object, |
5967 Handle<JSFunction> getter, | 6140 Handle<Map> map, |
5968 Handle<JSObject> holder) { | 6141 Handle<JSFunction> getter, |
| 6142 Handle<JSObject> holder) { |
5969 AddCheckConstantFunction(holder, object, map); | 6143 AddCheckConstantFunction(holder, object, map); |
5970 AddInstruction(new(zone()) HPushArgument(object)); | 6144 AddInstruction(new(zone()) HPushArgument(object)); |
5971 return new(zone()) HCallConstantFunction(getter, 1); | 6145 return new(zone()) HCallConstantFunction(getter, 1); |
5972 } | 6146 } |
5973 | 6147 |
5974 | 6148 |
5975 HInstruction* HGraphBuilder::BuildLoadNamedMonomorphic(HValue* object, | 6149 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic( |
5976 Handle<String> name, | 6150 HValue* object, |
5977 Property* expr, | 6151 Handle<String> name, |
5978 Handle<Map> map) { | 6152 Property* expr, |
| 6153 Handle<Map> map) { |
5979 // Handle a load from a known field. | 6154 // Handle a load from a known field. |
5980 ASSERT(!map->is_dictionary_map()); | 6155 ASSERT(!map->is_dictionary_map()); |
5981 LookupResult lookup(isolate()); | 6156 LookupResult lookup(isolate()); |
5982 map->LookupDescriptor(NULL, *name, &lookup); | 6157 map->LookupDescriptor(NULL, *name, &lookup); |
5983 if (lookup.IsField()) { | 6158 if (lookup.IsField()) { |
5984 AddCheckMapsWithTransitions(object, map); | 6159 AddCheckMapsWithTransitions(object, map); |
5985 return BuildLoadNamedField(object, map, &lookup); | 6160 return BuildLoadNamedField(object, map, &lookup); |
5986 } | 6161 } |
5987 | 6162 |
5988 // Handle a load of a constant known function. | 6163 // Handle a load of a constant known function. |
(...skipping 13 matching lines...) Expand all Loading... |
6002 HInstruction* holder_value = | 6177 HInstruction* holder_value = |
6003 AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder)); | 6178 AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder)); |
6004 return BuildLoadNamedField(holder_value, holder_map, &lookup); | 6179 return BuildLoadNamedField(holder_value, holder_map, &lookup); |
6005 } | 6180 } |
6006 | 6181 |
6007 // No luck, do a generic load. | 6182 // No luck, do a generic load. |
6008 return BuildLoadNamedGeneric(object, name, expr); | 6183 return BuildLoadNamedGeneric(object, name, expr); |
6009 } | 6184 } |
6010 | 6185 |
6011 | 6186 |
6012 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, | 6187 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, |
6013 HValue* key) { | 6188 HValue* key) { |
6014 HValue* context = environment()->LookupContext(); | 6189 HValue* context = environment()->LookupContext(); |
6015 return new(zone()) HLoadKeyedGeneric(context, object, key); | 6190 return new(zone()) HLoadKeyedGeneric(context, object, key); |
6016 } | 6191 } |
6017 | 6192 |
6018 | 6193 |
6019 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( | 6194 HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess( |
6020 HValue* external_elements, | 6195 HValue* object, |
6021 HValue* checked_key, | 6196 HValue* key, |
6022 HValue* val, | 6197 HValue* val, |
6023 HValue* dependency, | 6198 HValue* dependency, |
6024 ElementsKind elements_kind, | 6199 Handle<Map> map, |
6025 bool is_store) { | 6200 bool is_store) { |
6026 if (is_store) { | |
6027 ASSERT(val != NULL); | |
6028 switch (elements_kind) { | |
6029 case EXTERNAL_PIXEL_ELEMENTS: { | |
6030 val = AddInstruction(new(zone()) HClampToUint8(val)); | |
6031 break; | |
6032 } | |
6033 case EXTERNAL_BYTE_ELEMENTS: | |
6034 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | |
6035 case EXTERNAL_SHORT_ELEMENTS: | |
6036 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | |
6037 case EXTERNAL_INT_ELEMENTS: | |
6038 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { | |
6039 break; | |
6040 } | |
6041 case EXTERNAL_FLOAT_ELEMENTS: | |
6042 case EXTERNAL_DOUBLE_ELEMENTS: | |
6043 break; | |
6044 case FAST_SMI_ELEMENTS: | |
6045 case FAST_ELEMENTS: | |
6046 case FAST_DOUBLE_ELEMENTS: | |
6047 case FAST_HOLEY_SMI_ELEMENTS: | |
6048 case FAST_HOLEY_ELEMENTS: | |
6049 case FAST_HOLEY_DOUBLE_ELEMENTS: | |
6050 case DICTIONARY_ELEMENTS: | |
6051 case NON_STRICT_ARGUMENTS_ELEMENTS: | |
6052 UNREACHABLE(); | |
6053 break; | |
6054 } | |
6055 return new(zone()) HStoreKeyed(external_elements, | |
6056 checked_key, | |
6057 val, | |
6058 elements_kind); | |
6059 } else { | |
6060 ASSERT(val == NULL); | |
6061 HLoadKeyed* load = | |
6062 new(zone()) HLoadKeyed( | |
6063 external_elements, checked_key, dependency, elements_kind); | |
6064 if (FLAG_opt_safe_uint32_operations && | |
6065 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { | |
6066 graph()->RecordUint32Instruction(load); | |
6067 } | |
6068 return load; | |
6069 } | |
6070 } | |
6071 | |
6072 | |
6073 HInstruction* HGraphBuilder::BuildFastElementAccess(HValue* elements, | |
6074 HValue* checked_key, | |
6075 HValue* val, | |
6076 HValue* load_dependency, | |
6077 ElementsKind elements_kind, | |
6078 bool is_store) { | |
6079 if (is_store) { | |
6080 ASSERT(val != NULL); | |
6081 switch (elements_kind) { | |
6082 case FAST_SMI_ELEMENTS: | |
6083 case FAST_HOLEY_SMI_ELEMENTS: | |
6084 // Smi-only arrays need a smi check. | |
6085 AddInstruction(new(zone()) HCheckSmi(val)); | |
6086 // Fall through. | |
6087 case FAST_ELEMENTS: | |
6088 case FAST_HOLEY_ELEMENTS: | |
6089 case FAST_DOUBLE_ELEMENTS: | |
6090 case FAST_HOLEY_DOUBLE_ELEMENTS: | |
6091 return new(zone()) HStoreKeyed( | |
6092 elements, checked_key, val, elements_kind); | |
6093 default: | |
6094 UNREACHABLE(); | |
6095 return NULL; | |
6096 } | |
6097 } | |
6098 // It's an element load (!is_store). | |
6099 return new(zone()) HLoadKeyed(elements, | |
6100 checked_key, | |
6101 load_dependency, | |
6102 elements_kind); | |
6103 } | |
6104 | |
6105 | |
6106 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, | |
6107 HValue* key, | |
6108 HValue* val, | |
6109 HValue* dependency, | |
6110 Handle<Map> map, | |
6111 bool is_store) { | |
6112 HCheckMaps* mapcheck = new(zone()) HCheckMaps(object, map, | 6201 HCheckMaps* mapcheck = new(zone()) HCheckMaps(object, map, |
6113 zone(), dependency); | 6202 zone(), dependency); |
6114 AddInstruction(mapcheck); | 6203 AddInstruction(mapcheck); |
6115 if (dependency) { | 6204 if (dependency) { |
6116 mapcheck->ClearGVNFlag(kDependsOnElementsKind); | 6205 mapcheck->ClearGVNFlag(kDependsOnElementsKind); |
6117 } | 6206 } |
6118 return BuildUncheckedMonomorphicElementAccess(object, key, val, | 6207 return BuildUncheckedMonomorphicElementAccess( |
6119 mapcheck, map, is_store); | 6208 object, key, val, |
| 6209 mapcheck, map->instance_type() == JS_ARRAY_TYPE, |
| 6210 map->elements_kind(), is_store); |
6120 } | 6211 } |
6121 | 6212 |
6122 | 6213 |
6123 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( | 6214 HInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad( |
6124 HValue* object, | 6215 HValue* object, |
6125 HValue* key, | 6216 HValue* key, |
6126 HValue* val, | 6217 HValue* val, |
6127 HCheckMaps* mapcheck, | |
6128 Handle<Map> map, | |
6129 bool is_store) { | |
6130 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency | |
6131 // on a HElementsTransition instruction. The flag can also be removed if the | |
6132 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further | |
6133 // ElementsKind transitions. Finally, the dependency can be removed for stores | |
6134 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the | |
6135 // generated store code. | |
6136 if ((map->elements_kind() == FAST_HOLEY_ELEMENTS) || | |
6137 (map->elements_kind() == FAST_ELEMENTS && is_store)) { | |
6138 mapcheck->ClearGVNFlag(kDependsOnElementsKind); | |
6139 } | |
6140 bool fast_smi_only_elements = map->has_fast_smi_elements(); | |
6141 bool fast_elements = map->has_fast_object_elements(); | |
6142 HInstruction* elements = | |
6143 AddInstruction(new(zone()) HLoadElements(object, mapcheck)); | |
6144 if (is_store && (fast_elements || fast_smi_only_elements)) { | |
6145 HCheckMaps* check_cow_map = new(zone()) HCheckMaps( | |
6146 elements, isolate()->factory()->fixed_array_map(), zone()); | |
6147 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | |
6148 AddInstruction(check_cow_map); | |
6149 } | |
6150 HInstruction* length = NULL; | |
6151 HInstruction* checked_key = NULL; | |
6152 if (map->has_external_array_elements()) { | |
6153 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | |
6154 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length, | |
6155 ALLOW_SMI_KEY)); | |
6156 HLoadExternalArrayPointer* external_elements = | |
6157 new(zone()) HLoadExternalArrayPointer(elements); | |
6158 AddInstruction(external_elements); | |
6159 return BuildExternalArrayElementAccess( | |
6160 external_elements, checked_key, val, mapcheck, | |
6161 map->elements_kind(), is_store); | |
6162 } | |
6163 ASSERT(fast_smi_only_elements || | |
6164 fast_elements || | |
6165 map->has_fast_double_elements()); | |
6166 if (map->instance_type() == JS_ARRAY_TYPE) { | |
6167 length = AddInstruction(new(zone()) HJSArrayLength(object, mapcheck, | |
6168 HType::Smi())); | |
6169 } else { | |
6170 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | |
6171 } | |
6172 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length, | |
6173 ALLOW_SMI_KEY)); | |
6174 return BuildFastElementAccess(elements, checked_key, val, mapcheck, | |
6175 map->elements_kind(), is_store); | |
6176 } | |
6177 | |
6178 | |
6179 HInstruction* HGraphBuilder::TryBuildConsolidatedElementLoad( | |
6180 HValue* object, | |
6181 HValue* key, | |
6182 HValue* val, | |
6183 SmallMapList* maps) { | 6218 SmallMapList* maps) { |
6184 // For polymorphic loads of similar elements kinds (i.e. all tagged or all | 6219 // For polymorphic loads of similar elements kinds (i.e. all tagged or all |
6185 // double), always use the "worst case" code without a transition. This is | 6220 // double), always use the "worst case" code without a transition. This is |
6186 // much faster than transitioning the elements to the worst case, trading a | 6221 // much faster than transitioning the elements to the worst case, trading a |
6187 // HTransitionElements for a HCheckMaps, and avoiding mutation of the array. | 6222 // HTransitionElements for a HCheckMaps, and avoiding mutation of the array. |
6188 bool has_double_maps = false; | 6223 bool has_double_maps = false; |
6189 bool has_smi_or_object_maps = false; | 6224 bool has_smi_or_object_maps = false; |
6190 bool has_js_array_access = false; | 6225 bool has_js_array_access = false; |
6191 bool has_non_js_array_access = false; | 6226 bool has_non_js_array_access = false; |
6192 Handle<Map> most_general_consolidated_map; | 6227 Handle<Map> most_general_consolidated_map; |
(...skipping 24 matching lines...) Expand all Loading... |
6217 most_general_consolidated_map->elements_kind(), | 6252 most_general_consolidated_map->elements_kind(), |
6218 map->elements_kind())) { | 6253 map->elements_kind())) { |
6219 most_general_consolidated_map = map; | 6254 most_general_consolidated_map = map; |
6220 } | 6255 } |
6221 } | 6256 } |
6222 if (!has_double_maps && !has_smi_or_object_maps) return NULL; | 6257 if (!has_double_maps && !has_smi_or_object_maps) return NULL; |
6223 | 6258 |
6224 HCheckMaps* check_maps = new(zone()) HCheckMaps(object, maps, zone()); | 6259 HCheckMaps* check_maps = new(zone()) HCheckMaps(object, maps, zone()); |
6225 AddInstruction(check_maps); | 6260 AddInstruction(check_maps); |
6226 HInstruction* instr = BuildUncheckedMonomorphicElementAccess( | 6261 HInstruction* instr = BuildUncheckedMonomorphicElementAccess( |
6227 object, key, val, check_maps, most_general_consolidated_map, false); | 6262 object, key, val, check_maps, |
| 6263 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, |
| 6264 most_general_consolidated_map->elements_kind(), |
| 6265 false); |
6228 return instr; | 6266 return instr; |
6229 } | 6267 } |
6230 | 6268 |
6231 | 6269 |
6232 HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, | 6270 HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( |
6233 HValue* key, | 6271 HValue* object, |
6234 HValue* val, | 6272 HValue* key, |
6235 Expression* prop, | 6273 HValue* val, |
6236 BailoutId ast_id, | 6274 Expression* prop, |
6237 int position, | 6275 BailoutId ast_id, |
6238 bool is_store, | 6276 int position, |
6239 bool* has_side_effects) { | 6277 bool is_store, |
| 6278 bool* has_side_effects) { |
6240 *has_side_effects = false; | 6279 *has_side_effects = false; |
6241 AddInstruction(new(zone()) HCheckNonSmi(object)); | 6280 AddInstruction(new(zone()) HCheckNonSmi(object)); |
6242 SmallMapList* maps = prop->GetReceiverTypes(); | 6281 SmallMapList* maps = prop->GetReceiverTypes(); |
6243 bool todo_external_array = false; | 6282 bool todo_external_array = false; |
6244 | 6283 |
6245 if (!is_store) { | 6284 if (!is_store) { |
6246 HInstruction* consolidated_load = | 6285 HInstruction* consolidated_load = |
6247 TryBuildConsolidatedElementLoad(object, key, val, maps); | 6286 TryBuildConsolidatedElementLoad(object, key, val, maps); |
6248 if (consolidated_load != NULL) { | 6287 if (consolidated_load != NULL) { |
6249 AddInstruction(consolidated_load); | 6288 AddInstruction(consolidated_load); |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6414 elements, checked_key, val, elements_kind_branch, | 6453 elements, checked_key, val, elements_kind_branch, |
6415 elements_kind, is_store)); | 6454 elements_kind, is_store)); |
6416 } else if (elements_kind == DICTIONARY_ELEMENTS) { | 6455 } else if (elements_kind == DICTIONARY_ELEMENTS) { |
6417 if (is_store) { | 6456 if (is_store) { |
6418 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); | 6457 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); |
6419 } else { | 6458 } else { |
6420 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); | 6459 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); |
6421 } | 6460 } |
6422 } else { // External array elements. | 6461 } else { // External array elements. |
6423 access = AddInstruction(BuildExternalArrayElementAccess( | 6462 access = AddInstruction(BuildExternalArrayElementAccess( |
6424 external_elements, checked_key, val, elements_kind_branch, | 6463 external_elements, checked_key, val, |
6425 elements_kind, is_store)); | 6464 elements_kind_branch, elements_kind, is_store)); |
6426 } | 6465 } |
6427 *has_side_effects |= access->HasObservableSideEffects(); | 6466 *has_side_effects |= access->HasObservableSideEffects(); |
6428 if (position != RelocInfo::kNoPosition) access->set_position(position); | 6467 if (position != RelocInfo::kNoPosition) access->set_position(position); |
6429 if (!is_store) { | 6468 if (!is_store) { |
6430 Push(access); | 6469 Push(access); |
6431 } | 6470 } |
6432 current_block()->Goto(join); | 6471 current_block()->Goto(join); |
6433 set_current_block(if_false); | 6472 set_current_block(if_false); |
6434 } | 6473 } |
6435 } | 6474 } |
6436 | 6475 |
6437 // Deopt if none of the cases matched. | 6476 // Deopt if none of the cases matched. |
6438 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); | 6477 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); |
6439 join->SetJoinId(ast_id); | 6478 join->SetJoinId(ast_id); |
6440 set_current_block(join); | 6479 set_current_block(join); |
6441 return is_store ? NULL : Pop(); | 6480 return is_store ? NULL : Pop(); |
6442 } | 6481 } |
6443 | 6482 |
6444 | 6483 |
6445 HValue* HGraphBuilder::HandleKeyedElementAccess(HValue* obj, | 6484 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( |
6446 HValue* key, | 6485 HValue* obj, |
6447 HValue* val, | 6486 HValue* key, |
6448 Expression* expr, | 6487 HValue* val, |
6449 BailoutId ast_id, | 6488 Expression* expr, |
6450 int position, | 6489 BailoutId ast_id, |
6451 bool is_store, | 6490 int position, |
6452 bool* has_side_effects) { | 6491 bool is_store, |
| 6492 bool* has_side_effects) { |
6453 ASSERT(!expr->IsPropertyName()); | 6493 ASSERT(!expr->IsPropertyName()); |
6454 HInstruction* instr = NULL; | 6494 HInstruction* instr = NULL; |
6455 if (expr->IsMonomorphic()) { | 6495 if (expr->IsMonomorphic()) { |
6456 Handle<Map> map = expr->GetMonomorphicReceiverType(); | 6496 Handle<Map> map = expr->GetMonomorphicReceiverType(); |
6457 if (map->has_slow_elements_kind()) { | 6497 if (map->has_slow_elements_kind()) { |
6458 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val) | 6498 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val) |
6459 : BuildLoadKeyedGeneric(obj, key); | 6499 : BuildLoadKeyedGeneric(obj, key); |
6460 } else { | 6500 } else { |
6461 AddInstruction(new(zone()) HCheckNonSmi(obj)); | 6501 AddInstruction(new(zone()) HCheckNonSmi(obj)); |
6462 instr = BuildMonomorphicElementAccess(obj, key, val, NULL, map, is_store); | 6502 instr = BuildMonomorphicElementAccess(obj, key, val, NULL, map, is_store); |
6463 } | 6503 } |
6464 } else if (expr->GetReceiverTypes() != NULL && | 6504 } else if (expr->GetReceiverTypes() != NULL && |
6465 !expr->GetReceiverTypes()->is_empty()) { | 6505 !expr->GetReceiverTypes()->is_empty()) { |
6466 return HandlePolymorphicElementAccess( | 6506 return HandlePolymorphicElementAccess( |
6467 obj, key, val, expr, ast_id, position, is_store, has_side_effects); | 6507 obj, key, val, expr, ast_id, position, is_store, has_side_effects); |
6468 } else { | 6508 } else { |
6469 if (is_store) { | 6509 if (is_store) { |
6470 instr = BuildStoreKeyedGeneric(obj, key, val); | 6510 instr = BuildStoreKeyedGeneric(obj, key, val); |
6471 } else { | 6511 } else { |
6472 instr = BuildLoadKeyedGeneric(obj, key); | 6512 instr = BuildLoadKeyedGeneric(obj, key); |
6473 } | 6513 } |
6474 } | 6514 } |
6475 if (position != RelocInfo::kNoPosition) instr->set_position(position); | 6515 if (position != RelocInfo::kNoPosition) instr->set_position(position); |
6476 AddInstruction(instr); | 6516 AddInstruction(instr); |
6477 *has_side_effects = instr->HasObservableSideEffects(); | 6517 *has_side_effects = instr->HasObservableSideEffects(); |
6478 return instr; | 6518 return instr; |
6479 } | 6519 } |
6480 | 6520 |
6481 | 6521 |
6482 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object, | 6522 HInstruction* HOptimizedGraphBuilder::BuildStoreKeyedGeneric( |
6483 HValue* key, | 6523 HValue* object, |
6484 HValue* value) { | 6524 HValue* key, |
| 6525 HValue* value) { |
6485 HValue* context = environment()->LookupContext(); | 6526 HValue* context = environment()->LookupContext(); |
6486 return new(zone()) HStoreKeyedGeneric( | 6527 return new(zone()) HStoreKeyedGeneric( |
6487 context, | 6528 context, |
6488 object, | 6529 object, |
6489 key, | 6530 key, |
6490 value, | 6531 value, |
6491 function_strict_mode_flag()); | 6532 function_strict_mode_flag()); |
6492 } | 6533 } |
6493 | 6534 |
6494 | 6535 |
6495 void HGraphBuilder::EnsureArgumentsArePushedForAccess() { | 6536 void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() { |
6496 // Outermost function already has arguments on the stack. | 6537 // Outermost function already has arguments on the stack. |
6497 if (function_state()->outer() == NULL) return; | 6538 if (function_state()->outer() == NULL) return; |
6498 | 6539 |
6499 if (function_state()->arguments_pushed()) return; | 6540 if (function_state()->arguments_pushed()) return; |
6500 | 6541 |
6501 // Push arguments when entering inlined function. | 6542 // Push arguments when entering inlined function. |
6502 HEnterInlined* entry = function_state()->entry(); | 6543 HEnterInlined* entry = function_state()->entry(); |
6503 entry->set_arguments_pushed(); | 6544 entry->set_arguments_pushed(); |
6504 | 6545 |
6505 ZoneList<HValue*>* arguments_values = entry->arguments_values(); | 6546 ZoneList<HValue*>* arguments_values = entry->arguments_values(); |
6506 | 6547 |
6507 HInstruction* insert_after = entry; | 6548 HInstruction* insert_after = entry; |
6508 for (int i = 0; i < arguments_values->length(); i++) { | 6549 for (int i = 0; i < arguments_values->length(); i++) { |
6509 HValue* argument = arguments_values->at(i); | 6550 HValue* argument = arguments_values->at(i); |
6510 HInstruction* push_argument = new(zone()) HPushArgument(argument); | 6551 HInstruction* push_argument = new(zone()) HPushArgument(argument); |
6511 push_argument->InsertAfter(insert_after); | 6552 push_argument->InsertAfter(insert_after); |
6512 insert_after = push_argument; | 6553 insert_after = push_argument; |
6513 } | 6554 } |
6514 | 6555 |
6515 HArgumentsElements* arguments_elements = | 6556 HArgumentsElements* arguments_elements = |
6516 new(zone()) HArgumentsElements(true); | 6557 new(zone()) HArgumentsElements(true); |
6517 arguments_elements->ClearFlag(HValue::kUseGVN); | 6558 arguments_elements->ClearFlag(HValue::kUseGVN); |
6518 arguments_elements->InsertAfter(insert_after); | 6559 arguments_elements->InsertAfter(insert_after); |
6519 function_state()->set_arguments_elements(arguments_elements); | 6560 function_state()->set_arguments_elements(arguments_elements); |
6520 } | 6561 } |
6521 | 6562 |
6522 | 6563 |
6523 bool HGraphBuilder::TryArgumentsAccess(Property* expr) { | 6564 bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) { |
6524 VariableProxy* proxy = expr->obj()->AsVariableProxy(); | 6565 VariableProxy* proxy = expr->obj()->AsVariableProxy(); |
6525 if (proxy == NULL) return false; | 6566 if (proxy == NULL) return false; |
6526 if (!proxy->var()->IsStackAllocated()) return false; | 6567 if (!proxy->var()->IsStackAllocated()) return false; |
6527 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) { | 6568 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) { |
6528 return false; | 6569 return false; |
6529 } | 6570 } |
6530 | 6571 |
6531 HInstruction* result = NULL; | 6572 HInstruction* result = NULL; |
6532 if (expr->key()->IsPropertyName()) { | 6573 if (expr->key()->IsPropertyName()) { |
6533 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); | 6574 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6572 HInstruction* checked_key = | 6613 HInstruction* checked_key = |
6573 AddInstruction(new(zone()) HBoundsCheck(key, length)); | 6614 AddInstruction(new(zone()) HBoundsCheck(key, length)); |
6574 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); | 6615 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
6575 } | 6616 } |
6576 } | 6617 } |
6577 ast_context()->ReturnInstruction(result, expr->id()); | 6618 ast_context()->ReturnInstruction(result, expr->id()); |
6578 return true; | 6619 return true; |
6579 } | 6620 } |
6580 | 6621 |
6581 | 6622 |
6582 void HGraphBuilder::VisitProperty(Property* expr) { | 6623 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { |
6583 ASSERT(!HasStackOverflow()); | 6624 ASSERT(!HasStackOverflow()); |
6584 ASSERT(current_block() != NULL); | 6625 ASSERT(current_block() != NULL); |
6585 ASSERT(current_block()->HasPredecessor()); | 6626 ASSERT(current_block()->HasPredecessor()); |
6586 expr->RecordTypeFeedback(oracle(), zone()); | 6627 expr->RecordTypeFeedback(oracle(), zone()); |
6587 | 6628 |
6588 if (TryArgumentsAccess(expr)) return; | 6629 if (TryArgumentsAccess(expr)) return; |
6589 | 6630 |
6590 CHECK_ALIVE(VisitForValue(expr->obj())); | 6631 CHECK_ALIVE(VisitForValue(expr->obj())); |
6591 | 6632 |
6592 HInstruction* instr = NULL; | 6633 HInstruction* instr = NULL; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6663 Drop(1); | 6704 Drop(1); |
6664 } | 6705 } |
6665 } | 6706 } |
6666 return ast_context()->ReturnValue(load); | 6707 return ast_context()->ReturnValue(load); |
6667 } | 6708 } |
6668 instr->set_position(expr->position()); | 6709 instr->set_position(expr->position()); |
6669 return ast_context()->ReturnInstruction(instr, expr->id()); | 6710 return ast_context()->ReturnInstruction(instr, expr->id()); |
6670 } | 6711 } |
6671 | 6712 |
6672 | 6713 |
6673 void HGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, | 6714 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, |
6674 Handle<Map> receiver_map) { | 6715 Handle<Map> receiver_map) { |
6675 if (!holder.is_null()) { | 6716 if (!holder.is_null()) { |
6676 AddInstruction(new(zone()) HCheckPrototypeMaps( | 6717 AddInstruction(new(zone()) HCheckPrototypeMaps( |
6677 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), holder)); | 6718 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), holder)); |
6678 } | 6719 } |
6679 } | 6720 } |
6680 | 6721 |
6681 | 6722 |
6682 void HGraphBuilder::AddCheckConstantFunction(Handle<JSObject> holder, | 6723 void HOptimizedGraphBuilder::AddCheckConstantFunction( |
6683 HValue* receiver, | 6724 Handle<JSObject> holder, |
6684 Handle<Map> receiver_map) { | 6725 HValue* receiver, |
| 6726 Handle<Map> receiver_map) { |
6685 // Constant functions have the nice property that the map will change if they | 6727 // Constant functions have the nice property that the map will change if they |
6686 // are overwritten. Therefore it is enough to check the map of the holder and | 6728 // are overwritten. Therefore it is enough to check the map of the holder and |
6687 // its prototypes. | 6729 // its prototypes. |
6688 AddCheckMapsWithTransitions(receiver, receiver_map); | 6730 AddCheckMapsWithTransitions(receiver, receiver_map); |
6689 AddCheckPrototypeMaps(holder, receiver_map); | 6731 AddCheckPrototypeMaps(holder, receiver_map); |
6690 } | 6732 } |
6691 | 6733 |
6692 | 6734 |
6693 class FunctionSorter { | 6735 class FunctionSorter { |
6694 public: | 6736 public: |
(...skipping 21 matching lines...) Expand all Loading... |
6716 FunctionSorter const* function1 = reinterpret_cast<FunctionSorter const*>(a); | 6758 FunctionSorter const* function1 = reinterpret_cast<FunctionSorter const*>(a); |
6717 FunctionSorter const* function2 = reinterpret_cast<FunctionSorter const*>(b); | 6759 FunctionSorter const* function2 = reinterpret_cast<FunctionSorter const*>(b); |
6718 int diff = function1->ticks() - function2->ticks(); | 6760 int diff = function1->ticks() - function2->ticks(); |
6719 if (diff != 0) return -diff; | 6761 if (diff != 0) return -diff; |
6720 diff = function1->ast_length() - function2->ast_length(); | 6762 diff = function1->ast_length() - function2->ast_length(); |
6721 if (diff != 0) return diff; | 6763 if (diff != 0) return diff; |
6722 return function1->src_length() - function2->src_length(); | 6764 return function1->src_length() - function2->src_length(); |
6723 } | 6765 } |
6724 | 6766 |
6725 | 6767 |
6726 void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr, | 6768 void HOptimizedGraphBuilder::HandlePolymorphicCallNamed( |
6727 HValue* receiver, | 6769 Call* expr, |
6728 SmallMapList* types, | 6770 HValue* receiver, |
6729 Handle<String> name) { | 6771 SmallMapList* types, |
| 6772 Handle<String> name) { |
6730 // TODO(ager): We should recognize when the prototype chains for different | 6773 // TODO(ager): We should recognize when the prototype chains for different |
6731 // maps are identical. In that case we can avoid repeatedly generating the | 6774 // maps are identical. In that case we can avoid repeatedly generating the |
6732 // same prototype map checks. | 6775 // same prototype map checks. |
6733 int argument_count = expr->arguments()->length() + 1; // Includes receiver. | 6776 int argument_count = expr->arguments()->length() + 1; // Includes receiver. |
6734 HBasicBlock* join = NULL; | 6777 HBasicBlock* join = NULL; |
6735 FunctionSorter order[kMaxCallPolymorphism]; | 6778 FunctionSorter order[kMaxCallPolymorphism]; |
6736 int ordered_functions = 0; | 6779 int ordered_functions = 0; |
6737 for (int i = 0; | 6780 for (int i = 0; |
6738 i < types->length() && ordered_functions < kMaxCallPolymorphism; | 6781 i < types->length() && ordered_functions < kMaxCallPolymorphism; |
6739 ++i) { | 6782 ++i) { |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6821 if (join->HasPredecessor()) { | 6864 if (join->HasPredecessor()) { |
6822 set_current_block(join); | 6865 set_current_block(join); |
6823 join->SetJoinId(expr->id()); | 6866 join->SetJoinId(expr->id()); |
6824 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); | 6867 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); |
6825 } else { | 6868 } else { |
6826 set_current_block(NULL); | 6869 set_current_block(NULL); |
6827 } | 6870 } |
6828 } | 6871 } |
6829 | 6872 |
6830 | 6873 |
6831 void HGraphBuilder::TraceInline(Handle<JSFunction> target, | 6874 void HOptimizedGraphBuilder::TraceInline(Handle<JSFunction> target, |
6832 Handle<JSFunction> caller, | 6875 Handle<JSFunction> caller, |
6833 const char* reason) { | 6876 const char* reason) { |
6834 if (FLAG_trace_inlining) { | 6877 if (FLAG_trace_inlining) { |
6835 SmartArrayPointer<char> target_name = | 6878 SmartArrayPointer<char> target_name = |
6836 target->shared()->DebugName()->ToCString(); | 6879 target->shared()->DebugName()->ToCString(); |
6837 SmartArrayPointer<char> caller_name = | 6880 SmartArrayPointer<char> caller_name = |
6838 caller->shared()->DebugName()->ToCString(); | 6881 caller->shared()->DebugName()->ToCString(); |
6839 if (reason == NULL) { | 6882 if (reason == NULL) { |
6840 PrintF("Inlined %s called from %s.\n", *target_name, *caller_name); | 6883 PrintF("Inlined %s called from %s.\n", *target_name, *caller_name); |
6841 } else { | 6884 } else { |
6842 PrintF("Did not inline %s called from %s (%s).\n", | 6885 PrintF("Did not inline %s called from %s (%s).\n", |
6843 *target_name, *caller_name, reason); | 6886 *target_name, *caller_name, reason); |
6844 } | 6887 } |
6845 } | 6888 } |
6846 } | 6889 } |
6847 | 6890 |
6848 | 6891 |
6849 static const int kNotInlinable = 1000000000; | 6892 static const int kNotInlinable = 1000000000; |
6850 | 6893 |
6851 | 6894 |
6852 int HGraphBuilder::InliningAstSize(Handle<JSFunction> target) { | 6895 int HOptimizedGraphBuilder::InliningAstSize(Handle<JSFunction> target) { |
6853 if (!FLAG_use_inlining) return kNotInlinable; | 6896 if (!FLAG_use_inlining) return kNotInlinable; |
6854 | 6897 |
6855 // Precondition: call is monomorphic and we have found a target with the | 6898 // Precondition: call is monomorphic and we have found a target with the |
6856 // appropriate arity. | 6899 // appropriate arity. |
6857 Handle<JSFunction> caller = info()->closure(); | 6900 Handle<JSFunction> caller = info()->closure(); |
6858 Handle<SharedFunctionInfo> target_shared(target->shared()); | 6901 Handle<SharedFunctionInfo> target_shared(target->shared()); |
6859 | 6902 |
6860 // Do a quick check on source code length to avoid parsing large | 6903 // Do a quick check on source code length to avoid parsing large |
6861 // inlining candidates. | 6904 // inlining candidates. |
6862 if (target_shared->SourceSize() > | 6905 if (target_shared->SourceSize() > |
(...skipping 10 matching lines...) Expand all Loading... |
6873 if (target_shared->dont_inline() || target_shared->dont_optimize()) { | 6916 if (target_shared->dont_inline() || target_shared->dont_optimize()) { |
6874 TraceInline(target, caller, "target contains unsupported syntax [early]"); | 6917 TraceInline(target, caller, "target contains unsupported syntax [early]"); |
6875 return kNotInlinable; | 6918 return kNotInlinable; |
6876 } | 6919 } |
6877 | 6920 |
6878 int nodes_added = target_shared->ast_node_count(); | 6921 int nodes_added = target_shared->ast_node_count(); |
6879 return nodes_added; | 6922 return nodes_added; |
6880 } | 6923 } |
6881 | 6924 |
6882 | 6925 |
6883 bool HGraphBuilder::TryInline(CallKind call_kind, | 6926 bool HOptimizedGraphBuilder::TryInline(CallKind call_kind, |
6884 Handle<JSFunction> target, | 6927 Handle<JSFunction> target, |
6885 int arguments_count, | 6928 int arguments_count, |
6886 HValue* implicit_return_value, | 6929 HValue* implicit_return_value, |
6887 BailoutId ast_id, | 6930 BailoutId ast_id, |
6888 BailoutId return_id, | 6931 BailoutId return_id, |
6889 InliningKind inlining_kind) { | 6932 InliningKind inlining_kind) { |
6890 int nodes_added = InliningAstSize(target); | 6933 int nodes_added = InliningAstSize(target); |
6891 if (nodes_added == kNotInlinable) return false; | 6934 if (nodes_added == kNotInlinable) return false; |
6892 | 6935 |
6893 Handle<JSFunction> caller = info()->closure(); | 6936 Handle<JSFunction> caller = info()->closure(); |
6894 | 6937 |
6895 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { | 6938 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { |
6896 TraceInline(target, caller, "target AST is too large [early]"); | 6939 TraceInline(target, caller, "target AST is too large [early]"); |
6897 return false; | 6940 return false; |
6898 } | 6941 } |
6899 | 6942 |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7188 function_return()->SetJoinId(ast_id); | 7231 function_return()->SetJoinId(ast_id); |
7189 set_current_block(function_return()); | 7232 set_current_block(function_return()); |
7190 } else { | 7233 } else { |
7191 set_current_block(NULL); | 7234 set_current_block(NULL); |
7192 } | 7235 } |
7193 delete target_state; | 7236 delete target_state; |
7194 return true; | 7237 return true; |
7195 } | 7238 } |
7196 | 7239 |
7197 | 7240 |
7198 bool HGraphBuilder::TryInlineCall(Call* expr, bool drop_extra) { | 7241 bool HOptimizedGraphBuilder::TryInlineCall(Call* expr, bool drop_extra) { |
7199 // The function call we are inlining is a method call if the call | 7242 // The function call we are inlining is a method call if the call |
7200 // is a property call. | 7243 // is a property call. |
7201 CallKind call_kind = (expr->expression()->AsProperty() == NULL) | 7244 CallKind call_kind = (expr->expression()->AsProperty() == NULL) |
7202 ? CALL_AS_FUNCTION | 7245 ? CALL_AS_FUNCTION |
7203 : CALL_AS_METHOD; | 7246 : CALL_AS_METHOD; |
7204 | 7247 |
7205 return TryInline(call_kind, | 7248 return TryInline(call_kind, |
7206 expr->target(), | 7249 expr->target(), |
7207 expr->arguments()->length(), | 7250 expr->arguments()->length(), |
7208 NULL, | 7251 NULL, |
7209 expr->id(), | 7252 expr->id(), |
7210 expr->ReturnId(), | 7253 expr->ReturnId(), |
7211 drop_extra ? DROP_EXTRA_ON_RETURN : NORMAL_RETURN); | 7254 drop_extra ? DROP_EXTRA_ON_RETURN : NORMAL_RETURN); |
7212 } | 7255 } |
7213 | 7256 |
7214 | 7257 |
7215 bool HGraphBuilder::TryInlineConstruct(CallNew* expr, | 7258 bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr, |
7216 HValue* implicit_return_value) { | 7259 HValue* implicit_return_value) { |
7217 return TryInline(CALL_AS_FUNCTION, | 7260 return TryInline(CALL_AS_FUNCTION, |
7218 expr->target(), | 7261 expr->target(), |
7219 expr->arguments()->length(), | 7262 expr->arguments()->length(), |
7220 implicit_return_value, | 7263 implicit_return_value, |
7221 expr->id(), | 7264 expr->id(), |
7222 expr->ReturnId(), | 7265 expr->ReturnId(), |
7223 CONSTRUCT_CALL_RETURN); | 7266 CONSTRUCT_CALL_RETURN); |
7224 } | 7267 } |
7225 | 7268 |
7226 | 7269 |
7227 bool HGraphBuilder::TryInlineGetter(Handle<JSFunction> getter, | 7270 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter, |
7228 Property* prop) { | 7271 Property* prop) { |
7229 return TryInline(CALL_AS_METHOD, | 7272 return TryInline(CALL_AS_METHOD, |
7230 getter, | 7273 getter, |
7231 0, | 7274 0, |
7232 NULL, | 7275 NULL, |
7233 prop->id(), | 7276 prop->id(), |
7234 prop->LoadId(), | 7277 prop->LoadId(), |
7235 GETTER_CALL_RETURN); | 7278 GETTER_CALL_RETURN); |
7236 } | 7279 } |
7237 | 7280 |
7238 | 7281 |
7239 bool HGraphBuilder::TryInlineSetter(Handle<JSFunction> setter, | 7282 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter, |
7240 Assignment* assignment, | 7283 Assignment* assignment, |
7241 HValue* implicit_return_value) { | 7284 HValue* implicit_return_value) { |
7242 return TryInline(CALL_AS_METHOD, | 7285 return TryInline(CALL_AS_METHOD, |
7243 setter, | 7286 setter, |
7244 1, | 7287 1, |
7245 implicit_return_value, | 7288 implicit_return_value, |
7246 assignment->id(), | 7289 assignment->id(), |
7247 assignment->AssignmentId(), | 7290 assignment->AssignmentId(), |
7248 SETTER_CALL_RETURN); | 7291 SETTER_CALL_RETURN); |
7249 } | 7292 } |
7250 | 7293 |
7251 | 7294 |
7252 bool HGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr, bool drop_extra) { | 7295 bool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr, |
| 7296 bool drop_extra) { |
7253 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; | 7297 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; |
7254 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); | 7298 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); |
7255 switch (id) { | 7299 switch (id) { |
7256 case kMathExp: | 7300 case kMathExp: |
7257 if (!FLAG_fast_math) break; | 7301 if (!FLAG_fast_math) break; |
7258 // Fall through if FLAG_fast_math. | 7302 // Fall through if FLAG_fast_math. |
7259 case kMathRound: | 7303 case kMathRound: |
7260 case kMathAbs: | 7304 case kMathAbs: |
7261 case kMathSqrt: | 7305 case kMathSqrt: |
7262 case kMathLog: | 7306 case kMathLog: |
(...skipping 13 matching lines...) Expand all Loading... |
7276 } | 7320 } |
7277 break; | 7321 break; |
7278 default: | 7322 default: |
7279 // Not supported for inlining yet. | 7323 // Not supported for inlining yet. |
7280 break; | 7324 break; |
7281 } | 7325 } |
7282 return false; | 7326 return false; |
7283 } | 7327 } |
7284 | 7328 |
7285 | 7329 |
7286 bool HGraphBuilder::TryInlineBuiltinMethodCall(Call* expr, | 7330 bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( |
7287 HValue* receiver, | 7331 Call* expr, |
7288 Handle<Map> receiver_map, | 7332 HValue* receiver, |
7289 CheckType check_type) { | 7333 Handle<Map> receiver_map, |
| 7334 CheckType check_type) { |
7290 ASSERT(check_type != RECEIVER_MAP_CHECK || !receiver_map.is_null()); | 7335 ASSERT(check_type != RECEIVER_MAP_CHECK || !receiver_map.is_null()); |
7291 // Try to inline calls like Math.* as operations in the calling function. | 7336 // Try to inline calls like Math.* as operations in the calling function. |
7292 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; | 7337 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; |
7293 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); | 7338 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); |
7294 int argument_count = expr->arguments()->length() + 1; // Plus receiver. | 7339 int argument_count = expr->arguments()->length() + 1; // Plus receiver. |
7295 switch (id) { | 7340 switch (id) { |
7296 case kStringCharCodeAt: | 7341 case kStringCharCodeAt: |
7297 case kStringCharAt: | 7342 case kStringCharAt: |
7298 if (argument_count == 2 && check_type == STRING_CHECK) { | 7343 if (argument_count == 2 && check_type == STRING_CHECK) { |
7299 HValue* index = Pop(); | 7344 HValue* index = Pop(); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7409 } | 7454 } |
7410 break; | 7455 break; |
7411 default: | 7456 default: |
7412 // Not yet supported for inlining. | 7457 // Not yet supported for inlining. |
7413 break; | 7458 break; |
7414 } | 7459 } |
7415 return false; | 7460 return false; |
7416 } | 7461 } |
7417 | 7462 |
7418 | 7463 |
7419 bool HGraphBuilder::TryCallApply(Call* expr) { | 7464 bool HOptimizedGraphBuilder::TryCallApply(Call* expr) { |
7420 Expression* callee = expr->expression(); | 7465 Expression* callee = expr->expression(); |
7421 Property* prop = callee->AsProperty(); | 7466 Property* prop = callee->AsProperty(); |
7422 ASSERT(prop != NULL); | 7467 ASSERT(prop != NULL); |
7423 | 7468 |
7424 if (!expr->IsMonomorphic() || expr->check_type() != RECEIVER_MAP_CHECK) { | 7469 if (!expr->IsMonomorphic() || expr->check_type() != RECEIVER_MAP_CHECK) { |
7425 return false; | 7470 return false; |
7426 } | 7471 } |
7427 Handle<Map> function_map = expr->GetReceiverTypes()->first(); | 7472 Handle<Map> function_map = expr->GetReceiverTypes()->first(); |
7428 if (function_map->instance_type() != JS_FUNCTION_TYPE || | 7473 if (function_map->instance_type() != JS_FUNCTION_TYPE || |
7429 !expr->target()->shared()->HasBuiltinFunctionId() || | 7474 !expr->target()->shared()->HasBuiltinFunctionId() || |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7537 return NULL; | 7582 return NULL; |
7538 } | 7583 } |
7539 current = next; | 7584 current = next; |
7540 } | 7585 } |
7541 } | 7586 } |
7542 | 7587 |
7543 return kinds[first_index]; | 7588 return kinds[first_index]; |
7544 } | 7589 } |
7545 | 7590 |
7546 | 7591 |
7547 void HGraphBuilder::VisitCall(Call* expr) { | 7592 void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
7548 ASSERT(!HasStackOverflow()); | 7593 ASSERT(!HasStackOverflow()); |
7549 ASSERT(current_block() != NULL); | 7594 ASSERT(current_block() != NULL); |
7550 ASSERT(current_block()->HasPredecessor()); | 7595 ASSERT(current_block()->HasPredecessor()); |
7551 Expression* callee = expr->expression(); | 7596 Expression* callee = expr->expression(); |
7552 int argument_count = expr->arguments()->length() + 1; // Plus receiver. | 7597 int argument_count = expr->arguments()->length() + 1; // Plus receiver. |
7553 HInstruction* call = NULL; | 7598 HInstruction* call = NULL; |
7554 | 7599 |
7555 Property* prop = callee->AsProperty(); | 7600 Property* prop = callee->AsProperty(); |
7556 if (prop != NULL) { | 7601 if (prop != NULL) { |
7557 if (!prop->key()->IsPropertyName()) { | 7602 if (!prop->key()->IsPropertyName()) { |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7767 | 7812 |
7768 | 7813 |
7769 // Checks whether allocation using the given constructor can be inlined. | 7814 // Checks whether allocation using the given constructor can be inlined. |
7770 static bool IsAllocationInlineable(Handle<JSFunction> constructor) { | 7815 static bool IsAllocationInlineable(Handle<JSFunction> constructor) { |
7771 return constructor->has_initial_map() && | 7816 return constructor->has_initial_map() && |
7772 constructor->initial_map()->instance_type() == JS_OBJECT_TYPE && | 7817 constructor->initial_map()->instance_type() == JS_OBJECT_TYPE && |
7773 constructor->initial_map()->instance_size() < HAllocateObject::kMaxSize; | 7818 constructor->initial_map()->instance_size() < HAllocateObject::kMaxSize; |
7774 } | 7819 } |
7775 | 7820 |
7776 | 7821 |
7777 void HGraphBuilder::VisitCallNew(CallNew* expr) { | 7822 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { |
7778 ASSERT(!HasStackOverflow()); | 7823 ASSERT(!HasStackOverflow()); |
7779 ASSERT(current_block() != NULL); | 7824 ASSERT(current_block() != NULL); |
7780 ASSERT(current_block()->HasPredecessor()); | 7825 ASSERT(current_block()->HasPredecessor()); |
7781 expr->RecordTypeFeedback(oracle()); | 7826 expr->RecordTypeFeedback(oracle()); |
7782 int argument_count = expr->arguments()->length() + 1; // Plus constructor. | 7827 int argument_count = expr->arguments()->length() + 1; // Plus constructor. |
7783 HValue* context = environment()->LookupContext(); | 7828 HValue* context = environment()->LookupContext(); |
7784 | 7829 |
7785 if (FLAG_inline_construct && | 7830 if (FLAG_inline_construct && |
7786 expr->IsMonomorphic() && | 7831 expr->IsMonomorphic() && |
7787 IsAllocationInlineable(expr->target())) { | 7832 IsAllocationInlineable(expr->target())) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7831 new(zone()) HCallNew(context, constructor, argument_count); | 7876 new(zone()) HCallNew(context, constructor, argument_count); |
7832 Drop(argument_count); | 7877 Drop(argument_count); |
7833 call->set_position(expr->position()); | 7878 call->set_position(expr->position()); |
7834 return ast_context()->ReturnInstruction(call, expr->id()); | 7879 return ast_context()->ReturnInstruction(call, expr->id()); |
7835 } | 7880 } |
7836 } | 7881 } |
7837 | 7882 |
7838 | 7883 |
7839 // Support for generating inlined runtime functions. | 7884 // Support for generating inlined runtime functions. |
7840 | 7885 |
7841 // Lookup table for generators for runtime calls that are generated inline. | 7886 // Lookup table for generators for runtime calls that are generated inline. |
7842 // Elements of the table are member pointers to functions of HGraphBuilder. | 7887 // Elements of the table are member pointers to functions of |
| 7888 // HOptimizedGraphBuilder. |
7843 #define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \ | 7889 #define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \ |
7844 &HGraphBuilder::Generate##Name, | 7890 &HOptimizedGraphBuilder::Generate##Name, |
7845 | 7891 |
7846 const HGraphBuilder::InlineFunctionGenerator | 7892 const HOptimizedGraphBuilder::InlineFunctionGenerator |
7847 HGraphBuilder::kInlineFunctionGenerators[] = { | 7893 HOptimizedGraphBuilder::kInlineFunctionGenerators[] = { |
7848 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) | 7894 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) |
7849 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) | 7895 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) |
7850 }; | 7896 }; |
7851 #undef INLINE_FUNCTION_GENERATOR_ADDRESS | 7897 #undef INLINE_FUNCTION_GENERATOR_ADDRESS |
7852 | 7898 |
7853 | 7899 |
7854 void HGraphBuilder::VisitCallRuntime(CallRuntime* expr) { | 7900 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { |
7855 ASSERT(!HasStackOverflow()); | 7901 ASSERT(!HasStackOverflow()); |
7856 ASSERT(current_block() != NULL); | 7902 ASSERT(current_block() != NULL); |
7857 ASSERT(current_block()->HasPredecessor()); | 7903 ASSERT(current_block()->HasPredecessor()); |
7858 if (expr->is_jsruntime()) { | 7904 if (expr->is_jsruntime()) { |
7859 return Bailout("call to a JavaScript runtime function"); | 7905 return Bailout("call to a JavaScript runtime function"); |
7860 } | 7906 } |
7861 | 7907 |
7862 const Runtime::Function* function = expr->function(); | 7908 const Runtime::Function* function = expr->function(); |
7863 ASSERT(function != NULL); | 7909 ASSERT(function != NULL); |
7864 if (function->intrinsic_type == Runtime::INLINE) { | 7910 if (function->intrinsic_type == Runtime::INLINE) { |
(...skipping 17 matching lines...) Expand all Loading... |
7882 Handle<String> name = expr->name(); | 7928 Handle<String> name = expr->name(); |
7883 int argument_count = expr->arguments()->length(); | 7929 int argument_count = expr->arguments()->length(); |
7884 HCallRuntime* call = | 7930 HCallRuntime* call = |
7885 new(zone()) HCallRuntime(context, name, function, argument_count); | 7931 new(zone()) HCallRuntime(context, name, function, argument_count); |
7886 Drop(argument_count); | 7932 Drop(argument_count); |
7887 return ast_context()->ReturnInstruction(call, expr->id()); | 7933 return ast_context()->ReturnInstruction(call, expr->id()); |
7888 } | 7934 } |
7889 } | 7935 } |
7890 | 7936 |
7891 | 7937 |
7892 void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { | 7938 void HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { |
7893 ASSERT(!HasStackOverflow()); | 7939 ASSERT(!HasStackOverflow()); |
7894 ASSERT(current_block() != NULL); | 7940 ASSERT(current_block() != NULL); |
7895 ASSERT(current_block()->HasPredecessor()); | 7941 ASSERT(current_block()->HasPredecessor()); |
7896 switch (expr->op()) { | 7942 switch (expr->op()) { |
7897 case Token::DELETE: return VisitDelete(expr); | 7943 case Token::DELETE: return VisitDelete(expr); |
7898 case Token::VOID: return VisitVoid(expr); | 7944 case Token::VOID: return VisitVoid(expr); |
7899 case Token::TYPEOF: return VisitTypeof(expr); | 7945 case Token::TYPEOF: return VisitTypeof(expr); |
7900 case Token::ADD: return VisitAdd(expr); | 7946 case Token::ADD: return VisitAdd(expr); |
7901 case Token::SUB: return VisitSub(expr); | 7947 case Token::SUB: return VisitSub(expr); |
7902 case Token::BIT_NOT: return VisitBitNot(expr); | 7948 case Token::BIT_NOT: return VisitBitNot(expr); |
7903 case Token::NOT: return VisitNot(expr); | 7949 case Token::NOT: return VisitNot(expr); |
7904 default: UNREACHABLE(); | 7950 default: UNREACHABLE(); |
7905 } | 7951 } |
7906 } | 7952 } |
7907 | 7953 |
7908 void HGraphBuilder::VisitDelete(UnaryOperation* expr) { | 7954 void HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) { |
7909 Property* prop = expr->expression()->AsProperty(); | 7955 Property* prop = expr->expression()->AsProperty(); |
7910 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 7956 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
7911 if (prop != NULL) { | 7957 if (prop != NULL) { |
7912 CHECK_ALIVE(VisitForValue(prop->obj())); | 7958 CHECK_ALIVE(VisitForValue(prop->obj())); |
7913 CHECK_ALIVE(VisitForValue(prop->key())); | 7959 CHECK_ALIVE(VisitForValue(prop->key())); |
7914 HValue* key = Pop(); | 7960 HValue* key = Pop(); |
7915 HValue* obj = Pop(); | 7961 HValue* obj = Pop(); |
7916 HValue* context = environment()->LookupContext(); | 7962 HValue* context = environment()->LookupContext(); |
7917 HDeleteProperty* instr = new(zone()) HDeleteProperty(context, obj, key); | 7963 HDeleteProperty* instr = new(zone()) HDeleteProperty(context, obj, key); |
7918 return ast_context()->ReturnInstruction(instr, expr->id()); | 7964 return ast_context()->ReturnInstruction(instr, expr->id()); |
(...skipping 14 matching lines...) Expand all Loading... |
7933 } | 7979 } |
7934 } else { | 7980 } else { |
7935 // Result of deleting non-property, non-variable reference is true. | 7981 // Result of deleting non-property, non-variable reference is true. |
7936 // Evaluate the subexpression for side effects. | 7982 // Evaluate the subexpression for side effects. |
7937 CHECK_ALIVE(VisitForEffect(expr->expression())); | 7983 CHECK_ALIVE(VisitForEffect(expr->expression())); |
7938 return ast_context()->ReturnValue(graph()->GetConstantTrue()); | 7984 return ast_context()->ReturnValue(graph()->GetConstantTrue()); |
7939 } | 7985 } |
7940 } | 7986 } |
7941 | 7987 |
7942 | 7988 |
7943 void HGraphBuilder::VisitVoid(UnaryOperation* expr) { | 7989 void HOptimizedGraphBuilder::VisitVoid(UnaryOperation* expr) { |
7944 CHECK_ALIVE(VisitForEffect(expr->expression())); | 7990 CHECK_ALIVE(VisitForEffect(expr->expression())); |
7945 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); | 7991 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); |
7946 } | 7992 } |
7947 | 7993 |
7948 | 7994 |
7949 void HGraphBuilder::VisitTypeof(UnaryOperation* expr) { | 7995 void HOptimizedGraphBuilder::VisitTypeof(UnaryOperation* expr) { |
7950 CHECK_ALIVE(VisitForTypeOf(expr->expression())); | 7996 CHECK_ALIVE(VisitForTypeOf(expr->expression())); |
7951 HValue* value = Pop(); | 7997 HValue* value = Pop(); |
7952 HValue* context = environment()->LookupContext(); | 7998 HValue* context = environment()->LookupContext(); |
7953 HInstruction* instr = new(zone()) HTypeof(context, value); | 7999 HInstruction* instr = new(zone()) HTypeof(context, value); |
7954 return ast_context()->ReturnInstruction(instr, expr->id()); | 8000 return ast_context()->ReturnInstruction(instr, expr->id()); |
7955 } | 8001 } |
7956 | 8002 |
7957 | 8003 |
7958 void HGraphBuilder::VisitAdd(UnaryOperation* expr) { | 8004 void HOptimizedGraphBuilder::VisitAdd(UnaryOperation* expr) { |
7959 CHECK_ALIVE(VisitForValue(expr->expression())); | 8005 CHECK_ALIVE(VisitForValue(expr->expression())); |
7960 HValue* value = Pop(); | 8006 HValue* value = Pop(); |
7961 HValue* context = environment()->LookupContext(); | 8007 HValue* context = environment()->LookupContext(); |
7962 HInstruction* instr = | 8008 HInstruction* instr = |
7963 new(zone()) HMul(context, value, graph_->GetConstant1()); | 8009 new(zone()) HMul(context, value, graph()->GetConstant1()); |
7964 return ast_context()->ReturnInstruction(instr, expr->id()); | 8010 return ast_context()->ReturnInstruction(instr, expr->id()); |
7965 } | 8011 } |
7966 | 8012 |
7967 | 8013 |
7968 void HGraphBuilder::VisitSub(UnaryOperation* expr) { | 8014 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { |
7969 CHECK_ALIVE(VisitForValue(expr->expression())); | 8015 CHECK_ALIVE(VisitForValue(expr->expression())); |
7970 HValue* value = Pop(); | 8016 HValue* value = Pop(); |
7971 HValue* context = environment()->LookupContext(); | 8017 HValue* context = environment()->LookupContext(); |
7972 HInstruction* instr = | 8018 HInstruction* instr = |
7973 new(zone()) HMul(context, value, graph_->GetConstantMinus1()); | 8019 new(zone()) HMul(context, value, graph()->GetConstantMinus1()); |
7974 TypeInfo info = oracle()->UnaryType(expr); | 8020 TypeInfo info = oracle()->UnaryType(expr); |
7975 Representation rep = ToRepresentation(info); | 8021 Representation rep = ToRepresentation(info); |
7976 if (info.IsUninitialized()) { | 8022 if (info.IsUninitialized()) { |
7977 AddInstruction(new(zone()) HSoftDeoptimize); | 8023 AddInstruction(new(zone()) HSoftDeoptimize); |
7978 current_block()->MarkAsDeoptimizing(); | 8024 current_block()->MarkAsDeoptimizing(); |
7979 info = TypeInfo::Unknown(); | 8025 info = TypeInfo::Unknown(); |
7980 } | 8026 } |
7981 HBinaryOperation::cast(instr)->set_observed_input_representation(rep, rep); | 8027 HBinaryOperation::cast(instr)->set_observed_input_representation(rep, rep); |
7982 return ast_context()->ReturnInstruction(instr, expr->id()); | 8028 return ast_context()->ReturnInstruction(instr, expr->id()); |
7983 } | 8029 } |
7984 | 8030 |
7985 | 8031 |
7986 void HGraphBuilder::VisitBitNot(UnaryOperation* expr) { | 8032 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) { |
7987 CHECK_ALIVE(VisitForValue(expr->expression())); | 8033 CHECK_ALIVE(VisitForValue(expr->expression())); |
7988 HValue* value = Pop(); | 8034 HValue* value = Pop(); |
7989 TypeInfo info = oracle()->UnaryType(expr); | 8035 TypeInfo info = oracle()->UnaryType(expr); |
7990 if (info.IsUninitialized()) { | 8036 if (info.IsUninitialized()) { |
7991 AddInstruction(new(zone()) HSoftDeoptimize); | 8037 AddInstruction(new(zone()) HSoftDeoptimize); |
7992 current_block()->MarkAsDeoptimizing(); | 8038 current_block()->MarkAsDeoptimizing(); |
7993 } | 8039 } |
7994 HInstruction* instr = new(zone()) HBitNot(value); | 8040 HInstruction* instr = new(zone()) HBitNot(value); |
7995 return ast_context()->ReturnInstruction(instr, expr->id()); | 8041 return ast_context()->ReturnInstruction(instr, expr->id()); |
7996 } | 8042 } |
7997 | 8043 |
7998 | 8044 |
7999 void HGraphBuilder::VisitNot(UnaryOperation* expr) { | 8045 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { |
8000 if (ast_context()->IsTest()) { | 8046 if (ast_context()->IsTest()) { |
8001 TestContext* context = TestContext::cast(ast_context()); | 8047 TestContext* context = TestContext::cast(ast_context()); |
8002 VisitForControl(expr->expression(), | 8048 VisitForControl(expr->expression(), |
8003 context->if_false(), | 8049 context->if_false(), |
8004 context->if_true()); | 8050 context->if_true()); |
8005 return; | 8051 return; |
8006 } | 8052 } |
8007 | 8053 |
8008 if (ast_context()->IsEffect()) { | 8054 if (ast_context()->IsEffect()) { |
8009 VisitForEffect(expr->expression()); | 8055 VisitForEffect(expr->expression()); |
(...skipping 23 matching lines...) Expand all Loading... |
8033 materialize_true = NULL; | 8079 materialize_true = NULL; |
8034 } | 8080 } |
8035 | 8081 |
8036 HBasicBlock* join = | 8082 HBasicBlock* join = |
8037 CreateJoin(materialize_false, materialize_true, expr->id()); | 8083 CreateJoin(materialize_false, materialize_true, expr->id()); |
8038 set_current_block(join); | 8084 set_current_block(join); |
8039 if (join != NULL) return ast_context()->ReturnValue(Pop()); | 8085 if (join != NULL) return ast_context()->ReturnValue(Pop()); |
8040 } | 8086 } |
8041 | 8087 |
8042 | 8088 |
8043 HInstruction* HGraphBuilder::BuildIncrement(bool returns_original_input, | 8089 HInstruction* HOptimizedGraphBuilder::BuildIncrement( |
8044 CountOperation* expr) { | 8090 bool returns_original_input, |
| 8091 CountOperation* expr) { |
8045 // The input to the count operation is on top of the expression stack. | 8092 // The input to the count operation is on top of the expression stack. |
8046 TypeInfo info = oracle()->IncrementType(expr); | 8093 TypeInfo info = oracle()->IncrementType(expr); |
8047 Representation rep = ToRepresentation(info); | 8094 Representation rep = ToRepresentation(info); |
8048 if (rep.IsTagged()) { | 8095 if (rep.IsTagged()) { |
8049 rep = Representation::Integer32(); | 8096 rep = Representation::Integer32(); |
8050 } | 8097 } |
8051 | 8098 |
8052 if (returns_original_input) { | 8099 if (returns_original_input) { |
8053 // We need an explicit HValue representing ToNumber(input). The | 8100 // We need an explicit HValue representing ToNumber(input). The |
8054 // actual HChange instruction we need is (sometimes) added in a later | 8101 // actual HChange instruction we need is (sometimes) added in a later |
8055 // phase, so it is not available now to be used as an input to HAdd and | 8102 // phase, so it is not available now to be used as an input to HAdd and |
8056 // as the return value. | 8103 // as the return value. |
8057 HInstruction* number_input = new(zone()) HForceRepresentation(Pop(), rep); | 8104 HInstruction* number_input = new(zone()) HForceRepresentation(Pop(), rep); |
8058 AddInstruction(number_input); | 8105 AddInstruction(number_input); |
8059 Push(number_input); | 8106 Push(number_input); |
8060 } | 8107 } |
8061 | 8108 |
8062 // The addition has no side effects, so we do not need | 8109 // The addition has no side effects, so we do not need |
8063 // to simulate the expression stack after this instruction. | 8110 // to simulate the expression stack after this instruction. |
8064 // Any later failures deopt to the load of the input or earlier. | 8111 // Any later failures deopt to the load of the input or earlier. |
8065 HConstant* delta = (expr->op() == Token::INC) | 8112 HConstant* delta = (expr->op() == Token::INC) |
8066 ? graph_->GetConstant1() | 8113 ? graph()->GetConstant1() |
8067 : graph_->GetConstantMinus1(); | 8114 : graph()->GetConstantMinus1(); |
8068 HValue* context = environment()->LookupContext(); | 8115 HValue* context = environment()->LookupContext(); |
8069 HInstruction* instr = new(zone()) HAdd(context, Top(), delta); | 8116 HInstruction* instr = new(zone()) HAdd(context, Top(), delta); |
8070 // We can't insert a simulate here, because it would break deoptimization, | 8117 // We can't insert a simulate here, because it would break deoptimization, |
8071 // so the HAdd must not have side effects, so we must freeze its | 8118 // so the HAdd must not have side effects, so we must freeze its |
8072 // representation. | 8119 // representation. |
8073 instr->AssumeRepresentation(rep); | 8120 instr->AssumeRepresentation(rep); |
8074 instr->ClearAllSideEffects(); | 8121 instr->ClearAllSideEffects(); |
8075 AddInstruction(instr); | 8122 AddInstruction(instr); |
8076 return instr; | 8123 return instr; |
8077 } | 8124 } |
8078 | 8125 |
8079 | 8126 |
8080 void HGraphBuilder::VisitCountOperation(CountOperation* expr) { | 8127 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { |
8081 ASSERT(!HasStackOverflow()); | 8128 ASSERT(!HasStackOverflow()); |
8082 ASSERT(current_block() != NULL); | 8129 ASSERT(current_block() != NULL); |
8083 ASSERT(current_block()->HasPredecessor()); | 8130 ASSERT(current_block()->HasPredecessor()); |
8084 Expression* target = expr->expression(); | 8131 Expression* target = expr->expression(); |
8085 VariableProxy* proxy = target->AsVariableProxy(); | 8132 VariableProxy* proxy = target->AsVariableProxy(); |
8086 Property* prop = target->AsProperty(); | 8133 Property* prop = target->AsProperty(); |
8087 if (proxy == NULL && prop == NULL) { | 8134 if (proxy == NULL && prop == NULL) { |
8088 return Bailout("invalid lhs in count operation"); | 8135 return Bailout("invalid lhs in count operation"); |
8089 } | 8136 } |
8090 | 8137 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8154 return Bailout("lookup variable in count operation"); | 8201 return Bailout("lookup variable in count operation"); |
8155 } | 8202 } |
8156 | 8203 |
8157 } else { | 8204 } else { |
8158 // Argument of the count operation is a property. | 8205 // Argument of the count operation is a property. |
8159 ASSERT(prop != NULL); | 8206 ASSERT(prop != NULL); |
8160 prop->RecordTypeFeedback(oracle(), zone()); | 8207 prop->RecordTypeFeedback(oracle(), zone()); |
8161 | 8208 |
8162 if (prop->key()->IsPropertyName()) { | 8209 if (prop->key()->IsPropertyName()) { |
8163 // Named property. | 8210 // Named property. |
8164 if (returns_original_input) Push(graph_->GetConstantUndefined()); | 8211 if (returns_original_input) Push(graph()->GetConstantUndefined()); |
8165 | 8212 |
8166 CHECK_ALIVE(VisitForValue(prop->obj())); | 8213 CHECK_ALIVE(VisitForValue(prop->obj())); |
8167 HValue* object = Top(); | 8214 HValue* object = Top(); |
8168 | 8215 |
8169 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 8216 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
8170 Handle<Map> map; | 8217 Handle<Map> map; |
8171 HInstruction* load; | 8218 HInstruction* load; |
8172 bool monomorphic = prop->IsMonomorphic(); | 8219 bool monomorphic = prop->IsMonomorphic(); |
8173 if (monomorphic) { | 8220 if (monomorphic) { |
8174 map = prop->GetReceiverTypes()->first(); | 8221 map = prop->GetReceiverTypes()->first(); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8215 // of the operation, and the placeholder with the original value if | 8262 // of the operation, and the placeholder with the original value if |
8216 // necessary. | 8263 // necessary. |
8217 environment()->SetExpressionStackAt(0, after); | 8264 environment()->SetExpressionStackAt(0, after); |
8218 if (returns_original_input) environment()->SetExpressionStackAt(1, input); | 8265 if (returns_original_input) environment()->SetExpressionStackAt(1, input); |
8219 if (store->HasObservableSideEffects()) { | 8266 if (store->HasObservableSideEffects()) { |
8220 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 8267 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); |
8221 } | 8268 } |
8222 | 8269 |
8223 } else { | 8270 } else { |
8224 // Keyed property. | 8271 // Keyed property. |
8225 if (returns_original_input) Push(graph_->GetConstantUndefined()); | 8272 if (returns_original_input) Push(graph()->GetConstantUndefined()); |
8226 | 8273 |
8227 CHECK_ALIVE(VisitForValue(prop->obj())); | 8274 CHECK_ALIVE(VisitForValue(prop->obj())); |
8228 CHECK_ALIVE(VisitForValue(prop->key())); | 8275 CHECK_ALIVE(VisitForValue(prop->key())); |
8229 HValue* obj = environment()->ExpressionStackAt(1); | 8276 HValue* obj = environment()->ExpressionStackAt(1); |
8230 HValue* key = environment()->ExpressionStackAt(0); | 8277 HValue* key = environment()->ExpressionStackAt(0); |
8231 | 8278 |
8232 bool has_side_effects = false; | 8279 bool has_side_effects = false; |
8233 HValue* load = HandleKeyedElementAccess( | 8280 HValue* load = HandleKeyedElementAccess( |
8234 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, | 8281 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, |
8235 false, // is_store | 8282 false, // is_store |
(...skipping 19 matching lines...) Expand all Loading... |
8255 ASSERT(has_side_effects); // Stores always have side effects. | 8302 ASSERT(has_side_effects); // Stores always have side effects. |
8256 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 8303 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); |
8257 } | 8304 } |
8258 } | 8305 } |
8259 | 8306 |
8260 Drop(returns_original_input ? 2 : 1); | 8307 Drop(returns_original_input ? 2 : 1); |
8261 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); | 8308 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); |
8262 } | 8309 } |
8263 | 8310 |
8264 | 8311 |
8265 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* context, | 8312 HStringCharCodeAt* HOptimizedGraphBuilder::BuildStringCharCodeAt( |
8266 HValue* string, | 8313 HValue* context, |
8267 HValue* index) { | 8314 HValue* string, |
| 8315 HValue* index) { |
8268 AddInstruction(new(zone()) HCheckNonSmi(string)); | 8316 AddInstruction(new(zone()) HCheckNonSmi(string)); |
8269 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); | 8317 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
8270 HStringLength* length = new(zone()) HStringLength(string); | 8318 HStringLength* length = new(zone()) HStringLength(string); |
8271 AddInstruction(length); | 8319 AddInstruction(length); |
8272 HInstruction* checked_index = | 8320 HInstruction* checked_index = |
8273 AddInstruction(new(zone()) HBoundsCheck(index, length)); | 8321 AddInstruction(new(zone()) HBoundsCheck(index, length)); |
8274 return new(zone()) HStringCharCodeAt(context, string, checked_index); | 8322 return new(zone()) HStringCharCodeAt(context, string, checked_index); |
8275 } | 8323 } |
8276 | 8324 |
8277 // Checks if the given shift amounts have form: (sa) and (32 - sa). | 8325 // Checks if the given shift amounts have form: (sa) and (32 - sa). |
8278 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, | 8326 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, |
8279 HValue* const32_minus_sa) { | 8327 HValue* const32_minus_sa) { |
8280 if (!const32_minus_sa->IsSub()) return false; | 8328 if (!const32_minus_sa->IsSub()) return false; |
8281 HSub* sub = HSub::cast(const32_minus_sa); | 8329 HSub* sub = HSub::cast(const32_minus_sa); |
8282 HValue* const32 = sub->left(); | 8330 HValue* const32 = sub->left(); |
8283 if (!const32->IsConstant() || | 8331 if (!const32->IsConstant() || |
8284 HConstant::cast(const32)->Integer32Value() != 32) { | 8332 HConstant::cast(const32)->Integer32Value() != 32) { |
8285 return false; | 8333 return false; |
8286 } | 8334 } |
8287 return (sub->right() == sa); | 8335 return (sub->right() == sa); |
8288 } | 8336 } |
8289 | 8337 |
8290 | 8338 |
8291 // Checks if the left and the right are shift instructions with the oposite | 8339 // Checks if the left and the right are shift instructions with the oposite |
8292 // directions that can be replaced by one rotate right instruction or not. | 8340 // directions that can be replaced by one rotate right instruction or not. |
8293 // Returns the operand and the shift amount for the rotate instruction in the | 8341 // Returns the operand and the shift amount for the rotate instruction in the |
8294 // former case. | 8342 // former case. |
8295 bool HGraphBuilder::MatchRotateRight(HValue* left, | 8343 bool HOptimizedGraphBuilder::MatchRotateRight(HValue* left, |
8296 HValue* right, | 8344 HValue* right, |
8297 HValue** operand, | 8345 HValue** operand, |
8298 HValue** shift_amount) { | 8346 HValue** shift_amount) { |
8299 HShl* shl; | 8347 HShl* shl; |
8300 HShr* shr; | 8348 HShr* shr; |
8301 if (left->IsShl() && right->IsShr()) { | 8349 if (left->IsShl() && right->IsShr()) { |
8302 shl = HShl::cast(left); | 8350 shl = HShl::cast(left); |
8303 shr = HShr::cast(right); | 8351 shr = HShr::cast(right); |
8304 } else if (left->IsShr() && right->IsShl()) { | 8352 } else if (left->IsShr() && right->IsShl()) { |
8305 shl = HShl::cast(right); | 8353 shl = HShl::cast(right); |
8306 shr = HShr::cast(left); | 8354 shr = HShr::cast(left); |
8307 } else { | 8355 } else { |
8308 return false; | 8356 return false; |
(...skipping 14 matching lines...) Expand all Loading... |
8323 HConstant* right_const = HConstant::cast(right); | 8371 HConstant* right_const = HConstant::cast(right); |
8324 if (right_const->HasInteger32Value() && | 8372 if (right_const->HasInteger32Value() && |
8325 (right_const->Integer32Value() & 0x1f) != 0) { | 8373 (right_const->Integer32Value() & 0x1f) != 0) { |
8326 return false; | 8374 return false; |
8327 } | 8375 } |
8328 } | 8376 } |
8329 return true; | 8377 return true; |
8330 } | 8378 } |
8331 | 8379 |
8332 | 8380 |
8333 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, | 8381 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( |
8334 HValue* left, | 8382 BinaryOperation* expr, |
8335 HValue* right) { | 8383 HValue* left, |
| 8384 HValue* right) { |
8336 HValue* context = environment()->LookupContext(); | 8385 HValue* context = environment()->LookupContext(); |
8337 TypeInfo left_info, right_info, result_info, combined_info; | 8386 TypeInfo left_info, right_info, result_info, combined_info; |
8338 oracle()->BinaryType(expr, &left_info, &right_info, &result_info); | 8387 oracle()->BinaryType(expr, &left_info, &right_info, &result_info); |
8339 Representation left_rep = ToRepresentation(left_info); | 8388 Representation left_rep = ToRepresentation(left_info); |
8340 Representation right_rep = ToRepresentation(right_info); | 8389 Representation right_rep = ToRepresentation(right_info); |
8341 Representation result_rep = ToRepresentation(result_info); | 8390 Representation result_rep = ToRepresentation(result_info); |
8342 if (left_info.IsUninitialized()) { | 8391 if (left_info.IsUninitialized()) { |
8343 // Can't have initialized one but not the other. | 8392 // Can't have initialized one but not the other. |
8344 ASSERT(right_info.IsUninitialized()); | 8393 ASSERT(right_info.IsUninitialized()); |
8345 AddInstruction(new(zone()) HSoftDeoptimize); | 8394 AddInstruction(new(zone()) HSoftDeoptimize); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8418 if (call == NULL) return false; | 8467 if (call == NULL) return false; |
8419 Literal* literal = expr->right()->AsLiteral(); | 8468 Literal* literal = expr->right()->AsLiteral(); |
8420 if (literal == NULL) return false; | 8469 if (literal == NULL) return false; |
8421 if (!literal->handle()->IsString()) return false; | 8470 if (!literal->handle()->IsString()) return false; |
8422 if (!call->name()->IsEqualTo(CStrVector("_ClassOf"))) return false; | 8471 if (!call->name()->IsEqualTo(CStrVector("_ClassOf"))) return false; |
8423 ASSERT(call->arguments()->length() == 1); | 8472 ASSERT(call->arguments()->length() == 1); |
8424 return true; | 8473 return true; |
8425 } | 8474 } |
8426 | 8475 |
8427 | 8476 |
8428 void HGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { | 8477 void HOptimizedGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { |
8429 ASSERT(!HasStackOverflow()); | 8478 ASSERT(!HasStackOverflow()); |
8430 ASSERT(current_block() != NULL); | 8479 ASSERT(current_block() != NULL); |
8431 ASSERT(current_block()->HasPredecessor()); | 8480 ASSERT(current_block()->HasPredecessor()); |
8432 switch (expr->op()) { | 8481 switch (expr->op()) { |
8433 case Token::COMMA: | 8482 case Token::COMMA: |
8434 return VisitComma(expr); | 8483 return VisitComma(expr); |
8435 case Token::OR: | 8484 case Token::OR: |
8436 case Token::AND: | 8485 case Token::AND: |
8437 return VisitLogicalExpression(expr); | 8486 return VisitLogicalExpression(expr); |
8438 default: | 8487 default: |
8439 return VisitArithmeticExpression(expr); | 8488 return VisitArithmeticExpression(expr); |
8440 } | 8489 } |
8441 } | 8490 } |
8442 | 8491 |
8443 | 8492 |
8444 void HGraphBuilder::VisitComma(BinaryOperation* expr) { | 8493 void HOptimizedGraphBuilder::VisitComma(BinaryOperation* expr) { |
8445 CHECK_ALIVE(VisitForEffect(expr->left())); | 8494 CHECK_ALIVE(VisitForEffect(expr->left())); |
8446 // Visit the right subexpression in the same AST context as the entire | 8495 // Visit the right subexpression in the same AST context as the entire |
8447 // expression. | 8496 // expression. |
8448 Visit(expr->right()); | 8497 Visit(expr->right()); |
8449 } | 8498 } |
8450 | 8499 |
8451 | 8500 |
8452 void HGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) { | 8501 void HOptimizedGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) { |
8453 bool is_logical_and = expr->op() == Token::AND; | 8502 bool is_logical_and = expr->op() == Token::AND; |
8454 if (ast_context()->IsTest()) { | 8503 if (ast_context()->IsTest()) { |
8455 TestContext* context = TestContext::cast(ast_context()); | 8504 TestContext* context = TestContext::cast(ast_context()); |
8456 // Translate left subexpression. | 8505 // Translate left subexpression. |
8457 HBasicBlock* eval_right = graph()->CreateBasicBlock(); | 8506 HBasicBlock* eval_right = graph()->CreateBasicBlock(); |
8458 if (is_logical_and) { | 8507 if (is_logical_and) { |
8459 CHECK_BAILOUT(VisitForControl(expr->left(), | 8508 CHECK_BAILOUT(VisitForControl(expr->left(), |
8460 eval_right, | 8509 eval_right, |
8461 context->if_false())); | 8510 context->if_false())); |
8462 } else { | 8511 } else { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8532 | 8581 |
8533 HBasicBlock* join_block = | 8582 HBasicBlock* join_block = |
8534 CreateJoin(empty_block, right_block, expr->id()); | 8583 CreateJoin(empty_block, right_block, expr->id()); |
8535 set_current_block(join_block); | 8584 set_current_block(join_block); |
8536 // We did not materialize any value in the predecessor environments, | 8585 // We did not materialize any value in the predecessor environments, |
8537 // so there is no need to handle it here. | 8586 // so there is no need to handle it here. |
8538 } | 8587 } |
8539 } | 8588 } |
8540 | 8589 |
8541 | 8590 |
8542 void HGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { | 8591 void HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { |
8543 CHECK_ALIVE(VisitForValue(expr->left())); | 8592 CHECK_ALIVE(VisitForValue(expr->left())); |
8544 CHECK_ALIVE(VisitForValue(expr->right())); | 8593 CHECK_ALIVE(VisitForValue(expr->right())); |
8545 HValue* right = Pop(); | 8594 HValue* right = Pop(); |
8546 HValue* left = Pop(); | 8595 HValue* left = Pop(); |
8547 HInstruction* instr = BuildBinaryOperation(expr, left, right); | 8596 HInstruction* instr = BuildBinaryOperation(expr, left, right); |
8548 instr->set_position(expr->position()); | 8597 instr->set_position(expr->position()); |
8549 return ast_context()->ReturnInstruction(instr, expr->id()); | 8598 return ast_context()->ReturnInstruction(instr, expr->id()); |
8550 } | 8599 } |
8551 | 8600 |
8552 | 8601 |
8553 Representation HGraphBuilder::ToRepresentation(TypeInfo info) { | 8602 Representation HOptimizedGraphBuilder::ToRepresentation(TypeInfo info) { |
8554 if (info.IsUninitialized()) return Representation::None(); | 8603 if (info.IsUninitialized()) return Representation::None(); |
8555 if (info.IsSmi()) return Representation::Integer32(); | 8604 if (info.IsSmi()) return Representation::Integer32(); |
8556 if (info.IsInteger32()) return Representation::Integer32(); | 8605 if (info.IsInteger32()) return Representation::Integer32(); |
8557 if (info.IsDouble()) return Representation::Double(); | 8606 if (info.IsDouble()) return Representation::Double(); |
8558 if (info.IsNumber()) return Representation::Double(); | 8607 if (info.IsNumber()) return Representation::Double(); |
8559 return Representation::Tagged(); | 8608 return Representation::Tagged(); |
8560 } | 8609 } |
8561 | 8610 |
8562 | 8611 |
8563 void HGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, | 8612 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, |
8564 HTypeof* typeof_expr, | 8613 HTypeof* typeof_expr, |
8565 Handle<String> check) { | 8614 Handle<String> check) { |
8566 // Note: The HTypeof itself is removed during canonicalization, if possible. | 8615 // Note: The HTypeof itself is removed during canonicalization, if possible. |
8567 HValue* value = typeof_expr->value(); | 8616 HValue* value = typeof_expr->value(); |
8568 HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check); | 8617 HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check); |
8569 instr->set_position(expr->position()); | 8618 instr->set_position(expr->position()); |
8570 return ast_context()->ReturnControl(instr, expr->id()); | 8619 return ast_context()->ReturnControl(instr, expr->id()); |
8571 } | 8620 } |
8572 | 8621 |
8573 | 8622 |
8574 static bool MatchLiteralCompareNil(HValue* left, | 8623 static bool MatchLiteralCompareNil(HValue* left, |
8575 Token::Value op, | 8624 Token::Value op, |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8625 | 8674 |
8626 static bool IsLiteralCompareBool(HValue* left, | 8675 static bool IsLiteralCompareBool(HValue* left, |
8627 Token::Value op, | 8676 Token::Value op, |
8628 HValue* right) { | 8677 HValue* right) { |
8629 return op == Token::EQ_STRICT && | 8678 return op == Token::EQ_STRICT && |
8630 ((left->IsConstant() && HConstant::cast(left)->handle()->IsBoolean()) || | 8679 ((left->IsConstant() && HConstant::cast(left)->handle()->IsBoolean()) || |
8631 (right->IsConstant() && HConstant::cast(right)->handle()->IsBoolean())); | 8680 (right->IsConstant() && HConstant::cast(right)->handle()->IsBoolean())); |
8632 } | 8681 } |
8633 | 8682 |
8634 | 8683 |
8635 void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) { | 8684 void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { |
8636 ASSERT(!HasStackOverflow()); | 8685 ASSERT(!HasStackOverflow()); |
8637 ASSERT(current_block() != NULL); | 8686 ASSERT(current_block() != NULL); |
8638 ASSERT(current_block()->HasPredecessor()); | 8687 ASSERT(current_block()->HasPredecessor()); |
8639 if (IsClassOfTest(expr)) { | 8688 if (IsClassOfTest(expr)) { |
8640 CallRuntime* call = expr->left()->AsCallRuntime(); | 8689 CallRuntime* call = expr->left()->AsCallRuntime(); |
8641 ASSERT(call->arguments()->length() == 1); | 8690 ASSERT(call->arguments()->length() == 1); |
8642 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 8691 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
8643 HValue* value = Pop(); | 8692 HValue* value = Pop(); |
8644 Literal* literal = expr->right()->AsLiteral(); | 8693 Literal* literal = expr->right()->AsLiteral(); |
8645 Handle<String> rhs = Handle<String>::cast(literal->handle()); | 8694 Handle<String> rhs = Handle<String>::cast(literal->handle()); |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8778 HCompareIDAndBranch* result = | 8827 HCompareIDAndBranch* result = |
8779 new(zone()) HCompareIDAndBranch(left, right, op); | 8828 new(zone()) HCompareIDAndBranch(left, right, op); |
8780 result->set_observed_input_representation(left_rep, right_rep); | 8829 result->set_observed_input_representation(left_rep, right_rep); |
8781 result->set_position(expr->position()); | 8830 result->set_position(expr->position()); |
8782 return ast_context()->ReturnControl(result, expr->id()); | 8831 return ast_context()->ReturnControl(result, expr->id()); |
8783 } | 8832 } |
8784 } | 8833 } |
8785 } | 8834 } |
8786 | 8835 |
8787 | 8836 |
8788 void HGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, | 8837 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, |
8789 HValue* value, | 8838 HValue* value, |
8790 NilValue nil) { | 8839 NilValue nil) { |
8791 ASSERT(!HasStackOverflow()); | 8840 ASSERT(!HasStackOverflow()); |
8792 ASSERT(current_block() != NULL); | 8841 ASSERT(current_block() != NULL); |
8793 ASSERT(current_block()->HasPredecessor()); | 8842 ASSERT(current_block()->HasPredecessor()); |
8794 EqualityKind kind = | 8843 EqualityKind kind = |
8795 expr->op() == Token::EQ_STRICT ? kStrictEquality : kNonStrictEquality; | 8844 expr->op() == Token::EQ_STRICT ? kStrictEquality : kNonStrictEquality; |
8796 HIsNilAndBranch* instr = new(zone()) HIsNilAndBranch(value, kind, nil); | 8845 HIsNilAndBranch* instr = new(zone()) HIsNilAndBranch(value, kind, nil); |
8797 instr->set_position(expr->position()); | 8846 instr->set_position(expr->position()); |
8798 return ast_context()->ReturnControl(instr, expr->id()); | 8847 return ast_context()->ReturnControl(instr, expr->id()); |
8799 } | 8848 } |
8800 | 8849 |
8801 | 8850 |
8802 HInstruction* HGraphBuilder::BuildThisFunction() { | 8851 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { |
8803 // If we share optimized code between different closures, the | 8852 // If we share optimized code between different closures, the |
8804 // this-function is not a constant, except inside an inlined body. | 8853 // this-function is not a constant, except inside an inlined body. |
8805 if (function_state()->outer() != NULL) { | 8854 if (function_state()->outer() != NULL) { |
8806 return new(zone()) HConstant( | 8855 return new(zone()) HConstant( |
8807 function_state()->compilation_info()->closure(), | 8856 function_state()->compilation_info()->closure(), |
8808 Representation::Tagged()); | 8857 Representation::Tagged()); |
8809 } else { | 8858 } else { |
8810 return new(zone()) HThisFunction; | 8859 return new(zone()) HThisFunction; |
8811 } | 8860 } |
8812 } | 8861 } |
8813 | 8862 |
8814 | 8863 |
8815 void HGraphBuilder::VisitThisFunction(ThisFunction* expr) { | 8864 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { |
8816 ASSERT(!HasStackOverflow()); | 8865 ASSERT(!HasStackOverflow()); |
8817 ASSERT(current_block() != NULL); | 8866 ASSERT(current_block() != NULL); |
8818 ASSERT(current_block()->HasPredecessor()); | 8867 ASSERT(current_block()->HasPredecessor()); |
8819 HInstruction* instr = BuildThisFunction(); | 8868 HInstruction* instr = BuildThisFunction(); |
8820 return ast_context()->ReturnInstruction(instr, expr->id()); | 8869 return ast_context()->ReturnInstruction(instr, expr->id()); |
8821 } | 8870 } |
8822 | 8871 |
8823 | 8872 |
8824 void HGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) { | 8873 void HOptimizedGraphBuilder::VisitDeclarations( |
| 8874 ZoneList<Declaration*>* declarations) { |
8825 ASSERT(globals_.is_empty()); | 8875 ASSERT(globals_.is_empty()); |
8826 AstVisitor::VisitDeclarations(declarations); | 8876 AstVisitor::VisitDeclarations(declarations); |
8827 if (!globals_.is_empty()) { | 8877 if (!globals_.is_empty()) { |
8828 Handle<FixedArray> array = | 8878 Handle<FixedArray> array = |
8829 isolate()->factory()->NewFixedArray(globals_.length(), TENURED); | 8879 isolate()->factory()->NewFixedArray(globals_.length(), TENURED); |
8830 for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i)); | 8880 for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i)); |
8831 int flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) | | 8881 int flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) | |
8832 DeclareGlobalsNativeFlag::encode(info()->is_native()) | | 8882 DeclareGlobalsNativeFlag::encode(info()->is_native()) | |
8833 DeclareGlobalsLanguageMode::encode(info()->language_mode()); | 8883 DeclareGlobalsLanguageMode::encode(info()->language_mode()); |
8834 HInstruction* result = new(zone()) HDeclareGlobals( | 8884 HInstruction* result = new(zone()) HDeclareGlobals( |
8835 environment()->LookupContext(), array, flags); | 8885 environment()->LookupContext(), array, flags); |
8836 AddInstruction(result); | 8886 AddInstruction(result); |
8837 globals_.Clear(); | 8887 globals_.Clear(); |
8838 } | 8888 } |
8839 } | 8889 } |
8840 | 8890 |
8841 | 8891 |
8842 void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) { | 8892 void HOptimizedGraphBuilder::VisitVariableDeclaration( |
| 8893 VariableDeclaration* declaration) { |
8843 VariableProxy* proxy = declaration->proxy(); | 8894 VariableProxy* proxy = declaration->proxy(); |
8844 VariableMode mode = declaration->mode(); | 8895 VariableMode mode = declaration->mode(); |
8845 Variable* variable = proxy->var(); | 8896 Variable* variable = proxy->var(); |
8846 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; | 8897 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; |
8847 switch (variable->location()) { | 8898 switch (variable->location()) { |
8848 case Variable::UNALLOCATED: | 8899 case Variable::UNALLOCATED: |
8849 globals_.Add(variable->name(), zone()); | 8900 globals_.Add(variable->name(), zone()); |
8850 globals_.Add(variable->binding_needs_init() | 8901 globals_.Add(variable->binding_needs_init() |
8851 ? isolate()->factory()->the_hole_value() | 8902 ? isolate()->factory()->the_hole_value() |
8852 : isolate()->factory()->undefined_value(), zone()); | 8903 : isolate()->factory()->undefined_value(), zone()); |
(...skipping 16 matching lines...) Expand all Loading... |
8869 AddSimulate(proxy->id(), REMOVABLE_SIMULATE); | 8920 AddSimulate(proxy->id(), REMOVABLE_SIMULATE); |
8870 } | 8921 } |
8871 } | 8922 } |
8872 break; | 8923 break; |
8873 case Variable::LOOKUP: | 8924 case Variable::LOOKUP: |
8874 return Bailout("unsupported lookup slot in declaration"); | 8925 return Bailout("unsupported lookup slot in declaration"); |
8875 } | 8926 } |
8876 } | 8927 } |
8877 | 8928 |
8878 | 8929 |
8879 void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) { | 8930 void HOptimizedGraphBuilder::VisitFunctionDeclaration( |
| 8931 FunctionDeclaration* declaration) { |
8880 VariableProxy* proxy = declaration->proxy(); | 8932 VariableProxy* proxy = declaration->proxy(); |
8881 Variable* variable = proxy->var(); | 8933 Variable* variable = proxy->var(); |
8882 switch (variable->location()) { | 8934 switch (variable->location()) { |
8883 case Variable::UNALLOCATED: { | 8935 case Variable::UNALLOCATED: { |
8884 globals_.Add(variable->name(), zone()); | 8936 globals_.Add(variable->name(), zone()); |
8885 Handle<SharedFunctionInfo> function = | 8937 Handle<SharedFunctionInfo> function = |
8886 Compiler::BuildFunctionInfo(declaration->fun(), info()->script()); | 8938 Compiler::BuildFunctionInfo(declaration->fun(), info()->script()); |
8887 // Check for stack-overflow exception. | 8939 // Check for stack-overflow exception. |
8888 if (function.is_null()) return SetStackOverflow(); | 8940 if (function.is_null()) return SetStackOverflow(); |
8889 globals_.Add(function, zone()); | 8941 globals_.Add(function, zone()); |
(...skipping 17 matching lines...) Expand all Loading... |
8907 AddSimulate(proxy->id(), REMOVABLE_SIMULATE); | 8959 AddSimulate(proxy->id(), REMOVABLE_SIMULATE); |
8908 } | 8960 } |
8909 break; | 8961 break; |
8910 } | 8962 } |
8911 case Variable::LOOKUP: | 8963 case Variable::LOOKUP: |
8912 return Bailout("unsupported lookup slot in declaration"); | 8964 return Bailout("unsupported lookup slot in declaration"); |
8913 } | 8965 } |
8914 } | 8966 } |
8915 | 8967 |
8916 | 8968 |
8917 void HGraphBuilder::VisitModuleDeclaration(ModuleDeclaration* declaration) { | 8969 void HOptimizedGraphBuilder::VisitModuleDeclaration( |
| 8970 ModuleDeclaration* declaration) { |
8918 UNREACHABLE(); | 8971 UNREACHABLE(); |
8919 } | 8972 } |
8920 | 8973 |
8921 | 8974 |
8922 void HGraphBuilder::VisitImportDeclaration(ImportDeclaration* declaration) { | 8975 void HOptimizedGraphBuilder::VisitImportDeclaration( |
| 8976 ImportDeclaration* declaration) { |
8923 UNREACHABLE(); | 8977 UNREACHABLE(); |
8924 } | 8978 } |
8925 | 8979 |
8926 | 8980 |
8927 void HGraphBuilder::VisitExportDeclaration(ExportDeclaration* declaration) { | 8981 void HOptimizedGraphBuilder::VisitExportDeclaration( |
| 8982 ExportDeclaration* declaration) { |
8928 UNREACHABLE(); | 8983 UNREACHABLE(); |
8929 } | 8984 } |
8930 | 8985 |
8931 | 8986 |
8932 void HGraphBuilder::VisitModuleLiteral(ModuleLiteral* module) { | 8987 void HOptimizedGraphBuilder::VisitModuleLiteral(ModuleLiteral* module) { |
8933 UNREACHABLE(); | 8988 UNREACHABLE(); |
8934 } | 8989 } |
8935 | 8990 |
8936 | 8991 |
8937 void HGraphBuilder::VisitModuleVariable(ModuleVariable* module) { | 8992 void HOptimizedGraphBuilder::VisitModuleVariable(ModuleVariable* module) { |
8938 UNREACHABLE(); | 8993 UNREACHABLE(); |
8939 } | 8994 } |
8940 | 8995 |
8941 | 8996 |
8942 void HGraphBuilder::VisitModulePath(ModulePath* module) { | 8997 void HOptimizedGraphBuilder::VisitModulePath(ModulePath* module) { |
8943 UNREACHABLE(); | 8998 UNREACHABLE(); |
8944 } | 8999 } |
8945 | 9000 |
8946 | 9001 |
8947 void HGraphBuilder::VisitModuleUrl(ModuleUrl* module) { | 9002 void HOptimizedGraphBuilder::VisitModuleUrl(ModuleUrl* module) { |
8948 UNREACHABLE(); | 9003 UNREACHABLE(); |
8949 } | 9004 } |
8950 | 9005 |
8951 | 9006 |
8952 void HGraphBuilder::VisitModuleStatement(ModuleStatement* stmt) { | 9007 void HOptimizedGraphBuilder::VisitModuleStatement(ModuleStatement* stmt) { |
8953 UNREACHABLE(); | 9008 UNREACHABLE(); |
8954 } | 9009 } |
8955 | 9010 |
8956 | 9011 |
8957 // Generators for inline runtime functions. | 9012 // Generators for inline runtime functions. |
8958 // Support for types. | 9013 // Support for types. |
8959 void HGraphBuilder::GenerateIsSmi(CallRuntime* call) { | 9014 void HOptimizedGraphBuilder::GenerateIsSmi(CallRuntime* call) { |
8960 ASSERT(call->arguments()->length() == 1); | 9015 ASSERT(call->arguments()->length() == 1); |
8961 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9016 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
8962 HValue* value = Pop(); | 9017 HValue* value = Pop(); |
8963 HIsSmiAndBranch* result = new(zone()) HIsSmiAndBranch(value); | 9018 HIsSmiAndBranch* result = new(zone()) HIsSmiAndBranch(value); |
8964 return ast_context()->ReturnControl(result, call->id()); | 9019 return ast_context()->ReturnControl(result, call->id()); |
8965 } | 9020 } |
8966 | 9021 |
8967 | 9022 |
8968 void HGraphBuilder::GenerateIsSpecObject(CallRuntime* call) { | 9023 void HOptimizedGraphBuilder::GenerateIsSpecObject(CallRuntime* call) { |
8969 ASSERT(call->arguments()->length() == 1); | 9024 ASSERT(call->arguments()->length() == 1); |
8970 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9025 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
8971 HValue* value = Pop(); | 9026 HValue* value = Pop(); |
8972 HHasInstanceTypeAndBranch* result = | 9027 HHasInstanceTypeAndBranch* result = |
8973 new(zone()) HHasInstanceTypeAndBranch(value, | 9028 new(zone()) HHasInstanceTypeAndBranch(value, |
8974 FIRST_SPEC_OBJECT_TYPE, | 9029 FIRST_SPEC_OBJECT_TYPE, |
8975 LAST_SPEC_OBJECT_TYPE); | 9030 LAST_SPEC_OBJECT_TYPE); |
8976 return ast_context()->ReturnControl(result, call->id()); | 9031 return ast_context()->ReturnControl(result, call->id()); |
8977 } | 9032 } |
8978 | 9033 |
8979 | 9034 |
8980 void HGraphBuilder::GenerateIsFunction(CallRuntime* call) { | 9035 void HOptimizedGraphBuilder::GenerateIsFunction(CallRuntime* call) { |
8981 ASSERT(call->arguments()->length() == 1); | 9036 ASSERT(call->arguments()->length() == 1); |
8982 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9037 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
8983 HValue* value = Pop(); | 9038 HValue* value = Pop(); |
8984 HHasInstanceTypeAndBranch* result = | 9039 HHasInstanceTypeAndBranch* result = |
8985 new(zone()) HHasInstanceTypeAndBranch(value, JS_FUNCTION_TYPE); | 9040 new(zone()) HHasInstanceTypeAndBranch(value, JS_FUNCTION_TYPE); |
8986 return ast_context()->ReturnControl(result, call->id()); | 9041 return ast_context()->ReturnControl(result, call->id()); |
8987 } | 9042 } |
8988 | 9043 |
8989 | 9044 |
8990 void HGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) { | 9045 void HOptimizedGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) { |
8991 ASSERT(call->arguments()->length() == 1); | 9046 ASSERT(call->arguments()->length() == 1); |
8992 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9047 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
8993 HValue* value = Pop(); | 9048 HValue* value = Pop(); |
8994 HHasCachedArrayIndexAndBranch* result = | 9049 HHasCachedArrayIndexAndBranch* result = |
8995 new(zone()) HHasCachedArrayIndexAndBranch(value); | 9050 new(zone()) HHasCachedArrayIndexAndBranch(value); |
8996 return ast_context()->ReturnControl(result, call->id()); | 9051 return ast_context()->ReturnControl(result, call->id()); |
8997 } | 9052 } |
8998 | 9053 |
8999 | 9054 |
9000 void HGraphBuilder::GenerateIsArray(CallRuntime* call) { | 9055 void HOptimizedGraphBuilder::GenerateIsArray(CallRuntime* call) { |
9001 ASSERT(call->arguments()->length() == 1); | 9056 ASSERT(call->arguments()->length() == 1); |
9002 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9057 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9003 HValue* value = Pop(); | 9058 HValue* value = Pop(); |
9004 HHasInstanceTypeAndBranch* result = | 9059 HHasInstanceTypeAndBranch* result = |
9005 new(zone()) HHasInstanceTypeAndBranch(value, JS_ARRAY_TYPE); | 9060 new(zone()) HHasInstanceTypeAndBranch(value, JS_ARRAY_TYPE); |
9006 return ast_context()->ReturnControl(result, call->id()); | 9061 return ast_context()->ReturnControl(result, call->id()); |
9007 } | 9062 } |
9008 | 9063 |
9009 | 9064 |
9010 void HGraphBuilder::GenerateIsRegExp(CallRuntime* call) { | 9065 void HOptimizedGraphBuilder::GenerateIsRegExp(CallRuntime* call) { |
9011 ASSERT(call->arguments()->length() == 1); | 9066 ASSERT(call->arguments()->length() == 1); |
9012 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9067 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9013 HValue* value = Pop(); | 9068 HValue* value = Pop(); |
9014 HHasInstanceTypeAndBranch* result = | 9069 HHasInstanceTypeAndBranch* result = |
9015 new(zone()) HHasInstanceTypeAndBranch(value, JS_REGEXP_TYPE); | 9070 new(zone()) HHasInstanceTypeAndBranch(value, JS_REGEXP_TYPE); |
9016 return ast_context()->ReturnControl(result, call->id()); | 9071 return ast_context()->ReturnControl(result, call->id()); |
9017 } | 9072 } |
9018 | 9073 |
9019 | 9074 |
9020 void HGraphBuilder::GenerateIsObject(CallRuntime* call) { | 9075 void HOptimizedGraphBuilder::GenerateIsObject(CallRuntime* call) { |
9021 ASSERT(call->arguments()->length() == 1); | 9076 ASSERT(call->arguments()->length() == 1); |
9022 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9077 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9023 HValue* value = Pop(); | 9078 HValue* value = Pop(); |
9024 HIsObjectAndBranch* result = new(zone()) HIsObjectAndBranch(value); | 9079 HIsObjectAndBranch* result = new(zone()) HIsObjectAndBranch(value); |
9025 return ast_context()->ReturnControl(result, call->id()); | 9080 return ast_context()->ReturnControl(result, call->id()); |
9026 } | 9081 } |
9027 | 9082 |
9028 | 9083 |
9029 void HGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) { | 9084 void HOptimizedGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) { |
9030 return Bailout("inlined runtime function: IsNonNegativeSmi"); | 9085 return Bailout("inlined runtime function: IsNonNegativeSmi"); |
9031 } | 9086 } |
9032 | 9087 |
9033 | 9088 |
9034 void HGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) { | 9089 void HOptimizedGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) { |
9035 ASSERT(call->arguments()->length() == 1); | 9090 ASSERT(call->arguments()->length() == 1); |
9036 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9091 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9037 HValue* value = Pop(); | 9092 HValue* value = Pop(); |
9038 HIsUndetectableAndBranch* result = | 9093 HIsUndetectableAndBranch* result = |
9039 new(zone()) HIsUndetectableAndBranch(value); | 9094 new(zone()) HIsUndetectableAndBranch(value); |
9040 return ast_context()->ReturnControl(result, call->id()); | 9095 return ast_context()->ReturnControl(result, call->id()); |
9041 } | 9096 } |
9042 | 9097 |
9043 | 9098 |
9044 void HGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf( | 9099 void HOptimizedGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf( |
9045 CallRuntime* call) { | 9100 CallRuntime* call) { |
9046 return Bailout( | 9101 return Bailout( |
9047 "inlined runtime function: IsStringWrapperSafeForDefaultValueOf"); | 9102 "inlined runtime function: IsStringWrapperSafeForDefaultValueOf"); |
9048 } | 9103 } |
9049 | 9104 |
9050 | 9105 |
9051 // Support for construct call checks. | 9106 // Support for construct call checks. |
9052 void HGraphBuilder::GenerateIsConstructCall(CallRuntime* call) { | 9107 void HOptimizedGraphBuilder::GenerateIsConstructCall(CallRuntime* call) { |
9053 ASSERT(call->arguments()->length() == 0); | 9108 ASSERT(call->arguments()->length() == 0); |
9054 if (function_state()->outer() != NULL) { | 9109 if (function_state()->outer() != NULL) { |
9055 // We are generating graph for inlined function. | 9110 // We are generating graph for inlined function. |
9056 HValue* value = function_state()->inlining_kind() == CONSTRUCT_CALL_RETURN | 9111 HValue* value = function_state()->inlining_kind() == CONSTRUCT_CALL_RETURN |
9057 ? graph()->GetConstantTrue() | 9112 ? graph()->GetConstantTrue() |
9058 : graph()->GetConstantFalse(); | 9113 : graph()->GetConstantFalse(); |
9059 return ast_context()->ReturnValue(value); | 9114 return ast_context()->ReturnValue(value); |
9060 } else { | 9115 } else { |
9061 return ast_context()->ReturnControl(new(zone()) HIsConstructCallAndBranch, | 9116 return ast_context()->ReturnControl(new(zone()) HIsConstructCallAndBranch, |
9062 call->id()); | 9117 call->id()); |
9063 } | 9118 } |
9064 } | 9119 } |
9065 | 9120 |
9066 | 9121 |
9067 // Support for arguments.length and arguments[?]. | 9122 // Support for arguments.length and arguments[?]. |
9068 void HGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { | 9123 void HOptimizedGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { |
9069 // Our implementation of arguments (based on this stack frame or an | 9124 // Our implementation of arguments (based on this stack frame or an |
9070 // adapter below it) does not work for inlined functions. This runtime | 9125 // adapter below it) does not work for inlined functions. This runtime |
9071 // function is blacklisted by AstNode::IsInlineable. | 9126 // function is blacklisted by AstNode::IsInlineable. |
9072 ASSERT(function_state()->outer() == NULL); | 9127 ASSERT(function_state()->outer() == NULL); |
9073 ASSERT(call->arguments()->length() == 0); | 9128 ASSERT(call->arguments()->length() == 0); |
9074 HInstruction* elements = AddInstruction( | 9129 HInstruction* elements = AddInstruction( |
9075 new(zone()) HArgumentsElements(false)); | 9130 new(zone()) HArgumentsElements(false)); |
9076 HArgumentsLength* result = new(zone()) HArgumentsLength(elements); | 9131 HArgumentsLength* result = new(zone()) HArgumentsLength(elements); |
9077 return ast_context()->ReturnInstruction(result, call->id()); | 9132 return ast_context()->ReturnInstruction(result, call->id()); |
9078 } | 9133 } |
9079 | 9134 |
9080 | 9135 |
9081 void HGraphBuilder::GenerateArguments(CallRuntime* call) { | 9136 void HOptimizedGraphBuilder::GenerateArguments(CallRuntime* call) { |
9082 // Our implementation of arguments (based on this stack frame or an | 9137 // Our implementation of arguments (based on this stack frame or an |
9083 // adapter below it) does not work for inlined functions. This runtime | 9138 // adapter below it) does not work for inlined functions. This runtime |
9084 // function is blacklisted by AstNode::IsInlineable. | 9139 // function is blacklisted by AstNode::IsInlineable. |
9085 ASSERT(function_state()->outer() == NULL); | 9140 ASSERT(function_state()->outer() == NULL); |
9086 ASSERT(call->arguments()->length() == 1); | 9141 ASSERT(call->arguments()->length() == 1); |
9087 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9142 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9088 HValue* index = Pop(); | 9143 HValue* index = Pop(); |
9089 HInstruction* elements = AddInstruction( | 9144 HInstruction* elements = AddInstruction( |
9090 new(zone()) HArgumentsElements(false)); | 9145 new(zone()) HArgumentsElements(false)); |
9091 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); | 9146 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); |
9092 HInstruction* checked_index = | 9147 HInstruction* checked_index = |
9093 AddInstruction(new(zone()) HBoundsCheck(index, length)); | 9148 AddInstruction(new(zone()) HBoundsCheck(index, length)); |
9094 HAccessArgumentsAt* result = | 9149 HAccessArgumentsAt* result = |
9095 new(zone()) HAccessArgumentsAt(elements, length, checked_index); | 9150 new(zone()) HAccessArgumentsAt(elements, length, checked_index); |
9096 return ast_context()->ReturnInstruction(result, call->id()); | 9151 return ast_context()->ReturnInstruction(result, call->id()); |
9097 } | 9152 } |
9098 | 9153 |
9099 | 9154 |
9100 // Support for accessing the class and value fields of an object. | 9155 // Support for accessing the class and value fields of an object. |
9101 void HGraphBuilder::GenerateClassOf(CallRuntime* call) { | 9156 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { |
9102 // The special form detected by IsClassOfTest is detected before we get here | 9157 // The special form detected by IsClassOfTest is detected before we get here |
9103 // and does not cause a bailout. | 9158 // and does not cause a bailout. |
9104 return Bailout("inlined runtime function: ClassOf"); | 9159 return Bailout("inlined runtime function: ClassOf"); |
9105 } | 9160 } |
9106 | 9161 |
9107 | 9162 |
9108 void HGraphBuilder::GenerateValueOf(CallRuntime* call) { | 9163 void HOptimizedGraphBuilder::GenerateValueOf(CallRuntime* call) { |
9109 ASSERT(call->arguments()->length() == 1); | 9164 ASSERT(call->arguments()->length() == 1); |
9110 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9165 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9111 HValue* value = Pop(); | 9166 HValue* value = Pop(); |
9112 HValueOf* result = new(zone()) HValueOf(value); | 9167 HValueOf* result = new(zone()) HValueOf(value); |
9113 return ast_context()->ReturnInstruction(result, call->id()); | 9168 return ast_context()->ReturnInstruction(result, call->id()); |
9114 } | 9169 } |
9115 | 9170 |
9116 | 9171 |
9117 void HGraphBuilder::GenerateDateField(CallRuntime* call) { | 9172 void HOptimizedGraphBuilder::GenerateDateField(CallRuntime* call) { |
9118 ASSERT(call->arguments()->length() == 2); | 9173 ASSERT(call->arguments()->length() == 2); |
9119 ASSERT_NE(NULL, call->arguments()->at(1)->AsLiteral()); | 9174 ASSERT_NE(NULL, call->arguments()->at(1)->AsLiteral()); |
9120 Smi* index = Smi::cast(*(call->arguments()->at(1)->AsLiteral()->handle())); | 9175 Smi* index = Smi::cast(*(call->arguments()->at(1)->AsLiteral()->handle())); |
9121 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9176 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9122 HValue* date = Pop(); | 9177 HValue* date = Pop(); |
9123 HDateField* result = new(zone()) HDateField(date, index); | 9178 HDateField* result = new(zone()) HDateField(date, index); |
9124 return ast_context()->ReturnInstruction(result, call->id()); | 9179 return ast_context()->ReturnInstruction(result, call->id()); |
9125 } | 9180 } |
9126 | 9181 |
9127 | 9182 |
9128 void HGraphBuilder::GenerateSetValueOf(CallRuntime* call) { | 9183 void HOptimizedGraphBuilder::GenerateSetValueOf(CallRuntime* call) { |
9129 ASSERT(call->arguments()->length() == 2); | 9184 ASSERT(call->arguments()->length() == 2); |
9130 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9185 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9131 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 9186 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
9132 HValue* value = Pop(); | 9187 HValue* value = Pop(); |
9133 HValue* object = Pop(); | 9188 HValue* object = Pop(); |
9134 // Check if object is a not a smi. | 9189 // Check if object is a not a smi. |
9135 HIsSmiAndBranch* smicheck = new(zone()) HIsSmiAndBranch(object); | 9190 HIsSmiAndBranch* smicheck = new(zone()) HIsSmiAndBranch(object); |
9136 HBasicBlock* if_smi = graph()->CreateBasicBlock(); | 9191 HBasicBlock* if_smi = graph()->CreateBasicBlock(); |
9137 HBasicBlock* if_heap_object = graph()->CreateBasicBlock(); | 9192 HBasicBlock* if_heap_object = graph()->CreateBasicBlock(); |
9138 HBasicBlock* join = graph()->CreateBasicBlock(); | 9193 HBasicBlock* join = graph()->CreateBasicBlock(); |
(...skipping 22 matching lines...) Expand all Loading... |
9161 true, // in-object store. | 9216 true, // in-object store. |
9162 JSValue::kValueOffset)); | 9217 JSValue::kValueOffset)); |
9163 if_js_value->Goto(join); | 9218 if_js_value->Goto(join); |
9164 join->SetJoinId(call->id()); | 9219 join->SetJoinId(call->id()); |
9165 set_current_block(join); | 9220 set_current_block(join); |
9166 return ast_context()->ReturnValue(value); | 9221 return ast_context()->ReturnValue(value); |
9167 } | 9222 } |
9168 | 9223 |
9169 | 9224 |
9170 // Fast support for charCodeAt(n). | 9225 // Fast support for charCodeAt(n). |
9171 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { | 9226 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { |
9172 ASSERT(call->arguments()->length() == 2); | 9227 ASSERT(call->arguments()->length() == 2); |
9173 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9228 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9174 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 9229 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
9175 HValue* index = Pop(); | 9230 HValue* index = Pop(); |
9176 HValue* string = Pop(); | 9231 HValue* string = Pop(); |
9177 HValue* context = environment()->LookupContext(); | 9232 HValue* context = environment()->LookupContext(); |
9178 HStringCharCodeAt* result = BuildStringCharCodeAt(context, string, index); | 9233 HStringCharCodeAt* result = BuildStringCharCodeAt(context, string, index); |
9179 return ast_context()->ReturnInstruction(result, call->id()); | 9234 return ast_context()->ReturnInstruction(result, call->id()); |
9180 } | 9235 } |
9181 | 9236 |
9182 | 9237 |
9183 // Fast support for string.charAt(n) and string[n]. | 9238 // Fast support for string.charAt(n) and string[n]. |
9184 void HGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { | 9239 void HOptimizedGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { |
9185 ASSERT(call->arguments()->length() == 1); | 9240 ASSERT(call->arguments()->length() == 1); |
9186 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9241 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9187 HValue* char_code = Pop(); | 9242 HValue* char_code = Pop(); |
9188 HValue* context = environment()->LookupContext(); | 9243 HValue* context = environment()->LookupContext(); |
9189 HStringCharFromCode* result = | 9244 HStringCharFromCode* result = |
9190 new(zone()) HStringCharFromCode(context, char_code); | 9245 new(zone()) HStringCharFromCode(context, char_code); |
9191 return ast_context()->ReturnInstruction(result, call->id()); | 9246 return ast_context()->ReturnInstruction(result, call->id()); |
9192 } | 9247 } |
9193 | 9248 |
9194 | 9249 |
9195 // Fast support for string.charAt(n) and string[n]. | 9250 // Fast support for string.charAt(n) and string[n]. |
9196 void HGraphBuilder::GenerateStringCharAt(CallRuntime* call) { | 9251 void HOptimizedGraphBuilder::GenerateStringCharAt(CallRuntime* call) { |
9197 ASSERT(call->arguments()->length() == 2); | 9252 ASSERT(call->arguments()->length() == 2); |
9198 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9253 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9199 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 9254 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
9200 HValue* index = Pop(); | 9255 HValue* index = Pop(); |
9201 HValue* string = Pop(); | 9256 HValue* string = Pop(); |
9202 HValue* context = environment()->LookupContext(); | 9257 HValue* context = environment()->LookupContext(); |
9203 HStringCharCodeAt* char_code = BuildStringCharCodeAt(context, string, index); | 9258 HStringCharCodeAt* char_code = BuildStringCharCodeAt(context, string, index); |
9204 AddInstruction(char_code); | 9259 AddInstruction(char_code); |
9205 HStringCharFromCode* result = | 9260 HStringCharFromCode* result = |
9206 new(zone()) HStringCharFromCode(context, char_code); | 9261 new(zone()) HStringCharFromCode(context, char_code); |
9207 return ast_context()->ReturnInstruction(result, call->id()); | 9262 return ast_context()->ReturnInstruction(result, call->id()); |
9208 } | 9263 } |
9209 | 9264 |
9210 | 9265 |
9211 // Fast support for object equality testing. | 9266 // Fast support for object equality testing. |
9212 void HGraphBuilder::GenerateObjectEquals(CallRuntime* call) { | 9267 void HOptimizedGraphBuilder::GenerateObjectEquals(CallRuntime* call) { |
9213 ASSERT(call->arguments()->length() == 2); | 9268 ASSERT(call->arguments()->length() == 2); |
9214 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9269 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9215 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 9270 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
9216 HValue* right = Pop(); | 9271 HValue* right = Pop(); |
9217 HValue* left = Pop(); | 9272 HValue* left = Pop(); |
9218 HCompareObjectEqAndBranch* result = | 9273 HCompareObjectEqAndBranch* result = |
9219 new(zone()) HCompareObjectEqAndBranch(left, right); | 9274 new(zone()) HCompareObjectEqAndBranch(left, right); |
9220 return ast_context()->ReturnControl(result, call->id()); | 9275 return ast_context()->ReturnControl(result, call->id()); |
9221 } | 9276 } |
9222 | 9277 |
9223 | 9278 |
9224 void HGraphBuilder::GenerateLog(CallRuntime* call) { | 9279 void HOptimizedGraphBuilder::GenerateLog(CallRuntime* call) { |
9225 // %_Log is ignored in optimized code. | 9280 // %_Log is ignored in optimized code. |
9226 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); | 9281 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); |
9227 } | 9282 } |
9228 | 9283 |
9229 | 9284 |
9230 // Fast support for Math.random(). | 9285 // Fast support for Math.random(). |
9231 void HGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) { | 9286 void HOptimizedGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) { |
9232 HValue* context = environment()->LookupContext(); | 9287 HValue* context = environment()->LookupContext(); |
9233 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 9288 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
9234 AddInstruction(global_object); | 9289 AddInstruction(global_object); |
9235 HRandom* result = new(zone()) HRandom(global_object); | 9290 HRandom* result = new(zone()) HRandom(global_object); |
9236 return ast_context()->ReturnInstruction(result, call->id()); | 9291 return ast_context()->ReturnInstruction(result, call->id()); |
9237 } | 9292 } |
9238 | 9293 |
9239 | 9294 |
9240 // Fast support for StringAdd. | 9295 // Fast support for StringAdd. |
9241 void HGraphBuilder::GenerateStringAdd(CallRuntime* call) { | 9296 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { |
9242 ASSERT_EQ(2, call->arguments()->length()); | 9297 ASSERT_EQ(2, call->arguments()->length()); |
9243 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 9298 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
9244 HValue* context = environment()->LookupContext(); | 9299 HValue* context = environment()->LookupContext(); |
9245 HCallStub* result = new(zone()) HCallStub(context, CodeStub::StringAdd, 2); | 9300 HCallStub* result = new(zone()) HCallStub(context, CodeStub::StringAdd, 2); |
9246 Drop(2); | 9301 Drop(2); |
9247 return ast_context()->ReturnInstruction(result, call->id()); | 9302 return ast_context()->ReturnInstruction(result, call->id()); |
9248 } | 9303 } |
9249 | 9304 |
9250 | 9305 |
9251 // Fast support for SubString. | 9306 // Fast support for SubString. |
9252 void HGraphBuilder::GenerateSubString(CallRuntime* call) { | 9307 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { |
9253 ASSERT_EQ(3, call->arguments()->length()); | 9308 ASSERT_EQ(3, call->arguments()->length()); |
9254 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 9309 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
9255 HValue* context = environment()->LookupContext(); | 9310 HValue* context = environment()->LookupContext(); |
9256 HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3); | 9311 HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3); |
9257 Drop(3); | 9312 Drop(3); |
9258 return ast_context()->ReturnInstruction(result, call->id()); | 9313 return ast_context()->ReturnInstruction(result, call->id()); |
9259 } | 9314 } |
9260 | 9315 |
9261 | 9316 |
9262 // Fast support for StringCompare. | 9317 // Fast support for StringCompare. |
9263 void HGraphBuilder::GenerateStringCompare(CallRuntime* call) { | 9318 void HOptimizedGraphBuilder::GenerateStringCompare(CallRuntime* call) { |
9264 ASSERT_EQ(2, call->arguments()->length()); | 9319 ASSERT_EQ(2, call->arguments()->length()); |
9265 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 9320 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
9266 HValue* context = environment()->LookupContext(); | 9321 HValue* context = environment()->LookupContext(); |
9267 HCallStub* result = | 9322 HCallStub* result = |
9268 new(zone()) HCallStub(context, CodeStub::StringCompare, 2); | 9323 new(zone()) HCallStub(context, CodeStub::StringCompare, 2); |
9269 Drop(2); | 9324 Drop(2); |
9270 return ast_context()->ReturnInstruction(result, call->id()); | 9325 return ast_context()->ReturnInstruction(result, call->id()); |
9271 } | 9326 } |
9272 | 9327 |
9273 | 9328 |
9274 // Support for direct calls from JavaScript to native RegExp code. | 9329 // Support for direct calls from JavaScript to native RegExp code. |
9275 void HGraphBuilder::GenerateRegExpExec(CallRuntime* call) { | 9330 void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) { |
9276 ASSERT_EQ(4, call->arguments()->length()); | 9331 ASSERT_EQ(4, call->arguments()->length()); |
9277 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 9332 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
9278 HValue* context = environment()->LookupContext(); | 9333 HValue* context = environment()->LookupContext(); |
9279 HCallStub* result = new(zone()) HCallStub(context, CodeStub::RegExpExec, 4); | 9334 HCallStub* result = new(zone()) HCallStub(context, CodeStub::RegExpExec, 4); |
9280 Drop(4); | 9335 Drop(4); |
9281 return ast_context()->ReturnInstruction(result, call->id()); | 9336 return ast_context()->ReturnInstruction(result, call->id()); |
9282 } | 9337 } |
9283 | 9338 |
9284 | 9339 |
9285 // Construct a RegExp exec result with two in-object properties. | 9340 // Construct a RegExp exec result with two in-object properties. |
9286 void HGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { | 9341 void HOptimizedGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { |
9287 ASSERT_EQ(3, call->arguments()->length()); | 9342 ASSERT_EQ(3, call->arguments()->length()); |
9288 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 9343 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
9289 HValue* context = environment()->LookupContext(); | 9344 HValue* context = environment()->LookupContext(); |
9290 HCallStub* result = | 9345 HCallStub* result = |
9291 new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3); | 9346 new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3); |
9292 Drop(3); | 9347 Drop(3); |
9293 return ast_context()->ReturnInstruction(result, call->id()); | 9348 return ast_context()->ReturnInstruction(result, call->id()); |
9294 } | 9349 } |
9295 | 9350 |
9296 | 9351 |
9297 // Support for fast native caches. | 9352 // Support for fast native caches. |
9298 void HGraphBuilder::GenerateGetFromCache(CallRuntime* call) { | 9353 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) { |
9299 return Bailout("inlined runtime function: GetFromCache"); | 9354 return Bailout("inlined runtime function: GetFromCache"); |
9300 } | 9355 } |
9301 | 9356 |
9302 | 9357 |
9303 // Fast support for number to string. | 9358 // Fast support for number to string. |
9304 void HGraphBuilder::GenerateNumberToString(CallRuntime* call) { | 9359 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { |
9305 ASSERT_EQ(1, call->arguments()->length()); | 9360 ASSERT_EQ(1, call->arguments()->length()); |
9306 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 9361 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
9307 HValue* context = environment()->LookupContext(); | 9362 HValue* context = environment()->LookupContext(); |
9308 HCallStub* result = | 9363 HCallStub* result = |
9309 new(zone()) HCallStub(context, CodeStub::NumberToString, 1); | 9364 new(zone()) HCallStub(context, CodeStub::NumberToString, 1); |
9310 Drop(1); | 9365 Drop(1); |
9311 return ast_context()->ReturnInstruction(result, call->id()); | 9366 return ast_context()->ReturnInstruction(result, call->id()); |
9312 } | 9367 } |
9313 | 9368 |
9314 | 9369 |
9315 // Fast call for custom callbacks. | 9370 // Fast call for custom callbacks. |
9316 void HGraphBuilder::GenerateCallFunction(CallRuntime* call) { | 9371 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) { |
9317 // 1 ~ The function to call is not itself an argument to the call. | 9372 // 1 ~ The function to call is not itself an argument to the call. |
9318 int arg_count = call->arguments()->length() - 1; | 9373 int arg_count = call->arguments()->length() - 1; |
9319 ASSERT(arg_count >= 1); // There's always at least a receiver. | 9374 ASSERT(arg_count >= 1); // There's always at least a receiver. |
9320 | 9375 |
9321 for (int i = 0; i < arg_count; ++i) { | 9376 for (int i = 0; i < arg_count; ++i) { |
9322 CHECK_ALIVE(VisitArgument(call->arguments()->at(i))); | 9377 CHECK_ALIVE(VisitArgument(call->arguments()->at(i))); |
9323 } | 9378 } |
9324 CHECK_ALIVE(VisitForValue(call->arguments()->last())); | 9379 CHECK_ALIVE(VisitForValue(call->arguments()->last())); |
9325 | 9380 |
9326 HValue* function = Pop(); | 9381 HValue* function = Pop(); |
(...skipping 23 matching lines...) Expand all Loading... |
9350 Push(call_result); | 9405 Push(call_result); |
9351 if_nonfunction->Goto(join); | 9406 if_nonfunction->Goto(join); |
9352 | 9407 |
9353 set_current_block(join); | 9408 set_current_block(join); |
9354 join->SetJoinId(call->id()); | 9409 join->SetJoinId(call->id()); |
9355 return ast_context()->ReturnValue(Pop()); | 9410 return ast_context()->ReturnValue(Pop()); |
9356 } | 9411 } |
9357 | 9412 |
9358 | 9413 |
9359 // Fast call to math functions. | 9414 // Fast call to math functions. |
9360 void HGraphBuilder::GenerateMathPow(CallRuntime* call) { | 9415 void HOptimizedGraphBuilder::GenerateMathPow(CallRuntime* call) { |
9361 ASSERT_EQ(2, call->arguments()->length()); | 9416 ASSERT_EQ(2, call->arguments()->length()); |
9362 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9417 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9363 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 9418 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
9364 HValue* right = Pop(); | 9419 HValue* right = Pop(); |
9365 HValue* left = Pop(); | 9420 HValue* left = Pop(); |
9366 HPower* result = new(zone()) HPower(left, right); | 9421 HPower* result = new(zone()) HPower(left, right); |
9367 return ast_context()->ReturnInstruction(result, call->id()); | 9422 return ast_context()->ReturnInstruction(result, call->id()); |
9368 } | 9423 } |
9369 | 9424 |
9370 | 9425 |
9371 void HGraphBuilder::GenerateMathSin(CallRuntime* call) { | 9426 void HOptimizedGraphBuilder::GenerateMathSin(CallRuntime* call) { |
9372 ASSERT_EQ(1, call->arguments()->length()); | 9427 ASSERT_EQ(1, call->arguments()->length()); |
9373 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 9428 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
9374 HValue* context = environment()->LookupContext(); | 9429 HValue* context = environment()->LookupContext(); |
9375 HCallStub* result = | 9430 HCallStub* result = |
9376 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); | 9431 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); |
9377 result->set_transcendental_type(TranscendentalCache::SIN); | 9432 result->set_transcendental_type(TranscendentalCache::SIN); |
9378 Drop(1); | 9433 Drop(1); |
9379 return ast_context()->ReturnInstruction(result, call->id()); | 9434 return ast_context()->ReturnInstruction(result, call->id()); |
9380 } | 9435 } |
9381 | 9436 |
9382 | 9437 |
9383 void HGraphBuilder::GenerateMathCos(CallRuntime* call) { | 9438 void HOptimizedGraphBuilder::GenerateMathCos(CallRuntime* call) { |
9384 ASSERT_EQ(1, call->arguments()->length()); | 9439 ASSERT_EQ(1, call->arguments()->length()); |
9385 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 9440 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
9386 HValue* context = environment()->LookupContext(); | 9441 HValue* context = environment()->LookupContext(); |
9387 HCallStub* result = | 9442 HCallStub* result = |
9388 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); | 9443 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); |
9389 result->set_transcendental_type(TranscendentalCache::COS); | 9444 result->set_transcendental_type(TranscendentalCache::COS); |
9390 Drop(1); | 9445 Drop(1); |
9391 return ast_context()->ReturnInstruction(result, call->id()); | 9446 return ast_context()->ReturnInstruction(result, call->id()); |
9392 } | 9447 } |
9393 | 9448 |
9394 | 9449 |
9395 void HGraphBuilder::GenerateMathTan(CallRuntime* call) { | 9450 void HOptimizedGraphBuilder::GenerateMathTan(CallRuntime* call) { |
9396 ASSERT_EQ(1, call->arguments()->length()); | 9451 ASSERT_EQ(1, call->arguments()->length()); |
9397 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 9452 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
9398 HValue* context = environment()->LookupContext(); | 9453 HValue* context = environment()->LookupContext(); |
9399 HCallStub* result = | 9454 HCallStub* result = |
9400 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); | 9455 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); |
9401 result->set_transcendental_type(TranscendentalCache::TAN); | 9456 result->set_transcendental_type(TranscendentalCache::TAN); |
9402 Drop(1); | 9457 Drop(1); |
9403 return ast_context()->ReturnInstruction(result, call->id()); | 9458 return ast_context()->ReturnInstruction(result, call->id()); |
9404 } | 9459 } |
9405 | 9460 |
9406 | 9461 |
9407 void HGraphBuilder::GenerateMathLog(CallRuntime* call) { | 9462 void HOptimizedGraphBuilder::GenerateMathLog(CallRuntime* call) { |
9408 ASSERT_EQ(1, call->arguments()->length()); | 9463 ASSERT_EQ(1, call->arguments()->length()); |
9409 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 9464 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
9410 HValue* context = environment()->LookupContext(); | 9465 HValue* context = environment()->LookupContext(); |
9411 HCallStub* result = | 9466 HCallStub* result = |
9412 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); | 9467 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); |
9413 result->set_transcendental_type(TranscendentalCache::LOG); | 9468 result->set_transcendental_type(TranscendentalCache::LOG); |
9414 Drop(1); | 9469 Drop(1); |
9415 return ast_context()->ReturnInstruction(result, call->id()); | 9470 return ast_context()->ReturnInstruction(result, call->id()); |
9416 } | 9471 } |
9417 | 9472 |
9418 | 9473 |
9419 void HGraphBuilder::GenerateMathSqrt(CallRuntime* call) { | 9474 void HOptimizedGraphBuilder::GenerateMathSqrt(CallRuntime* call) { |
9420 return Bailout("inlined runtime function: MathSqrt"); | 9475 return Bailout("inlined runtime function: MathSqrt"); |
9421 } | 9476 } |
9422 | 9477 |
9423 | 9478 |
9424 // Check whether two RegExps are equivalent | 9479 // Check whether two RegExps are equivalent |
9425 void HGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) { | 9480 void HOptimizedGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) { |
9426 return Bailout("inlined runtime function: IsRegExpEquivalent"); | 9481 return Bailout("inlined runtime function: IsRegExpEquivalent"); |
9427 } | 9482 } |
9428 | 9483 |
9429 | 9484 |
9430 void HGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) { | 9485 void HOptimizedGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) { |
9431 ASSERT(call->arguments()->length() == 1); | 9486 ASSERT(call->arguments()->length() == 1); |
9432 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9487 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9433 HValue* value = Pop(); | 9488 HValue* value = Pop(); |
9434 HGetCachedArrayIndex* result = new(zone()) HGetCachedArrayIndex(value); | 9489 HGetCachedArrayIndex* result = new(zone()) HGetCachedArrayIndex(value); |
9435 return ast_context()->ReturnInstruction(result, call->id()); | 9490 return ast_context()->ReturnInstruction(result, call->id()); |
9436 } | 9491 } |
9437 | 9492 |
9438 | 9493 |
9439 void HGraphBuilder::GenerateFastAsciiArrayJoin(CallRuntime* call) { | 9494 void HOptimizedGraphBuilder::GenerateFastAsciiArrayJoin(CallRuntime* call) { |
9440 return Bailout("inlined runtime function: FastAsciiArrayJoin"); | 9495 return Bailout("inlined runtime function: FastAsciiArrayJoin"); |
9441 } | 9496 } |
9442 | 9497 |
9443 | 9498 |
9444 #undef CHECK_BAILOUT | 9499 #undef CHECK_BAILOUT |
9445 #undef CHECK_ALIVE | 9500 #undef CHECK_ALIVE |
9446 | 9501 |
9447 | 9502 |
9448 HEnvironment::HEnvironment(HEnvironment* outer, | 9503 HEnvironment::HEnvironment(HEnvironment* outer, |
9449 Scope* scope, | 9504 Scope* scope, |
9450 Handle<JSFunction> closure, | 9505 Handle<JSFunction> closure, |
9451 Zone* zone) | 9506 Zone* zone) |
9452 : closure_(closure), | 9507 : closure_(closure), |
9453 values_(0, zone), | 9508 values_(0, zone), |
9454 assigned_variables_(4, zone), | 9509 assigned_variables_(4, zone), |
9455 frame_type_(JS_FUNCTION), | 9510 frame_type_(JS_FUNCTION), |
9456 parameter_count_(0), | 9511 parameter_count_(0), |
9457 specials_count_(1), | 9512 specials_count_(1), |
9458 local_count_(0), | 9513 local_count_(0), |
9459 outer_(outer), | 9514 outer_(outer), |
9460 entry_(NULL), | 9515 entry_(NULL), |
9461 pop_count_(0), | 9516 pop_count_(0), |
9462 push_count_(0), | 9517 push_count_(0), |
9463 ast_id_(BailoutId::None()), | 9518 ast_id_(BailoutId::None()), |
9464 zone_(zone) { | 9519 zone_(zone) { |
9465 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); | 9520 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); |
9466 } | 9521 } |
9467 | 9522 |
9468 | 9523 |
| 9524 HEnvironment::HEnvironment(Zone* zone) |
| 9525 : values_(0, zone), |
| 9526 assigned_variables_(0, zone), |
| 9527 frame_type_(STUB), |
| 9528 parameter_count_(0), |
| 9529 specials_count_(0), |
| 9530 local_count_(0), |
| 9531 outer_(NULL), |
| 9532 entry_(NULL), |
| 9533 pop_count_(0), |
| 9534 push_count_(0), |
| 9535 ast_id_(BailoutId::None()), |
| 9536 zone_(zone) { |
| 9537 Initialize(0, 0, 0); |
| 9538 } |
| 9539 |
| 9540 |
9469 HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) | 9541 HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) |
9470 : values_(0, zone), | 9542 : values_(0, zone), |
9471 assigned_variables_(0, zone), | 9543 assigned_variables_(0, zone), |
9472 frame_type_(JS_FUNCTION), | 9544 frame_type_(JS_FUNCTION), |
9473 parameter_count_(0), | 9545 parameter_count_(0), |
9474 specials_count_(1), | 9546 specials_count_(1), |
9475 local_count_(0), | 9547 local_count_(0), |
9476 outer_(NULL), | 9548 outer_(NULL), |
9477 entry_(NULL), | 9549 entry_(NULL), |
9478 pop_count_(0), | 9550 pop_count_(0), |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9726 | 9798 |
9727 | 9799 |
9728 void HEnvironment::PrintToStd() { | 9800 void HEnvironment::PrintToStd() { |
9729 HeapStringAllocator string_allocator; | 9801 HeapStringAllocator string_allocator; |
9730 StringStream trace(&string_allocator); | 9802 StringStream trace(&string_allocator); |
9731 PrintTo(&trace); | 9803 PrintTo(&trace); |
9732 PrintF("%s", *trace.ToCString()); | 9804 PrintF("%s", *trace.ToCString()); |
9733 } | 9805 } |
9734 | 9806 |
9735 | 9807 |
9736 void HTracer::TraceCompilation(FunctionLiteral* function) { | 9808 void HTracer::TraceCompilation(CompilationInfo* info) { |
9737 Tag tag(this, "compilation"); | 9809 Tag tag(this, "compilation"); |
9738 Handle<String> name = function->debug_name(); | 9810 if (info->IsOptimizing()) { |
9739 PrintStringProperty("name", *name->ToCString()); | 9811 Handle<String> name = info->function()->debug_name(); |
9740 PrintStringProperty("method", *name->ToCString()); | 9812 PrintStringProperty("name", *name->ToCString()); |
| 9813 PrintStringProperty("method", *name->ToCString()); |
| 9814 } else { |
| 9815 CodeStub::Major major_key = info->code_stub()->MajorKey(); |
| 9816 PrintStringProperty("name", CodeStub::MajorName(major_key, false)); |
| 9817 PrintStringProperty("method", "stub"); |
| 9818 } |
9741 PrintLongProperty("date", static_cast<int64_t>(OS::TimeCurrentMillis())); | 9819 PrintLongProperty("date", static_cast<int64_t>(OS::TimeCurrentMillis())); |
9742 } | 9820 } |
9743 | 9821 |
9744 | 9822 |
9745 void HTracer::TraceLithium(const char* name, LChunk* chunk) { | 9823 void HTracer::TraceLithium(const char* name, LChunk* chunk) { |
9746 Trace(name, chunk->graph(), chunk); | 9824 Trace(name, chunk->graph(), chunk); |
9747 } | 9825 } |
9748 | 9826 |
9749 | 9827 |
9750 void HTracer::TraceHydrogen(const char* name, HGraph* graph) { | 9828 void HTracer::TraceHydrogen(const char* name, HGraph* graph) { |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10059 } | 10137 } |
10060 } | 10138 } |
10061 | 10139 |
10062 #ifdef DEBUG | 10140 #ifdef DEBUG |
10063 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 10141 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
10064 if (allocator_ != NULL) allocator_->Verify(); | 10142 if (allocator_ != NULL) allocator_->Verify(); |
10065 #endif | 10143 #endif |
10066 } | 10144 } |
10067 | 10145 |
10068 } } // namespace v8::internal | 10146 } } // namespace v8::internal |
OLD | NEW |