1 // Copyright 2018 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #if !V8_ENABLE_WEBASSEMBLY 6 #error This header should only be included if WebAssembly is enabled. 7 #endif // !V8_ENABLE_WEBASSEMBLY 8 9 #ifndef V8_WASM_WASM_IMPORT_WRAPPER_CACHE_H_ 10 #define V8_WASM_WASM_IMPORT_WRAPPER_CACHE_H_ 11 12 #include "src/base/platform/mutex.h" 13 #include "src/compiler/wasm-compiler.h" 14 15 namespace v8 { 16 namespace internal { 17 18 class Counters; 19 20 namespace wasm { 21 22 class WasmCode; 23 class WasmEngine; 24 25 using FunctionSig = Signature<ValueType>; 26 27 // Implements a cache for import wrappers. 28 class WasmImportWrapperCache { 29 public: 30 struct CacheKey { CacheKeyCacheKey31 CacheKey(const compiler::WasmImportCallKind& _kind, const FunctionSig* _sig, 32 int _expected_arity, Suspend _suspend) 33 : kind(_kind), 34 signature(_sig), 35 expected_arity(_expected_arity == kDontAdaptArgumentsSentinel 36 ? 0 37 : _expected_arity), 38 suspend(_suspend) {} 39 40 bool operator==(const CacheKey& rhs) const { 41 return kind == rhs.kind && signature == rhs.signature && 42 expected_arity == rhs.expected_arity && suspend == rhs.suspend; 43 } 44 45 compiler::WasmImportCallKind kind; 46 const FunctionSig* signature; 47 int expected_arity; 48 Suspend suspend; 49 }; 50 51 class CacheKeyHash { 52 public: operator()53 size_t operator()(const CacheKey& key) const { 54 return base::hash_combine(static_cast<uint8_t>(key.kind), key.signature, 55 key.expected_arity); 56 } 57 }; 58 59 // Helper class to modify the cache under a lock. 60 class V8_NODISCARD ModificationScope { 61 public: ModificationScope(WasmImportWrapperCache * cache)62 explicit ModificationScope(WasmImportWrapperCache* cache) 63 : cache_(cache), guard_(&cache->mutex_) {} 64 65 V8_EXPORT_PRIVATE WasmCode*& operator[](const CacheKey& key); 66 67 private: 68 WasmImportWrapperCache* const cache_; 69 base::MutexGuard guard_; 70 }; 71 72 // Not thread-safe, use ModificationScope to get exclusive write access to the 73 // cache. 74 V8_EXPORT_PRIVATE WasmCode*& operator[](const CacheKey& key); 75 76 // Thread-safe. Assumes the key exists in the map. 77 V8_EXPORT_PRIVATE WasmCode* Get(compiler::WasmImportCallKind kind, 78 const FunctionSig* sig, int expected_arity, 79 Suspend suspend) const; 80 // Thread-safe. Returns nullptr if the key doesn't exist in the map. 81 WasmCode* MaybeGet(compiler::WasmImportCallKind kind, const FunctionSig* sig, 82 int expected_arity, Suspend suspend) const; 83 84 ~WasmImportWrapperCache(); 85 86 private: 87 mutable base::Mutex mutex_; 88 std::unordered_map<CacheKey, WasmCode*, CacheKeyHash> entry_map_; 89 }; 90 91 } // namespace wasm 92 } // namespace internal 93 } // namespace v8 94 95 #endif // V8_WASM_WASM_IMPORT_WRAPPER_CACHE_H_ 96