From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id A29D95B405D; Fri, 25 Aug 2023 18:05:12 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org A29D95B405D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1692975912; bh=mm0xnTooZvAoJ2hxRzxr/m9FkNVqyeY5qXxCa3tWtc8=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=e9X8wXQHQNN1YbOoM6yv6O20sdGQ3WvBvkE+VHh8PzLih/MSBj+zX4uQIoXVjLBW8 Ke5pRzsg34oL/UXxgb60p1a4EmHclr8hASWlTbD6+7p8rWAfCPLAmuHaxy0rtIlp1G qNQa4DoTckAFGfEK0Ig7Nr/hgsPjiJQbG8p9zVSM= Received: from smtp44.i.mail.ru (smtp44.i.mail.ru [95.163.41.82]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id E16CC553E0B for ; Fri, 25 Aug 2023 18:05:10 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org E16CC553E0B Received: by smtp44.i.mail.ru with esmtpa (envelope-from ) id 1qZYN3-00385E-1n; Fri, 25 Aug 2023 18:05:10 +0300 To: Maxim Kokryashkin , Sergey Bronnikov Date: Fri, 25 Aug 2023 18:00:24 +0300 Message-ID: <20230825150024.23247-1-skaplun@tarantool.org> X-Mailer: git-send-email 2.41.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Mailru-Src: smtp X-7564579A: B8F34718100C35BD X-77F55803: 4F1203BC0FB41BD9954329A9C7AF96E95E2F5ED1E806A3C3476BCD21812BC244182A05F538085040C20FB1023F894AAD5E354A12E1D725EA71F270978A2D5BE9CCC8394DA1DA2D7C X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE70FFC2100EB7B6895EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F79006373BFF7CCD9F2968778638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D8937F3C303D6A0B14EE64884E59468D84117882F4460429724CE54428C33FAD305F5C1EE8F4F765FCD2F7BF8B8A2C6FD9A471835C12D1D9774AD6D5ED66289B52BA9C0B312567BB23117882F446042972877693876707352026055571C92BF10F2CC0D3CB04F14752D2E47CDBA5A96583BA9C0B312567BB2376E601842F6C81A19E625A9149C048EE26055571C92BF10F302FCEF25BFAB3454AD6D5ED66289B523666184CF4C3C14F6136E347CC761E07725E5C173C3A84C3A367EA73E0D98AAD76E601842F6C81A1F004C906525384303E02D724532EE2C3F43C7A68FF6260569E8FC8737B5C22494854413538E1713FE827F84554CEF50127C277FBC8AE2E8BF1175FABE1C0F9B6AAAE862A0553A39223F8577A6DFFEA7C747589E6AAA3516243847C11F186F3C59DAA53EE0834AAEE X-C1DE0DAB: 0D63561A33F958A5C587996983C3ADED368C8DF137A79E807EF99FC0F73872F6F87CCE6106E1FC07E67D4AC08A07B9B06A1CB4668A9CA5FA9C5DF10A05D560A950611B66E3DA6D700B0A020F03D25A0997E3FB2386030E77 X-C8649E89: 1C3962B70DF3F0ADE00A9FD3E00BEEDF77DD89D51EBB7742D3581295AF09D3DF87807E0823442EA2ED31085941D9CD0AF7F820E7B07EA4CF543E85744BB438ECB85DF5C16D073F1605FEF957D3908517807B207FC3EFE21C12B9ACBE231CC78A65277D9847CC050AD98DE56B79E247FA52E1DBD52E90D426A74DFFEFA5DC0E7F02C26D483E81D6BE5EF9655DD6DEA7D65774BB76CC95456EEC5B5AD62611EEC62B5AFB4261A09AF0 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojyVV/YwCnDiQOQcp8ZTIPtg== X-Mailru-Sender: 11C2EC085EDE56FAC07928AF2646A769590B8A43A23478645E354A12E1D725EA5F9045B74F665CC8DEDBA653FF35249392D99EB8CC7091A70E183A470755BFD208F19895AA18418972D6B4FCE48DF648AE208404248635DF X-Mras: Ok Subject: [Tarantool-patches] [PATCH luajit] Fix maxslots when recording BC_TSETM. X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Sergey Kaplun via Tarantool-patches Reply-To: Sergey Kaplun Cc: tarantool-patches@dev.tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" From: Mike Pall Analyzed by Sergey Kaplun. (cherry-picked from commit 0cc5fdfbc0810073485150eb184dc358dab507d9) Recording of the `BC_TSETM` bytecode may keep too optimistic JIT maxslot. In that case, the slot above the top of the Lua stack may be considered used. When any VM event handler is called before the recording of the next instruction, this leads to an assertion failure in `rec_check_slots()`. This patch sets the `ra` as a maxslot, as far as the `ra` - 1 contains a table, which is always the highest slot after this bytecode. Also, it adds an assertion that we check slots below the top of the Lua stack. Sergey Kaplun: * added the description and the test for the problem Part of tarantool/tarantool#8825 --- Branch: https://github.com/tarantool/luajit/tree/skaplun/lj-1025-tsetm-maxslot Tarantool PR: https://github.com/tarantool/tarantool/pull/9040 Issues: * https://github.com/LuaJIT/LuaJIT/issues/1025 * https://github.com/tarantool/tarantool/issues/8825 src/lj_record.c | 2 + .../lj-1025-tsetm-maxslot.test.lua | 52 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 test/tarantool-tests/lj-1025-tsetm-maxslot.test.lua diff --git a/src/lj_record.c b/src/lj_record.c index 34d1210a..58b040ec 100644 --- a/src/lj_record.c +++ b/src/lj_record.c @@ -115,6 +115,7 @@ static void rec_check_slots(jit_State *J) cTValue *tv = &base[s]; IRRef ref = tref_ref(tr); IRIns *ir = NULL; /* Silence compiler. */ + lj_assertJ(tv < J->L->top, "slot %d above top of Lua stack", s); if (!LJ_FR2 || ref || !(tr & (TREF_FRAME | TREF_CONT))) { lj_assertJ(ref >= J->cur.nk && ref < J->cur.nins, "slot %d ref %04d out of range", s, ref - REF_BIAS); @@ -2342,6 +2343,7 @@ void lj_record_ins(jit_State *J) case BC_TSETM: rec_tsetm(J, ra, (BCReg)(J->L->top - J->L->base), (int32_t)rcv->u32.lo); + J->maxslot = ra; /* The table slot at ra-1 is the highest used slot. */ break; case BC_TNEW: diff --git a/test/tarantool-tests/lj-1025-tsetm-maxslot.test.lua b/test/tarantool-tests/lj-1025-tsetm-maxslot.test.lua new file mode 100644 index 00000000..7ae0a99d --- /dev/null +++ b/test/tarantool-tests/lj-1025-tsetm-maxslot.test.lua @@ -0,0 +1,52 @@ +local tap = require('tap') + +-- Test file to demonstrate LuaJIT incorrect recording of `TSETM` +-- bytecode. +-- See also: https://github.com/LuaJIT/LuaJIT/issues/1025. + +local test = tap.test('lj-1025-tsetm-maxslot'):skipcond({ + ['Test requires JIT enabled'] = not jit.status(), +}) + +test:plan(1) + +local jit_dump = require('jit.dump') + +local TEST_VALUE = '5' +local TEST_IDX = 5 + +local function slot5() + return nil, nil, nil, nil, TEST_VALUE +end + +local storage +local function test_tsetm(...) + -- Usage of `TSETM` bytecode. + storage = {slot5()} + -- Use this function again to trick use-def analysis and avoid + -- cleaning JIT slots, so the last JIT slot contains + -- `TEST_VALUE`. + return slot5(...) +end + +-- Wrapper to avoid the recording of just the inner `slot5()` +-- function. +local function wrap() + test_tsetm() +end + +jit.opt.start('hotloop=1') +-- We need to call the VM event handler after each recorded bytecode +-- instruction to pollute the Lua stack and the issue +-- becomes observable. +jit_dump.start('b', '/dev/null') + +-- Compile and execute the trace with `TSETM`. +wrap() +wrap() +wrap() + +test:is(storage[TEST_IDX], TEST_VALUE, + 'BC_TSETM recording with enabled jit.dump') + +test:done(true) -- 2.41.0