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

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

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

Powered by Google App Engine
This is Rietveld 408576698