Version 2.17.0-214.0.dev
Merge commit '5317e4c605d56ab7297ce9e4d92c68d81064b693' into 'dev'
diff --git a/pkg/dart2wasm/lib/class_info.dart b/pkg/dart2wasm/lib/class_info.dart
index 54037e0..e420c22 100644
--- a/pkg/dart2wasm/lib/class_info.dart
+++ b/pkg/dart2wasm/lib/class_info.dart
@@ -21,6 +21,8 @@
static const boxValue = 1;
static const identityHash = 1;
static const stringArray = 2;
+ static const hashBaseIndex = 2;
+ static const hashBaseData = 4;
static const closureContext = 2;
static const closureFunction = 3;
static const typedListBaseLength = 2;
@@ -45,6 +47,8 @@
check(translator.boxedDoubleClass, "value", FieldIndex.boxValue);
check(translator.oneByteStringClass, "_array", FieldIndex.stringArray);
check(translator.twoByteStringClass, "_array", FieldIndex.stringArray);
+ check(translator.hashFieldBaseClass, "_index", FieldIndex.hashBaseIndex);
+ check(translator.hashFieldBaseClass, "_data", FieldIndex.hashBaseData);
check(translator.functionClass, "context", FieldIndex.closureContext);
}
}
diff --git a/pkg/dart2wasm/lib/constants.dart b/pkg/dart2wasm/lib/constants.dart
index 789f070..4440b45 100644
--- a/pkg/dart2wasm/lib/constants.dart
+++ b/pkg/dart2wasm/lib/constants.dart
@@ -2,6 +2,7 @@
// 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:math';
import 'dart:typed_data';
import 'package:dart2wasm/class_info.dart';
@@ -578,6 +579,51 @@
}
@override
+ ConstantInfo? visitMapConstant(MapConstant constant) {
+ Constant keyTypeConstant = TypeLiteralConstant(constant.keyType);
+ ensureConstant(keyTypeConstant);
+ Constant valueTypeConstant = TypeLiteralConstant(constant.valueType);
+ ensureConstant(valueTypeConstant);
+ List<Constant> dataElements =
+ List.generate(constant.entries.length * 2, (i) {
+ ConstantMapEntry entry = constant.entries[i >> 1];
+ return i.isEven ? entry.key : entry.value;
+ });
+ ListConstant dataList = ListConstant(const DynamicType(), dataElements);
+ ensureConstant(dataList);
+
+ ClassInfo info = translator.classInfo[translator.immutableMapClass]!;
+ translator.functions.allocateClass(info.classId);
+ w.RefType type = info.nonNullableType;
+ return createConstant(constant, type, (function, b) {
+ // This computation of the hash mask follows the computations in
+ // [_ImmutableLinkedHashMapMixin._createIndex] and
+ // [_HashBase._indexSizeToHashMask].
+ const int initialIndexSize = 8;
+ final int indexSize = max(dataElements.length, initialIndexSize);
+ final int hashMask = (1 << (31 - (indexSize - 1).bitLength)) - 1;
+
+ w.RefType indexType =
+ info.struct.fields[FieldIndex.hashBaseIndex].type as w.RefType;
+ w.RefType dataType =
+ info.struct.fields[FieldIndex.hashBaseData].type as w.RefType;
+
+ b.i32_const(info.classId);
+ b.i32_const(initialIdentityHash);
+ b.ref_null(indexType.heapType); // _index
+ b.i64_const(hashMask); // _hashMask
+ constants.instantiateConstant(function, b, dataList, dataType); // _data
+ b.i64_const(dataElements.length); // _usedData
+ b.i64_const(0); // _deletedKeys
+ constants.instantiateConstant(
+ function, b, keyTypeConstant, constants.typeInfo.nullableType);
+ constants.instantiateConstant(
+ function, b, valueTypeConstant, constants.typeInfo.nullableType);
+ translator.struct_new(b, info);
+ });
+ }
+
+ @override
ConstantInfo? visitStaticTearOffConstant(StaticTearOffConstant constant) {
w.DefinedFunction closureFunction =
translator.getTearOffFunction(constant.targetReference.asProcedure);
diff --git a/pkg/dart2wasm/lib/constants_backend.dart b/pkg/dart2wasm/lib/constants_backend.dart
index 6871599..17e4bf4 100644
--- a/pkg/dart2wasm/lib/constants_backend.dart
+++ b/pkg/dart2wasm/lib/constants_backend.dart
@@ -7,68 +7,17 @@
import 'package:kernel/core_types.dart';
class WasmConstantsBackend extends ConstantsBackend {
- final Class immutableMapClass;
final Class unmodifiableSetClass;
final Field unmodifiableSetMap;
- WasmConstantsBackend._(this.immutableMapClass, this.unmodifiableSetMap,
- this.unmodifiableSetClass);
+ WasmConstantsBackend._(this.unmodifiableSetMap, this.unmodifiableSetClass);
factory WasmConstantsBackend(CoreTypes coreTypes) {
- final Library coreLibrary = coreTypes.coreLibrary;
- final Class immutableMapClass = coreLibrary.classes
- .firstWhere((Class klass) => klass.name == '_ImmutableMap');
Field unmodifiableSetMap =
coreTypes.index.getField('dart:collection', '_UnmodifiableSet', '_map');
- return new WasmConstantsBackend._(immutableMapClass, unmodifiableSetMap,
- unmodifiableSetMap.enclosingClass!);
- }
-
- @override
- Constant lowerMapConstant(MapConstant constant) {
- // The _ImmutableMap class is implemented via one field pointing to a list
- // of key/value pairs -- see runtime/lib/immutable_map.dart!
- final List<Constant> kvListPairs =
- new List<Constant>.generate(2 * constant.entries.length, (int i) {
- final int index = i ~/ 2;
- final ConstantMapEntry entry = constant.entries[index];
- return i % 2 == 0 ? entry.key : entry.value;
- });
- // This is a bit fishy, since we merge the key and the value type by
- // putting both into the same list.
- final ListConstant kvListConstant =
- new ListConstant(const DynamicType(), kvListPairs);
- assert(immutableMapClass.fields.length == 1);
- final Field kvPairListField = immutableMapClass.fields[0];
- return new InstanceConstant(immutableMapClass.reference, <DartType>[
- constant.keyType,
- constant.valueType,
- ], <Reference, Constant>{
- // We use getterReference as we refer to the field itself.
- kvPairListField.getterReference: kvListConstant,
- });
- }
-
- @override
- bool isLoweredMapConstant(Constant constant) {
- return constant is InstanceConstant &&
- constant.classNode == immutableMapClass;
- }
-
- @override
- void forEachLoweredMapConstantEntry(
- Constant constant, void Function(Constant key, Constant value) f) {
- assert(isLoweredMapConstant(constant));
- final InstanceConstant instance = constant as InstanceConstant;
- assert(immutableMapClass.fields.length == 1);
- final Field kvPairListField = immutableMapClass.fields[0];
- final ListConstant kvListConstant =
- instance.fieldValues[kvPairListField.getterReference] as ListConstant;
- assert(kvListConstant.entries.length % 2 == 0);
- for (int index = 0; index < kvListConstant.entries.length; index += 2) {
- f(kvListConstant.entries[index], kvListConstant.entries[index + 1]);
- }
+ return new WasmConstantsBackend._(
+ unmodifiableSetMap, unmodifiableSetMap.enclosingClass!);
}
@override
diff --git a/pkg/dart2wasm/lib/intrinsics.dart b/pkg/dart2wasm/lib/intrinsics.dart
index e795d85..002daa3 100644
--- a/pkg/dart2wasm/lib/intrinsics.dart
+++ b/pkg/dart2wasm/lib/intrinsics.dart
@@ -145,6 +145,13 @@
return w.NumType.i64;
}
+ if (node.interfaceTarget == translator.immutableMapIndexNullable) {
+ ClassInfo info = translator.classInfo[translator.hashFieldBaseClass]!;
+ codeGen.wrap(node.receiver, info.nullableType);
+ b.struct_get(info.struct, FieldIndex.hashBaseIndex);
+ return info.struct.fields[FieldIndex.hashBaseIndex].type.unpacked;
+ }
+
return null;
}
diff --git a/pkg/dart2wasm/lib/target.dart b/pkg/dart2wasm/lib/target.dart
index fa68680..76623cc 100644
--- a/pkg/dart2wasm/lib/target.dart
+++ b/pkg/dart2wasm/lib/target.dart
@@ -18,7 +18,7 @@
class WasmTarget extends Target {
Class? _growableList;
Class? _immutableList;
- Class? _immutableMap;
+ Class? _wasmImmutableLinkedHashMap;
Class? _unmodifiableSet;
Class? _compactLinkedCustomHashMap;
Class? _compactLinkedHashSet;
@@ -157,8 +157,8 @@
@override
Class concreteConstMapLiteralClass(CoreTypes coreTypes) {
- return _immutableMap ??=
- coreTypes.index.getClass('dart:collection', '_ImmutableMap');
+ return _wasmImmutableLinkedHashMap ??= coreTypes.index
+ .getClass('dart:collection', '_WasmImmutableLinkedHashMap');
}
@override
diff --git a/pkg/dart2wasm/lib/translator.dart b/pkg/dart2wasm/lib/translator.dart
index 1630176..e34f5ba 100644
--- a/pkg/dart2wasm/lib/translator.dart
+++ b/pkg/dart2wasm/lib/translator.dart
@@ -77,6 +77,8 @@
late final Class fixedLengthListClass;
late final Class growableListClass;
late final Class immutableListClass;
+ late final Class immutableMapClass;
+ late final Class hashFieldBaseClass;
late final Class stringBaseClass;
late final Class oneByteStringClass;
late final Class twoByteStringClass;
@@ -91,6 +93,7 @@
late final Procedure stringInterpolate;
late final Procedure mapFactory;
late final Procedure mapPut;
+ late final Procedure immutableMapIndexNullable;
late final Map<Class, w.StorageType> builtinTypes;
late final Map<w.ValueType, Class> boxedClasses;
@@ -172,6 +175,8 @@
listBaseClass = lookupCore("_ListBase");
growableListClass = lookupCore("_GrowableList");
immutableListClass = lookupCore("_ImmutableList");
+ immutableMapClass = lookupCollection("_WasmImmutableLinkedHashMap");
+ hashFieldBaseClass = lookupCollection("_HashFieldBase");
stringBaseClass = lookupCore("_StringBase");
oneByteStringClass = lookupCore("_OneByteString");
twoByteStringClass = lookupCore("_TwoByteString");
@@ -190,10 +195,12 @@
mapFactory = lookupCollection("LinkedHashMap").procedures.firstWhere(
(p) => p.kind == ProcedureKind.Factory && p.name.text == "_default");
mapPut = lookupCollection("_CompactLinkedCustomHashMap")
- .superclass! // _HashBase
.superclass! // _LinkedHashMapMixin<K, V>
.procedures
.firstWhere((p) => p.name.text == "[]=");
+ immutableMapIndexNullable = lookupCollection("_HashAbstractImmutableBase")
+ .procedures
+ .firstWhere((p) => p.name.text == "_indexNullable");
builtinTypes = {
coreTypes.boolClass: w.NumType.i32,
coreTypes.intClass: w.NumType.i64,
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_case1.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_case1.dart.expect
index 4a919d4..63b00b0 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_case1.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_case1.dart.expect
@@ -15,7 +15,7 @@
: self::InheritedElement::_dependents = <self::Element, core::Object?>{}, super self::Element::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3] method setDependencies([@vm.inferred-type.metadata=!] self::Element dependent, [@vm.inferred-type.metadata=dart.core::_Smi?] core::Object? value) → void {
- [@vm.call-site-attributes.metadata=receiverType:dart.core::Map<#lib::Element, dart.core::Object?>] [@vm.direct-call.metadata=dart.collection::__InternalLinkedHashMap&_HashVMBase&MapMixin&_LinkedHashMapMixin.[]=] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=#lib::InheritedElement._dependents] [@vm.inferred-type.metadata=dart.collection::_InternalLinkedHashMap<#lib::Element, dart.core::Object?>] this.{self::InheritedElement::_dependents}{core::Map<self::Element, core::Object?>}.{core::Map::[]=}(dependent, value){(self::Element, core::Object?) → void};
+ [@vm.call-site-attributes.metadata=receiverType:dart.core::Map<#lib::Element, dart.core::Object?>] [@vm.direct-call.metadata=dart.collection::__InternalLinkedHashMap&_HashVMBase&MapMixin&_HashBase&_OperatorEqualsAndHashCode&_LinkedHashMapMixin.[]=] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=#lib::InheritedElement._dependents] [@vm.inferred-type.metadata=dart.collection::_InternalLinkedHashMap<#lib::Element, dart.core::Object?>] this.{self::InheritedElement::_dependents}{core::Map<self::Element, core::Object?>}.{core::Map::[]=}(dependent, value){(self::Element, core::Object?) → void};
}
}
static method main() → dynamic {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/const_map.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/const_map.dart.expect
index 6c1795f..88fd00f 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/const_map.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/const_map.dart.expect
@@ -11,7 +11,7 @@
: super core::Object::•()
;
static method fromReader() → self::_Attribute {
- final self::_AttributeName name = [@vm.direct-call.metadata=dart.collection::_InternalImmutableLinkedHashMap.[]] [@vm.inferred-type.metadata=#lib::_AttributeName? (skip check)] #C8.{core::Map::[]}(#C1){(core::Object?) → self::_AttributeName?}!;
+ final self::_AttributeName name = [@vm.direct-call.metadata=dart.collection::__InternalImmutableLinkedHashMap&_HashVMImmutableBase&MapMixin&_HashBase&_OperatorEqualsAndCanonicalHashCode&_LinkedHashMapMixin&_UnmodifiableMapMixin&_ImmutableLinkedHashMapMixin.[]] [@vm.inferred-type.metadata=#lib::_AttributeName? (skip check)] #C8.{core::Map::[]}(#C1){(core::Object?) → self::_AttributeName?}!;
return new self::_Attribute::_();
}
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/const_set.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/const_set.dart.expect
index f345b4b..f8d211c 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/const_set.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/const_set.dart.expect
@@ -11,7 +11,7 @@
: super core::Object::•()
;
static method fromReader() → self::_Attribute {
- final core::bool name = [@vm.direct-call.metadata=dart.collection::_CompactImmutableLinkedHashSet.contains] [@vm.inferred-type.metadata=!? (skip check)] #C3.{core::Set::contains}(#C2){(core::Object?) → core::bool};
+ final core::bool name = [@vm.direct-call.metadata=dart.collection::__CompactImmutableLinkedHashSet&_HashVMImmutableBase&SetMixin&_HashBase&_OperatorEqualsAndCanonicalHashCode&_LinkedHashSetMixin&_UnmodifiableSetMixin&_ImmutableLinkedHashSetMixin.contains] [@vm.inferred-type.metadata=!? (skip check)] #C3.{core::Set::contains}(#C2){(core::Object?) → core::bool};
return let final self::_AttributeName #t1 = #C8.{core::List::[]}(#C2){(core::int) → self::_AttributeName} in new self::_Attribute::_();
}
}
diff --git a/runtime/vm/compiler/frontend/constant_reader.cc b/runtime/vm/compiler/frontend/constant_reader.cc
index a6bc6e5..ca1f9dc 100644
--- a/runtime/vm/compiler/frontend/constant_reader.cc
+++ b/runtime/vm/compiler/frontend/constant_reader.cc
@@ -293,8 +293,7 @@
const intptr_t used_data = (length << 1);
map.set_used_data(used_data);
- const intptr_t data_size = Utils::RoundUpToPowerOfTwo(used_data);
- const auto& data = Array::Handle(Z, Array::New(data_size));
+ const auto& data = Array::Handle(Z, Array::New(used_data));
map.set_data(data);
map.set_deleted_keys(0);
@@ -343,8 +342,7 @@
const intptr_t used_data = length;
set.set_used_data(used_data);
- const intptr_t data_size = Utils::RoundUpToPowerOfTwo(used_data);
- const auto& data = Array::Handle(Z, Array::New(data_size));
+ const auto& data = Array::Handle(Z, Array::New(used_data));
set.set_data(data);
set.set_deleted_keys(0);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 2b6b9c2..0ef9ca6 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -24498,7 +24498,7 @@
Zone* const zone = thread->zone();
const auto& data_array = Array::Handle(zone, data());
- const intptr_t data_length = data_array.Length();
+ const intptr_t data_length = Utils::RoundUpToPowerOfTwo(data_array.Length());
const intptr_t index_size_mult = IsLinkedHashMap() ? 1 : 2;
const intptr_t index_size = Utils::Maximum(LinkedHashBase::kInitialIndexSize,
data_length * index_size_mult);
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index ac5c703..237ffb0 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -5226,12 +5226,14 @@
// Check data, only for non-nested.
const auto& data1 = Array::Handle(map1.data());
const auto& data2 = Array::Handle(map2.data());
- const bool data_length_equal = data1.Length() == data2.Length();
+ const intptr_t data1_length = Smi::Value(map1.used_data());
+ const intptr_t data2_length = Smi::Value(map2.used_data());
+ const bool data_length_equal = data1_length == data2_length;
bool data_equal = data_length_equal;
if (data_length_equal) {
auto& object1 = Instance::Handle();
auto& object2 = Instance::Handle();
- for (intptr_t i = 0; i < data1.Length(); i++) {
+ for (intptr_t i = 0; i < data1_length; i++) {
object1 ^= data1.At(i);
object2 ^= data2.At(i);
data_equal &= object1.CanonicalizeEquals(object2);
@@ -5242,14 +5244,14 @@
THR_Print("LinkedHashBaseEqual Data not equal.\n");
THR_Print("LinkedHashBaseEqual data1.length %" Pd " data1.length %" Pd
" \n",
- data1.Length(), data2.Length());
+ data1_length, data2_length);
auto& object1 = Instance::Handle();
- for (intptr_t i = 0; i < data1.Length(); i++) {
+ for (intptr_t i = 0; i < data1_length; i++) {
object1 ^= data1.At(i);
THR_Print("LinkedHashBaseEqual data1[%" Pd "] %s\n", i,
object1.ToCString());
}
- for (intptr_t i = 0; i < data2.Length(); i++) {
+ for (intptr_t i = 0; i < data2_length; i++) {
object1 ^= data2.At(i);
THR_Print("LinkedHashBaseEqual data2[%" Pd "] %s\n", i,
object1.ToCString());
@@ -5315,7 +5317,7 @@
const TypeArguments& type_arguments) {
auto& map = LinkedHashMap::Handle(ImmutableLinkedHashMap::NewUninitialized());
- const auto& data = Array::Handle(Array::New(input_data.Length()));
+ const auto& data = Array::Handle(Array::New(used_data));
for (intptr_t i = 0; i < used_data; i++) {
data.SetAt(i, Object::Handle(input_data.At(i)));
}
@@ -5706,7 +5708,7 @@
const TypeArguments& type_arguments) {
auto& set = LinkedHashSet::Handle(ImmutableLinkedHashSet::NewUninitialized());
- const auto& data = Array::Handle(Array::New(input_data.Length()));
+ const auto& data = Array::Handle(Array::New(used_data));
for (intptr_t i = 0; i < used_data; i++) {
data.SetAt(i, Object::Handle(input_data.At(i)));
}
diff --git a/sdk/lib/_internal/vm/lib/compact_hash.dart b/sdk/lib/_internal/vm/lib/compact_hash.dart
index fa4b32d..c49bb48 100644
--- a/sdk/lib/_internal/vm/lib/compact_hash.dart
+++ b/sdk/lib/_internal/vm/lib/compact_hash.dart
@@ -16,7 +16,30 @@
}
}
-abstract class _HashFieldBase {
+// Common interface for [_HashFieldBase] and [_HashVMBase].
+abstract class _HashAbstractBase {
+ Uint32List get _index;
+ void set _index(Uint32List value);
+
+ int get _hashMask;
+ void set _hashMask(int value);
+
+ List get _data;
+ void set _data(List value);
+
+ int get _usedData;
+ void set _usedData(int value);
+
+ int get _deletedKeys;
+ void set _deletedKeys(int value);
+}
+
+abstract class _HashAbstractImmutableBase extends _HashAbstractBase {
+ @pragma("wasm:entry-point")
+ Uint32List? get _indexNullable;
+}
+
+abstract class _HashFieldBase implements _HashAbstractBase {
// Each occupied entry in _index is a fixed-size integer that encodes a pair:
// [ hash pattern for key | index of entry in _data ]
// The hash pattern is based on hashCode, but is guaranteed to be non-zero.
@@ -43,11 +66,11 @@
// Note: All fields are initialized in a single constructor so that the VM
// recognizes they cannot hold null values. This makes a big (20%) performance
// difference on some operations.
- _HashFieldBase(int dataSize);
+ _HashFieldBase();
}
// Base class for VM-internal classes; keep in sync with _HashFieldBase.
-abstract class _HashVMBase {
+abstract class _HashVMBase implements _HashAbstractBase {
@pragma("vm:recognized", "other")
@pragma("vm:exact-result-type", "dart:typed_data#_Uint32List")
@pragma("vm:prefer-inline")
@@ -99,8 +122,9 @@
external void set _deletedKeys(int value);
}
-// Base class for VM-internal classes; keep in sync with _HashFieldBase.
-abstract class _HashVMImmutableBase extends _HashVMBase {
+// Base class for immutable VM-internal classes.
+abstract class _HashVMImmutableBase extends _HashVMBase
+ implements _HashAbstractImmutableBase {
// The data is an immutable list rather than a mutable list.
@pragma("vm:recognized", "other")
@pragma("vm:exact-result-type", "dart:core#_ImmutableList")
@@ -123,8 +147,7 @@
// This mixin can be applied to _HashFieldBase or _HashVMBase (for
// normal and VM-internalized classes, respectiveley), which provide the
// actual fields/accessors that this mixin assumes.
-// TODO(koda): Consider moving field comments to _HashFieldBase.
-abstract class _HashBase implements _HashVMBase {
+mixin _HashBase on _HashAbstractBase {
// The number of bits used for each component is determined by table size.
// If initialized, the length of _index is (at least) twice the number of
// entries in _data, and both are doubled when _data is full. Thus, _index
@@ -208,17 +231,22 @@
}
}
-class _OperatorEqualsAndHashCode {
+abstract class _EqualsAndHashCode {
+ int _hashCode(e);
+ bool _equals(e1, e2);
+}
+
+mixin _OperatorEqualsAndHashCode implements _EqualsAndHashCode {
int _hashCode(e) => e.hashCode;
bool _equals(e1, e2) => e1 == e2;
}
-class _IdenticalAndIdentityHashCode {
+mixin _IdenticalAndIdentityHashCode implements _EqualsAndHashCode {
int _hashCode(e) => identityHashCode(e);
bool _equals(e1, e2) => identical(e1, e2);
}
-class _OperatorEqualsAndCanonicalHashCode {
+mixin _OperatorEqualsAndCanonicalHashCode implements _EqualsAndHashCode {
static final int cidSymbol = ClassID.getID(#a);
int _hashCode(e) {
@@ -232,6 +260,14 @@
bool _equals(e1, e2) => e1 == e2;
}
+mixin _CustomEqualsAndHashCode implements _EqualsAndHashCode {
+ dynamic get _hasher;
+ dynamic get _equality;
+
+ int _hashCode(e) => _hasher(e);
+ bool _equals(e1, e2) => _equality(e1, e2);
+}
+
final _uninitializedIndex = new Uint32List(_HashBase._UNINITIALIZED_INDEX_SIZE);
// Note: not const. Const arrays are made immutable by having a different class
// than regular arrays that throws on element assignment. We want the data field
@@ -243,9 +279,9 @@
class _InternalLinkedHashMap<K, V> extends _HashVMBase
with
MapMixin<K, V>,
- _LinkedHashMapMixin<K, V>,
_HashBase,
- _OperatorEqualsAndHashCode
+ _OperatorEqualsAndHashCode,
+ _LinkedHashMapMixin<K, V>
implements LinkedHashMap<K, V> {
_InternalLinkedHashMap() {
_index = _uninitializedIndex;
@@ -273,15 +309,19 @@
class _InternalImmutableLinkedHashMap<K, V> extends _HashVMImmutableBase
with
MapMixin<K, V>,
- _LinkedHashMapMixin<K, V>,
_HashBase,
_OperatorEqualsAndCanonicalHashCode,
- _UnmodifiableMapMixin<K, V>
+ _LinkedHashMapMixin<K, V>,
+ _UnmodifiableMapMixin<K, V>,
+ _ImmutableLinkedHashMapMixin<K, V>
implements LinkedHashMap<K, V> {
factory _InternalImmutableLinkedHashMap._uninstantiable() {
throw new UnsupportedError("ImmutableMap can only be allocated by the VM");
}
+}
+mixin _ImmutableLinkedHashMapMixin<K, V>
+ on _LinkedHashMapMixin<K, V>, _HashAbstractImmutableBase {
bool containsKey(Object? key) {
if (_indexNullable == null) {
_createIndex();
@@ -297,8 +337,8 @@
}
void _createIndex() {
- final size = max(_data.length, _HashBase._INITIAL_INDEX_SIZE);
- assert(size == _roundUpToPowerOfTwo(size));
+ final size =
+ _roundUpToPowerOfTwo(max(_data.length, _HashBase._INITIAL_INDEX_SIZE));
final newIndex = new Uint32List(size);
final hashMask = _HashBase._indexSizeToHashMask(size);
assert(_hashMask == hashMask);
@@ -345,12 +385,7 @@
return x + 1;
}
-abstract class _LinkedHashMapMixin<K, V> implements _HashBase {
- int _hashCode(e);
- bool _equals(e1, e2);
- int get _checkSum;
- bool _isModifiedSince(List oldData, int oldCheckSum);
-
+mixin _LinkedHashMapMixin<K, V> on _HashBase, _EqualsAndHashCode {
int get length => (_usedData >> 1) - _deletedKeys;
bool get isEmpty => length == 0;
bool get isNotEmpty => !isEmpty;
@@ -592,12 +627,10 @@
class _CompactLinkedIdentityHashMap<K, V> extends _HashFieldBase
with
MapMixin<K, V>,
- _LinkedHashMapMixin<K, V>,
_HashBase,
- _IdenticalAndIdentityHashCode
+ _IdenticalAndIdentityHashCode,
+ _LinkedHashMapMixin<K, V>
implements LinkedHashMap<K, V> {
- _CompactLinkedIdentityHashMap() : super(_HashBase._INITIAL_INDEX_SIZE);
-
void addAll(Map<K, V> other) {
if (other is _CompactLinkedIdentityHashMap) {
final otherBase = other as _CompactLinkedIdentityHashMap;
@@ -610,15 +643,15 @@
}
class _CompactLinkedCustomHashMap<K, V> extends _HashFieldBase
- with MapMixin<K, V>, _LinkedHashMapMixin<K, V>, _HashBase
+ with
+ MapMixin<K, V>,
+ _HashBase,
+ _CustomEqualsAndHashCode,
+ _LinkedHashMapMixin<K, V>
implements LinkedHashMap<K, V> {
- final _equality;
- final _hasher;
- final _validKey;
-
- // TODO(koda): Ask gbracha why I cannot have fields _equals/_hashCode.
- int _hashCode(e) => _hasher(e);
- bool _equals(e1, e2) => _equality(e1, e2);
+ final dynamic _equality;
+ final dynamic _hasher;
+ final dynamic _validKey;
bool containsKey(Object? o) => _validKey(o) ? super.containsKey(o) : false;
V? operator [](Object? o) => _validKey(o) ? super[o] : null;
@@ -628,8 +661,7 @@
void operator []=(K key, V value);
_CompactLinkedCustomHashMap(this._equality, this._hasher, validKey)
- : _validKey = (validKey != null) ? validKey : new _TypeTest<K>().test,
- super(_HashBase._INITIAL_INDEX_SIZE);
+ : _validKey = (validKey != null) ? validKey : new _TypeTest<K>().test;
}
// Iterates through _data[_offset + _step], _data[_offset + 2*_step], ...
@@ -739,12 +771,7 @@
E get current => _current as E;
}
-abstract class _LinkedHashSetMixin<E> implements _HashBase {
- int _hashCode(e);
- bool _equals(e1, e2);
- int get _checkSum;
- bool _isModifiedSince(List oldData, int oldCheckSum);
-
+mixin _LinkedHashSetMixin<E> on _HashBase, _EqualsAndHashCode {
bool get isEmpty => length == 0;
bool get isNotEmpty => !isEmpty;
int get length => _usedData - _deletedKeys;
@@ -910,14 +937,14 @@
}
}
-// Set implementation, analogous to _CompactLinkedHashMap.
+// Set implementation, analogous to _InternalLinkedHashMap.
@pragma('vm:entry-point')
class _CompactLinkedHashSet<E> extends _HashVMBase
with
SetMixin<E>,
- _LinkedHashSetMixin<E>,
_HashBase,
- _OperatorEqualsAndHashCode
+ _OperatorEqualsAndHashCode,
+ _LinkedHashSetMixin<E>
implements LinkedHashSet<E> {
_CompactLinkedHashSet() {
_index = _uninitializedIndex;
@@ -951,15 +978,19 @@
class _CompactImmutableLinkedHashSet<E> extends _HashVMImmutableBase
with
SetMixin<E>,
- _LinkedHashSetMixin<E>,
_HashBase,
_OperatorEqualsAndCanonicalHashCode,
- _UnmodifiableSetMixin<E>
+ _LinkedHashSetMixin<E>,
+ _UnmodifiableSetMixin<E>,
+ _ImmutableLinkedHashSetMixin<E>
implements LinkedHashSet<E> {
factory _CompactImmutableLinkedHashSet._uninstantiable() {
throw new UnsupportedError("ImmutableSet can only be allocated by the VM");
}
+}
+mixin _ImmutableLinkedHashSetMixin<E>
+ on Set<E>, _LinkedHashSetMixin<E>, _HashAbstractImmutableBase {
E? lookup(Object? key) {
if (_indexNullable == null) {
_createIndex();
@@ -1029,12 +1060,10 @@
class _CompactLinkedIdentityHashSet<E> extends _HashFieldBase
with
SetMixin<E>,
- _LinkedHashSetMixin<E>,
_HashBase,
- _IdenticalAndIdentityHashCode
+ _IdenticalAndIdentityHashCode,
+ _LinkedHashSetMixin<E>
implements LinkedHashSet<E> {
- _CompactLinkedIdentityHashSet() : super(_HashBase._INITIAL_INDEX_SIZE);
-
Set<E> toSet() => new _CompactLinkedIdentityHashSet<E>()..addAll(this);
static Set<R> _newEmpty<R>() => new _CompactLinkedIdentityHashSet<R>();
@@ -1053,22 +1082,22 @@
}
class _CompactLinkedCustomHashSet<E> extends _HashFieldBase
- with SetMixin<E>, _LinkedHashSetMixin<E>, _HashBase
+ with
+ SetMixin<E>,
+ _HashBase,
+ _CustomEqualsAndHashCode,
+ _LinkedHashSetMixin<E>
implements LinkedHashSet<E> {
- final _equality;
- final _hasher;
- final _validKey;
-
- int _hashCode(e) => _hasher(e);
- bool _equals(e1, e2) => _equality(e1, e2);
+ final dynamic _equality;
+ final dynamic _hasher;
+ final dynamic _validKey;
bool contains(Object? o) => _validKey(o) ? super.contains(o) : false;
E? lookup(Object? o) => _validKey(o) ? super.lookup(o) : null;
bool remove(Object? o) => _validKey(o) ? super.remove(o) : false;
_CompactLinkedCustomHashSet(this._equality, this._hasher, validKey)
- : _validKey = (validKey != null) ? validKey : new _TypeTest<E>().test,
- super(_HashBase._INITIAL_INDEX_SIZE);
+ : _validKey = (validKey != null) ? validKey : new _TypeTest<E>().test;
Set<R> cast<R>() => Set.castFrom<E, R>(this);
Set<E> toSet() =>
diff --git a/sdk/lib/_internal/wasm/lib/hash_factories.dart b/sdk/lib/_internal/wasm/lib/hash_factories.dart
index 4217e38..8159f09 100644
--- a/sdk/lib/_internal/wasm/lib/hash_factories.dart
+++ b/sdk/lib/_internal/wasm/lib/hash_factories.dart
@@ -49,3 +49,24 @@
@patch
factory LinkedHashSet.identity() => new _CompactLinkedIdentityHashSet<E>();
}
+
+abstract class _HashWasmImmutableBase extends _HashFieldBase
+ implements _HashAbstractImmutableBase {
+ external Uint32List? get _indexNullable;
+}
+
+@pragma("wasm:entry-point")
+class _WasmImmutableLinkedHashMap<K, V> extends _HashWasmImmutableBase
+ with
+ MapMixin<K, V>,
+ _HashBase,
+ _OperatorEqualsAndHashCode,
+ _LinkedHashMapMixin<K, V>,
+ _UnmodifiableMapMixin<K, V>,
+ _ImmutableLinkedHashMapMixin<K, V>
+ implements LinkedHashMap<K, V> {
+ factory _WasmImmutableLinkedHashMap._uninstantiable() {
+ throw new UnsupportedError(
+ "Immutable maps can only be instantiated via constants");
+ }
+}
diff --git a/sdk/lib/_internal/wasm/lib/immutable_map.dart b/sdk/lib/_internal/wasm/lib/immutable_map.dart
deleted file mode 100644
index 74127f4..0000000
--- a/sdk/lib/_internal/wasm/lib/immutable_map.dart
+++ /dev/null
@@ -1,221 +0,0 @@
-// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
-// 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.
-
-// part of "core_patch.dart";
-
-/// Immutable map class for compiler generated map literals.
-// TODO(lrn): Extend MapBase with UnmodifiableMapMixin when mixins
-// support forwarding const constructors.
-@pragma("wasm:entry-point")
-class _ImmutableMap<K, V> implements Map<K, V> {
- final _ImmutableList _kvPairs;
-
- @pragma("wasm:entry-point")
- const _ImmutableMap._create(_ImmutableList keyValuePairs)
- : _kvPairs = keyValuePairs;
-
- Map<K2, V2> cast<K2, V2>() => Map.castFrom<K, V, K2, V2>(this);
-
- V? operator [](Object? key) {
- // To preserve the key-value order of the map literal, the keys are
- // not sorted. Need to do linear search or implement an additional
- // lookup table.
- for (int i = 0; i < _kvPairs.length - 1; i += 2) {
- if (key == _kvPairs[i]) {
- return _kvPairs[i + 1];
- }
- }
- return null;
- }
-
- bool get isEmpty {
- return _kvPairs.length == 0;
- }
-
- bool get isNotEmpty => !isEmpty;
-
- int get length {
- return _kvPairs.length ~/ 2;
- }
-
- void forEach(void f(K key, V value)) {
- for (int i = 0; i < _kvPairs.length; i += 2) {
- f(_kvPairs[i], _kvPairs[i + 1]);
- }
- }
-
- Iterable<K> get keys {
- return new _ImmutableMapKeyIterable<K>(this);
- }
-
- Iterable<V> get values {
- return new _ImmutableMapValueIterable<V>(this);
- }
-
- bool containsKey(Object? key) {
- for (int i = 0; i < _kvPairs.length; i += 2) {
- if (key == _kvPairs[i]) {
- return true;
- }
- }
- return false;
- }
-
- bool containsValue(Object? value) {
- for (int i = 1; i < _kvPairs.length; i += 2) {
- if (value == _kvPairs[i]) {
- return true;
- }
- }
- return false;
- }
-
- void operator []=(K key, V value) {
- throw new UnsupportedError("Cannot set value in unmodifiable Map");
- }
-
- void addAll(Map<K, V> other) {
- throw new UnsupportedError("Cannot set value in unmodifiable Map");
- }
-
- V putIfAbsent(K key, V ifAbsent()) {
- throw new UnsupportedError("Cannot set value in unmodifiable Map");
- }
-
- void clear() {
- throw new UnsupportedError("Cannot clear unmodifiable Map");
- }
-
- V? remove(Object? key) {
- throw new UnsupportedError("Cannot remove from unmodifiable Map");
- }
-
- Iterable<MapEntry<K, V>> get entries =>
- new _ImmutableMapEntryIterable<K, V>(this);
-
- Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> f(K key, V value)) {
- var result = <K2, V2>{};
- for (int i = 0; i < _kvPairs.length; i += 2) {
- var entry = f(_kvPairs[i], _kvPairs[i + 1]);
- result[entry.key] = entry.value;
- }
- return result;
- }
-
- void addEntries(Iterable<MapEntry<K, V>> newEntries) {
- throw new UnsupportedError("Cannot modify an unmodifiable Map");
- }
-
- V update(K key, V update(V value), {V ifAbsent()?}) {
- throw new UnsupportedError("Cannot modify an unmodifiable Map");
- }
-
- void updateAll(V update(K key, V value)) {
- throw new UnsupportedError("Cannot modify an unmodifiable Map");
- }
-
- void removeWhere(bool predicate(K key, V value)) {
- throw new UnsupportedError("Cannot modify an unmodifiable Map");
- }
-
- String toString() => MapBase.mapToString(this);
-}
-
-class _ImmutableMapKeyIterable<E> extends EfficientLengthIterable<E> {
- final _ImmutableMap _map;
- _ImmutableMapKeyIterable(this._map);
-
- Iterator<E> get iterator {
- return new _ImmutableMapKeyIterator<E>(_map);
- }
-
- int get length => _map.length;
-}
-
-class _ImmutableMapValueIterable<E> extends EfficientLengthIterable<E> {
- final _ImmutableMap _map;
- _ImmutableMapValueIterable(this._map);
-
- Iterator<E> get iterator {
- return new _ImmutableMapValueIterator<E>(_map);
- }
-
- int get length => _map.length;
-}
-
-class _ImmutableMapEntryIterable<K, V>
- extends EfficientLengthIterable<MapEntry<K, V>> {
- final _ImmutableMap _map;
- _ImmutableMapEntryIterable(this._map);
-
- Iterator<MapEntry<K, V>> get iterator {
- return new _ImmutableMapEntryIterator<K, V>(_map);
- }
-
- int get length => _map.length;
-}
-
-class _ImmutableMapKeyIterator<E> implements Iterator<E> {
- _ImmutableMap _map;
- int _nextIndex = 0;
- E? _current;
-
- _ImmutableMapKeyIterator(this._map);
-
- bool moveNext() {
- int newIndex = _nextIndex;
- if (newIndex < _map.length) {
- _nextIndex = newIndex + 1;
- _current = _map._kvPairs[newIndex * 2];
- return true;
- }
- _current = null;
- return false;
- }
-
- E get current => _current as E;
-}
-
-class _ImmutableMapValueIterator<E> implements Iterator<E> {
- _ImmutableMap _map;
- int _nextIndex = 0;
- E? _current;
-
- _ImmutableMapValueIterator(this._map);
-
- bool moveNext() {
- int newIndex = _nextIndex;
- if (newIndex < _map.length) {
- _nextIndex = newIndex + 1;
- _current = _map._kvPairs[newIndex * 2 + 1];
- return true;
- }
- _current = null;
- return false;
- }
-
- E get current => _current as E;
-}
-
-class _ImmutableMapEntryIterator<K, V> implements Iterator<MapEntry<K, V>> {
- _ImmutableMap _map;
- int _nextIndex = 0;
- MapEntry<K, V>? _current;
-
- _ImmutableMapEntryIterator(this._map);
-
- bool moveNext() {
- int newIndex = _nextIndex;
- if (newIndex < _map.length) {
- _nextIndex = newIndex + 1;
- _current = new MapEntry<K, V>(
- _map._kvPairs[newIndex * 2], _map._kvPairs[newIndex * 2 + 1]);
- return true;
- }
- _current = null;
- return false;
- }
-
- MapEntry<K, V> get current => _current as MapEntry<K, V>;
-}
diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json
index 619c1c0..b05ae57 100644
--- a/sdk/lib/libraries.json
+++ b/sdk/lib/libraries.json
@@ -197,7 +197,6 @@
"_internal/wasm/lib/function.dart",
"_internal/wasm/lib/growable_list.dart",
"_internal/wasm/lib/identical_patch.dart",
- "_internal/wasm/lib/immutable_map.dart",
"_internal/wasm/lib/int.dart",
"_internal/vm/lib/integers_patch.dart",
"_internal/wasm/lib/list.dart",
diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml
index 055f5e8..d4e109f 100644
--- a/sdk/lib/libraries.yaml
+++ b/sdk/lib/libraries.yaml
@@ -189,7 +189,6 @@
- _internal/wasm/lib/function.dart
- _internal/wasm/lib/growable_list.dart
- _internal/wasm/lib/identical_patch.dart
- - _internal/wasm/lib/immutable_map.dart
- _internal/wasm/lib/int.dart
- _internal/vm/lib/integers_patch.dart
- _internal/wasm/lib/list.dart
diff --git a/tools/VERSION b/tools/VERSION
index f0d0abe..59c79ec 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 17
PATCH 0
-PRERELEASE 213
+PRERELEASE 214
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/utils.py b/tools/utils.py
index cecdbc2..3741a0b 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -154,10 +154,10 @@
os_id = platform.machine()
if os_id.startswith('armv6'):
return 'armv6'
+ elif os_id.startswith('aarch64') or os_id == 'arm64':
+ return 'arm64'
elif os_id.startswith('arm'):
return 'arm'
- elif os_id.startswith('aarch64'):
- return 'arm64'
elif '64' in os_id:
return 'x64'
elif (not os_id) or (not re.match('(x|i[3-6])86', os_id) is None):