Zilliqa / scilla-rtl

Execute Scilla code compiled by the Scilla -> LLVM compiler.
GNU General Public License v3.0
8 stars 3 forks source link

Refactor building of `ScillaJIT` object #24

Closed vaivaswatha closed 3 years ago

vaivaswatha commented 3 years ago

On release builds, creating a ScillaJIT object takes ~10ms, which an actual message execution takes < 1ms.

While one solution is to cache ScillaJIT objects, separately created for each popular contract and reuse them, it is better to see if its creation can be refactored so that multiple contracts can use the same ScillaJIT object. Note that all Scilla allocated memory is freed after each message execution / deployment anyway.

The main challenge is that different Scilla modules have same named identifiers in them, so LLJIT will have trouble resolving names when multiple of these object files are loaded.

vaivaswatha commented 3 years ago

Turned out that the culprit for ~10ms ScillaJIT objection creation time was creating the Secp256k1 context. This is now fixed by having a single global context (not thread-safe).

Also experiments revealed that the object file generated by LLVM-JIT can be linked into a shared object (.so) by using clang -shared on it. This .so can then be loaded with dlopen and functions in it invoked. This path has none of the overheads of LLVM JIT creation.

So a good solution is to generate LLVM bitcode binaries in the Scilla-LLVM compiler. Run clang -fPIC -shared on the command line on the bitcode and generate .so. These shared objects can be cached and used directly in the VM. The VM will no longer do any JIT compilation and will not have an LLVM dependence either. It will become a pure run-time library.