what do @pragma("vm:prefer-inline") mean in Flutter?

Viewed 3054

When I studied framework code, I found that there was a lot of code in the following form:

@pragma("vm:entry-point", "call") @pragma("vm:entry-point", "set") @pragma("vm:entry-point", "get") @pragma("vm:prefer-inline") ......

What do these mean?

2 Answers

For the general meaning of @pragma cfr above the NKSM's answer.

I will cite two important specific use case:

  • @pragma('vm:prefer-inline') to inline functions

    (I mean compile-time inlining, which has nothing to do with 'inline function' intended as a synonym for closure/lambda, as is sometimes done)

    This annotation is similar to inline keyword in Kotlin

  • @pragma("vm:entry-point") to mark a function (or other entities, as classes) to indicate to the compiler that it will be used from native code. Without this annotation, the dart compiler could strip out unused functions, inline them, shrink names, etc, and the native code would fail to call it.

    A very good doc (written much more clearly than usual) about entry-point is https://github.com/dart-lang/sdk/blob/master/runtime/docs/compiler/aot/entry_point_pragma.md

If you want to do a first test with inlining in dart, I suggest you compile with dart2js, which outputs fairly readable javascript code (at least until you increase the shrinking level beyond the default one; and readability is obviously decent only in minimal programs). However, inlining in dart/js requires a slightly different @pragma annotation: @pragma ('dart2js: tryInline').

An interesting discussion about inlining in dart can be found in dart-lang issue #40522 - Annotation for method inlining

In general, I suggest Mraleph blog. His latest article is on benchmarking in dart, and also shows the use of @pragma(vm:entry-point). Mraleph is a Dart Sdk developer (he is also an author of the official doc cited above), and it is a very precious source about Dart VM related topics.

Flutter uses the Dart programming language.

Pragma class is a hint to tools.

Tools that work with Dart programs may accept hints to guide their behavior as pragma annotations on declarations. Each tool decides which hints it accepts, what they mean, and whether and how they apply to sub-parts of the annotated entity.

Tools that recognize pragma hints should pick a pragma prefix to identify the tool. They should recognize any hint with a name starting with their prefix followed by : as if it was intended for that tool. A hint with a prefix for another tool should be ignored (unless compatibility with that other tool is a goal).

A tool may recognize unprefixed names as well, if they would recognize that name with their own prefix in front.

If the hint can be parameterized, an extra options object can be added as well.

For example:

@pragma('Tool:pragma-name', [param1, param2, ...])
class Foo { }

@pragma('OtherTool:other-pragma')
void foo() { }

Here class Foo is annotated with a Tool specific pragma 'pragma-name' and function foo is annotated with a pragma 'other-pragma' specific to OtherTool.

The above can be found on dart.dev documentation.

The @pragma('vm:entry-point') annotation here. Its core logic is Tree-Shaking. In AOT (Ahead of Time) compilation, if it cannot be called by the Main entry of the application, it will be discarded as useless code. The injection logic of the AOP code is non-invasive, so obviously it will not be called by the Main entry. Therefore, this annotation is required to tell the compiler not to discard this logic.

Related