// Copyright 2018 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include "src/objects-inl.h" #include "src/wasm/wasm-engine.h" #include "src/wasm/wasm-module-builder.h" #include "src/wasm/wasm-module.h" #include "src/wasm/wasm-objects-inl.h" #include "test/cctest/cctest.h" #include "test/common/wasm/test-signatures.h" #include "test/common/wasm/wasm-macro-gen.h" #include "test/common/wasm/wasm-module-runner.h" namespace v8 { namespace internal { namespace wasm { 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: explicit SharedEngine(size_t max_committed = kMaxWasmCodeMemory) : wasm_engine_(base::make_unique( base::make_unique(max_committed))) {} ~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(wasm_engine_.use_count()) - 1; } std::shared_ptr ExportEngineForSharing() { return wasm_engine_; } private: std::shared_ptr wasm_engine_; }; // Helper type definition representing a WebAssembly module shared between // multiple Isolates with implicit reference counting. using SharedModule = std::shared_ptr; // Helper class representing an Isolate based on a given shared WebAssembly // engine available at construction time. class SharedEngineIsolate { public: explicit SharedEngineIsolate(SharedEngine* engine) : isolate_(v8::Isolate::Allocate()) { isolate()->set_wasm_engine(engine->ExportEngineForSharing()); v8::Isolate::CreateParams create_params; create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); v8::Isolate::Initialize(isolate_, create_params); v8::HandleScope handle_scope(v8_isolate()); v8::Context::New(v8_isolate())->Enter(); testing::SetupIsolateForWasmModule(isolate()); zone_.reset(new Zone(isolate()->allocator(), ZONE_NAME)); } ~SharedEngineIsolate() { zone_.reset(); isolate_->Dispose(); } Zone* zone() const { return zone_.get(); } v8::Isolate* v8_isolate() { return isolate_; } Isolate* isolate() { return reinterpret_cast(isolate_); } Handle CompileAndInstantiate(ZoneBuffer* buffer) { ErrorThrower thrower(isolate(), "CompileAndInstantiate"); MaybeHandle instance = testing::CompileAndInstantiateForTesting( isolate(), &thrower, ModuleWireBytes(buffer->begin(), buffer->end())); return instance.ToHandleChecked(); } // TODO(mstarzinger): Switch over to a public API for sharing modules via the // {v8::WasmCompiledModule::TransferrableModule} class once it is ready. Handle ImportInstance(SharedModule shared_module) { Vector wire_bytes = shared_module->wire_bytes(); Handle