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

Side by Side Diff: src/compiler/ast-graph-builder.cc

Issue 2541813002: [compiler] Remove context value input from JSLoadContext and JSStoreContext. (Closed)
Patch Set: Rebase. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/compiler/bytecode-graph-builder.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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/compile-time-value.h" 7 #include "src/ast/compile-time-value.h"
8 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/compilation-info.h" 9 #include "src/compilation-info.h"
10 #include "src/compiler.h" 10 #include "src/compiler.h"
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 if (closure_scope->is_script_scope() || 298 if (closure_scope->is_script_scope() ||
299 closure_scope->is_module_scope()) { 299 closure_scope->is_module_scope()) {
300 // Contexts nested in the native context have a canonical empty function as 300 // Contexts nested in the native context have a canonical empty function as
301 // their closure, not the anonymous closure containing the global code. 301 // their closure, not the anonymous closure containing the global code.
302 return BuildLoadNativeContextField(Context::CLOSURE_INDEX); 302 return BuildLoadNativeContextField(Context::CLOSURE_INDEX);
303 } else if (closure_scope->is_eval_scope()) { 303 } else if (closure_scope->is_eval_scope()) {
304 // Contexts nested inside eval code have the same closure as the context 304 // Contexts nested inside eval code have the same closure as the context
305 // calling eval, not the anonymous closure containing the eval code. 305 // calling eval, not the anonymous closure containing the eval code.
306 const Operator* op = 306 const Operator* op =
307 javascript()->LoadContext(0, Context::CLOSURE_INDEX, false); 307 javascript()->LoadContext(0, Context::CLOSURE_INDEX, false);
308 return NewNode(op, current_context()); 308 return NewNode(op);
309 } else { 309 } else {
310 DCHECK(closure_scope->is_function_scope()); 310 DCHECK(closure_scope->is_function_scope());
311 return GetFunctionClosure(); 311 return GetFunctionClosure();
312 } 312 }
313 } 313 }
314 314
315 315
316 Node* AstGraphBuilder::GetFunctionClosure() { 316 Node* AstGraphBuilder::GetFunctionClosure() {
317 if (!function_closure_.is_set()) { 317 if (!function_closure_.is_set()) {
318 int index = Linkage::kJSCallClosureParamIndex; 318 int index = Linkage::kJSCallClosureParamIndex;
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after
938 case VariableLocation::LOCAL: 938 case VariableLocation::LOCAL:
939 if (variable->binding_needs_init()) { 939 if (variable->binding_needs_init()) {
940 Node* value = jsgraph()->TheHoleConstant(); 940 Node* value = jsgraph()->TheHoleConstant();
941 environment()->Bind(variable, value); 941 environment()->Bind(variable, value);
942 } 942 }
943 break; 943 break;
944 case VariableLocation::CONTEXT: 944 case VariableLocation::CONTEXT:
945 if (variable->binding_needs_init()) { 945 if (variable->binding_needs_init()) {
946 Node* value = jsgraph()->TheHoleConstant(); 946 Node* value = jsgraph()->TheHoleConstant();
947 const Operator* op = javascript()->StoreContext(0, variable->index()); 947 const Operator* op = javascript()->StoreContext(0, variable->index());
948 NewNode(op, current_context(), value); 948 NewNode(op, value);
949 } 949 }
950 break; 950 break;
951 case VariableLocation::LOOKUP: 951 case VariableLocation::LOOKUP:
952 case VariableLocation::MODULE: 952 case VariableLocation::MODULE:
953 UNREACHABLE(); 953 UNREACHABLE();
954 } 954 }
955 } 955 }
956 956
957 957
958 void AstGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) { 958 void AstGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) {
(...skipping 15 matching lines...) Expand all
974 case VariableLocation::LOCAL: { 974 case VariableLocation::LOCAL: {
975 VisitForValue(decl->fun()); 975 VisitForValue(decl->fun());
976 Node* value = environment()->Pop(); 976 Node* value = environment()->Pop();
977 environment()->Bind(variable, value); 977 environment()->Bind(variable, value);
978 break; 978 break;
979 } 979 }
980 case VariableLocation::CONTEXT: { 980 case VariableLocation::CONTEXT: {
981 VisitForValue(decl->fun()); 981 VisitForValue(decl->fun());
982 Node* value = environment()->Pop(); 982 Node* value = environment()->Pop();
983 const Operator* op = javascript()->StoreContext(0, variable->index()); 983 const Operator* op = javascript()->StoreContext(0, variable->index());
984 NewNode(op, current_context(), value); 984 NewNode(op, value);
985 break; 985 break;
986 } 986 }
987 case VariableLocation::LOOKUP: 987 case VariableLocation::LOOKUP:
988 case VariableLocation::MODULE: 988 case VariableLocation::MODULE:
989 UNREACHABLE(); 989 UNREACHABLE();
990 } 990 }
991 } 991 }
992 992
993 993
994 void AstGraphBuilder::VisitBlock(Block* stmt) { 994 void AstGraphBuilder::VisitBlock(Block* stmt) {
(...skipping 1648 matching lines...) Expand 10 before | Expand all | Expand 10 after
2643 Node* local_context = scope->is_script_scope() 2643 Node* local_context = scope->is_script_scope()
2644 ? BuildLocalScriptContext(scope) 2644 ? BuildLocalScriptContext(scope)
2645 : BuildLocalFunctionContext(scope); 2645 : BuildLocalFunctionContext(scope);
2646 2646
2647 if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) { 2647 if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) {
2648 Node* receiver = environment()->RawParameterLookup(0); 2648 Node* receiver = environment()->RawParameterLookup(0);
2649 // Context variable (at bottom of the context chain). 2649 // Context variable (at bottom of the context chain).
2650 Variable* variable = scope->receiver(); 2650 Variable* variable = scope->receiver();
2651 DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); 2651 DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
2652 const Operator* op = javascript()->StoreContext(0, variable->index()); 2652 const Operator* op = javascript()->StoreContext(0, variable->index());
2653 NewNode(op, local_context, receiver); 2653 Node* node = NewNode(op, receiver);
2654 NodeProperties::ReplaceContextInput(node, local_context);
2654 } 2655 }
2655 2656
2656 // Copy parameters into context if necessary. 2657 // Copy parameters into context if necessary.
2657 int num_parameters = scope->num_parameters(); 2658 int num_parameters = scope->num_parameters();
2658 for (int i = 0; i < num_parameters; i++) { 2659 for (int i = 0; i < num_parameters; i++) {
2659 Variable* variable = scope->parameter(i); 2660 Variable* variable = scope->parameter(i);
2660 if (!variable->IsContextSlot()) continue; 2661 if (!variable->IsContextSlot()) continue;
2661 Node* parameter = environment()->RawParameterLookup(i + 1); 2662 Node* parameter = environment()->RawParameterLookup(i + 1);
2662 // Context variable (at bottom of the context chain). 2663 // Context variable (at bottom of the context chain).
2663 DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); 2664 DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
2664 const Operator* op = javascript()->StoreContext(0, variable->index()); 2665 const Operator* op = javascript()->StoreContext(0, variable->index());
2665 NewNode(op, local_context, parameter); 2666 Node* node = NewNode(op, parameter);
2667 NodeProperties::ReplaceContextInput(node, local_context);
2666 } 2668 }
2667 2669
2668 return local_context; 2670 return local_context;
2669 } 2671 }
2670 2672
2671 2673
2672 Node* AstGraphBuilder::BuildLocalFunctionContext(Scope* scope) { 2674 Node* AstGraphBuilder::BuildLocalFunctionContext(Scope* scope) {
2673 DCHECK(scope->is_function_scope() || scope->is_eval_scope()); 2675 DCHECK(scope->is_function_scope() || scope->is_eval_scope());
2674 2676
2675 // Allocate a new local context. 2677 // Allocate a new local context.
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2794 case VariableLocation::CONTEXT: { 2796 case VariableLocation::CONTEXT: {
2795 // Context variable (potentially up the context chain). 2797 // Context variable (potentially up the context chain).
2796 int depth = current_scope()->ContextChainLength(variable->scope()); 2798 int depth = current_scope()->ContextChainLength(variable->scope());
2797 // TODO(mstarzinger): The {maybe_assigned} flag computed during variable 2799 // TODO(mstarzinger): The {maybe_assigned} flag computed during variable
2798 // resolution is highly inaccurate and cannot be trusted. We are only 2800 // resolution is highly inaccurate and cannot be trusted. We are only
2799 // taking this information into account when asm.js compilation is used. 2801 // taking this information into account when asm.js compilation is used.
2800 bool immutable = variable->maybe_assigned() == kNotAssigned && 2802 bool immutable = variable->maybe_assigned() == kNotAssigned &&
2801 info()->is_function_context_specializing(); 2803 info()->is_function_context_specializing();
2802 const Operator* op = 2804 const Operator* op =
2803 javascript()->LoadContext(depth, variable->index(), immutable); 2805 javascript()->LoadContext(depth, variable->index(), immutable);
2804 Node* value = NewNode(op, current_context()); 2806 Node* value = NewNode(op);
2805 // TODO(titzer): initialization checks are redundant for already 2807 // TODO(titzer): initialization checks are redundant for already
2806 // initialized immutable context loads, but only specialization knows. 2808 // initialized immutable context loads, but only specialization knows.
2807 // Maybe specializer should be a parameter to the graph builder? 2809 // Maybe specializer should be a parameter to the graph builder?
2808 if (variable->binding_needs_init()) { 2810 if (variable->binding_needs_init()) {
2809 // Perform check for uninitialized let/const variables. 2811 // Perform check for uninitialized let/const variables.
2810 value = BuildHoleCheckThenThrow(value, variable, value, bailout_id); 2812 value = BuildHoleCheckThenThrow(value, variable, value, bailout_id);
2811 } 2813 }
2812 return value; 2814 return value;
2813 } 2815 }
2814 case VariableLocation::LOOKUP: 2816 case VariableLocation::LOOKUP:
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
2911 } 2913 }
2912 environment()->Bind(variable, value); 2914 environment()->Bind(variable, value);
2913 return value; 2915 return value;
2914 case VariableLocation::CONTEXT: { 2916 case VariableLocation::CONTEXT: {
2915 // Context variable (potentially up the context chain). 2917 // Context variable (potentially up the context chain).
2916 int depth = current_scope()->ContextChainLength(variable->scope()); 2918 int depth = current_scope()->ContextChainLength(variable->scope());
2917 if (mode == LET && op != Token::INIT && variable->binding_needs_init()) { 2919 if (mode == LET && op != Token::INIT && variable->binding_needs_init()) {
2918 // Perform an initialization check for let declared variables. 2920 // Perform an initialization check for let declared variables.
2919 const Operator* op = 2921 const Operator* op =
2920 javascript()->LoadContext(depth, variable->index(), false); 2922 javascript()->LoadContext(depth, variable->index(), false);
2921 Node* current = NewNode(op, current_context()); 2923 Node* current = NewNode(op);
2922 value = BuildHoleCheckThenThrow(current, variable, value, bailout_id); 2924 value = BuildHoleCheckThenThrow(current, variable, value, bailout_id);
2923 } else if (mode == CONST && op == Token::INIT) { 2925 } else if (mode == CONST && op == Token::INIT) {
2924 // Perform an initialization check for const {this} variables. 2926 // Perform an initialization check for const {this} variables.
2925 // Note that the {this} variable is the only const variable being able 2927 // Note that the {this} variable is the only const variable being able
2926 // to trigger bind operations outside the TDZ, via {super} calls. 2928 // to trigger bind operations outside the TDZ, via {super} calls.
2927 if (variable->is_this()) { 2929 if (variable->is_this()) {
2928 const Operator* op = 2930 const Operator* op =
2929 javascript()->LoadContext(depth, variable->index(), false); 2931 javascript()->LoadContext(depth, variable->index(), false);
2930 Node* current = NewNode(op, current_context()); 2932 Node* current = NewNode(op);
2931 value = BuildHoleCheckElseThrow(current, variable, value, bailout_id); 2933 value = BuildHoleCheckElseThrow(current, variable, value, bailout_id);
2932 } 2934 }
2933 } else if (mode == CONST && op != Token::INIT && 2935 } else if (mode == CONST && op != Token::INIT &&
2934 variable->is_sloppy_function_name()) { 2936 variable->is_sloppy_function_name()) {
2935 // Non-initializing assignment to sloppy function names is 2937 // Non-initializing assignment to sloppy function names is
2936 // - exception in strict mode. 2938 // - exception in strict mode.
2937 // - ignored in sloppy mode. 2939 // - ignored in sloppy mode.
2938 DCHECK(!variable->binding_needs_init()); 2940 DCHECK(!variable->binding_needs_init());
2939 if (variable->throw_on_const_assignment(language_mode())) { 2941 if (variable->throw_on_const_assignment(language_mode())) {
2940 return BuildThrowConstAssignError(bailout_id); 2942 return BuildThrowConstAssignError(bailout_id);
2941 } 2943 }
2942 return value; 2944 return value;
2943 } else if (mode == CONST && op != Token::INIT) { 2945 } else if (mode == CONST && op != Token::INIT) {
2944 if (variable->binding_needs_init()) { 2946 if (variable->binding_needs_init()) {
2945 const Operator* op = 2947 const Operator* op =
2946 javascript()->LoadContext(depth, variable->index(), false); 2948 javascript()->LoadContext(depth, variable->index(), false);
2947 Node* current = NewNode(op, current_context()); 2949 Node* current = NewNode(op);
2948 BuildHoleCheckThenThrow(current, variable, value, bailout_id); 2950 BuildHoleCheckThenThrow(current, variable, value, bailout_id);
2949 } 2951 }
2950 // Assignment to const is exception in all modes. 2952 // Assignment to const is exception in all modes.
2951 return BuildThrowConstAssignError(bailout_id); 2953 return BuildThrowConstAssignError(bailout_id);
2952 } 2954 }
2953 const Operator* op = javascript()->StoreContext(depth, variable->index()); 2955 const Operator* op = javascript()->StoreContext(depth, variable->index());
2954 return NewNode(op, current_context(), value); 2956 return NewNode(op, value);
2955 } 2957 }
2956 case VariableLocation::LOOKUP: 2958 case VariableLocation::LOOKUP:
2957 case VariableLocation::MODULE: 2959 case VariableLocation::MODULE:
2958 UNREACHABLE(); 2960 UNREACHABLE();
2959 } 2961 }
2960 UNREACHABLE(); 2962 UNREACHABLE();
2961 return nullptr; 2963 return nullptr;
2962 } 2964 }
2963 2965
2964 2966
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
3056 } 3058 }
3057 3059
3058 Node* AstGraphBuilder::BuildLoadGlobalObject() { 3060 Node* AstGraphBuilder::BuildLoadGlobalObject() {
3059 return BuildLoadNativeContextField(Context::EXTENSION_INDEX); 3061 return BuildLoadNativeContextField(Context::EXTENSION_INDEX);
3060 } 3062 }
3061 3063
3062 3064
3063 Node* AstGraphBuilder::BuildLoadNativeContextField(int index) { 3065 Node* AstGraphBuilder::BuildLoadNativeContextField(int index) {
3064 const Operator* op = 3066 const Operator* op =
3065 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true); 3067 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true);
3066 Node* native_context = NewNode(op, current_context()); 3068 Node* native_context = NewNode(op);
3067 return NewNode(javascript()->LoadContext(0, index, true), native_context); 3069 Node* result = NewNode(javascript()->LoadContext(0, index, true));
3070 NodeProperties::ReplaceContextInput(result, native_context);
3071 return result;
3068 } 3072 }
3069 3073
3070 3074
3071 Node* AstGraphBuilder::BuildToBoolean(Node* input, TypeFeedbackId feedback_id) { 3075 Node* AstGraphBuilder::BuildToBoolean(Node* input, TypeFeedbackId feedback_id) {
3072 if (Node* node = TryFastToBoolean(input)) return node; 3076 if (Node* node = TryFastToBoolean(input)) return node;
3073 ToBooleanHints hints = ToBooleanHint::kAny; 3077 ToBooleanHints hints = ToBooleanHint::kAny;
3074 return NewNode(javascript()->ToBoolean(hints), input); 3078 return NewNode(javascript()->ToBoolean(hints), input);
3075 } 3079 }
3076 3080
3077 3081
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
3492 contexts()->back() = effect = 3496 contexts()->back() = effect =
3493 graph->NewNode(guard_op, contexts()->back(), effect, osr_loop_entry); 3497 graph->NewNode(guard_op, contexts()->back(), effect, osr_loop_entry);
3494 3498
3495 // The innermost context is the OSR value, and the outer contexts are 3499 // The innermost context is the OSR value, and the outer contexts are
3496 // reconstructed by dynamically walking up the context chain. 3500 // reconstructed by dynamically walking up the context chain.
3497 const Operator* load_op = 3501 const Operator* load_op =
3498 builder_->javascript()->LoadContext(0, Context::PREVIOUS_INDEX, true); 3502 builder_->javascript()->LoadContext(0, Context::PREVIOUS_INDEX, true);
3499 Node* osr_context = effect = contexts()->back(); 3503 Node* osr_context = effect = contexts()->back();
3500 int last = static_cast<int>(contexts()->size() - 1); 3504 int last = static_cast<int>(contexts()->size() - 1);
3501 for (int i = last - 1; i >= 0; i--) { 3505 for (int i = last - 1; i >= 0; i--) {
3502 osr_context = effect = 3506 osr_context = effect = graph->NewNode(load_op, osr_context, effect);
3503 graph->NewNode(load_op, osr_context, osr_context, effect);
3504 contexts()->at(i) = osr_context; 3507 contexts()->at(i) = osr_context;
3505 } 3508 }
3506 UpdateEffectDependency(effect); 3509 UpdateEffectDependency(effect);
3507 } 3510 }
3508 3511
3509 void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned) { 3512 void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned) {
3510 int size = static_cast<int>(values()->size()); 3513 int size = static_cast<int>(values()->size());
3511 3514
3512 Node* control = builder_->NewLoop(); 3515 Node* control = builder_->NewLoop();
3513 if (assigned == nullptr) { 3516 if (assigned == nullptr) {
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
3621 float invocation_frequency, LoopAssignmentAnalysis* loop_assignment, 3624 float invocation_frequency, LoopAssignmentAnalysis* loop_assignment,
3622 SourcePositionTable* source_positions, int inlining_id) 3625 SourcePositionTable* source_positions, int inlining_id)
3623 : AstGraphBuilder(local_zone, info, jsgraph, invocation_frequency, 3626 : AstGraphBuilder(local_zone, info, jsgraph, invocation_frequency,
3624 loop_assignment), 3627 loop_assignment),
3625 source_positions_(source_positions), 3628 source_positions_(source_positions),
3626 start_position_(info->shared_info()->start_position(), inlining_id) {} 3629 start_position_(info->shared_info()->start_position(), inlining_id) {}
3627 3630
3628 } // namespace compiler 3631 } // namespace compiler
3629 } // namespace internal 3632 } // namespace internal
3630 } // namespace v8 3633 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/bytecode-graph-builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698