[debugger,compiler] do not recompile already compiled inner functions.

GetSharedFunctionInfo will compile inner functions if we get the
compile-eager hint, even if the shared function info already exists, and
the function already has been compiled. This breaks suspended generator
objects.

R=mstarzinger@chromium.org, neis@chromium.org
BUG=v8:5575

Review-Url: https://codereview.chromium.org/2494043002
Cr-Commit-Position: refs/heads/master@{#40936}
This commit is contained in:
yangguo 2016-11-11 07:53:02 -08:00 committed by Commit bot
parent df5b86de4c
commit 389d0dd115
4 changed files with 80 additions and 1 deletions

View File

@ -1591,7 +1591,15 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
RuntimeCallTimerScope runtimeTimer(isolate, &RuntimeCallStats::CompileCode);
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode");
if (!literal->ShouldEagerCompile()) {
if (result->is_compiled()) {
// If this inner function is already compiled, we don't need to compile
// again. When compiling for debug, we are not interested in having debug
// break slots in inner functions, neither for setting break points nor
// for revealing inner functions.
// This is especially important for generators. We must not replace the
// code for generators, as there may be suspended generator objects.
return result;
} else if (!literal->ShouldEagerCompile()) {
info.SetCode(isolate->builtins()->CompileLazy());
Scope* outer_scope = literal->scope()->GetOuterScopeWithContext();
if (outer_scope) {

View File

@ -0,0 +1,21 @@
// 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.
Debug = debug.Debug;
Debug.setListener(function() {});
function factory() {
return function* generator() {
debugger;
yield 42;
}
}
Debug.setBreakPoint(function(){}, 0, 0);
var generator = factory();
var obj = generator();
obj.next();
Debug.setBreakPoint(factory, 0, 0);
obj.next();

View File

@ -0,0 +1,21 @@
// 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.
Debug = debug.Debug;
Debug.setListener(function() {});
function main() {
function* boo() {
debugger;
yield 42;
}
var gen = boo();
gen.next();
Debug.setBreakPoint(main, 0, 0);
gen.next();
}
main();

View File

@ -0,0 +1,29 @@
// 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.
Debug = debug.Debug;
let n = 0;
function listener(event, exec_state, event_data, data) {
if (event == Debug.DebugEvent.Break) {
if (n++ == 0) {
Debug.setBreakPoint(main, 0, 0);
}
}
}
Debug.setListener(listener);
function main() {
function* boo() {
debugger;
yield;
}
var gen = boo();
gen.next();
gen.next();
}
main();