Chromium Code Reviews| Index: pkg/compiler/tool/perf.dart |
| diff --git a/pkg/compiler/tool/perf.dart b/pkg/compiler/tool/perf.dart |
| index 51f98d61021901b04ac80ef5644223be97e48c82..9cb7cef0cb8d89d67a3c1006bd3cec79ac2e58b2 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,70 @@ 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(); |
| + dynamic b = backend; |
|
Harry Terkelsen
2016/10/21 16:41:47
don't use single-letter variable names
Siggi Cherem (dart-lang)
2016/10/21 17:01:40
Done :), sorry I was just doing a quick and dirty
|
| + var p = b.kernelTask.program; |
| + tasks.add(b.kernelTask); |
|
Harry Terkelsen
2016/10/21 16:41:48
is this required?
Siggi Cherem (dart-lang)
2016/10/21 17:01:40
you are correct, it is not, I had this before addi
|
| + print('total libraries: ${p.libraries.length}'); |
| + }); |
| +} |