#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_H_
#include "base/compiler_specific.h"
#include "base/functional/callback_forward.h"
#include "build/build_config.h"
#include "third_party/blink/renderer/platform/bindings/active_script_wrappable_manager.h"
#include "third_party/blink/renderer/platform/heap/forward.h"
#include "third_party/blink/renderer/platform/heap/thread_state_storage.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/threading.h"
#include "v8/include/cppgc/common.h"
#include "v8/include/cppgc/heap-consistency.h"
#include "v8/include/v8-callbacks.h"
#include "v8/include/v8-cppgc.h"
#include "v8/include/v8-profiler.h"
namespace v8 {
class CppHeap;
class EmbedderRootsHandler;
}
namespace blink {
class ActiveScriptWrappableManager;
class BlinkGCMemoryDumpProvider;
class PLATFORM_EXPORT ThreadState final {
public:
class GCForbiddenScope;
class NoAllocationScope;
using StackState = cppgc::EmbedderStackState;
using DevToolsCountersCallback = void (*)(v8::Isolate*);
ALWAYS_INLINE static ThreadState* Current() {
return &ThreadStateStorage::Current()->thread_state();
}
static ThreadState* AttachMainThread();
static ThreadState* AttachCurrentThread();
static void DetachCurrentThread();
void AttachToIsolate(v8::Isolate* isolate, DevToolsCountersCallback);
void DetachFromIsolate();
std::unique_ptr<v8::CppHeap> ReleaseCppHeap();
ALWAYS_INLINE cppgc::HeapHandle& heap_handle() const { return heap_handle_; }
ALWAYS_INLINE v8::CppHeap& cpp_heap() const { return *cpp_heap_; }
bool IsMainThread() const {
return this ==
&ThreadStateStorage::MainThreadStateStorage()->thread_state();
}
bool IsCreationThread() const { return thread_id_ == CurrentThread(); }
bool IsAllocationAllowed() const {
return cppgc::subtle::DisallowGarbageCollectionScope::
IsGarbageCollectionAllowed(cpp_heap().GetHeapHandle());
}
void CollectNodeAndCssStatistics(
base::OnceCallback<void(size_t allocated_node_bytes,
size_t allocated_css_bytes)>);
bool IsIncrementalMarking() const;
bool IsSweepingOnOwningThread() const;
bool IsTakingHeapSnapshot() const;
const char* CopyNameForHeapSnapshot(const char* name) const;
ActiveScriptWrappableManager* GetActiveScriptWrappableManager() {
return active_script_wrappable_manager_.Get();
}
static ThreadState* AttachMainThreadForTesting(v8::Platform*);
static ThreadState* AttachCurrentThreadForTesting(v8::Platform*);
void CollectAllGarbageForTesting(
StackState stack_state = StackState::kNoHeapPointers);
void CollectGarbageInYoungGenerationForTesting(
StackState stack_state = StackState::kNoHeapPointers);
void EnableDetachedGarbageCollectionsForTesting();
void RecoverCppHeapAfterIsolateTearDownForTesting();
void TakeHeapSnapshotForTesting(const char* filename) const;
private:
static void RecoverCppHeapTrampoline(std::unique_ptr<v8::CppHeap>);
static void GcPrologue(v8::Isolate*, v8::GCType, v8::GCCallbackFlags);
static void GcEpilogue(v8::Isolate*, v8::GCType, v8::GCCallbackFlags);
explicit ThreadState(v8::Platform*);
~ThreadState();
void RecoverCppHeap(std::unique_ptr<v8::CppHeap>);
std::unique_ptr<v8::CppHeap> owning_cpp_heap_;
v8::CppHeap* cpp_heap_;
std::unique_ptr<v8::EmbedderRootsHandler> embedder_roots_handler_;
cppgc::HeapHandle& heap_handle_;
v8::Isolate* isolate_ = nullptr;
base::PlatformThreadId thread_id_;
size_t gc_callback_depth_ = 0;
Persistent<ActiveScriptWrappableManager> active_script_wrappable_manager_;
DevToolsCountersCallback dev_tools_counters_callback_;
friend class BlinkGCMemoryDumpProvider;
};
}
#endif