HolyLib Wiki

HolyLib LuaJIT

HolyLib LuaJIT

JIT Support

If you enabled HolyLib's JIT build (See below) then some C functions may support being JIT'd.
If you see a function having the JIT SINCE x.x mark, then it supports this - if a function does NOT support it you can expect LuaJIT to fail tracing it and either result to trace stitching or aborting the trace entirely, resulting in worse performance.

Updating JIT

HolyLib has a luajit module that updates Garry's mod LuaJIT version to a newer one.
In addition, it also restores debug.upvaluejoin, debug.upvalueid, debug.setupvalue, debug.setlocal.
It also exposes lua's original require function under jit.require allowing you to require things like ffi and jit.profiler.
by default string.buffer and ffi are already loaded.

Enabling the module

  1. Add -holylib_enable_luajit 1 to the server startup arguments
  2. Restart the server
  3. Verify using print(jit.version) that it updated. (It should print something like LuaJIT 2.1.1697887905)

Changes in our LuaJIT build

There are more changes than it just being an newer JIT version

- [+] Save and restore XMCSR flags when entering & leaving the VM (See https://github.com/RaphaelIT7/gmod-holylib/issues/129) - [+] Added the ability to concat bool values.
- [+] Added block debug functionality for function to prevent someone from getting functions they shouldn't have.
- [+] Added read only table functionality to prevent someone from modifying a table while its being used by another thread
- [+] Exposed luaopen_jit_profile & lua_index2adr for HolyLib.
- [+] Implemented fix for FFI Sandwich/LUA VM re-entry through JIT trace (See https://github.com/LuaJIT/LuaJIT/pull/1165)
- [+] Experimentally implemented Sink optimization (See https://github.com/LuaJIT/LuaJIT/pull/652)
- [+] Specialize to the global environment change (See https://github.com/LuaJIT/LuaJIT/pull/910)
- [+] Compile unpack() given constant start and end indices (See https://github.com/LuaJIT/LuaJIT/pull/910)
- [+] Experimentally implemented Reduce method overhead in loops by specializing to metatables (See https://github.com/LuaJIT/LuaJIT/pull/899)
- [+] Added JIT support for userdata meta- & usertable access
- [+] Made newproxy JITd & added new IR_UDNEW opcode
- [+] Implement LUAJIT_ENABLE_CHECKHOOK as a runtime toggle (See: https://github.com/RaphaelIT7/gmod-holylib/issues/151)
- [+] Implemented a custom external trace recorder API allowing HolyLib to make C functions recordable without recompiling JIT.
- [#] Made cdata return the type as LUA_TUSERDATA so that we can more easily allow FFI -> C calls without needing to hook 10 functions (& the TypeID also conflicted with gmod)
- [#] Improved GMODLUA_GetUserType to directly do it's stuff without using the Lua stack
- [#] Fixed table.insert trying to shift values when inserting into negatives, causing performance issues
- [#] Reduced GCudata, GCtrace, GCproto, global_State sizes saving memory.

Using JIT with StarFall

In newer JIT versions debug.sethook no longer will stop JIT meaning the whole CPU usage checks will fail as LuaJIT may trace a loop and run it, then while the debug hook that SF uses would never be called.
LuaJIT has a flag for this.
LUAJIT_ENABLE_CHECKHOOK is a normal JIT compile time flag that forces LuaJIT to include mask checking to trigger debug hook calls from inside JIT code.
BUT this usually means that JITd code- specifically loops will have a slight overhead, which could be noticeable in large/hot loops but not massive, especially since for GMods cases loops won't just be simple.
Since many servers may not use SF HolyLib has this flag NOT enabled by default, BUT since some servers may need it for SF- HolyLib's JIT version exposes two functions to toggle the flag at runtime.
_jit.enablecheckhook and jit.disablecheckhook enable and disable the hook- these will ALSO flush all JIT code to avoid issues, so they are meant to NOT be constantly toggled but instead rarely changed / for example only once enabled at startup and left enabled the entire time.