[CFE] Allow counting method calls when instrumenting

When instrumenting one can use "--count" to instrument counting method
calls instead of instrumenting to create a flame graph.

From that I can for instance see that `Reference.node` is called 6+ mio
times when compiling compile.dart.

Example run:
out/ReleaseX64/dart pkg/front_end/tool/flame/instrumenter.dart pkg/front_end/tool/_fasta/compile.dart --count
out/ReleaseX64/dart pkg/front_end/tool/_fasta/compile.dart.dill.instrumented.dill pkg/front_end/tool/_fasta/compile.dart

Change-Id: I583f4b53a474c3777bb059ea89d932607b7c23ad
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/298100
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
This commit is contained in:
Jens Johansen 2023-04-25 10:11:30 +00:00 committed by Commit Queue
parent 1574e860c8
commit e5c2dd28c7
2 changed files with 92 additions and 7 deletions

26
pkg/front_end/tool/flame/instrumenter.dart Executable file → Normal file
View file

@ -26,8 +26,11 @@ Future<void> main(List<String> arguments) async {
Future<void> _main(List<String> inputArguments, Directory tmpDir) async {
List<String> candidates = [];
List<String> arguments = [];
bool doCount = false;
for (String arg in inputArguments) {
if (arg.startsWith("--candidates=")) {
if (arg == "--count") {
doCount = true;
} else if (arg.startsWith("--candidates=")) {
candidates.add(arg.substring("--candidates=".length));
} else {
arguments.add(arg);
@ -46,10 +49,14 @@ Future<void> _main(List<String> inputArguments, Directory tmpDir) async {
print("Compiling the instrumentation library.");
Uri instrumentationLibDill = tmpDir.uri.resolve("instrumenter.dill");
String libFilename = "instrumenter_lib.dart";
if (doCount) {
libFilename = "instrumenter_lib_counter.dart";
}
await fasta_compile.main([
"--omit-platform",
"-o=${instrumentationLibDill.toFilePath()}",
Platform.script.resolve("instrumenter_lib.dart").toFilePath()
Platform.script.resolve(libFilename).toFilePath()
]);
if (!File.fromUri(instrumentationLibDill).existsSync()) {
throw "Instrumentation library didn't compile as expected.";
@ -117,11 +124,15 @@ void addIfWanted(List<Procedure> output, List<Procedure> input,
}
}
String getName(Procedure p) {
String getName(Procedure p, {bool renameSetter = false}) {
String name = p.name.text;
if (renameSetter && p.isSetter) {
name = "set:$name";
}
if (p.parent is Class) {
return "${(p.parent as Class).name}.${p.name.text}";
return "${(p.parent as Class).name}.$name";
} else {
return p.name.text;
return name;
}
}
@ -162,8 +173,9 @@ void initializeAndReport(
instrumenterReport,
new Arguments([
new ListLiteral(procedures
.map((p) => new StringLiteral(
"${p.fileUri.pathSegments.last}|${getName(p)}"))
.map(
(p) => new StringLiteral("${p.fileUri.pathSegments.last}|"
"${getName(p, renameSetter: true)}"))
.toList()),
new BoolLiteral(reportCandidates),
])))),

View file

@ -0,0 +1,73 @@
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import "dart:typed_data";
Stopwatch stopwatch = new Stopwatch();
Uint32List counts = new Uint32List(0);
void initialize(int count) {
counts = new Uint32List(count);
stopwatch.start();
}
@pragma("vm:prefer-inline")
void enter(int i) {
counts[i]++;
}
@pragma("vm:prefer-inline")
void exit(int i) {}
void report(List<String> names, bool reportCandidates) {
List<NameWithCount> data = [];
for (int i = 0; i < counts.length; i++) {
int count = counts[i];
if (count < 10000) continue;
data.add(new NameWithCount(names[i], count));
}
data.sort((a, b) => a.count - b.count);
for (NameWithCount element in data) {
print("${_formatInt(element.count, 11)}: ${element.name}");
}
}
class NameWithCount {
final String name;
final int count;
NameWithCount(this.name, this.count);
}
String _formatInt(int input, int minLength) {
bool negative = false;
if (input < 0) {
negative = true;
input = -input;
}
String asString = "$input";
int length = asString.length;
int countSeparators = (length - 1) ~/ 3;
int outLength = length + countSeparators;
if (negative) outLength++;
StringBuffer sb = new StringBuffer();
if (outLength < minLength) {
sb.write(" " * (minLength - outLength));
}
if (negative) sb.write("-");
int end = length - (countSeparators * 3);
sb.write(asString.substring(0, end));
int begin = end;
end += 3;
while (end <= length) {
sb.write(",");
sb.write(asString.substring(begin, end));
begin = end;
end += 3;
}
return sb.toString();
}