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

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

Issue 2620023002: Use elements/types in constants/values (Closed)
Patch Set: Created 3 years, 11 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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 js_backend.namer; 5 library js_backend.namer;
6 6
7 import 'dart:collection' show HashMap; 7 import 'dart:collection' show HashMap;
8 8
9 import 'package:js_runtime/shared/embedded_names.dart' show JsGetName; 9 import 'package:js_runtime/shared/embedded_names.dart' show JsGetName;
10 10
11 import '../closure.dart'; 11 import '../closure.dart';
12 import '../common.dart'; 12 import '../common.dart';
13 import '../common/names.dart' show Identifiers, Selectors; 13 import '../common/names.dart' show Identifiers, Selectors;
14 import '../compiler.dart' show Compiler; 14 import '../compiler.dart' show Compiler;
15 import '../constants/values.dart'; 15 import '../constants/values.dart';
16 import '../core_types.dart' show CommonElements; 16 import '../core_types.dart' show CommonElements;
17 import '../elements/resolution_types.dart'; 17 import '../elements/resolution_types.dart';
18 import '../diagnostics/invariant.dart' show DEBUG_MODE; 18 import '../diagnostics/invariant.dart' show DEBUG_MODE;
19 import '../elements/elements.dart'; 19 import '../elements/elements.dart';
20 import '../elements/entities.dart'; 20 import '../elements/entities.dart';
21 import '../js/js.dart' as jsAst; 21 import '../js/js.dart' as jsAst;
22 import '../js/js.dart' show js; 22 import '../js/js.dart' show js;
23 import '../tree/tree.dart'; 23 import '../tree/tree.dart';
24 import '../universe/call_structure.dart' show CallStructure; 24 import '../universe/call_structure.dart' show CallStructure;
25 import '../universe/selector.dart' show Selector, SelectorKind; 25 import '../universe/selector.dart' show Selector, SelectorKind;
26 import '../universe/world_builder.dart' show CodegenWorldBuilder;
26 import '../util/characters.dart'; 27 import '../util/characters.dart';
27 import '../util/util.dart'; 28 import '../util/util.dart';
28 import '../world.dart' show ClosedWorld; 29 import '../world.dart' show ClosedWorld;
29 import 'backend.dart'; 30 import 'backend.dart';
30 import 'backend_helpers.dart'; 31 import 'backend_helpers.dart';
31 import 'constant_system_javascript.dart'; 32 import 'constant_system_javascript.dart';
32 33
33 part 'field_naming_mixin.dart'; 34 part 'field_naming_mixin.dart';
34 part 'frequency_namer.dart'; 35 part 'frequency_namer.dart';
35 part 'minify_namer.dart'; 36 part 'minify_namer.dart';
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 jsAst.Name get rtiFieldName => _rtiFieldName ??= new StringBackedName(r'$ti'); 398 jsAst.Name get rtiFieldName => _rtiFieldName ??= new StringBackedName(r'$ti');
398 399
399 // Name of property in a class description for the native dispatch metadata. 400 // Name of property in a class description for the native dispatch metadata.
400 final String nativeSpecProperty = '%'; 401 final String nativeSpecProperty = '%';
401 402
402 static final RegExp IDENTIFIER = new RegExp(r'^[A-Za-z_$][A-Za-z0-9_$]*$'); 403 static final RegExp IDENTIFIER = new RegExp(r'^[A-Za-z_$][A-Za-z0-9_$]*$');
403 static final RegExp NON_IDENTIFIER_CHAR = new RegExp(r'[^A-Za-z_0-9$]'); 404 static final RegExp NON_IDENTIFIER_CHAR = new RegExp(r'[^A-Za-z_0-9$]');
404 405
405 final JavaScriptBackend backend; 406 final JavaScriptBackend backend;
406 final ClosedWorld closedWorld; 407 final ClosedWorld closedWorld;
408 final CodegenWorldBuilder codegenWorldBuilder;
407 409
408 /// Used disambiguated names in the global namespace, issued by 410 /// Used disambiguated names in the global namespace, issued by
409 /// [_disambiguateGlobal], and [_disambiguateInternalGlobal]. 411 /// [_disambiguateGlobal], and [_disambiguateInternalGlobal].
410 /// 412 ///
411 /// Although global names are distributed across a number of global objects, 413 /// Although global names are distributed across a number of global objects,
412 /// (see [globalObjectFor]), we currently use a single namespace for all these 414 /// (see [globalObjectFor]), we currently use a single namespace for all these
413 /// names. 415 /// names.
414 final NamingScope globalScope = new NamingScope(); 416 final NamingScope globalScope = new NamingScope();
415 final Map<Element, jsAst.Name> userGlobals = 417 final Map<Element, jsAst.Name> userGlobals =
416 new HashMap<Element, jsAst.Name>(); 418 new HashMap<Element, jsAst.Name>();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 455
454 final Map<String, String> suggestedGlobalNames = <String, String>{}; 456 final Map<String, String> suggestedGlobalNames = <String, String>{};
455 final Map<String, String> suggestedInstanceNames = <String, String>{}; 457 final Map<String, String> suggestedInstanceNames = <String, String>{};
456 458
457 /// Used to store unique keys for library names. Keys are not used as names, 459 /// Used to store unique keys for library names. Keys are not used as names,
458 /// nor are they visible in the output. The only serve as an internal 460 /// nor are they visible in the output. The only serve as an internal
459 /// key into maps. 461 /// key into maps.
460 final Map<LibraryElement, String> _libraryKeys = 462 final Map<LibraryElement, String> _libraryKeys =
461 new HashMap<LibraryElement, String>(); 463 new HashMap<LibraryElement, String>();
462 464
463 Namer(JavaScriptBackend backend, this.closedWorld) 465 Namer(JavaScriptBackend backend, this.closedWorld,
466 CodegenWorldBuilder codegenWorldBuilder)
464 : this.backend = backend, 467 : this.backend = backend,
465 constantHasher = 468 this.codegenWorldBuilder = codegenWorldBuilder,
466 new ConstantCanonicalHasher(backend.rtiEncoder, backend.reporter), 469 constantHasher = new ConstantCanonicalHasher(
470 backend.rtiEncoder, backend.reporter, codegenWorldBuilder),
467 functionTypeNamer = new FunctionTypeNamer(backend.rtiEncoder) { 471 functionTypeNamer = new FunctionTypeNamer(backend.rtiEncoder) {
468 _literalAsyncPrefix = new StringBackedName(asyncPrefix); 472 _literalAsyncPrefix = new StringBackedName(asyncPrefix);
469 _literalGetterPrefix = new StringBackedName(getterPrefix); 473 _literalGetterPrefix = new StringBackedName(getterPrefix);
470 _literalSetterPrefix = new StringBackedName(setterPrefix); 474 _literalSetterPrefix = new StringBackedName(setterPrefix);
471 _literalLazyGetterPrefix = new StringBackedName(lazyGetterPrefix); 475 _literalLazyGetterPrefix = new StringBackedName(lazyGetterPrefix);
472 } 476 }
473 477
474 BackendHelpers get helpers => backend.helpers; 478 BackendHelpers get helpers => backend.helpers;
475 479
476 DiagnosticReporter get reporter => backend.reporter; 480 DiagnosticReporter get reporter => backend.reporter;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 constantNames[constant] = result; 589 constantNames[constant] = result;
586 } 590 }
587 return _newReference(result); 591 return _newReference(result);
588 } 592 }
589 593
590 /// Proposed name for [constant]. 594 /// Proposed name for [constant].
591 String constantLongName(ConstantValue constant) { 595 String constantLongName(ConstantValue constant) {
592 String longName = constantLongNames[constant]; 596 String longName = constantLongNames[constant];
593 if (longName == null) { 597 if (longName == null) {
594 longName = new ConstantNamingVisitor( 598 longName = new ConstantNamingVisitor(
595 backend.rtiEncoder, reporter, constantHasher) 599 backend.rtiEncoder, reporter, codegenWorldBuilder, constantHasher)
596 .getName(constant); 600 .getName(constant);
597 constantLongNames[constant] = longName; 601 constantLongNames[constant] = longName;
598 } 602 }
599 return longName; 603 return longName;
600 } 604 }
601 605
602 String breakLabelName(LabelDefinition label) { 606 String breakLabelName(LabelDefinition label) {
603 return '\$${label.labelName}\$${label.target.nestingLevel}'; 607 return '\$${label.labelName}\$${label.target.nestingLevel}';
604 } 608 }
605 609
(...skipping 1032 matching lines...) Expand 10 before | Expand all | Expand 10 after
1638 * 1642 *
1639 */ 1643 */
1640 class ConstantNamingVisitor implements ConstantValueVisitor { 1644 class ConstantNamingVisitor implements ConstantValueVisitor {
1641 static final RegExp IDENTIFIER = new RegExp(r'^[A-Za-z_$][A-Za-z0-9_$]*$'); 1645 static final RegExp IDENTIFIER = new RegExp(r'^[A-Za-z_$][A-Za-z0-9_$]*$');
1642 static const MAX_FRAGMENTS = 5; 1646 static const MAX_FRAGMENTS = 5;
1643 static const MAX_EXTRA_LENGTH = 30; 1647 static const MAX_EXTRA_LENGTH = 30;
1644 static const DEFAULT_TAG_LENGTH = 3; 1648 static const DEFAULT_TAG_LENGTH = 3;
1645 1649
1646 final RuntimeTypesEncoder rtiEncoder; 1650 final RuntimeTypesEncoder rtiEncoder;
1647 final DiagnosticReporter reporter; 1651 final DiagnosticReporter reporter;
1652 final CodegenWorldBuilder codegenWorldBuilder;
1648 final ConstantCanonicalHasher hasher; 1653 final ConstantCanonicalHasher hasher;
1649 1654
1650 String root = null; // First word, usually a type name. 1655 String root = null; // First word, usually a type name.
1651 bool failed = false; // Failed to generate something pretty. 1656 bool failed = false; // Failed to generate something pretty.
1652 List<String> fragments = <String>[]; 1657 List<String> fragments = <String>[];
1653 int length = 0; 1658 int length = 0;
1654 1659
1655 ConstantNamingVisitor(this.rtiEncoder, this.reporter, this.hasher); 1660 ConstantNamingVisitor(
1661 this.rtiEncoder, this.reporter, this.codegenWorldBuilder, this.hasher);
1656 1662
1657 String getName(ConstantValue constant) { 1663 String getName(ConstantValue constant) {
1658 _visit(constant); 1664 _visit(constant);
1659 if (root == null) return 'CONSTANT'; 1665 if (root == null) return 'CONSTANT';
1660 if (failed) return '${root}_${getHashTag(constant, DEFAULT_TAG_LENGTH)}'; 1666 if (failed) return '${root}_${getHashTag(constant, DEFAULT_TAG_LENGTH)}';
1661 if (fragments.length == 1) return 'C_${root}'; 1667 if (fragments.length == 1) return 'C_${root}';
1662 return fragments.join('_'); 1668 return fragments.join('_');
1663 } 1669 }
1664 1670
1665 String getHashTag(ConstantValue constant, int width) => 1671 String getHashTag(ConstantValue constant, int width) =>
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1774 } else { 1780 } else {
1775 // Using some bits from the keys hash tag groups the names Maps with the 1781 // Using some bits from the keys hash tag groups the names Maps with the
1776 // same structure. 1782 // same structure.
1777 add(getHashTag(constant.keyList, 2) + getHashTag(constant, 3)); 1783 add(getHashTag(constant.keyList, 2) + getHashTag(constant, 3));
1778 } 1784 }
1779 } 1785 }
1780 1786
1781 @override 1787 @override
1782 void visitConstructed(ConstructedConstantValue constant, [_]) { 1788 void visitConstructed(ConstructedConstantValue constant, [_]) {
1783 addRoot(constant.type.element.name); 1789 addRoot(constant.type.element.name);
1784 constant.type.element.forEachInstanceField((_, FieldElement field) { 1790 codegenWorldBuilder.forEachInstanceField(constant.type.element,
Siggi Cherem (dart-lang) 2017/01/11 22:57:47 interesting - correct me if I'm wrong, but I thoug
Johnni Winther 2017/01/12 11:17:45 I agree. We should create a ClosedWorld for codege
1791 (_, FieldElement field) {
1785 if (failed) return; 1792 if (failed) return;
1786 _visit(constant.fields[field]); 1793 _visit(constant.fields[field]);
1787 }, includeSuperAndInjectedMembers: true); 1794 });
1788 } 1795 }
1789 1796
1790 @override 1797 @override
1791 void visitType(TypeConstantValue constant, [_]) { 1798 void visitType(TypeConstantValue constant, [_]) {
1792 // Generates something like 'Type_String_k8F', using the simple name of the 1799 // Generates something like 'Type_String_k8F', using the simple name of the
1793 // type and a hash to disambiguate the same name in different libraries. 1800 // type and a hash to disambiguate the same name in different libraries.
1794 addRoot('Type'); 1801 addRoot('Type');
1795 ResolutionDartType type = constant.representedType; 1802 ResolutionDartType type = constant.representedType;
1796 String name = type.element?.name; 1803 String name = type.element?.name;
1797 if (name == null) { 1804 if (name == null) {
1798 // e.g. DartType 'dynamic' has no element. 1805 // e.g. DartType 'dynamic' has no element.
1799 name = rtiEncoder.getTypeRepresentationForTypeConstant(type); 1806 name = rtiEncoder.getTypeRepresentationForTypeConstant(type);
1800 } 1807 }
1801 addIdentifier(name); 1808 addIdentifier(name);
1802 add(getHashTag(constant, 3)); 1809 add(getHashTag(constant, 3));
1803 } 1810 }
1804 1811
1805 @override 1812 @override
1806 void visitInterceptor(InterceptorConstantValue constant, [_]) { 1813 void visitInterceptor(InterceptorConstantValue constant, [_]) {
1807 addRoot(constant.dispatchedType.element.name); 1814 addRoot(constant.cls.name);
1808 add('methods'); 1815 add('methods');
1809 } 1816 }
1810 1817
1811 @override 1818 @override
1812 void visitSynthetic(SyntheticConstantValue constant, [_]) { 1819 void visitSynthetic(SyntheticConstantValue constant, [_]) {
1813 switch (constant.valueKind) { 1820 switch (constant.valueKind) {
1814 case SyntheticConstantKind.DUMMY_INTERCEPTOR: 1821 case SyntheticConstantKind.DUMMY_INTERCEPTOR:
1815 add('dummy_receiver'); 1822 add('dummy_receiver');
1816 break; 1823 break;
1817 case SyntheticConstantKind.TYPEVARIABLE_REFERENCE: 1824 case SyntheticConstantKind.TYPEVARIABLE_REFERENCE:
(...skipping 21 matching lines...) Expand all
1839 * so it can't be used for generating names. This hasher keeps consistency 1846 * so it can't be used for generating names. This hasher keeps consistency
1840 * between runs by basing hash values of the names of elements, rather than 1847 * between runs by basing hash values of the names of elements, rather than
1841 * their hashCodes. 1848 * their hashCodes.
1842 */ 1849 */
1843 class ConstantCanonicalHasher implements ConstantValueVisitor<int, Null> { 1850 class ConstantCanonicalHasher implements ConstantValueVisitor<int, Null> {
1844 static const _MASK = 0x1fffffff; 1851 static const _MASK = 0x1fffffff;
1845 static const _UINT32_LIMIT = 4 * 1024 * 1024 * 1024; 1852 static const _UINT32_LIMIT = 4 * 1024 * 1024 * 1024;
1846 1853
1847 final DiagnosticReporter reporter; 1854 final DiagnosticReporter reporter;
1848 final RuntimeTypesEncoder rtiEncoder; 1855 final RuntimeTypesEncoder rtiEncoder;
1856 final CodegenWorldBuilder codegenWorldBuilder;
1849 final Map<ConstantValue, int> hashes = new Map<ConstantValue, int>(); 1857 final Map<ConstantValue, int> hashes = new Map<ConstantValue, int>();
1850 1858
1851 ConstantCanonicalHasher(this.rtiEncoder, this.reporter); 1859 ConstantCanonicalHasher(
1860 this.rtiEncoder, this.reporter, this.codegenWorldBuilder);
1852 1861
1853 int getHash(ConstantValue constant) => _visit(constant); 1862 int getHash(ConstantValue constant) => _visit(constant);
1854 1863
1855 int _visit(ConstantValue constant) { 1864 int _visit(ConstantValue constant) {
1856 int hash = hashes[constant]; 1865 int hash = hashes[constant];
1857 if (hash == null) { 1866 if (hash == null) {
1858 hash = _finish(constant.accept(this, null)); 1867 hash = _finish(constant.accept(this, null));
1859 hashes[constant] = hash; 1868 hashes[constant] = hash;
1860 } 1869 }
1861 return hash; 1870 return hash;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1899 1908
1900 @override 1909 @override
1901 int visitMap(MapConstantValue constant, [_]) { 1910 int visitMap(MapConstantValue constant, [_]) {
1902 int hash = _hashList(constant.length, constant.keys); 1911 int hash = _hashList(constant.length, constant.keys);
1903 return _hashList(hash, constant.values); 1912 return _hashList(hash, constant.values);
1904 } 1913 }
1905 1914
1906 @override 1915 @override
1907 int visitConstructed(ConstructedConstantValue constant, [_]) { 1916 int visitConstructed(ConstructedConstantValue constant, [_]) {
1908 int hash = _hashString(3, constant.type.element.name); 1917 int hash = _hashString(3, constant.type.element.name);
1909 constant.type.element.forEachInstanceField((_, FieldElement field) { 1918 codegenWorldBuilder.forEachInstanceField(constant.type.element,
1919 (_, FieldElement field) {
1910 hash = _combine(hash, _visit(constant.fields[field])); 1920 hash = _combine(hash, _visit(constant.fields[field]));
1911 }, includeSuperAndInjectedMembers: true); 1921 });
1912 return hash; 1922 return hash;
1913 } 1923 }
1914 1924
1915 @override 1925 @override
1916 int visitType(TypeConstantValue constant, [_]) { 1926 int visitType(TypeConstantValue constant, [_]) {
1917 ResolutionDartType type = constant.representedType; 1927 ResolutionDartType type = constant.representedType;
1918 // This name includes the library name and type parameters. 1928 // This name includes the library name and type parameters.
1919 String name = rtiEncoder.getTypeRepresentationForTypeConstant(type); 1929 String name = rtiEncoder.getTypeRepresentationForTypeConstant(type);
1920 return _hashString(4, name); 1930 return _hashString(4, name);
1921 } 1931 }
1922 1932
1923 @override 1933 @override
1924 int visitInterceptor(InterceptorConstantValue constant, [_]) { 1934 int visitInterceptor(InterceptorConstantValue constant, [_]) {
1925 String typeName = constant.dispatchedType.element.name; 1935 String typeName = constant.cls.name;
1926 return _hashString(5, typeName); 1936 return _hashString(5, typeName);
1927 } 1937 }
1928 1938
1929 @override 1939 @override
1930 int visitSynthetic(SyntheticConstantValue constant, [_]) { 1940 int visitSynthetic(SyntheticConstantValue constant, [_]) {
1931 switch (constant.valueKind) { 1941 switch (constant.valueKind) {
1932 case SyntheticConstantKind.TYPEVARIABLE_REFERENCE: 1942 case SyntheticConstantKind.TYPEVARIABLE_REFERENCE:
1933 // These contain a deferred opaque index into metadata. There is nothing 1943 // These contain a deferred opaque index into metadata. There is nothing
1934 // we can access that is stable between compiles. Luckily, since they 1944 // we can access that is stable between compiles. Luckily, since they
1935 // resolve to integer indexes, they're always part of a larger constant. 1945 // resolve to integer indexes, they're always part of a larger constant.
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
2095 void addSuggestion(String original, String suggestion) { 2105 void addSuggestion(String original, String suggestion) {
2096 assert(!_suggestedNames.containsKey(original)); 2106 assert(!_suggestedNames.containsKey(original));
2097 _suggestedNames[original] = suggestion; 2107 _suggestedNames[original] = suggestion;
2098 } 2108 }
2099 2109
2100 bool hasSuggestion(String original) => _suggestedNames.containsKey(original); 2110 bool hasSuggestion(String original) => _suggestedNames.containsKey(original);
2101 bool isSuggestion(String candidate) { 2111 bool isSuggestion(String candidate) {
2102 return _suggestedNames.containsValue(candidate); 2112 return _suggestedNames.containsValue(candidate);
2103 } 2113 }
2104 } 2114 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698