Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implemented slab storage that allocates handles (mozilla#1730)
This will be used for passing handles across the FFI. This have several advantages as an FFI type: * Generation counter to detect use-after-free bugs * Slab ID to detect using a handle with the wrong type. * The same data structures can be used on the foreign side, rather than us having to figure out how to leak references in all languages. * Integers come with less gotchas. For example, we use a bit to differentiate between foreign and Rust handles. This would be possible with tagged pointers but there's a lot of details to worry about there. See the `tagged_pointer` crate some. * Our current code mixes actual pointers and usize integers. For example, the callback continuation is a leaked pointer on Swift, but a usize map key on Kotlin. * Constant width at 64 bits rather than using the platform word size. This will simplify some things, especially reading/writing them to `RustBuffer` * Only the first 48 bits are significant which helps with languages like JS. Performance should be pretty good. Insert/get/remove are all lock-free thanks to the `append_only_vec` crate and some atomic code: * For objects, this represents a small overhead over simply leaking the Arc. The same is true for the Swift objects that we leak using `Unmanaged<>`. * For trait interfaces, this is probably a small gain compared to adding an extra box, then leaking it. * This is going to be way faster than the foreign code that uses a lock and a map. The main disadvantage is the extra complexity, but it seems relatively small to me. The stress tests and loom tests give us good confidence that the code is correct. As mentioned above, I'm pretty sure that we can leverage this for foreign handles as well, and should be able to remove some code on from the bindings.
- Loading branch information