#ifndef V8_HEAP_CPPGC_PROCESS_HEAP_H_
#define V8_HEAP_CPPGC_PROCESS_HEAP_H_
#include <vector>
#include "src/base/macros.h"
#include "src/base/platform/mutex.h"
#include "src/heap/cppgc/trace-event.h"
namespace cppgc::internal {
class HeapBase;
class ProcessGlobalLock final {
public:
enum class Reason {
kForGC,
kForCrossThreadHandleCreation,
};
template <Reason reason>
V8_INLINE static void Lock() {
process_mutex_.Pointer()->Lock();
#if defined(V8_USE_PERFETTO)
switch (reason) {
case Reason::kForGC:
TRACE_EVENT_BEGIN(TRACE_DISABLED_BY_DEFAULT("cppgc"), "AcquiredForGC",
perfetto::NamedTrack("CppGC.ProcessGlobalLock"));
break;
case Reason::kForCrossThreadHandleCreation:
#ifdef DEBUG
TRACE_EVENT_BEGIN(TRACE_DISABLED_BY_DEFAULT("cppgc"),
"AcquiredForCrossThreadHandleCreation",
perfetto::NamedTrack("CppGC.ProcessGlobalLock"));
#endif
break;
}
#endif
}
template <Reason reason>
V8_INLINE static void Unlock() {
#if defined(V8_USE_PERFETTO)
switch (reason) {
case Reason::kForGC:
TRACE_EVENT_END(TRACE_DISABLED_BY_DEFAULT("cppgc"),
perfetto::NamedTrack("CppGC.ProcessGlobalLock"));
break;
case Reason::kForCrossThreadHandleCreation:
#ifdef DEBUG
TRACE_EVENT_END(TRACE_DISABLED_BY_DEFAULT("cppgc"),
perfetto::NamedTrack("CppGC.ProcessGlobalLock"));
#endif
break;
}
#endif
process_mutex_.Pointer()->Unlock();
}
V8_INLINE static void AssertHeld() { process_mutex_.Pointer()->AssertHeld(); }
private:
static v8::base::LazyMutex process_mutex_;
};
class V8_EXPORT_PRIVATE HeapRegistry final {
public:
using Storage = std::vector<HeapBase*>;
class Subscription final {
public:
inline explicit Subscription(HeapBase&);
inline ~Subscription();
private:
HeapBase& heap_;
};
static HeapBase* TryFromManagedPointer(const void* needle);
static const Storage& GetRegisteredHeapsForTesting();
private:
static void RegisterHeap(HeapBase&);
static void UnregisterHeap(HeapBase&);
};
HeapRegistry::Subscription::Subscription(HeapBase& heap) : heap_(heap) {
HeapRegistry::RegisterHeap(heap_);
}
HeapRegistry::Subscription::~Subscription() {
HeapRegistry::UnregisterHeap(heap_);
}
}
#endif