Tarantool development patches archive
 help / color / mirror / Atom feed
From: Sergey Kaplun via Tarantool-patches <tarantool-patches@dev.tarantool.org>
To: Igor Munkin <imun@tarantool.org>,
	Sergey Bronnikov <sergeyb@tarantool.org>
Cc: tarantool-patches@dev.tarantool.org
Subject: [Tarantool-patches] [PATCH luajit 02/19] test: introduce mcode generator for tests
Date: Wed,  9 Aug 2023 18:35:51 +0300	[thread overview]
Message-ID: <67642b3989e440fb554bf60db140828653c59659.1691592488.git.skaplun@tarantool.org> (raw)
In-Reply-To: <cover.1691592488.git.skaplun@tarantool.org>

The test <test/tarantool-tests/gh-6098-fix-side-exit-patching-on-arm64>
depends on particular offset of mcode for side trace regarding the
parent trace. Before this commit just run some amount of functions to
generate traces to fill the required mcode range. Unfortunately, this
approach is not robust, since sometimes trace is not recorded due to
errors "leaving loop in root trace" observed because of hotcount
collisions.

This patch introduces the following helpers:
* `frontend.gettraceno(func)` -- returns the traceno for the given
  function, assumming that there is compiled trace for its prototype
  (i.e. the 0th bytecode is JFUNC).
* `jit.generators.fillmcode(traceno, size)` fills mcode area of the
  given size from the given trace. It is useful to generate some mcode
  to test jumps to side traces remote enough from the parent.
---
 ...8-fix-side-exit-patching-on-arm64.test.lua |  78 ++----------
 test/tarantool-tests/utils/frontend.lua       |  24 ++++
 test/tarantool-tests/utils/jit/generators.lua | 115 ++++++++++++++++++
 3 files changed, 150 insertions(+), 67 deletions(-)
 create mode 100644 test/tarantool-tests/utils/jit/generators.lua

diff --git a/test/tarantool-tests/gh-6098-fix-side-exit-patching-on-arm64.test.lua b/test/tarantool-tests/gh-6098-fix-side-exit-patching-on-arm64.test.lua
index 93db3041..678ac914 100644
--- a/test/tarantool-tests/gh-6098-fix-side-exit-patching-on-arm64.test.lua
+++ b/test/tarantool-tests/gh-6098-fix-side-exit-patching-on-arm64.test.lua
@@ -1,8 +1,12 @@
 local tap = require('tap')
 local test = tap.test('gh-6098-fix-side-exit-patching-on-arm64'):skipcond({
   ['Test requires JIT enabled'] = not jit.status(),
+  ['Disabled on *BSD due to #4819'] = jit.os == 'BSD',
 })
 
+local generators = require('utils').jit.generators
+local frontend = require('utils').frontend
+
 test:plan(1)
 
 -- The function to be tested for side exit patching:
@@ -20,52 +24,6 @@ local function cbool(cond)
   end
 end
 
--- XXX: Function template below produces 8Kb mcode for ARM64, so
--- we need to compile at least 128 traces to exceed 1Mb delta
--- between <cbool> root trace side exit and <cbool> side trace.
--- Unfortunately, we have no other option for extending this jump
--- delta, since the base of the current mcode area (J->mcarea) is
--- used as a hint for mcode allocator (see lj_mcode.c for info).
-local FUNCS = 128
-local recfuncs = { }
-for i = 1, FUNCS do
-  -- This is a quite heavy workload (though it doesn't look like
-  -- one at first). Each load from a table is type guarded. Each
-  -- table lookup (for both stores and loads) is guarded for table
-  -- <hmask> value and metatable presence. The code below results
-  -- to 8Kb of mcode for ARM64 in practice.
-  recfuncs[i] = assert(load(([[
-    return function(src)
-      local p = %d
-      local tmp = { }
-      local dst = { }
-      for i = 1, 3 do
-        tmp.a = src.a * p   tmp.j = src.j * p   tmp.s = src.s * p
-        tmp.b = src.b * p   tmp.k = src.k * p   tmp.t = src.t * p
-        tmp.c = src.c * p   tmp.l = src.l * p   tmp.u = src.u * p
-        tmp.d = src.d * p   tmp.m = src.m * p   tmp.v = src.v * p
-        tmp.e = src.e * p   tmp.n = src.n * p   tmp.w = src.w * p
-        tmp.f = src.f * p   tmp.o = src.o * p   tmp.x = src.x * p
-        tmp.g = src.g * p   tmp.p = src.p * p   tmp.y = src.y * p
-        tmp.h = src.h * p   tmp.q = src.q * p   tmp.z = src.z * p
-        tmp.i = src.i * p   tmp.r = src.r * p
-
-        dst.a = tmp.z + p   dst.j = tmp.q + p   dst.s = tmp.h + p
-        dst.b = tmp.y + p   dst.k = tmp.p + p   dst.t = tmp.g + p
-        dst.c = tmp.x + p   dst.l = tmp.o + p   dst.u = tmp.f + p
-        dst.d = tmp.w + p   dst.m = tmp.n + p   dst.v = tmp.e + p
-        dst.e = tmp.v + p   dst.n = tmp.m + p   dst.w = tmp.d + p
-        dst.f = tmp.u + p   dst.o = tmp.l + p   dst.x = tmp.c + p
-        dst.g = tmp.t + p   dst.p = tmp.k + p   dst.y = tmp.b + p
-        dst.h = tmp.s + p   dst.q = tmp.j + p   dst.z = tmp.a + p
-        dst.i = tmp.r + p   dst.r = tmp.i + p
-      end
-      dst.tmp = tmp
-      return dst
-    end
-  ]]):format(i)), ('Syntax error in function recfuncs[%d]'):format(i))()
-end
-
 -- Make compiler work hard:
 -- * No optimizations at all to produce more mcode.
 -- * Try to compile all compiled paths as early as JIT can.
@@ -78,27 +36,13 @@ cbool(true)
 -- a root trace for <cbool>.
 cbool(true)
 
-for i = 1, FUNCS do
-  -- XXX: FNEW is NYI, hence loop recording fails at this point.
-  -- The recording is aborted on purpose: we are going to record
-  -- <FUNCS> number of traces for functions in <recfuncs>.
-  -- Otherwise, loop recording might lead to a very long trace
-  -- error (via return to a lower frame), or a trace with lots of
-  -- side traces. We need neither of this, but just bunch of
-  -- traces filling the available mcode area.
-  local function tnew(p)
-    return {
-      a = p + 1, f = p + 6,  k = p + 11, p = p + 16, u = p + 21, z = p + 26,
-      b = p + 2, g = p + 7,  l = p + 12, q = p + 17, v = p + 22,
-      c = p + 3, h = p + 8,  m = p + 13, r = p + 18, w = p + 23,
-      d = p + 4, i = p + 9,  n = p + 14, s = p + 19, x = p + 24,
-      e = p + 5, j = p + 10, o = p + 15, t = p + 20, y = p + 25,
-    }
-  end
-  -- Each function call produces a trace (see the template for the
-  -- function definition above).
-  recfuncs[i](tnew(i))
-end
+local cbool_traceno = frontend.gettraceno(cbool)
+
+-- XXX: Unfortunately, we have no other option for extending
+-- this jump delta, since the base of the current mcode area
+-- (J->mcarea) is used as a hint for mcode allocator (see
+-- lj_mcode.c for info).
+generators.fillmcode(cbool_traceno, 1024 * 1024)
 
 -- XXX: I tried to make the test in pure Lua, but I failed to
 -- implement the robust solution. As a result I've implemented a
diff --git a/test/tarantool-tests/utils/frontend.lua b/test/tarantool-tests/utils/frontend.lua
index 2afebbb2..414257fd 100644
--- a/test/tarantool-tests/utils/frontend.lua
+++ b/test/tarantool-tests/utils/frontend.lua
@@ -1,6 +1,10 @@
 local M = {}
 
 local bc = require('jit.bc')
+local jutil = require('jit.util')
+local vmdef = require('jit.vmdef')
+local bcnames = vmdef.bcnames
+local band, rshift = bit.band, bit.rshift
 
 function M.hasbc(f, bytecode)
   assert(type(f) == 'function', 'argument #1 should be a function')
@@ -22,4 +26,24 @@ function M.hasbc(f, bytecode)
   return hasbc
 end
 
+-- Get traceno of the trace assotiated for the given function.
+function M.gettraceno(func)
+  assert(type(func) == 'function', 'argument #1 should be a function')
+
+  -- The 0th BC is the header.
+  local func_ins = jutil.funcbc(func, 0)
+  local BC_NAME_LENGTH = 6
+  local RD_SHIFT = 16
+
+  -- Calculate index in `bcnames` string.
+  local op_idx = BC_NAME_LENGTH * band(func_ins, 0xff)
+  -- Get the name of the operation.
+  local op_name = string.sub(bcnames, op_idx + 1, op_idx + BC_NAME_LENGTH)
+  assert(op_name:match('JFUNC'),
+         'The given function has non-jitted header: ' .. op_name)
+
+  -- RD contains the traceno.
+  return rshift(func_ins, RD_SHIFT)
+end
+
 return M
diff --git a/test/tarantool-tests/utils/jit/generators.lua b/test/tarantool-tests/utils/jit/generators.lua
new file mode 100644
index 00000000..62b6e0ef
--- /dev/null
+++ b/test/tarantool-tests/utils/jit/generators.lua
@@ -0,0 +1,115 @@
+local M = {}
+
+local jutil = require('jit.util')
+
+local function getlast_traceno()
+  return misc.getmetrics().jit_trace_num
+end
+
+-- Convert addr to positive value if needed.
+local function canonize_address(addr)
+  if addr < 0 then addr = addr + 2 ^ 32 end
+  return addr
+end
+
+-- Need some storage to avoid functions and traces to be
+-- collected.
+local recfuncs = {}
+local last_i = 0
+-- This function generates a table of functions with heavy mcode
+-- payload with tab arithmetics to fill the mcode area from the
+-- one trace mcode by the some given size. This size is usually
+-- big enough, because we want to check long jump side exits from
+-- some traces.
+-- Assumes, that maxmcode and maxtrace options are set to be sure,
+-- that we can produce such amount of mcode.
+function M.fillmcode(trace_from, size)
+  local mcode, addr_from = jutil.tracemc(trace_from)
+  assert(mcode, 'the #1 argument should be an existed trace number')
+  addr_from = canonize_address(addr_from)
+  local required_diff = size + #mcode
+
+  -- Marker to check that traces are not flushed.
+  local maxtraceno = getlast_traceno()
+  local FLUSH_ERR = 'Traces are flushed, check your maxtrace, maxmcode options'
+
+  local _, last_addr = jutil.tracemc(maxtraceno)
+  last_addr = canonize_address(last_addr)
+
+  -- Addresses of traces may increase or decrease depending on OS,
+  -- so use absolute diff.
+  while math.abs(last_addr - addr_from) > required_diff do
+    last_i = last_i + 1
+    -- This is a quite heavy workload (though it doesn't look like
+    -- one at first). Each load from a table is type guarded. Each
+    -- table lookup (for both stores and loads) is guarded for
+    -- table <hmask> value and presence of the metatable. The code
+    -- below results to ~8Kb of mcode for ARM64 and MIPS64 in
+    -- practice.
+    local fname = ('fillmcode[%d]'):format(last_i)
+    recfuncs[last_i] = assert(loadstring(([[
+      return function(src)
+        local p = %d
+        local tmp = { }
+        local dst = { }
+        -- XXX: use 5 as stop index to reduce LLEAVE (leaving loop
+        -- in root trace) errors due to hotcount collisions.
+        for i = 1, 5 do
+          tmp.a = src.a * p   tmp.j = src.j * p   tmp.s = src.s * p
+          tmp.b = src.b * p   tmp.k = src.k * p   tmp.t = src.t * p
+          tmp.c = src.c * p   tmp.l = src.l * p   tmp.u = src.u * p
+          tmp.d = src.d * p   tmp.m = src.m * p   tmp.v = src.v * p
+          tmp.e = src.e * p   tmp.n = src.n * p   tmp.w = src.w * p
+          tmp.f = src.f * p   tmp.o = src.o * p   tmp.x = src.x * p
+          tmp.g = src.g * p   tmp.p = src.p * p   tmp.y = src.y * p
+          tmp.h = src.h * p   tmp.q = src.q * p   tmp.z = src.z * p
+          tmp.i = src.i * p   tmp.r = src.r * p
+
+          dst.a = tmp.z + p   dst.j = tmp.q + p   dst.s = tmp.h + p
+          dst.b = tmp.y + p   dst.k = tmp.p + p   dst.t = tmp.g + p
+          dst.c = tmp.x + p   dst.l = tmp.o + p   dst.u = tmp.f + p
+          dst.d = tmp.w + p   dst.m = tmp.n + p   dst.v = tmp.e + p
+          dst.e = tmp.v + p   dst.n = tmp.m + p   dst.w = tmp.d + p
+          dst.f = tmp.u + p   dst.o = tmp.l + p   dst.x = tmp.c + p
+          dst.g = tmp.t + p   dst.p = tmp.k + p   dst.y = tmp.b + p
+          dst.h = tmp.s + p   dst.q = tmp.j + p   dst.z = tmp.a + p
+          dst.i = tmp.r + p   dst.r = tmp.i + p
+        end
+        dst.tmp = tmp
+        return dst
+      end
+    ]]):format(last_i), fname), ('Syntax error in function %s'):format(fname))()
+    -- XXX: FNEW is NYI, hence loop recording fails at this point.
+    -- The recording is aborted on purpose: the whole loop
+    -- recording might lead to a very long trace error (via return
+    -- to a lower frame), or a trace with lots of side traces. We
+    -- need neither of this, but just a bunch of traces filling
+    -- the available mcode area.
+    local function tnew(p)
+      return {
+        a = p + 1, f = p + 6,  k = p + 11, p = p + 16, u = p + 21, z = p + 26,
+        b = p + 2, g = p + 7,  l = p + 12, q = p + 17, v = p + 22,
+        c = p + 3, h = p + 8,  m = p + 13, r = p + 18, w = p + 23,
+        d = p + 4, i = p + 9,  n = p + 14, s = p + 19, x = p + 24,
+        e = p + 5, j = p + 10, o = p + 15, t = p + 20, y = p + 25,
+      }
+    end
+    -- Each function call produces a trace (see the template for
+    -- the function definition above).
+    recfuncs[last_i](tnew(last_i))
+    local last_traceno = getlast_traceno()
+    if last_traceno < maxtraceno then
+      error(FLUSH_ERR)
+    end
+
+    -- Calculate the address of the last trace start.
+    maxtraceno = last_traceno
+    _, last_addr = jutil.tracemc(last_traceno)
+    if not last_addr then
+      error(FLUSH_ERR)
+    end
+    last_addr = canonize_address(last_addr)
+  end
+end
+
+return M
-- 
2.41.0


  parent reply	other threads:[~2023-08-09 15:41 UTC|newest]

Thread overview: 97+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-09 15:35 [Tarantool-patches] [PATCH luajit 00/19] Prerequisites for improve assertions Sergey Kaplun via Tarantool-patches
2023-08-09 15:35 ` [Tarantool-patches] [PATCH luajit 01/19] MIPS: Use precise search for exit jump patching Sergey Kaplun via Tarantool-patches
2023-08-15  9:36   ` Maxim Kokryashkin via Tarantool-patches
2023-08-16 12:40     ` Sergey Kaplun via Tarantool-patches
2023-08-16 13:25   ` Sergey Bronnikov via Tarantool-patches
2023-08-09 15:35 ` Sergey Kaplun via Tarantool-patches [this message]
2023-08-15 10:14   ` [Tarantool-patches] [PATCH luajit 02/19] test: introduce mcode generator for tests Maxim Kokryashkin via Tarantool-patches
2023-08-16 12:55     ` Sergey Kaplun via Tarantool-patches
2023-08-16 13:06       ` Maxim Kokryashkin via Tarantool-patches
2023-08-16 14:32   ` Sergey Bronnikov via Tarantool-patches
2023-08-16 15:20     ` Sergey Kaplun via Tarantool-patches
2023-08-16 16:08       ` Sergey Bronnikov via Tarantool-patches
2023-08-09 15:35 ` [Tarantool-patches] [PATCH luajit 03/19] MIPS: Fix handling of spare long-range jump slots Sergey Kaplun via Tarantool-patches
2023-08-15 11:13   ` Maxim Kokryashkin via Tarantool-patches
2023-08-16 13:05     ` Sergey Kaplun via Tarantool-patches
2023-08-16 15:02   ` Sergey Bronnikov via Tarantool-patches
2023-08-16 15:32     ` Sergey Kaplun via Tarantool-patches
2023-08-16 16:08       ` Sergey Bronnikov via Tarantool-patches
2023-08-09 15:35 ` [Tarantool-patches] [PATCH luajit 04/19] MIPS64: Add soft-float support to JIT compiler backend Sergey Kaplun via Tarantool-patches
2023-08-15 11:27   ` Maxim Kokryashkin via Tarantool-patches
2023-08-16 13:10     ` Sergey Kaplun via Tarantool-patches
2023-08-16 16:07   ` Sergey Bronnikov via Tarantool-patches
2023-08-09 15:35 ` [Tarantool-patches] [PATCH luajit 05/19] PPC: Add soft-float support to interpreter Sergey Kaplun via Tarantool-patches
2023-08-15 11:40   ` Maxim Kokryashkin via Tarantool-patches
2023-08-16 13:13     ` Sergey Kaplun via Tarantool-patches
2023-08-17 14:53   ` Sergey Bronnikov via Tarantool-patches
2023-08-09 15:35 ` [Tarantool-patches] [PATCH luajit 06/19] PPC: Add soft-float support to JIT compiler backend Sergey Kaplun via Tarantool-patches
2023-08-15 11:46   ` Maxim Kokryashkin via Tarantool-patches
2023-08-16 13:21     ` Sergey Kaplun via Tarantool-patches
2023-08-17 14:33   ` Sergey Bronnikov via Tarantool-patches
2023-08-09 15:35 ` [Tarantool-patches] [PATCH luajit 07/19] build: fix non-Linux/macOS builds Sergey Kaplun via Tarantool-patches
2023-08-15 11:58   ` Maxim Kokryashkin via Tarantool-patches
2023-08-16 13:40     ` Sergey Kaplun via Tarantool-patches
2023-08-17 14:31   ` Sergey Bronnikov via Tarantool-patches
2023-08-09 15:35 ` [Tarantool-patches] [PATCH luajit 08/19] Windows: Add UWP support, part 1 Sergey Kaplun via Tarantool-patches
2023-08-15 12:09   ` Maxim Kokryashkin via Tarantool-patches
2023-08-16 13:50     ` Sergey Kaplun via Tarantool-patches
2023-08-16 16:40   ` Sergey Bronnikov via Tarantool-patches
2023-08-09 15:35 ` [Tarantool-patches] [PATCH luajit 09/19] FFI: Eliminate hardcoded string hashes Sergey Kaplun via Tarantool-patches
2023-08-15 13:07   ` Maxim Kokryashkin via Tarantool-patches
2023-08-16 13:52     ` Sergey Kaplun via Tarantool-patches
2023-08-16 17:04     ` Sergey Bronnikov via Tarantool-patches
2023-08-09 15:35 ` [Tarantool-patches] [PATCH luajit 10/19] Cleanup math function compilation and fix inconsistencies Sergey Kaplun via Tarantool-patches
2023-08-11  8:06   ` Sergey Kaplun via Tarantool-patches
2023-08-15 13:10   ` Maxim Kokryashkin via Tarantool-patches
2023-08-16 17:15   ` Sergey Bronnikov via Tarantool-patches
2023-08-09 15:36 ` [Tarantool-patches] [PATCH luajit 11/19] Fix GCC 7 -Wimplicit-fallthrough warnings Sergey Kaplun via Tarantool-patches
2023-08-15 13:17   ` Maxim Kokryashkin via Tarantool-patches
2023-08-16 13:59     ` Sergey Kaplun via Tarantool-patches
2023-08-17  7:37   ` Sergey Bronnikov via Tarantool-patches
2023-08-09 15:36 ` [Tarantool-patches] [PATCH luajit 12/19] DynASM: Fix warning Sergey Kaplun via Tarantool-patches
2023-08-15 13:21   ` Maxim Kokryashkin via Tarantool-patches
2023-08-16 14:01     ` Sergey Kaplun via Tarantool-patches
2023-08-17  7:39   ` Sergey Bronnikov via Tarantool-patches
2023-08-17  7:51     ` Sergey Bronnikov via Tarantool-patches
2023-08-17  7:58       ` Sergey Kaplun via Tarantool-patches
2023-08-09 15:36 ` [Tarantool-patches] [PATCH luajit 13/19] ARM: Fix GCC 7 -Wimplicit-fallthrough warnings Sergey Kaplun via Tarantool-patches
2023-08-15 13:25   ` Maxim Kokryashkin via Tarantool-patches
2023-08-16 14:08     ` Sergey Kaplun via Tarantool-patches
2023-08-17  7:44   ` Sergey Bronnikov via Tarantool-patches
2023-08-17  8:01     ` Sergey Kaplun via Tarantool-patches
2023-08-09 15:36 ` [Tarantool-patches] [PATCH luajit 14/19] Fix debug.getinfo() argument check Sergey Kaplun via Tarantool-patches
2023-08-15 13:35   ` Maxim Kokryashkin via Tarantool-patches
2023-08-16 14:20     ` Sergey Kaplun via Tarantool-patches
2023-08-16 20:13       ` Maxim Kokryashkin via Tarantool-patches
2023-08-17  8:29   ` Sergey Bronnikov via Tarantool-patches
2023-08-09 15:36 ` [Tarantool-patches] [PATCH luajit 15/19] Fix LJ_MAX_JSLOTS assertion in rec_check_slots() Sergey Kaplun via Tarantool-patches
2023-08-15 14:07   ` Maxim Kokryashkin via Tarantool-patches
2023-08-16 14:22     ` Sergey Kaplun via Tarantool-patches
2023-08-17  8:57   ` Sergey Bronnikov via Tarantool-patches
2023-08-17  8:57     ` Sergey Kaplun via Tarantool-patches
2023-08-09 15:36 ` [Tarantool-patches] [PATCH luajit 16/19] Prevent integer overflow while parsing long strings Sergey Kaplun via Tarantool-patches
2023-08-15 14:38   ` Maxim Kokryashkin via Tarantool-patches
2023-08-16 14:52     ` Sergey Kaplun via Tarantool-patches
2023-08-17 10:53   ` Sergey Bronnikov via Tarantool-patches
2023-08-17 13:57     ` Sergey Kaplun via Tarantool-patches
2023-08-17 14:28       ` Sergey Bronnikov via Tarantool-patches
2023-08-09 15:36 ` [Tarantool-patches] [PATCH luajit 17/19] MIPS64: Fix register allocation in assembly of HREF Sergey Kaplun via Tarantool-patches
2023-08-16  9:01   ` Maxim Kokryashkin via Tarantool-patches
2023-08-16 15:17     ` Sergey Kaplun via Tarantool-patches
2023-08-16 20:14       ` Maxim Kokryashkin via Tarantool-patches
2023-08-17 11:06   ` Sergey Bronnikov via Tarantool-patches
2023-08-17 13:50     ` Sergey Kaplun via Tarantool-patches
2023-08-17 14:30       ` Sergey Bronnikov via Tarantool-patches
2023-08-09 15:36 ` [Tarantool-patches] [PATCH luajit 18/19] DynASM/MIPS: Fix shadowed variable Sergey Kaplun via Tarantool-patches
2023-08-16  9:03   ` Maxim Kokryashkin via Tarantool-patches
2023-08-16 15:22     ` Sergey Kaplun via Tarantool-patches
2023-08-17 12:01   ` Sergey Bronnikov via Tarantool-patches
2023-08-09 15:36 ` [Tarantool-patches] [PATCH luajit 19/19] MIPS: Add MIPS64 R6 port Sergey Kaplun via Tarantool-patches
2023-08-16  9:16   ` Maxim Kokryashkin via Tarantool-patches
2023-08-16 15:24     ` Sergey Kaplun via Tarantool-patches
2023-08-17 13:03   ` Sergey Bronnikov via Tarantool-patches
2023-08-17 13:59     ` Sergey Kaplun via Tarantool-patches
2023-08-16 15:35 ` [Tarantool-patches] [PATCH luajit 00/19] Prerequisites for improve assertions Sergey Kaplun via Tarantool-patches
2023-08-17 14:06   ` Maxim Kokryashkin via Tarantool-patches
2023-08-17 14:38 ` Sergey Bronnikov via Tarantool-patches
2023-08-31 15:17 ` Igor Munkin via Tarantool-patches

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=67642b3989e440fb554bf60db140828653c59659.1691592488.git.skaplun@tarantool.org \
    --to=tarantool-patches@dev.tarantool.org \
    --cc=imun@tarantool.org \
    --cc=sergeyb@tarantool.org \
    --cc=skaplun@tarantool.org \
    --subject='Re: [Tarantool-patches] [PATCH luajit 02/19] test: introduce mcode generator for tests' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox