| 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 front_end and measure its performance. | 5 /// An entrypoint used to run portions of front_end and measure its performance. |
| 6 library front_end.tool.perf; | 6 library front_end.tool.perf; |
| 7 | 7 |
| 8 import 'dart:async'; | 8 import 'dart:async'; |
| 9 import 'dart:io' show exit, stderr; | 9 import 'dart:io' show exit, stderr; |
| 10 | 10 |
| 11 import 'package:analyzer/dart/ast/ast.dart'; | 11 import 'package:analyzer/dart/ast/ast.dart'; |
| 12 import 'package:analyzer/error/listener.dart'; | 12 import 'package:analyzer/error/listener.dart'; |
| 13 import 'package:analyzer/file_system/file_system.dart' show ResourceUriResolver; | 13 import 'package:analyzer/file_system/file_system.dart' show ResourceUriResolver; |
| 14 import 'package:analyzer/file_system/physical_file_system.dart' | 14 import 'package:analyzer/file_system/physical_file_system.dart' |
| 15 show PhysicalResourceProvider; | 15 show PhysicalResourceProvider; |
| 16 import 'package:analyzer/source/package_map_resolver.dart'; | 16 import 'package:analyzer/source/package_map_resolver.dart'; |
| 17 import 'package:analyzer/src/context/builder.dart'; | 17 import 'package:analyzer/src/context/builder.dart'; |
| 18 import 'package:analyzer/src/dart/sdk/sdk.dart' show FolderBasedDartSdk; | 18 import 'package:analyzer/src/dart/sdk/sdk.dart' show FolderBasedDartSdk; |
| 19 import 'package:analyzer/src/generated/parser.dart'; | 19 import 'package:analyzer/src/generated/parser.dart'; |
| 20 import 'package:analyzer/src/generated/source.dart'; | 20 import 'package:analyzer/src/generated/source.dart'; |
| 21 import 'package:analyzer/src/generated/source_io.dart'; | 21 import 'package:analyzer/src/generated/source_io.dart'; |
| 22 import 'package:analyzer/src/summary/format.dart'; | 22 import 'package:analyzer/src/summary/format.dart'; |
| 23 import 'package:analyzer/src/summary/idl.dart'; |
| 24 import 'package:analyzer/src/summary/prelink.dart'; |
| 23 import 'package:analyzer/src/summary/summarize_ast.dart'; | 25 import 'package:analyzer/src/summary/summarize_ast.dart'; |
| 24 import 'package:kernel/analyzer/loader.dart'; | 26 import 'package:kernel/analyzer/loader.dart'; |
| 25 import 'package:kernel/kernel.dart'; | 27 import 'package:kernel/kernel.dart'; |
| 26 import 'package:package_config/discovery.dart'; | 28 import 'package:package_config/discovery.dart'; |
| 27 | 29 |
| 28 import 'package:front_end/src/scanner/reader.dart'; | 30 import 'package:front_end/src/scanner/reader.dart'; |
| 29 import 'package:front_end/src/scanner/scanner.dart'; | 31 import 'package:front_end/src/scanner/scanner.dart'; |
| 30 import 'package:front_end/src/scanner/token.dart'; | 32 import 'package:front_end/src/scanner/token.dart'; |
| 31 | 33 |
| 32 /// Cumulative total number of chars scanned. | 34 /// Cumulative total number of chars scanned. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 scanReachableFiles(entryUri); | 76 scanReachableFiles(entryUri); |
| 75 // TODO(sigmund): replace this warmup. Note that for very large programs, | 77 // TODO(sigmund): replace this warmup. Note that for very large programs, |
| 76 // the GC pressure on the VM seems to make this worse with time (maybe we | 78 // the GC pressure on the VM seems to make this worse with time (maybe we |
| 77 // are leaking memory?). That's why we run it twice and not 10 times. | 79 // are leaking memory?). That's why we run it twice and not 10 times. |
| 78 for (int i = 0; i < 2; i++) await generateKernel(entryUri); | 80 for (int i = 0; i < 2; i++) await generateKernel(entryUri); |
| 79 }, | 81 }, |
| 80 'unlinked_summarize': () async { | 82 'unlinked_summarize': () async { |
| 81 Set<Source> files = scanReachableFiles(entryUri); | 83 Set<Source> files = scanReachableFiles(entryUri); |
| 82 // TODO(sigmund): replace the warmup with instrumented snapshots. | 84 // TODO(sigmund): replace the warmup with instrumented snapshots. |
| 83 for (int i = 0; i < 10; i++) unlinkedSummarizeFiles(files); | 85 for (int i = 0; i < 10; i++) unlinkedSummarizeFiles(files); |
| 86 }, |
| 87 'prelinked_summarize': () async { |
| 88 Set<Source> files = scanReachableFiles(entryUri); |
| 89 // TODO(sigmund): replace the warmup with instrumented snapshots. |
| 90 for (int i = 0; i < 10; i++) prelinkedSummarizeFiles(files); |
| 84 } | 91 } |
| 85 }; | 92 }; |
| 86 | 93 |
| 87 var handler = handlers[bench]; | 94 var handler = handlers[bench]; |
| 88 if (handler == null) { | 95 if (handler == null) { |
| 89 // TODO(sigmund): implement the remaining benchmarks. | 96 // TODO(sigmund): implement the remaining benchmarks. |
| 90 print('unsupported bench-id: $bench. Please specify one of the following: ' | 97 print('unsupported bench-id: $bench. Please specify one of the following: ' |
| 91 '${handlers.keys.join(", ")}'); | 98 '${handlers.keys.join(", ")}'); |
| 92 exit(1); | 99 exit(1); |
| 93 } | 100 } |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 if (old != scanTotalChars) print('input size changed? ${old} chars'); | 209 if (old != scanTotalChars) print('input size changed? ${old} chars'); |
| 203 report("scan", scanTimer.elapsedMicroseconds); | 210 report("scan", scanTimer.elapsedMicroseconds); |
| 204 report("parse", parseTimer.elapsedMicroseconds); | 211 report("parse", parseTimer.elapsedMicroseconds); |
| 205 report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds); | 212 report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds); |
| 206 report( | 213 report( |
| 207 'unlinked summarize + parse', | 214 'unlinked summarize + parse', |
| 208 unlinkedSummarizeTimer.elapsedMicroseconds + | 215 unlinkedSummarizeTimer.elapsedMicroseconds + |
| 209 parseTimer.elapsedMicroseconds); | 216 parseTimer.elapsedMicroseconds); |
| 210 } | 217 } |
| 211 | 218 |
| 219 /// Produces prelinked summaries for every file in [files] and reports the time |
| 220 /// spent doing so. |
| 221 void prelinkedSummarizeFiles(Set<Source> files) { |
| 222 // The code below will record again how many chars are scanned and how long it |
| 223 // takes to scan them, even though we already did so in [scanReachableFiles]. |
| 224 // Recording and reporting this twice is unnecessary, but we do so for now to |
| 225 // validate that the results are consistent. |
| 226 scanTimer = new Stopwatch(); |
| 227 var old = scanTotalChars; |
| 228 scanTotalChars = 0; |
| 229 parseTimer = new Stopwatch(); |
| 230 unlinkedSummarizeTimer = new Stopwatch(); |
| 231 var unlinkedSummaries = <Source, UnlinkedUnit>{}; |
| 232 for (var source in files) { |
| 233 unlinkedSummaries[source] = unlinkedSummarize(source); |
| 234 } |
| 235 var prelinkTimer = new Stopwatch()..start(); |
| 236 for (var source in files) { |
| 237 UnlinkedUnit getSummary(String uri) { |
| 238 var resolvedUri = sources.resolveUri(source, uri); |
| 239 var result = unlinkedSummaries[resolvedUri]; |
| 240 if (result == null) { |
| 241 print('Warning: no summary found for: $uri'); |
| 242 } |
| 243 return result; |
| 244 } |
| 245 |
| 246 UnlinkedPublicNamespace getImport(String uri) => |
| 247 getSummary(uri)?.publicNamespace; |
| 248 String getDeclaredVariable(String s) => null; |
| 249 prelink( |
| 250 unlinkedSummaries[source], getSummary, getImport, getDeclaredVariable); |
| 251 } |
| 252 prelinkTimer.stop(); |
| 253 |
| 254 if (old != scanTotalChars) print('input size changed? ${old} chars'); |
| 255 report("scan", scanTimer.elapsedMicroseconds); |
| 256 report("parse", parseTimer.elapsedMicroseconds); |
| 257 report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds); |
| 258 report( |
| 259 'unlinked summarize + parse', |
| 260 unlinkedSummarizeTimer.elapsedMicroseconds + |
| 261 parseTimer.elapsedMicroseconds); |
| 262 report('prelink', prelinkTimer.elapsedMicroseconds); |
| 263 } |
| 264 |
| 212 /// Add to [files] all sources reachable from [start]. | 265 /// Add to [files] all sources reachable from [start]. |
| 213 void collectSources(Source start, Set<Source> files) { | 266 void collectSources(Source start, Set<Source> files) { |
| 214 if (!files.add(start)) return; | 267 if (!files.add(start)) return; |
| 215 var unit = parseDirectives(start); | 268 var unit = parseDirectives(start); |
| 216 for (var directive in unit.directives) { | 269 for (var directive in unit.directives) { |
| 217 if (directive is UriBasedDirective) { | 270 if (directive is UriBasedDirective) { |
| 218 var next = sources.resolveUri(start, directive.uri.stringValue); | 271 var next = sources.resolveUri(start, directive.uri.stringValue); |
| 219 collectSources(next, files); | 272 collectSources(next, files); |
| 220 } | 273 } |
| 221 } | 274 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 const int errorLimit = 100; | 347 const int errorLimit = 100; |
| 295 stderr.writeln(errors.take(errorLimit).join('\n')); | 348 stderr.writeln(errors.take(errorLimit).join('\n')); |
| 296 if (errors.length > errorLimit) { | 349 if (errors.length > errorLimit) { |
| 297 stderr.writeln('[error] ${errors.length - errorLimit} errors not shown'); | 350 stderr.writeln('[error] ${errors.length - errorLimit} errors not shown'); |
| 298 } | 351 } |
| 299 } | 352 } |
| 300 dartkTimer.stop(); | 353 dartkTimer.stop(); |
| 301 report("kernel_gen_e2e", dartkTimer.elapsedMicroseconds); | 354 report("kernel_gen_e2e", dartkTimer.elapsedMicroseconds); |
| 302 return program; | 355 return program; |
| 303 } | 356 } |
| OLD | NEW |