Skip to content

Commit 73e35eb

Browse files
committed
Update RTI optimization to handle type literal uses
... for generic methods and local function. Also update capture conversion to recognize the new kinds of type variables. Change-Id: I9b8771b0ebe6c9e926712fa31b0bdea966cc6a25 Reviewed-on: https://dart-review.googlesource.com/34600 Reviewed-by: Sigmund Cherem <[email protected]> Reviewed-by: Emily Fortuna <[email protected]>
1 parent b2f8b54 commit 73e35eb

14 files changed

+573
-187
lines changed

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

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -179,16 +179,18 @@ class JavaScriptImpactTransformer extends ImpactTransformer {
179179
_customElementsResolutionAnalysis.registerTypeLiteral(type);
180180
if (type.isTypeVariable) {
181181
TypeVariableType typeVariable = type;
182-
if (typeVariable.element.typeDeclaration is ClassEntity) {
183-
// GENERIC_METHODS: The `is!` test above filters away method type
184-
// variables, because they have the value `dynamic` with the
185-
// incomplete support for generic methods offered with
186-
// '--generic-method-syntax'. This must be revised in order to
187-
// support generic methods fully.
188-
ClassEntity cls = typeVariable.element.typeDeclaration;
189-
_rtiNeedBuilder.registerClassUsingTypeVariableExpression(cls);
190-
registerImpact(_impacts.typeVariableExpression);
182+
Entity typeDeclaration = typeVariable.element.typeDeclaration;
183+
if (typeDeclaration is ClassEntity) {
184+
_rtiNeedBuilder
185+
.registerClassUsingTypeVariableLiteral(typeDeclaration);
186+
} else if (typeDeclaration is FunctionEntity) {
187+
_rtiNeedBuilder
188+
.registerMethodUsingTypeVariableLiteral(typeDeclaration);
189+
} else if (typeDeclaration is Local) {
190+
_rtiNeedBuilder.registerLocalFunctionUsingTypeVariableLiteral(
191+
typeDeclaration);
191192
}
193+
registerImpact(_impacts.typeVariableExpression);
192194
}
193195
hasTypeLiteral = true;
194196
break;

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

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ abstract class RuntimeTypesNeed {
9595
// TODO(redemption): Remove this when the old frontend is deleted.
9696
bool localFunctionNeedsSignature(Local localFunction);
9797

98-
bool classUsesTypeVariableExpression(ClassEntity cls);
98+
bool classUsesTypeVariableLiteral(ClassEntity cls);
9999
}
100100

101101
class TrivialRuntimeTypesNeed implements RuntimeTypesNeed {
@@ -105,7 +105,7 @@ class TrivialRuntimeTypesNeed implements RuntimeTypesNeed {
105105
bool classNeedsTypeArguments(ClassEntity cls) => true;
106106

107107
@override
108-
bool classUsesTypeVariableExpression(ClassEntity cls) => true;
108+
bool classUsesTypeVariableLiteral(ClassEntity cls) => true;
109109

110110
@override
111111
bool localFunctionNeedsSignature(Local localFunction) => true;
@@ -125,8 +125,15 @@ class TrivialRuntimeTypesNeed implements RuntimeTypesNeed {
125125

126126
/// Interface for computing classes and methods that need runtime types.
127127
abstract class RuntimeTypesNeedBuilder {
128-
/// Registers that [cls] contains a type variable literal.
129-
void registerClassUsingTypeVariableExpression(ClassEntity cls);
128+
/// Registers that [cls] uses one of its type variables as a literal.
129+
void registerClassUsingTypeVariableLiteral(ClassEntity cls);
130+
131+
/// Registers that [method] uses one of its type variables as a literal.
132+
void registerMethodUsingTypeVariableLiteral(FunctionEntity method);
133+
134+
/// Registers that [localFunction] uses one of its type variables as a
135+
/// literal.
136+
void registerLocalFunctionUsingTypeVariableLiteral(Local localFunction);
130137

131138
/// Registers that if [element] needs type arguments at runtime then so does
132139
/// [dependency].
@@ -163,7 +170,13 @@ class TrivialRuntimeTypesNeedBuilder implements RuntimeTypesNeedBuilder {
163170
const TrivialRuntimeTypesNeedBuilder();
164171

165172
@override
166-
void registerClassUsingTypeVariableExpression(ClassEntity cls) {}
173+
void registerClassUsingTypeVariableLiteral(ClassEntity cls) {}
174+
175+
@override
176+
void registerMethodUsingTypeVariableLiteral(FunctionEntity method) {}
177+
178+
@override
179+
void registerLocalFunctionUsingTypeVariableLiteral(Local localFunction) {}
167180

168181
@override
169182
RuntimeTypesNeed computeRuntimeTypesNeed(
@@ -526,9 +539,8 @@ class RuntimeTypesNeedImpl implements RuntimeTypesNeed {
526539
final Set<Local> localFunctionsNeedingSignature;
527540
final Set<Local> localFunctionsNeedingTypeArguments;
528541

529-
/// The set of classes that use one of their type variables as expressions
530-
/// to get the runtime type.
531-
final Set<ClassEntity> classesUsingTypeVariableExpression;
542+
/// The set of classes that use one of their type variables as literals.
543+
final Set<ClassEntity> classesUsingTypeVariableLiterals;
532544

533545
RuntimeTypesNeedImpl(
534546
this._elementEnvironment,
@@ -538,7 +550,7 @@ class RuntimeTypesNeedImpl implements RuntimeTypesNeed {
538550
this.methodsNeedingTypeArguments,
539551
this.localFunctionsNeedingSignature,
540552
this.localFunctionsNeedingTypeArguments,
541-
this.classesUsingTypeVariableExpression);
553+
this.classesUsingTypeVariableLiterals);
542554

543555
bool checkClass(covariant ClassEntity cls) => true;
544556

@@ -580,28 +592,28 @@ class RuntimeTypesNeedImpl implements RuntimeTypesNeed {
580592
}
581593

582594
@override
583-
bool classUsesTypeVariableExpression(ClassEntity cls) {
584-
return classesUsingTypeVariableExpression.contains(cls);
595+
bool classUsesTypeVariableLiteral(ClassEntity cls) {
596+
return classesUsingTypeVariableLiterals.contains(cls);
585597
}
586598
}
587599

588600
class _ResolutionRuntimeTypesNeed extends RuntimeTypesNeedImpl {
589601
_ResolutionRuntimeTypesNeed(
590602
ElementEnvironment elementEnvironment,
591603
BackendUsage backendUsage,
592-
Set<ClassEntity> classesNeedingRti,
593-
Set<FunctionEntity> methodsNeedingRti,
594-
Set<FunctionEntity> methodsNeedingGenericRti,
595-
Set<Local> localFunctionsNeedingRti,
604+
Set<ClassEntity> classesNeedingTypeArguments,
605+
Set<FunctionEntity> methodsNeedingSignature,
606+
Set<FunctionEntity> methodsNeedingTypeArguments,
607+
Set<Local> localFunctionsNeedingSignature,
596608
Set<Local> localFunctionsNeedingTypeArguments,
597609
Set<ClassEntity> classesUsingTypeVariableExpression)
598610
: super(
599611
elementEnvironment,
600612
backendUsage,
601-
classesNeedingRti,
602-
methodsNeedingRti,
603-
methodsNeedingGenericRti,
604-
localFunctionsNeedingRti,
613+
classesNeedingTypeArguments,
614+
methodsNeedingSignature,
615+
methodsNeedingTypeArguments,
616+
localFunctionsNeedingSignature,
605617
localFunctionsNeedingTypeArguments,
606618
classesUsingTypeVariableExpression);
607619

@@ -615,9 +627,14 @@ class RuntimeTypesNeedBuilderImpl extends _RuntimeTypesBase
615627
final Map<Entity, Set<Entity>> typeArgumentDependencies =
616628
<Entity, Set<Entity>>{};
617629

618-
final Set<ClassEntity> classesUsingTypeVariableExpression =
630+
final Set<ClassEntity> classesUsingTypeVariableLiterals =
619631
new Set<ClassEntity>();
620632

633+
final Set<FunctionEntity> methodsUsingTypeVariableLiterals =
634+
new Set<FunctionEntity>();
635+
636+
final Set<Local> localFunctionsUsingTypeVariableLiterals = new Set<Local>();
637+
621638
final Set<ClassEntity> classesUsingTypeVariableTests = new Set<ClassEntity>();
622639

623640
Set<DartType> isChecks;
@@ -630,8 +647,18 @@ class RuntimeTypesNeedBuilderImpl extends _RuntimeTypesBase
630647
bool checkClass(covariant ClassEntity cls) => true;
631648

632649
@override
633-
void registerClassUsingTypeVariableExpression(ClassEntity cls) {
634-
classesUsingTypeVariableExpression.add(cls);
650+
void registerClassUsingTypeVariableLiteral(ClassEntity cls) {
651+
classesUsingTypeVariableLiterals.add(cls);
652+
}
653+
654+
@override
655+
void registerMethodUsingTypeVariableLiteral(FunctionEntity method) {
656+
methodsUsingTypeVariableLiterals.add(method);
657+
}
658+
659+
@override
660+
void registerLocalFunctionUsingTypeVariableLiteral(Local localFunction) {
661+
localFunctionsUsingTypeVariableLiterals.add(localFunction);
635662
}
636663

637664
@override
@@ -771,9 +798,12 @@ class RuntimeTypesNeedBuilderImpl extends _RuntimeTypesBase
771798
checkClosures();
772799
}
773800

774-
// Add the classes that need RTI because they use a type variable as
775-
// expression.
776-
classesUsingTypeVariableExpression.forEach(potentiallyNeedTypeArguments);
801+
// Add the classes, methods and local functions that need type arguments
802+
// because they use a type variable as a literal.
803+
classesUsingTypeVariableLiterals.forEach(potentiallyNeedTypeArguments);
804+
methodsUsingTypeVariableLiterals.forEach(potentiallyNeedTypeArguments);
805+
localFunctionsUsingTypeVariableLiterals
806+
.forEach(potentiallyNeedTypeArguments);
777807

778808
return _createRuntimeTypesNeed(
779809
_elementEnvironment,
@@ -783,7 +813,7 @@ class RuntimeTypesNeedBuilderImpl extends _RuntimeTypesBase
783813
methodsNeedingTypeArguments,
784814
localFunctionsNeedingSignature,
785815
localFunctionsNeedingTypeArguments,
786-
classesUsingTypeVariableExpression);
816+
classesUsingTypeVariableLiterals);
787817
}
788818

789819
RuntimeTypesNeed _createRuntimeTypesNeed(

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ class RuntimeTypeGenerator {
331331
if (generated.contains(superclass)) return;
332332

333333
if (classesUsingTypeVariableTests.contains(superclass) ||
334-
_rtiNeed.classUsesTypeVariableExpression(superclass) ||
334+
_rtiNeed.classUsesTypeVariableLiteral(superclass) ||
335335
checkedClasses.contains(superclass)) {
336336
// Generate substitution. If no substitution is necessary, emit
337337
// `null` to overwrite a (possibly) existing substitution from the

0 commit comments

Comments
 (0)