Skip to content

Commit 4f1b0fd

Browse files
fishythefishcommit-bot@chromium.org
authored andcommitted
[dart2js] (New RTI) Check all subtypes for trivial substitutions only when necessary.
Change-Id: Ic434db1efa58d361b92acfed0cf33a119e394837 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/113520 Reviewed-by: Stephen Adams <[email protected]> Commit-Queue: Mayank Patke <[email protected]>
1 parent 12c1b43 commit 4f1b0fd

File tree

7 files changed

+40
-11
lines changed

7 files changed

+40
-11
lines changed

pkg/compiler/lib/src/js_backend/runtime_types_new.dart

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -299,14 +299,12 @@ class _RecipeGenerator implements DartTypeVisitor<void, void> {
299299
// TODO(sra): We might be in a context where the class type variable has an
300300
// index, even though in the general case it is not at a specific index.
301301

302-
if (_closedWorld.isUsedAsMixin(cls)) return null;
303-
304-
// TODO(fishythefish): We should only check strict subclasses for
305-
// non-trivial substitutions in the general case. We should check all strict
306-
// subtypes only when [cls] is a mixin (above) or when [cls] is a type
307-
// argument to `extractTypeArguments`.
308302
ClassHierarchy classHierarchy = _closedWorld.classHierarchy;
309-
if (classHierarchy.anyStrictSubtypeOf(cls, (ClassEntity subclass) {
303+
var test = mustCheckAllSubtypes(_closedWorld, cls)
304+
? classHierarchy.anyStrictSubtypeOf
305+
: classHierarchy.anyStrictSubclassOf;
306+
307+
if (test(cls, (ClassEntity subclass) {
310308
return !_rtiSubstitutions.isTrivialSubstitution(subclass, cls);
311309
})) {
312310
return null;
@@ -470,6 +468,10 @@ class _RecipeGenerator implements DartTypeVisitor<void, void> {
470468
}
471469
}
472470

471+
bool mustCheckAllSubtypes(JClosedWorld world, ClassEntity cls) =>
472+
world.isUsedAsMixin(cls) ||
473+
world.extractTypeArgumentsInterfacesNewRti.contains(cls);
474+
473475
class _RulesetEntry {
474476
final InterfaceType _targetType;
475477
List<InterfaceType> _supertypes;

pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import '../../js_backend/runtime_types.dart'
3030
show RuntimeTypesChecks, RuntimeTypesEncoder;
3131
import '../../js_backend/runtime_types_new.dart'
3232
show RecipeEncoder, RecipeEncoding;
33+
import '../../js_backend/runtime_types_new.dart' as newRti;
3334
import '../../js_backend/runtime_types_resolution.dart' show RuntimeTypesNeed;
3435
import '../../js_model/elements.dart' show JGeneratorBody, JSignatureMethod;
3536
import '../../js_model/type_recipe.dart'
@@ -852,8 +853,12 @@ class ProgramBuilder {
852853
void associateNamedTypeVariablesNewRti() {
853854
for (TypeVariableType typeVariable in _codegenWorld.namedTypeVariablesNewRti
854855
.union(_lateNamedTypeVariablesNewRti)) {
855-
for (ClassEntity entity
856-
in _classHierarchy.subtypesOf(typeVariable.element.typeDeclaration)) {
856+
ClassEntity declaration = typeVariable.element.typeDeclaration;
857+
Iterable<ClassEntity> subtypes =
858+
newRti.mustCheckAllSubtypes(_closedWorld, declaration)
859+
? _classHierarchy.subtypesOf(declaration)
860+
: _classHierarchy.subclassesOf(declaration);
861+
for (ClassEntity entity in subtypes) {
857862
Class cls = _classes[entity];
858863
if (cls == null) continue;
859864
cls.namedTypeVariablesNewRti.add(typeVariable);

pkg/compiler/lib/src/js_model/js_world.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ class JsClosedWorld implements JClosedWorld {
7575
@override
7676
final Set<MemberEntity> processedMembers;
7777

78+
@override
79+
final Set<ClassEntity> extractTypeArgumentsInterfacesNewRti;
80+
7881
@override
7982
final ClassHierarchy classHierarchy;
8083

@@ -109,6 +112,7 @@ class JsClosedWorld implements JClosedWorld {
109112
this.liveInstanceMembers,
110113
this.assignedInstanceMembers,
111114
this.processedMembers,
115+
this.extractTypeArgumentsInterfacesNewRti,
112116
this.mixinUses,
113117
this.typesImplementedBySubclasses,
114118
this.classHierarchy,
@@ -154,6 +158,8 @@ class JsClosedWorld implements JClosedWorld {
154158

155159
Set<ClassEntity> implementedClasses = source.readClasses().toSet();
156160
Set<ClassEntity> liveNativeClasses = source.readClasses().toSet();
161+
Set<ClassEntity> extractTypeArgumentsInterfacesNewRti =
162+
source.readClasses().toSet();
157163
Set<MemberEntity> liveInstanceMembers = source.readMembers().toSet();
158164
Set<MemberEntity> assignedInstanceMembers = source.readMembers().toSet();
159165
Set<MemberEntity> processedMembers = source.readMembers().toSet();
@@ -191,6 +197,7 @@ class JsClosedWorld implements JClosedWorld {
191197
liveInstanceMembers,
192198
assignedInstanceMembers,
193199
processedMembers,
200+
extractTypeArgumentsInterfacesNewRti,
194201
mixinUses,
195202
typesImplementedBySubclasses,
196203
classHierarchy,
@@ -217,6 +224,7 @@ class JsClosedWorld implements JClosedWorld {
217224
noSuchMethodData.writeToDataSink(sink);
218225
sink.writeClasses(implementedClasses);
219226
sink.writeClasses(liveNativeClasses);
227+
sink.writeClasses(extractTypeArgumentsInterfacesNewRti);
220228
sink.writeMembers(liveInstanceMembers);
221229
sink.writeMembers(assignedInstanceMembers);
222230
sink.writeMembers(processedMembers);
@@ -558,6 +566,11 @@ class JsClosedWorld implements JClosedWorld {
558566
MemberAccess getMemberAccess(MemberEntity member) {
559567
return memberAccess[member];
560568
}
569+
570+
@override
571+
void registerExtractTypeArguments(ClassEntity interface) {
572+
extractTypeArgumentsInterfacesNewRti.add(interface);
573+
}
561574
}
562575

563576
class KernelSorter implements Sorter {

pkg/compiler/lib/src/js_model/js_world_builder.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ class JsClosedWorldBuilder {
130130
Set<MemberEntity> processedMembers =
131131
map.toBackendMemberSet(closedWorld.liveMemberUsage.keys);
132132

133+
Set<ClassEntity> extractTypeArgumentsInterfacesNewRti = {};
134+
133135
RuntimeTypesNeed rtiNeed;
134136

135137
List<FunctionEntity> callMethods = <FunctionEntity>[];
@@ -223,6 +225,7 @@ class JsClosedWorldBuilder {
223225
liveInstanceMembers /*..addAll(callMethods)*/,
224226
assignedInstanceMembers,
225227
processedMembers,
228+
extractTypeArgumentsInterfacesNewRti,
226229
mixinUses,
227230
typesImplementedBySubclasses,
228231
new ClassHierarchyImpl(

pkg/compiler/lib/src/ssa/builder_kernel.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4040,6 +4040,7 @@ class KernelSsaGraphBuilder extends ir.Visitor {
40404040
List<DartType> typeArguments = <DartType>[];
40414041

40424042
if (options.experimentNewRti) {
4043+
closedWorld.registerExtractTypeArguments(cls);
40434044
HInstruction instanceType =
40444045
HInstanceEnvironment(object, _abstractValueDomain.dynamicType);
40454046
add(instanceType);

pkg/compiler/lib/src/ssa/codegen.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3478,8 +3478,6 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
34783478
js.Expression recipe = encoding.recipe;
34793479

34803480
for (TypeVariableType typeVariable in encoding.typeVariables) {
3481-
// TODO(fishythefish): Constraint the type variable to only be emitted on
3482-
// (subtypes of) the environment type.
34833481
_registry.registerTypeUse(TypeUse.namedTypeVariableNewRti(typeVariable));
34843482
}
34853483

pkg/compiler/lib/src/world.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ abstract class JClosedWorld implements World {
7070

7171
Iterable<MemberEntity> get processedMembers;
7272

73+
/// Returns the set of interfaces passed as type arguments to the internal
74+
/// `extractTypeArguments` function.
75+
Set<ClassEntity> get extractTypeArgumentsInterfacesNewRti;
76+
7377
ClassHierarchy get classHierarchy;
7478

7579
AnnotationsData get annotationsData;
@@ -202,6 +206,9 @@ abstract class JClosedWorld implements World {
202206
/// Returns the set of read, write, and invocation accesses found on [member]
203207
/// during the closed world computation.
204208
MemberAccess getMemberAccess(MemberEntity member);
209+
210+
/// Registers [interface] as a type argument to `extractTypeArguments`.
211+
void registerExtractTypeArguments(ClassEntity interface);
205212
}
206213

207214
abstract class OpenWorld implements World {

0 commit comments

Comments
 (0)