From: sergos via Tarantool-patches <tarantool-patches@dev.tarantool.org> To: Sergey Kaplun <skaplun@tarantool.org> Cc: tarantool-patches@dev.tarantool.org Subject: Re: [Tarantool-patches] [PATCH luajit] Add missing LJ_MAX_JSLOTS check. Date: Fri, 25 Mar 2022 18:51:10 +0300 [thread overview] Message-ID: <A3F8323A-8A97-4DFF-AB90-A6521383AE77@tarantool.org> (raw) In-Reply-To: <20211022114653.4225-1-skaplun@tarantool.org> Hi! Thanks for the patch! Some nits in comments and I have exactly the same test result with and without the patch: root@dev1:/workspaces/t.sergos/third_party/luajit/test/tarantool-tests# ../../src/luajit fix-slot-check-for-mm-record.test.lua TAP version 13 1..2 ok - nil ok - nil for the reference - GC64 is off: root@dev1:/workspaces/t.sergos/third_party/luajit/test/tarantool-tests# ../../src/luajit -e "print(require('ffi').abi('gc64'))" false Regards, Sergos > On 22 Oct 2021, at 14:46, Sergey Kaplun <skaplun@tarantool.org> wrote: > > From: Mike Pall <mike> > > Thanks to Yichun Zhang. > > (cherry picked from commit 630ff3196a06353c6a7ccd1e9ac3958f4a8ca13c) > > Before the patch, JIT compiler doesn't check slots overflow for Shall we put it like “before the patch”? We’re describing current behavior, which is apparently without the patch. Then we can use simple present tense. > recording of metamethods call. So the assertion in `rec_check_slots()` > checking that we don't overflow the slots limit (the limit > `LJ_MAX_JSLOTS` is 250) is failing, Slots limit overflow assertion fails in `rec_check_slots()` > when we record metamethod call > (`J->baseslot` diff + `J->maxslot` ~ 5-8 stack slots), while almost all > slots of JIT engine are occupied. > unlike the `lj_record_call()` (if I got it right?) during a metamethod recording. > This patch adds the corresponding check in `lj_record_call()`. > > Sergey Kaplun: > * added the description and the test for the problem > --- > > Tarantool branch: https://github.com/tarantool/tarantool/tree/skaplun/gh-noticket-fix-slot-check-for-mm-record > Branch: https://github.com/tarantool/luajit/tree/skaplun/gh-noticket-fix-slot-check-for-mm-record > > src/lj_record.c | 2 + > .../fix-slot-check-for-mm-record.test.lua | 81 +++++++++++++++++++ > 2 files changed, 83 insertions(+) > create mode 100644 test/tarantool-tests/fix-slot-check-for-mm-record.test.lua > > diff --git a/src/lj_record.c b/src/lj_record.c > index 42af09e5..adf2370e 100644 > --- a/src/lj_record.c > +++ b/src/lj_record.c > @@ -731,6 +731,8 @@ void lj_record_call(jit_State *J, BCReg func, ptrdiff_t nargs) > J->framedepth++; > J->base += func+1+LJ_FR2; > J->baseslot += func+1+LJ_FR2; > + if (J->baseslot + J->maxslot >= LJ_MAX_JSLOTS) > + lj_trace_err(J, LJ_TRERR_STACKOV); > } > > /* Record tail call. */ > diff --git a/test/tarantool-tests/fix-slot-check-for-mm-record.test.lua b/test/tarantool-tests/fix-slot-check-for-mm-record.test.lua > new file mode 100644 > index 00000000..e361830d > --- /dev/null > +++ b/test/tarantool-tests/fix-slot-check-for-mm-record.test.lua > @@ -0,0 +1,81 @@ > +local tap = require('tap') > + > +local test = tap.test('fix-slot-check-for-mm-record') > +test:plan(2) > + > +-- Before the patch, JIT compiler doesn't check slots overflow > +-- for recording of metamethods call. So the assertion checking > +-- that we don't overflow the slots limit (the limit > +-- `LJ_MAX_JSLOTS` is 250) is failing, when we record metamethod > +-- call (`J->baseslot` diff + `J->maxslot` ~ 5-8 stack slots), > +-- while almost all slots of JIT engine are occupied. > + > +-- Table with the simplest metamethod to call. > +local a0 = setmetatable({}, { > + __add = function(t, arg1) > + t[arg1] = arg1 > + end > +}) > +_G.a0 = a0 > + > +-- Fixarg function with call to metamethod. > +local function a1() > + -- This constant is not setted as an upvalue to simplify stack ^^^^^^ set > + -- slots counting. Just remember that it is 42. > + return a0 + 42 > +end > +_G.a1 = a1 > + > +-- Generate bunch of functions to call them recursively. > +-- Each function is a vararg function bumps slots on > +-- 2 (4) = 1 (2) * 2 for usual Lua frame and vararg frame > +-- recording for GC32 (GC64). > +for i = 2, 121 do > + local f, err = load(('local r = a%d() return r'):format(i - 1)) > + assert(f, err) > + _G['a'..i] = f > +end > + > +-- Trace is long enough, so we need to increase maxrecord. > +jit.opt.start('hotloop=1', 'maxrecord=2048') > + > +local function test_gc32() > + -- 1 - Base slot. > + -- 3 slots for cycle start, stop, step. > + for _ = 1, 4 do > + -- Occupy 1 slot for the function itself + 2 next slots will > + -- occupied for a call to the vararg function. > + -- Need 121 calls: 7 (baseslot after `a121()` is recorded) > + -- + 119 * 2 + 1 (`a1` -- is not vararg function) = 246 slots. > + -- The next call of metamethod in `a0` to record have 2 args > + -- + 2 slots for metamethod function + 1 slot for frame. > + -- luacheck: no global > + a121() > + assert(a0[42] == 42) > + a0[42] = nil > + end > + return true > +end > + > +local function test_gc64() > + -- 2 - Base slot. > + -- 3 slots for cycle start, stop, step. > + for _ = 1, 4 do > + -- Occupy 1 slot for the function itself + 4 next slots will > + -- occupied for a call to the vararg function. > + -- Need 60 calls: 10 (baseslot after `a60()` is recorded) > + -- + 58 * 4 + 2 (`a1` -- is not vararg function) = 244 slots. > + -- The next call of metamethod in `a0` to record have 2 args > + -- + 3 slots for metamethod function + 2 slots for frame. > + -- luacheck: no global > + a60() > + assert(a0[42] == 42) > + a0[42] = nil > + end > + return true > +end > + > +test:ok(test_gc32()) > +test:ok(test_gc64()) > + > +os.exit(test:check() and 0 or 1) > -- > 2.31.0 >
next prev parent reply other threads:[~2022-03-25 15:51 UTC|newest] Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-10-22 11:46 Sergey Kaplun via Tarantool-patches 2022-03-25 15:51 ` sergos via Tarantool-patches [this message] 2022-03-28 10:02 ` Sergey Kaplun via Tarantool-patches 2022-03-30 10:02 ` sergos via Tarantool-patches 2022-04-06 7:21 ` Sergey Kaplun via Tarantool-patches 2022-06-27 19:58 ` Igor Munkin via Tarantool-patches 2022-06-28 6:39 ` Sergey Kaplun via Tarantool-patches 2022-06-30 12:08 ` Igor Munkin via Tarantool-patches
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=A3F8323A-8A97-4DFF-AB90-A6521383AE77@tarantool.org \ --to=tarantool-patches@dev.tarantool.org \ --cc=sergos@tarantool.org \ --cc=skaplun@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH luajit] Add missing LJ_MAX_JSLOTS check.' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox