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

Side by Side Diff: src/hydrogen.cc

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