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 9F9766EC58; Sun, 1 Aug 2021 14:06:59 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 9F9766EC58 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1627816019; bh=uvgs4k/WI1cP5ipXXVepuCD0l7imIbFk5596TuzYo+8=; h=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=RrVNQ8C0h2BQ5KtIYGv6dDM8TBceZtrgpky9LnRp/Nd/uZBWRQ+gE3oNpILy307yV C31PXKm2z5ElGs4ncWOXdUX/Y+E6xjXG48ODGMOrZkRbuhWmLTqgWPBNDEiBr1/RO9 RYPY5R1IjlGHsZulncl3qfe7jQoIDI0sT7Wau440= Received: from smtpng1.i.mail.ru (smtpng1.i.mail.ru [94.100.181.251]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id BA52D6EC58 for ; Sun, 1 Aug 2021 14:06:56 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org BA52D6EC58 Received: by smtpng1.m.smailru.net with esmtpa (envelope-from ) id 1mA9J1-00053w-Iz; Sun, 01 Aug 2021 14:06:56 +0300 Date: Sun, 1 Aug 2021 13:43:18 +0300 To: Sergey Kaplun Message-ID: <20210801104318.GZ27855@tarantool.org> References: <20210719073632.12008-1-skaplun@tarantool.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20210719073632.12008-1-skaplun@tarantool.org> X-Clacks-Overhead: GNU Terry Pratchett User-Agent: Mutt/1.10.1 (2018-07-13) X-4EC0790: 10 X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD941C43E597735A9C366EE405EC28A2001F8302D8429E0DE58182A05F53808504092FCF8AB22B653AC16C8AD213FBA8C527BA8819DD3EB730EBC77B4210FEEAD0D X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE77633BACAB33B9508C2099A533E45F2D0395957E7521B51C2CFCAF695D4D8E9FCEA1F7E6F0F101C6778DA827A17800CE7B3BECF8700137300EA1F7E6F0F101C6723150C8DA25C47586E58E00D9D99D84E1BDDB23E98D2D38BBCA57AF85F7723F200F03D530D3F642363865C407397458FCC7F00164DA146DAFE8445B8C89999728AA50765F79006372A3B24BF85B2E607389733CBF5DBD5E9C8A9BA7A39EFB766F5D81C698A659EA7CC7F00164DA146DA9985D098DBDEAEC87AE820D2C17D0E56F6B57BC7E6449061A352F6E88A58FB86F5D81C698A659EA7E827F84554CEF5019E625A9149C048EE9ECD01F8117BC8BEE2021AF6380DFAD18AA50765F790063735872C767BF85DA227C277FBC8AE2E8BC6A536F79815AD9275ECD9A6C639B01B4E70A05D1297E1BBCB5012B2E24CD356 X-C1DE0DAB: 0D63561A33F958A565E8CB11F5ECF281E74FC8A17205E99FF7AEC32E5FFEA7A7D59269BC5F550898D99A6476B3ADF6B47008B74DF8BB9EF7333BD3B22AA88B938A852937E12ACA751B940EDA0DFB0535410CA545F18667F91A7EA1CDA0B5A7A0 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D34B8CF715B894FC711703ACF69B1C9ADA375527A5179923224A2465A7340686BFC2CDA96C0F72BEC2D1D7E09C32AA3244CC4453B10E1B95724405C7B72E51588C48580396430872480927AC6DF5659F194 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojMCfuYI4PreeQC1rGgVXhyA== X-Mailru-Sender: 689FA8AB762F7393C37E3C1AEC41BA5D5ACD292A934B08155C856578A4B52F21A7C8D0F45F857DBFE9F1EFEE2F478337FB559BB5D741EB964C8C2C849690F8E70A04DAD6CC59E33667EA787935ED9F1B X-Mras: Ok Subject: Re: [Tarantool-patches] [PATCH luajit] Fix bytecode register allocation for comparisons. 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: Igor Munkin via Tarantool-patches Reply-To: Igor Munkin Cc: tarantool-patches@dev.tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" Sergey, Thanks for the patch! Please consider the comments below. I didn't check the test yet, since I don't get the JIT peculiarities from your commit message and comments. Please provide a clearer description and I'll proceed with the review of the test case then. On 19.07.21, Sergey Kaplun wrote: > From: Mike Pall > > (cherry picked from commit 2f3f07882fb4ad9c64967d7088461b1ca0a25d3a) > > When LuaJIT is build with LJ_FR2 (GC64), information about frame takes > two slots -- the first takes the TValue with the function to call, the > second takes the additional frame information. The recording JIT Minor: The second slot is the framelink in LuaJIT terms. > machinery works pretty the same -- the function IR_KGC is loaded in the > first slot, and the second is set to TREF_FRAME value. This value > should be rewritten after return from a callee. It is done either by the > return values either this slot is cleared (set to zero) manually with > the next bytecode with RA dst mode with the assumption, that the dst RA > takes the next slot after TREF_FRAME, i.e. an earlier instruction uses > the smallest possible destination register (see `lj_record_ins()` for > the details). The main point lies in the monstrous 5-line sentence. I've read several times, but still don't get it. Could you please reword it in a not such complex sentence? > > Bytecode allocator swaps operands for ISGT and ISGE comparisons. > When it happens, the aforementioned rule for registers allocations > may be violated. When it happens, and this chunk is recording, the slot > with TREF_FRAME is not rewritten (but the next empty slot after > TREF_FRAME is) during bytecode recording. This leads to JIT slots > inconsistency and assertion failure in `rec_check_slots()` during > recording the next bytecode instruction. > > This patch fixes bytecode register allocation by changing the register > allocation order in case of ISGT and ISGE bytecodes. It's better to use "virtual register" or even "VM register" to avoid ambiguous plain "register" usage. > > Sergey Kaplun: > * added the description and the test for the problem > > Resolves tarantool/tarantool#6227 Minor: Why #5629 is not mentioned? > --- > > Branch: https://github.com/tarantool/luajit/tree/skaplun/gh-6227-fix-bytecode-allocator-for-comp > Tarantool branch: https://github.com/tarantool/tarantool/tree/skaplun/gh-6227-fix-bytecode-allocator-for-comp > Issue: https://github.com/tarantool/tarantool/issues/6227 > > src/lj_parse.c | 7 +++- > ...ytecode-allocator-for-comparisons.test.lua | 41 +++++++++++++++++++ > 2 files changed, 46 insertions(+), 2 deletions(-) > create mode 100644 test/tarantool-tests/gh-6227-bytecode-allocator-for-comparisons.test.lua > > diff --git a/src/lj_parse.c b/src/lj_parse.c > index 08f7cfa6..a6325a76 100644 > --- a/src/lj_parse.c > +++ b/src/lj_parse.c > @@ -853,9 +853,12 @@ static void bcemit_comp(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2) > e1 = e2; e2 = eret; /* Swap operands. */ > op = ((op-BC_ISLT)^3)+BC_ISLT; > expr_toval(fs, e1); > + ra = expr_toanyreg(fs, e1); > + rd = expr_toanyreg(fs, e2); > + } else { > + rd = expr_toanyreg(fs, e2); > + ra = expr_toanyreg(fs, e1); > } > - rd = expr_toanyreg(fs, e2); > - ra = expr_toanyreg(fs, e1); > ins = BCINS_AD(op, ra, rd); > } > /* Using expr_free might cause asserts if the order is wrong. */ > diff --git a/test/tarantool-tests/gh-6227-bytecode-allocator-for-comparisons.test.lua b/test/tarantool-tests/gh-6227-bytecode-allocator-for-comparisons.test.lua > new file mode 100644 > index 00000000..66f6885e > --- /dev/null > +++ b/test/tarantool-tests/gh-6227-bytecode-allocator-for-comparisons.test.lua > @@ -0,0 +1,41 @@ > +local tap = require('tap') > +local test = tap.test('gh-6227-bytecode-allocator-for-comparisons') > +test:plan(1) > + > +-- Test file to demonstrate assertion failure during recording > +-- wrong allocated bytecode for comparisons. > +-- See also https://github.com/tarantool/tarantool/issues/6227. > + > +-- Need function with RET0 bytecode to avoid reset of > +-- the first JIT slot with frame info. Also need no assignments > +-- by the caller. > +local function empty() end > + > +local uv = 0 > + > +-- This function needs to reset register enumerating. > +-- Also set `J->maxslot` to zero. > +-- The upvalue function to call is loaded to 0 slot. > +local function bump_frame() > + -- First call function with RET0 to set TREF_FRAME in the > + -- last slot. > + empty() > + -- Test ISGE or ISGT bytecode. These bytecodes swap their > + -- operands. Also, a constant is always loaded into the slot > + -- smaller than upvalue. So, if upvalue loads before KSHORT, > + -- then the difference between registers is more than 2 (2 is > + -- needed for LJ_FR2) and TREF_FRAME slot is not rewriting by > + -- the bytecode after call and return as expected. That leads > + -- to recording slots inconsistency and assertion failure at > + -- `rec_check_slots()`. > + empty(1>uv) > +end > + > +jit.opt.start('hotloop=1') > + > +for _ = 1,3 do > + bump_frame() > +end > + > +test:ok(true) > +os.exit(test:check() and 0 or 1) > -- > 2.31.0 > -- Best regards, IM