forked from LuaJIT/LuaJIT
-
Notifications
You must be signed in to change notification settings - Fork 13
/
lj-611-always-snapshot-functions-for-non-base-frames.test.lua
43 lines (36 loc) · 1.47 KB
/
lj-611-always-snapshot-functions-for-non-base-frames.test.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
local tap = require('tap')
local test = tap.test('lj-611-always-snapshot-functions-for-non-base-frames')
test:plan(1)
jit.opt.start('hotloop=1', 'hotexit=1')
-- Test reproduces a bug "GC64: Function missing in snapshot for non-base
-- frame" [1], and based on reproducer described in [2].
--
-- [1]: https://github.com/LuaJIT/LuaJIT/issues/611
-- [2]: https://github.com/LuaJIT/LuaJIT/issues/611#issuecomment-679228156
--
-- Function `outer` is recorded to a trace and calls a builtin function that is
-- not JIT-compilable and therefore triggers exit to interpreter, and then it
-- resumes tracing just after the call returns - this is a trace stitching.
-- Then, within the call, we need the potential for a side trace. Finally, we need
-- that side exit to be taken enough for the exit to be compiled into a trace.
-- The loop at the bottom has enough iterations to trigger JIT compilation, and
-- enough more on top on trigger compilation of the not case. Compilation of
-- this case hits the assertion failure.
local outer
for j = 1, 3 do
outer = function(_, i)
return i < 4
end
end
local function outer(i)
-- The function `string.gsub` is not JIT-compilable and triggers a trace
-- exit. For example, `string.gmatch` and `string.match` are suitable as
-- well.
-- See https://github.com/tarantool/tarantool/wiki/LuaJIT-Not-Yet-Implemented.
inner(string.gsub('', '', ''), i)
end
for i = 1, 4 do
outer(i)
end
test:ok(true, 'function is present in snapshot')
test:done(true)