-
Notifications
You must be signed in to change notification settings - Fork 28.7k
PluginUtilities.getCallbackHandle and tree-shaking #118608
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
See also dart-lang/sdk#50649 |
Added in flutter/engine#5539. |
Would it be possible to somehow implicitly mark methods that get passed to |
Furthermore, I am wondering whether |
It appears that flutter is in fact passing this flag when running in debug mode (I verified this happens for a
Yet, this flag is not catching the issue of the missing |
@goderbauer I think the problem is that engine has a cache so it does not always go through the code path that verifies the entry point (see We can also add a method, something like
It's only trivial to do that if the value is constant at It is theoretically possible to beef up TFA to figure this out - but I think this is too complicated. Actually looking at the code as it is written now even dart-lang/language#2776 not gonna help all that much here because the value flows through an object field. I think we could maybe add an annotation on a parameter (tentative name): static CallbackHandle? getCallbackHandle(@pragma('vm:expects-entry-point') Function callback);
static String restorablePushAndRemoveUntil<T extends Object?>(
BuildContext context,
@pragma('vm:expects-entry-point') RestorableRouteBuilder<T> newRouteBuilder,
RoutePredicate predicate, {Object? arguments}) and then add logic in TFA that applies We can also add a lint that checks that you mark things transitively with Maybe as part of this work we can also promote the logic for computing callback handles to VM. |
@mkustermann points out that magically applying entry-points to functions is that it hides the dependency on the function name stability from the user. @goderbauer what is expected to happen if you release an update to your app where you rename some route builder callback? Is restoration still supposed to work correctly? |
This sounds like a good idea and would keep the route restoration API tidy and user friendly.
Currently, restoration data is blown away when an update is installed, that's default platform behavior. So, after an update no state restoration is going to take place. Therefore, from the perspective of the route restoration API it's totally OK to rename the route builder callback since it will not be invoked after an update anyways. |
Changes the default value of the --verify-entry-points flag to true. Changes the default value for the check_is_entrypoint argument to to the Invoke/InvokeGetter/InvokeSetter flags to true. The mirrors library implementation and calls via vm-service explicitly pass false for this argument now. Add annotations as needed, such as annotating classes with annotated generative constructors. In some cases, the annotations were more general than needed (e.g., annotating with a no-argument entry point annotation when only the setter is needed), so make those annotations more specific. As this pattern is already common in downstream code, allow Dart_Invoke on fields as long as the field is annotated for getter access. (That is, calling Dart_Invoke for a field is equivalent to retrieving the closure value via Dart_GetField and then calling Dart_InvokeClosure.) TEST=vm/cc/DartAPI_MissingEntryPoints vm/dart/entrypoints_verification_test Issue: #50649 Issue: flutter/flutter#118608 Change-Id: Ibb3bf15632ab2958d8791b449af8651d47f871a5 Cq-Include-Trybots: luci.dart.try:vm-aot-linux-product-x64-try,vm-aot-linux-debug-x64-try,vm-aot-mac-release-arm64-try,vm-aot-mac-product-arm64-try,vm-aot-dwarf-linux-product-x64-try CoreLibraryReviewExempt: adding/editing vm-only pragma annotations Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/363566 Reviewed-by: Martin Kustermann <[email protected]> Commit-Queue: Tess Strickland <[email protected]>
This reverts commit cb9ecbc. Reason for revert: causes failures during Dart->Flutter roll and on Flutter HHH bots (see comments on the original CL). Original change's description: > [vm] Enforce that entry points must be annotated by default. > > Changes the default value of the --verify-entry-points flag > to true. > > Changes the default value for the check_is_entrypoint argument to > to the Invoke/InvokeGetter/InvokeSetter flags to true. The mirrors > library implementation and calls via vm-service explicitly pass > false for this argument now. > > Add annotations as needed, such as annotating classes with > annotated generative constructors. In some cases, the annotations > were more general than needed (e.g., annotating with a no-argument > entry point annotation when only the setter is needed), so make > those annotations more specific. > > As this pattern is already common in downstream code, allow > Dart_Invoke on fields as long as the field is annotated for getter > access. (That is, calling Dart_Invoke for a field is equivalent to > retrieving the closure value via Dart_GetField and then calling > Dart_InvokeClosure.) > > TEST=vm/cc/DartAPI_MissingEntryPoints > vm/dart/entrypoints_verification_test > > Issue: #50649 > Issue: flutter/flutter#118608 > > Change-Id: Ibb3bf15632ab2958d8791b449af8651d47f871a5 > Cq-Include-Trybots: luci.dart.try:vm-aot-linux-product-x64-try,vm-aot-linux-debug-x64-try,vm-aot-mac-release-arm64-try,vm-aot-mac-product-arm64-try,vm-aot-dwarf-linux-product-x64-try > CoreLibraryReviewExempt: adding/editing vm-only pragma annotations > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/363566 > Reviewed-by: Martin Kustermann <[email protected]> > Commit-Queue: Tess Strickland <[email protected]> Issue: #50649 Issue: flutter/flutter#118608 Change-Id: Idba168f77b0636a50ad93309e29dc9989cc1f388 Cq-Include-Trybots: luci.dart.try:vm-aot-linux-product-x64-try,vm-aot-linux-debug-x64-try,vm-aot-mac-release-arm64-try,vm-aot-mac-product-arm64-try,vm-aot-dwarf-linux-product-x64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/391460 Auto-Submit: Alexander Markov <[email protected]> Reviewed-by: Tess Strickland <[email protected]> Commit-Queue: Tess Strickland <[email protected]> Bot-Commit: Rubber Stamper <[email protected]>
This is a reland of commit cb9ecbc This reland only turns on the entry point verification flag by default in AOT mode. After Flutter tests that use native access in JIT mode have been appropriately updated, a followup CL will turn this flag on by default in JIT mode as well. Original change's description: > [vm] Enforce that entry points must be annotated by default. > > Changes the default value of the --verify-entry-points flag > to true. > > Changes the default value for the check_is_entrypoint argument to > to the Invoke/InvokeGetter/InvokeSetter flags to true. The mirrors > library implementation and calls via vm-service explicitly pass > false for this argument now. > > Add annotations as needed, such as annotating classes with > annotated generative constructors. In some cases, the annotations > were more general than needed (e.g., annotating with a no-argument > entry point annotation when only the setter is needed), so make > those annotations more specific. > > As this pattern is already common in downstream code, allow > Dart_Invoke on fields as long as the field is annotated for getter > access. (That is, calling Dart_Invoke for a field is equivalent to > retrieving the closure value via Dart_GetField and then calling > Dart_InvokeClosure.) > > TEST=vm/cc/DartAPI_MissingEntryPoints > vm/dart/entrypoints_verification_test > > Issue: #50649 > Issue: flutter/flutter#118608 > > Change-Id: Ibb3bf15632ab2958d8791b449af8651d47f871a5 > Cq-Include-Trybots: luci.dart.try:vm-aot-linux-product-x64-try,vm-aot-linux-debug-x64-try,vm-aot-mac-release-arm64-try,vm-aot-mac-product-arm64-try,vm-aot-dwarf-linux-product-x64-try > CoreLibraryReviewExempt: adding/editing vm-only pragma annotations > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/363566 > Reviewed-by: Martin Kustermann <[email protected]> > Commit-Queue: Tess Strickland <[email protected]> TEST=vm/cc/DartAPI_MissingEntryPoints vm/dart/entrypoints_verification_test Change-Id: I24919c32ab4760c7c5435c378879791086256f02 Cq-Include-Trybots: luci.dart.try:vm-aot-linux-product-x64-try,vm-aot-linux-debug-x64-try,vm-aot-mac-release-arm64-try,vm-aot-mac-product-arm64-try,vm-aot-dwarf-linux-product-x64-try,flutter-linux-try,vm-linux-debug-x64-try,vm-linux-release-x64-try,vm-appjit-linux-product-x64-try CoreLibraryReviewExempt: adding/editing vm-only pragma annotations Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/391620 Reviewed-by: Martin Kustermann <[email protected]> Commit-Queue: Tess Strickland <[email protected]>
This change adds entry-point annotations to methods and classes accessed by native code during Flutter tests. Currently, entry point annotations are not checked by the Dart VM when running in JIT mode, only in AOT mode. In order to also enforce entry point annotations in JIT mode, first tests in Flutter must be appropriately annotated to avoid roll failures. Related issues: * #118608 * dart-lang/sdk#50649 ## Pre-launch Checklist - [X] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [X] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [X] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [X] I signed the [CLA]. - [X] I listed at least one issue that this PR fixes in the description above. - [X] I updated/added relevant documentation (doc comments with `///`). - [X] I added new tests to check the change I am making, or this PR is [test-exempt]. - [X] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [X] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This change adds entry-point annotations to methods and classes accessed by native code during engine tests. Currently, entry point annotations are not checked by the Dart VM when running in JIT mode, only in AOT mode. In order to also enforce entry point annotations in JIT mode, first tests in Flutter must be appropriately annotated to avoid roll failures. Related issues: * flutter/flutter#118608 * dart-lang/sdk#50649
This change adds entry-point annotations to methods and classes accessed by native code during Flutter tests. Currently, entry point annotations are not checked by the Dart VM when running in JIT mode, only in AOT mode. In order to also enforce entry point annotations in JIT mode, first tests in Flutter must be appropriately annotated to avoid roll failures. Related issues: * #118608 * dart-lang/sdk#50649 ## Pre-launch Checklist - [X] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [X] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [X] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [X] I signed the [CLA]. - [X] I listed at least one issue that this PR fixes in the description above. - [X] I updated/added relevant documentation (doc comments with `///`). - [X] I added new tests to check the change I am making, or this PR is [test-exempt]. - [X] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [X] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
Now that Flutter tests that access entry points from native code have been annotated[1], we can turn on entry point checking in JIT mode. This CL also removes the A flag category from flag_list.h and the AOT_FLAG_MACRO definitions and uses from flags.[cc,h], as they were created as a temporary measure until this flag could be unconditionally defaulted to true. [1] See the following PRs: * flutter/engine#57158 * flutter/flutter#160158 * flutter/flutter#160421 TEST=vm/dart/entrypoints_verification_test vm/cc/IRTest vm/cc/StreamingFlowGraphBuilder vm/cc/STC vm/cc/TTS Issue: #50649 Issue: flutter/flutter#118608 Cq-Include-Trybots: luci.dart.try:vm-aot-linux-product-x64-try,vm-aot-linux-debug-x64-try,vm-aot-mac-release-arm64-try,vm-aot-mac-product-arm64-try,vm-aot-dwarf-linux-product-x64-try,vm-linux-debug-x64-try,vm-linux-release-x64-try,vm-appjit-linux-product-x64-try Change-Id: Ibe5b21bb74f1a6fb88824b71ff87b9e555216dbf Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/400301 Reviewed-by: Martin Kustermann <[email protected]> Commit-Queue: Tess Strickland <[email protected]>
This change adds entry-point annotations to methods and classes accessed by native code during engine tests. Currently, entry point annotations are not checked by the Dart VM when running in JIT mode, only in AOT mode. In order to also enforce entry point annotations in JIT mode, first tests in Flutter must be appropriately annotated to avoid roll failures. Related issues: * flutter#118608 * dart-lang/sdk#50649
This reverts commit 982b9fa. Reason for revert: b/385114574 Original change's description: > [vm] Turn on entry point checking in JIT mode. > > Now that Flutter tests that access entry points from native code > have been annotated[1], we can turn on entry point checking in JIT > mode. > > This CL also removes the A flag category from flag_list.h and the > AOT_FLAG_MACRO definitions and uses from flags.[cc,h], as they were > created as a temporary measure until this flag could be unconditionally > defaulted to true. > > [1] See the following PRs: > * flutter/engine#57158 > * flutter/flutter#160158 > * flutter/flutter#160421 > > TEST=vm/dart/entrypoints_verification_test vm/cc/IRTest > vm/cc/StreamingFlowGraphBuilder vm/cc/STC vm/cc/TTS > > Issue: #50649 > Issue: flutter/flutter#118608 > > Cq-Include-Trybots: luci.dart.try:vm-aot-linux-product-x64-try,vm-aot-linux-debug-x64-try,vm-aot-mac-release-arm64-try,vm-aot-mac-product-arm64-try,vm-aot-dwarf-linux-product-x64-try,vm-linux-debug-x64-try,vm-linux-release-x64-try,vm-appjit-linux-product-x64-try > Change-Id: Ibe5b21bb74f1a6fb88824b71ff87b9e555216dbf > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/400301 > Reviewed-by: Martin Kustermann <[email protected]> > Commit-Queue: Tess Strickland <[email protected]> Issue: #50649 Issue: flutter/flutter#118608 Change-Id: Id403cd0832807e417202e17dac57c2224cab09e7 Cq-Include-Trybots: luci.dart.try:vm-aot-linux-product-x64-try,vm-aot-linux-debug-x64-try,vm-aot-mac-release-arm64-try,vm-aot-mac-product-arm64-try,vm-aot-dwarf-linux-product-x64-try,vm-linux-debug-x64-try,vm-linux-release-x64-try,vm-appjit-linux-product-x64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/401880 Bot-Commit: Rubber Stamper <[email protected]> Reviewed-by: Martin Kustermann <[email protected]> Commit-Queue: Ivan Inozemtsev <[email protected]>
This is a reland of commit 982b9fa Original change's description: > [vm] Turn on entry point checking in JIT mode. > > Now that Flutter tests that access entry points from native code > have been annotated[1], we can turn on entry point checking in JIT > mode. > > This CL also removes the A flag category from flag_list.h and the > AOT_FLAG_MACRO definitions and uses from flags.[cc,h], as they were > created as a temporary measure until this flag could be unconditionally > defaulted to true. > > [1] See the following PRs: > * flutter/engine#57158 > * flutter/flutter#160158 > * flutter/flutter#160421 > > TEST=vm/dart/entrypoints_verification_test vm/cc/IRTest > vm/cc/StreamingFlowGraphBuilder vm/cc/STC vm/cc/TTS > > Issue: #50649 > Issue: flutter/flutter#118608 > > Cq-Include-Trybots: luci.dart.try:vm-aot-linux-product-x64-try,vm-aot-linux-debug-x64-try,vm-aot-mac-release-arm64-try,vm-aot-mac-product-arm64-try,vm-aot-dwarf-linux-product-x64-try,vm-linux-debug-x64-try,vm-linux-release-x64-try,vm-appjit-linux-product-x64-try > Change-Id: Ibe5b21bb74f1a6fb88824b71ff87b9e555216dbf > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/400301 > Reviewed-by: Martin Kustermann <[email protected]> > Commit-Queue: Tess Strickland <[email protected]> TEST=vm/dart/entrypoints_verification_test vm/cc/IRTest vm/cc/StreamingFlowGraphBuilder vm/cc/STC vm/cc/TTS Change-Id: Ibd5f362f908b4aaa68cda870a387c081537bbc16 Cq-Include-Trybots: luci.dart.try:vm-aot-linux-product-x64-try,vm-aot-linux-debug-x64-try,vm-aot-mac-release-arm64-try,vm-aot-mac-product-arm64-try,vm-aot-dwarf-linux-product-x64-try,vm-linux-debug-x64-try,vm-linux-release-x64-try,vm-appjit-linux-product-x64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/403360 Auto-Submit: Ivan Inozemtsev <[email protected]> Commit-Queue: Ivan Inozemtsev <[email protected]> Reviewed-by: Martin Kustermann <[email protected]>
Current implementation (and documenation) of
PluginUtilities.getCallbackHandle
does not respect the concept of tree-shaking and consequently causes problems in release builds whenever it is used, especially when it is used as an implementation detail.PluginUtilities.getCallbackHandle
expects that any static function in a Dart application can be uniquely identified by a tuple(libraryUri, className, functionName)
, meaning that it expects to be able to convert any static function tear-off into such tuple and then expects to be able to look up the same tear-off by doing reflective access through Dart VM C API.While this does work reliably in debug (JIT) mode, this is not guaranteed to work in release (AOT) mode. Release mode requires that any reflectively accessed program element (library, method, class, function) is annotated with
@pragma('vm:entry-point')
. Program elements not annotated as entry points might be shaken from the resulting binary or at least will be evicted from lookup dictionaries, making reflective access to them impossible.This introduces discrepancy between release/profile and debug modes, which leads to obscure crashes like this one:
Dart Error: Class not found in library ''.
#118565Ultimately this means at the very least we need to ensure that any function passed to
PluginUtilities.getCallbackHandle
is annotated with@pragma('vm:entry-point')
. We need to update documentation to make this requirement absolutely clear. Note that this needs to be applied transitively: e.g. if state restoration code is usingPluginUtilities.getCallbackHandle
under the hood we need to document that some specific function needs to be annotated.Dart VM has a flag which enforces the presence of
entry-point
annotations on any reflectively accessed element (--verify_entry_points
). This flag was not turned on by default because it was breaking Flutter applications - I think we need to turn it on because the applications which hit those asserts are broken anyway (/cc @mkustermann)Long term Flutter needs to redesign the implementation of
PluginUtilities.getCallbackHandle
to avoid this problem. One possible direction is described in #94571 by @ds84182.A potential Dart language level solution requires some way to enforce const-ness of the parameter value. I have submitted language level proposal here: dart-lang/language#2776
/cc @goderbauer @mkustermann @chinmaygarde @zanderso
The text was updated successfully, but these errors were encountered: