blob: 0a8312986610a254b0caf6b090c6612522de9a15 [file] [log] [blame] [edit]
// Copyright (c) 2014, 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.
library;
import 'package:kernel/text/indentation.dart' show Indentation;
import '../compiler_api.dart' as api;
import 'js_model/js_world.dart' show JClosedWorld;
import 'options.dart' show CompilerOptions;
import 'ssa/nodes.dart' as ssa show HGraph;
import 'ssa/tracer.dart' show HTracer;
String? traceFilterPatternForTest;
/// Dumps the intermediate representation after each phase in a format
/// readable by IR Hydra.
class Tracer with TracerUtil {
final JClosedWorld closedWorld;
bool traceActive = false;
@override
final api.OutputSink? output;
final RegExp? traceFilter;
Tracer._(this.closedWorld, this.traceFilter, this.output);
factory Tracer(
JClosedWorld closedWorld,
CompilerOptions options,
api.CompilerOutput compilerOutput,
) {
String? pattern = options.dumpSsaPattern ?? traceFilterPatternForTest;
if (pattern == null) return Tracer._(closedWorld, null, null);
var traceFilter = RegExp(pattern);
var output = compilerOutput.createOutputSink(
'',
'cfg',
api.OutputType.debug,
);
return Tracer._(closedWorld, traceFilter, output);
}
bool get isEnabled => traceFilter != null;
void traceCompilation(String methodName) {
if (!isEnabled) return;
traceActive = traceFilter!.hasMatch(methodName);
if (!traceActive) return;
tag("compilation", () {
printProperty("name", methodName);
printProperty("method", methodName);
printProperty("date", DateTime.now().millisecondsSinceEpoch);
});
}
void traceGraph(String name, ssa.HGraph graph) {
if (!traceActive) return;
HTracer(output!, closedWorld).traceGraph(name, graph);
}
void traceJavaScriptText(String name, String Function() getText) {
if (!traceActive) return;
HTracer(output!, closedWorld).traceJavaScriptText(name, getText());
}
void close() {
if (output != null) {
output!.close();
}
}
}
mixin TracerUtil {
api.OutputSink? get output;
final Indentation _ind = Indentation();
void tag(String tagName, Function f) {
println("begin_$tagName");
_ind.indentBlock(f);
println("end_$tagName");
}
void println(String string) {
addIndent();
add(string);
add("\n");
}
void printEmptyProperty(String propertyName) {
println(propertyName);
}
String formatPrty(Object? x) {
if (x is num) {
return '$x';
} else if (x is String) {
return '"$x"';
} else if (x is Iterable) {
return x.map((s) => formatPrty(s)).join(' ');
} else {
throw "invalid property type: $x";
}
}
void printProperty(String propertyName, Object? value) {
println("$propertyName ${formatPrty(value)}");
}
void add(String string) {
output!.add(string);
}
void addIndent() {
add(_ind.indentation);
}
}