heap: Introduce ThreadStateStorage
Splits off the storage parts of ThreadState to allow only including that in garbage_collected.h which is what users need to define their GCed objects. Follow up CLs will remove thread_state.h from anything that doesn't need to manually invoke GC or set up the heaps. Bug: chromium:1269227 Change-Id: I191b6fcbf7691ba600ca9567fc741005d6694bad Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3298109 Reviewed-by: Anton Bikineev <bikineev@chromium.org> Reviewed-by: Kentaro Hara <haraken@chromium.org> Commit-Queue: Michael Lippautz <mlippautz@chromium.org> Cr-Commit-Position: refs/heads/main@{#944879}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
190f2afe4f
commit
b462ff997a
third_party/blink/renderer
@@ -77,6 +77,7 @@
|
|||||||
#include "third_party/blink/renderer/platform/bindings/v8_per_context_data.h"
|
#include "third_party/blink/renderer/platform/bindings/v8_per_context_data.h"
|
||||||
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
|
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
|
||||||
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
|
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
|
||||||
|
#include "third_party/blink/renderer/platform/heap/thread_state_storage.h"
|
||||||
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
|
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
|
||||||
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
|
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
|
||||||
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
|
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
|
||||||
@@ -776,7 +777,7 @@ void V8Initializer::InitializeMainThread(
|
|||||||
// ThreadState::isolate_ needs to be set before setting the EmbedderHeapTracer
|
// ThreadState::isolate_ needs to be set before setting the EmbedderHeapTracer
|
||||||
// as setting the tracer indicates that a V8 garbage collection should trace
|
// as setting the tracer indicates that a V8 garbage collection should trace
|
||||||
// over to Blink.
|
// over to Blink.
|
||||||
DCHECK(ThreadState::MainThreadState());
|
DCHECK(ThreadStateStorage::MainThreadStateStorage());
|
||||||
|
|
||||||
InitializeV8Common(isolate);
|
InitializeV8Common(isolate);
|
||||||
|
|
||||||
|
@@ -52,6 +52,8 @@ blink_platform_sources("heap") {
|
|||||||
"thread_state.cc",
|
"thread_state.cc",
|
||||||
"thread_state.h",
|
"thread_state.h",
|
||||||
"thread_state_scopes.h",
|
"thread_state_scopes.h",
|
||||||
|
"thread_state_storage.cc",
|
||||||
|
"thread_state_storage.h",
|
||||||
"trace_traits.h",
|
"trace_traits.h",
|
||||||
"visitor.h",
|
"visitor.h",
|
||||||
"write_barrier.h",
|
"write_barrier.h",
|
||||||
|
@@ -5,11 +5,15 @@
|
|||||||
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_GARBAGE_COLLECTED_H_
|
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_GARBAGE_COLLECTED_H_
|
||||||
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_GARBAGE_COLLECTED_H_
|
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_GARBAGE_COLLECTED_H_
|
||||||
|
|
||||||
#include "third_party/blink/renderer/platform/heap/thread_state.h"
|
#include "third_party/blink/renderer/platform/heap/thread_state_storage.h"
|
||||||
#include "v8/include/cppgc/allocation.h"
|
#include "v8/include/cppgc/allocation.h"
|
||||||
#include "v8/include/cppgc/garbage-collected.h"
|
#include "v8/include/cppgc/garbage-collected.h"
|
||||||
#include "v8/include/cppgc/type-traits.h"
|
#include "v8/include/cppgc/type-traits.h"
|
||||||
|
|
||||||
|
namespace cppgc {
|
||||||
|
class Visitor;
|
||||||
|
} // namespace cppgc
|
||||||
|
|
||||||
namespace blink {
|
namespace blink {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@@ -17,12 +21,14 @@ using GarbageCollected = cppgc::GarbageCollected<T>;
|
|||||||
|
|
||||||
using GarbageCollectedMixin = cppgc::GarbageCollectedMixin;
|
using GarbageCollectedMixin = cppgc::GarbageCollectedMixin;
|
||||||
|
|
||||||
|
using Visitor = cppgc::Visitor;
|
||||||
|
|
||||||
// Default MakeGarbageCollected: Constructs an instance of T, which is a garbage
|
// Default MakeGarbageCollected: Constructs an instance of T, which is a garbage
|
||||||
// collected type.
|
// collected type.
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
T* MakeGarbageCollected(Args&&... args) {
|
T* MakeGarbageCollected(Args&&... args) {
|
||||||
return cppgc::MakeGarbageCollected<T>(
|
return cppgc::MakeGarbageCollected<T>(
|
||||||
ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState()
|
ThreadStateStorageFor<ThreadingTrait<T>::kAffinity>::GetState()
|
||||||
->allocation_handle(),
|
->allocation_handle(),
|
||||||
std::forward<Args>(args)...);
|
std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
@@ -34,7 +40,7 @@ using AdditionalBytes = cppgc::AdditionalBytes;
|
|||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
T* MakeGarbageCollected(AdditionalBytes additional_bytes, Args&&... args) {
|
T* MakeGarbageCollected(AdditionalBytes additional_bytes, Args&&... args) {
|
||||||
return cppgc::MakeGarbageCollected<T>(
|
return cppgc::MakeGarbageCollected<T>(
|
||||||
ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState()
|
ThreadStateStorageFor<ThreadingTrait<T>::kAffinity>::GetState()
|
||||||
->allocation_handle(),
|
->allocation_handle(),
|
||||||
std::forward<AdditionalBytes>(additional_bytes),
|
std::forward<AdditionalBytes>(additional_bytes),
|
||||||
std::forward<Args>(args)...);
|
std::forward<Args>(args)...);
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h"
|
#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h"
|
||||||
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
|
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
|
||||||
#include "third_party/blink/renderer/platform/heap/thread_state.h"
|
#include "third_party/blink/renderer/platform/heap/thread_state.h"
|
||||||
|
#include "third_party/blink/renderer/platform/heap/thread_state_storage.h"
|
||||||
#include "third_party/blink/renderer/platform/heap/visitor.h"
|
#include "third_party/blink/renderer/platform/heap/visitor.h"
|
||||||
#include "third_party/blink/renderer/platform/heap/write_barrier.h"
|
#include "third_party/blink/renderer/platform/heap/write_barrier.h"
|
||||||
#include "third_party/blink/renderer/platform/platform_export.h"
|
#include "third_party/blink/renderer/platform/platform_export.h"
|
||||||
@@ -60,7 +61,7 @@ class PLATFORM_EXPORT HeapAllocator {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
HeapVectorBacking<T>::FromArray(array)->Free(
|
HeapVectorBacking<T>::FromArray(array)->Free(
|
||||||
ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState()
|
ThreadStateStorageFor<ThreadingTrait<T>::kAffinity>::GetState()
|
||||||
->heap_handle());
|
->heap_handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +97,7 @@ class PLATFORM_EXPORT HeapAllocator {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
HeapHashTableBacking<HashTable>::FromArray(array)->Free(
|
HeapHashTableBacking<HashTable>::FromArray(array)->Free(
|
||||||
ThreadStateFor<ThreadingTrait<
|
ThreadStateStorageFor<ThreadingTrait<
|
||||||
HeapHashTableBacking<HashTable>>::kAffinity>::GetState()
|
HeapHashTableBacking<HashTable>>::kAffinity>::GetState()
|
||||||
->heap_handle());
|
->heap_handle());
|
||||||
}
|
}
|
||||||
@@ -109,11 +110,12 @@ class PLATFORM_EXPORT HeapAllocator {
|
|||||||
|
|
||||||
static bool IsAllocationAllowed() {
|
static bool IsAllocationAllowed() {
|
||||||
return cppgc::subtle::DisallowGarbageCollectionScope::
|
return cppgc::subtle::DisallowGarbageCollectionScope::
|
||||||
IsGarbageCollectionAllowed(ThreadState::Current()->heap_handle());
|
IsGarbageCollectionAllowed(
|
||||||
|
ThreadStateStorage::Current()->heap_handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsIncrementalMarking() {
|
static bool IsIncrementalMarking() {
|
||||||
auto& heap_handle = ThreadState::Current()->heap_handle();
|
auto& heap_handle = ThreadStateStorage::Current()->heap_handle();
|
||||||
return cppgc::subtle::HeapState::IsMarking(heap_handle) &&
|
return cppgc::subtle::HeapState::IsMarking(heap_handle) &&
|
||||||
!cppgc::subtle::HeapState::IsInAtomicPause(heap_handle);
|
!cppgc::subtle::HeapState::IsInAtomicPause(heap_handle);
|
||||||
}
|
}
|
||||||
@@ -156,7 +158,7 @@ class PLATFORM_EXPORT HeapAllocator {
|
|||||||
// garbage collected type but may be kept inline.
|
// garbage collected type but may be kept inline.
|
||||||
switch (HeapConsistency::GetWriteBarrierType(
|
switch (HeapConsistency::GetWriteBarrierType(
|
||||||
slot_in_backing, params, []() -> cppgc::HeapHandle& {
|
slot_in_backing, params, []() -> cppgc::HeapHandle& {
|
||||||
return ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState()
|
return ThreadStateStorageFor<ThreadingTrait<T>::kAffinity>::GetState()
|
||||||
->heap_handle();
|
->heap_handle();
|
||||||
})) {
|
})) {
|
||||||
case HeapConsistency::WriteBarrierType::kMarking:
|
case HeapConsistency::WriteBarrierType::kMarking:
|
||||||
@@ -181,7 +183,7 @@ class PLATFORM_EXPORT HeapAllocator {
|
|||||||
// garbage collected type but may be kept inline.
|
// garbage collected type but may be kept inline.
|
||||||
switch (HeapConsistency::GetWriteBarrierType(
|
switch (HeapConsistency::GetWriteBarrierType(
|
||||||
first_element, params, []() -> cppgc::HeapHandle& {
|
first_element, params, []() -> cppgc::HeapHandle& {
|
||||||
return ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState()
|
return ThreadStateStorageFor<ThreadingTrait<T>::kAffinity>::GetState()
|
||||||
->heap_handle();
|
->heap_handle();
|
||||||
})) {
|
})) {
|
||||||
case HeapConsistency::WriteBarrierType::kMarking:
|
case HeapConsistency::WriteBarrierType::kMarking:
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
|
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
|
||||||
#include "third_party/blink/renderer/platform/bindings/wrapper_type_info.h"
|
#include "third_party/blink/renderer/platform/bindings/wrapper_type_info.h"
|
||||||
#include "third_party/blink/renderer/platform/heap/custom_spaces.h"
|
#include "third_party/blink/renderer/platform/heap/custom_spaces.h"
|
||||||
|
#include "third_party/blink/renderer/platform/heap/thread_state_storage.h"
|
||||||
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
|
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
|
||||||
#include "third_party/blink/renderer/platform/wtf/vector.h"
|
#include "third_party/blink/renderer/platform/wtf/vector.h"
|
||||||
#include "v8/include/cppgc/heap-consistency.h"
|
#include "v8/include/cppgc/heap-consistency.h"
|
||||||
@@ -86,39 +87,41 @@ class BlinkRootsHandler final : public v8::EmbedderRootsHandler {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
thread_local ThreadState* g_thread_specific_ CONSTINIT
|
|
||||||
__attribute__((tls_model(BLINK_HEAP_THREAD_LOCAL_MODEL))) = nullptr;
|
|
||||||
|
|
||||||
// static
|
|
||||||
alignas(ThreadState) uint8_t
|
|
||||||
ThreadState::main_thread_state_storage_[sizeof(ThreadState)];
|
|
||||||
|
|
||||||
BLINK_HEAP_DEFINE_THREAD_LOCAL_GETTER(ThreadState::Current,
|
|
||||||
ThreadState*,
|
|
||||||
g_thread_specific_)
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
ThreadState* ThreadState::AttachMainThread() {
|
ThreadState* ThreadState::AttachMainThread() {
|
||||||
return new (main_thread_state_storage_) ThreadState(gin::V8Platform::Get());
|
auto* thread_state = new ThreadState(gin::V8Platform::Get());
|
||||||
|
ThreadStateStorage::CreateMain(*thread_state,
|
||||||
|
thread_state->cpp_heap().GetAllocationHandle(),
|
||||||
|
thread_state->cpp_heap().GetHeapHandle());
|
||||||
|
return thread_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
ThreadState* ThreadState::AttachMainThreadForTesting(v8::Platform* platform) {
|
ThreadState* ThreadState::AttachMainThreadForTesting(v8::Platform* platform) {
|
||||||
ThreadState* thread_state =
|
auto* thread_state = new ThreadState(platform);
|
||||||
new (main_thread_state_storage_) ThreadState(platform);
|
ThreadStateStorage::CreateMain(*thread_state,
|
||||||
|
thread_state->cpp_heap().GetAllocationHandle(),
|
||||||
|
thread_state->cpp_heap().GetHeapHandle());
|
||||||
thread_state->EnableDetachedGarbageCollectionsForTesting();
|
thread_state->EnableDetachedGarbageCollectionsForTesting();
|
||||||
return thread_state;
|
return thread_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
ThreadState* ThreadState::AttachCurrentThread() {
|
ThreadState* ThreadState::AttachCurrentThread() {
|
||||||
return new ThreadState(gin::V8Platform::Get());
|
auto* thread_state = new ThreadState(gin::V8Platform::Get());
|
||||||
|
ThreadStateStorage::Create(*thread_state,
|
||||||
|
thread_state->cpp_heap().GetAllocationHandle(),
|
||||||
|
thread_state->cpp_heap().GetHeapHandle());
|
||||||
|
return thread_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
ThreadState* ThreadState::AttachCurrentThreadForTesting(
|
ThreadState* ThreadState::AttachCurrentThreadForTesting(
|
||||||
v8::Platform* platform) {
|
v8::Platform* platform) {
|
||||||
ThreadState* thread_state = new ThreadState(platform);
|
ThreadState* thread_state = new ThreadState(platform);
|
||||||
|
ThreadStateStorage::Create(*thread_state,
|
||||||
|
thread_state->cpp_heap().GetAllocationHandle(),
|
||||||
|
thread_state->cpp_heap().GetHeapHandle());
|
||||||
thread_state->EnableDetachedGarbageCollectionsForTesting();
|
thread_state->EnableDetachedGarbageCollectionsForTesting();
|
||||||
return thread_state;
|
return thread_state;
|
||||||
}
|
}
|
||||||
@@ -153,16 +156,13 @@ ThreadState::ThreadState(v8::Platform* platform)
|
|||||||
v8::WrapperDescriptor(kV8DOMWrapperTypeIndex,
|
v8::WrapperDescriptor(kV8DOMWrapperTypeIndex,
|
||||||
kV8DOMWrapperObjectIndex,
|
kV8DOMWrapperObjectIndex,
|
||||||
gin::GinEmbedder::kEmbedderBlink)})),
|
gin::GinEmbedder::kEmbedderBlink)})),
|
||||||
allocation_handle_(cpp_heap_->GetAllocationHandle()),
|
|
||||||
heap_handle_(cpp_heap_->GetHeapHandle()),
|
heap_handle_(cpp_heap_->GetHeapHandle()),
|
||||||
thread_id_(CurrentThread()) {
|
thread_id_(CurrentThread()) {}
|
||||||
g_thread_specific_ = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreadState::~ThreadState() {
|
ThreadState::~ThreadState() {
|
||||||
DCHECK(!IsMainThread());
|
|
||||||
DCHECK(IsCreationThread());
|
DCHECK(IsCreationThread());
|
||||||
cpp_heap_->Terminate();
|
cpp_heap_->Terminate();
|
||||||
|
delete ThreadStateStorage::Current();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadState::SafePoint(StackState stack_state) {
|
void ThreadState::SafePoint(StackState stack_state) {
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
#include "base/compiler_specific.h"
|
#include "base/compiler_specific.h"
|
||||||
#include "build/build_config.h"
|
#include "build/build_config.h"
|
||||||
#include "third_party/blink/renderer/platform/heap/forward.h"
|
#include "third_party/blink/renderer/platform/heap/forward.h"
|
||||||
#include "third_party/blink/renderer/platform/heap/thread_local.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/allocator/allocator.h"
|
||||||
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
|
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
|
||||||
#include "third_party/blink/renderer/platform/wtf/threading.h"
|
#include "third_party/blink/renderer/platform/wtf/threading.h"
|
||||||
@@ -22,10 +22,6 @@ namespace v8 {
|
|||||||
class CppHeap;
|
class CppHeap;
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
|
||||||
namespace cppgc {
|
|
||||||
class AllocationHandle;
|
|
||||||
} // namespace cppgc
|
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
class EmbedderGraph;
|
class EmbedderGraph;
|
||||||
class EmbedderRootsHandler;
|
class EmbedderRootsHandler;
|
||||||
@@ -33,38 +29,10 @@ class EmbedderRootsHandler;
|
|||||||
|
|
||||||
namespace blink {
|
namespace blink {
|
||||||
|
|
||||||
// ThreadAffinity indicates which threads objects can be used on. We
|
|
||||||
// distinguish between objects that can be used on the main thread
|
|
||||||
// only and objects that can be used on any thread.
|
|
||||||
//
|
|
||||||
// For objects that can only be used on the main thread, we avoid going
|
|
||||||
// through thread-local storage to get to the thread state. This is
|
|
||||||
// important for performance.
|
|
||||||
enum ThreadAffinity {
|
|
||||||
kAnyThread,
|
|
||||||
kMainThreadOnly,
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, typename = void>
|
|
||||||
struct ThreadingTrait {
|
|
||||||
STATIC_ONLY(ThreadingTrait);
|
|
||||||
static constexpr ThreadAffinity kAffinity = kAnyThread;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <ThreadAffinity>
|
|
||||||
class ThreadStateFor;
|
|
||||||
class ThreadState;
|
|
||||||
|
|
||||||
using V8BuildEmbedderGraphCallback = void (*)(v8::Isolate*,
|
using V8BuildEmbedderGraphCallback = void (*)(v8::Isolate*,
|
||||||
v8::EmbedderGraph*,
|
v8::EmbedderGraph*,
|
||||||
void*);
|
void*);
|
||||||
|
|
||||||
// Storage for all ThreadState objects. This includes the main-thread
|
|
||||||
// ThreadState as well. Keep it outside the class so that PLATFORM_EXPORT
|
|
||||||
// doesn't apply to it (otherwise, clang-cl complains).
|
|
||||||
extern thread_local ThreadState* g_thread_specific_ CONSTINIT
|
|
||||||
__attribute__((tls_model(BLINK_HEAP_THREAD_LOCAL_MODEL)));
|
|
||||||
|
|
||||||
class PLATFORM_EXPORT ThreadState final {
|
class PLATFORM_EXPORT ThreadState final {
|
||||||
public:
|
public:
|
||||||
class NoAllocationScope;
|
class NoAllocationScope;
|
||||||
@@ -72,12 +40,8 @@ class PLATFORM_EXPORT ThreadState final {
|
|||||||
|
|
||||||
using StackState = cppgc::EmbedderStackState;
|
using StackState = cppgc::EmbedderStackState;
|
||||||
|
|
||||||
BLINK_HEAP_DECLARE_THREAD_LOCAL_GETTER(Current,
|
static ALWAYS_INLINE ThreadState* Current() {
|
||||||
ThreadState*,
|
return &ThreadStateStorage::Current()->thread_state();
|
||||||
g_thread_specific_)
|
|
||||||
|
|
||||||
static ALWAYS_INLINE ThreadState* MainThreadState() {
|
|
||||||
return reinterpret_cast<ThreadState*>(main_thread_state_storage_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attaches a ThreadState to the main-thread.
|
// Attaches a ThreadState to the main-thread.
|
||||||
@@ -90,16 +54,16 @@ class PLATFORM_EXPORT ThreadState final {
|
|||||||
void AttachToIsolate(v8::Isolate* isolate, V8BuildEmbedderGraphCallback);
|
void AttachToIsolate(v8::Isolate* isolate, V8BuildEmbedderGraphCallback);
|
||||||
void DetachFromIsolate();
|
void DetachFromIsolate();
|
||||||
|
|
||||||
ALWAYS_INLINE cppgc::AllocationHandle& allocation_handle() const {
|
|
||||||
return allocation_handle_;
|
|
||||||
}
|
|
||||||
ALWAYS_INLINE cppgc::HeapHandle& heap_handle() const { return heap_handle_; }
|
ALWAYS_INLINE cppgc::HeapHandle& heap_handle() const { return heap_handle_; }
|
||||||
ALWAYS_INLINE v8::CppHeap& cpp_heap() const { return *cpp_heap_; }
|
ALWAYS_INLINE v8::CppHeap& cpp_heap() const { return *cpp_heap_; }
|
||||||
ALWAYS_INLINE v8::Isolate* GetIsolate() const { return isolate_; }
|
ALWAYS_INLINE v8::Isolate* GetIsolate() const { return isolate_; }
|
||||||
|
|
||||||
void SafePoint(StackState);
|
void SafePoint(StackState);
|
||||||
|
|
||||||
bool IsMainThread() const { return this == MainThreadState(); }
|
bool IsMainThread() const {
|
||||||
|
return this ==
|
||||||
|
&ThreadStateStorage::MainThreadStateStorage()->thread_state();
|
||||||
|
}
|
||||||
bool IsCreationThread() const { return thread_id_ == CurrentThread(); }
|
bool IsCreationThread() const { return thread_id_ == CurrentThread(); }
|
||||||
|
|
||||||
void NotifyGarbageCollection(v8::GCType, v8::GCCallbackFlags);
|
void NotifyGarbageCollection(v8::GCType, v8::GCCallbackFlags);
|
||||||
@@ -135,42 +99,17 @@ class PLATFORM_EXPORT ThreadState final {
|
|||||||
static ThreadState* AttachCurrentThreadForTesting(v8::Platform*);
|
static ThreadState* AttachCurrentThreadForTesting(v8::Platform*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Main-thread ThreadState avoids TLS completely by using a regular global.
|
|
||||||
// The object is manually managed and should not rely on global ctor/dtor.
|
|
||||||
static uint8_t main_thread_state_storage_[];
|
|
||||||
|
|
||||||
explicit ThreadState(v8::Platform*);
|
explicit ThreadState(v8::Platform*);
|
||||||
~ThreadState();
|
~ThreadState();
|
||||||
|
|
||||||
std::unique_ptr<v8::CppHeap> cpp_heap_;
|
std::unique_ptr<v8::CppHeap> cpp_heap_;
|
||||||
std::unique_ptr<v8::EmbedderRootsHandler> embedder_roots_handler_;
|
std::unique_ptr<v8::EmbedderRootsHandler> embedder_roots_handler_;
|
||||||
cppgc::AllocationHandle& allocation_handle_;
|
|
||||||
cppgc::HeapHandle& heap_handle_;
|
cppgc::HeapHandle& heap_handle_;
|
||||||
v8::Isolate* isolate_ = nullptr;
|
v8::Isolate* isolate_ = nullptr;
|
||||||
base::PlatformThreadId thread_id_;
|
base::PlatformThreadId thread_id_;
|
||||||
bool forced_scheduled_gc_for_testing_ = false;
|
bool forced_scheduled_gc_for_testing_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
|
||||||
class ThreadStateFor<kMainThreadOnly> {
|
|
||||||
STATIC_ONLY(ThreadStateFor);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static ALWAYS_INLINE ThreadState* GetState() {
|
|
||||||
return ThreadState::MainThreadState();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class ThreadStateFor<kAnyThread> {
|
|
||||||
STATIC_ONLY(ThreadStateFor);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static ALWAYS_INLINE ThreadState* GetState() {
|
|
||||||
return ThreadState::Current();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace blink
|
} // namespace blink
|
||||||
|
|
||||||
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_H_
|
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_H_
|
||||||
|
52
third_party/blink/renderer/platform/heap/thread_state_storage.cc
vendored
Normal file
52
third_party/blink/renderer/platform/heap/thread_state_storage.cc
vendored
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
// Copyright 2020 The Chromium 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 "third_party/blink/renderer/platform/heap/thread_state_storage.h"
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
namespace blink {
|
||||||
|
|
||||||
|
thread_local ThreadStateStorage* g_thread_specific_ CONSTINIT
|
||||||
|
__attribute__((tls_model(BLINK_HEAP_THREAD_LOCAL_MODEL))) = nullptr;
|
||||||
|
|
||||||
|
// static
|
||||||
|
alignas(ThreadStateStorage) uint8_t
|
||||||
|
ThreadStateStorage::main_thread_state_storage_[sizeof(ThreadStateStorage)];
|
||||||
|
|
||||||
|
BLINK_HEAP_DEFINE_THREAD_LOCAL_GETTER(ThreadStateStorage::Current,
|
||||||
|
ThreadStateStorage*,
|
||||||
|
g_thread_specific_)
|
||||||
|
|
||||||
|
// static
|
||||||
|
void ThreadStateStorage::CreateMain(ThreadState& thread_state,
|
||||||
|
cppgc::AllocationHandle& allocation_handle,
|
||||||
|
cppgc::HeapHandle& heap_handle) {
|
||||||
|
new (main_thread_state_storage_)
|
||||||
|
ThreadStateStorage(thread_state, allocation_handle, heap_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void ThreadStateStorage::Create(ThreadState& thread_state,
|
||||||
|
cppgc::AllocationHandle& allocation_handle,
|
||||||
|
cppgc::HeapHandle& heap_handle) {
|
||||||
|
new ThreadStateStorage(thread_state, allocation_handle, heap_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadStateStorage::ThreadStateStorage(
|
||||||
|
ThreadState& thread_state,
|
||||||
|
cppgc::AllocationHandle& allocation_handle,
|
||||||
|
cppgc::HeapHandle& heap_handle)
|
||||||
|
: allocation_handle_(allocation_handle),
|
||||||
|
heap_handle_(heap_handle),
|
||||||
|
thread_state_(thread_state) {
|
||||||
|
g_thread_specific_ = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadStateStorage::~ThreadStateStorage() {
|
||||||
|
DCHECK(!IsMainThread());
|
||||||
|
g_thread_specific_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace blink
|
123
third_party/blink/renderer/platform/heap/thread_state_storage.h
vendored
Normal file
123
third_party/blink/renderer/platform/heap/thread_state_storage.h
vendored
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
// Copyright 2020 The Chromium 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_STORAGE_H_
|
||||||
|
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_STORAGE_H_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "base/compiler_specific.h"
|
||||||
|
#include "third_party/blink/renderer/platform/heap/thread_local.h"
|
||||||
|
#include "third_party/blink/renderer/platform/platform_export.h"
|
||||||
|
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
|
||||||
|
|
||||||
|
namespace cppgc {
|
||||||
|
class AllocationHandle;
|
||||||
|
class HeapHandle;
|
||||||
|
} // namespace cppgc
|
||||||
|
|
||||||
|
namespace blink {
|
||||||
|
|
||||||
|
class ThreadState;
|
||||||
|
class ThreadStateStorage;
|
||||||
|
|
||||||
|
// ThreadAffinity indicates which threads objects can be used on. We
|
||||||
|
// distinguish between objects that can be used on the main thread
|
||||||
|
// only and objects that can be used on any thread.
|
||||||
|
//
|
||||||
|
// For objects that can only be used on the main thread, we avoid going
|
||||||
|
// through thread-local storage to get to the thread state. This is
|
||||||
|
// important for performance.
|
||||||
|
enum ThreadAffinity {
|
||||||
|
kAnyThread,
|
||||||
|
kMainThreadOnly,
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename = void>
|
||||||
|
struct ThreadingTrait {
|
||||||
|
STATIC_ONLY(ThreadingTrait);
|
||||||
|
static constexpr ThreadAffinity kAffinity = kAnyThread;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Storage for all ThreadState objects. This includes the main-thread
|
||||||
|
// ThreadState as well. Keep it outside the class so that PLATFORM_EXPORT
|
||||||
|
// doesn't apply to it (otherwise, clang-cl complains).
|
||||||
|
extern thread_local ThreadStateStorage* g_thread_specific_ CONSTINIT
|
||||||
|
__attribute__((tls_model(BLINK_HEAP_THREAD_LOCAL_MODEL)));
|
||||||
|
|
||||||
|
// ThreadStateStorage is the explicitly managed TLS- and global-backed storage
|
||||||
|
// for ThreadState.
|
||||||
|
class PLATFORM_EXPORT ThreadStateStorage final {
|
||||||
|
public:
|
||||||
|
static ALWAYS_INLINE ThreadStateStorage* MainThreadStateStorage() {
|
||||||
|
return reinterpret_cast<ThreadStateStorage*>(main_thread_state_storage_);
|
||||||
|
}
|
||||||
|
|
||||||
|
BLINK_HEAP_DECLARE_THREAD_LOCAL_GETTER(Current,
|
||||||
|
ThreadStateStorage*,
|
||||||
|
g_thread_specific_)
|
||||||
|
|
||||||
|
ALWAYS_INLINE cppgc::AllocationHandle& allocation_handle() const {
|
||||||
|
return allocation_handle_;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALWAYS_INLINE cppgc::HeapHandle& heap_handle() const { return heap_handle_; }
|
||||||
|
|
||||||
|
ALWAYS_INLINE ThreadState& thread_state() const { return thread_state_; }
|
||||||
|
|
||||||
|
ALWAYS_INLINE bool IsMainThread() const {
|
||||||
|
return this == MainThreadStateStorage();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void CreateMain(ThreadState&,
|
||||||
|
cppgc::AllocationHandle&,
|
||||||
|
cppgc::HeapHandle&);
|
||||||
|
static void Create(ThreadState&,
|
||||||
|
cppgc::AllocationHandle&,
|
||||||
|
cppgc::HeapHandle&);
|
||||||
|
|
||||||
|
// Main-thread ThreadStateStorage avoids TLS completely by using a regular
|
||||||
|
// global. The object is manually managed and should not rely on global
|
||||||
|
// ctor/dtor.
|
||||||
|
static uint8_t main_thread_state_storage_[];
|
||||||
|
|
||||||
|
ThreadStateStorage(ThreadState&,
|
||||||
|
cppgc::AllocationHandle&,
|
||||||
|
cppgc::HeapHandle&);
|
||||||
|
~ThreadStateStorage();
|
||||||
|
|
||||||
|
cppgc::AllocationHandle& allocation_handle_;
|
||||||
|
cppgc::HeapHandle& heap_handle_;
|
||||||
|
ThreadState& thread_state_;
|
||||||
|
|
||||||
|
friend class ThreadState;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <ThreadAffinity>
|
||||||
|
class ThreadStateStorageFor;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class ThreadStateStorageFor<kMainThreadOnly> {
|
||||||
|
STATIC_ONLY(ThreadStateStorageFor);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static ALWAYS_INLINE ThreadStateStorage* GetState() {
|
||||||
|
return ThreadStateStorage::MainThreadStateStorage();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class ThreadStateStorageFor<kAnyThread> {
|
||||||
|
STATIC_ONLY(ThreadStateStorageFor);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static ALWAYS_INLINE ThreadStateStorage* GetState() {
|
||||||
|
return ThreadStateStorage::Current();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace blink
|
||||||
|
|
||||||
|
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_STORAGE_H_
|
@@ -37,7 +37,7 @@
|
|||||||
#include "mojo/core/embedder/embedder.h"
|
#include "mojo/core/embedder/embedder.h"
|
||||||
#include "mojo/core/embedder/scoped_ipc_support.h"
|
#include "mojo/core/embedder/scoped_ipc_support.h"
|
||||||
#include "skia/ext/test_fonts.h"
|
#include "skia/ext/test_fonts.h"
|
||||||
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
|
#include "third_party/blink/renderer/platform/heap/thread_state.h"
|
||||||
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
|
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
Reference in New Issue
Block a user