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

Unified Diff: pkg/compiler/lib/src/enqueue.dart

Issue 2494093002: Refactor enqueuers (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/deferred_load.dart ('k') | pkg/compiler/lib/src/js_backend/backend.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/enqueue.dart
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart
index b254e0d75b57c89d186b5c1b291c05430546dc88..660e2e866dedf682cf5e6a9e716f54cdcfdb7bc3 100644
--- a/pkg/compiler/lib/src/enqueue.dart
+++ b/pkg/compiler/lib/src/enqueue.dart
@@ -19,16 +19,12 @@ import 'elements/elements.dart'
AnalyzableElement,
AstElement,
ClassElement,
- ConstructorElement,
Element,
- Elements,
Entity,
FunctionElement,
LibraryElement,
- Member,
- Name,
- TypedElement,
- TypedefElement;
+ LocalFunctionElement,
+ TypedElement;
import 'native/native.dart' as native;
import 'types/types.dart' show TypeMaskStrategy;
import 'universe/selector.dart' show Selector;
@@ -100,15 +96,7 @@ abstract class Enqueuer {
void enableIsolateSupport();
- /// Enqueue the static fields that have been marked as used by reflective
- /// usage through `MirrorsUsed`.
- void enqueueReflectiveStaticFields(Iterable<Element> elements);
-
- /// Enqueue all elements that are matched by the mirrors used
- /// annotation or, in lack thereof, all elements.
- void enqueueReflectiveElements(Iterable<ClassElement> recents);
-
- void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false});
+ void registerInstantiatedType(InterfaceType type);
void forEach(void f(WorkItem work));
/// Apply the [worldImpact] to this enqueuer. If the [impactSource] is provided
@@ -122,6 +110,8 @@ abstract class Enqueuer {
bool isProcessed(Element member);
Iterable<Entity> get processedEntities;
+
+ Iterable<ClassElement> get processedClasses;
}
/// [Enqueuer] which is specific to resolution.
@@ -138,14 +128,8 @@ class ResolutionEnqueuer extends Enqueuer {
final ResolutionWorldBuilderImpl _universe =
new ResolutionWorldBuilderImpl(const TypeMaskStrategy());
- static final TRACE_MIRROR_ENQUEUING =
- const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING");
-
bool queueIsClosed = false;
- bool hasEnqueuedReflectiveElements = false;
- bool hasEnqueuedReflectiveStaticFields = false;
-
WorldImpactVisitor impactVisitor;
ResolutionEnqueuer(Compiler compiler, this.strategy)
@@ -186,12 +170,19 @@ class ResolutionEnqueuer extends Enqueuer {
}
}
+ void registerInstantiatedType(InterfaceType type) {
+ _registerInstantiatedType(type, globalDependency: true);
+ }
+
void applyImpact(WorldImpact worldImpact, {Element impactSource}) {
compiler.impactStrategy
.visitImpact(impactSource, worldImpact, impactVisitor, impactUse);
}
- void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false}) {
+ void _registerInstantiatedType(InterfaceType type,
+ {bool mirrorUsage: false,
+ bool nativeUsage: false,
+ bool globalDependency: false}) {
task.measure(() {
ClassElement cls = type.element;
cls.ensureResolved(resolution);
@@ -199,9 +190,15 @@ class ResolutionEnqueuer extends Enqueuer {
_universe.registerTypeInstantiation(type,
isNative: isNative,
byMirrors: mirrorUsage, onImplemented: (ClassElement cls) {
- compiler.backend
- .registerImplementedClass(cls, this, compiler.globalDependencies);
+ compiler.backend.registerImplementedClass(cls, this);
});
+ if (globalDependency && !mirrorUsage) {
+ compiler.globalDependencies.registerDependency(type.element);
+ }
+ if (nativeUsage) {
+ nativeEnqueuer.onInstantiatedType(type);
+ }
+ compiler.backend.registerInstantiatedType(type);
// TODO(johnniwinther): Share this reasoning with [Universe].
if (!cls.isAbstract || isNative || mirrorUsage) {
processInstantiatedClass(cls);
@@ -325,8 +322,7 @@ class ResolutionEnqueuer extends Enqueuer {
// We only tell the backend once that [superclass] was instantiated, so
// any additional dependencies must be treated as global
// dependencies.
- compiler.backend.registerInstantiatedClass(
- superclass, this, compiler.globalDependencies);
+ compiler.backend.registerInstantiatedClass(superclass, this);
}
ClassElement superclass = cls;
@@ -345,172 +341,6 @@ class ResolutionEnqueuer extends Enqueuer {
});
}
- void logEnqueueReflectiveAction(action, [msg = ""]) {
- if (TRACE_MIRROR_ENQUEUING) {
- print("MIRROR_ENQUEUE (R): $action $msg");
- }
- }
-
- /// Enqeue the constructor [ctor] if it is required for reflection.
- ///
- /// [enclosingWasIncluded] provides a hint whether the enclosing element was
- /// needed for reflection.
- void enqueueReflectiveConstructor(
- ConstructorElement ctor, bool enclosingWasIncluded) {
- if (shouldIncludeElementDueToMirrors(ctor,
- includedEnclosing: enclosingWasIncluded)) {
- logEnqueueReflectiveAction(ctor);
- ClassElement cls = ctor.declaration.enclosingClass;
- compiler.backend.registerInstantiatedType(
- cls.rawType, this, compiler.mirrorDependencies,
- mirrorUsage: true);
- registerStaticUse(new StaticUse.foreignUse(ctor.declaration));
- }
- }
-
- /// Enqeue the member [element] if it is required for reflection.
- ///
- /// [enclosingWasIncluded] provides a hint whether the enclosing element was
- /// needed for reflection.
- void enqueueReflectiveMember(Element element, bool enclosingWasIncluded) {
- if (shouldIncludeElementDueToMirrors(element,
- includedEnclosing: enclosingWasIncluded)) {
- logEnqueueReflectiveAction(element);
- if (element.isTypedef) {
- TypedefElement typedef = element;
- typedef.ensureResolved(resolution);
- } else if (Elements.isStaticOrTopLevel(element)) {
- registerStaticUse(new StaticUse.foreignUse(element.declaration));
- } else if (element.isInstanceMember) {
- // We need to enqueue all members matching this one in subclasses, as
- // well.
- // TODO(herhut): Use TypedSelector.subtype for enqueueing
- DynamicUse dynamicUse =
- new DynamicUse(new Selector.fromElement(element), null);
- registerDynamicUse(dynamicUse);
- if (element.isField) {
- DynamicUse dynamicUse = new DynamicUse(
- new Selector.setter(
- new Name(element.name, element.library, isSetter: true)),
- null);
- registerDynamicUse(dynamicUse);
- }
- }
- }
- }
-
- /// Enqeue the member [element] if it is required for reflection.
- ///
- /// [enclosingWasIncluded] provides a hint whether the enclosing element was
- /// needed for reflection.
- void enqueueReflectiveElementsInClass(ClassElement cls,
- Iterable<ClassElement> recents, bool enclosingWasIncluded) {
- if (cls.library.isInternalLibrary || cls.isInjected) return;
- bool includeClass = shouldIncludeElementDueToMirrors(cls,
- includedEnclosing: enclosingWasIncluded);
- if (includeClass) {
- logEnqueueReflectiveAction(cls, "register");
- ClassElement decl = cls.declaration;
- decl.ensureResolved(resolution);
- compiler.backend.registerInstantiatedType(
- decl.rawType, this, compiler.mirrorDependencies,
- mirrorUsage: true);
- }
- // If the class is never instantiated, we know nothing of it can possibly
- // be reflected upon.
- // TODO(herhut): Add a warning if a mirrors annotation cannot hit.
- if (recents.contains(cls.declaration)) {
- logEnqueueReflectiveAction(cls, "members");
- cls.constructors.forEach((Element element) {
- enqueueReflectiveConstructor(element, includeClass);
- });
- cls.forEachClassMember((Member member) {
- enqueueReflectiveMember(member.element, includeClass);
- });
- }
- }
-
- /// Enqeue special classes that might not be visible by normal means or that
- /// would not normally be enqueued:
- ///
- /// [Closure] is treated specially as it is the superclass of all closures.
- /// Although it is in an internal library, we mark it as reflectable. Note
- /// that none of its methods are reflectable, unless reflectable by
- /// inheritance.
- void enqueueReflectiveSpecialClasses() {
- Iterable<ClassElement> classes =
- compiler.backend.classesRequiredForReflection;
- for (ClassElement cls in classes) {
- if (compiler.backend.referencedFromMirrorSystem(cls)) {
- logEnqueueReflectiveAction(cls);
- cls.ensureResolved(resolution);
- compiler.backend.registerInstantiatedType(
- cls.rawType, this, compiler.mirrorDependencies,
- mirrorUsage: true);
- }
- }
- }
-
- /// Enqeue all local members of the library [lib] if they are required for
- /// reflection.
- void enqueueReflectiveElementsInLibrary(
- LibraryElement lib, Iterable<ClassElement> recents) {
- bool includeLibrary =
- shouldIncludeElementDueToMirrors(lib, includedEnclosing: false);
- lib.forEachLocalMember((Element member) {
- if (member.isInjected) return;
- if (member.isClass) {
- enqueueReflectiveElementsInClass(member, recents, includeLibrary);
- } else {
- enqueueReflectiveMember(member, includeLibrary);
- }
- });
- }
-
- /// Enqueue all elements that are matched by the mirrors used
- /// annotation or, in lack thereof, all elements.
- void enqueueReflectiveElements(Iterable<ClassElement> recents) {
- if (!hasEnqueuedReflectiveElements) {
- logEnqueueReflectiveAction("!START enqueueAll");
- // First round of enqueuing, visit everything that is visible to
- // also pick up static top levels, etc.
- // Also, during the first round, consider all classes that have been seen
- // as recently seen, as we do not know how many rounds of resolution might
- // have run before tree shaking is disabled and thus everything is
- // enqueued.
- recents = _processedClasses.toSet();
- reporter.log('Enqueuing everything');
- for (LibraryElement lib in compiler.libraryLoader.libraries) {
- enqueueReflectiveElementsInLibrary(lib, recents);
- }
- enqueueReflectiveSpecialClasses();
- hasEnqueuedReflectiveElements = true;
- hasEnqueuedReflectiveStaticFields = true;
- logEnqueueReflectiveAction("!DONE enqueueAll");
- } else if (recents.isNotEmpty) {
- // Keep looking at new classes until fixpoint is reached.
- logEnqueueReflectiveAction("!START enqueueRecents");
- recents.forEach((ClassElement cls) {
- enqueueReflectiveElementsInClass(
- cls,
- recents,
- shouldIncludeElementDueToMirrors(cls.library,
- includedEnclosing: false));
- });
- logEnqueueReflectiveAction("!DONE enqueueRecents");
- }
- }
-
- /// Enqueue the static fields that have been marked as used by reflective
- /// usage through `MirrorsUsed`.
- void enqueueReflectiveStaticFields(Iterable<Element> elements) {
- if (hasEnqueuedReflectiveStaticFields) return;
- hasEnqueuedReflectiveStaticFields = true;
- for (Element element in elements) {
- enqueueReflectiveMember(element, true);
- }
- }
-
void processSet(
Map<String, Set<Element>> map, String memberName, bool f(Element e)) {
Set<Element> members = map[memberName];
@@ -576,7 +406,7 @@ class ResolutionEnqueuer extends Enqueuer {
assert(invariant(element, element.isDeclaration,
message: "Element ${element} is not the declaration."));
_universe.registerStaticUse(staticUse);
- compiler.backend.registerStaticUse(element, forResolution: true);
+ compiler.backend.registerStaticUse(this, element);
bool addElement = true;
switch (staticUse.kind) {
case StaticUseKind.STATIC_TEAR_OFF:
@@ -589,6 +419,10 @@ class ResolutionEnqueuer extends Enqueuer {
// [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue.
// Also [CLOSURE] contains [LocalFunctionElement] which we cannot
// enqueue.
+ LocalFunctionElement closure = staticUse.element;
+ if (closure.type.containsTypeVariables) {
+ universe.closuresWithFreeTypeVariables.add(closure);
+ }
addElement = false;
break;
case StaticUseKind.SUPER_FIELD_SET:
@@ -613,7 +447,15 @@ class ResolutionEnqueuer extends Enqueuer {
DartType type = typeUse.type;
switch (typeUse.kind) {
case TypeUseKind.INSTANTIATION:
- registerInstantiatedType(type);
+ _registerInstantiatedType(type, globalDependency: false);
+ break;
+ case TypeUseKind.MIRROR_INSTANTIATION:
+ _registerInstantiatedType(type,
+ mirrorUsage: true, globalDependency: false);
+ break;
+ case TypeUseKind.NATIVE_INSTANTIATION:
+ _registerInstantiatedType(type,
+ nativeUsage: true, globalDependency: true);
break;
case TypeUseKind.IS_CHECK:
case TypeUseKind.AS_CAST:
@@ -639,16 +481,14 @@ class ResolutionEnqueuer extends Enqueuer {
}
void registerCallMethodWithFreeTypeVariables(Element element) {
- compiler.backend.registerCallMethodWithFreeTypeVariables(
- element, this, compiler.globalDependencies);
+ compiler.backend.registerCallMethodWithFreeTypeVariables(element, this);
_universe.callMethodsWithFreeTypeVariables.add(element);
}
void registerClosurizedMember(TypedElement element) {
assert(element.isInstanceMember);
if (element.computeType(resolution).containsTypeVariables) {
- compiler.backend.registerClosureWithFreeTypeVariables(
- element, this, compiler.globalDependencies);
+ compiler.backend.registerClosureWithFreeTypeVariables(element, this);
_universe.closuresWithFreeTypeVariables.add(element);
}
compiler.backend.registerBoundClosure(this);
@@ -706,20 +546,6 @@ class ResolutionEnqueuer extends Enqueuer {
}
/**
- * Decides whether an element should be included to satisfy requirements
- * of the mirror system.
- *
- * During resolution, we have to resort to matching elements against the
- * [MirrorsUsed] pattern, as we do not have a complete picture of the world,
- * yet.
- */
- bool shouldIncludeElementDueToMirrors(Element element,
- {bool includedEnclosing}) {
- return includedEnclosing ||
- compiler.backend.requiredByMirrorSystem(element);
- }
-
- /**
* Adds [element] to the work list if it has not already been processed.
*
* Returns [true] if the element was actually added to the queue.
@@ -765,7 +591,7 @@ class ResolutionEnqueuer extends Enqueuer {
// runtime type.
compiler.enabledRuntimeType = true;
// TODO(ahe): Record precise dependency here.
- compiler.backend.registerRuntimeType(this, compiler.globalDependencies);
+ compiler.backend.registerRuntimeType(this);
} else if (compiler.commonElements.isFunctionApplyMethod(element)) {
compiler.enabledFunctionApply = true;
}
« no previous file with comments | « pkg/compiler/lib/src/deferred_load.dart ('k') | pkg/compiler/lib/src/js_backend/backend.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698