[dart2js] Cosmetic changes for experimental inferrer.
- Rename DynamicCallSiteTypeInformation.concreteTargets to 'targets' to more accurately reflect that they are not all concrete.
- Add convenience function 'forEachConcreteTarget' to DynamicCallSiteTypeInformation to handle expansion of targets to actual concrete targets.
- Change forEach methods to work with bools rather than IterationStep. No code was returning SKIP_SUBCLASS anymore.
Change-Id: I2d4010c62ea42b2a22fff76068ab8c80182ff861
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/291401
Reviewed-by: Mayank Patke <fishythefish@google.com>
diff --git a/pkg/compiler/lib/src/inferrer_experimental/engine.dart b/pkg/compiler/lib/src/inferrer_experimental/engine.dart
index 14fdf5a..a23bd6f 100644
--- a/pkg/compiler/lib/src/inferrer_experimental/engine.dart
+++ b/pkg/compiler/lib/src/inferrer_experimental/engine.dart
@@ -25,7 +25,6 @@
import '../options.dart';
import '../serialization/serialization.dart';
import '../universe/call_structure.dart';
-import '../universe/class_set.dart';
import '../universe/member_hierarchy.dart';
import '../universe/selector.dart';
import '../universe/side_effects.dart';
@@ -142,10 +141,7 @@
final targets = memberHierarchyBuilder.rootsForCall(mask, selector);
for (final target in targets) {
memberHierarchyBuilder.forEachTargetMember(
- target,
- (member) => (member.isAbstract || f(member))
- ? IterationStep.CONTINUE
- : IterationStep.STOP);
+ target, (member) => member.isAbstract || f(member));
}
}
@@ -423,16 +419,14 @@
// of this closure call are not a root to trace but an intermediate
// for some other function.
elements = [];
- for (final target in info.concreteTargets) {
- IterationStep processTarget(MemberEntity entity) {
- if (entity.isFunction && !entity.isAbstract) {
- elements.add(entity as FunctionEntity);
- }
- return IterationStep.CONTINUE;
+ bool processTarget(MemberEntity entity) {
+ if (entity.isFunction && !entity.isAbstract) {
+ elements.add(entity as FunctionEntity);
}
-
- memberHierarchyBuilder.forEachTargetMember(target, processTarget);
+ return true;
}
+
+ info.forEachConcreteTarget(memberHierarchyBuilder, processTarget);
} else {
elements = List<FunctionEntity>.from(
info.callees.where((e) => e.isFunction));
@@ -1036,7 +1030,7 @@
// There is nothing to do so no need to iterate over target members.
if (!needsClosurization && !shouldMarkCalled) return;
- IterationStep handleTarget(MemberEntity member) {
+ bool handleTarget(MemberEntity member) {
if (!member.isAbstract) {
MemberTypeInformation info = types.getInferredTypeOfMember(member);
if (shouldMarkCalled) info.markCalled();
@@ -1046,7 +1040,7 @@
remove: false, addToQueue: false);
}
}
- return IterationStep.CONTINUE;
+ return true;
}
memberHierarchyBuilder.forEachTargetMember(target, handleTarget);
@@ -1060,7 +1054,7 @@
void _processCalledTargets({required bool shouldMarkCalled}) {
for (final call in types.allocatedCalls) {
if (call is DynamicCallSiteTypeInformation) {
- for (final target in call.concreteTargets) {
+ for (final target in call.targets) {
_processDynamicTarget(target, call,
shouldMarkCalled: shouldMarkCalled);
}
@@ -1352,12 +1346,10 @@
if (callSite is StaticCallSiteTypeInformation) {
(callers[callSite.calledElement] ??= {}).add(callSite.caller);
} else if (callSite is DynamicCallSiteTypeInformation) {
- for (final target in callSite.concreteTargets) {
- memberHierarchyBuilder.forEachTargetMember(target, (member) {
- (callers[target.member] ??= {}).add(callSite.caller);
- return IterationStep.CONTINUE;
- });
- }
+ callSite.forEachConcreteTarget(memberHierarchyBuilder, (member) {
+ (callers[member] ??= {}).add(callSite.caller);
+ return true;
+ });
}
}
}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/node_tracer.dart b/pkg/compiler/lib/src/inferrer_experimental/node_tracer.dart
index 0cd68433..1dec22f 100644
--- a/pkg/compiler/lib/src/inferrer_experimental/node_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer_experimental/node_tracer.dart
@@ -488,18 +488,15 @@
final user = currentUser;
if (user is MemberTypeInformation) {
- for (final target in info.concreteTargets) {
- IterationStep checkMember(MemberEntity member) {
- if (member == user.member) {
- addNewEscapeInformation(info);
- return IterationStep.STOP;
- }
- return IterationStep.CONTINUE;
+ bool checkMember(MemberEntity member) {
+ if (member == user.member) {
+ addNewEscapeInformation(info);
+ return false;
}
-
- inferrer.memberHierarchyBuilder
- .forEachTargetMember(target, checkMember);
+ return true;
}
+
+ info.forEachConcreteTarget(inferrer.memberHierarchyBuilder, checkMember);
}
}
diff --git a/pkg/compiler/lib/src/inferrer_experimental/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer_experimental/type_graph_nodes.dart
index 2146c77..90a47dc 100644
--- a/pkg/compiler/lib/src/inferrer_experimental/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer_experimental/type_graph_nodes.dart
@@ -1104,9 +1104,9 @@
bool get isConditional => _hasFlag(_Flag.isConditional);
/// Cached concrete targets of this call.
- Iterable<DynamicCallTarget>? _concreteTargets;
+ Iterable<DynamicCallTarget>? _targets;
- /// Recomputed when _concreteTargets changes.
+ /// Recomputed when [_targets] changes.
/// [_hasTargetsIncludeComplexNoSuchMethod] indicates whether this value
/// is stale and needs to be recomputed.
bool get _targetsIncludeComplexNoSuchMethod =>
@@ -1148,14 +1148,14 @@
final typeMask = computeTypedSelector(inferrer);
_hasClosureCallTargets =
inferrer.closedWorld.includesClosureCall(selector!, typeMask);
- final concreteTargets = _concreteTargets =
+ final targets = _targets =
inferrer.memberHierarchyBuilder.rootsForCall(typeMask, selector!);
invalidateTargetsIncludeComplexNoSuchMethod();
receiver.addUser(this);
if (arguments != null) {
arguments!.forEach((info) => info.addUser(this));
}
- for (final target in concreteTargets) {
+ for (final target in targets) {
_handleCalledTarget(target, inferrer, addToQueue: false, remove: false);
}
}
@@ -1169,10 +1169,17 @@
/// All concrete targets of this invocation. If [hasClosureCallTargets] is
/// `true` the invocation can additional target an unknown set of 'call'
/// methods on closures.
- Iterable<DynamicCallTarget> get concreteTargets => _concreteTargets!;
+ Iterable<DynamicCallTarget> get targets => _targets!;
+
+ void forEachConcreteTarget(
+ MemberHierarchyBuilder builder, bool Function(MemberEntity member) f) {
+ for (final target in targets) {
+ builder.forEachTargetMember(target, f);
+ }
+ }
@override
- Iterable<MemberEntity> get callees => concreteTargets.map((e) => e.member);
+ Iterable<MemberEntity> get callees => targets.map((e) => e.member);
AbstractValue? computeTypedSelector(InferrerEngine inferrer) {
AbstractValue receiverType = receiver.type;
@@ -1315,7 +1322,7 @@
AbstractValue computeType(InferrerEngine inferrer) {
JClosedWorld closedWorld = inferrer.closedWorld;
AbstractValueDomain abstractValueDomain = closedWorld.abstractValueDomain;
- final oldTargets = _concreteTargets!;
+ final oldTargets = _targets!;
final typeMask = computeTypedSelector(inferrer);
final localSelector = selector!;
inferrer.updateSelectorInMember(
@@ -1323,14 +1330,14 @@
final includesClosureCall = _hasClosureCallTargets =
closedWorld.includesClosureCall(localSelector, typeMask);
- final concreteTargets = _concreteTargets =
+ final targets = _targets =
inferrer.memberHierarchyBuilder.rootsForCall(typeMask, localSelector);
// Update the call graph if the targets could have changed.
- if (!identical(concreteTargets, oldTargets)) {
+ if (!identical(targets, oldTargets)) {
invalidateTargetsIncludeComplexNoSuchMethod();
// Add calls to new targets to the graph.
- concreteTargets
+ targets
.where((target) => !oldTargets.contains(target))
.forEach((DynamicCallTarget target) {
_handleCalledTarget(target, inferrer, addToQueue: true, remove: false);
@@ -1338,7 +1345,7 @@
// Walk over the old targets, and remove calls that cannot happen anymore.
oldTargets
- .where((target) => !concreteTargets.contains(target))
+ .where((target) => !targets.contains(target))
.forEach((DynamicCallTarget target) {
_handleCalledTarget(target, inferrer, addToQueue: true, remove: true);
});
@@ -1350,8 +1357,8 @@
if (includesClosureCall) {
result = abstractValueDomain.dynamicType;
} else {
- result = inferrer.types
- .joinTypeMasks(concreteTargets.map((DynamicCallTarget target) {
+ result =
+ inferrer.types.joinTypeMasks(targets.map((DynamicCallTarget target) {
final element = target.member;
if (typeMask != null &&
inferrer.returnsListElementType(localSelector, typeMask)) {
@@ -1416,14 +1423,14 @@
if (!abandonInferencing) {
inferrer.updateSelectorInMember(
caller, _callType, callNode as ir.TreeNode, selector, mask);
- final oldTargets = concreteTargets;
+ final oldTargets = targets;
final localSelector = selector!;
_hasClosureCallTargets =
inferrer.closedWorld.includesClosureCall(localSelector, mask);
- final newConcreteTargets = _concreteTargets =
+ final newTargets = _targets =
inferrer.memberHierarchyBuilder.rootsForCall(mask, localSelector);
invalidateTargetsIncludeComplexNoSuchMethod();
- for (final target in newConcreteTargets) {
+ for (final target in newTargets) {
if (!oldTargets.contains(target)) {
_handleCalledTarget(target, inferrer,
addToQueue: true, remove: false);
diff --git a/pkg/compiler/lib/src/universe/member_hierarchy.dart b/pkg/compiler/lib/src/universe/member_hierarchy.dart
index 3d08cd3..c4e8d4f 100644
--- a/pkg/compiler/lib/src/universe/member_hierarchy.dart
+++ b/pkg/compiler/lib/src/universe/member_hierarchy.dart
@@ -116,47 +116,34 @@
/// Applies [f] to each override of [entity].
///
- /// If [f] returns [IterationStep.CONTINUE] for a given input then that
- /// member's overrides are also visited. If [f] returns for a member
- /// [IterationStep.SKIP_SUBCLASSES] then the overrides of that member are
- /// skipped. If [f] returns [IterationStep.STOP] then iteration is immediately
+ /// If [f] returns `false` for a given input then iteration is immediately
/// stopped and [f] is not called on any more members.
void forEachOverride(
- MemberEntity entity, IterationStep Function(MemberEntity override) f) {
+ MemberEntity entity, bool Function(MemberEntity override) f) {
_forEachOverrideSkipVisited(entity, f, {entity});
}
/// Applies [f] to each target represented by [target] including overrides
/// if the call is virtual.
///
- /// If [f] returns [IterationStep.CONTINUE] for a given input then that
- /// member's overrides are also visited. If [f] returns for a member
- /// [IterationStep.SKIP_SUBCLASSES] then the overrides of that member are
- /// skipped. If [f] returns [IterationStep.STOP] then iteration is immediately
+ /// If [f] returns `false` for a given input then iteration is immediately
/// stopped and [f] is not called on any more members.
- void forEachTargetMember(DynamicCallTarget target,
- IterationStep Function(MemberEntity override) f) {
- final initialResult = f(target.member);
- if (initialResult == IterationStep.STOP ||
- initialResult == IterationStep.SKIP_SUBCLASSES) {
- return;
- }
+ void forEachTargetMember(
+ DynamicCallTarget target, bool Function(MemberEntity override) f) {
+ if (!f(target.member)) return;
+
if (target.isVirtual) {
forEachOverride(target.member, f);
}
}
- void _forEachOverrideSkipVisited(
- MemberEntity entity,
- IterationStep Function(MemberEntity override) f,
- Set<MemberEntity> visited) {
+ void _forEachOverrideSkipVisited(MemberEntity entity,
+ bool Function(MemberEntity override) f, Set<MemberEntity> visited) {
final overrides = _overrides[entity];
if (overrides == null) return;
for (final override in overrides) {
if (!visited.add(override)) continue;
- final result = f(override);
- if (result == IterationStep.SKIP_SUBCLASSES) continue;
- if (result == IterationStep.STOP) return;
+ if (!f(override)) return;
_forEachOverrideSkipVisited(override, f, visited);
}
}
@@ -170,9 +157,9 @@
if (classHierarchy.isSubclassOf(override.enclosingClass!, cls) ||
closedWorld.hasAnySubclassThatMixes(cls, override.enclosingClass!)) {
needsVirtual = true;
- return IterationStep.STOP;
+ return false;
}
- return IterationStep.CONTINUE;
+ return true;
});
return needsVirtual;
}