Skip to content

Commit 9197c1b

Browse files
rakudramacommit-bot@chromium.org
authored andcommitted
[dart2js] new-rti: fix TypeEval GVN
Type expression GVN needs to structural equality on TypeRecipe and TypeEnvironmentStructure. Change-Id: Iaa4985ec99fff6db29e8bfd63fd0dbacdc10dde6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/109942 Reviewed-by: Mayank Patke <[email protected]> Commit-Queue: Stephen Adams <[email protected]>
1 parent 60a952e commit 9197c1b

File tree

3 files changed

+72
-4
lines changed

3 files changed

+72
-4
lines changed

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

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,30 @@ import '../elements/types.dart';
1212
/// A type environment maps type parameter variables to type values. The type
1313
/// variables are mostly elided in the runtime representation, replaced by
1414
/// indexes into the reified environment.
15-
abstract class TypeEnvironmentStructure {}
15+
abstract class TypeEnvironmentStructure {
16+
/// Structural equality on [TypeEnvironmentStructure].
17+
static bool same(TypeEnvironmentStructure a, TypeEnvironmentStructure b) {
18+
if (a is SingletonTypeEnvironmentStructure) {
19+
if (b is SingletonTypeEnvironmentStructure) {
20+
return a.variable == b.variable;
21+
}
22+
return false;
23+
}
24+
return _sameFullStructure(a, b);
25+
}
26+
27+
static bool _sameFullStructure(
28+
FullTypeEnvironmentStructure a, FullTypeEnvironmentStructure b) {
29+
if (a.classType != b.classType) return false;
30+
List<TypeVariableType> aBindings = a.bindings;
31+
List<TypeVariableType> bBindings = b.bindings;
32+
if (aBindings.length != bBindings.length) return false;
33+
for (int i = 0; i < aBindings.length; i++) {
34+
if (aBindings[i] != bBindings[i]) return false;
35+
}
36+
return true;
37+
}
38+
}
1639

1740
/// A singleton type environment maps a binds a single value.
1841
class SingletonTypeEnvironmentStructure extends TypeEnvironmentStructure {
@@ -38,14 +61,37 @@ class FullTypeEnvironmentStructure extends TypeEnvironmentStructure {
3861

3962
/// A TypeRecipe is evaluated against a type environment to produce either a
4063
/// type, or another type environment.
41-
abstract class TypeRecipe {}
64+
abstract class TypeRecipe {
65+
/// Returns `true` is [recipeB] evaluated in an environment described by
66+
/// [structureB] gives the same type as [recipeA] evaluated in environment
67+
/// described by [structureA].
68+
static bool yieldsSameType(
69+
TypeRecipe recipeA,
70+
TypeEnvironmentStructure structureA,
71+
TypeRecipe recipeB,
72+
TypeEnvironmentStructure structureB) {
73+
if (recipeA == recipeB &&
74+
TypeEnvironmentStructure.same(structureA, structureB)) {
75+
return true;
76+
}
77+
78+
// TODO(sra): Type recipes that are different but equal modulo naming also
79+
// yield the same type, e.g. `List<X> @X` and `List<Y> @Y`.
80+
return false;
81+
}
82+
}
4283

4384
/// A recipe that yields a reified type.
4485
class TypeExpressionRecipe extends TypeRecipe {
4586
final DartType type;
4687

4788
TypeExpressionRecipe(this.type);
4889

90+
@override
91+
bool operator ==(other) {
92+
return other is TypeExpressionRecipe && type == other.type;
93+
}
94+
4995
@override
5096
String toString() => 'TypeExpressionRecipe($type)';
5197
}
@@ -60,6 +106,11 @@ class SingletonTypeEnvironmentRecipe extends TypeEnvironmentRecipe {
60106

61107
SingletonTypeEnvironmentRecipe(this.type);
62108

109+
@override
110+
bool operator ==(other) {
111+
return other is SingletonTypeEnvironmentRecipe && type == other.type;
112+
}
113+
63114
@override
64115
String toString() => 'SingletonTypeEnvironmentRecipe($type)';
65116
}
@@ -80,6 +131,22 @@ class FullTypeEnvironmentRecipe extends TypeEnvironmentRecipe {
80131

81132
FullTypeEnvironmentRecipe({this.classType, this.types = const []});
82133

134+
@override
135+
bool operator ==(other) {
136+
return other is FullTypeEnvironmentRecipe && _equal(this, other);
137+
}
138+
139+
static bool _equal(FullTypeEnvironmentRecipe a, FullTypeEnvironmentRecipe b) {
140+
if (a.classType != b.classType) return false;
141+
List<DartType> aTypes = a.types;
142+
List<DartType> bTypes = b.types;
143+
if (aTypes.length != bTypes.length) return false;
144+
for (int i = 0; i < aTypes.length; i++) {
145+
if (aTypes[i] != bTypes[i]) return false;
146+
}
147+
return true;
148+
}
149+
83150
@override
84151
String toString() => 'FullTypeEnvironmentRecipe($classType, $types)';
85152
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4521,7 +4521,8 @@ class HTypeEval extends HRtiInstruction {
45214521

45224522
@override
45234523
bool dataEquals(HTypeEval other) {
4524-
return typeExpression == other.typeExpression;
4524+
return TypeRecipe.yieldsSameType(
4525+
typeExpression, envStructure, other.typeExpression, other.envStructure);
45254526
}
45264527

45274528
@override

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,7 @@ class HInstructionStringifier implements HVisitor<String> {
708708
@override
709709
String visitTypeEval(HTypeEval node) {
710710
var inputs = node.inputs.map(temporaryId).join(', ');
711-
return "TypeEval: ${node.typeExpression} $inputs";
711+
return "TypeEval: ${node.typeExpression} ${node.envStructure} $inputs";
712712
}
713713

714714
@override

0 commit comments

Comments
 (0)