Commit 6b3e8e69 authored by Peter Kvitek's avatar Peter Kvitek Committed by Commit Bot

[DevTools] Re-implemented Profiler.getRuntimeCallStats.

The original Profiler.getRuntimeCallStats implementation retrieved
a bunch of V8 Counters instead of runtime call counters. This
functionality is now available through the new APIs:
enableCounters, disableCounters and getCounters.

The getRuntimeCallStats API now retrieves real V8 Runtime Call Stats.

Change-Id: I702f60a6c43773f5c41b6861be3f9435975c370f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2380853
Commit-Queue: Peter Kvitek <kvitekp@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69753}
parent abb7cdc9
...@@ -863,6 +863,16 @@ domain Profiler ...@@ -863,6 +863,16 @@ domain Profiler
# Counter value. # Counter value.
integer value integer value
# Runtime call counter information.
experimental type RuntimeCallCounterInfo extends object
properties
# Counter name.
string name
# Counter value.
number value
# Counter time in seconds.
number time
command disable command disable
command enable command enable
...@@ -927,6 +937,18 @@ domain Profiler ...@@ -927,6 +937,18 @@ domain Profiler
# Type profile for all scripts since startTypeProfile() was turned on. # Type profile for all scripts since startTypeProfile() was turned on.
array of ScriptTypeProfile result array of ScriptTypeProfile result
# Enable counters collection.
experimental command enableCounters
# Disable counters collection.
experimental command disableCounters
# Retrieve counters.
experimental command getCounters
returns
# Collected counters information.
array of CounterInfo result
# Enable run time call stats collection. # Enable run time call stats collection.
experimental command enableRuntimeCallStats experimental command enableRuntimeCallStats
...@@ -936,8 +958,8 @@ domain Profiler ...@@ -936,8 +958,8 @@ domain Profiler
# Retrieve run time call stats. # Retrieve run time call stats.
experimental command getRuntimeCallStats experimental command getRuntimeCallStats
returns returns
# Collected counter information. # Collected runtime call counter information.
array of CounterInfo result array of RuntimeCallCounterInfo result
event consoleProfileFinished event consoleProfileFinished
parameters parameters
......
...@@ -10244,6 +10244,14 @@ int64_t debug::GetNextRandomInt64(v8::Isolate* v8_isolate) { ...@@ -10244,6 +10244,14 @@ int64_t debug::GetNextRandomInt64(v8::Isolate* v8_isolate) {
->NextInt64(); ->NextInt64();
} }
void debug::EnumerateRuntimeCallCounters(v8::Isolate* v8_isolate,
RuntimeCallCounterCallback callback) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
if (isolate->counters()) {
isolate->counters()->runtime_call_stats()->EnumerateCounters(callback);
}
}
int debug::GetDebuggingId(v8::Local<v8::Function> function) { int debug::GetDebuggingId(v8::Local<v8::Function> function) {
i::Handle<i::JSReceiver> callable = v8::Utils::OpenHandle(*function); i::Handle<i::JSReceiver> callable = v8::Utils::OpenHandle(*function);
if (!callable->IsJSFunction()) return i::DebugInfo::kNoDebuggingId; if (!callable->IsJSFunction()) return i::DebugInfo::kNoDebuggingId;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "include/v8-inspector.h" #include "include/v8-inspector.h"
#include "include/v8-util.h" #include "include/v8-util.h"
#include "include/v8.h" #include "include/v8.h"
#include "src/base/platform/time.h"
#include "src/common/globals.h" #include "src/common/globals.h"
#include "src/debug/interface-types.h" #include "src/debug/interface-types.h"
#include "src/utils/vector.h" #include "src/utils/vector.h"
...@@ -505,6 +506,11 @@ enum class NativeAccessorType { ...@@ -505,6 +506,11 @@ enum class NativeAccessorType {
int64_t GetNextRandomInt64(v8::Isolate* isolate); int64_t GetNextRandomInt64(v8::Isolate* isolate);
using RuntimeCallCounterCallback =
std::function<void(const char* name, int64_t count, base::TimeDelta time)>;
void EnumerateRuntimeCallCounters(v8::Isolate* isolate,
RuntimeCallCounterCallback callback);
enum class EvaluateGlobalMode { enum class EvaluateGlobalMode {
kDefault, kDefault,
kDisableBreaks, kDisableBreaks,
......
...@@ -13,6 +13,7 @@ include_rules = [ ...@@ -13,6 +13,7 @@ include_rules = [
"+src/base/safe_conversions.h", "+src/base/safe_conversions.h",
"+src/base/template-utils.h", "+src/base/template-utils.h",
"+src/base/v8-fallthrough.h", "+src/base/v8-fallthrough.h",
"+src/logging/tracing-flags.h",
"+src/numbers/conversions.h", "+src/numbers/conversions.h",
"+src/inspector", "+src/inspector",
"+src/tracing", "+src/tracing",
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <vector> #include <vector>
#include "include/v8-profiler.h"
#include "src/base/atomicops.h" #include "src/base/atomicops.h"
#include "src/base/platform/time.h" #include "src/base/platform/time.h"
#include "src/debug/debug-interface.h" #include "src/debug/debug-interface.h"
...@@ -15,8 +16,7 @@ ...@@ -15,8 +16,7 @@
#include "src/inspector/v8-inspector-impl.h" #include "src/inspector/v8-inspector-impl.h"
#include "src/inspector/v8-inspector-session-impl.h" #include "src/inspector/v8-inspector-session-impl.h"
#include "src/inspector/v8-stack-trace-impl.h" #include "src/inspector/v8-stack-trace-impl.h"
#include "src/logging/tracing-flags.h"
#include "include/v8-profiler.h"
namespace v8_inspector { namespace v8_inspector {
...@@ -30,6 +30,8 @@ static const char preciseCoverageDetailed[] = "preciseCoverageDetailed"; ...@@ -30,6 +30,8 @@ static const char preciseCoverageDetailed[] = "preciseCoverageDetailed";
static const char preciseCoverageAllowTriggeredUpdates[] = static const char preciseCoverageAllowTriggeredUpdates[] =
"preciseCoverageAllowTriggeredUpdates"; "preciseCoverageAllowTriggeredUpdates";
static const char typeProfileStarted[] = "typeProfileStarted"; static const char typeProfileStarted[] = "typeProfileStarted";
static const char countersEnabled[] = "countersEnabled";
static const char runtimeCallStatsEnabled[] = "runtimeCallStatsEnabled";
} // namespace ProfilerAgentState } // namespace ProfilerAgentState
namespace { namespace {
...@@ -220,22 +222,36 @@ void V8ProfilerAgentImpl::consoleProfileEnd(const String16& title) { ...@@ -220,22 +222,36 @@ void V8ProfilerAgentImpl::consoleProfileEnd(const String16& title) {
} }
Response V8ProfilerAgentImpl::enable() { Response V8ProfilerAgentImpl::enable() {
if (m_enabled) return Response::Success(); if (!m_enabled) {
m_enabled = true; m_enabled = true;
m_state->setBoolean(ProfilerAgentState::profilerEnabled, true); m_state->setBoolean(ProfilerAgentState::profilerEnabled, true);
}
return Response::Success(); return Response::Success();
} }
Response V8ProfilerAgentImpl::disable() { Response V8ProfilerAgentImpl::disable() {
if (!m_enabled) return Response::Success(); if (m_enabled) {
for (size_t i = m_startedProfiles.size(); i > 0; --i) for (size_t i = m_startedProfiles.size(); i > 0; --i)
stopProfiling(m_startedProfiles[i - 1].m_id, false); stopProfiling(m_startedProfiles[i - 1].m_id, false);
m_startedProfiles.clear(); m_startedProfiles.clear();
stop(nullptr); stop(nullptr);
stopPreciseCoverage(); stopPreciseCoverage();
DCHECK(!m_profiler); DCHECK(!m_profiler);
m_enabled = false; m_enabled = false;
m_state->setBoolean(ProfilerAgentState::profilerEnabled, false); m_state->setBoolean(ProfilerAgentState::profilerEnabled, false);
}
if (m_counters) {
disableCounters();
m_state->setBoolean(ProfilerAgentState::countersEnabled, false);
}
if (m_runtime_call_stats_enabled) {
disableRuntimeCallStats();
m_state->setBoolean(ProfilerAgentState::runtimeCallStatsEnabled, false);
}
return Response::Success(); return Response::Success();
} }
...@@ -250,25 +266,34 @@ Response V8ProfilerAgentImpl::setSamplingInterval(int interval) { ...@@ -250,25 +266,34 @@ Response V8ProfilerAgentImpl::setSamplingInterval(int interval) {
void V8ProfilerAgentImpl::restore() { void V8ProfilerAgentImpl::restore() {
DCHECK(!m_enabled); DCHECK(!m_enabled);
if (!m_state->booleanProperty(ProfilerAgentState::profilerEnabled, false)) if (m_state->booleanProperty(ProfilerAgentState::profilerEnabled, false)) {
return; m_enabled = true;
m_enabled = true; DCHECK(!m_profiler);
DCHECK(!m_profiler); if (m_state->booleanProperty(ProfilerAgentState::userInitiatedProfiling,
if (m_state->booleanProperty(ProfilerAgentState::userInitiatedProfiling, false)) {
false)) { start();
start(); }
if (m_state->booleanProperty(ProfilerAgentState::preciseCoverageStarted,
false)) {
bool callCount = m_state->booleanProperty(
ProfilerAgentState::preciseCoverageCallCount, false);
bool detailed = m_state->booleanProperty(
ProfilerAgentState::preciseCoverageDetailed, false);
bool updatesAllowed = m_state->booleanProperty(
ProfilerAgentState::preciseCoverageAllowTriggeredUpdates, false);
double timestamp;
startPreciseCoverage(Maybe<bool>(callCount), Maybe<bool>(detailed),
Maybe<bool>(updatesAllowed), &timestamp);
}
} }
if (m_state->booleanProperty(ProfilerAgentState::preciseCoverageStarted,
if (m_state->booleanProperty(ProfilerAgentState::countersEnabled, false)) {
enableCounters();
}
if (m_state->booleanProperty(ProfilerAgentState::runtimeCallStatsEnabled,
false)) { false)) {
bool callCount = m_state->booleanProperty( enableRuntimeCallStats();
ProfilerAgentState::preciseCoverageCallCount, false);
bool detailed = m_state->booleanProperty(
ProfilerAgentState::preciseCoverageDetailed, false);
bool updatesAllowed = m_state->booleanProperty(
ProfilerAgentState::preciseCoverageAllowTriggeredUpdates, false);
double timestamp;
startPreciseCoverage(Maybe<bool>(callCount), Maybe<bool>(detailed),
Maybe<bool>(updatesAllowed), &timestamp);
} }
} }
...@@ -525,10 +550,9 @@ Response V8ProfilerAgentImpl::takeTypeProfile( ...@@ -525,10 +550,9 @@ Response V8ProfilerAgentImpl::takeTypeProfile(
return Response::Success(); return Response::Success();
} }
Response V8ProfilerAgentImpl::enableRuntimeCallStats() { Response V8ProfilerAgentImpl::enableCounters() {
if (m_counters) if (m_counters)
return Response::ServerError( return Response::ServerError("Counters collection already enabled.");
"RuntimeCallStats collection already enabled.");
if (V8Inspector* inspector = v8::debug::GetInspector(m_isolate)) if (V8Inspector* inspector = v8::debug::GetInspector(m_isolate))
m_counters = inspector->enableCounters(); m_counters = inspector->enableCounters();
...@@ -538,16 +562,16 @@ Response V8ProfilerAgentImpl::enableRuntimeCallStats() { ...@@ -538,16 +562,16 @@ Response V8ProfilerAgentImpl::enableRuntimeCallStats() {
return Response::Success(); return Response::Success();
} }
Response V8ProfilerAgentImpl::disableRuntimeCallStats() { Response V8ProfilerAgentImpl::disableCounters() {
if (m_counters) m_counters.reset(); if (m_counters) m_counters.reset();
return Response::Success(); return Response::Success();
} }
Response V8ProfilerAgentImpl::getRuntimeCallStats( Response V8ProfilerAgentImpl::getCounters(
std::unique_ptr<protocol::Array<protocol::Profiler::CounterInfo>>* std::unique_ptr<protocol::Array<protocol::Profiler::CounterInfo>>*
out_result) { out_result) {
if (!m_counters) if (!m_counters)
return Response::ServerError("RuntimeCallStats collection is not enabled."); return Response::ServerError("Counters collection is not enabled.");
*out_result = *out_result =
std::make_unique<protocol::Array<protocol::Profiler::CounterInfo>>(); std::make_unique<protocol::Array<protocol::Profiler::CounterInfo>>();
...@@ -564,6 +588,66 @@ Response V8ProfilerAgentImpl::getRuntimeCallStats( ...@@ -564,6 +588,66 @@ Response V8ProfilerAgentImpl::getRuntimeCallStats(
return Response::Success(); return Response::Success();
} }
Response V8ProfilerAgentImpl::enableRuntimeCallStats() {
if (v8::internal::TracingFlags::runtime_stats.load()) {
return Response::ServerError(
"Runtime Call Stats collection is already enabled.");
}
v8::internal::TracingFlags::runtime_stats.store(true);
m_runtime_call_stats_enabled = true;
return Response::Success();
}
Response V8ProfilerAgentImpl::disableRuntimeCallStats() {
if (!v8::internal::TracingFlags::runtime_stats.load()) {
return Response::ServerError(
"Runtime Call Stats collection is not enabled.");
}
if (!m_runtime_call_stats_enabled) {
return Response::ServerError(
"Runtime Call Stats collection was not enabled by this session.");
}
v8::internal::TracingFlags::runtime_stats.store(false);
m_runtime_call_stats_enabled = false;
return Response::Success();
}
Response V8ProfilerAgentImpl::getRuntimeCallStats(
std::unique_ptr<
protocol::Array<protocol::Profiler::RuntimeCallCounterInfo>>*
out_result) {
if (!m_runtime_call_stats_enabled) {
return Response::ServerError(
"Runtime Call Stats collection is not enabled.");
}
if (!v8::internal::TracingFlags::runtime_stats.load()) {
return Response::ServerError(
"Runtime Call Stats collection was disabled outside of this session.");
}
*out_result = std::make_unique<
protocol::Array<protocol::Profiler::RuntimeCallCounterInfo>>();
v8::debug::EnumerateRuntimeCallCounters(
m_isolate,
[&](const char* name, int64_t count, v8::base::TimeDelta time) {
(*out_result)
->emplace_back(protocol::Profiler::RuntimeCallCounterInfo::create()
.setName(String16(name))
.setValue(static_cast<double>(count))
.setTime(time.InSecondsF())
.build());
});
return Response::Success();
}
String16 V8ProfilerAgentImpl::nextProfileId() { String16 V8ProfilerAgentImpl::nextProfileId() {
return String16::fromInteger( return String16::fromInteger(
v8::base::Relaxed_AtomicIncrement(&s_lastProfileId, 1)); v8::base::Relaxed_AtomicIncrement(&s_lastProfileId, 1));
......
...@@ -57,10 +57,17 @@ class V8ProfilerAgentImpl : public protocol::Profiler::Backend { ...@@ -57,10 +57,17 @@ class V8ProfilerAgentImpl : public protocol::Profiler::Backend {
std::unique_ptr<protocol::Array<protocol::Profiler::ScriptTypeProfile>>* std::unique_ptr<protocol::Array<protocol::Profiler::ScriptTypeProfile>>*
out_result) override; out_result) override;
Response enableCounters() override;
Response disableCounters() override;
Response getCounters(
std::unique_ptr<protocol::Array<protocol::Profiler::CounterInfo>>*
out_result) override;
Response enableRuntimeCallStats() override; Response enableRuntimeCallStats() override;
Response disableRuntimeCallStats() override; Response disableRuntimeCallStats() override;
Response getRuntimeCallStats( Response getRuntimeCallStats(
std::unique_ptr<protocol::Array<protocol::Profiler::CounterInfo>>* std::unique_ptr<
protocol::Array<protocol::Profiler::RuntimeCallCounterInfo>>*
out_result) override; out_result) override;
void consoleProfile(const String16& title); void consoleProfile(const String16& title);
...@@ -87,6 +94,7 @@ class V8ProfilerAgentImpl : public protocol::Profiler::Backend { ...@@ -87,6 +94,7 @@ class V8ProfilerAgentImpl : public protocol::Profiler::Backend {
String16 m_frontendInitiatedProfileId; String16 m_frontendInitiatedProfileId;
int m_startedProfilesCount = 0; int m_startedProfilesCount = 0;
std::shared_ptr<V8Inspector::Counters> m_counters; std::shared_ptr<V8Inspector::Counters> m_counters;
bool m_runtime_call_stats_enabled = false;
DISALLOW_COPY_AND_ASSIGN(V8ProfilerAgentImpl); DISALLOW_COPY_AND_ASSIGN(V8ProfilerAgentImpl);
}; };
......
...@@ -557,6 +557,17 @@ void RuntimeCallStats::Print(std::ostream& os) { ...@@ -557,6 +557,17 @@ void RuntimeCallStats::Print(std::ostream& os) {
entries.Print(os); entries.Print(os);
} }
void RuntimeCallStats::EnumerateCounters(
debug::RuntimeCallCounterCallback callback) {
if (current_timer_.Value() != nullptr) {
current_timer_.Value()->Snapshot();
}
for (int i = 0; i < kNumberOfCounters; i++) {
RuntimeCallCounter* counter = GetCounter(i);
callback(counter->name(), counter->count(), counter->time());
}
}
void RuntimeCallStats::Reset() { void RuntimeCallStats::Reset() {
if (V8_LIKELY(!TracingFlags::is_runtime_stats_enabled())) return; if (V8_LIKELY(!TracingFlags::is_runtime_stats_enabled())) return;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "src/base/platform/elapsed-timer.h" #include "src/base/platform/elapsed-timer.h"
#include "src/base/platform/time.h" #include "src/base/platform/time.h"
#include "src/common/globals.h" #include "src/common/globals.h"
#include "src/debug/debug-interface.h"
#include "src/execution/isolate.h" #include "src/execution/isolate.h"
#include "src/init/heap-symbols.h" #include "src/init/heap-symbols.h"
#include "src/logging/counters-definitions.h" #include "src/logging/counters-definitions.h"
...@@ -1146,6 +1147,9 @@ class RuntimeCallStats final { ...@@ -1146,6 +1147,9 @@ class RuntimeCallStats final {
V8_EXPORT_PRIVATE void Print(); V8_EXPORT_PRIVATE void Print();
V8_NOINLINE void Dump(v8::tracing::TracedValue* value); V8_NOINLINE void Dump(v8::tracing::TracedValue* value);
V8_EXPORT_PRIVATE void EnumerateCounters(
debug::RuntimeCallCounterCallback callback);
ThreadId thread_id() const { return thread_id_; } ThreadId thread_id() const { return thread_id_; }
RuntimeCallTimer* current_timer() { return current_timer_.Value(); } RuntimeCallTimer* current_timer() { return current_timer_.Value(); }
RuntimeCallCounter* current_counter() { return current_counter_.Value(); } RuntimeCallCounter* current_counter() { return current_counter_.Value(); }
......
...@@ -32,6 +32,7 @@ v8_executable("inspector-test") { ...@@ -32,6 +32,7 @@ v8_executable("inspector-test") {
data = [ data = [
"console/", "console/",
"counters/",
"cpu-profiler/", "cpu-profiler/",
"debugger/", "debugger/",
"heap-profiler/", "heap-profiler/",
......
Test Counters collection using Profiler.getCounters.
PASSED
// Copyright 2020 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.
let {session, contextGroup, Protocol} = InspectorTest.start(
'Test Counters collection using Profiler.getCounters.');
var source =
`
function fib(x) {
if (x < 2) return 1;
return fib(x-1) + fib(x-2);
}
fib(5);
`;
function buildCounterMap(result) {
let counterMap = new Map();
let counters = result.result.result;
for (const {name, value} of counters) {
counterMap.set(name, value);
}
return counterMap;
}
function compareCounterMaps(counterMap, counterMap2) {
// Check for counters that are present in the first map but are not found
// in the the second map
for (let counter of counterMap.keys()) {
if (!counterMap2.has(counter)) {
InspectorTest.log(`Counter ${counter} is missing`);
return false;
}
}
// Check for the counter value changes
let counterValueIncreased = false;
for (let [counter, value2] of counterMap2) {
let value = counterMap.get(counter);
if (value !== undefined) {
if (value2 < value) {
InspectorTest.log(`Counter ${counter} value decreased: ${value} -> ${value2}`);
return false;
}
if (value2 > value) {
counterValueIncreased = true;
}
}
}
if (!counterValueIncreased && counterMap.size === counterMap2.size) {
InspectorTest.log(`No counter values has increased or added`);
return false;
}
return true;
}
(async function test() {
await Protocol.Runtime.enable();
await Protocol.Profiler.enableCounters();
let counterMap = buildCounterMap(await Protocol.Profiler.getCounters());
await Protocol.Runtime.evaluate({ expression: source, sourceURL: arguments.callee.name, persistScript: true });
let counterMap2 = buildCounterMap(await Protocol.Profiler.getCounters());
const check1 = compareCounterMaps(counterMap, counterMap2);
await Protocol.Runtime.evaluate({ expression: source, sourceURL: arguments.callee.name, persistScript: true });
let counterMap3 = buildCounterMap(await Protocol.Profiler.getCounters());
const check2 = compareCounterMaps(counterMap2, counterMap3);
await Protocol.Profiler.disableCounters();
await Protocol.Runtime.disable();
InspectorTest.log(check1 && check2 ? 'PASSED' : 'FAILED');
InspectorTest.completeTest();
})().catch(e => InspectorTest.log('caught: ' + e));
Test Counters collection enabling and disabling.
Expected error: "Counters collection is not enabled."
Expected error: "Counters collection already enabled."
Some counters reported
Expected error: "Counters collection is not enabled."
Less counters reported
// Copyright 2020 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.
let {session, contextGroup, Protocol} = InspectorTest.start(
'Test Counters collection enabling and disabling.');
var source =
`
function fib(x) {
if (x < 2) return 1;
return fib(x-1) + fib(x-2);
}
fib(5);
`;
function logErrorMessage(result) {
InspectorTest.log('Expected error: "' + result.error.message + '"');
}
(async function test() {
await Protocol.Runtime.enable();
// This should fail with "not enabled" error.
logErrorMessage(await Protocol.Profiler.getCounters());
// This should fail with "already enabled" error.
await Protocol.Profiler.enableCounters();
logErrorMessage(await Protocol.Profiler.enableCounters());
// The result should not be empty.
await Protocol.Runtime.evaluate({ expression: source, sourceURL: arguments.callee.name, persistScript: true });
const counters = (await Protocol.Profiler.getCounters()).result.result;
if (counters.length > 0)
InspectorTest.log('Some counters reported');
await Protocol.Profiler.disableCounters();
// This should fail with "not enabled" error too.
logErrorMessage(await Protocol.Profiler.getCounters());
// The result should not be empty and have smaller amount of counters than
// the first result.
await Protocol.Profiler.enableCounters();
const counters2 = (await Protocol.Profiler.getCounters()).result.result;
if (counters2.length > 0 && counters2.length < counters.length)
InspectorTest.log('Less counters reported');
await Protocol.Profiler.disableCounters();
await Protocol.Runtime.disable();
InspectorTest.completeTest();
})().catch(e => InspectorTest.log('caught: ' + e));
// Copyright 2019 the V8 project authors. All rights reserved. // Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
......
Test RunTimeCallStats collection enabling and disabling. Test Runtime Call Stats collection enabling and disabling.
Expected error: "RuntimeCallStats collection is not enabled." Expected error: "Runtime Call Stats collection is not enabled."
Expected error: "RuntimeCallStats collection already enabled." Expected error: "Runtime Call Stats collection is already enabled."
Some counters reported Some counters reported
Expected error: "RuntimeCallStats collection is not enabled." Expected error: "Runtime Call Stats collection is not enabled."
Less counters reported
// Copyright 2019 the V8 project authors. All rights reserved. // Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start( let {session, contextGroup, Protocol} = InspectorTest.start(
'Test RunTimeCallStats collection enabling and disabling.'); 'Test Runtime Call Stats collection enabling and disabling.');
var source = var source =
` `
function fib(x) { function fib(x) {
if (x < 2) return 1; if (x < 2) return 1;
return fib(x-1) + fib(x-2); return fib(x-1) + fib(x-2);
} }
fib(5); fib(5);
`; `;
function logErrorMessage(result) { function logErrorMessage(result) {
InspectorTest.log('Expected error: "' + result.error.message + '"'); InspectorTest.log('Expected error: "' + result.error.message + '"');
} }
(async function test() { (async function test() {
await Protocol.Runtime.enable(); await Protocol.Runtime.enable();
// This should fail with "not enabled" error. // This should fail with "not enabled" error.
logErrorMessage(await Protocol.Profiler.getRuntimeCallStats()); logErrorMessage(await Protocol.Profiler.getRuntimeCallStats());
// This should fail with "already enabled" error. // This should fail with "already enabled" error.
await Protocol.Profiler.enableRuntimeCallStats(); await Protocol.Profiler.enableRuntimeCallStats();
logErrorMessage(await Protocol.Profiler.enableRuntimeCallStats()); logErrorMessage(await Protocol.Profiler.enableRuntimeCallStats());
// The result should not be empty. // The result should not be empty.
await Protocol.Runtime.evaluate({ expression: source, sourceURL: arguments.callee.name, persistScript: true }); await Protocol.Runtime.evaluate({ expression: source, sourceURL: arguments.callee.name, persistScript: true });
const counters = (await Protocol.Profiler.getRuntimeCallStats()).result.result; const counters = (await Protocol.Profiler.getRuntimeCallStats()).result.result;
if (counters.length > 0) if (counters.length > 0)
InspectorTest.log('Some counters reported'); InspectorTest.log('Some counters reported');
await Protocol.Profiler.disableRuntimeCallStats(); await Protocol.Profiler.disableRuntimeCallStats();
// This should fail with "not enabled" error too. // This should fail with "not enabled" error too.
logErrorMessage(await Protocol.Profiler.getRuntimeCallStats()); logErrorMessage(await Protocol.Profiler.getRuntimeCallStats());
// The result should not be empty and have smaller amount of counters than // The result should not be empty and have smaller amount of counters than
// the first result. // the first result.
await Protocol.Profiler.enableRuntimeCallStats(); await Protocol.Profiler.enableRuntimeCallStats();
const counters2 = (await Protocol.Profiler.getRuntimeCallStats()).result.result; const counters2 = (await Protocol.Profiler.getRuntimeCallStats()).result.result;
if (counters2.length > 0 && counters2.length < counters.length) if (counters2.length > 0 && counters2.length < counters.length)
InspectorTest.log('Less counters reported'); InspectorTest.log('Less counters reported');
await Protocol.Profiler.disableRuntimeCallStats(); await Protocol.Profiler.disableRuntimeCallStats();
await Protocol.Runtime.disable(); await Protocol.Runtime.disable();
InspectorTest.completeTest(); InspectorTest.completeTest();
})().catch(e => InspectorTest.log('caught: ' + e)); })().catch(e => InspectorTest.log('caught: ' + e));
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