Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(799)

Side by Side Diff: pkg/front_end/tool/perf.dart

Issue 2562643006: Fix "unused import" warnings and sort declarations. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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;
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'; 23 import 'package:analyzer/src/summary/idl.dart';
24 import 'package:analyzer/src/summary/link.dart'; 24 import 'package:analyzer/src/summary/link.dart';
25 import 'package:analyzer/src/summary/summarize_ast.dart'; 25 import 'package:analyzer/src/summary/summarize_ast.dart';
26 import 'package:kernel/analyzer/loader.dart';
27 import 'package:kernel/kernel.dart';
28 import 'package:package_config/discovery.dart';
29
30 import 'package:front_end/compiler_options.dart'; 26 import 'package:front_end/compiler_options.dart';
31 import 'package:front_end/kernel_generator.dart'; 27 import 'package:front_end/kernel_generator.dart';
32 import 'package:front_end/src/scanner/reader.dart'; 28 import 'package:front_end/src/scanner/reader.dart';
33 import 'package:front_end/src/scanner/scanner.dart'; 29 import 'package:front_end/src/scanner/scanner.dart';
34 import 'package:front_end/src/scanner/token.dart'; 30 import 'package:front_end/src/scanner/token.dart';
35 31 import 'package:kernel/kernel.dart';
36 /// Cumulative total number of chars scanned. 32 import 'package:package_config/discovery.dart';
37 int scanTotalChars = 0;
38
39 /// Cumulative time spent scanning.
40 Stopwatch scanTimer = new Stopwatch();
41
42 /// Cumulative time spent parsing.
43 Stopwatch parseTimer = new Stopwatch();
44
45 /// Cumulative time spent building unlinked summaries.
46 Stopwatch unlinkedSummarizeTimer = new Stopwatch();
47
48 /// Cumulative time spent prelinking summaries.
49 Stopwatch prelinkSummaryTimer = new Stopwatch();
50
51 /// Factory to load and resolve app, packages, and sdk sources.
52 SourceFactory sources;
53 33
54 main(List<String> args) async { 34 main(List<String> args) async {
55 // TODO(sigmund): provide sdk folder as well. 35 // TODO(sigmund): provide sdk folder as well.
56 if (args.length < 2) { 36 if (args.length < 2) {
57 print('usage: perf.dart <bench-id> <entry.dart>'); 37 print('usage: perf.dart <bench-id> <entry.dart>');
58 exit(1); 38 exit(1);
59 } 39 }
60 var totalTimer = new Stopwatch()..start(); 40 var totalTimer = new Stopwatch()..start();
61 41
62 var bench = args[0]; 42 var bench = args[0];
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 print('unsupported bench-id: $bench. Please specify one of the following: ' 101 print('unsupported bench-id: $bench. Please specify one of the following: '
122 '${handlers.keys.join(", ")}'); 102 '${handlers.keys.join(", ")}');
123 exit(1); 103 exit(1);
124 } 104 }
125 await handler(); 105 await handler();
126 106
127 totalTimer.stop(); 107 totalTimer.stop();
128 report("total", totalTimer.elapsedMicroseconds); 108 report("total", totalTimer.elapsedMicroseconds);
129 } 109 }
130 110
131 /// Sets up analyzer to be able to load and resolve app, packages, and sdk 111 /// Cumulative time spent parsing.
132 /// sources. 112 Stopwatch parseTimer = new Stopwatch();
133 Future setup(Uri entryUri) async { 113
134 var provider = PhysicalResourceProvider.INSTANCE; 114 /// Cumulative time spent prelinking summaries.
135 var packageMap = new ContextBuilder(provider, null, null) 115 Stopwatch prelinkSummaryTimer = new Stopwatch();
136 .convertPackagesToMap(await findPackages(entryUri)); 116
137 sources = new SourceFactory([ 117 /// Cumulative time spent scanning.
138 new ResourceUriResolver(provider), 118 Stopwatch scanTimer = new Stopwatch();
139 new PackageMapUriResolver(provider, packageMap), 119
140 new DartUriResolver( 120 /// Cumulative total number of chars scanned.
141 new FolderBasedDartSdk(provider, provider.getFolder("sdk"))), 121 int scanTotalChars = 0;
142 ]); 122
123 /// Factory to load and resolve app, packages, and sdk sources.
124 SourceFactory sources;
125
126 /// Cumulative time spent building unlinked summaries.
127 Stopwatch unlinkedSummarizeTimer = new Stopwatch();
128
129 /// Add to [files] all sources reachable from [start].
130 void collectSources(Source start, Set<Source> files) {
131 if (!files.add(start)) return;
132 var unit = parseDirectives(start);
133 for (var directive in unit.directives) {
134 if (directive is UriBasedDirective) {
135 var next = sources.resolveUri(start, directive.uri.stringValue);
136 collectSources(next, files);
137 }
138 }
143 } 139 }
144 140
145 /// Load and scans all files we need to process: files reachable from the 141 Future<Program> generateKernel(Uri entryUri,
146 /// entrypoint and all core libraries automatically included by the VM. 142 {bool useSdkSummary: false, bool compileSdk: true}) async {
147 Set<Source> scanReachableFiles(Uri entryUri) { 143 var dartkTimer = new Stopwatch()..start();
148 var files = new Set<Source>(); 144 // TODO(sigmund): add a constructor with named args to compiler options.
149 var loadTimer = new Stopwatch()..start(); 145 var options = new CompilerOptions()
150 collectSources(sources.forUri2(entryUri), files); 146 ..strongMode = false
151 147 ..compileSdk = compileSdk
152 var libs = [ 148 ..packagesFilePath = '.packages'
153 "dart:async", 149 ..onError = ((e) => print('${e.message}'));
154 "dart:collection", 150 if (useSdkSummary) {
155 "dart:convert", 151 // TODO(sigmund): adjust path based on the benchmark runner architecture.
156 "dart:core", 152 // Possibly let the runner make the file available at an architecture
157 "dart:developer", 153 // independent location.
158 "dart:_internal", 154 options.sdkSummary = 'out/ReleaseX64/dart-sdk/lib/_internal/spec.sum';
159 "dart:isolate", 155 } else {
160 "dart:math", 156 options.sdkPath = 'sdk';
161 "dart:mirrors",
162 "dart:typed_data",
163 "dart:io"
164 ];
165
166 for (var lib in libs) {
167 collectSources(sources.forUri(lib), files);
168 } 157 }
169 158 Program program = await kernelForProgram(entryUri, options);
170 loadTimer.stop(); 159 dartkTimer.stop();
171 160 var suffix = useSdkSummary ? "_sum" : "";
172 print('input size: ${scanTotalChars} chars'); 161 report("kernel_gen_e2e${suffix}", dartkTimer.elapsedMicroseconds);
173 var loadTime = loadTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds; 162 return program;
174 report("load", loadTime);
175 report("scan", scanTimer.elapsedMicroseconds);
176 return files;
177 } 163 }
178 164
179 /// Scans every file in [files] and reports the time spent doing so. 165 /// Generates unlinkmed summaries for all files in [files], and returns them in
180 void scanFiles(Set<Source> files) { 166 /// an [UnlinkedSummaries] container.
167 UnlinkedSummaries generateUnlinkedSummaries(Set<Source> files) {
168 var unlinkedSummaries = new UnlinkedSummaries();
169 for (var source in files) {
170 unlinkedSummaries.summariesByUri[source.uri.toString()] =
171 unlinkedSummarize(source);
172 }
173 return unlinkedSummaries;
174 }
175
176 /// Produces linked summaries for every file in [files] and reports the time
177 /// spent doing so.
178 void linkedSummarizeFiles(Set<Source> files) {
181 // The code below will record again how many chars are scanned and how long it 179 // The code below will record again how many chars are scanned and how long it
182 // takes to scan them, even though we already did so in [scanReachableFiles]. 180 // takes to scan them, even though we already did so in [scanReachableFiles].
183 // Recording and reporting this twice is unnecessary, but we do so for now to 181 // Recording and reporting this twice is unnecessary, but we do so for now to
184 // validate that the results are consistent.
185 scanTimer = new Stopwatch();
186 var old = scanTotalChars;
187 scanTotalChars = 0;
188 for (var source in files) {
189 tokenize(source);
190 }
191
192 // Report size and scanning time again. See discussion above.
193 if (old != scanTotalChars) print('input size changed? ${old} chars');
194 report("scan", scanTimer.elapsedMicroseconds);
195 }
196
197 /// Parses every file in [files] and reports the time spent doing so.
198 void parseFiles(Set<Source> files) {
199 // The code below will record again how many chars are scanned and how long it
200 // takes to scan them, even though we already did so in [scanReachableFiles].
201 // Recording and reporting this twice is unnecessary, but we do so for now to
202 // validate that the results are consistent.
203 scanTimer = new Stopwatch();
204 var old = scanTotalChars;
205 scanTotalChars = 0;
206 parseTimer = new Stopwatch();
207 for (var source in files) {
208 parseFull(source);
209 }
210
211 // Report size and scanning time again. See discussion above.
212 if (old != scanTotalChars) print('input size changed? ${old} chars');
213 report("scan", scanTimer.elapsedMicroseconds);
214 report("parse", parseTimer.elapsedMicroseconds);
215 }
216
217 /// Produces unlinked summaries for every file in [files] and reports the time
218 /// spent doing so.
219 void unlinkedSummarizeFiles(Set<Source> files) {
220 // The code below will record again how many chars are scanned and how long it
221 // takes to scan them, even though we already did so in [scanReachableFiles].
222 // Recording and reporting this twice is unnecessary, but we do so for now to
223 // validate that the results are consistent. 182 // validate that the results are consistent.
224 scanTimer = new Stopwatch(); 183 scanTimer = new Stopwatch();
225 var old = scanTotalChars; 184 var old = scanTotalChars;
226 scanTotalChars = 0; 185 scanTotalChars = 0;
227 parseTimer = new Stopwatch(); 186 parseTimer = new Stopwatch();
228 unlinkedSummarizeTimer = new Stopwatch(); 187 unlinkedSummarizeTimer = new Stopwatch();
229 generateUnlinkedSummaries(files); 188 var unlinkedSummaries = generateUnlinkedSummaries(files);
189 prelinkSummaryTimer = new Stopwatch();
190 Map<String, LinkedLibraryBuilder> prelinkedLibraries =
191 prelinkSummaries(files, unlinkedSummaries);
192 var linkTimer = new Stopwatch()..start();
193 LinkedLibrary getDependency(String uri) {
194 // getDependency should never be called because all dependencies are present
195 // in [prelinkedLibraries].
196 print('Warning: getDependency called for: $uri');
197 return null;
198 }
199
200 bool strong = true;
201 relink(prelinkedLibraries, getDependency, unlinkedSummaries.getUnit, strong);
202 linkTimer.stop();
230 203
231 if (old != scanTotalChars) print('input size changed? ${old} chars'); 204 if (old != scanTotalChars) print('input size changed? ${old} chars');
232 report("scan", scanTimer.elapsedMicroseconds); 205 report("scan", scanTimer.elapsedMicroseconds);
233 report("parse", parseTimer.elapsedMicroseconds); 206 report("parse", parseTimer.elapsedMicroseconds);
234 report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds); 207 report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds);
235 report( 208 report(
236 'unlinked summarize + parse', 209 'unlinked summarize + parse',
237 unlinkedSummarizeTimer.elapsedMicroseconds + 210 unlinkedSummarizeTimer.elapsedMicroseconds +
238 parseTimer.elapsedMicroseconds); 211 parseTimer.elapsedMicroseconds);
212 report('prelink', prelinkSummaryTimer.elapsedMicroseconds);
213 report('link', linkTimer.elapsedMicroseconds);
239 } 214 }
240 215
241 /// Simple container for a mapping from URI string to an unlinked summary. 216 /// Uses the diet-parser to parse only directives in [source].
242 class UnlinkedSummaries { 217 CompilationUnit parseDirectives(Source source) {
243 final summariesByUri = <String, UnlinkedUnit>{}; 218 var token = tokenize(source);
244 219 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER);
245 /// Get the unlinked summary for the given URI, and report a warning if it 220 return parser.parseDirectives(token);
246 /// can't be found.
247 UnlinkedUnit getUnit(String uri) {
248 var result = summariesByUri[uri];
249 if (result == null) {
250 print('Warning: no summary found for: $uri');
251 }
252 return result;
253 }
254 } 221 }
255 222
256 /// Generates unlinkmed summaries for all files in [files], and returns them in 223 /// Parses every file in [files] and reports the time spent doing so.
257 /// an [UnlinkedSummaries] container. 224 void parseFiles(Set<Source> files) {
258 UnlinkedSummaries generateUnlinkedSummaries(Set<Source> files) {
259 var unlinkedSummaries = new UnlinkedSummaries();
260 for (var source in files) {
261 unlinkedSummaries.summariesByUri[source.uri.toString()] =
262 unlinkedSummarize(source);
263 }
264 return unlinkedSummaries;
265 }
266
267 /// Produces prelinked summaries for every file in [files] and reports the time
268 /// spent doing so.
269 void prelinkedSummarizeFiles(Set<Source> files) {
270 // The code below will record again how many chars are scanned and how long it 225 // The code below will record again how many chars are scanned and how long it
271 // takes to scan them, even though we already did so in [scanReachableFiles]. 226 // takes to scan them, even though we already did so in [scanReachableFiles].
272 // Recording and reporting this twice is unnecessary, but we do so for now to 227 // Recording and reporting this twice is unnecessary, but we do so for now to
273 // validate that the results are consistent. 228 // validate that the results are consistent.
274 scanTimer = new Stopwatch(); 229 scanTimer = new Stopwatch();
275 var old = scanTotalChars; 230 var old = scanTotalChars;
276 scanTotalChars = 0; 231 scanTotalChars = 0;
277 parseTimer = new Stopwatch(); 232 parseTimer = new Stopwatch();
278 unlinkedSummarizeTimer = new Stopwatch(); 233 for (var source in files) {
279 var unlinkedSummaries = generateUnlinkedSummaries(files); 234 parseFull(source);
280 prelinkSummaryTimer = new Stopwatch(); 235 }
281 prelinkSummaries(files, unlinkedSummaries);
282 236
237 // Report size and scanning time again. See discussion above.
283 if (old != scanTotalChars) print('input size changed? ${old} chars'); 238 if (old != scanTotalChars) print('input size changed? ${old} chars');
284 report("scan", scanTimer.elapsedMicroseconds); 239 report("scan", scanTimer.elapsedMicroseconds);
285 report("parse", parseTimer.elapsedMicroseconds); 240 report("parse", parseTimer.elapsedMicroseconds);
286 report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds);
287 report(
288 'unlinked summarize + parse',
289 unlinkedSummarizeTimer.elapsedMicroseconds +
290 parseTimer.elapsedMicroseconds);
291 report('prelink', prelinkSummaryTimer.elapsedMicroseconds);
292 } 241 }
293 242
294 /// Produces linked summaries for every file in [files] and reports the time 243 /// Parse the full body of [source] and return it's compilation unit.
244 CompilationUnit parseFull(Source source) {
245 var token = tokenize(source);
246 parseTimer.start();
247 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER);
248 var unit = parser.parseCompilationUnit(token);
249 parseTimer.stop();
250 return unit;
251 }
252
253 /// Produces prelinked summaries for every file in [files] and reports the time
295 /// spent doing so. 254 /// spent doing so.
296 void linkedSummarizeFiles(Set<Source> files) { 255 void prelinkedSummarizeFiles(Set<Source> files) {
297 // The code below will record again how many chars are scanned and how long it 256 // The code below will record again how many chars are scanned and how long it
298 // takes to scan them, even though we already did so in [scanReachableFiles]. 257 // takes to scan them, even though we already did so in [scanReachableFiles].
299 // Recording and reporting this twice is unnecessary, but we do so for now to 258 // Recording and reporting this twice is unnecessary, but we do so for now to
300 // validate that the results are consistent. 259 // validate that the results are consistent.
301 scanTimer = new Stopwatch(); 260 scanTimer = new Stopwatch();
302 var old = scanTotalChars; 261 var old = scanTotalChars;
303 scanTotalChars = 0; 262 scanTotalChars = 0;
304 parseTimer = new Stopwatch(); 263 parseTimer = new Stopwatch();
305 unlinkedSummarizeTimer = new Stopwatch(); 264 unlinkedSummarizeTimer = new Stopwatch();
306 var unlinkedSummaries = generateUnlinkedSummaries(files); 265 var unlinkedSummaries = generateUnlinkedSummaries(files);
307 prelinkSummaryTimer = new Stopwatch(); 266 prelinkSummaryTimer = new Stopwatch();
308 Map<String, LinkedLibraryBuilder> prelinkedLibraries = 267 prelinkSummaries(files, unlinkedSummaries);
309 prelinkSummaries(files, unlinkedSummaries);
310 var linkTimer = new Stopwatch()..start();
311 LinkedLibrary getDependency(String uri) {
312 // getDependency should never be called because all dependencies are present
313 // in [prelinkedLibraries].
314 print('Warning: getDependency called for: $uri');
315 return null;
316 }
317
318 bool strong = true;
319 relink(prelinkedLibraries, getDependency, unlinkedSummaries.getUnit, strong);
320 linkTimer.stop();
321 268
322 if (old != scanTotalChars) print('input size changed? ${old} chars'); 269 if (old != scanTotalChars) print('input size changed? ${old} chars');
323 report("scan", scanTimer.elapsedMicroseconds); 270 report("scan", scanTimer.elapsedMicroseconds);
324 report("parse", parseTimer.elapsedMicroseconds); 271 report("parse", parseTimer.elapsedMicroseconds);
325 report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds); 272 report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds);
326 report( 273 report(
327 'unlinked summarize + parse', 274 'unlinked summarize + parse',
328 unlinkedSummarizeTimer.elapsedMicroseconds + 275 unlinkedSummarizeTimer.elapsedMicroseconds +
329 parseTimer.elapsedMicroseconds); 276 parseTimer.elapsedMicroseconds);
330 report('prelink', prelinkSummaryTimer.elapsedMicroseconds); 277 report('prelink', prelinkSummaryTimer.elapsedMicroseconds);
331 report('link', linkTimer.elapsedMicroseconds);
332 } 278 }
333 279
334 /// Prelinks all the summaries for [files], using [unlinkedSummaries] to obtain 280 /// Prelinks all the summaries for [files], using [unlinkedSummaries] to obtain
335 /// their unlinked summaries. 281 /// their unlinked summaries.
336 /// 282 ///
337 /// The return value is suitable for passing to the summary linker. 283 /// The return value is suitable for passing to the summary linker.
338 Map<String, LinkedLibraryBuilder> prelinkSummaries( 284 Map<String, LinkedLibraryBuilder> prelinkSummaries(
339 Set<Source> files, UnlinkedSummaries unlinkedSummaries) { 285 Set<Source> files, UnlinkedSummaries unlinkedSummaries) {
340 prelinkSummaryTimer.start(); 286 prelinkSummaryTimer.start();
341 Set<String> libraryUris = 287 Set<String> libraryUris =
342 files.map((source) => source.uri.toString()).toSet(); 288 files.map((source) => source.uri.toString()).toSet();
343 289
344 String getDeclaredVariable(String s) => null; 290 String getDeclaredVariable(String s) => null;
345 var prelinkedLibraries = 291 var prelinkedLibraries =
346 setupForLink(libraryUris, unlinkedSummaries.getUnit, getDeclaredVariable); 292 setupForLink(libraryUris, unlinkedSummaries.getUnit, getDeclaredVariable);
347 prelinkSummaryTimer.stop(); 293 prelinkSummaryTimer.stop();
348 return prelinkedLibraries; 294 return prelinkedLibraries;
349 } 295 }
350 296
351 /// Add to [files] all sources reachable from [start]. 297 /// Report that metric [name] took [time] micro-seconds to process
352 void collectSources(Source start, Set<Source> files) { 298 /// [scanTotalChars] characters.
353 if (!files.add(start)) return; 299 void report(String name, int time) {
354 var unit = parseDirectives(start); 300 var sb = new StringBuffer();
355 for (var directive in unit.directives) { 301 sb.write('$name: $time us, ${time ~/ 1000} ms');
356 if (directive is UriBasedDirective) { 302 sb.write(', ${scanTotalChars * 1000 ~/ time} chars/ms');
357 var next = sources.resolveUri(start, directive.uri.stringValue); 303 print('$sb');
358 collectSources(next, files);
359 }
360 }
361 } 304 }
362 305
363 /// Uses the diet-parser to parse only directives in [source]. 306 /// Scans every file in [files] and reports the time spent doing so.
364 CompilationUnit parseDirectives(Source source) { 307 void scanFiles(Set<Source> files) {
365 var token = tokenize(source); 308 // The code below will record again how many chars are scanned and how long it
366 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER); 309 // takes to scan them, even though we already did so in [scanReachableFiles].
367 return parser.parseDirectives(token); 310 // Recording and reporting this twice is unnecessary, but we do so for now to
311 // validate that the results are consistent.
312 scanTimer = new Stopwatch();
313 var old = scanTotalChars;
314 scanTotalChars = 0;
315 for (var source in files) {
316 tokenize(source);
317 }
318
319 // Report size and scanning time again. See discussion above.
320 if (old != scanTotalChars) print('input size changed? ${old} chars');
321 report("scan", scanTimer.elapsedMicroseconds);
368 } 322 }
369 323
370 /// Parse the full body of [source] and return it's compilation unit. 324 /// Load and scans all files we need to process: files reachable from the
371 CompilationUnit parseFull(Source source) { 325 /// entrypoint and all core libraries automatically included by the VM.
372 var token = tokenize(source); 326 Set<Source> scanReachableFiles(Uri entryUri) {
373 parseTimer.start(); 327 var files = new Set<Source>();
374 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER); 328 var loadTimer = new Stopwatch()..start();
375 var unit = parser.parseCompilationUnit(token); 329 collectSources(sources.forUri2(entryUri), files);
376 parseTimer.stop(); 330
377 return unit; 331 var libs = [
332 "dart:async",
333 "dart:collection",
334 "dart:convert",
335 "dart:core",
336 "dart:developer",
337 "dart:_internal",
338 "dart:isolate",
339 "dart:math",
340 "dart:mirrors",
341 "dart:typed_data",
342 "dart:io"
343 ];
344
345 for (var lib in libs) {
346 collectSources(sources.forUri(lib), files);
347 }
348
349 loadTimer.stop();
350
351 print('input size: ${scanTotalChars} chars');
352 var loadTime = loadTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds;
353 report("load", loadTime);
354 report("scan", scanTimer.elapsedMicroseconds);
355 return files;
378 } 356 }
379 357
380 UnlinkedUnitBuilder unlinkedSummarize(Source source) { 358 /// Sets up analyzer to be able to load and resolve app, packages, and sdk
381 var unit = parseFull(source); 359 /// sources.
382 unlinkedSummarizeTimer.start(); 360 Future setup(Uri entryUri) async {
383 var unlinkedUnit = serializeAstUnlinked(unit); 361 var provider = PhysicalResourceProvider.INSTANCE;
384 unlinkedSummarizeTimer.stop(); 362 var packageMap = new ContextBuilder(provider, null, null)
385 return unlinkedUnit; 363 .convertPackagesToMap(await findPackages(entryUri));
364 sources = new SourceFactory([
365 new ResourceUriResolver(provider),
366 new PackageMapUriResolver(provider, packageMap),
367 new DartUriResolver(
368 new FolderBasedDartSdk(provider, provider.getFolder("sdk"))),
369 ]);
386 } 370 }
387 371
388 /// Scan [source] and return the first token produced by the scanner. 372 /// Scan [source] and return the first token produced by the scanner.
389 Token tokenize(Source source) { 373 Token tokenize(Source source) {
390 scanTimer.start(); 374 scanTimer.start();
391 var contents = source.contents.data; 375 var contents = source.contents.data;
392 scanTotalChars += contents.length; 376 scanTotalChars += contents.length;
393 // TODO(sigmund): is there a way to scan from a random-access-file without 377 // TODO(sigmund): is there a way to scan from a random-access-file without
394 // first converting to String? 378 // first converting to String?
395 var scanner = new _Scanner(contents); 379 var scanner = new _Scanner(contents);
396 var token = scanner.tokenize(); 380 var token = scanner.tokenize();
397 scanTimer.stop(); 381 scanTimer.stop();
398 return token; 382 return token;
399 } 383 }
400 384
385 UnlinkedUnitBuilder unlinkedSummarize(Source source) {
386 var unit = parseFull(source);
387 unlinkedSummarizeTimer.start();
388 var unlinkedUnit = serializeAstUnlinked(unit);
389 unlinkedSummarizeTimer.stop();
390 return unlinkedUnit;
391 }
392
393 /// Produces unlinked summaries for every file in [files] and reports the time
394 /// spent doing so.
395 void unlinkedSummarizeFiles(Set<Source> files) {
396 // The code below will record again how many chars are scanned and how long it
397 // takes to scan them, even though we already did so in [scanReachableFiles].
398 // Recording and reporting this twice is unnecessary, but we do so for now to
399 // validate that the results are consistent.
400 scanTimer = new Stopwatch();
401 var old = scanTotalChars;
402 scanTotalChars = 0;
403 parseTimer = new Stopwatch();
404 unlinkedSummarizeTimer = new Stopwatch();
405 generateUnlinkedSummaries(files);
406
407 if (old != scanTotalChars) print('input size changed? ${old} chars');
408 report("scan", scanTimer.elapsedMicroseconds);
409 report("parse", parseTimer.elapsedMicroseconds);
410 report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds);
411 report(
412 'unlinked summarize + parse',
413 unlinkedSummarizeTimer.elapsedMicroseconds +
414 parseTimer.elapsedMicroseconds);
415 }
416
417 /// Simple container for a mapping from URI string to an unlinked summary.
418 class UnlinkedSummaries {
419 final summariesByUri = <String, UnlinkedUnit>{};
420
421 /// Get the unlinked summary for the given URI, and report a warning if it
422 /// can't be found.
423 UnlinkedUnit getUnit(String uri) {
424 var result = summariesByUri[uri];
425 if (result == null) {
426 print('Warning: no summary found for: $uri');
427 }
428 return result;
429 }
430 }
431
401 class _Scanner extends Scanner { 432 class _Scanner extends Scanner {
402 _Scanner(String contents) : super(new CharSequenceReader(contents)) { 433 _Scanner(String contents) : super(new CharSequenceReader(contents)) {
403 preserveComments = false; 434 preserveComments = false;
404 } 435 }
405 436
406 @override 437 @override
407 void reportError(errorCode, int offset, List<Object> arguments) { 438 void reportError(errorCode, int offset, List<Object> arguments) {
408 // ignore errors. 439 // ignore errors.
409 } 440 }
410 } 441 }
411
412 /// Report that metric [name] took [time] micro-seconds to process
413 /// [scanTotalChars] characters.
414 void report(String name, int time) {
415 var sb = new StringBuffer();
416 sb.write('$name: $time us, ${time ~/ 1000} ms');
417 sb.write(', ${scanTotalChars * 1000 ~/ time} chars/ms');
418 print('$sb');
419 }
420
421 Future<Program> generateKernel(Uri entryUri,
422 {bool useSdkSummary: false, bool compileSdk: true}) async {
423 var dartkTimer = new Stopwatch()..start();
424 // TODO(sigmund): add a constructor with named args to compiler options.
425 var options = new CompilerOptions()
426 ..strongMode = false
427 ..compileSdk = compileSdk
428 ..packagesFilePath = '.packages'
429 ..onError = ((e) => print('${e.message}'));
430 if (useSdkSummary) {
431 // TODO(sigmund): adjust path based on the benchmark runner architecture.
432 // Possibly let the runner make the file available at an architecture
433 // independent location.
434 options.sdkSummary = 'out/ReleaseX64/dart-sdk/lib/_internal/spec.sum';
435 } else {
436 options.sdkPath = 'sdk';
437 }
438 Program program = await kernelForProgram(entryUri, options);
439 dartkTimer.stop();
440 var suffix = useSdkSummary ? "_sum" : "";
441 report("kernel_gen_e2e${suffix}", dartkTimer.elapsedMicroseconds);
442 return program;
443 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698