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

Side by Side Diff: lib/compiler/implementation/compiler.dart

Issue 10532158: Some cleanup of recompilation (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixed "Closure" Created 8 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | lib/compiler/implementation/enqueue.dart » ('j') | 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 5
6 /** 6 /**
7 * If true, print a warning for each method that was resolved, but not 7 * If true, print a warning for each method that was resolved, but not
8 * compiled. 8 * compiled.
9 */ 9 */
10 final bool REPORT_EXCESS_RESOLUTION = false; 10 final bool REPORT_EXCESS_RESOLUTION = false;
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 ScannerTask scanner; 164 ScannerTask scanner;
165 DietParserTask dietParser; 165 DietParserTask dietParser;
166 ParserTask parser; 166 ParserTask parser;
167 TreeValidatorTask validator; 167 TreeValidatorTask validator;
168 UnparseValidator unparseValidator; 168 UnparseValidator unparseValidator;
169 ResolverTask resolver; 169 ResolverTask resolver;
170 TypeCheckerTask checker; 170 TypeCheckerTask checker;
171 Backend backend; 171 Backend backend;
172 ConstantHandler constantHandler; 172 ConstantHandler constantHandler;
173 EnqueueTask enqueuer; 173 EnqueueTask enqueuer;
174 int pass = 1;
175 174
176 static final SourceString MAIN = const SourceString('main'); 175 static final SourceString MAIN = const SourceString('main');
177 static final SourceString NO_SUCH_METHOD = const SourceString('noSuchMethod'); 176 static final SourceString NO_SUCH_METHOD = const SourceString('noSuchMethod');
178 static final SourceString NO_SUCH_METHOD_EXCEPTION = 177 static final SourceString NO_SUCH_METHOD_EXCEPTION =
179 const SourceString('NoSuchMethodException'); 178 const SourceString('NoSuchMethodException');
180 static final SourceString START_ROOT_ISOLATE = 179 static final SourceString START_ROOT_ISOLATE =
181 const SourceString('startRootIsolate'); 180 const SourceString('startRootIsolate');
182 bool enabledNoSuchMethod = false; 181 bool enabledNoSuchMethod = false;
183 182
184 Stopwatch codegenProgress; 183 Stopwatch progress;
184
185 static final int PHASE_SCANNING = 0;
186 static final int PHASE_RESOLVING = 1;
187 static final int PHASE_COMPILING = 2;
188 static final int PHASE_RECOMPILING = 3;
189 int phase;
185 190
186 Compiler([this.tracer = const Tracer(), 191 Compiler([this.tracer = const Tracer(),
187 this.enableTypeAssertions = false, 192 this.enableTypeAssertions = false,
188 this.enableUserAssertions = false, 193 this.enableUserAssertions = false,
189 bool emitJavascript = true, 194 bool emitJavascript = true,
190 validateUnparse = false]) 195 validateUnparse = false])
191 : libraries = new Map<String, LibraryElement>(), 196 : libraries = new Map<String, LibraryElement>(),
192 world = new World(), 197 world = new World(),
193 codegenProgress = new Stopwatch.start() { 198 progress = new Stopwatch.start() {
194 namer = new Namer(this); 199 namer = new Namer(this);
195 constantHandler = new ConstantHandler(this); 200 constantHandler = new ConstantHandler(this);
196 scanner = new ScannerTask(this); 201 scanner = new ScannerTask(this);
197 dietParser = new DietParserTask(this); 202 dietParser = new DietParserTask(this);
198 parser = new ParserTask(this); 203 parser = new ParserTask(this);
199 validator = new TreeValidatorTask(this); 204 validator = new TreeValidatorTask(this);
200 unparseValidator = new UnparseValidator(this, validateUnparse); 205 unparseValidator = new UnparseValidator(this, validateUnparse);
201 resolver = new ResolverTask(this); 206 resolver = new ResolverTask(this);
202 checker = new TypeCheckerTask(this); 207 checker = new TypeCheckerTask(this);
203 backend = emitJavascript ? 208 backend = emitJavascript ?
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 parameters.forEachParameter((Element parameter) { 421 parameters.forEachParameter((Element parameter) {
417 reportFatalError('main cannot have parameters', parameter); 422 reportFatalError('main cannot have parameters', parameter);
418 }); 423 });
419 } 424 }
420 425
421 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution 426 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution
422 // should know this. 427 // should know this.
423 world.populate(this, libraries.getValues()); 428 world.populate(this, libraries.getValues());
424 429
425 log('Resolving...'); 430 log('Resolving...');
431 phase = PHASE_RESOLVING;
426 backend.enqueueHelpers(enqueuer.resolution); 432 backend.enqueueHelpers(enqueuer.resolution);
427 processQueue(enqueuer.resolution, main); 433 processQueue(enqueuer.resolution, main);
428 log('Resolved ${enqueuer.resolution.resolvedElements.length} elements.'); 434 log('Resolved ${enqueuer.resolution.resolvedElements.length} elements.');
429 435
430 log('Compiling...'); 436 log('Compiling...');
437 phase = PHASE_COMPILING;
431 processQueue(enqueuer.codegen, main); 438 processQueue(enqueuer.codegen, main);
432 log("Recompiling ${enqueuer.codegen.recompilationCandidates.length} " 439 log("Recompiling ${enqueuer.codegen.recompilationCandidates.length} "
433 "methods..."); 440 "methods...");
441 phase = PHASE_RECOMPILING;
434 processRecompilationQueue(enqueuer.codegen); 442 processRecompilationQueue(enqueuer.codegen);
435 log('Compiled ${codegenWorld.generatedCode.length} methods.'); 443 log('Compiled ${codegenWorld.generatedCode.length} methods.');
436 444
437 backend.assembleProgram(); 445 backend.assembleProgram();
438 446
439 checkQueues(); 447 checkQueues();
440 } 448 }
441 449
442 void processQueue(Enqueuer world, Element main) { 450 void processQueue(Enqueuer world, Element main) {
443 backend.processNativeClasses(world, libraries.getValues()); 451 backend.processNativeClasses(world, libraries.getValues());
444 world.addToWorkList(main); 452 world.addToWorkList(main);
445 codegenProgress.reset(); 453 progress.reset();
446 world.forEach((WorkItem work) { 454 world.forEach((WorkItem work) {
447 withCurrentElement(work.element, () => work.run(this, world)); 455 withCurrentElement(work.element, () => work.run(this, world));
448 }); 456 });
449 world.queueIsClosed = true; 457 world.queueIsClosed = true;
450 assert(world.checkNoEnqueuedInvokedInstanceMethods()); 458 assert(world.checkNoEnqueuedInvokedInstanceMethods());
451 world.registerFieldClosureInvocations(); 459 world.registerFieldClosureInvocations();
452 } 460 }
453 461
454 void processRecompilationQueue(Enqueuer world) { 462 void processRecompilationQueue(Enqueuer world) {
455 pass = 2; 463 assert(phase == PHASE_RECOMPILING);
456 while (!world.recompilationCandidates.isEmpty()) { 464 while (!world.recompilationCandidates.isEmpty()) {
457 WorkItem work = world.recompilationCandidates.next(); 465 WorkItem work = world.recompilationCandidates.next();
466 world.universe.generatedCode.remove(work.element);
458 var oldCode = world.universe.generatedCode[work.element]; 467 var oldCode = world.universe.generatedCode[work.element];
459 world.universe.generatedCode.remove(work.element);
460 withCurrentElement(work.element, () => work.run(this, world)); 468 withCurrentElement(work.element, () => work.run(this, world));
461 var newCode = world.universe.generatedCode[work.element]; 469 var newCode = world.universe.generatedCode[work.element];
462 if (REPORT_PASS2_OPTIMIZATIONS && newCode != oldCode) { 470 if (REPORT_PASS2_OPTIMIZATIONS && newCode != oldCode) {
463 log("Pass 2 optimization:"); 471 log("Pass 2 optimization:");
464 log("Before:\n$oldCode"); 472 log("Before:\n$oldCode");
465 log("After:\n$newCode"); 473 log("After:\n$newCode");
466 } 474 }
467 } 475 }
468 } 476 }
469 477
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 Node tree = parser.parse(element); 537 Node tree = parser.parse(element);
530 validator.validate(tree); 538 validator.validate(tree);
531 unparseValidator.check(element); 539 unparseValidator.check(element);
532 elements = resolver.resolve(element); 540 elements = resolver.resolve(element);
533 checker.check(tree, elements); 541 checker.check(tree, elements);
534 return elements; 542 return elements;
535 } 543 }
536 544
537 TreeElements analyze(WorkItem work, Enqueuer world) { 545 TreeElements analyze(WorkItem work, Enqueuer world) {
538 if (work.isAnalyzed()) return work.resolutionTree; 546 if (work.isAnalyzed()) return work.resolutionTree;
547 if (progress.elapsedInMs() > 500) {
548 // TODO(ahe): Add structured diagnostics to the compiler API and
549 // use it to separate this from the --verbose option.
550 if (phase == PHASE_RESOLVING) {
551 log('Resolved ${enqueuer.resolution.resolvedElements.length}'
552 'elements.');
553 progress.reset();
554 }
555 }
539 Element element = work.element; 556 Element element = work.element;
540 TreeElements result = world.getCachedElements(element); 557 TreeElements result = world.getCachedElements(element);
541 if (result !== null) return result; 558 if (result !== null) return result;
542 if (world !== enqueuer.resolution) { 559 if (world !== enqueuer.resolution) {
543 internalErrorOnElement(element, 560 internalErrorOnElement(element,
544 'Internal error: unresolved element: $element.'); 561 'Internal error: unresolved element: $element.');
545 } 562 }
546 result = analyzeElement(element); 563 result = analyzeElement(element);
547 enqueuer.resolution.resolvedElements[element] = result; 564 enqueuer.resolution.resolvedElements[element] = result;
548 return result; 565 return result;
549 } 566 }
550 567
551 String codegen(WorkItem work, Enqueuer world) { 568 String codegen(WorkItem work, Enqueuer world) {
552 if (world !== enqueuer.codegen) return null; 569 if (world !== enqueuer.codegen) return null;
553 if (codegenProgress.elapsedInMs() > 500) { 570 if (progress.elapsedInMs() > 500) {
554 // TODO(ahe): Add structured diagnostics to the compiler API and 571 // TODO(ahe): Add structured diagnostics to the compiler API and
555 // use it to separate this from the --verbose option. 572 // use it to separate this from the --verbose option.
556 log('Compiled ${codegenWorld.generatedCode.length} methods.'); 573 if (phase == PHASE_COMPILING) {
557 codegenProgress.reset(); 574 log('Compiled ${codegenWorld.generatedCode.length} methods.');
575 } else {
576 log('Recompiled ${world.recompilationCandidates.processed} methods.');
577 }
578 progress.reset();
558 } 579 }
559 if (work.element.kind.category == ElementCategory.VARIABLE) { 580 if (work.element.kind.category == ElementCategory.VARIABLE) {
560 constantHandler.compileWorkItem(work); 581 constantHandler.compileWorkItem(work);
561 return null; 582 return null;
562 } else { 583 } else {
563 String code = backend.codegen(work); 584 String code = backend.codegen(work);
564 codegenWorld.addGeneratedCode(work, code); 585 codegenWorld.addGeneratedCode(work, code);
565 return code; 586 return code;
566 } 587 }
567 } 588 }
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 // invariant that endOffset > beginOffset, but for EOF the 762 // invariant that endOffset > beginOffset, but for EOF the
742 // charoffset of the next token may be [beginOffset]. This can 763 // charoffset of the next token may be [beginOffset]. This can
743 // also happen for synthetized tokens that are produced during 764 // also happen for synthetized tokens that are produced during
744 // error handling. 765 // error handling.
745 final endOffset = 766 final endOffset =
746 Math.max((end.next !== null) ? end.next.charOffset : 0, beginOffset + 1); 767 Math.max((end.next !== null) ? end.next.charOffset : 0, beginOffset + 1);
747 assert(endOffset > beginOffset); 768 assert(endOffset > beginOffset);
748 return f(beginOffset, endOffset); 769 return f(beginOffset, endOffset);
749 } 770 }
750 } 771 }
OLDNEW
« no previous file with comments | « no previous file | lib/compiler/implementation/enqueue.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698