[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: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#47021}
This commit is contained in:
parent
6fbbe93c5e
commit
f455986fc1
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user