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

Unified Diff: src/compiler.cc

Issue 1233073005: Debugger: prepare code for debugging on a per-function basis. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: addressed comments. Created 5 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler.h ('k') | src/compiler/js-inlining.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler.cc
diff --git a/src/compiler.cc b/src/compiler.cc
index ab0a620bedc007000931dd8b43529baaec61d2c0..fc6760d3f26386b8a23cb09316dbf78a5b17de30 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -338,11 +338,10 @@ class HOptimizedGraphBuilderWithPositions: public HOptimizedGraphBuilder {
OptimizedCompileJob::Status OptimizedCompileJob::CreateGraph() {
DCHECK(info()->IsOptimizing());
- DCHECK(!info()->IsCompilingForDebugging());
// Do not use Crankshaft/TurboFan if we need to be able to set break points.
- if (isolate()->debug()->has_break_points()) {
- return RetryOptimization(kDebuggerHasBreakPoints);
+ if (info()->shared_info()->HasDebugInfo()) {
+ return AbortOptimization(kFunctionBeingDebugged);
}
// Limit the number of times we try to optimize functions.
@@ -905,18 +904,6 @@ MaybeHandle<Code> Compiler::GetLazyCode(Handle<JSFunction> function) {
}
-MaybeHandle<Code> Compiler::GetUnoptimizedCode(
- Handle<SharedFunctionInfo> shared) {
- DCHECK(!shared->GetIsolate()->has_pending_exception());
- DCHECK(!shared->is_compiled());
-
- Zone zone;
- ParseInfo parse_info(&zone, shared);
- CompilationInfo info(&parse_info);
- return GetUnoptimizedCodeCommon(&info);
-}
-
-
bool Compiler::EnsureCompiled(Handle<JSFunction> function,
ClearExceptionFlag flag) {
if (function->is_compiled()) return true;
@@ -979,45 +966,41 @@ bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) {
}
-// Compile full code for debugging. This code will have debug break slots
-// and deoptimization information. Deoptimization information is required
-// in case that an optimized version of this function is still activated on
-// the stack. It will also make sure that the full code is compiled with
-// the same flags as the previous version, that is flags which can change
-// the code generated. The current method of mapping from already compiled
-// full code without debug break slots to full code with debug break slots
-// depends on the generated code is otherwise exactly the same.
-// If compilation fails, just keep the existing code.
-MaybeHandle<Code> Compiler::GetDebugCode(Handle<JSFunction> function) {
- CompilationInfoWithZone info(function);
- Isolate* isolate = info.isolate();
- VMState<COMPILER> state(isolate);
-
- info.MarkAsDebug();
-
- DCHECK(!isolate->has_pending_exception());
- Handle<Code> old_code(function->shared()->code());
- DCHECK(old_code->kind() == Code::FUNCTION);
- DCHECK(!old_code->has_debug_break_slots());
-
- info.MarkCompilingForDebugging();
- if (old_code->is_compiled_optimizable()) {
- info.EnableDeoptimizationSupport();
- } else {
- info.MarkNonOptimizable();
+MaybeHandle<Code> CompileForDebugging(CompilationInfo* info) {
+ info->MarkAsDebug();
+ VMState<COMPILER> state(info->isolate());
+ if (info->shared_info()->is_compiled()) {
+ if (info->shared_info()->code()->is_compiled_optimizable()) {
+ info->EnableDeoptimizationSupport();
+ } else {
+ info->MarkNonOptimizable();
+ }
}
- MaybeHandle<Code> maybe_new_code = GetUnoptimizedCodeCommon(&info);
+ MaybeHandle<Code> maybe_new_code = GetUnoptimizedCodeCommon(info);
Handle<Code> new_code;
if (!maybe_new_code.ToHandle(&new_code)) {
- isolate->clear_pending_exception();
- } else {
- DCHECK_EQ(old_code->is_compiled_optimizable(),
- new_code->is_compiled_optimizable());
+ info->isolate()->clear_pending_exception();
}
return maybe_new_code;
}
+MaybeHandle<Code> Compiler::GetDebugCode(Handle<JSFunction> function) {
+ CompilationInfoWithZone info(function);
+ VMState<COMPILER> state(info.isolate());
+ return CompileForDebugging(&info);
+}
+
+
+MaybeHandle<Code> Compiler::GetDebugCode(Handle<SharedFunctionInfo> shared) {
+ DCHECK(shared->allows_lazy_compilation_without_context());
+ Zone zone;
+ ParseInfo parse_info(&zone, shared);
+ CompilationInfo info(&parse_info);
+ return CompileForDebugging(&info);
+}
+
+
void Compiler::CompileForLiveEdit(Handle<Script> script) {
// TODO(635): support extensions.
Zone zone;
@@ -1065,12 +1048,13 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
{ VMState<COMPILER> state(info->isolate());
if (parse_info->literal() == NULL) {
// Parse the script if needed (if it's already parsed, function() is
- // non-NULL).
+ // non-NULL). If compiling for debugging, we may eagerly compile inner
+ // functions, so do not parse lazily in that case.
ScriptCompiler::CompileOptions options = parse_info->compile_options();
bool parse_allow_lazy = (options == ScriptCompiler::kConsumeParserCache ||
String::cast(script->source())->length() >
FLAG_min_preparse_length) &&
- !Compiler::DebuggerWantsEagerCompilation(isolate);
+ !info->is_debug();
parse_info->set_allow_lazy_parsing(parse_allow_lazy);
if (!parse_allow_lazy &&
@@ -1180,6 +1164,8 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
parse_info.set_parse_restriction(restriction);
parse_info.set_context(context);
+ // If we eval from debug code, compile for debugging as well.
+ if (outer_info->HasDebugCode()) info.MarkAsDebug();
Debug::RecordEvalCaller(script);
shared_info = CompileToplevel(&info);
@@ -1371,9 +1357,13 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
// We found an existing shared function info. If it's already compiled,
// don't worry about compiling it, and simply return it. If it's not yet
// compiled, continue to decide whether to eagerly compile.
+ // Carry on if we are compiling eager to obtain code for debugging,
+ // unless we already have code with debut break slots.
Handle<SharedFunctionInfo> existing;
if (maybe_existing.ToHandle(&existing) && existing->is_compiled()) {
- return existing;
+ if (!outer_info->is_debug() || existing->HasDebugCode()) {
+ return existing;
+ }
}
Zone zone;
@@ -1384,6 +1374,7 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
parse_info.set_language_mode(literal->scope()->language_mode());
if (outer_info->will_serialize()) info.PrepareForSerializing();
if (outer_info->is_first_compile()) info.MarkAsFirstCompile();
+ if (outer_info->is_debug()) info.MarkAsDebug();
LiveEditFunctionTracker live_edit_tracker(isolate, literal);
// Determine if the function can be lazily compiled. This is necessary to
@@ -1396,9 +1387,11 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
// of functions without an outer context when setting a breakpoint through
// Debug::FindSharedFunctionInfoInScript.
bool allow_lazy_without_ctx = literal->AllowsLazyCompilationWithoutContext();
- bool allow_lazy =
- literal->AllowsLazyCompilation() &&
- !DebuggerWantsEagerCompilation(isolate, allow_lazy_without_ctx);
+ // Compile eagerly for live edit. When compiling debug code, eagerly compile
+ // unless we can lazily compile without the context.
+ bool allow_lazy = literal->AllowsLazyCompilation() &&
+ !LiveEditFunctionTracker::IsActive(isolate) &&
+ (!info.is_debug() || allow_lazy_without_ctx);
if (outer_info->parse_info()->is_toplevel() && outer_info->will_serialize()) {
// Make sure that if the toplevel code (possibly to be serialized),
@@ -1463,8 +1456,8 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
live_edit_tracker.RecordFunctionInfo(result, literal, info.zone());
return result;
} else if (!lazy) {
- // We have additional data from compilation now.
- DCHECK(!existing->is_compiled());
+ // Assert that we are not overwriting (possibly patched) debug code.
+ DCHECK(!existing->HasDebugCode());
existing->ReplaceCode(*info.code());
existing->set_scope_info(*scope_info);
existing->set_feedback_vector(*info.feedback_vector());
@@ -1478,6 +1471,10 @@ MaybeHandle<Code> Compiler::GetOptimizedCode(Handle<JSFunction> function,
ConcurrencyMode mode,
BailoutId osr_ast_id,
JavaScriptFrame* osr_frame) {
+ Isolate* isolate = function->GetIsolate();
+ Handle<SharedFunctionInfo> shared(function->shared(), isolate);
+ if (shared->HasDebugInfo()) return MaybeHandle<Code>();
+
Handle<Code> cached_code;
if (GetCodeFromOptimizedCodeMap(
function, osr_ast_id).ToHandle(&cached_code)) {
@@ -1492,10 +1489,8 @@ MaybeHandle<Code> Compiler::GetOptimizedCode(Handle<JSFunction> function,
return cached_code;
}
- Isolate* isolate = function->GetIsolate();
DCHECK(AllowCompilation::IsAllowed(isolate));
- Handle<SharedFunctionInfo> shared(function->shared(), isolate);
if (!shared->is_compiled() ||
shared->scope_info() == ScopeInfo::Empty(isolate)) {
// The function was never compiled. Compile it unoptimized first.
@@ -1557,19 +1552,18 @@ Handle<Code> Compiler::GetConcurrentlyOptimizedCode(OptimizedCompileJob* job) {
Handle<SharedFunctionInfo> shared = info->shared_info();
shared->code()->set_profiler_ticks(0);
+ DCHECK(!shared->HasDebugInfo());
+
// 1) Optimization on the concurrent thread may have failed.
// 2) The function may have already been optimized by OSR. Simply continue.
// Except when OSR already disabled optimization for some reason.
// 3) The code may have already been invalidated due to dependency change.
- // 4) Debugger may have been activated.
- // 5) Code generation may have failed.
+ // 4) Code generation may have failed.
if (job->last_status() == OptimizedCompileJob::SUCCEEDED) {
if (shared->optimization_disabled()) {
job->RetryOptimization(kOptimizationDisabled);
} else if (info->dependencies()->HasAborted()) {
job->RetryOptimization(kBailedOutDueToDependencyChange);
- } else if (isolate->debug()->has_break_points()) {
- job->RetryOptimization(kDebuggerHasBreakPoints);
} else if (job->GenerateCode() == OptimizedCompileJob::SUCCEEDED) {
RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info.get(), shared);
if (shared->SearchOptimizedCodeMap(info->context()->native_context(),
@@ -1595,15 +1589,6 @@ Handle<Code> Compiler::GetConcurrentlyOptimizedCode(OptimizedCompileJob* job) {
}
-bool Compiler::DebuggerWantsEagerCompilation(Isolate* isolate,
- bool allow_lazy_without_ctx) {
- if (LiveEditFunctionTracker::IsActive(isolate)) return true;
- Debug* debug = isolate->debug();
- bool debugging = debug->is_active() || debug->has_break_points();
- return debugging && !allow_lazy_without_ctx;
-}
-
-
CompilationPhase::CompilationPhase(const char* name, CompilationInfo* info)
: name_(name), info_(info) {
if (FLAG_hydrogen_stats) {
« no previous file with comments | « src/compiler.h ('k') | src/compiler/js-inlining.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698