OLD | NEW |
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 |
11 import '../closure.dart'; | 11 import '../closure.dart'; |
12 import '../common.dart'; | 12 import '../common.dart'; |
13 import '../common/backend_api.dart' | 13 import '../common/backend_api.dart' |
14 show Backend, ImpactTransformer, ForeignResolver, NativeRegistry; | 14 show Backend, ImpactTransformer, ForeignResolver, NativeRegistry; |
15 import '../common/codegen.dart' show CodegenImpact, CodegenWorkItem; | 15 import '../common/codegen.dart' show CodegenImpact, CodegenWorkItem; |
16 import '../common/names.dart' show Identifiers, Selectors, Uris; | 16 import '../common/names.dart' show Identifiers, Selectors, Uris; |
17 import '../common/registry.dart' show EagerRegistry, Registry; | 17 import '../common/registry.dart' show Registry; |
18 import '../common/resolution.dart' show Frontend, Resolution, ResolutionImpact; | 18 import '../common/resolution.dart' show Frontend, Resolution, ResolutionImpact; |
19 import '../common/tasks.dart' show CompilerTask; | 19 import '../common/tasks.dart' show CompilerTask; |
20 import '../compiler.dart' show Compiler; | 20 import '../compiler.dart' show Compiler; |
21 import '../constants/constant_system.dart'; | 21 import '../constants/constant_system.dart'; |
22 import '../constants/expressions.dart'; | 22 import '../constants/expressions.dart'; |
23 import '../constants/values.dart'; | 23 import '../constants/values.dart'; |
24 import '../core_types.dart' show CoreClasses, CoreTypes; | 24 import '../core_types.dart' show CoreClasses, CoreTypes; |
25 import '../dart_types.dart'; | 25 import '../dart_types.dart'; |
26 import '../deferred_load.dart' show DeferredLoadTask; | 26 import '../deferred_load.dart' show DeferredLoadTask; |
27 import '../dump_info.dart' show DumpInfoTask; | 27 import '../dump_info.dart' show DumpInfoTask; |
(...skipping 19 matching lines...) Expand all Loading... |
47 import '../universe/selector.dart' show Selector; | 47 import '../universe/selector.dart' show Selector; |
48 import '../universe/universe.dart'; | 48 import '../universe/universe.dart'; |
49 import '../universe/use.dart' | 49 import '../universe/use.dart' |
50 show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind; | 50 show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind; |
51 import '../universe/world_impact.dart' | 51 import '../universe/world_impact.dart' |
52 show | 52 show |
53 ImpactStrategy, | 53 ImpactStrategy, |
54 ImpactUseCase, | 54 ImpactUseCase, |
55 TransformedWorldImpact, | 55 TransformedWorldImpact, |
56 WorldImpact, | 56 WorldImpact, |
57 WorldImpactVisitor; | 57 WorldImpactBuilder, |
| 58 WorldImpactVisitor, |
| 59 StagedWorldImpactBuilder; |
58 import '../util/util.dart'; | 60 import '../util/util.dart'; |
59 import '../world.dart' show ClassWorld; | 61 import '../world.dart' show ClassWorld; |
60 import 'backend_helpers.dart'; | 62 import 'backend_helpers.dart'; |
61 import 'backend_impact.dart'; | 63 import 'backend_impact.dart'; |
62 import 'backend_serialization.dart' show JavaScriptBackendSerialization; | 64 import 'backend_serialization.dart' show JavaScriptBackendSerialization; |
63 import 'checked_mode_helpers.dart'; | 65 import 'checked_mode_helpers.dart'; |
64 import 'constant_handler_javascript.dart'; | 66 import 'constant_handler_javascript.dart'; |
65 import 'custom_elements_analysis.dart'; | 67 import 'custom_elements_analysis.dart'; |
66 import 'enqueuer.dart'; | 68 import 'enqueuer.dart'; |
67 import 'js_interop_analysis.dart' show JsInteropAnalysis; | 69 import 'js_interop_analysis.dart' show JsInteropAnalysis; |
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 JavaScriptImpactTransformer impactTransformer; | 574 JavaScriptImpactTransformer impactTransformer; |
573 | 575 |
574 PatchResolverTask patchResolverTask; | 576 PatchResolverTask patchResolverTask; |
575 | 577 |
576 bool enabledNoSuchMethod = false; | 578 bool enabledNoSuchMethod = false; |
577 | 579 |
578 SourceInformationStrategy sourceInformationStrategy; | 580 SourceInformationStrategy sourceInformationStrategy; |
579 | 581 |
580 JavaScriptBackendSerialization serialization; | 582 JavaScriptBackendSerialization serialization; |
581 | 583 |
| 584 StagedWorldImpactBuilder constantImpactsForResolution = |
| 585 new StagedWorldImpactBuilder(); |
| 586 |
| 587 StagedWorldImpactBuilder constantImpactsForCodegen = |
| 588 new StagedWorldImpactBuilder(); |
| 589 |
582 final NativeData nativeData = new NativeData(); | 590 final NativeData nativeData = new NativeData(); |
583 | 591 |
584 final BackendHelpers helpers; | 592 final BackendHelpers helpers; |
585 final BackendImpacts impacts; | 593 final BackendImpacts impacts; |
586 | 594 |
587 final JSFrontendAccess frontend; | 595 final JSFrontendAccess frontend; |
588 | 596 |
589 JavaScriptBackend(Compiler compiler, | 597 JavaScriptBackend(Compiler compiler, |
590 {bool generateSourceMap: true, | 598 {bool generateSourceMap: true, |
591 bool useStartupEmitter: false, | 599 bool useStartupEmitter: false, |
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1062 jsAst.Name name = namer.nameForGetInterceptor(classes); | 1070 jsAst.Name name = namer.nameForGetInterceptor(classes); |
1063 if (classes.contains(helpers.jsInterceptorClass)) { | 1071 if (classes.contains(helpers.jsInterceptorClass)) { |
1064 // We can't use a specialized [getInterceptorMethod], so we make | 1072 // We can't use a specialized [getInterceptorMethod], so we make |
1065 // sure we emit the one with all checks. | 1073 // sure we emit the one with all checks. |
1066 specializedGetInterceptors[name] = interceptedClasses; | 1074 specializedGetInterceptors[name] = interceptedClasses; |
1067 } else { | 1075 } else { |
1068 specializedGetInterceptors[name] = classes; | 1076 specializedGetInterceptors[name] = classes; |
1069 } | 1077 } |
1070 } | 1078 } |
1071 | 1079 |
1072 void registerCompileTimeConstant(ConstantValue constant, Registry registry) { | 1080 void computeImpactForCompileTimeConstant(ConstantValue constant, |
1073 registerCompileTimeConstantInternal(constant, registry); | 1081 WorldImpactBuilder impactBuilder, bool isForResolution) { |
| 1082 computeImpactForCompileTimeConstantInternal( |
| 1083 constant, impactBuilder, isForResolution); |
1074 | 1084 |
1075 if (!registry.isForResolution && lookupMapAnalysis.isLookupMap(constant)) { | 1085 if (!isForResolution && lookupMapAnalysis.isLookupMap(constant)) { |
1076 // Note: internally, this registration will temporarily remove the | 1086 // Note: internally, this registration will temporarily remove the |
1077 // constant dependencies and add them later on-demand. | 1087 // constant dependencies and add them later on-demand. |
1078 lookupMapAnalysis.registerLookupMapReference(constant); | 1088 lookupMapAnalysis.registerLookupMapReference(constant); |
1079 } | 1089 } |
1080 | 1090 |
1081 for (ConstantValue dependency in constant.getDependencies()) { | 1091 for (ConstantValue dependency in constant.getDependencies()) { |
1082 registerCompileTimeConstant(dependency, registry); | 1092 computeImpactForCompileTimeConstant( |
| 1093 dependency, impactBuilder, isForResolution); |
1083 } | 1094 } |
1084 } | 1095 } |
1085 | 1096 |
1086 void addCompileTimeConstantForEmission(ConstantValue constant) { | 1097 void addCompileTimeConstantForEmission(ConstantValue constant) { |
1087 constants.addCompileTimeConstantForEmission(constant); | 1098 constants.addCompileTimeConstantForEmission(constant); |
1088 } | 1099 } |
1089 | 1100 |
1090 void registerCompileTimeConstantInternal( | 1101 void computeImpactForCompileTimeConstantInternal(ConstantValue constant, |
1091 ConstantValue constant, Registry registry) { | 1102 WorldImpactBuilder impactBuilder, bool isForResolution) { |
1092 DartType type = constant.getType(compiler.coreTypes); | 1103 DartType type = constant.getType(compiler.coreTypes); |
1093 registerInstantiatedConstantType(type, registry); | 1104 computeImpactForInstantiatedConstantType(type, impactBuilder); |
1094 | 1105 |
1095 if (constant.isFunction) { | 1106 if (constant.isFunction) { |
1096 FunctionConstantValue function = constant; | 1107 FunctionConstantValue function = constant; |
1097 registry.registerStaticUse(new StaticUse.staticTearOff(function.element)); | 1108 impactBuilder |
| 1109 .registerStaticUse(new StaticUse.staticTearOff(function.element)); |
1098 } else if (constant.isInterceptor) { | 1110 } else if (constant.isInterceptor) { |
1099 // An interceptor constant references the class's prototype chain. | 1111 // An interceptor constant references the class's prototype chain. |
1100 InterceptorConstantValue interceptor = constant; | 1112 InterceptorConstantValue interceptor = constant; |
1101 registerInstantiatedConstantType(interceptor.dispatchedType, registry); | 1113 computeImpactForInstantiatedConstantType( |
| 1114 interceptor.dispatchedType, impactBuilder); |
1102 } else if (constant.isType) { | 1115 } else if (constant.isType) { |
1103 enqueueInResolution(helpers.createRuntimeType, registry); | 1116 if (isForResolution) { |
1104 registry.registerInstantiation(typeImplementation.rawType); | 1117 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
| 1118 // TODO(johnniwinther): Find the right [CallStructure]. |
| 1119 helpers.createRuntimeType, |
| 1120 null)); |
| 1121 registerBackendUse(helpers.createRuntimeType); |
| 1122 } |
| 1123 impactBuilder.registerTypeUse( |
| 1124 new TypeUse.instantiation(typeImplementation.rawType)); |
1105 } | 1125 } |
1106 lookupMapAnalysis.registerConstantKey(constant); | 1126 lookupMapAnalysis.registerConstantKey(constant); |
1107 } | 1127 } |
1108 | 1128 |
1109 void registerInstantiatedConstantType(DartType type, Registry registry) { | 1129 void computeImpactForInstantiatedConstantType( |
| 1130 DartType type, WorldImpactBuilder impactBuilder) { |
1110 DartType instantiatedType = | 1131 DartType instantiatedType = |
1111 type.isFunctionType ? coreTypes.functionType : type; | 1132 type.isFunctionType ? coreTypes.functionType : type; |
1112 if (type is InterfaceType) { | 1133 if (type is InterfaceType) { |
1113 registry.registerInstantiation(instantiatedType); | 1134 impactBuilder |
| 1135 .registerTypeUse(new TypeUse.instantiation(instantiatedType)); |
1114 if (classNeedsRtiField(type.element)) { | 1136 if (classNeedsRtiField(type.element)) { |
1115 registry.registerStaticUse(new StaticUse.staticInvoke( | 1137 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
1116 // TODO(johnniwinther): Find the right [CallStructure]. | 1138 // TODO(johnniwinther): Find the right [CallStructure]. |
1117 helpers.setRuntimeTypeInfo, | 1139 helpers.setRuntimeTypeInfo, |
1118 null)); | 1140 null)); |
1119 } | 1141 } |
1120 if (type.element == typeImplementation) { | 1142 if (type.element == typeImplementation) { |
1121 // If we use a type literal in a constant, the compile time | 1143 // If we use a type literal in a constant, the compile time |
1122 // constant emitter will generate a call to the createRuntimeType | 1144 // constant emitter will generate a call to the createRuntimeType |
1123 // helper so we register a use of that. | 1145 // helper so we register a use of that. |
1124 registry.registerStaticUse(new StaticUse.staticInvoke( | 1146 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
1125 // TODO(johnniwinther): Find the right [CallStructure]. | 1147 // TODO(johnniwinther): Find the right [CallStructure]. |
1126 helpers.createRuntimeType, | 1148 helpers.createRuntimeType, |
1127 null)); | 1149 null)); |
1128 } | 1150 } |
1129 } | 1151 } |
1130 } | 1152 } |
1131 | 1153 |
1132 void registerInstantiatedClass( | 1154 void registerInstantiatedClass( |
1133 ClassElement cls, Enqueuer enqueuer, Registry registry) { | 1155 ClassElement cls, Enqueuer enqueuer, Registry registry) { |
1134 _processClass(cls, enqueuer, registry); | 1156 _processClass(cls, enqueuer, registry); |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1283 | 1305 |
1284 customElementsAnalysis.registerInstantiatedClass(cls, enqueuer); | 1306 customElementsAnalysis.registerInstantiatedClass(cls, enqueuer); |
1285 if (!enqueuer.isResolutionQueue) { | 1307 if (!enqueuer.isResolutionQueue) { |
1286 lookupMapAnalysis.registerInstantiatedClass(cls); | 1308 lookupMapAnalysis.registerInstantiatedClass(cls); |
1287 } | 1309 } |
1288 } | 1310 } |
1289 | 1311 |
1290 void registerInstantiatedType( | 1312 void registerInstantiatedType( |
1291 InterfaceType type, Enqueuer enqueuer, Registry registry, | 1313 InterfaceType type, Enqueuer enqueuer, Registry registry, |
1292 {bool mirrorUsage: false}) { | 1314 {bool mirrorUsage: false}) { |
1293 lookupMapAnalysis.registerInstantiatedType(type, registry); | 1315 lookupMapAnalysis.registerInstantiatedType(type); |
1294 super.registerInstantiatedType(type, enqueuer, registry, | 1316 super.registerInstantiatedType(type, enqueuer, registry, |
1295 mirrorUsage: mirrorUsage); | 1317 mirrorUsage: mirrorUsage); |
1296 } | 1318 } |
1297 | 1319 |
1298 void registerUseInterceptor(Enqueuer enqueuer) { | |
1299 assert(!enqueuer.isResolutionQueue); | |
1300 if (!enqueuer.nativeEnqueuer.hasInstantiatedNativeClasses()) return; | |
1301 Registry registry = compiler.globalDependencies; | |
1302 enqueue(enqueuer, helpers.getNativeInterceptorMethod, registry); | |
1303 enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass, registry); | |
1304 enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass, registry); | |
1305 enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass, registry); | |
1306 needToInitializeIsolateAffinityTag = true; | |
1307 needToInitializeDispatchProperty = true; | |
1308 } | |
1309 | |
1310 void enqueueHelpers(ResolutionEnqueuer world, Registry registry) { | 1320 void enqueueHelpers(ResolutionEnqueuer world, Registry registry) { |
1311 assert(helpers.interceptorsLibrary != null); | 1321 assert(helpers.interceptorsLibrary != null); |
1312 // TODO(ngeoffray): Not enqueuing those two classes currently make | 1322 // TODO(ngeoffray): Not enqueuing those two classes currently make |
1313 // the compiler potentially crash. However, any reasonable program | 1323 // the compiler potentially crash. However, any reasonable program |
1314 // will instantiate those two classes. | 1324 // will instantiate those two classes. |
1315 addInterceptors(helpers.jsBoolClass, world, registry); | 1325 addInterceptors(helpers.jsBoolClass, world, registry); |
1316 addInterceptors(helpers.jsNullClass, world, registry); | 1326 addInterceptors(helpers.jsNullClass, world, registry); |
1317 if (compiler.options.enableTypeAssertions) { | 1327 if (compiler.options.enableTypeAssertions) { |
1318 // Unconditionally register the helper that checks if the | 1328 // Unconditionally register the helper that checks if the |
1319 // expression in an if/while/for is a boolean. | 1329 // expression in an if/while/for is a boolean. |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1598 element.enclosingClass == helpers.jsNullClass) { | 1608 element.enclosingClass == helpers.jsNullClass) { |
1599 // Work around a problem compiling JSNull's constructor. | 1609 // Work around a problem compiling JSNull's constructor. |
1600 return const CodegenImpact(); | 1610 return const CodegenImpact(); |
1601 } | 1611 } |
1602 if (kind.category == ElementCategory.VARIABLE) { | 1612 if (kind.category == ElementCategory.VARIABLE) { |
1603 VariableElement variableElement = element; | 1613 VariableElement variableElement = element; |
1604 ConstantExpression constant = variableElement.constant; | 1614 ConstantExpression constant = variableElement.constant; |
1605 if (constant != null) { | 1615 if (constant != null) { |
1606 ConstantValue initialValue = constants.getConstantValue(constant); | 1616 ConstantValue initialValue = constants.getConstantValue(constant); |
1607 if (initialValue != null) { | 1617 if (initialValue != null) { |
1608 registerCompileTimeConstant(initialValue, work.registry); | 1618 computeImpactForCompileTimeConstant( |
| 1619 initialValue, work.registry.worldImpact, false); |
1609 addCompileTimeConstantForEmission(initialValue); | 1620 addCompileTimeConstantForEmission(initialValue); |
1610 // We don't need to generate code for static or top-level | 1621 // We don't need to generate code for static or top-level |
1611 // variables. For instance variables, we may need to generate | 1622 // variables. For instance variables, we may need to generate |
1612 // the checked setter. | 1623 // the checked setter. |
1613 if (Elements.isStaticOrTopLevel(element)) { | 1624 if (Elements.isStaticOrTopLevel(element)) { |
1614 return impactTransformer | 1625 return impactTransformer |
1615 .transformCodegenImpact(work.registry.worldImpact); | 1626 .transformCodegenImpact(work.registry.worldImpact); |
1616 } | 1627 } |
1617 } else { | 1628 } else { |
1618 assert(invariant( | 1629 assert(invariant( |
(...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2345 staticFields.add(target); | 2356 staticFields.add(target); |
2346 } else if (target.isLibrary || target.isClass) { | 2357 } else if (target.isLibrary || target.isClass) { |
2347 addFieldsInContainer(target); | 2358 addFieldsInContainer(target); |
2348 } | 2359 } |
2349 } | 2360 } |
2350 return staticFields; | 2361 return staticFields; |
2351 } | 2362 } |
2352 | 2363 |
2353 /// Called when [enqueuer] is empty, but before it is closed. | 2364 /// Called when [enqueuer] is empty, but before it is closed. |
2354 bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassElement> recentClasses) { | 2365 bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassElement> recentClasses) { |
2355 if (!compiler.options.resolveOnly) { | 2366 // Add elements used synthetically, that is, through features rather than |
2356 // TODO(johnniwinther): The custom element analysis eagerly enqueues | 2367 // syntax, for instance custom elements. |
2357 // elements on the codegen queue. Change to compute the data needed | 2368 // |
2358 // instead. | 2369 // Return early if any elements are added to avoid counting the elements as |
| 2370 // due to mirrors. |
| 2371 customElementsAnalysis.onQueueEmpty(enqueuer); |
| 2372 lookupMapAnalysis.onQueueEmpty(enqueuer); |
| 2373 typeVariableHandler.onQueueEmpty(enqueuer); |
2359 | 2374 |
2360 // Add elements referenced only via custom elements. Return early if any | |
2361 // elements are added to avoid counting the elements as due to mirrors. | |
2362 customElementsAnalysis.onQueueEmpty(enqueuer); | |
2363 } | |
2364 if (!enqueuer.queueIsEmpty) return false; | 2375 if (!enqueuer.queueIsEmpty) return false; |
2365 | 2376 |
2366 noSuchMethodRegistry.onQueueEmpty(); | 2377 noSuchMethodRegistry.onQueueEmpty(); |
2367 if (!enabledNoSuchMethod && | 2378 if (!enabledNoSuchMethod && |
2368 (noSuchMethodRegistry.hasThrowingNoSuchMethod || | 2379 (noSuchMethodRegistry.hasThrowingNoSuchMethod || |
2369 noSuchMethodRegistry.hasComplexNoSuchMethod)) { | 2380 noSuchMethodRegistry.hasComplexNoSuchMethod)) { |
2370 enableNoSuchMethod(enqueuer); | 2381 enableNoSuchMethod(enqueuer); |
2371 enabledNoSuchMethod = true; | 2382 enabledNoSuchMethod = true; |
2372 } | 2383 } |
2373 | 2384 |
(...skipping 23 matching lines...) Expand all Loading... |
2397 enqueuer.enqueueReflectiveStaticFields(_findStaticFieldTargets()); | 2408 enqueuer.enqueueReflectiveStaticFields(_findStaticFieldTargets()); |
2398 } | 2409 } |
2399 | 2410 |
2400 if (mustPreserveNames) reporter.log('Preserving names.'); | 2411 if (mustPreserveNames) reporter.log('Preserving names.'); |
2401 | 2412 |
2402 if (mustRetainMetadata) { | 2413 if (mustRetainMetadata) { |
2403 reporter.log('Retaining metadata.'); | 2414 reporter.log('Retaining metadata.'); |
2404 | 2415 |
2405 compiler.libraryLoader.libraries.forEach(retainMetadataOf); | 2416 compiler.libraryLoader.libraries.forEach(retainMetadataOf); |
2406 | 2417 |
| 2418 StagedWorldImpactBuilder impactBuilder = enqueuer.isResolutionQueue |
| 2419 ? constantImpactsForResolution |
| 2420 : constantImpactsForResolution; |
2407 if (enqueuer.isResolutionQueue && !enqueuer.queueIsClosed) { | 2421 if (enqueuer.isResolutionQueue && !enqueuer.queueIsClosed) { |
2408 /// Register the constant value of [metadata] as live in resolution. | 2422 /// Register the constant value of [metadata] as live in resolution. |
2409 void registerMetadataConstant(MetadataAnnotation metadata) { | 2423 void registerMetadataConstant(MetadataAnnotation metadata) { |
2410 ConstantValue constant = | 2424 ConstantValue constant = |
2411 constants.getConstantValueForMetadata(metadata); | 2425 constants.getConstantValueForMetadata(metadata); |
2412 Dependency dependency = | 2426 Dependency dependency = |
2413 new Dependency(constant, metadata.annotatedElement); | 2427 new Dependency(constant, metadata.annotatedElement); |
2414 metadataConstants.add(dependency); | 2428 metadataConstants.add(dependency); |
2415 registerCompileTimeConstant(dependency.constant, | 2429 computeImpactForCompileTimeConstant( |
2416 new EagerRegistry('EagerRegistry for ${dependency}', enqueuer)); | 2430 dependency.constant, impactBuilder, enqueuer.isResolutionQueue); |
2417 } | 2431 } |
2418 | 2432 |
2419 // TODO(johnniwinther): We should have access to all recently processed | 2433 // TODO(johnniwinther): We should have access to all recently processed |
2420 // elements and process these instead. | 2434 // elements and process these instead. |
2421 processMetadata(compiler.enqueuer.resolution.processedElements, | 2435 processMetadata(compiler.enqueuer.resolution.processedElements, |
2422 registerMetadataConstant); | 2436 registerMetadataConstant); |
2423 } else { | 2437 } else { |
2424 for (Dependency dependency in metadataConstants) { | 2438 for (Dependency dependency in metadataConstants) { |
2425 registerCompileTimeConstant(dependency.constant, | 2439 computeImpactForCompileTimeConstant( |
2426 new EagerRegistry('EagerRegistry for ${dependency}', enqueuer)); | 2440 dependency.constant, impactBuilder, enqueuer.isResolutionQueue); |
2427 } | 2441 } |
2428 metadataConstants.clear(); | 2442 metadataConstants.clear(); |
2429 } | 2443 } |
| 2444 enqueuer.applyImpact(null, impactBuilder.flush()); |
2430 } | 2445 } |
2431 return true; | 2446 return true; |
2432 } | 2447 } |
2433 | 2448 |
2434 /// Call [registerMetadataConstant] on all metadata from [elements]. | 2449 /// Call [registerMetadataConstant] on all metadata from [elements]. |
2435 void processMetadata(Iterable<Element> elements, | 2450 void processMetadata(Iterable<Element> elements, |
2436 void onMetadata(MetadataAnnotation metadata)) { | 2451 void onMetadata(MetadataAnnotation metadata)) { |
2437 void processLibraryMetadata(LibraryElement library) { | 2452 void processLibraryMetadata(LibraryElement library) { |
2438 if (_registeredMetadata.add(library)) { | 2453 if (_registeredMetadata.add(library)) { |
2439 library.metadata.forEach(onMetadata); | 2454 library.metadata.forEach(onMetadata); |
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3007 worldImpact.registerTypeUse(new TypeUse.instantiation(instantiatedType)); | 3022 worldImpact.registerTypeUse(new TypeUse.instantiation(instantiatedType)); |
3008 } | 3023 } |
3009 for (ClassElement cls in backendImpact.instantiatedClasses) { | 3024 for (ClassElement cls in backendImpact.instantiatedClasses) { |
3010 cls.ensureResolved(backend.resolution); | 3025 cls.ensureResolved(backend.resolution); |
3011 backend.registerBackendUse(cls); | 3026 backend.registerBackendUse(cls); |
3012 worldImpact.registerTypeUse(new TypeUse.instantiation(cls.rawType)); | 3027 worldImpact.registerTypeUse(new TypeUse.instantiation(cls.rawType)); |
3013 } | 3028 } |
3014 for (BackendImpact otherImpact in backendImpact.otherImpacts) { | 3029 for (BackendImpact otherImpact in backendImpact.otherImpacts) { |
3015 registerBackendImpact(worldImpact, otherImpact); | 3030 registerBackendImpact(worldImpact, otherImpact); |
3016 } | 3031 } |
| 3032 for (BackendFeature feature in backendImpact.features) { |
| 3033 switch (feature) { |
| 3034 case BackendFeature.needToInitializeDispatchProperty: |
| 3035 backend.needToInitializeDispatchProperty = true; |
| 3036 break; |
| 3037 case BackendFeature.needToInitializeIsolateAffinityTag: |
| 3038 backend.needToInitializeIsolateAffinityTag = true; |
| 3039 break; |
| 3040 } |
| 3041 } |
3017 } | 3042 } |
3018 | 3043 |
3019 /// Register [type] as required for the runtime type information system. | 3044 /// Register [type] as required for the runtime type information system. |
3020 void registerRequiredType(DartType type) { | 3045 void registerRequiredType(DartType type) { |
3021 // If [argument] has type variables or is a type variable, this method | 3046 // If [argument] has type variables or is a type variable, this method |
3022 // registers a RTI dependency between the class where the type variable is | 3047 // registers a RTI dependency between the class where the type variable is |
3023 // defined (that is the enclosing class of the current element being | 3048 // defined (that is the enclosing class of the current element being |
3024 // resolved) and the class of [type]. If the class of [type] requires RTI, | 3049 // resolved) and the class of [type]. If the class of [type] requires RTI, |
3025 // then the class of the type variable does too. | 3050 // then the class of the type variable does too. |
3026 ClassElement contextClass = Types.getClassContext(type); | 3051 ClassElement contextClass = Types.getClassContext(type); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3098 // We will neeed to add the "$is" and "$as" properties on the | 3123 // We will neeed to add the "$is" and "$as" properties on the |
3099 // JavaScript object prototype, so we make sure | 3124 // JavaScript object prototype, so we make sure |
3100 // [:defineProperty:] is compiled. | 3125 // [:defineProperty:] is compiled. |
3101 registerBackendImpact(transformed, impacts.nativeTypeCheck); | 3126 registerBackendImpact(transformed, impacts.nativeTypeCheck); |
3102 } | 3127 } |
3103 } | 3128 } |
3104 | 3129 |
3105 @override | 3130 @override |
3106 WorldImpact transformCodegenImpact(CodegenImpact impact) { | 3131 WorldImpact transformCodegenImpact(CodegenImpact impact) { |
3107 TransformedWorldImpact transformed = new TransformedWorldImpact(impact); | 3132 TransformedWorldImpact transformed = new TransformedWorldImpact(impact); |
3108 EagerRegistry registry = impact.registry; | |
3109 Enqueuer world = registry.world; | |
3110 | 3133 |
3111 for (TypeUse typeUse in impact.typeUses) { | 3134 for (TypeUse typeUse in impact.typeUses) { |
3112 DartType type = typeUse.type; | 3135 DartType type = typeUse.type; |
3113 switch (typeUse.kind) { | 3136 switch (typeUse.kind) { |
3114 case TypeUseKind.INSTANTIATION: | 3137 case TypeUseKind.INSTANTIATION: |
3115 backend.lookupMapAnalysis.registerInstantiatedType(type, registry); | 3138 backend.lookupMapAnalysis.registerInstantiatedType(type); |
3116 break; | 3139 break; |
3117 case TypeUseKind.IS_CHECK: | 3140 case TypeUseKind.IS_CHECK: |
3118 onIsCheckForCodegen(type, transformed); | 3141 onIsCheckForCodegen(type, transformed); |
3119 break; | 3142 break; |
3120 default: | 3143 default: |
3121 } | 3144 } |
3122 } | 3145 } |
3123 | 3146 |
3124 for (ConstantValue constant in impact.compileTimeConstants) { | 3147 for (ConstantValue constant in impact.compileTimeConstants) { |
3125 backend.registerCompileTimeConstant(constant, registry); | 3148 backend.computeImpactForCompileTimeConstant(constant, transformed, false); |
3126 backend.addCompileTimeConstantForEmission(constant); | 3149 backend.addCompileTimeConstantForEmission(constant); |
3127 } | 3150 } |
3128 | 3151 |
3129 for (Pair<DartType, DartType> check | 3152 for (Pair<DartType, DartType> check |
3130 in impact.typeVariableBoundsSubtypeChecks) { | 3153 in impact.typeVariableBoundsSubtypeChecks) { |
3131 backend.registerTypeVariableBoundsSubtypeCheck(check.a, check.b); | 3154 backend.registerTypeVariableBoundsSubtypeCheck(check.a, check.b); |
3132 } | 3155 } |
3133 | 3156 |
3134 for (StaticUse staticUse in impact.staticUses) { | 3157 for (StaticUse staticUse in impact.staticUses) { |
3135 if (staticUse.kind == StaticUseKind.CLOSURE) { | 3158 if (staticUse.kind == StaticUseKind.CLOSURE) { |
3136 LocalFunctionElement closure = staticUse.element; | 3159 LocalFunctionElement closure = staticUse.element; |
3137 if (backend.methodNeedsRti(closure)) { | 3160 if (backend.methodNeedsRti(closure)) { |
3138 registerBackendImpact(transformed, impacts.computeSignature); | 3161 registerBackendImpact(transformed, impacts.computeSignature); |
3139 } | 3162 } |
3140 } | 3163 } |
3141 } | 3164 } |
3142 | 3165 |
3143 for (String name in impact.constSymbols) { | 3166 for (String name in impact.constSymbols) { |
3144 backend.registerConstSymbol(name); | 3167 backend.registerConstSymbol(name); |
3145 } | 3168 } |
3146 | 3169 |
3147 for (Set<ClassElement> classes in impact.specializedGetInterceptors) { | 3170 for (Set<ClassElement> classes in impact.specializedGetInterceptors) { |
3148 backend.registerSpecializedGetInterceptor(classes); | 3171 backend.registerSpecializedGetInterceptor(classes); |
3149 } | 3172 } |
3150 | 3173 |
3151 if (impact.usesInterceptor) { | 3174 if (impact.usesInterceptor) { |
3152 backend.registerUseInterceptor(world); | 3175 if (backend.codegenEnqueuer.nativeEnqueuer.hasInstantiatedNativeClasses) { |
| 3176 registerBackendImpact(transformed, impacts.interceptorUse); |
| 3177 } |
3153 } | 3178 } |
3154 | 3179 |
3155 for (ClassElement element in impact.typeConstants) { | 3180 for (ClassElement element in impact.typeConstants) { |
3156 backend.customElementsAnalysis.registerTypeConstant(element); | 3181 backend.customElementsAnalysis.registerTypeConstant(element); |
3157 backend.lookupMapAnalysis.registerTypeConstant(element); | 3182 backend.lookupMapAnalysis.registerTypeConstant(element); |
3158 } | 3183 } |
3159 | 3184 |
3160 for (FunctionElement element in impact.asyncMarkers) { | 3185 for (FunctionElement element in impact.asyncMarkers) { |
3161 switch (element.asyncMarker) { | 3186 switch (element.asyncMarker) { |
3162 case AsyncMarker.ASYNC: | 3187 case AsyncMarker.ASYNC: |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3200 | 3225 |
3201 @override | 3226 @override |
3202 void visitImpact(Element element, WorldImpact impact, | 3227 void visitImpact(Element element, WorldImpact impact, |
3203 WorldImpactVisitor visitor, ImpactUseCase impactUse) { | 3228 WorldImpactVisitor visitor, ImpactUseCase impactUse) { |
3204 // TODO(johnniwinther): Compute the application strategy once for each use. | 3229 // TODO(johnniwinther): Compute the application strategy once for each use. |
3205 if (impactUse == ResolutionEnqueuer.IMPACT_USE) { | 3230 if (impactUse == ResolutionEnqueuer.IMPACT_USE) { |
3206 if (supportDeferredLoad || supportSerialization) { | 3231 if (supportDeferredLoad || supportSerialization) { |
3207 impact.apply(visitor); | 3232 impact.apply(visitor); |
3208 } else { | 3233 } else { |
3209 impact.apply(visitor); | 3234 impact.apply(visitor); |
3210 resolution.uncacheWorldImpact(element); | 3235 if (element != null) { |
| 3236 resolution.uncacheWorldImpact(element); |
| 3237 } |
3211 } | 3238 } |
3212 } else if (impactUse == DeferredLoadTask.IMPACT_USE) { | 3239 } else if (impactUse == DeferredLoadTask.IMPACT_USE) { |
3213 impact.apply(visitor); | 3240 impact.apply(visitor); |
3214 // Impacts are uncached globally in [onImpactUsed]. | 3241 // Impacts are uncached globally in [onImpactUsed]. |
3215 } else if (impactUse == DumpInfoTask.IMPACT_USE) { | 3242 } else if (impactUse == DumpInfoTask.IMPACT_USE) { |
3216 impact.apply(visitor); | 3243 impact.apply(visitor); |
3217 dumpInfoTask.unregisterImpact(element); | 3244 dumpInfoTask.unregisterImpact(element); |
3218 } else { | 3245 } else { |
3219 impact.apply(visitor); | 3246 impact.apply(visitor); |
3220 } | 3247 } |
3221 } | 3248 } |
3222 | 3249 |
3223 @override | 3250 @override |
3224 void onImpactUsed(ImpactUseCase impactUse) { | 3251 void onImpactUsed(ImpactUseCase impactUse) { |
3225 if (impactUse == DeferredLoadTask.IMPACT_USE && !supportSerialization) { | 3252 if (impactUse == DeferredLoadTask.IMPACT_USE && !supportSerialization) { |
3226 // TODO(johnniwinther): Allow emptying when serialization has been | 3253 // TODO(johnniwinther): Allow emptying when serialization has been |
3227 // performed. | 3254 // performed. |
3228 resolution.emptyCache(); | 3255 resolution.emptyCache(); |
3229 } | 3256 } |
3230 } | 3257 } |
3231 } | 3258 } |
OLD | NEW |