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 42B035BC4B2; Tue, 29 Aug 2023 15:41:30 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 42B035BC4B2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1693312890; bh=fc0oL5uacbNmSaX5QdMuRW6Y68iy4CnUMicGD9y7YXc=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=EVlYPt9mx57QFiTgv1yJo9vDuukt+HRwyvCrHlbQUBhkTtGxNOWlaJCUZb5ENWWUh siTlV1TYV0mL2MN3Y8+L569PwOwAu46eASllW+Srm+XXwGpTcmQpDRupCZtpuPLUUa F5D+cBxShW7/9zQCmFBj2BH5DYk67N20JQabi7tk= Received: from smtp61.i.mail.ru (smtp61.i.mail.ru [95.163.41.99]) (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 CEC1F5BC4B2 for ; Tue, 29 Aug 2023 15:41:28 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org CEC1F5BC4B2 Received: by smtp61.i.mail.ru with esmtpa (envelope-from ) id 1qay2A-005aZ7-1m; Tue, 29 Aug 2023 15:41:27 +0300 To: Maxim Kokryashkin , Sergey Bronnikov Date: Tue, 29 Aug 2023 15:36:41 +0300 Message-ID: <20230829123641.3303-1-skaplun@tarantool.org> X-Mailer: git-send-email 2.42.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Mailru-Src: smtp X-7564579A: 78E4E2B564C1792B X-77F55803: 4F1203BC0FB41BD9AE2E1BB6058F4E36552EA1C3F1CF6DBD59AE557CBA416E4D182A05F538085040A5DA2B2BEF93EA454B8DE1A5C30AB4A234CE005AE55E1BDFBCB4625F635B37CF X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE707314F92EEE30EB3EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F790063721F819F5952827038638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D8EA624BB4CBA1D4E503C337220F35F397117882F4460429724CE54428C33FAD305F5C1EE8F4F765FC972D20C7389F068BA471835C12D1D9774AD6D5ED66289B52BA9C0B312567BB23117882F446042972877693876707352026055571C92BF10FCB629EEF1311BF91D2E47CDBA5A96583BA9C0B312567BB2376E601842F6C81A19E625A9149C048EE4B6963042765DA4B8F49F126DDB898E8D8FC6C240DEA76429C9F4D5AE37F343AA9539A8B242431040A6AB1C7CE11FEE3643FE6A0CAC512C7BA3038C0950A5D36B5C8C57E37DE458B330BD67F2E7D9AF16D1867E19FE14079C09775C1D3CA48CF3D321E7403792E342EB15956EA79C166A417C69337E82CC275ECD9A6C639B01B78DA827A17800CE7F45C1E71A9DFFA2A731C566533BA786AA5CC5B56E945C8DA X-C1DE0DAB: 0D63561A33F958A5CA8B9BB0BFB596285471A70F272457F8E69048E04F6EDF1BF87CCE6106E1FC07E67D4AC08A07B9B0BFD98ABA943BD70B9C5DF10A05D560A950611B66E3DA6D700B0A020F03D25A0997E3FB2386030E77 X-C8649E89: 1C3962B70DF3F0ADE00A9FD3E00BEEDF77DD89D51EBB7742D3581295AF09D3DF87807E0823442EA2ED31085941D9CD0AF7F820E7B07EA4CFF3E9146E09ECBD1CE8A32CBFDF2DF52F347E7349C6C3C99B64AF2076A434743E8135B9CF208C7BB75088795BE90126485C1ABE8B5B66AFDA8FC09948F53A0666A74DFFEFA5DC0E7F02C26D483E81D6BE5EF9655DD6DEA7D65774BB76CC95456EEC5B5AD62611EEC62B5AFB4261A09AF0 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojA5xtch+oMC66PL5VFdrzVw== X-Mailru-Sender: 11C2EC085EDE56FAC07928AF2646A769C7664E672ABA8D254B8DE1A5C30AB4A287D154BA7A9C8918DEDBA653FF35249392D99EB8CC7091A70E183A470755BFD208F19895AA18418972D6B4FCE48DF648AE208404248635DF X-Mras: Ok Subject: [Tarantool-patches] [PATCH luajit] Handle table unsinking in the presence of IRFL_TAB_NOMM. 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 Reported by Sergey Kaplun. (cherry-picked from commit 0ef51b495f9497aac77b41eb3d837c9c38b9424b) Table `NEWREF` storage for non-constant keys also emits `FREF` IR with `IRFL_TAB_NOMM` to invalidate the metamethod cache. When table creation and `NEWREF` are sinked, the corresponding `FSTORE` is sinked too and should be restored on trace exit. However, `snap_unsink()` doesn't expect anything except `IRFL_TAB_META` as the second operand of `FREF`, so the corresponding assertion fails. This patch adds a switch-case statement to handle the `IRFL_TAB_NOMM` case. Since `FREF` with `IRFL_TAB_NOMM` always follows some hash store, we can avoid a duplication of the cache invalidation, so this case just does nothing. 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-1052-unsink-with-irfl-tab-nomm Tarantool PR: https://github.com/tarantool/tarantool/pull/9055 Related issues: * https://github.com/LuaJIT/LuaJIT/issues/1052 * https://github.com/tarantool/tarantool/issues/8825 src/lj_snap.c | 18 +++++++--- ...lj-1052-unsink-with-irfl-tab-nomm.test.lua | 36 +++++++++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 test/tarantool-tests/lj-1052-unsink-with-irfl-tab-nomm.test.lua diff --git a/src/lj_snap.c b/src/lj_snap.c index 2dc281cb..6c5e5e53 100644 --- a/src/lj_snap.c +++ b/src/lj_snap.c @@ -836,11 +836,19 @@ static void snap_unsink(jit_State *J, GCtrace *T, ExitState *ex, irs->o == IR_FSTORE, "sunk store with bad op %d", irs->o); if (irk->o == IR_FREF) { - lj_assertJ(irk->op2 == IRFL_TAB_META, - "sunk store with bad field %d", irk->op2); - snap_restoreval(J, T, ex, snapno, rfilt, irs->op2, &tmp); - /* NOBARRIER: The table is new (marked white). */ - setgcref(t->metatable, obj2gco(tabV(&tmp))); + switch (irk->op2) { + case IRFL_TAB_META: + snap_restoreval(J, T, ex, snapno, rfilt, irs->op2, &tmp); + /* NOBARRIER: The table is new (marked white). */ + setgcref(t->metatable, obj2gco(tabV(&tmp))); + break; + case IRFL_TAB_NOMM: + /* Negative metamethod cache invalidated by lj_tab_set() below. */ + break; + default: + lj_assertJ(0, "sunk store with bad field %d", irk->op2); + break; + } } else { irk = &T->ir[irk->op2]; if (irk->o == IR_KSLOT) irk = &T->ir[irk->op1]; diff --git a/test/tarantool-tests/lj-1052-unsink-with-irfl-tab-nomm.test.lua b/test/tarantool-tests/lj-1052-unsink-with-irfl-tab-nomm.test.lua new file mode 100644 index 00000000..aaf5349f --- /dev/null +++ b/test/tarantool-tests/lj-1052-unsink-with-irfl-tab-nomm.test.lua @@ -0,0 +1,36 @@ +local tap = require('tap') + +-- Test file to demonstrate LuaJIT's incorrect restoration of a +-- table from a snapshot with the presence of `IRFL_TAB_NOMM`. +-- See also: https://github.com/LuaJIT/LuaJIT/issues/1052. + +local test = tap.test('lj-1052-unsink-with-irfl-tab-nomm'):skipcond({ + ['Test requires JIT enabled'] = not jit.status(), +}) + +test:plan(2) + +local TEST_VALUE = 'test' + +jit.opt.start('hotloop=1') + +local counter = 0 +local slot = 'slot' +while true do + counter = counter + 1 + -- Use a non-constant slot to emit `FREF` with `IRFL_TAB_NOMM`. + -- After re-emitting the variant part of the loop, NEWREF will + -- contain a constant key (see below). + slot = {[slot] = TEST_VALUE} + -- Emit exit here to be sure that the table will be restored + -- from the snapshot. + if counter > 2 then break end + -- We need a constant reference for NEWREF. Just use the old + -- value. + slot = 'slot' +end + +test:is(slot.slot, TEST_VALUE, 'correct table content') +test:ok(debug.getmetatable(slot) == nil, 'no metatable on the restored table') + +test:done(true) -- 2.42.0