holyjit

Generic purpose Just-In-time compiler for Rust.

  • Owner: nbp/holyjit
  • Platform:
  • License:: Mozilla Public License 2.0
  • Category::
  • Topic:
  • Like:
    0
      Compare:

Github stars Tracking Chart

Making a Just-In-Time compiler is complex, a large source of security
issues, and is a price which is frequently paid to have better performance
results.

HolyJit is made to remove this trade-off! Simplicity and security should no
longer be sacrificed for performance reasons.

HolyJit

HolyJit is a high-level Just-In-Time compiler. It extends the Rust compiler
to convert the code of an interpreter written in Rust to tune a JIT compiler
to handle the same interpreted language.

HolyJit aims at being:

  • Easy.
  • Safe.
  • Fast.

Easy

HolyJit extends the Rust compiler to copy its internal representation of
functions and convert it into a representation which can be consumed by the
JIT compiler provided by HolyJit library.

As a user, this implies that to inline a function in JIT compiled code, one
just need to annotate it with the jit! macro:

jit!{
    fn eval(script: &Script, args: &[Value]) -> Result<Value, Error>
    = eval_impl
    in script.as_ref()
}

fn eval_impl(script: &Script, args: &[Value]) -> Result<Value, Error> {
    // ...
    // ... A few hundred lines of ordinary Rust code later ...
    // ...
}

fn main() {
    let script = ...;
    let args = ...;
    // Call it as any ordinary function.
    let res = eval(&script, &args);
    println!("Result: {}", res);
}

Thus, you basically have to write an interpreter, and annotate it properly
to teach the JIT compiler what can be optimized by the compiler.

No assembly knowledge is required to start instrumenting your code to make
it available to the JIT compiler's set of known functions.

Safe

Security issues from JIT compilers arise from:

  • Duplication of the runtime into a set of MacroAssembler functions.
  • Correctness of the compiler optimizations.

As HolyJit extends the Rust compiler to extract the effective knowledge of
the compiler, there is no more risk of having correctness issues caused by
the duplication of code.

Moreover, the code which is given to the JIT compiler is as safe as the code
users wrote in the Rust language.

As HolyJit aims at being a JIT library which can easily be embedded into
other projects, correctness of the compiler optimizations should be caught
by the community of users and fuzzers, thus leaving less bugs for you to
find.

Fast

Fast is a tricky question when dealing with a JIT compiler, as the cost of
the compilation is part of the equation.

HolyJit aims at reducing the start-up time, based on annotations made out of
macros, to guide the early tiers of the compilers for unrolling loops and
generating inline caches.

For final compilation tiers, it uses special types/traits to wrap the data
in order to instrument and monitor the values which are being used, such
that guards can later be converted into constraints.

Using HolyJit

HolyJit is a rustc driver, which means that it has to be used in-place of rustc
or as a rustc wrapper, i.e. by settings either the RUSTC or RUSTC_WRAPPER
environment variable.

When holyjit is used, the binary is instrumented the generated code with
enough information to resume with the JIT compilation at runtime.

When rustc is used, a binary is still produced but the JIT is disabled as no
data are stored in the binary to be consumed by the JIT compiler at runtime.

To run tests, you can either run the test of the library with cargo test,
or run the examples of HolyJit with:

$ RUSTC_WRAPPER=$(pwd)/rustc.sh cargo run --example brainfuck --verbose

At the moment, HolyJit is far from being yet ready for production! This is
currently at a prototype stage, and most of the code & dependencies present
today were made only as a proof of concept and not as a definitive
implementation design.

HolyJit Roadmap for 0.0.0

The current goal is to make a proof of concept which highlights the main
feature, i.e. being trivial to integrate into an existing code base and to
have a running JIT compiler.

As of today, HolyJit contains a draft of what the interface might look like,
and is able to generate code for the example present in the repository.

  • Create Rust library

    • Allocate pages and map them as executable.
    • Add a way to call either a dynamically compiled function or a
      statically compiled function.
    • Add a jit! macro, to make calls transparent from the usage point of
      view.
    • Create a JitContext class, and use it to request JIT compiled code.
    • Create a graph representation.
    • Consume the graph to generate code.
  • Create a MIR plugin

    • Detect locations which have to be patched.
    • Find functions which have to be converted.
    • Inject a generated vector in the binary content.
    • Inject static variables as a tuple.
    • Collect static variable references.
    • Convert the MIR (from the Rust compiler) to the library graph
      representation.

Main metrics

Overview
Name With Ownernbp/holyjit
Primary LanguageRust
Program languageRust (Language Count: 3)
Platform
License:Mozilla Public License 2.0
所有者活动
Created At2017-10-12 15:24:41
Pushed At2019-05-12 14:14:20
Last Commit At2018-08-18 18:53:06
Release Count1
Last Release Namev0.0.0 (Posted on )
First Release Namev0.0.0 (Posted on )
用户参与
Stargazers Count1.5k
Watchers Count56
Fork Count27
Commits Count34
Has Issues Enabled
Issues Count27
Issue Open Count12
Pull Requests Count7
Pull Requests Open Count1
Pull Requests Close Count3
项目设置
Has Wiki Enabled
Is Archived
Is Fork
Is Locked
Is Mirror
Is Private