/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
deps/v8/src/wasm/wasm-export-wrapper-cache.h
99 строк
4 KB
Michaël Zasso
deps: update V8 to 14.6.202.33
24 апр 2026, 19:01
Не верифицирован
24 апр 2026, 19:01
f1e0b83
Код
Авторство
О чём код?
// Copyright 2025 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_EXPORT_WRAPPER_CACHE_H_ #define V8_WASM_WASM_EXPORT_WRAPPER_CACHE_H_ #if !V8_ENABLE_WEBASSEMBLY #error This header should only be included if WebAssembly is enabled. #endif // !V8_ENABLE_WEBASSEMBLY #include "src/objects/code.h" #include "src/objects/fixed-array.h" #include "src/objects/internal-index.h" #include "src/wasm/canonical-types.h" #include "src/wasm/value-type.h" namespace v8::internal::wasm { // Provides functionality for caching JS-to-Wasm wrappers in an {Isolate}. // Since these wrappers are JS-compatible {Code} objects living in managed // code space, the cache is also Isolate-specific. It uses a WeakFixedArray // as backing store in order to not leak unused wrappers, and a HashTable- // inspired indexing scheme rather than a dense array layout because we expect // only a minority of canonical type indices to have a corresponding wrapper. // For sandbox purposes, the cache itself is untrusted, but calls through the // wrappers are protected by our regular signature verification scheme. class WasmExportWrapperCache : public AllStatic { public: // DCHECK-fails if a caller attempts to overwrite an existing wrapper. static void Put(Isolate* isolate, CanonicalTypeIndex sig_index, bool receiver_is_first_param, DirectHandle<Code> code); // Returns an empty Tagged if no cache entry was found. static Tagged<CodeWrapper> Get(Isolate* isolate, CanonicalTypeIndex sig_index, bool receiver_is_first_param); #ifdef VERIFY_HEAP static void Verify(Heap* heap); #endif // VERIFY_HEAP // Defined in cctest/test-run-wasm-wrappers.cc to not bloat shipping binaries. static int CountWrappersForTesting(Isolate* isolate); private: static constexpr int kUnused = -1; static constexpr int kNumUsedElementsIndex = 0; static constexpr int kReservedSlots = 1; // Key (Smi), value (Weak<CodeWrapper>). static constexpr int kSlotsPerEntry = 2; static DirectHandle<WeakFixedArray> New(Isolate* isolate, int capacity); static uint32_t Capacity(Tagged<WeakFixedArray> cache); static uint32_t Hash(CanonicalTypeIndex sig_index, bool receiver_is_first_param) { // We expect most signatures to get only one wrapper, so putting the // {receiver_is_first_param} bit at the top should give good distribution // of hash values. // Note: "hash" is a bit of a misnomer here; we require this value to // fully represent the identity of the cached value. See {FirstProbe} for // the step where collisions can and do happen. static_assert(kMaxCanonicalTypes < (1u << 21)); return ((receiver_is_first_param ? 1 : 0) << 21) | sig_index.index; } // Maps the n-th entry to an index in the underlying WeakFixedArray. static int ToArraySlot(InternalIndex entry) { return kReservedSlots + entry.as_int() * kSlotsPerEntry; } static InternalIndex FirstProbe(uint32_t hash, uint32_t capacity) { #if V8_HASHES_COLLIDE if (v8_flags.hashes_collide) hash = base::kCollidingHash; #endif // V8_HASHES_COLLIDE // {New()} ensures that {capacity} is always a power of two. return InternalIndex(hash & (capacity - 1)); } static InternalIndex NextProbe(InternalIndex last, uint32_t number, uint32_t capacity) { // {New()} ensures that {capacity} is always a power of two. return InternalIndex((last.as_uint32() + number) & (capacity - 1)); } V8_WARN_UNUSED_RESULT static Tagged<WeakFixedArray> EnsureCapacity( Isolate* isolate); template <bool entry_may_exist> static void PutInternal(Tagged<WeakFixedArray> cache, uint32_t hash, Tagged<MaybeWeak<Object>> value); }; } // namespace v8::internal::wasm #endif // V8_WASM_WASM_EXPORT_WRAPPER_CACHE_H_