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

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

Powered by Google App Engine
This is Rietveld 408576698