Skip to content

Commit 6b3e8e6

Browse files
Peter KvitekCommit Bot
authored andcommitted
[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: Yang Guo <yangguo@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#69753}
1 parent abb7cdc commit 6b3e8e6

16 files changed

Lines changed: 366 additions & 80 deletions

include/js_protocol.pdl

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,16 @@ domain Profiler
863863
# Counter value.
864864
integer value
865865

866+
# Runtime call counter information.
867+
experimental type RuntimeCallCounterInfo extends object
868+
properties
869+
# Counter name.
870+
string name
871+
# Counter value.
872+
number value
873+
# Counter time in seconds.
874+
number time
875+
866876
command disable
867877

868878
command enable
@@ -927,6 +937,18 @@ domain Profiler
927937
# Type profile for all scripts since startTypeProfile() was turned on.
928938
array of ScriptTypeProfile result
929939

940+
# Enable counters collection.
941+
experimental command enableCounters
942+
943+
# Disable counters collection.
944+
experimental command disableCounters
945+
946+
# Retrieve counters.
947+
experimental command getCounters
948+
returns
949+
# Collected counters information.
950+
array of CounterInfo result
951+
930952
# Enable run time call stats collection.
931953
experimental command enableRuntimeCallStats
932954

@@ -936,8 +958,8 @@ domain Profiler
936958
# Retrieve run time call stats.
937959
experimental command getRuntimeCallStats
938960
returns
939-
# Collected counter information.
940-
array of CounterInfo result
961+
# Collected runtime call counter information.
962+
array of RuntimeCallCounterInfo result
941963

942964
event consoleProfileFinished
943965
parameters

src/api/api.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10244,6 +10244,14 @@ int64_t debug::GetNextRandomInt64(v8::Isolate* v8_isolate) {
1024410244
->NextInt64();
1024510245
}
1024610246

10247+
void debug::EnumerateRuntimeCallCounters(v8::Isolate* v8_isolate,
10248+
RuntimeCallCounterCallback callback) {
10249+
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
10250+
if (isolate->counters()) {
10251+
isolate->counters()->runtime_call_stats()->EnumerateCounters(callback);
10252+
}
10253+
}
10254+
1024710255
int debug::GetDebuggingId(v8::Local<v8::Function> function) {
1024810256
i::Handle<i::JSReceiver> callable = v8::Utils::OpenHandle(*function);
1024910257
if (!callable->IsJSFunction()) return i::DebugInfo::kNoDebuggingId;

src/debug/debug-interface.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "include/v8-inspector.h"
1111
#include "include/v8-util.h"
1212
#include "include/v8.h"
13+
#include "src/base/platform/time.h"
1314
#include "src/common/globals.h"
1415
#include "src/debug/interface-types.h"
1516
#include "src/utils/vector.h"
@@ -505,6 +506,11 @@ enum class NativeAccessorType {
505506

506507
int64_t GetNextRandomInt64(v8::Isolate* isolate);
507508

509+
using RuntimeCallCounterCallback =
510+
std::function<void(const char* name, int64_t count, base::TimeDelta time)>;
511+
void EnumerateRuntimeCallCounters(v8::Isolate* isolate,
512+
RuntimeCallCounterCallback callback);
513+
508514
enum class EvaluateGlobalMode {
509515
kDefault,
510516
kDisableBreaks,

src/inspector/DEPS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ include_rules = [
1313
"+src/base/safe_conversions.h",
1414
"+src/base/template-utils.h",
1515
"+src/base/v8-fallthrough.h",
16+
"+src/logging/tracing-flags.h",
1617
"+src/numbers/conversions.h",
1718
"+src/inspector",
1819
"+src/tracing",

src/inspector/v8-profiler-agent-impl.cc

Lines changed: 121 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <vector>
88

9+
#include "include/v8-profiler.h"
910
#include "src/base/atomicops.h"
1011
#include "src/base/platform/time.h"
1112
#include "src/debug/debug-interface.h"
@@ -15,8 +16,7 @@
1516
#include "src/inspector/v8-inspector-impl.h"
1617
#include "src/inspector/v8-inspector-session-impl.h"
1718
#include "src/inspector/v8-stack-trace-impl.h"
18-
19-
#include "include/v8-profiler.h"
19+
#include "src/logging/tracing-flags.h"
2020

2121
namespace v8_inspector {
2222

@@ -30,6 +30,8 @@ static const char preciseCoverageDetailed[] = "preciseCoverageDetailed";
3030
static const char preciseCoverageAllowTriggeredUpdates[] =
3131
"preciseCoverageAllowTriggeredUpdates";
3232
static const char typeProfileStarted[] = "typeProfileStarted";
33+
static const char countersEnabled[] = "countersEnabled";
34+
static const char runtimeCallStatsEnabled[] = "runtimeCallStatsEnabled";
3335
} // namespace ProfilerAgentState
3436

3537
namespace {
@@ -220,22 +222,36 @@ void V8ProfilerAgentImpl::consoleProfileEnd(const String16& title) {
220222
}
221223

222224
Response V8ProfilerAgentImpl::enable() {
223-
if (m_enabled) return Response::Success();
224-
m_enabled = true;
225-
m_state->setBoolean(ProfilerAgentState::profilerEnabled, true);
225+
if (!m_enabled) {
226+
m_enabled = true;
227+
m_state->setBoolean(ProfilerAgentState::profilerEnabled, true);
228+
}
229+
226230
return Response::Success();
227231
}
228232

229233
Response V8ProfilerAgentImpl::disable() {
230-
if (!m_enabled) return Response::Success();
231-
for (size_t i = m_startedProfiles.size(); i > 0; --i)
232-
stopProfiling(m_startedProfiles[i - 1].m_id, false);
233-
m_startedProfiles.clear();
234-
stop(nullptr);
235-
stopPreciseCoverage();
236-
DCHECK(!m_profiler);
237-
m_enabled = false;
238-
m_state->setBoolean(ProfilerAgentState::profilerEnabled, false);
234+
if (m_enabled) {
235+
for (size_t i = m_startedProfiles.size(); i > 0; --i)
236+
stopProfiling(m_startedProfiles[i - 1].m_id, false);
237+
m_startedProfiles.clear();
238+
stop(nullptr);
239+
stopPreciseCoverage();
240+
DCHECK(!m_profiler);
241+
m_enabled = false;
242+
m_state->setBoolean(ProfilerAgentState::profilerEnabled, false);
243+
}
244+
245+
if (m_counters) {
246+
disableCounters();
247+
m_state->setBoolean(ProfilerAgentState::countersEnabled, false);
248+
}
249+
250+
if (m_runtime_call_stats_enabled) {
251+
disableRuntimeCallStats();
252+
m_state->setBoolean(ProfilerAgentState::runtimeCallStatsEnabled, false);
253+
}
254+
239255
return Response::Success();
240256
}
241257

@@ -250,25 +266,34 @@ Response V8ProfilerAgentImpl::setSamplingInterval(int interval) {
250266

251267
void V8ProfilerAgentImpl::restore() {
252268
DCHECK(!m_enabled);
253-
if (!m_state->booleanProperty(ProfilerAgentState::profilerEnabled, false))
254-
return;
255-
m_enabled = true;
256-
DCHECK(!m_profiler);
257-
if (m_state->booleanProperty(ProfilerAgentState::userInitiatedProfiling,
258-
false)) {
259-
start();
269+
if (m_state->booleanProperty(ProfilerAgentState::profilerEnabled, false)) {
270+
m_enabled = true;
271+
DCHECK(!m_profiler);
272+
if (m_state->booleanProperty(ProfilerAgentState::userInitiatedProfiling,
273+
false)) {
274+
start();
275+
}
276+
if (m_state->booleanProperty(ProfilerAgentState::preciseCoverageStarted,
277+
false)) {
278+
bool callCount = m_state->booleanProperty(
279+
ProfilerAgentState::preciseCoverageCallCount, false);
280+
bool detailed = m_state->booleanProperty(
281+
ProfilerAgentState::preciseCoverageDetailed, false);
282+
bool updatesAllowed = m_state->booleanProperty(
283+
ProfilerAgentState::preciseCoverageAllowTriggeredUpdates, false);
284+
double timestamp;
285+
startPreciseCoverage(Maybe<bool>(callCount), Maybe<bool>(detailed),
286+
Maybe<bool>(updatesAllowed), &timestamp);
287+
}
260288
}
261-
if (m_state->booleanProperty(ProfilerAgentState::preciseCoverageStarted,
289+
290+
if (m_state->booleanProperty(ProfilerAgentState::countersEnabled, false)) {
291+
enableCounters();
292+
}
293+
294+
if (m_state->booleanProperty(ProfilerAgentState::runtimeCallStatsEnabled,
262295
false)) {
263-
bool callCount = m_state->booleanProperty(
264-
ProfilerAgentState::preciseCoverageCallCount, false);
265-
bool detailed = m_state->booleanProperty(
266-
ProfilerAgentState::preciseCoverageDetailed, false);
267-
bool updatesAllowed = m_state->booleanProperty(
268-
ProfilerAgentState::preciseCoverageAllowTriggeredUpdates, false);
269-
double timestamp;
270-
startPreciseCoverage(Maybe<bool>(callCount), Maybe<bool>(detailed),
271-
Maybe<bool>(updatesAllowed), &timestamp);
296+
enableRuntimeCallStats();
272297
}
273298
}
274299

@@ -525,10 +550,9 @@ Response V8ProfilerAgentImpl::takeTypeProfile(
525550
return Response::Success();
526551
}
527552

528-
Response V8ProfilerAgentImpl::enableRuntimeCallStats() {
553+
Response V8ProfilerAgentImpl::enableCounters() {
529554
if (m_counters)
530-
return Response::ServerError(
531-
"RuntimeCallStats collection already enabled.");
555+
return Response::ServerError("Counters collection already enabled.");
532556

533557
if (V8Inspector* inspector = v8::debug::GetInspector(m_isolate))
534558
m_counters = inspector->enableCounters();
@@ -538,16 +562,16 @@ Response V8ProfilerAgentImpl::enableRuntimeCallStats() {
538562
return Response::Success();
539563
}
540564

541-
Response V8ProfilerAgentImpl::disableRuntimeCallStats() {
565+
Response V8ProfilerAgentImpl::disableCounters() {
542566
if (m_counters) m_counters.reset();
543567
return Response::Success();
544568
}
545569

546-
Response V8ProfilerAgentImpl::getRuntimeCallStats(
570+
Response V8ProfilerAgentImpl::getCounters(
547571
std::unique_ptr<protocol::Array<protocol::Profiler::CounterInfo>>*
548572
out_result) {
549573
if (!m_counters)
550-
return Response::ServerError("RuntimeCallStats collection is not enabled.");
574+
return Response::ServerError("Counters collection is not enabled.");
551575

552576
*out_result =
553577
std::make_unique<protocol::Array<protocol::Profiler::CounterInfo>>();
@@ -564,6 +588,66 @@ Response V8ProfilerAgentImpl::getRuntimeCallStats(
564588
return Response::Success();
565589
}
566590

591+
Response V8ProfilerAgentImpl::enableRuntimeCallStats() {
592+
if (v8::internal::TracingFlags::runtime_stats.load()) {
593+
return Response::ServerError(
594+
"Runtime Call Stats collection is already enabled.");
595+
}
596+
597+
v8::internal::TracingFlags::runtime_stats.store(true);
598+
m_runtime_call_stats_enabled = true;
599+
600+
return Response::Success();
601+
}
602+
603+
Response V8ProfilerAgentImpl::disableRuntimeCallStats() {
604+
if (!v8::internal::TracingFlags::runtime_stats.load()) {
605+
return Response::ServerError(
606+
"Runtime Call Stats collection is not enabled.");
607+
}
608+
609+
if (!m_runtime_call_stats_enabled) {
610+
return Response::ServerError(
611+
"Runtime Call Stats collection was not enabled by this session.");
612+
}
613+
614+
v8::internal::TracingFlags::runtime_stats.store(false);
615+
m_runtime_call_stats_enabled = false;
616+
617+
return Response::Success();
618+
}
619+
620+
Response V8ProfilerAgentImpl::getRuntimeCallStats(
621+
std::unique_ptr<
622+
protocol::Array<protocol::Profiler::RuntimeCallCounterInfo>>*
623+
out_result) {
624+
if (!m_runtime_call_stats_enabled) {
625+
return Response::ServerError(
626+
"Runtime Call Stats collection is not enabled.");
627+
}
628+
629+
if (!v8::internal::TracingFlags::runtime_stats.load()) {
630+
return Response::ServerError(
631+
"Runtime Call Stats collection was disabled outside of this session.");
632+
}
633+
634+
*out_result = std::make_unique<
635+
protocol::Array<protocol::Profiler::RuntimeCallCounterInfo>>();
636+
637+
v8::debug::EnumerateRuntimeCallCounters(
638+
m_isolate,
639+
[&](const char* name, int64_t count, v8::base::TimeDelta time) {
640+
(*out_result)
641+
->emplace_back(protocol::Profiler::RuntimeCallCounterInfo::create()
642+
.setName(String16(name))
643+
.setValue(static_cast<double>(count))
644+
.setTime(time.InSecondsF())
645+
.build());
646+
});
647+
648+
return Response::Success();
649+
}
650+
567651
String16 V8ProfilerAgentImpl::nextProfileId() {
568652
return String16::fromInteger(
569653
v8::base::Relaxed_AtomicIncrement(&s_lastProfileId, 1));

src/inspector/v8-profiler-agent-impl.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,17 @@ class V8ProfilerAgentImpl : public protocol::Profiler::Backend {
5757
std::unique_ptr<protocol::Array<protocol::Profiler::ScriptTypeProfile>>*
5858
out_result) override;
5959

60+
Response enableCounters() override;
61+
Response disableCounters() override;
62+
Response getCounters(
63+
std::unique_ptr<protocol::Array<protocol::Profiler::CounterInfo>>*
64+
out_result) override;
65+
6066
Response enableRuntimeCallStats() override;
6167
Response disableRuntimeCallStats() override;
6268
Response getRuntimeCallStats(
63-
std::unique_ptr<protocol::Array<protocol::Profiler::CounterInfo>>*
69+
std::unique_ptr<
70+
protocol::Array<protocol::Profiler::RuntimeCallCounterInfo>>*
6471
out_result) override;
6572

6673
void consoleProfile(const String16& title);
@@ -87,6 +94,7 @@ class V8ProfilerAgentImpl : public protocol::Profiler::Backend {
8794
String16 m_frontendInitiatedProfileId;
8895
int m_startedProfilesCount = 0;
8996
std::shared_ptr<V8Inspector::Counters> m_counters;
97+
bool m_runtime_call_stats_enabled = false;
9098

9199
DISALLOW_COPY_AND_ASSIGN(V8ProfilerAgentImpl);
92100
};

src/logging/counters.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,17 @@ void RuntimeCallStats::Print(std::ostream& os) {
557557
entries.Print(os);
558558
}
559559

560+
void RuntimeCallStats::EnumerateCounters(
561+
debug::RuntimeCallCounterCallback callback) {
562+
if (current_timer_.Value() != nullptr) {
563+
current_timer_.Value()->Snapshot();
564+
}
565+
for (int i = 0; i < kNumberOfCounters; i++) {
566+
RuntimeCallCounter* counter = GetCounter(i);
567+
callback(counter->name(), counter->count(), counter->time());
568+
}
569+
}
570+
560571
void RuntimeCallStats::Reset() {
561572
if (V8_LIKELY(!TracingFlags::is_runtime_stats_enabled())) return;
562573

src/logging/counters.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "src/base/platform/elapsed-timer.h"
1414
#include "src/base/platform/time.h"
1515
#include "src/common/globals.h"
16+
#include "src/debug/debug-interface.h"
1617
#include "src/execution/isolate.h"
1718
#include "src/init/heap-symbols.h"
1819
#include "src/logging/counters-definitions.h"
@@ -1146,6 +1147,9 @@ class RuntimeCallStats final {
11461147
V8_EXPORT_PRIVATE void Print();
11471148
V8_NOINLINE void Dump(v8::tracing::TracedValue* value);
11481149

1150+
V8_EXPORT_PRIVATE void EnumerateCounters(
1151+
debug::RuntimeCallCounterCallback callback);
1152+
11491153
ThreadId thread_id() const { return thread_id_; }
11501154
RuntimeCallTimer* current_timer() { return current_timer_.Value(); }
11511155
RuntimeCallCounter* current_counter() { return current_counter_.Value(); }

test/inspector/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ v8_executable("inspector-test") {
3232

3333
data = [
3434
"console/",
35+
"counters/",
3536
"cpu-profiler/",
3637
"debugger/",
3738
"heap-profiler/",
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Test Counters collection using Profiler.getCounters.
2+
PASSED

0 commit comments

Comments
 (0)