2017-12-05 00:28:35 +00:00
|
|
|
// Copyright 2017 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.
|
|
|
|
|
2018-02-02 12:05:19 +00:00
|
|
|
#ifndef V8_WASM_WASM_ENGINE_H_
|
|
|
|
#define V8_WASM_WASM_ENGINE_H_
|
2017-12-05 00:28:35 +00:00
|
|
|
|
2020-02-03 12:13:26 +00:00
|
|
|
#include <algorithm>
|
|
|
|
#include <map>
|
2017-12-05 00:28:35 +00:00
|
|
|
#include <memory>
|
2019-12-18 13:41:12 +00:00
|
|
|
#include <unordered_map>
|
2018-09-25 11:24:09 +00:00
|
|
|
#include <unordered_set>
|
2017-12-05 00:28:35 +00:00
|
|
|
|
2019-12-18 13:41:12 +00:00
|
|
|
#include "src/base/platform/condition-variable.h"
|
|
|
|
#include "src/base/platform/mutex.h"
|
2019-05-24 13:51:59 +00:00
|
|
|
#include "src/tasks/cancelable-task.h"
|
2017-12-05 01:47:59 +00:00
|
|
|
#include "src/wasm/wasm-code-manager.h"
|
2018-08-21 15:01:31 +00:00
|
|
|
#include "src/wasm/wasm-tier.h"
|
2018-07-09 08:02:54 +00:00
|
|
|
#include "src/zone/accounting-allocator.h"
|
2017-12-05 00:28:35 +00:00
|
|
|
|
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
|
|
|
|
2018-11-21 21:19:18 +00:00
|
|
|
class AsmWasmData;
|
2018-07-16 11:52:11 +00:00
|
|
|
class CodeTracer;
|
2018-07-10 13:15:29 +00:00
|
|
|
class CompilationStatistics;
|
2018-12-25 00:19:47 +00:00
|
|
|
class HeapNumber;
|
2018-01-18 10:52:52 +00:00
|
|
|
class WasmInstanceObject;
|
2018-10-23 11:37:58 +00:00
|
|
|
class WasmModuleObject;
|
2019-09-09 10:19:34 +00:00
|
|
|
class JSArrayBuffer;
|
2018-01-18 10:52:52 +00:00
|
|
|
|
2017-12-05 00:28:35 +00:00
|
|
|
namespace wasm {
|
|
|
|
|
2018-10-23 11:37:58 +00:00
|
|
|
class AsyncCompileJob;
|
2018-01-18 10:52:52 +00:00
|
|
|
class ErrorThrower;
|
|
|
|
struct ModuleWireBytes;
|
2019-11-26 16:25:14 +00:00
|
|
|
class WasmFeatures;
|
2018-01-18 10:52:52 +00:00
|
|
|
|
2020-02-17 05:01:29 +00:00
|
|
|
namespace gdb_server {
|
|
|
|
class GdbServer;
|
|
|
|
}
|
|
|
|
|
2018-05-24 21:22:27 +00:00
|
|
|
class V8_EXPORT_PRIVATE CompilationResultResolver {
|
|
|
|
public:
|
|
|
|
virtual void OnCompilationSucceeded(Handle<WasmModuleObject> result) = 0;
|
|
|
|
virtual void OnCompilationFailed(Handle<Object> error_reason) = 0;
|
2018-09-13 09:27:26 +00:00
|
|
|
virtual ~CompilationResultResolver() = default;
|
2018-05-24 21:22:27 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class V8_EXPORT_PRIVATE InstantiationResultResolver {
|
|
|
|
public:
|
|
|
|
virtual void OnInstantiationSucceeded(Handle<WasmInstanceObject> result) = 0;
|
|
|
|
virtual void OnInstantiationFailed(Handle<Object> error_reason) = 0;
|
2018-09-13 09:27:26 +00:00
|
|
|
virtual ~InstantiationResultResolver() = default;
|
2018-05-24 21:22:27 +00:00
|
|
|
};
|
|
|
|
|
2020-01-21 14:19:18 +00:00
|
|
|
// Native modules cached by their wire bytes.
|
|
|
|
class NativeModuleCache {
|
|
|
|
public:
|
2020-02-03 12:13:26 +00:00
|
|
|
struct Key {
|
|
|
|
// Store the prefix hash as part of the key for faster lookup, and to
|
|
|
|
// quickly check existing prefixes for streaming compilation.
|
|
|
|
size_t prefix_hash;
|
|
|
|
Vector<const uint8_t> bytes;
|
|
|
|
|
|
|
|
bool operator==(const Key& other) const {
|
|
|
|
bool eq = bytes == other.bytes;
|
|
|
|
DCHECK_IMPLIES(eq, prefix_hash == other.prefix_hash);
|
|
|
|
return eq;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator<(const Key& other) const {
|
|
|
|
if (prefix_hash != other.prefix_hash) {
|
2020-02-06 14:11:05 +00:00
|
|
|
DCHECK_IMPLIES(!bytes.empty() && !other.bytes.empty(),
|
|
|
|
bytes != other.bytes);
|
2020-02-03 12:13:26 +00:00
|
|
|
return prefix_hash < other.prefix_hash;
|
|
|
|
}
|
2020-02-04 17:39:08 +00:00
|
|
|
if (bytes.size() != other.bytes.size()) {
|
|
|
|
return bytes.size() < other.bytes.size();
|
|
|
|
}
|
|
|
|
// Fast path when the base pointers are the same.
|
|
|
|
// Also handles the {nullptr} case which would be UB for memcmp.
|
|
|
|
if (bytes.begin() == other.bytes.begin()) {
|
2020-02-06 14:11:05 +00:00
|
|
|
DCHECK_EQ(prefix_hash, other.prefix_hash);
|
2020-02-04 17:39:08 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
DCHECK_NOT_NULL(bytes.begin());
|
|
|
|
DCHECK_NOT_NULL(other.bytes.begin());
|
|
|
|
return memcmp(bytes.begin(), other.bytes.begin(), bytes.size()) < 0;
|
2020-02-03 12:13:26 +00:00
|
|
|
}
|
2020-01-21 14:19:18 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
std::shared_ptr<NativeModule> MaybeGetNativeModule(
|
|
|
|
ModuleOrigin origin, Vector<const uint8_t> wire_bytes);
|
2020-02-03 12:13:26 +00:00
|
|
|
bool GetStreamingCompilationOwnership(size_t prefix_hash);
|
|
|
|
void StreamingCompilationFailed(size_t prefix_hash);
|
|
|
|
std::shared_ptr<NativeModule> Update(
|
|
|
|
std::shared_ptr<NativeModule> native_module, bool error);
|
2020-01-21 14:19:18 +00:00
|
|
|
void Erase(NativeModule* native_module);
|
|
|
|
|
2020-02-06 14:11:05 +00:00
|
|
|
bool empty() { return map_.empty(); }
|
|
|
|
|
2020-02-03 12:13:26 +00:00
|
|
|
static size_t WireBytesHash(Vector<const uint8_t> bytes);
|
|
|
|
|
|
|
|
// Hash the wire bytes up to the code section header. Used as a heuristic to
|
|
|
|
// avoid streaming compilation of modules that are likely already in the
|
|
|
|
// cache. See {GetStreamingCompilationOwnership}. Assumes that the bytes have
|
|
|
|
// already been validated.
|
|
|
|
static size_t PrefixHash(Vector<const uint8_t> wire_bytes);
|
|
|
|
|
2020-01-21 14:19:18 +00:00
|
|
|
private:
|
|
|
|
// Each key points to the corresponding native module's wire bytes, so they
|
|
|
|
// should always be valid as long as the native module is alive. When
|
|
|
|
// the native module dies, {FreeNativeModule} deletes the entry from the
|
|
|
|
// map, so that we do not leave any dangling key pointing to an expired
|
|
|
|
// weak_ptr. This also serves as a way to regularly clean up the map, which
|
|
|
|
// would otherwise accumulate expired entries.
|
|
|
|
// A {nullopt} value is inserted to indicate that this native module is
|
|
|
|
// currently being created in some thread, and that other threads should wait
|
|
|
|
// before trying to get it from the cache.
|
|
|
|
// By contrast, an expired {weak_ptr} indicates that the native module died
|
|
|
|
// and will soon be cleaned up from the cache.
|
2020-02-03 12:13:26 +00:00
|
|
|
std::map<Key, base::Optional<std::weak_ptr<NativeModule>>> map_;
|
2020-01-21 14:19:18 +00:00
|
|
|
|
|
|
|
base::Mutex mutex_;
|
|
|
|
|
|
|
|
// This condition variable is used to synchronize threads compiling the same
|
|
|
|
// module. Only one thread will create the {NativeModule}. Other threads
|
|
|
|
// will wait on this variable until the first thread wakes them up.
|
|
|
|
base::ConditionVariable cache_cv_;
|
|
|
|
};
|
|
|
|
|
2017-12-05 00:28:35 +00:00
|
|
|
// The central data structure that represents an engine instance capable of
|
2020-03-30 16:15:05 +00:00
|
|
|
// loading, instantiating, and executing Wasm code.
|
2018-01-17 14:46:27 +00:00
|
|
|
class V8_EXPORT_PRIVATE WasmEngine {
|
2017-12-05 00:28:35 +00:00
|
|
|
public:
|
2018-09-18 13:05:45 +00:00
|
|
|
WasmEngine();
|
2018-07-10 13:15:29 +00:00
|
|
|
~WasmEngine();
|
2017-12-05 00:28:35 +00:00
|
|
|
|
2020-03-30 16:15:05 +00:00
|
|
|
// Synchronously validates the given bytes that represent an encoded Wasm
|
2018-01-18 10:52:52 +00:00
|
|
|
// module.
|
2018-08-08 14:54:44 +00:00
|
|
|
bool SyncValidate(Isolate* isolate, const WasmFeatures& enabled,
|
|
|
|
const ModuleWireBytes& bytes);
|
2018-01-17 14:46:27 +00:00
|
|
|
|
2018-01-18 10:52:52 +00:00
|
|
|
// Synchronously compiles the given bytes that represent a translated
|
|
|
|
// asm.js module.
|
2018-11-21 21:19:18 +00:00
|
|
|
MaybeHandle<AsmWasmData> SyncCompileTranslatedAsmJs(
|
2018-01-18 10:52:52 +00:00
|
|
|
Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes,
|
2018-11-21 21:19:18 +00:00
|
|
|
Vector<const byte> asm_js_offset_table_bytes,
|
2019-07-19 11:10:49 +00:00
|
|
|
Handle<HeapNumber> uses_bitset, LanguageMode language_mode);
|
2018-11-21 21:19:18 +00:00
|
|
|
Handle<WasmModuleObject> FinalizeTranslatedAsmJs(
|
|
|
|
Isolate* isolate, Handle<AsmWasmData> asm_wasm_data,
|
|
|
|
Handle<Script> script);
|
2018-01-18 10:52:52 +00:00
|
|
|
|
2020-03-30 16:15:05 +00:00
|
|
|
// Synchronously compiles the given bytes that represent an encoded Wasm
|
2018-01-18 10:52:52 +00:00
|
|
|
// module.
|
|
|
|
MaybeHandle<WasmModuleObject> SyncCompile(Isolate* isolate,
|
2018-08-08 14:54:44 +00:00
|
|
|
const WasmFeatures& enabled,
|
2018-01-18 10:52:52 +00:00
|
|
|
ErrorThrower* thrower,
|
|
|
|
const ModuleWireBytes& bytes);
|
|
|
|
|
2020-03-30 16:15:05 +00:00
|
|
|
// Synchronously instantiate the given Wasm module with the given imports.
|
2018-01-18 10:52:52 +00:00
|
|
|
// If the module represents an asm.js module, then the supplied {memory}
|
|
|
|
// should be used as the memory of the instance.
|
|
|
|
MaybeHandle<WasmInstanceObject> SyncInstantiate(
|
|
|
|
Isolate* isolate, ErrorThrower* thrower,
|
|
|
|
Handle<WasmModuleObject> module_object, MaybeHandle<JSReceiver> imports,
|
|
|
|
MaybeHandle<JSArrayBuffer> memory);
|
|
|
|
|
|
|
|
// Begin an asynchronous compilation of the given bytes that represent an
|
2020-03-30 16:15:05 +00:00
|
|
|
// encoded Wasm module.
|
2018-01-18 10:52:52 +00:00
|
|
|
// The {is_shared} flag indicates if the bytes backing the module could
|
|
|
|
// be shared across threads, i.e. could be concurrently modified.
|
2018-08-08 14:54:44 +00:00
|
|
|
void AsyncCompile(Isolate* isolate, const WasmFeatures& enabled,
|
2018-08-13 13:35:54 +00:00
|
|
|
std::shared_ptr<CompilationResultResolver> resolver,
|
2019-05-20 11:14:29 +00:00
|
|
|
const ModuleWireBytes& bytes, bool is_shared,
|
|
|
|
const char* api_method_name_for_errors);
|
2018-01-18 10:52:52 +00:00
|
|
|
|
2020-03-30 16:15:05 +00:00
|
|
|
// Begin an asynchronous instantiation of the given Wasm module.
|
2018-05-24 21:22:27 +00:00
|
|
|
void AsyncInstantiate(Isolate* isolate,
|
|
|
|
std::unique_ptr<InstantiationResultResolver> resolver,
|
2018-01-18 10:52:52 +00:00
|
|
|
Handle<WasmModuleObject> module_object,
|
|
|
|
MaybeHandle<JSReceiver> imports);
|
|
|
|
|
2018-05-09 13:48:47 +00:00
|
|
|
std::shared_ptr<StreamingDecoder> StartStreamingCompilation(
|
2018-08-08 14:54:44 +00:00
|
|
|
Isolate* isolate, const WasmFeatures& enabled, Handle<Context> context,
|
2019-04-30 14:04:56 +00:00
|
|
|
const char* api_method_name,
|
2018-08-13 13:35:54 +00:00
|
|
|
std::shared_ptr<CompilationResultResolver> resolver);
|
2017-12-05 00:28:35 +00:00
|
|
|
|
2018-12-12 15:18:38 +00:00
|
|
|
// Compiles the function with the given index at a specific compilation tier.
|
|
|
|
// Errors are stored internally in the CompilationState.
|
|
|
|
// This is mostly used for testing to force a function into a specific tier.
|
|
|
|
void CompileFunction(Isolate* isolate, NativeModule* native_module,
|
2018-08-21 15:01:31 +00:00
|
|
|
uint32_t function_index, ExecutionTier tier);
|
2018-08-17 12:35:29 +00:00
|
|
|
|
2020-01-22 18:01:34 +00:00
|
|
|
// Recompiles all functions at a specific compilation tier.
|
|
|
|
void RecompileAllFunctions(Isolate* isolate, NativeModule* native_module,
|
|
|
|
ExecutionTier tier);
|
|
|
|
|
2020-02-05 17:32:47 +00:00
|
|
|
void TierDownAllModulesPerIsolate(Isolate* isolate);
|
2020-03-09 16:07:57 +00:00
|
|
|
void TierUpAllModulesPerIsolate(Isolate* isolate);
|
2020-02-05 17:32:47 +00:00
|
|
|
|
2018-07-31 08:16:22 +00:00
|
|
|
// Exports the sharable parts of the given module object so that they can be
|
|
|
|
// transferred to a different Context/Isolate using the same engine.
|
|
|
|
std::shared_ptr<NativeModule> ExportNativeModule(
|
|
|
|
Handle<WasmModuleObject> module_object);
|
|
|
|
|
|
|
|
// Imports the shared part of a module from a different Context/Isolate using
|
|
|
|
// the the same engine, recreating a full module object in the given Isolate.
|
|
|
|
Handle<WasmModuleObject> ImportNativeModule(
|
2018-09-07 11:04:24 +00:00
|
|
|
Isolate* isolate, std::shared_ptr<NativeModule> shared_module);
|
2018-07-31 08:16:22 +00:00
|
|
|
|
2018-09-18 13:05:45 +00:00
|
|
|
WasmCodeManager* code_manager() { return &code_manager_; }
|
2017-12-05 00:28:35 +00:00
|
|
|
|
2018-07-09 08:02:54 +00:00
|
|
|
AccountingAllocator* allocator() { return &allocator_; }
|
|
|
|
|
2018-07-10 13:15:29 +00:00
|
|
|
// Compilation statistics for TurboFan compilations.
|
|
|
|
CompilationStatistics* GetOrCreateTurboStatistics();
|
|
|
|
|
|
|
|
// Prints the gathered compilation statistics, then resets them.
|
|
|
|
void DumpAndResetTurboStatistics();
|
|
|
|
|
2018-07-16 11:52:11 +00:00
|
|
|
// Used to redirect tracing output from {stdout} to a file.
|
|
|
|
CodeTracer* GetCodeTracer();
|
|
|
|
|
2018-05-09 13:48:47 +00:00
|
|
|
// Remove {job} from the list of active compile jobs.
|
2019-01-08 13:58:01 +00:00
|
|
|
std::unique_ptr<AsyncCompileJob> RemoveCompileJob(AsyncCompileJob* job);
|
2018-05-09 13:48:47 +00:00
|
|
|
|
2018-08-01 12:36:38 +00:00
|
|
|
// Returns true if at least one AsyncCompileJob that belongs to the given
|
|
|
|
// Isolate is currently running.
|
|
|
|
bool HasRunningCompileJob(Isolate* isolate);
|
2018-05-09 13:48:47 +00:00
|
|
|
|
2019-07-10 10:56:53 +00:00
|
|
|
// Deletes all AsyncCompileJobs that belong to the given context. All
|
|
|
|
// compilation is aborted, no more callbacks will be triggered. This is used
|
|
|
|
// when a context is disposed, e.g. because of browser navigation.
|
|
|
|
void DeleteCompileJobsOnContext(Handle<Context> context);
|
|
|
|
|
2019-01-08 13:58:01 +00:00
|
|
|
// Deletes all AsyncCompileJobs that belong to the given Isolate. All
|
2018-08-13 09:01:48 +00:00
|
|
|
// compilation is aborted, no more callbacks will be triggered. This is used
|
|
|
|
// for tearing down an isolate, or to clean it up to be reused.
|
2019-01-08 13:58:01 +00:00
|
|
|
void DeleteCompileJobsOnIsolate(Isolate* isolate);
|
2018-03-19 09:22:23 +00:00
|
|
|
|
2018-09-25 11:24:09 +00:00
|
|
|
// Manage the set of Isolates that use this WasmEngine.
|
|
|
|
void AddIsolate(Isolate* isolate);
|
|
|
|
void RemoveIsolate(Isolate* isolate);
|
|
|
|
|
2019-01-25 10:35:37 +00:00
|
|
|
template <typename T, typename... Args>
|
|
|
|
std::unique_ptr<T> NewBackgroundCompileTask(Args&&... args) {
|
2019-09-10 10:12:00 +00:00
|
|
|
return std::make_unique<T>(&background_compile_task_manager_,
|
|
|
|
std::forward<Args>(args)...);
|
2019-01-25 10:35:37 +00:00
|
|
|
}
|
|
|
|
|
2019-12-02 08:44:05 +00:00
|
|
|
// Trigger code logging for the given code objects in all Isolates which have
|
|
|
|
// access to the NativeModule containing this code. This method can be called
|
|
|
|
// from background threads.
|
|
|
|
void LogCode(Vector<WasmCode*>);
|
2019-01-25 10:44:42 +00:00
|
|
|
|
2019-02-06 11:19:03 +00:00
|
|
|
// Enable code logging for the given Isolate. Initially, code logging is
|
|
|
|
// enabled if {WasmCode::ShouldBeLogged(Isolate*)} returns true during
|
|
|
|
// {AddIsolate}.
|
|
|
|
void EnableCodeLogging(Isolate*);
|
|
|
|
|
2019-04-16 11:48:09 +00:00
|
|
|
// This is called from the foreground thread of the Isolate to log all
|
|
|
|
// outstanding code objects (added via {LogCode}).
|
|
|
|
void LogOutstandingCodesForIsolate(Isolate*);
|
|
|
|
|
2019-01-25 10:35:37 +00:00
|
|
|
// Create a new NativeModule. The caller is responsible for its
|
|
|
|
// lifetime. The native module will be given some memory for code,
|
|
|
|
// which will be page size aligned. The size of the initial memory
|
2019-11-07 17:16:45 +00:00
|
|
|
// is determined by {code_size_estimate}. The native module may later request
|
|
|
|
// more memory.
|
|
|
|
// TODO(wasm): isolate is only required here for CompilationState.
|
2019-07-30 14:58:41 +00:00
|
|
|
std::shared_ptr<NativeModule> NewNativeModule(
|
|
|
|
Isolate* isolate, const WasmFeatures& enabled_features,
|
2019-11-07 17:16:45 +00:00
|
|
|
std::shared_ptr<const WasmModule> module, size_t code_size_estimate);
|
2019-01-25 10:35:37 +00:00
|
|
|
|
2020-02-03 12:13:26 +00:00
|
|
|
// Try getting a cached {NativeModule}, or get ownership for its creation.
|
|
|
|
// Return {nullptr} if no {NativeModule} exists for these bytes. In this case,
|
|
|
|
// a {nullopt} entry is added to let other threads know that a {NativeModule}
|
|
|
|
// for these bytes is currently being created. The caller should eventually
|
|
|
|
// call {UpdateNativeModuleCache} to update the entry and wake up other
|
|
|
|
// threads. The {wire_bytes}' underlying array should be valid at least until
|
|
|
|
// the call to {UpdateNativeModuleCache}.
|
2019-12-18 13:41:12 +00:00
|
|
|
std::shared_ptr<NativeModule> MaybeGetNativeModule(
|
2020-02-27 17:45:18 +00:00
|
|
|
ModuleOrigin origin, Vector<const uint8_t> wire_bytes, Isolate* isolate);
|
2019-12-18 13:41:12 +00:00
|
|
|
|
2020-02-03 12:13:26 +00:00
|
|
|
// Replace the temporary {nullopt} with the new native module, or
|
|
|
|
// erase it if any error occurred. Wake up blocked threads waiting for this
|
2019-12-18 13:41:12 +00:00
|
|
|
// module.
|
2020-02-03 12:13:26 +00:00
|
|
|
// To avoid a deadlock on the main thread between synchronous and streaming
|
|
|
|
// compilation, two compilation jobs might compile the same native module at
|
|
|
|
// the same time. In this case the first call to {UpdateNativeModuleCache}
|
|
|
|
// will insert the native module in the cache, and the last call will discard
|
|
|
|
// its {native_module} argument and replace it with the existing entry.
|
|
|
|
// Return true in the former case, and false in the latter.
|
|
|
|
bool UpdateNativeModuleCache(bool error,
|
2020-02-27 17:45:18 +00:00
|
|
|
std::shared_ptr<NativeModule>* native_module,
|
|
|
|
Isolate* isolate);
|
2020-02-03 12:13:26 +00:00
|
|
|
|
|
|
|
// Register this prefix hash for a streaming compilation job.
|
|
|
|
// If the hash is not in the cache yet, the function returns true and the
|
|
|
|
// caller owns the compilation of this module.
|
|
|
|
// Otherwise another compilation job is currently preparing or has already
|
|
|
|
// prepared a module with the same prefix hash. The caller should wait until
|
|
|
|
// the stream is finished and call {MaybeGetNativeModule} to either get the
|
|
|
|
// module from the cache or get ownership for the compilation of these bytes.
|
|
|
|
bool GetStreamingCompilationOwnership(size_t prefix_hash);
|
|
|
|
|
|
|
|
// Remove the prefix hash from the cache when compilation failed. If
|
|
|
|
// compilation succeeded, {UpdateNativeModuleCache} should be called instead.
|
|
|
|
void StreamingCompilationFailed(size_t prefix_hash);
|
2019-12-18 13:41:12 +00:00
|
|
|
|
2019-01-25 10:35:37 +00:00
|
|
|
void FreeNativeModule(NativeModule*);
|
|
|
|
|
2019-03-11 14:51:56 +00:00
|
|
|
// Sample the code size of the given {NativeModule} in all isolates that have
|
|
|
|
// access to it. Call this after top-tier compilation finished.
|
|
|
|
// This will spawn foreground tasks that do *not* keep the NativeModule alive.
|
|
|
|
void SampleTopTierCodeSizeInAllIsolates(const std::shared_ptr<NativeModule>&);
|
|
|
|
|
2019-05-07 09:21:49 +00:00
|
|
|
// Called by each Isolate to report its live code for a GC cycle. First
|
|
|
|
// version reports an externally determined set of live code (might be empty),
|
|
|
|
// second version gets live code from the execution stack of that isolate.
|
|
|
|
void ReportLiveCodeForGC(Isolate*, Vector<WasmCode*>);
|
|
|
|
void ReportLiveCodeFromStackForGC(Isolate*);
|
2019-04-09 13:05:37 +00:00
|
|
|
|
2019-04-09 14:00:09 +00:00
|
|
|
// Add potentially dead code. The occurrence in the set of potentially dead
|
|
|
|
// code counts as a reference, and is decremented on the next GC.
|
|
|
|
// Returns {true} if the code was added to the set of potentially dead code,
|
|
|
|
// {false} if an entry already exists. The ref count is *unchanged* in any
|
|
|
|
// case.
|
|
|
|
V8_WARN_UNUSED_RESULT bool AddPotentiallyDeadCode(WasmCode*);
|
|
|
|
|
2019-05-03 08:50:51 +00:00
|
|
|
// Free dead code.
|
|
|
|
using DeadCodeMap = std::unordered_map<NativeModule*, std::vector<WasmCode*>>;
|
|
|
|
void FreeDeadCode(const DeadCodeMap&);
|
|
|
|
void FreeDeadCodeLocked(const DeadCodeMap&);
|
2019-04-29 08:24:11 +00:00
|
|
|
|
2020-04-09 12:38:56 +00:00
|
|
|
Handle<Script> GetOrCreateScript(Isolate*, NativeModule*,
|
|
|
|
Vector<const char> source_map_url,
|
|
|
|
WireBytesRef name,
|
2020-04-06 12:20:04 +00:00
|
|
|
Vector<const char> source_url = {});
|
|
|
|
|
2018-07-24 15:58:31 +00:00
|
|
|
// Call on process start and exit.
|
|
|
|
static void InitializeOncePerProcess();
|
|
|
|
static void GlobalTearDown();
|
|
|
|
|
2019-10-16 13:28:32 +00:00
|
|
|
// Returns a reference to the WasmEngine shared by the entire process. Try to
|
|
|
|
// use {Isolate::wasm_engine} instead if it is available, which encapsulates
|
|
|
|
// engine lifetime decisions during Isolate bootstrapping.
|
2018-07-24 15:58:31 +00:00
|
|
|
static std::shared_ptr<WasmEngine> GetWasmEngine();
|
|
|
|
|
2017-12-05 00:28:35 +00:00
|
|
|
private:
|
2019-04-09 13:05:37 +00:00
|
|
|
struct CurrentGCInfo;
|
2019-01-25 10:35:37 +00:00
|
|
|
struct IsolateInfo;
|
2019-04-09 14:00:09 +00:00
|
|
|
struct NativeModuleInfo;
|
2019-01-25 10:35:37 +00:00
|
|
|
|
2019-01-08 13:58:01 +00:00
|
|
|
AsyncCompileJob* CreateAsyncCompileJob(
|
2018-08-08 14:54:44 +00:00
|
|
|
Isolate* isolate, const WasmFeatures& enabled,
|
|
|
|
std::unique_ptr<byte[]> bytes_copy, size_t length,
|
2019-04-30 14:04:56 +00:00
|
|
|
Handle<Context> context, const char* api_method_name,
|
2018-08-13 13:35:54 +00:00
|
|
|
std::shared_ptr<CompilationResultResolver> resolver);
|
2018-07-31 16:30:57 +00:00
|
|
|
|
2019-05-17 08:33:10 +00:00
|
|
|
void TriggerGC(int8_t gc_sequence_index);
|
2019-04-09 13:05:37 +00:00
|
|
|
|
2019-05-07 12:26:25 +00:00
|
|
|
// Remove an isolate from the outstanding isolates of the current GC. Returns
|
|
|
|
// true if the isolate was still outstanding, false otherwise. Hold {mutex_}
|
|
|
|
// when calling this method.
|
|
|
|
bool RemoveIsolateFromCurrentGC(Isolate*);
|
|
|
|
|
|
|
|
// Finish a GC if there are no more outstanding isolates. Hold {mutex_} when
|
|
|
|
// calling this method.
|
|
|
|
void PotentiallyFinishCurrentGC();
|
|
|
|
|
2018-09-18 13:05:45 +00:00
|
|
|
WasmCodeManager code_manager_;
|
2018-07-09 08:02:54 +00:00
|
|
|
AccountingAllocator allocator_;
|
2018-01-06 01:33:31 +00:00
|
|
|
|
2019-01-23 11:49:36 +00:00
|
|
|
// Task manager managing all background compile jobs. Before shut down of the
|
|
|
|
// engine, they must all be finished because they access the allocator.
|
|
|
|
CancelableTaskManager background_compile_task_manager_;
|
|
|
|
|
2020-02-17 05:01:29 +00:00
|
|
|
#ifdef V8_ENABLE_WASM_GDB_REMOTE_DEBUGGING
|
|
|
|
// Implements a GDB-remote stub for WebAssembly debugging.
|
|
|
|
std::unique_ptr<gdb_server::GdbServer> gdb_server_;
|
|
|
|
#endif // V8_ENABLE_WASM_GDB_REMOTE_DEBUGGING
|
|
|
|
|
2018-07-16 11:52:11 +00:00
|
|
|
// This mutex protects all information which is mutated concurrently or
|
|
|
|
// fields that are initialized lazily on the first access.
|
|
|
|
base::Mutex mutex_;
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Protected by {mutex_}:
|
|
|
|
|
2019-01-08 13:58:01 +00:00
|
|
|
// We use an AsyncCompileJob as the key for itself so that we can delete the
|
|
|
|
// job from the map when it is finished.
|
2019-02-01 14:57:59 +00:00
|
|
|
std::unordered_map<AsyncCompileJob*, std::unique_ptr<AsyncCompileJob>>
|
|
|
|
async_compile_jobs_;
|
2018-07-31 09:41:11 +00:00
|
|
|
|
2018-07-16 11:52:11 +00:00
|
|
|
std::unique_ptr<CompilationStatistics> compilation_stats_;
|
|
|
|
std::unique_ptr<CodeTracer> code_tracer_;
|
|
|
|
|
2019-01-25 10:35:37 +00:00
|
|
|
// Set of isolates which use this WasmEngine.
|
|
|
|
std::unordered_map<Isolate*, std::unique_ptr<IsolateInfo>> isolates_;
|
|
|
|
|
2019-04-09 14:00:09 +00:00
|
|
|
// Set of native modules managed by this engine.
|
|
|
|
std::unordered_map<NativeModule*, std::unique_ptr<NativeModuleInfo>>
|
|
|
|
native_modules_;
|
|
|
|
|
|
|
|
// Size of code that became dead since the last GC. If this exceeds a certain
|
|
|
|
// threshold, a new GC is triggered.
|
|
|
|
size_t new_potentially_dead_code_size_ = 0;
|
2018-09-25 11:24:09 +00:00
|
|
|
|
2019-04-09 13:05:37 +00:00
|
|
|
// If an engine-wide GC is currently running, this pointer stores information
|
|
|
|
// about that.
|
|
|
|
std::unique_ptr<CurrentGCInfo> current_gc_info_;
|
|
|
|
|
2020-01-21 14:19:18 +00:00
|
|
|
NativeModuleCache native_module_cache_;
|
2019-12-18 13:41:12 +00:00
|
|
|
|
2018-07-16 11:52:11 +00:00
|
|
|
// End of fields protected by {mutex_}.
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2018-01-06 01:33:31 +00:00
|
|
|
DISALLOW_COPY_AND_ASSIGN(WasmEngine);
|
2017-12-05 00:28:35 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace wasm
|
|
|
|
} // namespace internal
|
|
|
|
} // namespace v8
|
|
|
|
|
2018-02-02 12:05:19 +00:00
|
|
|
#endif // V8_WASM_WASM_ENGINE_H_
|