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