From 64754cf2f53bb3e1bc936ae9e1d382a2d808f33f Mon Sep 17 00:00:00 2001 From: Yang Guo Date: Mon, 20 Mar 2017 15:00:02 +0100 Subject: [PATCH] [debug] collect coverage for functions on the stack when enabling. BUG=v8:5808 Change-Id: I7bb3c3655e17271b44de881416e150ef51811154 Reviewed-on: https://chromium-review.googlesource.com/457336 Commit-Queue: Yang Guo Reviewed-by: Jakob Gruber Cr-Commit-Position: refs/heads/master@{#43939} --- src/debug/debug-coverage.cc | 8 ++ src/feedback-vector-inl.h | 5 ++ src/feedback-vector.h | 1 + .../cpu-profiler/coverage-expected.txt | 79 +++++++++++++++++++ test/inspector/cpu-profiler/coverage.js | 36 +++++++++ 5 files changed, 129 insertions(+) diff --git a/src/debug/debug-coverage.cc b/src/debug/debug-coverage.cc index 75643eda68..06f2ad466f 100644 --- a/src/debug/debug-coverage.cc +++ b/src/debug/debug-coverage.cc @@ -6,6 +6,7 @@ #include "src/base/hashmap.h" #include "src/deoptimizer.h" +#include "src/frames-inl.h" #include "src/isolate.h" #include "src/objects-inl.h" #include "src/objects.h" @@ -148,6 +149,13 @@ void Coverage::TogglePrecise(Isolate* isolate, bool enable) { ArrayList::New(isolate, static_cast(vectors.size())); for (const auto& vector : vectors) list = ArrayList::Add(list, vector); isolate->SetCodeCoverageList(*list); + // Increment count for functions currently on the stack. We won't observe + // entry of these functions, but we know they have coverage. + for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) { + JSFunction* function = it.frame()->function(); + if (!function->shared()->IsSubjectToDebugging()) continue; + function->feedback_vector()->increment_invocation_count(); + } } else { isolate->SetCodeCoverageList(isolate->heap()->undefined_value()); } diff --git a/src/feedback-vector-inl.h b/src/feedback-vector-inl.h index b6512e20ff..9013a691d4 100644 --- a/src/feedback-vector-inl.h +++ b/src/feedback-vector-inl.h @@ -98,6 +98,11 @@ int FeedbackVector::invocation_count() const { return Smi::cast(get(kInvocationCountIndex))->value(); } +void FeedbackVector::increment_invocation_count() { + int count = invocation_count() + 1; + if (Smi::IsValid(count)) set(kInvocationCountIndex, Smi::FromInt(count)); +} + void FeedbackVector::clear_invocation_count() { set(kInvocationCountIndex, Smi::kZero); } diff --git a/src/feedback-vector.h b/src/feedback-vector.h index a3cdace375..813a3beb37 100644 --- a/src/feedback-vector.h +++ b/src/feedback-vector.h @@ -299,6 +299,7 @@ class FeedbackVector : public FixedArray { inline FeedbackMetadata* metadata() const; inline SharedFunctionInfo* shared_function_info() const; inline int invocation_count() const; + inline void increment_invocation_count(); inline void clear_invocation_count(); // Conversion from a slot to an integer index to the underlying array. diff --git a/test/inspector/cpu-profiler/coverage-expected.txt b/test/inspector/cpu-profiler/coverage-expected.txt index 496e37bce1..e6e7c5a866 100644 --- a/test/inspector/cpu-profiler/coverage-expected.txt +++ b/test/inspector/cpu-profiler/coverage-expected.txt @@ -347,3 +347,82 @@ Running test: testBestEffortCoveragePrecise ] } } + +Running test: testEnablePreciseCoverageAtPause +{ + id : + result : { + result : { + type : undefined + } + } +} +{ + id : + result : { + result : [ + [0] : { + functions : [ + [0] : { + functionName : + ranges : [ + [0] : { + count : 1 + endOffset : 114 + startOffset : 0 + } + ] + } + [1] : { + functionName : g + ranges : [ + [0] : { + count : 1 + endOffset : 29 + startOffset : 1 + } + ] + } + [2] : { + functionName : f + ranges : [ + [0] : { + count : 4 + endOffset : 83 + startOffset : 30 + } + ] + } + [3] : { + functionName : h + ranges : [ + [0] : { + count : 0 + endOffset : 107 + startOffset : 84 + } + ] + } + ] + scriptId : + url : 5 + } + [1] : { + functions : [ + [0] : { + functionName : + ranges : [ + [0] : { + count : 1 + endOffset : 11 + startOffset : 0 + } + ] + } + ] + scriptId : + url : + } + ] + } +} diff --git a/test/inspector/cpu-profiler/coverage.js b/test/inspector/cpu-profiler/coverage.js index 11c34521b7..495b536995 100644 --- a/test/inspector/cpu-profiler/coverage.js +++ b/test/inspector/cpu-profiler/coverage.js @@ -14,6 +14,21 @@ function fib(x) { fib(5); `; +var break_source = +` +function g() { + debugger; +} +function f(x) { + if (x == 0) g(); + else f(x - 1); +} +function h() { + g(); +} +f(3); +`; + InspectorTest.log("Test collecting code coverage data with Profiler.collectCoverage."); function ClearAndGC() { @@ -118,4 +133,25 @@ InspectorTest.runTestSuite([ .then(Protocol.Runtime.disable) .then(next); }, + function testEnablePreciseCoverageAtPause(next) + { + function handleDebuggerPause() { + Protocol.Profiler.enable() + .then(Protocol.Profiler.startPreciseCoverage) + .then(Protocol.Debugger.resume) + } + Protocol.Debugger.enable(); + Protocol.Debugger.oncePaused().then(handleDebuggerPause); + Protocol.Runtime.enable() + .then(() => Protocol.Runtime.compileScript({ expression: break_source, sourceURL: "5", persistScript: true })) + .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId })) + .then(InspectorTest.logMessage) + .then(ClearAndGC) + .then(Protocol.Profiler.takePreciseCoverage) + .then(LogSorted) + .then(Protocol.Profiler.stopPreciseCoverage) + .then(Protocol.Profiler.disable) + .then(Protocol.Runtime.disable) + .then(next); + }, ]);