blob: aff29ddb7f37b0301c360eac6b785715562da6ed [file] [log] [blame]
// 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.
#ifndef V8_WASM_WASM_IMPORT_WRAPPER_CACHE_H_
#define V8_WASM_WASM_IMPORT_WRAPPER_CACHE_H_
#if !V8_ENABLE_WEBASSEMBLY
#error This header should only be included if WebAssembly is enabled.
#endif // !V8_ENABLE_WEBASSEMBLY
#include <unordered_map>
#include "src/base/platform/mutex.h"
#include "src/wasm/module-instantiate.h"
#include "src/wasm/wasm-code-manager.h"
namespace v8::internal::wasm {
class WasmCode;
class WasmEngine;
// Implements a cache for import wrappers.
class WasmImportWrapperCache {
public:
struct CacheKey {
CacheKey(ImportCallKind kind, CanonicalTypeIndex type_index,
int expected_arity, Suspend suspend)
: kind(kind),
type_index(type_index),
expected_arity(expected_arity),
suspend(suspend) {}
bool operator==(const CacheKey& rhs) const = default;
ImportCallKind kind;
CanonicalTypeIndex type_index;
int expected_arity;
Suspend suspend;
};
class CacheKeyHash {
public:
size_t operator()(const CacheKey& key) const {
return base::hash_combine(static_cast<uint8_t>(key.kind),
key.type_index.index, key.expected_arity);
}
};
// Helper class to modify the cache under a lock.
class V8_NODISCARD ModificationScope {
public:
explicit ModificationScope(WasmImportWrapperCache* cache)
: cache_(cache), guard_(&cache->mutex_) {}
V8_EXPORT_PRIVATE WasmCode* operator[](const CacheKey& key);
WasmCode* AddWrapper(const CacheKey& key, WasmCompilationResult result,
WasmCode::Kind kind, uint64_t signature_hash);
private:
WasmImportWrapperCache* const cache_;
base::MutexGuard guard_;
};
WasmImportWrapperCache() = default;
~WasmImportWrapperCache() = default;
void LazyInitialize(Isolate* triggering_isolate);
void Free(std::vector<WasmCode*>& wrappers);
// Thread-safe. Returns nullptr if the key doesn't exist in the map.
// Adds the returned code to the surrounding WasmCodeRefScope.
V8_EXPORT_PRIVATE WasmCode* MaybeGet(ImportCallKind kind,
CanonicalTypeIndex type_index,
int expected_arity,
Suspend suspend) const;
WasmCode* Lookup(Address pc) const;
void LogForIsolate(Isolate* isolate);
size_t EstimateCurrentMemoryConsumption() const;
// Returns nullptr if {call_target} doesn't belong to a known wrapper.
V8_EXPORT_PRIVATE WasmCode* FindWrapper(WasmCodePointer call_target);
WasmCode* CompileWasmImportCallWrapper(Isolate* isolate, ImportCallKind kind,
const CanonicalSig* sig,
CanonicalTypeIndex sig_index,
bool source_positions,
int expected_arity, Suspend suspend);
private:
std::unique_ptr<WasmCodeAllocator> code_allocator_;
mutable base::Mutex mutex_;
std::unordered_map<CacheKey, WasmCode*, CacheKeyHash> entry_map_;
// Lookup support. The map key is the instruction start address.
std::map<Address, WasmCode*> codes_;
};
} // namespace v8::internal::wasm
#endif // V8_WASM_WASM_IMPORT_WRAPPER_CACHE_H_