7 ms·
The Road to the JIT
- azhenley 6y agoPutting multiple Erlang functions into a single C function to avoid using C’s stack sounds awesome but also horrifying.
- chrisseaton 6y ago> Putting multiple Erlang functions into a single C function to avoid using C’s stack sounds awesome but also horrifying. Why's that horrifying? Isn't inlining a super-basic and well-understood optimisation that any serious compiler would be doing?
- azhenley 6y agoNo, this isn't inlining. They're managing their own call stack and relying on undefined behavior. See the quote from the article: > BEAM/C generated a single C function for each Erlang module. Local calls within the module were made by explicitly pushing the return address to the Erlang stack followed by a goto to the label of the called function. (Strictly speaking, the calling function stores the return address to BEAM register and the called function pushes that register to the stack.) > Calls to other modules were done similarly by using the GCC extension that makes it possible to take the address of a label and later jumping to it. Thus an external call was made by pushing the return address to the stack followed by a goto to the address of a label in another C function. > Isn’t that undefined behavior? > Yes, it is undefined behavior even in GCC.
- chrisseaton 6y agoAh sorry I see.
- jpcooper 6y agoWhy is it undefined behaviour?
- IainIreland 6y agoYou aren't allowed to goto a label in a different function. From the C standard: > The identifier in a goto statement shall name a label located somewhere in the enclosing function. `Shall` is a term of art here: > If a "shall" or "shall not" requirement that appears outside of a constraint is violated, the behavior is undefined. (Sections 6.8.6.1.1 and 4.2, respectively: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf)
- jpcooper 6y agoAppreciated.
- jhoechtl 6y agoIt's undefined in the C standard. That doesn't mean its insecure or undefined as seen from the machine code. nothin is hilding you back to do your own code generation and clearly define this behaviour.
- MaxBarraclough 6y agoThey weren't doing their own code-generation, BEAM/C treated C as the target language, and then relied on a standard C compiler. From the article: > it is undefined behavior even in GCC. It happened to work with GCC on Sparc, but not on GCC for X86.
- deleted 6y ago[deleted]
- dnautics 6y agoover in zigland in private we're saying that one of the endgoals of zig should be to reimplement the BEAM. One of the most active users of zig is doing some really neat things with task-stealing, allocation-free, lock-free schedulers that are a lot like the BEAM's techniques, except super performant: (watch this for till the benchmarks demos ~ finishing 1h:17min https://www.youtube.com/watch?v=UaF6-5BmX2I&t=1h9m https://www.youtube.com/watch?v=UaF6-5BmX2I&t=1h9m)
- shiny 6y agoTo anyone just reading comments, this is referring to the old BEAM/C compiler, not the new JIT.
- ngrilly 6y agoErlang (the language, the runtime and the OTP framework) is a fascinating alternative in the design space for programming languages. Always happy to read about it, even if I don't use it for my projects.
- brightball 6y agoAgreed. After reading enough about it I’ve become convinced that there are only 2 different platforms in the world. OTP/BEAM and everything else. Every other language that I’ve studied seems to just cope with the same problems in slightly different ways.
- macintux 6y agoErlang/OTP/BEAM are so unusual within the computing world: highly opinionated components that, thanks to their constraints, are keenly complementary and optimized for each other. No kitchen sink language here: play by their rules or choose a different environment.
- idolaspecus 6y agoContrarily, this is exactly what makes Unix environments so powerful (and wonderful). The "Unix Philosophy" is typically considered unopinionated (in the "let the user choose" sense), but I'd say that it's more like it has a few very strong yet well-chosen opinions that produce a highly integrated universe where all sorts of different tools just work.
- the_only_law 6y agoYes Erlang is one of the few languages I instantly liked upon reading about it and playing with it, even outside its typically parroted features it has a ton of stuff I wish was available in more languages (working with bit oriented protocols is so much more pleasant in Erlang than most languages thanks to bitstrings). However, as other have mentioned it’s not exactly a go to for general purpose stuff and even when it seems a perfect fit, I often have to look elsewhere for a variety of reasons.
- kasperni 6y agoSeeing how many billions have been posted into JIT runtimes such as CLR/JVM/V8. I'm questioning whether or not it is realistic to create a production ready JIT as a side project?
- artemonster 6y agoLuaJIT?
- deleted 6y ago[deleted]
- MaxBarraclough 6y agoYou beat me to it. If you're aiming to compete with HotSpot and .Net then you'll need to invest millions, but not all JITs are this ambitious. GNU Lightning is another example of a JIT with few people behind it.
- hinkley 6y agoThe BEAM is mostly concerned with correctness and horizontal scalability. I think a little vertical scalability from a JIT raises the throughout of the system without really changing how it works or what you use it for. If anything, maybe you write less stuff in native code. A great deal of research has been published in the last 25 years, and some of it invalidates earlier wisdom due to changes in processor design. Just following this trail and applying the 80/20 rule could get a lot done for a little effort. And a simple JIT has half a prayer of being correct.
- toast0 6y agoIt's important to note that the goals of this BEAM JIT are a lot more modest than those other JITs. There's no goal of heroic optimization; the optimization goal is really just to remove the overhead of interpretation. This removes the need to apply the JIT only to some code, because it's fairly simple, it's fast enough to apply when the code is loaded, and so all code is JITed to native as it's loaded. Or you're on an unsupported platform and all code is interpretted. Because it's all or nothing, testing the OTP release should uncover any JIT bugs; you won't have the hard to track bugs sometimes seen in other systems where a function's correctness depends on whether or not it was JITed and that depends on runtime state. That won't mean no JIT bugs, of course, but they should be easier to track down.
- didibus 6y agoOh, so is Erlang Beam VM code currently only running interpreted?
- cpeterso 6y agoThe article says: “The modern BEAM only has the interpreter.”
- dnautics 6y agoit's interpreted bytecode. The bytecode is a highly optimized constrained language that looks a whole lot like machine language. It would not be unreasonable to build hardware that runs it, if you wanted to. I guess it would not be unreasonable to say, it's interpreted in the same way that running arm-compiled code on qemu on an x86 is interpreted.
- dasyatidprime 6y agoQEMU in fact does dynamic translation, which is more like how JIT works in bytecode languages; this is why it's much faster than some earlier machine emulator software. (I think e.g. Bochs didn't have dynamic translation back when QEMU was coming into play, but the Web suggests that there's at least discussion around that feature so maybe that's not true anymore.) The BEAM is currently a bytecode interpreter. The article describes it as using threaded code, which if you look at the C source is true in a sense on platforms where the C compiler provides the GNU-style extension of being able to take the address of labels for dynamic `goto` (https://stenmans.org/happi_blog/?p=194 https://stenmans.org/happi_blog/?p=194 agrees with my skim of `beam_emu.c`)—though if that's the only use as it seems, I might find that an edge case of the term, since I associate “threaded code” with the style used in Forth where “user-level” subroutines can be pointed to directly. If computed `goto` isn't available, then it uses a conventional switch/case loop, repeatedly dispatching the result of fetching the next bytecode instruction pointer value.
- dnautics 6y agoAh sorry, indeed. Bochs is a better analogy. Though that brings up a question... I wonder if you could write a qemu backend to the BEAM, and start working towards dynamic translation that way?
- jolux 6y agoIs there currently a plan to move towards making the JIT the default implementation?
- di4na 6y agoYes, it will be the default on all supported platform as of OTP 24
- joisig 6y agoI listened to a very interesting podcast episode [1] on the Thinking Elixir Podcast on this subject recently, an interview with John Högberg and Lukas Larsson. Not covered in this blog post but discussed in some detail in the podcast is that because you get standard debugging symbols from the JIT, you will now be able to use gdb and prof and similar tools when working with the BEAM. [1] https://podcasts.google.com/?feed=aHR0cHM6Ly90aGlua2luZ2VsaXhpci5jb20vZmVlZC9wb2RjYXN0Lw&ep=14&episode=aHR0cHM6Ly90aGlua2luZ2VsaXhpci5jb20vP3Bvc3RfdHlwZT1wb2RjYXN0LWVwaXNvZGVzJnA9NjA0NQ https://podcasts.google.com/?feed=aHR0cHM6Ly90aGlua2luZ2VsaX...
- paulgdp 6y agoFor people interested in this subject, this recent HN post might be also relevant: https://news.ycombinator.com/item?id=25253070 https://news.ycombinator.com/item?id=25253070 My interpretation is that the end goal seems similar, but this project starts with the Rust language instead.
- tiffanyh 6y ago> "Dialyzer was only about 10 percent slower with the JIT than with HiPE" This is the first time I've seen AsmJIT compared to HiPE. Interesting.
- brokencode 6y agoJust want to point out that later in the paragraph they said AsmJIT now roughly matches the performance of HiPE for Dialyzer.
- liveoneggs 6y agoJAM (Joe’s Abstract Machine) In 1989 JAM (Joe’s Abstract Machine) was first implemented. Mike Williams wrote the runtime system in C, Joe Armstrong wrote the compiler, and Robert Virding wrote the libraries. "Joe Armstrong" is a link to github.com/joearms -> " joearms has no activity yet for this period. " Now I'm sad :(
- yawaramin 6y agoLook at it this way, he's in the Arctic Code Vault. His name and work will survive into the next millennium.
- yawaramin 6y agoA super well-written and easy-to-read post. It takes real skill and craft to communicate this well.
- namelosw 6y agoI'm actually very interested in the Prolog prototype - especially on how it's done and how do they iterate the design. Does anyone have any information about it?
- icandoit 6y agoI found this link to Armstrong 2003 thesis: https://web.archive.org/web/20041204143417/http://www.sics.se/~joe/thesis/armstrong_thesis_2003.pdf https://web.archive.org/web/20041204143417/http://www.sics.s... found that link here: https://thenewstack.io/why-erlang-joe-armstrongs-legacy-of-fault-tolerant-computing/ https://thenewstack.io/why-erlang-joe-armstrongs-legacy-of-f... It's not working for me right now, but you may have better luck.
- namelosw 6y agoThank you so much! Although I skimmed through it didn't say too much about the Prolog interpreter, it's very educative.