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

Side by Side Diff: src/interpreter/bytecode-generator.cc

Issue 2336643002: [Interpreter] Move context chain search loop to handler (Closed)
Patch Set: Fix documentation nits Created 4 years, 3 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
« no previous file with comments | « src/interpreter/bytecode-array-builder.cc ('k') | src/interpreter/bytecodes.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/interpreter/bytecode-generator.h" 5 #include "src/interpreter/bytecode-generator.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/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/compilation-info.h" 10 #include "src/compilation-info.h"
(...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 case VariableLocation::PARAMETER: 916 case VariableLocation::PARAMETER:
917 if (variable->binding_needs_init()) { 917 if (variable->binding_needs_init()) {
918 // The parameter indices are shifted by 1 (receiver is variable 918 // The parameter indices are shifted by 1 (receiver is variable
919 // index -1 but is parameter index 0 in BytecodeArrayBuilder). 919 // index -1 but is parameter index 0 in BytecodeArrayBuilder).
920 Register destination(builder()->Parameter(variable->index() + 1)); 920 Register destination(builder()->Parameter(variable->index() + 1));
921 builder()->LoadTheHole().StoreAccumulatorInRegister(destination); 921 builder()->LoadTheHole().StoreAccumulatorInRegister(destination);
922 } 922 }
923 break; 923 break;
924 case VariableLocation::CONTEXT: 924 case VariableLocation::CONTEXT:
925 if (variable->binding_needs_init()) { 925 if (variable->binding_needs_init()) {
926 DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope()));
926 builder()->LoadTheHole().StoreContextSlot(execution_context()->reg(), 927 builder()->LoadTheHole().StoreContextSlot(execution_context()->reg(),
927 variable->index()); 928 variable->index(), 0);
928 } 929 }
929 break; 930 break;
930 case VariableLocation::LOOKUP: { 931 case VariableLocation::LOOKUP: {
931 DCHECK_EQ(VAR, variable->mode()); 932 DCHECK_EQ(VAR, variable->mode());
932 DCHECK(!variable->binding_needs_init()); 933 DCHECK(!variable->binding_needs_init());
933 934
934 Register name = register_allocator()->NewRegister(); 935 Register name = register_allocator()->NewRegister();
935 936
936 builder() 937 builder()
937 ->LoadLiteral(variable->name()) 938 ->LoadLiteral(variable->name())
(...skipping 18 matching lines...) Expand all
956 case VariableLocation::PARAMETER: 957 case VariableLocation::PARAMETER:
957 case VariableLocation::LOCAL: { 958 case VariableLocation::LOCAL: {
958 VisitForAccumulatorValue(decl->fun()); 959 VisitForAccumulatorValue(decl->fun());
959 VisitVariableAssignment(variable, Token::INIT, 960 VisitVariableAssignment(variable, Token::INIT,
960 FeedbackVectorSlot::Invalid()); 961 FeedbackVectorSlot::Invalid());
961 break; 962 break;
962 } 963 }
963 case VariableLocation::CONTEXT: { 964 case VariableLocation::CONTEXT: {
964 DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope())); 965 DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope()));
965 VisitForAccumulatorValue(decl->fun()); 966 VisitForAccumulatorValue(decl->fun());
966 builder()->StoreContextSlot(execution_context()->reg(), 967 builder()->StoreContextSlot(execution_context()->reg(), variable->index(),
967 variable->index()); 968 0);
968 break; 969 break;
969 } 970 }
970 case VariableLocation::LOOKUP: { 971 case VariableLocation::LOOKUP: {
971 register_allocator()->PrepareForConsecutiveAllocations(2); 972 register_allocator()->PrepareForConsecutiveAllocations(2);
972 Register name = register_allocator()->NextConsecutiveRegister(); 973 Register name = register_allocator()->NextConsecutiveRegister();
973 Register literal = register_allocator()->NextConsecutiveRegister(); 974 Register literal = register_allocator()->NextConsecutiveRegister();
974 builder()->LoadLiteral(variable->name()).StoreAccumulatorInRegister(name); 975 builder()->LoadLiteral(variable->name()).StoreAccumulatorInRegister(name);
975 976
976 VisitForAccumulatorValue(decl->fun()); 977 VisitForAccumulatorValue(decl->fun());
977 builder()->StoreAccumulatorInRegister(literal).CallRuntime( 978 builder()->StoreAccumulatorInRegister(literal).CallRuntime(
(...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after
1946 case VariableLocation::UNALLOCATED: { 1947 case VariableLocation::UNALLOCATED: {
1947 builder()->LoadGlobal(feedback_index(slot), typeof_mode); 1948 builder()->LoadGlobal(feedback_index(slot), typeof_mode);
1948 break; 1949 break;
1949 } 1950 }
1950 case VariableLocation::CONTEXT: { 1951 case VariableLocation::CONTEXT: {
1951 int depth = execution_context()->ContextChainDepth(variable->scope()); 1952 int depth = execution_context()->ContextChainDepth(variable->scope());
1952 ContextScope* context = execution_context()->Previous(depth); 1953 ContextScope* context = execution_context()->Previous(depth);
1953 Register context_reg; 1954 Register context_reg;
1954 if (context) { 1955 if (context) {
1955 context_reg = context->reg(); 1956 context_reg = context->reg();
1957 depth = 0;
1956 } else { 1958 } else {
1957 context_reg = register_allocator()->NewRegister(); 1959 context_reg = execution_context()->reg();
1958 // Walk the context chain to find the context at the given depth.
1959 // TODO(rmcilroy): Perform this work in a bytecode handler once we have
1960 // a generic mechanism for performing jumps in interpreter.cc.
1961 // TODO(mythria): Also update bytecode graph builder with correct depth
1962 // when this changes.
1963 builder()
1964 ->LoadAccumulatorWithRegister(execution_context()->reg())
1965 .StoreAccumulatorInRegister(context_reg);
1966 for (int i = 0; i < depth; ++i) {
1967 builder()
1968 ->LoadContextSlot(context_reg, Context::PREVIOUS_INDEX)
1969 .StoreAccumulatorInRegister(context_reg);
1970 }
1971 } 1960 }
1972 1961
1973 builder()->LoadContextSlot(context_reg, variable->index()); 1962 builder()->LoadContextSlot(context_reg, variable->index(), depth);
1974 BuildHoleCheckForVariableLoad(variable); 1963 BuildHoleCheckForVariableLoad(variable);
1975 break; 1964 break;
1976 } 1965 }
1977 case VariableLocation::LOOKUP: { 1966 case VariableLocation::LOOKUP: {
1978 builder()->LoadLookupSlot(variable->name(), typeof_mode); 1967 builder()->LoadLookupSlot(variable->name(), typeof_mode);
1979 break; 1968 break;
1980 } 1969 }
1981 case VariableLocation::MODULE: 1970 case VariableLocation::MODULE:
1982 UNREACHABLE(); 1971 UNREACHABLE();
1983 } 1972 }
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
2128 language_mode()); 2117 language_mode());
2129 break; 2118 break;
2130 } 2119 }
2131 case VariableLocation::CONTEXT: { 2120 case VariableLocation::CONTEXT: {
2132 int depth = execution_context()->ContextChainDepth(variable->scope()); 2121 int depth = execution_context()->ContextChainDepth(variable->scope());
2133 ContextScope* context = execution_context()->Previous(depth); 2122 ContextScope* context = execution_context()->Previous(depth);
2134 Register context_reg; 2123 Register context_reg;
2135 2124
2136 if (context) { 2125 if (context) {
2137 context_reg = context->reg(); 2126 context_reg = context->reg();
2127 depth = 0;
2138 } else { 2128 } else {
2139 Register value_temp = register_allocator()->NewRegister(); 2129 context_reg = execution_context()->reg();
2140 context_reg = register_allocator()->NewRegister();
2141 // Walk the context chain to find the context at the given depth.
2142 // TODO(rmcilroy): Perform this work in a bytecode handler once we have
2143 // a generic mechanism for performing jumps in interpreter.cc.
2144 // TODO(mythria): Also update bytecode graph builder with correct depth
2145 // when this changes.
2146 builder()
2147 ->StoreAccumulatorInRegister(value_temp)
2148 .LoadAccumulatorWithRegister(execution_context()->reg())
2149 .StoreAccumulatorInRegister(context_reg);
2150 for (int i = 0; i < depth; ++i) {
2151 builder()
2152 ->LoadContextSlot(context_reg, Context::PREVIOUS_INDEX)
2153 .StoreAccumulatorInRegister(context_reg);
2154 }
2155 builder()->LoadAccumulatorWithRegister(value_temp);
2156 } 2130 }
2157 2131
2158 if (hole_check_required) { 2132 if (hole_check_required) {
2159 // Load destination to check for hole. 2133 // Load destination to check for hole.
2160 Register value_temp = register_allocator()->NewRegister(); 2134 Register value_temp = register_allocator()->NewRegister();
2161 builder() 2135 builder()
2162 ->StoreAccumulatorInRegister(value_temp) 2136 ->StoreAccumulatorInRegister(value_temp)
2163 .LoadContextSlot(context_reg, variable->index()); 2137 .LoadContextSlot(context_reg, variable->index(), depth);
2164 2138
2165 BuildHoleCheckForVariableAssignment(variable, op); 2139 BuildHoleCheckForVariableAssignment(variable, op);
2166 builder()->LoadAccumulatorWithRegister(value_temp); 2140 builder()->LoadAccumulatorWithRegister(value_temp);
2167 } 2141 }
2168 2142
2169 if (mode != CONST || op == Token::INIT) { 2143 if (mode != CONST || op == Token::INIT) {
2170 builder()->StoreContextSlot(context_reg, variable->index()); 2144 builder()->StoreContextSlot(context_reg, variable->index(), depth);
2171 } else if (variable->throw_on_const_assignment(language_mode())) { 2145 } else if (variable->throw_on_const_assignment(language_mode())) {
2172 builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(), 0); 2146 builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(), 0);
2173 } 2147 }
2174 break; 2148 break;
2175 } 2149 }
2176 case VariableLocation::LOOKUP: { 2150 case VariableLocation::LOOKUP: {
2177 builder()->StoreLookupSlot(variable->name(), language_mode()); 2151 builder()->StoreLookupSlot(variable->name(), language_mode());
2178 break; 2152 break;
2179 } 2153 }
2180 case VariableLocation::MODULE: 2154 case VariableLocation::MODULE:
(...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after
2826 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 2800 VariableProxy* proxy = expr->expression()->AsVariableProxy();
2827 Variable* variable = proxy->var(); 2801 Variable* variable = proxy->var();
2828 DCHECK(is_sloppy(language_mode()) || variable->is_this()); 2802 DCHECK(is_sloppy(language_mode()) || variable->is_this());
2829 switch (variable->location()) { 2803 switch (variable->location()) {
2830 case VariableLocation::UNALLOCATED: { 2804 case VariableLocation::UNALLOCATED: {
2831 // Global var, let, const or variables not explicitly declared. 2805 // Global var, let, const or variables not explicitly declared.
2832 Register native_context = register_allocator()->NewRegister(); 2806 Register native_context = register_allocator()->NewRegister();
2833 Register global_object = register_allocator()->NewRegister(); 2807 Register global_object = register_allocator()->NewRegister();
2834 builder() 2808 builder()
2835 ->LoadContextSlot(execution_context()->reg(), 2809 ->LoadContextSlot(execution_context()->reg(),
2836 Context::NATIVE_CONTEXT_INDEX) 2810 Context::NATIVE_CONTEXT_INDEX, 0)
2837 .StoreAccumulatorInRegister(native_context) 2811 .StoreAccumulatorInRegister(native_context)
2838 .LoadContextSlot(native_context, Context::EXTENSION_INDEX) 2812 .LoadContextSlot(native_context, Context::EXTENSION_INDEX, 0)
2839 .StoreAccumulatorInRegister(global_object) 2813 .StoreAccumulatorInRegister(global_object)
2840 .LoadLiteral(variable->name()) 2814 .LoadLiteral(variable->name())
2841 .Delete(global_object, language_mode()); 2815 .Delete(global_object, language_mode());
2842 break; 2816 break;
2843 } 2817 }
2844 case VariableLocation::PARAMETER: 2818 case VariableLocation::PARAMETER:
2845 case VariableLocation::LOCAL: 2819 case VariableLocation::LOCAL:
2846 case VariableLocation::CONTEXT: { 2820 case VariableLocation::CONTEXT: {
2847 // Deleting local var/let/const, context variables, and arguments 2821 // Deleting local var/let/const, context variables, and arguments
2848 // does not have any effect. 2822 // does not have any effect.
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
3156 3130
3157 void BytecodeGenerator::BuildLocalActivationContextInitialization() { 3131 void BytecodeGenerator::BuildLocalActivationContextInitialization() {
3158 DeclarationScope* scope = this->scope(); 3132 DeclarationScope* scope = this->scope();
3159 3133
3160 if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) { 3134 if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) {
3161 Variable* variable = scope->receiver(); 3135 Variable* variable = scope->receiver();
3162 Register receiver(builder()->Parameter(0)); 3136 Register receiver(builder()->Parameter(0));
3163 // Context variable (at bottom of the context chain). 3137 // Context variable (at bottom of the context chain).
3164 DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); 3138 DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
3165 builder()->LoadAccumulatorWithRegister(receiver).StoreContextSlot( 3139 builder()->LoadAccumulatorWithRegister(receiver).StoreContextSlot(
3166 execution_context()->reg(), variable->index()); 3140 execution_context()->reg(), variable->index(), 0);
3167 } 3141 }
3168 3142
3169 // Copy parameters into context if necessary. 3143 // Copy parameters into context if necessary.
3170 int num_parameters = scope->num_parameters(); 3144 int num_parameters = scope->num_parameters();
3171 for (int i = 0; i < num_parameters; i++) { 3145 for (int i = 0; i < num_parameters; i++) {
3172 Variable* variable = scope->parameter(i); 3146 Variable* variable = scope->parameter(i);
3173 if (!variable->IsContextSlot()) continue; 3147 if (!variable->IsContextSlot()) continue;
3174 3148
3175 // The parameter indices are shifted by 1 (receiver is variable 3149 // The parameter indices are shifted by 1 (receiver is variable
3176 // index -1 but is parameter index 0 in BytecodeArrayBuilder). 3150 // index -1 but is parameter index 0 in BytecodeArrayBuilder).
3177 Register parameter(builder()->Parameter(i + 1)); 3151 Register parameter(builder()->Parameter(i + 1));
3178 // Context variable (at bottom of the context chain). 3152 // Context variable (at bottom of the context chain).
3179 DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); 3153 DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
3180 builder()->LoadAccumulatorWithRegister(parameter) 3154 builder()->LoadAccumulatorWithRegister(parameter).StoreContextSlot(
3181 .StoreContextSlot(execution_context()->reg(), variable->index()); 3155 execution_context()->reg(), variable->index(), 0);
3182 } 3156 }
3183 } 3157 }
3184 3158
3185 void BytecodeGenerator::BuildNewLocalBlockContext(Scope* scope) { 3159 void BytecodeGenerator::BuildNewLocalBlockContext(Scope* scope) {
3186 AccumulatorResultScope accumulator_execution_result(this); 3160 AccumulatorResultScope accumulator_execution_result(this);
3187 DCHECK(scope->is_block_scope()); 3161 DCHECK(scope->is_block_scope());
3188 3162
3189 VisitFunctionClosureForContext(); 3163 VisitFunctionClosureForContext();
3190 builder()->CreateBlockContext(scope->scope_info()); 3164 builder()->CreateBlockContext(scope->scope_info());
3191 execution_result()->SetResultInAccumulator(); 3165 execution_result()->SetResultInAccumulator();
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
3293 AccumulatorResultScope accumulator_execution_result(this); 3267 AccumulatorResultScope accumulator_execution_result(this);
3294 DeclarationScope* closure_scope = 3268 DeclarationScope* closure_scope =
3295 execution_context()->scope()->GetClosureScope(); 3269 execution_context()->scope()->GetClosureScope();
3296 if (closure_scope->is_script_scope() || 3270 if (closure_scope->is_script_scope() ||
3297 closure_scope->is_module_scope()) { 3271 closure_scope->is_module_scope()) {
3298 // Contexts nested in the native context have a canonical empty function as 3272 // Contexts nested in the native context have a canonical empty function as
3299 // their closure, not the anonymous closure containing the global code. 3273 // their closure, not the anonymous closure containing the global code.
3300 Register native_context = register_allocator()->NewRegister(); 3274 Register native_context = register_allocator()->NewRegister();
3301 builder() 3275 builder()
3302 ->LoadContextSlot(execution_context()->reg(), 3276 ->LoadContextSlot(execution_context()->reg(),
3303 Context::NATIVE_CONTEXT_INDEX) 3277 Context::NATIVE_CONTEXT_INDEX, 0)
3304 .StoreAccumulatorInRegister(native_context) 3278 .StoreAccumulatorInRegister(native_context)
3305 .LoadContextSlot(native_context, Context::CLOSURE_INDEX); 3279 .LoadContextSlot(native_context, Context::CLOSURE_INDEX, 0);
3306 } else if (closure_scope->is_eval_scope()) { 3280 } else if (closure_scope->is_eval_scope()) {
3307 // Contexts created by a call to eval have the same closure as the 3281 // Contexts created by a call to eval have the same closure as the
3308 // context calling eval, not the anonymous closure containing the eval 3282 // context calling eval, not the anonymous closure containing the eval
3309 // code. Fetch it from the context. 3283 // code. Fetch it from the context.
3310 builder()->LoadContextSlot(execution_context()->reg(), 3284 builder()->LoadContextSlot(execution_context()->reg(),
3311 Context::CLOSURE_INDEX); 3285 Context::CLOSURE_INDEX, 0);
3312 } else { 3286 } else {
3313 DCHECK(closure_scope->is_function_scope()); 3287 DCHECK(closure_scope->is_function_scope());
3314 builder()->LoadAccumulatorWithRegister(Register::function_closure()); 3288 builder()->LoadAccumulatorWithRegister(Register::function_closure());
3315 } 3289 }
3316 execution_result()->SetResultInAccumulator(); 3290 execution_result()->SetResultInAccumulator();
3317 } 3291 }
3318 3292
3319 // Visits the expression |expr| and places the result in the accumulator. 3293 // Visits the expression |expr| and places the result in the accumulator.
3320 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) { 3294 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) {
3321 AccumulatorResultScope accumulator_scope(this); 3295 AccumulatorResultScope accumulator_scope(this);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
3393 return execution_context()->scope()->language_mode(); 3367 return execution_context()->scope()->language_mode();
3394 } 3368 }
3395 3369
3396 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 3370 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
3397 return TypeFeedbackVector::GetIndex(slot); 3371 return TypeFeedbackVector::GetIndex(slot);
3398 } 3372 }
3399 3373
3400 } // namespace interpreter 3374 } // namespace interpreter
3401 } // namespace internal 3375 } // namespace internal
3402 } // namespace v8 3376 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-array-builder.cc ('k') | src/interpreter/bytecodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698