Source (I think) - Looks like it's bundled with language and platform source
https://happi.github.io/theBeamBook/#CH-Beam_loader: A very interesting part from the aforementioned book about the BEAM code loader and transformation from generic to specific instructions. Basically the Erlang bytecode loader does a large amount of work rewriting the generic "transport format" bytecode in the object files into the concrete internal bytecode operations that are actually executed. This recognizes common sequences and replaces them with optimized single-opcode versions.
http://gomoripeti.github.io/beam_by_example/: A peak into the Erlang compiler and BEAM bytecode. This is an overview of all the intermediate representations of the Erlang code. Steps described in the article are as follows: Erlang source code --> Abstract Syntax Tree ('P') --> expanded AST ('E') --> Core Erlang ('to_core') --> BEAM byte-code
. However I would also add two missing steps namely BEAM generic bytecode --> BEAM specific bytecode and Core Erlang --> Kernel Erlang.
So to sum up, the main compilation stages for Erlang are:
StackOverflow question with an interesting answer which contains some details about the Erlang pattern match compiler:
https://stackoverflow.com/questions/587996/erlang-beam-bytecode
Source code of the Kernel Erlang compiler (v3_kernel.erl
) with useful comments:
https://github.com/erlang/otp/blob/master/lib/compiler/src/v3_kernel.erl#L20
A nice thread descibing compilation to BEAM bytecode via EAF
(in the context of Elixir). It also contains useful links:
Erlang compile
module docs:
http://erlang.org/doc/man/compile.html#file-2
BEAM file format:
http://rnyingma.synrc.com/publications/cat/Functional%20Languages/Erlang/BEAM.pdf
Erlang abstract format docs:
http://erlang.org/doc/apps/erts/absform.html
The Erlang BEAM Virtual Machine Specification by one of its designers (Björn in the BEAM):
http://www.cs-lab.org/historical_beam_instruction_set.html
A Peek Inside the Erlang Compiler:
http://prog21.dadgum.com/127.html
BEAM wisdoms:
Also a nice description of the BEAM instruction set: http://erlangonxen.org/more/beam
Thesis which contains some useful information about the Erlang implementation: http://uu.diva-portal.org/smash/get/diva2:428121/FULLTEXT01.pdf
Code of the BEAM loader which was described above: https://github.com/erlang/otp/blob/master/erts/emulator/beam/beam_load.c You might be particularly interested in the static int transform_engine(LoaderState* st)
function.
Internal doc in the erts/emulator is a treasure trove of the underlying implementation details: https://github.com/erlang/otp/tree/master/erts/emulator/internal_doc
Will put reference to the Erlang garbage collection doc as a separate link: https://github.com/erlang/otp/blob/master/erts/emulator/internal_doc/GarbageCollection.md
Reductions:
Current max reductions is 4000.
Information regarding reduction from the BeamBook.
What counts as a VM reduction: As per Erlang VM maintainer Lukas Larsson's comment:
As a general rule of thumb; a function call (not the return) or anything that may take an unknown amount of time counts reductions. This includes bifs, nifs, gc, sending/receiving messages and probably more that I cannot think of right now.
Internal OTP doc which contains useful insights regaring the process managements, lock and run queues:
https://github.com/erlang/otp/blob/master/erts/emulator/internal_doc/ProcessManagementOptimizations.md
Insights by one of the original designers of BEAM SMP support (Rickard Green) into the scheduler compaction of load mode taken from this email thread: http://erlang.org/pipermail/erlang-questions/2012-October/069585.html
The runtime system tries to compact the load on as few schedulers as possible without getting run-queues that build up. The runtime system wont wake up new schedulers unless some overload has accumulated. This overload either show up as a quickly growing run-queue or a small run-queue over a longer time. The +swt flags sets the threshold that is used for determining when enough overload has accumulated to wake up another scheduler. This compaction of load onto fewer schedulers is there in order to reduce communication overhead when there aren't enough work to fully utilize all schedulers. The performance gain of this compaction depends on the hardware. We have gotten reports about problems with this functionality, but we have not found any bugs in this functionality. We have only found that it behaves as expected. That is, if more schedulers aren't woken this is
due to not enough accumulated overload. The +swt switch was introduced in order to give the user the possibility do define what is enough overload for his or her taste. The currently used wakeup strategy is very quick to forget about previously accumulated overload that has disappeared. Maybe even too quick for my taste when "+swt very_low" is used. I've therefore implemented an alternative strategy that most likely will be the default in R16. As of R15B02 you can try this strategy out by passing "+sws proposal" as a command line argument. In combination with "+swt very_low", the runtime system should be even more eager to wake up schedulers than when only using "+swt very_low".
When access an ETS table, there are wo locks that need to be taken:
ETS Scalability paper: http://winsh.me/papers/erlang_workshop_2013.pdf
ETS meta table source code: https://github.com/erlang/otp/blob/master/erts/emulator/beam/erl_db.c#L324
Official Erlang documentation on this topic
term_to_binary/2 docs
C implementation of the term_to_binary in ERTS.
Garbage collect C implementation.
erl_create_process function.
We always use BIFs in Erlang such as element
or spawn_link
or whatnot in our code. gen
and gen_server
are based on the erlang:spawn
BIF, hence I think it's important to know how BIFs are actually implemented: https://github.com/erlang/otp/blob/master/lib/stdlib/src/erl_internal.erl#L22 stdlib/erl_internal
here is just a BIF-proxy because all the functions are implemented natively in C inside the ERTS/BEAM.
Core C implementation of BIFs resides here
The most important parts from the Erlang code purger such as purge
, soft_purge
, etc.
Lists module functionality. Some of the functions such as keyfind/3
, keymember/3
, etc. are implemented as BIFs and defined in a separate C file inside of BEAM.
Core functionality of the Erlang message passing
https://github.com/erlang/otp/tree/master/erts/emulator/internal_doc
Last modified 07 July 2025