Skip to content

Commit 8c5f895

Browse files
osa1Commit Queue
authored andcommitted
[dart2wasm, vm] Use list implementation class methods in List factories
In dart2wasm, implementation class methods for `filled` and `generate` are much faster: - In `filled` we use a single `array.fill`. - In `generate` we update the array directly without bounds checks. In VM, this shouldn't make things worse, but it may make things better as the `result[i] = ...` lines will have a more precise receiver types in the implementation class methods. This replaces the explicit loops in `List.filled` and `generate` factories with implementation class `filled` and `generate` methods. Tested: Existing tests. Change-Id: Ib24e5be687df325a43d335657a7142f7d9f980ce Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/321040 Commit-Queue: Ömer Ağacan <[email protected]> Reviewed-by: Martin Kustermann <[email protected]>
1 parent 7a29aa5 commit 8c5f895

File tree

2 files changed

+14
-30
lines changed

2 files changed

+14
-30
lines changed

pkg/vm/testcases/transformations/type_flow/transformer/lists.dart.expect

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class A extends core::Object {
2626
[@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:20] final field core::List<core::int> generateFactory6;
2727
[@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:21] final field core::List<core::int> generateFactory7;
2828
synthetic constructor •() → self::A
29-
: self::A::literal1 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::•<core::int>(0), self::A::literal2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::_literal3<core::int>(1, 2, 3), self::A::filledFactory1 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::filled<core::int>(2, 0), self::A::filledFactory2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::filled<core::int>(), self::A::filledFactory3 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::filled<core::int>(2, 0), self::A::filledFactory4 = let final core::bool #t1 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::filled<core::int>(2, 0, #t1), self::A::filledFactory5 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int?>] core::_List::•<core::int?>(2), self::A::filledFactory6 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int?>] core::_GrowableList::•<core::int?>(2), self::A::filledFactory7 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int?>] core::_List::•<core::int?>(2), self::A::filledFactory8 = let final core::bool #t2 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::filled<core::int?>(2, null, #t2), self::A::filledFactory9 = let final core::int #t3 = 2 in let final core::bool #t4 = true in [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int?>] core::_GrowableList::•<core::int?>(#t3), self::A::filledFactory10 = let final core::int #t5 = 2 in let final core::bool #t6 = false in [@vm.inferred-type.metadata=dart.core::_List<dart.core::int?>] core::_List::•<core::int?>(#t5), self::A::generateFactory1 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::generate<core::int>(2, (core::int i) → core::int => i), self::A::generateFactory2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::generate<core::int>(2, (core::int i) → core::int => i), self::A::generateFactory3 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::generate<core::int>((core::int i) → core::int => i), self::A::generateFactory4 = let final (core::int) → core::int #t7 = (core::int i) → core::int => i in let final core::bool #t8 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::generate<core::int>(#t7, #t8), self::A::generateFactory5 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::List<dart.core::int>>] core::_GrowableList::generate<core::List<core::int>>(2, (core::int _) → core::List<core::int> => core::_GrowableList::•<core::int>(0)), self::A::generateFactory6 = let final core::int #t9 = 2 in let final core::bool #t10 = true in [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::generate<core::int>(#t9, (core::int i) → core::int => i), self::A::generateFactory7 = let final core::int #t11 = 2 in let final core::bool #t12 = false in [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::generate<core::int>((core::int i) → core::int => i), super core::Object::•()
29+
: self::A::literal1 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::•<core::int>(0), self::A::literal2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::_literal3<core::int>(1, 2, 3), self::A::filledFactory1 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::filled<core::int>(2, 0), self::A::filledFactory2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::filled<core::int>(2, 0), self::A::filledFactory3 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::filled<core::int>(2, 0), self::A::filledFactory4 = let final core::bool #t1 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::filled<core::int>(2, 0, #t1), self::A::filledFactory5 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int?>] core::_List::•<core::int?>(2), self::A::filledFactory6 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int?>] core::_GrowableList::•<core::int?>(2), self::A::filledFactory7 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int?>] core::_List::•<core::int?>(2), self::A::filledFactory8 = let final core::bool #t2 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::filled<core::int?>(2, null, #t2), self::A::filledFactory9 = let final core::int #t3 = 2 in let final core::bool #t4 = true in [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int?>] core::_GrowableList::•<core::int?>(#t3), self::A::filledFactory10 = let final core::int #t5 = 2 in let final core::bool #t6 = false in [@vm.inferred-type.metadata=dart.core::_List<dart.core::int?>] core::_List::•<core::int?>(#t5), self::A::generateFactory1 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::generate<core::int>(2, (core::int i) → core::int => i), self::A::generateFactory2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::generate<core::int>(2, (core::int i) → core::int => i), self::A::generateFactory3 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::generate<core::int>((core::int i) → core::int => i), self::A::generateFactory4 = let final (core::int) → core::int #t7 = (core::int i) → core::int => i in let final core::bool #t8 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::generate<core::int>(#t7, #t8), self::A::generateFactory5 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::List<dart.core::int>>] core::_GrowableList::generate<core::List<core::int>>(2, (core::int _) → core::List<core::int> => core::_GrowableList::•<core::int>(0)), self::A::generateFactory6 = let final core::int #t9 = 2 in let final core::bool #t10 = true in [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::generate<core::int>(#t9, (core::int i) → core::int => i), self::A::generateFactory7 = let final core::int #t11 = 2 in let final core::bool #t12 = false in [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::generate<core::int>((core::int i) → core::int => i), super core::Object::•()
3030
;
3131
}
3232
static method nonConstant() → dynamic

sdk/lib/_internal/vm_shared/lib/array_patch.dart

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,10 @@ class List<E> {
1313
}
1414

1515
@patch
16-
factory List.filled(int length, E fill, {bool growable = false}) {
17-
// All error handling on the length parameter is done at the implementation
18-
// of new _List.
19-
var result = growable ? new _GrowableList<E>(length) : new _List<E>(length);
20-
if (fill != null) {
21-
for (int i = 0; i < length; i++) {
22-
result[i] = fill;
23-
}
24-
}
25-
return result;
26-
}
16+
@pragma("vm:prefer-inline")
17+
factory List.filled(int length, E fill, {bool growable = false}) => growable
18+
? _GrowableList<E>.filled(length, fill)
19+
: _List<E>.filled(length, fill);
2720

2821
@patch
2922
factory List.from(Iterable elements, {bool growable = true}) {
@@ -32,8 +25,7 @@ class List<E> {
3225
if (elements is Iterable<E>) {
3326
return List.of(elements, growable: growable);
3427
}
35-
36-
List<E> list = new _GrowableList<E>(0);
28+
List<E> list = _GrowableList<E>(0);
3729
for (E e in elements) {
3830
list.add(e);
3931
}
@@ -42,29 +34,21 @@ class List<E> {
4234
}
4335

4436
@patch
45-
factory List.of(Iterable<E> elements, {bool growable = true}) {
46-
if (growable) {
47-
return _GrowableList.of(elements);
48-
} else {
49-
return _List.of(elements);
50-
}
51-
}
37+
@pragma("vm:prefer-inline")
38+
factory List.of(Iterable<E> elements, {bool growable = true}) =>
39+
growable ? _GrowableList<E>.of(elements) : _List<E>.of(elements);
5240

5341
@patch
5442
@pragma("vm:prefer-inline")
5543
factory List.generate(int length, E generator(int index),
56-
{bool growable = true}) {
57-
final List<E> result =
58-
growable ? new _GrowableList<E>(length) : new _List<E>(length);
59-
for (int i = 0; i < result.length; ++i) {
60-
result[i] = generator(i);
61-
}
62-
return result;
63-
}
44+
{bool growable = true}) =>
45+
growable
46+
? _GrowableList<E>.generate(length, generator)
47+
: _List<E>.generate(length, generator);
6448

6549
@patch
6650
factory List.unmodifiable(Iterable elements) {
67-
final result = new List<E>.from(elements, growable: false);
51+
final result = List<E>.from(elements, growable: false);
6852
return makeFixedListUnmodifiable(result);
6953
}
7054
}

0 commit comments

Comments
 (0)