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

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

Issue 2602003002: fe: minor change to benchmarks to match what the runners expect (Closed)
Patch Set: . Created 3 years, 11 months 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 | « pkg/compiler/tool/perf.dart ('k') | 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; 9 import 'dart:io' show exit;
10 10
(...skipping 19 matching lines...) Expand all
30 import 'package:front_end/src/scanner/token.dart'; 30 import 'package:front_end/src/scanner/token.dart';
31 import 'package:kernel/kernel.dart'; 31 import 'package:kernel/kernel.dart';
32 import 'package:package_config/discovery.dart'; 32 import 'package:package_config/discovery.dart';
33 33
34 main(List<String> args) async { 34 main(List<String> args) async {
35 // TODO(sigmund): provide sdk folder as well. 35 // TODO(sigmund): provide sdk folder as well.
36 if (args.length < 2) { 36 if (args.length < 2) {
37 print('usage: perf.dart <bench-id> <entry.dart>'); 37 print('usage: perf.dart <bench-id> <entry.dart>');
38 exit(1); 38 exit(1);
39 } 39 }
40 var totalTimer = new Stopwatch()..start();
41 40
42 var bench = args[0]; 41 var bench = args[0];
43 var entryUri = Uri.base.resolve(args[1]); 42 var entryUri = Uri.base.resolve(args[1]);
44 43
45 await setup(entryUri); 44 await setup(entryUri);
46 45
46 Set<Source> files = scanReachableFiles(entryUri);
47 var handlers = { 47 var handlers = {
48 'scan': () async { 48 'scan': () async => scanFiles(files),
49 Set<Source> files = scanReachableFiles(entryUri); 49 'parse': () async => parseFiles(files),
50 // TODO(sigmund): replace the warmup with instrumented snapshots.
51 for (int i = 0; i < 10; i++) scanFiles(files);
52 },
53 'parse': () async {
54 Set<Source> files = scanReachableFiles(entryUri);
55 // TODO(sigmund): replace the warmup with instrumented snapshots.
56 for (int i = 0; i < 10; i++) parseFiles(files);
57 },
58 'kernel_gen_e2e': () async { 50 'kernel_gen_e2e': () async {
59 // TODO(sigmund): remove. This is used to compute the input size, we 51 await generateKernel(entryUri, useSdkSummary: false);
60 // should extract input size from frontend instead.
61 scanReachableFiles(entryUri);
62 // TODO(sigmund): replace this warmup. Note that for very large programs,
63 // the GC pressure on the VM seems to make this worse with time (maybe we
64 // are leaking memory?). That's why we run it twice and not 10 times.
65 for (int i = 0; i < 2; i++) {
66 await generateKernel(entryUri, useSdkSummary: false);
67 }
68 }, 52 },
69 'kernel_gen_e2e_sum': () async { 53 'kernel_gen_e2e_sum': () async {
70 // TODO(sigmund): remove. This is incorrect since it includes sizes for 54 await generateKernel(entryUri, useSdkSummary: true, compileSdk: false);
71 // files that will not be loaded when using summaries. We need to extract
72 // input size from frontend instead.
73 scanReachableFiles(entryUri);
74 // TODO(sigmund): replace this warmup. Note that for very large programs,
75 // the GC pressure on the VM seems to make this worse with time (maybe we
76 // are leaking memory?). That's why we run it twice and not 10 times.
77 for (int i = 0; i < 2; i++) {
78 await generateKernel(entryUri, useSdkSummary: true, compileSdk: false);
79 }
80 }, 55 },
81 'unlinked_summarize': () async { 56 'unlinked_summarize': () async => summarize(files),
82 Set<Source> files = scanReachableFiles(entryUri); 57 'prelinked_summarize': () async => summarize(files, prelink: true),
83 // TODO(sigmund): replace the warmup with instrumented snapshots. 58 'linked_summarize': () async => summarize(files, link: true),
84 for (int i = 0; i < 10; i++) unlinkedSummarizeFiles(files);
85 },
86 'prelinked_summarize': () async {
87 Set<Source> files = scanReachableFiles(entryUri);
88 // TODO(sigmund): replace the warmup with instrumented snapshots.
89 for (int i = 0; i < 10; i++) prelinkedSummarizeFiles(files);
90 },
91 'linked_summarize': () async {
92 Set<Source> files = scanReachableFiles(entryUri);
93 // TODO(sigmund): replace the warmup with instrumented snapshots.
94 for (int i = 0; i < 10; i++) linkedSummarizeFiles(files);
95 }
96 }; 59 };
97 60
98 var handler = handlers[bench]; 61 var handler = handlers[bench];
99 if (handler == null) { 62 if (handler == null) {
100 // TODO(sigmund): implement the remaining benchmarks.
101 print('unsupported bench-id: $bench. Please specify one of the following: ' 63 print('unsupported bench-id: $bench. Please specify one of the following: '
102 '${handlers.keys.join(", ")}'); 64 '${handlers.keys.join(", ")}');
103 exit(1); 65 exit(1);
104 } 66 }
105 await handler();
106 67
107 totalTimer.stop(); 68 // TODO(sigmund): replace the warmup with instrumented snapshots.
108 report("total", totalTimer.elapsedMicroseconds); 69 int iterations = bench.contains('kernel_gen') ? 2 : 10;
70 for (int i = 0; i < iterations; i++) {
71 var totalTimer = new Stopwatch()..start();
72 print('== iteration $i');
73 await handler();
74 totalTimer.stop();
75 report("total", totalTimer.elapsedMicroseconds);
76 }
77
109 } 78 }
110 79
111 /// Cumulative time spent parsing. 80 /// Cumulative time spent parsing.
112 Stopwatch parseTimer = new Stopwatch(); 81 Stopwatch parseTimer = new Stopwatch();
113 82
114 /// Cumulative time spent prelinking summaries. 83 /// Cumulative time spent building unlinked summaries.
115 Stopwatch prelinkSummaryTimer = new Stopwatch(); 84 Stopwatch unlinkedSummarizeTimer = new Stopwatch();
116 85
117 /// Cumulative time spent scanning. 86 /// Cumulative time spent scanning.
118 Stopwatch scanTimer = new Stopwatch(); 87 Stopwatch scanTimer = new Stopwatch();
119 88
120 /// Cumulative total number of chars scanned. 89 /// Size of all sources.
121 int scanTotalChars = 0; 90 int inputSize = 0;
122 91
123 /// Factory to load and resolve app, packages, and sdk sources. 92 /// Factory to load and resolve app, packages, and sdk sources.
124 SourceFactory sources; 93 SourceFactory sources;
125 94
126 /// Cumulative time spent building unlinked summaries.
127 Stopwatch unlinkedSummarizeTimer = new Stopwatch();
128
129 /// Add to [files] all sources reachable from [start]. 95 /// Add to [files] all sources reachable from [start].
130 void collectSources(Source start, Set<Source> files) { 96 void collectSources(Source start, Set<Source> files) {
131 if (!files.add(start)) return; 97 if (!files.add(start)) return;
132 var unit = parseDirectives(start); 98 var unit = parseDirectives(start);
133 for (var directive in unit.directives) { 99 for (var directive in unit.directives) {
134 if (directive is UriBasedDirective) { 100 if (directive is UriBasedDirective) {
135 var next = sources.resolveUri(start, directive.uri.stringValue); 101 var next = sources.resolveUri(start, directive.uri.stringValue);
136 collectSources(next, files); 102 collectSources(next, files);
137 } 103 }
138 } 104 }
139 } 105 }
140 106
141 Future<Program> generateKernel(Uri entryUri, 107 Future<Program> generateKernel(Uri entryUri,
142 {bool useSdkSummary: false, bool compileSdk: true}) async { 108 {bool useSdkSummary: false, bool compileSdk: true}) async {
109 // TODO(sigmund): this is here only to compute the input size,
110 // we should extract the input size from the frontend instead.
111 scanReachableFiles(entryUri);
112
143 var dartkTimer = new Stopwatch()..start(); 113 var dartkTimer = new Stopwatch()..start();
144 // TODO(sigmund): add a constructor with named args to compiler options. 114 // TODO(sigmund): add a constructor with named args to compiler options.
145 var options = new CompilerOptions() 115 var options = new CompilerOptions()
146 ..strongMode = false 116 ..strongMode = false
147 ..compileSdk = compileSdk 117 ..compileSdk = compileSdk
148 ..packagesFilePath = '.packages' 118 ..packagesFilePath = '.packages'
149 ..onError = ((e) => print('${e.message}')); 119 ..onError = ((e) => print('${e.message}'));
150 if (useSdkSummary) { 120 if (useSdkSummary) {
151 // TODO(sigmund): adjust path based on the benchmark runner architecture. 121 // TODO(sigmund): adjust path based on the benchmark runner architecture.
152 // Possibly let the runner make the file available at an architecture 122 // Possibly let the runner make the file available at an architecture
153 // independent location. 123 // independent location.
154 options.sdkSummary = 'out/ReleaseX64/dart-sdk/lib/_internal/spec.sum'; 124 options.sdkSummary = 'out/ReleaseX64/dart-sdk/lib/_internal/spec.sum';
155 } else { 125 } else {
156 options.sdkPath = 'sdk'; 126 options.sdkPath = 'sdk';
157 } 127 }
158 Program program = await kernelForProgram(entryUri, options); 128 Program program = await kernelForProgram(entryUri, options);
159 dartkTimer.stop(); 129 dartkTimer.stop();
160 var suffix = useSdkSummary ? "_sum" : ""; 130 var suffix = useSdkSummary ? "_sum" : "";
161 report("kernel_gen_e2e${suffix}", dartkTimer.elapsedMicroseconds); 131 report("kernel_gen_e2e${suffix}", dartkTimer.elapsedMicroseconds);
162 return program; 132 return program;
163 } 133 }
164 134
165 /// Generates unlinkmed summaries for all files in [files], and returns them in 135 /// Generates unlinkmed summaries for all files in [files], and returns them in
166 /// an [UnlinkedSummaries] container. 136 /// an [_UnlinkedSummaries] container.
167 UnlinkedSummaries generateUnlinkedSummaries(Set<Source> files) { 137 _UnlinkedSummaries generateUnlinkedSummaries(Set<Source> files) {
168 var unlinkedSummaries = new UnlinkedSummaries(); 138 var unlinkedSummaries = new _UnlinkedSummaries();
169 for (var source in files) { 139 for (var source in files) {
170 unlinkedSummaries.summariesByUri[source.uri.toString()] = 140 unlinkedSummaries.summariesByUri[source.uri.toString()] =
171 unlinkedSummarize(source); 141 unlinkedSummarize(source);
172 } 142 }
173 return unlinkedSummaries; 143 return unlinkedSummaries;
174 } 144 }
175 145
176 /// Produces linked summaries for every file in [files] and reports the time 146 /// Produces linked summaries for every file in [files] and reports the time
Paul Berry 2017/01/03 17:58:34 Doc comment is no longer accurate.
Siggi Cherem (dart-lang) 2017/01/04 00:01:04 Done.
177 /// spent doing so. 147 /// spent doing so.
178 void linkedSummarizeFiles(Set<Source> files) { 148 void summarize(Set<Source> files, {bool prelink: false, bool link: false}) {
179 // The code below will record again how many chars are scanned and how long it
180 // takes to scan them, even though we already did so in [scanReachableFiles].
181 // Recording and reporting this twice is unnecessary, but we do so for now to
182 // validate that the results are consistent.
183 scanTimer = new Stopwatch(); 149 scanTimer = new Stopwatch();
184 var old = scanTotalChars;
185 scanTotalChars = 0;
186 parseTimer = new Stopwatch(); 150 parseTimer = new Stopwatch();
187 unlinkedSummarizeTimer = new Stopwatch(); 151 unlinkedSummarizeTimer = new Stopwatch();
188 var unlinkedSummaries = generateUnlinkedSummaries(files); 152 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();
203
204 if (old != scanTotalChars) print('input size changed? ${old} chars');
205 report("scan", scanTimer.elapsedMicroseconds); 153 report("scan", scanTimer.elapsedMicroseconds);
206 report("parse", parseTimer.elapsedMicroseconds); 154 report("parse", parseTimer.elapsedMicroseconds);
207 report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds); 155 report('unlink extract', unlinkedSummarizeTimer.elapsedMicroseconds);
Paul Berry 2017/01/03 17:58:34 I don't really have strong feelings about nomencla
Siggi Cherem (dart-lang) 2017/01/04 00:01:04 In all honestly, I'm not convinced about "extract"
Paul Berry 2017/01/04 13:55:43 In that case I'd prefer (b), on the theory that tr
208 report( 156 report(
209 'unlinked summarize + parse', 157 'unlinked_summarize',
210 unlinkedSummarizeTimer.elapsedMicroseconds + 158 unlinkedSummarizeTimer.elapsedMicroseconds +
211 parseTimer.elapsedMicroseconds); 159 parseTimer.elapsedMicroseconds);
212 report('prelink', prelinkSummaryTimer.elapsedMicroseconds); 160
213 report('link', linkTimer.elapsedMicroseconds); 161 if (prelink || link) {
162 var prelinkTimer = new Stopwatch()..start();
163 var prelinkedLibraries = prelinkSummaries(files, unlinkedSummaries);
164 prelinkTimer.stop();
165 report('prelinked_summarize', prelinkTimer.elapsedMicroseconds);
166
167 if (link) {
168 var linkTimer = new Stopwatch()..start();
169 LinkedLibrary getDependency(String uri) {
170 // getDependency should never be called because all dependencies are
171 // present in [prelinkedLibraries].
172 print('Warning: getDependency called for: $uri');
173 return null;
174 }
175
176 relink(prelinkedLibraries, getDependency, unlinkedSummaries.getUnit,
177 true /*strong*/);
178 linkTimer.stop();
179 report('linked_summarize', linkTimer.elapsedMicroseconds);
180 }
181 }
214 } 182 }
215 183
216 /// Uses the diet-parser to parse only directives in [source]. 184 /// Uses the diet-parser to parse only directives in [source].
217 CompilationUnit parseDirectives(Source source) { 185 CompilationUnit parseDirectives(Source source) {
218 var token = tokenize(source); 186 var token = tokenize(source);
219 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER); 187 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER);
220 return parser.parseDirectives(token); 188 return parser.parseDirectives(token);
221 } 189 }
222 190
223 /// Parses every file in [files] and reports the time spent doing so. 191 /// Parses every file in [files] and reports the time spent doing so.
224 void parseFiles(Set<Source> files) { 192 void parseFiles(Set<Source> files) {
225 // The code below will record again how many chars are scanned and how long it
226 // takes to scan them, even though we already did so in [scanReachableFiles].
227 // Recording and reporting this twice is unnecessary, but we do so for now to
228 // validate that the results are consistent.
229 scanTimer = new Stopwatch(); 193 scanTimer = new Stopwatch();
230 var old = scanTotalChars;
231 scanTotalChars = 0;
232 parseTimer = new Stopwatch(); 194 parseTimer = new Stopwatch();
233 for (var source in files) { 195 for (var source in files) {
234 parseFull(source); 196 parseFull(source);
235 } 197 }
236 198
237 // Report size and scanning time again. See discussion above.
238 if (old != scanTotalChars) print('input size changed? ${old} chars');
239 report("scan", scanTimer.elapsedMicroseconds); 199 report("scan", scanTimer.elapsedMicroseconds);
240 report("parse", parseTimer.elapsedMicroseconds); 200 report("parse", parseTimer.elapsedMicroseconds);
241 } 201 }
242 202
243 /// Parse the full body of [source] and return it's compilation unit. 203 /// Parse the full body of [source] and return it's compilation unit.
244 CompilationUnit parseFull(Source source) { 204 CompilationUnit parseFull(Source source) {
245 var token = tokenize(source); 205 var token = tokenize(source);
246 parseTimer.start(); 206 parseTimer.start();
247 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER); 207 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER);
248 var unit = parser.parseCompilationUnit(token); 208 var unit = parser.parseCompilationUnit(token);
249 parseTimer.stop(); 209 parseTimer.stop();
250 return unit; 210 return unit;
251 } 211 }
252 212
253 /// Produces prelinked summaries for every file in [files] and reports the time
254 /// spent doing so.
255 void prelinkedSummarizeFiles(Set<Source> files) {
256 // The code below will record again how many chars are scanned and how long it
257 // takes to scan them, even though we already did so in [scanReachableFiles].
258 // Recording and reporting this twice is unnecessary, but we do so for now to
259 // validate that the results are consistent.
260 scanTimer = new Stopwatch();
261 var old = scanTotalChars;
262 scanTotalChars = 0;
263 parseTimer = new Stopwatch();
264 unlinkedSummarizeTimer = new Stopwatch();
265 var unlinkedSummaries = generateUnlinkedSummaries(files);
266 prelinkSummaryTimer = new Stopwatch();
267 prelinkSummaries(files, unlinkedSummaries);
268
269 if (old != scanTotalChars) print('input size changed? ${old} chars');
270 report("scan", scanTimer.elapsedMicroseconds);
271 report("parse", parseTimer.elapsedMicroseconds);
272 report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds);
273 report(
274 'unlinked summarize + parse',
275 unlinkedSummarizeTimer.elapsedMicroseconds +
276 parseTimer.elapsedMicroseconds);
277 report('prelink', prelinkSummaryTimer.elapsedMicroseconds);
278 }
279
280 /// Prelinks all the summaries for [files], using [unlinkedSummaries] to obtain 213 /// Prelinks all the summaries for [files], using [unlinkedSummaries] to obtain
281 /// their unlinked summaries. 214 /// their unlinked summaries.
282 /// 215 ///
283 /// The return value is suitable for passing to the summary linker. 216 /// The return value is suitable for passing to the summary linker.
284 Map<String, LinkedLibraryBuilder> prelinkSummaries( 217 Map<String, LinkedLibraryBuilder> prelinkSummaries(
285 Set<Source> files, UnlinkedSummaries unlinkedSummaries) { 218 Set<Source> files, _UnlinkedSummaries unlinkedSummaries) {
286 prelinkSummaryTimer.start(); 219 Set<String> libraryUris = files.map((source) => '${source.uri}').toSet();
287 Set<String> libraryUris =
288 files.map((source) => source.uri.toString()).toSet();
289 220
290 String getDeclaredVariable(String s) => null; 221 String getDeclaredVariable(String s) => null;
291 var prelinkedLibraries = 222 var prelinkedLibraries =
292 setupForLink(libraryUris, unlinkedSummaries.getUnit, getDeclaredVariable); 223 setupForLink(libraryUris, unlinkedSummaries.getUnit, getDeclaredVariable);
293 prelinkSummaryTimer.stop();
294 return prelinkedLibraries; 224 return prelinkedLibraries;
295 } 225 }
296 226
297 /// Report that metric [name] took [time] micro-seconds to process 227 /// Report that metric [name] took [time] micro-seconds to process
298 /// [scanTotalChars] characters. 228 /// [inputSize] characters.
299 void report(String name, int time) { 229 void report(String name, int time) {
300 var sb = new StringBuffer(); 230 var sb = new StringBuffer();
301 sb.write('$name: $time us, ${time ~/ 1000} ms'); 231 var padding = " " * (20 - name.length);
302 sb.write(', ${scanTotalChars * 1000 ~/ time} chars/ms'); 232 sb.write('$name:$padding $time us, ${time ~/ 1000} ms');
233 sb.write(', ${time * 1000 ~/ inputSize} ns/char');
303 print('$sb'); 234 print('$sb');
304 } 235 }
305 236
306 /// Scans every file in [files] and reports the time spent doing so. 237 /// Scans every file in [files] and reports the time spent doing so.
307 void scanFiles(Set<Source> files) { 238 void scanFiles(Set<Source> files) {
308 // The code below will record again how many chars are scanned and how long it 239 // `tokenize` records how many chars are scanned and how long it takes to scan
309 // takes to scan them, even though we already did so in [scanReachableFiles]. 240 // them. As this function is called repeatedly when running as a benchmark, we
310 // Recording and reporting this twice is unnecessary, but we do so for now to 241 // make sure to clear the data and compute it again every time.
311 // validate that the results are consistent.
312 scanTimer = new Stopwatch(); 242 scanTimer = new Stopwatch();
313 var old = scanTotalChars;
314 scanTotalChars = 0;
315 for (var source in files) { 243 for (var source in files) {
316 tokenize(source); 244 tokenize(source);
317 } 245 }
318 246
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); 247 report("scan", scanTimer.elapsedMicroseconds);
322 } 248 }
323 249
324 /// Load and scans all files we need to process: files reachable from the 250 /// Load and scans all files we need to process: files reachable from the
325 /// entrypoint and all core libraries automatically included by the VM. 251 /// entrypoint and all core libraries automatically included by the VM.
326 Set<Source> scanReachableFiles(Uri entryUri) { 252 Set<Source> scanReachableFiles(Uri entryUri) {
327 var files = new Set<Source>(); 253 var files = new Set<Source>();
328 var loadTimer = new Stopwatch()..start(); 254 var loadTimer = new Stopwatch()..start();
329 collectSources(sources.forUri2(entryUri), files); 255 collectSources(sources.forUri2(entryUri), files);
330 256
(...skipping 10 matching lines...) Expand all
341 "dart:typed_data", 267 "dart:typed_data",
342 "dart:io" 268 "dart:io"
343 ]; 269 ];
344 270
345 for (var lib in libs) { 271 for (var lib in libs) {
346 collectSources(sources.forUri(lib), files); 272 collectSources(sources.forUri(lib), files);
347 } 273 }
348 274
349 loadTimer.stop(); 275 loadTimer.stop();
350 276
351 print('input size: ${scanTotalChars} chars'); 277 for (var s in files) inputSize += s.contents.data.length;
278 print('input size: ${inputSize} chars');
352 var loadTime = loadTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds; 279 var loadTime = loadTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds;
353 report("load", loadTime); 280 report("load", loadTime);
354 report("scan", scanTimer.elapsedMicroseconds); 281 report("scan", scanTimer.elapsedMicroseconds);
355 return files; 282 return files;
356 } 283 }
357 284
358 /// Sets up analyzer to be able to load and resolve app, packages, and sdk 285 /// Sets up analyzer to be able to load and resolve app, packages, and sdk
359 /// sources. 286 /// sources.
360 Future setup(Uri entryUri) async { 287 Future setup(Uri entryUri) async {
361 var provider = PhysicalResourceProvider.INSTANCE; 288 var provider = PhysicalResourceProvider.INSTANCE;
362 var packageMap = new ContextBuilder(provider, null, null) 289 var packageMap = new ContextBuilder(provider, null, null)
363 .convertPackagesToMap(await findPackages(entryUri)); 290 .convertPackagesToMap(await findPackages(entryUri));
364 sources = new SourceFactory([ 291 sources = new SourceFactory([
365 new ResourceUriResolver(provider), 292 new ResourceUriResolver(provider),
366 new PackageMapUriResolver(provider, packageMap), 293 new PackageMapUriResolver(provider, packageMap),
367 new DartUriResolver( 294 new DartUriResolver(
368 new FolderBasedDartSdk(provider, provider.getFolder("sdk"))), 295 new FolderBasedDartSdk(provider, provider.getFolder("sdk"))),
369 ]); 296 ]);
370 } 297 }
371 298
372 /// Scan [source] and return the first token produced by the scanner. 299 /// Scan [source] and return the first token produced by the scanner.
373 Token tokenize(Source source) { 300 Token tokenize(Source source) {
374 scanTimer.start(); 301 scanTimer.start();
375 var contents = source.contents.data;
376 scanTotalChars += contents.length;
377 // TODO(sigmund): is there a way to scan from a random-access-file without 302 // TODO(sigmund): is there a way to scan from a random-access-file without
378 // first converting to String? 303 // first converting to String?
379 var scanner = new _Scanner(contents); 304 var scanner = new _Scanner(source.contents.data);
380 var token = scanner.tokenize(); 305 var token = scanner.tokenize();
381 scanTimer.stop(); 306 scanTimer.stop();
382 return token; 307 return token;
383 } 308 }
384 309
385 UnlinkedUnitBuilder unlinkedSummarize(Source source) { 310 UnlinkedUnitBuilder unlinkedSummarize(Source source) {
386 var unit = parseFull(source); 311 var unit = parseFull(source);
387 unlinkedSummarizeTimer.start(); 312 unlinkedSummarizeTimer.start();
388 var unlinkedUnit = serializeAstUnlinked(unit); 313 var unlinkedUnit = serializeAstUnlinked(unit);
389 unlinkedSummarizeTimer.stop(); 314 unlinkedSummarizeTimer.stop();
390 return unlinkedUnit; 315 return unlinkedUnit;
391 } 316 }
392 317
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. 318 /// Simple container for a mapping from URI string to an unlinked summary.
418 class UnlinkedSummaries { 319 class _UnlinkedSummaries {
419 final summariesByUri = <String, UnlinkedUnit>{}; 320 final summariesByUri = <String, UnlinkedUnit>{};
420 321
421 /// Get the unlinked summary for the given URI, and report a warning if it 322 /// Get the unlinked summary for the given URI, and report a warning if it
422 /// can't be found. 323 /// can't be found.
423 UnlinkedUnit getUnit(String uri) { 324 UnlinkedUnit getUnit(String uri) {
424 var result = summariesByUri[uri]; 325 var result = summariesByUri[uri];
425 if (result == null) { 326 if (result == null) {
426 print('Warning: no summary found for: $uri'); 327 print('Warning: no summary found for: $uri');
427 } 328 }
428 return result; 329 return result;
429 } 330 }
430 } 331 }
431 332
432 class _Scanner extends Scanner { 333 class _Scanner extends Scanner {
433 _Scanner(String contents) : super(new CharSequenceReader(contents)) { 334 _Scanner(String contents) : super(new CharSequenceReader(contents)) {
434 preserveComments = false; 335 preserveComments = false;
435 } 336 }
436 337
437 @override 338 @override
438 void reportError(errorCode, int offset, List<Object> arguments) { 339 void reportError(errorCode, int offset, List<Object> arguments) {
439 // ignore errors. 340 // ignore errors.
440 } 341 }
441 } 342 }
OLDNEW
« no previous file with comments | « pkg/compiler/tool/perf.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698