]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
Merge branch 'master' into v2.1
authorMike Pall <mike>
Mon, 21 Aug 2023 00:38:56 +0000 (02:38 +0200)
committerMike Pall <mike>
Mon, 21 Aug 2023 00:38:56 +0000 (02:38 +0200)
14 files changed:
1  2 
README
doc/contact.html
doc/ext_buffer.html
doc/ext_c_api.html
doc/ext_ffi.html
doc/ext_ffi_api.html
doc/ext_ffi_semantics.html
doc/ext_ffi_tutorial.html
doc/ext_jit.html
doc/ext_profiler.html
doc/extensions.html
doc/install.html
doc/luajit.html
doc/running.html

diff --cc README
index e6631432f3c792d76d7119616835900cf70cb683,dfa7ca94ff57124dde7e3dfece43676cc244aa06..e4a692654dc1cbbd75e8414088f865f2f4aa6236
--- 1/README
--- 2/README
+++ b/README
@@@ -1,5 -1,5 +1,5 @@@
- README for LuaJIT 2.1.0-beta3
- -----------------------------
 -README for LuaJIT 2.0
++README for LuaJIT 2.1
+ ---------------------
  
  LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language.
  
index 478c4bff5546eb71fcbbff1b0617eaa30f635055,c32bc9dc114674e16021a9a126cc485eb4719be9..cc4d8c7235d104c8504c3f88d95aa953c786c861
  <a href="ext_jit.html">jit.* Library</a>
  </li><li>
  <a href="ext_c_api.html">Lua/C API</a>
 +</li><li>
 +<a href="ext_profiler.html">Profiler</a>
  </li></ul>
  </li><li>
- <a href="status.html">Status</a>
+ <a href="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
  </li><li>
- <a href="faq.html">FAQ</a>
+ <a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></a>
  </li><li>
  <a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
  </li></ul>
index 35f01c9a9787de610bf0f14e0c291f67663ec7fa,0000000000000000000000000000000000000000..bfaa24cbd7570b833312217a463d8f003385ead9
mode 100644,000000..100644
--- /dev/null
@@@ -1,689 -1,0 +1,689 @@@
- <a href="status.html">Status</a>
 +<!DOCTYPE html>
 +<html>
 +<head>
 +<title>String Buffer Library</title>
 +<meta charset="utf-8">
 +<meta name="Copyright" content="Copyright (C) 2005-2023">
 +<meta name="Language" content="en">
 +<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 +<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
 +<style type="text/css">
 +.lib {
 +  vertical-align: middle;
 +  margin-left: 5px;
 +  padding: 0 5px;
 +  font-size: 60%;
 +  border-radius: 5px;
 +  background: #c5d5ff;
 +  color: #000;
 +}
 +</style>
 +</head>
 +<body>
 +<div id="site">
 +<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
 +</div>
 +<div id="head">
 +<h1>String Buffer Library</h1>
 +</div>
 +<div id="nav">
 +<ul><li>
 +<a href="luajit.html">LuaJIT</a>
 +<ul><li>
 +<a href="https://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
 +</li><li>
 +<a href="install.html">Installation</a>
 +</li><li>
 +<a href="running.html">Running</a>
 +</li></ul>
 +</li><li>
 +<a href="extensions.html">Extensions</a>
 +<ul><li>
 +<a href="ext_ffi.html">FFI Library</a>
 +<ul><li>
 +<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
 +</li><li>
 +<a href="ext_ffi_api.html">ffi.* API</a>
 +</li><li>
 +<a href="ext_ffi_semantics.html">FFI Semantics</a>
 +</li></ul>
 +</li><li>
 +<a class="current" href="ext_buffer.html">String Buffers</a>
 +</li><li>
 +<a href="ext_jit.html">jit.* Library</a>
 +</li><li>
 +<a href="ext_c_api.html">Lua/C API</a>
 +</li><li>
 +<a href="ext_profiler.html">Profiler</a>
 +</li></ul>
 +</li><li>
- <a href="faq.html">FAQ</a>
++<a href="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
 +</li><li>
++<a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></a>
 +</li><li>
 +<a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
 +</li></ul>
 +</div>
 +<div id="main">
 +<p>
 +The string buffer library allows <b>high-performance manipulation of
 +string-like data</b>.
 +</p>
 +<p>
 +Unlike Lua strings, which are constants, string buffers are
 +<b>mutable</b> sequences of 8-bit (binary-transparent) characters. Data
 +can be stored, formatted and encoded into a string buffer and later
 +converted, extracted or decoded.
 +</p>
 +<p>
 +The convenient string buffer API simplifies common string manipulation
 +tasks, that would otherwise require creating many intermediate strings.
 +String buffers improve performance by eliminating redundant memory
 +copies, object creation, string interning and garbage collection
 +overhead. In conjunction with the FFI library, they allow zero-copy
 +operations.
 +</p>
 +<p>
 +The string buffer library also includes a high-performance
 +<a href="serialize">serializer</a> for Lua objects.
 +</p>
 +
 +<h2 id="use">Using the String Buffer Library</h2>
 +<p>
 +The string buffer library is built into LuaJIT by default, but it's not
 +loaded by default. Add this to the start of every Lua file that needs
 +one of its functions:
 +</p>
 +<pre class="code">
 +local buffer = require("string.buffer")
 +</pre>
 +<p>
 +The convention for the syntax shown on this page is that <tt>buffer</tt>
 +refers to the buffer library and <tt>buf</tt> refers to an individual
 +buffer object.
 +</p>
 +<p>
 +Please note the difference between a Lua function call, e.g.
 +<tt>buffer.new()</tt> (with a dot) and a Lua method call, e.g.
 +<tt>buf:reset()</tt> (with a colon).
 +</p>
 +
 +<h3 id="buffer_object">Buffer Objects</h3>
 +<p>
 +A buffer object is a garbage-collected Lua object. After creation with
 +<tt>buffer.new()</tt>, it can (and should) be reused for many operations.
 +When the last reference to a buffer object is gone, it will eventually
 +be freed by the garbage collector, along with the allocated buffer
 +space.
 +</p>
 +<p>
 +Buffers operate like a FIFO (first-in first-out) data structure. Data
 +can be appended (written) to the end of the buffer and consumed (read)
 +from the front of the buffer. These operations may be freely mixed.
 +</p>
 +<p>
 +The buffer space that holds the characters is managed automatically
 +&mdash; it grows as needed and already consumed space is recycled. Use
 +<tt>buffer.new(size)</tt> and <tt>buf:free()</tt>, if you need more
 +control.
 +</p>
 +<p>
 +The maximum size of a single buffer is the same as the maximum size of a
 +Lua string, which is slightly below two gigabytes. For huge data sizes,
 +neither strings nor buffers are the right data structure &mdash; use the
 +FFI library to directly map memory or files up to the virtual memory
 +limit of your OS.
 +</p>
 +
 +<h3 id="buffer_overview">Buffer Method Overview</h3>
 +<ul>
 +<li>
 +The <tt>buf:put*()</tt>-like methods append (write) characters to the
 +end of the buffer.
 +</li>
 +<li>
 +The <tt>buf:get*()</tt>-like methods consume (read) characters from the
 +front of the buffer.
 +</li>
 +<li>
 +Other methods, like <tt>buf:tostring()</tt> only read the buffer
 +contents, but don't change the buffer.
 +</li>
 +<li>
 +The <tt>buf:set()</tt> method allows zero-copy consumption of a string
 +or an FFI cdata object as a buffer.
 +</li>
 +<li>
 +The FFI-specific methods allow zero-copy read/write-style operations or
 +modifying the buffer contents in-place. Please check the
 +<a href="#ffi_caveats">FFI caveats</a> below, too.
 +</li>
 +<li>
 +Methods that don't need to return anything specific, return the buffer
 +object itself as a convenience. This allows method chaining, e.g.:
 +<tt>buf:reset():encode(obj)</tt> or <tt>buf:skip(len):get()</tt>
 +</li>
 +</ul>
 +
 +<h2 id="create">Buffer Creation and Management</h2>
 +
 +<h3 id="buffer_new"><tt>local buf = buffer.new([size [,options]])<br>
 +local buf = buffer.new([options])</tt></h3>
 +<p>
 +Creates a new buffer object.
 +</p>
 +<p>
 +The optional <tt>size</tt> argument ensures a minimum initial buffer
 +size. This is strictly an optimization when the required buffer size is
 +known beforehand. The buffer space will grow as needed, in any case.
 +</p>
 +<p>
 +The optional table <tt>options</tt> sets various
 +<a href="#serialize_options">serialization options</a>.
 +</p>
 +
 +<h3 id="buffer_reset"><tt>buf = buf:reset()</tt></h3>
 +<p>
 +Reset (empty) the buffer. The allocated buffer space is not freed and
 +may be reused.
 +</p>
 +
 +<h3 id="buffer_free"><tt>buf = buf:free()</tt></h3>
 +<p>
 +The buffer space of the buffer object is freed. The object itself
 +remains intact, empty and may be reused.
 +</p>
 +<p>
 +Note: you normally don't need to use this method. The garbage collector
 +automatically frees the buffer space, when the buffer object is
 +collected. Use this method, if you need to free the associated memory
 +immediately.
 +</p>
 +
 +<h2 id="write">Buffer Writers</h2>
 +
 +<h3 id="buffer_put"><tt>buf = buf:put([str|num|obj] [,…])</tt></h3>
 +<p>
 +Appends a string <tt>str</tt>, a number <tt>num</tt> or any object
 +<tt>obj</tt> with a <tt>__tostring</tt> metamethod to the buffer.
 +Multiple arguments are appended in the given order.
 +</p>
 +<p>
 +Appending a buffer to a buffer is possible and short-circuited
 +internally. But it still involves a copy. Better combine the buffer
 +writes to use a single buffer.
 +</p>
 +
 +<h3 id="buffer_putf"><tt>buf = buf:putf(format, …)</tt></h3>
 +<p>
 +Appends the formatted arguments to the buffer. The <tt>format</tt>
 +string supports the same options as <tt>string.format()</tt>.
 +</p>
 +
 +<h3 id="buffer_putcdata"><tt>buf = buf:putcdata(cdata, len)</tt><span class="lib">FFI</span></h3>
 +<p>
 +Appends the given <tt>len</tt> number of bytes from the memory pointed
 +to by the FFI <tt>cdata</tt> object to the buffer. The object needs to
 +be convertible to a (constant) pointer.
 +</p>
 +
 +<h3 id="buffer_set"><tt>buf = buf:set(str)<br>
 +buf = buf:set(cdata, len)</tt><span class="lib">FFI</span></h3>
 +<p>
 +This method allows zero-copy consumption of a string or an FFI cdata
 +object as a buffer. It stores a reference to the passed string
 +<tt>str</tt> or the FFI <tt>cdata</tt> object in the buffer. Any buffer
 +space originally allocated is freed. This is <i>not</i> an append
 +operation, unlike the <tt>buf:put*()</tt> methods.
 +</p>
 +<p>
 +After calling this method, the buffer behaves as if
 +<tt>buf:free():put(str)</tt> or <tt>buf:free():put(cdata,&nbsp;len)</tt>
 +had been called. However, the data is only referenced and not copied, as
 +long as the buffer is only consumed.
 +</p>
 +<p>
 +In case the buffer is written to later on, the referenced data is copied
 +and the object reference is removed (copy-on-write semantics).
 +</p>
 +<p>
 +The stored reference is an anchor for the garbage collector and keeps the
 +originally passed string or FFI cdata object alive.
 +</p>
 +
 +<h3 id="buffer_reserve"><tt>ptr, len = buf:reserve(size)</tt><span class="lib">FFI</span><br>
 +<tt>buf = buf:commit(used)</tt><span class="lib">FFI</span></h3>
 +<p>
 +The <tt>reserve</tt> method reserves at least <tt>size</tt> bytes of
 +write space in the buffer. It returns an <tt>uint8_t&nbsp;*</tt> FFI
 +cdata pointer <tt>ptr</tt> that points to this space.
 +</p>
 +<p>
 +The available length in bytes is returned in <tt>len</tt>. This is at
 +least <tt>size</tt> bytes, but may be more to facilitate efficient
 +buffer growth. You can either make use of the additional space or ignore
 +<tt>len</tt> and only use <tt>size</tt> bytes.
 +</p>
 +<p>
 +The <tt>commit</tt> method appends the <tt>used</tt> bytes of the
 +previously returned write space to the buffer data.
 +</p>
 +<p>
 +This pair of methods allows zero-copy use of C read-style APIs:
 +</p>
 +<pre class="code">
 +local MIN_SIZE = 65536
 +repeat
 +  local ptr, len = buf:reserve(MIN_SIZE)
 +  local n = C.read(fd, ptr, len)
 +  if n == 0 then break end -- EOF.
 +  if n &lt; 0 then error("read error") end
 +  buf:commit(n)
 +until false
 +</pre>
 +<p>
 +The reserved write space is <i>not</i> initialized. At least the
 +<tt>used</tt> bytes <b>must</b> be written to before calling the
 +<tt>commit</tt> method. There's no need to call the <tt>commit</tt>
 +method, if nothing is added to the buffer (e.g. on error).
 +</p>
 +
 +<h2 id="read">Buffer Readers</h2>
 +
 +<h3 id="buffer_length"><tt>len = #buf</tt></h3>
 +<p>
 +Returns the current length of the buffer data in bytes.
 +</p>
 +
 +<h3 id="buffer_concat"><tt>res = str|num|buf .. str|num|buf […]</tt></h3>
 +<p>
 +The Lua concatenation operator <tt>..</tt> also accepts buffers, just
 +like strings or numbers. It always returns a string and not a buffer.
 +</p>
 +<p>
 +Note that although this is supported for convenience, this thwarts one
 +of the main reasons to use buffers, which is to avoid string
 +allocations. Rewrite it with <tt>buf:put()</tt> and <tt>buf:get()</tt>.
 +</p>
 +<p>
 +Mixing this with unrelated objects that have a <tt>__concat</tt>
 +metamethod may not work, since these probably only expect strings.
 +</p>
 +
 +<h3 id="buffer_skip"><tt>buf = buf:skip(len)</tt></h3>
 +<p>
 +Skips (consumes) <tt>len</tt> bytes from the buffer up to the current
 +length of the buffer data.
 +</p>
 +
 +<h3 id="buffer_get"><tt>str, … = buf:get([len|nil] [,…])</tt></h3>
 +<p>
 +Consumes the buffer data and returns one or more strings. If called
 +without arguments, the whole buffer data is consumed. If called with a
 +number, up to <tt>len</tt> bytes are consumed. A <tt>nil</tt> argument
 +consumes the remaining buffer space (this only makes sense as the last
 +argument). Multiple arguments consume the buffer data in the given
 +order.
 +</p>
 +<p>
 +Note: a zero length or no remaining buffer data returns an empty string
 +and not <tt>nil</tt>.
 +</p>
 +
 +<h3 id="buffer_tostring"><tt>str = buf:tostring()<br>
 +str = tostring(buf)</tt></h3>
 +<p>
 +Creates a string from the buffer data, but doesn't consume it. The
 +buffer remains unchanged.
 +</p>
 +<p>
 +Buffer objects also define a <tt>__tostring</tt> metamethod. This means
 +buffers can be passed to the global <tt>tostring()</tt> function and
 +many other functions that accept this in place of strings. The important
 +internal uses in functions like <tt>io.write()</tt> are short-circuited
 +to avoid the creation of an intermediate string object.
 +</p>
 +
 +<h3 id="buffer_ref"><tt>ptr, len = buf:ref()</tt><span class="lib">FFI</span></h3>
 +<p>
 +Returns an <tt>uint8_t&nbsp;*</tt> FFI cdata pointer <tt>ptr</tt> that
 +points to the buffer data. The length of the buffer data in bytes is
 +returned in <tt>len</tt>.
 +</p>
 +<p>
 +The returned pointer can be directly passed to C functions that expect a
 +buffer and a length. You can also do bytewise reads
 +(<tt>local&nbsp;x&nbsp;=&nbsp;ptr[i]</tt>) or writes
 +(<tt>ptr[i]&nbsp;=&nbsp;0x40</tt>) of the buffer data.
 +</p>
 +<p>
 +In conjunction with the <tt>skip</tt> method, this allows zero-copy use
 +of C write-style APIs:
 +</p>
 +<pre class="code">
 +repeat
 +  local ptr, len = buf:ref()
 +  if len == 0 then break end
 +  local n = C.write(fd, ptr, len)
 +  if n &lt; 0 then error("write error") end
 +  buf:skip(n)
 +until n >= len
 +</pre>
 +<p>
 +Unlike Lua strings, buffer data is <i>not</i> implicitly
 +zero-terminated. It's not safe to pass <tt>ptr</tt> to C functions that
 +expect zero-terminated strings. If you're not using <tt>len</tt>, then
 +you're doing something wrong.
 +</p>
 +
 +<h2 id="serialize">Serialization of Lua Objects</h2>
 +<p>
 +The following functions and methods allow <b>high-speed serialization</b>
 +(encoding) of a Lua object into a string and decoding it back to a Lua
 +object. This allows convenient storage and transport of <b>structured
 +data</b>.
 +</p>
 +<p>
 +The encoded data is in an <a href="#serialize_format">internal binary
 +format</a>. The data can be stored in files, binary-transparent
 +databases or transmitted to other LuaJIT instances across threads,
 +processes or networks.
 +</p>
 +<p>
 +Encoding speed can reach up to 1 Gigabyte/second on a modern desktop- or
 +server-class system, even when serializing many small objects. Decoding
 +speed is mostly constrained by object creation cost.
 +</p>
 +<p>
 +The serializer handles most Lua types, common FFI number types and
 +nested structures. Functions, thread objects, other FFI cdata and full
 +userdata cannot be serialized (yet).
 +</p>
 +<p>
 +The encoder serializes nested structures as trees. Multiple references
 +to a single object will be stored separately and create distinct objects
 +after decoding. Circular references cause an error.
 +</p>
 +
 +<h3 id="serialize_methods">Serialization Functions and Methods</h3>
 +
 +<h3 id="buffer_encode"><tt>str = buffer.encode(obj)<br>
 +buf = buf:encode(obj)</tt></h3>
 +<p>
 +Serializes (encodes) the Lua object <tt>obj</tt>. The stand-alone
 +function returns a string <tt>str</tt>. The buffer method appends the
 +encoding to the buffer.
 +</p>
 +<p>
 +<tt>obj</tt> can be any of the supported Lua types &mdash; it doesn't
 +need to be a Lua table.
 +</p>
 +<p>
 +This function may throw an error when attempting to serialize
 +unsupported object types, circular references or deeply nested tables.
 +</p>
 +
 +<h3 id="buffer_decode"><tt>obj = buffer.decode(str)<br>
 +obj = buf:decode()</tt></h3>
 +<p>
 +The stand-alone function deserializes (decodes) the string
 +<tt>str</tt>, the buffer method deserializes one object from the
 +buffer. Both return a Lua object <tt>obj</tt>.
 +</p>
 +<p>
 +The returned object may be any of the supported Lua types &mdash;
 +even <tt>nil</tt>.
 +</p>
 +<p>
 +This function may throw an error when fed with malformed or incomplete
 +encoded data. The stand-alone function throws when there's left-over
 +data after decoding a single top-level object. The buffer method leaves
 +any left-over data in the buffer.
 +</p>
 +<p>
 +Attempting to deserialize an FFI type will throw an error, if the FFI
 +library is not built-in or has not been loaded, yet.
 +</p>
 +
 +<h3 id="serialize_options">Serialization Options</h3>
 +<p>
 +The <tt>options</tt> table passed to <tt>buffer.new()</tt> may contain
 +the following members (all optional):
 +</p>
 +<ul>
 +<li>
 +<tt>dict</tt> is a Lua table holding a <b>dictionary of strings</b> that
 +commonly occur as table keys of objects you are serializing. These keys
 +are compactly encoded as indexes during serialization. A well-chosen
 +dictionary saves space and improves serialization performance.
 +</li>
 +<li>
 +<tt>metatable</tt> is a Lua table holding a <b>dictionary of metatables</b>
 +for the table objects you are serializing.
 +</li>
 +</ul>
 +<p>
 +<tt>dict</tt> needs to be an array of strings and <tt>metatable</tt> needs
 +to be an array of tables. Both starting at index 1 and without holes (no
 +<tt>nil</tt> in between). The tables are anchored in the buffer object and
 +internally modified into a two-way index (don't do this yourself, just pass
 +a plain array). The tables must not be modified after they have been passed
 +to <tt>buffer.new()</tt>.
 +</p>
 +<p>
 +The <tt>dict</tt> and <tt>metatable</tt> tables used by the encoder and
 +decoder must be the same. Put the most common entries at the front. Extend
 +at the end to ensure backwards-compatibility &mdash; older encodings can
 +then still be read. You may also set some indexes to <tt>false</tt> to
 +explicitly drop backwards-compatibility. Old encodings that use these
 +indexes will throw an error when decoded.
 +</p>
 +<p>
 +Metatables that are not found in the <tt>metatable</tt> dictionary are
 +ignored when encoding. Decoding returns a table with a <tt>nil</tt>
 +metatable.
 +</p>
 +<p>
 +Note: parsing and preparation of the options table is somewhat
 +expensive. Create a buffer object only once and recycle it for multiple
 +uses. Avoid mixing encoder and decoder buffers, since the
 +<tt>buf:set()</tt> method frees the already allocated buffer space:
 +</p>
 +<pre class="code">
 +local options = {
 +  dict = { "commonly", "used", "string", "keys" },
 +}
 +local buf_enc = buffer.new(options)
 +local buf_dec = buffer.new(options)
 +
 +local function encode(obj)
 +  return buf_enc:reset():encode(obj):get()
 +end
 +
 +local function decode(str)
 +  return buf_dec:set(str):decode()
 +end
 +</pre>
 +
 +<h3 id="serialize_stream">Streaming Serialization</h3>
 +<p>
 +In some contexts, it's desirable to do piecewise serialization of large
 +datasets, also known as <i>streaming</i>.
 +</p>
 +<p>
 +This serialization format can be safely concatenated and supports streaming.
 +Multiple encodings can simply be appended to a buffer and later decoded
 +individually:
 +</p>
 +<pre class="code">
 +local buf = buffer.new()
 +buf:encode(obj1)
 +buf:encode(obj2)
 +local copy1 = buf:decode()
 +local copy2 = buf:decode()
 +</pre>
 +<p>
 +Here's how to iterate over a stream:
 +</p>
 +<pre class="code">
 +while #buf ~= 0 do
 +  local obj = buf:decode()
 +  -- Do something with obj.
 +end
 +</pre>
 +<p>
 +Since the serialization format doesn't prepend a length to its encoding,
 +network applications may need to transmit the length, too.
 +</p>
 +
 +<h3 id="serialize_format">Serialization Format Specification</h3>
 +<p>
 +This serialization format is designed for <b>internal use</b> by LuaJIT
 +applications. Serialized data is upwards-compatible and portable across
 +all supported LuaJIT platforms.
 +</p>
 +<p>
 +It's an <b>8-bit binary format</b> and not human-readable. It uses e.g.
 +embedded zeroes and stores embedded Lua string objects unmodified, which
 +are 8-bit-clean, too. Encoded data can be safely concatenated for
 +streaming and later decoded one top-level object at a time.
 +</p>
 +<p>
 +The encoding is reasonably compact, but tuned for maximum performance,
 +not for minimum space usage. It compresses well with any of the common
 +byte-oriented data compression algorithms.
 +</p>
 +<p>
 +Although documented here for reference, this format is explicitly
 +<b>not</b> intended to be a 'public standard' for structured data
 +interchange across computer languages (like JSON or MessagePack). Please
 +do not use it as such.
 +</p>
 +<p>
 +The specification is given below as a context-free grammar with a
 +top-level <tt>object</tt> as the starting point. Alternatives are
 +separated by the <tt>|</tt> symbol and <tt>*</tt> indicates repeats.
 +Grouping is implicit or indicated by <tt>{…}</tt>. Terminals are
 +either plain hex numbers, encoded as bytes, or have a <tt>.format</tt>
 +suffix.
 +</p>
 +<pre>
 +object    → nil | false | true
 +          | null | lightud32 | lightud64
 +          | int | num | tab | tab_mt
 +          | int64 | uint64 | complex
 +          | string
 +
 +nil       → 0x00
 +false     → 0x01
 +true      → 0x02
 +
 +null      → 0x03                            // NULL lightuserdata
 +lightud32 → 0x04 data.I                   // 32 bit lightuserdata
 +lightud64 → 0x05 data.L                   // 64 bit lightuserdata
 +
 +int       → 0x06 int.I                                 // int32_t
 +num       → 0x07 double.L
 +
 +tab       → 0x08                                   // Empty table
 +          | 0x09 h.U h*{object object}          // Key/value hash
 +          | 0x0a a.U a*object                    // 0-based array
 +          | 0x0b a.U a*object h.U h*{object object}      // Mixed
 +          | 0x0c a.U (a-1)*object                // 1-based array
 +          | 0x0d a.U (a-1)*object h.U h*{object object}  // Mixed
 +tab_mt    → 0x0e (index-1).U tab          // Metatable dict entry
 +
 +int64     → 0x10 int.L                             // FFI int64_t
 +uint64    → 0x11 uint.L                           // FFI uint64_t
 +complex   → 0x12 re.L im.L                         // FFI complex
 +
 +string    → (0x20+len).U len*char.B
 +          | 0x0f (index-1).U                 // String dict entry
 +
 +.B = 8 bit
 +.I = 32 bit little-endian
 +.L = 64 bit little-endian
 +.U = prefix-encoded 32 bit unsigned number n:
 +     0x00..0xdf   → n.B
 +     0xe0..0x1fdf → (0xe0|(((n-0xe0)>>8)&0x1f)).B ((n-0xe0)&0xff).B
 +   0x1fe0..       → 0xff n.I
 +</pre>
 +
 +<h2 id="error">Error handling</h2>
 +<p>
 +Many of the buffer methods can throw an error. Out-of-memory or usage
 +errors are best caught with an outer wrapper for larger parts of code.
 +There's not much one can do after that, anyway.
 +</p>
 +<p>
 +OTOH, you may want to catch some errors individually. Buffer methods need
 +to receive the buffer object as the first argument. The Lua colon-syntax
 +<tt>obj:method()</tt> does that implicitly. But to wrap a method with
 +<tt>pcall()</tt>, the arguments need to be passed like this:
 +</p>
 +<pre class="code">
 +local ok, err = pcall(buf.encode, buf, obj)
 +if not ok then
 +  -- Handle error in err.
 +end
 +</pre>
 +
 +<h2 id="ffi_caveats">FFI caveats</h2>
 +<p>
 +The string buffer library has been designed to work well together with
 +the FFI library. But due to the low-level nature of the FFI library,
 +some care needs to be taken:
 +</p>
 +<p>
 +First, please remember that FFI pointers are zero-indexed. The space
 +returned by <tt>buf:reserve()</tt> and <tt>buf:ref()</tt> starts at the
 +returned pointer and ends before <tt>len</tt> bytes after that.
 +</p>
 +<p>
 +I.e. the first valid index is <tt>ptr[0]</tt> and the last valid index
 +is <tt>ptr[len-1]</tt>. If the returned length is zero, there's no valid
 +index at all. The returned pointer may even be <tt>NULL</tt>.
 +</p>
 +<p>
 +The space pointed to by the returned pointer is only valid as long as
 +the buffer is not modified in any way (neither append, nor consume, nor
 +reset, etc.). The pointer is also not a GC anchor for the buffer object
 +itself.
 +</p>
 +<p>
 +Buffer data is only guaranteed to be byte-aligned. Casting the returned
 +pointer to a data type with higher alignment may cause unaligned
 +accesses. It depends on the CPU architecture whether this is allowed or
 +not (it's always OK on x86/x64 and mostly OK on other modern
 +architectures).
 +</p>
 +<p>
 +FFI pointers or references do not count as GC anchors for an underlying
 +object. E.g. an <tt>array</tt> allocated with <tt>ffi.new()</tt> is
 +anchored by <tt>buf:set(array,&nbsp;len)</tt>, but not by
 +<tt>buf:set(array+offset,&nbsp;len)</tt>. The addition of the offset
 +creates a new pointer, even when the offset is zero. In this case, you
 +need to make sure there's still a reference to the original array as
 +long as its contents are in use by the buffer.
 +</p>
 +<p>
 +Even though each LuaJIT VM instance is single-threaded (but you can
 +create multiple VMs), FFI data structures can be accessed concurrently.
 +Be careful when reading/writing FFI cdata from/to buffers to avoid
 +concurrent accesses or modifications. In particular, the memory
 +referenced by <tt>buf:set(cdata,&nbsp;len)</tt> must not be modified
 +while buffer readers are working on it. Shared, but read-only memory
 +mappings of files are OK, but only if the file does not change.
 +</p>
 +<br class="flush">
 +</div>
 +<div id="foot">
 +<hr class="hide">
 +Copyright &copy; 2005-2023
 +<span class="noprint">
 +&middot;
 +<a href="contact.html">Contact</a>
 +</span>
 +</div>
 +</body>
 +</html>
index ab72d19ae2048de9c8ca03f5a9ae3eeb9f892c56,43c8204719229d32b9ee20127adfc3e14164d811..d5e6bb60f47370a46dd96a9ef1652887205527fe
  <a href="ext_jit.html">jit.* Library</a>
  </li><li>
  <a class="current" href="ext_c_api.html">Lua/C API</a>
 +</li><li>
 +<a href="ext_profiler.html">Profiler</a>
  </li></ul>
  </li><li>
- <a href="status.html">Status</a>
+ <a href="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
  </li><li>
- <a href="faq.html">FAQ</a>
+ <a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></a>
  </li><li>
  <a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
  </li></ul>
index e8e5565d232204f1fe2398c0734b0754158d7e9b,683c0cd0fb2435a55607f4bbe5155a0117f0dc00..eaa176b615ad59090e47a3986782c73d737a4ff9
  <a href="ext_jit.html">jit.* Library</a>
  </li><li>
  <a href="ext_c_api.html">Lua/C API</a>
 +</li><li>
 +<a href="ext_profiler.html">Profiler</a>
  </li></ul>
  </li><li>
- <a href="status.html">Status</a>
+ <a href="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
  </li><li>
- <a href="faq.html">FAQ</a>
+ <a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></a>
  </li><li>
  <a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
  </li></ul>
index ea03168a6a5915a188598f40da04daa0b2be8c84,d5f7032fbdf98d094c6af8d147743e027ad8d96e..500a2143ee8317ab31044fb3bcc6e1bae68e23ca
@@@ -47,13 -45,11 +47,13 @@@ td.abiparam { font-weight: bold; width
  <a href="ext_jit.html">jit.* Library</a>
  </li><li>
  <a href="ext_c_api.html">Lua/C API</a>
 +</li><li>
 +<a href="ext_profiler.html">Profiler</a>
  </li></ul>
  </li><li>
- <a href="status.html">Status</a>
+ <a href="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
  </li><li>
- <a href="faq.html">FAQ</a>
+ <a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></a>
  </li><li>
  <a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
  </li></ul>
index 419ef07adb2fab9083b21acbe26c360e5162eba1,381a2010ecea789571385b76617391ac3310b2aa..5ba82a1e77b32c310220b73c28b305a4637df734
@@@ -47,13 -45,11 +47,13 @@@ td.convop { font-style: italic; width: 
  <a href="ext_jit.html">jit.* Library</a>
  </li><li>
  <a href="ext_c_api.html">Lua/C API</a>
 +</li><li>
 +<a href="ext_profiler.html">Profiler</a>
  </li></ul>
  </li><li>
- <a href="status.html">Status</a>
+ <a href="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
  </li><li>
- <a href="faq.html">FAQ</a>
+ <a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></a>
  </li><li>
  <a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
  </li></ul>
index 3cf4862a4b0d0c168246da77cbcdf6804840a528,03b6ec56953e24207dc2a0fb9332bdbe76662f65..a5236f0bd0e28e2bfbb810d6946e07a2d48e096f
@@@ -49,13 -47,11 +49,13 @@@ td.idiomlua b { font-weight: normal; co
  <a href="ext_jit.html">jit.* Library</a>
  </li><li>
  <a href="ext_c_api.html">Lua/C API</a>
 +</li><li>
 +<a href="ext_profiler.html">Profiler</a>
  </li></ul>
  </li><li>
- <a href="status.html">Status</a>
+ <a href="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
  </li><li>
- <a href="faq.html">FAQ</a>
+ <a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></a>
  </li><li>
  <a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
  </li></ul>
index 7bf9f343d41bccad065d15ccddc16baf9882652c,b1dbf36c2ccc18161386829e061b5ff34294d047..dd136d65e90a0b8519b6fcdeb45009b073c64e21
  <a class="current" href="ext_jit.html">jit.* Library</a>
  </li><li>
  <a href="ext_c_api.html">Lua/C API</a>
 +</li><li>
 +<a href="ext_profiler.html">Profiler</a>
  </li></ul>
  </li><li>
- <a href="status.html">Status</a>
+ <a href="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
  </li><li>
- <a href="faq.html">FAQ</a>
+ <a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></a>
  </li><li>
  <a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
  </li></ul>
index 18880239c3217baf708c0dba0a0df9edaa9563a2,0000000000000000000000000000000000000000..81b5d7739cd08a0ef8f29cf775ca1a2184a5d7ba
mode 100644,000000..100644
--- /dev/null
@@@ -1,359 -1,0 +1,359 @@@
- <a href="status.html">Status</a>
 +<!DOCTYPE html>
 +<html>
 +<head>
 +<title>Profiler</title>
 +<meta charset="utf-8">
 +<meta name="Copyright" content="Copyright (C) 2005-2023">
 +<meta name="Language" content="en">
 +<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 +<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
 +</head>
 +<body>
 +<div id="site">
 +<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
 +</div>
 +<div id="head">
 +<h1>Profiler</h1>
 +</div>
 +<div id="nav">
 +<ul><li>
 +<a href="luajit.html">LuaJIT</a>
 +<ul><li>
 +<a href="https://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
 +</li><li>
 +<a href="install.html">Installation</a>
 +</li><li>
 +<a href="running.html">Running</a>
 +</li></ul>
 +</li><li>
 +<a href="extensions.html">Extensions</a>
 +<ul><li>
 +<a href="ext_ffi.html">FFI Library</a>
 +<ul><li>
 +<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
 +</li><li>
 +<a href="ext_ffi_api.html">ffi.* API</a>
 +</li><li>
 +<a href="ext_ffi_semantics.html">FFI Semantics</a>
 +</li></ul>
 +</li><li>
 +<a href="ext_buffer.html">String Buffers</a>
 +</li><li>
 +<a href="ext_jit.html">jit.* Library</a>
 +</li><li>
 +<a href="ext_c_api.html">Lua/C API</a>
 +</li><li>
 +<a class="current" href="ext_profiler.html">Profiler</a>
 +</li></ul>
 +</li><li>
- <a href="faq.html">FAQ</a>
++<a href="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
 +</li><li>
++<a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></a>
 +</li><li>
 +<a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
 +</li></ul>
 +</div>
 +<div id="main">
 +<p>
 +LuaJIT has an integrated statistical profiler with very low overhead. It
 +allows sampling the currently executing stack and other parameters in
 +regular intervals.
 +</p>
 +<p>
 +The integrated profiler can be accessed from three levels:
 +</p>
 +<ul>
 +<li>The <a href="#hl_profiler">bundled high-level profiler</a>, invoked by the
 +<a href="#j_p"><tt>-jp</tt></a> command line option.</li>
 +<li>A <a href="#ll_lua_api">low-level Lua API</a> to control the profiler.</li>
 +<li>A <a href="#ll_c_api">low-level C API</a> to control the profiler.</li>
 +</ul>
 +
 +<h2 id="hl_profiler">High-Level Profiler</h2>
 +<p>
 +The bundled high-level profiler offers basic profiling functionality. It
 +generates simple textual summaries or source code annotations. It can be
 +accessed with the <a href="#j_p"><tt>-jp</tt></a> command line option
 +or from Lua code by loading the underlying <tt>jit.p</tt> module.
 +</p>
 +<p>
 +To cut to the chase &mdash; run this to get a CPU usage profile by
 +function name:
 +</p>
 +<pre class="code">
 +luajit -jp myapp.lua
 +</pre>
 +<p>
 +It's <em>not</em> a stated goal of the bundled profiler to add every
 +possible option or to cater for special profiling needs. The low-level
 +profiler APIs are documented below. They may be used by third-party
 +authors to implement advanced functionality, e.g. IDE integration or
 +graphical profilers.
 +</p>
 +<p>
 +Note: Sampling works for both interpreted and JIT-compiled code. The
 +results for JIT-compiled code may sometimes be surprising. LuaJIT
 +heavily optimizes and inlines Lua code &mdash; there's no simple
 +one-to-one correspondence between source code lines and the sampled
 +machine code.
 +</p>
 +
 +<h3 id="j_p"><tt>-jp=[options[,output]]</tt></h3>
 +<p>
 +The <tt>-jp</tt> command line option starts the high-level profiler.
 +When the application run by the command line terminates, the profiler
 +stops and writes the results to <tt>stdout</tt> or to the specified
 +<tt>output</tt> file.
 +</p>
 +<p>
 +The <tt>options</tt> argument specifies how the profiling is to be
 +performed:
 +</p>
 +<ul>
 +<li><tt>f</tt> &mdash; Stack dump: function name, otherwise module:line.
 +This is the default mode.</li>
 +<li><tt>F</tt> &mdash; Stack dump: ditto, but dump module:name.</li>
 +<li><tt>l</tt> &mdash; Stack dump: module:line.</li>
 +<li><tt>&lt;number&gt;</tt> &mdash; stack dump depth (callee &larr;
 +caller). Default: 1.</li>
 +<li><tt>-&lt;number&gt;</tt> &mdash; Inverse stack dump depth (caller
 +&rarr; callee).</li>
 +<li><tt>s</tt> &mdash; Split stack dump after first stack level. Implies
 +depth&nbsp;&ge;&nbsp;2 or depth&nbsp;&le;&nbsp;-2.</li>
 +<li><tt>p</tt> &mdash; Show full path for module names.</li>
 +<li><tt>v</tt> &mdash; Show VM states.</li>
 +<li><tt>z</tt> &mdash; Show <a href="#jit_zone">zones</a>.</li>
 +<li><tt>r</tt> &mdash; Show raw sample counts. Default: show percentages.</li>
 +<li><tt>a</tt> &mdash; Annotate excerpts from source code files.</li>
 +<li><tt>A</tt> &mdash; Annotate complete source code files.</li>
 +<li><tt>G</tt> &mdash; Produce raw output suitable for graphical tools.</li>
 +<li><tt>m&lt;number&gt;</tt> &mdash; Minimum sample percentage to be shown.
 +Default: 3%.</li>
 +<li><tt>i&lt;number&gt;</tt> &mdash; Sampling interval in milliseconds.
 +Default: 10ms.<br>
 +Note: The actual sampling precision is OS-dependent.</li>
 +</ul>
 +<p>
 +The default output for <tt>-jp</tt> is a list of the most CPU consuming
 +spots in the application. Increasing the stack dump depth with (say)
 +<tt>-jp=2</tt> may help to point out the main callers or callees of
 +hotspots. But sample aggregation is still flat per unique stack dump.
 +</p>
 +<p>
 +To get a two-level view (split view) of callers/callees, use
 +<tt>-jp=s</tt> or <tt>-jp=-s</tt>. The percentages shown for the second
 +level are relative to the first level.
 +</p>
 +<p>
 +To see how much time is spent in each line relative to a function, use
 +<tt>-jp=fl</tt>.
 +</p>
 +<p>
 +To see how much time is spent in different VM states or
 +<a href="#jit_zone">zones</a>, use <tt>-jp=v</tt> or <tt>-jp=z</tt>.
 +</p>
 +<p>
 +Combinations of <tt>v/z</tt> with <tt>f/F/l</tt> produce two-level
 +views, e.g. <tt>-jp=vf</tt> or <tt>-jp=fv</tt>. This shows the time
 +spent in a VM state or zone vs. hotspots. This can be used to answer
 +questions like "Which time-consuming functions are only interpreted?" or
 +"What's the garbage collector overhead for a specific function?".
 +</p>
 +<p>
 +Multiple options can be combined &mdash; but not all combinations make
 +sense, see above. E.g. <tt>-jp=3si4m1</tt> samples three stack levels
 +deep in 4ms intervals and shows a split view of the CPU consuming
 +functions and their callers with a 1% threshold.
 +</p>
 +<p>
 +Source code annotations produced by <tt>-jp=a</tt> or <tt>-jp=A</tt> are
 +always flat and at the line level. Obviously, the source code files need
 +to be readable by the profiler script.
 +</p>
 +<p>
 +The high-level profiler can also be started and stopped from Lua code with:
 +</p>
 +<pre class="code">
 +require("jit.p").start(options, output)
 +...
 +require("jit.p").stop()
 +</pre>
 +
 +<h3 id="jit_zone"><tt>jit.zone</tt> &mdash; Zones</h3>
 +<p>
 +Zones can be used to provide information about different parts of an
 +application to the high-level profiler. E.g. a game could make use of an
 +<tt>"AI"</tt> zone, a <tt>"PHYS"</tt> zone, etc. Zones are hierarchical,
 +organized as a stack.
 +</p>
 +<p>
 +The <tt>jit.zone</tt> module needs to be loaded explicitly:
 +</p>
 +<pre class="code">
 +local zone = require("jit.zone")
 +</pre>
 +<ul>
 +<li><tt>zone("name")</tt> pushes a named zone to the zone stack.</li>
 +<li><tt>zone()</tt> pops the current zone from the zone stack and
 +returns its name.</li>
 +<li><tt>zone:get()</tt> returns the current zone name or <tt>nil</tt>.</li>
 +<li><tt>zone:flush()</tt> flushes the zone stack.</li>
 +</ul>
 +<p>
 +To show the time spent in each zone use <tt>-jp=z</tt>. To show the time
 +spent relative to hotspots use e.g. <tt>-jp=zf</tt> or <tt>-jp=fz</tt>.
 +</p>
 +
 +<h2 id="ll_lua_api">Low-level Lua API</h2>
 +<p>
 +The <tt>jit.profile</tt> module gives access to the low-level API of the
 +profiler from Lua code. This module needs to be loaded explicitly:
 +<pre class="code">
 +local profile = require("jit.profile")
 +</pre>
 +<p>
 +This module can be used to implement your own higher-level profiler.
 +A typical profiling run starts the profiler, captures stack dumps in
 +the profiler callback, adds them to a hash table to aggregate the number
 +of samples, stops the profiler and then analyzes all captured
 +stack dumps. Other parameters can be sampled in the profiler callback,
 +too. But it's important not to spend too much time in the callback,
 +since this may skew the statistics.
 +</p>
 +
 +<h3 id="profile_start"><tt>profile.start(mode, cb)</tt>
 +&mdash; Start profiler</h3>
 +<p>
 +This function starts the profiler. The <tt>mode</tt> argument is a
 +string holding options:
 +</p>
 +<ul>
 +<li><tt>f</tt> &mdash; Profile with precision down to the function level.</li>
 +<li><tt>l</tt> &mdash; Profile with precision down to the line level.</li>
 +<li><tt>i&lt;number&gt;</tt> &mdash; Sampling interval in milliseconds (default
 +10ms).</br>
 +Note: The actual sampling precision is OS-dependent.
 +</li>
 +</ul>
 +<p>
 +The <tt>cb</tt> argument is a callback function which is called with
 +three arguments: <tt>(thread, samples, vmstate)</tt>. The callback is
 +called on a separate coroutine, the <tt>thread</tt> argument is the
 +state that holds the stack to sample for profiling. Note: do
 +<em>not</em> modify the stack of that state or call functions on it.
 +</p>
 +<p>
 +<tt>samples</tt> gives the number of accumulated samples since the last
 +callback (usually 1).
 +</p>
 +<p>
 +<tt>vmstate</tt> holds the VM state at the time the profiling timer
 +triggered. This may or may not correspond to the state of the VM when
 +the profiling callback is called. The state is either <tt>'N'</tt>
 +native (compiled) code, <tt>'I'</tt> interpreted code, <tt>'C'</tt>
 +C&nbsp;code, <tt>'G'</tt> the garbage collector, or <tt>'J'</tt> the JIT
 +compiler.
 +</p>
 +
 +<h3 id="profile_stop"><tt>profile.stop()</tt>
 +&mdash; Stop profiler</h3>
 +<p>
 +This function stops the profiler.
 +</p>
 +
 +<h3 id="profile_dump"><tt>dump = profile.dumpstack([thread,] fmt, depth)</tt>
 +&mdash; Dump stack </h3>
 +<p>
 +This function allows taking stack dumps in an efficient manner. It
 +returns a string with a stack dump for the <tt>thread</tt> (coroutine),
 +formatted according to the <tt>fmt</tt> argument:
 +</p>
 +<ul>
 +<li><tt>p</tt> &mdash; Preserve the full path for module names. Otherwise,
 +only the file name is used.</li>
 +<li><tt>f</tt> &mdash; Dump the function name if it can be derived. Otherwise,
 +use module:line.</li>
 +<li><tt>F</tt> &mdash; Ditto, but dump module:name.</li>
 +<li><tt>l</tt> &mdash; Dump module:line.</li>
 +<li><tt>Z</tt> &mdash; Zap the following characters for the last dumped
 +frame.</li>
 +<li>All other characters are added verbatim to the output string.</li>
 +</ul>
 +<p>
 +The <tt>depth</tt> argument gives the number of frames to dump, starting
 +at the topmost frame of the thread. A negative number dumps the frames in
 +inverse order.
 +</p>
 +<p>
 +The first example prints a list of the current module names and line
 +numbers of up to 10 frames in separate lines. The second example prints
 +semicolon-separated function names for all frames (up to 100) in inverse
 +order:
 +</p>
 +<pre class="code">
 +print(profile.dumpstack(thread, "l\n", 10))
 +print(profile.dumpstack(thread, "lZ;", -100))
 +</pre>
 +
 +<h2 id="ll_c_api">Low-level C API</h2>
 +<p>
 +The profiler can be controlled directly from C&nbsp;code, e.g. for
 +use by IDEs. The declarations are in <tt>"luajit.h"</tt> (see
 +<a href="ext_c_api.html">Lua/C API</a> extensions).
 +</p>
 +
 +<h3 id="luaJIT_profile_start"><tt>luaJIT_profile_start(L, mode, cb, data)</tt>
 +&mdash; Start profiler</h3>
 +<p>
 +This function starts the profiler. <a href="#profile_start">See
 +above</a> for a description of the <tt>mode</tt> argument.
 +</p>
 +<p>
 +The <tt>cb</tt> argument is a callback function with the following
 +declaration:
 +</p>
 +<pre class="code">
 +typedef void (*luaJIT_profile_callback)(void *data, lua_State *L,
 +                                        int samples, int vmstate);
 +</pre>
 +<p>
 +<tt>data</tt> is available for use by the callback. <tt>L</tt> is the
 +state that holds the stack to sample for profiling. Note: do
 +<em>not</em> modify this stack or call functions on this stack &mdash;
 +use a separate coroutine for this purpose. <a href="#profile_start">See
 +above</a> for a description of <tt>samples</tt> and <tt>vmstate</tt>.
 +</p>
 +
 +<h3 id="luaJIT_profile_stop"><tt>luaJIT_profile_stop(L)</tt>
 +&mdash; Stop profiler</h3>
 +<p>
 +This function stops the profiler.
 +</p>
 +
 +<h3 id="luaJIT_profile_dumpstack"><tt>p = luaJIT_profile_dumpstack(L, fmt, depth, len)</tt>
 +&mdash; Dump stack </h3>
 +<p>
 +This function allows taking stack dumps in an efficient manner.
 +<a href="#profile_dump">See above</a> for a description of <tt>fmt</tt>
 +and <tt>depth</tt>.
 +</p>
 +<p>
 +This function returns a <tt>const&nbsp;char&nbsp;*</tt> pointing to a
 +private string buffer of the profiler. The <tt>int&nbsp;*len</tt>
 +argument returns the length of the output string. The buffer is
 +overwritten on the next call and deallocated when the profiler stops.
 +You either need to consume the content immediately or copy it for later
 +use.
 +</p>
 +<br class="flush">
 +</div>
 +<div id="foot">
 +<hr class="hide">
 +Copyright &copy; 2005-2023
 +<span class="noprint">
 +&middot;
 +<a href="contact.html">Contact</a>
 +</span>
 +</div>
 +</body>
 +</html>
index c7ace01586819b0e77f4491a06559e4ea7c88277,f8b45c28594da1b960de8dd4ef85fbdd7cbf6b80..eb591d1e758013c512eb984514c986ac23b92111
@@@ -59,13 -57,11 +59,13 @@@ td.excinterop 
  <a href="ext_jit.html">jit.* Library</a>
  </li><li>
  <a href="ext_c_api.html">Lua/C API</a>
 +</li><li>
 +<a href="ext_profiler.html">Profiler</a>
  </li></ul>
  </li><li>
- <a href="status.html">Status</a>
+ <a href="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
  </li><li>
- <a href="faq.html">FAQ</a>
+ <a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></a>
  </li><li>
  <a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
  </li></ul>
index 0ccd37aafab00244dacb200ac70636837df3f2db,218663151cd29a059a27f1000bce046c5bc1323b..be721031b814f85e9989ded45e820f3d76b7134b
@@@ -65,13 -63,11 +65,13 @@@ td.compatx 
  <a href="ext_jit.html">jit.* Library</a>
  </li><li>
  <a href="ext_c_api.html">Lua/C API</a>
 +</li><li>
 +<a href="ext_profiler.html">Profiler</a>
  </li></ul>
  </li><li>
- <a href="status.html">Status</a>
+ <a href="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
  </li><li>
- <a href="faq.html">FAQ</a>
+ <a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></a>
  </li><li>
  <a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
  </li></ul>
@@@ -510,28 -283,22 +312,28 @@@ Here are some examples for targets wit
  make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- \
       TARGET_CFLAGS="-mfloat-abi=soft"
  
 -# ARM soft-float ABI with VFP (example for Cortex-A8)
 +# ARM soft-float ABI with VFP (example for Cortex-A9)
  make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- \
 -     TARGET_CFLAGS="-mcpu=cortex-a8 -mfloat-abi=softfp"
 +     TARGET_CFLAGS="-mcpu=cortex-a9 -mfloat-abi=softfp"
  
 -# ARM hard-float ABI with VFP (armhf, requires recent toolchain)
 +# ARM hard-float ABI with VFP (armhf, most modern toolchains)
  make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabihf-
  
- make CROSS=aarch64-linux-
 +# ARM64
++make CROSS=aarch64-linux-gnu-
 +
  # PPC
  make HOST_CC="gcc -m32" CROSS=powerpc-linux-gnu-
 -# PPC/e500v2 (fast interpreter only)
 -make HOST_CC="gcc -m32" CROSS=powerpc-e500v2-linux-gnuspe-
  
 -# MIPS big-endian
 -make HOST_CC="gcc -m32" CROSS=mips-linux-
 -# MIPS little-endian
 -make HOST_CC="gcc -m32" CROSS=mipsel-linux-
 +# MIPS32 big-endian
- make HOST_CC="gcc -m32" CROSS=mips-linux-
++make HOST_CC="gcc -m32" CROSS=mips-linux-gnu-
 +# MIPS32 little-endian
- make HOST_CC="gcc -m32" CROSS=mipsel-linux-
++make HOST_CC="gcc -m32" CROSS=mipsel-linux-gnu-
 +
 +# MIPS64 big-endian
 +make CROSS=mips-linux- TARGET_CFLAGS="-mips64r2 -mabi=64"
 +# MIPS64 little-endian
 +make CROSS=mipsel-linux- TARGET_CFLAGS="-mips64r2 -mabi=64"
  </pre>
  <p>
  You can cross-compile for <b id="android">Android</b> using the <a href="https://developer.android.com/ndk/"><span class="ext">&raquo;</span>&nbsp;Android NDK</a>.
diff --cc doc/luajit.html
index 3bb8aaf27768f66d55fc3714b03a56726d29361a,7346acb31e26eec8e2ef5dbd8fb7cbf5173978d1..030cf705ad79e5528a43309658871e384bedcb53
@@@ -127,13 -101,11 +103,13 @@@ table.fcompat td 
  <a href="ext_jit.html">jit.* Library</a>
  </li><li>
  <a href="ext_c_api.html">Lua/C API</a>
 +</li><li>
 +<a href="ext_profiler.html">Profiler</a>
  </li></ul>
  </li><li>
- <a href="status.html">Status</a>
+ <a href="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
  </li><li>
- <a href="faq.html">FAQ</a>
+ <a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></a>
  </li><li>
  <a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
  </li></ul>
index 325cb6bb902b5bdb7e0c60907ea761db97ad34c3,c7d9e9b6980c7d4a04e8936458574cae9ee2fe8d..3afc1b560b5508c1f61e763e8dc4b70b6a52dd7a
@@@ -64,13 -62,11 +64,13 @@@ td.param_default 
  <a href="ext_jit.html">jit.* Library</a>
  </li><li>
  <a href="ext_c_api.html">Lua/C API</a>
 +</li><li>
 +<a href="ext_profiler.html">Profiler</a>
  </li></ul>
  </li><li>
- <a href="status.html">Status</a>
+ <a href="https://luajit.org/status.html">Status <span class="ext">&raquo;</span></a>
  </li><li>
- <a href="faq.html">FAQ</a>
+ <a href="https://luajit.org/faq.html">FAQ <span class="ext">&raquo;</span></a>
  </li><li>
  <a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
  </li></ul>