Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wip] Add JIT optimization tool: lib.specialize(fn) #1053

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,19 @@ lib.parse({foo=42, bar=43}, {foo={required=true}, bar={}, baz={default=44}})
=> {foo=42, bar=43, baz=44}
```

— Function **lib.specialize** *function*

Returns a clone of the given function with a shallow copy of its
function definition. The clone function has a separate bytecode
definition and any JIT traces that start in the clone will be
aggressively specialized by LuaJIT for the environment of the clone.

This can lead to especially efficient machine code when:
- The function being specialized contains a loop (`for` or `while` or `repeat`) directly in its source code (not in a subroutine because the bytecode cloning is shallow).
- The function will benefit from being compiled separately from other uses, for example because the way the clone will be called is expected to lead to a peculiar flow of control.
- The function refers to values in its closure environment, which the JIT will treat more like constants than variables.

See background information at [LuaJIT/LuaJIT#208](https://github.com/LuaJIT/LuaJIT/issues/208).

## Main

Expand Down
9 changes: 9 additions & 0 deletions src/core/app.lua
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ function apply_config_actions (actions, conf)
app.shm.dtime = {counter, C.get_unix_time()}
app.shm = shm.create_frame("apps/"..name, app.shm)
end
specialize(app)
end
function ops.restart (name)
ops.stop(name)
Expand All @@ -209,6 +210,7 @@ function apply_config_actions (actions, conf)
new_app_table[name] = app
table.insert(new_app_array, app)
app_name_to_index[name] = #new_app_array
specialize(app)
else
ops.restart(name)
end
Expand Down Expand Up @@ -252,6 +254,13 @@ function apply_config_actions (actions, conf)
end
end

-- Specialize an app so that its pull and push methods can be JITed
-- into instance-specific machine code.
function specialize (app)
if app.pull then app.pull = lib.specialize(app.pull) end
if app.push then app.push = lib.specialize(app.push) end
end

-- Call this to "run snabb switch".
function main (options)
options = options or {}
Expand Down
18 changes: 18 additions & 0 deletions src/core/lib.lua
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,24 @@ function parse (arg, config)
return ret
end

-- Return a clone of the given function with separate bytecode.
-- (Code taken from http://leafo.net/guides/function-cloning-in-lua.html)
function specialize (fn)
local dumped = string.dump(fn)
local cloned = loadstring(dumped)
local i = 1
while true do
local name = debug.getupvalue(fn, i)
if not name then
break
end
debug.upvaluejoin(cloned, i, fn, i)
i = i + 1
end
return cloned
end


function selftest ()
print("selftest: lib")
print("Testing equal")
Expand Down