Commit 6ad860b3 authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

[wasm][cleanup] Hold wasm engine in a raw pointer

After the --wasm-shared-engine flag was removed (in
https://crrev.com/c/1864935), there is no point any more in holding the
wasm engine in a shared_ptr. The engine is initialized once for the
whole process, and only deallocated during global tear down.

R=jkummerow@chromium.org

Bug: v8:11384
Change-Id: Id8e96eaecfcab8b44842ec323c94529e9c5a5e25
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2853589Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74253}
parent 5a8afe01
...@@ -2692,9 +2692,10 @@ void Isolate::UnregisterManagedPtrDestructor(ManagedPtrDestructor* destructor) { ...@@ -2692,9 +2692,10 @@ void Isolate::UnregisterManagedPtrDestructor(ManagedPtrDestructor* destructor) {
} }
#if V8_ENABLE_WEBASSEMBLY #if V8_ENABLE_WEBASSEMBLY
void Isolate::SetWasmEngine(std::shared_ptr<wasm::WasmEngine> engine) { void Isolate::SetWasmEngine(wasm::WasmEngine* engine) {
DCHECK_NULL(wasm_engine_); // Only call once before {Init}. DCHECK_NULL(wasm_engine_); // Only call once before {Init}.
wasm_engine_ = std::move(engine); DCHECK_NOT_NULL(engine);
wasm_engine_ = engine;
wasm_engine_->AddIsolate(this); wasm_engine_->AddIsolate(this);
} }
...@@ -3136,10 +3137,7 @@ void Isolate::Deinit() { ...@@ -3136,10 +3137,7 @@ void Isolate::Deinit() {
if (logfile != nullptr) base::Fclose(logfile); if (logfile != nullptr) base::Fclose(logfile);
#if V8_ENABLE_WEBASSEMBLY #if V8_ENABLE_WEBASSEMBLY
if (wasm_engine_) {
wasm_engine_->RemoveIsolate(this); wasm_engine_->RemoveIsolate(this);
wasm_engine_.reset();
}
#endif // V8_ENABLE_WEBASSEMBLY #endif // V8_ENABLE_WEBASSEMBLY
TearDownEmbeddedBlob(); TearDownEmbeddedBlob();
...@@ -3617,11 +3615,7 @@ bool Isolate::Init(SnapshotData* startup_snapshot_data, ...@@ -3617,11 +3615,7 @@ bool Isolate::Init(SnapshotData* startup_snapshot_data,
isolate_data_.external_reference_table()->Init(this); isolate_data_.external_reference_table()->Init(this);
#if V8_ENABLE_WEBASSEMBLY #if V8_ENABLE_WEBASSEMBLY
// Setup the wasm engine.
if (wasm_engine_ == nullptr) {
SetWasmEngine(wasm::WasmEngine::GetWasmEngine()); SetWasmEngine(wasm::WasmEngine::GetWasmEngine());
}
DCHECK_NOT_NULL(wasm_engine_);
#endif // V8_ENABLE_WEBASSEMBLY #endif // V8_ENABLE_WEBASSEMBLY
if (setup_delegate_ == nullptr) { if (setup_delegate_ == nullptr) {
......
...@@ -1684,8 +1684,9 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory { ...@@ -1684,8 +1684,9 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
} }
#if V8_ENABLE_WEBASSEMBLY #if V8_ENABLE_WEBASSEMBLY
wasm::WasmEngine* wasm_engine() const { return wasm_engine_.get(); } // TODO(wasm): Replace all uses by {WasmEngine::GetWasmEngine}?
void SetWasmEngine(std::shared_ptr<wasm::WasmEngine> engine); wasm::WasmEngine* wasm_engine() const { return wasm_engine_; }
void SetWasmEngine(wasm::WasmEngine* engine);
void AddSharedWasmMemory(Handle<WasmMemoryObject> memory_object); void AddSharedWasmMemory(Handle<WasmMemoryObject> memory_object);
#endif // V8_ENABLE_WEBASSEMBLY #endif // V8_ENABLE_WEBASSEMBLY
...@@ -2135,7 +2136,7 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory { ...@@ -2135,7 +2136,7 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
size_t elements_deletion_counter_ = 0; size_t elements_deletion_counter_ = 0;
#if V8_ENABLE_WEBASSEMBLY #if V8_ENABLE_WEBASSEMBLY
std::shared_ptr<wasm::WasmEngine> wasm_engine_; wasm::WasmEngine* wasm_engine_ = nullptr;
#endif // V8_ENABLE_WEBASSEMBLY #endif // V8_ENABLE_WEBASSEMBLY
std::unique_ptr<TracingCpuProfilerImpl> tracing_cpu_profiler_; std::unique_ptr<TracingCpuProfilerImpl> tracing_cpu_profiler_;
......
...@@ -1561,24 +1561,29 @@ void WasmEngine::PotentiallyFinishCurrentGC() { ...@@ -1561,24 +1561,29 @@ void WasmEngine::PotentiallyFinishCurrentGC() {
namespace { namespace {
DEFINE_LAZY_LEAKY_OBJECT_GETTER(std::shared_ptr<WasmEngine>, WasmEngine* global_wasm_engine = nullptr;
GetSharedWasmEngine)
} // namespace } // namespace
// static // static
void WasmEngine::InitializeOncePerProcess() { void WasmEngine::InitializeOncePerProcess() {
*GetSharedWasmEngine() = std::make_shared<WasmEngine>(); DCHECK_NULL(global_wasm_engine);
global_wasm_engine = new WasmEngine();
} }
// static // static
void WasmEngine::GlobalTearDown() { void WasmEngine::GlobalTearDown() {
GetSharedWasmEngine()->reset(); // Note: This can be called multiple times in a row (see
// test-api/InitializeAndDisposeMultiple). This is fine, as
// {global_wasm_engine} will be nullptr then.
delete global_wasm_engine;
global_wasm_engine = nullptr;
} }
// static // static
std::shared_ptr<WasmEngine> WasmEngine::GetWasmEngine() { WasmEngine* WasmEngine::GetWasmEngine() {
return *GetSharedWasmEngine(); DCHECK_NOT_NULL(global_wasm_engine);
return global_wasm_engine;
} }
// {max_mem_pages} is declared in wasm-limits.h. // {max_mem_pages} is declared in wasm-limits.h.
......
...@@ -357,10 +357,8 @@ class V8_EXPORT_PRIVATE WasmEngine { ...@@ -357,10 +357,8 @@ class V8_EXPORT_PRIVATE WasmEngine {
static void InitializeOncePerProcess(); static void InitializeOncePerProcess();
static void GlobalTearDown(); static void GlobalTearDown();
// Returns a reference to the WasmEngine shared by the entire process. Try to // Returns a reference to the WasmEngine shared by the entire process.
// use {Isolate::wasm_engine} instead if it is available, which encapsulates static WasmEngine* GetWasmEngine();
// engine lifetime decisions during Isolate bootstrapping.
static std::shared_ptr<WasmEngine> GetWasmEngine();
private: private:
struct CurrentGCInfo; struct CurrentGCInfo;
......
...@@ -257,7 +257,6 @@ TEST(BlockWasmCodeGenAtDeserialization) { ...@@ -257,7 +257,6 @@ TEST(BlockWasmCodeGenAtDeserialization) {
} }
UNINITIALIZED_TEST(CompiledWasmModulesTransfer) { UNINITIALIZED_TEST(CompiledWasmModulesTransfer) {
i::wasm::WasmEngine::InitializeOncePerProcess();
v8::internal::AccountingAllocator allocator; v8::internal::AccountingAllocator allocator;
Zone zone(&allocator, ZONE_NAME); Zone zone(&allocator, ZONE_NAME);
......
...@@ -22,40 +22,15 @@ namespace internal { ...@@ -22,40 +22,15 @@ namespace internal {
namespace wasm { namespace wasm {
namespace test_wasm_shared_engine { namespace test_wasm_shared_engine {
// Helper class representing a WebAssembly engine that is capable of being
// shared between multiple Isolates, sharing the underlying generated code.
class SharedEngine {
public:
~SharedEngine() {
// Ensure no remaining uses exist.
CHECK(wasm_engine_.unique());
}
WasmEngine* engine() const { return wasm_engine_.get(); }
WasmCodeManager* code_manager() const { return engine()->code_manager(); }
int NumberOfExportedEngineUses() const {
// This class holds one implicit use itself, which we discount.
return static_cast<int>(wasm_engine_.use_count()) - 1;
}
std::shared_ptr<WasmEngine> ExportEngineForSharing() { return wasm_engine_; }
private:
std::shared_ptr<WasmEngine> wasm_engine_ = std::make_unique<WasmEngine>();
};
// Helper type definition representing a WebAssembly module shared between // Helper type definition representing a WebAssembly module shared between
// multiple Isolates with implicit reference counting. // multiple Isolates with implicit reference counting.
using SharedModule = std::shared_ptr<NativeModule>; using SharedModule = std::shared_ptr<NativeModule>;
// Helper class representing an Isolate based on a given shared WebAssembly // Helper class representing an Isolate that uses the process-wide (shared) wasm
// engine available at construction time. // engine.
class SharedEngineIsolate { class SharedEngineIsolate {
public: public:
explicit SharedEngineIsolate(SharedEngine* engine) SharedEngineIsolate() : isolate_(v8::Isolate::Allocate()) {
: isolate_(v8::Isolate::Allocate()) {
isolate()->SetWasmEngine(engine->ExportEngineForSharing());
v8::Isolate::CreateParams create_params; v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate::Initialize(isolate_, create_params); v8::Isolate::Initialize(isolate_, create_params);
...@@ -111,19 +86,16 @@ class SharedEngineIsolate { ...@@ -111,19 +86,16 @@ class SharedEngineIsolate {
// with a shared WebAssembly engine available at construction time. // with a shared WebAssembly engine available at construction time.
class SharedEngineThread : public v8::base::Thread { class SharedEngineThread : public v8::base::Thread {
public: public:
SharedEngineThread(SharedEngine* engine, explicit SharedEngineThread(
std::function<void(SharedEngineIsolate*)> callback) std::function<void(SharedEngineIsolate*)> callback)
: Thread(Options("SharedEngineThread")), : Thread(Options("SharedEngineThread")), callback_(callback) {}
engine_(engine),
callback_(callback) {}
void Run() override { void Run() override {
SharedEngineIsolate isolate(engine_); SharedEngineIsolate isolate;
callback_(&isolate); callback_(&isolate);
} }
private: private:
SharedEngine* engine_;
std::function<void(SharedEngineIsolate*)> callback_; std::function<void(SharedEngineIsolate*)> callback_;
}; };
...@@ -201,34 +173,16 @@ Handle<WasmInstanceObject> CompileAndInstantiateAsync( ...@@ -201,34 +173,16 @@ Handle<WasmInstanceObject> CompileAndInstantiateAsync(
} // namespace } // namespace
TEST(SharedEngineUseCount) {
SharedEngine engine;
CHECK_EQ(0, engine.NumberOfExportedEngineUses());
{
SharedEngineIsolate isolate(&engine);
CHECK_EQ(1, engine.NumberOfExportedEngineUses());
}
CHECK_EQ(0, engine.NumberOfExportedEngineUses());
{
SharedEngineIsolate isolate1(&engine);
CHECK_EQ(1, engine.NumberOfExportedEngineUses());
SharedEngineIsolate isolate2(&engine);
CHECK_EQ(2, engine.NumberOfExportedEngineUses());
}
CHECK_EQ(0, engine.NumberOfExportedEngineUses());
}
TEST(SharedEngineRunSeparated) { TEST(SharedEngineRunSeparated) {
SharedEngine engine;
{ {
SharedEngineIsolate isolate(&engine); SharedEngineIsolate isolate;
HandleScope scope(isolate.isolate()); HandleScope scope(isolate.isolate());
ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 23); ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 23);
Handle<WasmInstanceObject> instance = isolate.CompileAndInstantiate(buffer); Handle<WasmInstanceObject> instance = isolate.CompileAndInstantiate(buffer);
CHECK_EQ(23, isolate.Run(instance)); CHECK_EQ(23, isolate.Run(instance));
} }
{ {
SharedEngineIsolate isolate(&engine); SharedEngineIsolate isolate;
HandleScope scope(isolate.isolate()); HandleScope scope(isolate.isolate());
ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 42); ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 42);
Handle<WasmInstanceObject> instance = isolate.CompileAndInstantiate(buffer); Handle<WasmInstanceObject> instance = isolate.CompileAndInstantiate(buffer);
...@@ -237,10 +191,9 @@ TEST(SharedEngineRunSeparated) { ...@@ -237,10 +191,9 @@ TEST(SharedEngineRunSeparated) {
} }
TEST(SharedEngineRunImported) { TEST(SharedEngineRunImported) {
SharedEngine engine;
SharedModule module; SharedModule module;
{ {
SharedEngineIsolate isolate(&engine); SharedEngineIsolate isolate;
HandleScope scope(isolate.isolate()); HandleScope scope(isolate.isolate());
ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 23); ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 23);
Handle<WasmInstanceObject> instance = isolate.CompileAndInstantiate(buffer); Handle<WasmInstanceObject> instance = isolate.CompileAndInstantiate(buffer);
...@@ -248,7 +201,7 @@ TEST(SharedEngineRunImported) { ...@@ -248,7 +201,7 @@ TEST(SharedEngineRunImported) {
CHECK_EQ(23, isolate.Run(instance)); CHECK_EQ(23, isolate.Run(instance));
} }
{ {
SharedEngineIsolate isolate(&engine); SharedEngineIsolate isolate;
HandleScope scope(isolate.isolate()); HandleScope scope(isolate.isolate());
Handle<WasmInstanceObject> instance = isolate.ImportInstance(module); Handle<WasmInstanceObject> instance = isolate.ImportInstance(module);
CHECK_EQ(23, isolate.Run(instance)); CHECK_EQ(23, isolate.Run(instance));
...@@ -256,15 +209,14 @@ TEST(SharedEngineRunImported) { ...@@ -256,15 +209,14 @@ TEST(SharedEngineRunImported) {
} }
TEST(SharedEngineRunThreadedBuildingSync) { TEST(SharedEngineRunThreadedBuildingSync) {
SharedEngine engine; SharedEngineThread thread1([](SharedEngineIsolate* isolate) {
SharedEngineThread thread1(&engine, [](SharedEngineIsolate* isolate) {
HandleScope scope(isolate->isolate()); HandleScope scope(isolate->isolate());
ZoneBuffer* buffer = BuildReturnConstantModule(isolate->zone(), 23); ZoneBuffer* buffer = BuildReturnConstantModule(isolate->zone(), 23);
Handle<WasmInstanceObject> instance = Handle<WasmInstanceObject> instance =
isolate->CompileAndInstantiate(buffer); isolate->CompileAndInstantiate(buffer);
CHECK_EQ(23, isolate->Run(instance)); CHECK_EQ(23, isolate->Run(instance));
}); });
SharedEngineThread thread2(&engine, [](SharedEngineIsolate* isolate) { SharedEngineThread thread2([](SharedEngineIsolate* isolate) {
HandleScope scope(isolate->isolate()); HandleScope scope(isolate->isolate());
ZoneBuffer* buffer = BuildReturnConstantModule(isolate->zone(), 42); ZoneBuffer* buffer = BuildReturnConstantModule(isolate->zone(), 42);
Handle<WasmInstanceObject> instance = Handle<WasmInstanceObject> instance =
...@@ -278,15 +230,14 @@ TEST(SharedEngineRunThreadedBuildingSync) { ...@@ -278,15 +230,14 @@ TEST(SharedEngineRunThreadedBuildingSync) {
} }
TEST(SharedEngineRunThreadedBuildingAsync) { TEST(SharedEngineRunThreadedBuildingAsync) {
SharedEngine engine; SharedEngineThread thread1([](SharedEngineIsolate* isolate) {
SharedEngineThread thread1(&engine, [](SharedEngineIsolate* isolate) {
HandleScope scope(isolate->isolate()); HandleScope scope(isolate->isolate());
ZoneBuffer* buffer = BuildReturnConstantModule(isolate->zone(), 23); ZoneBuffer* buffer = BuildReturnConstantModule(isolate->zone(), 23);
Handle<WasmInstanceObject> instance = Handle<WasmInstanceObject> instance =
CompileAndInstantiateAsync(isolate, buffer); CompileAndInstantiateAsync(isolate, buffer);
CHECK_EQ(23, isolate->Run(instance)); CHECK_EQ(23, isolate->Run(instance));
}); });
SharedEngineThread thread2(&engine, [](SharedEngineIsolate* isolate) { SharedEngineThread thread2([](SharedEngineIsolate* isolate) {
HandleScope scope(isolate->isolate()); HandleScope scope(isolate->isolate());
ZoneBuffer* buffer = BuildReturnConstantModule(isolate->zone(), 42); ZoneBuffer* buffer = BuildReturnConstantModule(isolate->zone(), 42);
Handle<WasmInstanceObject> instance = Handle<WasmInstanceObject> instance =
...@@ -300,21 +251,20 @@ TEST(SharedEngineRunThreadedBuildingAsync) { ...@@ -300,21 +251,20 @@ TEST(SharedEngineRunThreadedBuildingAsync) {
} }
TEST(SharedEngineRunThreadedExecution) { TEST(SharedEngineRunThreadedExecution) {
SharedEngine engine;
SharedModule module; SharedModule module;
{ {
SharedEngineIsolate isolate(&engine); SharedEngineIsolate isolate;
HandleScope scope(isolate.isolate()); HandleScope scope(isolate.isolate());
ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 23); ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 23);
Handle<WasmInstanceObject> instance = isolate.CompileAndInstantiate(buffer); Handle<WasmInstanceObject> instance = isolate.CompileAndInstantiate(buffer);
module = isolate.ExportInstance(instance); module = isolate.ExportInstance(instance);
} }
SharedEngineThread thread1(&engine, [module](SharedEngineIsolate* isolate) { SharedEngineThread thread1([module](SharedEngineIsolate* isolate) {
HandleScope scope(isolate->isolate()); HandleScope scope(isolate->isolate());
Handle<WasmInstanceObject> instance = isolate->ImportInstance(module); Handle<WasmInstanceObject> instance = isolate->ImportInstance(module);
CHECK_EQ(23, isolate->Run(instance)); CHECK_EQ(23, isolate->Run(instance));
}); });
SharedEngineThread thread2(&engine, [module](SharedEngineIsolate* isolate) { SharedEngineThread thread2([module](SharedEngineIsolate* isolate) {
HandleScope scope(isolate->isolate()); HandleScope scope(isolate->isolate());
Handle<WasmInstanceObject> instance = isolate->ImportInstance(module); Handle<WasmInstanceObject> instance = isolate->ImportInstance(module);
CHECK_EQ(23, isolate->Run(instance)); CHECK_EQ(23, isolate->Run(instance));
...@@ -326,10 +276,9 @@ TEST(SharedEngineRunThreadedExecution) { ...@@ -326,10 +276,9 @@ TEST(SharedEngineRunThreadedExecution) {
} }
TEST(SharedEngineRunThreadedTierUp) { TEST(SharedEngineRunThreadedTierUp) {
SharedEngine engine;
SharedModule module; SharedModule module;
{ {
SharedEngineIsolate isolate(&engine); SharedEngineIsolate isolate;
HandleScope scope(isolate.isolate()); HandleScope scope(isolate.isolate());
ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 23); ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 23);
Handle<WasmInstanceObject> instance = isolate.CompileAndInstantiate(buffer); Handle<WasmInstanceObject> instance = isolate.CompileAndInstantiate(buffer);
...@@ -338,7 +287,7 @@ TEST(SharedEngineRunThreadedTierUp) { ...@@ -338,7 +287,7 @@ TEST(SharedEngineRunThreadedTierUp) {
constexpr int kNumberOfThreads = 5; constexpr int kNumberOfThreads = 5;
std::list<SharedEngineThread> threads; std::list<SharedEngineThread> threads;
for (int i = 0; i < kNumberOfThreads; ++i) { for (int i = 0; i < kNumberOfThreads; ++i) {
threads.emplace_back(&engine, [module](SharedEngineIsolate* isolate) { threads.emplace_back([module](SharedEngineIsolate* isolate) {
constexpr int kNumberOfIterations = 100; constexpr int kNumberOfIterations = 100;
HandleScope scope(isolate->isolate()); HandleScope scope(isolate->isolate());
Handle<WasmInstanceObject> instance = isolate->ImportInstance(module); Handle<WasmInstanceObject> instance = isolate->ImportInstance(module);
...@@ -347,7 +296,7 @@ TEST(SharedEngineRunThreadedTierUp) { ...@@ -347,7 +296,7 @@ TEST(SharedEngineRunThreadedTierUp) {
} }
}); });
} }
threads.emplace_back(&engine, [module](SharedEngineIsolate* isolate) { threads.emplace_back([module](SharedEngineIsolate* isolate) {
HandleScope scope(isolate->isolate()); HandleScope scope(isolate->isolate());
Handle<WasmInstanceObject> instance = isolate->ImportInstance(module); Handle<WasmInstanceObject> instance = isolate->ImportInstance(module);
WasmFeatures detected = WasmFeatures::None(); WasmFeatures detected = WasmFeatures::None();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment