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

Side by Side Diff: pkg/compiler/lib/src/compiler.dart

Issue 1376863004: Avoid eager enqueueing from resolution (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Update minimal_resolution_test. Created 5 years, 2 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
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 library dart2js.compiler_base; 5 library dart2js.compiler_base;
6 6
7 import 'dart:async' show 7 import 'dart:async' show
8 EventSink, 8 EventSink,
9 Future; 9 Future;
10 10
11 import '../compiler_new.dart' as api; 11 import '../compiler_new.dart' as api;
12 import 'cache_strategy.dart' show 12 import 'cache_strategy.dart' show
13 CacheStrategy; 13 CacheStrategy;
14 import 'closure.dart' as closureMapping show 14 import 'closure.dart' as closureMapping show
15 ClosureTask; 15 ClosureTask;
16 import 'common/backend_api.dart' show 16 import 'common/backend_api.dart' show
17 Backend; 17 Backend;
18 import 'common/codegen.dart' show 18 import 'common/codegen.dart' show
19 CodegenRegistry, 19 CodegenRegistry,
20 CodegenWorkItem; 20 CodegenWorkItem;
21 import 'common/names.dart' show 21 import 'common/names.dart' show
22 Identifiers, 22 Identifiers,
23 Uris; 23 Uris;
24 import 'common/registry.dart' show 24 import 'common/registry.dart' show
25 Registry; 25 Registry;
26 import 'common/resolution.dart' show 26 import 'common/resolution.dart' show
27 Parsing, 27 Parsing,
28 Resolution, 28 Resolution,
29 ResolutionWorkItem; 29 ResolutionWorkItem,
30 ResolutionWorldImpact;
30 import 'common/tasks.dart' show 31 import 'common/tasks.dart' show
31 CompilerTask, 32 CompilerTask,
32 GenericTask; 33 GenericTask;
33 import 'common/work.dart' show 34 import 'common/work.dart' show
34 WorkItem; 35 WorkItem;
35 import 'compile_time_constants.dart'; 36 import 'compile_time_constants.dart';
36 import 'constants/values.dart'; 37 import 'constants/values.dart';
37 import 'core_types.dart' show 38 import 'core_types.dart' show
38 CoreTypes; 39 CoreTypes;
39 import 'dart_backend/dart_backend.dart' as dart_backend; 40 import 'dart_backend/dart_backend.dart' as dart_backend;
(...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 .then((LibraryElement libraryElement) { 907 .then((LibraryElement libraryElement) {
907 documentClass = libraryElement.find('Comment'); 908 documentClass = libraryElement.find('Comment');
908 }); 909 });
909 } 910 }
910 }).then((_) => backend.onLibrariesLoaded(loadedLibraries)); 911 }).then((_) => backend.onLibrariesLoaded(loadedLibraries));
911 } 912 }
912 913
913 bool isProxyConstant(ConstantValue value) { 914 bool isProxyConstant(ConstantValue value) {
914 FieldElement field = coreLibrary.find('proxy'); 915 FieldElement field = coreLibrary.find('proxy');
915 if (field == null) return false; 916 if (field == null) return false;
916 if (!enqueuer.resolution.hasBeenResolved(field)) return false; 917 if (!resolution.hasBeenResolved(field)) return false;
917 if (proxyConstant == null) { 918 if (proxyConstant == null) {
918 proxyConstant = 919 proxyConstant =
919 constants.getConstantValue( 920 constants.getConstantValue(
920 resolver.constantCompiler.compileConstant(field)); 921 resolver.constantCompiler.compileConstant(field));
921 } 922 }
922 return proxyConstant == value; 923 return proxyConstant == value;
923 } 924 }
924 925
925 Element findRequiredElement(LibraryElement library, String name) { 926 Element findRequiredElement(LibraryElement library, String name) {
926 var element = library.find(name); 927 var element = library.find(name);
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
1316 * processing the queues). Also compute the number of methods that 1317 * processing the queues). Also compute the number of methods that
1317 * were resolved, but not compiled (aka excess resolution). 1318 * were resolved, but not compiled (aka excess resolution).
1318 */ 1319 */
1319 checkQueues() { 1320 checkQueues() {
1320 for (Enqueuer world in [enqueuer.resolution, enqueuer.codegen]) { 1321 for (Enqueuer world in [enqueuer.resolution, enqueuer.codegen]) {
1321 world.forEach((WorkItem work) { 1322 world.forEach((WorkItem work) {
1322 internalError(work.element, "Work list is not empty."); 1323 internalError(work.element, "Work list is not empty.");
1323 }); 1324 });
1324 } 1325 }
1325 if (!REPORT_EXCESS_RESOLUTION) return; 1326 if (!REPORT_EXCESS_RESOLUTION) return;
1326 var resolved = new Set.from(enqueuer.resolution.resolvedElements); 1327 var resolved = new Set.from(enqueuer.resolution.processedElements);
1327 for (Element e in enqueuer.codegen.generatedCode.keys) { 1328 for (Element e in enqueuer.codegen.generatedCode.keys) {
1328 resolved.remove(e); 1329 resolved.remove(e);
1329 } 1330 }
1330 for (Element e in new Set.from(resolved)) { 1331 for (Element e in new Set.from(resolved)) {
1331 if (e.isClass || 1332 if (e.isClass ||
1332 e.isField || 1333 e.isField ||
1333 e.isTypeVariable || 1334 e.isTypeVariable ||
1334 e.isTypedef || 1335 e.isTypedef ||
1335 identical(e.kind, ElementKind.ABSTRACT_FIELD)) { 1336 identical(e.kind, ElementKind.ABSTRACT_FIELD)) {
1336 resolved.remove(e); 1337 resolved.remove(e);
1337 } 1338 }
1338 if (identical(e.kind, ElementKind.GENERATIVE_CONSTRUCTOR)) { 1339 if (identical(e.kind, ElementKind.GENERATIVE_CONSTRUCTOR)) {
1339 resolved.remove(e); 1340 resolved.remove(e);
1340 } 1341 }
1341 if (backend.isBackendLibrary(e.library)) { 1342 if (backend.isBackendLibrary(e.library)) {
1342 resolved.remove(e); 1343 resolved.remove(e);
1343 } 1344 }
1344 } 1345 }
1345 log('Excess resolution work: ${resolved.length}.'); 1346 log('Excess resolution work: ${resolved.length}.');
1346 for (Element e in resolved) { 1347 for (Element e in resolved) {
1347 reportWarningMessage(e, 1348 reportWarningMessage(e,
1348 MessageKind.GENERIC, 1349 MessageKind.GENERIC,
1349 {'text': 'Warning: $e resolved but not compiled.'}); 1350 {'text': 'Warning: $e resolved but not compiled.'});
1350 } 1351 }
1351 } 1352 }
1352 1353
1353 WorldImpact analyzeElement(Element element) { 1354 ResolutionWorldImpact analyzeElement(Element element) {
1354 assert(invariant(element, 1355 assert(invariant(element,
1355 element.impliesType || 1356 element.impliesType ||
1356 element.isField || 1357 element.isField ||
1357 element.isFunction || 1358 element.isFunction ||
1358 element.isGenerativeConstructor || 1359 element.isGenerativeConstructor ||
1359 element.isGetter || 1360 element.isGetter ||
1360 element.isSetter, 1361 element.isSetter,
1361 message: 'Unexpected element kind: ${element.kind}')); 1362 message: 'Unexpected element kind: ${element.kind}'));
1362 assert(invariant(element, element is AnalyzableElement, 1363 assert(invariant(element, element is AnalyzableElement,
1363 message: 'Element $element is not analyzable.')); 1364 message: 'Element $element is not analyzable.'));
1364 assert(invariant(element, element.isDeclaration)); 1365 assert(invariant(element, element.isDeclaration));
1365 ResolutionEnqueuer world = enqueuer.resolution; 1366 return resolution.analyzeElement(element);
1366 if (world.hasBeenResolved(element)) {
1367 return const WorldImpact();
1368 }
1369 assert(parser != null);
1370 Node tree = parser.parse(element);
1371 assert(invariant(element, !element.isSynthesized || tree == null));
1372 WorldImpact worldImpact = resolver.resolve(element);
1373 if (tree != null && !analyzeSignaturesOnly && !suppressWarnings) {
1374 // Only analyze nodes with a corresponding [TreeElements].
1375 checker.check(element);
1376 }
1377 world.registerResolvedElement(element);
1378 return worldImpact;
1379 } 1367 }
1380 1368
1381 WorldImpact analyze(ResolutionWorkItem work, ResolutionEnqueuer world) { 1369 ResolutionWorldImpact analyze(ResolutionWorkItem work,
1370 ResolutionEnqueuer world) {
1382 assert(invariant(work.element, identical(world, enqueuer.resolution))); 1371 assert(invariant(work.element, identical(world, enqueuer.resolution)));
1383 assert(invariant(work.element, !work.isAnalyzed, 1372 assert(invariant(work.element, !work.isAnalyzed,
1384 message: 'Element ${work.element} has already been analyzed')); 1373 message: 'Element ${work.element} has already been analyzed'));
1385 if (shouldPrintProgress) { 1374 if (shouldPrintProgress) {
1386 // TODO(ahe): Add structured diagnostics to the compiler API and 1375 // TODO(ahe): Add structured diagnostics to the compiler API and
1387 // use it to separate this from the --verbose option. 1376 // use it to separate this from the --verbose option.
1388 if (phase == PHASE_RESOLVING) { 1377 if (phase == PHASE_RESOLVING) {
1389 log('Resolved ${enqueuer.resolution.resolvedElements.length} ' 1378 log('Resolved ${enqueuer.resolution.processedElements.length} '
1390 'elements.'); 1379 'elements.');
1391 progress.reset(); 1380 progress.reset();
1392 } 1381 }
1393 } 1382 }
1394 AstElement element = work.element; 1383 AstElement element = work.element;
1395 if (world.hasBeenResolved(element)) { 1384 if (world.hasBeenProcessed(element)) {
1396 return const WorldImpact(); 1385 return const ResolutionWorldImpact();
1397 } 1386 }
1398 WorldImpact worldImpact = analyzeElement(element); 1387 ResolutionWorldImpact worldImpact = analyzeElement(element);
1399 backend.onElementResolved(element, element.resolvedAst.elements); 1388 backend.onElementResolved(element, element.resolvedAst.elements);
1389 world.registerProcessedElement(element);
1400 return worldImpact; 1390 return worldImpact;
1401 } 1391 }
1402 1392
1403 WorldImpact codegen(CodegenWorkItem work, CodegenEnqueuer world) { 1393 WorldImpact codegen(CodegenWorkItem work, CodegenEnqueuer world) {
1404 assert(invariant(work.element, identical(world, enqueuer.codegen))); 1394 assert(invariant(work.element, identical(world, enqueuer.codegen)));
1405 if (shouldPrintProgress) { 1395 if (shouldPrintProgress) {
1406 // TODO(ahe): Add structured diagnostics to the compiler API and 1396 // TODO(ahe): Add structured diagnostics to the compiler API and
1407 // use it to separate this from the --verbose option. 1397 // use it to separate this from the --verbose option.
1408 log('Compiled ${enqueuer.codegen.generatedCode.length} methods.'); 1398 log('Compiled ${enqueuer.codegen.generatedCode.length} methods.');
1409 progress.reset(); 1399 progress.reset();
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1619 prevToken = currentToken; 1609 prevToken = currentToken;
1620 currentToken = currentToken.next; 1610 currentToken = currentToken.next;
1621 } 1611 }
1622 return firstToken; 1612 return firstToken;
1623 } 1613 }
1624 1614
1625 void reportUnusedCode() { 1615 void reportUnusedCode() {
1626 void checkLive(member) { 1616 void checkLive(member) {
1627 if (member.isErroneous) return; 1617 if (member.isErroneous) return;
1628 if (member.isFunction) { 1618 if (member.isFunction) {
1629 if (!enqueuer.resolution.hasBeenResolved(member)) { 1619 if (!enqueuer.resolution.hasBeenProcessed(member)) {
1630 reportHintMessage( 1620 reportHintMessage(
1631 member, MessageKind.UNUSED_METHOD, {'name': member.name}); 1621 member, MessageKind.UNUSED_METHOD, {'name': member.name});
1632 } 1622 }
1633 } else if (member.isClass) { 1623 } else if (member.isClass) {
1634 if (!member.isResolved) { 1624 if (!member.isResolved) {
1635 reportHintMessage( 1625 reportHintMessage(
1636 member, MessageKind.UNUSED_CLASS, {'name': member.name}); 1626 member, MessageKind.UNUSED_CLASS, {'name': member.name});
1637 } else { 1627 } else {
1638 member.forEachLocalMember(checkLive); 1628 member.forEachLocalMember(checkLive);
1639 } 1629 }
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1779 ClassElement symbolClass; 1769 ClassElement symbolClass;
1780 ClassElement stackTraceClass; 1770 ClassElement stackTraceClass;
1781 ClassElement futureClass; 1771 ClassElement futureClass;
1782 ClassElement iterableClass; 1772 ClassElement iterableClass;
1783 ClassElement streamClass; 1773 ClassElement streamClass;
1784 ClassElement resourceClass; 1774 ClassElement resourceClass;
1785 1775
1786 _CompilerCoreTypes(this.resolution); 1776 _CompilerCoreTypes(this.resolution);
1787 1777
1788 @override 1778 @override
1789 InterfaceType get objectType => objectClass.computeType(resolution); 1779 InterfaceType get objectType {
1780 objectClass.ensureResolved(resolution);
1781 return objectClass.rawType;
1782 }
1790 1783
1791 @override 1784 @override
1792 InterfaceType get boolType => boolClass.computeType(resolution); 1785 InterfaceType get boolType {
1786 boolClass.ensureResolved(resolution);
1787 return boolClass.rawType;
1788 }
1793 1789
1794 @override 1790 @override
1795 InterfaceType get doubleType => doubleClass.computeType(resolution); 1791 InterfaceType get doubleType {
1792 doubleClass.ensureResolved(resolution);
1793 return doubleClass.rawType;
1794 }
1796 1795
1797 @override 1796 @override
1798 InterfaceType get functionType => functionClass.computeType(resolution); 1797 InterfaceType get functionType {
1798 functionClass.ensureResolved(resolution);
1799 return functionClass.rawType;
1800 }
1799 1801
1800 @override 1802 @override
1801 InterfaceType get intType => intClass.computeType(resolution); 1803 InterfaceType get intType {
1804 intClass.ensureResolved(resolution);
1805 return intClass.rawType;
1806 }
1802 1807
1803 @override 1808 @override
1804 InterfaceType get resourceType => resourceClass.computeType(resolution); 1809 InterfaceType get resourceType {
1810 resourceClass.ensureResolved(resolution);
1811 return resourceClass.rawType;
1812 }
1805 1813
1806 @override 1814 @override
1807 InterfaceType listType([DartType elementType]) { 1815 InterfaceType listType([DartType elementType]) {
1808 InterfaceType type = listClass.computeType(resolution); 1816 listClass.ensureResolved(resolution);
1817 InterfaceType type = listClass.rawType;
1809 if (elementType == null) { 1818 if (elementType == null) {
1810 return listClass.rawType; 1819 return type;
1811 } 1820 }
1812 return type.createInstantiation([elementType]); 1821 return type.createInstantiation([elementType]);
1813 } 1822 }
1814 1823
1815 @override 1824 @override
1816 InterfaceType mapType([DartType keyType, 1825 InterfaceType mapType([DartType keyType,
1817 DartType valueType]) { 1826 DartType valueType]) {
1818 InterfaceType type = mapClass.computeType(resolution); 1827 mapClass.ensureResolved(resolution);
1828 InterfaceType type = mapClass.rawType;
1819 if (keyType == null && valueType == null) { 1829 if (keyType == null && valueType == null) {
1820 return mapClass.rawType; 1830 return type;
1821 } else if (keyType == null) { 1831 } else if (keyType == null) {
1822 keyType = const DynamicType(); 1832 keyType = const DynamicType();
1823 } else if (valueType == null) { 1833 } else if (valueType == null) {
1824 valueType = const DynamicType(); 1834 valueType = const DynamicType();
1825 } 1835 }
1826 return type.createInstantiation([keyType, valueType]); 1836 return type.createInstantiation([keyType, valueType]);
1827 } 1837 }
1828 1838
1829 @override 1839 @override
1830 InterfaceType get nullType => nullClass.computeType(resolution); 1840 InterfaceType get nullType {
1841 nullClass.ensureResolved(resolution);
1842 return nullClass.rawType;
1843 }
1831 1844
1832 @override 1845 @override
1833 InterfaceType get numType => numClass.computeType(resolution); 1846 InterfaceType get numType {
1847 numClass.ensureResolved(resolution);
1848 return numClass.rawType;
1849 }
1834 1850
1835 @override 1851 @override
1836 InterfaceType get stringType => stringClass.computeType(resolution); 1852 InterfaceType get stringType {
1853 stringClass.ensureResolved(resolution);
1854 return stringClass.rawType;
1855 }
1837 1856
1838 @override 1857 @override
1839 InterfaceType get symbolType => symbolClass.computeType(resolution); 1858 InterfaceType get symbolType {
1859 symbolClass.ensureResolved(resolution);
1860 return symbolClass.rawType;
1861 }
1840 1862
1841 @override 1863 @override
1842 InterfaceType get typeType => typeClass.computeType(resolution); 1864 InterfaceType get typeType {
1865 typeClass.ensureResolved(resolution);
1866 return typeClass.rawType;
1867 }
1843 1868
1844 @override 1869 @override
1845 InterfaceType iterableType([DartType elementType]) { 1870 InterfaceType iterableType([DartType elementType]) {
1846 InterfaceType type = iterableClass.computeType(resolution); 1871 iterableClass.ensureResolved(resolution);
1872 InterfaceType type = iterableClass.rawType;
1847 if (elementType == null) { 1873 if (elementType == null) {
1848 return iterableClass.rawType; 1874 return type;
1849 } 1875 }
1850 return type.createInstantiation([elementType]); 1876 return type.createInstantiation([elementType]);
1851 } 1877 }
1852 1878
1853 @override 1879 @override
1854 InterfaceType futureType([DartType elementType]) { 1880 InterfaceType futureType([DartType elementType]) {
1855 InterfaceType type = futureClass.computeType(resolution); 1881 futureClass.ensureResolved(resolution);
1882 InterfaceType type = futureClass.rawType;
1856 if (elementType == null) { 1883 if (elementType == null) {
1857 return futureClass.rawType; 1884 return type;
1858 } 1885 }
1859 return type.createInstantiation([elementType]); 1886 return type.createInstantiation([elementType]);
1860 } 1887 }
1861 1888
1862 @override 1889 @override
1863 InterfaceType streamType([DartType elementType]) { 1890 InterfaceType streamType([DartType elementType]) {
1864 InterfaceType type = streamClass.computeType(resolution); 1891 streamClass.ensureResolved(resolution);
1892 InterfaceType type = streamClass.rawType;
1865 if (elementType == null) { 1893 if (elementType == null) {
1866 return streamClass.rawType; 1894 return type;
1867 } 1895 }
1868 return type.createInstantiation([elementType]); 1896 return type.createInstantiation([elementType]);
1869 } 1897 }
1870 } 1898 }
1871 1899
1872 // TODO(johnniwinther): Move [ResolverTask] here. 1900 // TODO(johnniwinther): Move [ResolverTask] here.
1873 class _CompilerResolution implements Resolution { 1901 class _CompilerResolution implements Resolution {
1874 final Compiler compiler; 1902 final Compiler compiler;
1903 final Map<Element, ResolutionWorldImpact> _worldImpactCache =
1904 <Element, ResolutionWorldImpact>{};
1875 1905
1876 _CompilerResolution(this.compiler); 1906 _CompilerResolution(this.compiler);
1877 1907
1878 @override 1908 @override
1879 DiagnosticListener get listener => compiler; 1909 DiagnosticListener get listener => compiler;
1880 1910
1881 @override 1911 @override
1882 Parsing get parsing => compiler.parsing; 1912 Parsing get parsing => compiler.parsing;
1883 1913
1884 @override 1914 @override
(...skipping 21 matching lines...) Expand all
1906 1936
1907 @override 1937 @override
1908 FunctionSignature resolveSignature(FunctionElement function) { 1938 FunctionSignature resolveSignature(FunctionElement function) {
1909 return compiler.resolver.resolveSignature(function); 1939 return compiler.resolver.resolveSignature(function);
1910 } 1940 }
1911 1941
1912 @override 1942 @override
1913 DartType resolveTypeAnnotation(Element element, TypeAnnotation node) { 1943 DartType resolveTypeAnnotation(Element element, TypeAnnotation node) {
1914 return compiler.resolver.resolveTypeAnnotation(element, node); 1944 return compiler.resolver.resolveTypeAnnotation(element, node);
1915 } 1945 }
1946
1947 ResolutionWorldImpact analyzeElement(Element element) {
1948 return _worldImpactCache.putIfAbsent(element, () {
1949 assert(compiler.parser != null);
1950 Node tree = compiler.parser.parse(element);
1951 assert(invariant(element, !element.isSynthesized || tree == null));
1952 ResolutionWorldImpact worldImpact = compiler.resolver.resolve(element);
1953 if (tree != null &&
1954 !compiler.analyzeSignaturesOnly &&
1955 !compiler.suppressWarnings) {
1956 // Only analyze nodes with a corresponding [TreeElements].
1957 compiler.checker.check(element);
1958 }
1959 return worldImpact;
1960 });
1961 }
1962
1963 @override
1964 bool hasBeenResolved(Element element) {
1965 return _worldImpactCache.containsKey(element);
1966 }
1916 } 1967 }
1917 1968
1918 // TODO(johnniwinther): Move [ParserTask], [PatchParserTask], [DietParserTask] 1969 // TODO(johnniwinther): Move [ParserTask], [PatchParserTask], [DietParserTask]
1919 // and [ScannerTask] here. 1970 // and [ScannerTask] here.
1920 class _CompilerParsing implements Parsing { 1971 class _CompilerParsing implements Parsing {
1921 final Compiler compiler; 1972 final Compiler compiler;
1922 1973
1923 _CompilerParsing(this.compiler); 1974 _CompilerParsing(this.compiler);
1924 1975
1925 @override 1976 @override
1926 DiagnosticListener get listener => compiler; 1977 DiagnosticListener get listener => compiler;
1927 1978
1928 @override 1979 @override
1929 measure(f()) => compiler.parser.measure(f); 1980 measure(f()) => compiler.parser.measure(f);
1930 1981
1931 @override 1982 @override
1932 void parsePatchClass(ClassElement cls) { 1983 void parsePatchClass(ClassElement cls) {
1933 compiler.patchParser.measure(() { 1984 compiler.patchParser.measure(() {
1934 if (cls.isPatch) { 1985 if (cls.isPatch) {
1935 compiler.patchParser.parsePatchClassNode(cls); 1986 compiler.patchParser.parsePatchClassNode(cls);
1936 } 1987 }
1937 }); 1988 });
1938 } 1989 }
1939 } 1990 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698