Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(206)

Side by Side Diff: src/hydrogen.cc

Issue 10701054: Enable stub generation using Hydrogen/Lithium (again) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698