Split deferred load entity computation by class, member and local function
Change-Id: Ifb612de6ac945d2ececa96871f0eb3fc5ceb4052
Reviewed-on: https://dart-review.googlesource.com/55896
Reviewed-by: Sigmund Cherem <sigmund@google.com>
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index 2064ae8..7418a1a 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -16,11 +16,9 @@
ConstructedConstantValue,
DeferredConstantValue,
DeferredGlobalConstantValue,
- InstantiationConstantValue,
- TypeConstantValue;
+ InstantiationConstantValue;
import 'elements/types.dart';
import 'elements/entities.dart';
-import 'kernel/kelements.dart' show KLocalFunction;
import 'universe/use.dart';
import 'universe/world_impact.dart'
show ImpactUseCase, WorldImpact, WorldImpactVisitorImpl;
@@ -111,8 +109,15 @@
/// this map.
final Map<ImportEntity, String> _importDeferName = <ImportEntity, String>{};
- /// A mapping from elements and constants to their import set.
- Map<Entity, ImportSet> _elementToSet = new Map<Entity, ImportSet>();
+ /// A mapping from classes to their import set.
+ Map<ClassEntity, ImportSet> _classToSet = new Map<ClassEntity, ImportSet>();
+
+ /// A mapping from members to their import set.
+ Map<MemberEntity, ImportSet> _memberToSet =
+ new Map<MemberEntity, ImportSet>();
+
+ /// A mapping from local functions to their import set.
+ Map<Local, ImportSet> _localFunctionToSet = new Map<Local, ImportSet>();
/// A mapping from constants to their import set.
Map<ConstantValue, ImportSet> _constantToSet =
@@ -180,69 +185,72 @@
}
/// Returns every [ImportEntity] that imports [element] into [library].
- Iterable<ImportEntity> importsTo(Entity element, LibraryEntity library);
+ Iterable<ImportEntity> classImportsTo(
+ ClassEntity element, LibraryEntity library);
+
+ /// Returns every [ImportEntity] that imports [element] into [library].
+ Iterable<ImportEntity> memberImportsTo(
+ MemberEntity element, LibraryEntity library);
+
+ /// Collects all direct dependencies of [element].
+ ///
+ /// The collected dependent elements and constants are are added to
+ /// [elements] and [constants] respectively.
+ void _collectDirectMemberDependencies(
+ MemberEntity element, Dependencies dependencies) {
+ // TODO(sigurdm): We want to be more specific about this - need a better
+ // way to query "liveness".
+ if (!compiler.resolutionWorldBuilder.isMemberUsed(element)) {
+ return;
+ }
+ _collectDependenciesFromImpact(element, dependencies);
+ collectConstantsInBody(element, dependencies);
+ }
/// Finds all elements and constants that [element] depends directly on.
/// (not the transitive closure.)
///
/// Adds the results to [elements] and [constants].
- void _collectAllElementsAndConstantsResolvedFrom(Entity element,
- Set<Entity> elements, Set<ConstantValue> constants, isMirrorUsage) {
- /// Collects all direct dependencies of [element].
- ///
- /// The collected dependent elements and constants are are added to
- /// [elements] and [constants] respectively.
- void collectDependencies(Entity element) {
- if (element is TypedefEntity) {
- _collectTypeDependencies(
- elementEnvironment.getTypedefTypeOfTypedef(element), elements);
- return;
- }
-
- // TODO(sigurdm): We want to be more specific about this - need a better
- // way to query "liveness".
- if (!compiler.resolutionWorldBuilder.isMemberUsed(element)) {
- return;
- }
- _collectDependenciesFromImpact(element, elements);
- collectConstantsInBody(element, constants);
+ void _collectAllElementsAndConstantsResolvedFromClass(
+ ClassEntity element, Dependencies dependencies) {
+ // If we see a class, add everything its live instance members refer
+ // to. Static members are not relevant, unless we are processing
+ // extra dependencies due to mirrors.
+ void addLiveInstanceMember(MemberEntity member) {
+ if (!compiler.resolutionWorldBuilder.isMemberUsed(member)) return;
+ if (!member.isInstanceMember) return;
+ dependencies.members.add(member);
+ _collectDirectMemberDependencies(member, dependencies);
}
+ ClassEntity cls = element;
+ elementEnvironment.forEachLocalClassMember(cls, addLiveInstanceMember);
+ elementEnvironment.forEachSupertype(cls, (InterfaceType type) {
+ _collectTypeDependencies(type, dependencies);
+ });
+ dependencies.classes.add(cls);
+ }
+
+ /// Finds all elements and constants that [element] depends directly on.
+ /// (not the transitive closure.)
+ ///
+ /// Adds the results to [elements] and [constants].
+ void _collectAllElementsAndConstantsResolvedFromMember(
+ MemberEntity element, Dependencies dependencies) {
if (element is FunctionEntity) {
_collectTypeDependencies(
- elementEnvironment.getFunctionType(element), elements);
+ elementEnvironment.getFunctionType(element), dependencies);
}
-
- if (element is ClassEntity) {
- // If we see a class, add everything its live instance members refer
- // to. Static members are not relevant, unless we are processing
- // extra dependencies due to mirrors.
- void addLiveInstanceMember(_element) {
- MemberEntity element = _element;
- if (!compiler.resolutionWorldBuilder.isMemberUsed(element)) return;
- if (!isMirrorUsage && !element.isInstanceMember) return;
- elements.add(element);
- collectDependencies(element);
- }
-
- ClassEntity cls = element;
- elementEnvironment.forEachLocalClassMember(cls, addLiveInstanceMember);
- elementEnvironment.forEachSupertype(cls, (InterfaceType type) {
- _collectTypeDependencies(type, elements);
- });
- elements.add(cls);
- } else if (element is MemberEntity &&
- (element.isStatic || element.isTopLevel || element.isConstructor)) {
- elements.add(element);
- collectDependencies(element);
+ if (element.isStatic || element.isTopLevel || element.isConstructor) {
+ dependencies.members.add(element);
+ _collectDirectMemberDependencies(element, dependencies);
}
if (element is ConstructorEntity && element.isGenerativeConstructor) {
// When instantiating a class, we record a reference to the
// constructor, not the class itself. We must add all the
// instance members of the constructor's class.
ClassEntity cls = element.enclosingClass;
- _collectAllElementsAndConstantsResolvedFrom(
- cls, elements, constants, isMirrorUsage);
+ _collectAllElementsAndConstantsResolvedFromClass(cls, dependencies);
}
// Other elements, in particular instance members, are ignored as
@@ -257,45 +265,55 @@
Entity element, Set<ConstantValue> constants);
/// Extract the set of constants that are used in the body of [element].
- void collectConstantsInBody(Entity element, Set<ConstantValue> constants);
+ void collectConstantsInBody(MemberEntity element, Dependencies dependencies);
/// Recursively collects all the dependencies of [type].
- void _collectTypeDependencies(DartType type, Set<Entity> elements) {
+ void _collectTypeDependencies(DartType type, Dependencies dependencies) {
// TODO(het): we would like to separate out types that are only needed for
// rti from types that are needed for their members.
if (type is FunctionType) {
for (DartType argumentType in type.parameterTypes) {
- _collectTypeDependencies(argumentType, elements);
+ _collectTypeDependencies(argumentType, dependencies);
}
for (DartType argumentType in type.optionalParameterTypes) {
- _collectTypeDependencies(argumentType, elements);
+ _collectTypeDependencies(argumentType, dependencies);
}
for (DartType argumentType in type.namedParameterTypes) {
- _collectTypeDependencies(argumentType, elements);
+ _collectTypeDependencies(argumentType, dependencies);
}
- _collectTypeDependencies(type.returnType, elements);
+ _collectTypeDependencies(type.returnType, dependencies);
} else if (type is TypedefType) {
- type.typeArguments.forEach((t) => _collectTypeDependencies(t, elements));
- elements.add(type.element);
- _collectTypeDependencies(type.unaliased, elements);
+ type.typeArguments
+ .forEach((t) => _collectTypeDependencies(t, dependencies));
+ _collectTypeDependencies(type.unaliased, dependencies);
} else if (type is InterfaceType) {
- type.typeArguments.forEach((t) => _collectTypeDependencies(t, elements));
- elements.add(type.element);
+ type.typeArguments
+ .forEach((t) => _collectTypeDependencies(t, dependencies));
+ dependencies.classes.add(type.element);
}
}
/// Extract any dependencies that are known from the impact of [element].
- void _collectDependenciesFromImpact(Entity element, Set<Entity> elements) {
+ void _collectDependenciesFromImpact(
+ MemberEntity element, Dependencies dependencies) {
WorldImpact worldImpact = compiler.impactCache[element];
compiler.impactStrategy.visitImpact(
element,
worldImpact,
new WorldImpactVisitorImpl(visitStaticUse: (StaticUse staticUse) {
- elements.add(staticUse.element);
+ if (staticUse.element is MemberEntity) {
+ dependencies.members.add(staticUse.element);
+ } else {
+ assert(
+ staticUse.element is Local,
+ failedAt(
+ staticUse.element, "Unexpected static use $staticUse."));
+ dependencies.localFunctions.add(staticUse.element);
+ }
switch (staticUse.kind) {
case StaticUseKind.CONSTRUCTOR_INVOKE:
case StaticUseKind.CONST_CONSTRUCTOR_INVOKE:
- _collectTypeDependencies(staticUse.type, elements);
+ _collectTypeDependencies(staticUse.type, dependencies);
break;
case StaticUseKind.INVOKE:
case StaticUseKind.CLOSURE_CALL:
@@ -305,7 +323,7 @@
List<DartType> typeArguments = staticUse.typeArguments;
if (typeArguments != null) {
for (DartType typeArgument in typeArguments) {
- _collectTypeDependencies(typeArgument, elements);
+ _collectTypeDependencies(typeArgument, dependencies);
}
}
break;
@@ -315,12 +333,9 @@
DartType type = typeUse.type;
switch (typeUse.kind) {
case TypeUseKind.TYPE_LITERAL:
- if (type.isTypedef) {
- TypedefType typedef = type;
- elements.add(typedef.element);
- } else if (type.isInterfaceType) {
+ if (type.isInterfaceType) {
InterfaceType interface = type;
- elements.add(interface.element);
+ dependencies.classes.add(interface.element);
}
break;
case TypeUseKind.INSTANTIATION:
@@ -329,21 +344,21 @@
case TypeUseKind.IS_CHECK:
case TypeUseKind.AS_CAST:
case TypeUseKind.CATCH_TYPE:
- _collectTypeDependencies(type, elements);
+ _collectTypeDependencies(type, dependencies);
break;
case TypeUseKind.IMPLICIT_CAST:
if (compiler.options.implicitDowncastCheckPolicy.isEmitted) {
- _collectTypeDependencies(type, elements);
+ _collectTypeDependencies(type, dependencies);
}
break;
case TypeUseKind.PARAMETER_CHECK:
if (compiler.options.parameterCheckPolicy.isEmitted) {
- _collectTypeDependencies(type, elements);
+ _collectTypeDependencies(type, dependencies);
}
break;
case TypeUseKind.CHECKED_MODE_CHECK:
if (compiler.options.assignmentCheckPolicy.isEmitted) {
- _collectTypeDependencies(type, elements);
+ _collectTypeDependencies(type, dependencies);
}
break;
}
@@ -353,7 +368,7 @@
List<DartType> typeArguments = dynamicUse.typeArguments;
if (typeArguments != null) {
for (DartType typeArgument in typeArguments) {
- _collectTypeDependencies(typeArgument, elements);
+ _collectTypeDependencies(typeArgument, dependencies);
}
}
}),
@@ -380,18 +395,12 @@
_constantToSet[constant] = newSet;
if (constant is ConstructedConstantValue) {
ClassEntity cls = constant.type.element;
- _updateElementRecursive(cls, oldSet, newSet, queue);
- }
- if (constant is TypeConstantValue) {
- var type = constant.representedType;
- if (type is TypedefType) {
- _updateElementRecursive(type.element, oldSet, newSet, queue);
- }
+ _updateClassRecursive(cls, oldSet, newSet, queue);
}
if (constant is InstantiationConstantValue) {
for (DartType type in constant.typeArguments) {
if (type is InterfaceType) {
- _updateElementRecursive(type.element, oldSet, newSet, queue);
+ _updateClassRecursive(type.element, oldSet, newSet, queue);
}
}
}
@@ -421,77 +430,111 @@
}
}
- /// Update the import set of all elements reachable from [element], as long as
- /// they had the [oldSet]. As soon as we see an element with a different
- /// import set, we stop and enqueue a new recursive update in [queue].
- void _updateElementRecursive(
- Entity element, ImportSet oldSet, ImportSet newSet, WorkQueue queue,
- {bool isMirrorUsage: false}) {
+ void _updateClassRecursive(ClassEntity element, ImportSet oldSet,
+ ImportSet newSet, WorkQueue queue) {
if (element == null) return;
- var currentSet = _elementToSet[element];
+
+ ImportSet currentSet = _classToSet[element];
// Already visited. We may visit some root nodes a second time with
// [isMirrorUsage] in order to mark static members used reflectively.
- if (currentSet == newSet && !isMirrorUsage) return;
+ if (currentSet == newSet) return;
// Elements in the main output unit always remain there.
if (currentSet == importSets.mainSet) return;
if (currentSet == oldSet) {
// Continue recursively updating from [oldSet] to [newSet].
- _elementToSet[element] = newSet;
+ _classToSet[element] = newSet;
- Set<Entity> dependentElements = new Set<Entity>();
- Set<ConstantValue> dependentConstants = new Set<ConstantValue>();
- _collectAllElementsAndConstantsResolvedFrom(
- element, dependentElements, dependentConstants, isMirrorUsage);
-
- // TODO(sigmund): split API to collect data about each kind of entity
- // separately so we can avoid this ugly pattern.
- LibraryEntity library;
- if (element is ClassEntity) {
- library = element.library;
- } else if (element is MemberEntity) {
- library = element.library;
- } else if (element is TypedefEntity) {
- library = element.library;
- } else if (element is KLocalFunction) {
- // TODO(sigmund): consider adding `Local.library`
- library = element.memberContext.library;
- } else {
- assert(false, "Unexpected entity: ${element.runtimeType}");
- }
-
- for (Entity dependency in dependentElements) {
- Iterable<ImportEntity> imports = importsTo(dependency, library);
- if (_isExplicitlyDeferred(imports)) {
- /// New deferred-imports are only discovered when we are visiting the
- /// main output unit (size == 0) or code reachable from a deferred
- /// import (size == 1). After that, we are rediscovering the
- /// same nodes we have already seen.
- if (newSet.length <= 1) {
- for (ImportEntity deferredImport in imports) {
- queue.addElement(
- dependency, importSets.singleton(deferredImport));
- }
- }
- } else {
- _updateElementRecursive(dependency, oldSet, newSet, queue);
- }
- }
-
- for (ConstantValue dependency in dependentConstants) {
- if (dependency is DeferredConstantValue) {
- if (newSet.length <= 1) {
- queue.addConstant(
- dependency, importSets.singleton(dependency.import));
- }
- } else {
- _updateConstantRecursive(dependency, oldSet, newSet, queue);
- }
- }
+ Dependencies dependencies = new Dependencies();
+ _collectAllElementsAndConstantsResolvedFromClass(element, dependencies);
+ LibraryEntity library = element.library;
+ _processDependencies(library, dependencies, oldSet, newSet, queue);
} else {
- queue.addElement(element, newSet);
+ queue.addClass(element, newSet);
+ }
+ }
+
+ void _updateMemberRecursive(MemberEntity element, ImportSet oldSet,
+ ImportSet newSet, WorkQueue queue) {
+ if (element == null) return;
+
+ ImportSet currentSet = _memberToSet[element];
+
+ // Already visited. We may visit some root nodes a second time with
+ // [isMirrorUsage] in order to mark static members used reflectively.
+ if (currentSet == newSet) return;
+
+ // Elements in the main output unit always remain there.
+ if (currentSet == importSets.mainSet) return;
+
+ if (currentSet == oldSet) {
+ // Continue recursively updating from [oldSet] to [newSet].
+ _memberToSet[element] = newSet;
+
+ Dependencies dependencies = new Dependencies();
+ _collectAllElementsAndConstantsResolvedFromMember(element, dependencies);
+
+ LibraryEntity library = element.library;
+ _processDependencies(library, dependencies, oldSet, newSet, queue);
+ } else {
+ queue.addMember(element, newSet);
+ }
+ }
+
+ void _processDependencies(LibraryEntity library, Dependencies dependencies,
+ ImportSet oldSet, ImportSet newSet, WorkQueue queue) {
+ for (ClassEntity cls in dependencies.classes) {
+ Iterable<ImportEntity> imports = classImportsTo(cls, library);
+ if (_isExplicitlyDeferred(imports)) {
+ /// New deferred-imports are only discovered when we are visiting the
+ /// main output unit (size == 0) or code reachable from a deferred
+ /// import (size == 1). After that, we are rediscovering the
+ /// same nodes we have already seen.
+ if (newSet.length <= 1) {
+ for (ImportEntity deferredImport in imports) {
+ queue.addClass(cls, importSets.singleton(deferredImport));
+ }
+ }
+ } else {
+ _updateClassRecursive(cls, oldSet, newSet, queue);
+ }
+ }
+
+ for (MemberEntity member in dependencies.members) {
+ Iterable<ImportEntity> imports = memberImportsTo(member, library);
+ if (_isExplicitlyDeferred(imports)) {
+ /// New deferred-imports are only discovered when we are visiting the
+ /// main output unit (size == 0) or code reachable from a deferred
+ /// import (size == 1). After that, we are rediscovering the
+ /// same nodes we have already seen.
+ if (newSet.length <= 1) {
+ for (ImportEntity deferredImport in imports) {
+ queue.addMember(member, importSets.singleton(deferredImport));
+ }
+ }
+ } else {
+ _updateMemberRecursive(member, oldSet, newSet, queue);
+ }
+ }
+
+ for (Local localFunction in dependencies.localFunctions) {
+ // Local function are not updated recursively because the dependencies are
+ // already visited as dependencies of the enclosing member, so we just
+ // assign the [newSet] to each local function.
+ _localFunctionToSet[localFunction] = newSet;
+ }
+
+ for (ConstantValue dependency in dependencies.constants) {
+ if (dependency is DeferredConstantValue) {
+ if (newSet.length <= 1) {
+ queue.addConstant(
+ dependency, importSets.singleton(dependency.import));
+ }
+ } else {
+ _updateConstantRecursive(dependency, oldSet, newSet, queue);
+ }
}
}
@@ -517,7 +560,9 @@
// Generate an output unit for all import sets that are associated with an
// element or constant.
- _elementToSet.values.forEach(addUnit);
+ _classToSet.values.forEach(addUnit);
+ _memberToSet.values.forEach(addUnit);
+ _localFunctionToSet.values.forEach(addUnit);
_constantToSet.values.forEach(addUnit);
// Sort output units to make the output of the compiler more stable.
@@ -665,7 +710,7 @@
// Add `main` and their recursive dependencies to the main output unit.
// We do this upfront to avoid wasting time visiting these elements when
// analyzing deferred imports.
- queue.addElement(main, importSets.mainSet);
+ queue.addMember(main, importSets.mainSet);
// Also add "global" dependencies to the main output unit. These are
// things that the backend needs but cannot associate with a particular
@@ -673,26 +718,17 @@
// information.
for (MemberEntity element
in closedWorld.backendUsage.globalFunctionDependencies) {
- queue.addElement(element, importSets.mainSet);
+ queue.addMember(element, importSets.mainSet);
}
for (ClassEntity element
in closedWorld.backendUsage.globalClassDependencies) {
- queue.addElement(element, importSets.mainSet);
+ queue.addClass(element, importSets.mainSet);
}
void emptyQueue() {
while (queue.isNotEmpty) {
- var item = queue.nextItem();
- if (item.element != null) {
- var oldSet = _elementToSet[item.element];
- var newSet = importSets.union(oldSet, item.newSet);
- _updateElementRecursive(item.element, oldSet, newSet, queue,
- isMirrorUsage: item.isMirrorUsage);
- } else if (item.value != null) {
- var oldSet = _constantToSet[item.value];
- var newSet = importSets.union(oldSet, item.newSet);
- _updateConstantRecursive(item.value, oldSet, newSet, queue);
- }
+ WorkItem item = queue.nextItem();
+ item.update(this, queue);
}
}
@@ -710,16 +746,29 @@
OutputUnitData _buildResult() {
_createOutputUnits();
_setupHunksToLoad();
- Map<Entity, OutputUnit> entityMap = <Entity, OutputUnit>{};
+ Map<ClassEntity, OutputUnit> classMap = <ClassEntity, OutputUnit>{};
+ Map<MemberEntity, OutputUnit> memberMap = <MemberEntity, OutputUnit>{};
+ Map<Local, OutputUnit> localFunctionMap = <Local, OutputUnit>{};
Map<ConstantValue, OutputUnit> constantMap = <ConstantValue, OutputUnit>{};
- _elementToSet.forEach((entity, s) => entityMap[entity] = s.unit);
+ _classToSet.forEach((cls, s) => classMap[cls] = s.unit);
+ _memberToSet.forEach((member, s) => memberMap[member] = s.unit);
+ _localFunctionToSet.forEach(
+ (localFunction, s) => localFunctionMap[localFunction] = s.unit);
_constantToSet.forEach((constant, s) => constantMap[constant] = s.unit);
- _elementToSet = null;
+ _classToSet = null;
+ _memberToSet = null;
+ _localFunctionToSet = null;
_constantToSet = null;
cleanup();
- return new OutputUnitData(this.isProgramSplit && !disableProgramSplit,
- this.mainOutputUnit, entityMap, constantMap, importSets);
+ return new OutputUnitData(
+ this.isProgramSplit && !disableProgramSplit,
+ this.mainOutputUnit,
+ classMap,
+ memberMap,
+ localFunctionMap,
+ constantMap,
+ importSets);
}
/// Frees up strategy-specific temporary data.
@@ -808,25 +857,31 @@
String dump() {
Map<OutputUnit, List<String>> elementMap = <OutputUnit, List<String>>{};
Map<OutputUnit, List<String>> constantMap = <OutputUnit, List<String>>{};
- _elementToSet.forEach((Entity element, ImportSet importSet) {
+ _classToSet.forEach((ClassEntity element, ImportSet importSet) {
if (ignoreEntityInDump(element)) return;
var elements = elementMap.putIfAbsent(importSet.unit, () => <String>[]);
var id = element.name ?? '$element';
- if (element is MemberEntity) {
- var cls = element.enclosingClass?.name;
- if (cls != null) id = '$cls.$id';
- if (element.isSetter) id = '$id=';
- id = '$id member';
- } else if (element is ClassEntity) {
- id = '$id cls';
- } else if (element is TypedefEntity) {
- id = '$id typedef';
- } else if (element is Local) {
- var context = (element as dynamic).memberContext.name;
- id = element.name == null || element.name == '' ? '<anonymous>' : id;
- id = '$context.$id';
- id = '$id local';
- }
+ id = '$id cls';
+ elements.add(id);
+ });
+ _memberToSet.forEach((MemberEntity element, ImportSet importSet) {
+ if (ignoreEntityInDump(element)) return;
+ var elements = elementMap.putIfAbsent(importSet.unit, () => <String>[]);
+ var id = element.name ?? '$element';
+ var cls = element.enclosingClass?.name;
+ if (cls != null) id = '$cls.$id';
+ if (element.isSetter) id = '$id=';
+ id = '$id member';
+ elements.add(id);
+ });
+ _localFunctionToSet.forEach((Local element, ImportSet importSet) {
+ if (ignoreEntityInDump(element)) return;
+ var elements = elementMap.putIfAbsent(importSet.unit, () => <String>[]);
+ var id = element.name ?? '$element';
+ var context = (element as dynamic).memberContext.name;
+ id = element.name == null || element.name == '' ? '<anonymous>' : id;
+ id = '$context.$id';
+ id = '$id local';
elements.add(id);
});
_constantToSet.forEach((ConstantValue value, ImportSet importSet) {
@@ -1027,8 +1082,11 @@
/// The actual queue of work that needs to be done.
final Queue<WorkItem> queue = new Queue<WorkItem>();
- /// An index to find work items in the queue corresponding to an entity.
- final Map<Entity, WorkItem> pendingElements = <Entity, WorkItem>{};
+ /// An index to find work items in the queue corresponding to a class.
+ final Map<ClassEntity, WorkItem> pendingClasses = <ClassEntity, WorkItem>{};
+
+ /// An index to find work items in the queue corresponding to a member.
+ final Map<MemberEntity, WorkItem> pendingMembers = <MemberEntity, WorkItem>{};
/// An index to find work items in the queue corresponding to a constant.
final Map<ConstantValue, WorkItem> pendingConstants =
@@ -1045,26 +1103,37 @@
/// Pop the next element in the queue.
WorkItem nextItem() {
assert(isNotEmpty);
- var item = queue.removeFirst();
- if (item.element != null) pendingElements.remove(item.element);
- if (item.value != null) pendingConstants.remove(item.value);
- return item;
+ return queue.removeFirst();
}
/// Add to the queue that [element] should be updated to include all imports
/// in [importSet]. If there is already a work item in the queue for
/// [element], this makes sure that the work item now includes the union of
/// [importSet] and the existing work item's import set.
- void addElement(Entity element, ImportSet importSet, {isMirrorUsage: false}) {
- var item = pendingElements[element];
+ void addClass(ClassEntity element, ImportSet importSet) {
+ var item = pendingClasses[element];
if (item == null) {
- item = new WorkItem(element, importSet);
- pendingElements[element] = item;
+ item = new ClassWorkItem(element, importSet);
+ pendingClasses[element] = item;
queue.add(item);
} else {
- item.newSet = _importSets.union(item.newSet, importSet);
+ item.importsToAdd = _importSets.union(item.importsToAdd, importSet);
}
- if (isMirrorUsage) item.isMirrorUsage = true;
+ }
+
+ /// Add to the queue that [element] should be updated to include all imports
+ /// in [importSet]. If there is already a work item in the queue for
+ /// [element], this makes sure that the work item now includes the union of
+ /// [importSet] and the existing work item's import set.
+ void addMember(MemberEntity element, ImportSet importSet) {
+ var item = pendingMembers[element];
+ if (item == null) {
+ item = new MemberWorkItem(element, importSet);
+ pendingMembers[element] = item;
+ queue.add(item);
+ } else {
+ item.importsToAdd = _importSets.union(item.importsToAdd, importSet);
+ }
}
/// Add to the queue that [constant] should be updated to include all imports
@@ -1074,39 +1143,73 @@
void addConstant(ConstantValue constant, ImportSet importSet) {
var item = pendingConstants[constant];
if (item == null) {
- item = new WorkItem.constant(constant, importSet);
+ item = new ConstantWorkItem(constant, importSet);
pendingConstants[constant] = item;
queue.add(item);
} else {
- item.newSet = _importSets.union(item.newSet, importSet);
+ item.importsToAdd = _importSets.union(item.importsToAdd, importSet);
}
}
}
-/// Summary of the work that needs to be done on an entity or constant.
-class WorkItem {
- /// Entity to be recursively updated.
- final Entity element;
-
- /// Constant to be recursively updated.
- final ConstantValue value;
-
+/// Summary of the work that needs to be done on a class, member, or constant.
+abstract class WorkItem {
/// Additional imports that use [element] or [value] and need to be added by
/// the algorithm.
///
/// This is non-final in case we add more deferred imports to the set before
/// the work item is applied (see [WorkQueue.addElement] and
/// [WorkQueue.addConstant]).
- ImportSet newSet;
+ ImportSet importsToAdd;
- /// Whether [element] is used via mirrors.
- ///
- /// This is non-final in case we later discover that the same [element] is
- /// used via mirrors (but before the work item is applied).
- bool isMirrorUsage = false;
+ WorkItem(this.importsToAdd);
- WorkItem(this.element, this.newSet) : value = null;
- WorkItem.constant(this.value, this.newSet) : element = null;
+ void update(DeferredLoadTask task, WorkQueue queue);
+}
+
+/// Summary of the work that needs to be done on a class.
+class ClassWorkItem extends WorkItem {
+ /// Class to be recursively updated.
+ final ClassEntity cls;
+
+ ClassWorkItem(this.cls, ImportSet newSet) : super(newSet);
+
+ void update(DeferredLoadTask task, WorkQueue queue) {
+ queue.pendingClasses.remove(cls);
+ ImportSet oldSet = task._classToSet[cls];
+ ImportSet newSet = task.importSets.union(oldSet, importsToAdd);
+ task._updateClassRecursive(cls, oldSet, newSet, queue);
+ }
+}
+
+/// Summary of the work that needs to be done on a member.
+class MemberWorkItem extends WorkItem {
+ /// Member to be recursively updated.
+ final MemberEntity member;
+
+ MemberWorkItem(this.member, ImportSet newSet) : super(newSet);
+
+ void update(DeferredLoadTask task, WorkQueue queue) {
+ queue.pendingMembers.remove(member);
+ ImportSet oldSet = task._memberToSet[member];
+ ImportSet newSet = task.importSets.union(oldSet, importsToAdd);
+ task._updateMemberRecursive(member, oldSet, newSet, queue);
+ }
+}
+
+/// Summary of the work that needs to be done on a constant.
+class ConstantWorkItem extends WorkItem {
+ /// Constant to be recursively updated.
+ final ConstantValue constant;
+
+ ConstantWorkItem(this.constant, ImportSet newSet) : super(newSet);
+
+ void update(DeferredLoadTask task, WorkQueue queue) {
+ queue.pendingConstants.remove(constant);
+ ImportSet oldSet = task._constantToSet[constant];
+ ImportSet newSet = task.importSets.union(oldSet, importsToAdd);
+ task._updateConstantRecursive(constant, oldSet, newSet, queue);
+ }
}
/// Results of the deferred loading algorithm.
@@ -1118,57 +1221,63 @@
class OutputUnitData {
final bool isProgramSplit;
final OutputUnit mainOutputUnit;
- final Map<Entity, OutputUnit> _entityToUnit;
+ final Map<ClassEntity, OutputUnit> _classToUnit;
+ final Map<MemberEntity, OutputUnit> _memberToUnit;
+ final Map<Local, OutputUnit> _localFunctionToUnit;
final Map<ConstantValue, OutputUnit> _constantToUnit;
final ImportSetLattice _importSets;
- OutputUnitData(this.isProgramSplit, this.mainOutputUnit, this._entityToUnit,
- this._constantToUnit, this._importSets);
+ OutputUnitData(
+ this.isProgramSplit,
+ this.mainOutputUnit,
+ this._classToUnit,
+ this._memberToUnit,
+ this._localFunctionToUnit,
+ this._constantToUnit,
+ this._importSets);
OutputUnitData.from(
OutputUnitData other,
- Map<Entity, OutputUnit> Function(Map<Entity, OutputUnit>)
- convertEntityMap,
+ Map<ClassEntity, OutputUnit> Function(
+ Map<ClassEntity, OutputUnit>, Map<Local, OutputUnit>)
+ convertClassMap,
+ Map<MemberEntity, OutputUnit> Function(
+ Map<MemberEntity, OutputUnit>, Map<Local, OutputUnit>)
+ convertMemberMap,
Map<ConstantValue, OutputUnit> Function(Map<ConstantValue, OutputUnit>)
convertConstantMap)
: isProgramSplit = other.isProgramSplit,
mainOutputUnit = other.mainOutputUnit,
- _entityToUnit = convertEntityMap(other._entityToUnit),
+ _memberToUnit =
+ convertMemberMap(other._memberToUnit, other._localFunctionToUnit),
+ _classToUnit =
+ convertClassMap(other._classToUnit, other._localFunctionToUnit),
+ _localFunctionToUnit = const <Local, OutputUnit>{},
_constantToUnit = convertConstantMap(other._constantToUnit),
_importSets = other._importSets;
- /// Returns the [OutputUnit] where [element] belongs.
- OutputUnit outputUnitForEntity(Entity entity) {
- // TODO(johnniwinther): Support use of entities by splitting maps by
- // entity kind.
+ /// Returns the [OutputUnit] where [cls] belongs.
+ OutputUnit outputUnitForClass(ClassEntity cls) {
if (!isProgramSplit) return mainOutputUnit;
- OutputUnit unit = _entityToUnit[entity];
+ OutputUnit unit = _classToUnit[cls];
+ return unit ?? mainOutputUnit;
+ }
+
+ /// Returns the [OutputUnit] where [member] belongs.
+ OutputUnit outputUnitForMember(MemberEntity member) {
+ if (!isProgramSplit) return mainOutputUnit;
+ OutputUnit unit = _memberToUnit[member];
if (unit != null) return unit;
- if (entity is MemberEntity && entity.isInstanceMember) {
- return outputUnitForEntity(entity.enclosingClass);
+ if (member.isInstanceMember) {
+ return outputUnitForClass(member.enclosingClass);
}
return mainOutputUnit;
}
- /// Direct access to the output-unit to element relation used for testing.
- OutputUnit outputUnitForEntityForTesting(Entity entity) {
- return _entityToUnit[entity];
- }
-
/// Direct access to the output-unit to constants map used for testing.
Iterable<ConstantValue> get constantsForTesting => _constantToUnit.keys;
- /// Returns the [OutputUnit] where [element] belongs.
- OutputUnit outputUnitForClass(ClassEntity element) {
- return outputUnitForEntity(element);
- }
-
- /// Returns the [OutputUnit] where [element] belongs.
- OutputUnit outputUnitForMember(MemberEntity element) {
- return outputUnitForEntity(element);
- }
-
/// Returns the [OutputUnit] where [constant] belongs.
OutputUnit outputUnitForConstant(ConstantValue constant) {
if (!isProgramSplit) return mainOutputUnit;
@@ -1176,13 +1285,8 @@
}
/// Indicates whether [element] is deferred.
- bool isDeferred(Entity element) {
- return outputUnitForEntity(element) != mainOutputUnit;
- }
-
- /// Indicates whether [element] is deferred.
bool isDeferredClass(ClassEntity element) {
- return outputUnitForEntity(element) != mainOutputUnit;
+ return outputUnitForClass(element) != mainOutputUnit;
}
/// Returns `true` if element [to] is reachable from element [from] without
@@ -1191,9 +1295,9 @@
/// For example, if we have two deferred libraries `A` and `B` that both
/// import a library `C`, then even though elements from `A` and `C` end up in
/// different output units, there is a non-deferred path between `A` and `C`.
- bool hasOnlyNonDeferredImportPaths(Entity from, Entity to) {
- OutputUnit outputUnitFrom = outputUnitForEntity(from);
- OutputUnit outputUnitTo = outputUnitForEntity(to);
+ bool hasOnlyNonDeferredImportPaths(MemberEntity from, MemberEntity to) {
+ OutputUnit outputUnitFrom = outputUnitForMember(from);
+ OutputUnit outputUnitTo = outputUnitForMember(to);
if (outputUnitTo == mainOutputUnit) return true;
if (outputUnitFrom == mainOutputUnit) return false;
return outputUnitTo._imports.containsAll(outputUnitFrom._imports);
@@ -1213,7 +1317,14 @@
/// [existingEntity];
void registerColocatedMembers(
MemberEntity existingEntity, MemberEntity newEntity) {
- assert(_entityToUnit[newEntity] == null);
- _entityToUnit[newEntity] = outputUnitForMember(existingEntity);
+ assert(_memberToUnit[newEntity] == null);
+ _memberToUnit[newEntity] = outputUnitForMember(existingEntity);
}
}
+
+class Dependencies {
+ final Set<ClassEntity> classes = new Set<ClassEntity>();
+ final Set<MemberEntity> members = new Set<MemberEntity>();
+ final Set<Local> localFunctions = new Set<Local>();
+ final Set<ConstantValue> constants = new Set<ConstantValue>();
+}
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index a975519..2e82222 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -109,7 +109,7 @@
TypedefInfo visitTypedef(TypedefEntity typdef) {
var type = environment.getFunctionTypeOfTypedef(typdef);
TypedefInfo info =
- new TypedefInfo(typdef.name, '$type', _unitInfoForEntity(typdef));
+ new TypedefInfo(typdef.name, '$type', _unitInfoForTypedef(typdef));
_entityToInfo[typdef] = info;
LibraryInfo lib = _entityToInfo[typdef.library];
lib.typedefs.add(info);
@@ -147,7 +147,7 @@
type: '${environment.getFieldType(field)}',
inferredType: '$inferredType',
code: code,
- outputUnit: _unitInfoForEntity(field),
+ outputUnit: _unitInfoForMember(field),
isConst: field.isConst);
_entityToInfo[field] = info;
if (codegenWorldBuilder.hasConstantFieldInitializer(field)) {
@@ -179,7 +179,7 @@
ClassInfo classInfo = new ClassInfo(
name: clazz.name,
isAbstract: clazz.isAbstract,
- outputUnit: _unitInfoForEntity(clazz));
+ outputUnit: _unitInfoForClass(clazz));
_entityToInfo[clazz] = classInfo;
int size = compiler.dumpInfoTask.sizeOf(clazz);
@@ -232,7 +232,7 @@
ClosureInfo visitClosureClass(ClassEntity element) {
ClosureInfo closureInfo = new ClosureInfo(
name: element.name,
- outputUnit: _unitInfoForEntity(element),
+ outputUnit: _unitInfoForClass(element),
size: compiler.dumpInfoTask.sizeOf(element));
_entityToInfo[element] = closureInfo;
@@ -313,7 +313,7 @@
inlinedCount: inlinedCount,
code: code,
type: functionType.toString(),
- outputUnit: _unitInfoForEntity(function));
+ outputUnit: _unitInfoForMember(function));
_entityToInfo[function] = info;
int closureSize = _addClosureInfo(info, function);
@@ -366,9 +366,14 @@
});
}
- OutputUnitInfo _unitInfoForEntity(Entity entity) {
+ OutputUnitInfo _unitInfoForMember(MemberEntity entity) {
return _infoFromOutputUnit(
- compiler.backend.outputUnitData.outputUnitForEntity(entity));
+ compiler.backend.outputUnitData.outputUnitForMember(entity));
+ }
+
+ OutputUnitInfo _unitInfoForClass(ClassEntity entity) {
+ return _infoFromOutputUnit(
+ compiler.backend.outputUnitData.outputUnitForClass(entity));
}
OutputUnitInfo _unitInfoForConstant(ConstantValue constant) {
@@ -380,6 +385,11 @@
}
return _infoFromOutputUnit(outputUnit);
}
+
+ OutputUnitInfo _unitInfoForTypedef(TypedefEntity entity) {
+ // TODO(johnniwinther): Do we ever emit typedefs?
+ return null;
+ }
}
class Selection {
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
index ee51d11..3a54cf6 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
@@ -93,7 +93,7 @@
jsAst.Name constructorName = namer.className(classElement);
OutputUnit outputUnit =
- compiler.backend.outputUnitData.outputUnitForEntity(classElement);
+ compiler.backend.outputUnitData.outputUnitForClass(classElement);
emitter.assemblePrecompiledConstructor(
outputUnit, constructorName, constructorAst, fieldNames);
}
@@ -317,7 +317,7 @@
ClassEntity cls = member.enclosingClass;
jsAst.Name className = namer.className(cls);
OutputUnit outputUnit =
- compiler.backend.outputUnitData.outputUnitForEntity(member);
+ compiler.backend.outputUnitData.outputUnitForMember(member);
emitter
.cspPrecompiledFunctionFor(outputUnit)
.add(js('#.prototype.# = #', [className, getterName, function]));
@@ -332,7 +332,7 @@
ClassEntity cls = member.enclosingClass;
jsAst.Name className = namer.className(cls);
OutputUnit outputUnit =
- compiler.backend.outputUnitData.outputUnitForEntity(member);
+ compiler.backend.outputUnitData.outputUnitForMember(member);
emitter
.cspPrecompiledFunctionFor(outputUnit)
.add(js('#.prototype.# = #', [className, setterName, function]));
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index 28e67b6..29a368a 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -102,24 +102,51 @@
return map.toBackendLibrary(entity);
}
- // Convert a front-end map containing K-entities keys to a backend map using
- // J-entities as keys.
- Map<Entity, OutputUnit> convertEntityMap(Map<Entity, OutputUnit> input) {
- var result = <Entity, OutputUnit>{};
- input.forEach((Entity entity, OutputUnit unit) {
- // Closures have both a class and a call-method, we ensure both are
- // included in the corresponding output unit.
+ // Convert front-end maps containing K-class and K-local function keys to a
+ // backend map using J-classes as keys.
+ Map<ClassEntity, OutputUnit> convertClassMap(
+ Map<ClassEntity, OutputUnit> classMap,
+ Map<Local, OutputUnit> localFunctionMap) {
+ var result = <ClassEntity, OutputUnit>{};
+ classMap.forEach((ClassEntity entity, OutputUnit unit) {
+ ClassEntity backendEntity = toBackendEntity(entity);
+ if (backendEntity != null) {
+ // If [entity] isn't used it doesn't have a corresponding backend
+ // entity.
+ result[backendEntity] = unit;
+ }
+ });
+ localFunctionMap.forEach((Local entity, OutputUnit unit) {
+ // Ensure closure classes are included in the output unit corresponding
+ // to the local function.
if (entity is KLocalFunction) {
var closureInfo = _closureDataLookup.getClosureInfo(entity.node);
result[closureInfo.closureClassEntity] = unit;
+ }
+ });
+ return result;
+ }
+
+ // Convert front-end maps containing K-member and K-local function keys to
+ // a backend map using J-members as keys.
+ Map<MemberEntity, OutputUnit> convertMemberMap(
+ Map<MemberEntity, OutputUnit> memberMap,
+ Map<Local, OutputUnit> localFunctionMap) {
+ var result = <MemberEntity, OutputUnit>{};
+ memberMap.forEach((MemberEntity entity, OutputUnit unit) {
+ MemberEntity backendEntity = toBackendEntity(entity);
+ if (backendEntity != null) {
+ // If [entity] isn't used it doesn't have a corresponding backend
+ // entity.
+ result[backendEntity] = unit;
+ }
+ });
+ localFunctionMap.forEach((Local entity, OutputUnit unit) {
+ // Ensure closure call-methods are included in the output unit
+ // corresponding to the local function.
+ if (entity is KLocalFunction) {
+ var closureInfo = _closureDataLookup.getClosureInfo(entity.node);
result[closureInfo.callMethod] = unit;
- } else {
- Entity backendEntity = toBackendEntity(entity);
- if (backendEntity != null) {
- // If [entity] isn't used it doesn't have a corresponding backend
- // entity.
- result[backendEntity] = unit;
- }
}
});
return result;
@@ -131,7 +158,8 @@
return new OutputUnitData.from(
data,
- convertEntityMap,
+ convertClassMap,
+ convertMemberMap,
(m) => convertMap<ConstantValue, OutputUnit>(
m, toBackendConstant, (v) => v));
}
diff --git a/pkg/compiler/lib/src/kernel/deferred_load.dart b/pkg/compiler/lib/src/kernel/deferred_load.dart
index f3f1a9c..b312027 100644
--- a/pkg/compiler/lib/src/kernel/deferred_load.dart
+++ b/pkg/compiler/lib/src/kernel/deferred_load.dart
@@ -20,37 +20,8 @@
KernelDeferredLoadTask(Compiler compiler, this._elementMap) : super(compiler);
- @override
- Iterable<ImportEntity> importsTo(Entity element, LibraryEntity library) {
- ir.NamedNode node;
- String nodeName;
- ir.Library enclosingLibrary;
- if (element is ClassEntity) {
- ClassDefinition definition = _elementMap.getClassDefinition(element);
- if (definition.kind != ClassKind.regular) {
- // You can't import closures.
- return const <ImportEntity>[];
- }
- ir.Class _node = definition.node;
- nodeName = _node.name;
- enclosingLibrary = _node.enclosingLibrary;
- node = _node;
- } else if (element is MemberEntity) {
- ir.Member _node = _elementMap.getMemberDefinition(element).node;
- nodeName = _node.name.name;
- enclosingLibrary = _node.enclosingLibrary;
- node = _node;
- } else if (element is Local ||
- element is LibraryEntity ||
- element is TypeVariableEntity) {
- return const <ImportEntity>[];
- } else if (element is TypedefEntity) {
- throw new UnimplementedError("KernelDeferredLoadTask.importsTo typedef");
- } else {
- throw new UnsupportedError(
- "KernelDeferredLoadTask.importsTo unexpected entity type: "
- "${element.runtimeType}");
- }
+ Iterable<ImportEntity> _findImportsTo(ir.NamedNode node, String nodeName,
+ ir.Library enclosingLibrary, LibraryEntity library) {
List<ImportEntity> imports = [];
ir.Library source = _elementMap.getLibraryNode(library);
for (ir.LibraryDependency dependency in source.dependencies) {
@@ -65,6 +36,25 @@
}
@override
+ Iterable<ImportEntity> classImportsTo(
+ ClassEntity element, LibraryEntity library) {
+ ClassDefinition definition = _elementMap.getClassDefinition(element);
+ if (definition.kind != ClassKind.regular) {
+ // You can't import closures.
+ return const <ImportEntity>[];
+ }
+ ir.Class node = definition.node;
+ return _findImportsTo(node, node.name, node.enclosingLibrary, library);
+ }
+
+ @override
+ Iterable<ImportEntity> memberImportsTo(
+ Entity element, LibraryEntity library) {
+ ir.Member node = _elementMap.getMemberDefinition(element).node;
+ return _findImportsTo(node, node.name.name, node.enclosingLibrary, library);
+ }
+
+ @override
void checkForDeferredErrorCases(LibraryEntity library) {
// Nothing to do. The FE checks for error cases upfront.
}
@@ -77,14 +67,13 @@
}
@override
- void collectConstantsInBody(
- covariant MemberEntity element, Set<ConstantValue> constants) {
+ void collectConstantsInBody(MemberEntity element, Dependencies dependencies) {
ir.Member node = _elementMap.getMemberDefinition(element).node;
// Fetch the internal node in order to skip annotations on the member.
// TODO(sigmund): replace this pattern when the kernel-ast provides a better
// way to skip annotations (issue 31565).
- var visitor = new ConstantCollector(_elementMap, constants);
+ var visitor = new ConstantCollector(_elementMap, dependencies);
if (node is ir.Field) {
node.initializer?.accept(visitor);
return;
@@ -135,9 +124,9 @@
class ConstantCollector extends ir.RecursiveVisitor {
final KernelToElementMapForImpact elementMap;
- final Set<ConstantValue> constants;
+ final Dependencies dependencies;
- ConstantCollector(this.elementMap, this.constants);
+ ConstantCollector(this.elementMap, this.dependencies);
CommonElements get commonElements => elementMap.commonElements;
@@ -145,7 +134,7 @@
ConstantValue constant =
elementMap.getConstantValue(node, requireConstant: required);
if (constant != null) {
- constants.add(constant);
+ dependencies.constants.add(constant);
}
}
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index c8a203c..65e1636 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -2839,7 +2839,7 @@
ConstantValue value = _elementMap.getFieldConstantValue(field);
if (value != null) {
if (!field.isAssignable) {
- var unit = compiler.backend.outputUnitData.outputUnitForEntity(field);
+ var unit = compiler.backend.outputUnitData.outputUnitForMember(field);
// TODO(sigmund): this is not equivalent to what the old FE does: if
// there is no prefix the old FE wouldn't treat this in any special
// way. Also, if the prefix points to a constant in the main output
diff --git a/tests/compiler/dart2js/deferred/custom_element_test.dart b/tests/compiler/dart2js/deferred/custom_element_test.dart
index 01fb615..d2e6236 100644
--- a/tests/compiler/dart2js/deferred/custom_element_test.dart
+++ b/tests/compiler/dart2js/deferred/custom_element_test.dart
@@ -23,15 +23,16 @@
await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES);
Compiler compiler = result.compiler;
var closedWorld = compiler.backendClosedWorldForTesting;
- var outputUnitForEntity = compiler.backend.outputUnitData.outputUnitForEntity;
+ var outputUnitForMember = compiler.backend.outputUnitData.outputUnitForMember;
+ var outputUnitForClass = compiler.backend.outputUnitData.outputUnitForClass;
var mainOutputUnit = compiler.backend.outputUnitData.mainOutputUnit;
var elementEnvironment = closedWorld.elementEnvironment;
dynamic lib = elementEnvironment.lookupLibrary(Uri.parse("memory:lib.dart"));
var customType = elementEnvironment.lookupClass(lib, "CustomType");
var foo = elementEnvironment.lookupLibraryMember(lib, "foo");
- Expect.notEquals(mainOutputUnit, outputUnitForEntity(foo));
+ Expect.notEquals(mainOutputUnit, outputUnitForMember(foo));
// Native elements are not deferred
- Expect.equals(mainOutputUnit, outputUnitForEntity(customType));
+ Expect.equals(mainOutputUnit, outputUnitForClass(customType));
}
// The main library imports a file defining a custom element.
diff --git a/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart b/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart
index 33da0d2..e65d0c2 100644
--- a/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart
+++ b/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart
@@ -25,20 +25,20 @@
return elementEnvironment.lookupLibrary(Uri.parse(name));
}
- var outputUnitForEntity =
- compiler.backend.outputUnitData.outputUnitForEntity;
+ var outputUnitForMember =
+ compiler.backend.outputUnitData.outputUnitForMember;
dynamic lib1 = lookupLibrary("memory:lib1.dart");
var foo1 = elementEnvironment.lookupLibraryMember(lib1, "foo");
- var ou_lib1 = outputUnitForEntity(foo1);
+ var ou_lib1 = outputUnitForMember(foo1);
dynamic lib2 = lookupLibrary("memory:lib2.dart");
var foo2 = elementEnvironment.lookupLibraryMember(lib2, "foo");
- var ou_lib2 = outputUnitForEntity(foo2);
+ var ou_lib2 = outputUnitForMember(foo2);
dynamic mainApp = elementEnvironment.mainLibrary;
var fooMain = elementEnvironment.lookupLibraryMember(mainApp, "foo");
- var ou_lib1_lib2 = outputUnitForEntity(fooMain);
+ var ou_lib1_lib2 = outputUnitForMember(fooMain);
String mainOutput = collector.getOutput("", OutputType.js);
String lib1Output =
diff --git a/tests/compiler/dart2js/deferred/dont_inline_deferred_globals_test.dart b/tests/compiler/dart2js/deferred/dont_inline_deferred_globals_test.dart
index 7b6db2d..25c48e3 100644
--- a/tests/compiler/dart2js/deferred/dont_inline_deferred_globals_test.dart
+++ b/tests/compiler/dart2js/deferred/dont_inline_deferred_globals_test.dart
@@ -25,12 +25,12 @@
return elementEnvironment.lookupLibrary(Uri.parse(name));
}
- var outputUnitForEntity =
- compiler.backend.outputUnitData.outputUnitForEntity;
+ var outputUnitForMember =
+ compiler.backend.outputUnitData.outputUnitForMember;
dynamic lib1 = lookupLibrary("memory:lib1.dart");
var foo1 = elementEnvironment.lookupLibraryMember(lib1, "finalVar");
- var ou_lib1 = outputUnitForEntity(foo1);
+ var ou_lib1 = outputUnitForMember(foo1);
String mainOutput = collector.getOutput("", OutputType.js);
String lib1Output =
diff --git a/tests/compiler/dart2js/deferred/follow_implicit_super_regression_test.dart b/tests/compiler/dart2js/deferred/follow_implicit_super_regression_test.dart
index f5e7858..f3aecaa 100644
--- a/tests/compiler/dart2js/deferred/follow_implicit_super_regression_test.dart
+++ b/tests/compiler/dart2js/deferred/follow_implicit_super_regression_test.dart
@@ -20,17 +20,17 @@
return elementEnvironment.lookupLibrary(Uri.parse(name));
}
- var outputUnitForEntity =
- compiler.backend.outputUnitData.outputUnitForEntity;
+ var outputUnitForMember =
+ compiler.backend.outputUnitData.outputUnitForMember;
dynamic lib = lookupLibrary("memory:lib.dart");
var a = elementEnvironment.lookupLibraryMember(lib, "a");
var b = elementEnvironment.lookupLibraryMember(lib, "b");
var c = elementEnvironment.lookupLibraryMember(lib, "c");
var d = elementEnvironment.lookupLibraryMember(lib, "d");
- Expect.equals(outputUnitForEntity(a), outputUnitForEntity(b));
- Expect.equals(outputUnitForEntity(a), outputUnitForEntity(c));
- Expect.equals(outputUnitForEntity(a), outputUnitForEntity(d));
+ Expect.equals(outputUnitForMember(a), outputUnitForMember(b));
+ Expect.equals(outputUnitForMember(a), outputUnitForMember(c));
+ Expect.equals(outputUnitForMember(a), outputUnitForMember(d));
}
asyncTest(() async {
diff --git a/tests/compiler/dart2js/deferred/inline_restrictions_test.dart b/tests/compiler/dart2js/deferred/inline_restrictions_test.dart
index a296c65e..6c53fcf 100644
--- a/tests/compiler/dart2js/deferred/inline_restrictions_test.dart
+++ b/tests/compiler/dart2js/deferred/inline_restrictions_test.dart
@@ -18,16 +18,16 @@
memorySourceFiles: MEMORY_SOURCE_FILES, outputProvider: collector);
Compiler compiler = result.compiler;
var env = compiler.backendClosedWorldForTesting.elementEnvironment;
- var outputUnitForEntity =
- compiler.backend.outputUnitData.outputUnitForEntity;
+ var outputUnitForMember =
+ compiler.backend.outputUnitData.outputUnitForMember;
lookupLibrary(name) => env.lookupLibrary(Uri.parse(name));
dynamic lib1 = lookupLibrary("memory:lib1.dart");
var inlineMeAway = env.lookupLibraryMember(lib1, "inlineMeAway");
- var ou_lib1 = outputUnitForEntity(inlineMeAway);
+ var ou_lib1 = outputUnitForMember(inlineMeAway);
dynamic lib3 = lookupLibrary("memory:lib3.dart");
var sameContextInline = env.lookupLibraryMember(lib3, "sameContextInline");
- var ou_lib3 = outputUnitForEntity(sameContextInline);
+ var ou_lib3 = outputUnitForMember(sameContextInline);
// Test that we actually got different output units.
Expect.notEquals(ou_lib1.name, ou_lib3.name);
diff --git a/tests/compiler/dart2js/deferred/load_graph_segmentation2_test.dart b/tests/compiler/dart2js/deferred/load_graph_segmentation2_test.dart
index c73eb2e..985ad2a 100644
--- a/tests/compiler/dart2js/deferred/load_graph_segmentation2_test.dart
+++ b/tests/compiler/dart2js/deferred/load_graph_segmentation2_test.dart
@@ -16,15 +16,15 @@
CompilationResult result =
await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES);
Compiler compiler = result.compiler;
- var outputUnitForEntity =
- compiler.backend.outputUnitData.outputUnitForEntity;
+ var outputUnitForMember =
+ compiler.backend.outputUnitData.outputUnitForMember;
var env = compiler.backendClosedWorldForTesting.elementEnvironment;
var mainOutputUnit = compiler.backend.outputUnitData.mainOutputUnit;
dynamic lib = env.lookupLibrary(Uri.parse("memory:lib.dart"));
var f1 = env.lookupLibraryMember(lib, "f1");
var f2 = env.lookupLibraryMember(lib, "f2");
- Expect.notEquals(mainOutputUnit, outputUnitForEntity(f1));
- Expect.equals(mainOutputUnit, outputUnitForEntity(f2));
+ Expect.notEquals(mainOutputUnit, outputUnitForMember(f1));
+ Expect.equals(mainOutputUnit, outputUnitForMember(f2));
});
}
diff --git a/tests/compiler/dart2js/deferred/load_graph_segmentation_test.dart b/tests/compiler/dart2js/deferred/load_graph_segmentation_test.dart
index 8135ce0..f20cef3 100644
--- a/tests/compiler/dart2js/deferred/load_graph_segmentation_test.dart
+++ b/tests/compiler/dart2js/deferred/load_graph_segmentation_test.dart
@@ -23,8 +23,9 @@
var main = env.mainFunction;
Expect.isNotNull(main, "Could not find 'main'");
- var outputUnitForEntity =
- compiler.backend.outputUnitData.outputUnitForEntity;
+ var outputUnitForMember =
+ compiler.backend.outputUnitData.outputUnitForMember;
+ var outputUnitForClass = compiler.backend.outputUnitData.outputUnitForClass;
var mainOutputUnit = compiler.backend.outputUnitData.mainOutputUnit;
var backend = compiler.backend;
@@ -40,21 +41,21 @@
var bar1 = env.lookupLibraryMember(lib4, "bar1");
var bar2 = env.lookupLibraryMember(lib4, "bar2");
- OutputUnit ou_lib1 = outputUnitForEntity(foo1);
- OutputUnit ou_lib2 = outputUnitForEntity(foo2);
- OutputUnit ou_lib1_lib2 = outputUnitForEntity(foo3);
- OutputUnit ou_lib4_1 = outputUnitForEntity(bar1);
- OutputUnit ou_lib4_2 = outputUnitForEntity(bar2);
+ OutputUnit ou_lib1 = outputUnitForMember(foo1);
+ OutputUnit ou_lib2 = outputUnitForMember(foo2);
+ OutputUnit ou_lib1_lib2 = outputUnitForMember(foo3);
+ OutputUnit ou_lib4_1 = outputUnitForMember(bar1);
+ OutputUnit ou_lib4_2 = outputUnitForMember(bar2);
- Expect.equals(mainOutputUnit, outputUnitForEntity(main));
- Expect.notEquals(mainOutputUnit, outputUnitForEntity(foo1));
+ Expect.equals(mainOutputUnit, outputUnitForMember(main));
+ Expect.notEquals(mainOutputUnit, outputUnitForMember(foo1));
Expect.notEquals(ou_lib1, ou_lib1_lib2);
Expect.notEquals(ou_lib2, ou_lib1_lib2);
Expect.notEquals(ou_lib1, ou_lib2);
Expect.notEquals(ou_lib4_1, ou_lib4_2);
Expect.notEquals(ou_lib1, ou_lib4_2);
// InputElement is native, so it should be in the mainOutputUnit.
- Expect.equals(mainOutputUnit, outputUnitForEntity(inputElement));
+ Expect.equals(mainOutputUnit, outputUnitForClass(inputElement));
var hunksToLoad = compiler.deferredLoadTask.hunksToLoad;
diff --git a/tests/compiler/dart2js/deferred/not_in_main_test.dart b/tests/compiler/dart2js/deferred/not_in_main_test.dart
index 4a13b29..a259716 100644
--- a/tests/compiler/dart2js/deferred/not_in_main_test.dart
+++ b/tests/compiler/dart2js/deferred/not_in_main_test.dart
@@ -20,8 +20,8 @@
asyncTest(() async {
CompilationResult result = await runCompiler(memorySourceFiles: TEST1);
Compiler compiler = result.compiler;
- var outputUnitForEntity =
- compiler.backend.outputUnitData.outputUnitForEntity;
+ var outputUnitForMember =
+ compiler.backend.outputUnitData.outputUnitForMember;
var mainOutputUnit = compiler.backend.outputUnitData.mainOutputUnit;
var env = compiler.backendClosedWorldForTesting.elementEnvironment;
lookupLibrary(name) => env.lookupLibrary(Uri.parse(name));
@@ -30,7 +30,7 @@
env.lookupLibraryMember(lib1, "foo1");
var foo2 = env.lookupLibraryMember(lib2, "foo2");
- Expect.notEquals(mainOutputUnit, outputUnitForEntity(foo2));
+ Expect.notEquals(mainOutputUnit, outputUnitForMember(foo2));
});
}
@@ -38,16 +38,15 @@
asyncTest(() async {
CompilationResult result = await runCompiler(memorySourceFiles: TEST2);
Compiler compiler = result.compiler;
- var outputUnitForEntity =
- compiler.backend.outputUnitData.outputUnitForEntity;
+ var outputUnitForClass = compiler.backend.outputUnitData.outputUnitForClass;
var mainOutputUnit = compiler.backend.outputUnitData.mainOutputUnit;
var env = compiler.backendClosedWorldForTesting.elementEnvironment;
lookupLibrary(name) => env.lookupLibrary(Uri.parse(name));
dynamic shared = lookupLibrary("memory:shared.dart");
- var a = env.lookupLibraryMember(shared, "A");
+ var a = env.lookupClass(shared, "A");
- Expect.equals(mainOutputUnit, outputUnitForEntity(a));
+ Expect.equals(mainOutputUnit, outputUnitForClass(a));
});
}
diff --git a/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
index cef5d1b..ca8c88f 100644
--- a/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
+++ b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
@@ -117,7 +117,7 @@
: super(reporter, actualMap);
String getMemberValue(MemberEntity member) {
- return outputUnitString(_data.outputUnitForEntity(member));
+ return outputUnitString(_data.outputUnitForMember(member));
}
@override
@@ -162,7 +162,7 @@
Compiler compiler, ClassEntity cls, Map<Id, ActualData> actualMap,
{bool verbose: false}) {
OutputUnitData data = compiler.backend.outputUnitData;
- String value = outputUnitString(data.outputUnitForEntity(cls));
+ String value = outputUnitString(data.outputUnitForClass(cls));
KernelBackendStrategy backendStrategy = compiler.backendStrategy;
KernelToElementMapForBuilding elementMap = backendStrategy.elementMap;