Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /// An entrypoint used to run portions of dart2js and measure its performance. | 5 /// An entrypoint used to run portions of dart2js and measure its performance. |
| 6 library compiler.tool.perf; | 6 library compiler.tool.perf; |
| 7 | 7 |
| 8 import 'dart:async'; | 8 import 'dart:async'; |
| 9 import 'dart:io'; | 9 import 'dart:io'; |
| 10 | 10 |
| 11 import 'package:compiler/compiler_new.dart'; | 11 import 'package:compiler/compiler_new.dart'; |
| 12 import 'package:compiler/src/apiimpl.dart'; | |
| 13 import 'package:compiler/src/compiler.dart'; | |
| 14 import 'package:compiler/src/kernel/task.dart'; | |
| 15 import 'package:compiler/src/elements/elements.dart'; | |
| 12 import 'package:compiler/src/common.dart'; | 16 import 'package:compiler/src/common.dart'; |
| 13 import 'package:compiler/src/diagnostics/diagnostic_listener.dart'; | 17 import 'package:compiler/src/diagnostics/diagnostic_listener.dart'; |
| 14 import 'package:compiler/src/diagnostics/messages.dart' | 18 import 'package:compiler/src/diagnostics/messages.dart' |
| 15 show Message, MessageTemplate; | 19 show Message, MessageTemplate; |
| 16 import 'package:compiler/src/io/source_file.dart'; | 20 import 'package:compiler/src/io/source_file.dart'; |
| 17 import 'package:compiler/src/options.dart' show ParserOptions; | 21 import 'package:compiler/src/options.dart' show ParserOptions; |
| 18 import 'package:compiler/src/options.dart'; | 22 import 'package:compiler/src/options.dart'; |
| 19 import 'package:compiler/src/parser/element_listener.dart' show ScannerOptions; | 23 import 'package:compiler/src/parser/element_listener.dart' show ScannerOptions; |
| 20 import 'package:compiler/src/parser/listener.dart'; | 24 import 'package:compiler/src/parser/listener.dart'; |
| 21 import 'package:compiler/src/parser/node_listener.dart' show NodeListener; | 25 import 'package:compiler/src/parser/node_listener.dart' show NodeListener; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 44 print('usage: perf.dart <bench-id> <entry.dart>'); | 48 print('usage: perf.dart <bench-id> <entry.dart>'); |
| 45 exit(1); | 49 exit(1); |
| 46 } | 50 } |
| 47 var totalTimer = new Stopwatch()..start(); | 51 var totalTimer = new Stopwatch()..start(); |
| 48 | 52 |
| 49 var bench = args[0]; | 53 var bench = args[0]; |
| 50 var entryUri = Uri.base.resolve(args[1]); | 54 var entryUri = Uri.base.resolve(args[1]); |
| 51 | 55 |
| 52 await setup(entryUri); | 56 await setup(entryUri); |
| 53 | 57 |
| 54 if (bench == 'scan') { | 58 var handlers = { |
| 55 Set<SourceFile> files = await scanReachableFiles(entryUri); | 59 'scan': () async { |
| 56 // TODO(sigmund): consider replacing the warmup with instrumented snapshots. | 60 Set<SourceFile> files = await scanReachableFiles(entryUri); |
| 57 for (int i = 0; i < 10; i++) scanFiles(files); | 61 // TODO(sigmund): replace the warmup with instrumented snapshots. |
| 58 } else if (bench == 'parse') { | 62 for (int i = 0; i < 10; i++) scanFiles(files); |
| 59 Set<SourceFile> files = await scanReachableFiles(entryUri); | 63 }, |
| 60 // TODO(sigmund): consider replacing the warmup with instrumented snapshots. | 64 'parse': () async { |
| 61 for (int i = 0; i < 10; i++) parseFiles(files); | 65 Set<SourceFile> files = await scanReachableFiles(entryUri); |
| 62 } else { | 66 // TODO(sigmund): replace the warmup with instrumented snapshots. |
| 63 print('unsupported bench-id: $bench. Please specify "scan" or "parse"'); | 67 for (int i = 0; i < 10; i++) parseFiles(files); |
| 68 }, | |
| 69 'kernel_gen_e2e': () async { | |
| 70 // TODO(sigmund): remove. This is used to compute the input size, we | |
| 71 // should extract input size from frontend instead. | |
| 72 await scanReachableFiles(entryUri); | |
| 73 // TODO(sigmund): replace this warmup. Note that for very large programs, | |
| 74 // the GC pressure on the VM seems to make this worse with time (maybe we | |
| 75 // are leaking memory?). That's why we run it twice and not 10 times. | |
| 76 for (int i = 0; i < 2; i++) await generateKernel(entryUri); | |
| 77 }, | |
| 78 }; | |
| 79 | |
| 80 var handler = handlers[bench]; | |
| 81 if (handler == null) { | |
| 64 // TODO(sigmund): implement the remaining benchmarks. | 82 // TODO(sigmund): implement the remaining benchmarks. |
| 83 print('unsupported bench-id: $bench. Please specify one of the following: ' | |
| 84 '${handler.keys.join(", ")}'); | |
| 65 exit(1); | 85 exit(1); |
| 66 } | 86 } |
| 67 | 87 await handler(); |
| 68 totalTimer.stop(); | 88 totalTimer.stop(); |
| 69 report("total", totalTimer.elapsedMicroseconds); | 89 report("total", totalTimer.elapsedMicroseconds); |
| 70 } | 90 } |
| 71 | 91 |
| 72 Future setup(Uri entryUri) async { | 92 Future setup(Uri entryUri) async { |
| 73 var inputProvider = new CompilerSourceFileProvider(); | 93 var inputProvider = new CompilerSourceFileProvider(); |
| 74 var sdkLibraries = await platform.load(_platformConfigUri, inputProvider); | 94 var sdkLibraries = await platform.load(_platformConfigUri, inputProvider); |
| 75 var packages = await findPackages(entryUri); | 95 var packages = await findPackages(entryUri); |
| 76 loader = new _Loader(inputProvider, sdkLibraries, packages); | 96 loader = new _Loader(inputProvider, sdkLibraries, packages); |
| 77 } | 97 } |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 310 return packages.resolve(uri, notFound: (_) { | 330 return packages.resolve(uri, notFound: (_) { |
| 311 print('$uri not found'); | 331 print('$uri not found'); |
| 312 }); | 332 }); |
| 313 } | 333 } |
| 314 } | 334 } |
| 315 | 335 |
| 316 class _ParserOptions implements ParserOptions { | 336 class _ParserOptions implements ParserOptions { |
| 317 const _ParserOptions(); | 337 const _ParserOptions(); |
| 318 bool get enableGenericMethodSyntax => true; | 338 bool get enableGenericMethodSyntax => true; |
| 319 } | 339 } |
| 340 | |
| 341 generateKernel(Uri entryUri) async { | |
| 342 var timer = new Stopwatch()..start(); | |
| 343 var options = new CompilerOptions( | |
| 344 entryPoint: entryUri, | |
| 345 libraryRoot: _libraryRoot, | |
| 346 packagesDiscoveryProvider: findPackages, | |
| 347 platformConfigUri: _platformConfigUri, | |
| 348 useKernel: true, | |
| 349 verbose: false); // set to true to debug internal timings | |
| 350 var inputProvider = new CompilerSourceFileProvider(); | |
| 351 var diagnosticHandler = new FormattingDiagnosticHandler(inputProvider) | |
| 352 ..verbose = options.verbose; | |
| 353 var compiler = new MyCompiler(inputProvider, diagnosticHandler, options); | |
| 354 await compiler.run(entryUri); | |
| 355 timer.stop(); | |
| 356 report("kernel_gen_e2e", timer.elapsedMicroseconds); | |
| 357 } | |
| 358 | |
| 359 // We subclass compiler to skip phases and stop after creating kernel. | |
| 360 class MyCompiler extends CompilerImpl { | |
| 361 MyCompiler(CompilerInput provider, CompilerDiagnostics handler, | |
| 362 CompilerOptions options) | |
| 363 : super(provider, null, handler, options) {} | |
| 364 | |
| 365 /// Performs the compilation when all libraries have been loaded. | |
| 366 void compileLoadedLibraries() => | |
| 367 selfTask.measureSubtask("KernelCompiler.compileLoadedLibraries", () { | |
| 368 computeMain(); | |
| 369 mirrorUsageAnalyzerTask.analyzeUsage(mainApp); | |
| 370 | |
| 371 deferredLoadTask.beforeResolution(this); | |
| 372 impactStrategy = backend.createImpactStrategy( | |
| 373 supportDeferredLoad: deferredLoadTask.isProgramSplit, | |
| 374 supportDumpInfo: options.dumpInfo, | |
| 375 supportSerialization: serialization.supportSerialization); | |
| 376 | |
| 377 phase = Compiler.PHASE_RESOLVING; | |
| 378 | |
| 379 // Note: we enqueue everything in the program so we measure generating | |
| 380 // kernel for the entire code, not just what's reachable from main. | |
| 381 libraryLoader.libraries.forEach((LibraryElement library) { | |
| 382 fullyEnqueueLibrary(library, enqueuer.resolution); | |
| 383 }); | |
| 384 | |
| 385 backend.enqueueHelpers(enqueuer.resolution, globalDependencies); | |
| 386 resolveLibraryMetadata(); | |
| 387 reporter.log('Resolving...'); | |
| 388 processQueue(enqueuer.resolution, mainFunction); | |
| 389 enqueuer.resolution.logSummary(reporter.log); | |
| 390 | |
| 391 (reporter as CompilerDiagnosticReporter) | |
| 392 .reportSuppressedMessagesSummary(); | |
| 393 | |
| 394 if (compilationFailed) { | |
| 395 // TODO(sigmund): more diagnostics? | |
| 396 print("compilation failed!"); | |
| 397 exit(1); | |
| 398 } | |
| 399 | |
| 400 closeResolution(); | |
| 401 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
| |
| 402 var p = b.kernelTask.program; | |
| 403 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
| |
| 404 print('total libraries: ${p.libraries.length}'); | |
| 405 }); | |
| 406 } | |
| OLD | NEW |