Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(556)

Unified Diff: pkg/compiler/lib/src/js_backend/backend.dart

Issue 2531303002: Decouple WorkItem from Compiler (Closed)
Patch Set: Updated cf. comments. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/enqueue.dart ('k') | pkg/compiler/lib/src/js_backend/backend_helpers.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 03e5839570856295873893783f61988c4c98356e..1bf2a94052410488772eb7cb416f29b7631d7a82 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -335,7 +335,6 @@ class JavaScriptBackend extends Backend {
static const String TRACE_METHOD = const String.fromEnvironment('traceCalls');
static const bool TRACE_CALLS =
TRACE_METHOD == 'post' || TRACE_METHOD == 'console';
- MethodElement traceHelper;
TypeMask get stringType => compiler.closedWorld.commonMasks.stringType;
TypeMask get doubleType => compiler.closedWorld.commonMasks.doubleType;
@@ -1036,9 +1035,9 @@ class JavaScriptBackend extends Backend {
});
}
- void addInterceptorsForNativeClassMembers(
- ClassElement cls, Enqueuer enqueuer) {
- if (enqueuer.isResolutionQueue) {
+ void addInterceptorsForNativeClassMembers(ClassElement cls,
+ {bool forResolution}) {
+ if (forResolution) {
cls.ensureResolved(resolution);
cls.forEachMember((ClassElement classElement, Element member) {
if (member.name == Identifiers.call) {
@@ -1062,20 +1061,22 @@ class JavaScriptBackend extends Backend {
}
}
- void addInterceptors(ClassElement cls, Enqueuer enqueuer) {
- if (enqueuer.isResolutionQueue) {
+ void addInterceptors(ClassElement cls, WorldImpactBuilder impactBuilder,
+ {bool forResolution}) {
+ if (forResolution) {
+ if (_interceptedClasses.add(cls)) {
+ cls.ensureResolved(resolution);
+ cls.forEachMember((ClassElement classElement, Element member) {
+ // All methods on [Object] are shadowed by [Interceptor].
+ if (classElement == coreClasses.objectClass) return;
+ Set<Element> set = interceptedElements.putIfAbsent(
+ member.name, () => new Set<Element>());
+ set.add(member);
+ }, includeSuperAndInjectedMembers: true);
+ }
_interceptedClasses.add(helpers.jsInterceptorClass);
- _interceptedClasses.add(cls);
- cls.ensureResolved(resolution);
- cls.forEachMember((ClassElement classElement, Element member) {
- // All methods on [Object] are shadowed by [Interceptor].
- if (classElement == coreClasses.objectClass) return;
- Set<Element> set = interceptedElements.putIfAbsent(
- member.name, () => new Set<Element>());
- set.add(member);
- }, includeSuperAndInjectedMembers: true);
}
- enqueueClass(enqueuer, cls);
+ impactTransformer.registerBackendInstantiation(impactBuilder, cls);
}
Set<ClassElement> get interceptedClasses {
@@ -1168,190 +1169,168 @@ class JavaScriptBackend extends Backend {
}
}
- void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) {
- _processClass(cls, enqueuer);
+ WorldImpact registerInstantiatedClass(ClassElement cls,
+ {bool forResolution}) {
+ return _processClass(cls, forResolution: forResolution);
}
- void registerImplementedClass(ClassElement cls, Enqueuer enqueuer) {
- _processClass(cls, enqueuer);
+ WorldImpact registerImplementedClass(ClassElement cls, {bool forResolution}) {
+ return _processClass(cls, forResolution: forResolution);
}
- void _processClass(ClassElement cls, Enqueuer enqueuer) {
+ WorldImpact _processClass(ClassElement cls, {bool forResolution}) {
+ WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
if (!cls.typeVariables.isEmpty) {
- typeVariableHandler.registerClassWithTypeVariables(cls, enqueuer);
+ typeVariableHandler.registerClassWithTypeVariables(cls,
+ forResolution: forResolution);
}
// Register any helper that will be needed by the backend.
- if (enqueuer.isResolutionQueue) {
+ if (forResolution) {
if (cls == coreClasses.intClass ||
cls == coreClasses.doubleClass ||
cls == coreClasses.numClass) {
- // The backend will try to optimize number operations and use the
- // `iae` helper directly.
- enqueue(enqueuer, helpers.throwIllegalArgumentException);
+ impactTransformer.registerBackendImpact(
+ impactBuilder, impacts.numClasses);
} else if (cls == coreClasses.listClass ||
cls == coreClasses.stringClass) {
- // The backend will try to optimize array and string access and use the
- // `ioore` and `iae` helpers directly.
- enqueue(enqueuer, helpers.throwIndexOutOfRangeException);
- enqueue(enqueuer, helpers.throwIllegalArgumentException);
+ impactTransformer.registerBackendImpact(
+ impactBuilder, impacts.listOrStringClasses);
} else if (cls == coreClasses.functionClass) {
- enqueueClass(enqueuer, helpers.closureClass);
+ impactTransformer.registerBackendImpact(
+ impactBuilder, impacts.functionClass);
} else if (cls == coreClasses.mapClass) {
- // The backend will use a literal list to initialize the entries
- // of the map.
- enqueueClass(enqueuer, coreClasses.listClass);
- enqueueClass(enqueuer, helpers.mapLiteralClass);
+ impactTransformer.registerBackendImpact(
+ impactBuilder, impacts.mapClass);
// For map literals, the dependency between the implementation class
// and [Map] is not visible, so we have to add it manually.
rti.registerRtiDependency(helpers.mapLiteralClass, cls);
} else if (cls == helpers.boundClosureClass) {
- // TODO(johnniwinther): Is this a noop?
- enqueueClass(enqueuer, helpers.boundClosureClass);
+ impactTransformer.registerBackendImpact(
+ impactBuilder, impacts.boundClosureClass);
} else if (isNativeOrExtendsNative(cls)) {
- enqueue(enqueuer, helpers.getNativeInterceptorMethod);
- enqueueClass(enqueuer, helpers.jsInterceptorClass);
- enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass);
- enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass);
- enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass);
+ impactTransformer.registerBackendImpact(
+ impactBuilder, impacts.nativeOrExtendsClass);
} else if (cls == helpers.mapLiteralClass) {
- // For map literals, the dependency between the implementation class
- // and [Map] is not visible, so we have to add it manually.
- Element getFactory(String name, int arity) {
- // The constructor is on the patch class, but dart2js unit tests don't
- // have a patch class.
- ClassElement implementation = cls.implementation;
- ConstructorElement ctor = implementation.lookupConstructor(name);
- if (ctor == null ||
- (Name.isPrivateName(name) &&
- ctor.library != helpers.mapLiteralClass.library)) {
- reporter.internalError(
- helpers.mapLiteralClass,
- "Map literal class ${helpers.mapLiteralClass} missing "
- "'$name' constructor"
- " ${helpers.mapLiteralClass.constructors}");
- }
- return ctor;
- }
-
- Element getMember(String name) {
- // The constructor is on the patch class, but dart2js unit tests don't
- // have a patch class.
- ClassElement implementation = cls.implementation;
- Element element = implementation.lookupLocalMember(name);
- if (element == null || !element.isFunction || !element.isStatic) {
- reporter.internalError(
- helpers.mapLiteralClass,
- "Map literal class ${helpers.mapLiteralClass} missing "
- "'$name' static member function");
- }
- return element;
- }
-
- helpers.mapLiteralConstructor = getFactory('_literal', 1);
- helpers.mapLiteralConstructorEmpty = getFactory('_empty', 0);
- enqueue(enqueuer, helpers.mapLiteralConstructor);
- enqueue(enqueuer, helpers.mapLiteralConstructorEmpty);
-
- helpers.mapLiteralUntypedMaker = getMember('_makeLiteral');
- helpers.mapLiteralUntypedEmptyMaker = getMember('_makeEmpty');
- enqueue(enqueuer, helpers.mapLiteralUntypedMaker);
- enqueue(enqueuer, helpers.mapLiteralUntypedEmptyMaker);
+ impactTransformer.registerBackendImpact(
+ impactBuilder, impacts.mapLiteralClass);
}
}
if (cls == helpers.closureClass) {
- enqueue(enqueuer, helpers.closureFromTearOff);
+ impactTransformer.registerBackendImpact(
+ impactBuilder, impacts.closureClass);
}
if (cls == coreClasses.stringClass || cls == helpers.jsStringClass) {
- addInterceptors(helpers.jsStringClass, enqueuer);
+ addInterceptors(helpers.jsStringClass, impactBuilder,
+ forResolution: forResolution);
} else if (cls == coreClasses.listClass ||
cls == helpers.jsArrayClass ||
cls == helpers.jsFixedArrayClass ||
cls == helpers.jsExtendableArrayClass ||
cls == helpers.jsUnmodifiableArrayClass) {
- addInterceptors(helpers.jsArrayClass, enqueuer);
- addInterceptors(helpers.jsMutableArrayClass, enqueuer);
- addInterceptors(helpers.jsFixedArrayClass, enqueuer);
- addInterceptors(helpers.jsExtendableArrayClass, enqueuer);
- addInterceptors(helpers.jsUnmodifiableArrayClass, enqueuer);
- if (enqueuer.isResolutionQueue) {
- // Literal lists can be translated into calls to these functions:
- enqueue(enqueuer, helpers.jsArrayTypedConstructor);
- enqueue(enqueuer, helpers.setRuntimeTypeInfo);
- enqueue(enqueuer, helpers.getTypeArgumentByIndex);
+ addInterceptors(helpers.jsArrayClass, impactBuilder,
+ forResolution: forResolution);
+ addInterceptors(helpers.jsMutableArrayClass, impactBuilder,
+ forResolution: forResolution);
+ addInterceptors(helpers.jsFixedArrayClass, impactBuilder,
+ forResolution: forResolution);
+ addInterceptors(helpers.jsExtendableArrayClass, impactBuilder,
+ forResolution: forResolution);
+ addInterceptors(helpers.jsUnmodifiableArrayClass, impactBuilder,
+ forResolution: forResolution);
+ if (forResolution) {
+ impactTransformer.registerBackendImpact(
+ impactBuilder, impacts.listClasses);
}
} else if (cls == coreClasses.intClass || cls == helpers.jsIntClass) {
- addInterceptors(helpers.jsIntClass, enqueuer);
- addInterceptors(helpers.jsPositiveIntClass, enqueuer);
- addInterceptors(helpers.jsUInt32Class, enqueuer);
- addInterceptors(helpers.jsUInt31Class, enqueuer);
- addInterceptors(helpers.jsNumberClass, enqueuer);
+ addInterceptors(helpers.jsIntClass, impactBuilder,
+ forResolution: forResolution);
+ addInterceptors(helpers.jsPositiveIntClass, impactBuilder,
+ forResolution: forResolution);
+ addInterceptors(helpers.jsUInt32Class, impactBuilder,
+ forResolution: forResolution);
+ addInterceptors(helpers.jsUInt31Class, impactBuilder,
+ forResolution: forResolution);
+ addInterceptors(helpers.jsNumberClass, impactBuilder,
+ forResolution: forResolution);
} else if (cls == coreClasses.doubleClass || cls == helpers.jsDoubleClass) {
- addInterceptors(helpers.jsDoubleClass, enqueuer);
- addInterceptors(helpers.jsNumberClass, enqueuer);
+ addInterceptors(helpers.jsDoubleClass, impactBuilder,
+ forResolution: forResolution);
+ addInterceptors(helpers.jsNumberClass, impactBuilder,
+ forResolution: forResolution);
} else if (cls == coreClasses.boolClass || cls == helpers.jsBoolClass) {
- addInterceptors(helpers.jsBoolClass, enqueuer);
+ addInterceptors(helpers.jsBoolClass, impactBuilder,
+ forResolution: forResolution);
} else if (cls == coreClasses.nullClass || cls == helpers.jsNullClass) {
- addInterceptors(helpers.jsNullClass, enqueuer);
+ addInterceptors(helpers.jsNullClass, impactBuilder,
+ forResolution: forResolution);
} else if (cls == coreClasses.numClass || cls == helpers.jsNumberClass) {
- addInterceptors(helpers.jsIntClass, enqueuer);
- addInterceptors(helpers.jsPositiveIntClass, enqueuer);
- addInterceptors(helpers.jsUInt32Class, enqueuer);
- addInterceptors(helpers.jsUInt31Class, enqueuer);
- addInterceptors(helpers.jsDoubleClass, enqueuer);
- addInterceptors(helpers.jsNumberClass, enqueuer);
+ addInterceptors(helpers.jsIntClass, impactBuilder,
+ forResolution: forResolution);
+ addInterceptors(helpers.jsPositiveIntClass, impactBuilder,
+ forResolution: forResolution);
+ addInterceptors(helpers.jsUInt32Class, impactBuilder,
+ forResolution: forResolution);
+ addInterceptors(helpers.jsUInt31Class, impactBuilder,
+ forResolution: forResolution);
+ addInterceptors(helpers.jsDoubleClass, impactBuilder,
+ forResolution: forResolution);
+ addInterceptors(helpers.jsNumberClass, impactBuilder,
+ forResolution: forResolution);
} else if (cls == helpers.jsJavaScriptObjectClass) {
- addInterceptors(helpers.jsJavaScriptObjectClass, enqueuer);
+ addInterceptors(helpers.jsJavaScriptObjectClass, impactBuilder,
+ forResolution: forResolution);
} else if (cls == helpers.jsPlainJavaScriptObjectClass) {
- addInterceptors(helpers.jsPlainJavaScriptObjectClass, enqueuer);
+ addInterceptors(helpers.jsPlainJavaScriptObjectClass, impactBuilder,
+ forResolution: forResolution);
} else if (cls == helpers.jsUnknownJavaScriptObjectClass) {
- addInterceptors(helpers.jsUnknownJavaScriptObjectClass, enqueuer);
+ addInterceptors(helpers.jsUnknownJavaScriptObjectClass, impactBuilder,
+ forResolution: forResolution);
} else if (cls == helpers.jsJavaScriptFunctionClass) {
- addInterceptors(helpers.jsJavaScriptFunctionClass, enqueuer);
+ addInterceptors(helpers.jsJavaScriptFunctionClass, impactBuilder,
+ forResolution: forResolution);
} else if (isNativeOrExtendsNative(cls)) {
- addInterceptorsForNativeClassMembers(cls, enqueuer);
+ addInterceptorsForNativeClassMembers(cls, forResolution: forResolution);
} else if (cls == helpers.jsIndexingBehaviorInterface) {
- // These two helpers are used by the emitter and the codegen.
- // Because we cannot enqueue elements at the time of emission,
- // we make sure they are always generated.
- enqueue(enqueuer, helpers.isJsIndexable);
+ impactTransformer.registerBackendImpact(
+ impactBuilder, impacts.jsIndexingBehavior);
}
customElementsAnalysis.registerInstantiatedClass(cls,
- forResolution: enqueuer.isResolutionQueue);
- if (!enqueuer.isResolutionQueue) {
+ forResolution: forResolution);
+ if (!forResolution) {
lookupMapAnalysis.registerInstantiatedClass(cls);
}
+
+ return impactBuilder;
}
void registerInstantiatedType(InterfaceType type) {
lookupMapAnalysis.registerInstantiatedType(type);
}
- void enqueueHelpers(ResolutionEnqueuer enqueuer) {
+ @override
+ WorldImpact computeHelpersImpact() {
assert(helpers.interceptorsLibrary != null);
+ WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
// TODO(ngeoffray): Not enqueuing those two classes currently make
// the compiler potentially crash. However, any reasonable program
// will instantiate those two classes.
- addInterceptors(helpers.jsBoolClass, enqueuer);
- addInterceptors(helpers.jsNullClass, enqueuer);
+ addInterceptors(helpers.jsBoolClass, impactBuilder, forResolution: true);
+ addInterceptors(helpers.jsNullClass, impactBuilder, forResolution: true);
if (compiler.options.enableTypeAssertions) {
- // Unconditionally register the helper that checks if the
- // expression in an if/while/for is a boolean.
- // TODO(ngeoffray): Should we have the resolver register those instead?
- Element e = helpers.boolConversionCheck;
- if (e != null) enqueue(enqueuer, e);
+ impactTransformer.registerBackendImpact(
+ impactBuilder, impacts.enableTypeAssertions);
}
if (TRACE_CALLS) {
- traceHelper = TRACE_METHOD == 'console'
- ? helpers.consoleTraceHelper
- : helpers.postTraceHelper;
- assert(traceHelper != null);
- enqueue(enqueuer, traceHelper);
+ impactTransformer.registerBackendImpact(
+ impactBuilder, impacts.traceHelper);
}
- enqueue(enqueuer, helpers.assertUnreachableMethod);
- registerCheckedModeHelpers(enqueuer);
+ impactTransformer.registerBackendImpact(
+ impactBuilder, impacts.assertUnreachable);
+ _registerCheckedModeHelpers(impactBuilder);
+ return impactBuilder;
}
onResolutionComplete() {
@@ -1366,47 +1345,39 @@ class JavaScriptBackend extends Backend {
noSuchMethodRegistry.onTypeInferenceComplete();
}
- void registerGetRuntimeTypeArgument() {
- enqueueImpact(compiler.enqueuer.resolution, impacts.getRuntimeTypeArgument);
- }
-
- void registerCallMethodWithFreeTypeVariables(
- Element callMethod, Enqueuer enqueuer) {
- if (enqueuer.isResolutionQueue || methodNeedsRti(callMethod)) {
- registerComputeSignature(enqueuer);
+ WorldImpact registerCallMethodWithFreeTypeVariables(Element callMethod,
+ {bool forResolution}) {
+ if (forResolution || methodNeedsRti(callMethod)) {
+ return _registerComputeSignature();
}
+ return const WorldImpact();
}
- void registerClosureWithFreeTypeVariables(
- Element closure, Enqueuer enqueuer) {
- if (enqueuer.isResolutionQueue || methodNeedsRti(closure)) {
- registerComputeSignature(enqueuer);
+ WorldImpact registerClosureWithFreeTypeVariables(Element closure,
+ {bool forResolution}) {
+ if (forResolution || methodNeedsRti(closure)) {
+ return _registerComputeSignature();
}
+ return const WorldImpact();
}
- void registerBoundClosure(Enqueuer enqueuer) {
- helpers.boundClosureClass.ensureResolved(resolution);
- enqueuer.registerInstantiatedType(helpers.boundClosureClass.rawType);
+ WorldImpact registerBoundClosure() {
+ return impactTransformer.createImpactFor(impacts.memberClosure);
}
- void registerGetOfStaticFunction(Enqueuer enqueuer) {
- helpers.closureClass.ensureResolved(resolution);
- enqueuer.registerInstantiatedType(helpers.closureClass.rawType);
+ WorldImpact registerGetOfStaticFunction() {
+ return impactTransformer.createImpactFor(impacts.staticClosure);
}
- void registerComputeSignature(Enqueuer enqueuer) {
+ WorldImpact _registerComputeSignature() {
// Calls to [:computeSignature:] are generated by the emitter and we
// therefore need to enqueue the used elements in the codegen enqueuer as
// well as in the resolution enqueuer.
- enqueueImpact(enqueuer, impacts.computeSignature);
+ return impactTransformer.createImpactFor(impacts.computeSignature);
}
- void registerRuntimeType(ResolutionEnqueuer enqueuer) {
- registerComputeSignature(enqueuer);
- enqueue(enqueuer, helpers.setRuntimeTypeInfo);
- registerGetRuntimeTypeArgument();
- enqueue(enqueuer, helpers.getRuntimeTypeInfo);
- enqueueClass(enqueuer, coreClasses.listClass);
+ WorldImpact registerRuntimeType() {
+ return impactTransformer.createImpactFor(impacts.runtimeTypeSupport);
}
void registerTypeVariableBoundsSubtypeCheck(
@@ -1414,10 +1385,8 @@ class JavaScriptBackend extends Backend {
rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound);
}
- void registerCheckDeferredIsLoaded(ResolutionEnqueuer enqueuer) {
- enqueue(enqueuer, helpers.checkDeferredIsLoaded);
- // Also register the types of the arguments passed to this method.
- enqueueClass(enqueuer, coreClasses.stringClass);
+ WorldImpact computeDeferredLoadingImpact() {
+ return impactTransformer.createImpactFor(impacts.deferredLoading);
}
void registerNoSuchMethod(FunctionElement noSuchMethod) {
@@ -1458,12 +1427,12 @@ class JavaScriptBackend extends Backend {
return null;
}
- void enableNoSuchMethod(Enqueuer world) {
- enqueue(world, helpers.createInvocationMirror);
- world.registerDynamicUse(new DynamicUse(Selectors.noSuchMethod_, null));
+ WorldImpact enableNoSuchMethod() {
+ return impactTransformer.createImpactFor(impacts.noSuchMethodSupport);
}
- void enableIsolateSupport(Enqueuer enqueuer) {
+ WorldImpact enableIsolateSupport({bool forResolution}) {
+ WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
// TODO(floitsch): We should also ensure that the class IsolateMessage is
// instantiated. Currently, just enabling isolate support works.
if (compiler.mainFunction != null) {
@@ -1474,22 +1443,16 @@ class JavaScriptBackend extends Backend {
// The JavaScript backend of [Isolate.spawnUri] uses the same internal
// implementation as [Isolate.spawn], and fails if it cannot look main up
// by name.
- enqueuer.registerStaticUse(
+ impactBuilder.registerStaticUse(
new StaticUse.staticTearOff(compiler.mainFunction));
}
- if (enqueuer.isResolutionQueue) {
- void enqueue(Element element) {
- enqueuer.addToWorkList(element);
- compiler.globalDependencies.registerDependency(element);
- helpersUsed.add(element.declaration);
- }
-
- enqueue(helpers.startRootIsolate);
- enqueue(helpers.currentIsolate);
- enqueue(helpers.callInIsolate);
- } else {
- enqueuer.addToWorkList(helpers.startRootIsolate);
+ impactTransformer.registerBackendImpact(
+ impactBuilder, impacts.isolateSupport);
+ if (forResolution) {
+ impactTransformer.registerBackendImpact(
+ impactBuilder, impacts.isolateSupportForResolution);
}
+ return impactBuilder;
}
bool classNeedsRti(ClassElement cls) {
@@ -1519,60 +1482,6 @@ class JavaScriptBackend extends Backend {
compiler.resolverWorld.hasRuntimeTypeSupport;
}
- /// Enqueue [e] in [enqueuer].
- ///
- /// This method calls [registerBackendUse].
- void enqueue(Enqueuer enqueuer, Element e) {
- if (e == null) return;
- registerBackendUse(e);
- enqueuer.addToWorkList(e);
- compiler.globalDependencies.registerDependency(e);
- }
-
- /// Register instantiation of [cls] in [enqueuer].
- ///
- /// This method calls [registerBackendUse].
- void enqueueClass(Enqueuer enqueuer, ClassElement cls) {
- if (cls == null) return;
- registerBackendUse(cls);
- helpersUsed.add(cls.declaration);
- if (cls.declaration != cls.implementation) {
- helpersUsed.add(cls.implementation);
- }
- cls.ensureResolved(resolution);
- enqueuer.registerInstantiatedType(cls.rawType);
- }
-
- /// Register instantiation of [type] in [enqueuer].
- ///
- /// This method calls [registerBackendUse].
- void enqueueType(Enqueuer enqueuer, InterfaceType type) {
- if (type == null) return;
- ClassElement cls = type.element;
- registerBackendUse(cls);
- helpersUsed.add(cls.declaration);
- if (cls.declaration != cls.implementation) {
- helpersUsed.add(cls.implementation);
- }
- cls.ensureResolved(resolution);
- enqueuer.registerInstantiatedType(type);
- }
-
- void enqueueImpact(Enqueuer enqueuer, BackendImpact impact) {
- for (Element staticUse in impact.staticUses) {
- enqueue(enqueuer, staticUse);
- }
- for (InterfaceType type in impact.instantiatedTypes) {
- enqueueType(enqueuer, type);
- }
- for (ClassElement cls in impact.instantiatedClasses) {
- enqueueClass(enqueuer, cls);
- }
- for (BackendImpact otherImpact in impact.otherImpacts) {
- enqueueImpact(enqueuer, otherImpact);
- }
- }
-
CodegenEnqueuer get codegenEnqueuer => compiler.enqueuer.codegen;
CodegenEnqueuer createCodegenEnqueuer(CompilerTask task, Compiler compiler) {
@@ -1634,7 +1543,7 @@ class JavaScriptBackend extends Backend {
// go through the builder (below) to generate the lazy initializer for
// the static variable.
// We also need to register the use of the cyclic-error helper.
- compiler.enqueuer.codegen.registerStaticUse(new StaticUse.staticInvoke(
+ work.registry.worldImpact.registerStaticUse(new StaticUse.staticInvoke(
helpers.cyclicThrowHelper, CallStructure.ONE_ARG));
}
}
@@ -1856,12 +1765,15 @@ class JavaScriptBackend extends Backend {
}
}
- void registerCheckedModeHelpers(ResolutionEnqueuer enqueuer) {
+ void _registerCheckedModeHelpers(WorldImpactBuilder impactBuilder) {
// We register all the helpers in the resolution queue.
// TODO(13155): Find a way to register fewer helpers.
+ List<Element> staticUses = <Element>[];
for (CheckedModeHelper helper in checkedModeHelpers) {
- enqueue(enqueuer, helper.getStaticUse(compiler).element);
+ staticUses.add(helper.getStaticUse(compiler).element);
}
+ impactTransformer.registerBackendImpact(
+ impactBuilder, new BackendImpact(globalUses: staticUses));
}
/**
@@ -1892,7 +1804,8 @@ class JavaScriptBackend extends Backend {
return compiler.closedWorld.hasOnlySubclasses(classElement);
}
- void registerStaticUse(Enqueuer enqueuer, Element element) {
+ WorldImpact registerStaticUse(Element element, {bool forResolution}) {
+ WorldImpactBuilderImpl worldImpact = new WorldImpactBuilderImpl();
if (element == helpers.disableTreeShakingMarker) {
isTreeShakingDisabled = true;
} else if (element == helpers.preserveNamesMarker) {
@@ -1909,15 +1822,17 @@ class JavaScriptBackend extends Backend {
// TODO(sigurdm): Create a function registerLoadLibraryAccess.
if (!isLoadLibraryFunctionResolved) {
isLoadLibraryFunctionResolved = true;
- if (enqueuer.isResolutionQueue) {
- enqueue(enqueuer, helpers.loadLibraryWrapper);
+ if (forResolution) {
+ impactTransformer.registerBackendImpact(
+ worldImpact, impacts.loadLibrary);
}
}
} else if (element == helpers.requiresPreambleMarker) {
requiresPreamble = true;
}
customElementsAnalysis.registerStaticUse(element,
- forResolution: enqueuer.isResolutionQueue);
+ forResolution: forResolution);
+ return worldImpact;
}
/// Called when [:const Symbol(name):] is seen.
@@ -2344,13 +2259,11 @@ class JavaScriptBackend extends Backend {
//
// Return early if any elements are added to avoid counting the elements as
// due to mirrors.
+ enqueuer.applyImpact(customElementsAnalysis.flush(
+ forResolution: enqueuer.isResolutionQueue));
enqueuer.applyImpact(
- compiler.impactStrategy,
- customElementsAnalysis.flush(
- forResolution: enqueuer.isResolutionQueue));
- enqueuer.applyImpact(compiler.impactStrategy,
lookupMapAnalysis.flush(forResolution: enqueuer.isResolutionQueue));
- enqueuer.applyImpact(compiler.impactStrategy,
+ enqueuer.applyImpact(
typeVariableHandler.flush(forResolution: enqueuer.isResolutionQueue));
if (!enqueuer.queueIsEmpty) return false;
@@ -2359,7 +2272,7 @@ class JavaScriptBackend extends Backend {
if (!enabledNoSuchMethod &&
(noSuchMethodRegistry.hasThrowingNoSuchMethod ||
noSuchMethodRegistry.hasComplexNoSuchMethod)) {
- enableNoSuchMethod(enqueuer);
+ enqueuer.applyImpact(enableNoSuchMethod());
enabledNoSuchMethod = true;
}
@@ -2369,10 +2282,10 @@ class JavaScriptBackend extends Backend {
if (compiler.options.hasIncrementalSupport) {
// Always enable tear-off closures during incremental compilation.
- Element e = helpers.closureFromTearOff;
- if (e != null && !enqueuer.isProcessed(e)) {
- registerBackendUse(e);
- enqueuer.addToWorkList(e);
+ Element element = helpers.closureFromTearOff;
+ if (element != null && !enqueuer.isProcessed(element)) {
+ enqueuer.applyImpact(
+ impactTransformer.createImpactFor(impacts.closureClass));
}
}
@@ -2381,19 +2294,17 @@ class JavaScriptBackend extends Backend {
}
if (isTreeShakingDisabled) {
- enqueuer.applyImpact(
- compiler.impactStrategy,
- mirrorsAnalysis.computeImpactForReflectiveElements(recentClasses,
- enqueuer.processedClasses, compiler.libraryLoader.libraries,
- forResolution: enqueuer.isResolutionQueue));
+ enqueuer.applyImpact(mirrorsAnalysis.computeImpactForReflectiveElements(
+ recentClasses,
+ enqueuer.processedClasses,
+ compiler.libraryLoader.libraries,
+ forResolution: enqueuer.isResolutionQueue));
} else if (!targetsUsed.isEmpty && enqueuer.isResolutionQueue) {
// Add all static elements (not classes) that have been requested for
// reflection. If there is no mirror-usage these are probably not
// necessary, but the backend relies on them being resolved.
- enqueuer.applyImpact(
- compiler.impactStrategy,
- mirrorsAnalysis.computeImpactForReflectiveStaticFields(
- _findStaticFieldTargets(),
+ enqueuer.applyImpact(mirrorsAnalysis
+ .computeImpactForReflectiveStaticFields(_findStaticFieldTargets(),
forResolution: enqueuer.isResolutionQueue));
}
@@ -2430,7 +2341,7 @@ class JavaScriptBackend extends Backend {
}
metadataConstants.clear();
}
- enqueuer.applyImpact(compiler.impactStrategy, impactBuilder.flush());
+ enqueuer.applyImpact(impactBuilder.flush());
}
return true;
}
@@ -2579,7 +2490,8 @@ class JavaScriptBackend extends Backend {
}
@override
- WorldImpact computeMainImpact(Enqueuer enqueuer, MethodElement mainMethod) {
+ WorldImpact computeMainImpact(MethodElement mainMethod,
+ {bool forResolution}) {
WorldImpactBuilderImpl mainImpact = new WorldImpactBuilderImpl();
if (mainMethod.parameters.isNotEmpty) {
impactTransformer.registerBackendImpact(
@@ -2590,7 +2502,7 @@ class JavaScriptBackend extends Backend {
// target of Isolate.spawnUri. Strictly speaking, that can happen also if
// main takes no arguments, but in this case the spawned isolate can't
// communicate with the spawning isolate.
- enqueuer.enableIsolateSupport();
+ mainImpact.addImpact(enableIsolateSupport(forResolution: forResolution));
}
mainImpact.registerStaticUse(
new StaticUse.staticInvoke(mainMethod, CallStructure.NO_ARGS));
@@ -2612,11 +2524,7 @@ class JavaScriptBackend extends Backend {
}
@override
- bool enableDeferredLoadingIfSupported(
- ResolutionEnqueuer enqueuer, Spannable node) {
- registerCheckDeferredIsLoaded(enqueuer);
- return true;
- }
+ bool enableDeferredLoadingIfSupported(Spannable node) => true;
@override
bool enableCodegenWithErrorsIfSupported(Spannable node) => true;
@@ -3011,14 +2919,44 @@ class JavaScriptImpactTransformer extends ImpactTransformer {
return transformed;
}
+ WorldImpact createImpactFor(BackendImpact impact) {
+ WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
+ registerBackendImpact(impactBuilder, impact);
+ return impactBuilder;
+ }
+
+ void registerBackendStaticUse(
+ WorldImpactBuilder worldImpact, MethodElement element,
+ {bool isGlobal: false}) {
+ backend.registerBackendUse(element);
+ worldImpact.registerStaticUse(
+ // TODO(johnniwinther): Store the correct use in impacts.
+ new StaticUse.foreignUse(element));
+ if (isGlobal) {
+ backend.compiler.globalDependencies.registerDependency(element);
+ }
+ }
+
+ void registerBackendInstantiation(
+ WorldImpactBuilder worldImpact, ClassElement cls,
+ {bool isGlobal: false}) {
+ cls.ensureResolved(backend.resolution);
+ backend.registerBackendUse(cls);
+ worldImpact.registerTypeUse(new TypeUse.instantiation(cls.rawType));
+ if (isGlobal) {
+ backend.compiler.globalDependencies.registerDependency(cls);
+ }
+ }
+
void registerBackendImpact(
WorldImpactBuilder worldImpact, BackendImpact backendImpact) {
for (Element staticUse in backendImpact.staticUses) {
assert(staticUse != null);
- backend.registerBackendUse(staticUse);
- worldImpact.registerStaticUse(
- // TODO(johnniwinther): Store the correct use in impacts.
- new StaticUse.foreignUse(staticUse));
+ registerBackendStaticUse(worldImpact, staticUse);
+ }
+ for (Element staticUse in backendImpact.globalUses) {
+ assert(staticUse != null);
+ registerBackendStaticUse(worldImpact, staticUse, isGlobal: true);
}
for (Selector selector in backendImpact.dynamicUses) {
assert(selector != null);
@@ -3029,9 +2967,10 @@ class JavaScriptImpactTransformer extends ImpactTransformer {
worldImpact.registerTypeUse(new TypeUse.instantiation(instantiatedType));
}
for (ClassElement cls in backendImpact.instantiatedClasses) {
- cls.ensureResolved(backend.resolution);
- backend.registerBackendUse(cls);
- worldImpact.registerTypeUse(new TypeUse.instantiation(cls.rawType));
+ registerBackendInstantiation(worldImpact, cls);
+ }
+ for (ClassElement cls in backendImpact.globalClasses) {
+ registerBackendInstantiation(worldImpact, cls, isGlobal: true);
}
for (BackendImpact otherImpact in backendImpact.otherImpacts) {
registerBackendImpact(worldImpact, otherImpact);
« no previous file with comments | « pkg/compiler/lib/src/enqueue.dart ('k') | pkg/compiler/lib/src/js_backend/backend_helpers.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698