Hi,
What the documentation refers to as the "exit number" is the snapshot
number LuaJIT uses when restoring the C stack from the JIT registers.
Let's dump the bytecode with the following:
require("jit.dump").on("is")
Where the 'i' argument prints the IR, and 's' the snapshot maps[1].
We'll see 8 traces and their respective IR in the stdout output. Let's
take a look at two of them (apologies in advance for my mail client may
truncate lines):
---- TRACE 1 IR
.... SNAP #0 [ ---- ]
0001 int SLOAD #6 CI
0002 > tab SLOAD #1 T
0003 int FLOAD 0002 tab.asize
0004 > int ABC 0003 +1
0005 p32 FLOAD 0002 tab.array
0006 p32 AREF 0005 +1
0007 tab FLOAD 0002 tab.meta
0008 > tab EQ 0007 NULL
0009 num CONV 0001
num.int
0010 num ASTORE 0006 0009
0011 + int ADD 0001 +1
.... SNAP #1 [ ---- ---- ---- ---- ---- ---- ]
0012 > int LE 0011 +100
.... SNAP #2 [ ---- ---- ---- ---- ---- ---- 0011 ---- ----
0011 ]
0013 ------ LOOP ------------
0014 num CONV 0011
num.int
0015 num ASTORE 0006 0014
0016 + int ADD 0011 +1
.... SNAP #3 [ ---- ---- ---- ---- ---- ---- ]
0017 > int LE 0016 +100
0018 int PHI 0011 0016
---- TRACE 1 stop -> loop
[... other traces ...]
---- TRACE 5 start 1/3 jit.lua:11
---- TRACE 5 IR
.... SNAP #0 [ ---- ---- ---- ---- ---- ---- ]
0001 > tab SLOAD #1 T
0002 int FLOAD 0001 tab.asize
0003 > int ABC 0002 +2
0004 p32 FLOAD 0001 tab.array
0005 p32 AREF 0004 +2
0006 tab FLOAD 0001 tab.meta
0007 > tab EQ 0006 NULL
0008 str ASTORE 0005 "1end2begin"
0009 nil TBAR 0001
.... SNAP #1 [ ---- ---- ---- ---- ---- ---- +1 +100 +1
+1 ]
---- TRACE 5 stop -> 2
The part that interests you here is "TRACE 5 start 1/3". The first
number (1) indicates the parent trace number as you pointed out, and the
second one (3) is the "exit number". What this means is that this
sidetrace was created from snapshot #3 of TRACE 1. See this line in TRACE 1:
.... SNAP #3 [ ---- ---- ---- ---- ---- ---- ]
The JIT compiler saved a snapshot indicating that no registers should be
changed when exiting back to the interpreter. The following instruction:
0017 > int LE 0016 +100
is a guard instruction, and in case of failure, the JIT will be
instructed to restore the previous snapshot (#3 in this case). This
instruction is your loop's exit-condition. When 'i' reaches 100, this
write guard will indeed fail, and the JIT must restore the previous
snapshot before moving on.
Regarding the second part of your question, you may have already had a
look at this part of the documentation[2]. It may be so that the loop in
question isn't worth it for the JIT to kick-in (e.g. it is falling back
to interpreter mode too quickly), so my guess is that it may eventually
be blacklisted, since the interpreter would still be faster than
constantly interpreting and attempting tracing. Since this is in re.lua
I suppose that it may be because your regex (or subject) is simple
enough that it does not warrant a lot of iterations in whatever loop is
being executed? We'd have to see the code to be able to tell.
Best,
Thibault
[1]:
https://github.com/LuaJIT/LuaJIT/blob/master/src/jit/dump.lua
[2]:
https://github.com/LuaJIT/LuaJIT/blob/master/src/jit/v.lua#L47-L49