4 ms·
> Just in Time (JIT) compilation is not possible as dynamic Wasm code generation is not allowed for security reasons. Browsers definitely use a form of JIT-ing
by flohofwoe 2y ago
> Just in Time (JIT) compilation is not possible as dynamic Wasm code generation is not allowed for security reasons.
Browsers definitely use a form of JIT-ing for WASM (which is a bit unfortunate, because just as with JITs, you might see slight 'warmup stutter' when running WASM code for the first time - although this has gotten a lot better over the years).
...also I'm pretty sure you can dynamically create a WASM blob in the browser and then dynamically instantiate and run that - not sure if that's possible in other WASM runtimes though, and even in the browser you'll have to reach out Javascript, but that's needed for accessing any sort of 'web API'.
- torginus 2y ago>Browsers definitely use a form of JIT-ing for WASM I (and the article) wasn't referring to this kind of JIT. I was referring to the ability to dynamically create or modify methods or load libraries while the app is running (like `DynamicMethod` in .NET). Afaik WASM even in the browser does not allow modifying the blob after instantiation. The thing you are referring to puzzles me as well. I initially thought that WASM would be analogous to x86 or ARM asm and would be just another architecture emitted by the compiler. Running it in the browser would just involve a quick translation pass to the native architecture (with usually 1-to-1 mapping to machine instructions) and some quick check to see that it doesn't do anything naughty. Instead it's an LLVM IR analog that needs to be fed into a full-fledged compiler backend. I'm sure there are good technical reasons as to why it was designed like this, but as you mentioned, it comes with tangible costc like startup time and runtime complexity.
- flohofwoe 2y ago> Afaik WASM even in the browser does not allow modifying the blob after instantiation. ...not your own WASM blob, but you can build a new WASM blob and run that. > The thing you are referring to puzzles me as well... Yes, compilers emit WASM, but that WASM is just a bytecode (similar to JVM or .NET bytecode but even higher level because WASM enforces 'structured control flow') and needs to be compiled to actual machine code on the client before it can run, and this isn't a simple AOT compilation - in browsers at least (it used to be for a while in Firefox, but that caused issues for large projects like Unity games, which might take dozens of seconds to AOT compile). AFAIK all browsers now use a tiered approach. The WASM-to-machine-code compilation doesn't happen on the whole WASM blob at once, but function by function. For the first time a WASM function is called, a fast compilation will happen which may have slow runtime performance, from then on, 'hot functions' will be compiled with a higher tier backend which does additional optimization, is slow to compile but has better runtime performance - and AFAIK this is also quite similar to how Javascript JIT-ing works. Also from what I understand WASM compilation is more complex than just translating bytecode instructions to native instructions. It's more like compiling an AST into machine code - at least if you want any performance out of it. The only difference to JS might be that WASM functions are never 'de-optimized'.
- torginus 2y agoI feel like I need to be a bit more frank > WASM is just a bytecode (similar to JVM or .NET bytecode but even higher level ... Yes, and I think this was a poor engineering choice on behalf of WASM engineering team, instead of using something much closer to actual assembly. And we are grappling with long startup times and lots of compiler infra pushed into the client because of that. > ...not your own WASM blob, but you can build a new WASM blob and run that. another baffling limitation, considering you can modify your C#, Java or even native code at runtime. Unless they are working around some constraint unknown to me, in which case I'd love to know about what it is, they made bad technical decisions in the design.
- flohofwoe 2y ago> they made bad technical decisions in the design Considering that the most important design requirement was to have a security model that's good enough for running untrusted code in web browsers at near native performance, I think the WASM peeps did a pretty good job. Your requirements may be different, but then maybe WASM simply isn't the right solution for you (there are plenty of alternatives outside web browsers after all).
- torginus 2y agoPNacl also had the same sandboxing requirement, yet had many of the features still missing today from WAsm (threads, 3d graphics API support, access to other native APIs), and it didn't suffer from slow startup times. It had pretty nice and quick uptake considering the tooling was very similar to native toolchains. According to this benchmark (first Google result I found), it was even faster: https://apryse.com/blog/wasm/wasm-vs-pnacl https://apryse.com/blog/wasm/wasm-vs-pnacl While it might not have been perfect, WASM is yet to catch up in many ways, and some of its limitations might come from its design.
- flohofwoe 2y agoI had been working both with NaCl and PNaCl back then, and truth be told, once Google made the switch from NaCl to PNaCl most advantages just disappeared. The compilation of the PNaCl bytecode on start (which was more or less just a subset of LLVM IR) took longer than even the first WASM implementations. PNaCl definitely suffered hard from slow startup times because it ran LLVM for compilation from PNaCl bytecode to native code on startup, and LLVM is slow (I even noticed this compilation process on startup on my absolutely trivial test code). Only the predecessor NaCl didn't suffer from this problem. There was no 'access to other native APIs', PNaCl created its own set of wrapper APIs to access browser features, and while some of those were better than their standardized web API counterparts, some NaCl/PNaCl APIs were worse than the web APIs they replaced - and for the future, PNaCl would have to create more non-standard APIs for every little feature available in browsers, because: Integration with the webpage and Javascript was done via message passing, which was just terrible when compared to how easy and fast it is to call between WASM and JS. The NaCl/PNaCl multithreading feature would have been hit just as hard by Spectre/Meltdown as the SharedArrayBuffer based threading in WASM. Finally, when you look at the PNaCl toolchain versus Emscripten, Emscripten definitely comes out on top because Emscripten was much more concerned about integrating well with existing build systems and simplify porting of existing code, while NaCl/PNaCl had its own weird build system (in old Google NIH tradition). Working with NaCl/PNaCl felt more like working with the Android NDK, which is pretty much the worst developer experience in the world.