From f02fd0cd21ef954f2d0e3ee2a350bbd9505e0bee Mon Sep 17 00:00:00 2001 From: Martin Kustermann Date: Fri, 14 Nov 2025 02:52:30 -0800 Subject: [PATCH] [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 Commit-Queue: Martin Kustermann --- pkg/wasm_builder/lib/src/builder/types.dart | 35 ++++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/pkg/wasm_builder/lib/src/builder/types.dart b/pkg/wasm_builder/lib/src/builder/types.dart index daed2b99265..3ea4ad617ca 100644 --- a/pkg/wasm_builder/lib/src/builder/types.dart +++ b/pkg/wasm_builder/lib/src/builder/types.dart @@ -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), List>>( - 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>>{}; 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 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); + } +}