From: Mike Pall Date: Mon, 21 Aug 2023 00:38:56 +0000 (+0200) Subject: Merge branch 'master' into v2.1 X-Git-Tag: v2.1.ROLLING~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f0ff869bc2fffa17bb765c4c773457578da125a9;p=thirdparty%2FLuaJIT.git Merge branch 'master' into v2.1 --- f0ff869bc2fffa17bb765c4c773457578da125a9 diff --cc README index e6631432,dfa7ca94..e4a69265 --- a/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. diff --cc doc/contact.html index 478c4bff,c32bc9dc..cc4d8c72 --- a/doc/contact.html +++ b/doc/contact.html @@@ -42,13 -40,11 +42,13 @@@ jit.* Library
  • Lua/C API +
  • +Profiler
  • - Status + Status »
  • - FAQ + FAQ »
  • Mailing List »
  • diff --cc doc/ext_buffer.html index 35f01c9a,00000000..bfaa24cb mode 100644,000000..100644 --- a/doc/ext_buffer.html +++ b/doc/ext_buffer.html @@@ -1,689 -1,0 +1,689 @@@ + + + +String Buffer Library + + + + + + + + +
    +Lua +
    + + +
    +

    +The string buffer library allows high-performance manipulation of +string-like data. +

    +

    +Unlike Lua strings, which are constants, string buffers are +mutable sequences of 8-bit (binary-transparent) characters. Data +can be stored, formatted and encoded into a string buffer and later +converted, extracted or decoded. +

    +

    +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. +

    +

    +The string buffer library also includes a high-performance +serializer for Lua objects. +

    + +

    Using the String Buffer Library

    +

    +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: +

    +
     +local buffer = require("string.buffer")
     +
    +

    +The convention for the syntax shown on this page is that buffer +refers to the buffer library and buf refers to an individual +buffer object. +

    +

    +Please note the difference between a Lua function call, e.g. +buffer.new() (with a dot) and a Lua method call, e.g. +buf:reset() (with a colon). +

    + +

    Buffer Objects

    +

    +A buffer object is a garbage-collected Lua object. After creation with +buffer.new(), 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. +

    +

    +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. +

    +

    +The buffer space that holds the characters is managed automatically +— it grows as needed and already consumed space is recycled. Use +buffer.new(size) and buf:free(), if you need more +control. +

    +

    +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 — use the +FFI library to directly map memory or files up to the virtual memory +limit of your OS. +

    + +

    Buffer Method Overview

    + + +

    Buffer Creation and Management

    + +

    local buf = buffer.new([size [,options]])
    +local buf = buffer.new([options])

    +

    +Creates a new buffer object. +

    +

    +The optional size 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. +

    +

    +The optional table options sets various +serialization options. +

    + +

    buf = buf:reset()

    +

    +Reset (empty) the buffer. The allocated buffer space is not freed and +may be reused. +

    + +

    buf = buf:free()

    +

    +The buffer space of the buffer object is freed. The object itself +remains intact, empty and may be reused. +

    +

    +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. +

    + +

    Buffer Writers

    + +

    buf = buf:put([str|num|obj] [,…])

    +

    +Appends a string str, a number num or any object +obj with a __tostring metamethod to the buffer. +Multiple arguments are appended in the given order. +

    +

    +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. +

    + +

    buf = buf:putf(format, …)

    +

    +Appends the formatted arguments to the buffer. The format +string supports the same options as string.format(). +

    + +

    buf = buf:putcdata(cdata, len)FFI

    +

    +Appends the given len number of bytes from the memory pointed +to by the FFI cdata object to the buffer. The object needs to +be convertible to a (constant) pointer. +

    + +

    buf = buf:set(str)
    +buf = buf:set(cdata, len)
    FFI

    +

    +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 +str or the FFI cdata object in the buffer. Any buffer +space originally allocated is freed. This is not an append +operation, unlike the buf:put*() methods. +

    +

    +After calling this method, the buffer behaves as if +buf:free():put(str) or buf:free():put(cdata, len) +had been called. However, the data is only referenced and not copied, as +long as the buffer is only consumed. +

    +

    +In case the buffer is written to later on, the referenced data is copied +and the object reference is removed (copy-on-write semantics). +

    +

    +The stored reference is an anchor for the garbage collector and keeps the +originally passed string or FFI cdata object alive. +

    + +

    ptr, len = buf:reserve(size)FFI
    +buf = buf:commit(used)FFI

    +

    +The reserve method reserves at least size bytes of +write space in the buffer. It returns an uint8_t * FFI +cdata pointer ptr that points to this space. +

    +

    +The available length in bytes is returned in len. This is at +least size bytes, but may be more to facilitate efficient +buffer growth. You can either make use of the additional space or ignore +len and only use size bytes. +

    +

    +The commit method appends the used bytes of the +previously returned write space to the buffer data. +

    +

    +This pair of methods allows zero-copy use of C read-style APIs: +

    +
     +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 < 0 then error("read error") end
     +  buf:commit(n)
     +until false
     +
    +

    +The reserved write space is not initialized. At least the +used bytes must be written to before calling the +commit method. There's no need to call the commit +method, if nothing is added to the buffer (e.g. on error). +

    + +

    Buffer Readers

    + +

    len = #buf

    +

    +Returns the current length of the buffer data in bytes. +

    + +

    res = str|num|buf .. str|num|buf […]

    +

    +The Lua concatenation operator .. also accepts buffers, just +like strings or numbers. It always returns a string and not a buffer. +

    +

    +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 buf:put() and buf:get(). +

    +

    +Mixing this with unrelated objects that have a __concat +metamethod may not work, since these probably only expect strings. +

    + +

    buf = buf:skip(len)

    +

    +Skips (consumes) len bytes from the buffer up to the current +length of the buffer data. +

    + +

    str, … = buf:get([len|nil] [,…])

    +

    +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 len bytes are consumed. A nil argument +consumes the remaining buffer space (this only makes sense as the last +argument). Multiple arguments consume the buffer data in the given +order. +

    +

    +Note: a zero length or no remaining buffer data returns an empty string +and not nil. +

    + +

    str = buf:tostring()
    +str = tostring(buf)

    +

    +Creates a string from the buffer data, but doesn't consume it. The +buffer remains unchanged. +

    +

    +Buffer objects also define a __tostring metamethod. This means +buffers can be passed to the global tostring() function and +many other functions that accept this in place of strings. The important +internal uses in functions like io.write() are short-circuited +to avoid the creation of an intermediate string object. +

    + +

    ptr, len = buf:ref()FFI

    +

    +Returns an uint8_t * FFI cdata pointer ptr that +points to the buffer data. The length of the buffer data in bytes is +returned in len. +

    +

    +The returned pointer can be directly passed to C functions that expect a +buffer and a length. You can also do bytewise reads +(local x = ptr[i]) or writes +(ptr[i] = 0x40) of the buffer data. +

    +

    +In conjunction with the skip method, this allows zero-copy use +of C write-style APIs: +

    +
     +repeat
     +  local ptr, len = buf:ref()
     +  if len == 0 then break end
     +  local n = C.write(fd, ptr, len)
     +  if n < 0 then error("write error") end
     +  buf:skip(n)
     +until n >= len
     +
    +

    +Unlike Lua strings, buffer data is not implicitly +zero-terminated. It's not safe to pass ptr to C functions that +expect zero-terminated strings. If you're not using len, then +you're doing something wrong. +

    + +

    Serialization of Lua Objects

    +

    +The following functions and methods allow high-speed serialization +(encoding) of a Lua object into a string and decoding it back to a Lua +object. This allows convenient storage and transport of structured +data. +

    +

    +The encoded data is in an internal binary +format. The data can be stored in files, binary-transparent +databases or transmitted to other LuaJIT instances across threads, +processes or networks. +

    +

    +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. +

    +

    +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). +

    +

    +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. +

    + +

    Serialization Functions and Methods

    + +

    str = buffer.encode(obj)
    +buf = buf:encode(obj)

    +

    +Serializes (encodes) the Lua object obj. The stand-alone +function returns a string str. The buffer method appends the +encoding to the buffer. +

    +

    +obj can be any of the supported Lua types — it doesn't +need to be a Lua table. +

    +

    +This function may throw an error when attempting to serialize +unsupported object types, circular references or deeply nested tables. +

    + +

    obj = buffer.decode(str)
    +obj = buf:decode()

    +

    +The stand-alone function deserializes (decodes) the string +str, the buffer method deserializes one object from the +buffer. Both return a Lua object obj. +

    +

    +The returned object may be any of the supported Lua types — +even nil. +

    +

    +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. +

    +

    +Attempting to deserialize an FFI type will throw an error, if the FFI +library is not built-in or has not been loaded, yet. +

    + +

    Serialization Options

    +

    +The options table passed to buffer.new() may contain +the following members (all optional): +

    + +

    +dict needs to be an array of strings and metatable needs +to be an array of tables. Both starting at index 1 and without holes (no +nil 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 buffer.new(). +

    +

    +The dict and metatable 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 — older encodings can +then still be read. You may also set some indexes to false to +explicitly drop backwards-compatibility. Old encodings that use these +indexes will throw an error when decoded. +

    +

    +Metatables that are not found in the metatable dictionary are +ignored when encoding. Decoding returns a table with a nil +metatable. +

    +

    +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 +buf:set() method frees the already allocated buffer space: +

    +
     +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
     +
    + +

    Streaming Serialization

    +

    +In some contexts, it's desirable to do piecewise serialization of large +datasets, also known as streaming. +

    +

    +This serialization format can be safely concatenated and supports streaming. +Multiple encodings can simply be appended to a buffer and later decoded +individually: +

    +
     +local buf = buffer.new()
     +buf:encode(obj1)
     +buf:encode(obj2)
     +local copy1 = buf:decode()
     +local copy2 = buf:decode()
     +
    +

    +Here's how to iterate over a stream: +

    +
     +while #buf ~= 0 do
     +  local obj = buf:decode()
     +  -- Do something with obj.
     +end
     +
    +

    +Since the serialization format doesn't prepend a length to its encoding, +network applications may need to transmit the length, too. +

    + +

    Serialization Format Specification

    +

    +This serialization format is designed for internal use by LuaJIT +applications. Serialized data is upwards-compatible and portable across +all supported LuaJIT platforms. +

    +

    +It's an 8-bit binary format 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. +

    +

    +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. +

    +

    +Although documented here for reference, this format is explicitly +not intended to be a 'public standard' for structured data +interchange across computer languages (like JSON or MessagePack). Please +do not use it as such. +

    +

    +The specification is given below as a context-free grammar with a +top-level object as the starting point. Alternatives are +separated by the | symbol and * indicates repeats. +Grouping is implicit or indicated by {…}. Terminals are +either plain hex numbers, encoded as bytes, or have a .format +suffix. +

    +
     +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
     +
    + +

    Error handling

    +

    +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. +

    +

    +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 +obj:method() does that implicitly. But to wrap a method with +pcall(), the arguments need to be passed like this: +

    +
     +local ok, err = pcall(buf.encode, buf, obj)
     +if not ok then
     +  -- Handle error in err.
     +end
     +
    + +

    FFI caveats

    +

    +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: +

    +

    +First, please remember that FFI pointers are zero-indexed. The space +returned by buf:reserve() and buf:ref() starts at the +returned pointer and ends before len bytes after that. +

    +

    +I.e. the first valid index is ptr[0] and the last valid index +is ptr[len-1]. If the returned length is zero, there's no valid +index at all. The returned pointer may even be NULL. +

    +

    +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. +

    +

    +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). +

    +

    +FFI pointers or references do not count as GC anchors for an underlying +object. E.g. an array allocated with ffi.new() is +anchored by buf:set(array, len), but not by +buf:set(array+offset, len). 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. +

    +

    +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 buf:set(cdata, len) 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. +

    +
    +
    + + + diff --cc doc/ext_c_api.html index ab72d19a,43c82047..d5e6bb60 --- a/doc/ext_c_api.html +++ b/doc/ext_c_api.html @@@ -42,13 -40,11 +42,13 @@@ jit.* Library
  • Lua/C API +
  • +Profiler
  • - Status + Status »
  • - FAQ + FAQ »
  • Mailing List »
  • diff --cc doc/ext_ffi.html index e8e5565d,683c0cd0..eaa176b6 --- a/doc/ext_ffi.html +++ b/doc/ext_ffi.html @@@ -42,13 -40,11 +42,13 @@@ jit.* Library
  • Lua/C API +
  • +Profiler
  • - Status + Status »
  • - FAQ + FAQ »
  • Mailing List »
  • diff --cc doc/ext_ffi_api.html index ea03168a,d5f7032f..500a2143 --- a/doc/ext_ffi_api.html +++ b/doc/ext_ffi_api.html @@@ -47,13 -45,11 +47,13 @@@ td.abiparam { font-weight: bold; width jit.* Library
  • Lua/C API +
  • +Profiler
  • - Status + Status »
  • - FAQ + FAQ »
  • Mailing List »
  • diff --cc doc/ext_ffi_semantics.html index 419ef07a,381a2010..5ba82a1e --- a/doc/ext_ffi_semantics.html +++ b/doc/ext_ffi_semantics.html @@@ -47,13 -45,11 +47,13 @@@ td.convop { font-style: italic; width: jit.* Library
  • Lua/C API +
  • +Profiler
  • - Status + Status »
  • - FAQ + FAQ »
  • Mailing List »
  • diff --cc doc/ext_ffi_tutorial.html index 3cf4862a,03b6ec56..a5236f0b --- a/doc/ext_ffi_tutorial.html +++ b/doc/ext_ffi_tutorial.html @@@ -49,13 -47,11 +49,13 @@@ td.idiomlua b { font-weight: normal; co jit.* Library
  • Lua/C API +
  • +Profiler
  • - Status + Status »
  • - FAQ + FAQ »
  • Mailing List »
  • diff --cc doc/ext_jit.html index 7bf9f343,b1dbf36c..dd136d65 --- a/doc/ext_jit.html +++ b/doc/ext_jit.html @@@ -42,13 -40,11 +42,13 @@@ jit.* Library
  • Lua/C API +
  • +Profiler
  • - Status + Status »
  • - FAQ + FAQ »
  • Mailing List »
  • diff --cc doc/ext_profiler.html index 18880239,00000000..81b5d773 mode 100644,000000..100644 --- a/doc/ext_profiler.html +++ b/doc/ext_profiler.html @@@ -1,359 -1,0 +1,359 @@@ + + + +Profiler + + + + + + + +
    +Lua +
    + + +
    +

    +LuaJIT has an integrated statistical profiler with very low overhead. It +allows sampling the currently executing stack and other parameters in +regular intervals. +

    +

    +The integrated profiler can be accessed from three levels: +

    + + +

    High-Level Profiler

    +

    +The bundled high-level profiler offers basic profiling functionality. It +generates simple textual summaries or source code annotations. It can be +accessed with the -jp command line option +or from Lua code by loading the underlying jit.p module. +

    +

    +To cut to the chase — run this to get a CPU usage profile by +function name: +

    +
     +luajit -jp myapp.lua
     +
    +

    +It's not 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. +

    +

    +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 — there's no simple +one-to-one correspondence between source code lines and the sampled +machine code. +

    + +

    -jp=[options[,output]]

    +

    +The -jp 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 stdout or to the specified +output file. +

    +

    +The options argument specifies how the profiling is to be +performed: +

    + +

    +The default output for -jp is a list of the most CPU consuming +spots in the application. Increasing the stack dump depth with (say) +-jp=2 may help to point out the main callers or callees of +hotspots. But sample aggregation is still flat per unique stack dump. +

    +

    +To get a two-level view (split view) of callers/callees, use +-jp=s or -jp=-s. The percentages shown for the second +level are relative to the first level. +

    +

    +To see how much time is spent in each line relative to a function, use +-jp=fl. +

    +

    +To see how much time is spent in different VM states or +zones, use -jp=v or -jp=z. +

    +

    +Combinations of v/z with f/F/l produce two-level +views, e.g. -jp=vf or -jp=fv. 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?". +

    +

    +Multiple options can be combined — but not all combinations make +sense, see above. E.g. -jp=3si4m1 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. +

    +

    +Source code annotations produced by -jp=a or -jp=A are +always flat and at the line level. Obviously, the source code files need +to be readable by the profiler script. +

    +

    +The high-level profiler can also be started and stopped from Lua code with: +

    +
     +require("jit.p").start(options, output)
     +...
     +require("jit.p").stop()
     +
    + +

    jit.zone — Zones

    +

    +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 +"AI" zone, a "PHYS" zone, etc. Zones are hierarchical, +organized as a stack. +

    +

    +The jit.zone module needs to be loaded explicitly: +

    +
     +local zone = require("jit.zone")
     +
    + +

    +To show the time spent in each zone use -jp=z. To show the time +spent relative to hotspots use e.g. -jp=zf or -jp=fz. +

    + +

    Low-level Lua API

    +

    +The jit.profile module gives access to the low-level API of the +profiler from Lua code. This module needs to be loaded explicitly: +

     +local profile = require("jit.profile")
     +
    +

    +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. +

    + +

    profile.start(mode, cb) +— Start profiler

    +

    +This function starts the profiler. The mode argument is a +string holding options: +

    + +

    +The cb argument is a callback function which is called with +three arguments: (thread, samples, vmstate). The callback is +called on a separate coroutine, the thread argument is the +state that holds the stack to sample for profiling. Note: do +not modify the stack of that state or call functions on it. +

    +

    +samples gives the number of accumulated samples since the last +callback (usually 1). +

    +

    +vmstate 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 'N' +native (compiled) code, 'I' interpreted code, 'C' +C code, 'G' the garbage collector, or 'J' the JIT +compiler. +

    + +

    profile.stop() +— Stop profiler

    +

    +This function stops the profiler. +

    + +

    dump = profile.dumpstack([thread,] fmt, depth) +— Dump stack

    +

    +This function allows taking stack dumps in an efficient manner. It +returns a string with a stack dump for the thread (coroutine), +formatted according to the fmt argument: +

    + +

    +The depth 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. +

    +

    +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: +

    +
     +print(profile.dumpstack(thread, "l\n", 10))
     +print(profile.dumpstack(thread, "lZ;", -100))
     +
    + +

    Low-level C API

    +

    +The profiler can be controlled directly from C code, e.g. for +use by IDEs. The declarations are in "luajit.h" (see +Lua/C API extensions). +

    + +

    luaJIT_profile_start(L, mode, cb, data) +— Start profiler

    +

    +This function starts the profiler. See +above for a description of the mode argument. +

    +

    +The cb argument is a callback function with the following +declaration: +

    +
     +typedef void (*luaJIT_profile_callback)(void *data, lua_State *L,
     +                                        int samples, int vmstate);
     +
    +

    +data is available for use by the callback. L is the +state that holds the stack to sample for profiling. Note: do +not modify this stack or call functions on this stack — +use a separate coroutine for this purpose. See +above for a description of samples and vmstate. +

    + +

    luaJIT_profile_stop(L) +— Stop profiler

    +

    +This function stops the profiler. +

    + +

    p = luaJIT_profile_dumpstack(L, fmt, depth, len) +— Dump stack

    +

    +This function allows taking stack dumps in an efficient manner. +See above for a description of fmt +and depth. +

    +

    +This function returns a const char * pointing to a +private string buffer of the profiler. The int *len +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. +

    +
    +
    + + + diff --cc doc/extensions.html index c7ace015,f8b45c28..eb591d1e --- a/doc/extensions.html +++ b/doc/extensions.html @@@ -59,13 -57,11 +59,13 @@@ td.excinterop jit.* Library
  • Lua/C API +
  • +Profiler
  • - Status + Status »
  • - FAQ + FAQ »
  • Mailing List »
  • diff --cc doc/install.html index 0ccd37aa,21866315..be721031 --- a/doc/install.html +++ b/doc/install.html @@@ -65,13 -63,11 +65,13 @@@ td.compatx jit.* Library
  • Lua/C API +
  • +Profiler
  • - Status + Status »
  • - FAQ + FAQ »
  • Mailing List »
  • @@@ -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- +# ARM64 - make CROSS=aarch64-linux- ++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"

    You can cross-compile for Android using the » Android NDK. diff --cc doc/luajit.html index 3bb8aaf2,7346acb3..030cf705 --- a/doc/luajit.html +++ b/doc/luajit.html @@@ -127,13 -101,11 +103,13 @@@ table.fcompat td jit.* Library

  • Lua/C API +
  • +Profiler
  • - Status + Status »
  • - FAQ + FAQ »
  • Mailing List »
  • diff --cc doc/running.html index 325cb6bb,c7d9e9b6..3afc1b56 --- a/doc/running.html +++ b/doc/running.html @@@ -64,13 -62,11 +64,13 @@@ td.param_default jit.* Library
  • Lua/C API +
  • +Profiler
  • - Status + Status »
  • - FAQ + FAQ »
  • Mailing List »