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

Add a V8 engine #166

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft

Add a V8 engine #166

wants to merge 6 commits into from

Conversation

abrown
Copy link
Collaborator

@abrown abrown commented Apr 21, 2022

This change adds the beginnings of a new V8 engine to Sightglass. It uses V8's libwee8 library as the backing engine and constructs a libengine.so in C++ that is compatible with Sightglass. As-is, it has some limitations (discussed below), but the current change can run benchmarks under very specific circumstances and represents a significant effort to make this all work. I do not expect to include this as a part of CI until some of these limitations are resolved.

Limitations, in order of importance:

  • V8 expects only one engine to be instantiated in any process; to fix this, I would expect that we would need a safe way to create a static reference to the engine in the shared library (?). To get around this now, the example make test-lib will only run a single iteration.
  • The WASI support for this library is minimal and merely stubbed out; this allows running only the simplest of benchmarks. We should consider integrating an existing WASI implementation, e.g., uvwasi; the challenge is that some of the WASI calls are modified, i.e., to collect all stdout and stderr into files. To avoid this limitation for now, this change adds a --no-output-check to skip checking for collected output.
  • The libwee8 build is slow: it takes approximately 27 minutes on my machine. Much of the time is spent retrieving the various dependencies of V8. It is not clear to me that all of these are needed and it may be possible to compile libwee8 with less fetching.

For now, though, this library is functional:

$ make test-lib
RUST_LOG=trace cargo run -- benchmark ../../benchmarks-next/noop/benchmark.wasm \
        --engine build/libengine.so --processes 1 --iterations-per-process 1 \
        --skip-output-check
   Compiling sightglass-cli v0.1.0 (/home/abrown/Code/sightglass/crates/cli)
    Finished dev [unoptimized + debuginfo] target(s) in 1.77s
     Running `/home/abrown/Code/sightglass/target/debug/sightglass-cli benchmark ../../benchmarks-next/noop/benchmark.wasm --engine build/libengine.so --processes 1 --iterations-per-process 1 --skip-output-check`
 TRACE sightglass_cli > Executing command: Benchmark(BenchmarkCommand { engines: ["build/libengine.so"], processes: 1, iterations_per_process: 1, raw: false, output_format: Json, output_file: None, measure: WallCycles, small_workloads: false, working_dir: None, wasm_files: ["../../benchmarks-next/noop/benchmark.wasm"], stop_after_phase: None, significance_level: 0.01, skip_output_check: true })
 DEBUG sightglass_artifact::engine > Using already-built engine path: build/libengine.so
 INFO  sightglass_cli::benchmark   > Using benchmark engine: build/libengine.so
 INFO  sightglass_cli::benchmark   > Using Wasm benchmark: ../../benchmarks-next/noop/benchmark.wasm
 INFO  sightglass_cli::benchmark   > Using working directory: ../../benchmarks-next/noop
 DEBUG sightglass_cli::benchmark   > Wasm benchmark size: 3871 bytes
 INFO  sightglass_recorder::bench_api > Starting new measurement
 INFO  sightglass_recorder::bench_api > Finished measuring compilation
 INFO  sightglass_recorder::benchmark > Compiled successfully
 INFO  sightglass_recorder::bench_api > Starting new measurement
 INFO  sightglass_recorder::bench_api > Finished measuring instantiation
 INFO  sightglass_recorder::benchmark > Instantiated successfully
fd_write
bench_start
 INFO  sightglass_recorder::bench_api > Starting new measurement
 INFO  sightglass_recorder::bench_api > Finished measuring execution
bench_end
fd_write
proc_exit
 INFO  sightglass_recorder::benchmark > Executed successfully
compilation
  ../../benchmarks-next/noop/benchmark.wasm
    cycles
      [91751789 91751789.00 91751789] build/libengine.so
    nanoseconds
      [28786700 28786700.00 28786700] build/libengine.so
instantiation
  ../../benchmarks-next/noop/benchmark.wasm
    cycles
      [57176762 57176762.00 57176762] build/libengine.so
    nanoseconds
      [17938945 17938945.00 17938945] build/libengine.so
execution
  ../../benchmarks-next/noop/benchmark.wasm
    cycles
      [4219 4219.00 4219] build/libengine.so
    nanoseconds
      [1323 1323.00 1323] build/libengine.so

@abrown abrown requested review from fitzgen and jlb6740 April 21, 2022 20:40
@fitzgen
Copy link
Member

fitzgen commented Apr 22, 2022

The libwee8 build is slow: it takes approximately 27 minutes on my machine. Much of the time is spent retrieving the various dependencies of V8. It is not clear to me that all of these are needed and it may be possible to compile libwee8 with less fetching.

Do they publish prebuilt .sos or something we could use, instead of building from source?

Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add engines/v8/README.md that describes what this is, gives an overview of its current implementation status, and explains why it is here (rough comparison point for wasmtime/cranelift) and why it is not (benchmark wars, getting rigorous benchmark result numbers for V8)

Comment on lines +6 to +8
is_debug = true
symbol_level = 2
v8_optimized_debug = false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean we are building V8 with debug symbols and/or without optimizations?

Comment on lines +18 to +19
st->engine = wasm::Engine::make(); // TODO cannot instantiate an EngineImpl
// multiple times.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you do something like

static wasm::Engine* engine;
if (engine == nullptr) {
    engine = wasm::Engine::make();
}
st->engine = engine;

here?

public:
BenchState(Config config) : config(config) {}
Config config;
std::unique_ptr<wasm::Engine> engine;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And then this would have to become a raw pointer or reference instead of a unique_ptr.

Comment on lines +14 to +18
// std::cerr << "Found import: " << module_str << " " << name_str <<
// std::endl;
import_names.push_back(ImportName(module_str, name_str));
}
// std::cerr << "Number of imports: " << import_names.size() << std::endl;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: delete this commented out logging or add a proper logging macro that can turn logging on/off at build time or via env var.

auto proc_exit(const wasm::Val args[], wasm::Val results[])
-> wasm::own<wasm::Trap> {
std::cerr << "proc_exit" << std::endl;
// exit(args[0].i32()); // TODO this cannot actually exit here; should trap?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, WASI traps when you call proc_exit, and saves the exit code in some side state so the embedder can differentiate between an exit and another kind of trap.

Comment on lines +17 to +19
// TODO actually write contents; needs access to linear memory.
// results[0] = args[0].copy();
results[0] = wasm::Val::i32(65553);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not return the length of the buffer, even if we didn't actually do the write (for now)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants