Skip to content

Kotlin pointer-only FFI experiment #2752

@bendk

Description

@bendk

We've been discussing an "FFI v2" for a few months now with an eye towards better performance on non-C languages, like Kotlin, Python, and external JS bindings. Performance was the main goal, but we also speculated that it might improve stability on Kotlin by side-stepping some JNA issues (either in JNA itself or how we're using JNA).

However, we've recently started noticing a lot of Android crashes, especially when using the newer async code. There's also #2740. Before we implement the FFI v2, we should probably try to address the stability issues first. That way we can design the FFI v2 around the same principles and have good confidence that it will also improve stability. We should putting in a lot of work to implement a new FFI that's shiny and fast, but still has stability issues on Kotlin

As a starting point, I'd like to experiment with a pointer-only FFI. Pointers seem like one of the safer types to pass with JNA since they're always exactly 1 machine word. We can use them as a buffer to pack in other value types. Here's what I'm thinking:

  • Rename the scaffolding-ffi-buffer-fns feature ffi-pointer and use that for the user function scaffolding on Kotlin. scaffolding-ffi-buffer-fns was an experiment at a new FFI that was never adopted, but it seems great for this purpose. I think ffi-pointer is a nicer name it has the same form as ffi-v2, which is the feature flag I'm hoping to use for the later one.
  • Implement other functions, like rust_buffer_alloc using the pointer FFI.
  • Prefix all the new FFI functions with uniffi_pointer_.

We probably shouldn't merge or release this code since the goal is experimentation. Instead we can create a branch off of 0.27.3, update the Firefox Android/application-services code to use that branch, then monitor our crash reports. We can also re-introduce our async viaduct code, which we had to back out last time because of crashes, and see if it's better with this new system. If this doesn't address crashes, then I guess we're back to the drawing board. Hopefully we learn something at least.

If other teams also want to test out this code, that's great. I'm not sure how hard it would be to rebase the changes on top of a different version, but it should be doable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions