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

Side by Side Diff: dart/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart

Issue 12033003: Deferred (aka lazy) loading of static functions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Missing imports Created 7 years, 10 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 part of js_backend; 5 part of js_backend;
6 6
7 /** 7 /**
8 * A function element that represents a closure call. The signature is copied 8 * A function element that represents a closure call. The signature is copied
9 * from the given element. 9 * from the given element.
10 */ 10 */
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 class CodeEmitterTask extends CompilerTask { 54 class CodeEmitterTask extends CompilerTask {
55 bool needsInheritFunction = false; 55 bool needsInheritFunction = false;
56 bool needsDefineClass = false; 56 bool needsDefineClass = false;
57 bool needsClosureClass = false; 57 bool needsClosureClass = false;
58 bool needsLazyInitializer = false; 58 bool needsLazyInitializer = false;
59 final Namer namer; 59 final Namer namer;
60 ConstantEmitter constantEmitter; 60 ConstantEmitter constantEmitter;
61 NativeEmitter nativeEmitter; 61 NativeEmitter nativeEmitter;
62 CodeBuffer boundClosureBuffer; 62 CodeBuffer boundClosureBuffer;
63 CodeBuffer mainBuffer; 63 CodeBuffer mainBuffer;
64 final CodeBuffer deferredBuffer = new CodeBuffer();
64 /** Shorter access to [isolatePropertiesName]. Both here in the code, as 65 /** Shorter access to [isolatePropertiesName]. Both here in the code, as
65 well as in the generated code. */ 66 well as in the generated code. */
66 String isolateProperties; 67 String isolateProperties;
67 String classesCollector; 68 String classesCollector;
68 Set<ClassElement> neededClasses; 69 Set<ClassElement> neededClasses;
69 // TODO(ngeoffray): remove this field. 70 // TODO(ngeoffray): remove this field.
70 Set<ClassElement> instantiatedClasses; 71 Set<ClassElement> instantiatedClasses;
71 72
72 JavaScriptBackend get backend => compiler.backend; 73 JavaScriptBackend get backend => compiler.backend;
73 74
(...skipping 1631 matching lines...) Expand 10 before | Expand all | Expand 10 after
1705 Element member = element.lookupLocalMember(noSuchMethodName); 1706 Element member = element.lookupLocalMember(noSuchMethodName);
1706 if (member == null) continue; 1707 if (member == null) continue;
1707 if (noSuchMethodSelector.applies(member, compiler)) { 1708 if (noSuchMethodSelector.applies(member, compiler)) {
1708 nativeEmitter.handleNoSuchMethod = true; 1709 nativeEmitter.handleNoSuchMethod = true;
1709 break; 1710 break;
1710 } 1711 }
1711 } 1712 }
1712 } 1713 }
1713 1714
1714 for (ClassElement element in sortedClasses) { 1715 for (ClassElement element in sortedClasses) {
1716 if (isDeferred(element)) {
1717 warnNotImplemented(
1718 element,
1719 'Warning: deferred loading of classes is not implemented yet.');
1720 }
1715 generateClass(element, buffer); 1721 generateClass(element, buffer);
1716 } 1722 }
1717 1723
1718 // The closure class could have become necessary because of the generation 1724 // The closure class could have become necessary because of the generation
1719 // of stubs. 1725 // of stubs.
1720 ClassElement closureClass = compiler.closureClass; 1726 ClassElement closureClass = compiler.closureClass;
1721 if (needsClosureClass && !instantiatedClasses.contains(closureClass)) { 1727 if (needsClosureClass && !instantiatedClasses.contains(closureClass)) {
1722 generateClass(closureClass, buffer); 1728 generateClass(closureClass, buffer);
1723 } 1729 }
1724 } 1730 }
1725 1731
1726 void emitFinishClassesInvocationIfNecessary(CodeBuffer buffer) { 1732 void emitFinishClassesInvocationIfNecessary(CodeBuffer buffer) {
1727 if (needsDefineClass) { 1733 if (needsDefineClass) {
1728 buffer.add("$finishClassesName($classesCollector)$N"); 1734 buffer.add("$finishClassesName($classesCollector)$N");
1729 // Reset the map. 1735 // Reset the map.
1730 buffer.add("$classesCollector$_=$_{}$N"); 1736 buffer.add("$classesCollector$_=$_{}$N");
1731 } 1737 }
1732 } 1738 }
1733 1739
1734 void emitStaticFunction(CodeBuffer buffer, 1740 void emitStaticFunction(CodeBuffer buffer,
1735 String name, 1741 String name,
1736 jsAst.Expression functionExpression) { 1742 jsAst.Expression functionExpression) {
1737 jsAst.Expression assignment = 1743 jsAst.Expression assignment =
1738 js[isolateProperties][name].assign(functionExpression); 1744 js[isolateProperties][name].assign(functionExpression);
1739 buffer.add(jsAst.prettyPrint(assignment, compiler)); 1745 buffer.add(jsAst.prettyPrint(assignment, compiler));
1740 buffer.add('$N$n'); 1746 buffer.add('$N$n');
1741 } 1747 }
1742 1748
1743 void emitStaticFunctions(CodeBuffer buffer) { 1749 void emitStaticFunctions(CodeBuffer eagerBuffer) {
1744 bool isStaticFunction(Element element) => 1750 bool isStaticFunction(Element element) =>
1745 !element.isInstanceMember() && !element.isField(); 1751 !element.isInstanceMember() && !element.isField();
1746 1752
1747 Iterable<Element> elements = 1753 Iterable<Element> elements =
1748 backend.generatedCode.keys.where(isStaticFunction); 1754 backend.generatedCode.keys.where(isStaticFunction);
1749 Set<Element> pendingElementsWithBailouts = 1755 Set<Element> pendingElementsWithBailouts =
1750 backend.generatedBailoutCode.keys 1756 backend.generatedBailoutCode.keys
1751 .where(isStaticFunction) 1757 .where(isStaticFunction)
1752 .toSet(); 1758 .toSet();
1753 1759
1754 for (Element element in Elements.sortedByPosition(elements)) { 1760 for (Element element in Elements.sortedByPosition(elements)) {
1761 CodeBuffer buffer = isDeferred(element) ? deferredBuffer : eagerBuffer;
1755 jsAst.Expression code = backend.generatedCode[element]; 1762 jsAst.Expression code = backend.generatedCode[element];
1756 emitStaticFunction(buffer, namer.getName(element), code); 1763 emitStaticFunction(buffer, namer.getName(element), code);
1757 jsAst.Expression bailoutCode = backend.generatedBailoutCode[element]; 1764 jsAst.Expression bailoutCode = backend.generatedBailoutCode[element];
1758 if (bailoutCode != null) { 1765 if (bailoutCode != null) {
1759 pendingElementsWithBailouts.remove(element); 1766 pendingElementsWithBailouts.remove(element);
1760 emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode); 1767 emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode);
1761 } 1768 }
1762 } 1769 }
1763 1770
1764 // Is it possible the primary function was inlined but the bailout was not? 1771 // Is it possible the primary function was inlined but the bailout was not?
1765 for (Element element in 1772 for (Element element in
1766 Elements.sortedByPosition(pendingElementsWithBailouts)) { 1773 Elements.sortedByPosition(pendingElementsWithBailouts)) {
1774 CodeBuffer buffer = isDeferred(element) ? deferredBuffer : eagerBuffer;
1767 jsAst.Expression bailoutCode = backend.generatedBailoutCode[element]; 1775 jsAst.Expression bailoutCode = backend.generatedBailoutCode[element];
1768 emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode); 1776 emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode);
1769 } 1777 }
1770 } 1778 }
1771 1779
1772 void emitStaticFunctionGetters(CodeBuffer buffer) { 1780 void emitStaticFunctionGetters(CodeBuffer buffer) {
1773 Set<FunctionElement> functionsNeedingGetter = 1781 Set<FunctionElement> functionsNeedingGetter =
1774 compiler.codegenWorld.staticFunctionsNeedingGetter; 1782 compiler.codegenWorld.staticFunctionsNeedingGetter;
1775 for (FunctionElement element in 1783 for (FunctionElement element in
1776 Elements.sortedByPosition(functionsNeedingGetter)) { 1784 Elements.sortedByPosition(functionsNeedingGetter)) {
1785 // TODO(ahe): Defer loading of these getters.
ngeoffray 2013/02/19 10:04:57 warnNotImplemented?
ahe 2013/02/19 11:10:36 The overhead is small, and I can't give a location
1786
1777 // The static function does not have the correct name. Since 1787 // The static function does not have the correct name. Since
1778 // [addParameterStubs] use the name to create its stubs we simply 1788 // [addParameterStubs] use the name to create its stubs we simply
1779 // create a fake element with the correct name. 1789 // create a fake element with the correct name.
1780 // Note: the callElement will not have any enclosingElement. 1790 // Note: the callElement will not have any enclosingElement.
1781 FunctionElement callElement = 1791 FunctionElement callElement =
1782 new ClosureInvocationElement(namer.closureInvocationSelectorName, 1792 new ClosureInvocationElement(namer.closureInvocationSelectorName,
1783 element); 1793 element);
1784 String staticName = namer.getName(element); 1794 String staticName = namer.getName(element);
1785 String invocationName = namer.instanceMethodName(callElement); 1795 String invocationName = namer.instanceMethodName(callElement);
1786 String fieldAccess = '$isolateProperties.$staticName'; 1796 String fieldAccess = '$isolateProperties.$staticName';
(...skipping 821 matching lines...) Expand 10 before | Expand all | Expand 10 after
2608 2618
2609 emitFinishIsolateConstructorInvocation(mainBuffer); 2619 emitFinishIsolateConstructorInvocation(mainBuffer);
2610 mainBuffer.add('var ${namer.CURRENT_ISOLATE}$_=' 2620 mainBuffer.add('var ${namer.CURRENT_ISOLATE}$_='
2611 '${_}new ${namer.isolateName}()$N'); 2621 '${_}new ${namer.isolateName}()$N');
2612 2622
2613 nativeEmitter.assembleCode(mainBuffer); 2623 nativeEmitter.assembleCode(mainBuffer);
2614 emitMain(mainBuffer); 2624 emitMain(mainBuffer);
2615 emitInitFunction(mainBuffer); 2625 emitInitFunction(mainBuffer);
2616 compiler.assembledCode = mainBuffer.getText(); 2626 compiler.assembledCode = mainBuffer.getText();
2617 2627
2618 if (generateSourceMap) { 2628 if (!deferredBuffer.isEmpty) {
2619 SourceFile compiledFile = new SourceFile(null, compiler.assembledCode); 2629 String code = deferredBuffer.getText();
2620 String sourceMap = buildSourceMap(mainBuffer, compiledFile); 2630 compiler.outputProvider('part', 'js')
2621 compiler.outputProvider('', 'js.map') 2631 ..add(code)
2622 ..add(sourceMap)
2623 ..close(); 2632 ..close();
2633 outputSourceMap(deferredBuffer, compiler.assembledCode, 'part');
2624 } 2634 }
2635
2636 outputSourceMap(mainBuffer, compiler.assembledCode, '');
2625 }); 2637 });
2626 return compiler.assembledCode; 2638 return compiler.assembledCode;
2627 } 2639 }
2628 2640
2629 String buildSourceMap(CodeBuffer buffer, SourceFile compiledFile) { 2641 String buildSourceMap(CodeBuffer buffer, SourceFile compiledFile) {
2630 SourceMapBuilder sourceMapBuilder = new SourceMapBuilder(); 2642 SourceMapBuilder sourceMapBuilder = new SourceMapBuilder();
2631 buffer.forEachSourceLocation(sourceMapBuilder.addMapping); 2643 buffer.forEachSourceLocation(sourceMapBuilder.addMapping);
2632 return sourceMapBuilder.build(compiledFile); 2644 return sourceMapBuilder.build(compiledFile);
2633 } 2645 }
2646
2647 void outputSourceMap(CodeBuffer buffer, String code, String name) {
2648 if (!generateSourceMap) return;
2649 SourceFile compiledFile = new SourceFile(null, compiler.assembledCode);
2650 String sourceMap = buildSourceMap(mainBuffer, compiledFile);
2651 compiler.outputProvider(name, 'js.map')
2652 ..add(sourceMap)
2653 ..close();
2654 }
2655
2656 bool isDeferred(Element element) {
2657 return compiler.deferredLoadTask.isDeferred(element);
2658 }
2659
2660 // TODO(ahe): Remove this when deferred loading is fully implemented.
2661 void warnNotImplemented(Element element, String message) {
2662 compiler.reportMessage(compiler.spanFromSpannable(element),
2663 MessageKind.GENERIC.error({'text': message}),
2664 api.Diagnostic.WARNING);
2665 }
2634 } 2666 }
2635 2667
2636 const String GENERATED_BY = """ 2668 const String GENERATED_BY = """
2637 // Generated by dart2js, the Dart to JavaScript compiler. 2669 // Generated by dart2js, the Dart to JavaScript compiler.
2638 """; 2670 """;
2639 const String HOOKS_API_USAGE = """ 2671 const String HOOKS_API_USAGE = """
2640 // The code supports the following hooks: 2672 // The code supports the following hooks:
2641 // dartPrint(message) - if this function is defined it is called 2673 // dartPrint(message) - if this function is defined it is called
2642 // instead of the Dart [print] method. 2674 // instead of the Dart [print] method.
2643 // dartMainRunner(main) - if this function is defined, the Dart [main] 2675 // dartMainRunner(main) - if this function is defined, the Dart [main]
2644 // method will not be invoked directly. 2676 // method will not be invoked directly.
2645 // Instead, a closure that will invoke [main] is 2677 // Instead, a closure that will invoke [main] is
2646 // passed to [dartMainRunner]. 2678 // passed to [dartMainRunner].
2647 """; 2679 """;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698