Commit f455986f authored by Alexey Kozyatinskiy's avatar Alexey Kozyatinskiy Committed by Commit Bot

[inspector] speedup Debugger.getPossibleBreakpoints

In current implementation we call PrepareForBreakPoints during getting possible breakpoints, this call produce GC and iteration through heap, but it's not needed before we set real breakpoint.

On my machine, get-possible-breakpoints-master.js without CL takes ~200ms, with CL it takes ~60 ms. Running test without getPossibleBreakpoints protocol call takes ~50 ms. It means that we have (200-50)/(60-50) = 15 times faster getPossibleBreakpoints.

R=yangguo@chromium.org,jgrubber@chromium.org

Bug: none
Change-Id: If12e41cd87dbba11a89aa5895e3b4d88123d7d3d
Reviewed-on: https://chromium-review.googlesource.com/591027
Commit-Queue: Aleksey Kozyatinskiy <kozyatinskiy@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47021}
parent 6fbbe93c
......@@ -666,6 +666,7 @@ bool Debug::SetBreakPoint(Handle<JSFunction> function,
// Make sure the function is compiled and has set up the debug info.
Handle<SharedFunctionInfo> shared(function->shared());
if (!EnsureBreakInfo(shared)) return true;
CHECK(PrepareFunctionForBreakPoints(shared));
Handle<DebugInfo> debug_info(shared->GetDebugInfo());
// Source positions starts with zero.
DCHECK(*source_position >= 0);
......@@ -703,6 +704,7 @@ bool Debug::SetBreakPointForScript(Handle<Script> script,
// Make sure the function has set up the debug info.
Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(result);
if (!EnsureBreakInfo(shared)) return false;
CHECK(PrepareFunctionForBreakPoints(shared));
// Find position within function. The script position might be before the
// source position of the first function.
......@@ -810,6 +812,7 @@ void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared,
if (IsBlackboxed(shared)) return;
// Make sure the function is compiled and has set up the debug info.
if (!EnsureBreakInfo(shared)) return;
CHECK(PrepareFunctionForBreakPoints(shared));
Handle<DebugInfo> debug_info(shared->GetDebugInfo());
// Flood the function with break points.
if (debug_info->HasDebugCode()) {
......@@ -1254,7 +1257,14 @@ class RedirectActiveFunctions : public ThreadVisitor {
bool Debug::PrepareFunctionForBreakPoints(Handle<SharedFunctionInfo> shared) {
// To prepare bytecode for debugging, we already need to have the debug
// info (containing the debug copy) upfront, but since we do not recompile,
// preparing for break points cannot fail.
DCHECK(shared->is_compiled());
DCHECK(shared->HasDebugInfo());
DCHECK(shared->HasBreakInfo());
Handle<DebugInfo> debug_info = GetOrCreateDebugInfo(shared);
if (debug_info->IsPreparedForBreakpoints()) return true;
if (isolate_->concurrent_recompilation_enabled()) {
isolate_->optimizing_compile_dispatcher()->Flush(
......@@ -1311,6 +1321,8 @@ bool Debug::PrepareFunctionForBreakPoints(Handle<SharedFunctionInfo> shared) {
redirect_visitor.VisitThread(isolate_, isolate_->thread_local_top());
isolate_->thread_manager()->IterateArchivedThreads(&redirect_visitor);
debug_info->set_flags(debug_info->flags() |
DebugInfo::kPreparedForBreakpoints);
return true;
}
......@@ -1519,12 +1531,7 @@ bool Debug::EnsureBreakInfo(Handle<SharedFunctionInfo> shared) {
if (!shared->is_compiled() && !Compiler::CompileDebugCode(shared)) {
return false;
}
// To prepare bytecode for debugging, we already need to have the debug
// info (containing the debug copy) upfront, but since we do not recompile,
// preparing for break points cannot fail.
CreateBreakInfo(shared);
CHECK(PrepareFunctionForBreakPoints(shared));
return true;
}
......
......@@ -12,13 +12,18 @@ bool DebugInfo::IsEmpty() const { return flags() == kNone; }
bool DebugInfo::HasBreakInfo() const { return (flags() & kHasBreakInfo) != 0; }
bool DebugInfo::IsPreparedForBreakpoints() const {
DCHECK(HasBreakInfo());
return (flags() & kPreparedForBreakpoints) != 0;
}
bool DebugInfo::ClearBreakInfo() {
Isolate* isolate = GetIsolate();
set_debug_bytecode_array(isolate->heap()->undefined_value());
set_break_points(isolate->heap()->empty_fixed_array());
int new_flags = flags() & ~kHasBreakInfo;
int new_flags = flags() & ~kHasBreakInfo & ~kPreparedForBreakpoints;
set_flags(new_flags);
return new_flags == kNone;
......
......@@ -20,7 +20,8 @@ class DebugInfo : public Struct {
enum Flag {
kNone = 0,
kHasBreakInfo = 1 << 0,
kHasCoverageInfo = 1 << 1,
kPreparedForBreakpoints = 1 << 1,
kHasCoverageInfo = 2 << 1,
};
typedef base::Flags<Flag> Flags;
......@@ -41,6 +42,8 @@ class DebugInfo : public Struct {
bool HasBreakInfo() const;
bool IsPreparedForBreakpoints() const;
// Clears all fields related to break points. Returns true iff the
// DebugInfo is now empty.
bool ClearBreakInfo();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment