Hey I am developing a little operating system. Is there some usage of cranelift/JIT in no_std and in kernel mode possible?
hey Robin! As a policy, we don't support no_std in either Cranelift or Wasmtime: https://docs.wasmtime.dev/stability-platform-support.html?highlight=no_std#what-about-no_std You'll have to support enough of an environment for std to work, at least for the time being
I'm not sure if cranelift works in no-std these days, it did at one point in time, but it is a pretty large burden on developers for miniscule gain
fwiw, you will probably get further implementing std
for your OS, stubbing things out with panics as necessary, than by trying to make everything in your dep tree no-std
for context, this wasmtime doc describes some of the issues with no-std and burden on the developers: https://docs.wasmtime.dev/stability-platform-support.html#what-about-no_std
Give that cranelift_codegen still uses #![no_std]
, rust-analyzer actually prefers auto importing from core and alloc instead of std. Other than using the std re-exports in many places, and hashmaps (for which we should probably use the no_std compatible FxHashMap type alias anyway), cranelift-codegen only uses libstd in a handful of places. As such I don't think there is any burden in supporting no_std for cranelift-codegen apart from a single refactor to stop using the std re-exports. For wasmtime and cranelift-module (and dependent crates) I do agree that it is a burden.
Heya (gonna revive this channel a bit hehe) I've been updating my cranelift fork today and thought I'd give the old upstreaming attempt another go if y'all are interested. This time around (I have a lot of practice in porting cranlift nowadays lol) I've broken up the no_std
support into a bunch of smaller and hopefully easier to review PRs (9977, 9976, and 9975)
(that I've been spamming y'all with sorry for that)
the big blocker is still std::sync::OnceLock
though :/
I might have already mentioned this but one tactic I did for wasmtime was to add a no_std
version which basically panics on contention. So still safe in no_std
and functional but non-functional in multi-threaded cases, which at leat for wasmtime's purposes is fine in that no_std
typically doesn't have threads
(and thanks for this PRs!)
yeah that’s a fine approach for embedded sadly it doesn’t help my case where I plan on supporting multiple cores
but it might be a first step before removing the need for those oncelocks all together as someone mentioned in that pr way back
if you're putting in efforts to port and want to "do it right" slightly more, pushing on removing OnceLock
s might be reasonable: they are only used to lazily initialize register configurations in ABI code; the configurations are nominally static, and are only created dynamically because they include Vec
s; &'static
slices (and hence letting the register environments be fully static data) would be reasonable alternatives I think. This does imply a change to regalloc2's MachineEnv
type but that should be trivial I think
yeah going to try to do that next week actually, right now my cranelift fork uses spin
but that has always really bothered me since i do have my own sync library
and having two of them just doesn’t feel right
Maybe you can use the once-cell crate? With the critical-section feature enabled it allows you to provide your own synchronization primitive.
Chris Fallin said:
if you're putting in efforts to port and want to "do it right" slightly more, pushing on removing
OnceLock
s might be reasonable: they are only used to lazily initialize register configurations in ABI code; the configurations are nominally static, and are only created dynamically because they includeVec
s;&'static
slices (and hence letting the register environments be fully static data) would be reasonable alternatives I think. This does imply a change to regalloc2'sMachineEnv
type but that should be trivial I think
making MachineEnv
take static slices and the necessary work on regalloc2s side indeed was quite easy, but I'm not quite sure what to do on the cranelift side
putting the whole MachineEnv
into a static
doesn't really work bc of the way they are constructed, and replacing all the non-const functions with const ones would mean readability = 0
on the other hand MachineEnv
is 120 bytes in size, idk if cloning that around is the best idea either
Jonas Kruckenberg said:
putting the whole
MachineEnv
into astatic
doesn't really work bc of the way they are constructed, and replacing all the non-const functions with const ones would mean readability = 0
well plus it the construction kind of depends on runtime configuration
putting the whole
MachineEnv
into astatic
doesn't really work bc of the way they are constructed, and replacing all the non-const functions with const ones would mean readability = 0
Well, yes, but there are a small number of configs (two!) so we can create both statically and return the right one -- e.g. here for x64, here for aarch64, here for s390x. And riscv64 has only one. This should be very readable IMHO: if flag { &PINNED_REG_ENV } else { &DEFAULT_REG_ENV }
or thereabouts.
aye alright yeah so the job is to make the machineenvs const constructible in a nice way
i can work with that
yeah, and in particular there's really just one level of helper (create_reg_env
or equiv) and then some register newtype converters that should either already be const or can be trivially made so (hopefully!). You'd turn the helper's body into a static struct initializer more or less
yeah that's the plan!
Last updated: Jan 24 2025 at 00:11 UTC