/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
deps/v8/src/wasm/wasm-code-pointer-table.cc
151 строка
5 KB
Michaël Zasso
deps: update V8 to 13.6.233.8
02 май 2025, 16:06
Не верифицирован
02 май 2025, 16:06
918fe04
Код
Авторство
О чём код?
// Copyright 2024 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 "src/wasm/wasm-code-pointer-table.h" #include "src/sandbox/external-entity-table-inl.h" #include "src/wasm/wasm-code-pointer-table-inl.h" namespace v8::internal::wasm { void WasmCodePointerTable::Initialize() { Base::Initialize(); } void WasmCodePointerTable::TearDown() { FreeNativeFunctionHandles(); SweepSegments(0); DCHECK(freelist_head_.load().is_empty()); Base::TearDown(); } DEFINE_LAZY_LEAKY_OBJECT_GETTER(WasmCodePointerTable, GetProcessWideWasmCodePointerTable) std::vector<uint32_t> WasmCodePointerTable::FreelistToVector( WasmCodePointerTable::FreelistHead freelist) { DCHECK(!freelist.is_empty()); std::vector<uint32_t> entries(freelist.length()); uint32_t entry = freelist.next(); for (uint32_t i = 0; i < freelist.length(); i++) { entries[i] = entry; entry = at(entry).GetNextFreelistEntryIndex(); } return entries; } WasmCodePointerTable::FreelistHead WasmCodePointerTable::VectorToFreelist( std::vector<uint32_t> entries) { if (entries.empty()) { return FreelistHead(); } FreelistHead new_freelist = FreelistHead(entries[0], static_cast<uint32_t>(entries.size())); WriteScope write_scope("Freelist write"); for (size_t i = 0; i < entries.size() - 1; i++) { uint32_t entry = entries[i]; uint32_t next_entry = entries[i + 1]; at(entry).MakeFreelistEntry(next_entry); } return new_freelist; } void WasmCodePointerTable::SweepSegments(size_t threshold) { if (threshold < kEntriesPerSegment) { // We need at least a whole empty segment if we want to sweep anything. threshold = kEntriesPerSegment; } FreelistHead initial_head, empty_freelist; do { initial_head = ReadFreelistHead(); if (initial_head.length() < threshold) { return; } // Try to unlink the freelist. If it fails, try again. } while ( !freelist_head_.compare_exchange_strong(initial_head, empty_freelist)); // We unlinked the whole free list, so we have exclusive access to it at // this point. // Now search for empty segments (== all entries are freelist entries) and // unlink them. std::vector<uint32_t> freelist_entries = FreelistToVector(initial_head); std::sort(freelist_entries.begin(), freelist_entries.end()); // The minimum threshold is kEntriesPerSegment. DCHECK_GE(freelist_entries.size(), kEntriesPerSegment); // We iterate over all freelist entries and copy them over to a new vector, // while skipping and unmapping empty segments. std::vector<uint32_t> new_freelist_entries; for (size_t i = 0; i < freelist_entries.size(); i++) { uint32_t entry = freelist_entries[i]; Segment segment = Segment::Containing(entry); if (segment.first_entry() == entry && i + kEntriesPerSegment - 1 < freelist_entries.size()) { uint32_t last_entry = freelist_entries[i + kEntriesPerSegment - 1]; if (segment.last_entry() == last_entry) { // The whole segment is empty. Delete the segment and skip all // entries; FreeTableSegment(segment); i += kEntriesPerSegment - 1; continue; } } new_freelist_entries.push_back(entry); } DCHECK_LE(new_freelist_entries.size(), freelist_entries.size()); DCHECK(IsAligned(freelist_entries.size() - new_freelist_entries.size(), kEntriesPerSegment)); if (new_freelist_entries.empty()) { return; } // Finally, add the new freelist back. uint32_t last_element = new_freelist_entries.back(); FreelistHead new_freelist = VectorToFreelist(new_freelist_entries); LinkFreelist(new_freelist, last_element); } WasmCodePointer WasmCodePointerTable::GetOrCreateHandleForNativeFunction( Address addr) { base::MutexGuard guard(&native_function_map_mutex_); auto it = native_function_map_.find(addr); if (it != native_function_map_.end()) { return it->second; } WasmCodePointer handle = AllocateAndInitializeEntry(addr, -1); native_function_map_.insert({addr, handle}); return handle; } bool WasmCodePointerTable::EntrypointEqualTo(WasmCodePointer index, Address address) { return at(index.value()).GetEntrypointWithoutSignatureCheck() == address; } void WasmCodePointerTable::FreeNativeFunctionHandles() { base::MutexGuard guard(&native_function_map_mutex_); for (auto const& [address, handle] : native_function_map_) { FreeEntry(handle); } native_function_map_.clear(); } } // namespace v8::internal::wasm