OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
6 | 6 |
7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/compiler/ast-loop-assignment-analyzer.h" | 8 #include "src/compiler/ast-loop-assignment-analyzer.h" |
9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
10 #include "src/compiler/js-type-feedback.h" | 10 #include "src/compiler/js-type-feedback.h" |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 | 518 |
519 // Initialize the incoming context. | 519 // Initialize the incoming context. |
520 CreateFunctionContext(constant_context); | 520 CreateFunctionContext(constant_context); |
521 ContextScope incoming(this, scope, function_context_.get()); | 521 ContextScope incoming(this, scope, function_context_.get()); |
522 | 522 |
523 // Initialize control scope. | 523 // Initialize control scope. |
524 ControlScope control(this); | 524 ControlScope control(this); |
525 | 525 |
526 // Build receiver check for sloppy mode if necessary. | 526 // Build receiver check for sloppy mode if necessary. |
527 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC? | 527 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC? |
528 Node* patched_receiver = nullptr; | |
529 if (scope->has_this_declaration()) { | 528 if (scope->has_this_declaration()) { |
530 Node* original_receiver = NewNode(common()->Parameter(0), graph()->start()); | 529 Node* original_receiver = env.RawParameterLookup(0); |
531 patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); | 530 Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); |
532 if (scope->receiver()->IsStackAllocated()) { | 531 env.RawParameterBind(0, patched_receiver); |
533 env.Bind(scope->receiver(), patched_receiver); | |
534 } | |
535 } | 532 } |
536 | 533 |
537 // Build function context only if there are context allocated variables. | 534 // Build function context only if there are context allocated variables. |
538 if (info()->num_heap_slots() > 0) { | 535 if (info()->num_heap_slots() > 0) { |
539 // Push a new inner context scope for the function. | 536 // Push a new inner context scope for the function. |
540 Node* inner_context = | 537 Node* inner_context = BuildLocalFunctionContext(function_context_.get()); |
541 BuildLocalFunctionContext(function_context_.get(), patched_receiver); | |
542 ContextScope top_context(this, scope, inner_context); | 538 ContextScope top_context(this, scope, inner_context); |
543 CreateGraphBody(stack_check); | 539 CreateGraphBody(stack_check); |
544 } else { | 540 } else { |
545 // Simply use the outer function context in building the graph. | 541 // Simply use the outer function context in building the graph. |
546 CreateGraphBody(stack_check); | 542 CreateGraphBody(stack_check); |
547 } | 543 } |
548 | 544 |
549 // Finish the basic structure of the graph. | 545 // Finish the basic structure of the graph. |
550 DCHECK_NE(0u, exit_controls_.size()); | 546 DCHECK_NE(0u, exit_controls_.size()); |
551 int const input_count = static_cast<int>(exit_controls_.size()); | 547 int const input_count = static_cast<int>(exit_controls_.size()); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 control_dependency_(control_dependency), | 674 control_dependency_(control_dependency), |
679 effect_dependency_(control_dependency), | 675 effect_dependency_(control_dependency), |
680 parameters_node_(nullptr), | 676 parameters_node_(nullptr), |
681 locals_node_(nullptr), | 677 locals_node_(nullptr), |
682 stack_node_(nullptr) { | 678 stack_node_(nullptr) { |
683 DCHECK_EQ(scope->num_parameters() + 1, parameters_count()); | 679 DCHECK_EQ(scope->num_parameters() + 1, parameters_count()); |
684 | 680 |
685 // Bind the receiver variable. | 681 // Bind the receiver variable. |
686 int param_num = 0; | 682 int param_num = 0; |
687 if (builder->info()->is_this_defined()) { | 683 if (builder->info()->is_this_defined()) { |
688 Node* receiver = builder->graph()->NewNode( | 684 const Operator* op = common()->Parameter(param_num++, "%this"); |
689 common()->Parameter(param_num++, "%this"), builder->graph()->start()); | 685 Node* receiver = builder->graph()->NewNode(op, builder->graph()->start()); |
690 values()->push_back(receiver); | 686 values()->push_back(receiver); |
691 } else { | 687 } else { |
692 values()->push_back(builder->jsgraph()->UndefinedConstant()); | 688 values()->push_back(builder->jsgraph()->UndefinedConstant()); |
693 } | 689 } |
694 | 690 |
695 // Bind all parameter variables. The parameter indices are shifted by 1 | 691 // Bind all parameter variables. The parameter indices are shifted by 1 |
696 // (receiver is parameter index -1 but environment index 0). | 692 // (receiver is parameter index -1 but environment index 0). |
697 for (int i = 0; i < scope->num_parameters(); ++i) { | 693 for (int i = 0; i < scope->num_parameters(); ++i) { |
698 const char* debug_name = GetDebugParameterName(graph()->zone(), scope, i); | 694 const char* debug_name = GetDebugParameterName(graph()->zone(), scope, i); |
699 Node* parameter = | 695 const Operator* op = common()->Parameter(param_num++, debug_name); |
700 builder->graph()->NewNode(common()->Parameter(param_num++, debug_name), | 696 Node* parameter = builder->graph()->NewNode(op, builder->graph()->start()); |
701 builder->graph()->start()); | |
702 values()->push_back(parameter); | 697 values()->push_back(parameter); |
703 } | 698 } |
704 | 699 |
705 // Bind all local variables to undefined. | 700 // Bind all local variables to undefined. |
706 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); | 701 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); |
707 values()->insert(values()->end(), locals_count(), undefined_constant); | 702 values()->insert(values()->end(), locals_count(), undefined_constant); |
708 } | 703 } |
709 | 704 |
710 | 705 |
711 AstGraphBuilder::Environment::Environment(AstGraphBuilder::Environment* copy, | 706 AstGraphBuilder::Environment::Environment(AstGraphBuilder::Environment* copy, |
(...skipping 20 matching lines...) Expand all Loading... |
732 | 727 |
733 void AstGraphBuilder::Environment::Bind(Variable* variable, Node* node) { | 728 void AstGraphBuilder::Environment::Bind(Variable* variable, Node* node) { |
734 DCHECK(variable->IsStackAllocated()); | 729 DCHECK(variable->IsStackAllocated()); |
735 if (variable->IsParameter()) { | 730 if (variable->IsParameter()) { |
736 // The parameter indices are shifted by 1 (receiver is parameter | 731 // The parameter indices are shifted by 1 (receiver is parameter |
737 // index -1 but environment index 0). | 732 // index -1 but environment index 0). |
738 values()->at(variable->index() + 1) = node; | 733 values()->at(variable->index() + 1) = node; |
739 } else { | 734 } else { |
740 DCHECK(variable->IsStackLocal()); | 735 DCHECK(variable->IsStackLocal()); |
741 values()->at(variable->index() + parameters_count_) = node; | 736 values()->at(variable->index() + parameters_count_) = node; |
742 | |
743 DCHECK(IsLivenessBlockConsistent()); | 737 DCHECK(IsLivenessBlockConsistent()); |
744 if (liveness_block() != nullptr) { | 738 if (liveness_block() != nullptr) { |
745 liveness_block()->Bind(variable->index()); | 739 liveness_block()->Bind(variable->index()); |
746 } | 740 } |
747 } | 741 } |
748 } | 742 } |
749 | 743 |
750 | 744 |
751 Node* AstGraphBuilder::Environment::Lookup(Variable* variable) { | 745 Node* AstGraphBuilder::Environment::Lookup(Variable* variable) { |
752 DCHECK(variable->IsStackAllocated()); | 746 DCHECK(variable->IsStackAllocated()); |
(...skipping 15 matching lines...) Expand all Loading... |
768 void AstGraphBuilder::Environment::MarkAllLocalsLive() { | 762 void AstGraphBuilder::Environment::MarkAllLocalsLive() { |
769 DCHECK(IsLivenessBlockConsistent()); | 763 DCHECK(IsLivenessBlockConsistent()); |
770 if (liveness_block() != nullptr) { | 764 if (liveness_block() != nullptr) { |
771 for (int i = 0; i < locals_count_; i++) { | 765 for (int i = 0; i < locals_count_; i++) { |
772 liveness_block()->Lookup(i); | 766 liveness_block()->Lookup(i); |
773 } | 767 } |
774 } | 768 } |
775 } | 769 } |
776 | 770 |
777 | 771 |
| 772 void AstGraphBuilder::Environment::RawParameterBind(int index, Node* node) { |
| 773 DCHECK_LT(index, parameters_count()); |
| 774 values()->at(index) = node; |
| 775 } |
| 776 |
| 777 |
| 778 Node* AstGraphBuilder::Environment::RawParameterLookup(int index) { |
| 779 DCHECK_LT(index, parameters_count()); |
| 780 return values()->at(index); |
| 781 } |
| 782 |
| 783 |
778 AstGraphBuilder::Environment* | 784 AstGraphBuilder::Environment* |
779 AstGraphBuilder::Environment::CopyForConditional() { | 785 AstGraphBuilder::Environment::CopyForConditional() { |
780 LivenessAnalyzerBlock* copy_liveness_block = nullptr; | 786 LivenessAnalyzerBlock* copy_liveness_block = nullptr; |
781 if (liveness_block() != nullptr) { | 787 if (liveness_block() != nullptr) { |
782 copy_liveness_block = | 788 copy_liveness_block = |
783 builder_->liveness_analyzer()->NewBlock(liveness_block()); | 789 builder_->liveness_analyzer()->NewBlock(liveness_block()); |
784 liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block()); | 790 liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block()); |
785 } | 791 } |
786 return new (zone()) Environment(this, copy_liveness_block); | 792 return new (zone()) Environment(this, copy_liveness_block); |
787 } | 793 } |
(...skipping 2274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3062 receiver_check.Then(); | 3068 receiver_check.Then(); |
3063 Node* proxy = BuildLoadGlobalProxy(); | 3069 Node* proxy = BuildLoadGlobalProxy(); |
3064 environment()->Push(proxy); | 3070 environment()->Push(proxy); |
3065 receiver_check.Else(); | 3071 receiver_check.Else(); |
3066 environment()->Push(receiver); | 3072 environment()->Push(receiver); |
3067 receiver_check.End(); | 3073 receiver_check.End(); |
3068 return environment()->Pop(); | 3074 return environment()->Pop(); |
3069 } | 3075 } |
3070 | 3076 |
3071 | 3077 |
3072 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context, | 3078 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context) { |
3073 Node* patched_receiver) { | |
3074 Scope* scope = info()->scope(); | 3079 Scope* scope = info()->scope(); |
3075 Node* closure = GetFunctionClosure(); | 3080 Node* closure = GetFunctionClosure(); |
3076 | 3081 |
3077 // Allocate a new local context. | 3082 // Allocate a new local context. |
3078 Node* local_context = | 3083 Node* local_context = |
3079 scope->is_script_scope() | 3084 scope->is_script_scope() |
3080 ? BuildLocalScriptContext(scope) | 3085 ? BuildLocalScriptContext(scope) |
3081 : NewNode(javascript()->CreateFunctionContext(), closure); | 3086 : NewNode(javascript()->CreateFunctionContext(), closure); |
3082 | 3087 |
3083 if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) { | 3088 if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) { |
3084 DCHECK_NOT_NULL(patched_receiver); | 3089 Node* receiver = environment()->RawParameterLookup(0); |
3085 // Context variable (at bottom of the context chain). | 3090 // Context variable (at bottom of the context chain). |
3086 Variable* variable = scope->receiver(); | 3091 Variable* variable = scope->receiver(); |
3087 DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); | 3092 DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); |
3088 const Operator* op = javascript()->StoreContext(0, variable->index()); | 3093 const Operator* op = javascript()->StoreContext(0, variable->index()); |
3089 NewNode(op, local_context, patched_receiver); | 3094 NewNode(op, local_context, receiver); |
3090 } | 3095 } |
3091 | 3096 |
3092 // Copy parameters into context if necessary. | 3097 // Copy parameters into context if necessary. |
3093 int num_parameters = scope->num_parameters(); | 3098 int num_parameters = scope->num_parameters(); |
3094 for (int i = 0; i < num_parameters; i++) { | 3099 for (int i = 0; i < num_parameters; i++) { |
3095 Variable* variable = scope->parameter(i); | 3100 Variable* variable = scope->parameter(i); |
3096 if (!variable->IsContextSlot()) continue; | 3101 if (!variable->IsContextSlot()) continue; |
3097 // Temporary parameter node. The parameter indices are shifted by 1 | 3102 Node* parameter = environment()->RawParameterLookup(i + 1); |
3098 // (receiver is parameter index -1 but environment index 0). | |
3099 Node* parameter = NewNode(common()->Parameter(i + 1), graph()->start()); | |
3100 // Context variable (at bottom of the context chain). | 3103 // Context variable (at bottom of the context chain). |
3101 DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); | 3104 DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); |
3102 const Operator* op = javascript()->StoreContext(0, variable->index()); | 3105 const Operator* op = javascript()->StoreContext(0, variable->index()); |
3103 NewNode(op, local_context, parameter); | 3106 NewNode(op, local_context, parameter); |
3104 } | 3107 } |
3105 | 3108 |
3106 return local_context; | 3109 return local_context; |
3107 } | 3110 } |
3108 | 3111 |
3109 | 3112 |
(...skipping 1060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4170 // Phi does not exist yet, introduce one. | 4173 // Phi does not exist yet, introduce one. |
4171 value = NewPhi(inputs, value, control); | 4174 value = NewPhi(inputs, value, control); |
4172 value->ReplaceInput(inputs - 1, other); | 4175 value->ReplaceInput(inputs - 1, other); |
4173 } | 4176 } |
4174 return value; | 4177 return value; |
4175 } | 4178 } |
4176 | 4179 |
4177 } // namespace compiler | 4180 } // namespace compiler |
4178 } // namespace internal | 4181 } // namespace internal |
4179 } // namespace v8 | 4182 } // namespace v8 |
OLD | NEW |