-
Notifications
You must be signed in to change notification settings - Fork 849
Description
We avoid writing the dylib file out to disk where available. There's some options:
On Linuxy-things we can (it seems) just dlopen from /proc/self/fd/NN. Need to verify positioning - could dup + seek if it takes the position of the file, and if not could try mmapping the memory again (pages should be identical) but at an offset (not sure if that works).
On BSD there's fdlopen that takes the fd directly. Also need to verify positioning.
On Android we can use ANDROID_DLEXT_USE_LIBRARY_FD ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET of android_dlopen_ext to point dlopen directly to a byte offset in an fd: https://developer.android.com/ndk/reference/group/libdl
Unknown on mac yet. Could stick with the fallback to start.
If we can't get one of the functions to dlopen from a position (and instead just an offset) we can exploit the fact that flatbuffers are just pointers into contiguous address ranges so we can take the pointer to the dylib in the executable and subtract the base pointer of the mmapped region to get the file offset in the originally-mapped fd.
We can keep the current disk approach as the ultimate fallback, but there's a better fallback where we use memfd_create+tmpfs, memcpy into that from the flatbuffer mmapped memory, and then dlopen from that fd/fdlopen/android_dlopen_ext/etc. That wires memory that we otherwise wouldn't, but executable binaries are small (no large constants) and compared to touching the disk at all it's probably in the ballpark of 1000x+ faster.
- test: linux w/ dlopen to existing wrapper mmap fd fd at position
- test: linux w/ dlopen to memfd_create memcpy'd memory
- test: android w/ android_dlopen_ext to existing wrapper mmap fd at position
- test: android w/ android_dlopen_ext to memfd_create memcpy'd memory
If we can get these working then on those platforms we can completely eliminate file IO from the runtime. Both approaches also set us up for sandboxing (where we can map the wrapper flatbuffer in one process and then share the sealed fd with the sandbox process such that it can share the same pages for the executables).