Index: pkg/compiler/lib/src/js_backend/backend.dart |
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart |
index 6650db7073f640499f6ff8f9ff370efa784db55b..0aac614d313ebb5a3c1773309173abb1ca2d4b40 100644 |
--- a/pkg/compiler/lib/src/js_backend/backend.dart |
+++ b/pkg/compiler/lib/src/js_backend/backend.dart |
@@ -55,7 +55,9 @@ import '../universe/world_impact.dart' |
ImpactUseCase, |
TransformedWorldImpact, |
WorldImpact, |
- WorldImpactVisitor; |
+ WorldImpactBuilder, |
+ WorldImpactVisitor, |
+ StagedWorldImpactBuilder; |
import '../util/util.dart'; |
import '../world.dart' show ClassWorld; |
import 'backend_helpers.dart'; |
@@ -576,6 +578,12 @@ class JavaScriptBackend extends Backend { |
JavaScriptBackendSerialization serialization; |
+ StagedWorldImpactBuilder constantImpactsForResolution = |
+ new StagedWorldImpactBuilder(); |
+ |
+ StagedWorldImpactBuilder constantImpactsForCodegen = |
+ new StagedWorldImpactBuilder(); |
+ |
final NativeData nativeData = new NativeData(); |
final BackendHelpers helpers; |
@@ -1060,17 +1068,20 @@ class JavaScriptBackend extends Backend { |
} |
} |
- void registerCompileTimeConstant(ConstantValue constant, Registry registry) { |
- registerCompileTimeConstantInternal(constant, registry); |
+ void computeImpactForCompileTimeConstant(ConstantValue constant, |
+ WorldImpactBuilder impactBuilder, bool isForResolution) { |
+ computeImpactForCompileTimeConstantInternal( |
+ constant, impactBuilder, isForResolution); |
- if (!registry.isForResolution && lookupMapAnalysis.isLookupMap(constant)) { |
+ if (!isForResolution && lookupMapAnalysis.isLookupMap(constant)) { |
// Note: internally, this registration will temporarily remove the |
// constant dependencies and add them later on-demand. |
lookupMapAnalysis.registerLookupMapReference(constant); |
} |
for (ConstantValue dependency in constant.getDependencies()) { |
- registerCompileTimeConstant(dependency, registry); |
+ computeImpactForCompileTimeConstant( |
+ dependency, impactBuilder, isForResolution); |
} |
} |
@@ -1078,32 +1089,43 @@ class JavaScriptBackend extends Backend { |
constants.addCompileTimeConstantForEmission(constant); |
} |
- void registerCompileTimeConstantInternal( |
- ConstantValue constant, Registry registry) { |
+ void computeImpactForCompileTimeConstantInternal(ConstantValue constant, |
+ WorldImpactBuilder impactBuilder, bool isForResolution) { |
DartType type = constant.getType(compiler.coreTypes); |
- registerInstantiatedConstantType(type, registry); |
+ computeImpactForInstantiatedConstantType(type, impactBuilder); |
if (constant.isFunction) { |
FunctionConstantValue function = constant; |
- registry.registerStaticUse(new StaticUse.staticTearOff(function.element)); |
+ impactBuilder |
+ .registerStaticUse(new StaticUse.staticTearOff(function.element)); |
} else if (constant.isInterceptor) { |
// An interceptor constant references the class's prototype chain. |
InterceptorConstantValue interceptor = constant; |
- registerInstantiatedConstantType(interceptor.dispatchedType, registry); |
+ computeImpactForInstantiatedConstantType( |
+ interceptor.dispatchedType, impactBuilder); |
} else if (constant.isType) { |
- enqueueInResolution(helpers.createRuntimeType, registry); |
- registry.registerInstantiation(typeImplementation.rawType); |
+ if (isForResolution) { |
+ impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
+ // TODO(johnniwinther): Find the right [CallStructure]. |
+ helpers.createRuntimeType, |
+ null)); |
+ registerBackendUse(helpers.createRuntimeType); |
+ } |
+ impactBuilder.registerTypeUse( |
+ new TypeUse.instantiation(typeImplementation.rawType)); |
} |
lookupMapAnalysis.registerConstantKey(constant); |
} |
- void registerInstantiatedConstantType(DartType type, Registry registry) { |
+ void computeImpactForInstantiatedConstantType( |
+ DartType type, WorldImpactBuilder impactBuilder) { |
DartType instantiatedType = |
type.isFunctionType ? coreTypes.functionType : type; |
if (type is InterfaceType) { |
- registry.registerInstantiation(instantiatedType); |
+ impactBuilder |
+ .registerTypeUse(new TypeUse.instantiation(instantiatedType)); |
if (!type.treatAsRaw && classNeedsRti(type.element)) { |
- registry.registerStaticUse(new StaticUse.staticInvoke( |
+ impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
// TODO(johnniwinther): Find the right [CallStructure]. |
helpers.setRuntimeTypeInfo, |
null)); |
@@ -1112,7 +1134,7 @@ class JavaScriptBackend extends Backend { |
// If we use a type literal in a constant, the compile time |
// constant emitter will generate a call to the createRuntimeType |
// helper so we register a use of that. |
- registry.registerStaticUse(new StaticUse.staticInvoke( |
+ impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
// TODO(johnniwinther): Find the right [CallStructure]. |
helpers.createRuntimeType, |
null)); |
@@ -1281,23 +1303,11 @@ class JavaScriptBackend extends Backend { |
void registerInstantiatedType( |
InterfaceType type, Enqueuer enqueuer, Registry registry, |
{bool mirrorUsage: false}) { |
- lookupMapAnalysis.registerInstantiatedType(type, registry); |
+ lookupMapAnalysis.registerInstantiatedType(type); |
super.registerInstantiatedType(type, enqueuer, registry, |
mirrorUsage: mirrorUsage); |
} |
- void registerUseInterceptor(Enqueuer enqueuer) { |
- assert(!enqueuer.isResolutionQueue); |
- if (!enqueuer.nativeEnqueuer.hasInstantiatedNativeClasses()) return; |
- Registry registry = compiler.globalDependencies; |
- enqueue(enqueuer, helpers.getNativeInterceptorMethod, registry); |
- enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass, registry); |
- enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass, registry); |
- enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass, registry); |
- needToInitializeIsolateAffinityTag = true; |
- needToInitializeDispatchProperty = true; |
- } |
- |
void enqueueHelpers(ResolutionEnqueuer world, Registry registry) { |
assert(helpers.interceptorsLibrary != null); |
// TODO(ngeoffray): Not enqueuing those two classes currently make |
@@ -1590,7 +1600,8 @@ class JavaScriptBackend extends Backend { |
if (constant != null) { |
ConstantValue initialValue = constants.getConstantValue(constant); |
if (initialValue != null) { |
- registerCompileTimeConstant(initialValue, work.registry); |
+ computeImpactForCompileTimeConstant( |
+ initialValue, work.registry.worldImpact, false); |
addCompileTimeConstantForEmission(initialValue); |
// We don't need to generate code for static or top-level |
// variables. For instance variables, we may need to generate |
@@ -2337,15 +2348,15 @@ class JavaScriptBackend extends Backend { |
/// Called when [enqueuer] is empty, but before it is closed. |
bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassElement> recentClasses) { |
- if (!compiler.options.resolveOnly) { |
- // TODO(johnniwinther): The custom element analysis eagerly enqueues |
- // elements on the codegen queue. Change to compute the data needed |
- // instead. |
+ // Add elements used synthetically, that is, through features rather than |
+ // syntax, for instance custom elements. |
+ // |
+ // Return early if any elements are added to avoid counting the elements as |
+ // due to mirrors. |
+ customElementsAnalysis.onQueueEmpty(enqueuer); |
+ lookupMapAnalysis.onQueueEmpty(enqueuer); |
+ typeVariableHandler.onQueueEmpty(enqueuer); |
- // Add elements referenced only via custom elements. Return early if any |
- // elements are added to avoid counting the elements as due to mirrors. |
- customElementsAnalysis.onQueueEmpty(enqueuer); |
- } |
if (!enqueuer.queueIsEmpty) return false; |
noSuchMethodRegistry.onQueueEmpty(); |
@@ -2385,6 +2396,9 @@ class JavaScriptBackend extends Backend { |
compiler.libraryLoader.libraries.forEach(retainMetadataOf); |
+ StagedWorldImpactBuilder impactBuilder = enqueuer.isResolutionQueue |
+ ? constantImpactsForResolution |
+ : constantImpactsForResolution; |
if (enqueuer.isResolutionQueue && !enqueuer.queueIsClosed) { |
/// Register the constant value of [metadata] as live in resolution. |
void registerMetadataConstant(MetadataAnnotation metadata) { |
@@ -2393,8 +2407,8 @@ class JavaScriptBackend extends Backend { |
Dependency dependency = |
new Dependency(constant, metadata.annotatedElement); |
metadataConstants.add(dependency); |
- registerCompileTimeConstant(dependency.constant, |
- new EagerRegistry('EagerRegistry for ${dependency}', enqueuer)); |
+ computeImpactForCompileTimeConstant( |
+ dependency.constant, impactBuilder, enqueuer.isResolutionQueue); |
Harry Terkelsen
2016/09/19 21:17:52
enqueuer.isResolutionQueue -> true?
|
} |
// TODO(johnniwinther): We should have access to all recently processed |
@@ -2403,11 +2417,12 @@ class JavaScriptBackend extends Backend { |
registerMetadataConstant); |
} else { |
for (Dependency dependency in metadataConstants) { |
- registerCompileTimeConstant(dependency.constant, |
- new EagerRegistry('EagerRegistry for ${dependency}', enqueuer)); |
+ computeImpactForCompileTimeConstant( |
+ dependency.constant, impactBuilder, enqueuer.isResolutionQueue); |
Harry Terkelsen
2016/09/19 21:17:52
enqueuer.isResolutionQueue -> false?
|
} |
metadataConstants.clear(); |
} |
+ enqueuer.applyImpact(null, impactBuilder.flush()); |
} |
return true; |
} |
@@ -3080,14 +3095,12 @@ class JavaScriptImpactTransformer extends ImpactTransformer { |
@override |
WorldImpact transformCodegenImpact(CodegenImpact impact) { |
TransformedWorldImpact transformed = new TransformedWorldImpact(impact); |
- EagerRegistry registry = impact.registry; |
- Enqueuer world = registry.world; |
for (TypeUse typeUse in impact.typeUses) { |
DartType type = typeUse.type; |
switch (typeUse.kind) { |
case TypeUseKind.INSTANTIATION: |
- backend.lookupMapAnalysis.registerInstantiatedType(type, registry); |
+ backend.lookupMapAnalysis.registerInstantiatedType(type); |
break; |
case TypeUseKind.IS_CHECK: |
onIsCheckForCodegen(type, transformed); |
@@ -3097,7 +3110,7 @@ class JavaScriptImpactTransformer extends ImpactTransformer { |
} |
for (ConstantValue constant in impact.compileTimeConstants) { |
- backend.registerCompileTimeConstant(constant, registry); |
+ backend.computeImpactForCompileTimeConstant(constant, transformed, false); |
backend.addCompileTimeConstantForEmission(constant); |
} |
@@ -3124,7 +3137,9 @@ class JavaScriptImpactTransformer extends ImpactTransformer { |
} |
if (impact.usesInterceptor) { |
- backend.registerUseInterceptor(world); |
+ if (backend.codegenEnqueuer.nativeEnqueuer.hasInstantiatedNativeClasses) { |
+ registerBackendImpact(transformed, impacts.interceptorUse); |
+ } |
} |
for (ClassElement element in impact.typeConstants) { |
@@ -3182,7 +3197,9 @@ class JavaScriptImpactStrategy extends ImpactStrategy { |
impact.apply(visitor); |
} else { |
impact.apply(visitor); |
- resolution.uncacheWorldImpact(element); |
+ if (element != null) { |
+ resolution.uncacheWorldImpact(element); |
+ } |
} |
} else if (impactUse == DeferredLoadTask.IMPACT_USE) { |
impact.apply(visitor); |