summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/heap/v8_wrapper
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/heap/v8_wrapper')
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.cc125
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/collection_support/heap_hash_table_backing.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/collection_support/heap_vector_backing.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap_allocator_impl.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_local.h63
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.h21
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state_scopes.h16
9 files changed, 217 insertions, 50 deletions
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.cc b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.cc
index dd1edb88b0d..e31f7721321 100644
--- a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.cc
@@ -5,8 +5,13 @@
#include "third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.h"
#include <inttypes.h>
+#include <ios>
+#include <sstream>
+#include <string>
+#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
+#include "base/trace_event/memory_allocator_dump.h"
#include "base/trace_event/memory_dump_manager.h"
#include "third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.h"
#include "v8/include/cppgc/heap-statistics.h"
@@ -24,6 +29,27 @@ constexpr const char* HeapTypeString(
}
}
+void RecordType(
+ std::vector<cppgc::HeapStatistics::ObjectStatsEntry>& global_object_stats,
+ const cppgc::HeapStatistics::ObjectStatsEntry& local_object_stats,
+ size_t entry_index) {
+ global_object_stats[entry_index].allocated_bytes +=
+ local_object_stats.allocated_bytes;
+ global_object_stats[entry_index].object_count +=
+ local_object_stats.object_count;
+}
+
+// Use the id to generate a unique name as different types may provide the same
+// string as typename. This happens in component builds when cppgc creates
+// different internal types for the same C++ class when it is instantiated from
+// different libraries.
+std::string GetUniqueName(std::string name, size_t id) {
+ std::stringstream stream;
+ // Convert the id to hex to avoid it reading like an object count.
+ stream << name << " (0x" << std::hex << id << ")";
+ return stream.str();
+}
+
} // namespace
BlinkGCMemoryDumpProvider::BlinkGCMemoryDumpProvider(
@@ -33,7 +59,7 @@ BlinkGCMemoryDumpProvider::BlinkGCMemoryDumpProvider(
: thread_state_(thread_state),
heap_type_(heap_type),
dump_base_name_(
- "blink_gc/" + std::string(HeapTypeString(heap_type_)) + "/heap" +
+ "blink_gc/" + std::string(HeapTypeString(heap_type_)) +
(heap_type_ == HeapType::kBlinkWorkerThread
? "/" + base::StringPrintf(
"worker_0x%" PRIXPTR,
@@ -60,10 +86,11 @@ bool BlinkGCMemoryDumpProvider::OnMemoryDump(
::cppgc::HeapStatistics stats =
ThreadState::Current()->cpp_heap().CollectStatistics(detail_level);
- auto* heap_dump = process_memory_dump->CreateAllocatorDump(dump_base_name_);
+ auto* heap_dump =
+ process_memory_dump->CreateAllocatorDump(dump_base_name_ + "/heap");
heap_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
base::trace_event::MemoryAllocatorDump::kUnitsBytes,
- stats.physical_size_bytes);
+ stats.resident_size_bytes);
heap_dump->AddScalar("allocated_objects_size",
base::trace_event::MemoryAllocatorDump::kUnitsBytes,
stats.used_size_bytes);
@@ -72,16 +99,19 @@ bool BlinkGCMemoryDumpProvider::OnMemoryDump(
return true;
}
- // Detailed statistics.
+ // Aggregate global object stats from per page statistics.
+ std::vector<cppgc::HeapStatistics::ObjectStatsEntry> global_object_stats;
+ global_object_stats.resize(stats.type_names.size());
+
+ // Detailed statistics follow.
for (const ::cppgc::HeapStatistics::SpaceStatistics& space_stats :
stats.space_stats) {
- std::string arena_dump_name = dump_base_name_ + "/" + space_stats.name;
- auto* arena_dump =
- process_memory_dump->CreateAllocatorDump(arena_dump_name);
- arena_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
+ auto* space_dump = process_memory_dump->CreateAllocatorDump(
+ heap_dump->absolute_name() + "/" + space_stats.name);
+ space_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
base::trace_event::MemoryAllocatorDump::kUnitsBytes,
- space_stats.physical_size_bytes);
- arena_dump->AddScalar("allocated_objects_size",
+ space_stats.resident_size_bytes);
+ space_dump->AddScalar("allocated_objects_size",
base::trace_event::MemoryAllocatorDump::kUnitsBytes,
space_stats.used_size_bytes);
@@ -89,19 +119,42 @@ bool BlinkGCMemoryDumpProvider::OnMemoryDump(
for (const ::cppgc::HeapStatistics::PageStatistics& page_stats :
space_stats.page_stats) {
auto* page_dump = process_memory_dump->CreateAllocatorDump(
- arena_dump_name + "/pages/page_" +
+ space_dump->absolute_name() + "/pages/page_" +
base::NumberToString(page_count++));
+ page_dump->AddScalar("committed_size",
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ page_stats.committed_size_bytes);
page_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
base::trace_event::MemoryAllocatorDump::kUnitsBytes,
- page_stats.physical_size_bytes);
+ page_stats.resident_size_bytes);
page_dump->AddScalar("allocated_objects_size",
base::trace_event::MemoryAllocatorDump::kUnitsBytes,
page_stats.used_size_bytes);
+
+ const auto& object_stats = page_stats.object_statistics;
+ for (size_t i = 0; i < object_stats.size(); i++) {
+ if (!object_stats[i].object_count)
+ continue;
+
+ auto* page_class_dump = process_memory_dump->CreateAllocatorDump(
+ page_dump->absolute_name() + "/types/" +
+ GetUniqueName(stats.type_names[i], i));
+ page_class_dump->AddScalar(
+ base::trace_event::MemoryAllocatorDump::kNameObjectCount,
+ base::trace_event::MemoryAllocatorDump::kUnitsObjects,
+ object_stats[i].object_count);
+ page_class_dump->AddScalar(
+ "allocated_objects_size",
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ object_stats[i].allocated_bytes);
+
+ RecordType(global_object_stats, object_stats[i], i);
+ }
}
const ::cppgc::HeapStatistics::FreeListStatistics& free_list_stats =
space_stats.free_list_stats;
- for (wtf_size_t i = 0; i < free_list_stats.bucket_size.size(); ++i) {
+ for (size_t i = 0; i < free_list_stats.bucket_size.size(); ++i) {
constexpr size_t kDigits = 8;
std::string original_bucket_size =
base::NumberToString(free_list_stats.bucket_size[i]);
@@ -109,28 +162,40 @@ bool BlinkGCMemoryDumpProvider::OnMemoryDump(
std::string(kDigits - original_bucket_size.length(), '0') +
original_bucket_size;
auto* free_list_bucket_dump = process_memory_dump->CreateAllocatorDump(
- arena_dump_name + "/freelist/bucket_" + padded_bucket_size);
+ space_dump->absolute_name() + "/freelist/bucket_" +
+ padded_bucket_size);
free_list_bucket_dump->AddScalar(
- "free_size", base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ "free_slot_count",
+ base::trace_event::MemoryAllocatorDump::kUnitsObjects,
+ free_list_stats.free_count[i]);
+ free_list_bucket_dump->AddScalar(
+ "free_usable_size",
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
free_list_stats.free_size[i]);
}
+ }
- const ::cppgc::HeapStatistics::ObjectStatistics& object_stats =
- space_stats.object_stats;
- for (wtf_size_t i = 1; i < object_stats.num_types; i++) {
- if (object_stats.type_name[i].empty())
- continue;
-
- auto* class_dump = process_memory_dump->CreateAllocatorDump(
- arena_dump_name + "/classes/" + object_stats.type_name[i]);
- class_dump->AddScalar(
- "object_count", base::trace_event::MemoryAllocatorDump::kUnitsObjects,
- object_stats.type_count[i]);
- class_dump->AddScalar("object_size",
- base::trace_event::MemoryAllocatorDump::kUnitsBytes,
- object_stats.type_bytes[i]);
- }
+ // Populate "allocated_objects" and "blink_objects/blink_gc" dumps.
+ const auto* allocated_objects_dump = process_memory_dump->CreateAllocatorDump(
+ dump_base_name_ + "/allocated_objects");
+ for (size_t i = 0; i < global_object_stats.size(); i++) {
+ auto* details = process_memory_dump->CreateAllocatorDump(
+ "blink_objects/blink_gc/" + GetUniqueName(stats.type_names[i], i));
+ details->AddScalar("allocated_objects_size",
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ global_object_stats[i].allocated_bytes);
+ details->AddScalar(base::trace_event::MemoryAllocatorDump::kNameObjectCount,
+ base::trace_event::MemoryAllocatorDump::kUnitsObjects,
+ global_object_stats[i].object_count);
+ details->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ global_object_stats[i].allocated_bytes);
+ process_memory_dump->AddSuballocation(
+ details->guid(), dump_base_name_ + "/allocated_objects");
}
+ process_memory_dump->AddOwnershipEdge(allocated_objects_dump->guid(),
+ heap_dump->guid());
+
return true;
}
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/collection_support/heap_hash_table_backing.h b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/collection_support/heap_hash_table_backing.h
index 2d81ed8ee91..ad05f4a5e59 100644
--- a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/collection_support/heap_hash_table_backing.h
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/collection_support/heap_hash_table_backing.h
@@ -14,6 +14,7 @@
#include "third_party/blink/renderer/platform/wtf/conditional_destructor.h"
#include "third_party/blink/renderer/platform/wtf/hash_table.h"
#include "third_party/blink/renderer/platform/wtf/hash_traits.h"
+#include "third_party/blink/renderer/platform/wtf/sanitizers.h"
#include "v8/include/cppgc/custom-space.h"
#include "v8/include/cppgc/explicit-management.h"
#include "v8/include/cppgc/object-size-trait.h"
@@ -30,11 +31,16 @@ class HeapHashTableBacking final
using ValueType = typename Table::ValueType;
public:
- static ValueType* ToArray(ClassType* backing) {
+ // Although the HeapHashTableBacking is fully constructed, the array resulting
+ // from ToArray may not be fully constructed as the elements of the array are
+ // not initialized and may have null vtable pointers. Null vtable pointer
+ // violates CFI for polymorphic types.
+ NO_SANITIZE_UNRELATED_CAST ALWAYS_INLINE static ValueType* ToArray(
+ ClassType* backing) {
return reinterpret_cast<ValueType*>(backing);
}
- static ClassType* FromArray(ValueType* array) {
+ ALWAYS_INLINE static ClassType* FromArray(ValueType* array) {
return reinterpret_cast<ClassType*>(array);
}
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/collection_support/heap_vector_backing.h b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/collection_support/heap_vector_backing.h
index 68590093c5a..e2db74b9209 100644
--- a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/collection_support/heap_vector_backing.h
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/collection_support/heap_vector_backing.h
@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/platform/heap/trace_traits.h"
#include "third_party/blink/renderer/platform/wtf/conditional_destructor.h"
#include "third_party/blink/renderer/platform/wtf/container_annotations.h"
+#include "third_party/blink/renderer/platform/wtf/sanitizers.h"
#include "third_party/blink/renderer/platform/wtf/type_traits.h"
#include "third_party/blink/renderer/platform/wtf/vector_traits.h"
#include "v8/include/cppgc/allocation.h"
@@ -38,11 +39,16 @@ class HeapVectorBacking final
using ClassType = HeapVectorBacking<T, Traits>;
public:
- static T* ToArray(ClassType* backing) {
+ // Although the HeapVectorBacking is fully constructed, the array resulting
+ // from ToArray may not be fully constructed as the elements of the array are
+ // not initialized and may have null vtable pointers. Null vtable pointer
+ // violates CFI for polymorphic types.
+ NO_SANITIZE_UNRELATED_CAST ALWAYS_INLINE static T* ToArray(
+ ClassType* backing) {
return reinterpret_cast<T*>(backing);
}
- static ClassType* FromArray(T* payload) {
+ ALWAYS_INLINE static ClassType* FromArray(T* payload) {
return reinterpret_cast<ClassType*>(payload);
}
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap.h b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap.h
index e81eb2f4d80..0b452aa7a68 100644
--- a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap.h
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap.h
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.h"
#include "v8/include/cppgc/allocation.h"
#include "v8/include/cppgc/garbage-collected.h"
+#include "v8/include/cppgc/internal/pointer-policies.h"
#include "v8/include/cppgc/liveness-broker.h"
namespace blink {
@@ -41,6 +42,10 @@ T* MakeGarbageCollected(AdditionalBytes additional_bytes, Args&&... args) {
std::forward<Args>(args)...);
}
+static constexpr bool kBlinkGCHasDebugChecks =
+ !std::is_same<cppgc::internal::DefaultMemberCheckingPolicy,
+ cppgc::internal::DisabledCheckingPolicy>::value;
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_HEAP_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap_allocator_impl.h b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap_allocator_impl.h
index b36b1d24e46..4179e550510 100644
--- a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap_allocator_impl.h
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap_allocator_impl.h
@@ -137,11 +137,11 @@ class PLATFORM_EXPORT HeapAllocator {
}
template <typename T>
- static void TraceBackingStoreIfMarked(T** slot) {
+ static void TraceBackingStoreIfMarked(T* object) {
HeapConsistency::WriteBarrierParams params;
- if (HeapConsistency::GetWriteBarrierType(slot, *slot, params) ==
+ if (HeapConsistency::GetWriteBarrierType(object, params) ==
HeapConsistency::WriteBarrierType::kMarking) {
- HeapConsistency::SteeleWriteBarrier(params, *slot);
+ HeapConsistency::SteeleWriteBarrier(params, object);
}
}
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_local.h b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_local.h
new file mode 100644
index 00000000000..1a0c43b0eaf
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_local.h
@@ -0,0 +1,63 @@
+// Copyright 2021 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_V8_WRAPPER_THREAD_LOCAL_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_THREAD_LOCAL_H_
+
+#include "base/compiler_specific.h"
+#include "build/build_config.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+
+// On component builds, always hide the thread_local variable behind a call.
+// This avoids complexity with "global-dyn" and allows to use "local-dyn"
+// instead, across all platforms. On non-component (release) builds, don't hide
+// the variable behind the call (to improve performance in access time), but use
+// different tls models on different platforms. On Windows, since chrome is
+// linked into the chrome.dll which is always linked to chrome.exe at static
+// link time (DT_NEEDED in ELF terms), use "init-exec". On Android, since the
+// library can be opened with "dlopen" (through JNI), use "local-dyn". On other
+// systems (Linux/ChromeOS/MacOS) use the fastest "local-exec".
+
+// |_____component_____|___non-component___|
+// ________|_tls_model__|_hide_|_tls_model__|_hide_|
+// Windows | local-dyn | yes | init-exec | no |
+// Android | local-dyn | yes | local-dyn | no |
+// Other | local-dyn | yes | local-exec | no |
+
+// The call is still cheaper than multiple calls through WTF/base/pthread*
+// layers.
+#if defined(COMPONENT_BUILD)
+#define BLINK_HEAP_HIDE_THREAD_LOCAL_IN_LIBRARY 1
+#else
+#define BLINK_HEAP_HIDE_THREAD_LOCAL_IN_LIBRARY 0
+#endif
+
+#if BLINK_HEAP_HIDE_THREAD_LOCAL_IN_LIBRARY
+#define BLINK_HEAP_THREAD_LOCAL_MODEL "local-dynamic"
+#else
+#if defined(OS_WIN)
+#define BLINK_HEAP_THREAD_LOCAL_MODEL "initial-exec"
+#elif defined(OS_ANDROID)
+#define BLINK_HEAP_THREAD_LOCAL_MODEL "local-dynamic"
+#else
+#define BLINK_HEAP_THREAD_LOCAL_MODEL "local-exec"
+#endif
+#endif
+
+#if defined(BLINK_HEAP_HIDE_THREAD_LOCAL_IN_LIBRARY)
+
+#define BLINK_HEAP_DECLARE_THREAD_LOCAL_GETTER(Name, Type, Member) \
+ static NOINLINE Type Name();
+#define BLINK_HEAP_DEFINE_THREAD_LOCAL_GETTER(Name, Type, Member) \
+ NOINLINE Type Name() { return Member; }
+
+#else // !defined(BLINK_HEAP_HIDE_THREAD_LOCAL_IN_LIBRARY)
+
+#define BLINK_HEAP_DECLARE_THREAD_LOCAL_GETTER(Name, Type, Member) \
+ static ALWAYS_INLINE Type Name() { return Member; }
+#define BLINK_HEAP_DEFINE_THREAD_LOCAL_GETTER(Name, Type, Member)
+
+#endif // defined(BLINK_HEAP_HIDE_THREAD_LOCAL_IN_LIBRARY)
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_THREAD_LOCAL_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.cc b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.cc
index 78da3ce32f9..303c2839488 100644
--- a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.cc
@@ -82,14 +82,17 @@ class BlinkRootsHandler final : public v8::EmbedderRootsHandler {
} // namespace
-// static
-base::LazyInstance<WTF::ThreadSpecific<ThreadState*>>::Leaky
- ThreadState::thread_specific_ = LAZY_INSTANCE_INITIALIZER;
+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
ThreadState* ThreadState::AttachMainThread() {
return new (main_thread_state_storage_) ThreadState(gin::V8Platform::Get());
@@ -149,7 +152,7 @@ ThreadState::ThreadState(v8::Platform* platform)
allocation_handle_(cpp_heap_->GetAllocationHandle()),
heap_handle_(cpp_heap_->GetHeapHandle()),
thread_id_(CurrentThread()) {
- *(thread_specific_.Get()) = this;
+ g_thread_specific_ = this;
}
ThreadState::~ThreadState() {
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.h b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.h
index 8b6b1f920e0..682a0b54c5b 100644
--- a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.h
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.h
@@ -6,11 +6,11 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_THREAD_STATE_H_
#include "base/compiler_specific.h"
-#include "base/lazy_instance.h"
+#include "build/build_config.h"
#include "third_party/blink/renderer/platform/heap/blink_gc.h"
+#include "third_party/blink/renderer/platform/heap/v8_wrapper/thread_local.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/thread_specific.h"
#include "third_party/blink/renderer/platform/wtf/threading.h"
#include "v8-profiler.h"
#include "v8/include/cppgc/heap-consistency.h"
@@ -61,13 +61,20 @@ using V8BuildEmbedderGraphCallback = void (*)(v8::Isolate*,
v8::EmbedderGraph*,
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 {
public:
class NoAllocationScope;
+ class GCForbiddenScope;
- static ALWAYS_INLINE ThreadState* Current() {
- return *(thread_specific_.Get());
- }
+ BLINK_HEAP_DECLARE_THREAD_LOCAL_GETTER(Current,
+ ThreadState*,
+ g_thread_specific_)
static ALWAYS_INLINE ThreadState* MainThreadState() {
return reinterpret_cast<ThreadState*>(main_thread_state_storage_);
@@ -132,10 +139,6 @@ class PLATFORM_EXPORT ThreadState final {
// 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_[];
- // Storage for all ThreadState objects. This includes the main-thread
- // ThreadState as well.
- static base::LazyInstance<WTF::ThreadSpecific<ThreadState*>>::Leaky
- thread_specific_;
explicit ThreadState(v8::Platform*);
~ThreadState();
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state_scopes.h b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state_scopes.h
index bec9605a0c6..82e71e98598 100644
--- a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state_scopes.h
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state_scopes.h
@@ -26,6 +26,22 @@ class ThreadState::NoAllocationScope final {
const cppgc::subtle::DisallowGarbageCollectionScope disallow_gc_;
};
+// The GCForbiddenScope class is used to prevent GC finalization
+// when it is not safe to do so.
+class ThreadState::GCForbiddenScope final {
+ STACK_ALLOCATED();
+
+ public:
+ explicit GCForbiddenScope(ThreadState* state)
+ : no_gc_(state->cpp_heap().GetHeapHandle()) {}
+
+ GCForbiddenScope(const NoAllocationScope&) = delete;
+ GCForbiddenScope& operator=(const NoAllocationScope&) = delete;
+
+ private:
+ const cppgc::subtle::NoGarbageCollectionScope no_gc_;
+};
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_THREAD_STATE_SCOPES_H_