Implement BeamAsm – A JIT for Erlang/OTP
github.com
github.com
Some background on the journey to BeamJIT: https://drive.google.com/file/d/1hHCs90kDX_wJ9AbLzGNu5bZKdIV...
It's not a tracing or optimising JIT, but instead at load time translates the BEAM opcodes to native code using asmjit.
There's been talks of JIT for quite a few years, but they didn't want to merge it in until they had something that's easy to maintain, and doesn't introduce significant performance regressions. The end result looks really solid.
To make something faster may mean calcifying some part of the architecture; this code handles every scenario that the design defines now, but it can’t handle other scenarios we might have wanted to consider later. Those are now harder to implement or counter to our assumptions. People don’t like it when you take back things you previously gave them, meaning no new feature or a huge opportunity cost for that feature (because it’s reimplementing other features as well as adding a new one).
Also Facebook open-sourcing its static typed Erlang prototype in November.
A runtime type guard that asserts that the shape of data conforms to a particular type and from that point forward compiler will trust the guard and assume that the message is of particular type.
In a dynamically typed world, I doubt one could do much better.
Question: how does performance compare to HiPE. I see reference to improvements over the Interpreter but what about performance vs HiPE?
I know it's probably "it depends", but in Elixir let's say you were doing a lot of string parsing or mucking around with a bunch of Enum functions or doing a bit of math. Will this put Elixir's performance on par with at least Python and Ruby in those cases?
I know this feature is meant for Erlang but I'm assuming it applies back to Elixir too?
To get an idea of the instruction stream of the BEAM (not the same as .beam asm), you can use the erts_debug module:
iex> :erts_debug.df(String)
This will dump a BEAM machine instruction stream to a file named Elixir.String.dis in your current working directory. You'll see things like: 000000001B81AFB0: i_func_info_IaaI 0 `'Elixir.String'` `at` 2
000000001B81AFD8: is_integer_fx f(000000001B81AFB0) x(1)
000000001B81AFE8: is_ge_literal_fxc f(000000001B81B008) x(1) `0`
000000001B81B000: i_call_only_f loc(`'Elixir.String'`:`do_at`/2)
000000001B81B008: allocate_tt 2 2
000000001B81B010: move_window2_xxy x(1) x(0) y(0)
000000001B81B018: i_call_f loc(`'Elixir.String'`:`length`/1)
000000001B81B020: i_plus_xyjd x(0) y(0) j(0) x(0)
000000001B81B030: is_ge_literal_fxc f(000000001B81B060) x(0) `0`
000000001B81B048: move_shift_yxx y(1) x(0) x(1)
000000001B81B050: i_call_last_fQ loc(`'Elixir.String'`:`do_at`/2) 2
000000001B81B060: move_deallocate_return_cQ `nil` 2
Each of those instructions are what the .beam file loader currently generates. With the JIT, these will be replaced by machine code.There is something to be said about internal consistency and for a codebase as established as this, C++ is more of a detriment than a gain.
It has its problems but blindly being anti C++ is silly.
It's been a C codebase so far. Introducing C++ makes this no longer the case. This has strong implications for both development and deployment. I'm perplexed since there exist battle-tested code generation engines written in C (e.g. dynasm). Correct me if I'm wrong but it doesn't look like asmjit is anything special in that regard.
I can't imagine Joe Armstrong being happy about this.
I do agree with you though.
https://github.com/erlang/otp/pull/2745#issuecomment-6914821...
Then again I spent none of my time working on this project so I refuse to criticize the result. That would be obnoxious.
Using C++ doesn't mean one needs to use everything from it, and improving C while keeping its semantics will hardly lead to anything much different from what C++ already offers.