Skip to content

SubtypeTestCache overflows due to is checks with many different receivers #48235

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

Open
mkustermann opened this issue Jan 27, 2022 · 2 comments
Open
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. type-performance Issue relates to performance or code size

Comments

@mkustermann
Copy link
Member

mkustermann commented Jan 27, 2022

We have code like this in the core libraries _Future implementation (from future_impl.dart)

  void _asyncComplete(FutureOr<T> value) {
    if (value is Future<T>) {
      _chainFuture(value);
      return;
    }
    _asyncCompleteWithValue(value as dynamic);
  }

This code will be called with return values of async functions. At runtime the value can therefore be of many different types. This causes an issue with this is Future<T> check.

The is check is performed via SubtypeTestCache which have a maximum length of 100 and will fallback to runtime after that. Since value will obtain many different class ids, the SubtypeTestCache easily fills up and causes very slow performance.

Due to the fact that this will happen on pretty much any program which uses lots of async code, it's quite a severe issue.

See also b/182183059

@mkustermann mkustermann added area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. type-performance Issue relates to performance or code size labels Jan 27, 2022
@rakudrama
Copy link
Member

This kind of test is also expensive for dart2js. We don't yet have a subtype cache in dart2js but I have considered one. A dart2js cache would use some kind of identity map rather than a linear scan, so the concerns are about total size, and the initial probe cost.

Is the SubtypeTestCache ever cleared?

@mkustermann
Copy link
Member Author

Is the SubtypeTestCache ever cleared?

The cache itself not. But every time we recompile a function (in either unoptimized or optimized mode) it will obtain a new cache.

copybara-service bot pushed a commit that referenced this issue Feb 4, 2022
… 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]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. type-performance Issue relates to performance or code size
Projects
None yet
Development

No branches or pull requests

2 participants