Conversation

Replying to and
Fully polymorphic code is pretty large too in machine code, and is full of indirect branches already. Byte code has the opportunity to be a lot smaller, and an interpreter could be nearly as fast while using up less instruction cache space
1
2
I rely heavily on LTO and dead code elimination in generic code for the Rust I write on microcontrollers (< 100kB ROM, < 10kB RAM). I don't think my code would appreciate embedding a full interpreter just because a few cold code paths couldn't be optimized out LOL.
2
1
Replying to and
Sure, there are definitely places where you don’t want to introduce dependencies on a runtime. Across a full blown OS on a desktop CPU, being able to make better use of memory and cache by sharing code is a big systemic optimization; for a single purpose controller not so much
1
2
On modern Android versions, apps start out using a multi-tier JIT compiler with an interpreter as the baseline. It saves the JIT profile information persistently and that's used to perform AOT compilation when the device is idle and during background installation of OS updates.
1
2
Cold code never ends up being compiled to native code, since it's never identified as hot enough to warrant being JIT compiled in memory and the AOT compilation is based on an aggregation of those JIT profiles. The AOT compilation is more aggressive but still skips lots of code.
1
1
JIT compilation is constrained by memory usage since it creates dirty pages in memory, along with being limited by time since compilation wastes CPU cycles / battery life. It's willing to compile much more code with AOT compilation in the background based on the JIT profiles.
2
Replying to
I was confused specifically about this wording: >The AOT compilation is more aggressive but still skips lots of code. Skips lots of already-JITted code, skips lots of bytecode, or both?
2
Replying to and
Btw, for the record... All this stuff is utterly fascinating, but it's not relevant to my use case :P. I'm looking to make sure that the minimum possible _usable_ compiled app in a modern language stays in the kBs, not MBs.
Quote Tweet
Replying to @cr1901 @jckarter and 2 others
Also, I have msp430 code in Rust I deployed that needs to fit in 2kB ROM and 128 BYTES of RAM; and it does with proper optimizations turned on, minus RefCell panic string misoptimizations :/ An interpreter would NEVER fit there unless it's the worlds tiniest stack machine lmao.
1
Replying to
Yeah, just an example of how an approach like this is already used in production on a huge number of devices. Devices with barely any storage are also able to choose not to do AOT or lower how much is done. Devices with low memory can disable the JIT or lower JIT cache size, etc.