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 part of js_backend; | 5 part of js_backend; |
6 | 6 |
7 const VERBOSE_OPTIMIZER_HINTS = false; | 7 const VERBOSE_OPTIMIZER_HINTS = false; |
8 | 8 |
9 class JavaScriptItemCompilationContext extends ItemCompilationContext { | 9 class JavaScriptItemCompilationContext extends ItemCompilationContext { |
10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); | 10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 /// True if a core-library function requires the preamble file to function. | 442 /// True if a core-library function requires the preamble file to function. |
443 bool requiresPreamble = false; | 443 bool requiresPreamble = false; |
444 | 444 |
445 /// True if the html library has been loaded. | 445 /// True if the html library has been loaded. |
446 bool htmlLibraryIsLoaded = false; | 446 bool htmlLibraryIsLoaded = false; |
447 | 447 |
448 /// List of constants from metadata. If metadata must be preserved, | 448 /// List of constants from metadata. If metadata must be preserved, |
449 /// these constants must be registered. | 449 /// these constants must be registered. |
450 final List<Dependency> metadataConstants = <Dependency>[]; | 450 final List<Dependency> metadataConstants = <Dependency>[]; |
451 | 451 |
| 452 /// Set of elements for which metadata has been registered as dependencies. |
| 453 final Set<Element> _registeredMetadata = new Set<Element>(); |
| 454 |
452 /// List of elements that the user has requested for reflection. | 455 /// List of elements that the user has requested for reflection. |
453 final Set<Element> targetsUsed = new Set<Element>(); | 456 final Set<Element> targetsUsed = new Set<Element>(); |
454 | 457 |
455 /// List of annotations provided by user that indicate that the annotated | 458 /// List of annotations provided by user that indicate that the annotated |
456 /// element must be retained. | 459 /// element must be retained. |
457 final Set<Element> metaTargetsUsed = new Set<Element>(); | 460 final Set<Element> metaTargetsUsed = new Set<Element>(); |
458 | 461 |
459 /// Set of methods that are needed by reflection. Computed using | 462 /// Set of methods that are needed by reflection. Computed using |
460 /// [computeMembersNeededForReflection] on first use. | 463 /// [computeMembersNeededForReflection] on first use. |
461 Set<Element> _membersNeededForReflection = null; | 464 Set<Element> _membersNeededForReflection = null; |
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1040 // TODO(johnniwinther): Find the right [CallStructure]. | 1043 // TODO(johnniwinther): Find the right [CallStructure]. |
1041 helpers.setRuntimeTypeInfo, | 1044 helpers.setRuntimeTypeInfo, |
1042 null)); | 1045 null)); |
1043 } | 1046 } |
1044 if (type.element == typeImplementation) { | 1047 if (type.element == typeImplementation) { |
1045 // If we use a type literal in a constant, the compile time | 1048 // If we use a type literal in a constant, the compile time |
1046 // constant emitter will generate a call to the createRuntimeType | 1049 // constant emitter will generate a call to the createRuntimeType |
1047 // helper so we register a use of that. | 1050 // helper so we register a use of that. |
1048 registry.registerStaticUse(new StaticUse.staticInvoke( | 1051 registry.registerStaticUse(new StaticUse.staticInvoke( |
1049 // TODO(johnniwinther): Find the right [CallStructure]. | 1052 // TODO(johnniwinther): Find the right [CallStructure]. |
1050 | |
1051 helpers.createRuntimeType, | 1053 helpers.createRuntimeType, |
1052 null)); | 1054 null)); |
1053 } | 1055 } |
1054 } | 1056 } |
1055 } | 1057 } |
1056 | 1058 |
1057 void registerMetadataConstant(MetadataAnnotation metadata, | |
1058 Element annotatedElement, Registry registry) { | |
1059 assert(registry.isForResolution); | |
1060 ConstantValue constant = constants.getConstantValueForMetadata(metadata); | |
1061 registerCompileTimeConstant(constant, registry); | |
1062 metadataConstants.add(new Dependency(constant, annotatedElement)); | |
1063 } | |
1064 | |
1065 void registerInstantiatedClass( | 1059 void registerInstantiatedClass( |
1066 ClassElement cls, Enqueuer enqueuer, Registry registry) { | 1060 ClassElement cls, Enqueuer enqueuer, Registry registry) { |
1067 _processClass(cls, enqueuer, registry); | 1061 _processClass(cls, enqueuer, registry); |
1068 } | 1062 } |
1069 | 1063 |
1070 void registerImplementedClass( | 1064 void registerImplementedClass( |
1071 ClassElement cls, Enqueuer enqueuer, Registry registry) { | 1065 ClassElement cls, Enqueuer enqueuer, Registry registry) { |
1072 _processClass(cls, enqueuer, registry); | 1066 _processClass(cls, enqueuer, registry); |
1073 } | 1067 } |
1074 | 1068 |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1265 enqueueInResolution(traceHelper, registry); | 1259 enqueueInResolution(traceHelper, registry); |
1266 } | 1260 } |
1267 enqueueInResolution(helpers.assertUnreachableMethod, registry); | 1261 enqueueInResolution(helpers.assertUnreachableMethod, registry); |
1268 registerCheckedModeHelpers(registry); | 1262 registerCheckedModeHelpers(registry); |
1269 } | 1263 } |
1270 | 1264 |
1271 onResolutionComplete() { | 1265 onResolutionComplete() { |
1272 super.onResolutionComplete(); | 1266 super.onResolutionComplete(); |
1273 computeMembersNeededForReflection(); | 1267 computeMembersNeededForReflection(); |
1274 rti.computeClassesNeedingRti(); | 1268 rti.computeClassesNeedingRti(); |
| 1269 _registeredMetadata.clear(); |
1275 } | 1270 } |
1276 | 1271 |
1277 onTypeInferenceComplete() { | 1272 onTypeInferenceComplete() { |
1278 super.onTypeInferenceComplete(); | 1273 super.onTypeInferenceComplete(); |
1279 noSuchMethodRegistry.onTypeInferenceComplete(); | 1274 noSuchMethodRegistry.onTypeInferenceComplete(); |
1280 } | 1275 } |
1281 | 1276 |
1282 void registerGetRuntimeTypeArgument(Registry registry) { | 1277 void registerGetRuntimeTypeArgument(Registry registry) { |
1283 enqueueImpact( | 1278 enqueueImpact( |
1284 compiler.enqueuer.resolution, impacts.getRuntimeTypeArgument, registry); | 1279 compiler.enqueuer.resolution, impacts.getRuntimeTypeArgument, registry); |
(...skipping 1012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2297 // necessary, but the backend relies on them being resolved. | 2292 // necessary, but the backend relies on them being resolved. |
2298 enqueuer.enqueueReflectiveStaticFields(_findStaticFieldTargets()); | 2293 enqueuer.enqueueReflectiveStaticFields(_findStaticFieldTargets()); |
2299 } | 2294 } |
2300 | 2295 |
2301 if (mustPreserveNames) reporter.log('Preserving names.'); | 2296 if (mustPreserveNames) reporter.log('Preserving names.'); |
2302 | 2297 |
2303 if (mustRetainMetadata) { | 2298 if (mustRetainMetadata) { |
2304 reporter.log('Retaining metadata.'); | 2299 reporter.log('Retaining metadata.'); |
2305 | 2300 |
2306 compiler.libraryLoader.libraries.forEach(retainMetadataOf); | 2301 compiler.libraryLoader.libraries.forEach(retainMetadataOf); |
2307 for (Dependency dependency in metadataConstants) { | 2302 |
2308 registerCompileTimeConstant(dependency.constant, | 2303 if (enqueuer.isResolutionQueue && !enqueuer.queueIsClosed) { |
2309 new EagerRegistry('EagerRegistry for ${dependency}', enqueuer)); | 2304 /// Register the constant value of [metadata] as live in resolution. |
2310 } | 2305 void registerMetadataConstant(MetadataAnnotation metadata) { |
2311 if (!enqueuer.isResolutionQueue) { | 2306 ConstantValue constant = |
| 2307 constants.getConstantValueForMetadata(metadata); |
| 2308 Dependency dependency = |
| 2309 new Dependency(constant, metadata.annotatedElement); |
| 2310 metadataConstants.add(dependency); |
| 2311 registerCompileTimeConstant(dependency.constant, |
| 2312 new EagerRegistry('EagerRegistry for ${dependency}', enqueuer)); |
| 2313 } |
| 2314 |
| 2315 // TODO(johnniwinther): We should have access to all recently processed |
| 2316 // elements and process these instead. |
| 2317 processMetadata(compiler.enqueuer.resolution.processedElements, |
| 2318 registerMetadataConstant); |
| 2319 } else { |
| 2320 for (Dependency dependency in metadataConstants) { |
| 2321 registerCompileTimeConstant(dependency.constant, |
| 2322 new EagerRegistry('EagerRegistry for ${dependency}', enqueuer)); |
| 2323 } |
2312 metadataConstants.clear(); | 2324 metadataConstants.clear(); |
2313 } | 2325 } |
2314 } | 2326 } |
2315 return true; | 2327 return true; |
2316 } | 2328 } |
2317 | 2329 |
| 2330 /// Call [registerMetadataConstant] on all metadata from [elements]. |
| 2331 void processMetadata(Iterable<Element> elements, |
| 2332 void onMetadata(MetadataAnnotation metadata)) { |
| 2333 void processLibraryMetadata(LibraryElement library) { |
| 2334 if (_registeredMetadata.add(library)) { |
| 2335 library.metadata.forEach(onMetadata); |
| 2336 library.entryCompilationUnit.metadata.forEach(onMetadata); |
| 2337 for (ImportElement import in library.imports) { |
| 2338 import.metadata.forEach(onMetadata); |
| 2339 } |
| 2340 } |
| 2341 } |
| 2342 |
| 2343 void processElementMetadata(Element element) { |
| 2344 if (_registeredMetadata.add(element)) { |
| 2345 element.metadata.forEach(onMetadata); |
| 2346 if (element.isFunction) { |
| 2347 FunctionElement function = element; |
| 2348 for (ParameterElement parameter in function.parameters) { |
| 2349 parameter.metadata.forEach(onMetadata); |
| 2350 } |
| 2351 } |
| 2352 if (element.enclosingClass != null) { |
| 2353 processElementMetadata(element.enclosingClass); |
| 2354 } else { |
| 2355 processLibraryMetadata(element.library); |
| 2356 } |
| 2357 } |
| 2358 } |
| 2359 |
| 2360 elements.forEach(processElementMetadata); |
| 2361 } |
| 2362 |
2318 void onQueueClosed() { | 2363 void onQueueClosed() { |
2319 lookupMapAnalysis.onQueueClosed(); | 2364 lookupMapAnalysis.onQueueClosed(); |
2320 jsInteropAnalysis.onQueueClosed(); | 2365 jsInteropAnalysis.onQueueClosed(); |
2321 } | 2366 } |
2322 | 2367 |
2323 void onCodegenStart() { | 2368 void onCodegenStart() { |
2324 lookupMapAnalysis.onCodegenStart(); | 2369 lookupMapAnalysis.onCodegenStart(); |
2325 } | 2370 } |
2326 | 2371 |
2327 @override | 2372 @override |
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3030 return transformed; | 3075 return transformed; |
3031 } | 3076 } |
3032 } | 3077 } |
3033 | 3078 |
3034 /// Records that [constant] is used by the element behind [registry]. | 3079 /// Records that [constant] is used by the element behind [registry]. |
3035 class Dependency { | 3080 class Dependency { |
3036 final ConstantValue constant; | 3081 final ConstantValue constant; |
3037 final Element annotatedElement; | 3082 final Element annotatedElement; |
3038 | 3083 |
3039 const Dependency(this.constant, this.annotatedElement); | 3084 const Dependency(this.constant, this.annotatedElement); |
| 3085 |
| 3086 String toString() => '$annotatedElement:${constant.toStructuredText()}'; |
3040 } | 3087 } |
3041 | 3088 |
3042 class JavaScriptImpactStrategy extends ImpactStrategy { | 3089 class JavaScriptImpactStrategy extends ImpactStrategy { |
3043 final Resolution resolution; | 3090 final Resolution resolution; |
3044 final DumpInfoTask dumpInfoTask; | 3091 final DumpInfoTask dumpInfoTask; |
3045 final bool supportDeferredLoad; | 3092 final bool supportDeferredLoad; |
3046 final bool supportDumpInfo; | 3093 final bool supportDumpInfo; |
3047 final bool supportSerialization; | 3094 final bool supportSerialization; |
3048 | 3095 |
3049 JavaScriptImpactStrategy(this.resolution, this.dumpInfoTask, | 3096 JavaScriptImpactStrategy(this.resolution, this.dumpInfoTask, |
(...skipping 25 matching lines...) Expand all Loading... |
3075 | 3122 |
3076 @override | 3123 @override |
3077 void onImpactUsed(ImpactUseCase impactUse) { | 3124 void onImpactUsed(ImpactUseCase impactUse) { |
3078 if (impactUse == DeferredLoadTask.IMPACT_USE && !supportSerialization) { | 3125 if (impactUse == DeferredLoadTask.IMPACT_USE && !supportSerialization) { |
3079 // TODO(johnniwinther): Allow emptying when serialization has been | 3126 // TODO(johnniwinther): Allow emptying when serialization has been |
3080 // performed. | 3127 // performed. |
3081 resolution.emptyCache(); | 3128 resolution.emptyCache(); |
3082 } | 3129 } |
3083 } | 3130 } |
3084 } | 3131 } |
OLD | NEW |