Thanks to visit codestin.com
Credit goes to github.com

Skip to content

PluginUtilities.getCallbackHandle and tree-shaking #118608

Open
@mraleph

Description

@mraleph

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:

Ultimately 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 using PluginUtilities.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

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Issues that are less important to the Flutter projectc: proposalA detailed proposal for a change to Fluttercustomer: swissengineflutter/engine repository. See also e: labels.team-engineOwned by Engine teamtriaged-engineTriaged by Engine team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions