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 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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/feature.dart'; | 51 import '../universe/feature.dart'; |
52 import '../universe/world_impact.dart' | 52 import '../universe/world_impact.dart' |
53 show | 53 show |
54 ImpactStrategy, | 54 ImpactStrategy, |
55 ImpactUseCase, | 55 ImpactUseCase, |
56 TransformedWorldImpact, | 56 TransformedWorldImpact, |
57 WorldImpact, | 57 WorldImpact, |
58 WorldImpactVisitor; | 58 WorldImpactBuilder, |
59 WorldImpactVisitor, | |
60 StagedWorldImpactBuilder; | |
59 import '../util/util.dart'; | 61 import '../util/util.dart'; |
60 import '../world.dart' show ClassWorld; | 62 import '../world.dart' show ClassWorld; |
61 import 'backend_helpers.dart'; | 63 import 'backend_helpers.dart'; |
62 import 'backend_impact.dart'; | 64 import 'backend_impact.dart'; |
63 import 'backend_serialization.dart' show JavaScriptBackendSerialization; | 65 import 'backend_serialization.dart' show JavaScriptBackendSerialization; |
64 import 'checked_mode_helpers.dart'; | 66 import 'checked_mode_helpers.dart'; |
65 import 'constant_handler_javascript.dart'; | 67 import 'constant_handler_javascript.dart'; |
66 import 'custom_elements_analysis.dart'; | 68 import 'custom_elements_analysis.dart'; |
67 import 'enqueuer.dart'; | 69 import 'enqueuer.dart'; |
68 import 'js_interop_analysis.dart' show JsInteropAnalysis; | 70 import 'js_interop_analysis.dart' show JsInteropAnalysis; |
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
569 JavaScriptImpactTransformer impactTransformer; | 571 JavaScriptImpactTransformer impactTransformer; |
570 | 572 |
571 PatchResolverTask patchResolverTask; | 573 PatchResolverTask patchResolverTask; |
572 | 574 |
573 bool enabledNoSuchMethod = false; | 575 bool enabledNoSuchMethod = false; |
574 | 576 |
575 SourceInformationStrategy sourceInformationStrategy; | 577 SourceInformationStrategy sourceInformationStrategy; |
576 | 578 |
577 JavaScriptBackendSerialization serialization; | 579 JavaScriptBackendSerialization serialization; |
578 | 580 |
581 StagedWorldImpactBuilder constantImpactsForResolution = | |
582 new StagedWorldImpactBuilder(); | |
583 | |
584 StagedWorldImpactBuilder constantImpactsForCodegen = | |
585 new StagedWorldImpactBuilder(); | |
586 | |
579 final NativeData nativeData = new NativeData(); | 587 final NativeData nativeData = new NativeData(); |
580 | 588 |
581 final BackendHelpers helpers; | 589 final BackendHelpers helpers; |
582 final BackendImpacts impacts; | 590 final BackendImpacts impacts; |
583 | 591 |
584 final JSFrontendAccess frontend; | 592 final JSFrontendAccess frontend; |
585 | 593 |
586 JavaScriptBackend(Compiler compiler, | 594 JavaScriptBackend(Compiler compiler, |
587 {bool generateSourceMap: true, | 595 {bool generateSourceMap: true, |
588 bool useStartupEmitter: false, | 596 bool useStartupEmitter: false, |
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1053 jsAst.Name name = namer.nameForGetInterceptor(classes); | 1061 jsAst.Name name = namer.nameForGetInterceptor(classes); |
1054 if (classes.contains(helpers.jsInterceptorClass)) { | 1062 if (classes.contains(helpers.jsInterceptorClass)) { |
1055 // We can't use a specialized [getInterceptorMethod], so we make | 1063 // We can't use a specialized [getInterceptorMethod], so we make |
1056 // sure we emit the one with all checks. | 1064 // sure we emit the one with all checks. |
1057 specializedGetInterceptors[name] = interceptedClasses; | 1065 specializedGetInterceptors[name] = interceptedClasses; |
1058 } else { | 1066 } else { |
1059 specializedGetInterceptors[name] = classes; | 1067 specializedGetInterceptors[name] = classes; |
1060 } | 1068 } |
1061 } | 1069 } |
1062 | 1070 |
1063 void registerCompileTimeConstant(ConstantValue constant, Registry registry) { | 1071 void computeImpactForCompileTimeConstant(ConstantValue constant, |
1064 registerCompileTimeConstantInternal(constant, registry); | 1072 WorldImpactBuilder impactBuilder, bool isForResolution) { |
1073 computeImpactForCompileTimeConstantInternal( | |
1074 constant, impactBuilder, isForResolution); | |
1065 | 1075 |
1066 if (!registry.isForResolution && lookupMapAnalysis.isLookupMap(constant)) { | 1076 if (!isForResolution && lookupMapAnalysis.isLookupMap(constant)) { |
1067 // Note: internally, this registration will temporarily remove the | 1077 // Note: internally, this registration will temporarily remove the |
1068 // constant dependencies and add them later on-demand. | 1078 // constant dependencies and add them later on-demand. |
1069 lookupMapAnalysis.registerLookupMapReference(constant); | 1079 lookupMapAnalysis.registerLookupMapReference(constant); |
1070 } | 1080 } |
1071 | 1081 |
1072 for (ConstantValue dependency in constant.getDependencies()) { | 1082 for (ConstantValue dependency in constant.getDependencies()) { |
1073 registerCompileTimeConstant(dependency, registry); | 1083 computeImpactForCompileTimeConstant( |
1084 dependency, impactBuilder, isForResolution); | |
1074 } | 1085 } |
1075 } | 1086 } |
1076 | 1087 |
1077 void addCompileTimeConstantForEmission(ConstantValue constant) { | 1088 void addCompileTimeConstantForEmission(ConstantValue constant) { |
1078 constants.addCompileTimeConstantForEmission(constant); | 1089 constants.addCompileTimeConstantForEmission(constant); |
1079 } | 1090 } |
1080 | 1091 |
1081 void registerCompileTimeConstantInternal( | 1092 void computeImpactForCompileTimeConstantInternal(ConstantValue constant, |
1082 ConstantValue constant, Registry registry) { | 1093 WorldImpactBuilder impactBuilder, bool isForResolution) { |
1083 DartType type = constant.getType(compiler.coreTypes); | 1094 DartType type = constant.getType(compiler.coreTypes); |
1084 registerInstantiatedConstantType(type, registry); | 1095 computeImpactForInstantiatedConstantType(type, impactBuilder); |
1085 | 1096 |
1086 if (constant.isFunction) { | 1097 if (constant.isFunction) { |
1087 FunctionConstantValue function = constant; | 1098 FunctionConstantValue function = constant; |
1088 registry.registerStaticUse(new StaticUse.staticTearOff(function.element)); | 1099 impactBuilder |
1100 .registerStaticUse(new StaticUse.staticTearOff(function.element)); | |
1089 } else if (constant.isInterceptor) { | 1101 } else if (constant.isInterceptor) { |
1090 // An interceptor constant references the class's prototype chain. | 1102 // An interceptor constant references the class's prototype chain. |
1091 InterceptorConstantValue interceptor = constant; | 1103 InterceptorConstantValue interceptor = constant; |
1092 registerInstantiatedConstantType(interceptor.dispatchedType, registry); | 1104 computeImpactForInstantiatedConstantType( |
1105 interceptor.dispatchedType, impactBuilder); | |
1093 } else if (constant.isType) { | 1106 } else if (constant.isType) { |
1094 enqueueInResolution(helpers.createRuntimeType, registry); | 1107 if (isForResolution) { |
1095 registry.registerInstantiation(typeImplementation.rawType); | 1108 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
1109 // TODO(johnniwinther): Find the right [CallStructure]. | |
1110 helpers.createRuntimeType, | |
1111 null)); | |
1112 registerBackendUse(helpers.createRuntimeType); | |
1113 } | |
1114 impactBuilder.registerTypeUse( | |
1115 new TypeUse.instantiation(typeImplementation.rawType)); | |
1096 } | 1116 } |
1097 lookupMapAnalysis.registerConstantKey(constant); | 1117 lookupMapAnalysis.registerConstantKey(constant); |
1098 } | 1118 } |
1099 | 1119 |
1100 void registerInstantiatedConstantType(DartType type, Registry registry) { | 1120 void computeImpactForInstantiatedConstantType( |
1121 DartType type, WorldImpactBuilder impactBuilder) { | |
1101 DartType instantiatedType = | 1122 DartType instantiatedType = |
1102 type.isFunctionType ? coreTypes.functionType : type; | 1123 type.isFunctionType ? coreTypes.functionType : type; |
1103 if (type is InterfaceType) { | 1124 if (type is InterfaceType) { |
1104 registry.registerInstantiation(instantiatedType); | 1125 impactBuilder |
1126 .registerTypeUse(new TypeUse.instantiation(instantiatedType)); | |
1105 if (!type.treatAsRaw && classNeedsRti(type.element)) { | 1127 if (!type.treatAsRaw && classNeedsRti(type.element)) { |
1106 registry.registerStaticUse(new StaticUse.staticInvoke( | 1128 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
1107 // TODO(johnniwinther): Find the right [CallStructure]. | 1129 // TODO(johnniwinther): Find the right [CallStructure]. |
1108 helpers.setRuntimeTypeInfo, | 1130 helpers.setRuntimeTypeInfo, |
1109 null)); | 1131 null)); |
1110 } | 1132 } |
1111 if (type.element == typeImplementation) { | 1133 if (type.element == typeImplementation) { |
1112 // If we use a type literal in a constant, the compile time | 1134 // If we use a type literal in a constant, the compile time |
1113 // constant emitter will generate a call to the createRuntimeType | 1135 // constant emitter will generate a call to the createRuntimeType |
1114 // helper so we register a use of that. | 1136 // helper so we register a use of that. |
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.createRuntimeType, | 1139 helpers.createRuntimeType, |
1118 null)); | 1140 null)); |
1119 } | 1141 } |
1120 } | 1142 } |
1121 } | 1143 } |
1122 | 1144 |
1123 void registerInstantiatedClass( | 1145 void registerInstantiatedClass( |
1124 ClassElement cls, Enqueuer enqueuer, Registry registry) { | 1146 ClassElement cls, Enqueuer enqueuer, Registry registry) { |
1125 _processClass(cls, enqueuer, registry); | 1147 _processClass(cls, enqueuer, registry); |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1274 | 1296 |
1275 customElementsAnalysis.registerInstantiatedClass(cls, enqueuer); | 1297 customElementsAnalysis.registerInstantiatedClass(cls, enqueuer); |
1276 if (!enqueuer.isResolutionQueue) { | 1298 if (!enqueuer.isResolutionQueue) { |
1277 lookupMapAnalysis.registerInstantiatedClass(cls); | 1299 lookupMapAnalysis.registerInstantiatedClass(cls); |
1278 } | 1300 } |
1279 } | 1301 } |
1280 | 1302 |
1281 void registerInstantiatedType( | 1303 void registerInstantiatedType( |
1282 InterfaceType type, Enqueuer enqueuer, Registry registry, | 1304 InterfaceType type, Enqueuer enqueuer, Registry registry, |
1283 {bool mirrorUsage: false}) { | 1305 {bool mirrorUsage: false}) { |
1284 lookupMapAnalysis.registerInstantiatedType(type, registry); | 1306 lookupMapAnalysis.registerInstantiatedType(type); |
1285 super.registerInstantiatedType(type, enqueuer, registry, | 1307 super.registerInstantiatedType(type, enqueuer, registry, |
1286 mirrorUsage: mirrorUsage); | 1308 mirrorUsage: mirrorUsage); |
1287 } | 1309 } |
1288 | 1310 |
1289 void registerUseInterceptor(Enqueuer enqueuer) { | |
1290 assert(!enqueuer.isResolutionQueue); | |
1291 if (!enqueuer.nativeEnqueuer.hasInstantiatedNativeClasses()) return; | |
1292 Registry registry = compiler.globalDependencies; | |
1293 enqueue(enqueuer, helpers.getNativeInterceptorMethod, registry); | |
1294 enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass, registry); | |
1295 enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass, registry); | |
1296 enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass, registry); | |
1297 needToInitializeIsolateAffinityTag = true; | |
1298 needToInitializeDispatchProperty = true; | |
1299 } | |
1300 | |
1301 void enqueueHelpers(ResolutionEnqueuer world, Registry registry) { | 1311 void enqueueHelpers(ResolutionEnqueuer world, Registry registry) { |
1302 assert(helpers.interceptorsLibrary != null); | 1312 assert(helpers.interceptorsLibrary != null); |
1303 // TODO(ngeoffray): Not enqueuing those two classes currently make | 1313 // TODO(ngeoffray): Not enqueuing those two classes currently make |
1304 // the compiler potentially crash. However, any reasonable program | 1314 // the compiler potentially crash. However, any reasonable program |
1305 // will instantiate those two classes. | 1315 // will instantiate those two classes. |
1306 addInterceptors(helpers.jsBoolClass, world, registry); | 1316 addInterceptors(helpers.jsBoolClass, world, registry); |
1307 addInterceptors(helpers.jsNullClass, world, registry); | 1317 addInterceptors(helpers.jsNullClass, world, registry); |
1308 if (compiler.options.enableTypeAssertions) { | 1318 if (compiler.options.enableTypeAssertions) { |
1309 // Unconditionally register the helper that checks if the | 1319 // Unconditionally register the helper that checks if the |
1310 // expression in an if/while/for is a boolean. | 1320 // expression in an if/while/for is a boolean. |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1583 element.enclosingClass == helpers.jsNullClass) { | 1593 element.enclosingClass == helpers.jsNullClass) { |
1584 // Work around a problem compiling JSNull's constructor. | 1594 // Work around a problem compiling JSNull's constructor. |
1585 return const CodegenImpact(); | 1595 return const CodegenImpact(); |
1586 } | 1596 } |
1587 if (kind.category == ElementCategory.VARIABLE) { | 1597 if (kind.category == ElementCategory.VARIABLE) { |
1588 VariableElement variableElement = element; | 1598 VariableElement variableElement = element; |
1589 ConstantExpression constant = variableElement.constant; | 1599 ConstantExpression constant = variableElement.constant; |
1590 if (constant != null) { | 1600 if (constant != null) { |
1591 ConstantValue initialValue = constants.getConstantValue(constant); | 1601 ConstantValue initialValue = constants.getConstantValue(constant); |
1592 if (initialValue != null) { | 1602 if (initialValue != null) { |
1593 registerCompileTimeConstant(initialValue, work.registry); | 1603 computeImpactForCompileTimeConstant( |
1604 initialValue, work.registry.worldImpact, false); | |
1594 addCompileTimeConstantForEmission(initialValue); | 1605 addCompileTimeConstantForEmission(initialValue); |
1595 // We don't need to generate code for static or top-level | 1606 // We don't need to generate code for static or top-level |
1596 // variables. For instance variables, we may need to generate | 1607 // variables. For instance variables, we may need to generate |
1597 // the checked setter. | 1608 // the checked setter. |
1598 if (Elements.isStaticOrTopLevel(element)) { | 1609 if (Elements.isStaticOrTopLevel(element)) { |
1599 return impactTransformer | 1610 return impactTransformer |
1600 .transformCodegenImpact(work.registry.worldImpact); | 1611 .transformCodegenImpact(work.registry.worldImpact); |
1601 } | 1612 } |
1602 } else { | 1613 } else { |
1603 assert(invariant( | 1614 assert(invariant( |
(...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2330 staticFields.add(target); | 2341 staticFields.add(target); |
2331 } else if (target.isLibrary || target.isClass) { | 2342 } else if (target.isLibrary || target.isClass) { |
2332 addFieldsInContainer(target); | 2343 addFieldsInContainer(target); |
2333 } | 2344 } |
2334 } | 2345 } |
2335 return staticFields; | 2346 return staticFields; |
2336 } | 2347 } |
2337 | 2348 |
2338 /// Called when [enqueuer] is empty, but before it is closed. | 2349 /// Called when [enqueuer] is empty, but before it is closed. |
2339 bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassElement> recentClasses) { | 2350 bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassElement> recentClasses) { |
2340 if (!compiler.options.resolveOnly) { | 2351 // Add elements used synthetically, that is, through features rather than |
2341 // TODO(johnniwinther): The custom element analysis eagerly enqueues | 2352 // syntax, for instance custom elements. |
2342 // elements on the codegen queue. Change to compute the data needed | 2353 // |
2343 // instead. | 2354 // Return early if any elements are added to avoid counting the elements as |
2355 // due to mirrors. | |
2356 customElementsAnalysis.onQueueEmpty(enqueuer); | |
2357 lookupMapAnalysis.onQueueEmpty(enqueuer); | |
2358 typeVariableHandler.onQueueEmpty(enqueuer); | |
2344 | 2359 |
2345 // Add elements referenced only via custom elements. Return early if any | |
2346 // elements are added to avoid counting the elements as due to mirrors. | |
2347 customElementsAnalysis.onQueueEmpty(enqueuer); | |
2348 } | |
2349 if (!enqueuer.queueIsEmpty) return false; | 2360 if (!enqueuer.queueIsEmpty) return false; |
2350 | 2361 |
2351 noSuchMethodRegistry.onQueueEmpty(); | 2362 noSuchMethodRegistry.onQueueEmpty(); |
2352 if (!enabledNoSuchMethod && | 2363 if (!enabledNoSuchMethod && |
2353 (noSuchMethodRegistry.hasThrowingNoSuchMethod || | 2364 (noSuchMethodRegistry.hasThrowingNoSuchMethod || |
2354 noSuchMethodRegistry.hasComplexNoSuchMethod)) { | 2365 noSuchMethodRegistry.hasComplexNoSuchMethod)) { |
2355 enableNoSuchMethod(enqueuer); | 2366 enableNoSuchMethod(enqueuer); |
2356 enabledNoSuchMethod = true; | 2367 enabledNoSuchMethod = true; |
2357 } | 2368 } |
2358 | 2369 |
(...skipping 19 matching lines...) Expand all Loading... | |
2378 enqueuer.enqueueReflectiveStaticFields(_findStaticFieldTargets()); | 2389 enqueuer.enqueueReflectiveStaticFields(_findStaticFieldTargets()); |
2379 } | 2390 } |
2380 | 2391 |
2381 if (mustPreserveNames) reporter.log('Preserving names.'); | 2392 if (mustPreserveNames) reporter.log('Preserving names.'); |
2382 | 2393 |
2383 if (mustRetainMetadata) { | 2394 if (mustRetainMetadata) { |
2384 reporter.log('Retaining metadata.'); | 2395 reporter.log('Retaining metadata.'); |
2385 | 2396 |
2386 compiler.libraryLoader.libraries.forEach(retainMetadataOf); | 2397 compiler.libraryLoader.libraries.forEach(retainMetadataOf); |
2387 | 2398 |
2399 StagedWorldImpactBuilder impactBuilder = enqueuer.isResolutionQueue | |
2400 ? constantImpactsForResolution | |
2401 : constantImpactsForResolution; | |
2388 if (enqueuer.isResolutionQueue && !enqueuer.queueIsClosed) { | 2402 if (enqueuer.isResolutionQueue && !enqueuer.queueIsClosed) { |
2389 /// Register the constant value of [metadata] as live in resolution. | 2403 /// Register the constant value of [metadata] as live in resolution. |
2390 void registerMetadataConstant(MetadataAnnotation metadata) { | 2404 void registerMetadataConstant(MetadataAnnotation metadata) { |
2391 ConstantValue constant = | 2405 ConstantValue constant = |
2392 constants.getConstantValueForMetadata(metadata); | 2406 constants.getConstantValueForMetadata(metadata); |
2393 Dependency dependency = | 2407 Dependency dependency = |
2394 new Dependency(constant, metadata.annotatedElement); | 2408 new Dependency(constant, metadata.annotatedElement); |
2395 metadataConstants.add(dependency); | 2409 metadataConstants.add(dependency); |
2396 registerCompileTimeConstant(dependency.constant, | 2410 computeImpactForCompileTimeConstant( |
2397 new EagerRegistry('EagerRegistry for ${dependency}', enqueuer)); | 2411 dependency.constant, impactBuilder, enqueuer.isResolutionQueue); |
Harry Terkelsen
2016/09/19 21:17:52
enqueuer.isResolutionQueue -> true?
| |
2398 } | 2412 } |
2399 | 2413 |
2400 // TODO(johnniwinther): We should have access to all recently processed | 2414 // TODO(johnniwinther): We should have access to all recently processed |
2401 // elements and process these instead. | 2415 // elements and process these instead. |
2402 processMetadata(compiler.enqueuer.resolution.processedElements, | 2416 processMetadata(compiler.enqueuer.resolution.processedElements, |
2403 registerMetadataConstant); | 2417 registerMetadataConstant); |
2404 } else { | 2418 } else { |
2405 for (Dependency dependency in metadataConstants) { | 2419 for (Dependency dependency in metadataConstants) { |
2406 registerCompileTimeConstant(dependency.constant, | 2420 computeImpactForCompileTimeConstant( |
2407 new EagerRegistry('EagerRegistry for ${dependency}', enqueuer)); | 2421 dependency.constant, impactBuilder, enqueuer.isResolutionQueue); |
Harry Terkelsen
2016/09/19 21:17:52
enqueuer.isResolutionQueue -> false?
| |
2408 } | 2422 } |
2409 metadataConstants.clear(); | 2423 metadataConstants.clear(); |
2410 } | 2424 } |
2425 enqueuer.applyImpact(null, impactBuilder.flush()); | |
2411 } | 2426 } |
2412 return true; | 2427 return true; |
2413 } | 2428 } |
2414 | 2429 |
2415 /// Call [registerMetadataConstant] on all metadata from [elements]. | 2430 /// Call [registerMetadataConstant] on all metadata from [elements]. |
2416 void processMetadata(Iterable<Element> elements, | 2431 void processMetadata(Iterable<Element> elements, |
2417 void onMetadata(MetadataAnnotation metadata)) { | 2432 void onMetadata(MetadataAnnotation metadata)) { |
2418 void processLibraryMetadata(LibraryElement library) { | 2433 void processLibraryMetadata(LibraryElement library) { |
2419 if (_registeredMetadata.add(library)) { | 2434 if (_registeredMetadata.add(library)) { |
2420 library.metadata.forEach(onMetadata); | 2435 library.metadata.forEach(onMetadata); |
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3073 // We will neeed to add the "$is" and "$as" properties on the | 3088 // We will neeed to add the "$is" and "$as" properties on the |
3074 // JavaScript object prototype, so we make sure | 3089 // JavaScript object prototype, so we make sure |
3075 // [:defineProperty:] is compiled. | 3090 // [:defineProperty:] is compiled. |
3076 registerBackendImpact(transformed, impacts.nativeTypeCheck); | 3091 registerBackendImpact(transformed, impacts.nativeTypeCheck); |
3077 } | 3092 } |
3078 } | 3093 } |
3079 | 3094 |
3080 @override | 3095 @override |
3081 WorldImpact transformCodegenImpact(CodegenImpact impact) { | 3096 WorldImpact transformCodegenImpact(CodegenImpact impact) { |
3082 TransformedWorldImpact transformed = new TransformedWorldImpact(impact); | 3097 TransformedWorldImpact transformed = new TransformedWorldImpact(impact); |
3083 EagerRegistry registry = impact.registry; | |
3084 Enqueuer world = registry.world; | |
3085 | 3098 |
3086 for (TypeUse typeUse in impact.typeUses) { | 3099 for (TypeUse typeUse in impact.typeUses) { |
3087 DartType type = typeUse.type; | 3100 DartType type = typeUse.type; |
3088 switch (typeUse.kind) { | 3101 switch (typeUse.kind) { |
3089 case TypeUseKind.INSTANTIATION: | 3102 case TypeUseKind.INSTANTIATION: |
3090 backend.lookupMapAnalysis.registerInstantiatedType(type, registry); | 3103 backend.lookupMapAnalysis.registerInstantiatedType(type); |
3091 break; | 3104 break; |
3092 case TypeUseKind.IS_CHECK: | 3105 case TypeUseKind.IS_CHECK: |
3093 onIsCheckForCodegen(type, transformed); | 3106 onIsCheckForCodegen(type, transformed); |
3094 break; | 3107 break; |
3095 default: | 3108 default: |
3096 } | 3109 } |
3097 } | 3110 } |
3098 | 3111 |
3099 for (ConstantValue constant in impact.compileTimeConstants) { | 3112 for (ConstantValue constant in impact.compileTimeConstants) { |
3100 backend.registerCompileTimeConstant(constant, registry); | 3113 backend.computeImpactForCompileTimeConstant(constant, transformed, false); |
3101 backend.addCompileTimeConstantForEmission(constant); | 3114 backend.addCompileTimeConstantForEmission(constant); |
3102 } | 3115 } |
3103 | 3116 |
3104 for (Pair<DartType, DartType> check | 3117 for (Pair<DartType, DartType> check |
3105 in impact.typeVariableBoundsSubtypeChecks) { | 3118 in impact.typeVariableBoundsSubtypeChecks) { |
3106 backend.registerTypeVariableBoundsSubtypeCheck(check.a, check.b); | 3119 backend.registerTypeVariableBoundsSubtypeCheck(check.a, check.b); |
3107 } | 3120 } |
3108 | 3121 |
3109 for (StaticUse staticUse in impact.staticUses) { | 3122 for (StaticUse staticUse in impact.staticUses) { |
3110 if (staticUse.kind == StaticUseKind.CLOSURE) { | 3123 if (staticUse.kind == StaticUseKind.CLOSURE) { |
3111 LocalFunctionElement closure = staticUse.element; | 3124 LocalFunctionElement closure = staticUse.element; |
3112 if (backend.methodNeedsRti(closure)) { | 3125 if (backend.methodNeedsRti(closure)) { |
3113 registerBackendImpact(transformed, impacts.computeSignature); | 3126 registerBackendImpact(transformed, impacts.computeSignature); |
3114 } | 3127 } |
3115 } | 3128 } |
3116 } | 3129 } |
3117 | 3130 |
3118 for (String name in impact.constSymbols) { | 3131 for (String name in impact.constSymbols) { |
3119 backend.registerConstSymbol(name); | 3132 backend.registerConstSymbol(name); |
3120 } | 3133 } |
3121 | 3134 |
3122 for (Set<ClassElement> classes in impact.specializedGetInterceptors) { | 3135 for (Set<ClassElement> classes in impact.specializedGetInterceptors) { |
3123 backend.registerSpecializedGetInterceptor(classes); | 3136 backend.registerSpecializedGetInterceptor(classes); |
3124 } | 3137 } |
3125 | 3138 |
3126 if (impact.usesInterceptor) { | 3139 if (impact.usesInterceptor) { |
3127 backend.registerUseInterceptor(world); | 3140 if (backend.codegenEnqueuer.nativeEnqueuer.hasInstantiatedNativeClasses) { |
3141 registerBackendImpact(transformed, impacts.interceptorUse); | |
3142 } | |
3128 } | 3143 } |
3129 | 3144 |
3130 for (ClassElement element in impact.typeConstants) { | 3145 for (ClassElement element in impact.typeConstants) { |
3131 backend.customElementsAnalysis.registerTypeConstant(element); | 3146 backend.customElementsAnalysis.registerTypeConstant(element); |
3132 backend.lookupMapAnalysis.registerTypeConstant(element); | 3147 backend.lookupMapAnalysis.registerTypeConstant(element); |
3133 } | 3148 } |
3134 | 3149 |
3135 for (FunctionElement element in impact.asyncMarkers) { | 3150 for (FunctionElement element in impact.asyncMarkers) { |
3136 switch (element.asyncMarker) { | 3151 switch (element.asyncMarker) { |
3137 case AsyncMarker.ASYNC: | 3152 case AsyncMarker.ASYNC: |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3175 | 3190 |
3176 @override | 3191 @override |
3177 void visitImpact(Element element, WorldImpact impact, | 3192 void visitImpact(Element element, WorldImpact impact, |
3178 WorldImpactVisitor visitor, ImpactUseCase impactUse) { | 3193 WorldImpactVisitor visitor, ImpactUseCase impactUse) { |
3179 // TODO(johnniwinther): Compute the application strategy once for each use. | 3194 // TODO(johnniwinther): Compute the application strategy once for each use. |
3180 if (impactUse == ResolutionEnqueuer.IMPACT_USE) { | 3195 if (impactUse == ResolutionEnqueuer.IMPACT_USE) { |
3181 if (supportDeferredLoad || supportSerialization) { | 3196 if (supportDeferredLoad || supportSerialization) { |
3182 impact.apply(visitor); | 3197 impact.apply(visitor); |
3183 } else { | 3198 } else { |
3184 impact.apply(visitor); | 3199 impact.apply(visitor); |
3185 resolution.uncacheWorldImpact(element); | 3200 if (element != null) { |
3201 resolution.uncacheWorldImpact(element); | |
3202 } | |
3186 } | 3203 } |
3187 } else if (impactUse == DeferredLoadTask.IMPACT_USE) { | 3204 } else if (impactUse == DeferredLoadTask.IMPACT_USE) { |
3188 impact.apply(visitor); | 3205 impact.apply(visitor); |
3189 // Impacts are uncached globally in [onImpactUsed]. | 3206 // Impacts are uncached globally in [onImpactUsed]. |
3190 } else if (impactUse == DumpInfoTask.IMPACT_USE) { | 3207 } else if (impactUse == DumpInfoTask.IMPACT_USE) { |
3191 impact.apply(visitor); | 3208 impact.apply(visitor); |
3192 dumpInfoTask.unregisterImpact(element); | 3209 dumpInfoTask.unregisterImpact(element); |
3193 } else { | 3210 } else { |
3194 impact.apply(visitor); | 3211 impact.apply(visitor); |
3195 } | 3212 } |
3196 } | 3213 } |
3197 | 3214 |
3198 @override | 3215 @override |
3199 void onImpactUsed(ImpactUseCase impactUse) { | 3216 void onImpactUsed(ImpactUseCase impactUse) { |
3200 if (impactUse == DeferredLoadTask.IMPACT_USE && !supportSerialization) { | 3217 if (impactUse == DeferredLoadTask.IMPACT_USE && !supportSerialization) { |
3201 // TODO(johnniwinther): Allow emptying when serialization has been | 3218 // TODO(johnniwinther): Allow emptying when serialization has been |
3202 // performed. | 3219 // performed. |
3203 resolution.emptyCache(); | 3220 resolution.emptyCache(); |
3204 } | 3221 } |
3205 } | 3222 } |
3206 } | 3223 } |
OLD | NEW |