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 95fcf9c4094c598808e4ff2f6c4aecf3440c2a25..fd9efa19d9adfc5a6212a839148c1834d63927c5 100644 |
--- a/pkg/compiler/lib/src/js_backend/backend.dart |
+++ b/pkg/compiler/lib/src/js_backend/backend.dart |
@@ -14,7 +14,7 @@ import '../common/backend_api.dart' |
show Backend, ImpactTransformer, ForeignResolver, NativeRegistry; |
import '../common/codegen.dart' show CodegenImpact, CodegenWorkItem; |
import '../common/names.dart' show Identifiers, Selectors, Uris; |
-import '../common/registry.dart' show Registry; |
+import '../common/registry.dart' show EagerRegistry, Registry; |
import '../common/resolution.dart' show Frontend, Resolution, ResolutionImpact; |
import '../common/tasks.dart' show CompilerTask; |
import '../compiler.dart' show Compiler; |
@@ -54,9 +54,7 @@ import '../universe/world_impact.dart' |
ImpactUseCase, |
TransformedWorldImpact, |
WorldImpact, |
- WorldImpactBuilder, |
- WorldImpactVisitor, |
- StagedWorldImpactBuilder; |
+ WorldImpactVisitor; |
import '../util/util.dart'; |
import '../world.dart' show ClassWorld; |
import 'backend_helpers.dart'; |
@@ -581,12 +579,6 @@ class JavaScriptBackend extends Backend { |
JavaScriptBackendSerialization serialization; |
- StagedWorldImpactBuilder constantImpactsForResolution = |
- new StagedWorldImpactBuilder(); |
- |
- StagedWorldImpactBuilder constantImpactsForCodegen = |
- new StagedWorldImpactBuilder(); |
- |
final NativeData nativeData = new NativeData(); |
final BackendHelpers helpers; |
@@ -1077,20 +1069,17 @@ class JavaScriptBackend extends Backend { |
} |
} |
- void computeImpactForCompileTimeConstant(ConstantValue constant, |
- WorldImpactBuilder impactBuilder, bool isForResolution) { |
- computeImpactForCompileTimeConstantInternal( |
- constant, impactBuilder, isForResolution); |
+ void registerCompileTimeConstant(ConstantValue constant, Registry registry) { |
+ registerCompileTimeConstantInternal(constant, registry); |
- if (!isForResolution && lookupMapAnalysis.isLookupMap(constant)) { |
+ if (!registry.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()) { |
- computeImpactForCompileTimeConstant( |
- dependency, impactBuilder, isForResolution); |
+ registerCompileTimeConstant(dependency, registry); |
} |
} |
@@ -1098,43 +1087,32 @@ class JavaScriptBackend extends Backend { |
constants.addCompileTimeConstantForEmission(constant); |
} |
- void computeImpactForCompileTimeConstantInternal(ConstantValue constant, |
- WorldImpactBuilder impactBuilder, bool isForResolution) { |
+ void registerCompileTimeConstantInternal( |
+ ConstantValue constant, Registry registry) { |
DartType type = constant.getType(compiler.coreTypes); |
- computeImpactForInstantiatedConstantType(type, impactBuilder); |
+ registerInstantiatedConstantType(type, registry); |
if (constant.isFunction) { |
FunctionConstantValue function = constant; |
- impactBuilder |
- .registerStaticUse(new StaticUse.staticTearOff(function.element)); |
+ registry.registerStaticUse(new StaticUse.staticTearOff(function.element)); |
} else if (constant.isInterceptor) { |
// An interceptor constant references the class's prototype chain. |
InterceptorConstantValue interceptor = constant; |
- computeImpactForInstantiatedConstantType( |
- interceptor.dispatchedType, impactBuilder); |
+ registerInstantiatedConstantType(interceptor.dispatchedType, registry); |
} else if (constant.isType) { |
- 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)); |
+ enqueueInResolution(helpers.createRuntimeType, registry); |
+ registry.registerInstantiation(typeImplementation.rawType); |
} |
lookupMapAnalysis.registerConstantKey(constant); |
} |
- void computeImpactForInstantiatedConstantType( |
- DartType type, WorldImpactBuilder impactBuilder) { |
+ void registerInstantiatedConstantType(DartType type, Registry registry) { |
DartType instantiatedType = |
type.isFunctionType ? coreTypes.functionType : type; |
if (type is InterfaceType) { |
- impactBuilder.registerTypeUse( |
- new TypeUse.instantiation(instantiatedType)); |
+ registry.registerInstantiation(instantiatedType); |
if (classNeedsRtiField(type.element)) { |
- impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
+ registry.registerStaticUse(new StaticUse.staticInvoke( |
// TODO(johnniwinther): Find the right [CallStructure]. |
helpers.setRuntimeTypeInfo, |
null)); |
@@ -1143,7 +1121,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. |
- impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
+ registry.registerStaticUse(new StaticUse.staticInvoke( |
// TODO(johnniwinther): Find the right [CallStructure]. |
helpers.createRuntimeType, |
null)); |
@@ -1312,11 +1290,23 @@ class JavaScriptBackend extends Backend { |
void registerInstantiatedType( |
InterfaceType type, Enqueuer enqueuer, Registry registry, |
{bool mirrorUsage: false}) { |
- lookupMapAnalysis.registerInstantiatedType(type); |
+ lookupMapAnalysis.registerInstantiatedType(type, registry); |
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 |
@@ -1615,8 +1605,7 @@ class JavaScriptBackend extends Backend { |
if (constant != null) { |
ConstantValue initialValue = constants.getConstantValue(constant); |
if (initialValue != null) { |
- computeImpactForCompileTimeConstant( |
- initialValue, work.registry.worldImpact, false); |
+ registerCompileTimeConstant(initialValue, work.registry); |
addCompileTimeConstantForEmission(initialValue); |
// We don't need to generate code for static or top-level |
// variables. For instance variables, we may need to generate |
@@ -2363,15 +2352,15 @@ class JavaScriptBackend extends Backend { |
/// Called when [enqueuer] is empty, but before it is closed. |
bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassElement> recentClasses) { |
- // 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); |
+ 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 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(); |
@@ -2415,9 +2404,6 @@ 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) { |
@@ -2426,8 +2412,8 @@ class JavaScriptBackend extends Backend { |
Dependency dependency = |
new Dependency(constant, metadata.annotatedElement); |
metadataConstants.add(dependency); |
- computeImpactForCompileTimeConstant( |
- dependency.constant, impactBuilder, enqueuer.isResolutionQueue); |
+ registerCompileTimeConstant(dependency.constant, |
+ new EagerRegistry('EagerRegistry for ${dependency}', enqueuer)); |
} |
// TODO(johnniwinther): We should have access to all recently processed |
@@ -2436,12 +2422,11 @@ class JavaScriptBackend extends Backend { |
registerMetadataConstant); |
} else { |
for (Dependency dependency in metadataConstants) { |
- computeImpactForCompileTimeConstant( |
- dependency.constant, impactBuilder, enqueuer.isResolutionQueue); |
+ registerCompileTimeConstant(dependency.constant, |
+ new EagerRegistry('EagerRegistry for ${dependency}', enqueuer)); |
} |
metadataConstants.clear(); |
} |
- enqueuer.applyImpact(null, impactBuilder.flush()); |
} |
return true; |
} |
@@ -3120,12 +3105,14 @@ 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); |
+ backend.lookupMapAnalysis.registerInstantiatedType(type, registry); |
break; |
case TypeUseKind.IS_CHECK: |
onIsCheckForCodegen(type, transformed); |
@@ -3135,7 +3122,7 @@ class JavaScriptImpactTransformer extends ImpactTransformer { |
} |
for (ConstantValue constant in impact.compileTimeConstants) { |
- backend.computeImpactForCompileTimeConstant(constant, transformed, false); |
+ backend.registerCompileTimeConstant(constant, registry); |
backend.addCompileTimeConstantForEmission(constant); |
} |
@@ -3162,9 +3149,7 @@ class JavaScriptImpactTransformer extends ImpactTransformer { |
} |
if (impact.usesInterceptor) { |
- if (backend.codegenEnqueuer.nativeEnqueuer.hasInstantiatedNativeClasses) { |
- registerBackendImpact(transformed, impacts.interceptorUse); |
- } |
+ backend.registerUseInterceptor(world); |
} |
for (ClassElement element in impact.typeConstants) { |
@@ -3222,9 +3207,7 @@ class JavaScriptImpactStrategy extends ImpactStrategy { |
impact.apply(visitor); |
} else { |
impact.apply(visitor); |
- if (element != null) { |
- resolution.uncacheWorldImpact(element); |
- } |
+ resolution.uncacheWorldImpact(element); |
} |
} else if (impactUse == DeferredLoadTask.IMPACT_USE) { |
impact.apply(visitor); |