| 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 |