Inline-Lua

 view release on metacpan or  search on metacpan

ffi/target/release/build/mlua-sys-6a99a2ae50f12319/out/luajit-build/build/src/jit/p.lua  view on Meta::CPAN

----------------------------------------------------------------------------
-- LuaJIT profiler.
--
-- Copyright (C) 2005-2025 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
--
-- This module is a simple command line interface to the built-in
-- low-overhead profiler of LuaJIT.
--
-- The lower-level API of the profiler is accessible via the "jit.profile"
-- module or the luaJIT_profile_* C API.
--
-- Example usage:
--
--   luajit -jp myapp.lua
--   luajit -jp=s myapp.lua
--   luajit -jp=-s myapp.lua
--   luajit -jp=vl myapp.lua
--   luajit -jp=G,profile.txt myapp.lua
--
-- The following dump features are available:
--
--   f  Stack dump: function name, otherwise module:line. Default mode.
--   F  Stack dump: ditto, but always prepend module.
--   l  Stack dump: module:line.
--   <number> stack dump depth (callee < caller). Default: 1.
--   -<number> Inverse stack dump depth (caller > callee).
--   s  Split stack dump after first stack level. Implies abs(depth) >= 2.
--   p  Show full path for module names.
--   v  Show VM states. Can be combined with stack dumps, e.g. vf or fv.
--   z  Show zones. Can be combined with stack dumps, e.g. zf or fz.
--   r  Show raw sample counts. Default: show percentages.
--   a  Annotate excerpts from source code files.
--   A  Annotate complete source code files.
--   G  Produce raw output suitable for graphical tools (e.g. flame graphs).
--   m<number> Minimum sample percentage to be shown. Default: 3.
--   i<number> Sampling interval in milliseconds. Default: 10.
--
----------------------------------------------------------------------------

-- Cache some library functions and objects.
local jit = require("jit")
local profile = require("jit.profile")
local vmdef = require("jit.vmdef")
local math = math
local pairs, ipairs, tonumber, floor = pairs, ipairs, tonumber, math.floor
local sort, format = table.sort, string.format
local stdout = io.stdout
local zone -- Load jit.zone module on demand.

-- Output file handle.
local out

------------------------------------------------------------------------------

local prof_ud
local prof_states, prof_split, prof_min, prof_raw, prof_fmt, prof_depth
local prof_ann, prof_count1, prof_count2, prof_samples

local map_vmmode = {
  N = "Compiled",
  I = "Interpreted",
  C = "C code",
  G = "Garbage Collector",
  J = "JIT Compiler",
}

-- Profiler callback.
local function prof_cb(th, samples, vmmode)
  prof_samples = prof_samples + samples
  local key_stack, key_stack2, key_state
  -- Collect keys for sample.
  if prof_states then
    if prof_states == "v" then
      key_state = map_vmmode[vmmode] or vmmode
    else
      key_state = zone:get() or "(none)"
    end
  end
  if prof_fmt then
    key_stack = profile.dumpstack(th, prof_fmt, prof_depth)
    key_stack = key_stack:gsub("%[builtin#(%d+)%]", function(x)
      return vmdef.ffnames[tonumber(x)]
    end)
    if prof_split == 2 then
      local k1, k2 = key_stack:match("(.-) [<>] (.*)")
      if k2 then key_stack, key_stack2 = k1, k2 end
    elseif prof_split == 3 then
      key_stack2 = profile.dumpstack(th, "l", 1)
    end
  end
  -- Order keys.
  local k1, k2
  if prof_split == 1 then
    if key_state then
      k1 = key_state
      if key_stack then k2 = key_stack end
    end
  elseif key_stack then
    k1 = key_stack
    if key_stack2 then k2 = key_stack2 elseif key_state then k2 = key_state end
  end
  -- Coalesce samples in one or two levels.
  if k1 then

ffi/target/release/build/mlua-sys-6a99a2ae50f12319/out/luajit-build/build/src/jit/p.lua  view on Meta::CPAN

      if line:byte() == 27 then
	out:write("[Cannot annotate bytecode file]\n")
	break
      end
      local v = fl[n]
      if ann ~= 0 then
	local v2 = fl[n+ann]
	if show then
	  if v2 then show = n+ann elseif v then show = n
	  elseif show+ann < n then show = false end
	elseif v2 then
	  show = n+ann
	  out:write(format("@@ %d @@\n", n))
	end
	if not show then goto next end
      end
      if v then
	out:write(format(fmtv, v, line))
      else
	out:write(format(fmtn, line))
      end
    ::next::
      n = n + 1
    end
    fp:close()
  end
end

------------------------------------------------------------------------------

-- Finish profiling and dump result.
local function prof_finish()
  if prof_ud then
    profile.stop()
    local samples = prof_samples
    if samples == 0 then
      if prof_raw ~= true then out:write("[No samples collected]\n") end
    elseif prof_ann then
      prof_annotate(prof_count1, samples)
    else
      prof_top(prof_count1, prof_count2, samples, "")
    end
    prof_count1 = nil
    prof_count2 = nil
    prof_ud = nil
    if out ~= stdout then out:close() end
  end
end

-- Start profiling.
local function prof_start(mode)
  local interval = ""
  mode = mode:gsub("i%d*", function(s) interval = s; return "" end)
  prof_min = 3
  mode = mode:gsub("m(%d+)", function(s) prof_min = tonumber(s); return "" end)
  prof_depth = 1
  mode = mode:gsub("%-?%d+", function(s) prof_depth = tonumber(s); return "" end)
  local m = {}
  for c in mode:gmatch(".") do m[c] = c end
  prof_states = m.z or m.v
  if prof_states == "z" then zone = require("jit.zone") end
  local scope = m.l or m.f or m.F or (prof_states and "" or "f")
  local flags = (m.p or "")
  prof_raw = m.r
  if m.s then
    prof_split = 2
    if prof_depth == -1 or m["-"] then prof_depth = -2
    elseif prof_depth == 1 then prof_depth = 2 end
  elseif mode:find("[fF].*l") then
    scope = "l"
    prof_split = 3
  else
    prof_split = (scope == "" or mode:find("[zv].*[lfF]")) and 1 or 0
  end
  prof_ann = m.A and 0 or (m.a and 3)
  if prof_ann then
    scope = "l"
    prof_fmt = "pl"
    prof_split = 0
    prof_depth = 1
  elseif m.G and scope ~= "" then
    prof_fmt = flags..scope.."Z;"
    prof_depth = -100
    prof_raw = true
    prof_min = 0
  elseif scope == "" then
    prof_fmt = false
  else
    local sc = prof_split == 3 and m.f or m.F or scope
    prof_fmt = flags..sc..(prof_depth >= 0 and "Z < " or "Z > ")
  end
  prof_count1 = {}
  prof_count2 = {}
  prof_samples = 0
  profile.start(scope:lower()..interval, prof_cb)
  prof_ud = newproxy(true)
  getmetatable(prof_ud).__gc = prof_finish
end

------------------------------------------------------------------------------

local function start(mode, outfile)
  if not outfile then outfile = os.getenv("LUAJIT_PROFILEFILE") end
  if outfile then
    out = outfile == "-" and stdout or assert(io.open(outfile, "w"))
  else
    out = stdout
  end
  prof_start(mode or "f")
end

-- Public module functions.
return {
  start = start, -- For -j command line option.
  stop = prof_finish
}



( run in 0.821 second using v1.01-cache-2.11-cpan-39bf76dae61 )