1 // Copyright 2020 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 #include "src/heap/cppgc/process-heap.h" 6 7 #include <algorithm> 8 #include <vector> 9 10 #include "src/base/lazy-instance.h" 11 #include "src/base/logging.h" 12 #include "src/base/platform/mutex.h" 13 #include "src/heap/cppgc/heap-base.h" 14 #include "src/heap/cppgc/page-memory.h" 15 16 namespace cppgc { 17 namespace internal { 18 19 v8::base::LazyMutex g_process_mutex = LAZY_MUTEX_INITIALIZER; 20 21 namespace { 22 23 v8::base::LazyMutex g_heap_registry_mutex = LAZY_MUTEX_INITIALIZER; 24 GetHeapRegistryStorage()25HeapRegistry::Storage& GetHeapRegistryStorage() { 26 static v8::base::LazyInstance<HeapRegistry::Storage>::type heap_registry = 27 LAZY_INSTANCE_INITIALIZER; 28 return *heap_registry.Pointer(); 29 } 30 31 } // namespace 32 33 // static RegisterHeap(HeapBase & heap)34void HeapRegistry::RegisterHeap(HeapBase& heap) { 35 v8::base::MutexGuard guard(g_heap_registry_mutex.Pointer()); 36 37 auto& storage = GetHeapRegistryStorage(); 38 DCHECK_EQ(storage.end(), std::find(storage.begin(), storage.end(), &heap)); 39 storage.push_back(&heap); 40 } 41 42 // static UnregisterHeap(HeapBase & heap)43void HeapRegistry::UnregisterHeap(HeapBase& heap) { 44 v8::base::MutexGuard guard(g_heap_registry_mutex.Pointer()); 45 46 // HeapRegistry requires access to PageBackend which means it must still 47 // be present by the time a heap is removed from the registry. 48 DCHECK_NOT_NULL(heap.page_backend()); 49 50 auto& storage = GetHeapRegistryStorage(); 51 const auto pos = std::find(storage.begin(), storage.end(), &heap); 52 DCHECK_NE(storage.end(), pos); 53 storage.erase(pos); 54 } 55 56 // static TryFromManagedPointer(const void * needle)57HeapBase* HeapRegistry::TryFromManagedPointer(const void* needle) { 58 v8::base::MutexGuard guard(g_heap_registry_mutex.Pointer()); 59 60 for (auto* heap : GetHeapRegistryStorage()) { 61 const auto address = 62 heap->page_backend()->Lookup(reinterpret_cast<ConstAddress>(needle)); 63 if (address) return heap; 64 } 65 return nullptr; 66 } 67 68 // static GetRegisteredHeapsForTesting()69const HeapRegistry::Storage& HeapRegistry::GetRegisteredHeapsForTesting() { 70 return GetHeapRegistryStorage(); 71 } 72 73 } // namespace internal 74 } // namespace cppgc 75