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/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
9 #include "src/compiler/ast-loop-assignment-analyzer.h" | 9 #include "src/compiler/ast-loop-assignment-analyzer.h" |
10 #include "src/compiler/control-builders.h" | 10 #include "src/compiler/control-builders.h" |
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
499 liveness_analyzer_(static_cast<size_t>(info->scope()->num_stack_slots()), | 499 liveness_analyzer_(static_cast<size_t>(info->scope()->num_stack_slots()), |
500 local_zone), | 500 local_zone), |
501 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( | 501 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( |
502 FrameStateType::kJavaScriptFunction, info->num_parameters() + 1, | 502 FrameStateType::kJavaScriptFunction, info->num_parameters() + 1, |
503 info->scope()->num_stack_slots(), info->shared_info())) { | 503 info->scope()->num_stack_slots(), info->shared_info())) { |
504 InitializeAstVisitor(info->isolate()); | 504 InitializeAstVisitor(info->isolate()); |
505 } | 505 } |
506 | 506 |
507 | 507 |
508 Node* AstGraphBuilder::GetFunctionClosureForContext() { | 508 Node* AstGraphBuilder::GetFunctionClosureForContext() { |
509 Scope* closure_scope = current_scope()->ClosureScope(); | 509 DeclarationScope* closure_scope = current_scope()->GetClosureScope(); |
510 if (closure_scope->is_script_scope() || | 510 if (closure_scope->is_script_scope() || |
511 closure_scope->is_module_scope()) { | 511 closure_scope->is_module_scope()) { |
512 // Contexts nested in the native context have a canonical empty function as | 512 // Contexts nested in the native context have a canonical empty function as |
513 // their closure, not the anonymous closure containing the global code. | 513 // their closure, not the anonymous closure containing the global code. |
514 return BuildLoadNativeContextField(Context::CLOSURE_INDEX); | 514 return BuildLoadNativeContextField(Context::CLOSURE_INDEX); |
515 } else if (closure_scope->is_eval_scope()) { | 515 } else if (closure_scope->is_eval_scope()) { |
516 // Contexts nested inside eval code have the same closure as the context | 516 // Contexts nested inside eval code have the same closure as the context |
517 // calling eval, not the anonymous closure containing the eval code. | 517 // calling eval, not the anonymous closure containing the eval code. |
518 const Operator* op = | 518 const Operator* op = |
519 javascript()->LoadContext(0, Context::CLOSURE_INDEX, false); | 519 javascript()->LoadContext(0, Context::CLOSURE_INDEX, false); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
566 Node* node = graph()->NewNode( | 566 Node* node = graph()->NewNode( |
567 op, jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(), | 567 op, jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(), |
568 jsgraph()->EmptyStateValues(), jsgraph()->NoContextConstant(), | 568 jsgraph()->EmptyStateValues(), jsgraph()->NoContextConstant(), |
569 jsgraph()->UndefinedConstant(), graph()->start()); | 569 jsgraph()->UndefinedConstant(), graph()->start()); |
570 empty_frame_state_.set(node); | 570 empty_frame_state_.set(node); |
571 } | 571 } |
572 return empty_frame_state_.get(); | 572 return empty_frame_state_.get(); |
573 } | 573 } |
574 | 574 |
575 bool AstGraphBuilder::CreateGraph(bool stack_check) { | 575 bool AstGraphBuilder::CreateGraph(bool stack_check) { |
576 Scope* scope = info()->scope(); | 576 DeclarationScope* scope = info()->scope(); |
577 DCHECK_NOT_NULL(graph()); | 577 DCHECK_NOT_NULL(graph()); |
578 | 578 |
579 // Set up the basic structure of the graph. Outputs for {Start} are the formal | 579 // Set up the basic structure of the graph. Outputs for {Start} are the formal |
580 // parameters (including the receiver) plus new target, number of arguments, | 580 // parameters (including the receiver) plus new target, number of arguments, |
581 // context and closure. | 581 // context and closure. |
582 int actual_parameter_count = info()->num_parameters_including_this() + 4; | 582 int actual_parameter_count = info()->num_parameters_including_this() + 4; |
583 graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count))); | 583 graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count))); |
584 | 584 |
585 // Initialize the top-level environment. | 585 // Initialize the top-level environment. |
586 Environment env(this, scope, graph()->start()); | 586 Environment env(this, scope, graph()->start()); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
626 // Compute local variable liveness information and use it to relax | 626 // Compute local variable liveness information and use it to relax |
627 // frame states. | 627 // frame states. |
628 ClearNonLiveSlotsInFrameStates(); | 628 ClearNonLiveSlotsInFrameStates(); |
629 | 629 |
630 // Failures indicated by stack overflow. | 630 // Failures indicated by stack overflow. |
631 return !HasStackOverflow(); | 631 return !HasStackOverflow(); |
632 } | 632 } |
633 | 633 |
634 | 634 |
635 void AstGraphBuilder::CreateGraphBody(bool stack_check) { | 635 void AstGraphBuilder::CreateGraphBody(bool stack_check) { |
636 Scope* scope = info()->scope(); | 636 DeclarationScope* scope = info()->scope(); |
637 | 637 |
638 // Build the arguments object if it is used. | 638 // Build the arguments object if it is used. |
639 BuildArgumentsObject(scope->arguments()); | 639 BuildArgumentsObject(scope->arguments()); |
640 | 640 |
641 // Build rest arguments array if it is used. | 641 // Build rest arguments array if it is used. |
642 int rest_index; | 642 int rest_index; |
643 Variable* rest_parameter = scope->rest_parameter(&rest_index); | 643 Variable* rest_parameter = scope->rest_parameter(&rest_index); |
644 BuildRestArgumentsArray(rest_parameter, rest_index); | 644 BuildRestArgumentsArray(rest_parameter, rest_index); |
645 | 645 |
646 // Build assignment to {.this_function} variable if it is used. | 646 // Build assignment to {.this_function} variable if it is used. |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
692 } | 692 } |
693 | 693 |
694 | 694 |
695 // Gets the bailout id just before reading a variable proxy, but only for | 695 // Gets the bailout id just before reading a variable proxy, but only for |
696 // unallocated variables. | 696 // unallocated variables. |
697 static BailoutId BeforeId(VariableProxy* proxy) { | 697 static BailoutId BeforeId(VariableProxy* proxy) { |
698 return proxy->var()->IsUnallocatedOrGlobalSlot() ? proxy->BeforeId() | 698 return proxy->var()->IsUnallocatedOrGlobalSlot() ? proxy->BeforeId() |
699 : BailoutId::None(); | 699 : BailoutId::None(); |
700 } | 700 } |
701 | 701 |
702 | 702 static const char* GetDebugParameterName(Zone* zone, DeclarationScope* scope, |
703 static const char* GetDebugParameterName(Zone* zone, Scope* scope, int index) { | 703 int index) { |
704 #if DEBUG | 704 #if DEBUG |
705 const AstRawString* name = scope->parameter(index)->raw_name(); | 705 const AstRawString* name = scope->parameter(index)->raw_name(); |
706 if (name && name->length() > 0) { | 706 if (name && name->length() > 0) { |
707 char* data = zone->NewArray<char>(name->length() + 1); | 707 char* data = zone->NewArray<char>(name->length() + 1); |
708 data[name->length()] = 0; | 708 data[name->length()] = 0; |
709 memcpy(data, name->raw_data(), name->length()); | 709 memcpy(data, name->raw_data(), name->length()); |
710 return data; | 710 return data; |
711 } | 711 } |
712 #endif | 712 #endif |
713 return nullptr; | 713 return nullptr; |
714 } | 714 } |
715 | 715 |
716 | 716 |
717 AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder, | 717 AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder, |
718 Scope* scope, | 718 Scope* scope, |
Michael Starzinger
2016/08/03 13:02:19
nit: Can we change the signature to take "Declarat
| |
719 Node* control_dependency) | 719 Node* control_dependency) |
720 : builder_(builder), | 720 : builder_(builder), |
721 parameters_count_(scope->num_parameters() + 1), | 721 parameters_count_(scope->num_parameters() + 1), |
722 locals_count_(scope->num_stack_slots()), | 722 locals_count_(scope->num_stack_slots()), |
723 liveness_block_(IsLivenessAnalysisEnabled() | 723 liveness_block_(IsLivenessAnalysisEnabled() |
724 ? builder_->liveness_analyzer()->NewBlock() | 724 ? builder_->liveness_analyzer()->NewBlock() |
725 : nullptr), | 725 : nullptr), |
726 values_(builder_->local_zone()), | 726 values_(builder_->local_zone()), |
727 contexts_(builder_->local_zone()), | 727 contexts_(builder_->local_zone()), |
728 control_dependency_(control_dependency), | 728 control_dependency_(control_dependency), |
(...skipping 10 matching lines...) Expand all Loading... | |
739 Node* receiver = builder->graph()->NewNode(op, builder->graph()->start()); | 739 Node* receiver = builder->graph()->NewNode(op, builder->graph()->start()); |
740 values()->push_back(receiver); | 740 values()->push_back(receiver); |
741 } else { | 741 } else { |
742 values()->push_back(builder->jsgraph()->UndefinedConstant()); | 742 values()->push_back(builder->jsgraph()->UndefinedConstant()); |
743 } | 743 } |
744 | 744 |
745 // Bind all parameter variables. The parameter indices are shifted by 1 | 745 // Bind all parameter variables. The parameter indices are shifted by 1 |
746 // (receiver is variable index -1 but {Parameter} node index 0 and located at | 746 // (receiver is variable index -1 but {Parameter} node index 0 and located at |
747 // index 0 in the environment). | 747 // index 0 in the environment). |
748 for (int i = 0; i < scope->num_parameters(); ++i) { | 748 for (int i = 0; i < scope->num_parameters(); ++i) { |
749 const char* debug_name = GetDebugParameterName(graph()->zone(), scope, i); | 749 const char* debug_name = |
750 GetDebugParameterName(graph()->zone(), scope->AsDeclarationScope(), i); | |
Michael Starzinger
2016/08/03 13:02:19
nit: See comment above.
| |
750 const Operator* op = common()->Parameter(param_num++, debug_name); | 751 const Operator* op = common()->Parameter(param_num++, debug_name); |
751 Node* parameter = builder->graph()->NewNode(op, builder->graph()->start()); | 752 Node* parameter = builder->graph()->NewNode(op, builder->graph()->start()); |
752 values()->push_back(parameter); | 753 values()->push_back(parameter); |
753 } | 754 } |
754 | 755 |
755 // Bind all local variables to undefined. | 756 // Bind all local variables to undefined. |
756 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); | 757 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); |
757 values()->insert(values()->end(), locals_count(), undefined_constant); | 758 values()->insert(values()->end(), locals_count(), undefined_constant); |
758 } | 759 } |
759 | 760 |
(...skipping 2429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3189 Node** all = info()->zone()->NewArray<Node*>(arity); | 3190 Node** all = info()->zone()->NewArray<Node*>(arity); |
3190 for (int i = arity - 1; i >= 0; --i) { | 3191 for (int i = arity - 1; i >= 0; --i) { |
3191 all[i] = environment()->Pop(); | 3192 all[i] = environment()->Pop(); |
3192 } | 3193 } |
3193 Node* value = NewNode(op, arity, all); | 3194 Node* value = NewNode(op, arity, all); |
3194 return value; | 3195 return value; |
3195 } | 3196 } |
3196 | 3197 |
3197 | 3198 |
3198 Node* AstGraphBuilder::BuildLocalActivationContext(Node* context) { | 3199 Node* AstGraphBuilder::BuildLocalActivationContext(Node* context) { |
3199 Scope* scope = info()->scope(); | 3200 DeclarationScope* scope = info()->scope(); |
3200 | 3201 |
3201 // Allocate a new local context. | 3202 // Allocate a new local context. |
3202 Node* local_context = scope->is_script_scope() | 3203 Node* local_context = scope->is_script_scope() |
3203 ? BuildLocalScriptContext(scope) | 3204 ? BuildLocalScriptContext(scope) |
3204 : BuildLocalFunctionContext(scope); | 3205 : BuildLocalFunctionContext(scope); |
3205 | 3206 |
3206 if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) { | 3207 if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) { |
3207 Node* receiver = environment()->RawParameterLookup(0); | 3208 Node* receiver = environment()->RawParameterLookup(0); |
3208 // Context variable (at bottom of the context chain). | 3209 // Context variable (at bottom of the context chain). |
3209 Variable* variable = scope->receiver(); | 3210 Variable* variable = scope->receiver(); |
(...skipping 1180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4390 // Phi does not exist yet, introduce one. | 4391 // Phi does not exist yet, introduce one. |
4391 value = NewPhi(inputs, value, control); | 4392 value = NewPhi(inputs, value, control); |
4392 value->ReplaceInput(inputs - 1, other); | 4393 value->ReplaceInput(inputs - 1, other); |
4393 } | 4394 } |
4394 return value; | 4395 return value; |
4395 } | 4396 } |
4396 | 4397 |
4397 } // namespace compiler | 4398 } // namespace compiler |
4398 } // namespace internal | 4399 } // namespace internal |
4399 } // namespace v8 | 4400 } // namespace v8 |
OLD | NEW |