| Index: pkg/compiler/tool/perf.dart
|
| diff --git a/pkg/compiler/tool/perf.dart b/pkg/compiler/tool/perf.dart
|
| index 51f98d61021901b04ac80ef5644223be97e48c82..2cd9d0c38d458c98169ebc89a634c493adcb0d47 100644
|
| --- a/pkg/compiler/tool/perf.dart
|
| +++ b/pkg/compiler/tool/perf.dart
|
| @@ -9,6 +9,10 @@ import 'dart:async';
|
| import 'dart:io';
|
|
|
| import 'package:compiler/compiler_new.dart';
|
| +import 'package:compiler/src/apiimpl.dart';
|
| +import 'package:compiler/src/compiler.dart';
|
| +import 'package:compiler/src/kernel/task.dart';
|
| +import 'package:compiler/src/elements/elements.dart';
|
| import 'package:compiler/src/common.dart';
|
| import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
|
| import 'package:compiler/src/diagnostics/messages.dart'
|
| @@ -51,20 +55,36 @@ main(List<String> args) async {
|
|
|
| await setup(entryUri);
|
|
|
| - if (bench == 'scan') {
|
| - Set<SourceFile> files = await scanReachableFiles(entryUri);
|
| - // TODO(sigmund): consider replacing the warmup with instrumented snapshots.
|
| - for (int i = 0; i < 10; i++) scanFiles(files);
|
| - } else if (bench == 'parse') {
|
| - Set<SourceFile> files = await scanReachableFiles(entryUri);
|
| - // TODO(sigmund): consider replacing the warmup with instrumented snapshots.
|
| - for (int i = 0; i < 10; i++) parseFiles(files);
|
| - } else {
|
| - print('unsupported bench-id: $bench. Please specify "scan" or "parse"');
|
| + var handlers = {
|
| + 'scan': () async {
|
| + Set<SourceFile> files = await scanReachableFiles(entryUri);
|
| + // TODO(sigmund): replace the warmup with instrumented snapshots.
|
| + for (int i = 0; i < 10; i++) scanFiles(files);
|
| + },
|
| + 'parse': () async {
|
| + Set<SourceFile> files = await scanReachableFiles(entryUri);
|
| + // TODO(sigmund): replace the warmup with instrumented snapshots.
|
| + for (int i = 0; i < 10; i++) parseFiles(files);
|
| + },
|
| + 'kernel_gen_e2e': () async {
|
| + // TODO(sigmund): remove. This is used to compute the input size, we
|
| + // should extract input size from frontend instead.
|
| + await scanReachableFiles(entryUri);
|
| + // TODO(sigmund): replace this warmup. Note that for very large programs,
|
| + // the GC pressure on the VM seems to make this worse with time (maybe we
|
| + // are leaking memory?). That's why we run it twice and not 10 times.
|
| + for (int i = 0; i < 2; i++) await generateKernel(entryUri);
|
| + },
|
| + };
|
| +
|
| + var handler = handlers[bench];
|
| + if (handler == null) {
|
| // TODO(sigmund): implement the remaining benchmarks.
|
| + print('unsupported bench-id: $bench. Please specify one of the following: '
|
| + '${handler.keys.join(", ")}');
|
| exit(1);
|
| }
|
| -
|
| + await handler();
|
| totalTimer.stop();
|
| report("total", totalTimer.elapsedMicroseconds);
|
| }
|
| @@ -317,3 +337,68 @@ class _ParserOptions implements ParserOptions {
|
| const _ParserOptions();
|
| bool get enableGenericMethodSyntax => true;
|
| }
|
| +
|
| +generateKernel(Uri entryUri) async {
|
| + var timer = new Stopwatch()..start();
|
| + var options = new CompilerOptions(
|
| + entryPoint: entryUri,
|
| + libraryRoot: _libraryRoot,
|
| + packagesDiscoveryProvider: findPackages,
|
| + platformConfigUri: _platformConfigUri,
|
| + useKernel: true,
|
| + verbose: false); // set to true to debug internal timings
|
| + var inputProvider = new CompilerSourceFileProvider();
|
| + var diagnosticHandler = new FormattingDiagnosticHandler(inputProvider)
|
| + ..verbose = options.verbose;
|
| + var compiler = new MyCompiler(inputProvider, diagnosticHandler, options);
|
| + await compiler.run(entryUri);
|
| + timer.stop();
|
| + report("kernel_gen_e2e", timer.elapsedMicroseconds);
|
| +}
|
| +
|
| +// We subclass compiler to skip phases and stop after creating kernel.
|
| +class MyCompiler extends CompilerImpl {
|
| + MyCompiler(CompilerInput provider, CompilerDiagnostics handler,
|
| + CompilerOptions options)
|
| + : super(provider, null, handler, options) {}
|
| +
|
| + /// Performs the compilation when all libraries have been loaded.
|
| + void compileLoadedLibraries() =>
|
| + selfTask.measureSubtask("KernelCompiler.compileLoadedLibraries", () {
|
| + computeMain();
|
| + mirrorUsageAnalyzerTask.analyzeUsage(mainApp);
|
| +
|
| + deferredLoadTask.beforeResolution(this);
|
| + impactStrategy = backend.createImpactStrategy(
|
| + supportDeferredLoad: deferredLoadTask.isProgramSplit,
|
| + supportDumpInfo: options.dumpInfo,
|
| + supportSerialization: serialization.supportSerialization);
|
| +
|
| + phase = Compiler.PHASE_RESOLVING;
|
| +
|
| + // Note: we enqueue everything in the program so we measure generating
|
| + // kernel for the entire code, not just what's reachable from main.
|
| + libraryLoader.libraries.forEach((LibraryElement library) {
|
| + fullyEnqueueLibrary(library, enqueuer.resolution);
|
| + });
|
| +
|
| + backend.enqueueHelpers(enqueuer.resolution, globalDependencies);
|
| + resolveLibraryMetadata();
|
| + reporter.log('Resolving...');
|
| + processQueue(enqueuer.resolution, mainFunction);
|
| + enqueuer.resolution.logSummary(reporter.log);
|
| +
|
| + (reporter as CompilerDiagnosticReporter)
|
| + .reportSuppressedMessagesSummary();
|
| +
|
| + if (compilationFailed) {
|
| + // TODO(sigmund): more diagnostics?
|
| + print("compilation failed!");
|
| + exit(1);
|
| + }
|
| +
|
| + closeResolution();
|
| + var program = (backend as dynamic).kernelTask.program;
|
| + print('total libraries: ${program.libraries.length}');
|
| + });
|
| +}
|
|
|