Handle missing context when getting frame details

This bug was triggered by a very specific combination:

* A context-allocated variable at script scope.
* OSR optimization.
* A scheduled breakpoint, which triggers at stack checks.

Stack checks differ from other possible breakpoint locations in that
the context (among other things) may be in a register and not on the
stack, making it impossible to recover during deoptimization. The
frame_inspector then returns undefined when asked for the context.

In GetFrameDetails, handle this case by omitting all context-allocated
variables.

BUG=v8:5279

Review-Url: https://codereview.chromium.org/2245603002
Cr-Commit-Position: refs/heads/master@{#38611}
This commit is contained in:
jgruber 2016-08-12 04:19:56 -07:00 committed by Commit bot
parent 1b43aab528
commit d252808011
2 changed files with 25 additions and 4 deletions

View File

@ -606,8 +606,12 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
DCHECK(*scope_info != ScopeInfo::Empty(isolate));
// Get the locals names and values into a temporary array.
int local_count = scope_info->LocalCount();
for (int slot = 0; slot < scope_info->LocalCount(); ++slot) {
Handle<Object> maybe_context = frame_inspector.GetContext();
const int local_count_with_synthetic = maybe_context->IsContext()
? scope_info->LocalCount()
: scope_info->StackLocalCount();
int local_count = local_count_with_synthetic;
for (int slot = 0; slot < local_count_with_synthetic; ++slot) {
// Hide compiler-introduced temporary variables, whether on the stack or on
// the context.
if (ScopeInfo::VariableIsSynthetic(scope_info->LocalName(slot))) {
@ -633,8 +637,9 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
}
if (locals.length() < local_count * 2) {
// Get the context containing declarations.
Handle<Context> context(
Handle<Context>::cast(frame_inspector.GetContext())->closure_context());
DCHECK(maybe_context->IsContext());
Handle<Context> context(Context::cast(*maybe_context)->closure_context());
for (; i < scope_info->LocalCount(); ++i) {
Handle<String> name(scope_info->LocalName(i));
if (ScopeInfo::VariableIsSynthetic(*name)) continue;

View File

@ -0,0 +1,16 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --expose-debug-as debug
var Debug = debug.Debug;
Debug.setListener(() => undefined);
const myObj = {};
for (let i = 0; i < 10; i++) {
%OptimizeOsr();
%ScheduleBreak();
}