Skip to content

Dart: cache function pointers - #1830

Merged
pwrobeldev merged 8 commits into
masterfrom
pwrobeldev/dart-cache-function-pointer
Oct 20, 2026
Merged

pwrobeldev merged 8 commits into
masterfrom
pwrobeldev/dart-cache-function-pointer

Conversation

@pwrobeldev

Copy link
Copy Markdown
Contributor

---------- Motivation ----------
In the case of the generated Dart code each function call looked up
for the native function pointer to execute C++ code. The same applied
to property getters and setters.

Instead of caching the obtained pointer to avoid excessive lookups,
the code executed it for each invocation of any function.

Internally, the 'DynamicLibrary.lookupFunction()' executes 'dlsym()' or
similar OS level function that must lock the global linker mutex.

Because Flutter 3.29 or newer executes the Dart code in the main platform
thread, the frequent execution of 'dlsym()' and locking of global mutex
may encounter contention when other threads load dynamic library or look
for symbols.

Frequent lookups cause the following:

  • performance penalty is there, because we always need to lookup the symbol
    and lock global mutex
  • the locking of mutex can lead to ANRs of the main thread in Flutter 3.29+

---------- Solution ----------
This commit implements caching of the function pointers via usage of private
global variables.

The private variables are initialized lazily in Dart. It means that symbol
is loaded on the first call to the function.

This reduces the possibility of ANRs.

---------- Motivation ----------
In the case of the generated Dart code each function call looked up
for the native function pointer to execute C++ code. The same applied
to property getters and setters.

Instead of caching the obtained pointer to avoid excessive lookups,
the code executed it for each invocation of any function.

Internally, the 'DynamicLibrary.lookupFunction()' executes 'dlsym()' or
similar OS level function that must lock the global linker mutex.

Because Flutter 3.29 or newer executes the Dart code in the main platform
thread, the frequent execution of 'dlsym()' and locking of global mutex
may encounter contention when other threads load dynamic library or look
for symbols.

Frequent lookups cause the following:
 - performance penalty is there, because we always need to lookup the symbol
   and lock global mutex
 - the locking of mutex can lead to ANRs of the main thread in Flutter 3.29+

---------- Solution ----------
This commit implements caching of the function pointers via usage of private
global variables.

The private variables are initialized lazily in Dart. It means that symbol
is loaded on the first call to the function.

This reduces the possibility of ANRs.

Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
The caching of function pointers is visible.

Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
To ensure that declared private variable is used
do not lookup symbol in getter of cached property.

Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
The partials were not used. This is dead code.
It is removed by this commit.

Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
@pwrobeldev
pwrobeldev requested a review from Hsilgos October 14, 2026 15:23
Hsilgos
Hsilgos previously approved these changes Oct 15, 2026
When we have two nested interfaces, which extend the same parent
then Gluecodium generates duplicated name. This triggers compilation
error.

In the next commit the fix will be delivered.

Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
In the previous commit the names collision for nested interfaces
that inherit from the same parent interface was showed.

This commit resolves the problem by injecting the type name that
owns the function (in case when native symbol is identical).

Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
Show that owning type name is included in the name of
cached variable with function.

Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
@pwrobeldev
pwrobeldev merged commit 9613e6f into master Oct 20, 2026
21 checks passed
@pwrobeldev
pwrobeldev deleted the pwrobeldev/dart-cache-function-pointer branch October 20, 2026 07:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants