Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion bazel/external/wee8.genrule_cmd
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ WEE8_BUILD_ARGS+=" v8_use_external_startup_data=false"
WEE8_BUILD_ARGS+=" v8_enable_shared_ro_heap=false"

# Build wee8.
third_party/depot_tools/gn gen out/wee8 --args="$$WEE8_BUILD_ARGS"
if [[ `uname` == "Darwin" ]]; then
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Isn't third_party/depot_tools/gn the script supposed to do this? cc @PiotrSikora

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It is, but for some reason it doesn't work on @jplevyak's box.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That script also gropes around in the environment in a very non-hygienic way in order to do this very simple thing, which is probably why it doesn't work on my dev box.

buildtools/mac/gn gen out/wee8 --args="$$WEE8_BUILD_ARGS"
else
buildtools/linux64/gn gen out/wee8 --args="$$WEE8_BUILD_ARGS"
fi
third_party/depot_tools/ninja -C out/wee8 wee8

# Move compiled library to the expected destinations.
Expand Down
8 changes: 8 additions & 0 deletions source/extensions/common/wasm/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ envoy_cc_library(
],
)

envoy_cc_library(
name = "wasm_vm_base",
hdrs = ["wasm_vm_base.h"],
Comment thread
jplevyak marked this conversation as resolved.
deps = [
"//source/common/stats:stats_lib",
],
)

envoy_cc_library(
name = "wasm_vm_lib",
srcs = ["wasm_vm.cc"],
Expand Down
1 change: 1 addition & 0 deletions source/extensions/common/wasm/null/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ envoy_cc_library(
"//external:abseil_node_hash_map",
"//include/envoy/registry",
"//source/common/common:assert_lib",
"//source/extensions/common/wasm:wasm_vm_base",
"//source/extensions/common/wasm:wasm_vm_interface",
"//source/extensions/common/wasm:well_known_names",
],
Expand Down
2 changes: 1 addition & 1 deletion source/extensions/common/wasm/null/null.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace Common {
namespace Wasm {
namespace Null {

WasmVmPtr createVm() { return std::make_unique<NullVm>(); }
WasmVmPtr createVm(Stats::ScopeSharedPtr scope) { return std::make_unique<NullVm>(scope); }

} // namespace Null
} // namespace Wasm
Expand Down
2 changes: 1 addition & 1 deletion source/extensions/common/wasm/null/null.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Common {
namespace Wasm {
namespace Null {

WasmVmPtr createVm();
WasmVmPtr createVm(Stats::ScopeSharedPtr scope);

} // namespace Null
} // namespace Wasm
Expand Down
3 changes: 3 additions & 0 deletions source/extensions/common/wasm/null/null_vm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "envoy/registry/registry.h"

#include "common/common/assert.h"
#include "common/singleton/threadsafe_singleton.h"

#include "extensions/common/wasm/null/null_vm_plugin.h"
#include "extensions/common/wasm/well_known_names.h"
Expand All @@ -17,6 +18,8 @@ namespace Common {
namespace Wasm {
namespace Null {

ThreadSafeSingleton<VmGlobalStats> global_stats_;

WasmVmPtr NullVm::clone() {
auto cloned_null_vm = std::make_unique<NullVm>(*this);
cloned_null_vm->load(plugin_name_, false /* unused */);
Expand Down
15 changes: 11 additions & 4 deletions source/extensions/common/wasm/null/null_vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
#include "envoy/registry/registry.h"

#include "common/common/assert.h"
#include "common/singleton/threadsafe_singleton.h"

#include "extensions/common/wasm/null/null_vm_plugin.h"
#include "extensions/common/wasm/wasm_vm_base.h"
#include "extensions/common/wasm/well_known_names.h"

namespace Envoy {
Expand All @@ -17,16 +19,21 @@ namespace Common {
namespace Wasm {
namespace Null {

extern ThreadSafeSingleton<VmGlobalStats> global_stats_;

// The NullVm wraps a C++ WASM plugin which has been compiled with the WASM API
// and linked directly into the Envoy process. This is useful for development
// in that it permits the debugger to set breakpoints in both Envoy and the plugin.
struct NullVm : public WasmVm {
NullVm() = default;
NullVm(const NullVm& other) : plugin_name_(other.plugin_name_) {}
struct NullVm : public WasmVmBase {
NullVm(Stats::ScopeSharedPtr scope)
: WasmVmBase(scope, &global_stats_.get(), WasmRuntimeNames::get().Null) {}
NullVm(const NullVm& other)
: WasmVmBase(other.scope_, &global_stats_.get(), WasmRuntimeNames::get().Null),
plugin_name_(other.plugin_name_) {}

// WasmVm
absl::string_view runtime() override { return WasmRuntimeNames::get().Null; }
bool cloneable() override { return true; };
Cloneable cloneable() override { return Cloneable::InstantiatedModule; };
WasmVmPtr clone() override;
bool load(const std::string& code, bool allow_precompiled) override;
void link(absl::string_view debug_name) override;
Expand Down
1 change: 1 addition & 0 deletions source/extensions/common/wasm/v8/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ envoy_cc_library(
],
deps = [
"//source/common/common:assert_lib",
"//source/extensions/common/wasm:wasm_vm_base",
"//source/extensions/common/wasm:wasm_vm_interface",
"//source/extensions/common/wasm:well_known_names",
],
Expand Down
36 changes: 30 additions & 6 deletions source/extensions/common/wasm/v8/v8.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
#include <vector>

#include "common/common/assert.h"
#include "common/singleton/threadsafe_singleton.h"

#include "extensions/common/wasm/wasm_vm_base.h"
#include "extensions/common/wasm/well_known_names.h"

#include "absl/container/flat_hash_map.h"
Expand All @@ -18,6 +20,8 @@ namespace Common {
namespace Wasm {
namespace V8 {

ThreadSafeSingleton<VmGlobalStats> global_stats_;

wasm::Engine* engine() {
static const auto engine = wasm::Engine::make();
return engine.get();
Expand All @@ -33,9 +37,10 @@ struct FuncData {

using FuncDataPtr = std::unique_ptr<FuncData>;

class V8 : public WasmVm {
class V8 : public WasmVmBase {
public:
V8() = default;
V8(Stats::ScopeSharedPtr scope)
: WasmVmBase(scope, &global_stats_.get(), WasmRuntimeNames::get().V8) {}

// Extensions::Common::Wasm::WasmVm
absl::string_view runtime() override { return WasmRuntimeNames::get().V8; }
Expand All @@ -44,9 +49,8 @@ class V8 : public WasmVm {
absl::string_view getCustomSection(absl::string_view name) override;
void link(absl::string_view debug_name) override;

// V8 is currently not cloneable.
bool cloneable() override { return false; }
WasmVmPtr clone() override { return nullptr; }
Cloneable cloneable() override { return Cloneable::CompiledBytecode; }
WasmVmPtr clone() override;

uint64_t getMemorySize() override;
absl::optional<absl::string_view> getMemory(uint64_t pointer, uint64_t size) override;
Expand Down Expand Up @@ -89,6 +93,7 @@ class V8 : public WasmVm {
wasm::vec<byte_t> source_ = wasm::vec<byte_t>::invalid();
wasm::own<wasm::Store> store_;
wasm::own<wasm::Module> module_;
wasm::own<wasm::Shared<wasm::Module>> shared_module_;
wasm::own<wasm::Instance> instance_;
wasm::own<wasm::Memory> memory_;
wasm::own<wasm::Table> table_;
Expand Down Expand Up @@ -247,9 +252,28 @@ bool V8::load(const std::string& code, bool /* allow_precompiled */) {
::memcpy(source_.get(), code.data(), code.size());

module_ = wasm::Module::make(store_.get(), source_);
if (module_) {
shared_module_ = module_->share();
RELEASE_ASSERT(shared_module_ != nullptr, "");
}

return module_ != nullptr;
}

WasmVmPtr V8::clone() {
ENVOY_LOG(trace, "clone()");
ASSERT(shared_module_ != nullptr);

auto clone = std::make_unique<V8>(scope_);
clone->store_ = wasm::Store::make(engine());
RELEASE_ASSERT(clone->store_ != nullptr, "");

clone->module_ = wasm::Module::obtain(clone->store_.get(), shared_module_.get());
RELEASE_ASSERT(clone->module_ != nullptr, "");

return clone;
}

absl::string_view V8::getCustomSection(absl::string_view name) {
ENVOY_LOG(trace, "getCustomSection(\"{}\")", name);
ASSERT(source_.get() != nullptr);
Expand Down Expand Up @@ -562,7 +586,7 @@ void V8::getModuleFunctionImpl(absl::string_view function_name,
};
}

WasmVmPtr createVm() { return std::make_unique<V8>(); }
WasmVmPtr createVm(Stats::ScopeSharedPtr scope) { return std::make_unique<V8>(scope); }

} // namespace V8
} // namespace Wasm
Expand Down
2 changes: 1 addition & 1 deletion source/extensions/common/wasm/v8/v8.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Common {
namespace Wasm {
namespace V8 {

WasmVmPtr createVm();
WasmVmPtr createVm(Stats::ScopeSharedPtr scope);

} // namespace V8
} // namespace Wasm
Expand Down
6 changes: 3 additions & 3 deletions source/extensions/common/wasm/wasm_vm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ namespace Wasm {
thread_local Envoy::Extensions::Common::Wasm::Context* current_context_ = nullptr;
thread_local uint32_t effective_context_id_ = 0;

WasmVmPtr createWasmVm(absl::string_view runtime) {
WasmVmPtr createWasmVm(absl::string_view runtime, Stats::ScopeSharedPtr scope) {
if (runtime.empty()) {
throw WasmVmException("Failed to create WASM VM with unspecified runtime.");
} else if (runtime == WasmRuntimeNames::get().Null) {
return Null::createVm();
return Null::createVm(scope);
} else if (runtime == WasmRuntimeNames::get().V8) {
return V8::createVm();
return V8::createVm(scope);
} else {
throw WasmVmException(fmt::format(
"Failed to create WASM VM using {} runtime. Envoy was compiled without support for it.",
Expand Down
16 changes: 10 additions & 6 deletions source/extensions/common/wasm/wasm_vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <memory>

#include "envoy/common/exception.h"
#include "envoy/stats/scope.h"

#include "common/common/logger.h"

Expand Down Expand Up @@ -98,8 +99,7 @@ template <size_t N> using WasmCallWord = std::function<WasmFuncType<N, Word, Con

#define FOR_ALL_WASM_VM_EXPORTS(_f) \
_f(WasmCallVoid<0>) _f(WasmCallVoid<1>) _f(WasmCallVoid<2>) _f(WasmCallVoid<3>) \
_f(WasmCallVoid<4>) _f(WasmCallVoid<5>) _f(WasmCallVoid<8>) _f(WasmCallWord<0>) \
_f(WasmCallWord<1>) _f(WasmCallWord<2>) _f(WasmCallWord<3>)
_f(WasmCallVoid<5>) _f(WasmCallWord<1>) _f(WasmCallWord<2>) _f(WasmCallWord<3>)

// Calls out of the WASM VM.
// 1st arg is always a pointer to raw_context (void*).
Expand All @@ -111,6 +111,7 @@ template <size_t N> using WasmCallbackWord = WasmFuncType<N, Word, void*, Word>*
// Extended with W = Word
// Z = void, j = uint32_t, l = int64_t, m = uint64_t
using WasmCallback_WWl = Word (*)(void*, Word, int64_t);
using WasmCallback_WWlWW = Word (*)(void*, Word, int64_t, Word, Word);
using WasmCallback_WWm = Word (*)(void*, Word, uint64_t);
using WasmCallback_dd = double (*)(void*, double);

Expand All @@ -119,8 +120,11 @@ using WasmCallback_dd = double (*)(void*, double);
_f(WasmCallbackVoid<4>) _f(WasmCallbackWord<0>) _f(WasmCallbackWord<1>) \
_f(WasmCallbackWord<2>) _f(WasmCallbackWord<3>) _f(WasmCallbackWord<4>) \
_f(WasmCallbackWord<5>) _f(WasmCallbackWord<6>) _f(WasmCallbackWord<7>) \
_f(WasmCallbackWord<8>) _f(WasmCallbackWord<9>) _f(WasmCallback_WWl) \
_f(WasmCallback_WWm) _f(WasmCallback_dd)
_f(WasmCallbackWord<8>) _f(WasmCallbackWord<9>) _f(WasmCallbackWord<10>) \
_f(WasmCallback_WWl) _f(WasmCallback_WWlWW) _f(WasmCallback_WWm) \
_f(WasmCallback_dd)

enum class Cloneable { NotCloneable, CompiledBytecode, InstantiatedModule };

// Wasm VM instance. Provides the low level WASM interface.
class WasmVm : public Logger::Loggable<Logger::Id::wasm> {
Expand All @@ -143,7 +147,7 @@ class WasmVm : public Logger::Loggable<Logger::Id::wasm> {
* VM from scratch for each worker.
* @return true if the VM is cloneable.
*/
virtual bool cloneable() PURE;
virtual Cloneable cloneable() PURE;

/**
* Make a worker/thread-specific copy if supported by the underlying VM system (see cloneable()
Expand Down Expand Up @@ -287,7 +291,7 @@ struct SaveRestoreContext {
};

// Create a new low-level WASM VM using runtime of the given type (e.g. "envoy.wasm.runtime.wavm").
WasmVmPtr createWasmVm(absl::string_view runtime);
WasmVmPtr createWasmVm(absl::string_view runtime, Stats::ScopeSharedPtr scope);

} // namespace Wasm
} // namespace Common
Expand Down
63 changes: 63 additions & 0 deletions source/extensions/common/wasm/wasm_vm_base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#pragma once

#include "envoy/stats/scope.h"
#include "envoy/stats/stats.h"
#include "envoy/stats/stats_macros.h"

#include "extensions/common/wasm/wasm_vm.h"

#include "absl/strings/str_cat.h"

namespace Envoy {
namespace Extensions {
namespace Common {
namespace Wasm {

/**
* Wasm host stats.
*/
#define ALL_VM_STATS(COUNTER, GAUGE) \
COUNTER(created) \
COUNTER(cloned) \
GAUGE(active, NeverImport)

struct VmStats {
ALL_VM_STATS(GENERATE_COUNTER_STRUCT, GENERATE_GAUGE_STRUCT)
};

struct VmGlobalStats {
std::atomic<int64_t> active_;
};

// Wasm VM base instance. Provides common behavior (e.g. Stats).
class WasmVmBase : public WasmVm {
public:
WasmVmBase(Stats::ScopeSharedPtr scope, VmGlobalStats* global_stats_ptr,
absl::string_view runtime)
: scope_(scope), global_stats_ptr_(global_stats_ptr),
stats_(VmStats{
ALL_VM_STATS(POOL_COUNTER_PREFIX(*scope_, absl::StrCat("wasm_vm.", runtime, ".")),
POOL_GAUGE_PREFIX(*scope_, absl::StrCat("wasm_vm.", runtime, ".")))}),
runtime_(std::string(runtime)) {
global_stats_ptr_->active_++;
stats_.created_.inc();
stats_.active_.set(global_stats_ptr_->active_);
ENVOY_LOG(debug, "WasmVm created {} now active", runtime_, global_stats_ptr_->active_);
}
virtual ~WasmVmBase() {
global_stats_ptr_->active_--;
stats_.active_.set(global_stats_ptr_->active_);
ENVOY_LOG(debug, "~WasmVm {} {} remaining active", runtime_, global_stats_ptr_->active_);
}

protected:
Stats::ScopeSharedPtr scope_;
VmGlobalStats* global_stats_ptr_;
VmStats stats_;
std::string runtime_;
};

} // namespace Wasm
} // namespace Common
} // namespace Extensions
} // namespace Envoy
Loading