-
Notifications
You must be signed in to change notification settings - Fork 33
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
abrown
wants to merge
6
commits into
bytecodealliance:main
Choose a base branch
from
abrown:v8
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Add a V8 engine #166
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
62cac75
Add V8 engine
abrown a40ef68
Update to use libwee8
abrown 1289606
Switch to using C++ API
abrown 238049f
Add stubs for more WASI functions
abrown 13cc389
Add a way to run the noop benchmark
abrown cc238bf
Update Dockerfile
abrown File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
archive | ||
build | ||
v8 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
build | ||
v8 | ||
archive |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
FROM ubuntu:latest | ||
ARG REPOSITORY=https://github.com/WebAssembly/wasm-c-api | ||
ARG REVISION=branch-heads/9.9 | ||
|
||
# Install necessary dependencies | ||
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -yqq \ | ||
apt-utils \ | ||
curl \ | ||
git \ | ||
g++ \ | ||
make \ | ||
ninja-build \ | ||
pkg-config \ | ||
python3 | ||
|
||
# Setup V8 and build the `libwee8.a` library. TODO map REVISION to V8_VERSION. | ||
WORKDIR /usr/src | ||
COPY args.gn Makefile ./ | ||
RUN make v8-checkout | ||
RUN make wee8 | ||
|
||
# Build the Sightglass engine. | ||
COPY src ./src | ||
RUN make build/libengine.so | ||
RUN cp build/libengine.so /libengine.so |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
# This Makefile builds both the V8 components and the bench API wrapper for | ||
# Sightglass. | ||
all: v8-checkout test | ||
|
||
######### V8 ########## | ||
|
||
# In order to build the `libwee8` library, we must perform the following steps: | ||
# - `make v8-checkout` will retrieve the V8 repository (borrowing much the same | ||
# logic as https://github.com/WebAssembly/wasm-c-api) | ||
# - `make wee8` will build the `libwee8.a` library inside the v8 tree (see See | ||
# https://docs.google.com/document/d/1oFPHyNb_eXg6NzrE6xJDNPdJrHMZvx0LqsD6wpbd9vY/edit#) | ||
|
||
# TODO rename `v8` directory to `upstream`; potentially move this section to a | ||
# separate Makefile there. | ||
V8_VERSION = branch-heads/9.9 | ||
V8_ARCH = x64 | ||
V8_MODE = release | ||
V8_BUILD = ${V8_ARCH}.${V8_MODE} | ||
V8_OUT = ${V8_V8}/out.gn/${V8_BUILD} | ||
V8_DIR = v8 | ||
V8_DEPOT_TOOLS = ${V8_DIR}/depot_tools | ||
V8_V8 = ${V8_DIR}/v8 | ||
V8_PATH = $(abspath ${V8_DEPOT_TOOLS}):${PATH} | ||
V8_LIBWEE8 = ${V8_V8}/out/wee8/obj/libwee8.a | ||
|
||
.PHONY: v8-checkout | ||
v8-checkout: ${V8_DEPOT_TOOLS} ${V8_V8} | ||
(cd ${V8_V8}; git checkout -f main) | ||
(cd ${V8_V8}; git pull) | ||
(cd ${V8_V8}; git checkout ${V8_VERSION}) | ||
(cd ${V8_V8}; PATH=${V8_PATH} gclient sync) | ||
mkdir -p ${V8_OUT} | ||
echo >${V8_OUT}/version ${V8_VERSION} | ||
${V8_DEPOT_TOOLS}: | ||
mkdir -p ${V8_DIR} | ||
(cd ${V8_DIR}; git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git --depth 1) | ||
${V8_V8}: | ||
mkdir -p ${V8_DIR} | ||
(cd ${V8_DIR}; PATH=${V8_PATH} fetch --no-history v8) | ||
(cd ${V8_V8}; git checkout ${V8_VERSION}) | ||
|
||
.PHONY: wee8 | ||
wee8: ${V8_LIBWEE8} | ||
${V8_LIBWEE8}: args.gn | ||
mkdir -p ${V8_V8}/out/wee8 | ||
cp args.gn ${V8_V8}/out/wee8/ | ||
(cd ${V8_V8}; PATH=${V8_PATH} gn gen out/wee8) | ||
(cd ${V8_V8}; PATH=${V8_PATH} autoninja -C out/wee8 wee8) | ||
|
||
.PHONY: v8-clean | ||
v8-clean: | ||
rm -rf v8 | ||
|
||
|
||
|
||
######### BENCH-API ########## | ||
|
||
# The shared library that Sightglass expects must conform to a specific | ||
# interface (see `src/bench-api.h`). We interact with `libwee8.a` in | ||
# `src/bench-state.cc`. To build and test this functionality, use `make test`. | ||
|
||
# This Makefile setup roughly follows https://stackoverflow.com/a/2481326. | ||
CXXFLAGS=-g -O0 -fPIC -I ${V8_V8}/third_party/wasm-api | ||
WASM_HH=${V8_V8}/third_party/wasm-api/wasm.hh | ||
SRC_DIR=src | ||
TEST_DIR=test | ||
BUILD_DIR=build | ||
SRCS=src/bench-api.cc src/bench-state.cc src/link.cc src/wasi.cc | ||
OBJS=$(patsubst $(SRC_DIR)/%.cc,$(BUILD_DIR)/%.o,$(SRCS)) | ||
LDLIBS=$(V8_LIBWEE8) -ldl -pthread | ||
# See https://stackoverflow.com/questions/36692315. | ||
LDFLAGS=-rdynamic | ||
|
||
# Create the build directory, if necessary. | ||
$(BUILD_DIR): | ||
mkdir -p $(BUILD_DIR) | ||
|
||
# Built-in rules to compile the various source files. | ||
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cc | ||
$(CXX) $(CXXFLAGS) -c $< -o $@ | ||
$(BUILD_DIR)/%.o: $(TEST_DIR)/%.c | ||
$(CC) $(CFLAGS) -I $(SRC_DIR) -c $< -o $@ | ||
|
||
# Define the dependencies for each object. | ||
$(BUILD_DIR)/bench-api.o: $(SRC_DIR)/bench-api.cc $(SRC_DIR)/bench-api.h $(WASM_HH) | ||
$(BUILD_DIR)/bench-state.o: $(SRC_DIR)/bench-state.cc $(SRC_DIR)/bench-state.hh $(SRC_DIR)/bench-api.h $(WASM_HH) | ||
$(BUILD_DIR)/link.o: $(SRC_DIR)/link.cc $(SRC_DIR)/link.hh $(SRC_DIR)/bench-state.hh $(SRC_DIR)/wasi.hh $(WASM_HH) | ||
$(BUILD_DIR)/wasi.o: $(SRC_DIR)/wasi.cc $(SRC_DIR)/wasi.hh $(WASM_HH) | ||
$(BUILD_DIR)/main.o: $(TEST_DIR)/main.c $(SRC_DIR)/bench-api.h | ||
|
||
# Create a test target for building and running the test file with `make test`. | ||
.PHONY: test | ||
test: $(BUILD_DIR)/test | ||
$< ../../benchmarks-next/noop/benchmark.wasm | ||
$(BUILD_DIR)/test: $(BUILD_DIR) $(OBJS) $(BUILD_DIR)/main.o | ||
$(CXX) $(LDFLAGS) -o $@ $(OBJS) $(BUILD_DIR)/main.o $(LDLIBS) | ||
|
||
# Create the shared library target; this is what can be used by sightglass to | ||
# measure benchmarks. | ||
$(BUILD_DIR)/libengine.so: $(BUILD_DIR) $(OBJS) | ||
$(CXX) -shared $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS) | ||
test-lib: $(BUILD_DIR)/libengine.so | ||
RUST_LOG=trace cargo run -- benchmark ../../benchmarks-next/noop/benchmark.wasm \ | ||
--engine $(BUILD_DIR)/libengine.so --processes 1 --iterations-per-process 1 \ | ||
--skip-output-check | ||
|
||
.PHONY: test | ||
clean: | ||
rm -rf build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
is_component_build = false | ||
use_custom_libcxx = false | ||
v8_enable_fast_mksnapshot = true | ||
v8_enable_i18n_support = false | ||
v8_use_external_startup_data = false | ||
is_debug = true | ||
symbol_level = 2 | ||
v8_optimized_debug = false | ||
v8_expose_symbols = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
#include "bench-api.h" | ||
#include <stddef.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <iostream> | ||
#include <map> | ||
#include <optional> | ||
#include <utility> | ||
#include <vector> | ||
#include "bench-state.hh" | ||
#include "link.hh" | ||
#include "wasm.hh" | ||
|
||
extern "C" { | ||
|
||
int wasm_bench_create(wasm_bench_config_t config, void** out_ptr) { | ||
BenchState* st = new BenchState(Config::make(config)); | ||
st->engine = wasm::Engine::make(); // TODO cannot instantiate an EngineImpl | ||
// multiple times. | ||
Comment on lines
+18
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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? |
||
assert(st->engine != nullptr); | ||
st->store = wasm::Store::make(st->engine.get()); | ||
assert(st->store != nullptr); | ||
|
||
assert(out_ptr != NULL); | ||
*out_ptr = (void*)st; | ||
return 0; | ||
} | ||
|
||
void wasm_bench_free(void* state_) { | ||
BenchState* state = (BenchState*)state_; | ||
delete state; | ||
} | ||
|
||
int wasm_bench_compile(void* state_, | ||
char* wasm_bytes, | ||
size_t wasm_bytes_length) { | ||
BenchState* st = (BenchState*)state_; | ||
assert(st != nullptr); | ||
assert(st->store != nullptr); | ||
auto wasm = wasm::vec<byte_t>::make(wasm_bytes_length, wasm_bytes); | ||
|
||
st->config.compilation.start(); | ||
st->module = wasm::Module::make(st->store.get(), wasm); | ||
st->config.compilation.end(); | ||
|
||
if (!st->module) { | ||
std::cerr << "> Error compiling module!" << std::endl; | ||
return 1; | ||
} else { | ||
return 0; | ||
} | ||
} | ||
|
||
int wasm_bench_instantiate(void* state_) { | ||
BenchState* st = (BenchState*)state_; | ||
assert(st != nullptr); | ||
assert(st->module != nullptr); | ||
assert(st->store != nullptr); | ||
|
||
// Retrieve linked functions and extract their pointers here to avoid dropping | ||
// them too early. | ||
auto imports = link(st->store.get(), st->module.get(), &st->config.execution); | ||
const wasm::Extern* imports_as_extern[imports.size()]; | ||
for (size_t i = 0; i < imports.size(); ++i) { | ||
imports_as_extern[i] = imports[i].get(); | ||
} | ||
|
||
st->config.instantiation.start(); | ||
st->instance = wasm::Instance::make(st->store.get(), st->module.get(), | ||
imports_as_extern); | ||
st->config.instantiation.end(); | ||
|
||
if (!st->instance) { | ||
std::cerr << "> Error instantiating module!" << std::endl; | ||
return 1; | ||
} else { | ||
return 0; | ||
} | ||
} | ||
|
||
int wasm_bench_execute(void* state_) { | ||
BenchState* st = (BenchState*)state_; | ||
assert(st != nullptr); | ||
assert(st->module != nullptr); | ||
assert(st->instance != nullptr); | ||
|
||
// Find the _start function. | ||
auto start_fn = find_start_fn(st->module.get(), st->instance.get()); | ||
if (!start_fn) { | ||
std::cerr << "> Unable to find the '_start' function!" << std::endl; | ||
return 1; | ||
} | ||
|
||
// Run the start function. | ||
if (!start_fn->func()->call()) { | ||
std::cerr << "> Error calling start function!" << std::endl; | ||
return 1; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
} // extern "C" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Describe the C API that this engine must conform to for use within | ||
// Sightglass. | ||
#ifndef __BENCH_API_H | ||
#define __BENCH_API_H | ||
|
||
#include <stdio.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
typedef char* wasm_bench_timer_t; | ||
typedef void (*wasm_bench_callback_t)(wasm_bench_timer_t); | ||
|
||
/** | ||
* @brief This struct must match what is passed by sightglass (TODO cite). | ||
*/ | ||
typedef struct wasm_bench_config_t { | ||
char* working_dir_ptr; | ||
size_t working_dir_len; | ||
char* stdout_path_ptr; | ||
size_t stdout_path_len; | ||
char* stderr_path_ptr; | ||
size_t stderr_path_len; | ||
char* stdin_path_ptr; | ||
size_t stdin_path_len; | ||
wasm_bench_timer_t compilation_timer; | ||
wasm_bench_callback_t compilation_start; | ||
wasm_bench_callback_t compilation_end; | ||
wasm_bench_timer_t instantiation_timer; | ||
wasm_bench_callback_t instantiation_start; | ||
wasm_bench_callback_t instantiation_end; | ||
wasm_bench_timer_t execution_timer; | ||
wasm_bench_callback_t execution_start; | ||
wasm_bench_callback_t execution_end; | ||
} wasm_bench_config_t; | ||
|
||
/// API functions (TODO cite). | ||
|
||
int wasm_bench_create(wasm_bench_config_t config, void** state_out_ptr); | ||
void wasm_bench_free(void* state); | ||
int wasm_bench_compile(void* state, char* wasm_bytes, size_t wasm_bytes_length); | ||
int wasm_bench_instantiate(void* state); | ||
int wasm_bench_execute(void* state); | ||
|
||
#ifdef __cplusplus | ||
} // extern "C" | ||
#endif | ||
|
||
#endif // #ifdef __BENCH_API_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#include "bench-state.hh" | ||
#include <iostream> | ||
|
||
Config Config::make(wasm_bench_config_t config) { | ||
auto working_dir = | ||
std::string(config.working_dir_ptr, config.working_dir_len); | ||
auto stdout_path = | ||
std::string(config.stdout_path_ptr, config.stdout_path_len); | ||
auto stderr_path = | ||
std::string(config.stderr_path_ptr, config.stderr_path_len); | ||
auto stdin_path = std::string(config.stdin_path_ptr, config.stdin_path_len); | ||
auto compilation = Timer(config.compilation_timer, config.compilation_start, | ||
config.compilation_end); | ||
auto instantiation = | ||
Timer(config.instantiation_timer, config.instantiation_start, | ||
config.instantiation_end); | ||
auto execution = Timer(config.execution_timer, config.execution_start, | ||
config.execution_end); | ||
return Config(working_dir, stdout_path, stderr_path, stdin_path, compilation, | ||
instantiation, execution); | ||
} | ||
|
||
void Timer::start() const { | ||
if (this->start_timer != NULL) { | ||
(this->start_timer)(this->timer); | ||
} | ||
} | ||
|
||
void Timer::end() const { | ||
if (this->end_timer != NULL) { | ||
(this->end_timer)(this->timer); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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?