-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Avoid type checks in async completion implementation #48226
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Since we'll have a hard time telling the VM to omit the parameter type check for => Will try cl/230261 |
It's generally not sufficient to check The counter example in one direction is a In the other direction, a We really need to check against As for adding an |
Would love to see that land!
I have thought of a workaround to make it efficient for the majority of cases: Namely rely on the static types: Recognize that all returns in a function return types that cannot possibly be a Future. For such functions we can then generate code that avoids the |
…er knows its safe Currently we have to do a runtime `as FutureOr<T>` check for the parameter to `_Future<T>.asyncComplete(FutureOr<T> value)`. Although needed for general cases, for the particular usage in the VM's async/await transformer, we know that the test is going to suceed. This CL adds two VM-specific methods on `_Future` that take `dynamic` and downcast via `unsafeCast<>()` to avoid this rather large runtime type checking overhead. Issue #48226 TEST=ci Change-Id: Ieeffae3ac8e2960f849512cf22c51d41cadb1ecf Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/230261 Reviewed-by: Slava Egorov <[email protected]> Reviewed-by: Lasse Nielsen <[email protected]> Commit-Queue: Martin Kustermann <[email protected]>
…hen caller knows its safe" This reverts commit 8e0feb9. Reason for revert: breaks tests in Google3, see b/217919095 Original change's description: > [vm] Avoid type parameter check of _Future._asyncComplete() when caller knows its safe > > Currently we have to do a runtime `as FutureOr<T>` check for the > parameter to `_Future<T>.asyncComplete(FutureOr<T> value)`. Although > needed for general cases, for the particular usage in the VM's > async/await transformer, we know that the test is going to suceed. > > This CL adds two VM-specific methods on `_Future` that take `dynamic` > and downcast via `unsafeCast<>()` to avoid this rather large runtime > type checking overhead. > > Issue #48226 > > TEST=ci > > Change-Id: Ieeffae3ac8e2960f849512cf22c51d41cadb1ecf > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/230261 > Reviewed-by: Slava Egorov <[email protected]> > Reviewed-by: Lasse Nielsen <[email protected]> > Commit-Queue: Martin Kustermann <[email protected]> [email protected],[email protected],[email protected] Change-Id: I37a07cbb6fb37620e5305dfe1b759b0de1c37653 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/231703 Reviewed-by: Ilya Yanok <[email protected]> Commit-Queue: Ilya Yanok <[email protected]>
…hen caller knows its safe" Currently we have to do a runtime `as FutureOr<T>` check for the parameter to `_Future<T>.asyncComplete(FutureOr<T> value)`. Although needed for general cases, for the particular usage in the VM's async/await transformer, we know that the test is going to suceed. This CL adds two VM-specific methods on `_Future` that take `dynamic` and downcast via `unsafeCast<>()` to avoid this rather large runtime type checking overhead. Issue #48226 Change after revert: Replace the assert(value is T || value is Future<T>); with assert((value as FutureOr<T>) == value); The former doesn't allow `null` while the ladder might (depending on nullability of `T`). TEST=ci Change-Id: I2379c625003fea6aa836ac74beb1cd59201b3560 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/231704 Reviewed-by: Alexander Markov <[email protected]> Commit-Queue: Martin Kustermann <[email protected]>
… returned values In general any async function can return X or Future<X>. Though the future implementation has to do different things depending on which case we're in. It does so by using a `<obj> is Future<T>` test. This test is very expensive if many different classes flow into `<obj>`. Though most functions do not return `Future` objects from async functions. We can determine that statically by looking if any returned expression could be a future. If not, we can bypass the `is Future<T>` test entirely. Issue #48226 Issue #48235 TEST=pkg/front_end/testcases/general/async_function_returns_future_or.dart Change-Id: If655bdbdddc214dd7b12be9905b3c788252547d0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/230662 Reviewed-by: Alexander Markov <[email protected]> Reviewed-by: Lasse Nielsen <[email protected]> Commit-Queue: Martin Kustermann <[email protected]>
For an async method like this:
we generate currently this kernel:
The value of the return is fully typed all along:
_Future<String>
FutureOr<String>
Though we loose the correct type when we call
_completeOnAsyncReturn
, which looks like this:Notice, the parameter is typed
_Future
.The future implementation then looks like this:
This function performs
_Future<X>
to_Future<Object>
...)=> Though actually we know the call site, it was generated by kernel transformer, we know that the check will succeed.
=> This is probably an unnecessary check.
is Future<T>
=> We already know
value is FutureOr<T>
.=> Would it be sufficient to just check
is Future
(instead ofis Future<T>
) - makes the check faster/simpler?_asyncCompleteWithValue(value as dynamic)
will cause an implicitvalue as T
check.=> We already know that it is
T
and should not perform any checking here./cc @lrhn
(/cc @sstrickl The
FutureOr<T>
covariant parameter check falls through to STC which overflows)The text was updated successfully, but these errors were encountered: