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

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

Issue 1320503003: dart2js: add initial support for lookup-maps (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 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 part of js_backend; 5 part of js_backend;
6 6
7 const VERBOSE_OPTIMIZER_HINTS = false; 7 const VERBOSE_OPTIMIZER_HINTS = false;
8 8
9 class JavaScriptItemCompilationContext extends ItemCompilationContext { 9 class JavaScriptItemCompilationContext extends ItemCompilationContext {
10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); 10 final Set<HInstruction> boundsChecked = new Set<HInstruction>();
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 static final Uri DART_FOREIGN_HELPER = 228 static final Uri DART_FOREIGN_HELPER =
229 new Uri(scheme: 'dart', path: '_foreign_helper'); 229 new Uri(scheme: 'dart', path: '_foreign_helper');
230 static final Uri DART_JS_MIRRORS = 230 static final Uri DART_JS_MIRRORS =
231 new Uri(scheme: 'dart', path: '_js_mirrors'); 231 new Uri(scheme: 'dart', path: '_js_mirrors');
232 static final Uri DART_JS_NAMES = 232 static final Uri DART_JS_NAMES =
233 new Uri(scheme: 'dart', path: '_js_names'); 233 new Uri(scheme: 'dart', path: '_js_names');
234 static final Uri DART_EMBEDDED_NAMES = 234 static final Uri DART_EMBEDDED_NAMES =
235 new Uri(scheme: 'dart', path: '_js_embedded_names'); 235 new Uri(scheme: 'dart', path: '_js_embedded_names');
236 static final Uri DART_ISOLATE_HELPER = 236 static final Uri DART_ISOLATE_HELPER =
237 new Uri(scheme: 'dart', path: '_isolate_helper'); 237 new Uri(scheme: 'dart', path: '_isolate_helper');
238 static final Uri PACKAGE_LOOKUP_MAP =
239 new Uri(scheme: 'package', path: 'lookup_map/lookup_map.dart');
238 static final Uri DART_ASYNC = new Uri(scheme: 'dart', path: 'async'); 240 static final Uri DART_ASYNC = new Uri(scheme: 'dart', path: 'async');
239 static final Uri DART_HTML = new Uri(scheme: 'dart', path: 'html'); 241 static final Uri DART_HTML = new Uri(scheme: 'dart', path: 'html');
240 242
241 static const String INVOKE_ON = '_getCachedInvocation'; 243 static const String INVOKE_ON = '_getCachedInvocation';
242 static const String START_ROOT_ISOLATE = 'startRootIsolate'; 244 static const String START_ROOT_ISOLATE = 'startRootIsolate';
243 245
244 246
245 String get patchVersion => emitter.patchVersion; 247 String get patchVersion => emitter.patchVersion;
246 248
247 bool get supportsReflection => emitter.emitter.supportsReflection; 249 bool get supportsReflection => emitter.emitter.supportsReflection;
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 607
606 TypeVariableHandler typeVariableHandler; 608 TypeVariableHandler typeVariableHandler;
607 609
608 /// Number of methods compiled before considering reflection. 610 /// Number of methods compiled before considering reflection.
609 int preMirrorsMethodCount = 0; 611 int preMirrorsMethodCount = 0;
610 612
611 /// Resolution and codegen support for generating table of interceptors and 613 /// Resolution and codegen support for generating table of interceptors and
612 /// constructors for custom elements. 614 /// constructors for custom elements.
613 CustomElementsAnalysis customElementsAnalysis; 615 CustomElementsAnalysis customElementsAnalysis;
614 616
617 /// Codegen support for tree-shaking entries of `LookupMap`.
618 LookupMapAnalysis lookupMapAnalysis;
619
615 /// Support for classifying `noSuchMethod` implementations. 620 /// Support for classifying `noSuchMethod` implementations.
616 NoSuchMethodRegistry noSuchMethodRegistry; 621 NoSuchMethodRegistry noSuchMethodRegistry;
617 622
618 JavaScriptConstantTask constantCompilerTask; 623 JavaScriptConstantTask constantCompilerTask;
619 624
620 JavaScriptResolutionCallbacks resolutionCallbacks; 625 JavaScriptResolutionCallbacks resolutionCallbacks;
621 626
622 PatchResolverTask patchResolverTask; 627 PatchResolverTask patchResolverTask;
623 628
624 bool enabledNoSuchMethod = false; 629 bool enabledNoSuchMethod = false;
(...skipping 13 matching lines...) Expand all
638 generateSourceMap 643 generateSourceMap
639 ? (useNewSourceInfo 644 ? (useNewSourceInfo
640 ? const PositionSourceInformationStrategy() 645 ? const PositionSourceInformationStrategy()
641 : const StartEndSourceInformationStrategy()) 646 : const StartEndSourceInformationStrategy())
642 : const JavaScriptSourceInformationStrategy(), 647 : const JavaScriptSourceInformationStrategy(),
643 super(compiler) { 648 super(compiler) {
644 emitter = new CodeEmitterTask( 649 emitter = new CodeEmitterTask(
645 compiler, namer, generateSourceMap, useStartupEmitter); 650 compiler, namer, generateSourceMap, useStartupEmitter);
646 typeVariableHandler = new TypeVariableHandler(compiler); 651 typeVariableHandler = new TypeVariableHandler(compiler);
647 customElementsAnalysis = new CustomElementsAnalysis(this); 652 customElementsAnalysis = new CustomElementsAnalysis(this);
653 lookupMapAnalysis = new LookupMapAnalysis(this);
648 noSuchMethodRegistry = new NoSuchMethodRegistry(this); 654 noSuchMethodRegistry = new NoSuchMethodRegistry(this);
649 constantCompilerTask = new JavaScriptConstantTask(compiler); 655 constantCompilerTask = new JavaScriptConstantTask(compiler);
650 resolutionCallbacks = new JavaScriptResolutionCallbacks(this); 656 resolutionCallbacks = new JavaScriptResolutionCallbacks(this);
651 patchResolverTask = new PatchResolverTask(compiler); 657 patchResolverTask = new PatchResolverTask(compiler);
652 functionCompiler = compiler.useCpsIr 658 functionCompiler = compiler.useCpsIr
653 ? new CpsFunctionCompiler( 659 ? new CpsFunctionCompiler(
654 compiler, this, sourceInformationStrategy) 660 compiler, this, sourceInformationStrategy)
655 : new SsaFunctionCompiler(this, sourceInformationStrategy); 661 : new SsaFunctionCompiler(this, sourceInformationStrategy);
656 } 662 }
657 663
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 jsAst.Name name = namer.nameForGetInterceptor(classes); 952 jsAst.Name name = namer.nameForGetInterceptor(classes);
947 if (classes.contains(jsInterceptorClass)) { 953 if (classes.contains(jsInterceptorClass)) {
948 // We can't use a specialized [getInterceptorMethod], so we make 954 // We can't use a specialized [getInterceptorMethod], so we make
949 // sure we emit the one with all checks. 955 // sure we emit the one with all checks.
950 specializedGetInterceptors[name] = interceptedClasses; 956 specializedGetInterceptors[name] = interceptedClasses;
951 } else { 957 } else {
952 specializedGetInterceptors[name] = classes; 958 specializedGetInterceptors[name] = classes;
953 } 959 }
954 } 960 }
955 961
956 void registerCompileTimeConstant(ConstantValue constant, Registry registry) { 962 void registerCompileTimeConstant(ConstantValue constant, Registry registry,
963 {bool addForEmission: true}) {
957 registerCompileTimeConstantInternal(constant, registry); 964 registerCompileTimeConstantInternal(constant, registry);
965
966 if (!registry.isForResolution &&
967 lookupMapAnalysis.isLookupMap(constant)) {
968 // Note: internally, this registration will temporarily remove the
969 // constant dependencies and add them later on-demand.
970 lookupMapAnalysis.registerLookupMapReference(constant);
971 }
972
958 for (ConstantValue dependency in constant.getDependencies()) { 973 for (ConstantValue dependency in constant.getDependencies()) {
959 registerCompileTimeConstant(dependency, registry); 974 registerCompileTimeConstant(dependency, registry,
975 addForEmission: false);
960 } 976 }
977
978 if (addForEmission) constants.addCompileTimeConstantForEmission(constant);
961 } 979 }
962 980
963 void registerCompileTimeConstantInternal(ConstantValue constant, 981 void registerCompileTimeConstantInternal(ConstantValue constant,
964 Registry registry) { 982 Registry registry) {
965 DartType type = constant.getType(compiler.coreTypes); 983 DartType type = constant.getType(compiler.coreTypes);
966 registerInstantiatedConstantType(type, registry); 984 registerInstantiatedConstantType(type, registry);
967 985
968 if (constant.isFunction) { 986 if (constant.isFunction) {
969 FunctionConstantValue function = constant; 987 FunctionConstantValue function = constant;
970 registry.registerGetOfStaticFunction(function.element); 988 registry.registerGetOfStaticFunction(function.element);
971 } else if (constant.isInterceptor) { 989 } else if (constant.isInterceptor) {
972 // An interceptor constant references the class's prototype chain. 990 // An interceptor constant references the class's prototype chain.
973 InterceptorConstantValue interceptor = constant; 991 InterceptorConstantValue interceptor = constant;
974 registerInstantiatedConstantType(interceptor.dispatchedType, registry); 992 registerInstantiatedConstantType(interceptor.dispatchedType, registry);
975 } else if (constant.isType) { 993 } else if (constant.isType) {
976 enqueueInResolution(getCreateRuntimeType(), registry); 994 enqueueInResolution(getCreateRuntimeType(), registry);
977 registry.registerInstantiation(typeImplementation.rawType); 995 registry.registerInstantiation(typeImplementation.rawType);
996 DartType representedType =
997 (constant as TypeConstantValue).representedType;
herhut 2015/09/02 12:59:57 Why use as here? I think the usual style is to cas
Siggi Cherem (dart-lang) 2015/09/03 00:44:28 Done.
998 if (representedType != const DynamicType()) {
999 lookupMapAnalysis.registerTypeConstant(representedType.element);
1000 }
978 } 1001 }
979 } 1002 }
980 1003
981 void registerInstantiatedConstantType(DartType type, Registry registry) { 1004 void registerInstantiatedConstantType(DartType type, Registry registry) {
982 DartType instantiatedType = 1005 DartType instantiatedType =
983 type.isFunctionType ? compiler.functionClass.rawType : type; 1006 type.isFunctionType ? compiler.functionClass.rawType : type;
984 if (type is InterfaceType) { 1007 if (type is InterfaceType) {
985 registry.registerInstantiation(instantiatedType); 1008 registry.registerInstantiation(instantiatedType);
986 if (!type.treatAsRaw && classNeedsRti(type.element)) { 1009 if (!type.treatAsRaw && classNeedsRti(type.element)) {
987 registry.registerStaticInvocation(getSetRuntimeTypeInfo()); 1010 registry.registerStaticInvocation(getSetRuntimeTypeInfo());
988 } 1011 }
989 if (type.element == typeImplementation) { 1012 if (type.element == typeImplementation) {
990 // If we use a type literal in a constant, the compile time 1013 // If we use a type literal in a constant, the compile time
991 // constant emitter will generate a call to the createRuntimeType 1014 // constant emitter will generate a call to the createRuntimeType
992 // helper so we register a use of that. 1015 // helper so we register a use of that.
993 registry.registerStaticInvocation(getCreateRuntimeType()); 1016 registry.registerStaticInvocation(getCreateRuntimeType());
994 } 1017 }
995 } 1018 }
996 } 1019 }
997 1020
998 void registerMetadataConstant(MetadataAnnotation metadata, 1021 void registerMetadataConstant(MetadataAnnotation metadata,
999 Element annotatedElement, 1022 Element annotatedElement,
1000 Registry registry) { 1023 Registry registry) {
1001 assert(registry.isForResolution); 1024 assert(registry.isForResolution);
1002 ConstantValue constant = constants.getConstantValueForMetadata(metadata); 1025 ConstantValue constant = constants.getConstantValueForMetadata(metadata);
1003 registerCompileTimeConstant(constant, registry); 1026 registerCompileTimeConstant(constant, registry, addForEmission: false);
1004 metadataConstants.add(new Dependency(constant, annotatedElement)); 1027 metadataConstants.add(new Dependency(constant, annotatedElement));
1005 } 1028 }
1006 1029
1007 void registerInstantiatedClass(ClassElement cls, 1030 void registerInstantiatedClass(ClassElement cls,
1008 Enqueuer enqueuer, 1031 Enqueuer enqueuer,
1009 Registry registry) { 1032 Registry registry) {
1010 if (!cls.typeVariables.isEmpty) { 1033 if (!cls.typeVariables.isEmpty) {
1011 typeVariableHandler.registerClassWithTypeVariables(cls, enqueuer, 1034 typeVariableHandler.registerClassWithTypeVariables(cls, enqueuer,
1012 registry); 1035 registry);
1013 } 1036 }
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1126 } else if (Elements.isNativeOrExtendsNative(cls)) { 1149 } else if (Elements.isNativeOrExtendsNative(cls)) {
1127 addInterceptorsForNativeClassMembers(cls, enqueuer); 1150 addInterceptorsForNativeClassMembers(cls, enqueuer);
1128 } else if (cls == jsIndexingBehaviorInterface) { 1151 } else if (cls == jsIndexingBehaviorInterface) {
1129 // These two helpers are used by the emitter and the codegen. 1152 // These two helpers are used by the emitter and the codegen.
1130 // Because we cannot enqueue elements at the time of emission, 1153 // Because we cannot enqueue elements at the time of emission,
1131 // we make sure they are always generated. 1154 // we make sure they are always generated.
1132 enqueue(enqueuer, findHelper('isJsIndexable'), registry); 1155 enqueue(enqueuer, findHelper('isJsIndexable'), registry);
1133 } 1156 }
1134 1157
1135 customElementsAnalysis.registerInstantiatedClass(cls, enqueuer); 1158 customElementsAnalysis.registerInstantiatedClass(cls, enqueuer);
1159 if (!enqueuer.isResolutionQueue) {
1160 lookupMapAnalysis.registerInstantiatedClass(cls);
1161 }
1162 }
1163
1164 void registerInstantiatedType(InterfaceType type, Registry registry) {
1165 lookupMapAnalysis.registerInstantiatedType(type, registry);
1136 } 1166 }
1137 1167
1138 void registerUseInterceptor(Enqueuer enqueuer) { 1168 void registerUseInterceptor(Enqueuer enqueuer) {
1139 assert(!enqueuer.isResolutionQueue); 1169 assert(!enqueuer.isResolutionQueue);
1140 if (!enqueuer.nativeEnqueuer.hasInstantiatedNativeClasses()) return; 1170 if (!enqueuer.nativeEnqueuer.hasInstantiatedNativeClasses()) return;
1141 Registry registry = compiler.globalDependencies; 1171 Registry registry = compiler.globalDependencies;
1142 enqueue(enqueuer, getNativeInterceptorMethod, registry); 1172 enqueue(enqueuer, getNativeInterceptorMethod, registry);
1143 enqueueClass(enqueuer, jsPlainJavaScriptObjectClass, registry); 1173 enqueueClass(enqueuer, jsPlainJavaScriptObjectClass, registry);
1144 needToInitializeIsolateAffinityTag = true; 1174 needToInitializeIsolateAffinityTag = true;
1145 needToInitializeDispatchProperty = true; 1175 needToInitializeDispatchProperty = true;
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 } 1465 }
1436 if (element.isConstructor && element.enclosingClass == jsNullClass) { 1466 if (element.isConstructor && element.enclosingClass == jsNullClass) {
1437 // Work around a problem compiling JSNull's constructor. 1467 // Work around a problem compiling JSNull's constructor.
1438 return const WorldImpact(); 1468 return const WorldImpact();
1439 } 1469 }
1440 if (kind.category == ElementCategory.VARIABLE) { 1470 if (kind.category == ElementCategory.VARIABLE) {
1441 ConstantValue initialValue = 1471 ConstantValue initialValue =
1442 constants.getConstantValueForVariable(element); 1472 constants.getConstantValueForVariable(element);
1443 if (initialValue != null) { 1473 if (initialValue != null) {
1444 registerCompileTimeConstant(initialValue, work.registry); 1474 registerCompileTimeConstant(initialValue, work.registry);
1445 constants.addCompileTimeConstantForEmission(initialValue);
1446 // We don't need to generate code for static or top-level 1475 // We don't need to generate code for static or top-level
1447 // variables. For instance variables, we may need to generate 1476 // variables. For instance variables, we may need to generate
1448 // the checked setter. 1477 // the checked setter.
1449 if (Elements.isStaticOrTopLevel(element)) { 1478 if (Elements.isStaticOrTopLevel(element)) {
1450 return const WorldImpact(); 1479 return const WorldImpact();
1451 } 1480 }
1452 } else { 1481 } else {
1453 // If the constant-handler was not able to produce a result we have to 1482 // If the constant-handler was not able to produce a result we have to
1454 // go through the builder (below) to generate the lazy initializer for 1483 // go through the builder (below) to generate the lazy initializer for
1455 // the static variable. 1484 // the static variable.
(...skipping 674 matching lines...) Expand 10 before | Expand all | Expand 10 after
2130 preserveMetadataMarker = find(library, 'preserveMetadata'); 2159 preserveMetadataMarker = find(library, 'preserveMetadata');
2131 preserveUrisMarker = find(library, 'preserveUris'); 2160 preserveUrisMarker = find(library, 'preserveUris');
2132 preserveLibraryNamesMarker = find(library, 'preserveLibraryNames'); 2161 preserveLibraryNamesMarker = find(library, 'preserveLibraryNames');
2133 } else if (uri == DART_JS_NAMES) { 2162 } else if (uri == DART_JS_NAMES) {
2134 preserveNamesMarker = find(library, 'preserveNames'); 2163 preserveNamesMarker = find(library, 'preserveNames');
2135 } else if (uri == DART_EMBEDDED_NAMES) { 2164 } else if (uri == DART_EMBEDDED_NAMES) {
2136 jsGetNameEnum = find(library, 'JsGetName'); 2165 jsGetNameEnum = find(library, 'JsGetName');
2137 jsBuiltinEnum = find(library, 'JsBuiltin'); 2166 jsBuiltinEnum = find(library, 'JsBuiltin');
2138 } else if (uri == DART_HTML) { 2167 } else if (uri == DART_HTML) {
2139 htmlLibraryIsLoaded = true; 2168 htmlLibraryIsLoaded = true;
2169 } else if (uri == PACKAGE_LOOKUP_MAP) {
2170 lookupMapAnalysis.initRuntimeClass(find(library, 'LookupMap'));
2140 } 2171 }
2141 annotations.onLibraryScanned(library); 2172 annotations.onLibraryScanned(library);
2142 }); 2173 });
2143 } 2174 }
2144 2175
2145 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { 2176 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) {
2146 if (!loadedLibraries.containsLibrary(Compiler.DART_CORE)) { 2177 if (!loadedLibraries.containsLibrary(Compiler.DART_CORE)) {
2147 return new Future.value(); 2178 return new Future.value();
2148 } 2179 }
2149 2180
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
2523 } 2554 }
2524 } 2555 }
2525 return staticFields; 2556 return staticFields;
2526 } 2557 }
2527 2558
2528 /// Called when [enqueuer] is empty, but before it is closed. 2559 /// Called when [enqueuer] is empty, but before it is closed.
2529 bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassElement> recentClasses) { 2560 bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassElement> recentClasses) {
2530 // Add elements referenced only via custom elements. Return early if any 2561 // Add elements referenced only via custom elements. Return early if any
2531 // elements are added to avoid counting the elements as due to mirrors. 2562 // elements are added to avoid counting the elements as due to mirrors.
2532 customElementsAnalysis.onQueueEmpty(enqueuer); 2563 customElementsAnalysis.onQueueEmpty(enqueuer);
2564 lookupMapAnalysis.onQueueEmpty(enqueuer);
2533 if (!enqueuer.queueIsEmpty) return false; 2565 if (!enqueuer.queueIsEmpty) return false;
2534 2566
2535 noSuchMethodRegistry.onQueueEmpty(); 2567 noSuchMethodRegistry.onQueueEmpty();
2536 if (!enabledNoSuchMethod && 2568 if (!enabledNoSuchMethod &&
2537 (noSuchMethodRegistry.hasThrowingNoSuchMethod || 2569 (noSuchMethodRegistry.hasThrowingNoSuchMethod ||
2538 noSuchMethodRegistry.hasComplexNoSuchMethod)) { 2570 noSuchMethodRegistry.hasComplexNoSuchMethod)) {
2539 enableNoSuchMethod(enqueuer); 2571 enableNoSuchMethod(enqueuer);
2540 enabledNoSuchMethod = true; 2572 enabledNoSuchMethod = true;
2541 } 2573 }
2542 2574
(...skipping 23 matching lines...) Expand all
2566 2598
2567 if (mustRetainMetadata) { 2599 if (mustRetainMetadata) {
2568 compiler.log('Retaining metadata.'); 2600 compiler.log('Retaining metadata.');
2569 2601
2570 compiler.libraryLoader.libraries.forEach(retainMetadataOf); 2602 compiler.libraryLoader.libraries.forEach(retainMetadataOf);
2571 if (!enqueuer.isResolutionQueue) { 2603 if (!enqueuer.isResolutionQueue) {
2572 for (Dependency dependency in metadataConstants) { 2604 for (Dependency dependency in metadataConstants) {
2573 registerCompileTimeConstant( 2605 registerCompileTimeConstant(
2574 dependency.constant, 2606 dependency.constant,
2575 new CodegenRegistry(compiler, 2607 new CodegenRegistry(compiler,
2576 dependency.annotatedElement.analyzableElement.treeElements)); 2608 dependency.annotatedElement.analyzableElement.treeElements),
2609 addForEmission: false);
2577 } 2610 }
2578 metadataConstants.clear(); 2611 metadataConstants.clear();
2579 } 2612 }
2580 } 2613 }
2581 return true; 2614 return true;
2582 } 2615 }
2583 2616
2584 void onElementResolved(Element element, TreeElements elements) { 2617 void onElementResolved(Element element, TreeElements elements) {
2585 if ((element.isFunction || element.isGenerativeConstructor) && 2618 if ((element.isFunction || element.isGenerativeConstructor) &&
2586 annotations.noInline(element)) { 2619 annotations.noInline(element)) {
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after
3090 } 3123 }
3091 } 3124 }
3092 3125
3093 /// Records that [constant] is used by the element behind [registry]. 3126 /// Records that [constant] is used by the element behind [registry].
3094 class Dependency { 3127 class Dependency {
3095 final ConstantValue constant; 3128 final ConstantValue constant;
3096 final Element annotatedElement; 3129 final Element annotatedElement;
3097 3130
3098 const Dependency(this.constant, this.annotatedElement); 3131 const Dependency(this.constant, this.annotatedElement);
3099 } 3132 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698