| 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 fd9efa19d9adfc5a6212a839148c1834d63927c5..91b8b5b8521d73ce593925762d592c67c7fd1c2f 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 EagerRegistry, Registry;
|
| +import '../common/registry.dart' show Registry;
|
| import '../common/resolution.dart' show Frontend, Resolution, ResolutionImpact;
|
| import '../common/tasks.dart' show CompilerTask;
|
| import '../compiler.dart' show Compiler;
|
| @@ -54,7 +54,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';
|
| @@ -579,6 +581,12 @@ class JavaScriptBackend extends Backend {
|
|
|
| JavaScriptBackendSerialization serialization;
|
|
|
| + StagedWorldImpactBuilder constantImpactsForResolution =
|
| + new StagedWorldImpactBuilder();
|
| +
|
| + StagedWorldImpactBuilder constantImpactsForCodegen =
|
| + new StagedWorldImpactBuilder();
|
| +
|
| final NativeData nativeData = new NativeData();
|
|
|
| final BackendHelpers helpers;
|
| @@ -1069,17 +1077,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);
|
| }
|
| }
|
|
|
| @@ -1087,32 +1098,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 (classNeedsRtiField(type.element)) {
|
| - registry.registerStaticUse(new StaticUse.staticInvoke(
|
| + impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
|
| // TODO(johnniwinther): Find the right [CallStructure].
|
| helpers.setRuntimeTypeInfo,
|
| null));
|
| @@ -1121,7 +1143,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));
|
| @@ -1290,23 +1312,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
|
| @@ -1605,7 +1615,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
|
| @@ -2352,15 +2363,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();
|
| @@ -2404,6 +2415,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) {
|
| @@ -2412,8 +2426,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);
|
| }
|
|
|
| // TODO(johnniwinther): We should have access to all recently processed
|
| @@ -2422,11 +2436,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);
|
| }
|
| metadataConstants.clear();
|
| }
|
| + enqueuer.applyImpact(null, impactBuilder.flush());
|
| }
|
| return true;
|
| }
|
| @@ -3014,6 +3029,16 @@ class JavaScriptImpactTransformer extends ImpactTransformer {
|
| for (BackendImpact otherImpact in backendImpact.otherImpacts) {
|
| registerBackendImpact(worldImpact, otherImpact);
|
| }
|
| + for (BackendFeature feature in backendImpact.features) {
|
| + switch (feature) {
|
| + case BackendFeature.needToInitializeDispatchProperty:
|
| + backend.needToInitializeDispatchProperty = true;
|
| + break;
|
| + case BackendFeature.needToInitializeIsolateAffinityTag:
|
| + backend.needToInitializeIsolateAffinityTag = true;
|
| + break;
|
| + }
|
| + }
|
| }
|
|
|
| /// Register [type] as required for the runtime type information system.
|
| @@ -3105,14 +3130,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);
|
| @@ -3122,7 +3145,7 @@ class JavaScriptImpactTransformer extends ImpactTransformer {
|
| }
|
|
|
| for (ConstantValue constant in impact.compileTimeConstants) {
|
| - backend.registerCompileTimeConstant(constant, registry);
|
| + backend.computeImpactForCompileTimeConstant(constant, transformed, false);
|
| backend.addCompileTimeConstantForEmission(constant);
|
| }
|
|
|
| @@ -3149,7 +3172,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) {
|
| @@ -3207,7 +3232,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);
|
|
|