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

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

Issue 2494093002: Refactor enqueuers (Closed)
Patch Set: Updated cf. comments. Created 4 years, 1 month 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
« no previous file with comments | « pkg/compiler/lib/src/enqueue.dart ('k') | pkg/compiler/lib/src/js_backend/enqueuer.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 js_backend.backend; 5 library js_backend.backend;
6 6
7 import 'dart:async' show Future; 7 import 'dart:async' show Future;
8 8
9 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; 9 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames;
10 10
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 import 'backend_helpers.dart'; 67 import 'backend_helpers.dart';
68 import 'backend_impact.dart'; 68 import 'backend_impact.dart';
69 import 'backend_serialization.dart' show JavaScriptBackendSerialization; 69 import 'backend_serialization.dart' show JavaScriptBackendSerialization;
70 import 'checked_mode_helpers.dart'; 70 import 'checked_mode_helpers.dart';
71 import 'constant_handler_javascript.dart'; 71 import 'constant_handler_javascript.dart';
72 import 'custom_elements_analysis.dart'; 72 import 'custom_elements_analysis.dart';
73 import 'enqueuer.dart'; 73 import 'enqueuer.dart';
74 import 'js_interop_analysis.dart' show JsInteropAnalysis; 74 import 'js_interop_analysis.dart' show JsInteropAnalysis;
75 import '../kernel/task.dart'; 75 import '../kernel/task.dart';
76 import 'lookup_map_analysis.dart' show LookupMapAnalysis; 76 import 'lookup_map_analysis.dart' show LookupMapAnalysis;
77 import 'mirrors_analysis.dart';
77 import 'namer.dart'; 78 import 'namer.dart';
78 import 'native_data.dart' show NativeData; 79 import 'native_data.dart' show NativeData;
79 import 'no_such_method_registry.dart'; 80 import 'no_such_method_registry.dart';
80 import 'patch_resolver.dart'; 81 import 'patch_resolver.dart';
81 import 'type_variable_handler.dart'; 82 import 'type_variable_handler.dart';
82 83
83 part 'runtime_types.dart'; 84 part 'runtime_types.dart';
84 85
85 const VERBOSE_OPTIMIZER_HINTS = false; 86 const VERBOSE_OPTIMIZER_HINTS = false;
86 87
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 566
566 /// Codegen support for tree-shaking entries of `LookupMap`. 567 /// Codegen support for tree-shaking entries of `LookupMap`.
567 LookupMapAnalysis lookupMapAnalysis; 568 LookupMapAnalysis lookupMapAnalysis;
568 569
569 /// Codegen support for typed JavaScript interop. 570 /// Codegen support for typed JavaScript interop.
570 JsInteropAnalysis jsInteropAnalysis; 571 JsInteropAnalysis jsInteropAnalysis;
571 572
572 /// Support for classifying `noSuchMethod` implementations. 573 /// Support for classifying `noSuchMethod` implementations.
573 NoSuchMethodRegistry noSuchMethodRegistry; 574 NoSuchMethodRegistry noSuchMethodRegistry;
574 575
576 /// Resolution and codegen support for computing reflectable elements.
577 MirrorsAnalysis mirrorsAnalysis;
578
575 /// Builds kernel representation for the program. 579 /// Builds kernel representation for the program.
576 KernelTask kernelTask; 580 KernelTask kernelTask;
577 581
578 JavaScriptConstantTask constantCompilerTask; 582 JavaScriptConstantTask constantCompilerTask;
579 583
580 JavaScriptImpactTransformer impactTransformer; 584 JavaScriptImpactTransformer impactTransformer;
581 585
582 PatchResolverTask patchResolverTask; 586 PatchResolverTask patchResolverTask;
583 587
584 bool enabledNoSuchMethod = false; 588 bool enabledNoSuchMethod = false;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 helpers = new BackendHelpers(compiler), 625 helpers = new BackendHelpers(compiler),
622 impacts = new BackendImpacts(compiler), 626 impacts = new BackendImpacts(compiler),
623 frontend = new JSFrontendAccess(compiler), 627 frontend = new JSFrontendAccess(compiler),
624 super(compiler) { 628 super(compiler) {
625 emitter = new CodeEmitterTask( 629 emitter = new CodeEmitterTask(
626 compiler, namer, generateSourceMap, useStartupEmitter); 630 compiler, namer, generateSourceMap, useStartupEmitter);
627 typeVariableHandler = new TypeVariableHandler(compiler); 631 typeVariableHandler = new TypeVariableHandler(compiler);
628 customElementsAnalysis = new CustomElementsAnalysis(this); 632 customElementsAnalysis = new CustomElementsAnalysis(this);
629 lookupMapAnalysis = new LookupMapAnalysis(this, reporter); 633 lookupMapAnalysis = new LookupMapAnalysis(this, reporter);
630 jsInteropAnalysis = new JsInteropAnalysis(this); 634 jsInteropAnalysis = new JsInteropAnalysis(this);
635 mirrorsAnalysis = new MirrorsAnalysis(this, compiler.resolution);
631 636
632 noSuchMethodRegistry = new NoSuchMethodRegistry(this); 637 noSuchMethodRegistry = new NoSuchMethodRegistry(this);
633 kernelTask = new KernelTask(compiler); 638 kernelTask = new KernelTask(compiler);
634 constantCompilerTask = new JavaScriptConstantTask(compiler); 639 constantCompilerTask = new JavaScriptConstantTask(compiler);
635 impactTransformer = new JavaScriptImpactTransformer(this); 640 impactTransformer = new JavaScriptImpactTransformer(this);
636 patchResolverTask = new PatchResolverTask(compiler); 641 patchResolverTask = new PatchResolverTask(compiler);
637 functionCompiler = 642 functionCompiler =
638 new SsaFunctionCompiler(this, sourceInformationStrategy, useKernel); 643 new SsaFunctionCompiler(this, sourceInformationStrategy, useKernel);
639 serialization = new JavaScriptBackendSerialization(this); 644 serialization = new JavaScriptBackendSerialization(this);
640 backendClasses = new JavaScriptBackendClasses(helpers); 645 backendClasses = new JavaScriptBackendClasses(helpers);
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
1046 // Walk superclass chain to find mixins. 1051 // Walk superclass chain to find mixins.
1047 for (; cls != null; cls = cls.superclass) { 1052 for (; cls != null; cls = cls.superclass) {
1048 if (cls.isMixinApplication) { 1053 if (cls.isMixinApplication) {
1049 MixinApplicationElement mixinApplication = cls; 1054 MixinApplicationElement mixinApplication = cls;
1050 classesMixedIntoInterceptedClasses.add(mixinApplication.mixin); 1055 classesMixedIntoInterceptedClasses.add(mixinApplication.mixin);
1051 } 1056 }
1052 } 1057 }
1053 } 1058 }
1054 } 1059 }
1055 1060
1056 void addInterceptors(ClassElement cls, Enqueuer enqueuer, Registry registry) { 1061 void addInterceptors(ClassElement cls, Enqueuer enqueuer) {
1057 if (enqueuer.isResolutionQueue) { 1062 if (enqueuer.isResolutionQueue) {
1058 _interceptedClasses.add(helpers.jsInterceptorClass); 1063 _interceptedClasses.add(helpers.jsInterceptorClass);
1059 _interceptedClasses.add(cls); 1064 _interceptedClasses.add(cls);
1060 cls.ensureResolved(resolution); 1065 cls.ensureResolved(resolution);
1061 cls.forEachMember((ClassElement classElement, Element member) { 1066 cls.forEachMember((ClassElement classElement, Element member) {
1062 // All methods on [Object] are shadowed by [Interceptor]. 1067 // All methods on [Object] are shadowed by [Interceptor].
1063 if (classElement == coreClasses.objectClass) return; 1068 if (classElement == coreClasses.objectClass) return;
1064 Set<Element> set = interceptedElements.putIfAbsent( 1069 Set<Element> set = interceptedElements.putIfAbsent(
1065 member.name, () => new Set<Element>()); 1070 member.name, () => new Set<Element>());
1066 set.add(member); 1071 set.add(member);
1067 }, includeSuperAndInjectedMembers: true); 1072 }, includeSuperAndInjectedMembers: true);
1068 } 1073 }
1069 enqueueClass(enqueuer, cls, registry); 1074 enqueueClass(enqueuer, cls);
1070 } 1075 }
1071 1076
1072 Set<ClassElement> get interceptedClasses { 1077 Set<ClassElement> get interceptedClasses {
1073 assert(compiler.enqueuer.resolution.queueIsClosed); 1078 assert(compiler.enqueuer.resolution.queueIsClosed);
1074 return _interceptedClasses; 1079 return _interceptedClasses;
1075 } 1080 }
1076 1081
1077 void registerSpecializedGetInterceptor(Set<ClassElement> classes) { 1082 void registerSpecializedGetInterceptor(Set<ClassElement> classes) {
1078 jsAst.Name name = namer.nameForGetInterceptor(classes); 1083 jsAst.Name name = namer.nameForGetInterceptor(classes);
1079 if (classes.contains(helpers.jsInterceptorClass)) { 1084 if (classes.contains(helpers.jsInterceptorClass)) {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1152 // constant emitter will generate a call to the createRuntimeType 1157 // constant emitter will generate a call to the createRuntimeType
1153 // helper so we register a use of that. 1158 // helper so we register a use of that.
1154 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( 1159 impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
1155 // TODO(johnniwinther): Find the right [CallStructure]. 1160 // TODO(johnniwinther): Find the right [CallStructure].
1156 helpers.createRuntimeType, 1161 helpers.createRuntimeType,
1157 null)); 1162 null));
1158 } 1163 }
1159 } 1164 }
1160 } 1165 }
1161 1166
1162 void registerInstantiatedClass( 1167 void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) {
1163 ClassElement cls, Enqueuer enqueuer, Registry registry) { 1168 _processClass(cls, enqueuer);
1164 _processClass(cls, enqueuer, registry);
1165 } 1169 }
1166 1170
1167 void registerImplementedClass( 1171 void registerImplementedClass(ClassElement cls, Enqueuer enqueuer) {
1168 ClassElement cls, Enqueuer enqueuer, Registry registry) { 1172 _processClass(cls, enqueuer);
1169 _processClass(cls, enqueuer, registry);
1170 } 1173 }
1171 1174
1172 void _processClass(ClassElement cls, Enqueuer enqueuer, Registry registry) { 1175 void _processClass(ClassElement cls, Enqueuer enqueuer) {
1173 if (!cls.typeVariables.isEmpty) { 1176 if (!cls.typeVariables.isEmpty) {
1174 typeVariableHandler.registerClassWithTypeVariables( 1177 typeVariableHandler.registerClassWithTypeVariables(cls, enqueuer);
1175 cls, enqueuer, registry);
1176 } 1178 }
1177 1179
1178 // Register any helper that will be needed by the backend. 1180 // Register any helper that will be needed by the backend.
1179 if (enqueuer.isResolutionQueue) { 1181 if (enqueuer.isResolutionQueue) {
1180 if (cls == coreClasses.intClass || 1182 if (cls == coreClasses.intClass ||
1181 cls == coreClasses.doubleClass || 1183 cls == coreClasses.doubleClass ||
1182 cls == coreClasses.numClass) { 1184 cls == coreClasses.numClass) {
1183 // The backend will try to optimize number operations and use the 1185 // The backend will try to optimize number operations and use the
1184 // `iae` helper directly. 1186 // `iae` helper directly.
1185 enqueue(enqueuer, helpers.throwIllegalArgumentException, registry); 1187 enqueue(enqueuer, helpers.throwIllegalArgumentException);
1186 } else if (cls == coreClasses.listClass || 1188 } else if (cls == coreClasses.listClass ||
1187 cls == coreClasses.stringClass) { 1189 cls == coreClasses.stringClass) {
1188 // The backend will try to optimize array and string access and use the 1190 // The backend will try to optimize array and string access and use the
1189 // `ioore` and `iae` helpers directly. 1191 // `ioore` and `iae` helpers directly.
1190 enqueue(enqueuer, helpers.throwIndexOutOfRangeException, registry); 1192 enqueue(enqueuer, helpers.throwIndexOutOfRangeException);
1191 enqueue(enqueuer, helpers.throwIllegalArgumentException, registry); 1193 enqueue(enqueuer, helpers.throwIllegalArgumentException);
1192 } else if (cls == coreClasses.functionClass) { 1194 } else if (cls == coreClasses.functionClass) {
1193 enqueueClass(enqueuer, helpers.closureClass, registry); 1195 enqueueClass(enqueuer, helpers.closureClass);
1194 } else if (cls == coreClasses.mapClass) { 1196 } else if (cls == coreClasses.mapClass) {
1195 // The backend will use a literal list to initialize the entries 1197 // The backend will use a literal list to initialize the entries
1196 // of the map. 1198 // of the map.
1197 enqueueClass(enqueuer, coreClasses.listClass, registry); 1199 enqueueClass(enqueuer, coreClasses.listClass);
1198 enqueueClass(enqueuer, helpers.mapLiteralClass, registry); 1200 enqueueClass(enqueuer, helpers.mapLiteralClass);
1199 // For map literals, the dependency between the implementation class 1201 // For map literals, the dependency between the implementation class
1200 // and [Map] is not visible, so we have to add it manually. 1202 // and [Map] is not visible, so we have to add it manually.
1201 rti.registerRtiDependency(helpers.mapLiteralClass, cls); 1203 rti.registerRtiDependency(helpers.mapLiteralClass, cls);
1202 } else if (cls == helpers.boundClosureClass) { 1204 } else if (cls == helpers.boundClosureClass) {
1203 // TODO(johnniwinther): Is this a noop? 1205 // TODO(johnniwinther): Is this a noop?
1204 enqueueClass(enqueuer, helpers.boundClosureClass, registry); 1206 enqueueClass(enqueuer, helpers.boundClosureClass);
1205 } else if (isNativeOrExtendsNative(cls)) { 1207 } else if (isNativeOrExtendsNative(cls)) {
1206 enqueue(enqueuer, helpers.getNativeInterceptorMethod, registry); 1208 enqueue(enqueuer, helpers.getNativeInterceptorMethod);
1207 enqueueClass( 1209 enqueueClass(enqueuer, helpers.jsInterceptorClass);
1208 enqueuer, helpers.jsInterceptorClass, compiler.globalDependencies); 1210 enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass);
1209 enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass, registry); 1211 enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass);
1210 enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass, registry); 1212 enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass);
1211 enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass, registry);
1212 } else if (cls == helpers.mapLiteralClass) { 1213 } else if (cls == helpers.mapLiteralClass) {
1213 // For map literals, the dependency between the implementation class 1214 // For map literals, the dependency between the implementation class
1214 // and [Map] is not visible, so we have to add it manually. 1215 // and [Map] is not visible, so we have to add it manually.
1215 Element getFactory(String name, int arity) { 1216 Element getFactory(String name, int arity) {
1216 // The constructor is on the patch class, but dart2js unit tests don't 1217 // The constructor is on the patch class, but dart2js unit tests don't
1217 // have a patch class. 1218 // have a patch class.
1218 ClassElement implementation = cls.implementation; 1219 ClassElement implementation = cls.implementation;
1219 ConstructorElement ctor = implementation.lookupConstructor(name); 1220 ConstructorElement ctor = implementation.lookupConstructor(name);
1220 if (ctor == null || 1221 if (ctor == null ||
1221 (Name.isPrivateName(name) && 1222 (Name.isPrivateName(name) &&
(...skipping 16 matching lines...) Expand all
1238 reporter.internalError( 1239 reporter.internalError(
1239 helpers.mapLiteralClass, 1240 helpers.mapLiteralClass,
1240 "Map literal class ${helpers.mapLiteralClass} missing " 1241 "Map literal class ${helpers.mapLiteralClass} missing "
1241 "'$name' static member function"); 1242 "'$name' static member function");
1242 } 1243 }
1243 return element; 1244 return element;
1244 } 1245 }
1245 1246
1246 helpers.mapLiteralConstructor = getFactory('_literal', 1); 1247 helpers.mapLiteralConstructor = getFactory('_literal', 1);
1247 helpers.mapLiteralConstructorEmpty = getFactory('_empty', 0); 1248 helpers.mapLiteralConstructorEmpty = getFactory('_empty', 0);
1248 enqueueInResolution(helpers.mapLiteralConstructor, registry); 1249 enqueue(enqueuer, helpers.mapLiteralConstructor);
1249 enqueueInResolution(helpers.mapLiteralConstructorEmpty, registry); 1250 enqueue(enqueuer, helpers.mapLiteralConstructorEmpty);
1250 1251
1251 helpers.mapLiteralUntypedMaker = getMember('_makeLiteral'); 1252 helpers.mapLiteralUntypedMaker = getMember('_makeLiteral');
1252 helpers.mapLiteralUntypedEmptyMaker = getMember('_makeEmpty'); 1253 helpers.mapLiteralUntypedEmptyMaker = getMember('_makeEmpty');
1253 enqueueInResolution(helpers.mapLiteralUntypedMaker, registry); 1254 enqueue(enqueuer, helpers.mapLiteralUntypedMaker);
1254 enqueueInResolution(helpers.mapLiteralUntypedEmptyMaker, registry); 1255 enqueue(enqueuer, helpers.mapLiteralUntypedEmptyMaker);
1255 } 1256 }
1256 } 1257 }
1257 if (cls == helpers.closureClass) { 1258 if (cls == helpers.closureClass) {
1258 enqueue(enqueuer, helpers.closureFromTearOff, registry); 1259 enqueue(enqueuer, helpers.closureFromTearOff);
1259 } 1260 }
1260 if (cls == coreClasses.stringClass || cls == helpers.jsStringClass) { 1261 if (cls == coreClasses.stringClass || cls == helpers.jsStringClass) {
1261 addInterceptors(helpers.jsStringClass, enqueuer, registry); 1262 addInterceptors(helpers.jsStringClass, enqueuer);
1262 } else if (cls == coreClasses.listClass || 1263 } else if (cls == coreClasses.listClass ||
1263 cls == helpers.jsArrayClass || 1264 cls == helpers.jsArrayClass ||
1264 cls == helpers.jsFixedArrayClass || 1265 cls == helpers.jsFixedArrayClass ||
1265 cls == helpers.jsExtendableArrayClass || 1266 cls == helpers.jsExtendableArrayClass ||
1266 cls == helpers.jsUnmodifiableArrayClass) { 1267 cls == helpers.jsUnmodifiableArrayClass) {
1267 addInterceptors(helpers.jsArrayClass, enqueuer, registry); 1268 addInterceptors(helpers.jsArrayClass, enqueuer);
1268 addInterceptors(helpers.jsMutableArrayClass, enqueuer, registry); 1269 addInterceptors(helpers.jsMutableArrayClass, enqueuer);
1269 addInterceptors(helpers.jsFixedArrayClass, enqueuer, registry); 1270 addInterceptors(helpers.jsFixedArrayClass, enqueuer);
1270 addInterceptors(helpers.jsExtendableArrayClass, enqueuer, registry); 1271 addInterceptors(helpers.jsExtendableArrayClass, enqueuer);
1271 addInterceptors(helpers.jsUnmodifiableArrayClass, enqueuer, registry); 1272 addInterceptors(helpers.jsUnmodifiableArrayClass, enqueuer);
1272 // Literal lists can be translated into calls to these functions: 1273 if (enqueuer.isResolutionQueue) {
1273 enqueueInResolution(helpers.jsArrayTypedConstructor, registry); 1274 // Literal lists can be translated into calls to these functions:
1274 enqueueInResolution(helpers.setRuntimeTypeInfo, registry); 1275 enqueue(enqueuer, helpers.jsArrayTypedConstructor);
1275 enqueueInResolution(helpers.getTypeArgumentByIndex, registry); 1276 enqueue(enqueuer, helpers.setRuntimeTypeInfo);
1277 enqueue(enqueuer, helpers.getTypeArgumentByIndex);
1278 }
1276 } else if (cls == coreClasses.intClass || cls == helpers.jsIntClass) { 1279 } else if (cls == coreClasses.intClass || cls == helpers.jsIntClass) {
1277 addInterceptors(helpers.jsIntClass, enqueuer, registry); 1280 addInterceptors(helpers.jsIntClass, enqueuer);
1278 addInterceptors(helpers.jsPositiveIntClass, enqueuer, registry); 1281 addInterceptors(helpers.jsPositiveIntClass, enqueuer);
1279 addInterceptors(helpers.jsUInt32Class, enqueuer, registry); 1282 addInterceptors(helpers.jsUInt32Class, enqueuer);
1280 addInterceptors(helpers.jsUInt31Class, enqueuer, registry); 1283 addInterceptors(helpers.jsUInt31Class, enqueuer);
1281 addInterceptors(helpers.jsNumberClass, enqueuer, registry); 1284 addInterceptors(helpers.jsNumberClass, enqueuer);
1282 } else if (cls == coreClasses.doubleClass || cls == helpers.jsDoubleClass) { 1285 } else if (cls == coreClasses.doubleClass || cls == helpers.jsDoubleClass) {
1283 addInterceptors(helpers.jsDoubleClass, enqueuer, registry); 1286 addInterceptors(helpers.jsDoubleClass, enqueuer);
1284 addInterceptors(helpers.jsNumberClass, enqueuer, registry); 1287 addInterceptors(helpers.jsNumberClass, enqueuer);
1285 } else if (cls == coreClasses.boolClass || cls == helpers.jsBoolClass) { 1288 } else if (cls == coreClasses.boolClass || cls == helpers.jsBoolClass) {
1286 addInterceptors(helpers.jsBoolClass, enqueuer, registry); 1289 addInterceptors(helpers.jsBoolClass, enqueuer);
1287 } else if (cls == coreClasses.nullClass || cls == helpers.jsNullClass) { 1290 } else if (cls == coreClasses.nullClass || cls == helpers.jsNullClass) {
1288 addInterceptors(helpers.jsNullClass, enqueuer, registry); 1291 addInterceptors(helpers.jsNullClass, enqueuer);
1289 } else if (cls == coreClasses.numClass || cls == helpers.jsNumberClass) { 1292 } else if (cls == coreClasses.numClass || cls == helpers.jsNumberClass) {
1290 addInterceptors(helpers.jsIntClass, enqueuer, registry); 1293 addInterceptors(helpers.jsIntClass, enqueuer);
1291 addInterceptors(helpers.jsPositiveIntClass, enqueuer, registry); 1294 addInterceptors(helpers.jsPositiveIntClass, enqueuer);
1292 addInterceptors(helpers.jsUInt32Class, enqueuer, registry); 1295 addInterceptors(helpers.jsUInt32Class, enqueuer);
1293 addInterceptors(helpers.jsUInt31Class, enqueuer, registry); 1296 addInterceptors(helpers.jsUInt31Class, enqueuer);
1294 addInterceptors(helpers.jsDoubleClass, enqueuer, registry); 1297 addInterceptors(helpers.jsDoubleClass, enqueuer);
1295 addInterceptors(helpers.jsNumberClass, enqueuer, registry); 1298 addInterceptors(helpers.jsNumberClass, enqueuer);
1296 } else if (cls == helpers.jsJavaScriptObjectClass) { 1299 } else if (cls == helpers.jsJavaScriptObjectClass) {
1297 addInterceptors(helpers.jsJavaScriptObjectClass, enqueuer, registry); 1300 addInterceptors(helpers.jsJavaScriptObjectClass, enqueuer);
1298 } else if (cls == helpers.jsPlainJavaScriptObjectClass) { 1301 } else if (cls == helpers.jsPlainJavaScriptObjectClass) {
1299 addInterceptors(helpers.jsPlainJavaScriptObjectClass, enqueuer, registry); 1302 addInterceptors(helpers.jsPlainJavaScriptObjectClass, enqueuer);
1300 } else if (cls == helpers.jsUnknownJavaScriptObjectClass) { 1303 } else if (cls == helpers.jsUnknownJavaScriptObjectClass) {
1301 addInterceptors( 1304 addInterceptors(helpers.jsUnknownJavaScriptObjectClass, enqueuer);
1302 helpers.jsUnknownJavaScriptObjectClass, enqueuer, registry);
1303 } else if (cls == helpers.jsJavaScriptFunctionClass) { 1305 } else if (cls == helpers.jsJavaScriptFunctionClass) {
1304 addInterceptors(helpers.jsJavaScriptFunctionClass, enqueuer, registry); 1306 addInterceptors(helpers.jsJavaScriptFunctionClass, enqueuer);
1305 } else if (isNativeOrExtendsNative(cls)) { 1307 } else if (isNativeOrExtendsNative(cls)) {
1306 addInterceptorsForNativeClassMembers(cls, enqueuer); 1308 addInterceptorsForNativeClassMembers(cls, enqueuer);
1307 } else if (cls == helpers.jsIndexingBehaviorInterface) { 1309 } else if (cls == helpers.jsIndexingBehaviorInterface) {
1308 // These two helpers are used by the emitter and the codegen. 1310 // These two helpers are used by the emitter and the codegen.
1309 // Because we cannot enqueue elements at the time of emission, 1311 // Because we cannot enqueue elements at the time of emission,
1310 // we make sure they are always generated. 1312 // we make sure they are always generated.
1311 enqueue(enqueuer, helpers.isJsIndexable, registry); 1313 enqueue(enqueuer, helpers.isJsIndexable);
1312 } 1314 }
1313 1315
1314 customElementsAnalysis.registerInstantiatedClass(cls, 1316 customElementsAnalysis.registerInstantiatedClass(cls,
1315 forResolution: enqueuer.isResolutionQueue); 1317 forResolution: enqueuer.isResolutionQueue);
1316 if (!enqueuer.isResolutionQueue) { 1318 if (!enqueuer.isResolutionQueue) {
1317 lookupMapAnalysis.registerInstantiatedClass(cls); 1319 lookupMapAnalysis.registerInstantiatedClass(cls);
1318 } 1320 }
1319 } 1321 }
1320 1322
1321 void registerInstantiatedType( 1323 void registerInstantiatedType(InterfaceType type) {
1322 InterfaceType type, Enqueuer enqueuer, Registry registry,
1323 {bool mirrorUsage: false}) {
1324 lookupMapAnalysis.registerInstantiatedType(type); 1324 lookupMapAnalysis.registerInstantiatedType(type);
1325 super.registerInstantiatedType(type, enqueuer, registry,
1326 mirrorUsage: mirrorUsage);
1327 } 1325 }
1328 1326
1329 void enqueueHelpers(ResolutionEnqueuer world, Registry registry) { 1327 void enqueueHelpers(ResolutionEnqueuer enqueuer) {
1330 assert(helpers.interceptorsLibrary != null); 1328 assert(helpers.interceptorsLibrary != null);
1331 // TODO(ngeoffray): Not enqueuing those two classes currently make 1329 // TODO(ngeoffray): Not enqueuing those two classes currently make
1332 // the compiler potentially crash. However, any reasonable program 1330 // the compiler potentially crash. However, any reasonable program
1333 // will instantiate those two classes. 1331 // will instantiate those two classes.
1334 addInterceptors(helpers.jsBoolClass, world, registry); 1332 addInterceptors(helpers.jsBoolClass, enqueuer);
1335 addInterceptors(helpers.jsNullClass, world, registry); 1333 addInterceptors(helpers.jsNullClass, enqueuer);
1336 if (compiler.options.enableTypeAssertions) { 1334 if (compiler.options.enableTypeAssertions) {
1337 // Unconditionally register the helper that checks if the 1335 // Unconditionally register the helper that checks if the
1338 // expression in an if/while/for is a boolean. 1336 // expression in an if/while/for is a boolean.
1339 // TODO(ngeoffray): Should we have the resolver register those instead? 1337 // TODO(ngeoffray): Should we have the resolver register those instead?
1340 Element e = helpers.boolConversionCheck; 1338 Element e = helpers.boolConversionCheck;
1341 if (e != null) enqueue(world, e, registry); 1339 if (e != null) enqueue(enqueuer, e);
1342 } 1340 }
1343 1341
1344 if (TRACE_CALLS) { 1342 if (TRACE_CALLS) {
1345 traceHelper = TRACE_METHOD == 'console' 1343 traceHelper = TRACE_METHOD == 'console'
1346 ? helpers.consoleTraceHelper 1344 ? helpers.consoleTraceHelper
1347 : helpers.postTraceHelper; 1345 : helpers.postTraceHelper;
1348 assert(traceHelper != null); 1346 assert(traceHelper != null);
1349 enqueueInResolution(traceHelper, registry); 1347 enqueue(enqueuer, traceHelper);
1350 } 1348 }
1351 enqueueInResolution(helpers.assertUnreachableMethod, registry); 1349 enqueue(enqueuer, helpers.assertUnreachableMethod);
1352 registerCheckedModeHelpers(registry); 1350 registerCheckedModeHelpers(enqueuer);
1353 } 1351 }
1354 1352
1355 onResolutionComplete() { 1353 onResolutionComplete() {
1356 super.onResolutionComplete(); 1354 super.onResolutionComplete();
1357 computeMembersNeededForReflection(); 1355 computeMembersNeededForReflection();
1358 rti.computeClassesNeedingRti(); 1356 rti.computeClassesNeedingRti();
1359 _registeredMetadata.clear(); 1357 _registeredMetadata.clear();
1360 } 1358 }
1361 1359
1362 onTypeInferenceComplete() { 1360 onTypeInferenceComplete() {
1363 super.onTypeInferenceComplete(); 1361 super.onTypeInferenceComplete();
1364 noSuchMethodRegistry.onTypeInferenceComplete(); 1362 noSuchMethodRegistry.onTypeInferenceComplete();
1365 } 1363 }
1366 1364
1367 void registerGetRuntimeTypeArgument(Registry registry) { 1365 void registerGetRuntimeTypeArgument() {
1368 enqueueImpact( 1366 enqueueImpact(compiler.enqueuer.resolution, impacts.getRuntimeTypeArgument);
1369 compiler.enqueuer.resolution, impacts.getRuntimeTypeArgument, registry);
1370 } 1367 }
1371 1368
1372 void registerCallMethodWithFreeTypeVariables( 1369 void registerCallMethodWithFreeTypeVariables(
1373 Element callMethod, Enqueuer enqueuer, Registry registry) { 1370 Element callMethod, Enqueuer enqueuer) {
1374 if (enqueuer.isResolutionQueue || methodNeedsRti(callMethod)) { 1371 if (enqueuer.isResolutionQueue || methodNeedsRti(callMethod)) {
1375 registerComputeSignature(enqueuer, registry); 1372 registerComputeSignature(enqueuer);
1376 } 1373 }
1377 } 1374 }
1378 1375
1379 void registerClosureWithFreeTypeVariables( 1376 void registerClosureWithFreeTypeVariables(
1380 Element closure, Enqueuer enqueuer, Registry registry) { 1377 Element closure, Enqueuer enqueuer) {
1381 if (enqueuer.isResolutionQueue || methodNeedsRti(closure)) { 1378 if (enqueuer.isResolutionQueue || methodNeedsRti(closure)) {
1382 registerComputeSignature(enqueuer, registry); 1379 registerComputeSignature(enqueuer);
1383 } 1380 }
1384 } 1381 }
1385 1382
1386 void registerBoundClosure(Enqueuer enqueuer) { 1383 void registerBoundClosure(Enqueuer enqueuer) {
1387 helpers.boundClosureClass.ensureResolved(resolution); 1384 helpers.boundClosureClass.ensureResolved(resolution);
1388 registerInstantiatedType( 1385 enqueuer.registerInstantiatedType(helpers.boundClosureClass.rawType);
1389 helpers.boundClosureClass.rawType,
1390 enqueuer,
1391 // Precise dependency is not important here.
1392 compiler.globalDependencies);
1393 } 1386 }
1394 1387
1395 void registerGetOfStaticFunction(Enqueuer enqueuer) { 1388 void registerGetOfStaticFunction(Enqueuer enqueuer) {
1396 helpers.closureClass.ensureResolved(resolution); 1389 helpers.closureClass.ensureResolved(resolution);
1397 registerInstantiatedType( 1390 enqueuer.registerInstantiatedType(helpers.closureClass.rawType);
1398 helpers.closureClass.rawType, enqueuer, compiler.globalDependencies);
1399 } 1391 }
1400 1392
1401 void registerComputeSignature(Enqueuer enqueuer, Registry registry) { 1393 void registerComputeSignature(Enqueuer enqueuer) {
1402 // Calls to [:computeSignature:] are generated by the emitter and we 1394 // Calls to [:computeSignature:] are generated by the emitter and we
1403 // therefore need to enqueue the used elements in the codegen enqueuer as 1395 // therefore need to enqueue the used elements in the codegen enqueuer as
1404 // well as in the resolution enqueuer. 1396 // well as in the resolution enqueuer.
1405 enqueueImpact(enqueuer, impacts.computeSignature, registry); 1397 enqueueImpact(enqueuer, impacts.computeSignature);
1406 } 1398 }
1407 1399
1408 void registerRuntimeType(Enqueuer enqueuer, Registry registry) { 1400 void registerRuntimeType(ResolutionEnqueuer enqueuer) {
1409 registerComputeSignature(enqueuer, registry); 1401 registerComputeSignature(enqueuer);
1410 enqueueInResolution(helpers.setRuntimeTypeInfo, registry); 1402 enqueue(enqueuer, helpers.setRuntimeTypeInfo);
1411 registerGetRuntimeTypeArgument(registry); 1403 registerGetRuntimeTypeArgument();
1412 enqueueInResolution(helpers.getRuntimeTypeInfo, registry); 1404 enqueue(enqueuer, helpers.getRuntimeTypeInfo);
1413 enqueueClass(enqueuer, coreClasses.listClass, registry); 1405 enqueueClass(enqueuer, coreClasses.listClass);
1414 } 1406 }
1415 1407
1416 void registerTypeVariableBoundsSubtypeCheck( 1408 void registerTypeVariableBoundsSubtypeCheck(
1417 DartType typeArgument, DartType bound) { 1409 DartType typeArgument, DartType bound) {
1418 rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound); 1410 rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound);
1419 } 1411 }
1420 1412
1421 void registerCheckDeferredIsLoaded(Registry registry) { 1413 void registerCheckDeferredIsLoaded(ResolutionEnqueuer enqueuer) {
1422 enqueueInResolution(helpers.checkDeferredIsLoaded, registry); 1414 enqueue(enqueuer, helpers.checkDeferredIsLoaded);
1423 // Also register the types of the arguments passed to this method. 1415 // Also register the types of the arguments passed to this method.
1424 enqueueClass( 1416 enqueueClass(enqueuer, coreClasses.stringClass);
1425 compiler.enqueuer.resolution, coreClasses.stringClass, registry);
1426 } 1417 }
1427 1418
1428 void registerNoSuchMethod(FunctionElement noSuchMethod) { 1419 void registerNoSuchMethod(FunctionElement noSuchMethod) {
1429 noSuchMethodRegistry.registerNoSuchMethod(noSuchMethod); 1420 noSuchMethodRegistry.registerNoSuchMethod(noSuchMethod);
1430 } 1421 }
1431 1422
1432 /// Called when resolving a call to a foreign function. 1423 /// Called when resolving a call to a foreign function.
1433 native.NativeBehavior resolveForeignCall(Send node, Element element, 1424 native.NativeBehavior resolveForeignCall(Send node, Element element,
1434 CallStructure callStructure, ForeignResolver resolver) { 1425 CallStructure callStructure, ForeignResolver resolver) {
1435 native.NativeResolutionEnqueuer nativeEnqueuer = 1426 native.NativeResolutionEnqueuer nativeEnqueuer =
(...skipping 21 matching lines...) Expand all
1457 } 1448 }
1458 } 1449 }
1459 reporter.reportErrorMessage( 1450 reporter.reportErrorMessage(
1460 node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); 1451 node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT);
1461 } 1452 }
1462 // No native behavior for this call. 1453 // No native behavior for this call.
1463 return null; 1454 return null;
1464 } 1455 }
1465 1456
1466 void enableNoSuchMethod(Enqueuer world) { 1457 void enableNoSuchMethod(Enqueuer world) {
1467 enqueue(world, helpers.createInvocationMirror, compiler.globalDependencies); 1458 enqueue(world, helpers.createInvocationMirror);
1468 world.registerDynamicUse(new DynamicUse(Selectors.noSuchMethod_, null)); 1459 world.registerDynamicUse(new DynamicUse(Selectors.noSuchMethod_, null));
1469 } 1460 }
1470 1461
1471 void enableIsolateSupport(Enqueuer enqueuer) { 1462 void enableIsolateSupport(Enqueuer enqueuer) {
1472 // TODO(floitsch): We should also ensure that the class IsolateMessage is 1463 // TODO(floitsch): We should also ensure that the class IsolateMessage is
1473 // instantiated. Currently, just enabling isolate support works. 1464 // instantiated. Currently, just enabling isolate support works.
1474 if (compiler.mainFunction != null) { 1465 if (compiler.mainFunction != null) {
1475 // The JavaScript backend implements [Isolate.spawn] by looking up 1466 // The JavaScript backend implements [Isolate.spawn] by looking up
1476 // top-level functions by name. So all top-level function tear-off 1467 // top-level functions by name. So all top-level function tear-off
1477 // closures have a private name field. 1468 // closures have a private name field.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1520 } 1511 }
1521 1512
1522 bool methodNeedsRti(FunctionElement function) { 1513 bool methodNeedsRti(FunctionElement function) {
1523 return rti.methodsNeedingRti.contains(function) || 1514 return rti.methodsNeedingRti.contains(function) ||
1524 compiler.enabledRuntimeType; 1515 compiler.enabledRuntimeType;
1525 } 1516 }
1526 1517
1527 /// Enqueue [e] in [enqueuer]. 1518 /// Enqueue [e] in [enqueuer].
1528 /// 1519 ///
1529 /// This method calls [registerBackendUse]. 1520 /// This method calls [registerBackendUse].
1530 void enqueue(Enqueuer enqueuer, Element e, Registry registry) { 1521 void enqueue(Enqueuer enqueuer, Element e) {
1531 if (e == null) return; 1522 if (e == null) return;
1532 registerBackendUse(e); 1523 registerBackendUse(e);
1533 enqueuer.addToWorkList(e); 1524 enqueuer.addToWorkList(e);
1534 registry.registerDependency(e); 1525 compiler.globalDependencies.registerDependency(e);
1535 }
1536
1537 /// Enqueue [e] in the resolution enqueuer.
1538 ///
1539 /// This method calls [registerBackendUse].
1540 void enqueueInResolution(Element e, Registry registry) {
1541 if (e == null) return;
1542 ResolutionEnqueuer enqueuer = compiler.enqueuer.resolution;
1543 enqueue(enqueuer, e, registry);
1544 } 1526 }
1545 1527
1546 /// Register instantiation of [cls] in [enqueuer]. 1528 /// Register instantiation of [cls] in [enqueuer].
1547 /// 1529 ///
1548 /// This method calls [registerBackendUse]. 1530 /// This method calls [registerBackendUse].
1549 void enqueueClass(Enqueuer enqueuer, ClassElement cls, Registry registry) { 1531 void enqueueClass(Enqueuer enqueuer, ClassElement cls) {
1550 if (cls == null) return; 1532 if (cls == null) return;
1551 registerBackendUse(cls); 1533 registerBackendUse(cls);
1552 helpersUsed.add(cls.declaration); 1534 helpersUsed.add(cls.declaration);
1553 if (cls.declaration != cls.implementation) { 1535 if (cls.declaration != cls.implementation) {
1554 helpersUsed.add(cls.implementation); 1536 helpersUsed.add(cls.implementation);
1555 } 1537 }
1556 cls.ensureResolved(resolution); 1538 cls.ensureResolved(resolution);
1557 registerInstantiatedType(cls.rawType, enqueuer, registry); 1539 enqueuer.registerInstantiatedType(cls.rawType);
1558 } 1540 }
1559 1541
1560 /// Register instantiation of [type] in [enqueuer]. 1542 /// Register instantiation of [type] in [enqueuer].
1561 /// 1543 ///
1562 /// This method calls [registerBackendUse]. 1544 /// This method calls [registerBackendUse].
1563 void enqueueType(Enqueuer enqueuer, InterfaceType type, Registry registry) { 1545 void enqueueType(Enqueuer enqueuer, InterfaceType type) {
1564 if (type == null) return; 1546 if (type == null) return;
1565 ClassElement cls = type.element; 1547 ClassElement cls = type.element;
1566 registerBackendUse(cls); 1548 registerBackendUse(cls);
1567 helpersUsed.add(cls.declaration); 1549 helpersUsed.add(cls.declaration);
1568 if (cls.declaration != cls.implementation) { 1550 if (cls.declaration != cls.implementation) {
1569 helpersUsed.add(cls.implementation); 1551 helpersUsed.add(cls.implementation);
1570 } 1552 }
1571 cls.ensureResolved(resolution); 1553 cls.ensureResolved(resolution);
1572 registerInstantiatedType(type, enqueuer, registry); 1554 enqueuer.registerInstantiatedType(type);
1573 } 1555 }
1574 1556
1575 void enqueueImpact( 1557 void enqueueImpact(Enqueuer enqueuer, BackendImpact impact) {
1576 Enqueuer enqueuer, BackendImpact impact, Registry registry) {
1577 for (Element staticUse in impact.staticUses) { 1558 for (Element staticUse in impact.staticUses) {
1578 enqueue(enqueuer, staticUse, registry); 1559 enqueue(enqueuer, staticUse);
1579 } 1560 }
1580 for (InterfaceType type in impact.instantiatedTypes) { 1561 for (InterfaceType type in impact.instantiatedTypes) {
1581 enqueueType(enqueuer, type, registry); 1562 enqueueType(enqueuer, type);
1582 } 1563 }
1583 for (ClassElement cls in impact.instantiatedClasses) { 1564 for (ClassElement cls in impact.instantiatedClasses) {
1584 enqueueClass(enqueuer, cls, registry); 1565 enqueueClass(enqueuer, cls);
1585 } 1566 }
1586 for (BackendImpact otherImpact in impact.otherImpacts) { 1567 for (BackendImpact otherImpact in impact.otherImpacts) {
1587 enqueueImpact(enqueuer, otherImpact, registry); 1568 enqueueImpact(enqueuer, otherImpact);
1588 } 1569 }
1589 } 1570 }
1590 1571
1591 CodegenEnqueuer get codegenEnqueuer => compiler.enqueuer.codegen; 1572 CodegenEnqueuer get codegenEnqueuer => compiler.enqueuer.codegen;
1592 1573
1593 CodegenEnqueuer createCodegenEnqueuer(Compiler compiler) { 1574 CodegenEnqueuer createCodegenEnqueuer(Compiler compiler) {
1594 return new CodegenEnqueuer(compiler, const TreeShakingEnqueuerStrategy()); 1575 return new CodegenEnqueuer(compiler, const TreeShakingEnqueuerStrategy());
1595 } 1576 }
1596 1577
1597 WorldImpact codegen(CodegenWorkItem work) { 1578 WorldImpact codegen(CodegenWorkItem work) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1659 sourceInformationStrategy.buildSourceMappedMarker()); 1640 sourceInformationStrategy.buildSourceMappedMarker());
1660 } 1641 }
1661 generatedCode[element] = function; 1642 generatedCode[element] = function;
1662 WorldImpact worldImpact = 1643 WorldImpact worldImpact =
1663 impactTransformer.transformCodegenImpact(work.registry.worldImpact); 1644 impactTransformer.transformCodegenImpact(work.registry.worldImpact);
1664 compiler.dumpInfoTask.registerImpact(element, worldImpact); 1645 compiler.dumpInfoTask.registerImpact(element, worldImpact);
1665 return worldImpact; 1646 return worldImpact;
1666 } 1647 }
1667 1648
1668 native.NativeEnqueuer nativeResolutionEnqueuer(Enqueuer world) { 1649 native.NativeEnqueuer nativeResolutionEnqueuer(Enqueuer world) {
1669 return new native.NativeResolutionEnqueuer(world, compiler); 1650 return new native.NativeResolutionEnqueuer(compiler);
1670 } 1651 }
1671 1652
1672 native.NativeEnqueuer nativeCodegenEnqueuer(Enqueuer world) { 1653 native.NativeEnqueuer nativeCodegenEnqueuer(Enqueuer world) {
1673 return new native.NativeCodegenEnqueuer(world, compiler, emitter); 1654 return new native.NativeCodegenEnqueuer(compiler, emitter);
1674 } 1655 }
1675 1656
1676 ClassElement defaultSuperclass(ClassElement element) { 1657 ClassElement defaultSuperclass(ClassElement element) {
1677 if (isJsInterop(element)) { 1658 if (isJsInterop(element)) {
1678 return helpers.jsJavaScriptObjectClass; 1659 return helpers.jsJavaScriptObjectClass;
1679 } 1660 }
1680 // Native classes inherit from Interceptor. 1661 // Native classes inherit from Interceptor.
1681 return isNative(element) 1662 return isNative(element)
1682 ? helpers.jsInterceptorClass 1663 ? helpers.jsInterceptorClass
1683 : coreClasses.objectClass; 1664 : coreClasses.objectClass;
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1863 // interceptors? 1844 // interceptors?
1864 return typeCast ? 'interceptedTypeCast' : 'interceptedTypeCheck'; 1845 return typeCast ? 'interceptedTypeCast' : 'interceptedTypeCheck';
1865 } else { 1846 } else {
1866 return typeCast ? 'propertyTypeCast' : 'propertyTypeCheck'; 1847 return typeCast ? 'propertyTypeCast' : 'propertyTypeCheck';
1867 } 1848 }
1868 } 1849 }
1869 } 1850 }
1870 } 1851 }
1871 } 1852 }
1872 1853
1873 void registerCheckedModeHelpers(Registry registry) { 1854 void registerCheckedModeHelpers(ResolutionEnqueuer enqueuer) {
1874 // We register all the helpers in the resolution queue. 1855 // We register all the helpers in the resolution queue.
1875 // TODO(13155): Find a way to register fewer helpers. 1856 // TODO(13155): Find a way to register fewer helpers.
1876 for (CheckedModeHelper helper in checkedModeHelpers) { 1857 for (CheckedModeHelper helper in checkedModeHelpers) {
1877 enqueueInResolution(helper.getStaticUse(compiler).element, registry); 1858 enqueue(enqueuer, helper.getStaticUse(compiler).element);
1878 } 1859 }
1879 } 1860 }
1880 1861
1881 /** 1862 /**
1882 * Returns [:true:] if the checking of [type] is performed directly on the 1863 * Returns [:true:] if the checking of [type] is performed directly on the
1883 * object and not on an interceptor. 1864 * object and not on an interceptor.
1884 */ 1865 */
1885 bool hasDirectCheckFor(DartType type) { 1866 bool hasDirectCheckFor(DartType type) {
1886 Element element = type.element; 1867 Element element = type.element;
1887 return element == coreClasses.stringClass || 1868 return element == coreClasses.stringClass ||
(...skipping 11 matching lines...) Expand all
1899 bool mayGenerateInstanceofCheck(DartType type) { 1880 bool mayGenerateInstanceofCheck(DartType type) {
1900 // We can use an instanceof check for raw types that have no subclass that 1881 // We can use an instanceof check for raw types that have no subclass that
1901 // is mixed-in or in an implements clause. 1882 // is mixed-in or in an implements clause.
1902 1883
1903 if (!type.isRaw) return false; 1884 if (!type.isRaw) return false;
1904 ClassElement classElement = type.element; 1885 ClassElement classElement = type.element;
1905 if (isInterceptorClass(classElement)) return false; 1886 if (isInterceptorClass(classElement)) return false;
1906 return compiler.closedWorld.hasOnlySubclasses(classElement); 1887 return compiler.closedWorld.hasOnlySubclasses(classElement);
1907 } 1888 }
1908 1889
1909 void registerStaticUse(Element element, {bool forResolution}) { 1890 void registerStaticUse(Enqueuer enqueuer, Element element) {
1910 if (element == helpers.disableTreeShakingMarker) { 1891 if (element == helpers.disableTreeShakingMarker) {
1911 isTreeShakingDisabled = true; 1892 isTreeShakingDisabled = true;
1912 } else if (element == helpers.preserveNamesMarker) { 1893 } else if (element == helpers.preserveNamesMarker) {
1913 mustPreserveNames = true; 1894 mustPreserveNames = true;
1914 } else if (element == helpers.preserveMetadataMarker) { 1895 } else if (element == helpers.preserveMetadataMarker) {
1915 mustRetainMetadata = true; 1896 mustRetainMetadata = true;
1916 } else if (element == helpers.preserveUrisMarker) { 1897 } else if (element == helpers.preserveUrisMarker) {
1917 if (compiler.options.preserveUris) mustPreserveUris = true; 1898 if (compiler.options.preserveUris) mustPreserveUris = true;
1918 } else if (element == helpers.preserveLibraryNamesMarker) { 1899 } else if (element == helpers.preserveLibraryNamesMarker) {
1919 mustRetainLibraryNames = true; 1900 mustRetainLibraryNames = true;
1920 } else if (element == helpers.getIsolateAffinityTagMarker) { 1901 } else if (element == helpers.getIsolateAffinityTagMarker) {
1921 needToInitializeIsolateAffinityTag = true; 1902 needToInitializeIsolateAffinityTag = true;
1922 } else if (element.isDeferredLoaderGetter) { 1903 } else if (element.isDeferredLoaderGetter) {
1923 // TODO(sigurdm): Create a function registerLoadLibraryAccess. 1904 // TODO(sigurdm): Create a function registerLoadLibraryAccess.
1924 if (!isLoadLibraryFunctionResolved) { 1905 if (!isLoadLibraryFunctionResolved) {
1925 isLoadLibraryFunctionResolved = true; 1906 isLoadLibraryFunctionResolved = true;
1926 enqueueInResolution( 1907 if (enqueuer.isResolutionQueue) {
1927 helpers.loadLibraryWrapper, compiler.globalDependencies); 1908 enqueue(enqueuer, helpers.loadLibraryWrapper);
1909 }
1928 } 1910 }
1929 } else if (element == helpers.requiresPreambleMarker) { 1911 } else if (element == helpers.requiresPreambleMarker) {
1930 requiresPreamble = true; 1912 requiresPreamble = true;
1931 } 1913 }
1932 customElementsAnalysis.registerStaticUse(element, 1914 customElementsAnalysis.registerStaticUse(element,
1933 forResolution: forResolution); 1915 forResolution: enqueuer.isResolutionQueue);
1934 } 1916 }
1935 1917
1936 /// Called when [:const Symbol(name):] is seen. 1918 /// Called when [:const Symbol(name):] is seen.
1937 void registerConstSymbol(String name) { 1919 void registerConstSymbol(String name) {
1938 symbolsUsed.add(name); 1920 symbolsUsed.add(name);
1939 if (name.endsWith('=')) { 1921 if (name.endsWith('=')) {
1940 symbolsUsed.add(name.substring(0, name.length - 1)); 1922 symbolsUsed.add(name.substring(0, name.length - 1));
1941 } 1923 }
1942 } 1924 }
1943 1925
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
2388 registerBackendUse(e); 2370 registerBackendUse(e);
2389 enqueuer.addToWorkList(e); 2371 enqueuer.addToWorkList(e);
2390 } 2372 }
2391 } 2373 }
2392 2374
2393 if (!enqueuer.isResolutionQueue && preMirrorsMethodCount == 0) { 2375 if (!enqueuer.isResolutionQueue && preMirrorsMethodCount == 0) {
2394 preMirrorsMethodCount = generatedCode.length; 2376 preMirrorsMethodCount = generatedCode.length;
2395 } 2377 }
2396 2378
2397 if (isTreeShakingDisabled) { 2379 if (isTreeShakingDisabled) {
2398 enqueuer.enqueueReflectiveElements(recentClasses); 2380 mirrorsAnalysis.enqueueReflectiveElements(
2381 enqueuer, recentClasses, compiler.libraryLoader.libraries);
2399 } else if (!targetsUsed.isEmpty && enqueuer.isResolutionQueue) { 2382 } else if (!targetsUsed.isEmpty && enqueuer.isResolutionQueue) {
2400 // Add all static elements (not classes) that have been requested for 2383 // Add all static elements (not classes) that have been requested for
2401 // reflection. If there is no mirror-usage these are probably not 2384 // reflection. If there is no mirror-usage these are probably not
2402 // necessary, but the backend relies on them being resolved. 2385 // necessary, but the backend relies on them being resolved.
2403 enqueuer.enqueueReflectiveStaticFields(_findStaticFieldTargets()); 2386 mirrorsAnalysis.enqueueReflectiveStaticFields(
2387 enqueuer, _findStaticFieldTargets());
2404 } 2388 }
2405 2389
2406 if (mustPreserveNames) reporter.log('Preserving names.'); 2390 if (mustPreserveNames) reporter.log('Preserving names.');
2407 2391
2408 if (mustRetainMetadata) { 2392 if (mustRetainMetadata) {
2409 reporter.log('Retaining metadata.'); 2393 reporter.log('Retaining metadata.');
2410 2394
2411 compiler.libraryLoader.libraries.forEach(retainMetadataOf); 2395 compiler.libraryLoader.libraries.forEach(retainMetadataOf);
2412 2396
2413 StagedWorldImpactBuilder impactBuilder = enqueuer.isResolutionQueue 2397 StagedWorldImpactBuilder impactBuilder = enqueuer.isResolutionQueue
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
2600 assert(name != ""); 2584 assert(name != "");
2601 String outPath = compiler.options.outputUri != null 2585 String outPath = compiler.options.outputUri != null
2602 ? compiler.options.outputUri.path 2586 ? compiler.options.outputUri.path
2603 : "out"; 2587 : "out";
2604 String outName = outPath.substring(outPath.lastIndexOf('/') + 1); 2588 String outName = outPath.substring(outPath.lastIndexOf('/') + 1);
2605 String extension = addExtension ? ".part.js" : ""; 2589 String extension = addExtension ? ".part.js" : "";
2606 return "${outName}_$name$extension"; 2590 return "${outName}_$name$extension";
2607 } 2591 }
2608 2592
2609 @override 2593 @override
2610 bool enableDeferredLoadingIfSupported(Spannable node, Registry registry) { 2594 bool enableDeferredLoadingIfSupported(
2611 registerCheckDeferredIsLoaded(registry); 2595 ResolutionEnqueuer enqueuer, Spannable node) {
2596 registerCheckDeferredIsLoaded(enqueuer);
2612 return true; 2597 return true;
2613 } 2598 }
2614 2599
2615 @override 2600 @override
2616 bool enableCodegenWithErrorsIfSupported(Spannable node) => true; 2601 bool enableCodegenWithErrorsIfSupported(Spannable node) => true;
2617 2602
2618 jsAst.Expression rewriteAsync( 2603 jsAst.Expression rewriteAsync(
2619 FunctionElement element, jsAst.Expression code) { 2604 FunctionElement element, jsAst.Expression code) {
2620 AsyncRewriterBase rewriter = null; 2605 AsyncRewriterBase rewriter = null;
2621 jsAst.Name name = namer.methodPropertyName(element); 2606 jsAst.Name name = namer.methodPropertyName(element);
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
2785 } 2770 }
2786 } 2771 }
2787 2772
2788 class JavaScriptImpactTransformer extends ImpactTransformer { 2773 class JavaScriptImpactTransformer extends ImpactTransformer {
2789 final JavaScriptBackend backend; 2774 final JavaScriptBackend backend;
2790 2775
2791 JavaScriptImpactTransformer(this.backend); 2776 JavaScriptImpactTransformer(this.backend);
2792 2777
2793 BackendImpacts get impacts => backend.impacts; 2778 BackendImpacts get impacts => backend.impacts;
2794 2779
2795 // TODO(johnniwinther): Avoid this dependency.
2796 ResolutionEnqueuer get resolutionEnqueuer {
2797 return backend.compiler.enqueuer.resolution;
2798 }
2799
2800 @override 2780 @override
2801 WorldImpact transformResolutionImpact(ResolutionImpact worldImpact) { 2781 WorldImpact transformResolutionImpact(
2782 ResolutionEnqueuer enqueuer, ResolutionImpact worldImpact) {
2802 TransformedWorldImpact transformed = 2783 TransformedWorldImpact transformed =
2803 new TransformedWorldImpact(worldImpact); 2784 new TransformedWorldImpact(worldImpact);
2804 for (Feature feature in worldImpact.features) { 2785 for (Feature feature in worldImpact.features) {
2805 switch (feature) { 2786 switch (feature) {
2806 case Feature.ABSTRACT_CLASS_INSTANTIATION: 2787 case Feature.ABSTRACT_CLASS_INSTANTIATION:
2807 registerBackendImpact( 2788 registerBackendImpact(
2808 transformed, impacts.abstractClassInstantiation); 2789 transformed, impacts.abstractClassInstantiation);
2809 break; 2790 break;
2810 case Feature.ASSERT: 2791 case Feature.ASSERT:
2811 registerBackendImpact(transformed, impacts.assertWithoutMessage); 2792 registerBackendImpact(transformed, impacts.assertWithoutMessage);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
2878 break; 2859 break;
2879 } 2860 }
2880 } 2861 }
2881 2862
2882 bool hasAsCast = false; 2863 bool hasAsCast = false;
2883 bool hasTypeLiteral = false; 2864 bool hasTypeLiteral = false;
2884 for (TypeUse typeUse in worldImpact.typeUses) { 2865 for (TypeUse typeUse in worldImpact.typeUses) {
2885 DartType type = typeUse.type; 2866 DartType type = typeUse.type;
2886 switch (typeUse.kind) { 2867 switch (typeUse.kind) {
2887 case TypeUseKind.INSTANTIATION: 2868 case TypeUseKind.INSTANTIATION:
2869 case TypeUseKind.MIRROR_INSTANTIATION:
2870 case TypeUseKind.NATIVE_INSTANTIATION:
2888 registerRequiredType(type); 2871 registerRequiredType(type);
2889 break; 2872 break;
2890 case TypeUseKind.IS_CHECK: 2873 case TypeUseKind.IS_CHECK:
2891 onIsCheck(type, transformed); 2874 onIsCheck(type, transformed);
2892 break; 2875 break;
2893 case TypeUseKind.AS_CAST: 2876 case TypeUseKind.AS_CAST:
2894 onIsCheck(type, transformed); 2877 onIsCheck(type, transformed);
2895 hasAsCast = true; 2878 hasAsCast = true;
2896 break; 2879 break;
2897 case TypeUseKind.CHECKED_MODE_CHECK: 2880 case TypeUseKind.CHECKED_MODE_CHECK:
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2958 backend.registerConstSymbol(constSymbolName); 2941 backend.registerConstSymbol(constSymbolName);
2959 } 2942 }
2960 } 2943 }
2961 2944
2962 for (StaticUse staticUse in worldImpact.staticUses) { 2945 for (StaticUse staticUse in worldImpact.staticUses) {
2963 switch (staticUse.kind) { 2946 switch (staticUse.kind) {
2964 case StaticUseKind.CLOSURE: 2947 case StaticUseKind.CLOSURE:
2965 registerBackendImpact(transformed, impacts.closure); 2948 registerBackendImpact(transformed, impacts.closure);
2966 LocalFunctionElement closure = staticUse.element; 2949 LocalFunctionElement closure = staticUse.element;
2967 if (closure.type.containsTypeVariables) { 2950 if (closure.type.containsTypeVariables) {
2968 resolutionEnqueuer.universe.closuresWithFreeTypeVariables
2969 .add(closure);
2970 registerBackendImpact(transformed, impacts.computeSignature); 2951 registerBackendImpact(transformed, impacts.computeSignature);
2971 } 2952 }
2972 break; 2953 break;
2973 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: 2954 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE:
2974 case StaticUseKind.CONSTRUCTOR_INVOKE: 2955 case StaticUseKind.CONSTRUCTOR_INVOKE:
2975 registerRequiredType(staticUse.type); 2956 registerRequiredType(staticUse.type);
2976 break; 2957 break;
2977 default: 2958 default:
2978 } 2959 }
2979 } 2960 }
(...skipping 15 matching lines...) Expand all
2995 case ConstantExpressionKind.STRING: 2976 case ConstantExpressionKind.STRING:
2996 registerBackendImpact(transformed, impacts.stringLiteral); 2977 registerBackendImpact(transformed, impacts.stringLiteral);
2997 break; 2978 break;
2998 default: 2979 default:
2999 assert(invariant(NO_LOCATION_SPANNABLE, false, 2980 assert(invariant(NO_LOCATION_SPANNABLE, false,
3000 message: "Unexpected constant literal: ${constant.kind}.")); 2981 message: "Unexpected constant literal: ${constant.kind}."));
3001 } 2982 }
3002 } 2983 }
3003 2984
3004 for (native.NativeBehavior behavior in worldImpact.nativeData) { 2985 for (native.NativeBehavior behavior in worldImpact.nativeData) {
3005 resolutionEnqueuer.nativeEnqueuer 2986 enqueuer.nativeEnqueuer
3006 .registerNativeBehavior(behavior, worldImpact); 2987 .registerNativeBehavior(transformed, behavior, worldImpact);
3007 } 2988 }
3008 2989
3009 return transformed; 2990 return transformed;
3010 } 2991 }
3011 2992
3012 void registerBackendImpact( 2993 void registerBackendImpact(
3013 TransformedWorldImpact worldImpact, BackendImpact backendImpact) { 2994 TransformedWorldImpact worldImpact, BackendImpact backendImpact) {
3014 for (Element staticUse in backendImpact.staticUses) { 2995 for (Element staticUse in backendImpact.staticUses) {
3015 assert(staticUse != null); 2996 assert(staticUse != null);
3016 backend.registerBackendUse(staticUse); 2997 backend.registerBackendUse(staticUse);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
3096 3077
3097 void onIsCheckForCodegen(DartType type, TransformedWorldImpact transformed) { 3078 void onIsCheckForCodegen(DartType type, TransformedWorldImpact transformed) {
3098 type = type.unaliased; 3079 type = type.unaliased;
3099 registerBackendImpact(transformed, impacts.typeCheck); 3080 registerBackendImpact(transformed, impacts.typeCheck);
3100 3081
3101 bool inCheckedMode = backend.compiler.options.enableTypeAssertions; 3082 bool inCheckedMode = backend.compiler.options.enableTypeAssertions;
3102 // [registerIsCheck] is also called for checked mode checks, so we 3083 // [registerIsCheck] is also called for checked mode checks, so we
3103 // need to register checked mode helpers. 3084 // need to register checked mode helpers.
3104 if (inCheckedMode) { 3085 if (inCheckedMode) {
3105 // All helpers are added to resolution queue in enqueueHelpers. These 3086 // All helpers are added to resolution queue in enqueueHelpers. These
3106 // calls to enqueueInResolution serve as assertions that the helper was 3087 // calls to [enqueue] with the resolution enqueuer serve as assertions
3107 // in fact added. 3088 // that the helper was in fact added.
3108 // TODO(13155): Find a way to enqueue helpers lazily. 3089 // TODO(13155): Find a way to enqueue helpers lazily.
3109 CheckedModeHelper helper = 3090 CheckedModeHelper helper =
3110 backend.getCheckedModeHelper(type, typeCast: false); 3091 backend.getCheckedModeHelper(type, typeCast: false);
3111 if (helper != null) { 3092 if (helper != null) {
3112 StaticUse staticUse = helper.getStaticUse(backend.compiler); 3093 StaticUse staticUse = helper.getStaticUse(backend.compiler);
3113 transformed.registerStaticUse(staticUse); 3094 transformed.registerStaticUse(staticUse);
3114 backend.registerBackendUse(staticUse.element); 3095 backend.registerBackendUse(staticUse.element);
3115 } 3096 }
3116 // We also need the native variant of the check (for DOM types). 3097 // We also need the native variant of the check (for DOM types).
3117 helper = backend.getNativeCheckedModeHelper(type, typeCast: false); 3098 helper = backend.getNativeCheckedModeHelper(type, typeCast: false);
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
3288 ClassElement get mapImplementation => helpers.mapLiteralClass; 3269 ClassElement get mapImplementation => helpers.mapLiteralClass;
3289 ClassElement get constMapImplementation => helpers.constMapLiteralClass; 3270 ClassElement get constMapImplementation => helpers.constMapLiteralClass;
3290 ClassElement get typeImplementation => helpers.typeLiteralClass; 3271 ClassElement get typeImplementation => helpers.typeLiteralClass;
3291 ClassElement get boolImplementation => helpers.jsBoolClass; 3272 ClassElement get boolImplementation => helpers.jsBoolClass;
3292 ClassElement get nullImplementation => helpers.jsNullClass; 3273 ClassElement get nullImplementation => helpers.jsNullClass;
3293 ClassElement get syncStarIterableImplementation => helpers.syncStarIterable; 3274 ClassElement get syncStarIterableImplementation => helpers.syncStarIterable;
3294 ClassElement get asyncFutureImplementation => helpers.futureImplementation; 3275 ClassElement get asyncFutureImplementation => helpers.futureImplementation;
3295 ClassElement get asyncStarStreamImplementation => helpers.controllerStream; 3276 ClassElement get asyncStarStreamImplementation => helpers.controllerStream;
3296 ClassElement get functionImplementation => helpers.coreClasses.functionClass; 3277 ClassElement get functionImplementation => helpers.coreClasses.functionClass;
3297 } 3278 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/enqueue.dart ('k') | pkg/compiler/lib/src/js_backend/enqueuer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698