mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 17:40:04 +00:00
[dart2wasm] Make the index field in _HashFieldBase
nullable
This is to allow `_HashFieldBase` to be used for immutable maps and sets (which initialize their index lazily) without using an intrinsics hack to allow a non-nullable field to be `null`. This change is necessary for the upcoming optimization that will use non-nullable Wasm types for non-nullable Dart fields. Even though this code is shared with the VM, the change doesn't affect VM performance in practice, since the VM compiler is able to infer that the field is always non-null. Benchmark runs see no measurable performance difference. Change-Id: I3ba2f78044f965473a0ab10ddf864c78e7095634 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/321400 Commit-Queue: Aske Simon Christensen <askesc@google.com> Reviewed-by: Jess Lally <jessicalally@google.com>
This commit is contained in:
parent
851e696270
commit
da758538d3
|
@ -85,7 +85,8 @@ class FieldIndex {
|
|||
check(translator.twoByteStringClass, "_array", FieldIndex.stringArray);
|
||||
check(translator.listBaseClass, "_length", FieldIndex.listLength);
|
||||
check(translator.listBaseClass, "_data", FieldIndex.listArray);
|
||||
check(translator.hashFieldBaseClass, "_index", FieldIndex.hashBaseIndex);
|
||||
check(translator.hashFieldBaseClass, "_indexNullable",
|
||||
FieldIndex.hashBaseIndex);
|
||||
check(translator.hashFieldBaseClass, "_data", FieldIndex.hashBaseData);
|
||||
check(translator.closureClass, "context", FieldIndex.closureContext);
|
||||
check(translator.typeClass, "isDeclaredNullable",
|
||||
|
|
|
@ -182,14 +182,6 @@ class Intrinsifier {
|
|||
return w.NumType.i64;
|
||||
}
|
||||
|
||||
// _HashAbstractImmutableBase._indexNullable
|
||||
if (target == translator.hashImmutableIndexNullable) {
|
||||
ClassInfo info = translator.classInfo[translator.hashFieldBaseClass]!;
|
||||
codeGen.wrap(receiver, info.nonNullableType);
|
||||
b.struct_get(info.struct, FieldIndex.hashBaseIndex);
|
||||
return info.struct.fields[FieldIndex.hashBaseIndex].type.unpacked;
|
||||
}
|
||||
|
||||
// _Compound._typedDataBase
|
||||
if (cls == translator.ffiCompoundClass && name == '_typedDataBase') {
|
||||
// A compound (subclass of Struct or Union) is represented by its i32
|
||||
|
|
|
@ -36,11 +36,10 @@ abstract class _HashAbstractBase {
|
|||
}
|
||||
|
||||
abstract class _HashAbstractImmutableBase extends _HashAbstractBase {
|
||||
@pragma("wasm:entry-point")
|
||||
Uint32List? get _indexNullable;
|
||||
}
|
||||
|
||||
abstract class _HashFieldBase implements _HashAbstractBase {
|
||||
abstract class _HashFieldBase implements _HashAbstractImmutableBase {
|
||||
// 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.
|
||||
|
@ -48,7 +47,16 @@ abstract class _HashFieldBase implements _HashAbstractBase {
|
|||
// least one unoccupied entry.
|
||||
// NOTE: When maps are deserialized, their _index and _hashMask is regenerated
|
||||
// eagerly by _regenerateIndex.
|
||||
Uint32List _index = _uninitializedIndex;
|
||||
Uint32List? _indexNullable = _uninitializedIndex;
|
||||
|
||||
@pragma("vm:exact-result-type", "dart:typed_data#_Uint32List")
|
||||
@pragma("vm:prefer-inline")
|
||||
@pragma("wasm:prefer-inline")
|
||||
Uint32List get _index => _indexNullable!;
|
||||
|
||||
@pragma("vm:prefer-inline")
|
||||
@pragma("wasm:prefer-inline")
|
||||
void set _index(Uint32List value) => _indexNullable = value;
|
||||
|
||||
// Cached in-place mask for the hash pattern component.
|
||||
int _hashMask = _HashBase._UNINITIALIZED_HASH_MASK;
|
||||
|
|
|
@ -92,13 +92,8 @@ base class _WasmDefaultSet<E> extends _HashFieldBase
|
|||
Set<E> toSet() => _WasmDefaultSet<E>()..addAll(this);
|
||||
}
|
||||
|
||||
abstract class _HashWasmImmutableBase extends _HashFieldBase
|
||||
implements _HashAbstractImmutableBase {
|
||||
external Uint32List? get _indexNullable;
|
||||
}
|
||||
|
||||
@pragma("wasm:entry-point")
|
||||
base class _WasmImmutableMap<K, V> extends _HashWasmImmutableBase
|
||||
base class _WasmImmutableMap<K, V> extends _HashFieldBase
|
||||
with
|
||||
MapMixin<K, V>,
|
||||
_HashBase,
|
||||
|
@ -107,14 +102,16 @@ base class _WasmImmutableMap<K, V> extends _HashWasmImmutableBase
|
|||
_UnmodifiableMapMixin<K, V>,
|
||||
_ImmutableLinkedHashMapMixin<K, V>
|
||||
implements LinkedHashMap<K, V> {
|
||||
factory _WasmImmutableMap._uninstantiable() {
|
||||
throw UnsupportedError(
|
||||
"Immutable maps can only be instantiated via constants");
|
||||
// Dummy constructor to prevent the TFA from concluding that `_indexNullable`
|
||||
// is never `null`.
|
||||
@pragma("wasm:entry-point")
|
||||
_WasmImmutableMap._() {
|
||||
_indexNullable = null;
|
||||
}
|
||||
}
|
||||
|
||||
@pragma("wasm:entry-point")
|
||||
base class _WasmImmutableSet<E> extends _HashWasmImmutableBase
|
||||
base class _WasmImmutableSet<E> extends _HashFieldBase
|
||||
with
|
||||
SetMixin<E>,
|
||||
_HashBase,
|
||||
|
@ -123,9 +120,11 @@ base class _WasmImmutableSet<E> extends _HashWasmImmutableBase
|
|||
_UnmodifiableSetMixin<E>,
|
||||
_ImmutableLinkedHashSetMixin<E>
|
||||
implements LinkedHashSet<E> {
|
||||
factory _WasmImmutableSet._uninstantiable() {
|
||||
throw UnsupportedError(
|
||||
"Immutable sets can only be instantiated via constants");
|
||||
// Dummy constructor to prevent the TFA from concluding that `_indexNullable`
|
||||
// is never `null`.
|
||||
@pragma("wasm:entry-point")
|
||||
_WasmImmutableSet._() {
|
||||
_indexNullable = null;
|
||||
}
|
||||
|
||||
Set<R> cast<R>() => Set.castFrom<E, R>(this, newSet: _newEmpty);
|
||||
|
|
Loading…
Reference in a new issue