LuaJIT
Just-in-time compiler for the Lua programming language
- 4 min read
- 4 chapters
Related on Lably
Through Interpreter (computing), Operator (computer programming) and Type conversion
History
The LuaJIT project was started in 2005 by developer Mike Pall, released under the MIT open source license.
The second major release of the compiler, 2.0.0, featured major performance increases.
LuaJIT uses rolling releases. Mike Pall, the creator and maintainer recommends using the tip of the v2.1 branch, and does not believe in releases.
Mike Pall resigned in 2015 making only occasional patching to the future 2.1 version since then.
Sign in to keep reading
3 more chapters are free with a Lably account.
Notable users
- CERN, for their Methodical Accelerator Design 'next-generation' software for describing and simulating particle accelerators
- OpenResty, a fork of nginx with Lua scripting
- Neovim, a text editor based on vim that allows the use of Lua for plugins and configuration
- Kong, a web API gateway
- Cloudflare, who use LuaJIT in their web application firewall service
Performance
LuaJIT is often the fastest Lua runtime. LuaJIT has also been named the fastest implementation of a dynamic programming language.
LuaJIT includes a Foreign Function Interface compatible with C data structures. Its use is encouraged for numerical computation.
Tracing
LuaJIT is a tracing just-in-time compiler. LuaJIT chooses loops and function calls as trace anchors to begin recording possible hot paths. Function calls will require twice as many invocations to begin recording as a loop. Once LuaJIT begins recording, all control flow, including jumps and calls, are inlined to form a linear trace. All executed bytecode instructions are stored and incrementally converted into LuaJIT's static single-assignment intermediate representation. LuaJIT's trace compiler is often capable of inlining and removing dispatches from object orientation, operators, and type modifications.
Internal representation
LuaJIT uses two types of internal representation. A stack-based bytecode is used for the interpreter, and a static single-assignment form is used for the just-in-time compiler. The interpreter bytecode is frequently patched by the JIT compiler, often to begin executing a compiled trace or to mark a segment of bytecode for causing too many trace aborts.
<span id="mwfA"></span><span class="c1" id="mwfQ">-- Loop with if-statement</span> <span class="kd" id="mwfg">local</span><span class="w" id="mwfw"> </span><span class="nv" id="mwgA">x</span><span class="w" id="mwgQ"> </span><span class="o" id="mwgg">=</span><span class="w" id="mwgw"> </span><span class="mi" id="mwhA">0</span> <span class="kr" id="mwhQ">for</span><span class="w" id="mwhg"> </span><span class="nv" id="mwhw">i</span><span class="o" id="mwiA">=</span><span class="mi" id="mwiQ">1</span><span class="p" id="mwig">,</span><span class="mf" id="mwiw">1e4</span><span class="w" id="mwjA"> </span><span class="kr" id="mwjQ">do</span> <span class="w" id="mwjg"> </span><span class="nv" id="mwjw">x</span><span class="w" id="mwkA"> </span><span class="o" id="mwkQ">=</span><span class="w" id="mwkg"> </span><span class="nv" id="mwkw">x</span><span class="w" id="mwlA"> </span><span class="o" id="mwlQ">+</span><span class="w" id="mwlg"> </span><span class="mi" id="mwlw">11</span> <span class="w" id="mwmA"> </span><span class="kr" id="mwmQ">if</span><span class="w" id="mwmg"> </span><span class="nv" id="mwmw">i</span><span class="o" id="mwnA">%</span><span class="mi" id="mwnQ">10</span><span class="w" id="mwng"> </span><span class="o" id="mwnw">==</span><span class="w" id="mwoA"> </span><span class="mi" id="mwoQ">0</span><span class="w" id="mwog"> </span><span class="kr" id="mwow">then</span><span class="w" id="mwpA"> </span><span class="c1" id="mwpQ">-- if-statement</span> <span class="w" id="mwpg"> </span><span class="nv" id="mwpw">x</span><span class="w" id="mwqA"> </span><span class="o" id="mwqQ">=</span><span class="w" id="mwqg"> </span><span class="nv" id="mwqw">x</span><span class="w" id="mwrA"> </span><span class="o" id="mwrQ">+</span><span class="w" id="mwrg"> </span><span class="mi" id="mwrw">22</span> <span class="w" id="mwsA"> </span><span class="kr" id="mwsQ">end</span> <span class="w" id="mwsg"> </span><span class="nv" id="mwsw">x</span><span class="w" id="mwtA"> </span><span class="o" id="mwtQ">=</span><span class="w" id="mwtg"> </span><span class="nv" id="mwtw">x</span><span class="w" id="mwuA"> </span><span class="o" id="mwuQ">+</span><span class="w" id="mwug"> </span><span class="mi" id="mwuw">33</span> <span class="kr" id="mwvA">end</span>
<span id="mwvw"></span><span class="go" id="mwwA">---- TRACE 1 start Ex.lua:5</span> <span class="go" id="mwwQ">---- TRACE 1 IR</span> <span class="go" id="mwwg">0001 int SLOAD #2 CI</span> <span class="go" id="mwww">0002 > num SLOAD #1 T</span> <span class="go" id="mwxA">0003 num ADD 0002 +11</span> <span class="go" id="mwxQ">0004 int MOD 0001 +10</span> <span class="go" id="mwxg">0005 > int NE 0004 +0</span> <span class="go" id="mwxw">0006 + num ADD 0003 +33</span> <span class="go" id="mwyA">0007 + int ADD 0001 +1</span> <span class="go" id="mwyQ">0008 > int LE 0007 +10000</span> <span class="go" id="mwyg">0009 ------ LOOP ------------</span> <span class="go" id="mwyw">0010 num ADD 0006 +11</span> <span class="go" id="mwzA">0011 int MOD 0007 +10</span> <span class="go" id="mwzQ">0012 > int NE 0011 +0</span> <span class="go" id="mwzg">0013 + num ADD 0010 +33</span> <span class="go" id="mwzw">0014 + int ADD 0007 +1</span> <span class="go" id="mw0A">0015 > int LE 0014 +10000</span> <span class="go" id="mw0Q">0016 int PHI 0007 0014</span> <span class="go" id="mw0g">0017 num PHI 0006 0013</span> <span class="go" id="mw0w">---- TRACE 1 stop -> loop</span> <span class="go" id="mw1A">---- TRACE 2 start 1/4 Ex.lua:8</span> <span class="go" id="mw1Q">---- TRACE 2 IR</span> <span class="go" id="mw1g">0001 num SLOAD #1 PI</span> <span class="go" id="mw1w">0002 int SLOAD #2 PI</span> <span class="go" id="mw2A">0003 num ADD 0001 +22</span> <span class="go" id="mw2Q">0004 num ADD 0003 +33</span> <span class="go" id="mw2g">0005 int ADD 0002 +1</span> <span class="go" id="mw2w">0006 > int LE 0005 +10000</span> <span class="go" id="mw3A">0007 num CONV 0005 num.int</span> <span class="go" id="mw3Q">---- TRACE 2 stop -> 1</span>
Extensions
LuaJIT adds several extensions to its base implementation, Lua 5.1, most of which do not break compatibility.
- "BitOp" for binary operations on unsigned 32-bit integers (these operations are also compiled by the just-in-time compiler)
- "CoCo", which allows the VM to be fully resumable across all contexts
- A foreign function interface
- Portable bytecode (regardless of architecture, word size, or endianness, not version)

