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 98C5E6EFEE; Sun, 28 Jun 2026 19:33:18 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 98C5E6EFEE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1782664398; bh=vdtZuTeTfW2YBN0kz3Lm337Ha95Gvf2CRfe3vuV69+k=; 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=KMqKpcZKGGVI2+BiNZjmAXAz6paM7qXOKDNV8N7Ywc43tIuFIY8MGQhEMvAPXWL1n W+gxwlUPQ64MJ87lavcYMdHZBHGCkJqrGK5zyhIJvH5F9xpR4RrfAob3whTNxJN0pB YNMXny37DeDXRL/0m+TwO0rQZSfZChG8AbD8o2KA= Received: from send34.i.mail.ru (send34.i.mail.ru [89.221.237.129]) (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 B43216EFEE for ; Sun, 28 Jun 2026 19:33:17 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org B43216EFEE Received: by exim-smtp-78b8b8c574-svnlg with esmtpa (envelope-from ) id 1wdsRY-00000000TOW-1YjE; Sun, 28 Jun 2026 19:33:17 +0300 Date: Sun, 28 Jun 2026 19:32:38 +0300 To: Evgeniy Temirgaleev Message-ID: References: <20260625202903.3157425-1-skaplun@tarantool.org> <20260625202903.3157425-2-skaplun@tarantool.org> <1782608610.240669306@f725.i.mail.ru> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <1782608610.240669306@f725.i.mail.ru> X-Mailru-Src: smtp X-4EC0790: 10 X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD918D6BB028DF8CB61525AEE36BB2062474470531DE4816542182A05F5380850400FC95EAFEAB7C4243DE06ABAFEAF6705A72736F799998F254CE5878E25C57AE95A4E529B88FDD277 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE76ABD3380F320B62CEA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637AC83A81C8FD4AD23D82A6BABE6F325AC2E85FA5F3EDFCBAA7353EFBB553375667A8D271431AA2D75E485CCB8383E159FC4C031D853CD95626D6C3ADF685D60D0389733CBF5DBD5E913377AFFFEAFD269176DF2183F8FC7C0A29E2F051442AF778941B15DA834481FCF19DD082D7633A0EF3E4896CB9E6436389733CBF5DBD5E9D5E8D9A59859A8B6E5E764EB5D94DBD4CC7F00164DA146DA6F5DAA56C3B73B237318B6A418E8EAB86D1867E19FE14079C09775C1D3CA48CF3D321E7403792E342EB15956EA79C166A417C69337E82CC275ECD9A6C639B01B78DA827A17800CE7B2B7C64F398C7410731C566533BA786AA5CC5B56E945C8DA X-C1DE0DAB: 0D63561A33F958A5A87D424CF940A6395002B1117B3ED696C0E3C9E40944B692E772F934B9BCD185823CB91A9FED034534781492E4B8EEADA3FB0D9844EF8EC5BDAD6C7F3747799A X-C8649E89: 1C3962B70DF3F0AD73CAD6646DEDE191716CD42B3DD1D34CAB70F9BE574AE9C625B6776AC983F447FC0B9F89525902EE6F57B2FD27647F25E66C117BDB76D65935451D6A5554BF21E4CD964A1AE099737A4CEE942917430B650274AE6D559AF7510E95FFBB26F1EEB8341EE9D5BE9A0AA4B3A68352B58FA79E6AF8549A990DE305DDA53617F621DB6536EB022892E5344C41F94D744909CECFA6C6B0C050A61A8CAF69B82BA93681CD72808BE417F3B9E0E7457915DAA85F X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu53w8ahmwBjZKM/YPHZyZHvz5uv+WouB9+ObcCpyrx6l7KImUglyhkEat/+ysWwi0gdhEs0JGjl6ggRWTy1haxBpVdbIX1nthFXMZebaIdHP2ghjoIc/363UZI6Kf1ptIMVRSZSJkMhZtMznqq68ujNs0= X-DA7885C5: 4E157509695CC6B6F255D290C0D534F922D2DB24FC8D985EA6192483DF6D0ECC76373D233D39B8845B1A4C17EAA7BC4BEF2421ABFA55128DAF83EF9164C44C7E X-Mailru-Sender: 689FA8AB762F7393520AF17B8A65FDE228D5CA66607FE2127506CCBC957D0E1DFC012249CBF9BAD4E49D44BB4BD9522A059A1ED8796F048DB274557F927329BE89D5A3BC2B10C37545BD1C3CC395C826B4A721A3011E896F X-Mras: Ok Subject: Re: [Tarantool-patches] [PATCH luajit 1/3] dbg: introduce lj-ir, lj-jslots, lj-trace dumpers 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" Hi, Evgeniy! Thanks for the review! See my answers below. Branch is force-pushed with the fixes. On 28.06.26, Evgeniy Temirgaleev wrote: > Hi, Sergey! > > Thanks for the patch. Please, see my comments. > > -- > Best regards, > Evgeniy Temirgaleev > > > > > От кого: Sergey Kaplun > > Кому: Sergey Bronnikov , Evgeniy Temirgaleev > > > > Копия: tarantool-patches@dev.tarantool.org, Sergey Kaplun > > > > Дата: Четверг, 25 июня 2026, 23:29 +03:00 > > This patch adds dumpers for a single IR instruction (`lj-ir`), as well > > as for all bytecodes inside one trace (`lj-trace`). Its dump is quite > > similar to the -jdump flag but also reports types of register operands > > (`ref`, `lit`, `cst`) and operation mode (`N`, `A`, `W`, etc.). > > The `lj-trace` command accepts optional /rs flags to dump registers > > associated with IR and snapshots for the trace correspondingly. > > The `lj-ir` command can be used for dumping IR constants as well. > > The `lj-jslots` command dumps the content of `J->slot`. It is useful to > > simplify debugging of `rec_check_slots()` assertion failures. > > > > For LLDB value, the `__getitem__` metamethod now accepts bool keys. > > Also, `__index__` is set to allow lldb.value to be used as an index > > without explicit conversion to int. Old GDB versions (below 7.12) are > > not supported because of the gdb.Value lacks the `__index__` metamethod > > and can't be monkey-patched. The support for these versions may be added > > by demand. > > > > Part of tarantool/tarantool#4808 > > --- > > src/luajit_dbg.py | 1216 ++++++++++++++++- > > .../debug-extension-tests.py | 365 +++++ > > 2 files changed, 1570 insertions(+), 11 deletions(-) > > > > diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py > > index 2edb199a..fd6ca8a5 100644 > > --- a/src/luajit_dbg.py > > +++ b/src/luajit_dbg.py > > + if tp.GetTypeClass() == lldb.eTypeClassStruct: > > + len_fields = tp.GetNumberOfFields() > > + for n_field in range(len_fields): > > + islast = n_field == (len_fields - 1) > > + field = tp.GetFieldAtIndex(n_field) > > + start_field = field.GetOffsetInBytes() > > + if not islast: > > + end_field = tp.GetFieldAtIndex( > > + n_field + 1 > > + ).GetOffsetInBytes() > > + else: > > + end_field = tp.GetByteSize() > > + if start_field <= offset and offset < end_field: > > + next_name = self.member_by_offset( > > + field.GetType(), > > + offset - start_field, > > + prev_name=field.GetName() > > + ) > > + return '.{field}{suffix}'.format( > > + field=field.GetName(), > > + suffix=next_name if next_name else '' > > + ) > > + if tp.GetTypeClass() == lldb.eTypeClassArray: > > > > Typo?: elif Fixed, thanks! =================================================================== diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py index 62cd65d5..3b7cf7a1 100644 --- a/src/luajit_dbg.py +++ b/src/luajit_dbg.py @@ -657,7 +657,7 @@ class _LLDBDebugger(Debugger): field=field.GetName(), suffix=next_name if next_name else '' ) - if tp.GetTypeClass() == lldb.eTypeClassArray: + elif tp.GetTypeClass() == lldb.eTypeClassArray: # Get array field type. target = tp.GetArrayElementType() tsize = target.GetByteSize() =================================================================== > > +# Mode bits: Commutative, {Normal/Ref, Alloc, Load, Store}, > > +# Non-weak guard. */ > > > > Typo: C comment end */ Removed, thanks! =================================================================== diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py index 62cd65d5..3b7cf7a1 100644 @@ -1612,12 +1612,16 @@ IRS = [ # Mode bits: Commutative, {Normal/Ref, Alloc, Load, Store}, -# Non-weak guard. */ +# Non-weak guard. IRM_C = 0x10 IRM_A = 0x20 IRM_L = 0x40 =================================================================== > > > > > +IRM_C = 0x10 > > +IRM_A = 0x20 > > +IRM_L = 0x40 > > +IRM_S = 0x60 > > +IRM_W = 0x80 > > + > > + > > +# IR operand mode (2 bit). > > +IRM = [ > > + 'ref', > > + 'lit', > > + 'cst', > > + '', # none > > +] > > + > > + > > +lj_ir_mode_ = None > > + > > + > > +def lj_ir_mode(): > > + global lj_ir_mode_ > > + if lj_ir_mode_: > > + return lj_ir_mode_ > > + lj_ir_mode_ = dbg.lookup_global('lj_ir_mode') > > + return lj_ir_mode_ > > + > > + > > +def ir_left(op): > > + return IRM[int(lj_ir_mode()[op] & 3)] > > > > May be binary constant will be more clear? xxx & 0b0011 I prefer to leave it consistent with the original sources, see . Also, the bc decoding has the same format. > > > > > + > > + > > +def ir_right(op): > > + return IRM[int(lj_ir_mode()[op] >> 2 & 3)] > > > > May be binary constant will be more clear? (xxx & 0b1100) >> 2 Ditto. > > > > > + > > + > > +def ir_mode(op): > > + mode = '' > > + ir_mode = int(lj_ir_mode()[op] ^ IRM_W) > > > > > > > + if ir_mode == IRM_C: > > + mode = 'C' > > + elif ir_mode == IRM_A: > > + mode = 'A' > > + elif ir_mode == IRM_L: > > + mode = 'L' > > + elif ir_mode == IRM_S: > > + mode = 'S' > > + else: > > + mode = 'N' > > > > > > > + mode += 'W' if ir_mode & IRM_W else '' > > > > May be table with 16 items and comments will be more clear? E. g. return XXX[(lj_ir_mode()[op] & 0b11110000) >> 4] > And it will contain invalid values also. > # > XXX[0b0000] = ‘NW’ # Normal/Ref | !Non-weak guard > XXX[0b0001] = ‘CW’ # Commutative | !Non-weak guard > XXX[0b0011] = ‘Invalid’ > ... > XXX[0b1000] = ‘N’ # Normal/Ref | Non-weak guard > XXX[0b1001] = ‘C’ # Commutative | Non-weak guard > XXX[0b1011] = ‘Invalid’ > ... Rewrote with table usage as the following: Also, you help me to notice that the original implementation was incorrect (due to bits of operand modes after xor). Tests was corrupted as well, fixed. Thanks! =================================================================== diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py index d4f89eb5..32b0cea7 100644 --- a/src/luajit_dbg.py +++ b/src/luajit_dbg.py @@ -1613,11 +1613,15 @@ IRS = [ # Mode bits: Commutative, {Normal/Ref, Alloc, Load, Store}, # Non-weak guard. -IRM_C = 0x10 -IRM_A = 0x20 -IRM_L = 0x40 -IRM_S = 0x60 -IRM_W = 0x80 +IRM_BITS_W = 0x80 +IRM_BITS = { + 0x00: 'N', + 0x10: 'C', + 0x20: 'A', + 0x40: 'L', + 0x60: 'S', +} +IRM_BITS_MASK = 0x70 # IR operand mode (2 bit). @@ -1649,19 +1653,10 @@ def ir_right(op): def ir_mode(op): - mode = '' - ir_mode = int(lj_ir_mode()[op] ^ IRM_W) - if ir_mode == IRM_C: - mode = 'C' - elif ir_mode == IRM_A: - mode = 'A' - elif ir_mode == IRM_L: - mode = 'L' - elif ir_mode == IRM_S: - mode = 'S' - else: - mode = 'N' - mode += 'W' if ir_mode & IRM_W else '' + irmode = int((lj_ir_mode()[op])) + isweak = not bool(irmode & IRM_BITS_W) + mode = IRM_BITS[irmode & IRM_BITS_MASK] + mode += 'W' if isweak else '' return mode diff --git a/test/tarantool-debugger-tests/debug-extension-tests.py b/test/tarantool-debugger-tests/debug-extension-tests.py index 8e069fe0..f17de27e 100644 --- a/test/tarantool-debugger-tests/debug-extension-tests.py +++ b/test/tarantool-debugger-tests/debug-extension-tests.py @@ -530,12 +530,12 @@ class TestLJTraceBase(TestCaseBase): r'\t*proto: ' + RX_ADDR + r'\n' + r'\t*BC: ' + RX_ADDR + r'\n' + r'---- TRACE IR\n' + - RX_IRN + r'\s+ int SLOAD \[N \] lit: #[12] lit: C?I\n' + + RX_IRN + r'\s+ int SLOAD \[L \] lit: #[12] lit: C?I\n' + RX_IRN + r'\s+ \+ int ADD \[C \] ref: ' + RX_IRN + r' ref: integer 1\n' + RX_IRN + r'\s+ > int LE \[N \] ref: ' + RX_IRN + r' ref: integer 4\n' + - RX_IRN + r'\s+ > --- LOOP \[N \]\s*\n' + + RX_IRN + r'\s+ > --- LOOP \[S \]\s*\n' + RX_IRN + r'\s+ \+ int ADD \[C \] ref: ' + RX_IRN + r' ref: integer 1\n' + RX_IRN + r'\s+ > int LE \[N \] ref: ' + RX_IRN + =================================================================== But intentionally didn't use bit notation to be consistent with original declarations in . I've used the mask to strip lower bits related to "NonWeak" guard and operand modes. > > +# Don't use *[ to be compatible with Python 2. > > +REGISTERS = {'x64': [ > > + 'rax', > > + 'rcx', > > + 'rdx', > > + 'rbx', > > + 'rsp', > > + 'rbp', > > + 'rsi', > > + 'rdi', > > +] + [ > > + 'r{}'.format(i) for i in range(8, 16) # r8 .. r15 > > +] + [ > > + 'xmm{}'.format(i) for i in range(0, 16) # xmm0 .. xmm15 > > +], 'arm64': [ > > + 'x{}'.format(i) for i in range(0, 31) # x0 .. x30 > > +] + ['sp'] + [ # x31 > > + 'd{}'.format(i) for i in range(0, 32) # d0 .. d31 > > +]} > > > > It seems, the ‘arm64’ registers are missed. Actiually no, but I understand your confusion. Reformated as the following: =================================================================== diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py index 32b0cea7..a79caad0 100644 --- a/src/luajit_dbg.py +++ b/src/luajit_dbg.py @@ -1728,24 +1728,29 @@ IRFPMS = [ # Don't use *[ to be compatible with Python 2. -REGISTERS = {'x64': [ - 'rax', - 'rcx', - 'rdx', - 'rbx', - 'rsp', - 'rbp', - 'rsi', - 'rdi', -] + [ - 'r{}'.format(i) for i in range(8, 16) # r8 .. r15 -] + [ - 'xmm{}'.format(i) for i in range(0, 16) # xmm0 .. xmm15 -], 'arm64': [ - 'x{}'.format(i) for i in range(0, 31) # x0 .. x30 -] + ['sp'] + [ # x31 - 'd{}'.format(i) for i in range(0, 32) # d0 .. d31 -]} +REGISTERS = { + 'x64': [ + 'rax', + 'rcx', + 'rdx', + 'rbx', + 'rsp', + 'rbp', + 'rsi', + 'rdi', + ] + [ + 'r{}'.format(i) for i in range(8, 16) # r8 .. r15 + ] + [ + 'xmm{}'.format(i) for i in range(0, 16) # xmm0 .. xmm15 + ], + 'arm64': [ + 'x{}'.format(i) for i in range(0, 31) # x0 .. x30 + ] + [ + 'sp' # x31 + ] + [ + 'd{}'.format(i) for i in range(0, 32) # d0 .. d31 + ] +} IR_CALLS = [ =================================================================== > > > +def litname_xload(mode): > > + flags = ['-', 'R', 'V', 'RV', 'U', 'RU', 'VU', 'RVU'] > > > > Does we need a range check as in litname_bufhdr()? I prefer error raising if something goes wrong here (invalid IR or incorrect extension implementation). > > > > > + return flags[mode] > > + > > + > > +def litname_conv(mode): > > > > Does we need some range checking here? Ditto. > > > > > + > > + > > +def irt_ismarked(t): > > + return t['irt'] & IRT_MARK > > > > I propose explicit bool cast (!= 0) here and below. Added: =================================================================== diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py index a79caad0..6b0827d9 100644 --- a/src/luajit_dbg.py +++ b/src/luajit_dbg.py @@ -1978,15 +1978,15 @@ def tref_ref(tr): def irt_ismarked(t): - return t['irt'] & IRT_MARK + return bool(t['irt'] & IRT_MARK) def irt_isphi(t): - return t['irt'] & IRT_ISPHI + return bool(t['irt'] & IRT_ISPHI) def irt_isguard(t): - return t['irt'] & IRT_GUARD + return bool(t['irt'] & IRT_GUARD) def irt_toitype(irt): =================================================================== > > > > > + > > + > > +def irt_isphi(t): > > + return t['irt'] & IRT_ISPHI > > + > > + > > +def irt_isguard(t): > > + return t['irt'] & IRT_GUARD > > + > > + > > > > -- > > 2.54.0 > > -- Best regards, Sergey Kaplun