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

Side by Side Diff: src/hydrogen.cc

Issue 11498006: Revert 13157, 13145 and 13140: Crankshaft code stubs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: 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() ||
142 environment->closure()->shared()->VerifyBailoutId(ast_id)); 141 environment->closure()->shared()->VerifyBailoutId(ast_id));
143 142
144 int push_count = environment->push_count(); 143 int push_count = environment->push_count();
145 int pop_count = environment->pop_count(); 144 int pop_count = environment->pop_count();
146 145
147 HSimulate* instr = 146 HSimulate* instr =
148 new(zone()) HSimulate(ast_id, pop_count, zone(), removable); 147 new(zone()) HSimulate(ast_id, pop_count, zone(), removable);
149 // Order of pushed values: newest (top of stack) first. This allows 148 // Order of pushed values: newest (top of stack) first. This allows
150 // HSimulate::MergeInto() to easily append additional pushed values 149 // HSimulate::MergeInto() to easily append additional pushed values
151 // that are older (from further down the stack). 150 // that are older (from further down the stack).
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 HConstant* HGraph::GetConstantFalse() { 614 HConstant* HGraph::GetConstantFalse() {
616 return GetConstant(&constant_false_, isolate()->factory()->false_value()); 615 return GetConstant(&constant_false_, isolate()->factory()->false_value());
617 } 616 }
618 617
619 618
620 HConstant* HGraph::GetConstantHole() { 619 HConstant* HGraph::GetConstantHole() {
621 return GetConstant(&constant_hole_, isolate()->factory()->the_hole_value()); 620 return GetConstant(&constant_hole_, isolate()->factory()->the_hole_value());
622 } 621 }
623 622
624 623
625 HGraph* HGraphBuilder::CreateGraph() { 624 HGraphBuilder::HGraphBuilder(CompilationInfo* info,
626 graph_ = new(zone()) HGraph(info_); 625 TypeFeedbackOracle* oracle)
627 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info_); 626 : function_state_(NULL),
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),
800 initial_function_state_(this, info, oracle, NORMAL_RETURN), 627 initial_function_state_(this, info, oracle, NORMAL_RETURN),
801 ast_context_(NULL), 628 ast_context_(NULL),
802 break_scope_(NULL), 629 break_scope_(NULL),
630 graph_(NULL),
631 current_block_(NULL),
803 inlined_count_(0), 632 inlined_count_(0),
804 globals_(10, info->zone()), 633 globals_(10, info->zone()),
634 zone_(info->zone()),
805 inline_bailout_(false) { 635 inline_bailout_(false) {
806 // This is not initialized in the initializer list because the 636 // This is not initialized in the initializer list because the
807 // constructor for the initial state relies on function_state_ == NULL 637 // constructor for the initial state relies on function_state_ == NULL
808 // to know it's the initial state. 638 // to know it's the initial state.
809 function_state_= &initial_function_state_; 639 function_state_= &initial_function_state_;
810 InitializeAstVisitor();
811 } 640 }
812 641
813 642 HBasicBlock* HGraphBuilder::CreateJoin(HBasicBlock* first,
814 HBasicBlock* HOptimizedGraphBuilder::CreateJoin(HBasicBlock* first, 643 HBasicBlock* second,
815 HBasicBlock* second, 644 BailoutId join_id) {
816 BailoutId join_id) {
817 if (first == NULL) { 645 if (first == NULL) {
818 return second; 646 return second;
819 } else if (second == NULL) { 647 } else if (second == NULL) {
820 return first; 648 return first;
821 } else { 649 } else {
822 HBasicBlock* join_block = graph()->CreateBasicBlock(); 650 HBasicBlock* join_block = graph_->CreateBasicBlock();
823 first->Goto(join_block); 651 first->Goto(join_block);
824 second->Goto(join_block); 652 second->Goto(join_block);
825 join_block->SetJoinId(join_id); 653 join_block->SetJoinId(join_id);
826 return join_block; 654 return join_block;
827 } 655 }
828 } 656 }
829 657
830 658
831 HBasicBlock* HOptimizedGraphBuilder::JoinContinue(IterationStatement* statement, 659 HBasicBlock* HGraphBuilder::JoinContinue(IterationStatement* statement,
832 HBasicBlock* exit_block, 660 HBasicBlock* exit_block,
833 HBasicBlock* continue_block) { 661 HBasicBlock* continue_block) {
834 if (continue_block != NULL) { 662 if (continue_block != NULL) {
835 if (exit_block != NULL) exit_block->Goto(continue_block); 663 if (exit_block != NULL) exit_block->Goto(continue_block);
836 continue_block->SetJoinId(statement->ContinueId()); 664 continue_block->SetJoinId(statement->ContinueId());
837 return continue_block; 665 return continue_block;
838 } 666 }
839 return exit_block; 667 return exit_block;
840 } 668 }
841 669
842 670
843 HBasicBlock* HOptimizedGraphBuilder::CreateLoop(IterationStatement* statement, 671 HBasicBlock* HGraphBuilder::CreateLoop(IterationStatement* statement,
844 HBasicBlock* loop_entry, 672 HBasicBlock* loop_entry,
845 HBasicBlock* body_exit, 673 HBasicBlock* body_exit,
846 HBasicBlock* loop_successor, 674 HBasicBlock* loop_successor,
847 HBasicBlock* break_block) { 675 HBasicBlock* break_block) {
848 if (body_exit != NULL) body_exit->Goto(loop_entry); 676 if (body_exit != NULL) body_exit->Goto(loop_entry);
849 loop_entry->PostProcessLoopHeader(statement); 677 loop_entry->PostProcessLoopHeader(statement);
850 if (break_block != NULL) { 678 if (break_block != NULL) {
851 if (loop_successor != NULL) loop_successor->Goto(break_block); 679 if (loop_successor != NULL) loop_successor->Goto(break_block);
852 break_block->SetJoinId(statement->ExitId()); 680 break_block->SetJoinId(statement->ExitId());
853 return break_block; 681 return break_block;
854 } 682 }
855 return loop_successor; 683 return loop_successor;
856 } 684 }
857 685
(...skipping 10 matching lines...) Expand all
868 entry_block_(NULL), 696 entry_block_(NULL),
869 blocks_(8, info->zone()), 697 blocks_(8, info->zone()),
870 values_(16, info->zone()), 698 values_(16, info->zone()),
871 phi_list_(NULL), 699 phi_list_(NULL),
872 uint32_instructions_(NULL), 700 uint32_instructions_(NULL),
873 info_(info), 701 info_(info),
874 zone_(info->zone()), 702 zone_(info->zone()),
875 is_recursive_(false), 703 is_recursive_(false),
876 use_optimistic_licm_(false), 704 use_optimistic_licm_(false),
877 type_change_checksum_(0) { 705 type_change_checksum_(0) {
878 if (info->IsStub()) { 706 start_environment_ =
879 start_environment_ = 707 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_);
880 new(zone_) HEnvironment(zone_);
881 } else {
882 start_environment_ =
883 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_);
884 }
885 start_environment_->set_ast_id(BailoutId::FunctionEntry()); 708 start_environment_->set_ast_id(BailoutId::FunctionEntry());
886 entry_block_ = CreateBasicBlock(); 709 entry_block_ = CreateBasicBlock();
887 entry_block_->SetInitialEnvironment(start_environment_); 710 entry_block_->SetInitialEnvironment(start_environment_);
888 } 711 }
889 712
890 713
891 HBasicBlock* HGraph::CreateBasicBlock() { 714 HBasicBlock* HGraph::CreateBasicBlock() {
892 HBasicBlock* result = new(zone()) HBasicBlock(this); 715 HBasicBlock* result = new(zone()) HBasicBlock(this);
893 blocks_.Add(result, zone()); 716 blocks_.Add(result, zone());
894 return result; 717 return result;
(...skipping 2168 matching lines...) Expand 10 before | Expand all | Expand 10 after
3063 visited.Clear(); 2886 visited.Clear();
3064 } 2887 }
3065 } 2888 }
3066 } 2889 }
3067 } 2890 }
3068 } 2891 }
3069 2892
3070 2893
3071 // Implementation of utility class to encapsulate the translation state for 2894 // Implementation of utility class to encapsulate the translation state for
3072 // a (possibly inlined) function. 2895 // a (possibly inlined) function.
3073 FunctionState::FunctionState(HOptimizedGraphBuilder* owner, 2896 FunctionState::FunctionState(HGraphBuilder* owner,
3074 CompilationInfo* info, 2897 CompilationInfo* info,
3075 TypeFeedbackOracle* oracle, 2898 TypeFeedbackOracle* oracle,
3076 InliningKind inlining_kind) 2899 InliningKind inlining_kind)
3077 : owner_(owner), 2900 : owner_(owner),
3078 compilation_info_(info), 2901 compilation_info_(info),
3079 oracle_(oracle), 2902 oracle_(oracle),
3080 call_context_(NULL), 2903 call_context_(NULL),
3081 inlining_kind_(inlining_kind), 2904 inlining_kind_(inlining_kind),
3082 function_return_(NULL), 2905 function_return_(NULL),
3083 test_context_(NULL), 2906 test_context_(NULL),
(...skipping 28 matching lines...) Expand all
3112 2935
3113 2936
3114 FunctionState::~FunctionState() { 2937 FunctionState::~FunctionState() {
3115 delete test_context_; 2938 delete test_context_;
3116 owner_->set_function_state(outer_); 2939 owner_->set_function_state(outer_);
3117 } 2940 }
3118 2941
3119 2942
3120 // Implementation of utility classes to represent an expression's context in 2943 // Implementation of utility classes to represent an expression's context in
3121 // the AST. 2944 // the AST.
3122 AstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind) 2945 AstContext::AstContext(HGraphBuilder* owner, Expression::Context kind)
3123 : owner_(owner), 2946 : owner_(owner),
3124 kind_(kind), 2947 kind_(kind),
3125 outer_(owner->ast_context()), 2948 outer_(owner->ast_context()),
3126 for_typeof_(false) { 2949 for_typeof_(false) {
3127 owner->set_ast_context(this); // Push. 2950 owner->set_ast_context(this); // Push.
3128 #ifdef DEBUG 2951 #ifdef DEBUG
3129 ASSERT(owner->environment()->frame_type() == JS_FUNCTION); 2952 ASSERT(owner->environment()->frame_type() == JS_FUNCTION);
3130 original_length_ = owner->environment()->length(); 2953 original_length_ = owner->environment()->length();
3131 #endif 2954 #endif
3132 } 2955 }
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
3223 owner()->set_current_block(materialize_false); 3046 owner()->set_current_block(materialize_false);
3224 owner()->Push(owner()->graph()->GetConstantFalse()); 3047 owner()->Push(owner()->graph()->GetConstantFalse());
3225 HBasicBlock* join = 3048 HBasicBlock* join =
3226 owner()->CreateJoin(materialize_true, materialize_false, ast_id); 3049 owner()->CreateJoin(materialize_true, materialize_false, ast_id);
3227 owner()->set_current_block(join); 3050 owner()->set_current_block(join);
3228 } 3051 }
3229 3052
3230 3053
3231 void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 3054 void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
3232 ASSERT(!instr->IsControlInstruction()); 3055 ASSERT(!instr->IsControlInstruction());
3233 HOptimizedGraphBuilder* builder = owner(); 3056 HGraphBuilder* builder = owner();
3234 builder->AddInstruction(instr); 3057 builder->AddInstruction(instr);
3235 // We expect a simulate after every expression with side effects, though 3058 // We expect a simulate after every expression with side effects, though
3236 // this one isn't actually needed (and wouldn't work if it were targeted). 3059 // this one isn't actually needed (and wouldn't work if it were targeted).
3237 if (instr->HasObservableSideEffects()) { 3060 if (instr->HasObservableSideEffects()) {
3238 builder->Push(instr); 3061 builder->Push(instr);
3239 builder->AddSimulate(ast_id, REMOVABLE_SIMULATE); 3062 builder->AddSimulate(ast_id, REMOVABLE_SIMULATE);
3240 builder->Pop(); 3063 builder->Pop();
3241 } 3064 }
3242 BuildBranch(instr); 3065 BuildBranch(instr);
3243 } 3066 }
(...skipping 10 matching lines...) Expand all
3254 empty_false->Goto(if_false(), owner()->function_state()); 3077 empty_false->Goto(if_false(), owner()->function_state());
3255 owner()->set_current_block(NULL); 3078 owner()->set_current_block(NULL);
3256 } 3079 }
3257 3080
3258 3081
3259 void TestContext::BuildBranch(HValue* value) { 3082 void TestContext::BuildBranch(HValue* value) {
3260 // We expect the graph to be in edge-split form: there is no edge that 3083 // We expect the graph to be in edge-split form: there is no edge that
3261 // connects a branch node to a join node. We conservatively ensure that 3084 // connects a branch node to a join node. We conservatively ensure that
3262 // property by always adding an empty block on the outgoing edges of this 3085 // property by always adding an empty block on the outgoing edges of this
3263 // branch. 3086 // branch.
3264 HOptimizedGraphBuilder* builder = owner(); 3087 HGraphBuilder* builder = owner();
3265 if (value != NULL && value->CheckFlag(HValue::kIsArguments)) { 3088 if (value != NULL && value->CheckFlag(HValue::kIsArguments)) {
3266 builder->Bailout("arguments object value in a test context"); 3089 builder->Bailout("arguments object value in a test context");
3267 } 3090 }
3268 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); 3091 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock();
3269 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); 3092 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock();
3270 TypeFeedbackId test_id = condition()->test_id(); 3093 TypeFeedbackId test_id = condition()->test_id();
3271 ToBooleanStub::Types expected(oracle()->ToBooleanTypes(test_id)); 3094 ToBooleanStub::Types expected(oracle()->ToBooleanTypes(test_id));
3272 HBranch* test = new(zone()) HBranch(value, empty_true, empty_false, expected); 3095 HBranch* test = new(zone()) HBranch(value, empty_true, empty_false, expected);
3273 builder->current_block()->Finish(test); 3096 builder->current_block()->Finish(test);
3274 3097
3275 empty_true->Goto(if_true(), owner()->function_state()); 3098 empty_true->Goto(if_true(), owner()->function_state());
3276 empty_false->Goto(if_false(), owner()->function_state()); 3099 empty_false->Goto(if_false(), owner()->function_state());
3277 builder->set_current_block(NULL); 3100 builder->set_current_block(NULL);
3278 } 3101 }
3279 3102
3280 3103
3281 // HOptimizedGraphBuilder infrastructure for bailing out and checking bailouts. 3104 // HGraphBuilder infrastructure for bailing out and checking bailouts.
3282 #define CHECK_BAILOUT(call) \ 3105 #define CHECK_BAILOUT(call) \
3283 do { \ 3106 do { \
3284 call; \ 3107 call; \
3285 if (HasStackOverflow()) return; \ 3108 if (HasStackOverflow()) return; \
3286 } while (false) 3109 } while (false)
3287 3110
3288 3111
3289 #define CHECK_ALIVE(call) \ 3112 #define CHECK_ALIVE(call) \
3290 do { \ 3113 do { \
3291 call; \ 3114 call; \
3292 if (HasStackOverflow() || current_block() == NULL) return; \ 3115 if (HasStackOverflow() || current_block() == NULL) return; \
3293 } while (false) 3116 } while (false)
3294 3117
3295 3118
3296 void HOptimizedGraphBuilder::Bailout(const char* reason) { 3119 void HGraphBuilder::Bailout(const char* reason) {
3297 info()->set_bailout_reason(reason); 3120 info()->set_bailout_reason(reason);
3298 SetStackOverflow(); 3121 SetStackOverflow();
3299 } 3122 }
3300 3123
3301 3124
3302 void HOptimizedGraphBuilder::VisitForEffect(Expression* expr) { 3125 void HGraphBuilder::VisitForEffect(Expression* expr) {
3303 EffectContext for_effect(this); 3126 EffectContext for_effect(this);
3304 Visit(expr); 3127 Visit(expr);
3305 } 3128 }
3306 3129
3307 3130
3308 void HOptimizedGraphBuilder::VisitForValue(Expression* expr, 3131 void HGraphBuilder::VisitForValue(Expression* expr, ArgumentsAllowedFlag flag) {
3309 ArgumentsAllowedFlag flag) {
3310 ValueContext for_value(this, flag); 3132 ValueContext for_value(this, flag);
3311 Visit(expr); 3133 Visit(expr);
3312 } 3134 }
3313 3135
3314 3136
3315 void HOptimizedGraphBuilder::VisitForTypeOf(Expression* expr) { 3137 void HGraphBuilder::VisitForTypeOf(Expression* expr) {
3316 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); 3138 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED);
3317 for_value.set_for_typeof(true); 3139 for_value.set_for_typeof(true);
3318 Visit(expr); 3140 Visit(expr);
3319 } 3141 }
3320 3142
3321 3143
3322 3144
3323 void HOptimizedGraphBuilder::VisitForControl(Expression* expr, 3145 void HGraphBuilder::VisitForControl(Expression* expr,
3324 HBasicBlock* true_block, 3146 HBasicBlock* true_block,
3325 HBasicBlock* false_block) { 3147 HBasicBlock* false_block) {
3326 TestContext for_test(this, expr, oracle(), true_block, false_block); 3148 TestContext for_test(this, expr, oracle(), true_block, false_block);
3327 Visit(expr); 3149 Visit(expr);
3328 } 3150 }
3329 3151
3330 3152
3331 void HOptimizedGraphBuilder::VisitArgument(Expression* expr) { 3153 void HGraphBuilder::VisitArgument(Expression* expr) {
3332 CHECK_ALIVE(VisitForValue(expr)); 3154 CHECK_ALIVE(VisitForValue(expr));
3333 Push(AddInstruction(new(zone()) HPushArgument(Pop()))); 3155 Push(AddInstruction(new(zone()) HPushArgument(Pop())));
3334 } 3156 }
3335 3157
3336 3158
3337 void HOptimizedGraphBuilder::VisitArgumentList( 3159 void HGraphBuilder::VisitArgumentList(ZoneList<Expression*>* arguments) {
3338 ZoneList<Expression*>* arguments) {
3339 for (int i = 0; i < arguments->length(); i++) { 3160 for (int i = 0; i < arguments->length(); i++) {
3340 CHECK_ALIVE(VisitArgument(arguments->at(i))); 3161 CHECK_ALIVE(VisitArgument(arguments->at(i)));
3341 } 3162 }
3342 } 3163 }
3343 3164
3344 3165
3345 void HOptimizedGraphBuilder::VisitExpressions( 3166 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) {
3346 ZoneList<Expression*>* exprs) {
3347 for (int i = 0; i < exprs->length(); ++i) { 3167 for (int i = 0; i < exprs->length(); ++i) {
3348 CHECK_ALIVE(VisitForValue(exprs->at(i))); 3168 CHECK_ALIVE(VisitForValue(exprs->at(i)));
3349 } 3169 }
3350 } 3170 }
3351 3171
3352 3172
3353 bool HOptimizedGraphBuilder::BuildGraph() { 3173 HGraph* HGraphBuilder::CreateGraph() {
3354 Scope* scope = info()->scope(); 3174 graph_ = new(zone()) HGraph(info());
3355 if (scope->HasIllegalRedeclaration()) { 3175 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info());
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);
3364 3176
3365 // Add an edge to the body entry. This is warty: the graph's start 3177 {
3366 // environment will be used by the Lithium translation as the initial 3178 HPhase phase("H_Block building");
3367 // environment on graph entry, but it has now been mutated by the 3179 current_block_ = graph()->entry_block();
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);
3385 3180
3386 // Handle implicit declaration of the function name in named function 3181 Scope* scope = info()->scope();
3387 // expressions before other declarations. 3182 if (scope->HasIllegalRedeclaration()) {
3388 if (scope->is_function_scope() && scope->function() != NULL) { 3183 Bailout("function with illegal redeclaration");
3389 VisitVariableDeclaration(scope->function()); 3184 return NULL;
3390 } 3185 }
3391 VisitDeclarations(scope->declarations()); 3186 if (scope->calls_eval()) {
3392 AddSimulate(BailoutId::Declarations()); 3187 Bailout("function calls eval");
3188 return NULL;
3189 }
3190 SetUpScope(scope);
3393 3191
3394 HValue* context = environment()->LookupContext(); 3192 // Add an edge to the body entry. This is warty: the graph's start
3395 AddInstruction( 3193 // environment will be used by the Lithium translation as the initial
3396 new(zone()) HStackCheck(context, HStackCheck::kFunctionEntry)); 3194 // environment on graph entry, but it has now been mutated by the
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);
3397 3212
3398 VisitStatements(info()->function()->body()); 3213 // Handle implicit declaration of the function name in named function
3399 if (HasStackOverflow()) return false; 3214 // expressions before other declarations.
3215 if (scope->is_function_scope() && scope->function() != NULL) {
3216 VisitVariableDeclaration(scope->function());
3217 }
3218 VisitDeclarations(scope->declarations());
3219 AddSimulate(BailoutId::Declarations());
3400 3220
3401 if (current_block() != NULL) { 3221 HValue* context = environment()->LookupContext();
3402 HReturn* instr = new(zone()) HReturn(graph()->GetConstantUndefined()); 3222 AddInstruction(
3403 current_block()->FinishExit(instr); 3223 new(zone()) HStackCheck(context, HStackCheck::kFunctionEntry));
3404 set_current_block(NULL); 3224
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);
3405 } 3247 }
3406 3248
3407 // If the checksum of the number of type info changes is the same as the 3249 return graph();
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;
3422 } 3250 }
3423 3251
3424
3425 bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) { 3252 bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) {
3426 *bailout_reason = SmartArrayPointer<char>(); 3253 *bailout_reason = SmartArrayPointer<char>();
3427 OrderBlocks(); 3254 OrderBlocks();
3428 AssignDominators(); 3255 AssignDominators();
3429 3256
3430 #ifdef DEBUG 3257 #ifdef DEBUG
3431 // Do a full verify after building the graph and computing dominators. 3258 // Do a full verify after building the graph and computing dominators.
3432 Verify(true); 3259 Verify(true);
3433 #endif 3260 #endif
3434 3261
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
3928 } 3755 }
3929 instr->DeleteAndReplaceWith(NULL); 3756 instr->DeleteAndReplaceWith(NULL);
3930 for (int i = 0; i < instr->OperandCount(); ++i) { 3757 for (int i = 0; i < instr->OperandCount(); ++i) {
3931 HValue* operand = instr->OperandAt(i); 3758 HValue* operand = instr->OperandAt(i);
3932 if (operand->IsDead()) worklist.Add(HInstruction::cast(operand), zone()); 3759 if (operand->IsDead()) worklist.Add(HInstruction::cast(operand), zone());
3933 } 3760 }
3934 } 3761 }
3935 } 3762 }
3936 3763
3937 3764
3938 void HOptimizedGraphBuilder::AddPhi(HPhi* instr) { 3765 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
3766 ASSERT(current_block() != NULL);
3767 current_block()->AddInstruction(instr);
3768 return instr;
3769 }
3770
3771
3772 void HGraphBuilder::AddSimulate(BailoutId ast_id, RemovableSimulate removable) {
3773 ASSERT(current_block() != NULL);
3774 current_block()->AddSimulate(ast_id, removable);
3775 }
3776
3777
3778 void HGraphBuilder::AddPhi(HPhi* instr) {
3939 ASSERT(current_block() != NULL); 3779 ASSERT(current_block() != NULL);
3940 current_block()->AddPhi(instr); 3780 current_block()->AddPhi(instr);
3941 } 3781 }
3942 3782
3943 3783
3944 void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) { 3784 void HGraphBuilder::PushAndAdd(HInstruction* instr) {
3945 Push(instr); 3785 Push(instr);
3946 AddInstruction(instr); 3786 AddInstruction(instr);
3947 } 3787 }
3948 3788
3949 3789
3950 template <class Instruction> 3790 template <class Instruction>
3951 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { 3791 HInstruction* HGraphBuilder::PreProcessCall(Instruction* call) {
3952 int count = call->argument_count(); 3792 int count = call->argument_count();
3953 ZoneList<HValue*> arguments(count, zone()); 3793 ZoneList<HValue*> arguments(count, zone());
3954 for (int i = 0; i < count; ++i) { 3794 for (int i = 0; i < count; ++i) {
3955 arguments.Add(Pop(), zone()); 3795 arguments.Add(Pop(), zone());
3956 } 3796 }
3957 3797
3958 while (!arguments.is_empty()) { 3798 while (!arguments.is_empty()) {
3959 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); 3799 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast()));
3960 } 3800 }
3961 return call; 3801 return call;
3962 } 3802 }
3963 3803
3964 3804
3965 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) { 3805 void HGraphBuilder::SetUpScope(Scope* scope) {
3966 HConstant* undefined_constant = new(zone()) HConstant( 3806 HConstant* undefined_constant = new(zone()) HConstant(
3967 isolate()->factory()->undefined_value(), Representation::Tagged()); 3807 isolate()->factory()->undefined_value(), Representation::Tagged());
3968 AddInstruction(undefined_constant); 3808 AddInstruction(undefined_constant);
3969 graph()->set_undefined_constant(undefined_constant); 3809 graph_->set_undefined_constant(undefined_constant);
3970 3810
3971 HArgumentsObject* object = new(zone()) HArgumentsObject; 3811 HArgumentsObject* object = new(zone()) HArgumentsObject;
3972 AddInstruction(object); 3812 AddInstruction(object);
3973 graph()->SetArgumentsObject(object); 3813 graph()->SetArgumentsObject(object);
3974 3814
3975 // Set the initial values of parameters including "this". "This" has 3815 // Set the initial values of parameters including "this". "This" has
3976 // parameter index 0. 3816 // parameter index 0.
3977 ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count()); 3817 ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count());
3978 3818
3979 for (int i = 0; i < environment()->parameter_count(); ++i) { 3819 for (int i = 0; i < environment()->parameter_count(); ++i) {
(...skipping 18 matching lines...) Expand all
3998 if (!scope->arguments()->IsStackAllocated()) { 3838 if (!scope->arguments()->IsStackAllocated()) {
3999 return Bailout("context-allocated arguments"); 3839 return Bailout("context-allocated arguments");
4000 } 3840 }
4001 3841
4002 environment()->Bind(scope->arguments(), 3842 environment()->Bind(scope->arguments(),
4003 graph()->GetArgumentsObject()); 3843 graph()->GetArgumentsObject());
4004 } 3844 }
4005 } 3845 }
4006 3846
4007 3847
4008 void HOptimizedGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) { 3848 void HGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) {
4009 for (int i = 0; i < statements->length(); i++) { 3849 for (int i = 0; i < statements->length(); i++) {
4010 CHECK_ALIVE(Visit(statements->at(i))); 3850 CHECK_ALIVE(Visit(statements->at(i)));
4011 } 3851 }
4012 } 3852 }
4013 3853
4014 3854
4015 HBasicBlock* HOptimizedGraphBuilder::CreateBasicBlock(HEnvironment* env) { 3855 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) {
4016 HBasicBlock* b = graph()->CreateBasicBlock(); 3856 HBasicBlock* b = graph()->CreateBasicBlock();
4017 b->SetInitialEnvironment(env); 3857 b->SetInitialEnvironment(env);
4018 return b; 3858 return b;
4019 } 3859 }
4020 3860
4021 3861
4022 HBasicBlock* HOptimizedGraphBuilder::CreateLoopHeaderBlock() { 3862 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() {
4023 HBasicBlock* header = graph()->CreateBasicBlock(); 3863 HBasicBlock* header = graph()->CreateBasicBlock();
4024 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); 3864 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header);
4025 header->SetInitialEnvironment(entry_env); 3865 header->SetInitialEnvironment(entry_env);
4026 header->AttachLoopInformation(); 3866 header->AttachLoopInformation();
4027 return header; 3867 return header;
4028 } 3868 }
4029 3869
4030 3870
4031 void HOptimizedGraphBuilder::VisitBlock(Block* stmt) { 3871 void HGraphBuilder::VisitBlock(Block* stmt) {
4032 ASSERT(!HasStackOverflow()); 3872 ASSERT(!HasStackOverflow());
4033 ASSERT(current_block() != NULL); 3873 ASSERT(current_block() != NULL);
4034 ASSERT(current_block()->HasPredecessor()); 3874 ASSERT(current_block()->HasPredecessor());
4035 if (stmt->scope() != NULL) { 3875 if (stmt->scope() != NULL) {
4036 return Bailout("ScopedBlock"); 3876 return Bailout("ScopedBlock");
4037 } 3877 }
4038 BreakAndContinueInfo break_info(stmt); 3878 BreakAndContinueInfo break_info(stmt);
4039 { BreakAndContinueScope push(&break_info, this); 3879 { BreakAndContinueScope push(&break_info, this);
4040 CHECK_BAILOUT(VisitStatements(stmt->statements())); 3880 CHECK_BAILOUT(VisitStatements(stmt->statements()));
4041 } 3881 }
4042 HBasicBlock* break_block = break_info.break_block(); 3882 HBasicBlock* break_block = break_info.break_block();
4043 if (break_block != NULL) { 3883 if (break_block != NULL) {
4044 if (current_block() != NULL) current_block()->Goto(break_block); 3884 if (current_block() != NULL) current_block()->Goto(break_block);
4045 break_block->SetJoinId(stmt->ExitId()); 3885 break_block->SetJoinId(stmt->ExitId());
4046 set_current_block(break_block); 3886 set_current_block(break_block);
4047 } 3887 }
4048 } 3888 }
4049 3889
4050 3890
4051 void HOptimizedGraphBuilder::VisitExpressionStatement( 3891 void HGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) {
4052 ExpressionStatement* stmt) {
4053 ASSERT(!HasStackOverflow()); 3892 ASSERT(!HasStackOverflow());
4054 ASSERT(current_block() != NULL); 3893 ASSERT(current_block() != NULL);
4055 ASSERT(current_block()->HasPredecessor()); 3894 ASSERT(current_block()->HasPredecessor());
4056 VisitForEffect(stmt->expression()); 3895 VisitForEffect(stmt->expression());
4057 } 3896 }
4058 3897
4059 3898
4060 void HOptimizedGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) { 3899 void HGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) {
4061 ASSERT(!HasStackOverflow()); 3900 ASSERT(!HasStackOverflow());
4062 ASSERT(current_block() != NULL); 3901 ASSERT(current_block() != NULL);
4063 ASSERT(current_block()->HasPredecessor()); 3902 ASSERT(current_block()->HasPredecessor());
4064 } 3903 }
4065 3904
4066 3905
4067 void HOptimizedGraphBuilder::VisitIfStatement(IfStatement* stmt) { 3906 void HGraphBuilder::VisitIfStatement(IfStatement* stmt) {
4068 ASSERT(!HasStackOverflow()); 3907 ASSERT(!HasStackOverflow());
4069 ASSERT(current_block() != NULL); 3908 ASSERT(current_block() != NULL);
4070 ASSERT(current_block()->HasPredecessor()); 3909 ASSERT(current_block()->HasPredecessor());
4071 if (stmt->condition()->ToBooleanIsTrue()) { 3910 if (stmt->condition()->ToBooleanIsTrue()) {
4072 AddSimulate(stmt->ThenId()); 3911 AddSimulate(stmt->ThenId());
4073 Visit(stmt->then_statement()); 3912 Visit(stmt->then_statement());
4074 } else if (stmt->condition()->ToBooleanIsFalse()) { 3913 } else if (stmt->condition()->ToBooleanIsFalse()) {
4075 AddSimulate(stmt->ElseId()); 3914 AddSimulate(stmt->ElseId());
4076 Visit(stmt->else_statement()); 3915 Visit(stmt->else_statement());
4077 } else { 3916 } else {
(...skipping 18 matching lines...) Expand all
4096 } else { 3935 } else {
4097 cond_false = NULL; 3936 cond_false = NULL;
4098 } 3937 }
4099 3938
4100 HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->IfId()); 3939 HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->IfId());
4101 set_current_block(join); 3940 set_current_block(join);
4102 } 3941 }
4103 } 3942 }
4104 3943
4105 3944
4106 HBasicBlock* HOptimizedGraphBuilder::BreakAndContinueScope::Get( 3945 HBasicBlock* HGraphBuilder::BreakAndContinueScope::Get(
4107 BreakableStatement* stmt, 3946 BreakableStatement* stmt,
4108 BreakType type, 3947 BreakType type,
4109 int* drop_extra) { 3948 int* drop_extra) {
4110 *drop_extra = 0; 3949 *drop_extra = 0;
4111 BreakAndContinueScope* current = this; 3950 BreakAndContinueScope* current = this;
4112 while (current != NULL && current->info()->target() != stmt) { 3951 while (current != NULL && current->info()->target() != stmt) {
4113 *drop_extra += current->info()->drop_extra(); 3952 *drop_extra += current->info()->drop_extra();
4114 current = current->next(); 3953 current = current->next();
4115 } 3954 }
4116 ASSERT(current != NULL); // Always found (unless stack is malformed). 3955 ASSERT(current != NULL); // Always found (unless stack is malformed).
(...skipping 18 matching lines...) Expand all
4135 block = current->owner()->graph()->CreateBasicBlock(); 3974 block = current->owner()->graph()->CreateBasicBlock();
4136 current->info()->set_continue_block(block); 3975 current->info()->set_continue_block(block);
4137 } 3976 }
4138 break; 3977 break;
4139 } 3978 }
4140 3979
4141 return block; 3980 return block;
4142 } 3981 }
4143 3982
4144 3983
4145 void HOptimizedGraphBuilder::VisitContinueStatement( 3984 void HGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) {
4146 ContinueStatement* stmt) {
4147 ASSERT(!HasStackOverflow()); 3985 ASSERT(!HasStackOverflow());
4148 ASSERT(current_block() != NULL); 3986 ASSERT(current_block() != NULL);
4149 ASSERT(current_block()->HasPredecessor()); 3987 ASSERT(current_block()->HasPredecessor());
4150 int drop_extra = 0; 3988 int drop_extra = 0;
4151 HBasicBlock* continue_block = break_scope()->Get(stmt->target(), 3989 HBasicBlock* continue_block = break_scope()->Get(stmt->target(),
4152 CONTINUE, 3990 CONTINUE,
4153 &drop_extra); 3991 &drop_extra);
4154 Drop(drop_extra); 3992 Drop(drop_extra);
4155 current_block()->Goto(continue_block); 3993 current_block()->Goto(continue_block);
4156 set_current_block(NULL); 3994 set_current_block(NULL);
4157 } 3995 }
4158 3996
4159 3997
4160 void HOptimizedGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { 3998 void HGraphBuilder::VisitBreakStatement(BreakStatement* stmt) {
4161 ASSERT(!HasStackOverflow()); 3999 ASSERT(!HasStackOverflow());
4162 ASSERT(current_block() != NULL); 4000 ASSERT(current_block() != NULL);
4163 ASSERT(current_block()->HasPredecessor()); 4001 ASSERT(current_block()->HasPredecessor());
4164 int drop_extra = 0; 4002 int drop_extra = 0;
4165 HBasicBlock* break_block = break_scope()->Get(stmt->target(), 4003 HBasicBlock* break_block = break_scope()->Get(stmt->target(),
4166 BREAK, 4004 BREAK,
4167 &drop_extra); 4005 &drop_extra);
4168 Drop(drop_extra); 4006 Drop(drop_extra);
4169 current_block()->Goto(break_block); 4007 current_block()->Goto(break_block);
4170 set_current_block(NULL); 4008 set_current_block(NULL);
4171 } 4009 }
4172 4010
4173 4011
4174 void HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { 4012 void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
4175 ASSERT(!HasStackOverflow()); 4013 ASSERT(!HasStackOverflow());
4176 ASSERT(current_block() != NULL); 4014 ASSERT(current_block() != NULL);
4177 ASSERT(current_block()->HasPredecessor()); 4015 ASSERT(current_block()->HasPredecessor());
4178 FunctionState* state = function_state(); 4016 FunctionState* state = function_state();
4179 AstContext* context = call_context(); 4017 AstContext* context = call_context();
4180 if (context == NULL) { 4018 if (context == NULL) {
4181 // Not an inlined return, so an actual one. 4019 // Not an inlined return, so an actual one.
4182 CHECK_ALIVE(VisitForValue(stmt->expression())); 4020 CHECK_ALIVE(VisitForValue(stmt->expression()));
4183 HValue* result = environment()->Pop(); 4021 HValue* result = environment()->Pop();
4184 current_block()->FinishExit(new(zone()) HReturn(result)); 4022 current_block()->FinishExit(new(zone()) HReturn(result));
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
4236 } else { 4074 } else {
4237 ASSERT(context->IsValue()); 4075 ASSERT(context->IsValue());
4238 CHECK_ALIVE(VisitForValue(stmt->expression())); 4076 CHECK_ALIVE(VisitForValue(stmt->expression()));
4239 current_block()->AddLeaveInlined(Pop(), state); 4077 current_block()->AddLeaveInlined(Pop(), state);
4240 } 4078 }
4241 } 4079 }
4242 set_current_block(NULL); 4080 set_current_block(NULL);
4243 } 4081 }
4244 4082
4245 4083
4246 void HOptimizedGraphBuilder::VisitWithStatement(WithStatement* stmt) { 4084 void HGraphBuilder::VisitWithStatement(WithStatement* stmt) {
4247 ASSERT(!HasStackOverflow()); 4085 ASSERT(!HasStackOverflow());
4248 ASSERT(current_block() != NULL); 4086 ASSERT(current_block() != NULL);
4249 ASSERT(current_block()->HasPredecessor()); 4087 ASSERT(current_block()->HasPredecessor());
4250 return Bailout("WithStatement"); 4088 return Bailout("WithStatement");
4251 } 4089 }
4252 4090
4253 4091
4254 void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { 4092 void HGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
4255 ASSERT(!HasStackOverflow()); 4093 ASSERT(!HasStackOverflow());
4256 ASSERT(current_block() != NULL); 4094 ASSERT(current_block() != NULL);
4257 ASSERT(current_block()->HasPredecessor()); 4095 ASSERT(current_block()->HasPredecessor());
4258 // We only optimize switch statements with smi-literal smi comparisons, 4096 // We only optimize switch statements with smi-literal smi comparisons,
4259 // with a bounded number of clauses. 4097 // with a bounded number of clauses.
4260 const int kCaseClauseLimit = 128; 4098 const int kCaseClauseLimit = 128;
4261 ZoneList<CaseClause*>* clauses = stmt->cases(); 4099 ZoneList<CaseClause*>* clauses = stmt->cases();
4262 int clause_count = clauses->length(); 4100 int clause_count = clauses->length();
4263 if (clause_count > kCaseClauseLimit) { 4101 if (clause_count > kCaseClauseLimit) {
4264 return Bailout("SwitchStatement: too many clauses"); 4102 return Bailout("SwitchStatement: too many clauses");
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
4430 stmt->ExitId())); 4268 stmt->ExitId()));
4431 } else { 4269 } else {
4432 if (fall_through_block != NULL) fall_through_block->Goto(break_block); 4270 if (fall_through_block != NULL) fall_through_block->Goto(break_block);
4433 if (last_block != NULL) last_block->Goto(break_block); 4271 if (last_block != NULL) last_block->Goto(break_block);
4434 break_block->SetJoinId(stmt->ExitId()); 4272 break_block->SetJoinId(stmt->ExitId());
4435 set_current_block(break_block); 4273 set_current_block(break_block);
4436 } 4274 }
4437 } 4275 }
4438 4276
4439 4277
4440 bool HOptimizedGraphBuilder::HasOsrEntryAt(IterationStatement* statement) { 4278 bool HGraphBuilder::HasOsrEntryAt(IterationStatement* statement) {
4441 return statement->OsrEntryId() == info()->osr_ast_id(); 4279 return statement->OsrEntryId() == info()->osr_ast_id();
4442 } 4280 }
4443 4281
4444 4282
4445 bool HOptimizedGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) { 4283 bool HGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) {
4446 if (!HasOsrEntryAt(statement)) return false; 4284 if (!HasOsrEntryAt(statement)) return false;
4447 4285
4448 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock(); 4286 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock();
4449 HBasicBlock* osr_entry = graph()->CreateBasicBlock(); 4287 HBasicBlock* osr_entry = graph()->CreateBasicBlock();
4450 HValue* true_value = graph()->GetConstantTrue(); 4288 HValue* true_value = graph()->GetConstantTrue();
4451 HBranch* test = new(zone()) HBranch(true_value, non_osr_entry, osr_entry); 4289 HBranch* test = new(zone()) HBranch(true_value, non_osr_entry, osr_entry);
4452 current_block()->Finish(test); 4290 current_block()->Finish(test);
4453 4291
4454 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); 4292 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock();
4455 non_osr_entry->Goto(loop_predecessor); 4293 non_osr_entry->Goto(loop_predecessor);
(...skipping 29 matching lines...) Expand all
4485 HContext* context = new(zone()) HContext; 4323 HContext* context = new(zone()) HContext;
4486 AddInstruction(context); 4324 AddInstruction(context);
4487 environment()->BindContext(context); 4325 environment()->BindContext(context);
4488 current_block()->Goto(loop_predecessor); 4326 current_block()->Goto(loop_predecessor);
4489 loop_predecessor->SetJoinId(statement->EntryId()); 4327 loop_predecessor->SetJoinId(statement->EntryId());
4490 set_current_block(loop_predecessor); 4328 set_current_block(loop_predecessor);
4491 return true; 4329 return true;
4492 } 4330 }
4493 4331
4494 4332
4495 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, 4333 void HGraphBuilder::VisitLoopBody(IterationStatement* stmt,
4496 HBasicBlock* loop_entry, 4334 HBasicBlock* loop_entry,
4497 BreakAndContinueInfo* break_info) { 4335 BreakAndContinueInfo* break_info) {
4498 BreakAndContinueScope push(break_info, this); 4336 BreakAndContinueScope push(break_info, this);
4499 AddSimulate(stmt->StackCheckId()); 4337 AddSimulate(stmt->StackCheckId());
4500 HValue* context = environment()->LookupContext(); 4338 HValue* context = environment()->LookupContext();
4501 HStackCheck* stack_check = 4339 HStackCheck* stack_check =
4502 new(zone()) HStackCheck(context, HStackCheck::kBackwardsBranch); 4340 new(zone()) HStackCheck(context, HStackCheck::kBackwardsBranch);
4503 AddInstruction(stack_check); 4341 AddInstruction(stack_check);
4504 ASSERT(loop_entry->IsLoopHeader()); 4342 ASSERT(loop_entry->IsLoopHeader());
4505 loop_entry->loop_information()->set_stack_check(stack_check); 4343 loop_entry->loop_information()->set_stack_check(stack_check);
4506 CHECK_BAILOUT(Visit(stmt->body())); 4344 CHECK_BAILOUT(Visit(stmt->body()));
4507 } 4345 }
4508 4346
4509 4347
4510 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { 4348 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
4511 ASSERT(!HasStackOverflow()); 4349 ASSERT(!HasStackOverflow());
4512 ASSERT(current_block() != NULL); 4350 ASSERT(current_block() != NULL);
4513 ASSERT(current_block()->HasPredecessor()); 4351 ASSERT(current_block()->HasPredecessor());
4514 ASSERT(current_block() != NULL); 4352 ASSERT(current_block() != NULL);
4515 bool osr_entry = PreProcessOsrEntry(stmt); 4353 bool osr_entry = PreProcessOsrEntry(stmt);
4516 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); 4354 HBasicBlock* loop_entry = CreateLoopHeaderBlock();
4517 current_block()->Goto(loop_entry); 4355 current_block()->Goto(loop_entry);
4518 set_current_block(loop_entry); 4356 set_current_block(loop_entry);
4519 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); 4357 if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
4520 4358
(...skipping 22 matching lines...) Expand all
4543 } 4381 }
4544 HBasicBlock* loop_exit = CreateLoop(stmt, 4382 HBasicBlock* loop_exit = CreateLoop(stmt,
4545 loop_entry, 4383 loop_entry,
4546 body_exit, 4384 body_exit,
4547 loop_successor, 4385 loop_successor,
4548 break_info.break_block()); 4386 break_info.break_block());
4549 set_current_block(loop_exit); 4387 set_current_block(loop_exit);
4550 } 4388 }
4551 4389
4552 4390
4553 void HOptimizedGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { 4391 void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
4554 ASSERT(!HasStackOverflow()); 4392 ASSERT(!HasStackOverflow());
4555 ASSERT(current_block() != NULL); 4393 ASSERT(current_block() != NULL);
4556 ASSERT(current_block()->HasPredecessor()); 4394 ASSERT(current_block()->HasPredecessor());
4557 ASSERT(current_block() != NULL); 4395 ASSERT(current_block() != NULL);
4558 bool osr_entry = PreProcessOsrEntry(stmt); 4396 bool osr_entry = PreProcessOsrEntry(stmt);
4559 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); 4397 HBasicBlock* loop_entry = CreateLoopHeaderBlock();
4560 current_block()->Goto(loop_entry); 4398 current_block()->Goto(loop_entry);
4561 set_current_block(loop_entry); 4399 set_current_block(loop_entry);
4562 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); 4400 if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
4563 4401
(...skipping 23 matching lines...) Expand all
4587 JoinContinue(stmt, current_block(), break_info.continue_block()); 4425 JoinContinue(stmt, current_block(), break_info.continue_block());
4588 HBasicBlock* loop_exit = CreateLoop(stmt, 4426 HBasicBlock* loop_exit = CreateLoop(stmt,
4589 loop_entry, 4427 loop_entry,
4590 body_exit, 4428 body_exit,
4591 loop_successor, 4429 loop_successor,
4592 break_info.break_block()); 4430 break_info.break_block());
4593 set_current_block(loop_exit); 4431 set_current_block(loop_exit);
4594 } 4432 }
4595 4433
4596 4434
4597 void HOptimizedGraphBuilder::VisitForStatement(ForStatement* stmt) { 4435 void HGraphBuilder::VisitForStatement(ForStatement* stmt) {
4598 ASSERT(!HasStackOverflow()); 4436 ASSERT(!HasStackOverflow());
4599 ASSERT(current_block() != NULL); 4437 ASSERT(current_block() != NULL);
4600 ASSERT(current_block()->HasPredecessor()); 4438 ASSERT(current_block()->HasPredecessor());
4601 if (stmt->init() != NULL) { 4439 if (stmt->init() != NULL) {
4602 CHECK_ALIVE(Visit(stmt->init())); 4440 CHECK_ALIVE(Visit(stmt->init()));
4603 } 4441 }
4604 ASSERT(current_block() != NULL); 4442 ASSERT(current_block() != NULL);
4605 bool osr_entry = PreProcessOsrEntry(stmt); 4443 bool osr_entry = PreProcessOsrEntry(stmt);
4606 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); 4444 HBasicBlock* loop_entry = CreateLoopHeaderBlock();
4607 current_block()->Goto(loop_entry); 4445 current_block()->Goto(loop_entry);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
4639 4477
4640 HBasicBlock* loop_exit = CreateLoop(stmt, 4478 HBasicBlock* loop_exit = CreateLoop(stmt,
4641 loop_entry, 4479 loop_entry,
4642 body_exit, 4480 body_exit,
4643 loop_successor, 4481 loop_successor,
4644 break_info.break_block()); 4482 break_info.break_block());
4645 set_current_block(loop_exit); 4483 set_current_block(loop_exit);
4646 } 4484 }
4647 4485
4648 4486
4649 void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) { 4487 void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
4650 ASSERT(!HasStackOverflow()); 4488 ASSERT(!HasStackOverflow());
4651 ASSERT(current_block() != NULL); 4489 ASSERT(current_block() != NULL);
4652 ASSERT(current_block()->HasPredecessor()); 4490 ASSERT(current_block()->HasPredecessor());
4653 4491
4654 if (!FLAG_optimize_for_in) { 4492 if (!FLAG_optimize_for_in) {
4655 return Bailout("ForInStatement optimization is disabled"); 4493 return Bailout("ForInStatement optimization is disabled");
4656 } 4494 }
4657 4495
4658 if (!oracle()->IsForInFastCase(stmt)) { 4496 if (!oracle()->IsForInFastCase(stmt)) {
4659 return Bailout("ForInStatement is not fast case"); 4497 return Bailout("ForInStatement is not fast case");
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
4760 HBasicBlock* loop_exit = CreateLoop(stmt, 4598 HBasicBlock* loop_exit = CreateLoop(stmt,
4761 loop_entry, 4599 loop_entry,
4762 body_exit, 4600 body_exit,
4763 loop_successor, 4601 loop_successor,
4764 break_info.break_block()); 4602 break_info.break_block());
4765 4603
4766 set_current_block(loop_exit); 4604 set_current_block(loop_exit);
4767 } 4605 }
4768 4606
4769 4607
4770 void HOptimizedGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { 4608 void HGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
4771 ASSERT(!HasStackOverflow()); 4609 ASSERT(!HasStackOverflow());
4772 ASSERT(current_block() != NULL); 4610 ASSERT(current_block() != NULL);
4773 ASSERT(current_block()->HasPredecessor()); 4611 ASSERT(current_block()->HasPredecessor());
4774 return Bailout("TryCatchStatement"); 4612 return Bailout("TryCatchStatement");
4775 } 4613 }
4776 4614
4777 4615
4778 void HOptimizedGraphBuilder::VisitTryFinallyStatement( 4616 void HGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
4779 TryFinallyStatement* stmt) {
4780 ASSERT(!HasStackOverflow()); 4617 ASSERT(!HasStackOverflow());
4781 ASSERT(current_block() != NULL); 4618 ASSERT(current_block() != NULL);
4782 ASSERT(current_block()->HasPredecessor()); 4619 ASSERT(current_block()->HasPredecessor());
4783 return Bailout("TryFinallyStatement"); 4620 return Bailout("TryFinallyStatement");
4784 } 4621 }
4785 4622
4786 4623
4787 void HOptimizedGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { 4624 void HGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
4788 ASSERT(!HasStackOverflow()); 4625 ASSERT(!HasStackOverflow());
4789 ASSERT(current_block() != NULL); 4626 ASSERT(current_block() != NULL);
4790 ASSERT(current_block()->HasPredecessor()); 4627 ASSERT(current_block()->HasPredecessor());
4791 return Bailout("DebuggerStatement"); 4628 return Bailout("DebuggerStatement");
4792 } 4629 }
4793 4630
4794 4631
4795 static Handle<SharedFunctionInfo> SearchSharedFunctionInfo( 4632 static Handle<SharedFunctionInfo> SearchSharedFunctionInfo(
4796 Code* unoptimized_code, FunctionLiteral* expr) { 4633 Code* unoptimized_code, FunctionLiteral* expr) {
4797 int start_position = expr->start_position(); 4634 int start_position = expr->start_position();
4798 RelocIterator it(unoptimized_code); 4635 RelocIterator it(unoptimized_code);
4799 for (;!it.done(); it.next()) { 4636 for (;!it.done(); it.next()) {
4800 RelocInfo* rinfo = it.rinfo(); 4637 RelocInfo* rinfo = it.rinfo();
4801 if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue; 4638 if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue;
4802 Object* obj = rinfo->target_object(); 4639 Object* obj = rinfo->target_object();
4803 if (obj->IsSharedFunctionInfo()) { 4640 if (obj->IsSharedFunctionInfo()) {
4804 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); 4641 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
4805 if (shared->start_position() == start_position) { 4642 if (shared->start_position() == start_position) {
4806 return Handle<SharedFunctionInfo>(shared); 4643 return Handle<SharedFunctionInfo>(shared);
4807 } 4644 }
4808 } 4645 }
4809 } 4646 }
4810 4647
4811 return Handle<SharedFunctionInfo>(); 4648 return Handle<SharedFunctionInfo>();
4812 } 4649 }
4813 4650
4814 4651
4815 void HOptimizedGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { 4652 void HGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
4816 ASSERT(!HasStackOverflow()); 4653 ASSERT(!HasStackOverflow());
4817 ASSERT(current_block() != NULL); 4654 ASSERT(current_block() != NULL);
4818 ASSERT(current_block()->HasPredecessor()); 4655 ASSERT(current_block()->HasPredecessor());
4819 Handle<SharedFunctionInfo> shared_info = 4656 Handle<SharedFunctionInfo> shared_info =
4820 SearchSharedFunctionInfo(info()->shared_info()->code(), 4657 SearchSharedFunctionInfo(info()->shared_info()->code(),
4821 expr); 4658 expr);
4822 if (shared_info.is_null()) { 4659 if (shared_info.is_null()) {
4823 shared_info = Compiler::BuildFunctionInfo(expr, info()->script()); 4660 shared_info = Compiler::BuildFunctionInfo(expr, info()->script());
4824 } 4661 }
4825 // We also have a stack overflow if the recursive compilation did. 4662 // We also have a stack overflow if the recursive compilation did.
4826 if (HasStackOverflow()) return; 4663 if (HasStackOverflow()) return;
4827 HValue* context = environment()->LookupContext(); 4664 HValue* context = environment()->LookupContext();
4828 HFunctionLiteral* instr = 4665 HFunctionLiteral* instr =
4829 new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure()); 4666 new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure());
4830 return ast_context()->ReturnInstruction(instr, expr->id()); 4667 return ast_context()->ReturnInstruction(instr, expr->id());
4831 } 4668 }
4832 4669
4833 4670
4834 void HOptimizedGraphBuilder::VisitSharedFunctionInfoLiteral( 4671 void HGraphBuilder::VisitSharedFunctionInfoLiteral(
4835 SharedFunctionInfoLiteral* expr) { 4672 SharedFunctionInfoLiteral* expr) {
4836 ASSERT(!HasStackOverflow()); 4673 ASSERT(!HasStackOverflow());
4837 ASSERT(current_block() != NULL); 4674 ASSERT(current_block() != NULL);
4838 ASSERT(current_block()->HasPredecessor()); 4675 ASSERT(current_block()->HasPredecessor());
4839 return Bailout("SharedFunctionInfoLiteral"); 4676 return Bailout("SharedFunctionInfoLiteral");
4840 } 4677 }
4841 4678
4842 4679
4843 void HOptimizedGraphBuilder::VisitConditional(Conditional* expr) { 4680 void HGraphBuilder::VisitConditional(Conditional* expr) {
4844 ASSERT(!HasStackOverflow()); 4681 ASSERT(!HasStackOverflow());
4845 ASSERT(current_block() != NULL); 4682 ASSERT(current_block() != NULL);
4846 ASSERT(current_block()->HasPredecessor()); 4683 ASSERT(current_block()->HasPredecessor());
4847 HBasicBlock* cond_true = graph()->CreateBasicBlock(); 4684 HBasicBlock* cond_true = graph()->CreateBasicBlock();
4848 HBasicBlock* cond_false = graph()->CreateBasicBlock(); 4685 HBasicBlock* cond_false = graph()->CreateBasicBlock();
4849 CHECK_BAILOUT(VisitForControl(expr->condition(), cond_true, cond_false)); 4686 CHECK_BAILOUT(VisitForControl(expr->condition(), cond_true, cond_false));
4850 4687
4851 // Visit the true and false subexpressions in the same AST context as the 4688 // Visit the true and false subexpressions in the same AST context as the
4852 // whole expression. 4689 // whole expression.
4853 if (cond_true->HasPredecessor()) { 4690 if (cond_true->HasPredecessor()) {
(...skipping 17 matching lines...) Expand all
4871 if (!ast_context()->IsTest()) { 4708 if (!ast_context()->IsTest()) {
4872 HBasicBlock* join = CreateJoin(cond_true, cond_false, expr->id()); 4709 HBasicBlock* join = CreateJoin(cond_true, cond_false, expr->id());
4873 set_current_block(join); 4710 set_current_block(join);
4874 if (join != NULL && !ast_context()->IsEffect()) { 4711 if (join != NULL && !ast_context()->IsEffect()) {
4875 return ast_context()->ReturnValue(Pop()); 4712 return ast_context()->ReturnValue(Pop());
4876 } 4713 }
4877 } 4714 }
4878 } 4715 }
4879 4716
4880 4717
4881 HOptimizedGraphBuilder::GlobalPropertyAccess 4718 HGraphBuilder::GlobalPropertyAccess HGraphBuilder::LookupGlobalProperty(
4882 HOptimizedGraphBuilder::LookupGlobalProperty( 4719 Variable* var, LookupResult* lookup, bool is_store) {
4883 Variable* var, LookupResult* lookup, bool is_store) {
4884 if (var->is_this() || !info()->has_global_object()) { 4720 if (var->is_this() || !info()->has_global_object()) {
4885 return kUseGeneric; 4721 return kUseGeneric;
4886 } 4722 }
4887 Handle<GlobalObject> global(info()->global_object()); 4723 Handle<GlobalObject> global(info()->global_object());
4888 global->Lookup(*var->name(), lookup); 4724 global->Lookup(*var->name(), lookup);
4889 if (!lookup->IsNormal() || 4725 if (!lookup->IsNormal() ||
4890 (is_store && lookup->IsReadOnly()) || 4726 (is_store && lookup->IsReadOnly()) ||
4891 lookup->holder() != *global) { 4727 lookup->holder() != *global) {
4892 return kUseGeneric; 4728 return kUseGeneric;
4893 } 4729 }
4894 4730
4895 return kUseCell; 4731 return kUseCell;
4896 } 4732 }
4897 4733
4898 4734
4899 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { 4735 HValue* HGraphBuilder::BuildContextChainWalk(Variable* var) {
4900 ASSERT(var->IsContextSlot()); 4736 ASSERT(var->IsContextSlot());
4901 HValue* context = environment()->LookupContext(); 4737 HValue* context = environment()->LookupContext();
4902 int length = info()->scope()->ContextChainLength(var->scope()); 4738 int length = info()->scope()->ContextChainLength(var->scope());
4903 while (length-- > 0) { 4739 while (length-- > 0) {
4904 HInstruction* context_instruction = new(zone()) HOuterContext(context); 4740 HInstruction* context_instruction = new(zone()) HOuterContext(context);
4905 AddInstruction(context_instruction); 4741 AddInstruction(context_instruction);
4906 context = context_instruction; 4742 context = context_instruction;
4907 } 4743 }
4908 return context; 4744 return context;
4909 } 4745 }
4910 4746
4911 4747
4912 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { 4748 void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
4913 ASSERT(!HasStackOverflow()); 4749 ASSERT(!HasStackOverflow());
4914 ASSERT(current_block() != NULL); 4750 ASSERT(current_block() != NULL);
4915 ASSERT(current_block()->HasPredecessor()); 4751 ASSERT(current_block()->HasPredecessor());
4916 Variable* variable = expr->var(); 4752 Variable* variable = expr->var();
4917 switch (variable->location()) { 4753 switch (variable->location()) {
4918 case Variable::UNALLOCATED: { 4754 case Variable::UNALLOCATED: {
4919 if (IsLexicalVariableMode(variable->mode())) { 4755 if (IsLexicalVariableMode(variable->mode())) {
4920 // TODO(rossberg): should this be an ASSERT? 4756 // TODO(rossberg): should this be an ASSERT?
4921 return Bailout("reference to global lexical variable"); 4757 return Bailout("reference to global lexical variable");
4922 } 4758 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
4975 HLoadContextSlot* instr = new(zone()) HLoadContextSlot(context, variable); 4811 HLoadContextSlot* instr = new(zone()) HLoadContextSlot(context, variable);
4976 return ast_context()->ReturnInstruction(instr, expr->id()); 4812 return ast_context()->ReturnInstruction(instr, expr->id());
4977 } 4813 }
4978 4814
4979 case Variable::LOOKUP: 4815 case Variable::LOOKUP:
4980 return Bailout("reference to a variable which requires dynamic lookup"); 4816 return Bailout("reference to a variable which requires dynamic lookup");
4981 } 4817 }
4982 } 4818 }
4983 4819
4984 4820
4985 void HOptimizedGraphBuilder::VisitLiteral(Literal* expr) { 4821 void HGraphBuilder::VisitLiteral(Literal* expr) {
4986 ASSERT(!HasStackOverflow()); 4822 ASSERT(!HasStackOverflow());
4987 ASSERT(current_block() != NULL); 4823 ASSERT(current_block() != NULL);
4988 ASSERT(current_block()->HasPredecessor()); 4824 ASSERT(current_block()->HasPredecessor());
4989 HConstant* instr = 4825 HConstant* instr =
4990 new(zone()) HConstant(expr->handle(), Representation::None()); 4826 new(zone()) HConstant(expr->handle(), Representation::None());
4991 return ast_context()->ReturnInstruction(instr, expr->id()); 4827 return ast_context()->ReturnInstruction(instr, expr->id());
4992 } 4828 }
4993 4829
4994 4830
4995 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { 4831 void HGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
4996 ASSERT(!HasStackOverflow()); 4832 ASSERT(!HasStackOverflow());
4997 ASSERT(current_block() != NULL); 4833 ASSERT(current_block() != NULL);
4998 ASSERT(current_block()->HasPredecessor()); 4834 ASSERT(current_block()->HasPredecessor());
4999 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 4835 Handle<JSFunction> closure = function_state()->compilation_info()->closure();
5000 Handle<FixedArray> literals(closure->literals()); 4836 Handle<FixedArray> literals(closure->literals());
5001 HValue* context = environment()->LookupContext(); 4837 HValue* context = environment()->LookupContext();
5002 4838
5003 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context, 4839 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context,
5004 literals, 4840 literals,
5005 expr->pattern(), 4841 expr->pattern(),
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
5144 } 4980 }
5145 } 4981 }
5146 } 4982 }
5147 } 4983 }
5148 4984
5149 *total_size += boilerplate->map()->instance_size(); 4985 *total_size += boilerplate->map()->instance_size();
5150 return true; 4986 return true;
5151 } 4987 }
5152 4988
5153 4989
5154 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { 4990 void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
5155 ASSERT(!HasStackOverflow()); 4991 ASSERT(!HasStackOverflow());
5156 ASSERT(current_block() != NULL); 4992 ASSERT(current_block() != NULL);
5157 ASSERT(current_block()->HasPredecessor()); 4993 ASSERT(current_block()->HasPredecessor());
5158 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 4994 Handle<JSFunction> closure = function_state()->compilation_info()->closure();
5159 HValue* context = environment()->LookupContext(); 4995 HValue* context = environment()->LookupContext();
5160 HInstruction* literal; 4996 HInstruction* literal;
5161 4997
5162 // Check whether to use fast or slow deep-copying for boilerplate. 4998 // Check whether to use fast or slow deep-copying for boilerplate.
5163 int total_size = 0; 4999 int total_size = 0;
5164 int max_properties = HFastLiteral::kMaxLiteralProperties; 5000 int max_properties = HFastLiteral::kMaxLiteralProperties;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
5249 // (e.g. because of code motion). 5085 // (e.g. because of code motion).
5250 HToFastProperties* result = new(zone()) HToFastProperties(Pop()); 5086 HToFastProperties* result = new(zone()) HToFastProperties(Pop());
5251 AddInstruction(result); 5087 AddInstruction(result);
5252 return ast_context()->ReturnValue(result); 5088 return ast_context()->ReturnValue(result);
5253 } else { 5089 } else {
5254 return ast_context()->ReturnValue(Pop()); 5090 return ast_context()->ReturnValue(Pop());
5255 } 5091 }
5256 } 5092 }
5257 5093
5258 5094
5259 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { 5095 void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
5260 ASSERT(!HasStackOverflow()); 5096 ASSERT(!HasStackOverflow());
5261 ASSERT(current_block() != NULL); 5097 ASSERT(current_block() != NULL);
5262 ASSERT(current_block()->HasPredecessor()); 5098 ASSERT(current_block()->HasPredecessor());
5263 ZoneList<Expression*>* subexprs = expr->values(); 5099 ZoneList<Expression*>* subexprs = expr->values();
5264 int length = subexprs->length(); 5100 int length = subexprs->length();
5265 HValue* context = environment()->LookupContext(); 5101 HValue* context = environment()->LookupContext();
5266 HInstruction* literal; 5102 HInstruction* literal;
5267 5103
5268 Handle<FixedArray> literals(environment()->closure()->literals()); 5104 Handle<FixedArray> literals(environment()->closure()->literals());
5269 Handle<Object> raw_boilerplate(literals->get(expr->literal_index())); 5105 Handle<Object> raw_boilerplate(literals->get(expr->literal_index()));
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
5383 ASSERT(lookup->IsField() || lookup->IsTransitionToField(*type)); 5219 ASSERT(lookup->IsField() || lookup->IsTransitionToField(*type));
5384 if (lookup->IsField()) { 5220 if (lookup->IsField()) {
5385 return lookup->GetLocalFieldIndexFromMap(*type); 5221 return lookup->GetLocalFieldIndexFromMap(*type);
5386 } else { 5222 } else {
5387 Map* transition = lookup->GetTransitionMapFromMap(*type); 5223 Map* transition = lookup->GetTransitionMapFromMap(*type);
5388 return transition->PropertyIndexFor(*name) - type->inobject_properties(); 5224 return transition->PropertyIndexFor(*name) - type->inobject_properties();
5389 } 5225 }
5390 } 5226 }
5391 5227
5392 5228
5393 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object, 5229 void HGraphBuilder::AddCheckMapsWithTransitions(HValue* object,
5394 Handle<Map> map) { 5230 Handle<Map> map) {
5395 AddInstruction(new(zone()) HCheckNonSmi(object)); 5231 AddInstruction(new(zone()) HCheckNonSmi(object));
5396 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); 5232 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone()));
5397 } 5233 }
5398 5234
5399 5235
5400 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( 5236 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object,
5401 HValue* object, 5237 Handle<String> name,
5402 Handle<String> name, 5238 HValue* value,
5403 HValue* value, 5239 Handle<Map> map,
5404 Handle<Map> map, 5240 LookupResult* lookup) {
5405 LookupResult* lookup) {
5406 ASSERT(lookup->IsFound()); 5241 ASSERT(lookup->IsFound());
5407 // If the property does not exist yet, we have to check that it wasn't made 5242 // If the property does not exist yet, we have to check that it wasn't made
5408 // readonly or turned into a setter by some meanwhile modifications on the 5243 // readonly or turned into a setter by some meanwhile modifications on the
5409 // prototype chain. 5244 // prototype chain.
5410 if (!lookup->IsProperty() && map->prototype()->IsJSReceiver()) { 5245 if (!lookup->IsProperty() && map->prototype()->IsJSReceiver()) {
5411 Object* proto = map->prototype(); 5246 Object* proto = map->prototype();
5412 // First check that the prototype chain isn't affected already. 5247 // First check that the prototype chain isn't affected already.
5413 LookupResult proto_result(isolate()); 5248 LookupResult proto_result(isolate());
5414 proto->Lookup(*name, &proto_result); 5249 proto->Lookup(*name, &proto_result);
5415 if (proto_result.IsProperty()) { 5250 if (proto_result.IsProperty()) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
5447 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); 5282 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map));
5448 instr->set_transition(transition); 5283 instr->set_transition(transition);
5449 // TODO(fschneider): Record the new map type of the object in the IR to 5284 // TODO(fschneider): Record the new map type of the object in the IR to
5450 // enable elimination of redundant checks after the transition store. 5285 // enable elimination of redundant checks after the transition store.
5451 instr->SetGVNFlag(kChangesMaps); 5286 instr->SetGVNFlag(kChangesMaps);
5452 } 5287 }
5453 return instr; 5288 return instr;
5454 } 5289 }
5455 5290
5456 5291
5457 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedGeneric( 5292 HInstruction* HGraphBuilder::BuildStoreNamedGeneric(HValue* object,
5458 HValue* object, 5293 Handle<String> name,
5459 Handle<String> name, 5294 HValue* value) {
5460 HValue* value) {
5461 HValue* context = environment()->LookupContext(); 5295 HValue* context = environment()->LookupContext();
5462 return new(zone()) HStoreNamedGeneric( 5296 return new(zone()) HStoreNamedGeneric(
5463 context, 5297 context,
5464 object, 5298 object,
5465 name, 5299 name,
5466 value, 5300 value,
5467 function_strict_mode_flag()); 5301 function_strict_mode_flag());
5468 } 5302 }
5469 5303
5470 5304
5471 HInstruction* HOptimizedGraphBuilder::BuildCallSetter( 5305 HInstruction* HGraphBuilder::BuildCallSetter(HValue* object,
5472 HValue* object, 5306 HValue* value,
5473 HValue* value, 5307 Handle<Map> map,
5474 Handle<Map> map, 5308 Handle<JSFunction> setter,
5475 Handle<JSFunction> setter, 5309 Handle<JSObject> holder) {
5476 Handle<JSObject> holder) {
5477 AddCheckConstantFunction(holder, object, map); 5310 AddCheckConstantFunction(holder, object, map);
5478 AddInstruction(new(zone()) HPushArgument(object)); 5311 AddInstruction(new(zone()) HPushArgument(object));
5479 AddInstruction(new(zone()) HPushArgument(value)); 5312 AddInstruction(new(zone()) HPushArgument(value));
5480 return new(zone()) HCallConstantFunction(setter, 2); 5313 return new(zone()) HCallConstantFunction(setter, 2);
5481 } 5314 }
5482 5315
5483 5316
5484 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedMonomorphic( 5317 HInstruction* HGraphBuilder::BuildStoreNamedMonomorphic(HValue* object,
5485 HValue* object, 5318 Handle<String> name,
5486 Handle<String> name, 5319 HValue* value,
5487 HValue* value, 5320 Handle<Map> map) {
5488 Handle<Map> map) {
5489 // Handle a store to a known field. 5321 // Handle a store to a known field.
5490 LookupResult lookup(isolate()); 5322 LookupResult lookup(isolate());
5491 if (ComputeLoadStoreField(map, name, &lookup, true)) { 5323 if (ComputeLoadStoreField(map, name, &lookup, true)) {
5492 AddCheckMapsWithTransitions(object, map); 5324 AddCheckMapsWithTransitions(object, map);
5493 return BuildStoreNamedField(object, name, value, map, &lookup); 5325 return BuildStoreNamedField(object, name, value, map, &lookup);
5494 } 5326 }
5495 5327
5496 // No luck, do a generic store. 5328 // No luck, do a generic store.
5497 return BuildStoreNamedGeneric(object, name, value); 5329 return BuildStoreNamedGeneric(object, name, value);
5498 } 5330 }
5499 5331
5500 5332
5501 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( 5333 void HGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr,
5502 Property* expr, 5334 HValue* object,
5503 HValue* object, 5335 SmallMapList* types,
5504 SmallMapList* types, 5336 Handle<String> name) {
5505 Handle<String> name) {
5506 int count = 0; 5337 int count = 0;
5507 int previous_field_offset = 0; 5338 int previous_field_offset = 0;
5508 bool previous_field_is_in_object = false; 5339 bool previous_field_is_in_object = false;
5509 bool is_monomorphic_field = true; 5340 bool is_monomorphic_field = true;
5510 Handle<Map> map; 5341 Handle<Map> map;
5511 LookupResult lookup(isolate()); 5342 LookupResult lookup(isolate());
5512 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { 5343 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
5513 map = types->at(i); 5344 map = types->at(i);
5514 if (ComputeLoadStoreField(map, name, &lookup, false)) { 5345 if (ComputeLoadStoreField(map, name, &lookup, false)) {
5515 int index = ComputeLoadStoreFieldIndex(map, name, &lookup); 5346 int index = ComputeLoadStoreFieldIndex(map, name, &lookup);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
5547 types, 5378 types,
5548 name, 5379 name,
5549 zone()); 5380 zone());
5550 } 5381 }
5551 5382
5552 instr->set_position(expr->position()); 5383 instr->set_position(expr->position());
5553 return ast_context()->ReturnInstruction(instr, expr->id()); 5384 return ast_context()->ReturnInstruction(instr, expr->id());
5554 } 5385 }
5555 5386
5556 5387
5557 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( 5388 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr,
5558 Assignment* expr, 5389 HValue* object,
5559 HValue* object, 5390 HValue* value,
5560 HValue* value, 5391 SmallMapList* types,
5561 SmallMapList* types, 5392 Handle<String> name) {
5562 Handle<String> name) {
5563 // TODO(ager): We should recognize when the prototype chains for different 5393 // TODO(ager): We should recognize when the prototype chains for different
5564 // maps are identical. In that case we can avoid repeatedly generating the 5394 // maps are identical. In that case we can avoid repeatedly generating the
5565 // same prototype map checks. 5395 // same prototype map checks.
5566 int count = 0; 5396 int count = 0;
5567 HBasicBlock* join = NULL; 5397 HBasicBlock* join = NULL;
5568 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { 5398 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) {
5569 Handle<Map> map = types->at(i); 5399 Handle<Map> map = types->at(i);
5570 LookupResult lookup(isolate()); 5400 LookupResult lookup(isolate());
5571 if (ComputeLoadStoreField(map, name, &lookup, true)) { 5401 if (ComputeLoadStoreField(map, name, &lookup, true)) {
5572 if (count == 0) { 5402 if (count == 0) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
5624 } 5454 }
5625 } 5455 }
5626 5456
5627 ASSERT(join != NULL); 5457 ASSERT(join != NULL);
5628 join->SetJoinId(expr->id()); 5458 join->SetJoinId(expr->id());
5629 set_current_block(join); 5459 set_current_block(join);
5630 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); 5460 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop());
5631 } 5461 }
5632 5462
5633 5463
5634 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { 5464 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
5635 Property* prop = expr->target()->AsProperty(); 5465 Property* prop = expr->target()->AsProperty();
5636 ASSERT(prop != NULL); 5466 ASSERT(prop != NULL);
5637 expr->RecordTypeFeedback(oracle(), zone()); 5467 expr->RecordTypeFeedback(oracle(), zone());
5638 CHECK_ALIVE(VisitForValue(prop->obj())); 5468 CHECK_ALIVE(VisitForValue(prop->obj()));
5639 5469
5640 if (prop->key()->IsPropertyName()) { 5470 if (prop->key()->IsPropertyName()) {
5641 // Named store. 5471 // Named store.
5642 CHECK_ALIVE(VisitForValue(expr->value())); 5472 CHECK_ALIVE(VisitForValue(expr->value()));
5643 HValue* value = environment()->ExpressionStackAt(0); 5473 HValue* value = environment()->ExpressionStackAt(0);
5644 HValue* object = environment()->ExpressionStackAt(1); 5474 HValue* object = environment()->ExpressionStackAt(1);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
5707 ASSERT(has_side_effects); // Stores always have side effects. 5537 ASSERT(has_side_effects); // Stores always have side effects.
5708 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); 5538 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
5709 return ast_context()->ReturnValue(Pop()); 5539 return ast_context()->ReturnValue(Pop());
5710 } 5540 }
5711 } 5541 }
5712 5542
5713 5543
5714 // Because not every expression has a position and there is not common 5544 // Because not every expression has a position and there is not common
5715 // superclass of Assignment and CountOperation, we cannot just pass the 5545 // superclass of Assignment and CountOperation, we cannot just pass the
5716 // owning expression instead of position and ast_id separately. 5546 // owning expression instead of position and ast_id separately.
5717 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( 5547 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var,
5718 Variable* var, 5548 HValue* value,
5719 HValue* value, 5549 int position,
5720 int position, 5550 BailoutId ast_id) {
5721 BailoutId ast_id) {
5722 LookupResult lookup(isolate()); 5551 LookupResult lookup(isolate());
5723 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); 5552 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true);
5724 if (type == kUseCell) { 5553 if (type == kUseCell) {
5725 Handle<GlobalObject> global(info()->global_object()); 5554 Handle<GlobalObject> global(info()->global_object());
5726 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); 5555 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup));
5727 HInstruction* instr = 5556 HInstruction* instr =
5728 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); 5557 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails());
5729 instr->set_position(position); 5558 instr->set_position(position);
5730 AddInstruction(instr); 5559 AddInstruction(instr);
5731 if (instr->HasObservableSideEffects()) { 5560 if (instr->HasObservableSideEffects()) {
(...skipping 10 matching lines...) Expand all
5742 value, 5571 value,
5743 function_strict_mode_flag()); 5572 function_strict_mode_flag());
5744 instr->set_position(position); 5573 instr->set_position(position);
5745 AddInstruction(instr); 5574 AddInstruction(instr);
5746 ASSERT(instr->HasObservableSideEffects()); 5575 ASSERT(instr->HasObservableSideEffects());
5747 AddSimulate(ast_id, REMOVABLE_SIMULATE); 5576 AddSimulate(ast_id, REMOVABLE_SIMULATE);
5748 } 5577 }
5749 } 5578 }
5750 5579
5751 5580
5752 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 5581 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
5753 Expression* target = expr->target(); 5582 Expression* target = expr->target();
5754 VariableProxy* proxy = target->AsVariableProxy(); 5583 VariableProxy* proxy = target->AsVariableProxy();
5755 Property* prop = target->AsProperty(); 5584 Property* prop = target->AsProperty();
5756 ASSERT(proxy == NULL || prop == NULL); 5585 ASSERT(proxy == NULL || prop == NULL);
5757 5586
5758 // We have a second position recorded in the FullCodeGenerator to have 5587 // We have a second position recorded in the FullCodeGenerator to have
5759 // type feedback for the binary operation. 5588 // type feedback for the binary operation.
5760 BinaryOperation* operation = expr->binary_operation(); 5589 BinaryOperation* operation = expr->binary_operation();
5761 5590
5762 if (proxy != NULL) { 5591 if (proxy != NULL) {
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
5939 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); 5768 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
5940 return ast_context()->ReturnValue(Pop()); 5769 return ast_context()->ReturnValue(Pop());
5941 } 5770 }
5942 5771
5943 } else { 5772 } else {
5944 return Bailout("invalid lhs in compound assignment"); 5773 return Bailout("invalid lhs in compound assignment");
5945 } 5774 }
5946 } 5775 }
5947 5776
5948 5777
5949 void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { 5778 void HGraphBuilder::VisitAssignment(Assignment* expr) {
5950 ASSERT(!HasStackOverflow()); 5779 ASSERT(!HasStackOverflow());
5951 ASSERT(current_block() != NULL); 5780 ASSERT(current_block() != NULL);
5952 ASSERT(current_block()->HasPredecessor()); 5781 ASSERT(current_block()->HasPredecessor());
5953 VariableProxy* proxy = expr->target()->AsVariableProxy(); 5782 VariableProxy* proxy = expr->target()->AsVariableProxy();
5954 Property* prop = expr->target()->AsProperty(); 5783 Property* prop = expr->target()->AsProperty();
5955 ASSERT(proxy == NULL || prop == NULL); 5784 ASSERT(proxy == NULL || prop == NULL);
5956 5785
5957 if (expr->is_compound()) { 5786 if (expr->is_compound()) {
5958 HandleCompoundAssignment(expr); 5787 HandleCompoundAssignment(expr);
5959 return; 5788 return;
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
6066 5895
6067 case Variable::LOOKUP: 5896 case Variable::LOOKUP:
6068 return Bailout("assignment to LOOKUP variable"); 5897 return Bailout("assignment to LOOKUP variable");
6069 } 5898 }
6070 } else { 5899 } else {
6071 return Bailout("invalid left-hand side in assignment"); 5900 return Bailout("invalid left-hand side in assignment");
6072 } 5901 }
6073 } 5902 }
6074 5903
6075 5904
6076 void HOptimizedGraphBuilder::VisitThrow(Throw* expr) { 5905 void HGraphBuilder::VisitThrow(Throw* expr) {
6077 ASSERT(!HasStackOverflow()); 5906 ASSERT(!HasStackOverflow());
6078 ASSERT(current_block() != NULL); 5907 ASSERT(current_block() != NULL);
6079 ASSERT(current_block()->HasPredecessor()); 5908 ASSERT(current_block()->HasPredecessor());
6080 // We don't optimize functions with invalid left-hand sides in 5909 // We don't optimize functions with invalid left-hand sides in
6081 // assignments, count operations, or for-in. Consequently throw can 5910 // assignments, count operations, or for-in. Consequently throw can
6082 // currently only occur in an effect context. 5911 // currently only occur in an effect context.
6083 ASSERT(ast_context()->IsEffect()); 5912 ASSERT(ast_context()->IsEffect());
6084 CHECK_ALIVE(VisitForValue(expr->exception())); 5913 CHECK_ALIVE(VisitForValue(expr->exception()));
6085 5914
6086 HValue* context = environment()->LookupContext(); 5915 HValue* context = environment()->LookupContext();
6087 HValue* value = environment()->Pop(); 5916 HValue* value = environment()->Pop();
6088 HThrow* instr = new(zone()) HThrow(context, value); 5917 HThrow* instr = new(zone()) HThrow(context, value);
6089 instr->set_position(expr->position()); 5918 instr->set_position(expr->position());
6090 AddInstruction(instr); 5919 AddInstruction(instr);
6091 AddSimulate(expr->id()); 5920 AddSimulate(expr->id());
6092 current_block()->FinishExit(new(zone()) HAbnormalExit); 5921 current_block()->FinishExit(new(zone()) HAbnormalExit);
6093 set_current_block(NULL); 5922 set_current_block(NULL);
6094 } 5923 }
6095 5924
6096 5925
6097 HLoadNamedField* HOptimizedGraphBuilder::BuildLoadNamedField( 5926 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
6098 HValue* object, 5927 Handle<Map> map,
6099 Handle<Map> map, 5928 LookupResult* lookup) {
6100 LookupResult* lookup) {
6101 int index = lookup->GetLocalFieldIndexFromMap(*map); 5929 int index = lookup->GetLocalFieldIndexFromMap(*map);
6102 if (index < 0) { 5930 if (index < 0) {
6103 // Negative property indices are in-object properties, indexed 5931 // Negative property indices are in-object properties, indexed
6104 // from the end of the fixed part of the object. 5932 // from the end of the fixed part of the object.
6105 int offset = (index * kPointerSize) + map->instance_size(); 5933 int offset = (index * kPointerSize) + map->instance_size();
6106 return new(zone()) HLoadNamedField(object, true, offset); 5934 return new(zone()) HLoadNamedField(object, true, offset);
6107 } else { 5935 } else {
6108 // Non-negative property indices are in the properties array. 5936 // Non-negative property indices are in the properties array.
6109 int offset = (index * kPointerSize) + FixedArray::kHeaderSize; 5937 int offset = (index * kPointerSize) + FixedArray::kHeaderSize;
6110 return new(zone()) HLoadNamedField(object, false, offset); 5938 return new(zone()) HLoadNamedField(object, false, offset);
6111 } 5939 }
6112 } 5940 }
6113 5941
6114 5942
6115 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( 5943 HInstruction* HGraphBuilder::BuildLoadNamedGeneric(HValue* object,
6116 HValue* object, 5944 Handle<String> name,
6117 Handle<String> name, 5945 Property* expr) {
6118 Property* expr) {
6119 if (expr->IsUninitialized() && !FLAG_always_opt) { 5946 if (expr->IsUninitialized() && !FLAG_always_opt) {
6120 AddInstruction(new(zone()) HSoftDeoptimize); 5947 AddInstruction(new(zone()) HSoftDeoptimize);
6121 current_block()->MarkAsDeoptimizing(); 5948 current_block()->MarkAsDeoptimizing();
6122 } 5949 }
6123 HValue* context = environment()->LookupContext(); 5950 HValue* context = environment()->LookupContext();
6124 return new(zone()) HLoadNamedGeneric(context, object, name); 5951 return new(zone()) HLoadNamedGeneric(context, object, name);
6125 } 5952 }
6126 5953
6127 5954
6128 HInstruction* HOptimizedGraphBuilder::BuildCallGetter( 5955 HInstruction* HGraphBuilder::BuildCallGetter(HValue* object,
6129 HValue* object, 5956 Handle<Map> map,
6130 Handle<Map> map, 5957 Handle<JSFunction> getter,
6131 Handle<JSFunction> getter, 5958 Handle<JSObject> holder) {
6132 Handle<JSObject> holder) {
6133 AddCheckConstantFunction(holder, object, map); 5959 AddCheckConstantFunction(holder, object, map);
6134 AddInstruction(new(zone()) HPushArgument(object)); 5960 AddInstruction(new(zone()) HPushArgument(object));
6135 return new(zone()) HCallConstantFunction(getter, 1); 5961 return new(zone()) HCallConstantFunction(getter, 1);
6136 } 5962 }
6137 5963
6138 5964
6139 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic( 5965 HInstruction* HGraphBuilder::BuildLoadNamedMonomorphic(HValue* object,
6140 HValue* object, 5966 Handle<String> name,
6141 Handle<String> name, 5967 Property* expr,
6142 Property* expr, 5968 Handle<Map> map) {
6143 Handle<Map> map) {
6144 // Handle a load from a known field. 5969 // Handle a load from a known field.
6145 ASSERT(!map->is_dictionary_map()); 5970 ASSERT(!map->is_dictionary_map());
6146 LookupResult lookup(isolate()); 5971 LookupResult lookup(isolate());
6147 map->LookupDescriptor(NULL, *name, &lookup); 5972 map->LookupDescriptor(NULL, *name, &lookup);
6148 if (lookup.IsField()) { 5973 if (lookup.IsField()) {
6149 AddCheckMapsWithTransitions(object, map); 5974 AddCheckMapsWithTransitions(object, map);
6150 return BuildLoadNamedField(object, map, &lookup); 5975 return BuildLoadNamedField(object, map, &lookup);
6151 } 5976 }
6152 5977
6153 // Handle a load of a constant known function. 5978 // Handle a load of a constant known function.
(...skipping 13 matching lines...) Expand all
6167 HInstruction* holder_value = 5992 HInstruction* holder_value =
6168 AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder)); 5993 AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder));
6169 return BuildLoadNamedField(holder_value, holder_map, &lookup); 5994 return BuildLoadNamedField(holder_value, holder_map, &lookup);
6170 } 5995 }
6171 5996
6172 // No luck, do a generic load. 5997 // No luck, do a generic load.
6173 return BuildLoadNamedGeneric(object, name, expr); 5998 return BuildLoadNamedGeneric(object, name, expr);
6174 } 5999 }
6175 6000
6176 6001
6177 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, 6002 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object,
6178 HValue* key) { 6003 HValue* key) {
6179 HValue* context = environment()->LookupContext(); 6004 HValue* context = environment()->LookupContext();
6180 return new(zone()) HLoadKeyedGeneric(context, object, key); 6005 return new(zone()) HLoadKeyedGeneric(context, object, key);
6181 } 6006 }
6182 6007
6183 6008
6184 HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess( 6009 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess(
6185 HValue* object, 6010 HValue* external_elements,
6186 HValue* key, 6011 HValue* checked_key,
6187 HValue* val, 6012 HValue* val,
6188 HValue* dependency, 6013 HValue* dependency,
6189 Handle<Map> map, 6014 ElementsKind elements_kind,
6190 bool is_store) { 6015 bool is_store) {
6016 if (is_store) {
6017 ASSERT(val != NULL);
6018 switch (elements_kind) {
6019 case EXTERNAL_PIXEL_ELEMENTS: {
6020 val = AddInstruction(new(zone()) HClampToUint8(val));
6021 break;
6022 }
6023 case EXTERNAL_BYTE_ELEMENTS:
6024 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
6025 case EXTERNAL_SHORT_ELEMENTS:
6026 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
6027 case EXTERNAL_INT_ELEMENTS:
6028 case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
6029 break;
6030 }
6031 case EXTERNAL_FLOAT_ELEMENTS:
6032 case EXTERNAL_DOUBLE_ELEMENTS:
6033 break;
6034 case FAST_SMI_ELEMENTS:
6035 case FAST_ELEMENTS:
6036 case FAST_DOUBLE_ELEMENTS:
6037 case FAST_HOLEY_SMI_ELEMENTS:
6038 case FAST_HOLEY_ELEMENTS:
6039 case FAST_HOLEY_DOUBLE_ELEMENTS:
6040 case DICTIONARY_ELEMENTS:
6041 case NON_STRICT_ARGUMENTS_ELEMENTS:
6042 UNREACHABLE();
6043 break;
6044 }
6045 return new(zone()) HStoreKeyed(external_elements,
6046 checked_key,
6047 val,
6048 elements_kind);
6049 } else {
6050 ASSERT(val == NULL);
6051 HLoadKeyed* load =
6052 new(zone()) HLoadKeyed(
6053 external_elements, checked_key, dependency, elements_kind);
6054 if (FLAG_opt_safe_uint32_operations &&
6055 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) {
6056 graph()->RecordUint32Instruction(load);
6057 }
6058 return load;
6059 }
6060 }
6061
6062
6063 HInstruction* HGraphBuilder::BuildFastElementAccess(HValue* elements,
6064 HValue* checked_key,
6065 HValue* val,
6066 HValue* load_dependency,
6067 ElementsKind elements_kind,
6068 bool is_store) {
6069 if (is_store) {
6070 ASSERT(val != NULL);
6071 switch (elements_kind) {
6072 case FAST_SMI_ELEMENTS:
6073 case FAST_HOLEY_SMI_ELEMENTS:
6074 // Smi-only arrays need a smi check.
6075 AddInstruction(new(zone()) HCheckSmi(val));
6076 // Fall through.
6077 case FAST_ELEMENTS:
6078 case FAST_HOLEY_ELEMENTS:
6079 case FAST_DOUBLE_ELEMENTS:
6080 case FAST_HOLEY_DOUBLE_ELEMENTS:
6081 return new(zone()) HStoreKeyed(
6082 elements, checked_key, val, elements_kind);
6083 default:
6084 UNREACHABLE();
6085 return NULL;
6086 }
6087 }
6088 // It's an element load (!is_store).
6089 return new(zone()) HLoadKeyed(elements,
6090 checked_key,
6091 load_dependency,
6092 elements_kind);
6093 }
6094
6095
6096 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object,
6097 HValue* key,
6098 HValue* val,
6099 HValue* dependency,
6100 Handle<Map> map,
6101 bool is_store) {
6191 HCheckMaps* mapcheck = new(zone()) HCheckMaps(object, map, 6102 HCheckMaps* mapcheck = new(zone()) HCheckMaps(object, map,
6192 zone(), dependency); 6103 zone(), dependency);
6193 AddInstruction(mapcheck); 6104 AddInstruction(mapcheck);
6194 if (dependency) { 6105 if (dependency) {
6195 mapcheck->ClearGVNFlag(kDependsOnElementsKind); 6106 mapcheck->ClearGVNFlag(kDependsOnElementsKind);
6196 } 6107 }
6197 return BuildUncheckedMonomorphicElementAccess( 6108 return BuildUncheckedMonomorphicElementAccess(object, key, val,
6198 object, key, val, 6109 mapcheck, map, is_store);
6199 mapcheck, map->instance_type() == JS_ARRAY_TYPE,
6200 map->elements_kind(), is_store);
6201 } 6110 }
6202 6111
6203 6112
6204 HInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad( 6113 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
6205 HValue* object, 6114 HValue* object,
6206 HValue* key, 6115 HValue* key,
6207 HValue* val, 6116 HValue* val,
6117 HCheckMaps* mapcheck,
6118 Handle<Map> map,
6119 bool is_store) {
6120 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency
6121 // on a HElementsTransition instruction. The flag can also be removed if the
6122 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further
6123 // ElementsKind transitions. Finally, the dependency can be removed for stores
6124 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the
6125 // generated store code.
6126 if ((map->elements_kind() == FAST_HOLEY_ELEMENTS) ||
6127 (map->elements_kind() == FAST_ELEMENTS && is_store)) {
6128 mapcheck->ClearGVNFlag(kDependsOnElementsKind);
6129 }
6130 bool fast_smi_only_elements = map->has_fast_smi_elements();
6131 bool fast_elements = map->has_fast_object_elements();
6132 HInstruction* elements =
6133 AddInstruction(new(zone()) HLoadElements(object, mapcheck));
6134 if (is_store && (fast_elements || fast_smi_only_elements)) {
6135 HCheckMaps* check_cow_map = new(zone()) HCheckMaps(
6136 elements, isolate()->factory()->fixed_array_map(), zone());
6137 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
6138 AddInstruction(check_cow_map);
6139 }
6140 HInstruction* length = NULL;
6141 HInstruction* checked_key = NULL;
6142 if (map->has_external_array_elements()) {
6143 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
6144 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length,
6145 ALLOW_SMI_KEY));
6146 HLoadExternalArrayPointer* external_elements =
6147 new(zone()) HLoadExternalArrayPointer(elements);
6148 AddInstruction(external_elements);
6149 return BuildExternalArrayElementAccess(
6150 external_elements, checked_key, val, mapcheck,
6151 map->elements_kind(), is_store);
6152 }
6153 ASSERT(fast_smi_only_elements ||
6154 fast_elements ||
6155 map->has_fast_double_elements());
6156 if (map->instance_type() == JS_ARRAY_TYPE) {
6157 length = AddInstruction(new(zone()) HJSArrayLength(object, mapcheck,
6158 HType::Smi()));
6159 } else {
6160 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
6161 }
6162 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length,
6163 ALLOW_SMI_KEY));
6164 return BuildFastElementAccess(elements, checked_key, val, mapcheck,
6165 map->elements_kind(), is_store);
6166 }
6167
6168
6169 HInstruction* HGraphBuilder::TryBuildConsolidatedElementLoad(
6170 HValue* object,
6171 HValue* key,
6172 HValue* val,
6208 SmallMapList* maps) { 6173 SmallMapList* maps) {
6209 // For polymorphic loads of similar elements kinds (i.e. all tagged or all 6174 // For polymorphic loads of similar elements kinds (i.e. all tagged or all
6210 // double), always use the "worst case" code without a transition. This is 6175 // double), always use the "worst case" code without a transition. This is
6211 // much faster than transitioning the elements to the worst case, trading a 6176 // much faster than transitioning the elements to the worst case, trading a
6212 // HTransitionElements for a HCheckMaps, and avoiding mutation of the array. 6177 // HTransitionElements for a HCheckMaps, and avoiding mutation of the array.
6213 bool has_double_maps = false; 6178 bool has_double_maps = false;
6214 bool has_smi_or_object_maps = false; 6179 bool has_smi_or_object_maps = false;
6215 bool has_js_array_access = false; 6180 bool has_js_array_access = false;
6216 bool has_non_js_array_access = false; 6181 bool has_non_js_array_access = false;
6217 Handle<Map> most_general_consolidated_map; 6182 Handle<Map> most_general_consolidated_map;
(...skipping 24 matching lines...) Expand all
6242 most_general_consolidated_map->elements_kind(), 6207 most_general_consolidated_map->elements_kind(),
6243 map->elements_kind())) { 6208 map->elements_kind())) {
6244 most_general_consolidated_map = map; 6209 most_general_consolidated_map = map;
6245 } 6210 }
6246 } 6211 }
6247 if (!has_double_maps && !has_smi_or_object_maps) return NULL; 6212 if (!has_double_maps && !has_smi_or_object_maps) return NULL;
6248 6213
6249 HCheckMaps* check_maps = new(zone()) HCheckMaps(object, maps, zone()); 6214 HCheckMaps* check_maps = new(zone()) HCheckMaps(object, maps, zone());
6250 AddInstruction(check_maps); 6215 AddInstruction(check_maps);
6251 HInstruction* instr = BuildUncheckedMonomorphicElementAccess( 6216 HInstruction* instr = BuildUncheckedMonomorphicElementAccess(
6252 object, key, val, check_maps, 6217 object, key, val, check_maps, most_general_consolidated_map, false);
6253 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE,
6254 most_general_consolidated_map->elements_kind(),
6255 false);
6256 return instr; 6218 return instr;
6257 } 6219 }
6258 6220
6259 6221
6260 HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( 6222 HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
6261 HValue* object, 6223 HValue* key,
6262 HValue* key, 6224 HValue* val,
6263 HValue* val, 6225 Expression* prop,
6264 Expression* prop, 6226 BailoutId ast_id,
6265 BailoutId ast_id, 6227 int position,
6266 int position, 6228 bool is_store,
6267 bool is_store, 6229 bool* has_side_effects) {
6268 bool* has_side_effects) {
6269 *has_side_effects = false; 6230 *has_side_effects = false;
6270 AddInstruction(new(zone()) HCheckNonSmi(object)); 6231 AddInstruction(new(zone()) HCheckNonSmi(object));
6271 SmallMapList* maps = prop->GetReceiverTypes(); 6232 SmallMapList* maps = prop->GetReceiverTypes();
6272 bool todo_external_array = false; 6233 bool todo_external_array = false;
6273 6234
6274 if (!is_store) { 6235 if (!is_store) {
6275 HInstruction* consolidated_load = 6236 HInstruction* consolidated_load =
6276 TryBuildConsolidatedElementLoad(object, key, val, maps); 6237 TryBuildConsolidatedElementLoad(object, key, val, maps);
6277 if (consolidated_load != NULL) { 6238 if (consolidated_load != NULL) {
6278 AddInstruction(consolidated_load); 6239 AddInstruction(consolidated_load);
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
6443 elements, checked_key, val, elements_kind_branch, 6404 elements, checked_key, val, elements_kind_branch,
6444 elements_kind, is_store)); 6405 elements_kind, is_store));
6445 } else if (elements_kind == DICTIONARY_ELEMENTS) { 6406 } else if (elements_kind == DICTIONARY_ELEMENTS) {
6446 if (is_store) { 6407 if (is_store) {
6447 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); 6408 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val));
6448 } else { 6409 } else {
6449 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); 6410 access = AddInstruction(BuildLoadKeyedGeneric(object, key));
6450 } 6411 }
6451 } else { // External array elements. 6412 } else { // External array elements.
6452 access = AddInstruction(BuildExternalArrayElementAccess( 6413 access = AddInstruction(BuildExternalArrayElementAccess(
6453 external_elements, checked_key, val, 6414 external_elements, checked_key, val, elements_kind_branch,
6454 elements_kind_branch, elements_kind, is_store)); 6415 elements_kind, is_store));
6455 } 6416 }
6456 *has_side_effects |= access->HasObservableSideEffects(); 6417 *has_side_effects |= access->HasObservableSideEffects();
6457 if (position != RelocInfo::kNoPosition) access->set_position(position); 6418 if (position != RelocInfo::kNoPosition) access->set_position(position);
6458 if (!is_store) { 6419 if (!is_store) {
6459 Push(access); 6420 Push(access);
6460 } 6421 }
6461 current_block()->Goto(join); 6422 current_block()->Goto(join);
6462 set_current_block(if_false); 6423 set_current_block(if_false);
6463 } 6424 }
6464 } 6425 }
6465 6426
6466 // Deopt if none of the cases matched. 6427 // Deopt if none of the cases matched.
6467 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); 6428 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses);
6468 join->SetJoinId(ast_id); 6429 join->SetJoinId(ast_id);
6469 set_current_block(join); 6430 set_current_block(join);
6470 return is_store ? NULL : Pop(); 6431 return is_store ? NULL : Pop();
6471 } 6432 }
6472 6433
6473 6434
6474 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( 6435 HValue* HGraphBuilder::HandleKeyedElementAccess(HValue* obj,
6475 HValue* obj, 6436 HValue* key,
6476 HValue* key, 6437 HValue* val,
6477 HValue* val, 6438 Expression* expr,
6478 Expression* expr, 6439 BailoutId ast_id,
6479 BailoutId ast_id, 6440 int position,
6480 int position, 6441 bool is_store,
6481 bool is_store, 6442 bool* has_side_effects) {
6482 bool* has_side_effects) {
6483 ASSERT(!expr->IsPropertyName()); 6443 ASSERT(!expr->IsPropertyName());
6484 HInstruction* instr = NULL; 6444 HInstruction* instr = NULL;
6485 if (expr->IsMonomorphic()) { 6445 if (expr->IsMonomorphic()) {
6486 Handle<Map> map = expr->GetMonomorphicReceiverType(); 6446 Handle<Map> map = expr->GetMonomorphicReceiverType();
6487 if (map->has_slow_elements_kind()) { 6447 if (map->has_slow_elements_kind()) {
6488 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val) 6448 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val)
6489 : BuildLoadKeyedGeneric(obj, key); 6449 : BuildLoadKeyedGeneric(obj, key);
6490 } else { 6450 } else {
6491 AddInstruction(new(zone()) HCheckNonSmi(obj)); 6451 AddInstruction(new(zone()) HCheckNonSmi(obj));
6492 instr = BuildMonomorphicElementAccess(obj, key, val, NULL, map, is_store); 6452 instr = BuildMonomorphicElementAccess(obj, key, val, NULL, map, is_store);
6493 } 6453 }
6494 } else if (expr->GetReceiverTypes() != NULL && 6454 } else if (expr->GetReceiverTypes() != NULL &&
6495 !expr->GetReceiverTypes()->is_empty()) { 6455 !expr->GetReceiverTypes()->is_empty()) {
6496 return HandlePolymorphicElementAccess( 6456 return HandlePolymorphicElementAccess(
6497 obj, key, val, expr, ast_id, position, is_store, has_side_effects); 6457 obj, key, val, expr, ast_id, position, is_store, has_side_effects);
6498 } else { 6458 } else {
6499 if (is_store) { 6459 if (is_store) {
6500 instr = BuildStoreKeyedGeneric(obj, key, val); 6460 instr = BuildStoreKeyedGeneric(obj, key, val);
6501 } else { 6461 } else {
6502 instr = BuildLoadKeyedGeneric(obj, key); 6462 instr = BuildLoadKeyedGeneric(obj, key);
6503 } 6463 }
6504 } 6464 }
6505 if (position != RelocInfo::kNoPosition) instr->set_position(position); 6465 if (position != RelocInfo::kNoPosition) instr->set_position(position);
6506 AddInstruction(instr); 6466 AddInstruction(instr);
6507 *has_side_effects = instr->HasObservableSideEffects(); 6467 *has_side_effects = instr->HasObservableSideEffects();
6508 return instr; 6468 return instr;
6509 } 6469 }
6510 6470
6511 6471
6512 HInstruction* HOptimizedGraphBuilder::BuildStoreKeyedGeneric( 6472 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object,
6513 HValue* object, 6473 HValue* key,
6514 HValue* key, 6474 HValue* value) {
6515 HValue* value) {
6516 HValue* context = environment()->LookupContext(); 6475 HValue* context = environment()->LookupContext();
6517 return new(zone()) HStoreKeyedGeneric( 6476 return new(zone()) HStoreKeyedGeneric(
6518 context, 6477 context,
6519 object, 6478 object,
6520 key, 6479 key,
6521 value, 6480 value,
6522 function_strict_mode_flag()); 6481 function_strict_mode_flag());
6523 } 6482 }
6524 6483
6525 6484
6526 void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() { 6485 void HGraphBuilder::EnsureArgumentsArePushedForAccess() {
6527 // Outermost function already has arguments on the stack. 6486 // Outermost function already has arguments on the stack.
6528 if (function_state()->outer() == NULL) return; 6487 if (function_state()->outer() == NULL) return;
6529 6488
6530 if (function_state()->arguments_pushed()) return; 6489 if (function_state()->arguments_pushed()) return;
6531 6490
6532 // Push arguments when entering inlined function. 6491 // Push arguments when entering inlined function.
6533 HEnterInlined* entry = function_state()->entry(); 6492 HEnterInlined* entry = function_state()->entry();
6534 entry->set_arguments_pushed(); 6493 entry->set_arguments_pushed();
6535 6494
6536 ZoneList<HValue*>* arguments_values = entry->arguments_values(); 6495 ZoneList<HValue*>* arguments_values = entry->arguments_values();
6537 6496
6538 HInstruction* insert_after = entry; 6497 HInstruction* insert_after = entry;
6539 for (int i = 0; i < arguments_values->length(); i++) { 6498 for (int i = 0; i < arguments_values->length(); i++) {
6540 HValue* argument = arguments_values->at(i); 6499 HValue* argument = arguments_values->at(i);
6541 HInstruction* push_argument = new(zone()) HPushArgument(argument); 6500 HInstruction* push_argument = new(zone()) HPushArgument(argument);
6542 push_argument->InsertAfter(insert_after); 6501 push_argument->InsertAfter(insert_after);
6543 insert_after = push_argument; 6502 insert_after = push_argument;
6544 } 6503 }
6545 6504
6546 HArgumentsElements* arguments_elements = 6505 HArgumentsElements* arguments_elements =
6547 new(zone()) HArgumentsElements(true); 6506 new(zone()) HArgumentsElements(true);
6548 arguments_elements->ClearFlag(HValue::kUseGVN); 6507 arguments_elements->ClearFlag(HValue::kUseGVN);
6549 arguments_elements->InsertAfter(insert_after); 6508 arguments_elements->InsertAfter(insert_after);
6550 function_state()->set_arguments_elements(arguments_elements); 6509 function_state()->set_arguments_elements(arguments_elements);
6551 } 6510 }
6552 6511
6553 6512
6554 bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) { 6513 bool HGraphBuilder::TryArgumentsAccess(Property* expr) {
6555 VariableProxy* proxy = expr->obj()->AsVariableProxy(); 6514 VariableProxy* proxy = expr->obj()->AsVariableProxy();
6556 if (proxy == NULL) return false; 6515 if (proxy == NULL) return false;
6557 if (!proxy->var()->IsStackAllocated()) return false; 6516 if (!proxy->var()->IsStackAllocated()) return false;
6558 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) { 6517 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) {
6559 return false; 6518 return false;
6560 } 6519 }
6561 6520
6562 HInstruction* result = NULL; 6521 HInstruction* result = NULL;
6563 if (expr->key()->IsPropertyName()) { 6522 if (expr->key()->IsPropertyName()) {
6564 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 6523 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
6603 HInstruction* checked_key = 6562 HInstruction* checked_key =
6604 AddInstruction(new(zone()) HBoundsCheck(key, length)); 6563 AddInstruction(new(zone()) HBoundsCheck(key, length));
6605 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); 6564 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key);
6606 } 6565 }
6607 } 6566 }
6608 ast_context()->ReturnInstruction(result, expr->id()); 6567 ast_context()->ReturnInstruction(result, expr->id());
6609 return true; 6568 return true;
6610 } 6569 }
6611 6570
6612 6571
6613 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { 6572 void HGraphBuilder::VisitProperty(Property* expr) {
6614 ASSERT(!HasStackOverflow()); 6573 ASSERT(!HasStackOverflow());
6615 ASSERT(current_block() != NULL); 6574 ASSERT(current_block() != NULL);
6616 ASSERT(current_block()->HasPredecessor()); 6575 ASSERT(current_block()->HasPredecessor());
6617 expr->RecordTypeFeedback(oracle(), zone()); 6576 expr->RecordTypeFeedback(oracle(), zone());
6618 6577
6619 if (TryArgumentsAccess(expr)) return; 6578 if (TryArgumentsAccess(expr)) return;
6620 6579
6621 CHECK_ALIVE(VisitForValue(expr->obj())); 6580 CHECK_ALIVE(VisitForValue(expr->obj()));
6622 6581
6623 HInstruction* instr = NULL; 6582 HInstruction* instr = NULL;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
6694 Drop(1); 6653 Drop(1);
6695 } 6654 }
6696 } 6655 }
6697 return ast_context()->ReturnValue(load); 6656 return ast_context()->ReturnValue(load);
6698 } 6657 }
6699 instr->set_position(expr->position()); 6658 instr->set_position(expr->position());
6700 return ast_context()->ReturnInstruction(instr, expr->id()); 6659 return ast_context()->ReturnInstruction(instr, expr->id());
6701 } 6660 }
6702 6661
6703 6662
6704 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, 6663 void HGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder,
6705 Handle<Map> receiver_map) { 6664 Handle<Map> receiver_map) {
6706 if (!holder.is_null()) { 6665 if (!holder.is_null()) {
6707 AddInstruction(new(zone()) HCheckPrototypeMaps( 6666 AddInstruction(new(zone()) HCheckPrototypeMaps(
6708 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), holder)); 6667 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), holder));
6709 } 6668 }
6710 } 6669 }
6711 6670
6712 6671
6713 void HOptimizedGraphBuilder::AddCheckConstantFunction( 6672 void HGraphBuilder::AddCheckConstantFunction(Handle<JSObject> holder,
6714 Handle<JSObject> holder, 6673 HValue* receiver,
6715 HValue* receiver, 6674 Handle<Map> receiver_map) {
6716 Handle<Map> receiver_map) {
6717 // Constant functions have the nice property that the map will change if they 6675 // Constant functions have the nice property that the map will change if they
6718 // are overwritten. Therefore it is enough to check the map of the holder and 6676 // are overwritten. Therefore it is enough to check the map of the holder and
6719 // its prototypes. 6677 // its prototypes.
6720 AddCheckMapsWithTransitions(receiver, receiver_map); 6678 AddCheckMapsWithTransitions(receiver, receiver_map);
6721 AddCheckPrototypeMaps(holder, receiver_map); 6679 AddCheckPrototypeMaps(holder, receiver_map);
6722 } 6680 }
6723 6681
6724 6682
6725 class FunctionSorter { 6683 class FunctionSorter {
6726 public: 6684 public:
(...skipping 21 matching lines...) Expand all
6748 FunctionSorter const* function1 = reinterpret_cast<FunctionSorter const*>(a); 6706 FunctionSorter const* function1 = reinterpret_cast<FunctionSorter const*>(a);
6749 FunctionSorter const* function2 = reinterpret_cast<FunctionSorter const*>(b); 6707 FunctionSorter const* function2 = reinterpret_cast<FunctionSorter const*>(b);
6750 int diff = function1->ticks() - function2->ticks(); 6708 int diff = function1->ticks() - function2->ticks();
6751 if (diff != 0) return -diff; 6709 if (diff != 0) return -diff;
6752 diff = function1->ast_length() - function2->ast_length(); 6710 diff = function1->ast_length() - function2->ast_length();
6753 if (diff != 0) return diff; 6711 if (diff != 0) return diff;
6754 return function1->src_length() - function2->src_length(); 6712 return function1->src_length() - function2->src_length();
6755 } 6713 }
6756 6714
6757 6715
6758 void HOptimizedGraphBuilder::HandlePolymorphicCallNamed( 6716 void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
6759 Call* expr, 6717 HValue* receiver,
6760 HValue* receiver, 6718 SmallMapList* types,
6761 SmallMapList* types, 6719 Handle<String> name) {
6762 Handle<String> name) {
6763 // TODO(ager): We should recognize when the prototype chains for different 6720 // TODO(ager): We should recognize when the prototype chains for different
6764 // maps are identical. In that case we can avoid repeatedly generating the 6721 // maps are identical. In that case we can avoid repeatedly generating the
6765 // same prototype map checks. 6722 // same prototype map checks.
6766 int argument_count = expr->arguments()->length() + 1; // Includes receiver. 6723 int argument_count = expr->arguments()->length() + 1; // Includes receiver.
6767 HBasicBlock* join = NULL; 6724 HBasicBlock* join = NULL;
6768 FunctionSorter order[kMaxCallPolymorphism]; 6725 FunctionSorter order[kMaxCallPolymorphism];
6769 int ordered_functions = 0; 6726 int ordered_functions = 0;
6770 for (int i = 0; 6727 for (int i = 0;
6771 i < types->length() && ordered_functions < kMaxCallPolymorphism; 6728 i < types->length() && ordered_functions < kMaxCallPolymorphism;
6772 ++i) { 6729 ++i) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
6854 if (join->HasPredecessor()) { 6811 if (join->HasPredecessor()) {
6855 set_current_block(join); 6812 set_current_block(join);
6856 join->SetJoinId(expr->id()); 6813 join->SetJoinId(expr->id());
6857 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); 6814 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop());
6858 } else { 6815 } else {
6859 set_current_block(NULL); 6816 set_current_block(NULL);
6860 } 6817 }
6861 } 6818 }
6862 6819
6863 6820
6864 void HOptimizedGraphBuilder::TraceInline(Handle<JSFunction> target, 6821 void HGraphBuilder::TraceInline(Handle<JSFunction> target,
6865 Handle<JSFunction> caller, 6822 Handle<JSFunction> caller,
6866 const char* reason) { 6823 const char* reason) {
6867 if (FLAG_trace_inlining) { 6824 if (FLAG_trace_inlining) {
6868 SmartArrayPointer<char> target_name = 6825 SmartArrayPointer<char> target_name =
6869 target->shared()->DebugName()->ToCString(); 6826 target->shared()->DebugName()->ToCString();
6870 SmartArrayPointer<char> caller_name = 6827 SmartArrayPointer<char> caller_name =
6871 caller->shared()->DebugName()->ToCString(); 6828 caller->shared()->DebugName()->ToCString();
6872 if (reason == NULL) { 6829 if (reason == NULL) {
6873 PrintF("Inlined %s called from %s.\n", *target_name, *caller_name); 6830 PrintF("Inlined %s called from %s.\n", *target_name, *caller_name);
6874 } else { 6831 } else {
6875 PrintF("Did not inline %s called from %s (%s).\n", 6832 PrintF("Did not inline %s called from %s (%s).\n",
6876 *target_name, *caller_name, reason); 6833 *target_name, *caller_name, reason);
6877 } 6834 }
6878 } 6835 }
6879 } 6836 }
6880 6837
6881 6838
6882 static const int kNotInlinable = 1000000000; 6839 static const int kNotInlinable = 1000000000;
6883 6840
6884 6841
6885 int HOptimizedGraphBuilder::InliningAstSize(Handle<JSFunction> target) { 6842 int HGraphBuilder::InliningAstSize(Handle<JSFunction> target) {
6886 if (!FLAG_use_inlining) return kNotInlinable; 6843 if (!FLAG_use_inlining) return kNotInlinable;
6887 6844
6888 // Precondition: call is monomorphic and we have found a target with the 6845 // Precondition: call is monomorphic and we have found a target with the
6889 // appropriate arity. 6846 // appropriate arity.
6890 Handle<JSFunction> caller = info()->closure(); 6847 Handle<JSFunction> caller = info()->closure();
6891 Handle<SharedFunctionInfo> target_shared(target->shared()); 6848 Handle<SharedFunctionInfo> target_shared(target->shared());
6892 6849
6893 // Do a quick check on source code length to avoid parsing large 6850 // Do a quick check on source code length to avoid parsing large
6894 // inlining candidates. 6851 // inlining candidates.
6895 if (target_shared->SourceSize() > 6852 if (target_shared->SourceSize() >
(...skipping 10 matching lines...) Expand all
6906 if (target_shared->dont_inline() || target_shared->dont_optimize()) { 6863 if (target_shared->dont_inline() || target_shared->dont_optimize()) {
6907 TraceInline(target, caller, "target contains unsupported syntax [early]"); 6864 TraceInline(target, caller, "target contains unsupported syntax [early]");
6908 return kNotInlinable; 6865 return kNotInlinable;
6909 } 6866 }
6910 6867
6911 int nodes_added = target_shared->ast_node_count(); 6868 int nodes_added = target_shared->ast_node_count();
6912 return nodes_added; 6869 return nodes_added;
6913 } 6870 }
6914 6871
6915 6872
6916 bool HOptimizedGraphBuilder::TryInline(CallKind call_kind, 6873 bool HGraphBuilder::TryInline(CallKind call_kind,
6917 Handle<JSFunction> target, 6874 Handle<JSFunction> target,
6918 int arguments_count, 6875 int arguments_count,
6919 HValue* implicit_return_value, 6876 HValue* implicit_return_value,
6920 BailoutId ast_id, 6877 BailoutId ast_id,
6921 BailoutId return_id, 6878 BailoutId return_id,
6922 InliningKind inlining_kind) { 6879 InliningKind inlining_kind) {
6923 int nodes_added = InliningAstSize(target); 6880 int nodes_added = InliningAstSize(target);
6924 if (nodes_added == kNotInlinable) return false; 6881 if (nodes_added == kNotInlinable) return false;
6925 6882
6926 Handle<JSFunction> caller = info()->closure(); 6883 Handle<JSFunction> caller = info()->closure();
6927 6884
6928 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { 6885 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) {
6929 TraceInline(target, caller, "target AST is too large [early]"); 6886 TraceInline(target, caller, "target AST is too large [early]");
6930 return false; 6887 return false;
6931 } 6888 }
6932 6889
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
7221 function_return()->SetJoinId(ast_id); 7178 function_return()->SetJoinId(ast_id);
7222 set_current_block(function_return()); 7179 set_current_block(function_return());
7223 } else { 7180 } else {
7224 set_current_block(NULL); 7181 set_current_block(NULL);
7225 } 7182 }
7226 delete target_state; 7183 delete target_state;
7227 return true; 7184 return true;
7228 } 7185 }
7229 7186
7230 7187
7231 bool HOptimizedGraphBuilder::TryInlineCall(Call* expr, bool drop_extra) { 7188 bool HGraphBuilder::TryInlineCall(Call* expr, bool drop_extra) {
7232 // The function call we are inlining is a method call if the call 7189 // The function call we are inlining is a method call if the call
7233 // is a property call. 7190 // is a property call.
7234 CallKind call_kind = (expr->expression()->AsProperty() == NULL) 7191 CallKind call_kind = (expr->expression()->AsProperty() == NULL)
7235 ? CALL_AS_FUNCTION 7192 ? CALL_AS_FUNCTION
7236 : CALL_AS_METHOD; 7193 : CALL_AS_METHOD;
7237 7194
7238 return TryInline(call_kind, 7195 return TryInline(call_kind,
7239 expr->target(), 7196 expr->target(),
7240 expr->arguments()->length(), 7197 expr->arguments()->length(),
7241 NULL, 7198 NULL,
7242 expr->id(), 7199 expr->id(),
7243 expr->ReturnId(), 7200 expr->ReturnId(),
7244 drop_extra ? DROP_EXTRA_ON_RETURN : NORMAL_RETURN); 7201 drop_extra ? DROP_EXTRA_ON_RETURN : NORMAL_RETURN);
7245 } 7202 }
7246 7203
7247 7204
7248 bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr, 7205 bool HGraphBuilder::TryInlineConstruct(CallNew* expr,
7249 HValue* implicit_return_value) { 7206 HValue* implicit_return_value) {
7250 return TryInline(CALL_AS_FUNCTION, 7207 return TryInline(CALL_AS_FUNCTION,
7251 expr->target(), 7208 expr->target(),
7252 expr->arguments()->length(), 7209 expr->arguments()->length(),
7253 implicit_return_value, 7210 implicit_return_value,
7254 expr->id(), 7211 expr->id(),
7255 expr->ReturnId(), 7212 expr->ReturnId(),
7256 CONSTRUCT_CALL_RETURN); 7213 CONSTRUCT_CALL_RETURN);
7257 } 7214 }
7258 7215
7259 7216
7260 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter, 7217 bool HGraphBuilder::TryInlineGetter(Handle<JSFunction> getter,
7261 Property* prop) { 7218 Property* prop) {
7262 return TryInline(CALL_AS_METHOD, 7219 return TryInline(CALL_AS_METHOD,
7263 getter, 7220 getter,
7264 0, 7221 0,
7265 NULL, 7222 NULL,
7266 prop->id(), 7223 prop->id(),
7267 prop->LoadId(), 7224 prop->LoadId(),
7268 GETTER_CALL_RETURN); 7225 GETTER_CALL_RETURN);
7269 } 7226 }
7270 7227
7271 7228
7272 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter, 7229 bool HGraphBuilder::TryInlineSetter(Handle<JSFunction> setter,
7273 Assignment* assignment, 7230 Assignment* assignment,
7274 HValue* implicit_return_value) { 7231 HValue* implicit_return_value) {
7275 return TryInline(CALL_AS_METHOD, 7232 return TryInline(CALL_AS_METHOD,
7276 setter, 7233 setter,
7277 1, 7234 1,
7278 implicit_return_value, 7235 implicit_return_value,
7279 assignment->id(), 7236 assignment->id(),
7280 assignment->AssignmentId(), 7237 assignment->AssignmentId(),
7281 SETTER_CALL_RETURN); 7238 SETTER_CALL_RETURN);
7282 } 7239 }
7283 7240
7284 7241
7285 bool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr, 7242 bool HGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr, bool drop_extra) {
7286 bool drop_extra) {
7287 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; 7243 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false;
7288 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); 7244 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id();
7289 switch (id) { 7245 switch (id) {
7290 case kMathExp: 7246 case kMathExp:
7291 if (!FLAG_fast_math) break; 7247 if (!FLAG_fast_math) break;
7292 // Fall through if FLAG_fast_math. 7248 // Fall through if FLAG_fast_math.
7293 case kMathRound: 7249 case kMathRound:
7294 case kMathAbs: 7250 case kMathAbs:
7295 case kMathSqrt: 7251 case kMathSqrt:
7296 case kMathLog: 7252 case kMathLog:
(...skipping 13 matching lines...) Expand all
7310 } 7266 }
7311 break; 7267 break;
7312 default: 7268 default:
7313 // Not supported for inlining yet. 7269 // Not supported for inlining yet.
7314 break; 7270 break;
7315 } 7271 }
7316 return false; 7272 return false;
7317 } 7273 }
7318 7274
7319 7275
7320 bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( 7276 bool HGraphBuilder::TryInlineBuiltinMethodCall(Call* expr,
7321 Call* expr, 7277 HValue* receiver,
7322 HValue* receiver, 7278 Handle<Map> receiver_map,
7323 Handle<Map> receiver_map, 7279 CheckType check_type) {
7324 CheckType check_type) {
7325 ASSERT(check_type != RECEIVER_MAP_CHECK || !receiver_map.is_null()); 7280 ASSERT(check_type != RECEIVER_MAP_CHECK || !receiver_map.is_null());
7326 // Try to inline calls like Math.* as operations in the calling function. 7281 // Try to inline calls like Math.* as operations in the calling function.
7327 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; 7282 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false;
7328 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); 7283 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id();
7329 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 7284 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
7330 switch (id) { 7285 switch (id) {
7331 case kStringCharCodeAt: 7286 case kStringCharCodeAt:
7332 case kStringCharAt: 7287 case kStringCharAt:
7333 if (argument_count == 2 && check_type == STRING_CHECK) { 7288 if (argument_count == 2 && check_type == STRING_CHECK) {
7334 HValue* index = Pop(); 7289 HValue* index = Pop();
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
7444 } 7399 }
7445 break; 7400 break;
7446 default: 7401 default:
7447 // Not yet supported for inlining. 7402 // Not yet supported for inlining.
7448 break; 7403 break;
7449 } 7404 }
7450 return false; 7405 return false;
7451 } 7406 }
7452 7407
7453 7408
7454 bool HOptimizedGraphBuilder::TryCallApply(Call* expr) { 7409 bool HGraphBuilder::TryCallApply(Call* expr) {
7455 Expression* callee = expr->expression(); 7410 Expression* callee = expr->expression();
7456 Property* prop = callee->AsProperty(); 7411 Property* prop = callee->AsProperty();
7457 ASSERT(prop != NULL); 7412 ASSERT(prop != NULL);
7458 7413
7459 if (!expr->IsMonomorphic() || expr->check_type() != RECEIVER_MAP_CHECK) { 7414 if (!expr->IsMonomorphic() || expr->check_type() != RECEIVER_MAP_CHECK) {
7460 return false; 7415 return false;
7461 } 7416 }
7462 Handle<Map> function_map = expr->GetReceiverTypes()->first(); 7417 Handle<Map> function_map = expr->GetReceiverTypes()->first();
7463 if (function_map->instance_type() != JS_FUNCTION_TYPE || 7418 if (function_map->instance_type() != JS_FUNCTION_TYPE ||
7464 !expr->target()->shared()->HasBuiltinFunctionId() || 7419 !expr->target()->shared()->HasBuiltinFunctionId() ||
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
7572 return NULL; 7527 return NULL;
7573 } 7528 }
7574 current = next; 7529 current = next;
7575 } 7530 }
7576 } 7531 }
7577 7532
7578 return kinds[first_index]; 7533 return kinds[first_index];
7579 } 7534 }
7580 7535
7581 7536
7582 void HOptimizedGraphBuilder::VisitCall(Call* expr) { 7537 void HGraphBuilder::VisitCall(Call* expr) {
7583 ASSERT(!HasStackOverflow()); 7538 ASSERT(!HasStackOverflow());
7584 ASSERT(current_block() != NULL); 7539 ASSERT(current_block() != NULL);
7585 ASSERT(current_block()->HasPredecessor()); 7540 ASSERT(current_block()->HasPredecessor());
7586 Expression* callee = expr->expression(); 7541 Expression* callee = expr->expression();
7587 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 7542 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
7588 HInstruction* call = NULL; 7543 HInstruction* call = NULL;
7589 7544
7590 Property* prop = callee->AsProperty(); 7545 Property* prop = callee->AsProperty();
7591 if (prop != NULL) { 7546 if (prop != NULL) {
7592 if (!prop->key()->IsPropertyName()) { 7547 if (!prop->key()->IsPropertyName()) {
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
7802 7757
7803 7758
7804 // Checks whether allocation using the given constructor can be inlined. 7759 // Checks whether allocation using the given constructor can be inlined.
7805 static bool IsAllocationInlineable(Handle<JSFunction> constructor) { 7760 static bool IsAllocationInlineable(Handle<JSFunction> constructor) {
7806 return constructor->has_initial_map() && 7761 return constructor->has_initial_map() &&
7807 constructor->initial_map()->instance_type() == JS_OBJECT_TYPE && 7762 constructor->initial_map()->instance_type() == JS_OBJECT_TYPE &&
7808 constructor->initial_map()->instance_size() < HAllocateObject::kMaxSize; 7763 constructor->initial_map()->instance_size() < HAllocateObject::kMaxSize;
7809 } 7764 }
7810 7765
7811 7766
7812 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { 7767 void HGraphBuilder::VisitCallNew(CallNew* expr) {
7813 ASSERT(!HasStackOverflow()); 7768 ASSERT(!HasStackOverflow());
7814 ASSERT(current_block() != NULL); 7769 ASSERT(current_block() != NULL);
7815 ASSERT(current_block()->HasPredecessor()); 7770 ASSERT(current_block()->HasPredecessor());
7816 expr->RecordTypeFeedback(oracle()); 7771 expr->RecordTypeFeedback(oracle());
7817 int argument_count = expr->arguments()->length() + 1; // Plus constructor. 7772 int argument_count = expr->arguments()->length() + 1; // Plus constructor.
7818 HValue* context = environment()->LookupContext(); 7773 HValue* context = environment()->LookupContext();
7819 7774
7820 if (FLAG_inline_construct && 7775 if (FLAG_inline_construct &&
7821 expr->IsMonomorphic() && 7776 expr->IsMonomorphic() &&
7822 IsAllocationInlineable(expr->target())) { 7777 IsAllocationInlineable(expr->target())) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
7866 new(zone()) HCallNew(context, constructor, argument_count); 7821 new(zone()) HCallNew(context, constructor, argument_count);
7867 Drop(argument_count); 7822 Drop(argument_count);
7868 call->set_position(expr->position()); 7823 call->set_position(expr->position());
7869 return ast_context()->ReturnInstruction(call, expr->id()); 7824 return ast_context()->ReturnInstruction(call, expr->id());
7870 } 7825 }
7871 } 7826 }
7872 7827
7873 7828
7874 // Support for generating inlined runtime functions. 7829 // Support for generating inlined runtime functions.
7875 7830
7876 // Lookup table for generators for runtime calls that are generated inline. 7831 // Lookup table for generators for runtime calls that are generated inline.
7877 // Elements of the table are member pointers to functions of 7832 // Elements of the table are member pointers to functions of HGraphBuilder.
7878 // HOptimizedGraphBuilder.
7879 #define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \ 7833 #define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \
7880 &HOptimizedGraphBuilder::Generate##Name, 7834 &HGraphBuilder::Generate##Name,
7881 7835
7882 const HOptimizedGraphBuilder::InlineFunctionGenerator 7836 const HGraphBuilder::InlineFunctionGenerator
7883 HOptimizedGraphBuilder::kInlineFunctionGenerators[] = { 7837 HGraphBuilder::kInlineFunctionGenerators[] = {
7884 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) 7838 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
7885 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) 7839 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
7886 }; 7840 };
7887 #undef INLINE_FUNCTION_GENERATOR_ADDRESS 7841 #undef INLINE_FUNCTION_GENERATOR_ADDRESS
7888 7842
7889 7843
7890 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { 7844 void HGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
7891 ASSERT(!HasStackOverflow()); 7845 ASSERT(!HasStackOverflow());
7892 ASSERT(current_block() != NULL); 7846 ASSERT(current_block() != NULL);
7893 ASSERT(current_block()->HasPredecessor()); 7847 ASSERT(current_block()->HasPredecessor());
7894 if (expr->is_jsruntime()) { 7848 if (expr->is_jsruntime()) {
7895 return Bailout("call to a JavaScript runtime function"); 7849 return Bailout("call to a JavaScript runtime function");
7896 } 7850 }
7897 7851
7898 const Runtime::Function* function = expr->function(); 7852 const Runtime::Function* function = expr->function();
7899 ASSERT(function != NULL); 7853 ASSERT(function != NULL);
7900 if (function->intrinsic_type == Runtime::INLINE) { 7854 if (function->intrinsic_type == Runtime::INLINE) {
(...skipping 17 matching lines...) Expand all
7918 Handle<String> name = expr->name(); 7872 Handle<String> name = expr->name();
7919 int argument_count = expr->arguments()->length(); 7873 int argument_count = expr->arguments()->length();
7920 HCallRuntime* call = 7874 HCallRuntime* call =
7921 new(zone()) HCallRuntime(context, name, function, argument_count); 7875 new(zone()) HCallRuntime(context, name, function, argument_count);
7922 Drop(argument_count); 7876 Drop(argument_count);
7923 return ast_context()->ReturnInstruction(call, expr->id()); 7877 return ast_context()->ReturnInstruction(call, expr->id());
7924 } 7878 }
7925 } 7879 }
7926 7880
7927 7881
7928 void HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { 7882 void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
7929 ASSERT(!HasStackOverflow()); 7883 ASSERT(!HasStackOverflow());
7930 ASSERT(current_block() != NULL); 7884 ASSERT(current_block() != NULL);
7931 ASSERT(current_block()->HasPredecessor()); 7885 ASSERT(current_block()->HasPredecessor());
7932 switch (expr->op()) { 7886 switch (expr->op()) {
7933 case Token::DELETE: return VisitDelete(expr); 7887 case Token::DELETE: return VisitDelete(expr);
7934 case Token::VOID: return VisitVoid(expr); 7888 case Token::VOID: return VisitVoid(expr);
7935 case Token::TYPEOF: return VisitTypeof(expr); 7889 case Token::TYPEOF: return VisitTypeof(expr);
7936 case Token::ADD: return VisitAdd(expr); 7890 case Token::ADD: return VisitAdd(expr);
7937 case Token::SUB: return VisitSub(expr); 7891 case Token::SUB: return VisitSub(expr);
7938 case Token::BIT_NOT: return VisitBitNot(expr); 7892 case Token::BIT_NOT: return VisitBitNot(expr);
7939 case Token::NOT: return VisitNot(expr); 7893 case Token::NOT: return VisitNot(expr);
7940 default: UNREACHABLE(); 7894 default: UNREACHABLE();
7941 } 7895 }
7942 } 7896 }
7943 7897
7944 void HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) { 7898 void HGraphBuilder::VisitDelete(UnaryOperation* expr) {
7945 Property* prop = expr->expression()->AsProperty(); 7899 Property* prop = expr->expression()->AsProperty();
7946 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 7900 VariableProxy* proxy = expr->expression()->AsVariableProxy();
7947 if (prop != NULL) { 7901 if (prop != NULL) {
7948 CHECK_ALIVE(VisitForValue(prop->obj())); 7902 CHECK_ALIVE(VisitForValue(prop->obj()));
7949 CHECK_ALIVE(VisitForValue(prop->key())); 7903 CHECK_ALIVE(VisitForValue(prop->key()));
7950 HValue* key = Pop(); 7904 HValue* key = Pop();
7951 HValue* obj = Pop(); 7905 HValue* obj = Pop();
7952 HValue* context = environment()->LookupContext(); 7906 HValue* context = environment()->LookupContext();
7953 HDeleteProperty* instr = new(zone()) HDeleteProperty(context, obj, key); 7907 HDeleteProperty* instr = new(zone()) HDeleteProperty(context, obj, key);
7954 return ast_context()->ReturnInstruction(instr, expr->id()); 7908 return ast_context()->ReturnInstruction(instr, expr->id());
(...skipping 14 matching lines...) Expand all
7969 } 7923 }
7970 } else { 7924 } else {
7971 // Result of deleting non-property, non-variable reference is true. 7925 // Result of deleting non-property, non-variable reference is true.
7972 // Evaluate the subexpression for side effects. 7926 // Evaluate the subexpression for side effects.
7973 CHECK_ALIVE(VisitForEffect(expr->expression())); 7927 CHECK_ALIVE(VisitForEffect(expr->expression()));
7974 return ast_context()->ReturnValue(graph()->GetConstantTrue()); 7928 return ast_context()->ReturnValue(graph()->GetConstantTrue());
7975 } 7929 }
7976 } 7930 }
7977 7931
7978 7932
7979 void HOptimizedGraphBuilder::VisitVoid(UnaryOperation* expr) { 7933 void HGraphBuilder::VisitVoid(UnaryOperation* expr) {
7980 CHECK_ALIVE(VisitForEffect(expr->expression())); 7934 CHECK_ALIVE(VisitForEffect(expr->expression()));
7981 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 7935 return ast_context()->ReturnValue(graph()->GetConstantUndefined());
7982 } 7936 }
7983 7937
7984 7938
7985 void HOptimizedGraphBuilder::VisitTypeof(UnaryOperation* expr) { 7939 void HGraphBuilder::VisitTypeof(UnaryOperation* expr) {
7986 CHECK_ALIVE(VisitForTypeOf(expr->expression())); 7940 CHECK_ALIVE(VisitForTypeOf(expr->expression()));
7987 HValue* value = Pop(); 7941 HValue* value = Pop();
7988 HValue* context = environment()->LookupContext(); 7942 HValue* context = environment()->LookupContext();
7989 HInstruction* instr = new(zone()) HTypeof(context, value); 7943 HInstruction* instr = new(zone()) HTypeof(context, value);
7990 return ast_context()->ReturnInstruction(instr, expr->id()); 7944 return ast_context()->ReturnInstruction(instr, expr->id());
7991 } 7945 }
7992 7946
7993 7947
7994 void HOptimizedGraphBuilder::VisitAdd(UnaryOperation* expr) { 7948 void HGraphBuilder::VisitAdd(UnaryOperation* expr) {
7995 CHECK_ALIVE(VisitForValue(expr->expression())); 7949 CHECK_ALIVE(VisitForValue(expr->expression()));
7996 HValue* value = Pop(); 7950 HValue* value = Pop();
7997 HValue* context = environment()->LookupContext(); 7951 HValue* context = environment()->LookupContext();
7998 HInstruction* instr = 7952 HInstruction* instr =
7999 new(zone()) HMul(context, value, graph()->GetConstant1()); 7953 new(zone()) HMul(context, value, graph_->GetConstant1());
8000 return ast_context()->ReturnInstruction(instr, expr->id()); 7954 return ast_context()->ReturnInstruction(instr, expr->id());
8001 } 7955 }
8002 7956
8003 7957
8004 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { 7958 void HGraphBuilder::VisitSub(UnaryOperation* expr) {
8005 CHECK_ALIVE(VisitForValue(expr->expression())); 7959 CHECK_ALIVE(VisitForValue(expr->expression()));
8006 HValue* value = Pop(); 7960 HValue* value = Pop();
8007 HValue* context = environment()->LookupContext(); 7961 HValue* context = environment()->LookupContext();
8008 HInstruction* instr = 7962 HInstruction* instr =
8009 new(zone()) HMul(context, value, graph()->GetConstantMinus1()); 7963 new(zone()) HMul(context, value, graph_->GetConstantMinus1());
8010 TypeInfo info = oracle()->UnaryType(expr); 7964 TypeInfo info = oracle()->UnaryType(expr);
8011 Representation rep = ToRepresentation(info); 7965 Representation rep = ToRepresentation(info);
8012 if (info.IsUninitialized()) { 7966 if (info.IsUninitialized()) {
8013 AddInstruction(new(zone()) HSoftDeoptimize); 7967 AddInstruction(new(zone()) HSoftDeoptimize);
8014 current_block()->MarkAsDeoptimizing(); 7968 current_block()->MarkAsDeoptimizing();
8015 info = TypeInfo::Unknown(); 7969 info = TypeInfo::Unknown();
8016 } 7970 }
8017 HBinaryOperation::cast(instr)->set_observed_input_representation(rep, rep); 7971 HBinaryOperation::cast(instr)->set_observed_input_representation(rep, rep);
8018 return ast_context()->ReturnInstruction(instr, expr->id()); 7972 return ast_context()->ReturnInstruction(instr, expr->id());
8019 } 7973 }
8020 7974
8021 7975
8022 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) { 7976 void HGraphBuilder::VisitBitNot(UnaryOperation* expr) {
8023 CHECK_ALIVE(VisitForValue(expr->expression())); 7977 CHECK_ALIVE(VisitForValue(expr->expression()));
8024 HValue* value = Pop(); 7978 HValue* value = Pop();
8025 TypeInfo info = oracle()->UnaryType(expr); 7979 TypeInfo info = oracle()->UnaryType(expr);
8026 if (info.IsUninitialized()) { 7980 if (info.IsUninitialized()) {
8027 AddInstruction(new(zone()) HSoftDeoptimize); 7981 AddInstruction(new(zone()) HSoftDeoptimize);
8028 current_block()->MarkAsDeoptimizing(); 7982 current_block()->MarkAsDeoptimizing();
8029 } 7983 }
8030 HInstruction* instr = new(zone()) HBitNot(value); 7984 HInstruction* instr = new(zone()) HBitNot(value);
8031 return ast_context()->ReturnInstruction(instr, expr->id()); 7985 return ast_context()->ReturnInstruction(instr, expr->id());
8032 } 7986 }
8033 7987
8034 7988
8035 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { 7989 void HGraphBuilder::VisitNot(UnaryOperation* expr) {
8036 if (ast_context()->IsTest()) { 7990 if (ast_context()->IsTest()) {
8037 TestContext* context = TestContext::cast(ast_context()); 7991 TestContext* context = TestContext::cast(ast_context());
8038 VisitForControl(expr->expression(), 7992 VisitForControl(expr->expression(),
8039 context->if_false(), 7993 context->if_false(),
8040 context->if_true()); 7994 context->if_true());
8041 return; 7995 return;
8042 } 7996 }
8043 7997
8044 if (ast_context()->IsEffect()) { 7998 if (ast_context()->IsEffect()) {
8045 VisitForEffect(expr->expression()); 7999 VisitForEffect(expr->expression());
(...skipping 23 matching lines...) Expand all
8069 materialize_true = NULL; 8023 materialize_true = NULL;
8070 } 8024 }
8071 8025
8072 HBasicBlock* join = 8026 HBasicBlock* join =
8073 CreateJoin(materialize_false, materialize_true, expr->id()); 8027 CreateJoin(materialize_false, materialize_true, expr->id());
8074 set_current_block(join); 8028 set_current_block(join);
8075 if (join != NULL) return ast_context()->ReturnValue(Pop()); 8029 if (join != NULL) return ast_context()->ReturnValue(Pop());
8076 } 8030 }
8077 8031
8078 8032
8079 HInstruction* HOptimizedGraphBuilder::BuildIncrement( 8033 HInstruction* HGraphBuilder::BuildIncrement(bool returns_original_input,
8080 bool returns_original_input, 8034 CountOperation* expr) {
8081 CountOperation* expr) {
8082 // The input to the count operation is on top of the expression stack. 8035 // The input to the count operation is on top of the expression stack.
8083 TypeInfo info = oracle()->IncrementType(expr); 8036 TypeInfo info = oracle()->IncrementType(expr);
8084 Representation rep = ToRepresentation(info); 8037 Representation rep = ToRepresentation(info);
8085 if (rep.IsTagged()) { 8038 if (rep.IsTagged()) {
8086 rep = Representation::Integer32(); 8039 rep = Representation::Integer32();
8087 } 8040 }
8088 8041
8089 if (returns_original_input) { 8042 if (returns_original_input) {
8090 // We need an explicit HValue representing ToNumber(input). The 8043 // We need an explicit HValue representing ToNumber(input). The
8091 // actual HChange instruction we need is (sometimes) added in a later 8044 // actual HChange instruction we need is (sometimes) added in a later
8092 // phase, so it is not available now to be used as an input to HAdd and 8045 // phase, so it is not available now to be used as an input to HAdd and
8093 // as the return value. 8046 // as the return value.
8094 HInstruction* number_input = new(zone()) HForceRepresentation(Pop(), rep); 8047 HInstruction* number_input = new(zone()) HForceRepresentation(Pop(), rep);
8095 AddInstruction(number_input); 8048 AddInstruction(number_input);
8096 Push(number_input); 8049 Push(number_input);
8097 } 8050 }
8098 8051
8099 // The addition has no side effects, so we do not need 8052 // The addition has no side effects, so we do not need
8100 // to simulate the expression stack after this instruction. 8053 // to simulate the expression stack after this instruction.
8101 // Any later failures deopt to the load of the input or earlier. 8054 // Any later failures deopt to the load of the input or earlier.
8102 HConstant* delta = (expr->op() == Token::INC) 8055 HConstant* delta = (expr->op() == Token::INC)
8103 ? graph()->GetConstant1() 8056 ? graph_->GetConstant1()
8104 : graph()->GetConstantMinus1(); 8057 : graph_->GetConstantMinus1();
8105 HValue* context = environment()->LookupContext(); 8058 HValue* context = environment()->LookupContext();
8106 HInstruction* instr = new(zone()) HAdd(context, Top(), delta); 8059 HInstruction* instr = new(zone()) HAdd(context, Top(), delta);
8107 // We can't insert a simulate here, because it would break deoptimization, 8060 // We can't insert a simulate here, because it would break deoptimization,
8108 // so the HAdd must not have side effects, so we must freeze its 8061 // so the HAdd must not have side effects, so we must freeze its
8109 // representation. 8062 // representation.
8110 instr->AssumeRepresentation(rep); 8063 instr->AssumeRepresentation(rep);
8111 instr->ClearAllSideEffects(); 8064 instr->ClearAllSideEffects();
8112 AddInstruction(instr); 8065 AddInstruction(instr);
8113 return instr; 8066 return instr;
8114 } 8067 }
8115 8068
8116 8069
8117 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { 8070 void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
8118 ASSERT(!HasStackOverflow()); 8071 ASSERT(!HasStackOverflow());
8119 ASSERT(current_block() != NULL); 8072 ASSERT(current_block() != NULL);
8120 ASSERT(current_block()->HasPredecessor()); 8073 ASSERT(current_block()->HasPredecessor());
8121 Expression* target = expr->expression(); 8074 Expression* target = expr->expression();
8122 VariableProxy* proxy = target->AsVariableProxy(); 8075 VariableProxy* proxy = target->AsVariableProxy();
8123 Property* prop = target->AsProperty(); 8076 Property* prop = target->AsProperty();
8124 if (proxy == NULL && prop == NULL) { 8077 if (proxy == NULL && prop == NULL) {
8125 return Bailout("invalid lhs in count operation"); 8078 return Bailout("invalid lhs in count operation");
8126 } 8079 }
8127 8080
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
8191 return Bailout("lookup variable in count operation"); 8144 return Bailout("lookup variable in count operation");
8192 } 8145 }
8193 8146
8194 } else { 8147 } else {
8195 // Argument of the count operation is a property. 8148 // Argument of the count operation is a property.
8196 ASSERT(prop != NULL); 8149 ASSERT(prop != NULL);
8197 prop->RecordTypeFeedback(oracle(), zone()); 8150 prop->RecordTypeFeedback(oracle(), zone());
8198 8151
8199 if (prop->key()->IsPropertyName()) { 8152 if (prop->key()->IsPropertyName()) {
8200 // Named property. 8153 // Named property.
8201 if (returns_original_input) Push(graph()->GetConstantUndefined()); 8154 if (returns_original_input) Push(graph_->GetConstantUndefined());
8202 8155
8203 CHECK_ALIVE(VisitForValue(prop->obj())); 8156 CHECK_ALIVE(VisitForValue(prop->obj()));
8204 HValue* object = Top(); 8157 HValue* object = Top();
8205 8158
8206 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 8159 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
8207 Handle<Map> map; 8160 Handle<Map> map;
8208 HInstruction* load; 8161 HInstruction* load;
8209 bool monomorphic = prop->IsMonomorphic(); 8162 bool monomorphic = prop->IsMonomorphic();
8210 if (monomorphic) { 8163 if (monomorphic) {
8211 map = prop->GetReceiverTypes()->first(); 8164 map = prop->GetReceiverTypes()->first();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
8252 // of the operation, and the placeholder with the original value if 8205 // of the operation, and the placeholder with the original value if
8253 // necessary. 8206 // necessary.
8254 environment()->SetExpressionStackAt(0, after); 8207 environment()->SetExpressionStackAt(0, after);
8255 if (returns_original_input) environment()->SetExpressionStackAt(1, input); 8208 if (returns_original_input) environment()->SetExpressionStackAt(1, input);
8256 if (store->HasObservableSideEffects()) { 8209 if (store->HasObservableSideEffects()) {
8257 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); 8210 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
8258 } 8211 }
8259 8212
8260 } else { 8213 } else {
8261 // Keyed property. 8214 // Keyed property.
8262 if (returns_original_input) Push(graph()->GetConstantUndefined()); 8215 if (returns_original_input) Push(graph_->GetConstantUndefined());
8263 8216
8264 CHECK_ALIVE(VisitForValue(prop->obj())); 8217 CHECK_ALIVE(VisitForValue(prop->obj()));
8265 CHECK_ALIVE(VisitForValue(prop->key())); 8218 CHECK_ALIVE(VisitForValue(prop->key()));
8266 HValue* obj = environment()->ExpressionStackAt(1); 8219 HValue* obj = environment()->ExpressionStackAt(1);
8267 HValue* key = environment()->ExpressionStackAt(0); 8220 HValue* key = environment()->ExpressionStackAt(0);
8268 8221
8269 bool has_side_effects = false; 8222 bool has_side_effects = false;
8270 HValue* load = HandleKeyedElementAccess( 8223 HValue* load = HandleKeyedElementAccess(
8271 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, 8224 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition,
8272 false, // is_store 8225 false, // is_store
(...skipping 19 matching lines...) Expand all
8292 ASSERT(has_side_effects); // Stores always have side effects. 8245 ASSERT(has_side_effects); // Stores always have side effects.
8293 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); 8246 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
8294 } 8247 }
8295 } 8248 }
8296 8249
8297 Drop(returns_original_input ? 2 : 1); 8250 Drop(returns_original_input ? 2 : 1);
8298 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); 8251 return ast_context()->ReturnValue(expr->is_postfix() ? input : after);
8299 } 8252 }
8300 8253
8301 8254
8302 HStringCharCodeAt* HOptimizedGraphBuilder::BuildStringCharCodeAt( 8255 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* context,
8303 HValue* context, 8256 HValue* string,
8304 HValue* string, 8257 HValue* index) {
8305 HValue* index) {
8306 AddInstruction(new(zone()) HCheckNonSmi(string)); 8258 AddInstruction(new(zone()) HCheckNonSmi(string));
8307 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); 8259 AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
8308 HStringLength* length = new(zone()) HStringLength(string); 8260 HStringLength* length = new(zone()) HStringLength(string);
8309 AddInstruction(length); 8261 AddInstruction(length);
8310 HInstruction* checked_index = 8262 HInstruction* checked_index =
8311 AddInstruction(new(zone()) HBoundsCheck(index, length)); 8263 AddInstruction(new(zone()) HBoundsCheck(index, length));
8312 return new(zone()) HStringCharCodeAt(context, string, checked_index); 8264 return new(zone()) HStringCharCodeAt(context, string, checked_index);
8313 } 8265 }
8314 8266
8315 // Checks if the given shift amounts have form: (sa) and (32 - sa). 8267 // Checks if the given shift amounts have form: (sa) and (32 - sa).
8316 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, 8268 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa,
8317 HValue* const32_minus_sa) { 8269 HValue* const32_minus_sa) {
8318 if (!const32_minus_sa->IsSub()) return false; 8270 if (!const32_minus_sa->IsSub()) return false;
8319 HSub* sub = HSub::cast(const32_minus_sa); 8271 HSub* sub = HSub::cast(const32_minus_sa);
8320 HValue* const32 = sub->left(); 8272 HValue* const32 = sub->left();
8321 if (!const32->IsConstant() || 8273 if (!const32->IsConstant() ||
8322 HConstant::cast(const32)->Integer32Value() != 32) { 8274 HConstant::cast(const32)->Integer32Value() != 32) {
8323 return false; 8275 return false;
8324 } 8276 }
8325 return (sub->right() == sa); 8277 return (sub->right() == sa);
8326 } 8278 }
8327 8279
8328 8280
8329 // Checks if the left and the right are shift instructions with the oposite 8281 // Checks if the left and the right are shift instructions with the oposite
8330 // directions that can be replaced by one rotate right instruction or not. 8282 // directions that can be replaced by one rotate right instruction or not.
8331 // Returns the operand and the shift amount for the rotate instruction in the 8283 // Returns the operand and the shift amount for the rotate instruction in the
8332 // former case. 8284 // former case.
8333 bool HOptimizedGraphBuilder::MatchRotateRight(HValue* left, 8285 bool HGraphBuilder::MatchRotateRight(HValue* left,
8334 HValue* right, 8286 HValue* right,
8335 HValue** operand, 8287 HValue** operand,
8336 HValue** shift_amount) { 8288 HValue** shift_amount) {
8337 HShl* shl; 8289 HShl* shl;
8338 HShr* shr; 8290 HShr* shr;
8339 if (left->IsShl() && right->IsShr()) { 8291 if (left->IsShl() && right->IsShr()) {
8340 shl = HShl::cast(left); 8292 shl = HShl::cast(left);
8341 shr = HShr::cast(right); 8293 shr = HShr::cast(right);
8342 } else if (left->IsShr() && right->IsShl()) { 8294 } else if (left->IsShr() && right->IsShl()) {
8343 shl = HShl::cast(right); 8295 shl = HShl::cast(right);
8344 shr = HShr::cast(left); 8296 shr = HShr::cast(left);
8345 } else { 8297 } else {
8346 return false; 8298 return false;
(...skipping 14 matching lines...) Expand all
8361 HConstant* right_const = HConstant::cast(right); 8313 HConstant* right_const = HConstant::cast(right);
8362 if (right_const->HasInteger32Value() && 8314 if (right_const->HasInteger32Value() &&
8363 (right_const->Integer32Value() & 0x1f) != 0) { 8315 (right_const->Integer32Value() & 0x1f) != 0) {
8364 return false; 8316 return false;
8365 } 8317 }
8366 } 8318 }
8367 return true; 8319 return true;
8368 } 8320 }
8369 8321
8370 8322
8371 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( 8323 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr,
8372 BinaryOperation* expr, 8324 HValue* left,
8373 HValue* left, 8325 HValue* right) {
8374 HValue* right) {
8375 HValue* context = environment()->LookupContext(); 8326 HValue* context = environment()->LookupContext();
8376 TypeInfo left_info, right_info, result_info, combined_info; 8327 TypeInfo left_info, right_info, result_info, combined_info;
8377 oracle()->BinaryType(expr, &left_info, &right_info, &result_info); 8328 oracle()->BinaryType(expr, &left_info, &right_info, &result_info);
8378 Representation left_rep = ToRepresentation(left_info); 8329 Representation left_rep = ToRepresentation(left_info);
8379 Representation right_rep = ToRepresentation(right_info); 8330 Representation right_rep = ToRepresentation(right_info);
8380 Representation result_rep = ToRepresentation(result_info); 8331 Representation result_rep = ToRepresentation(result_info);
8381 if (left_info.IsUninitialized()) { 8332 if (left_info.IsUninitialized()) {
8382 // Can't have initialized one but not the other. 8333 // Can't have initialized one but not the other.
8383 ASSERT(right_info.IsUninitialized()); 8334 ASSERT(right_info.IsUninitialized());
8384 AddInstruction(new(zone()) HSoftDeoptimize); 8335 AddInstruction(new(zone()) HSoftDeoptimize);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
8457 if (call == NULL) return false; 8408 if (call == NULL) return false;
8458 Literal* literal = expr->right()->AsLiteral(); 8409 Literal* literal = expr->right()->AsLiteral();
8459 if (literal == NULL) return false; 8410 if (literal == NULL) return false;
8460 if (!literal->handle()->IsString()) return false; 8411 if (!literal->handle()->IsString()) return false;
8461 if (!call->name()->IsEqualTo(CStrVector("_ClassOf"))) return false; 8412 if (!call->name()->IsEqualTo(CStrVector("_ClassOf"))) return false;
8462 ASSERT(call->arguments()->length() == 1); 8413 ASSERT(call->arguments()->length() == 1);
8463 return true; 8414 return true;
8464 } 8415 }
8465 8416
8466 8417
8467 void HOptimizedGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { 8418 void HGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) {
8468 ASSERT(!HasStackOverflow()); 8419 ASSERT(!HasStackOverflow());
8469 ASSERT(current_block() != NULL); 8420 ASSERT(current_block() != NULL);
8470 ASSERT(current_block()->HasPredecessor()); 8421 ASSERT(current_block()->HasPredecessor());
8471 switch (expr->op()) { 8422 switch (expr->op()) {
8472 case Token::COMMA: 8423 case Token::COMMA:
8473 return VisitComma(expr); 8424 return VisitComma(expr);
8474 case Token::OR: 8425 case Token::OR:
8475 case Token::AND: 8426 case Token::AND:
8476 return VisitLogicalExpression(expr); 8427 return VisitLogicalExpression(expr);
8477 default: 8428 default:
8478 return VisitArithmeticExpression(expr); 8429 return VisitArithmeticExpression(expr);
8479 } 8430 }
8480 } 8431 }
8481 8432
8482 8433
8483 void HOptimizedGraphBuilder::VisitComma(BinaryOperation* expr) { 8434 void HGraphBuilder::VisitComma(BinaryOperation* expr) {
8484 CHECK_ALIVE(VisitForEffect(expr->left())); 8435 CHECK_ALIVE(VisitForEffect(expr->left()));
8485 // Visit the right subexpression in the same AST context as the entire 8436 // Visit the right subexpression in the same AST context as the entire
8486 // expression. 8437 // expression.
8487 Visit(expr->right()); 8438 Visit(expr->right());
8488 } 8439 }
8489 8440
8490 8441
8491 void HOptimizedGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) { 8442 void HGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) {
8492 bool is_logical_and = expr->op() == Token::AND; 8443 bool is_logical_and = expr->op() == Token::AND;
8493 if (ast_context()->IsTest()) { 8444 if (ast_context()->IsTest()) {
8494 TestContext* context = TestContext::cast(ast_context()); 8445 TestContext* context = TestContext::cast(ast_context());
8495 // Translate left subexpression. 8446 // Translate left subexpression.
8496 HBasicBlock* eval_right = graph()->CreateBasicBlock(); 8447 HBasicBlock* eval_right = graph()->CreateBasicBlock();
8497 if (is_logical_and) { 8448 if (is_logical_and) {
8498 CHECK_BAILOUT(VisitForControl(expr->left(), 8449 CHECK_BAILOUT(VisitForControl(expr->left(),
8499 eval_right, 8450 eval_right,
8500 context->if_false())); 8451 context->if_false()));
8501 } else { 8452 } else {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
8571 8522
8572 HBasicBlock* join_block = 8523 HBasicBlock* join_block =
8573 CreateJoin(empty_block, right_block, expr->id()); 8524 CreateJoin(empty_block, right_block, expr->id());
8574 set_current_block(join_block); 8525 set_current_block(join_block);
8575 // We did not materialize any value in the predecessor environments, 8526 // We did not materialize any value in the predecessor environments,
8576 // so there is no need to handle it here. 8527 // so there is no need to handle it here.
8577 } 8528 }
8578 } 8529 }
8579 8530
8580 8531
8581 void HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { 8532 void HGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) {
8582 CHECK_ALIVE(VisitForValue(expr->left())); 8533 CHECK_ALIVE(VisitForValue(expr->left()));
8583 CHECK_ALIVE(VisitForValue(expr->right())); 8534 CHECK_ALIVE(VisitForValue(expr->right()));
8584 HValue* right = Pop(); 8535 HValue* right = Pop();
8585 HValue* left = Pop(); 8536 HValue* left = Pop();
8586 HInstruction* instr = BuildBinaryOperation(expr, left, right); 8537 HInstruction* instr = BuildBinaryOperation(expr, left, right);
8587 instr->set_position(expr->position()); 8538 instr->set_position(expr->position());
8588 return ast_context()->ReturnInstruction(instr, expr->id()); 8539 return ast_context()->ReturnInstruction(instr, expr->id());
8589 } 8540 }
8590 8541
8591 8542
8592 Representation HOptimizedGraphBuilder::ToRepresentation(TypeInfo info) { 8543 Representation HGraphBuilder::ToRepresentation(TypeInfo info) {
8593 if (info.IsUninitialized()) return Representation::None(); 8544 if (info.IsUninitialized()) return Representation::None();
8594 if (info.IsSmi()) return Representation::Integer32(); 8545 if (info.IsSmi()) return Representation::Integer32();
8595 if (info.IsInteger32()) return Representation::Integer32(); 8546 if (info.IsInteger32()) return Representation::Integer32();
8596 if (info.IsDouble()) return Representation::Double(); 8547 if (info.IsDouble()) return Representation::Double();
8597 if (info.IsNumber()) return Representation::Double(); 8548 if (info.IsNumber()) return Representation::Double();
8598 return Representation::Tagged(); 8549 return Representation::Tagged();
8599 } 8550 }
8600 8551
8601 8552
8602 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, 8553 void HGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr,
8603 HTypeof* typeof_expr, 8554 HTypeof* typeof_expr,
8604 Handle<String> check) { 8555 Handle<String> check) {
8605 // Note: The HTypeof itself is removed during canonicalization, if possible. 8556 // Note: The HTypeof itself is removed during canonicalization, if possible.
8606 HValue* value = typeof_expr->value(); 8557 HValue* value = typeof_expr->value();
8607 HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check); 8558 HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check);
8608 instr->set_position(expr->position()); 8559 instr->set_position(expr->position());
8609 return ast_context()->ReturnControl(instr, expr->id()); 8560 return ast_context()->ReturnControl(instr, expr->id());
8610 } 8561 }
8611 8562
8612 8563
8613 static bool MatchLiteralCompareNil(HValue* left, 8564 static bool MatchLiteralCompareNil(HValue* left,
8614 Token::Value op, 8565 Token::Value op,
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
8664 8615
8665 static bool IsLiteralCompareBool(HValue* left, 8616 static bool IsLiteralCompareBool(HValue* left,
8666 Token::Value op, 8617 Token::Value op,
8667 HValue* right) { 8618 HValue* right) {
8668 return op == Token::EQ_STRICT && 8619 return op == Token::EQ_STRICT &&
8669 ((left->IsConstant() && HConstant::cast(left)->handle()->IsBoolean()) || 8620 ((left->IsConstant() && HConstant::cast(left)->handle()->IsBoolean()) ||
8670 (right->IsConstant() && HConstant::cast(right)->handle()->IsBoolean())); 8621 (right->IsConstant() && HConstant::cast(right)->handle()->IsBoolean()));
8671 } 8622 }
8672 8623
8673 8624
8674 void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { 8625 void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
8675 ASSERT(!HasStackOverflow()); 8626 ASSERT(!HasStackOverflow());
8676 ASSERT(current_block() != NULL); 8627 ASSERT(current_block() != NULL);
8677 ASSERT(current_block()->HasPredecessor()); 8628 ASSERT(current_block()->HasPredecessor());
8678 if (IsClassOfTest(expr)) { 8629 if (IsClassOfTest(expr)) {
8679 CallRuntime* call = expr->left()->AsCallRuntime(); 8630 CallRuntime* call = expr->left()->AsCallRuntime();
8680 ASSERT(call->arguments()->length() == 1); 8631 ASSERT(call->arguments()->length() == 1);
8681 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 8632 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
8682 HValue* value = Pop(); 8633 HValue* value = Pop();
8683 Literal* literal = expr->right()->AsLiteral(); 8634 Literal* literal = expr->right()->AsLiteral();
8684 Handle<String> rhs = Handle<String>::cast(literal->handle()); 8635 Handle<String> rhs = Handle<String>::cast(literal->handle());
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
8817 HCompareIDAndBranch* result = 8768 HCompareIDAndBranch* result =
8818 new(zone()) HCompareIDAndBranch(left, right, op); 8769 new(zone()) HCompareIDAndBranch(left, right, op);
8819 result->set_observed_input_representation(left_rep, right_rep); 8770 result->set_observed_input_representation(left_rep, right_rep);
8820 result->set_position(expr->position()); 8771 result->set_position(expr->position());
8821 return ast_context()->ReturnControl(result, expr->id()); 8772 return ast_context()->ReturnControl(result, expr->id());
8822 } 8773 }
8823 } 8774 }
8824 } 8775 }
8825 8776
8826 8777
8827 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, 8778 void HGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr,
8828 HValue* value, 8779 HValue* value,
8829 NilValue nil) { 8780 NilValue nil) {
8830 ASSERT(!HasStackOverflow()); 8781 ASSERT(!HasStackOverflow());
8831 ASSERT(current_block() != NULL); 8782 ASSERT(current_block() != NULL);
8832 ASSERT(current_block()->HasPredecessor()); 8783 ASSERT(current_block()->HasPredecessor());
8833 EqualityKind kind = 8784 EqualityKind kind =
8834 expr->op() == Token::EQ_STRICT ? kStrictEquality : kNonStrictEquality; 8785 expr->op() == Token::EQ_STRICT ? kStrictEquality : kNonStrictEquality;
8835 HIsNilAndBranch* instr = new(zone()) HIsNilAndBranch(value, kind, nil); 8786 HIsNilAndBranch* instr = new(zone()) HIsNilAndBranch(value, kind, nil);
8836 instr->set_position(expr->position()); 8787 instr->set_position(expr->position());
8837 return ast_context()->ReturnControl(instr, expr->id()); 8788 return ast_context()->ReturnControl(instr, expr->id());
8838 } 8789 }
8839 8790
8840 8791
8841 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { 8792 HInstruction* HGraphBuilder::BuildThisFunction() {
8842 // If we share optimized code between different closures, the 8793 // If we share optimized code between different closures, the
8843 // this-function is not a constant, except inside an inlined body. 8794 // this-function is not a constant, except inside an inlined body.
8844 if (function_state()->outer() != NULL) { 8795 if (function_state()->outer() != NULL) {
8845 return new(zone()) HConstant( 8796 return new(zone()) HConstant(
8846 function_state()->compilation_info()->closure(), 8797 function_state()->compilation_info()->closure(),
8847 Representation::Tagged()); 8798 Representation::Tagged());
8848 } else { 8799 } else {
8849 return new(zone()) HThisFunction; 8800 return new(zone()) HThisFunction;
8850 } 8801 }
8851 } 8802 }
8852 8803
8853 8804
8854 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { 8805 void HGraphBuilder::VisitThisFunction(ThisFunction* expr) {
8855 ASSERT(!HasStackOverflow()); 8806 ASSERT(!HasStackOverflow());
8856 ASSERT(current_block() != NULL); 8807 ASSERT(current_block() != NULL);
8857 ASSERT(current_block()->HasPredecessor()); 8808 ASSERT(current_block()->HasPredecessor());
8858 HInstruction* instr = BuildThisFunction(); 8809 HInstruction* instr = BuildThisFunction();
8859 return ast_context()->ReturnInstruction(instr, expr->id()); 8810 return ast_context()->ReturnInstruction(instr, expr->id());
8860 } 8811 }
8861 8812
8862 8813
8863 void HOptimizedGraphBuilder::VisitDeclarations( 8814 void HGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) {
8864 ZoneList<Declaration*>* declarations) {
8865 ASSERT(globals_.is_empty()); 8815 ASSERT(globals_.is_empty());
8866 AstVisitor::VisitDeclarations(declarations); 8816 AstVisitor::VisitDeclarations(declarations);
8867 if (!globals_.is_empty()) { 8817 if (!globals_.is_empty()) {
8868 Handle<FixedArray> array = 8818 Handle<FixedArray> array =
8869 isolate()->factory()->NewFixedArray(globals_.length(), TENURED); 8819 isolate()->factory()->NewFixedArray(globals_.length(), TENURED);
8870 for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i)); 8820 for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i));
8871 int flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) | 8821 int flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) |
8872 DeclareGlobalsNativeFlag::encode(info()->is_native()) | 8822 DeclareGlobalsNativeFlag::encode(info()->is_native()) |
8873 DeclareGlobalsLanguageMode::encode(info()->language_mode()); 8823 DeclareGlobalsLanguageMode::encode(info()->language_mode());
8874 HInstruction* result = new(zone()) HDeclareGlobals( 8824 HInstruction* result = new(zone()) HDeclareGlobals(
8875 environment()->LookupContext(), array, flags); 8825 environment()->LookupContext(), array, flags);
8876 AddInstruction(result); 8826 AddInstruction(result);
8877 globals_.Clear(); 8827 globals_.Clear();
8878 } 8828 }
8879 } 8829 }
8880 8830
8881 8831
8882 void HOptimizedGraphBuilder::VisitVariableDeclaration( 8832 void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) {
8883 VariableDeclaration* declaration) {
8884 VariableProxy* proxy = declaration->proxy(); 8833 VariableProxy* proxy = declaration->proxy();
8885 VariableMode mode = declaration->mode(); 8834 VariableMode mode = declaration->mode();
8886 Variable* variable = proxy->var(); 8835 Variable* variable = proxy->var();
8887 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; 8836 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
8888 switch (variable->location()) { 8837 switch (variable->location()) {
8889 case Variable::UNALLOCATED: 8838 case Variable::UNALLOCATED:
8890 globals_.Add(variable->name(), zone()); 8839 globals_.Add(variable->name(), zone());
8891 globals_.Add(variable->binding_needs_init() 8840 globals_.Add(variable->binding_needs_init()
8892 ? isolate()->factory()->the_hole_value() 8841 ? isolate()->factory()->the_hole_value()
8893 : isolate()->factory()->undefined_value(), zone()); 8842 : isolate()->factory()->undefined_value(), zone());
(...skipping 16 matching lines...) Expand all
8910 AddSimulate(proxy->id(), REMOVABLE_SIMULATE); 8859 AddSimulate(proxy->id(), REMOVABLE_SIMULATE);
8911 } 8860 }
8912 } 8861 }
8913 break; 8862 break;
8914 case Variable::LOOKUP: 8863 case Variable::LOOKUP:
8915 return Bailout("unsupported lookup slot in declaration"); 8864 return Bailout("unsupported lookup slot in declaration");
8916 } 8865 }
8917 } 8866 }
8918 8867
8919 8868
8920 void HOptimizedGraphBuilder::VisitFunctionDeclaration( 8869 void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) {
8921 FunctionDeclaration* declaration) {
8922 VariableProxy* proxy = declaration->proxy(); 8870 VariableProxy* proxy = declaration->proxy();
8923 Variable* variable = proxy->var(); 8871 Variable* variable = proxy->var();
8924 switch (variable->location()) { 8872 switch (variable->location()) {
8925 case Variable::UNALLOCATED: { 8873 case Variable::UNALLOCATED: {
8926 globals_.Add(variable->name(), zone()); 8874 globals_.Add(variable->name(), zone());
8927 Handle<SharedFunctionInfo> function = 8875 Handle<SharedFunctionInfo> function =
8928 Compiler::BuildFunctionInfo(declaration->fun(), info()->script()); 8876 Compiler::BuildFunctionInfo(declaration->fun(), info()->script());
8929 // Check for stack-overflow exception. 8877 // Check for stack-overflow exception.
8930 if (function.is_null()) return SetStackOverflow(); 8878 if (function.is_null()) return SetStackOverflow();
8931 globals_.Add(function, zone()); 8879 globals_.Add(function, zone());
(...skipping 17 matching lines...) Expand all
8949 AddSimulate(proxy->id(), REMOVABLE_SIMULATE); 8897 AddSimulate(proxy->id(), REMOVABLE_SIMULATE);
8950 } 8898 }
8951 break; 8899 break;
8952 } 8900 }
8953 case Variable::LOOKUP: 8901 case Variable::LOOKUP:
8954 return Bailout("unsupported lookup slot in declaration"); 8902 return Bailout("unsupported lookup slot in declaration");
8955 } 8903 }
8956 } 8904 }
8957 8905
8958 8906
8959 void HOptimizedGraphBuilder::VisitModuleDeclaration( 8907 void HGraphBuilder::VisitModuleDeclaration(ModuleDeclaration* declaration) {
8960 ModuleDeclaration* declaration) {
8961 UNREACHABLE(); 8908 UNREACHABLE();
8962 } 8909 }
8963 8910
8964 8911
8965 void HOptimizedGraphBuilder::VisitImportDeclaration( 8912 void HGraphBuilder::VisitImportDeclaration(ImportDeclaration* declaration) {
8966 ImportDeclaration* declaration) {
8967 UNREACHABLE(); 8913 UNREACHABLE();
8968 } 8914 }
8969 8915
8970 8916
8971 void HOptimizedGraphBuilder::VisitExportDeclaration( 8917 void HGraphBuilder::VisitExportDeclaration(ExportDeclaration* declaration) {
8972 ExportDeclaration* declaration) {
8973 UNREACHABLE(); 8918 UNREACHABLE();
8974 } 8919 }
8975 8920
8976 8921
8977 void HOptimizedGraphBuilder::VisitModuleLiteral(ModuleLiteral* module) { 8922 void HGraphBuilder::VisitModuleLiteral(ModuleLiteral* module) {
8978 UNREACHABLE(); 8923 UNREACHABLE();
8979 } 8924 }
8980 8925
8981 8926
8982 void HOptimizedGraphBuilder::VisitModuleVariable(ModuleVariable* module) { 8927 void HGraphBuilder::VisitModuleVariable(ModuleVariable* module) {
8983 UNREACHABLE(); 8928 UNREACHABLE();
8984 } 8929 }
8985 8930
8986 8931
8987 void HOptimizedGraphBuilder::VisitModulePath(ModulePath* module) { 8932 void HGraphBuilder::VisitModulePath(ModulePath* module) {
8988 UNREACHABLE(); 8933 UNREACHABLE();
8989 } 8934 }
8990 8935
8991 8936
8992 void HOptimizedGraphBuilder::VisitModuleUrl(ModuleUrl* module) { 8937 void HGraphBuilder::VisitModuleUrl(ModuleUrl* module) {
8993 UNREACHABLE(); 8938 UNREACHABLE();
8994 } 8939 }
8995 8940
8996 8941
8997 void HOptimizedGraphBuilder::VisitModuleStatement(ModuleStatement* stmt) { 8942 void HGraphBuilder::VisitModuleStatement(ModuleStatement* stmt) {
8998 UNREACHABLE(); 8943 UNREACHABLE();
8999 } 8944 }
9000 8945
9001 8946
9002 // Generators for inline runtime functions. 8947 // Generators for inline runtime functions.
9003 // Support for types. 8948 // Support for types.
9004 void HOptimizedGraphBuilder::GenerateIsSmi(CallRuntime* call) { 8949 void HGraphBuilder::GenerateIsSmi(CallRuntime* call) {
9005 ASSERT(call->arguments()->length() == 1); 8950 ASSERT(call->arguments()->length() == 1);
9006 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 8951 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9007 HValue* value = Pop(); 8952 HValue* value = Pop();
9008 HIsSmiAndBranch* result = new(zone()) HIsSmiAndBranch(value); 8953 HIsSmiAndBranch* result = new(zone()) HIsSmiAndBranch(value);
9009 return ast_context()->ReturnControl(result, call->id()); 8954 return ast_context()->ReturnControl(result, call->id());
9010 } 8955 }
9011 8956
9012 8957
9013 void HOptimizedGraphBuilder::GenerateIsSpecObject(CallRuntime* call) { 8958 void HGraphBuilder::GenerateIsSpecObject(CallRuntime* call) {
9014 ASSERT(call->arguments()->length() == 1); 8959 ASSERT(call->arguments()->length() == 1);
9015 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 8960 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9016 HValue* value = Pop(); 8961 HValue* value = Pop();
9017 HHasInstanceTypeAndBranch* result = 8962 HHasInstanceTypeAndBranch* result =
9018 new(zone()) HHasInstanceTypeAndBranch(value, 8963 new(zone()) HHasInstanceTypeAndBranch(value,
9019 FIRST_SPEC_OBJECT_TYPE, 8964 FIRST_SPEC_OBJECT_TYPE,
9020 LAST_SPEC_OBJECT_TYPE); 8965 LAST_SPEC_OBJECT_TYPE);
9021 return ast_context()->ReturnControl(result, call->id()); 8966 return ast_context()->ReturnControl(result, call->id());
9022 } 8967 }
9023 8968
9024 8969
9025 void HOptimizedGraphBuilder::GenerateIsFunction(CallRuntime* call) { 8970 void HGraphBuilder::GenerateIsFunction(CallRuntime* call) {
9026 ASSERT(call->arguments()->length() == 1); 8971 ASSERT(call->arguments()->length() == 1);
9027 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 8972 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9028 HValue* value = Pop(); 8973 HValue* value = Pop();
9029 HHasInstanceTypeAndBranch* result = 8974 HHasInstanceTypeAndBranch* result =
9030 new(zone()) HHasInstanceTypeAndBranch(value, JS_FUNCTION_TYPE); 8975 new(zone()) HHasInstanceTypeAndBranch(value, JS_FUNCTION_TYPE);
9031 return ast_context()->ReturnControl(result, call->id()); 8976 return ast_context()->ReturnControl(result, call->id());
9032 } 8977 }
9033 8978
9034 8979
9035 void HOptimizedGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) { 8980 void HGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) {
9036 ASSERT(call->arguments()->length() == 1); 8981 ASSERT(call->arguments()->length() == 1);
9037 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 8982 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9038 HValue* value = Pop(); 8983 HValue* value = Pop();
9039 HHasCachedArrayIndexAndBranch* result = 8984 HHasCachedArrayIndexAndBranch* result =
9040 new(zone()) HHasCachedArrayIndexAndBranch(value); 8985 new(zone()) HHasCachedArrayIndexAndBranch(value);
9041 return ast_context()->ReturnControl(result, call->id()); 8986 return ast_context()->ReturnControl(result, call->id());
9042 } 8987 }
9043 8988
9044 8989
9045 void HOptimizedGraphBuilder::GenerateIsArray(CallRuntime* call) { 8990 void HGraphBuilder::GenerateIsArray(CallRuntime* call) {
9046 ASSERT(call->arguments()->length() == 1); 8991 ASSERT(call->arguments()->length() == 1);
9047 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 8992 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9048 HValue* value = Pop(); 8993 HValue* value = Pop();
9049 HHasInstanceTypeAndBranch* result = 8994 HHasInstanceTypeAndBranch* result =
9050 new(zone()) HHasInstanceTypeAndBranch(value, JS_ARRAY_TYPE); 8995 new(zone()) HHasInstanceTypeAndBranch(value, JS_ARRAY_TYPE);
9051 return ast_context()->ReturnControl(result, call->id()); 8996 return ast_context()->ReturnControl(result, call->id());
9052 } 8997 }
9053 8998
9054 8999
9055 void HOptimizedGraphBuilder::GenerateIsRegExp(CallRuntime* call) { 9000 void HGraphBuilder::GenerateIsRegExp(CallRuntime* call) {
9056 ASSERT(call->arguments()->length() == 1); 9001 ASSERT(call->arguments()->length() == 1);
9057 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9002 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9058 HValue* value = Pop(); 9003 HValue* value = Pop();
9059 HHasInstanceTypeAndBranch* result = 9004 HHasInstanceTypeAndBranch* result =
9060 new(zone()) HHasInstanceTypeAndBranch(value, JS_REGEXP_TYPE); 9005 new(zone()) HHasInstanceTypeAndBranch(value, JS_REGEXP_TYPE);
9061 return ast_context()->ReturnControl(result, call->id()); 9006 return ast_context()->ReturnControl(result, call->id());
9062 } 9007 }
9063 9008
9064 9009
9065 void HOptimizedGraphBuilder::GenerateIsObject(CallRuntime* call) { 9010 void HGraphBuilder::GenerateIsObject(CallRuntime* call) {
9066 ASSERT(call->arguments()->length() == 1); 9011 ASSERT(call->arguments()->length() == 1);
9067 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9012 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9068 HValue* value = Pop(); 9013 HValue* value = Pop();
9069 HIsObjectAndBranch* result = new(zone()) HIsObjectAndBranch(value); 9014 HIsObjectAndBranch* result = new(zone()) HIsObjectAndBranch(value);
9070 return ast_context()->ReturnControl(result, call->id()); 9015 return ast_context()->ReturnControl(result, call->id());
9071 } 9016 }
9072 9017
9073 9018
9074 void HOptimizedGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) { 9019 void HGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) {
9075 return Bailout("inlined runtime function: IsNonNegativeSmi"); 9020 return Bailout("inlined runtime function: IsNonNegativeSmi");
9076 } 9021 }
9077 9022
9078 9023
9079 void HOptimizedGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) { 9024 void HGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) {
9080 ASSERT(call->arguments()->length() == 1); 9025 ASSERT(call->arguments()->length() == 1);
9081 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9026 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9082 HValue* value = Pop(); 9027 HValue* value = Pop();
9083 HIsUndetectableAndBranch* result = 9028 HIsUndetectableAndBranch* result =
9084 new(zone()) HIsUndetectableAndBranch(value); 9029 new(zone()) HIsUndetectableAndBranch(value);
9085 return ast_context()->ReturnControl(result, call->id()); 9030 return ast_context()->ReturnControl(result, call->id());
9086 } 9031 }
9087 9032
9088 9033
9089 void HOptimizedGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf( 9034 void HGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf(
9090 CallRuntime* call) { 9035 CallRuntime* call) {
9091 return Bailout( 9036 return Bailout(
9092 "inlined runtime function: IsStringWrapperSafeForDefaultValueOf"); 9037 "inlined runtime function: IsStringWrapperSafeForDefaultValueOf");
9093 } 9038 }
9094 9039
9095 9040
9096 // Support for construct call checks. 9041 // Support for construct call checks.
9097 void HOptimizedGraphBuilder::GenerateIsConstructCall(CallRuntime* call) { 9042 void HGraphBuilder::GenerateIsConstructCall(CallRuntime* call) {
9098 ASSERT(call->arguments()->length() == 0); 9043 ASSERT(call->arguments()->length() == 0);
9099 if (function_state()->outer() != NULL) { 9044 if (function_state()->outer() != NULL) {
9100 // We are generating graph for inlined function. 9045 // We are generating graph for inlined function.
9101 HValue* value = function_state()->inlining_kind() == CONSTRUCT_CALL_RETURN 9046 HValue* value = function_state()->inlining_kind() == CONSTRUCT_CALL_RETURN
9102 ? graph()->GetConstantTrue() 9047 ? graph()->GetConstantTrue()
9103 : graph()->GetConstantFalse(); 9048 : graph()->GetConstantFalse();
9104 return ast_context()->ReturnValue(value); 9049 return ast_context()->ReturnValue(value);
9105 } else { 9050 } else {
9106 return ast_context()->ReturnControl(new(zone()) HIsConstructCallAndBranch, 9051 return ast_context()->ReturnControl(new(zone()) HIsConstructCallAndBranch,
9107 call->id()); 9052 call->id());
9108 } 9053 }
9109 } 9054 }
9110 9055
9111 9056
9112 // Support for arguments.length and arguments[?]. 9057 // Support for arguments.length and arguments[?].
9113 void HOptimizedGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { 9058 void HGraphBuilder::GenerateArgumentsLength(CallRuntime* call) {
9114 // Our implementation of arguments (based on this stack frame or an 9059 // Our implementation of arguments (based on this stack frame or an
9115 // adapter below it) does not work for inlined functions. This runtime 9060 // adapter below it) does not work for inlined functions. This runtime
9116 // function is blacklisted by AstNode::IsInlineable. 9061 // function is blacklisted by AstNode::IsInlineable.
9117 ASSERT(function_state()->outer() == NULL); 9062 ASSERT(function_state()->outer() == NULL);
9118 ASSERT(call->arguments()->length() == 0); 9063 ASSERT(call->arguments()->length() == 0);
9119 HInstruction* elements = AddInstruction( 9064 HInstruction* elements = AddInstruction(
9120 new(zone()) HArgumentsElements(false)); 9065 new(zone()) HArgumentsElements(false));
9121 HArgumentsLength* result = new(zone()) HArgumentsLength(elements); 9066 HArgumentsLength* result = new(zone()) HArgumentsLength(elements);
9122 return ast_context()->ReturnInstruction(result, call->id()); 9067 return ast_context()->ReturnInstruction(result, call->id());
9123 } 9068 }
9124 9069
9125 9070
9126 void HOptimizedGraphBuilder::GenerateArguments(CallRuntime* call) { 9071 void HGraphBuilder::GenerateArguments(CallRuntime* call) {
9127 // Our implementation of arguments (based on this stack frame or an 9072 // Our implementation of arguments (based on this stack frame or an
9128 // adapter below it) does not work for inlined functions. This runtime 9073 // adapter below it) does not work for inlined functions. This runtime
9129 // function is blacklisted by AstNode::IsInlineable. 9074 // function is blacklisted by AstNode::IsInlineable.
9130 ASSERT(function_state()->outer() == NULL); 9075 ASSERT(function_state()->outer() == NULL);
9131 ASSERT(call->arguments()->length() == 1); 9076 ASSERT(call->arguments()->length() == 1);
9132 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9077 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9133 HValue* index = Pop(); 9078 HValue* index = Pop();
9134 HInstruction* elements = AddInstruction( 9079 HInstruction* elements = AddInstruction(
9135 new(zone()) HArgumentsElements(false)); 9080 new(zone()) HArgumentsElements(false));
9136 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); 9081 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements));
9137 HInstruction* checked_index = 9082 HInstruction* checked_index =
9138 AddInstruction(new(zone()) HBoundsCheck(index, length)); 9083 AddInstruction(new(zone()) HBoundsCheck(index, length));
9139 HAccessArgumentsAt* result = 9084 HAccessArgumentsAt* result =
9140 new(zone()) HAccessArgumentsAt(elements, length, checked_index); 9085 new(zone()) HAccessArgumentsAt(elements, length, checked_index);
9141 return ast_context()->ReturnInstruction(result, call->id()); 9086 return ast_context()->ReturnInstruction(result, call->id());
9142 } 9087 }
9143 9088
9144 9089
9145 // Support for accessing the class and value fields of an object. 9090 // Support for accessing the class and value fields of an object.
9146 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { 9091 void HGraphBuilder::GenerateClassOf(CallRuntime* call) {
9147 // The special form detected by IsClassOfTest is detected before we get here 9092 // The special form detected by IsClassOfTest is detected before we get here
9148 // and does not cause a bailout. 9093 // and does not cause a bailout.
9149 return Bailout("inlined runtime function: ClassOf"); 9094 return Bailout("inlined runtime function: ClassOf");
9150 } 9095 }
9151 9096
9152 9097
9153 void HOptimizedGraphBuilder::GenerateValueOf(CallRuntime* call) { 9098 void HGraphBuilder::GenerateValueOf(CallRuntime* call) {
9154 ASSERT(call->arguments()->length() == 1); 9099 ASSERT(call->arguments()->length() == 1);
9155 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9100 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9156 HValue* value = Pop(); 9101 HValue* value = Pop();
9157 HValueOf* result = new(zone()) HValueOf(value); 9102 HValueOf* result = new(zone()) HValueOf(value);
9158 return ast_context()->ReturnInstruction(result, call->id()); 9103 return ast_context()->ReturnInstruction(result, call->id());
9159 } 9104 }
9160 9105
9161 9106
9162 void HOptimizedGraphBuilder::GenerateDateField(CallRuntime* call) { 9107 void HGraphBuilder::GenerateDateField(CallRuntime* call) {
9163 ASSERT(call->arguments()->length() == 2); 9108 ASSERT(call->arguments()->length() == 2);
9164 ASSERT_NE(NULL, call->arguments()->at(1)->AsLiteral()); 9109 ASSERT_NE(NULL, call->arguments()->at(1)->AsLiteral());
9165 Smi* index = Smi::cast(*(call->arguments()->at(1)->AsLiteral()->handle())); 9110 Smi* index = Smi::cast(*(call->arguments()->at(1)->AsLiteral()->handle()));
9166 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9111 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9167 HValue* date = Pop(); 9112 HValue* date = Pop();
9168 HDateField* result = new(zone()) HDateField(date, index); 9113 HDateField* result = new(zone()) HDateField(date, index);
9169 return ast_context()->ReturnInstruction(result, call->id()); 9114 return ast_context()->ReturnInstruction(result, call->id());
9170 } 9115 }
9171 9116
9172 9117
9173 void HOptimizedGraphBuilder::GenerateOneByteSeqStringSetChar( 9118 void HGraphBuilder::GenerateOneByteSeqStringSetChar(
9174 CallRuntime* call) { 9119 CallRuntime* call) {
9175 ASSERT(call->arguments()->length() == 3); 9120 ASSERT(call->arguments()->length() == 3);
9176 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9121 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9177 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 9122 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
9178 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); 9123 CHECK_ALIVE(VisitForValue(call->arguments()->at(2)));
9179 HValue* value = Pop(); 9124 HValue* value = Pop();
9180 HValue* index = Pop(); 9125 HValue* index = Pop();
9181 HValue* string = Pop(); 9126 HValue* string = Pop();
9182 HSeqStringSetChar* result = new(zone()) HSeqStringSetChar( 9127 HSeqStringSetChar* result = new(zone()) HSeqStringSetChar(
9183 String::ONE_BYTE_ENCODING, string, index, value); 9128 String::ONE_BYTE_ENCODING, string, index, value);
9184 return ast_context()->ReturnInstruction(result, call->id()); 9129 return ast_context()->ReturnInstruction(result, call->id());
9185 } 9130 }
9186 9131
9187 9132
9188 void HOptimizedGraphBuilder::GenerateTwoByteSeqStringSetChar( 9133 void HGraphBuilder::GenerateTwoByteSeqStringSetChar(
9189 CallRuntime* call) { 9134 CallRuntime* call) {
9190 ASSERT(call->arguments()->length() == 3); 9135 ASSERT(call->arguments()->length() == 3);
9191 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9136 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9192 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 9137 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
9193 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); 9138 CHECK_ALIVE(VisitForValue(call->arguments()->at(2)));
9194 HValue* value = Pop(); 9139 HValue* value = Pop();
9195 HValue* index = Pop(); 9140 HValue* index = Pop();
9196 HValue* string = Pop(); 9141 HValue* string = Pop();
9197 HValue* context = environment()->LookupContext(); 9142 HValue* context = environment()->LookupContext();
9198 HStringCharCodeAt* char_code = BuildStringCharCodeAt(context, string, index); 9143 HStringCharCodeAt* char_code = BuildStringCharCodeAt(context, string, index);
9199 AddInstruction(char_code); 9144 AddInstruction(char_code);
9200 HSeqStringSetChar* result = new(zone()) HSeqStringSetChar( 9145 HSeqStringSetChar* result = new(zone()) HSeqStringSetChar(
9201 String::TWO_BYTE_ENCODING, string, index, value); 9146 String::TWO_BYTE_ENCODING, string, index, value);
9202 return ast_context()->ReturnInstruction(result, call->id()); 9147 return ast_context()->ReturnInstruction(result, call->id());
9203 } 9148 }
9204 9149
9205 9150
9206 void HOptimizedGraphBuilder::GenerateSetValueOf(CallRuntime* call) { 9151 void HGraphBuilder::GenerateSetValueOf(CallRuntime* call) {
9207 ASSERT(call->arguments()->length() == 2); 9152 ASSERT(call->arguments()->length() == 2);
9208 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9153 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9209 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 9154 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
9210 HValue* value = Pop(); 9155 HValue* value = Pop();
9211 HValue* object = Pop(); 9156 HValue* object = Pop();
9212 // Check if object is a not a smi. 9157 // Check if object is a not a smi.
9213 HIsSmiAndBranch* smicheck = new(zone()) HIsSmiAndBranch(object); 9158 HIsSmiAndBranch* smicheck = new(zone()) HIsSmiAndBranch(object);
9214 HBasicBlock* if_smi = graph()->CreateBasicBlock(); 9159 HBasicBlock* if_smi = graph()->CreateBasicBlock();
9215 HBasicBlock* if_heap_object = graph()->CreateBasicBlock(); 9160 HBasicBlock* if_heap_object = graph()->CreateBasicBlock();
9216 HBasicBlock* join = graph()->CreateBasicBlock(); 9161 HBasicBlock* join = graph()->CreateBasicBlock();
(...skipping 22 matching lines...) Expand all
9239 true, // in-object store. 9184 true, // in-object store.
9240 JSValue::kValueOffset)); 9185 JSValue::kValueOffset));
9241 if_js_value->Goto(join); 9186 if_js_value->Goto(join);
9242 join->SetJoinId(call->id()); 9187 join->SetJoinId(call->id());
9243 set_current_block(join); 9188 set_current_block(join);
9244 return ast_context()->ReturnValue(value); 9189 return ast_context()->ReturnValue(value);
9245 } 9190 }
9246 9191
9247 9192
9248 // Fast support for charCodeAt(n). 9193 // Fast support for charCodeAt(n).
9249 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { 9194 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) {
9250 ASSERT(call->arguments()->length() == 2); 9195 ASSERT(call->arguments()->length() == 2);
9251 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9196 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9252 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 9197 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
9253 HValue* index = Pop(); 9198 HValue* index = Pop();
9254 HValue* string = Pop(); 9199 HValue* string = Pop();
9255 HValue* context = environment()->LookupContext(); 9200 HValue* context = environment()->LookupContext();
9256 HStringCharCodeAt* result = BuildStringCharCodeAt(context, string, index); 9201 HStringCharCodeAt* result = BuildStringCharCodeAt(context, string, index);
9257 return ast_context()->ReturnInstruction(result, call->id()); 9202 return ast_context()->ReturnInstruction(result, call->id());
9258 } 9203 }
9259 9204
9260 9205
9261 // Fast support for string.charAt(n) and string[n]. 9206 // Fast support for string.charAt(n) and string[n].
9262 void HOptimizedGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { 9207 void HGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) {
9263 ASSERT(call->arguments()->length() == 1); 9208 ASSERT(call->arguments()->length() == 1);
9264 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9209 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9265 HValue* char_code = Pop(); 9210 HValue* char_code = Pop();
9266 HValue* context = environment()->LookupContext(); 9211 HValue* context = environment()->LookupContext();
9267 HStringCharFromCode* result = 9212 HStringCharFromCode* result =
9268 new(zone()) HStringCharFromCode(context, char_code); 9213 new(zone()) HStringCharFromCode(context, char_code);
9269 return ast_context()->ReturnInstruction(result, call->id()); 9214 return ast_context()->ReturnInstruction(result, call->id());
9270 } 9215 }
9271 9216
9272 9217
9273 // Fast support for string.charAt(n) and string[n]. 9218 // Fast support for string.charAt(n) and string[n].
9274 void HOptimizedGraphBuilder::GenerateStringCharAt(CallRuntime* call) { 9219 void HGraphBuilder::GenerateStringCharAt(CallRuntime* call) {
9275 ASSERT(call->arguments()->length() == 2); 9220 ASSERT(call->arguments()->length() == 2);
9276 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9221 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9277 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 9222 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
9278 HValue* index = Pop(); 9223 HValue* index = Pop();
9279 HValue* string = Pop(); 9224 HValue* string = Pop();
9280 HValue* context = environment()->LookupContext(); 9225 HValue* context = environment()->LookupContext();
9281 HStringCharCodeAt* char_code = BuildStringCharCodeAt(context, string, index); 9226 HStringCharCodeAt* char_code = BuildStringCharCodeAt(context, string, index);
9282 AddInstruction(char_code); 9227 AddInstruction(char_code);
9283 HStringCharFromCode* result = 9228 HStringCharFromCode* result =
9284 new(zone()) HStringCharFromCode(context, char_code); 9229 new(zone()) HStringCharFromCode(context, char_code);
9285 return ast_context()->ReturnInstruction(result, call->id()); 9230 return ast_context()->ReturnInstruction(result, call->id());
9286 } 9231 }
9287 9232
9288 9233
9289 // Fast support for object equality testing. 9234 // Fast support for object equality testing.
9290 void HOptimizedGraphBuilder::GenerateObjectEquals(CallRuntime* call) { 9235 void HGraphBuilder::GenerateObjectEquals(CallRuntime* call) {
9291 ASSERT(call->arguments()->length() == 2); 9236 ASSERT(call->arguments()->length() == 2);
9292 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9237 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9293 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 9238 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
9294 HValue* right = Pop(); 9239 HValue* right = Pop();
9295 HValue* left = Pop(); 9240 HValue* left = Pop();
9296 HCompareObjectEqAndBranch* result = 9241 HCompareObjectEqAndBranch* result =
9297 new(zone()) HCompareObjectEqAndBranch(left, right); 9242 new(zone()) HCompareObjectEqAndBranch(left, right);
9298 return ast_context()->ReturnControl(result, call->id()); 9243 return ast_context()->ReturnControl(result, call->id());
9299 } 9244 }
9300 9245
9301 9246
9302 void HOptimizedGraphBuilder::GenerateLog(CallRuntime* call) { 9247 void HGraphBuilder::GenerateLog(CallRuntime* call) {
9303 // %_Log is ignored in optimized code. 9248 // %_Log is ignored in optimized code.
9304 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 9249 return ast_context()->ReturnValue(graph()->GetConstantUndefined());
9305 } 9250 }
9306 9251
9307 9252
9308 // Fast support for Math.random(). 9253 // Fast support for Math.random().
9309 void HOptimizedGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) { 9254 void HGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) {
9310 HValue* context = environment()->LookupContext(); 9255 HValue* context = environment()->LookupContext();
9311 HGlobalObject* global_object = new(zone()) HGlobalObject(context); 9256 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
9312 AddInstruction(global_object); 9257 AddInstruction(global_object);
9313 HRandom* result = new(zone()) HRandom(global_object); 9258 HRandom* result = new(zone()) HRandom(global_object);
9314 return ast_context()->ReturnInstruction(result, call->id()); 9259 return ast_context()->ReturnInstruction(result, call->id());
9315 } 9260 }
9316 9261
9317 9262
9318 // Fast support for StringAdd. 9263 // Fast support for StringAdd.
9319 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { 9264 void HGraphBuilder::GenerateStringAdd(CallRuntime* call) {
9320 ASSERT_EQ(2, call->arguments()->length()); 9265 ASSERT_EQ(2, call->arguments()->length());
9321 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9266 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9322 HValue* context = environment()->LookupContext(); 9267 HValue* context = environment()->LookupContext();
9323 HCallStub* result = new(zone()) HCallStub(context, CodeStub::StringAdd, 2); 9268 HCallStub* result = new(zone()) HCallStub(context, CodeStub::StringAdd, 2);
9324 Drop(2); 9269 Drop(2);
9325 return ast_context()->ReturnInstruction(result, call->id()); 9270 return ast_context()->ReturnInstruction(result, call->id());
9326 } 9271 }
9327 9272
9328 9273
9329 // Fast support for SubString. 9274 // Fast support for SubString.
9330 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { 9275 void HGraphBuilder::GenerateSubString(CallRuntime* call) {
9331 ASSERT_EQ(3, call->arguments()->length()); 9276 ASSERT_EQ(3, call->arguments()->length());
9332 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9277 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9333 HValue* context = environment()->LookupContext(); 9278 HValue* context = environment()->LookupContext();
9334 HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3); 9279 HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3);
9335 Drop(3); 9280 Drop(3);
9336 return ast_context()->ReturnInstruction(result, call->id()); 9281 return ast_context()->ReturnInstruction(result, call->id());
9337 } 9282 }
9338 9283
9339 9284
9340 // Fast support for StringCompare. 9285 // Fast support for StringCompare.
9341 void HOptimizedGraphBuilder::GenerateStringCompare(CallRuntime* call) { 9286 void HGraphBuilder::GenerateStringCompare(CallRuntime* call) {
9342 ASSERT_EQ(2, call->arguments()->length()); 9287 ASSERT_EQ(2, call->arguments()->length());
9343 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9288 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9344 HValue* context = environment()->LookupContext(); 9289 HValue* context = environment()->LookupContext();
9345 HCallStub* result = 9290 HCallStub* result =
9346 new(zone()) HCallStub(context, CodeStub::StringCompare, 2); 9291 new(zone()) HCallStub(context, CodeStub::StringCompare, 2);
9347 Drop(2); 9292 Drop(2);
9348 return ast_context()->ReturnInstruction(result, call->id()); 9293 return ast_context()->ReturnInstruction(result, call->id());
9349 } 9294 }
9350 9295
9351 9296
9352 // Support for direct calls from JavaScript to native RegExp code. 9297 // Support for direct calls from JavaScript to native RegExp code.
9353 void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) { 9298 void HGraphBuilder::GenerateRegExpExec(CallRuntime* call) {
9354 ASSERT_EQ(4, call->arguments()->length()); 9299 ASSERT_EQ(4, call->arguments()->length());
9355 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9300 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9356 HValue* context = environment()->LookupContext(); 9301 HValue* context = environment()->LookupContext();
9357 HCallStub* result = new(zone()) HCallStub(context, CodeStub::RegExpExec, 4); 9302 HCallStub* result = new(zone()) HCallStub(context, CodeStub::RegExpExec, 4);
9358 Drop(4); 9303 Drop(4);
9359 return ast_context()->ReturnInstruction(result, call->id()); 9304 return ast_context()->ReturnInstruction(result, call->id());
9360 } 9305 }
9361 9306
9362 9307
9363 // Construct a RegExp exec result with two in-object properties. 9308 // Construct a RegExp exec result with two in-object properties.
9364 void HOptimizedGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { 9309 void HGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) {
9365 ASSERT_EQ(3, call->arguments()->length()); 9310 ASSERT_EQ(3, call->arguments()->length());
9366 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9311 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9367 HValue* context = environment()->LookupContext(); 9312 HValue* context = environment()->LookupContext();
9368 HCallStub* result = 9313 HCallStub* result =
9369 new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3); 9314 new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3);
9370 Drop(3); 9315 Drop(3);
9371 return ast_context()->ReturnInstruction(result, call->id()); 9316 return ast_context()->ReturnInstruction(result, call->id());
9372 } 9317 }
9373 9318
9374 9319
9375 // Support for fast native caches. 9320 // Support for fast native caches.
9376 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) { 9321 void HGraphBuilder::GenerateGetFromCache(CallRuntime* call) {
9377 return Bailout("inlined runtime function: GetFromCache"); 9322 return Bailout("inlined runtime function: GetFromCache");
9378 } 9323 }
9379 9324
9380 9325
9381 // Fast support for number to string. 9326 // Fast support for number to string.
9382 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { 9327 void HGraphBuilder::GenerateNumberToString(CallRuntime* call) {
9383 ASSERT_EQ(1, call->arguments()->length()); 9328 ASSERT_EQ(1, call->arguments()->length());
9384 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9329 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9385 HValue* context = environment()->LookupContext(); 9330 HValue* context = environment()->LookupContext();
9386 HCallStub* result = 9331 HCallStub* result =
9387 new(zone()) HCallStub(context, CodeStub::NumberToString, 1); 9332 new(zone()) HCallStub(context, CodeStub::NumberToString, 1);
9388 Drop(1); 9333 Drop(1);
9389 return ast_context()->ReturnInstruction(result, call->id()); 9334 return ast_context()->ReturnInstruction(result, call->id());
9390 } 9335 }
9391 9336
9392 9337
9393 // Fast call for custom callbacks. 9338 // Fast call for custom callbacks.
9394 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) { 9339 void HGraphBuilder::GenerateCallFunction(CallRuntime* call) {
9395 // 1 ~ The function to call is not itself an argument to the call. 9340 // 1 ~ The function to call is not itself an argument to the call.
9396 int arg_count = call->arguments()->length() - 1; 9341 int arg_count = call->arguments()->length() - 1;
9397 ASSERT(arg_count >= 1); // There's always at least a receiver. 9342 ASSERT(arg_count >= 1); // There's always at least a receiver.
9398 9343
9399 for (int i = 0; i < arg_count; ++i) { 9344 for (int i = 0; i < arg_count; ++i) {
9400 CHECK_ALIVE(VisitArgument(call->arguments()->at(i))); 9345 CHECK_ALIVE(VisitArgument(call->arguments()->at(i)));
9401 } 9346 }
9402 CHECK_ALIVE(VisitForValue(call->arguments()->last())); 9347 CHECK_ALIVE(VisitForValue(call->arguments()->last()));
9403 9348
9404 HValue* function = Pop(); 9349 HValue* function = Pop();
(...skipping 23 matching lines...) Expand all
9428 Push(call_result); 9373 Push(call_result);
9429 if_nonfunction->Goto(join); 9374 if_nonfunction->Goto(join);
9430 9375
9431 set_current_block(join); 9376 set_current_block(join);
9432 join->SetJoinId(call->id()); 9377 join->SetJoinId(call->id());
9433 return ast_context()->ReturnValue(Pop()); 9378 return ast_context()->ReturnValue(Pop());
9434 } 9379 }
9435 9380
9436 9381
9437 // Fast call to math functions. 9382 // Fast call to math functions.
9438 void HOptimizedGraphBuilder::GenerateMathPow(CallRuntime* call) { 9383 void HGraphBuilder::GenerateMathPow(CallRuntime* call) {
9439 ASSERT_EQ(2, call->arguments()->length()); 9384 ASSERT_EQ(2, call->arguments()->length());
9440 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9385 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9441 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 9386 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
9442 HValue* right = Pop(); 9387 HValue* right = Pop();
9443 HValue* left = Pop(); 9388 HValue* left = Pop();
9444 HPower* result = new(zone()) HPower(left, right); 9389 HPower* result = new(zone()) HPower(left, right);
9445 return ast_context()->ReturnInstruction(result, call->id()); 9390 return ast_context()->ReturnInstruction(result, call->id());
9446 } 9391 }
9447 9392
9448 9393
9449 void HOptimizedGraphBuilder::GenerateMathSin(CallRuntime* call) { 9394 void HGraphBuilder::GenerateMathSin(CallRuntime* call) {
9450 ASSERT_EQ(1, call->arguments()->length()); 9395 ASSERT_EQ(1, call->arguments()->length());
9451 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9396 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9452 HValue* context = environment()->LookupContext(); 9397 HValue* context = environment()->LookupContext();
9453 HCallStub* result = 9398 HCallStub* result =
9454 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); 9399 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
9455 result->set_transcendental_type(TranscendentalCache::SIN); 9400 result->set_transcendental_type(TranscendentalCache::SIN);
9456 Drop(1); 9401 Drop(1);
9457 return ast_context()->ReturnInstruction(result, call->id()); 9402 return ast_context()->ReturnInstruction(result, call->id());
9458 } 9403 }
9459 9404
9460 9405
9461 void HOptimizedGraphBuilder::GenerateMathCos(CallRuntime* call) { 9406 void HGraphBuilder::GenerateMathCos(CallRuntime* call) {
9462 ASSERT_EQ(1, call->arguments()->length()); 9407 ASSERT_EQ(1, call->arguments()->length());
9463 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9408 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9464 HValue* context = environment()->LookupContext(); 9409 HValue* context = environment()->LookupContext();
9465 HCallStub* result = 9410 HCallStub* result =
9466 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); 9411 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
9467 result->set_transcendental_type(TranscendentalCache::COS); 9412 result->set_transcendental_type(TranscendentalCache::COS);
9468 Drop(1); 9413 Drop(1);
9469 return ast_context()->ReturnInstruction(result, call->id()); 9414 return ast_context()->ReturnInstruction(result, call->id());
9470 } 9415 }
9471 9416
9472 9417
9473 void HOptimizedGraphBuilder::GenerateMathTan(CallRuntime* call) { 9418 void HGraphBuilder::GenerateMathTan(CallRuntime* call) {
9474 ASSERT_EQ(1, call->arguments()->length()); 9419 ASSERT_EQ(1, call->arguments()->length());
9475 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9420 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9476 HValue* context = environment()->LookupContext(); 9421 HValue* context = environment()->LookupContext();
9477 HCallStub* result = 9422 HCallStub* result =
9478 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); 9423 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
9479 result->set_transcendental_type(TranscendentalCache::TAN); 9424 result->set_transcendental_type(TranscendentalCache::TAN);
9480 Drop(1); 9425 Drop(1);
9481 return ast_context()->ReturnInstruction(result, call->id()); 9426 return ast_context()->ReturnInstruction(result, call->id());
9482 } 9427 }
9483 9428
9484 9429
9485 void HOptimizedGraphBuilder::GenerateMathLog(CallRuntime* call) { 9430 void HGraphBuilder::GenerateMathLog(CallRuntime* call) {
9486 ASSERT_EQ(1, call->arguments()->length()); 9431 ASSERT_EQ(1, call->arguments()->length());
9487 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9432 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9488 HValue* context = environment()->LookupContext(); 9433 HValue* context = environment()->LookupContext();
9489 HCallStub* result = 9434 HCallStub* result =
9490 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); 9435 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
9491 result->set_transcendental_type(TranscendentalCache::LOG); 9436 result->set_transcendental_type(TranscendentalCache::LOG);
9492 Drop(1); 9437 Drop(1);
9493 return ast_context()->ReturnInstruction(result, call->id()); 9438 return ast_context()->ReturnInstruction(result, call->id());
9494 } 9439 }
9495 9440
9496 9441
9497 void HOptimizedGraphBuilder::GenerateMathSqrt(CallRuntime* call) { 9442 void HGraphBuilder::GenerateMathSqrt(CallRuntime* call) {
9498 return Bailout("inlined runtime function: MathSqrt"); 9443 return Bailout("inlined runtime function: MathSqrt");
9499 } 9444 }
9500 9445
9501 9446
9502 // Check whether two RegExps are equivalent 9447 // Check whether two RegExps are equivalent
9503 void HOptimizedGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) { 9448 void HGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) {
9504 return Bailout("inlined runtime function: IsRegExpEquivalent"); 9449 return Bailout("inlined runtime function: IsRegExpEquivalent");
9505 } 9450 }
9506 9451
9507 9452
9508 void HOptimizedGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) { 9453 void HGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) {
9509 ASSERT(call->arguments()->length() == 1); 9454 ASSERT(call->arguments()->length() == 1);
9510 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9455 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9511 HValue* value = Pop(); 9456 HValue* value = Pop();
9512 HGetCachedArrayIndex* result = new(zone()) HGetCachedArrayIndex(value); 9457 HGetCachedArrayIndex* result = new(zone()) HGetCachedArrayIndex(value);
9513 return ast_context()->ReturnInstruction(result, call->id()); 9458 return ast_context()->ReturnInstruction(result, call->id());
9514 } 9459 }
9515 9460
9516 9461
9517 void HOptimizedGraphBuilder::GenerateFastAsciiArrayJoin(CallRuntime* call) { 9462 void HGraphBuilder::GenerateFastAsciiArrayJoin(CallRuntime* call) {
9518 return Bailout("inlined runtime function: FastAsciiArrayJoin"); 9463 return Bailout("inlined runtime function: FastAsciiArrayJoin");
9519 } 9464 }
9520 9465
9521 9466
9522 #undef CHECK_BAILOUT 9467 #undef CHECK_BAILOUT
9523 #undef CHECK_ALIVE 9468 #undef CHECK_ALIVE
9524 9469
9525 9470
9526 HEnvironment::HEnvironment(HEnvironment* outer, 9471 HEnvironment::HEnvironment(HEnvironment* outer,
9527 Scope* scope, 9472 Scope* scope,
9528 Handle<JSFunction> closure, 9473 Handle<JSFunction> closure,
9529 Zone* zone) 9474 Zone* zone)
9530 : closure_(closure), 9475 : closure_(closure),
9531 values_(0, zone), 9476 values_(0, zone),
9532 assigned_variables_(4, zone), 9477 assigned_variables_(4, zone),
9533 frame_type_(JS_FUNCTION), 9478 frame_type_(JS_FUNCTION),
9534 parameter_count_(0), 9479 parameter_count_(0),
9535 specials_count_(1), 9480 specials_count_(1),
9536 local_count_(0), 9481 local_count_(0),
9537 outer_(outer), 9482 outer_(outer),
9538 entry_(NULL), 9483 entry_(NULL),
9539 pop_count_(0), 9484 pop_count_(0),
9540 push_count_(0), 9485 push_count_(0),
9541 ast_id_(BailoutId::None()), 9486 ast_id_(BailoutId::None()),
9542 zone_(zone) { 9487 zone_(zone) {
9543 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); 9488 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0);
9544 } 9489 }
9545 9490
9546 9491
9547 HEnvironment::HEnvironment(Zone* zone)
9548 : values_(0, zone),
9549 assigned_variables_(0, zone),
9550 frame_type_(STUB),
9551 parameter_count_(0),
9552 specials_count_(0),
9553 local_count_(0),
9554 outer_(NULL),
9555 entry_(NULL),
9556 pop_count_(0),
9557 push_count_(0),
9558 ast_id_(BailoutId::None()),
9559 zone_(zone) {
9560 Initialize(0, 0, 0);
9561 }
9562
9563
9564 HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) 9492 HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone)
9565 : values_(0, zone), 9493 : values_(0, zone),
9566 assigned_variables_(0, zone), 9494 assigned_variables_(0, zone),
9567 frame_type_(JS_FUNCTION), 9495 frame_type_(JS_FUNCTION),
9568 parameter_count_(0), 9496 parameter_count_(0),
9569 specials_count_(1), 9497 specials_count_(1),
9570 local_count_(0), 9498 local_count_(0),
9571 outer_(NULL), 9499 outer_(NULL),
9572 entry_(NULL), 9500 entry_(NULL),
9573 pop_count_(0), 9501 pop_count_(0),
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
9821 9749
9822 9750
9823 void HEnvironment::PrintToStd() { 9751 void HEnvironment::PrintToStd() {
9824 HeapStringAllocator string_allocator; 9752 HeapStringAllocator string_allocator;
9825 StringStream trace(&string_allocator); 9753 StringStream trace(&string_allocator);
9826 PrintTo(&trace); 9754 PrintTo(&trace);
9827 PrintF("%s", *trace.ToCString()); 9755 PrintF("%s", *trace.ToCString());
9828 } 9756 }
9829 9757
9830 9758
9831 void HTracer::TraceCompilation(CompilationInfo* info) { 9759 void HTracer::TraceCompilation(FunctionLiteral* function) {
9832 Tag tag(this, "compilation"); 9760 Tag tag(this, "compilation");
9833 if (info->IsOptimizing()) { 9761 Handle<String> name = function->debug_name();
9834 Handle<String> name = info->function()->debug_name(); 9762 PrintStringProperty("name", *name->ToCString());
9835 PrintStringProperty("name", *name->ToCString()); 9763 PrintStringProperty("method", *name->ToCString());
9836 PrintStringProperty("method", *name->ToCString());
9837 } else {
9838 CodeStub::Major major_key = info->code_stub()->MajorKey();
9839 PrintStringProperty("name", CodeStub::MajorName(major_key, false));
9840 PrintStringProperty("method", "stub");
9841 }
9842 PrintLongProperty("date", static_cast<int64_t>(OS::TimeCurrentMillis())); 9764 PrintLongProperty("date", static_cast<int64_t>(OS::TimeCurrentMillis()));
9843 } 9765 }
9844 9766
9845 9767
9846 void HTracer::TraceLithium(const char* name, LChunk* chunk) { 9768 void HTracer::TraceLithium(const char* name, LChunk* chunk) {
9847 Trace(name, chunk->graph(), chunk); 9769 Trace(name, chunk->graph(), chunk);
9848 } 9770 }
9849 9771
9850 9772
9851 void HTracer::TraceHydrogen(const char* name, HGraph* graph) { 9773 void HTracer::TraceHydrogen(const char* name, HGraph* graph) {
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
10160 } 10082 }
10161 } 10083 }
10162 10084
10163 #ifdef DEBUG 10085 #ifdef DEBUG
10164 if (graph_ != NULL) graph_->Verify(false); // No full verify. 10086 if (graph_ != NULL) graph_->Verify(false); // No full verify.
10165 if (allocator_ != NULL) allocator_->Verify(); 10087 if (allocator_ != NULL) allocator_->Verify();
10166 #endif 10088 #endif
10167 } 10089 }
10168 10090
10169 } } // namespace v8::internal 10091 } } // 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