lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Mark Hamburg wrote:
> > The next version
> > of LuaJIT is able to inline many of the C functions from the
> > standard library. I've already added the math.* functions and
> > this gives another nice boost (e.g. math.abs() is 6 times faster).
> Do you do anything to detect whether people have replaced these functions?

The address of the closure is checked before continuing
with the inlined code. If it doesn't match the hint from
the optimizer, it falls back to a plain call.

Of course it's a good idea to load the optimizer _before_
you replace any standard library functions. Because the
optimizer (jit.opt_lib in this case) needs to store the
closure addresses (once).

Loading the optimizer first is the common case for the
standalone executable. But I guess I need to add a paragraph
or two for embedders.

> Doing so on the math functions would be perverse, but Lua allows it.

LuaJIT handles all those strange cases. Even stuff like this:

local f = string.len
local function foo(x)
  return f(x)


f = math.abs

In this case the inlined string.len is only used on the first
invocation. No, it doesn't recompile itself for the polymorphic
case on the second invocation (yet).

That said I've yet to encounter a single non-contrived program
where the optimizer hints are wrong. They are always validated
at runtime of course. The cost for validation is reasonably low
if you cache functions in locals or upvalues (local abs = math.abs).
[Two compares plus two correctly predicted not-taken branches.]

I cannot avoid the penalty for doing the global (e.g. type) or
global+table (math.abs) lookups every time, because almost any
Lua opcode could invalidate these (due to metamethods). But caching
standard library functions in locals should be a standard practice,