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 4E6D5589F60; Tue, 15 Aug 2023 15:37:13 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 4E6D5589F60 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1692103033; bh=CZXUZSrLpjYgeiyNdjnpLSVDLwXg9A/jkHHdKEp9tTM=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=PKdJsWH9XxX+5TvM3009wrPHuvJdd8/QoqHwfgo3dFVDp3fxVgLmBQA+0DioFZ0kQ b2oxfx+nU5zwUwA9E9FVz6GQjN1M2TApIWDfW1OUsy2Fq3yBXyB+dT9qPTwbUCNj7M ujnB9lniawBUaz7iYGjJQ6WFAZ+/aELBpRuNZOHA= Received: from smtp35.i.mail.ru (smtp35.i.mail.ru [95.163.41.76]) (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 D268E589F43 for ; Tue, 15 Aug 2023 15:37:12 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org D268E589F43 Received: by smtp35.i.mail.ru with esmtpa (envelope-from ) id 1qVtIN-004o2m-2C; Tue, 15 Aug 2023 15:37:12 +0300 To: Maxim Kokryashkin , Sergey Bronnikov Date: Tue, 15 Aug 2023 15:32:15 +0300 Message-ID: <20230815123215.510-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: 78E4E2B564C1792B X-77F55803: 4F1203BC0FB41BD969E04B5EED670DC8BEB87106826C4595A10F7F5F18564AA6182A05F5380850408F523F9A066E9CD5F8E2196DD28887A68EC30B53C7FEB50F46127C0983810EEE X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7AED985C8E545F588EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637F63E14183F8C6AF98638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D8C76C7633F709EB62B8582883588DD3C9117882F4460429724CE54428C33FAD305F5C1EE8F4F765FC406C66621D3021AFA471835C12D1D9774AD6D5ED66289B52BA9C0B312567BB23117882F446042972877693876707352026055571C92BF10FCB629EEF1311BF91D2E47CDBA5A96583BA9C0B312567BB2376E601842F6C81A19E625A9149C048EE26055571C92BF10F452896749CDDA0A6D8FC6C240DEA76429C9F4D5AE37F343AA9539A8B242431040A6AB1C7CE11FEE32D01283D1ACF37BA03F1AB874ED89028C4224003CC836476E2F48590F00D11D6E2021AF6380DFAD1A18204E546F3947CB11811A4A51E3B096D1867E19FE1407978DA827A17800CE79F72382A8EA570EC2DBA43225CD8A89F890A246B268E114E42539A7722CA490CB5C8C57E37DE458BEDA766A37F9254B7 X-C1DE0DAB: 0D63561A33F958A5A7239FB2E88A674F9823AA1D841B1FA68AB6CE151B797D12F87CCE6106E1FC07E67D4AC08A07B9B013BDA61BF53F5E1D9C5DF10A05D560A950611B66E3DA6D700B0A020F03D25A0997E3FB2386030E77 X-C8649E89: 1C3962B70DF3F0ADE00A9FD3E00BEEDF77DD89D51EBB7742D3581295AF09D3DF87807E0823442EA2ED31085941D9CD0AF7F820E7B07EA4CF03B7468217DF75551EEE6E65590BF79971FE50157F221BAEFB8E8E6C1186CBC8DAFD28DA9052916A90ABE3E74E35EA6F7CE18B31E39450D4B8C31A33A44B59E7A74DFFEFA5DC0E7F02C26D483E81D6BE5EF9655DD6DEA7D65774BB76CC95456EEC5B5AD62611EEC62B5AFB4261A09AF0 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojHVl7ekwB6hh0NXfTEVvUNw== X-Mailru-Sender: 11C2EC085EDE56FAC07928AF2646A7692CCC7E620511755AF8E2196DD28887A6C59A7EFB72EB47B2DEDBA653FF35249392D99EB8CC7091A70E183A470755BFD208F19895AA18418972D6B4FCE48DF648AE208404248635DF X-Mras: Ok Subject: [Tarantool-patches] [PATCH luajit] Fix maxslots when recording BC_VARG, part 3. 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 Thanks to Peter Cawley. (cherry-picked from commit abb27c7771947e082c9d919d184ad5f5f03e2e32) In case, when `BC_VARG` set the VARG slot to the non-top stack slot, `maxslot` value was unconditionally set to the destination slot, so some top slots may be omitted in the snapshot entry. Since these slots are omitted, they are not restored correctly, when restoring from snapshot for this side exit. This patch adds the check for the aforementioned case, to avoid maxslot shrinking. 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-1046-fix-bc-varg-recording PR: https://github.com/tarantool/tarantool/pull/8986 Related issues: * https://github.com/LuaJIT/LuaJIT/issues/1046 * https://github.com/tarantool/tarantool/issues/8825 src/lj_record.c | 12 +++- .../lj-1046-fix-bc-varg-recording.test.lua | 58 +++++++++++++++++++ 2 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 test/tarantool-tests/lj-1046-fix-bc-varg-recording.test.lua diff --git a/src/lj_record.c b/src/lj_record.c index 34d1210a..6bcdb04c 100644 --- a/src/lj_record.c +++ b/src/lj_record.c @@ -1807,8 +1807,12 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) if (J->framedepth > 0) { /* Simple case: varargs defined on-trace. */ ptrdiff_t i; if (nvararg < 0) nvararg = 0; - if (nresults == -1) nresults = nvararg; - J->maxslot = dst + (BCReg)nresults; + if (nresults != 1) { + if (nresults == -1) nresults = nvararg; + J->maxslot = dst + (BCReg)nresults; + } else if (dst >= J->maxslot) { + J->maxslot = dst + 1; + } for (i = 0; i < nresults; i++) J->base[dst+i] = i < nvararg ? getslot(J, i - nvararg - 1 - LJ_FR2) : TREF_NIL; } else { /* Unknown number of varargs passed to trace. */ @@ -1840,7 +1844,9 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) } for (i = nvararg; i < nresults; i++) J->base[dst+i] = TREF_NIL; - J->maxslot = dst + (BCReg)nresults; + if (nresults != 1 || dst >= J->maxslot) { + J->maxslot = dst + (BCReg)nresults; + } } else if (select_detect(J)) { /* y = select(x, ...) */ TRef tridx = J->base[dst-1]; TRef tr = TREF_NIL; diff --git a/test/tarantool-tests/lj-1046-fix-bc-varg-recording.test.lua b/test/tarantool-tests/lj-1046-fix-bc-varg-recording.test.lua new file mode 100644 index 00000000..34c5c572 --- /dev/null +++ b/test/tarantool-tests/lj-1046-fix-bc-varg-recording.test.lua @@ -0,0 +1,58 @@ +local tap = require('tap') +local test = tap.test('lj-1046-fix-bc-varg-recording'):skipcond({ + ['Test requires JIT enabled'] = not jit.status(), +}) + +test:plan(2) + +jit.opt.start('hotloop=1') + +-- luacheck: ignore +local anchor +local N_ITER = 5 +local SIDE_ITER = N_ITER - 1 +for i = 1, N_ITER do + -- In case, when `BC_VARG` set the VARG slot to the non-top + -- stack slot, `maxslot` value was unconditionally set to the + -- destination slot, so the following snapshot is used: + -- SNAP #4 [ ---- ---- ---- nil ] + -- instead of: + -- SNAP #4 [ ---- nil ---- ---- 0009 0001 ---- 0009 ] + -- Since these slots are omitted, they are not restored + -- correctly, when restoring from snapshot for this side exit. + anchor = ... + if i > SIDE_ITER then + -- XXX: Don't use `test:ok()` here to avoid double-running of + -- tests in case of `i` incorrect restoring from the snapshot. + assert(i > SIDE_ITER) + end +end + +test:ok(true, 'BC_VARG recording 0th frame depth, 1 result') + +-- Now the same case, but with an additional frame, so VARG slots +-- are defined on the trace. +local function varg_frame(anchor, i, side_iter, ...) + anchor = ... + -- In case, when `BC_VARG` set the VARG slot to the non-top + -- stack slot, `maxslot` value was unconditionally set to the + -- destination slot, so the following snapshot is used: + -- SNAP #4 [ | nil nil nil `varg_frame` | nil ] + -- instead of: + -- SNAP #4 [ | nil nil nil `varg_frame` | nil 0009 0005 ] + -- Since these slots are omitted, they are not restored + -- correctly, when restoring from snapshot for this side exit. + if i > side_iter then + -- XXX: Don't use `test:ok()` here to avoid double-running of + -- tests in case of `i` incorrect restoring from the snapshot. + assert(i > side_iter) + end +end + +for i = 1, N_ITER do + varg_frame(nil, i, SIDE_ITER) +end + +test:ok(true, 'BC_VARG recording with VARG slots defined on trace, 1 result') + +test:done(true) -- 2.41.0