Open mkustermann opened 8 months ago
I started looking into this. The metadata code isn't documented so I asked @kustermann. Here's how the new metadata works.
In this Dart:
void forEach1<A>(List<A> list, void Function(A) fun) {
for (final x in list) {
fun(x);
}
}
void forEach2<A>(List<A> list, void Function(A) fun) {
for (final x in list) {
fun(x);
}
}
int f(int i) {
if (int.parse('1') == 1) {
return i;
} else {
throw '';
}
}
void main() {
forEach1(<int>[1, 2, 3], (i) => print(f(i)));
forEach2(<int>[1, 2, 3], f);
}
forEach1
only calls the first closure in main
as fun
, and forEach2
only calls f
.
Ideally we want to compile forEach1
and forEach2
with direct calls to these closures.
(The arguments can then be dropped separately)
The metadata allows this. The kernel metadata is the same as other direct invocation metadata and the key is FunctionInvocation
.
Currently the metadata only returns null
when the target is a closure: https://github.com/dart-lang/sdk/blob/1b5368f3098e2440af7cd9f670fefd5cf6579519/pkg/vm/lib/metadata/direct_call.dart#L37
We can remove the isClosure
guard, but since closures are not members that's not useful.
Instead what the metadata stores for direct function invocations is the member + closure index. When the index is 0 that means the member itself is called. Otherwise it's the index of the function expression (starting from 1) in the member.
In forEach1
above, the metadata _memberReference
is main
, and _closureId
is 1
: the closure being called is the first closure in member main
.
In forEach2
, _memberReference
is f
and _closureId
is 0
: meaning f
itself is called (instead of a function expression in f
.
This is being implemented in https://dart-review.googlesource.com/c/sdk/+/397260.
Dart2wasm already takes advantage of devirtualization information from TFA for instance invocations.
TFA recently gained the ability to devirtualize function invocations. We should take advantage of this in the dart2wasm (just as 8c1f86e5dd1e95c3f64c10057b94d9c679944c9a takes advantage of it in the VM)
/cc @osa1