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 0428770349; Fri, 22 Oct 2021 14:48:40 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 0428770349 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1634903320; bh=Y5Ftc84RwpEzOGJIx7JszqhNl0f9L35TLtdt5OSLSFc=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=FVJLvot7ro8QVeVhxWfwgos9Vw0aCV+y44enrUdnl9TjCHYiNZ+J+cmo0+dBlclA4 yum4YJHaRpnXm78kIaYQ3OKbPGtIWJq0GoZz1aj6w8iE3hzaO8FRjqxX8ez8N9w3xz OXBcsYKnlJf2FRB41TmuARFM7y7yjg+dLXF5jKVw= Received: from smtp50.i.mail.ru (smtp50.i.mail.ru [94.100.177.110]) (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 3486670349 for ; Fri, 22 Oct 2021 14:48:38 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 3486670349 Received: by smtp50.i.mail.ru with esmtpa (envelope-from ) id 1mdt2L-0005a0-6R; Fri, 22 Oct 2021 14:48:37 +0300 To: Sergey Ostanevich , Igor Munkin Date: Fri, 22 Oct 2021 14:46:53 +0300 Message-Id: <20211022114653.4225-1-skaplun@tarantool.org> X-Mailer: git-send-email 2.31.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-7564579A: EEAE043A70213CC8 X-77F55803: 4F1203BC0FB41BD9C7814344C8C501C83238E3156CE19B78C95C7AD4390B7974182A05F538085040E43875D7F243BA2F7E52C51E74A82E640E362639544D148409262AD610E09F4E X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7A2F16E9F58889D70EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F79006370267BA244112F5C68638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D83E24769949DE7D0641995F3046906CFB117882F4460429724CE54428C33FAD305F5C1EE8F4F765FC2EE5AD8F952D28FBA471835C12D1D9774AD6D5ED66289B52BA9C0B312567BB23117882F446042972877693876707352033AC447995A7AD186FD1C55BDD38FC3FD2E47CDBA5A96583BA9C0B312567BB2376E601842F6C81A19E625A9149C048EEC24E1E72F37C03A0E0F2381F647739FAD8FC6C240DEA7642DBF02ECDB25306B2B78CF848AE20165D0A6AB1C7CE11FEE36A1CB4668A9CA5FA302FCEF25BFAB345C4224003CC836476EA7A3FFF5B025636E2021AF6380DFAD1A18204E546F3947CB11811A4A51E3B096D1867E19FE1407959CC434672EE6371089D37D7C0E48F6C8AA50765F79006371F24DFF1B2961425731C566533BA786AA5CC5B56E945C8DA X-B7AD71C0: AC4F5C86D027EB782CDD5689AFBDA7A213B5FB47DCBC3458834459D11680B505BC4F40A26706D2C452C70EC428301206 X-C1DE0DAB: C20DE7B7AB408E4181F030C43753B8186998911F362727C414F749A5E30D975C36D3CF9385F5124ECC69E8CCA131968496AEE641A7AF4E049C2B6934AE262D3EE7EAB7254005DCEDDD01B8980DE9A8611E0A4E2319210D9B64D260DF9561598F01A9E91200F654B02272C4C079A4C8AD93EDB24507CE13387DFF0A840B692CF8 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D34AC632F0BE69382F33F37398EEE6E50555D73B3DD3659697D9D0A005A6B0249339A57A74B485CB5B71D7E09C32AA3244C2B1E521540A21A2E8106E27E6075E962A95CA90A1D8AC565927AC6DF5659F194 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojoAoFOtfvdI1Fa+DfP+LAog== X-Mailru-Sender: 583F1D7ACE8F49BDE0FCA1347FF714A1FF37085EB0BFAD0262234E0ADCBCB61D0CCAF959E80A5802525762887713E5F1475755348978188EF9D3679FA3DE6E791CC59163FFD68303112434F685709FCF0DA7A0AF5A3A8387 X-Mras: Ok Subject: [Tarantool-patches] [PATCH luajit] Add missing LJ_MAX_JSLOTS check. 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 Yichun Zhang. (cherry picked from commit 630ff3196a06353c6a7ccd1e9ac3958f4a8ca13c) Before the patch, JIT compiler doesn't check slots overflow for 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, when we record metamethod call (`J->baseslot` diff + `J->maxslot` ~ 5-8 stack slots), while almost all slots of JIT engine are occupied. 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 + -- 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