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: lib/compiler/implementation/compiler.dart

Issue 10537025: Prototype re-compiling methods in dart2js (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Use the results from the resolver when trying to detect final fields 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
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;
11 11
12 /**
13 * If true, trace information on pass2 optimizations.
14 */
15 final bool REPORT_PASS2_OPTIMIZATIONS = false;
16
12 class WorkItem { 17 class WorkItem {
13 final Element element; 18 final Element element;
14 TreeElements resolutionTree; 19 TreeElements resolutionTree;
15 bool allowSpeculativeOptimization = true; 20 bool allowSpeculativeOptimization = true;
16 List<HTypeGuard> guards = const <HTypeGuard>[]; 21 List<HTypeGuard> guards = const <HTypeGuard>[];
17 22
18 WorkItem(this.element, this.resolutionTree); 23 WorkItem(this.element, this.resolutionTree);
19 24
20 bool isAnalyzed() => resolutionTree !== null; 25 bool isAnalyzed() => resolutionTree !== null;
21 26
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 ScannerTask scanner; 162 ScannerTask scanner;
158 DietParserTask dietParser; 163 DietParserTask dietParser;
159 ParserTask parser; 164 ParserTask parser;
160 TreeValidatorTask validator; 165 TreeValidatorTask validator;
161 UnparseValidator unparseValidator; 166 UnparseValidator unparseValidator;
162 ResolverTask resolver; 167 ResolverTask resolver;
163 TypeCheckerTask checker; 168 TypeCheckerTask checker;
164 Backend backend; 169 Backend backend;
165 ConstantHandler constantHandler; 170 ConstantHandler constantHandler;
166 EnqueueTask enqueuer; 171 EnqueueTask enqueuer;
172 int pass = 1;
ngeoffray 2012/06/14 12:42:24 This field name is a little too generic for my tas
Søren Gjesse 2012/06/15 09:25:02 Changed it to phase and added constants for each p
167 173
168 static final SourceString MAIN = const SourceString('main'); 174 static final SourceString MAIN = const SourceString('main');
169 static final SourceString NO_SUCH_METHOD = const SourceString('noSuchMethod'); 175 static final SourceString NO_SUCH_METHOD = const SourceString('noSuchMethod');
170 static final SourceString NO_SUCH_METHOD_EXCEPTION = 176 static final SourceString NO_SUCH_METHOD_EXCEPTION =
171 const SourceString('NoSuchMethodException'); 177 const SourceString('NoSuchMethodException');
172 static final SourceString START_ROOT_ISOLATE = 178 static final SourceString START_ROOT_ISOLATE =
173 const SourceString('startRootIsolate'); 179 const SourceString('startRootIsolate');
174 bool enabledNoSuchMethod = false; 180 bool enabledNoSuchMethod = false;
175 181
176 Stopwatch codegenProgress; 182 Stopwatch codegenProgress;
(...skipping 16 matching lines...) Expand all
193 resolver = new ResolverTask(this); 199 resolver = new ResolverTask(this);
194 checker = new TypeCheckerTask(this); 200 checker = new TypeCheckerTask(this);
195 backend = emitJavascript ? 201 backend = emitJavascript ?
196 new JavaScriptBackend(this) : new dart_backend.DartBackend(this); 202 new JavaScriptBackend(this) : new dart_backend.DartBackend(this);
197 enqueuer = new EnqueueTask(this); 203 enqueuer = new EnqueueTask(this);
198 tasks = [scanner, dietParser, parser, resolver, checker, 204 tasks = [scanner, dietParser, parser, resolver, checker,
199 unparseValidator, constantHandler, enqueuer]; 205 unparseValidator, constantHandler, enqueuer];
200 tasks.addAll(backend.tasks); 206 tasks.addAll(backend.tasks);
201 } 207 }
202 208
209 Universe get resolverWorld() => enqueuer.resolution.universe;
203 Universe get codegenWorld() => enqueuer.codegen.universe; 210 Universe get codegenWorld() => enqueuer.codegen.universe;
204 211
205 int getNextFreeClassId() => nextFreeClassId++; 212 int getNextFreeClassId() => nextFreeClassId++;
206 213
207 void ensure(bool condition) { 214 void ensure(bool condition) {
208 if (!condition) cancel('failed assertion in leg'); 215 if (!condition) cancel('failed assertion in leg');
209 } 216 }
210 217
211 void unimplemented(String methodName, 218 void unimplemented(String methodName,
212 [Node node, Token token, HInstruction instruction, 219 [Node node, Token token, HInstruction instruction,
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 // should know this. 420 // should know this.
414 world.populate(this, libraries.getValues()); 421 world.populate(this, libraries.getValues());
415 422
416 log('Resolving...'); 423 log('Resolving...');
417 backend.enqueueHelpers(enqueuer.resolution); 424 backend.enqueueHelpers(enqueuer.resolution);
418 processQueue(enqueuer.resolution, main); 425 processQueue(enqueuer.resolution, main);
419 log('Resolved ${enqueuer.resolution.resolvedElements.length} elements.'); 426 log('Resolved ${enqueuer.resolution.resolvedElements.length} elements.');
420 427
421 log('Compiling...'); 428 log('Compiling...');
422 processQueue(enqueuer.codegen, main); 429 processQueue(enqueuer.codegen, main);
430 log("Recompiling ${enqueuer.codegen.recompilationCandidates.length} "
431 "methods...");
432 processRecompilationQueue(enqueuer.codegen);
423 log('Compiled ${codegenWorld.generatedCode.length} methods.'); 433 log('Compiled ${codegenWorld.generatedCode.length} methods.');
424 434
425 backend.assembleProgram(); 435 backend.assembleProgram();
426 436
427 checkQueues(); 437 checkQueues();
428 } 438 }
429 439
430 processQueue(Enqueuer world, Element main) { 440 processQueue(Enqueuer world, Element main) {
431 backend.processNativeClasses(world, libraries.getValues()); 441 backend.processNativeClasses(world, libraries.getValues());
432 world.addToWorkList(main); 442 world.addToWorkList(main);
433 codegenProgress.reset(); 443 codegenProgress.reset();
434 world.forEach((WorkItem work) { 444 world.forEach((WorkItem work) {
435 withCurrentElement(work.element, () => work.run(this, world)); 445 withCurrentElement(work.element, () => work.run(this, world));
436 }); 446 });
437 world.queueIsClosed = true; 447 world.queueIsClosed = true;
438 assert(world.checkNoEnqueuedInvokedInstanceMethods()); 448 assert(world.checkNoEnqueuedInvokedInstanceMethods());
439 world.registerFieldClosureInvocations(); 449 world.registerFieldClosureInvocations();
440 } 450 }
441 451
452 processRecompilationQueue(Enqueuer world) {
453 pass = 2;
454 while (!world.recompilationCandidates.isEmpty()) {
455 WorkItem work = world.recompilationCandidates.next();
456 var oldCode = world.universe.generatedCode[work.element];
457 world.universe.generatedCode.remove(work.element);
458 withCurrentElement(work.element, () => work.run(this, world));
459 var newCode = world.universe.generatedCode[work.element];
460 if (REPORT_PASS2_OPTIMIZATIONS && newCode != oldCode) {
461 log("Pass 2 optimization:");
462 log("Before:\n$oldCode");
463 log("After:\n$newCode");
464 }
465 }
466 }
467
442 /** 468 /**
443 * Perform various checks of the queues. This includes checking that 469 * Perform various checks of the queues. This includes checking that
444 * the queues are empty (nothing was added after we stopped 470 * the queues are empty (nothing was added after we stopped
445 * processing the quese). Also compute the number of methods that 471 * processing the quese). Also compute the number of methods that
446 * were resolved, but not compiled (aka excess resolution). 472 * were resolved, but not compiled (aka excess resolution).
447 */ 473 */
448 checkQueues() { 474 checkQueues() {
449 for (var world in [enqueuer.resolution, enqueuer.codegen]) { 475 for (var world in [enqueuer.resolution, enqueuer.codegen]) {
450 world.forEach((WorkItem work) { 476 world.forEach((WorkItem work) {
451 internalErrorOnElement(work.element, "Work list is not empty."); 477 internalErrorOnElement(work.element, "Work list is not empty.");
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 result = analyzeElement(element); 543 result = analyzeElement(element);
518 enqueuer.resolution.resolvedElements[element] = result; 544 enqueuer.resolution.resolvedElements[element] = result;
519 return result; 545 return result;
520 } 546 }
521 547
522 String codegen(WorkItem work, Enqueuer world) { 548 String codegen(WorkItem work, Enqueuer world) {
523 if (world !== enqueuer.codegen) return null; 549 if (world !== enqueuer.codegen) return null;
524 if (codegenProgress.elapsedInMs() > 500) { 550 if (codegenProgress.elapsedInMs() > 500) {
525 // TODO(ahe): Add structured diagnostics to the compiler API and 551 // TODO(ahe): Add structured diagnostics to the compiler API and
526 // use it to separate this from the --verbose option. 552 // use it to separate this from the --verbose option.
527 log('Compiled ${codegenWorld.generatedCode.length} methods.'); 553 log('Compiled ${codegenWorld.generatedCode.length} methods.');
ahe 2012/06/14 13:23:54 I think you may have broken this message. I think
Søren Gjesse 2012/06/15 09:25:02 Updated to report something more useful. Made the
528 codegenProgress.reset(); 554 codegenProgress.reset();
529 } 555 }
530 if (work.element.kind.category == ElementCategory.VARIABLE) { 556 if (work.element.kind.category == ElementCategory.VARIABLE) {
531 constantHandler.compileWorkItem(work); 557 constantHandler.compileWorkItem(work);
532 return null; 558 return null;
533 } else { 559 } else {
534 String code = backend.codegen(work); 560 String code = backend.codegen(work);
535 codegenWorld.addGeneratedCode(work, code); 561 codegenWorld.addGeneratedCode(work, code);
536 return code; 562 return code;
537 } 563 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 if (message is TypeWarning) { 602 if (message is TypeWarning) {
577 // TODO(ahe): Don't supress these warning when the type checker 603 // TODO(ahe): Don't supress these warning when the type checker
578 // is more complete. 604 // is more complete.
579 if (message.message.kind === MessageKind.NOT_ASSIGNABLE) return; 605 if (message.message.kind === MessageKind.NOT_ASSIGNABLE) return;
580 if (message.message.kind === MessageKind.MISSING_RETURN) return; 606 if (message.message.kind === MessageKind.MISSING_RETURN) return;
581 if (message.message.kind === MessageKind.MAYBE_MISSING_RETURN) return; 607 if (message.message.kind === MessageKind.MAYBE_MISSING_RETURN) return;
582 if (message.message.kind === MessageKind.ADDITIONAL_ARGUMENT) return; 608 if (message.message.kind === MessageKind.ADDITIONAL_ARGUMENT) return;
583 if (message.message.kind === MessageKind.METHOD_NOT_FOUND) return; 609 if (message.message.kind === MessageKind.METHOD_NOT_FOUND) return;
584 } 610 }
585 SourceSpan span = spanFromNode(node); 611 SourceSpan span = spanFromNode(node);
612
586 reportDiagnostic(span, "${magenta('warning:')} $message", false); 613 reportDiagnostic(span, "${magenta('warning:')} $message", false);
587 } 614 }
588 615
589 reportError(Node node, var message) { 616 reportError(Node node, var message) {
590 SourceSpan span = spanFromNode(node); 617 SourceSpan span = spanFromNode(node);
591 reportDiagnostic(span, "${red('error:')} $message", true); 618 reportDiagnostic(span, "${red('error:')} $message", true);
592 throw new CompilerCancelledException(message.toString()); 619 throw new CompilerCancelledException(message.toString());
593 } 620 }
594 621
595 abstract void reportDiagnostic(SourceSpan span, String message, bool fatal); 622 abstract void reportDiagnostic(SourceSpan span, String message, bool fatal);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 // invariant that endOffset > beginOffset, but for EOF the 738 // invariant that endOffset > beginOffset, but for EOF the
712 // charoffset of the next token may be [beginOffset]. This can 739 // charoffset of the next token may be [beginOffset]. This can
713 // also happen for synthetized tokens that are produced during 740 // also happen for synthetized tokens that are produced during
714 // error handling. 741 // error handling.
715 final endOffset = 742 final endOffset =
716 Math.max((end.next !== null) ? end.next.charOffset : 0, beginOffset + 1); 743 Math.max((end.next !== null) ? end.next.charOffset : 0, beginOffset + 1);
717 assert(endOffset > beginOffset); 744 assert(endOffset > beginOffset);
718 return f(beginOffset, endOffset); 745 return f(beginOffset, endOffset);
719 } 746 }
720 } 747 }
OLDNEW
« no previous file with comments | « no previous file | lib/compiler/implementation/enqueue.dart » ('j') | lib/compiler/implementation/enqueue.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698