[dart2wasm] Change types builder to not use record types in maps

This reduces the time the codegen phase takes when compiling the
essentials app by 33% (1 min 43 sec -> 1 min 8)

Issue https://github.com/dart-lang/sdk/issues/61970

Change-Id: Ic26231a5823eeee24b562364e5cc6b03359792ba
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/461822
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
This commit is contained in:
Martin Kustermann
2025-11-14 02:52:30 -08:00
committed by Commit Queue
parent b0dace7771
commit f02fd0cd21
+23 -12
View File
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:collection';
import 'package:collection/collection.dart';
import '../ir/ir.dart' as ir;
import 'builder.dart';
@@ -130,22 +128,16 @@ class _RecGroupBuilder {
// (1) group length
// (2) length of first struct
// (3) group structural equality
final equivalenceGroups =
LinkedHashMap<(int, int, List<ir.DefType>), List<List<ir.DefType>>>(
hashCode: (a) => Object.hash(a.$1, a.$2),
equals: (a, b) =>
a.$1 == b.$1 &&
a.$2 == b.$2 &&
_areGroupsStructurallyEqual(a.$3, b.$3),
);
final equivalenceGroups = <_RecursionGroupKey, List<List<ir.DefType>>>{};
for (final group in groups) {
final structIndex = group.indexWhere((g) => g is ir.StructType);
// Skip groups with no struct types.
if (structIndex == -1) continue;
final structType = group[structIndex] as ir.StructType;
equivalenceGroups.putIfAbsent(
(group.length, structType.fields.length, group), () => []).add(group);
final key =
_RecursionGroupKey(group.length, structType.fields.length, group);
equivalenceGroups.putIfAbsent(key, () => []).add(group);
}
for (final equalGroups in equivalenceGroups.values) {
@@ -351,3 +343,22 @@ class _FunctionTypeKey {
return (inputHash * 2 + 1) * (outputHash * 2 + 1);
}
}
class _RecursionGroupKey {
final int groupLength;
final int lengthOfFirstStruct;
final List<ir.DefType> types;
_RecursionGroupKey(this.groupLength, this.lengthOfFirstStruct, this.types);
@override
int get hashCode => Object.hash(groupLength, lengthOfFirstStruct);
@override
bool operator ==(other) {
if (other is! _RecursionGroupKey) return false;
if (groupLength != other.groupLength) return false;
if (lengthOfFirstStruct != other.lengthOfFirstStruct) return false;
return _RecGroupBuilder._areGroupsStructurallyEqual(types, other.types);
}
}