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

Side by Side Diff: src/hydrogen.cc

Issue 20843012: Extract hardcoded error strings into a single place and replace them with enum. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: styles fixed Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 2560 matching lines...) Expand 10 before | Expand all | Expand 10 after
2571 2571
2572 void EffectContext::ReturnValue(HValue* value) { 2572 void EffectContext::ReturnValue(HValue* value) {
2573 // The value is simply ignored. 2573 // The value is simply ignored.
2574 } 2574 }
2575 2575
2576 2576
2577 void ValueContext::ReturnValue(HValue* value) { 2577 void ValueContext::ReturnValue(HValue* value) {
2578 // The value is tracked in the bailout environment, and communicated 2578 // The value is tracked in the bailout environment, and communicated
2579 // through the environment as the result of the expression. 2579 // through the environment as the result of the expression.
2580 if (!arguments_allowed() && value->CheckFlag(HValue::kIsArguments)) { 2580 if (!arguments_allowed() && value->CheckFlag(HValue::kIsArguments)) {
2581 owner()->Bailout("bad value context for arguments value"); 2581 owner()->Bailout(kBadValueContextForArgumentsValue);
2582 } 2582 }
2583 owner()->Push(value); 2583 owner()->Push(value);
2584 } 2584 }
2585 2585
2586 2586
2587 void TestContext::ReturnValue(HValue* value) { 2587 void TestContext::ReturnValue(HValue* value) {
2588 BuildBranch(value); 2588 BuildBranch(value);
2589 } 2589 }
2590 2590
2591 2591
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2623 } else { 2623 } else {
2624 HBasicBlock* join = owner()->CreateJoin(true_branch, false_branch, ast_id); 2624 HBasicBlock* join = owner()->CreateJoin(true_branch, false_branch, ast_id);
2625 owner()->set_current_block(join); 2625 owner()->set_current_block(join);
2626 } 2626 }
2627 } 2627 }
2628 2628
2629 2629
2630 void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 2630 void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
2631 ASSERT(!instr->IsControlInstruction()); 2631 ASSERT(!instr->IsControlInstruction());
2632 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { 2632 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) {
2633 return owner()->Bailout("bad value context for arguments object value"); 2633 return owner()->Bailout(kBadValueContextForArgumentsObjectValue);
2634 } 2634 }
2635 owner()->AddInstruction(instr); 2635 owner()->AddInstruction(instr);
2636 owner()->Push(instr); 2636 owner()->Push(instr);
2637 if (instr->HasObservableSideEffects()) { 2637 if (instr->HasObservableSideEffects()) {
2638 owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 2638 owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
2639 } 2639 }
2640 } 2640 }
2641 2641
2642 2642
2643 void ValueContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { 2643 void ValueContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) {
2644 ASSERT(!instr->HasObservableSideEffects()); 2644 ASSERT(!instr->HasObservableSideEffects());
2645 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { 2645 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) {
2646 return owner()->Bailout("bad value context for arguments object value"); 2646 return owner()->Bailout(kBadValueContextForArgumentsObjectValue);
2647 } 2647 }
2648 HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock(); 2648 HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock();
2649 HBasicBlock* materialize_true = owner()->graph()->CreateBasicBlock(); 2649 HBasicBlock* materialize_true = owner()->graph()->CreateBasicBlock();
2650 instr->SetSuccessorAt(0, materialize_true); 2650 instr->SetSuccessorAt(0, materialize_true);
2651 instr->SetSuccessorAt(1, materialize_false); 2651 instr->SetSuccessorAt(1, materialize_false);
2652 owner()->current_block()->Finish(instr); 2652 owner()->current_block()->Finish(instr);
2653 owner()->set_current_block(materialize_true); 2653 owner()->set_current_block(materialize_true);
2654 owner()->Push(owner()->graph()->GetConstantTrue()); 2654 owner()->Push(owner()->graph()->GetConstantTrue());
2655 owner()->set_current_block(materialize_false); 2655 owner()->set_current_block(materialize_false);
2656 owner()->Push(owner()->graph()->GetConstantFalse()); 2656 owner()->Push(owner()->graph()->GetConstantFalse());
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2726 } 2726 }
2727 2727
2728 2728
2729 void TestContext::BuildBranch(HValue* value) { 2729 void TestContext::BuildBranch(HValue* value) {
2730 // We expect the graph to be in edge-split form: there is no edge that 2730 // We expect the graph to be in edge-split form: there is no edge that
2731 // connects a branch node to a join node. We conservatively ensure that 2731 // connects a branch node to a join node. We conservatively ensure that
2732 // property by always adding an empty block on the outgoing edges of this 2732 // property by always adding an empty block on the outgoing edges of this
2733 // branch. 2733 // branch.
2734 HOptimizedGraphBuilder* builder = owner(); 2734 HOptimizedGraphBuilder* builder = owner();
2735 if (value != NULL && value->CheckFlag(HValue::kIsArguments)) { 2735 if (value != NULL && value->CheckFlag(HValue::kIsArguments)) {
2736 builder->Bailout("arguments object value in a test context"); 2736 builder->Bailout(kArgumentsObjectValueInATestContext);
2737 } 2737 }
2738 if (value->IsConstant()) { 2738 if (value->IsConstant()) {
2739 HConstant* constant_value = HConstant::cast(value); 2739 HConstant* constant_value = HConstant::cast(value);
2740 if (constant_value->BooleanValue()) { 2740 if (constant_value->BooleanValue()) {
2741 builder->current_block()->Goto(if_true(), builder->function_state()); 2741 builder->current_block()->Goto(if_true(), builder->function_state());
2742 } else { 2742 } else {
2743 builder->current_block()->Goto(if_false(), builder->function_state()); 2743 builder->current_block()->Goto(if_false(), builder->function_state());
2744 } 2744 }
2745 builder->set_current_block(NULL); 2745 builder->set_current_block(NULL);
2746 return; 2746 return;
(...skipping 25 matching lines...) Expand all
2772 } while (false) 2772 } while (false)
2773 2773
2774 2774
2775 #define CHECK_ALIVE_OR_RETURN(call, value) \ 2775 #define CHECK_ALIVE_OR_RETURN(call, value) \
2776 do { \ 2776 do { \
2777 call; \ 2777 call; \
2778 if (HasStackOverflow() || current_block() == NULL) return value; \ 2778 if (HasStackOverflow() || current_block() == NULL) return value; \
2779 } while (false) 2779 } while (false)
2780 2780
2781 2781
2782 void HOptimizedGraphBuilder::Bailout(const char* reason) { 2782 void HOptimizedGraphBuilder::Bailout(BailoutReason reason) {
2783 current_info()->set_bailout_reason(reason); 2783 current_info()->set_bailout_reason(reason);
2784 SetStackOverflow(); 2784 SetStackOverflow();
2785 } 2785 }
2786 2786
2787 2787
2788 void HOptimizedGraphBuilder::VisitForEffect(Expression* expr) { 2788 void HOptimizedGraphBuilder::VisitForEffect(Expression* expr) {
2789 EffectContext for_effect(this); 2789 EffectContext for_effect(this);
2790 Visit(expr); 2790 Visit(expr);
2791 } 2791 }
2792 2792
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2831 void HOptimizedGraphBuilder::VisitExpressions( 2831 void HOptimizedGraphBuilder::VisitExpressions(
2832 ZoneList<Expression*>* exprs) { 2832 ZoneList<Expression*>* exprs) {
2833 for (int i = 0; i < exprs->length(); ++i) { 2833 for (int i = 0; i < exprs->length(); ++i) {
2834 CHECK_ALIVE(VisitForValue(exprs->at(i))); 2834 CHECK_ALIVE(VisitForValue(exprs->at(i)));
2835 } 2835 }
2836 } 2836 }
2837 2837
2838 2838
2839 bool HOptimizedGraphBuilder::BuildGraph() { 2839 bool HOptimizedGraphBuilder::BuildGraph() {
2840 if (current_info()->function()->is_generator()) { 2840 if (current_info()->function()->is_generator()) {
2841 Bailout("function is a generator"); 2841 Bailout(kFunctionIsAGenerator);
2842 return false; 2842 return false;
2843 } 2843 }
2844 Scope* scope = current_info()->scope(); 2844 Scope* scope = current_info()->scope();
2845 if (scope->HasIllegalRedeclaration()) { 2845 if (scope->HasIllegalRedeclaration()) {
2846 Bailout("function with illegal redeclaration"); 2846 Bailout(kFunctionWithIllegalRedeclaration);
2847 return false; 2847 return false;
2848 } 2848 }
2849 if (scope->calls_eval()) { 2849 if (scope->calls_eval()) {
2850 Bailout("function calls eval"); 2850 Bailout(kFunctionCallsEval);
2851 return false; 2851 return false;
2852 } 2852 }
2853 SetUpScope(scope); 2853 SetUpScope(scope);
2854 2854
2855 // Add an edge to the body entry. This is warty: the graph's start 2855 // Add an edge to the body entry. This is warty: the graph's start
2856 // environment will be used by the Lithium translation as the initial 2856 // environment will be used by the Lithium translation as the initial
2857 // environment on graph entry, but it has now been mutated by the 2857 // environment on graph entry, but it has now been mutated by the
2858 // Hydrogen translation of the instructions in the start block. This 2858 // Hydrogen translation of the instructions in the start block. This
2859 // environment uses values which have not been defined yet. These 2859 // environment uses values which have not been defined yet. These
2860 // Hydrogen instructions will then be replayed by the Lithium 2860 // Hydrogen instructions will then be replayed by the Lithium
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2906 !type_info->matches_inlined_type_change_checksum(composite_checksum)); 2906 !type_info->matches_inlined_type_change_checksum(composite_checksum));
2907 type_info->set_inlined_type_change_checksum(composite_checksum); 2907 type_info->set_inlined_type_change_checksum(composite_checksum);
2908 2908
2909 // Perform any necessary OSR-specific cleanups or changes to the graph. 2909 // Perform any necessary OSR-specific cleanups or changes to the graph.
2910 osr_->FinishGraph(); 2910 osr_->FinishGraph();
2911 2911
2912 return true; 2912 return true;
2913 } 2913 }
2914 2914
2915 2915
2916 bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) { 2916 bool HGraph::Optimize(BailoutReason* bailout_reason) {
2917 *bailout_reason = SmartArrayPointer<char>();
2918 OrderBlocks(); 2917 OrderBlocks();
2919 AssignDominators(); 2918 AssignDominators();
2920 2919
2921 // We need to create a HConstant "zero" now so that GVN will fold every 2920 // We need to create a HConstant "zero" now so that GVN will fold every
2922 // zero-valued constant in the graph together. 2921 // zero-valued constant in the graph together.
2923 // The constant is needed to make idef-based bounds check work: the pass 2922 // The constant is needed to make idef-based bounds check work: the pass
2924 // evaluates relations with "zero" and that zero cannot be created after GVN. 2923 // evaluates relations with "zero" and that zero cannot be created after GVN.
2925 GetConstant0(); 2924 GetConstant0();
2926 2925
2927 #ifdef DEBUG 2926 #ifdef DEBUG
2928 // Do a full verify after building the graph and computing dominators. 2927 // Do a full verify after building the graph and computing dominators.
2929 Verify(true); 2928 Verify(true);
2930 #endif 2929 #endif
2931 2930
2932 if (FLAG_analyze_environment_liveness && maximum_environment_size() != 0) { 2931 if (FLAG_analyze_environment_liveness && maximum_environment_size() != 0) {
2933 Run<HEnvironmentLivenessAnalysisPhase>(); 2932 Run<HEnvironmentLivenessAnalysisPhase>();
2934 } 2933 }
2935 2934
2936 Run<HPropagateDeoptimizingMarkPhase>(); 2935 Run<HPropagateDeoptimizingMarkPhase>();
2937 if (!CheckConstPhiUses()) { 2936 if (!CheckConstPhiUses()) {
2938 *bailout_reason = SmartArrayPointer<char>(StrDup( 2937 *bailout_reason = kUnsupportedPhiUseOfConstVariable;
2939 "Unsupported phi use of const variable"));
2940 return false; 2938 return false;
2941 } 2939 }
2942 Run<HRedundantPhiEliminationPhase>(); 2940 Run<HRedundantPhiEliminationPhase>();
2943 if (!CheckArgumentsPhiUses()) { 2941 if (!CheckArgumentsPhiUses()) {
2944 *bailout_reason = SmartArrayPointer<char>(StrDup( 2942 *bailout_reason = kUnsupportedPhiUseOfArguments;
2945 "Unsupported phi use of arguments"));
2946 return false; 2943 return false;
2947 } 2944 }
2948 2945
2949 // Remove dead code and phis 2946 // Remove dead code and phis
2950 if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>(); 2947 if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>();
2951 CollectPhis(); 2948 CollectPhis();
2952 2949
2953 if (has_osr()) osr()->FinishOsrValues(); 2950 if (has_osr()) osr()->FinishOsrValues();
2954 2951
2955 Run<HInferRepresentationPhase>(); 2952 Run<HInferRepresentationPhase>();
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
3117 for (int i = environment()->parameter_count() + 1; 3114 for (int i = environment()->parameter_count() + 1;
3118 i < environment()->length(); 3115 i < environment()->length();
3119 ++i) { 3116 ++i) {
3120 environment()->Bind(i, undefined_constant); 3117 environment()->Bind(i, undefined_constant);
3121 } 3118 }
3122 3119
3123 // Handle the arguments and arguments shadow variables specially (they do 3120 // Handle the arguments and arguments shadow variables specially (they do
3124 // not have declarations). 3121 // not have declarations).
3125 if (scope->arguments() != NULL) { 3122 if (scope->arguments() != NULL) {
3126 if (!scope->arguments()->IsStackAllocated()) { 3123 if (!scope->arguments()->IsStackAllocated()) {
3127 return Bailout("context-allocated arguments"); 3124 return Bailout(kContextAllocatedArguments);
3128 } 3125 }
3129 3126
3130 environment()->Bind(scope->arguments(), 3127 environment()->Bind(scope->arguments(),
3131 graph()->GetArgumentsObject()); 3128 graph()->GetArgumentsObject());
3132 } 3129 }
3133 } 3130 }
3134 3131
3135 3132
3136 void HOptimizedGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) { 3133 void HOptimizedGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) {
3137 for (int i = 0; i < statements->length(); i++) { 3134 for (int i = 0; i < statements->length(); i++) {
3138 CHECK_ALIVE(Visit(statements->at(i))); 3135 CHECK_ALIVE(Visit(statements->at(i)));
3139 } 3136 }
3140 } 3137 }
3141 3138
3142 3139
3143 void HOptimizedGraphBuilder::VisitBlock(Block* stmt) { 3140 void HOptimizedGraphBuilder::VisitBlock(Block* stmt) {
3144 ASSERT(!HasStackOverflow()); 3141 ASSERT(!HasStackOverflow());
3145 ASSERT(current_block() != NULL); 3142 ASSERT(current_block() != NULL);
3146 ASSERT(current_block()->HasPredecessor()); 3143 ASSERT(current_block()->HasPredecessor());
3147 if (stmt->scope() != NULL) { 3144 if (stmt->scope() != NULL) {
3148 return Bailout("ScopedBlock"); 3145 return Bailout(kScopedBlock);
3149 } 3146 }
3150 BreakAndContinueInfo break_info(stmt); 3147 BreakAndContinueInfo break_info(stmt);
3151 { BreakAndContinueScope push(&break_info, this); 3148 { BreakAndContinueScope push(&break_info, this);
3152 CHECK_BAILOUT(VisitStatements(stmt->statements())); 3149 CHECK_BAILOUT(VisitStatements(stmt->statements()));
3153 } 3150 }
3154 HBasicBlock* break_block = break_info.break_block(); 3151 HBasicBlock* break_block = break_info.break_block();
3155 if (break_block != NULL) { 3152 if (break_block != NULL) {
3156 if (current_block() != NULL) current_block()->Goto(break_block); 3153 if (current_block() != NULL) current_block()->Goto(break_block);
3157 break_block->SetJoinId(stmt->ExitId()); 3154 break_block->SetJoinId(stmt->ExitId());
3158 set_current_block(break_block); 3155 set_current_block(break_block);
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
3350 } 3347 }
3351 } 3348 }
3352 set_current_block(NULL); 3349 set_current_block(NULL);
3353 } 3350 }
3354 3351
3355 3352
3356 void HOptimizedGraphBuilder::VisitWithStatement(WithStatement* stmt) { 3353 void HOptimizedGraphBuilder::VisitWithStatement(WithStatement* stmt) {
3357 ASSERT(!HasStackOverflow()); 3354 ASSERT(!HasStackOverflow());
3358 ASSERT(current_block() != NULL); 3355 ASSERT(current_block() != NULL);
3359 ASSERT(current_block()->HasPredecessor()); 3356 ASSERT(current_block()->HasPredecessor());
3360 return Bailout("WithStatement"); 3357 return Bailout(kWithStatement);
3361 } 3358 }
3362 3359
3363 3360
3364 void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { 3361 void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
3365 ASSERT(!HasStackOverflow()); 3362 ASSERT(!HasStackOverflow());
3366 ASSERT(current_block() != NULL); 3363 ASSERT(current_block() != NULL);
3367 ASSERT(current_block()->HasPredecessor()); 3364 ASSERT(current_block()->HasPredecessor());
3368 3365
3369 // We only optimize switch statements with smi-literal smi comparisons, 3366 // We only optimize switch statements with smi-literal smi comparisons,
3370 // with a bounded number of clauses. 3367 // with a bounded number of clauses.
3371 const int kCaseClauseLimit = 128; 3368 const int kCaseClauseLimit = 128;
3372 ZoneList<CaseClause*>* clauses = stmt->cases(); 3369 ZoneList<CaseClause*>* clauses = stmt->cases();
3373 int clause_count = clauses->length(); 3370 int clause_count = clauses->length();
3374 if (clause_count > kCaseClauseLimit) { 3371 if (clause_count > kCaseClauseLimit) {
3375 return Bailout("SwitchStatement: too many clauses"); 3372 return Bailout(kSwitchStatementTooManyClauses);
3376 } 3373 }
3377 3374
3378 ASSERT(stmt->switch_type() != SwitchStatement::UNKNOWN_SWITCH); 3375 ASSERT(stmt->switch_type() != SwitchStatement::UNKNOWN_SWITCH);
3379 if (stmt->switch_type() == SwitchStatement::GENERIC_SWITCH) { 3376 if (stmt->switch_type() == SwitchStatement::GENERIC_SWITCH) {
3380 return Bailout("SwitchStatement: mixed or non-literal switch labels"); 3377 return Bailout(kSwitchStatementMixedOrNonLiteralSwitchLabels);
3381 } 3378 }
3382 3379
3383 HValue* context = environment()->context(); 3380 HValue* context = environment()->context();
3384 3381
3385 CHECK_ALIVE(VisitForValue(stmt->tag())); 3382 CHECK_ALIVE(VisitForValue(stmt->tag()));
3386 Add<HSimulate>(stmt->EntryId()); 3383 Add<HSimulate>(stmt->EntryId());
3387 HValue* tag_value = Pop(); 3384 HValue* tag_value = Pop();
3388 HBasicBlock* first_test_block = current_block(); 3385 HBasicBlock* first_test_block = current_block();
3389 3386
3390 HUnaryControlInstruction* string_check = NULL; 3387 HUnaryControlInstruction* string_check = NULL;
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
3662 set_current_block(loop_exit); 3659 set_current_block(loop_exit);
3663 } 3660 }
3664 3661
3665 3662
3666 void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) { 3663 void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
3667 ASSERT(!HasStackOverflow()); 3664 ASSERT(!HasStackOverflow());
3668 ASSERT(current_block() != NULL); 3665 ASSERT(current_block() != NULL);
3669 ASSERT(current_block()->HasPredecessor()); 3666 ASSERT(current_block()->HasPredecessor());
3670 3667
3671 if (!FLAG_optimize_for_in) { 3668 if (!FLAG_optimize_for_in) {
3672 return Bailout("ForInStatement optimization is disabled"); 3669 return Bailout(kForInStatementOptimizationIsDisabled);
3673 } 3670 }
3674 3671
3675 if (stmt->for_in_type() != ForInStatement::FAST_FOR_IN) { 3672 if (stmt->for_in_type() != ForInStatement::FAST_FOR_IN) {
3676 return Bailout("ForInStatement is not fast case"); 3673 return Bailout(kForInStatementIsNotFastCase);
3677 } 3674 }
3678 3675
3679 if (!stmt->each()->IsVariableProxy() || 3676 if (!stmt->each()->IsVariableProxy() ||
3680 !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) { 3677 !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) {
3681 return Bailout("ForInStatement with non-local each variable"); 3678 return Bailout(kForInStatementWithNonLocalEachVariable);
3682 } 3679 }
3683 3680
3684 Variable* each_var = stmt->each()->AsVariableProxy()->var(); 3681 Variable* each_var = stmt->each()->AsVariableProxy()->var();
3685 3682
3686 CHECK_ALIVE(VisitForValue(stmt->enumerable())); 3683 CHECK_ALIVE(VisitForValue(stmt->enumerable()));
3687 HValue* enumerable = Top(); // Leave enumerable at the top. 3684 HValue* enumerable = Top(); // Leave enumerable at the top.
3688 3685
3689 HInstruction* map = Add<HForInPrepareMap>(enumerable); 3686 HInstruction* map = Add<HForInPrepareMap>(enumerable);
3690 Add<HSimulate>(stmt->PrepareId()); 3687 Add<HSimulate>(stmt->PrepareId());
3691 3688
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
3765 break_info.break_block()); 3762 break_info.break_block());
3766 3763
3767 set_current_block(loop_exit); 3764 set_current_block(loop_exit);
3768 } 3765 }
3769 3766
3770 3767
3771 void HOptimizedGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) { 3768 void HOptimizedGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) {
3772 ASSERT(!HasStackOverflow()); 3769 ASSERT(!HasStackOverflow());
3773 ASSERT(current_block() != NULL); 3770 ASSERT(current_block() != NULL);
3774 ASSERT(current_block()->HasPredecessor()); 3771 ASSERT(current_block()->HasPredecessor());
3775 return Bailout("ForOfStatement"); 3772 return Bailout(kForOfStatement);
3776 } 3773 }
3777 3774
3778 3775
3779 void HOptimizedGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { 3776 void HOptimizedGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
3780 ASSERT(!HasStackOverflow()); 3777 ASSERT(!HasStackOverflow());
3781 ASSERT(current_block() != NULL); 3778 ASSERT(current_block() != NULL);
3782 ASSERT(current_block()->HasPredecessor()); 3779 ASSERT(current_block()->HasPredecessor());
3783 return Bailout("TryCatchStatement"); 3780 return Bailout(kTryCatchStatement);
3784 } 3781 }
3785 3782
3786 3783
3787 void HOptimizedGraphBuilder::VisitTryFinallyStatement( 3784 void HOptimizedGraphBuilder::VisitTryFinallyStatement(
3788 TryFinallyStatement* stmt) { 3785 TryFinallyStatement* stmt) {
3789 ASSERT(!HasStackOverflow()); 3786 ASSERT(!HasStackOverflow());
3790 ASSERT(current_block() != NULL); 3787 ASSERT(current_block() != NULL);
3791 ASSERT(current_block()->HasPredecessor()); 3788 ASSERT(current_block()->HasPredecessor());
3792 return Bailout("TryFinallyStatement"); 3789 return Bailout(kTryFinallyStatement);
3793 } 3790 }
3794 3791
3795 3792
3796 void HOptimizedGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { 3793 void HOptimizedGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
3797 ASSERT(!HasStackOverflow()); 3794 ASSERT(!HasStackOverflow());
3798 ASSERT(current_block() != NULL); 3795 ASSERT(current_block() != NULL);
3799 ASSERT(current_block()->HasPredecessor()); 3796 ASSERT(current_block()->HasPredecessor());
3800 return Bailout("DebuggerStatement"); 3797 return Bailout(kDebuggerStatement);
3801 } 3798 }
3802 3799
3803 3800
3804 static Handle<SharedFunctionInfo> SearchSharedFunctionInfo( 3801 static Handle<SharedFunctionInfo> SearchSharedFunctionInfo(
3805 Code* unoptimized_code, FunctionLiteral* expr) { 3802 Code* unoptimized_code, FunctionLiteral* expr) {
3806 int start_position = expr->start_position(); 3803 int start_position = expr->start_position();
3807 for (RelocIterator it(unoptimized_code); !it.done(); it.next()) { 3804 for (RelocIterator it(unoptimized_code); !it.done(); it.next()) {
3808 RelocInfo* rinfo = it.rinfo(); 3805 RelocInfo* rinfo = it.rinfo();
3809 if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue; 3806 if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue;
3810 Object* obj = rinfo->target_object(); 3807 Object* obj = rinfo->target_object();
(...skipping 25 matching lines...) Expand all
3836 new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure()); 3833 new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure());
3837 return ast_context()->ReturnInstruction(instr, expr->id()); 3834 return ast_context()->ReturnInstruction(instr, expr->id());
3838 } 3835 }
3839 3836
3840 3837
3841 void HOptimizedGraphBuilder::VisitSharedFunctionInfoLiteral( 3838 void HOptimizedGraphBuilder::VisitSharedFunctionInfoLiteral(
3842 SharedFunctionInfoLiteral* expr) { 3839 SharedFunctionInfoLiteral* expr) {
3843 ASSERT(!HasStackOverflow()); 3840 ASSERT(!HasStackOverflow());
3844 ASSERT(current_block() != NULL); 3841 ASSERT(current_block() != NULL);
3845 ASSERT(current_block()->HasPredecessor()); 3842 ASSERT(current_block()->HasPredecessor());
3846 return Bailout("SharedFunctionInfoLiteral"); 3843 return Bailout(kSharedFunctionInfoLiteral);
3847 } 3844 }
3848 3845
3849 3846
3850 void HOptimizedGraphBuilder::VisitConditional(Conditional* expr) { 3847 void HOptimizedGraphBuilder::VisitConditional(Conditional* expr) {
3851 ASSERT(!HasStackOverflow()); 3848 ASSERT(!HasStackOverflow());
3852 ASSERT(current_block() != NULL); 3849 ASSERT(current_block() != NULL);
3853 ASSERT(current_block()->HasPredecessor()); 3850 ASSERT(current_block()->HasPredecessor());
3854 HBasicBlock* cond_true = graph()->CreateBasicBlock(); 3851 HBasicBlock* cond_true = graph()->CreateBasicBlock();
3855 HBasicBlock* cond_false = graph()->CreateBasicBlock(); 3852 HBasicBlock* cond_false = graph()->CreateBasicBlock();
3856 CHECK_BAILOUT(VisitForControl(expr->condition(), cond_true, cond_false)); 3853 CHECK_BAILOUT(VisitForControl(expr->condition(), cond_true, cond_false));
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
3916 3913
3917 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { 3914 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
3918 ASSERT(!HasStackOverflow()); 3915 ASSERT(!HasStackOverflow());
3919 ASSERT(current_block() != NULL); 3916 ASSERT(current_block() != NULL);
3920 ASSERT(current_block()->HasPredecessor()); 3917 ASSERT(current_block()->HasPredecessor());
3921 Variable* variable = expr->var(); 3918 Variable* variable = expr->var();
3922 switch (variable->location()) { 3919 switch (variable->location()) {
3923 case Variable::UNALLOCATED: { 3920 case Variable::UNALLOCATED: {
3924 if (IsLexicalVariableMode(variable->mode())) { 3921 if (IsLexicalVariableMode(variable->mode())) {
3925 // TODO(rossberg): should this be an ASSERT? 3922 // TODO(rossberg): should this be an ASSERT?
3926 return Bailout("reference to global lexical variable"); 3923 return Bailout(kReferenceToGlobalLexicalVariable);
3927 } 3924 }
3928 // Handle known global constants like 'undefined' specially to avoid a 3925 // Handle known global constants like 'undefined' specially to avoid a
3929 // load from a global cell for them. 3926 // load from a global cell for them.
3930 Handle<Object> constant_value = 3927 Handle<Object> constant_value =
3931 isolate()->factory()->GlobalConstantFor(variable->name()); 3928 isolate()->factory()->GlobalConstantFor(variable->name());
3932 if (!constant_value.is_null()) { 3929 if (!constant_value.is_null()) {
3933 HConstant* instr = New<HConstant>(constant_value); 3930 HConstant* instr = New<HConstant>(constant_value);
3934 return ast_context()->ReturnInstruction(instr, expr->id()); 3931 return ast_context()->ReturnInstruction(instr, expr->id());
3935 } 3932 }
3936 3933
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3973 return ast_context()->ReturnInstruction(instr, expr->id()); 3970 return ast_context()->ReturnInstruction(instr, expr->id());
3974 } 3971 }
3975 } 3972 }
3976 3973
3977 case Variable::PARAMETER: 3974 case Variable::PARAMETER:
3978 case Variable::LOCAL: { 3975 case Variable::LOCAL: {
3979 HValue* value = LookupAndMakeLive(variable); 3976 HValue* value = LookupAndMakeLive(variable);
3980 if (value == graph()->GetConstantHole()) { 3977 if (value == graph()->GetConstantHole()) {
3981 ASSERT(IsDeclaredVariableMode(variable->mode()) && 3978 ASSERT(IsDeclaredVariableMode(variable->mode()) &&
3982 variable->mode() != VAR); 3979 variable->mode() != VAR);
3983 return Bailout("reference to uninitialized variable"); 3980 return Bailout(kReferenceToUninitializedVariable);
3984 } 3981 }
3985 return ast_context()->ReturnValue(value); 3982 return ast_context()->ReturnValue(value);
3986 } 3983 }
3987 3984
3988 case Variable::CONTEXT: { 3985 case Variable::CONTEXT: {
3989 HValue* context = BuildContextChainWalk(variable); 3986 HValue* context = BuildContextChainWalk(variable);
3990 HLoadContextSlot* instr = new(zone()) HLoadContextSlot(context, variable); 3987 HLoadContextSlot* instr = new(zone()) HLoadContextSlot(context, variable);
3991 return ast_context()->ReturnInstruction(instr, expr->id()); 3988 return ast_context()->ReturnInstruction(instr, expr->id());
3992 } 3989 }
3993 3990
3994 case Variable::LOOKUP: 3991 case Variable::LOOKUP:
3995 return Bailout("reference to a variable which requires dynamic lookup"); 3992 return Bailout(kReferenceToAVariableWhichRequiresDynamicLookup);
3996 } 3993 }
3997 } 3994 }
3998 3995
3999 3996
4000 void HOptimizedGraphBuilder::VisitLiteral(Literal* expr) { 3997 void HOptimizedGraphBuilder::VisitLiteral(Literal* expr) {
4001 ASSERT(!HasStackOverflow()); 3998 ASSERT(!HasStackOverflow());
4002 ASSERT(current_block() != NULL); 3999 ASSERT(current_block() != NULL);
4003 ASSERT(current_block()->HasPredecessor()); 4000 ASSERT(current_block()->HasPredecessor());
4004 HConstant* instr = New<HConstant>(expr->value()); 4001 HConstant* instr = New<HConstant>(expr->value());
4005 return ast_context()->ReturnInstruction(instr, expr->id()); 4002 return ast_context()->ReturnInstruction(instr, expr->id());
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
4284 } 4281 }
4285 } else { 4282 } else {
4286 CHECK_ALIVE(VisitForEffect(value)); 4283 CHECK_ALIVE(VisitForEffect(value));
4287 } 4284 }
4288 break; 4285 break;
4289 } 4286 }
4290 // Fall through. 4287 // Fall through.
4291 case ObjectLiteral::Property::PROTOTYPE: 4288 case ObjectLiteral::Property::PROTOTYPE:
4292 case ObjectLiteral::Property::SETTER: 4289 case ObjectLiteral::Property::SETTER:
4293 case ObjectLiteral::Property::GETTER: 4290 case ObjectLiteral::Property::GETTER:
4294 return Bailout("Object literal with complex property"); 4291 return Bailout(kObjectLiteralWithComplexProperty);
4295 default: UNREACHABLE(); 4292 default: UNREACHABLE();
4296 } 4293 }
4297 } 4294 }
4298 4295
4299 if (expr->has_function()) { 4296 if (expr->has_function()) {
4300 // Return the result of the transformation to fast properties 4297 // Return the result of the transformation to fast properties
4301 // instead of the original since this operation changes the map 4298 // instead of the original since this operation changes the map
4302 // of the object. This makes sure that the original object won't 4299 // of the object. This makes sure that the original object won't
4303 // be used by other optimized code before it is transformed 4300 // be used by other optimized code before it is transformed
4304 // (e.g. because of code motion). 4301 // (e.g. because of code motion).
(...skipping 18 matching lines...) Expand all
4323 Handle<FixedArray> literals(environment()->closure()->literals(), isolate()); 4320 Handle<FixedArray> literals(environment()->closure()->literals(), isolate());
4324 bool uninitialized = false; 4321 bool uninitialized = false;
4325 Handle<Object> literals_cell(literals->get(expr->literal_index()), 4322 Handle<Object> literals_cell(literals->get(expr->literal_index()),
4326 isolate()); 4323 isolate());
4327 Handle<Object> raw_boilerplate; 4324 Handle<Object> raw_boilerplate;
4328 if (literals_cell->IsUndefined()) { 4325 if (literals_cell->IsUndefined()) {
4329 uninitialized = true; 4326 uninitialized = true;
4330 raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate( 4327 raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate(
4331 isolate(), literals, expr->constant_elements()); 4328 isolate(), literals, expr->constant_elements());
4332 if (raw_boilerplate.is_null()) { 4329 if (raw_boilerplate.is_null()) {
4333 return Bailout("array boilerplate creation failed"); 4330 return Bailout(kArrayBoilerplateCreationFailed);
4334 } 4331 }
4335 4332
4336 site = isolate()->factory()->NewAllocationSite(); 4333 site = isolate()->factory()->NewAllocationSite();
4337 site->set_transition_info(*raw_boilerplate); 4334 site->set_transition_info(*raw_boilerplate);
4338 literals->set(expr->literal_index(), *site); 4335 literals->set(expr->literal_index(), *site);
4339 4336
4340 if (JSObject::cast(*raw_boilerplate)->elements()->map() == 4337 if (JSObject::cast(*raw_boilerplate)->elements()->map() ==
4341 isolate()->heap()->fixed_cow_array_map()) { 4338 isolate()->heap()->fixed_cow_array_map()) {
4342 isolate()->counters()->cow_arrays_created_runtime()->Increment(); 4339 isolate()->counters()->cow_arrays_created_runtime()->Increment();
4343 } 4340 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
4414 HInstruction* elements = NULL; 4411 HInstruction* elements = NULL;
4415 4412
4416 for (int i = 0; i < length; i++) { 4413 for (int i = 0; i < length; i++) {
4417 Expression* subexpr = subexprs->at(i); 4414 Expression* subexpr = subexprs->at(i);
4418 // If the subexpression is a literal or a simple materialized literal it 4415 // If the subexpression is a literal or a simple materialized literal it
4419 // is already set in the cloned array. 4416 // is already set in the cloned array.
4420 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 4417 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
4421 4418
4422 CHECK_ALIVE(VisitForValue(subexpr)); 4419 CHECK_ALIVE(VisitForValue(subexpr));
4423 HValue* value = Pop(); 4420 HValue* value = Pop();
4424 if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal"); 4421 if (!Smi::IsValid(i)) return Bailout(kNonSmiKeyInArrayLiteral);
4425 4422
4426 elements = AddLoadElements(literal); 4423 elements = AddLoadElements(literal);
4427 4424
4428 HValue* key = Add<HConstant>(i); 4425 HValue* key = Add<HConstant>(i);
4429 4426
4430 switch (boilerplate_elements_kind) { 4427 switch (boilerplate_elements_kind) {
4431 case FAST_SMI_ELEMENTS: 4428 case FAST_SMI_ELEMENTS:
4432 case FAST_HOLEY_SMI_ELEMENTS: 4429 case FAST_HOLEY_SMI_ELEMENTS:
4433 case FAST_ELEMENTS: 4430 case FAST_ELEMENTS:
4434 case FAST_HOLEY_ELEMENTS: 4431 case FAST_HOLEY_ELEMENTS:
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
4494 // readonly or turned into a setter by some meanwhile modifications on the 4491 // readonly or turned into a setter by some meanwhile modifications on the
4495 // prototype chain. 4492 // prototype chain.
4496 if (!lookup->IsProperty() && map->prototype()->IsJSReceiver()) { 4493 if (!lookup->IsProperty() && map->prototype()->IsJSReceiver()) {
4497 Object* proto = map->prototype(); 4494 Object* proto = map->prototype();
4498 // First check that the prototype chain isn't affected already. 4495 // First check that the prototype chain isn't affected already.
4499 LookupResult proto_result(isolate()); 4496 LookupResult proto_result(isolate());
4500 proto->Lookup(*name, &proto_result); 4497 proto->Lookup(*name, &proto_result);
4501 if (proto_result.IsProperty()) { 4498 if (proto_result.IsProperty()) {
4502 // If the inherited property could induce readonly-ness, bail out. 4499 // If the inherited property could induce readonly-ness, bail out.
4503 if (proto_result.IsReadOnly() || !proto_result.IsCacheable()) { 4500 if (proto_result.IsReadOnly() || !proto_result.IsCacheable()) {
4504 Bailout("improper object on prototype chain for store"); 4501 Bailout(kImproperObjectOnPrototypeChainForStore);
4505 return NULL; 4502 return NULL;
4506 } 4503 }
4507 // We only need to check up to the preexisting property. 4504 // We only need to check up to the preexisting property.
4508 proto = proto_result.holder(); 4505 proto = proto_result.holder();
4509 } else { 4506 } else {
4510 // Otherwise, find the top prototype. 4507 // Otherwise, find the top prototype.
4511 while (proto->GetPrototype(isolate())->IsJSObject()) { 4508 while (proto->GetPrototype(isolate())->IsJSObject()) {
4512 proto = proto->GetPrototype(isolate()); 4509 proto = proto->GetPrototype(isolate());
4513 } 4510 }
4514 ASSERT(proto->GetPrototype(isolate())->IsNull()); 4511 ASSERT(proto->GetPrototype(isolate())->IsNull());
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
4998 Property* prop = target->AsProperty(); 4995 Property* prop = target->AsProperty();
4999 ASSERT(proxy == NULL || prop == NULL); 4996 ASSERT(proxy == NULL || prop == NULL);
5000 4997
5001 // We have a second position recorded in the FullCodeGenerator to have 4998 // We have a second position recorded in the FullCodeGenerator to have
5002 // type feedback for the binary operation. 4999 // type feedback for the binary operation.
5003 BinaryOperation* operation = expr->binary_operation(); 5000 BinaryOperation* operation = expr->binary_operation();
5004 5001
5005 if (proxy != NULL) { 5002 if (proxy != NULL) {
5006 Variable* var = proxy->var(); 5003 Variable* var = proxy->var();
5007 if (var->mode() == LET) { 5004 if (var->mode() == LET) {
5008 return Bailout("unsupported let compound assignment"); 5005 return Bailout(kUnsupportedLetCompoundAssignment);
5009 } 5006 }
5010 5007
5011 CHECK_ALIVE(VisitForValue(operation)); 5008 CHECK_ALIVE(VisitForValue(operation));
5012 5009
5013 switch (var->location()) { 5010 switch (var->location()) {
5014 case Variable::UNALLOCATED: 5011 case Variable::UNALLOCATED:
5015 HandleGlobalVariableAssignment(var, 5012 HandleGlobalVariableAssignment(var,
5016 Top(), 5013 Top(),
5017 expr->position(), 5014 expr->position(),
5018 expr->AssignmentId()); 5015 expr->AssignmentId());
5019 break; 5016 break;
5020 5017
5021 case Variable::PARAMETER: 5018 case Variable::PARAMETER:
5022 case Variable::LOCAL: 5019 case Variable::LOCAL:
5023 if (var->mode() == CONST) { 5020 if (var->mode() == CONST) {
5024 return Bailout("unsupported const compound assignment"); 5021 return Bailout(kUnsupportedConstCompoundAssignment);
5025 } 5022 }
5026 BindIfLive(var, Top()); 5023 BindIfLive(var, Top());
5027 break; 5024 break;
5028 5025
5029 case Variable::CONTEXT: { 5026 case Variable::CONTEXT: {
5030 // Bail out if we try to mutate a parameter value in a function 5027 // Bail out if we try to mutate a parameter value in a function
5031 // using the arguments object. We do not (yet) correctly handle the 5028 // using the arguments object. We do not (yet) correctly handle the
5032 // arguments property of the function. 5029 // arguments property of the function.
5033 if (current_info()->scope()->arguments() != NULL) { 5030 if (current_info()->scope()->arguments() != NULL) {
5034 // Parameters will be allocated to context slots. We have no 5031 // Parameters will be allocated to context slots. We have no
5035 // direct way to detect that the variable is a parameter so we do 5032 // direct way to detect that the variable is a parameter so we do
5036 // a linear search of the parameter variables. 5033 // a linear search of the parameter variables.
5037 int count = current_info()->scope()->num_parameters(); 5034 int count = current_info()->scope()->num_parameters();
5038 for (int i = 0; i < count; ++i) { 5035 for (int i = 0; i < count; ++i) {
5039 if (var == current_info()->scope()->parameter(i)) { 5036 if (var == current_info()->scope()->parameter(i)) {
5040 Bailout( 5037 Bailout(kAssignmentToParameterFunctionUsesArgumentsObject);
5041 "assignment to parameter, function uses arguments object");
5042 } 5038 }
5043 } 5039 }
5044 } 5040 }
5045 5041
5046 HStoreContextSlot::Mode mode; 5042 HStoreContextSlot::Mode mode;
5047 5043
5048 switch (var->mode()) { 5044 switch (var->mode()) {
5049 case LET: 5045 case LET:
5050 mode = HStoreContextSlot::kCheckDeoptimize; 5046 mode = HStoreContextSlot::kCheckDeoptimize;
5051 break; 5047 break;
(...skipping 10 matching lines...) Expand all
5062 HValue* context = BuildContextChainWalk(var); 5058 HValue* context = BuildContextChainWalk(var);
5063 HStoreContextSlot* instr = Add<HStoreContextSlot>( 5059 HStoreContextSlot* instr = Add<HStoreContextSlot>(
5064 context, var->index(), mode, Top()); 5060 context, var->index(), mode, Top());
5065 if (instr->HasObservableSideEffects()) { 5061 if (instr->HasObservableSideEffects()) {
5066 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 5062 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
5067 } 5063 }
5068 break; 5064 break;
5069 } 5065 }
5070 5066
5071 case Variable::LOOKUP: 5067 case Variable::LOOKUP:
5072 return Bailout("compound assignment to lookup slot"); 5068 return Bailout(kCompoundAssignmentToLookupSlot);
5073 } 5069 }
5074 return ast_context()->ReturnValue(Pop()); 5070 return ast_context()->ReturnValue(Pop());
5075 5071
5076 } else if (prop != NULL) { 5072 } else if (prop != NULL) {
5077 if (prop->key()->IsPropertyName()) { 5073 if (prop->key()->IsPropertyName()) {
5078 // Named property. 5074 // Named property.
5079 CHECK_ALIVE(VisitForValue(prop->obj())); 5075 CHECK_ALIVE(VisitForValue(prop->obj()));
5080 HValue* object = Top(); 5076 HValue* object = Top();
5081 5077
5082 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 5078 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
5151 5147
5152 // Drop the simulated receiver, key, and value. Return the value. 5148 // Drop the simulated receiver, key, and value. Return the value.
5153 Drop(3); 5149 Drop(3);
5154 Push(instr); 5150 Push(instr);
5155 ASSERT(has_side_effects); // Stores always have side effects. 5151 ASSERT(has_side_effects); // Stores always have side effects.
5156 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 5152 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
5157 return ast_context()->ReturnValue(Pop()); 5153 return ast_context()->ReturnValue(Pop());
5158 } 5154 }
5159 5155
5160 } else { 5156 } else {
5161 return Bailout("invalid lhs in compound assignment"); 5157 return Bailout(kInvalidLhsInCompoundAssignment);
5162 } 5158 }
5163 } 5159 }
5164 5160
5165 5161
5166 void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { 5162 void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) {
5167 ASSERT(!HasStackOverflow()); 5163 ASSERT(!HasStackOverflow());
5168 ASSERT(current_block() != NULL); 5164 ASSERT(current_block() != NULL);
5169 ASSERT(current_block()->HasPredecessor()); 5165 ASSERT(current_block()->HasPredecessor());
5170 VariableProxy* proxy = expr->target()->AsVariableProxy(); 5166 VariableProxy* proxy = expr->target()->AsVariableProxy();
5171 Property* prop = expr->target()->AsProperty(); 5167 Property* prop = expr->target()->AsProperty();
(...skipping 16 matching lines...) Expand all
5188 } 5184 }
5189 5185
5190 if (var->IsStackAllocated()) { 5186 if (var->IsStackAllocated()) {
5191 // We insert a use of the old value to detect unsupported uses of const 5187 // We insert a use of the old value to detect unsupported uses of const
5192 // variables (e.g. initialization inside a loop). 5188 // variables (e.g. initialization inside a loop).
5193 HValue* old_value = environment()->Lookup(var); 5189 HValue* old_value = environment()->Lookup(var);
5194 Add<HUseConst>(old_value); 5190 Add<HUseConst>(old_value);
5195 } 5191 }
5196 } else if (var->mode() == CONST_HARMONY) { 5192 } else if (var->mode() == CONST_HARMONY) {
5197 if (expr->op() != Token::INIT_CONST_HARMONY) { 5193 if (expr->op() != Token::INIT_CONST_HARMONY) {
5198 return Bailout("non-initializer assignment to const"); 5194 return Bailout(kNonInitializerAssignmentToConst);
5199 } 5195 }
5200 } 5196 }
5201 5197
5202 if (proxy->IsArguments()) return Bailout("assignment to arguments"); 5198 if (proxy->IsArguments()) return Bailout(kAssignmentToArguments);
5203 5199
5204 // Handle the assignment. 5200 // Handle the assignment.
5205 switch (var->location()) { 5201 switch (var->location()) {
5206 case Variable::UNALLOCATED: 5202 case Variable::UNALLOCATED:
5207 CHECK_ALIVE(VisitForValue(expr->value())); 5203 CHECK_ALIVE(VisitForValue(expr->value()));
5208 HandleGlobalVariableAssignment(var, 5204 HandleGlobalVariableAssignment(var,
5209 Top(), 5205 Top(),
5210 expr->position(), 5206 expr->position(),
5211 expr->AssignmentId()); 5207 expr->AssignmentId());
5212 return ast_context()->ReturnValue(Pop()); 5208 return ast_context()->ReturnValue(Pop());
5213 5209
5214 case Variable::PARAMETER: 5210 case Variable::PARAMETER:
5215 case Variable::LOCAL: { 5211 case Variable::LOCAL: {
5216 // Perform an initialization check for let declared variables 5212 // Perform an initialization check for let declared variables
5217 // or parameters. 5213 // or parameters.
5218 if (var->mode() == LET && expr->op() == Token::ASSIGN) { 5214 if (var->mode() == LET && expr->op() == Token::ASSIGN) {
5219 HValue* env_value = environment()->Lookup(var); 5215 HValue* env_value = environment()->Lookup(var);
5220 if (env_value == graph()->GetConstantHole()) { 5216 if (env_value == graph()->GetConstantHole()) {
5221 return Bailout("assignment to let variable before initialization"); 5217 return Bailout(kAssignmentToLetVariableBeforeInitialization);
5222 } 5218 }
5223 } 5219 }
5224 // We do not allow the arguments object to occur in a context where it 5220 // We do not allow the arguments object to occur in a context where it
5225 // may escape, but assignments to stack-allocated locals are 5221 // may escape, but assignments to stack-allocated locals are
5226 // permitted. 5222 // permitted.
5227 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); 5223 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED));
5228 HValue* value = Pop(); 5224 HValue* value = Pop();
5229 BindIfLive(var, value); 5225 BindIfLive(var, value);
5230 return ast_context()->ReturnValue(value); 5226 return ast_context()->ReturnValue(value);
5231 } 5227 }
5232 5228
5233 case Variable::CONTEXT: { 5229 case Variable::CONTEXT: {
5234 // Bail out if we try to mutate a parameter value in a function using 5230 // Bail out if we try to mutate a parameter value in a function using
5235 // the arguments object. We do not (yet) correctly handle the 5231 // the arguments object. We do not (yet) correctly handle the
5236 // arguments property of the function. 5232 // arguments property of the function.
5237 if (current_info()->scope()->arguments() != NULL) { 5233 if (current_info()->scope()->arguments() != NULL) {
5238 // Parameters will rewrite to context slots. We have no direct way 5234 // Parameters will rewrite to context slots. We have no direct way
5239 // to detect that the variable is a parameter. 5235 // to detect that the variable is a parameter.
5240 int count = current_info()->scope()->num_parameters(); 5236 int count = current_info()->scope()->num_parameters();
5241 for (int i = 0; i < count; ++i) { 5237 for (int i = 0; i < count; ++i) {
5242 if (var == current_info()->scope()->parameter(i)) { 5238 if (var == current_info()->scope()->parameter(i)) {
5243 return Bailout("assignment to parameter in arguments object"); 5239 return Bailout(kAssignmentToParameterInArgumentsObject);
5244 } 5240 }
5245 } 5241 }
5246 } 5242 }
5247 5243
5248 CHECK_ALIVE(VisitForValue(expr->value())); 5244 CHECK_ALIVE(VisitForValue(expr->value()));
5249 HStoreContextSlot::Mode mode; 5245 HStoreContextSlot::Mode mode;
5250 if (expr->op() == Token::ASSIGN) { 5246 if (expr->op() == Token::ASSIGN) {
5251 switch (var->mode()) { 5247 switch (var->mode()) {
5252 case LET: 5248 case LET:
5253 mode = HStoreContextSlot::kCheckDeoptimize; 5249 mode = HStoreContextSlot::kCheckDeoptimize;
(...skipping 20 matching lines...) Expand all
5274 HValue* context = BuildContextChainWalk(var); 5270 HValue* context = BuildContextChainWalk(var);
5275 HStoreContextSlot* instr = Add<HStoreContextSlot>( 5271 HStoreContextSlot* instr = Add<HStoreContextSlot>(
5276 context, var->index(), mode, Top()); 5272 context, var->index(), mode, Top());
5277 if (instr->HasObservableSideEffects()) { 5273 if (instr->HasObservableSideEffects()) {
5278 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 5274 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
5279 } 5275 }
5280 return ast_context()->ReturnValue(Pop()); 5276 return ast_context()->ReturnValue(Pop());
5281 } 5277 }
5282 5278
5283 case Variable::LOOKUP: 5279 case Variable::LOOKUP:
5284 return Bailout("assignment to LOOKUP variable"); 5280 return Bailout(kAssignmentToLOOKUPVariable);
5285 } 5281 }
5286 } else { 5282 } else {
5287 return Bailout("invalid left-hand side in assignment"); 5283 return Bailout(kInvalidLeftHandSideInAssignment);
5288 } 5284 }
5289 } 5285 }
5290 5286
5291 5287
5292 void HOptimizedGraphBuilder::VisitYield(Yield* expr) { 5288 void HOptimizedGraphBuilder::VisitYield(Yield* expr) {
5293 // Generators are not optimized, so we should never get here. 5289 // Generators are not optimized, so we should never get here.
5294 UNREACHABLE(); 5290 UNREACHABLE();
5295 } 5291 }
5296 5292
5297 5293
(...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after
6269 return false; 6265 return false;
6270 } 6266 }
6271 6267
6272 // Parse and allocate variables. 6268 // Parse and allocate variables.
6273 CompilationInfo target_info(target, zone()); 6269 CompilationInfo target_info(target, zone());
6274 Handle<SharedFunctionInfo> target_shared(target->shared()); 6270 Handle<SharedFunctionInfo> target_shared(target->shared());
6275 if (!Parser::Parse(&target_info) || !Scope::Analyze(&target_info)) { 6271 if (!Parser::Parse(&target_info) || !Scope::Analyze(&target_info)) {
6276 if (target_info.isolate()->has_pending_exception()) { 6272 if (target_info.isolate()->has_pending_exception()) {
6277 // Parse or scope error, never optimize this function. 6273 // Parse or scope error, never optimize this function.
6278 SetStackOverflow(); 6274 SetStackOverflow();
6279 target_shared->DisableOptimization("parse/scope error"); 6275 target_shared->DisableOptimization(kParseScopeError);
6280 } 6276 }
6281 TraceInline(target, caller, "parse failure"); 6277 TraceInline(target, caller, "parse failure");
6282 return false; 6278 return false;
6283 } 6279 }
6284 6280
6285 if (target_info.scope()->num_heap_slots() > 0) { 6281 if (target_info.scope()->num_heap_slots() > 0) {
6286 TraceInline(target, caller, "target has context-allocated variables"); 6282 TraceInline(target, caller, "target has context-allocated variables");
6287 return false; 6283 return false;
6288 } 6284 }
6289 FunctionLiteral* function = target_info.function(); 6285 FunctionLiteral* function = target_info.function();
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
6408 function->scope()->arguments(), 6404 function->scope()->arguments(),
6409 arguments_object, undefined_receiver); 6405 arguments_object, undefined_receiver);
6410 function_state()->set_entry(enter_inlined); 6406 function_state()->set_entry(enter_inlined);
6411 6407
6412 VisitDeclarations(target_info.scope()->declarations()); 6408 VisitDeclarations(target_info.scope()->declarations());
6413 VisitStatements(function->body()); 6409 VisitStatements(function->body());
6414 if (HasStackOverflow()) { 6410 if (HasStackOverflow()) {
6415 // Bail out if the inline function did, as we cannot residualize a call 6411 // Bail out if the inline function did, as we cannot residualize a call
6416 // instead. 6412 // instead.
6417 TraceInline(target, caller, "inline graph construction failed"); 6413 TraceInline(target, caller, "inline graph construction failed");
6418 target_shared->DisableOptimization("inlining bailed out"); 6414 target_shared->DisableOptimization(kInliningBailedOut);
6419 inline_bailout_ = true; 6415 inline_bailout_ = true;
6420 delete target_state; 6416 delete target_state;
6421 return true; 6417 return true;
6422 } 6418 }
6423 6419
6424 // Update inlined nodes count. 6420 // Update inlined nodes count.
6425 inlined_count_ += nodes_added; 6421 inlined_count_ += nodes_added;
6426 6422
6427 Handle<Code> unoptimized_code(target_shared->code()); 6423 Handle<Code> unoptimized_code(target_shared->code());
6428 ASSERT(unoptimized_code->kind() == Code::FUNCTION); 6424 ASSERT(unoptimized_code->kind() == Code::FUNCTION);
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
6953 6949
6954 } else { 6950 } else {
6955 HValue* context = environment()->context(); 6951 HValue* context = environment()->context();
6956 call = PreProcessCall( 6952 call = PreProcessCall(
6957 new(zone()) HCallNamed(context, name, argument_count)); 6953 new(zone()) HCallNamed(context, name, argument_count));
6958 } 6954 }
6959 6955
6960 } else { 6956 } else {
6961 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 6957 VariableProxy* proxy = expr->expression()->AsVariableProxy();
6962 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { 6958 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) {
6963 return Bailout("possible direct call to eval"); 6959 return Bailout(kPossibleDirectCallToEval);
6964 } 6960 }
6965 6961
6966 bool global_call = proxy != NULL && proxy->var()->IsUnallocated(); 6962 bool global_call = proxy != NULL && proxy->var()->IsUnallocated();
6967 if (global_call) { 6963 if (global_call) {
6968 Variable* var = proxy->var(); 6964 Variable* var = proxy->var();
6969 bool known_global_function = false; 6965 bool known_global_function = false;
6970 // If there is a global property cell for the name at compile time and 6966 // If there is a global property cell for the name at compile time and
6971 // access check is not enabled we assume that the function will not change 6967 // access check is not enabled we assume that the function will not change
6972 // and generate optimized code for calling the function. 6968 // and generate optimized code for calling the function.
6973 LookupResult lookup(isolate()); 6969 LookupResult lookup(isolate());
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
7221 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) 7217 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
7222 }; 7218 };
7223 #undef INLINE_FUNCTION_GENERATOR_ADDRESS 7219 #undef INLINE_FUNCTION_GENERATOR_ADDRESS
7224 7220
7225 7221
7226 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { 7222 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
7227 ASSERT(!HasStackOverflow()); 7223 ASSERT(!HasStackOverflow());
7228 ASSERT(current_block() != NULL); 7224 ASSERT(current_block() != NULL);
7229 ASSERT(current_block()->HasPredecessor()); 7225 ASSERT(current_block()->HasPredecessor());
7230 if (expr->is_jsruntime()) { 7226 if (expr->is_jsruntime()) {
7231 return Bailout("call to a JavaScript runtime function"); 7227 return Bailout(kCallToAJavaScriptRuntimeFunction);
7232 } 7228 }
7233 7229
7234 const Runtime::Function* function = expr->function(); 7230 const Runtime::Function* function = expr->function();
7235 ASSERT(function != NULL); 7231 ASSERT(function != NULL);
7236 if (function->intrinsic_type == Runtime::INLINE) { 7232 if (function->intrinsic_type == Runtime::INLINE) {
7237 ASSERT(expr->name()->length() > 0); 7233 ASSERT(expr->name()->length() > 0);
7238 ASSERT(expr->name()->Get(0) == '_'); 7234 ASSERT(expr->name()->Get(0) == '_');
7239 // Call to an inline function. 7235 // Call to an inline function.
7240 int lookup_index = static_cast<int>(function->function_id) - 7236 int lookup_index = static_cast<int>(function->function_id) -
7241 static_cast<int>(Runtime::kFirstInlineFunction); 7237 static_cast<int>(Runtime::kFirstInlineFunction);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
7288 Add<HPushArgument>(obj); 7284 Add<HPushArgument>(obj);
7289 Add<HPushArgument>(key); 7285 Add<HPushArgument>(key);
7290 Add<HPushArgument>(Add<HConstant>(function_strict_mode_flag())); 7286 Add<HPushArgument>(Add<HConstant>(function_strict_mode_flag()));
7291 // TODO(olivf) InvokeFunction produces a check for the parameter count, 7287 // TODO(olivf) InvokeFunction produces a check for the parameter count,
7292 // even though we are certain to pass the correct number of arguments here. 7288 // even though we are certain to pass the correct number of arguments here.
7293 HInstruction* instr = New<HInvokeFunction>(function, 3); 7289 HInstruction* instr = New<HInvokeFunction>(function, 3);
7294 return ast_context()->ReturnInstruction(instr, expr->id()); 7290 return ast_context()->ReturnInstruction(instr, expr->id());
7295 } else if (proxy != NULL) { 7291 } else if (proxy != NULL) {
7296 Variable* var = proxy->var(); 7292 Variable* var = proxy->var();
7297 if (var->IsUnallocated()) { 7293 if (var->IsUnallocated()) {
7298 Bailout("delete with global variable"); 7294 Bailout(kDeleteWithGlobalVariable);
7299 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 7295 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
7300 // Result of deleting non-global variables is false. 'this' is not 7296 // Result of deleting non-global variables is false. 'this' is not
7301 // really a variable, though we implement it as one. The 7297 // really a variable, though we implement it as one. The
7302 // subexpression does not have side effects. 7298 // subexpression does not have side effects.
7303 HValue* value = var->is_this() 7299 HValue* value = var->is_this()
7304 ? graph()->GetConstantTrue() 7300 ? graph()->GetConstantTrue()
7305 : graph()->GetConstantFalse(); 7301 : graph()->GetConstantFalse();
7306 return ast_context()->ReturnValue(value); 7302 return ast_context()->ReturnValue(value);
7307 } else { 7303 } else {
7308 Bailout("delete with non-global variable"); 7304 Bailout(kDeleteWithNonGlobalVariable);
7309 } 7305 }
7310 } else { 7306 } else {
7311 // Result of deleting non-property, non-variable reference is true. 7307 // Result of deleting non-property, non-variable reference is true.
7312 // Evaluate the subexpression for side effects. 7308 // Evaluate the subexpression for side effects.
7313 CHECK_ALIVE(VisitForEffect(expr->expression())); 7309 CHECK_ALIVE(VisitForEffect(expr->expression()));
7314 return ast_context()->ReturnValue(graph()->GetConstantTrue()); 7310 return ast_context()->ReturnValue(graph()->GetConstantTrue());
7315 } 7311 }
7316 } 7312 }
7317 7313
7318 7314
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
7430 7426
7431 7427
7432 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { 7428 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) {
7433 ASSERT(!HasStackOverflow()); 7429 ASSERT(!HasStackOverflow());
7434 ASSERT(current_block() != NULL); 7430 ASSERT(current_block() != NULL);
7435 ASSERT(current_block()->HasPredecessor()); 7431 ASSERT(current_block()->HasPredecessor());
7436 Expression* target = expr->expression(); 7432 Expression* target = expr->expression();
7437 VariableProxy* proxy = target->AsVariableProxy(); 7433 VariableProxy* proxy = target->AsVariableProxy();
7438 Property* prop = target->AsProperty(); 7434 Property* prop = target->AsProperty();
7439 if (proxy == NULL && prop == NULL) { 7435 if (proxy == NULL && prop == NULL) {
7440 return Bailout("invalid lhs in count operation"); 7436 return Bailout(kInvalidLhsInCountOperation);
7441 } 7437 }
7442 7438
7443 // Match the full code generator stack by simulating an extra stack 7439 // Match the full code generator stack by simulating an extra stack
7444 // element for postfix operations in a non-effect context. The return 7440 // element for postfix operations in a non-effect context. The return
7445 // value is ToNumber(input). 7441 // value is ToNumber(input).
7446 bool returns_original_input = 7442 bool returns_original_input =
7447 expr->is_postfix() && !ast_context()->IsEffect(); 7443 expr->is_postfix() && !ast_context()->IsEffect();
7448 HValue* input = NULL; // ToNumber(original_input). 7444 HValue* input = NULL; // ToNumber(original_input).
7449 HValue* after = NULL; // The result after incrementing or decrementing. 7445 HValue* after = NULL; // The result after incrementing or decrementing.
7450 7446
7451 if (proxy != NULL) { 7447 if (proxy != NULL) {
7452 Variable* var = proxy->var(); 7448 Variable* var = proxy->var();
7453 if (var->mode() == CONST) { 7449 if (var->mode() == CONST) {
7454 return Bailout("unsupported count operation with const"); 7450 return Bailout(kUnsupportedCountOperationWithConst);
7455 } 7451 }
7456 // Argument of the count operation is a variable, not a property. 7452 // Argument of the count operation is a variable, not a property.
7457 ASSERT(prop == NULL); 7453 ASSERT(prop == NULL);
7458 CHECK_ALIVE(VisitForValue(target)); 7454 CHECK_ALIVE(VisitForValue(target));
7459 7455
7460 after = BuildIncrement(returns_original_input, expr); 7456 after = BuildIncrement(returns_original_input, expr);
7461 input = returns_original_input ? Top() : Pop(); 7457 input = returns_original_input ? Top() : Pop();
7462 Push(after); 7458 Push(after);
7463 7459
7464 switch (var->location()) { 7460 switch (var->location()) {
(...skipping 13 matching lines...) Expand all
7478 // Bail out if we try to mutate a parameter value in a function 7474 // Bail out if we try to mutate a parameter value in a function
7479 // using the arguments object. We do not (yet) correctly handle the 7475 // using the arguments object. We do not (yet) correctly handle the
7480 // arguments property of the function. 7476 // arguments property of the function.
7481 if (current_info()->scope()->arguments() != NULL) { 7477 if (current_info()->scope()->arguments() != NULL) {
7482 // Parameters will rewrite to context slots. We have no direct 7478 // Parameters will rewrite to context slots. We have no direct
7483 // way to detect that the variable is a parameter so we use a 7479 // way to detect that the variable is a parameter so we use a
7484 // linear search of the parameter list. 7480 // linear search of the parameter list.
7485 int count = current_info()->scope()->num_parameters(); 7481 int count = current_info()->scope()->num_parameters();
7486 for (int i = 0; i < count; ++i) { 7482 for (int i = 0; i < count; ++i) {
7487 if (var == current_info()->scope()->parameter(i)) { 7483 if (var == current_info()->scope()->parameter(i)) {
7488 return Bailout("assignment to parameter in arguments object"); 7484 return Bailout(kAssignmentToParameterInArgumentsObject);
7489 } 7485 }
7490 } 7486 }
7491 } 7487 }
7492 7488
7493 HValue* context = BuildContextChainWalk(var); 7489 HValue* context = BuildContextChainWalk(var);
7494 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) 7490 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode())
7495 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; 7491 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck;
7496 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), 7492 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(),
7497 mode, after); 7493 mode, after);
7498 if (instr->HasObservableSideEffects()) { 7494 if (instr->HasObservableSideEffects()) {
7499 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 7495 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
7500 } 7496 }
7501 break; 7497 break;
7502 } 7498 }
7503 7499
7504 case Variable::LOOKUP: 7500 case Variable::LOOKUP:
7505 return Bailout("lookup variable in count operation"); 7501 return Bailout(kLookupVariableInCountOperation);
7506 } 7502 }
7507 7503
7508 } else { 7504 } else {
7509 // Argument of the count operation is a property. 7505 // Argument of the count operation is a property.
7510 ASSERT(prop != NULL); 7506 ASSERT(prop != NULL);
7511 7507
7512 if (prop->key()->IsPropertyName()) { 7508 if (prop->key()->IsPropertyName()) {
7513 // Named property. 7509 // Named property.
7514 if (returns_original_input) Push(graph()->GetConstantUndefined()); 7510 if (returns_original_input) Push(graph()->GetConstantUndefined());
7515 7511
(...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after
8104 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); 8100 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone()));
8105 BuildCheckHeapObject(right); 8101 BuildCheckHeapObject(right);
8106 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); 8102 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone()));
8107 HCompareObjectEqAndBranch* result = 8103 HCompareObjectEqAndBranch* result =
8108 new(zone()) HCompareObjectEqAndBranch(left, right); 8104 new(zone()) HCompareObjectEqAndBranch(left, right);
8109 result->set_position(expr->position()); 8105 result->set_position(expr->position());
8110 return ast_context()->ReturnControl(result, expr->id()); 8106 return ast_context()->ReturnControl(result, expr->id());
8111 } 8107 }
8112 } 8108 }
8113 default: 8109 default:
8114 return Bailout("Unsupported non-primitive compare"); 8110 return Bailout(kUnsupportedNonPrimitiveCompare);
8115 } 8111 }
8116 } else if (combined_type->Is(Type::InternalizedString()) && 8112 } else if (combined_type->Is(Type::InternalizedString()) &&
8117 Token::IsEqualityOp(op)) { 8113 Token::IsEqualityOp(op)) {
8118 BuildCheckHeapObject(left); 8114 BuildCheckHeapObject(left);
8119 AddInstruction(HCheckInstanceType::NewIsInternalizedString(left, zone())); 8115 AddInstruction(HCheckInstanceType::NewIsInternalizedString(left, zone()));
8120 BuildCheckHeapObject(right); 8116 BuildCheckHeapObject(right);
8121 AddInstruction(HCheckInstanceType::NewIsInternalizedString(right, zone())); 8117 AddInstruction(HCheckInstanceType::NewIsInternalizedString(right, zone()));
8122 HCompareObjectEqAndBranch* result = 8118 HCompareObjectEqAndBranch* result =
8123 new(zone()) HCompareObjectEqAndBranch(left, right); 8119 new(zone()) HCompareObjectEqAndBranch(left, right);
8124 result->set_position(expr->position()); 8120 result->set_position(expr->position());
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
8571 HValue* value = graph()->GetConstantHole(); 8567 HValue* value = graph()->GetConstantHole();
8572 HValue* context = environment()->context(); 8568 HValue* context = environment()->context();
8573 HStoreContextSlot* store = Add<HStoreContextSlot>( 8569 HStoreContextSlot* store = Add<HStoreContextSlot>(
8574 context, variable->index(), HStoreContextSlot::kNoCheck, value); 8570 context, variable->index(), HStoreContextSlot::kNoCheck, value);
8575 if (store->HasObservableSideEffects()) { 8571 if (store->HasObservableSideEffects()) {
8576 Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE); 8572 Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE);
8577 } 8573 }
8578 } 8574 }
8579 break; 8575 break;
8580 case Variable::LOOKUP: 8576 case Variable::LOOKUP:
8581 return Bailout("unsupported lookup slot in declaration"); 8577 return Bailout(kUnsupportedLookupSlotInDeclaration);
8582 } 8578 }
8583 } 8579 }
8584 8580
8585 8581
8586 void HOptimizedGraphBuilder::VisitFunctionDeclaration( 8582 void HOptimizedGraphBuilder::VisitFunctionDeclaration(
8587 FunctionDeclaration* declaration) { 8583 FunctionDeclaration* declaration) {
8588 VariableProxy* proxy = declaration->proxy(); 8584 VariableProxy* proxy = declaration->proxy();
8589 Variable* variable = proxy->var(); 8585 Variable* variable = proxy->var();
8590 switch (variable->location()) { 8586 switch (variable->location()) {
8591 case Variable::UNALLOCATED: { 8587 case Variable::UNALLOCATED: {
(...skipping 17 matching lines...) Expand all
8609 HValue* value = Pop(); 8605 HValue* value = Pop();
8610 HValue* context = environment()->context(); 8606 HValue* context = environment()->context();
8611 HStoreContextSlot* store = Add<HStoreContextSlot>( 8607 HStoreContextSlot* store = Add<HStoreContextSlot>(
8612 context, variable->index(), HStoreContextSlot::kNoCheck, value); 8608 context, variable->index(), HStoreContextSlot::kNoCheck, value);
8613 if (store->HasObservableSideEffects()) { 8609 if (store->HasObservableSideEffects()) {
8614 Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE); 8610 Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE);
8615 } 8611 }
8616 break; 8612 break;
8617 } 8613 }
8618 case Variable::LOOKUP: 8614 case Variable::LOOKUP:
8619 return Bailout("unsupported lookup slot in declaration"); 8615 return Bailout(kUnsupportedLookupSlotInDeclaration);
8620 } 8616 }
8621 } 8617 }
8622 8618
8623 8619
8624 void HOptimizedGraphBuilder::VisitModuleDeclaration( 8620 void HOptimizedGraphBuilder::VisitModuleDeclaration(
8625 ModuleDeclaration* declaration) { 8621 ModuleDeclaration* declaration) {
8626 UNREACHABLE(); 8622 UNREACHABLE();
8627 } 8623 }
8628 8624
8629 8625
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
8730 void HOptimizedGraphBuilder::GenerateIsObject(CallRuntime* call) { 8726 void HOptimizedGraphBuilder::GenerateIsObject(CallRuntime* call) {
8731 ASSERT(call->arguments()->length() == 1); 8727 ASSERT(call->arguments()->length() == 1);
8732 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 8728 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
8733 HValue* value = Pop(); 8729 HValue* value = Pop();
8734 HIsObjectAndBranch* result = new(zone()) HIsObjectAndBranch(value); 8730 HIsObjectAndBranch* result = new(zone()) HIsObjectAndBranch(value);
8735 return ast_context()->ReturnControl(result, call->id()); 8731 return ast_context()->ReturnControl(result, call->id());
8736 } 8732 }
8737 8733
8738 8734
8739 void HOptimizedGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) { 8735 void HOptimizedGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) {
8740 return Bailout("inlined runtime function: IsNonNegativeSmi"); 8736 return Bailout(kInlinedRuntimeFunctionIsNonNegativeSmi);
8741 } 8737 }
8742 8738
8743 8739
8744 void HOptimizedGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) { 8740 void HOptimizedGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) {
8745 ASSERT(call->arguments()->length() == 1); 8741 ASSERT(call->arguments()->length() == 1);
8746 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 8742 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
8747 HValue* value = Pop(); 8743 HValue* value = Pop();
8748 HIsUndetectableAndBranch* result = 8744 HIsUndetectableAndBranch* result =
8749 new(zone()) HIsUndetectableAndBranch(value); 8745 new(zone()) HIsUndetectableAndBranch(value);
8750 return ast_context()->ReturnControl(result, call->id()); 8746 return ast_context()->ReturnControl(result, call->id());
8751 } 8747 }
8752 8748
8753 8749
8754 void HOptimizedGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf( 8750 void HOptimizedGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf(
8755 CallRuntime* call) { 8751 CallRuntime* call) {
8756 return Bailout( 8752 return Bailout(kInlinedRuntimeFunctionIsStringWrapperSafeForDefaultValueOf);
8757 "inlined runtime function: IsStringWrapperSafeForDefaultValueOf");
8758 } 8753 }
8759 8754
8760 8755
8761 // Support for construct call checks. 8756 // Support for construct call checks.
8762 void HOptimizedGraphBuilder::GenerateIsConstructCall(CallRuntime* call) { 8757 void HOptimizedGraphBuilder::GenerateIsConstructCall(CallRuntime* call) {
8763 ASSERT(call->arguments()->length() == 0); 8758 ASSERT(call->arguments()->length() == 0);
8764 if (function_state()->outer() != NULL) { 8759 if (function_state()->outer() != NULL) {
8765 // We are generating graph for inlined function. 8760 // We are generating graph for inlined function.
8766 HValue* value = function_state()->inlining_kind() == CONSTRUCT_CALL_RETURN 8761 HValue* value = function_state()->inlining_kind() == CONSTRUCT_CALL_RETURN
8767 ? graph()->GetConstantTrue() 8762 ? graph()->GetConstantTrue()
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
8801 HAccessArgumentsAt* result = 8796 HAccessArgumentsAt* result =
8802 new(zone()) HAccessArgumentsAt(elements, length, checked_index); 8797 new(zone()) HAccessArgumentsAt(elements, length, checked_index);
8803 return ast_context()->ReturnInstruction(result, call->id()); 8798 return ast_context()->ReturnInstruction(result, call->id());
8804 } 8799 }
8805 8800
8806 8801
8807 // Support for accessing the class and value fields of an object. 8802 // Support for accessing the class and value fields of an object.
8808 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { 8803 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) {
8809 // The special form detected by IsClassOfTest is detected before we get here 8804 // The special form detected by IsClassOfTest is detected before we get here
8810 // and does not cause a bailout. 8805 // and does not cause a bailout.
8811 return Bailout("inlined runtime function: ClassOf"); 8806 return Bailout(kInlinedRuntimeFunctionClassOf);
8812 } 8807 }
8813 8808
8814 8809
8815 void HOptimizedGraphBuilder::GenerateValueOf(CallRuntime* call) { 8810 void HOptimizedGraphBuilder::GenerateValueOf(CallRuntime* call) {
8816 ASSERT(call->arguments()->length() == 1); 8811 ASSERT(call->arguments()->length() == 1);
8817 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 8812 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
8818 HValue* value = Pop(); 8813 HValue* value = Pop();
8819 HValueOf* result = new(zone()) HValueOf(value); 8814 HValueOf* result = new(zone()) HValueOf(value);
8820 return ast_context()->ReturnInstruction(result, call->id()); 8815 return ast_context()->ReturnInstruction(result, call->id());
8821 } 8816 }
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
9018 HValue* context = environment()->context(); 9013 HValue* context = environment()->context();
9019 HCallStub* result = 9014 HCallStub* result =
9020 new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3); 9015 new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3);
9021 Drop(3); 9016 Drop(3);
9022 return ast_context()->ReturnInstruction(result, call->id()); 9017 return ast_context()->ReturnInstruction(result, call->id());
9023 } 9018 }
9024 9019
9025 9020
9026 // Support for fast native caches. 9021 // Support for fast native caches.
9027 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) { 9022 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) {
9028 return Bailout("inlined runtime function: GetFromCache"); 9023 return Bailout(kInlinedRuntimeFunctionGetFromCache);
9029 } 9024 }
9030 9025
9031 9026
9032 // Fast support for number to string. 9027 // Fast support for number to string.
9033 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { 9028 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) {
9034 ASSERT_EQ(1, call->arguments()->length()); 9029 ASSERT_EQ(1, call->arguments()->length());
9035 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9030 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9036 HValue* context = environment()->context(); 9031 HValue* context = environment()->context();
9037 HCallStub* result = 9032 HCallStub* result =
9038 new(zone()) HCallStub(context, CodeStub::NumberToString, 1); 9033 new(zone()) HCallStub(context, CodeStub::NumberToString, 1);
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
9148 HValue* value = Pop(); 9143 HValue* value = Pop();
9149 HValue* context = environment()->context(); 9144 HValue* context = environment()->context();
9150 HInstruction* result = 9145 HInstruction* result =
9151 HUnaryMathOperation::New(zone(), context, value, kMathSqrt); 9146 HUnaryMathOperation::New(zone(), context, value, kMathSqrt);
9152 return ast_context()->ReturnInstruction(result, call->id()); 9147 return ast_context()->ReturnInstruction(result, call->id());
9153 } 9148 }
9154 9149
9155 9150
9156 // Check whether two RegExps are equivalent 9151 // Check whether two RegExps are equivalent
9157 void HOptimizedGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) { 9152 void HOptimizedGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) {
9158 return Bailout("inlined runtime function: IsRegExpEquivalent"); 9153 return Bailout(kInlinedRuntimeFunctionIsRegExpEquivalent);
9159 } 9154 }
9160 9155
9161 9156
9162 void HOptimizedGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) { 9157 void HOptimizedGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) {
9163 ASSERT(call->arguments()->length() == 1); 9158 ASSERT(call->arguments()->length() == 1);
9164 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9159 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9165 HValue* value = Pop(); 9160 HValue* value = Pop();
9166 HGetCachedArrayIndex* result = new(zone()) HGetCachedArrayIndex(value); 9161 HGetCachedArrayIndex* result = new(zone()) HGetCachedArrayIndex(value);
9167 return ast_context()->ReturnInstruction(result, call->id()); 9162 return ast_context()->ReturnInstruction(result, call->id());
9168 } 9163 }
9169 9164
9170 9165
9171 void HOptimizedGraphBuilder::GenerateFastAsciiArrayJoin(CallRuntime* call) { 9166 void HOptimizedGraphBuilder::GenerateFastAsciiArrayJoin(CallRuntime* call) {
9172 return Bailout("inlined runtime function: FastAsciiArrayJoin"); 9167 return Bailout(kInlinedRuntimeFunctionFastAsciiArrayJoin);
9173 } 9168 }
9174 9169
9175 9170
9176 // Support for generators. 9171 // Support for generators.
9177 void HOptimizedGraphBuilder::GenerateGeneratorNext(CallRuntime* call) { 9172 void HOptimizedGraphBuilder::GenerateGeneratorNext(CallRuntime* call) {
9178 return Bailout("inlined runtime function: GeneratorNext"); 9173 return Bailout(kInlinedRuntimeFunctionGeneratorNext);
9179 } 9174 }
9180 9175
9181 9176
9182 void HOptimizedGraphBuilder::GenerateGeneratorThrow(CallRuntime* call) { 9177 void HOptimizedGraphBuilder::GenerateGeneratorThrow(CallRuntime* call) {
9183 return Bailout("inlined runtime function: GeneratorThrow"); 9178 return Bailout(kInlinedRuntimeFunctionGeneratorThrow);
9184 } 9179 }
9185 9180
9186 9181
9187 void HOptimizedGraphBuilder::GenerateDebugBreakInOptimizedCode( 9182 void HOptimizedGraphBuilder::GenerateDebugBreakInOptimizedCode(
9188 CallRuntime* call) { 9183 CallRuntime* call) {
9189 AddInstruction(new(zone()) HDebugBreak()); 9184 AddInstruction(new(zone()) HDebugBreak());
9190 return ast_context()->ReturnValue(graph()->GetConstant0()); 9185 return ast_context()->ReturnValue(graph()->GetConstant0());
9191 } 9186 }
9192 9187
9193 9188
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after
9799 if (ShouldProduceTraceOutput()) { 9794 if (ShouldProduceTraceOutput()) {
9800 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 9795 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
9801 } 9796 }
9802 9797
9803 #ifdef DEBUG 9798 #ifdef DEBUG
9804 graph_->Verify(false); // No full verify. 9799 graph_->Verify(false); // No full verify.
9805 #endif 9800 #endif
9806 } 9801 }
9807 9802
9808 } } // namespace v8::internal 9803 } } // namespace v8::internal
OLDNEW
« src/compiler.cc ('K') | « src/hydrogen.h ('k') | src/ia32/builtins-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698