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

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 /// Generates unlinked summaries for every file in [files] and, if requested via
177 /// spent doing so. 147 /// [prelink] or [link], generates the pre-linked and linked summaries as well.
178 void linkedSummarizeFiles(Set<Source> files) { 148 ///
179 // The code below will record again how many chars are scanned and how long it 149 /// This function also prints a report of the time spent on each action.
180 // takes to scan them, even though we already did so in [scanReachableFiles]. 150 void summarize(Set<Source> files, {bool prelink: false, bool link: false}) {
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(); 151 scanTimer = new Stopwatch();
184 var old = scanTotalChars;
185 scanTotalChars = 0;
186 parseTimer = new Stopwatch(); 152 parseTimer = new Stopwatch();
187 unlinkedSummarizeTimer = new Stopwatch(); 153 unlinkedSummarizeTimer = new Stopwatch();
188 var unlinkedSummaries = generateUnlinkedSummaries(files); 154 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); 155 report("scan", scanTimer.elapsedMicroseconds);
206 report("parse", parseTimer.elapsedMicroseconds); 156 report("parse", parseTimer.elapsedMicroseconds);
207 report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds); 157 report('unlink extract', unlinkedSummarizeTimer.elapsedMicroseconds);
208 report( 158 report(
209 'unlinked summarize + parse', 159 'unlinked_summarize',
210 unlinkedSummarizeTimer.elapsedMicroseconds + 160 unlinkedSummarizeTimer.elapsedMicroseconds +
211 parseTimer.elapsedMicroseconds); 161 parseTimer.elapsedMicroseconds);
212 report('prelink', prelinkSummaryTimer.elapsedMicroseconds); 162
213 report('link', linkTimer.elapsedMicroseconds); 163 if (prelink || link) {
164 var prelinkTimer = new Stopwatch()..start();
165 var prelinkedLibraries = prelinkSummaries(files, unlinkedSummaries);
166 prelinkTimer.stop();
167 report('prelinked_summarize', prelinkTimer.elapsedMicroseconds);
168
169 if (link) {
170 var linkTimer = new Stopwatch()..start();
171 LinkedLibrary getDependency(String uri) {
172 // getDependency should never be called because all dependencies are
173 // present in [prelinkedLibraries].
174 print('Warning: getDependency called for: $uri');
175 return null;
176 }
177
178 relink(prelinkedLibraries, getDependency, unlinkedSummaries.getUnit,
179 true /*strong*/);
180 linkTimer.stop();
181 report('linked_summarize', linkTimer.elapsedMicroseconds);
182 }
183 }
214 } 184 }
215 185
216 /// Uses the diet-parser to parse only directives in [source]. 186 /// Uses the diet-parser to parse only directives in [source].
217 CompilationUnit parseDirectives(Source source) { 187 CompilationUnit parseDirectives(Source source) {
218 var token = tokenize(source); 188 var token = tokenize(source);
219 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER); 189 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER);
220 return parser.parseDirectives(token); 190 return parser.parseDirectives(token);
221 } 191 }
222 192
223 /// Parses every file in [files] and reports the time spent doing so. 193 /// Parses every file in [files] and reports the time spent doing so.
224 void parseFiles(Set<Source> files) { 194 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(); 195 scanTimer = new Stopwatch();
230 var old = scanTotalChars;
231 scanTotalChars = 0;
232 parseTimer = new Stopwatch(); 196 parseTimer = new Stopwatch();
233 for (var source in files) { 197 for (var source in files) {
234 parseFull(source); 198 parseFull(source);
235 } 199 }
236 200
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); 201 report("scan", scanTimer.elapsedMicroseconds);
240 report("parse", parseTimer.elapsedMicroseconds); 202 report("parse", parseTimer.elapsedMicroseconds);
241 } 203 }
242 204
243 /// Parse the full body of [source] and return it's compilation unit. 205 /// Parse the full body of [source] and return it's compilation unit.
244 CompilationUnit parseFull(Source source) { 206 CompilationUnit parseFull(Source source) {
245 var token = tokenize(source); 207 var token = tokenize(source);
246 parseTimer.start(); 208 parseTimer.start();
247 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER); 209 var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER);
248 var unit = parser.parseCompilationUnit(token); 210 var unit = parser.parseCompilationUnit(token);
249 parseTimer.stop(); 211 parseTimer.stop();
250 return unit; 212 return unit;
251 } 213 }
252 214
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 215 /// Prelinks all the summaries for [files], using [unlinkedSummaries] to obtain
281 /// their unlinked summaries. 216 /// their unlinked summaries.
282 /// 217 ///
283 /// The return value is suitable for passing to the summary linker. 218 /// The return value is suitable for passing to the summary linker.
284 Map<String, LinkedLibraryBuilder> prelinkSummaries( 219 Map<String, LinkedLibraryBuilder> prelinkSummaries(
285 Set<Source> files, UnlinkedSummaries unlinkedSummaries) { 220 Set<Source> files, _UnlinkedSummaries unlinkedSummaries) {
286 prelinkSummaryTimer.start(); 221 Set<String> libraryUris = files.map((source) => '${source.uri}').toSet();
287 Set<String> libraryUris =
288 files.map((source) => source.uri.toString()).toSet();
289 222
290 String getDeclaredVariable(String s) => null; 223 String getDeclaredVariable(String s) => null;
291 var prelinkedLibraries = 224 var prelinkedLibraries =
292 setupForLink(libraryUris, unlinkedSummaries.getUnit, getDeclaredVariable); 225 setupForLink(libraryUris, unlinkedSummaries.getUnit, getDeclaredVariable);
293 prelinkSummaryTimer.stop();
294 return prelinkedLibraries; 226 return prelinkedLibraries;
295 } 227 }
296 228
297 /// Report that metric [name] took [time] micro-seconds to process 229 /// Report that metric [name] took [time] micro-seconds to process
298 /// [scanTotalChars] characters. 230 /// [inputSize] characters.
299 void report(String name, int time) { 231 void report(String name, int time) {
300 var sb = new StringBuffer(); 232 var sb = new StringBuffer();
301 sb.write('$name: $time us, ${time ~/ 1000} ms'); 233 var padding = " " * (20 - name.length);
302 sb.write(', ${scanTotalChars * 1000 ~/ time} chars/ms'); 234 sb.write('$name:$padding $time us, ${time ~/ 1000} ms');
235 sb.write(', ${time * 1000 ~/ inputSize} ns/char');
303 print('$sb'); 236 print('$sb');
304 } 237 }
305 238
306 /// Scans every file in [files] and reports the time spent doing so. 239 /// Scans every file in [files] and reports the time spent doing so.
307 void scanFiles(Set<Source> files) { 240 void scanFiles(Set<Source> files) {
308 // The code below will record again how many chars are scanned and how long it 241 // `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]. 242 // 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 243 // make sure to clear the data and compute it again every time.
311 // validate that the results are consistent.
312 scanTimer = new Stopwatch(); 244 scanTimer = new Stopwatch();
313 var old = scanTotalChars;
314 scanTotalChars = 0;
315 for (var source in files) { 245 for (var source in files) {
316 tokenize(source); 246 tokenize(source);
317 } 247 }
318 248
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); 249 report("scan", scanTimer.elapsedMicroseconds);
322 } 250 }
323 251
324 /// Load and scans all files we need to process: files reachable from the 252 /// Load and scans all files we need to process: files reachable from the
325 /// entrypoint and all core libraries automatically included by the VM. 253 /// entrypoint and all core libraries automatically included by the VM.
326 Set<Source> scanReachableFiles(Uri entryUri) { 254 Set<Source> scanReachableFiles(Uri entryUri) {
327 var files = new Set<Source>(); 255 var files = new Set<Source>();
328 var loadTimer = new Stopwatch()..start(); 256 var loadTimer = new Stopwatch()..start();
329 collectSources(sources.forUri2(entryUri), files); 257 collectSources(sources.forUri2(entryUri), files);
330 258
(...skipping 10 matching lines...) Expand all
341 "dart:typed_data", 269 "dart:typed_data",
342 "dart:io" 270 "dart:io"
343 ]; 271 ];
344 272
345 for (var lib in libs) { 273 for (var lib in libs) {
346 collectSources(sources.forUri(lib), files); 274 collectSources(sources.forUri(lib), files);
347 } 275 }
348 276
349 loadTimer.stop(); 277 loadTimer.stop();
350 278
351 print('input size: ${scanTotalChars} chars'); 279 for (var s in files) inputSize += s.contents.data.length;
280 print('input size: ${inputSize} chars');
352 var loadTime = loadTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds; 281 var loadTime = loadTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds;
353 report("load", loadTime); 282 report("load", loadTime);
354 report("scan", scanTimer.elapsedMicroseconds); 283 report("scan", scanTimer.elapsedMicroseconds);
355 return files; 284 return files;
356 } 285 }
357 286
358 /// Sets up analyzer to be able to load and resolve app, packages, and sdk 287 /// Sets up analyzer to be able to load and resolve app, packages, and sdk
359 /// sources. 288 /// sources.
360 Future setup(Uri entryUri) async { 289 Future setup(Uri entryUri) async {
361 var provider = PhysicalResourceProvider.INSTANCE; 290 var provider = PhysicalResourceProvider.INSTANCE;
362 var packageMap = new ContextBuilder(provider, null, null) 291 var packageMap = new ContextBuilder(provider, null, null)
363 .convertPackagesToMap(await findPackages(entryUri)); 292 .convertPackagesToMap(await findPackages(entryUri));
364 sources = new SourceFactory([ 293 sources = new SourceFactory([
365 new ResourceUriResolver(provider), 294 new ResourceUriResolver(provider),
366 new PackageMapUriResolver(provider, packageMap), 295 new PackageMapUriResolver(provider, packageMap),
367 new DartUriResolver( 296 new DartUriResolver(
368 new FolderBasedDartSdk(provider, provider.getFolder("sdk"))), 297 new FolderBasedDartSdk(provider, provider.getFolder("sdk"))),
369 ]); 298 ]);
370 } 299 }
371 300
372 /// Scan [source] and return the first token produced by the scanner. 301 /// Scan [source] and return the first token produced by the scanner.
373 Token tokenize(Source source) { 302 Token tokenize(Source source) {
374 scanTimer.start(); 303 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 304 // TODO(sigmund): is there a way to scan from a random-access-file without
378 // first converting to String? 305 // first converting to String?
379 var scanner = new _Scanner(contents); 306 var scanner = new _Scanner(source.contents.data);
380 var token = scanner.tokenize(); 307 var token = scanner.tokenize();
381 scanTimer.stop(); 308 scanTimer.stop();
382 return token; 309 return token;
383 } 310 }
384 311
385 UnlinkedUnitBuilder unlinkedSummarize(Source source) { 312 UnlinkedUnitBuilder unlinkedSummarize(Source source) {
386 var unit = parseFull(source); 313 var unit = parseFull(source);
387 unlinkedSummarizeTimer.start(); 314 unlinkedSummarizeTimer.start();
388 var unlinkedUnit = serializeAstUnlinked(unit); 315 var unlinkedUnit = serializeAstUnlinked(unit);
389 unlinkedSummarizeTimer.stop(); 316 unlinkedSummarizeTimer.stop();
390 return unlinkedUnit; 317 return unlinkedUnit;
391 } 318 }
392 319
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. 320 /// Simple container for a mapping from URI string to an unlinked summary.
418 class UnlinkedSummaries { 321 class _UnlinkedSummaries {
419 final summariesByUri = <String, UnlinkedUnit>{}; 322 final summariesByUri = <String, UnlinkedUnit>{};
420 323
421 /// Get the unlinked summary for the given URI, and report a warning if it 324 /// Get the unlinked summary for the given URI, and report a warning if it
422 /// can't be found. 325 /// can't be found.
423 UnlinkedUnit getUnit(String uri) { 326 UnlinkedUnit getUnit(String uri) {
424 var result = summariesByUri[uri]; 327 var result = summariesByUri[uri];
425 if (result == null) { 328 if (result == null) {
426 print('Warning: no summary found for: $uri'); 329 print('Warning: no summary found for: $uri');
427 } 330 }
428 return result; 331 return result;
429 } 332 }
430 } 333 }
431 334
432 class _Scanner extends Scanner { 335 class _Scanner extends Scanner {
433 _Scanner(String contents) : super(new CharSequenceReader(contents)) { 336 _Scanner(String contents) : super(new CharSequenceReader(contents)) {
434 preserveComments = false; 337 preserveComments = false;
435 } 338 }
436 339
437 @override 340 @override
438 void reportError(errorCode, int offset, List<Object> arguments) { 341 void reportError(errorCode, int offset, List<Object> arguments) {
439 // ignore errors. 342 // ignore errors.
440 } 343 }
441 } 344 }
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