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

Side by Side Diff: src/runtime/runtime-debug.cc

Issue 1088503003: Avoid modifying the real context chain for debug evaluation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Minor fixes Created 5 years, 8 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 | « no previous file | test/mjsunit/debug-evaluate-locals-capturing.js » ('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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/arguments.h" 8 #include "src/arguments.h"
9 #include "src/compiler.h" 9 #include "src/compiler.h"
10 #include "src/debug.h" 10 #include "src/debug.h"
(...skipping 2235 matching lines...) Expand 10 before | Expand all | Expand 10 after
2246 2246
2247 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2247 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2248 isolate, materialized, 2248 isolate, materialized,
2249 MaterializeArgumentsObject(isolate, materialized, function)); 2249 MaterializeArgumentsObject(isolate, materialized, function));
2250 } 2250 }
2251 2251
2252 // At this point, the lookup chain may look like this: 2252 // At this point, the lookup chain may look like this:
2253 // [inner context] -> [function stack]+[function context] -> [outer context] 2253 // [inner context] -> [function stack]+[function context] -> [outer context]
2254 // The function stack is not an actual context, it complements the function 2254 // The function stack is not an actual context, it complements the function
2255 // context. In order to have the same lookup chain when debug-evaluating, 2255 // context. In order to have the same lookup chain when debug-evaluating,
2256 // we materialize the stack and insert it into the context chain as a 2256 // we:
2257 // with-context before the function context. 2257 // - clone inner context
2258 // [inner context] -> [with context] -> [function context] -> [outer context] 2258 // - materialize the stack and insert it into the context chain as a
2259 // with-context before the function context.
2260 // [inner context clone] -> [with context] -> [function context] ->
2261 // [outer context]
2259 // Ordering the with-context before the function context forces a dynamic 2262 // Ordering the with-context before the function context forces a dynamic
2260 // lookup instead of a static lookup that could fail as the scope info is 2263 // lookup instead of a static lookup that could fail as the scope info is
2261 // outdated and may expect variables to still be stack-allocated. 2264 // outdated and may expect variables to still be stack-allocated.
2262 // Afterwards, we write changes to the with-context back to the stack 2265 // Afterwards, we write changes to the with-context back to the stack, and
2263 // and remove it from the context chain. 2266 // write changes in cloned contexts back to original contexts.
2264 // This could cause lookup failures if debug-evaluate creates a closure that
2265 // uses this temporary context chain.
2266 2267
2267 DCHECK(!eval_context.is_null()); 2268 DCHECK(!eval_context.is_null());
2268 Handle<Context> function_context = eval_context; 2269 Handle<Context> function_context = eval_context;
2269 Handle<Context> outer_context(function->context(), isolate); 2270 Handle<Context> outer_context(function->context(), isolate);
2270 Handle<Context> inner_context; 2271 Handle<Context> inner_context;
2271 // We iterate to find the function's context. If the function has no 2272 Handle<Context> innermost_context;
2272 // context-allocated variables, we iterate until we hit the outer context. 2273
2274 // We iterate to find the function's context, cloning until we hit it.
2275 // If the function has no context-allocated variables, we iterate until
2276 // we hit the outer context.
2273 while (!function_context->IsFunctionContext() && 2277 while (!function_context->IsFunctionContext() &&
2274 !function_context->IsScriptContext() && 2278 !function_context->IsScriptContext() &&
2275 !function_context.is_identical_to(outer_context)) { 2279 !function_context.is_identical_to(outer_context)) {
2276 inner_context = function_context; 2280 Handle<Context> clone = Handle<Context>::cast(
2281 FixedArray::CopySize(function_context, function_context->length()));
2282 if (!inner_context.is_null()) {
2283 inner_context->set_previous(*clone);
2284 } else {
2285 innermost_context = clone;
2286 }
2287 inner_context = clone;
2277 function_context = Handle<Context>(function_context->previous(), isolate); 2288 function_context = Handle<Context>(function_context->previous(), isolate);
2278 } 2289 }
2279 2290
2280 Handle<Context> materialized_context = isolate->factory()->NewWithContext( 2291 Handle<Context> materialized_context = isolate->factory()->NewWithContext(
2281 function, function_context, materialized); 2292 function, function_context, materialized);
2282 2293
2283 if (inner_context.is_null()) { 2294 if (inner_context.is_null()) {
2284 // No inner context. The with-context is now inner-most. 2295 // No inner context. The with-context is now inner-most.
2285 eval_context = materialized_context; 2296 innermost_context = materialized_context;
2286 } else { 2297 } else {
2287 inner_context->set_previous(*materialized_context); 2298 inner_context->set_previous(*materialized_context);
2288 } 2299 }
2289 2300
2290 Handle<Object> receiver(frame->receiver(), isolate); 2301 Handle<Object> receiver(frame->receiver(), isolate);
2291 MaybeHandle<Object> maybe_result = DebugEvaluate( 2302 MaybeHandle<Object> maybe_result =
2292 isolate, outer_info, eval_context, context_extension, receiver, source); 2303 DebugEvaluate(isolate, outer_info, innermost_context, context_extension,
2293 2304 receiver, source);
2294 // Remove with-context if it was inserted in between.
2295 if (!inner_context.is_null()) inner_context->set_previous(*function_context);
2296 2305
2297 Handle<Object> result; 2306 Handle<Object> result;
2298 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result); 2307 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result);
2299 2308
2300 // Write back potential changes to materialized stack locals to the stack. 2309 // Write back potential changes to materialized stack locals to the stack.
2301 UpdateStackLocalsFromMaterializedObject(isolate, materialized, function, 2310 UpdateStackLocalsFromMaterializedObject(isolate, materialized, function,
2302 frame, inlined_jsframe_index); 2311 frame, inlined_jsframe_index);
2303 2312
2313 while (!innermost_context.is_identical_to(materialized_context)) {
2314 DCHECK(eval_context->map() == innermost_context->map());
2315 innermost_context->CopyTo(
2316 Context::MIN_CONTEXT_SLOTS, *eval_context, Context::MIN_CONTEXT_SLOTS,
2317 innermost_context->length() - Context::MIN_CONTEXT_SLOTS);
2318 innermost_context = handle(innermost_context->previous(), isolate);
2319 eval_context = handle(eval_context->previous(), isolate);
2320 }
2321
2304 return *result; 2322 return *result;
2305 } 2323 }
2306 2324
2307 2325
2308 RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) { 2326 RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) {
2309 HandleScope scope(isolate); 2327 HandleScope scope(isolate);
2310 2328
2311 // Check the execution state and decode arguments frame and source to be 2329 // Check the execution state and decode arguments frame and source to be
2312 // evaluated. 2330 // evaluated.
2313 DCHECK(args.length() == 4); 2331 DCHECK(args.length() == 4);
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
2819 return Smi::FromInt(isolate->debug()->is_active()); 2837 return Smi::FromInt(isolate->debug()->is_active());
2820 } 2838 }
2821 2839
2822 2840
2823 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { 2841 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) {
2824 UNIMPLEMENTED(); 2842 UNIMPLEMENTED();
2825 return NULL; 2843 return NULL;
2826 } 2844 }
2827 } 2845 }
2828 } // namespace v8::internal 2846 } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/debug-evaluate-locals-capturing.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698