| OLD | NEW |
| 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 27 matching lines...) Expand all Loading... |
| 38 Backend(this.compiler); | 38 Backend(this.compiler); |
| 39 | 39 |
| 40 void enqueueAllTopLevelFunctions(LibraryElement lib, Enqueuer world) { | 40 void enqueueAllTopLevelFunctions(LibraryElement lib, Enqueuer world) { |
| 41 lib.forEachExport((Element e) { | 41 lib.forEachExport((Element e) { |
| 42 if (e.isFunction()) world.addToWorkList(e); | 42 if (e.isFunction()) world.addToWorkList(e); |
| 43 }); | 43 }); |
| 44 } | 44 } |
| 45 | 45 |
| 46 abstract void enqueueHelpers(Enqueuer world); | 46 abstract void enqueueHelpers(Enqueuer world); |
| 47 abstract String codegen(WorkItem work); | 47 abstract String codegen(WorkItem work); |
| 48 abstract void processNativeClasses(world, libraries); | 48 abstract void processNativeClasses(Enqueuer world, |
| 49 Collection<LibraryElement> libraries); |
| 49 abstract void assembleProgram(); | 50 abstract void assembleProgram(); |
| 50 abstract List<CompilerTask> get tasks(); | 51 abstract List<CompilerTask> get tasks(); |
| 51 } | 52 } |
| 52 | 53 |
| 53 class JavaScriptBackend extends Backend { | 54 class JavaScriptBackend extends Backend { |
| 54 SsaBuilderTask builder; | 55 SsaBuilderTask builder; |
| 55 SsaOptimizerTask optimizer; | 56 SsaOptimizerTask optimizer; |
| 56 SsaCodeGeneratorTask generator; | 57 SsaCodeGeneratorTask generator; |
| 57 CodeEmitterTask emitter; | 58 CodeEmitterTask emitter; |
| 58 | 59 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 85 if (work.allowSpeculativeOptimization | 86 if (work.allowSpeculativeOptimization |
| 86 && optimizer.trySpeculativeOptimizations(work, graph)) { | 87 && optimizer.trySpeculativeOptimizations(work, graph)) { |
| 87 String code = generator.generateBailoutMethod(work, graph); | 88 String code = generator.generateBailoutMethod(work, graph); |
| 88 compiler.codegenWorld.addBailoutCode(work, code); | 89 compiler.codegenWorld.addBailoutCode(work, code); |
| 89 optimizer.prepareForSpeculativeOptimizations(work, graph); | 90 optimizer.prepareForSpeculativeOptimizations(work, graph); |
| 90 optimizer.optimize(work, graph); | 91 optimizer.optimize(work, graph); |
| 91 } | 92 } |
| 92 return generator.generateMethod(work, graph); | 93 return generator.generateMethod(work, graph); |
| 93 } | 94 } |
| 94 | 95 |
| 95 void processNativeClasses(world, libraries) { | 96 void processNativeClasses(Enqueuer world, |
| 97 Collection<LibraryElement> libraries) { |
| 96 native.processNativeClasses(world, emitter, libraries); | 98 native.processNativeClasses(world, emitter, libraries); |
| 97 } | 99 } |
| 98 | 100 |
| 99 void assembleProgram() { | 101 void assembleProgram() { |
| 100 emitter.assembleProgram(); | 102 emitter.assembleProgram(); |
| 101 } | 103 } |
| 102 } | 104 } |
| 103 | 105 |
| 104 class Compiler implements DiagnosticListener { | 106 class Compiler implements DiagnosticListener { |
| 105 final Map<String, LibraryElement> libraries; | 107 final Map<String, LibraryElement> libraries; |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 log("Recompiling ${enqueuer.codegen.recompilationCandidates.length} " | 432 log("Recompiling ${enqueuer.codegen.recompilationCandidates.length} " |
| 431 "methods..."); | 433 "methods..."); |
| 432 processRecompilationQueue(enqueuer.codegen); | 434 processRecompilationQueue(enqueuer.codegen); |
| 433 log('Compiled ${codegenWorld.generatedCode.length} methods.'); | 435 log('Compiled ${codegenWorld.generatedCode.length} methods.'); |
| 434 | 436 |
| 435 backend.assembleProgram(); | 437 backend.assembleProgram(); |
| 436 | 438 |
| 437 checkQueues(); | 439 checkQueues(); |
| 438 } | 440 } |
| 439 | 441 |
| 440 processQueue(Enqueuer world, Element main) { | 442 void processQueue(Enqueuer world, Element main) { |
| 441 backend.processNativeClasses(world, libraries.getValues()); | 443 backend.processNativeClasses(world, libraries.getValues()); |
| 442 world.addToWorkList(main); | 444 world.addToWorkList(main); |
| 443 codegenProgress.reset(); | 445 codegenProgress.reset(); |
| 444 world.forEach((WorkItem work) { | 446 world.forEach((WorkItem work) { |
| 445 withCurrentElement(work.element, () => work.run(this, world)); | 447 withCurrentElement(work.element, () => work.run(this, world)); |
| 446 }); | 448 }); |
| 447 world.queueIsClosed = true; | 449 world.queueIsClosed = true; |
| 448 assert(world.checkNoEnqueuedInvokedInstanceMethods()); | 450 assert(world.checkNoEnqueuedInvokedInstanceMethods()); |
| 449 world.registerFieldClosureInvocations(); | 451 world.registerFieldClosureInvocations(); |
| 450 } | 452 } |
| 451 | 453 |
| 452 processRecompilationQueue(Enqueuer world) { | 454 void processRecompilationQueue(Enqueuer world) { |
| 453 pass = 2; | 455 pass = 2; |
| 454 while (!world.recompilationCandidates.isEmpty()) { | 456 while (!world.recompilationCandidates.isEmpty()) { |
| 455 WorkItem work = world.recompilationCandidates.next(); | 457 WorkItem work = world.recompilationCandidates.next(); |
| 456 var oldCode = world.universe.generatedCode[work.element]; | 458 var oldCode = world.universe.generatedCode[work.element]; |
| 457 world.universe.generatedCode.remove(work.element); | 459 world.universe.generatedCode.remove(work.element); |
| 458 withCurrentElement(work.element, () => work.run(this, world)); | 460 withCurrentElement(work.element, () => work.run(this, world)); |
| 459 var newCode = world.universe.generatedCode[work.element]; | 461 var newCode = world.universe.generatedCode[work.element]; |
| 460 if (REPORT_PASS2_OPTIMIZATIONS && newCode != oldCode) { | 462 if (REPORT_PASS2_OPTIMIZATIONS && newCode != oldCode) { |
| 461 log("Pass 2 optimization:"); | 463 log("Pass 2 optimization:"); |
| 462 log("Before:\n$oldCode"); | 464 log("Before:\n$oldCode"); |
| 463 log("After:\n$newCode"); | 465 log("After:\n$newCode"); |
| 464 } | 466 } |
| 465 } | 467 } |
| 466 } | 468 } |
| 467 | 469 |
| 468 /** | 470 /** |
| 469 * Perform various checks of the queues. This includes checking that | 471 * Perform various checks of the queues. This includes checking that |
| 470 * the queues are empty (nothing was added after we stopped | 472 * the queues are empty (nothing was added after we stopped |
| 471 * processing the queues). Also compute the number of methods that | 473 * processing the queues). Also compute the number of methods that |
| 472 * were resolved, but not compiled (aka excess resolution). | 474 * were resolved, but not compiled (aka excess resolution). |
| 473 */ | 475 */ |
| 474 checkQueues() { | 476 checkQueues() { |
| 475 for (var world in [enqueuer.resolution, enqueuer.codegen]) { | 477 for (Enqueuer world in [enqueuer.resolution, enqueuer.codegen]) { |
| 476 world.forEach((WorkItem work) { | 478 world.forEach((WorkItem work) { |
| 477 internalErrorOnElement(work.element, "Work list is not empty."); | 479 internalErrorOnElement(work.element, "Work list is not empty."); |
| 478 }); | 480 }); |
| 479 } | 481 } |
| 480 var resolved = new Set.from(enqueuer.resolution.resolvedElements.getKeys()); | 482 var resolved = new Set.from(enqueuer.resolution.resolvedElements.getKeys()); |
| 481 for (Element e in codegenWorld.generatedCode.getKeys()) { | 483 for (Element e in codegenWorld.generatedCode.getKeys()) { |
| 482 resolved.remove(e); | 484 resolved.remove(e); |
| 483 } | 485 } |
| 484 for (Element e in new Set.from(resolved)) { | 486 for (Element e in new Set.from(resolved)) { |
| 485 if (e.isClass() || | 487 if (e.isClass() || |
| 486 e.isField() || | 488 e.isField() || |
| 487 e.isTypeVariable() || | 489 e.isTypeVariable() || |
| 488 e.isTypedef() || | 490 e.isTypedef() || |
| 489 e.kind === ElementKind.ABSTRACT_FIELD) { | 491 e.kind === ElementKind.ABSTRACT_FIELD) { |
| 490 resolved.remove(e); | 492 resolved.remove(e); |
| 491 } | 493 } |
| 492 if (e.kind === ElementKind.GENERATIVE_CONSTRUCTOR) { | 494 if (e.kind === ElementKind.GENERATIVE_CONSTRUCTOR) { |
| 493 if (e.enclosingElement.isInterface()) { | 495 ClassElement enclosingClass = e.enclosingElement; |
| 496 if (enclosingClass.isInterface()) { |
| 494 resolved.remove(e); | 497 resolved.remove(e); |
| 495 } | 498 } |
| 496 resolved.remove(e); | 499 resolved.remove(e); |
| 497 | 500 |
| 498 } | 501 } |
| 499 if (e.getLibrary() === jsHelperLibrary) { | 502 if (e.getLibrary() === jsHelperLibrary) { |
| 500 resolved.remove(e); | 503 resolved.remove(e); |
| 501 } | 504 } |
| 502 if (e.getLibrary() === interceptorsLibrary) { | 505 if (e.getLibrary() === interceptorsLibrary) { |
| 503 resolved.remove(e); | 506 resolved.remove(e); |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 738 // invariant that endOffset > beginOffset, but for EOF the | 741 // invariant that endOffset > beginOffset, but for EOF the |
| 739 // charoffset of the next token may be [beginOffset]. This can | 742 // charoffset of the next token may be [beginOffset]. This can |
| 740 // also happen for synthetized tokens that are produced during | 743 // also happen for synthetized tokens that are produced during |
| 741 // error handling. | 744 // error handling. |
| 742 final endOffset = | 745 final endOffset = |
| 743 Math.max((end.next !== null) ? end.next.charOffset : 0, beginOffset + 1); | 746 Math.max((end.next !== null) ? end.next.charOffset : 0, beginOffset + 1); |
| 744 assert(endOffset > beginOffset); | 747 assert(endOffset > beginOffset); |
| 745 return f(beginOffset, endOffset); | 748 return f(beginOffset, endOffset); |
| 746 } | 749 } |
| 747 } | 750 } |
| OLD | NEW |