summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/heap
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2021-03-12 09:13:00 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2021-03-16 09:58:26 +0000
commit03561cae90f1d99b5c54b1ef3be69f10e882b25e (patch)
treecc5f0958e823c044e7ae51cc0117fe51432abe5e /chromium/third_party/blink/renderer/platform/heap
parentfa98118a45f7e169f8846086dc2c22c49a8ba310 (diff)
downloadqtwebengine-chromium-03561cae90f1d99b5c54b1ef3be69f10e882b25e.tar.gz
BASELINE: Update Chromium to 88.0.4324.208
Change-Id: I3ae87d23e4eff4b4a469685658740a213600c667 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/heap')
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/BUILD.gn137
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/blink_gc.h124
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h45
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h18
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/disallow_new_wrapper.h51
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/garbage_collected.h117
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/gc_task_runner.h94
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/handle.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap.h734
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_allocator.h917
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.h467
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_traits.h38
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/atomic_entry_flag.h (renamed from chromium/third_party/blink/renderer/platform/heap/atomic_entry_flag.h)6
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/blink_gc.cc (renamed from chromium/third_party/blink/renderer/platform/heap/blink_gc.cc)1
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/blink_gc.h126
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/blink_gc_memory_dump_provider.cc (renamed from chromium/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.cc)2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/blink_gc_memory_dump_provider.h47
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/disallow_new_wrapper.h53
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/finalizer_traits.h (renamed from chromium/third_party/blink/renderer/platform/heap/finalizer_traits.h)6
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/garbage_collected.h117
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/gc_info.cc (renamed from chromium/third_party/blink/renderer/platform/heap/gc_info.cc)2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/gc_info.h (renamed from chromium/third_party/blink/renderer/platform/heap/gc_info.h)10
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/gc_task_runner.h90
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/heap.cc (renamed from chromium/third_party/blink/renderer/platform/heap/heap.cc)35
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/heap.h757
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/heap_allocator.cc (renamed from chromium/third_party/blink/renderer/platform/heap/heap_allocator.cc)0
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/heap_allocator.h909
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/heap_compact.cc (renamed from chromium/third_party/blink/renderer/platform/heap/heap_compact.cc)104
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/heap_compact.h (renamed from chromium/third_party/blink/renderer/platform/heap/heap_compact.h)6
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/heap_page.cc (renamed from chromium/third_party/blink/renderer/platform/heap/heap_page.cc)12
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/heap_page.h (renamed from chromium/third_party/blink/renderer/platform/heap/heap_page.h)16
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/heap_stats_collector.cc (renamed from chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.cc)0
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/heap_stats_collector.h469
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/heap_traits.h40
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/marking_scheduling_oracle.cc (renamed from chromium/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.cc)2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/marking_scheduling_oracle.h (renamed from chromium/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.h)6
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/marking_verifier.cc (renamed from chromium/third_party/blink/renderer/platform/heap/marking_verifier.cc)4
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/marking_verifier.h (renamed from chromium/third_party/blink/renderer/platform/heap/marking_verifier.h)6
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/marking_visitor.cc (renamed from chromium/third_party/blink/renderer/platform/heap/marking_visitor.cc)50
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/marking_visitor.h (renamed from chromium/third_party/blink/renderer/platform/heap/marking_visitor.h)27
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/member.h577
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/name_traits.h (renamed from chromium/third_party/blink/renderer/platform/heap/name_traits.h)6
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/page_bloom_filter.h (renamed from chromium/third_party/blink/renderer/platform/heap/page_bloom_filter.h)8
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/page_memory.cc (renamed from chromium/third_party/blink/renderer/platform/heap/page_memory.cc)2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/page_memory.h (renamed from chromium/third_party/blink/renderer/platform/heap/page_memory.h)8
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/page_pool.cc (renamed from chromium/third_party/blink/renderer/platform/heap/page_pool.cc)4
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/page_pool.h (renamed from chromium/third_party/blink/renderer/platform/heap/page_pool.h)6
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/persistent.h971
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/persistent_node.cc (renamed from chromium/third_party/blink/renderer/platform/heap/persistent_node.cc)4
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/persistent_node.h (renamed from chromium/third_party/blink/renderer/platform/heap/persistent_node.h)6
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/process_heap.cc (renamed from chromium/third_party/blink/renderer/platform/heap/process_heap.cc)4
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/process_heap.h69
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/thread_state.cc (renamed from chromium/third_party/blink/renderer/platform/heap/thread_state.cc)13
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/thread_state.h716
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/thread_state_scopes.h128
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/thread_state_statistics.cc (renamed from chromium/third_party/blink/renderer/platform/heap/thread_state_statistics.cc)2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/thread_state_statistics.h (renamed from chromium/third_party/blink/renderer/platform/heap/thread_state_statistics.h)6
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/threading_traits.h (renamed from chromium/third_party/blink/renderer/platform/heap/threading_traits.h)6
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/trace_traits.h (renamed from chromium/third_party/blink/renderer/platform/heap/trace_traits.h)35
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/unified_heap_controller.cc (renamed from chromium/third_party/blink/renderer/platform/heap/unified_heap_controller.cc)2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/unified_heap_controller.h75
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/unified_heap_marking_visitor.cc (renamed from chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc)0
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/unified_heap_marking_visitor.h89
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/unsanitized_atomic.cc (renamed from chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.cc)2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/unsanitized_atomic.h (renamed from chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.h)6
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/visitor.h312
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/impl/worklist.h (renamed from chromium/third_party/blink/renderer/platform/heap/worklist.h)6
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/member.h554
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/persistent.h969
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/process_heap.h69
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/thread_state.h719
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/thread_state_scopes.h126
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/unified_heap_controller.h73
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h88
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/disallow_new_wrapper.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/garbage_collected.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/gc_task_runner.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap.h19
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap_allocator.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap_stats_collector.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap_traits.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/member.h23
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/persistent.h20
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/process_heap.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.h17
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state_scopes.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/unified_heap_controller.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/unified_heap_marking_visitor.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/visitor.h16
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/visitor.h330
96 files changed, 6222 insertions, 5643 deletions
diff --git a/chromium/third_party/blink/renderer/platform/heap/BUILD.gn b/chromium/third_party/blink/renderer/platform/heap/BUILD.gn
index 7647b413521..52b0679d553 100644
--- a/chromium/third_party/blink/renderer/platform/heap/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/heap/BUILD.gn
@@ -16,6 +16,7 @@ buildflag_header("blink_heap_buildflags") {
flags = [
"BLINK_HEAP_VERIFICATION=$enable_blink_heap_verification",
"BLINK_HEAP_YOUNG_GENERATION=$enable_blink_heap_young_generation",
+ "BLINK_HEAP_USE_V8_OILPAN=$enable_blink_heap_use_v8_oilpan",
]
}
@@ -29,11 +30,18 @@ source_set("heap_unsanitized") {
# std::atomic<>:: functions must be inlined.
configs -= [ "//build/config/compiler:default_optimization" ]
configs += [ "//build/config/compiler:optimize_max" ]
+ if (using_mismatched_sample_profile) {
+ configs -= [ "//build/config/compiler:afdo_optimize_size" ]
+ }
- sources = [
- "unsanitized_atomic.cc",
- "unsanitized_atomic.h",
- ]
+ if (!enable_blink_heap_use_v8_oilpan) {
+ sources = [
+ "impl/unsanitized_atomic.cc",
+ "impl/unsanitized_atomic.h",
+ ]
+ } else {
+ sources = []
+ }
deps = [
"//base",
@@ -43,65 +51,30 @@ source_set("heap_unsanitized") {
}
blink_platform_sources("heap") {
+ configs += [ "//build/config/compiler:noshadowing" ]
+
sources = [
- "atomic_entry_flag.h",
- "blink_gc.cc",
- "blink_gc.h",
- "blink_gc_memory_dump_provider.cc",
"blink_gc_memory_dump_provider.h",
"collection_support/heap_hash_table_backing.h",
"collection_support/heap_linked_stack.h",
"collection_support/heap_vector_backing.h",
"disallow_new_wrapper.h",
- "finalizer_traits.h",
"garbage_collected.h",
- "gc_info.cc",
- "gc_info.h",
"gc_task_runner.h",
"handle.h",
- "heap.cc",
"heap.h",
- "heap_allocator.cc",
"heap_allocator.h",
- "heap_compact.cc",
- "heap_compact.h",
- "heap_page.cc",
- "heap_page.h",
- "heap_stats_collector.cc",
"heap_stats_collector.h",
"heap_traits.h",
- "marking_scheduling_oracle.cc",
- "marking_scheduling_oracle.h",
- "marking_verifier.cc",
- "marking_verifier.h",
- "marking_visitor.cc",
- "marking_visitor.h",
"member.h",
- "name_traits.h",
- "page_bloom_filter.h",
- "page_memory.cc",
- "page_memory.h",
- "page_pool.cc",
- "page_pool.h",
"persistent.h",
- "persistent_node.cc",
- "persistent_node.h",
- "process_heap.cc",
"process_heap.h",
"self_keep_alive.h",
- "thread_state.cc",
"thread_state.h",
"thread_state_scopes.h",
- "thread_state_statistics.cc",
- "thread_state_statistics.h",
- "threading_traits.h",
- "trace_traits.h",
- "unified_heap_controller.cc",
"unified_heap_controller.h",
- "unified_heap_marking_visitor.cc",
"unified_heap_marking_visitor.h",
"visitor.h",
- "worklist.h",
]
deps = [
@@ -114,9 +87,91 @@ blink_platform_sources("heap") {
"//v8",
]
+ if (enable_blink_heap_use_v8_oilpan) {
+ sources += [
+ "v8_wrapper/blink_gc.h",
+ "v8_wrapper/blink_gc_memory_dump_provider.h",
+ "v8_wrapper/disallow_new_wrapper.h",
+ "v8_wrapper/garbage_collected.h",
+ "v8_wrapper/gc_task_runner.h",
+ "v8_wrapper/heap.h",
+ "v8_wrapper/heap_allocator.h",
+ "v8_wrapper/heap_stats_collector.h",
+ "v8_wrapper/heap_traits.h",
+ "v8_wrapper/member.h",
+ "v8_wrapper/persistent.h",
+ "v8_wrapper/process_heap.h",
+ "v8_wrapper/thread_state.h",
+ "v8_wrapper/thread_state_scopes.h",
+ "v8_wrapper/unified_heap_controller.h",
+ "v8_wrapper/unified_heap_marking_visitor.h",
+ "v8_wrapper/visitor.h",
+ ]
+
+ deps += [ "//v8:cppgc" ]
+ } else {
+ sources += [
+ "impl/atomic_entry_flag.h",
+ "impl/blink_gc.cc",
+ "impl/blink_gc.h",
+ "impl/blink_gc_memory_dump_provider.cc",
+ "impl/blink_gc_memory_dump_provider.h",
+ "impl/disallow_new_wrapper.h",
+ "impl/finalizer_traits.h",
+ "impl/garbage_collected.h",
+ "impl/gc_info.cc",
+ "impl/gc_info.h",
+ "impl/gc_task_runner.h",
+ "impl/heap.cc",
+ "impl/heap.h",
+ "impl/heap_allocator.cc",
+ "impl/heap_allocator.h",
+ "impl/heap_compact.cc",
+ "impl/heap_compact.h",
+ "impl/heap_page.cc",
+ "impl/heap_page.h",
+ "impl/heap_stats_collector.cc",
+ "impl/heap_stats_collector.h",
+ "impl/heap_traits.h",
+ "impl/marking_scheduling_oracle.cc",
+ "impl/marking_scheduling_oracle.h",
+ "impl/marking_verifier.cc",
+ "impl/marking_verifier.h",
+ "impl/marking_visitor.cc",
+ "impl/marking_visitor.h",
+ "impl/member.h",
+ "impl/name_traits.h",
+ "impl/page_bloom_filter.h",
+ "impl/page_memory.cc",
+ "impl/page_memory.h",
+ "impl/page_pool.cc",
+ "impl/page_pool.h",
+ "impl/persistent.h",
+ "impl/persistent_node.cc",
+ "impl/persistent_node.h",
+ "impl/process_heap.cc",
+ "impl/process_heap.h",
+ "impl/thread_state.cc",
+ "impl/thread_state.h",
+ "impl/thread_state_scopes.h",
+ "impl/thread_state_statistics.cc",
+ "impl/thread_state_statistics.h",
+ "impl/threading_traits.h",
+ "impl/trace_traits.h",
+ "impl/unified_heap_controller.cc",
+ "impl/unified_heap_controller.h",
+ "impl/unified_heap_marking_visitor.cc",
+ "impl/unified_heap_marking_visitor.h",
+ "impl/visitor.h",
+ "impl/worklist.h",
+ ]
+ }
+
if (!is_debug && !optimize_for_size) {
configs -= [ "//build/config/compiler:default_optimization" ]
configs += [ "//build/config/compiler:optimize_max" ]
+ } else if (using_mismatched_sample_profile) {
+ configs -= [ "//build/config/compiler:afdo_optimize_size" ]
}
visibility = [
diff --git a/chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md b/chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md
index 2ccf1b181f8..b2c71f1c037 100644
--- a/chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md
+++ b/chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md
@@ -239,7 +239,7 @@ It may take some time for the pointer in a `WeakMember<T>` to become `nullptr` a
because this rewrite is only done within Blink GC's garbage collection period.
```c++
-class SomeGarbageCollectedClass : public GarbageCollected<GarbageCollectedSomething> {
+class SomeGarbageCollectedClass : public GarbageCollected<SomeGarbageCollectedClass> {
...
private:
Member<AnotherGarbageCollectedClass> another_; // OK, retained by Member<T>.
diff --git a/chromium/third_party/blink/renderer/platform/heap/blink_gc.h b/chromium/third_party/blink/renderer/platform/heap/blink_gc.h
index e6a47ee9bdf..bba521667cf 100644
--- a/chromium/third_party/blink/renderer/platform/heap/blink_gc.h
+++ b/chromium/third_party/blink/renderer/platform/heap/blink_gc.h
@@ -1,126 +1,16 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
+// 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_BLINK_GC_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_BLINK_GC_H_
-// BlinkGC.h is a file that defines common things used by Blink GC.
+#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-#define PRINT_HEAP_STATS 0 // Enable this macro to print heap stats to stderr.
-
-namespace blink {
-
-class LivenessBroker;
-class MarkingVisitor;
-class Visitor;
-
-using Address = uint8_t*;
-using ConstAddress = const uint8_t*;
-
-using VisitorCallback = void (*)(Visitor*, const void*);
-using MarkingVisitorCallback = void (*)(MarkingVisitor*, const void*);
-using TraceCallback = VisitorCallback;
-using WeakCallback = void (*)(const LivenessBroker&, const void*);
-using EphemeronCallback = VisitorCallback;
-
-// Simple alias to avoid heap compaction type signatures turning into
-// a sea of generic |void*|s.
-using MovableReference = const void*;
-
-// List of all arenas. Includes typed arenas as well.
-#define FOR_EACH_ARENA(H) \
- H(NormalPage1) \
- H(NormalPage2) \
- H(NormalPage3) \
- H(NormalPage4) \
- H(Vector) \
- H(HashTable) \
- H(Node) \
- H(CSSValue) \
- H(LargeObject)
-
-class PLATFORM_EXPORT WorklistTaskId {
- public:
- static constexpr int MutatorThread = 0;
- static constexpr int ConcurrentThreadBase = 1;
-};
-
-class PLATFORM_EXPORT BlinkGC final {
- STATIC_ONLY(BlinkGC);
-
- public:
- // CollectionType represents generational collection. kMinor collects objects
- // in the young generation (i.e. allocated since the previous collection
- // cycle, since we use sticky bits), kMajor collects the entire heap.
- enum class CollectionType { kMinor, kMajor };
-
- // When garbage collecting we need to know whether or not there
- // can be pointers to Blink GC managed objects on the stack for
- // each thread. When threads reach a safe point they record
- // whether or not they have pointers on the stack.
- enum StackState { kNoHeapPointersOnStack, kHeapPointersOnStack };
-
- enum MarkingType {
- // The marking completes synchronously.
- kAtomicMarking,
- // The marking task is split and executed in chunks (either on the mutator
- // thread or concurrently).
- kIncrementalAndConcurrentMarking
- };
-
- enum SweepingType {
- // The sweeping task is split into chunks and scheduled lazily and
- // concurrently.
- kConcurrentAndLazySweeping,
- // The sweeping task executes synchronously right after marking.
- kEagerSweeping,
- };
-
- // Commented out reasons have been used in the past but are not used any
- // longer. We keep them here as the corresponding UMA histograms cannot be
- // changed.
- enum class GCReason {
- // kIdleGC = 0
- // kPreciseGC = 1
- // kConservativeGC = 2
- kForcedGCForTesting = 3,
- // kMemoryPressureGC = 4
- // kPageNavigationGC = 5
- kThreadTerminationGC = 6,
- // kTesting = 7
- // kIncrementalIdleGC = 8
- // kIncrementalV8FollowupGC = 9
- kUnifiedHeapGC = 10,
- kUnifiedHeapForMemoryReductionGC = 11,
- kUnifiedHeapForcedForTestingGC = 12,
- // Used by UMA_HISTOGRAM_ENUMERATION macro.
- kMaxValue = kUnifiedHeapForcedForTestingGC,
- };
-
-#define DeclareArenaIndex(name) k##name##ArenaIndex,
- enum ArenaIndices {
- FOR_EACH_ARENA(DeclareArenaIndex)
- // Values used for iteration of heap segments.
- kNumberOfArenas,
- };
-#undef DeclareArenaIndex
-
- enum V8GCType {
- kV8MinorGC,
- kV8MajorGC,
- };
-
- static const char* ToString(GCReason);
- static const char* ToString(MarkingType);
- static const char* ToString(StackState);
- static const char* ToString(SweepingType);
- static const char* ToString(ArenaIndices);
-};
-
-} // namespace blink
+#if BUILDFLAG(BLINK_HEAP_USE_V8_OILPAN)
+#include "third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc.h"
+#else // !BLINK_HEAP_USE_V8_OILPAN
+#include "third_party/blink/renderer/platform/heap/impl/blink_gc.h"
+#endif // !BLINK_HEAP_USE_V8_OILPAN
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_BLINK_GC_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h b/chromium/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h
index 42be7084019..e3216e12529 100644
--- a/chromium/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h
+++ b/chromium/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h
@@ -1,47 +1,16 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
+// 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_BLINK_GC_MEMORY_DUMP_PROVIDER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_BLINK_GC_MEMORY_DUMP_PROVIDER_H_
-#include "base/trace_event/memory_dump_provider.h"
-#include "third_party/blink/renderer/platform/heap/blink_gc.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-namespace base {
-class SingleThreadTaskRunner;
-} // namespace base
-
-namespace blink {
-
-class ThreadState;
-
-class PLATFORM_EXPORT BlinkGCMemoryDumpProvider final
- : public base::trace_event::MemoryDumpProvider {
- USING_FAST_MALLOC(BlinkGCMemoryDumpProvider);
-
- public:
- enum class HeapType { kBlinkMainThread, kBlinkWorkerThread };
-
- ~BlinkGCMemoryDumpProvider() final;
- BlinkGCMemoryDumpProvider(
- ThreadState* thread_state,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- HeapType heap_type);
-
- // MemoryDumpProvider implementation.
- bool OnMemoryDump(const base::trace_event::MemoryDumpArgs&,
- base::trace_event::ProcessMemoryDump*) final;
-
- private:
- ThreadState* const thread_state_;
- const HeapType heap_type_;
- const std::string dump_base_name_;
-};
-
-} // namespace blink
+#if BUILDFLAG(BLINK_HEAP_USE_V8_OILPAN)
+#include "third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.h"
+#else // !BLINK_HEAP_USE_V8_OILPAN
+#include "third_party/blink/renderer/platform/heap/impl/blink_gc_memory_dump_provider.h"
+#endif // !BLINK_HEAP_USE_V8_OILPAN
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_BLINK_GC_MEMORY_DUMP_PROVIDER_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h b/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h
index e91e2e194a3..27460c3acca 100644
--- a/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h
+++ b/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h
@@ -5,9 +5,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_COLLECTION_SUPPORT_HEAP_HASH_TABLE_BACKING_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_COLLECTION_SUPPORT_HEAP_HASH_TABLE_BACKING_H_
-#include "third_party/blink/renderer/platform/heap/heap_page.h"
-#include "third_party/blink/renderer/platform/heap/threading_traits.h"
-#include "third_party/blink/renderer/platform/heap/trace_traits.h"
+#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
+#include "third_party/blink/renderer/platform/heap/impl/threading_traits.h"
+#include "third_party/blink/renderer/platform/heap/impl/trace_traits.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/conditional_destructor.h"
@@ -199,7 +199,8 @@ class ConcurrentBucket {
private:
// Alignment is needed for atomic accesses to |buf_| and to assure |buf_|
// can be accessed the same as objects of type T
- alignas(std::max(alignof(T), sizeof(size_t))) char buf_[sizeof(T)];
+ static constexpr size_t boundary = std::max(alignof(T), sizeof(size_t));
+ alignas(boundary) char buf_[sizeof(T)];
};
template <typename Key, typename Value>
@@ -223,7 +224,8 @@ class ConcurrentBucket<KeyValuePair<Key, Value>> {
private:
// Alignment is needed for atomic accesses to |buf_| and to assure |buf_|
// can be accessed the same as objects of type Key
- alignas(std::max(alignof(Key), sizeof(size_t))) char buf_[sizeof(Key)];
+ static constexpr size_t boundary = std::max(alignof(Key), sizeof(size_t));
+ alignas(boundary) char buf_[sizeof(Key)];
const Value* value_;
};
@@ -339,11 +341,7 @@ struct TraceKeyValuePairInCollectionTrait {
// The following passes on kNoWeakHandling for tracing value as the value
// callback is only invoked to keep value alive iff key is alive,
// following ephemeron semantics.
- visitor->TraceEphemeron(
- *helper.key, helper.value,
- blink::TraceCollectionIfEnabled<
- kNoWeakHandling, typename EphemeronHelper::ValueType,
- typename EphemeronHelper::ValueTraits>::Trace);
+ visitor->TraceEphemeron(*helper.key, helper.value);
}
};
diff --git a/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h b/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h
index 07c97e2e068..12b72b78ee9 100644
--- a/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h
+++ b/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h
@@ -6,13 +6,13 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_COLLECTION_SUPPORT_HEAP_VECTOR_BACKING_H_
#include "base/check_op.h"
-#include "third_party/blink/renderer/platform/heap/finalizer_traits.h"
-#include "third_party/blink/renderer/platform/heap/gc_info.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
+#include "third_party/blink/renderer/platform/heap/impl/finalizer_traits.h"
+#include "third_party/blink/renderer/platform/heap/impl/gc_info.h"
+#include "third_party/blink/renderer/platform/heap/impl/threading_traits.h"
+#include "third_party/blink/renderer/platform/heap/impl/trace_traits.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/heap/threading_traits.h"
-#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/vector.h"
diff --git a/chromium/third_party/blink/renderer/platform/heap/disallow_new_wrapper.h b/chromium/third_party/blink/renderer/platform/heap/disallow_new_wrapper.h
index 1d3b1f3031f..9d60caf37f6 100644
--- a/chromium/third_party/blink/renderer/platform/heap/disallow_new_wrapper.h
+++ b/chromium/third_party/blink/renderer/platform/heap/disallow_new_wrapper.h
@@ -1,53 +1,16 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// 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_DISALLOW_NEW_WRAPPER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_DISALLOW_NEW_WRAPPER_H_
-#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/visitor.h"
+#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-namespace blink {
-
-// DisallowNewWrapper wraps a disallow new type in a GarbageCollected class.
-template <typename T>
-class DisallowNewWrapper final
- : public GarbageCollected<DisallowNewWrapper<T>> {
- public:
- explicit DisallowNewWrapper(const T& value) : value_(value) {
- static_assert(WTF::IsDisallowNew<T>::value,
- "T needs to be a disallow new type");
- static_assert(WTF::IsTraceable<T>::value, "T needs to be traceable");
- }
- explicit DisallowNewWrapper(T&& value) : value_(std::forward<T>(value)) {
- static_assert(WTF::IsDisallowNew<T>::value,
- "T needs to be a disallow new type");
- static_assert(WTF::IsTraceable<T>::value, "T needs to be traceable");
- }
-
- const T& Value() const { return value_; }
- T&& TakeValue() { return std::move(value_); }
-
- void Trace(Visitor* visitor) const { visitor->Trace(value_); }
-
- private:
- T value_;
-};
-
-// Wraps a disallow new type in a GarbageCollected class, making it possible to
-// be referenced off heap from a Persistent.
-template <typename T>
-DisallowNewWrapper<T>* WrapDisallowNew(const T& value) {
- return MakeGarbageCollected<DisallowNewWrapper<T>>(value);
-}
-
-template <typename T>
-DisallowNewWrapper<T>* WrapDisallowNew(T&& value) {
- return MakeGarbageCollected<DisallowNewWrapper<T>>(std::forward<T>(value));
-}
-
-} // namespace blink
+#if BUILDFLAG(BLINK_HEAP_USE_V8_OILPAN)
+#include "third_party/blink/renderer/platform/heap/v8_wrapper/disallow_new_wrapper.h"
+#else // !BLINK_HEAP_USE_V8_OILPAN
+#include "third_party/blink/renderer/platform/heap/impl/disallow_new_wrapper.h"
+#endif // !BLINK_HEAP_USE_V8_OILPAN
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_DISALLOW_NEW_WRAPPER_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/garbage_collected.h b/chromium/third_party/blink/renderer/platform/heap/garbage_collected.h
index dfd6a12c930..93715933385 100644
--- a/chromium/third_party/blink/renderer/platform/heap/garbage_collected.h
+++ b/chromium/third_party/blink/renderer/platform/heap/garbage_collected.h
@@ -1,117 +1,16 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
+// 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_GARBAGE_COLLECTED_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_GARBAGE_COLLECTED_H_
-#include "base/macros.h"
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/assertions.h"
-#include "third_party/blink/renderer/platform/wtf/type_traits.h"
+#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-namespace blink {
+#if BUILDFLAG(BLINK_HEAP_USE_V8_OILPAN)
+#include "third_party/blink/renderer/platform/heap/v8_wrapper/garbage_collected.h"
+#else // !BLINK_HEAP_USE_V8_OILPAN
+#include "third_party/blink/renderer/platform/heap/impl/garbage_collected.h"
+#endif // !BLINK_HEAP_USE_V8_OILPAN
-template <typename T>
-class GarbageCollected;
-
-// GC_PLUGIN_IGNORE is used to make the plugin ignore a particular class or
-// field when checking for proper usage. When using GC_PLUGIN_IGNORE
-// a bug-number should be provided as an argument where the bug describes
-// what needs to happen to remove the GC_PLUGIN_IGNORE again.
-#if defined(__clang__)
-#define GC_PLUGIN_IGNORE(bug) \
- __attribute__((annotate("blink_gc_plugin_ignore")))
-#else
-#define GC_PLUGIN_IGNORE(bug)
-#endif
-
-// Template to determine if a class is a GarbageCollectedMixin by checking if it
-// has IsGarbageCollectedMixinMarker
-template <typename T>
-struct IsGarbageCollectedMixin {
- private:
- typedef char YesType;
- struct NoType {
- char padding[8];
- };
-
- template <typename U>
- static YesType CheckMarker(typename U::IsGarbageCollectedMixinMarker*);
- template <typename U>
- static NoType CheckMarker(...);
-
- public:
- static const bool value = sizeof(CheckMarker<T>(nullptr)) == sizeof(YesType);
-};
-
-// TraceDescriptor is used to describe how to trace an object.
-struct TraceDescriptor {
- STACK_ALLOCATED();
-
- public:
- // The adjusted base pointer of the object that should be traced.
- const void* base_object_payload;
- // A callback for tracing the object.
- TraceCallback callback;
-};
-
-// The GarbageCollectedMixin interface can be used to automatically define
-// TraceTrait/ObjectAliveTrait on non-leftmost deriving classes which need
-// to be garbage collected.
-class PLATFORM_EXPORT GarbageCollectedMixin {
- public:
- typedef int IsGarbageCollectedMixinMarker;
- virtual void Trace(Visitor*) const {}
-};
-
-// Base class for objects allocated in the Blink garbage-collected heap.
-//
-// Instances of GarbageCollected will be finalized if they are non-trivially
-// destructible.
-template <typename T>
-class GarbageCollected;
-
-template <typename T,
- bool = WTF::IsSubclassOfTemplate<typename std::remove_const<T>::type,
- GarbageCollected>::value>
-class NeedsAdjustPointer;
-
-template <typename T>
-class NeedsAdjustPointer<T, true> {
- static_assert(sizeof(T), "T must be fully defined");
-
- public:
- static const bool value = false;
-};
-
-template <typename T>
-class NeedsAdjustPointer<T, false> {
- static_assert(sizeof(T), "T must be fully defined");
-
- public:
- static const bool value =
- IsGarbageCollectedMixin<typename std::remove_const<T>::type>::value;
-};
-
-// TODO(sof): migrate to wtf/TypeTraits.h
-template <typename T>
-class IsFullyDefined {
- using TrueType = char;
- struct FalseType {
- char dummy[2];
- };
-
- template <typename U, size_t sz = sizeof(U)>
- static TrueType IsSizeofKnown(U*);
- static FalseType IsSizeofKnown(...);
- static T& t_;
-
- public:
- static const bool value = sizeof(TrueType) == sizeof(IsSizeofKnown(&t_));
-};
-
-} // namespace blink
-
-#endif
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_GARBAGE_COLLECTED_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/gc_task_runner.h b/chromium/third_party/blink/renderer/platform/heap/gc_task_runner.h
index b00f3b24d1f..758506b7e07 100644
--- a/chromium/third_party/blink/renderer/platform/heap/gc_task_runner.h
+++ b/chromium/third_party/blink/renderer/platform/heap/gc_task_runner.h
@@ -1,90 +1,16 @@
-/*
- * Copyright (C) 2014 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
+// 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_GC_TASK_RUNNER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_GC_TASK_RUNNER_H_
-#include <memory>
-#include "base/location.h"
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
-#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-namespace blink {
+#if BUILDFLAG(BLINK_HEAP_USE_V8_OILPAN)
+#include "third_party/blink/renderer/platform/heap/v8_wrapper/gc_task_runner.h"
+#else // !BLINK_HEAP_USE_V8_OILPAN
+#include "third_party/blink/renderer/platform/heap/impl/gc_task_runner.h"
+#endif // !BLINK_HEAP_USE_V8_OILPAN
-class GCTaskObserver final : public Thread::TaskObserver {
- USING_FAST_MALLOC(GCTaskObserver);
-
- public:
- GCTaskObserver() : nesting_(0) {}
-
- ~GCTaskObserver() override {
- // m_nesting can be 1 if this was unregistered in a task and
- // didProcessTask was not called.
- DCHECK(!nesting_ || nesting_ == 1);
- }
-
- void WillProcessTask(const base::PendingTask&, bool) override { nesting_++; }
-
- void DidProcessTask(const base::PendingTask&) override {
- // In the production code WebKit::initialize is called from inside the
- // message loop so we can get didProcessTask() without corresponding
- // willProcessTask once. This is benign.
- if (nesting_)
- nesting_--;
-
- ThreadState::Current()->SafePoint(nesting_
- ? BlinkGC::kHeapPointersOnStack
- : BlinkGC::kNoHeapPointersOnStack);
- }
-
- private:
- int nesting_;
-};
-
-class GCTaskRunner final {
- USING_FAST_MALLOC(GCTaskRunner);
-
- public:
- explicit GCTaskRunner(Thread* thread)
- : gc_task_observer_(std::make_unique<GCTaskObserver>()), thread_(thread) {
- thread_->AddTaskObserver(gc_task_observer_.get());
- }
-
- ~GCTaskRunner() { thread_->RemoveTaskObserver(gc_task_observer_.get()); }
-
- private:
- std::unique_ptr<GCTaskObserver> gc_task_observer_;
- Thread* thread_;
-};
-
-} // namespace blink
-
-#endif
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_GC_TASK_RUNNER_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/handle.h b/chromium/third_party/blink/renderer/platform/heap/handle.h
index 9df15cc43d6..ee07268f578 100644
--- a/chromium/third_party/blink/renderer/platform/heap/handle.h
+++ b/chromium/third_party/blink/renderer/platform/heap/handle.h
@@ -38,7 +38,6 @@
#include "third_party/blink/renderer/platform/heap/member.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
#include "third_party/blink/renderer/platform/heap/thread_state_scopes.h"
-#include "third_party/blink/renderer/platform/heap/trace_traits.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap.h b/chromium/third_party/blink/renderer/platform/heap/heap.h
index f27916bac06..7cbe94f71ec 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap.h
@@ -1,732 +1,16 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
+// 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_HEAP_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_H_
-#include <limits>
-#include <memory>
+#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-#include "base/macros.h"
-#include "build/build_config.h"
-#include "third_party/blink/renderer/platform/heap/finalizer_traits.h"
-#include "third_party/blink/renderer/platform/heap/gc_info.h"
-#include "third_party/blink/renderer/platform/heap/heap_page.h"
-#include "third_party/blink/renderer/platform/heap/process_heap.h"
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/heap/thread_state_statistics.h"
-#include "third_party/blink/renderer/platform/heap/visitor.h"
-#include "third_party/blink/renderer/platform/heap/worklist.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/assertions.h"
-#include "third_party/blink/renderer/platform/wtf/forward.h"
-#include "third_party/blink/renderer/platform/wtf/sanitizers.h"
-
-namespace blink {
-
-namespace incremental_marking_test {
-class IncrementalMarkingScopeBase;
-} // namespace incremental_marking_test
-
-class ConcurrentMarkingVisitor;
-class ThreadHeapStatsCollector;
-class PageBloomFilter;
-class PagePool;
-class ProcessHeapReporter;
-class RegionTree;
-class MarkingSchedulingOracle;
-
-using MarkingItem = TraceDescriptor;
-using NotFullyConstructedItem = const void*;
-
-struct EphemeronPairItem {
- const void* key;
- const void* value;
- TraceCallback value_trace_callback;
-};
-
-struct CustomCallbackItem {
- WeakCallback callback;
- const void* parameter;
-};
-
-struct NotSafeToConcurrentlyTraceItem {
- TraceDescriptor desc;
- size_t bailout_size;
-};
-
-using V8Reference = const TraceWrapperV8Reference<v8::Value>*;
-
-// Segment size of 512 entries necessary to avoid throughput regressions. Since
-// the work list is currently a temporary object this is not a problem.
-using MarkingWorklist = Worklist<MarkingItem, 512 /* local entries */>;
-using WriteBarrierWorklist = Worklist<HeapObjectHeader*, 64>;
-using NotFullyConstructedWorklist =
- Worklist<NotFullyConstructedItem, 16 /* local entries */>;
-using WeakCallbackWorklist =
- Worklist<CustomCallbackItem, 64 /* local entries */>;
-// Using large local segments here (sized 512 entries) to avoid throughput
-// regressions.
-using MovableReferenceWorklist =
- Worklist<const MovableReference*, 256 /* local entries */>;
-using EphemeronPairsWorklist =
- Worklist<EphemeronPairItem, 64 /* local entries */>;
-using V8ReferencesWorklist = Worklist<V8Reference, 16 /* local entries */>;
-using NotSafeToConcurrentlyTraceWorklist =
- Worklist<NotSafeToConcurrentlyTraceItem, 64 /* local entries */>;
-
-class PLATFORM_EXPORT HeapAllocHooks {
- STATIC_ONLY(HeapAllocHooks);
-
- public:
- // TODO(hajimehoshi): Pass a type name of the allocated object.
- typedef void AllocationHook(Address, size_t, const char*);
- typedef void FreeHook(Address);
-
- // Sets allocation hook. Only one hook is supported.
- static void SetAllocationHook(AllocationHook* hook) {
- CHECK(!allocation_hook_ || !hook);
- allocation_hook_ = hook;
- }
-
- // Sets free hook. Only one hook is supported.
- static void SetFreeHook(FreeHook* hook) {
- CHECK(!free_hook_ || !hook);
- free_hook_ = hook;
- }
-
- static void AllocationHookIfEnabled(Address address,
- size_t size,
- const char* type_name) {
- AllocationHook* allocation_hook = allocation_hook_;
- if (UNLIKELY(!!allocation_hook))
- allocation_hook(address, size, type_name);
- }
-
- static void FreeHookIfEnabled(Address address) {
- FreeHook* free_hook = free_hook_;
- if (UNLIKELY(!!free_hook))
- free_hook(address);
- }
-
- private:
- static AllocationHook* allocation_hook_;
- static FreeHook* free_hook_;
-};
-
-class HeapCompact;
-template <typename T>
-class Member;
-template <typename T>
-class WeakMember;
-template <typename T>
-class UntracedMember;
-
-namespace internal {
-
-class LivenessBrokerFactory;
-
-template <typename T, bool = NeedsAdjustPointer<T>::value>
-class ObjectAliveTrait;
-
-template <typename T>
-class ObjectAliveTrait<T, false> {
- STATIC_ONLY(ObjectAliveTrait);
-
- public:
- static bool IsHeapObjectAlive(const T* object) {
- static_assert(sizeof(T), "T must be fully defined");
- return HeapObjectHeader::FromPayload(object)->IsMarked();
- }
-};
-
-template <typename T>
-class ObjectAliveTrait<T, true> {
- STATIC_ONLY(ObjectAliveTrait);
-
- public:
- NO_SANITIZE_ADDRESS
- static bool IsHeapObjectAlive(const T* object) {
- static_assert(sizeof(T), "T must be fully defined");
- const HeapObjectHeader* header = HeapObjectHeader::FromPayload(
- TraceTrait<T>::GetTraceDescriptor(object).base_object_payload);
- DCHECK(!header->IsInConstruction() || header->IsMarked());
- return header->IsMarked();
- }
-};
-
-template <typename T, typename = int>
-struct IsGarbageCollectedContainer : std::false_type {};
-
-template <typename T>
-struct IsGarbageCollectedContainer<
- T,
- typename T::IsGarbageCollectedCollectionTypeMarker> : std::true_type {};
-
-} // namespace internal
-
-class PLATFORM_EXPORT ThreadHeap {
- USING_FAST_MALLOC(ThreadHeap);
-
- using EphemeronProcessing = ThreadState::EphemeronProcessing;
-
- public:
- explicit ThreadHeap(ThreadState*);
- ~ThreadHeap();
-
- MarkingWorklist* GetMarkingWorklist() const {
- return marking_worklist_.get();
- }
-
- WriteBarrierWorklist* GetWriteBarrierWorklist() const {
- return write_barrier_worklist_.get();
- }
-
- NotFullyConstructedWorklist* GetNotFullyConstructedWorklist() const {
- return not_fully_constructed_worklist_.get();
- }
-
- NotFullyConstructedWorklist* GetPreviouslyNotFullyConstructedWorklist()
- const {
- return previously_not_fully_constructed_worklist_.get();
- }
-
- WeakCallbackWorklist* GetWeakCallbackWorklist() const {
- return weak_callback_worklist_.get();
- }
-
- MovableReferenceWorklist* GetMovableReferenceWorklist() const {
- return movable_reference_worklist_.get();
- }
-
- EphemeronPairsWorklist* GetDiscoveredEphemeronPairsWorklist() const {
- return discovered_ephemeron_pairs_worklist_.get();
- }
-
- EphemeronPairsWorklist* GetEphemeronPairsToProcessWorklist() const {
- return ephemeron_pairs_to_process_worklist_.get();
- }
-
- V8ReferencesWorklist* GetV8ReferencesWorklist() const {
- return v8_references_worklist_.get();
- }
-
- NotSafeToConcurrentlyTraceWorklist* GetNotSafeToConcurrentlyTraceWorklist()
- const {
- return not_safe_to_concurrently_trace_worklist_.get();
- }
- // Register an ephemeron table for fixed-point iteration.
- void RegisterWeakTable(void* container_object,
- EphemeronCallback);
-
- // Heap compaction registration methods:
-
- // Checks whether we need to register |addr| as a backing store or a slot
- // containing reference to it.
- bool ShouldRegisterMovingAddress();
-
- RegionTree* GetRegionTree() { return region_tree_.get(); }
-
- static inline size_t AllocationSizeFromSize(size_t size) {
- // Add space for header.
- size_t allocation_size = size + sizeof(HeapObjectHeader);
- // The allocation size calculation can overflow for large sizes.
- CHECK_GT(allocation_size, size);
- // Align size with allocation granularity.
- allocation_size = (allocation_size + kAllocationMask) & ~kAllocationMask;
- return allocation_size;
- }
- Address AllocateOnArenaIndex(ThreadState*,
- size_t,
- int arena_index,
- uint32_t gc_info_index,
- const char* type_name);
- template <typename T>
- static Address Allocate(size_t);
-
- void WeakProcessing(MarkingVisitor*);
-
- // Moves not fully constructed objects to previously not fully constructed
- // objects. Such objects can be iterated using the Trace() method and do
- // not need to rely on conservative handling.
- void FlushNotFullyConstructedObjects();
-
- // Moves ephemeron pairs from |discovered_ephemeron_pairs_worklist_| to
- // |ephemeron_pairs_to_process_worklist_|
- void FlushEphemeronPairs(EphemeronProcessing);
-
- // Marks not fully constructed objects.
- void MarkNotFullyConstructedObjects(MarkingVisitor*);
- // Marks the transitive closure including ephemerons.
- bool AdvanceMarking(MarkingVisitor*, base::TimeTicks, EphemeronProcessing);
- void VerifyMarking();
-
- // Returns true if concurrent markers will have work to steal
- bool HasWorkForConcurrentMarking() const;
- // Returns the amount of work currently available for stealing (there could be
- // work remaining even if this is 0).
- size_t ConcurrentMarkingGlobalWorkSize() const;
- // Returns true if marker is done
- bool AdvanceConcurrentMarking(ConcurrentMarkingVisitor*,
- base::JobDelegate*,
- MarkingSchedulingOracle* marking_scheduler);
-
- // Conservatively checks whether an address is a pointer in any of the
- // thread heaps. If so marks the object pointed to as live.
- Address CheckAndMarkPointer(MarkingVisitor*, Address);
-
- // Visits remembered sets.
- void VisitRememberedSets(MarkingVisitor*);
-
- size_t ObjectPayloadSizeForTesting();
- void ResetAllocationPointForTesting();
-
- PagePool* GetFreePagePool() { return free_page_pool_.get(); }
-
- // This look-up uses the region search tree and a negative contains cache to
- // provide an efficient mapping from arbitrary addresses to the containing
- // heap-page if one exists.
- BasePage* LookupPageForAddress(ConstAddress);
-
- HeapCompact* Compaction();
-
- // Get one of the heap structures for this thread.
- // The thread heap is split into multiple heap parts based on object types
- // and object sizes.
- BaseArena* Arena(int arena_index) const {
- DCHECK_LE(0, arena_index);
- DCHECK_LT(arena_index, BlinkGC::kNumberOfArenas);
- return arenas_[arena_index];
- }
-
- static bool IsVectorArenaIndex(int arena_index) {
- return BlinkGC::kVectorArenaIndex == arena_index;
- }
- static bool IsNormalArenaIndex(int);
-
- void MakeConsistentForGC();
- // MakeConsistentForMutator() drops marks from marked objects and rebuild
- // free lists. This is called after taking a snapshot and before resuming
- // the executions of mutators.
- void MakeConsistentForMutator();
-
- // Unmarks all objects in the entire heap. This is supposed to be called in
- // the beginning of major GC.
- void Unmark();
-
- void Compact();
-
- bool AdvanceLazySweep(base::TimeTicks deadline);
- bool AdvanceConcurrentSweep(base::JobDelegate*);
-
- void PrepareForSweep(BlinkGC::CollectionType);
- void RemoveAllPages();
- void InvokeFinalizersOnSweptPages();
- void CompleteSweep();
-
- void CollectStatistics(ThreadState::Statistics* statistics);
-
- ThreadHeapStatsCollector* stats_collector() const {
- return heap_stats_collector_.get();
- }
-
-#if defined(ADDRESS_SANITIZER)
- void PoisonUnmarkedObjects();
-#endif
-
-#if DCHECK_IS_ON()
- // Infrastructure to determine if an address is within one of the
- // address ranges for the Blink heap. If the address is in the Blink
- // heap the containing heap page is returned.
- BasePage* FindPageFromAddress(Address);
- BasePage* FindPageFromAddress(const void* pointer) {
- return FindPageFromAddress(
- reinterpret_cast<Address>(const_cast<void*>(pointer)));
- }
-#endif
-
- PageBloomFilter* page_bloom_filter() { return page_bloom_filter_.get(); }
-
- bool IsInLastAllocatedRegion(Address address) const;
- void SetLastAllocatedRegion(Address start, size_t length);
-
- private:
- struct LastAllocatedRegion {
- Address start = nullptr;
- size_t length = 0;
- };
-
- static int ArenaIndexForObjectSize(size_t);
-
- void SetupWorklists(bool);
- void DestroyMarkingWorklists(BlinkGC::StackState);
- void DestroyCompactionWorklists();
-
- bool InvokeEphemeronCallbacks(EphemeronProcessing,
- MarkingVisitor*,
- base::TimeTicks);
-
- bool FlushV8References(base::TimeTicks);
-
- ThreadState* thread_state_;
- std::unique_ptr<ThreadHeapStatsCollector> heap_stats_collector_;
- std::unique_ptr<RegionTree> region_tree_;
- std::unique_ptr<PageBloomFilter> page_bloom_filter_;
- std::unique_ptr<PagePool> free_page_pool_;
- std::unique_ptr<ProcessHeapReporter> process_heap_reporter_;
-
- // All objects on this worklist have been fully initialized and assigned a
- // trace callback for iterating the body of the object. This worklist should
- // contain almost all objects.
- std::unique_ptr<MarkingWorklist> marking_worklist_;
-
- // Objects on this worklist have been collected in the write barrier. The
- // worklist is different from |marking_worklist_| to minimize execution in the
- // path where a write barrier is executed.
- std::unique_ptr<WriteBarrierWorklist> write_barrier_worklist_;
-
- // Objects on this worklist were observed to be in construction (in their
- // constructor) and thus have been delayed for processing. They have not yet
- // been assigned a valid header and trace callback.
- std::unique_ptr<NotFullyConstructedWorklist> not_fully_constructed_worklist_;
-
- // Objects on this worklist were previously in construction but have been
- // moved here upon observing a safepoint, i.e., processing without stack. They
- // have not yet been assigned a valid header and trace callback but are fully
- // specified and can thus be iterated using the trace callback (which can be
- // looked up dynamically).
- std::unique_ptr<NotFullyConstructedWorklist>
- previously_not_fully_constructed_worklist_;
-
- // Worklist of weak callbacks accumulated for objects. Such callbacks are
- // processed after finishing marking objects.
- std::unique_ptr<WeakCallbackWorklist> weak_callback_worklist_;
-
- // The worklist is to remember slots that are traced during
- // marking phases. The mapping between the slots and the backing stores are
- // created at the atomic pause phase.
- std::unique_ptr<MovableReferenceWorklist> movable_reference_worklist_;
-
- // Worklist of ephemeron callbacks. Used to pass new callbacks from
- // MarkingVisitor to ThreadHeap.
- std::unique_ptr<EphemeronPairsWorklist> discovered_ephemeron_pairs_worklist_;
- std::unique_ptr<EphemeronPairsWorklist> ephemeron_pairs_to_process_worklist_;
-
- // Worklist for storing the V8 references until ThreadHeap can flush them
- // to V8.
- std::unique_ptr<V8ReferencesWorklist> v8_references_worklist_;
-
- std::unique_ptr<NotSafeToConcurrentlyTraceWorklist>
- not_safe_to_concurrently_trace_worklist_;
-
- std::unique_ptr<HeapCompact> compaction_;
-
- LastAllocatedRegion last_allocated_region_;
-
- BaseArena* arenas_[BlinkGC::kNumberOfArenas];
-
- static ThreadHeap* main_thread_heap_;
-
- static constexpr size_t kStepsBeforeEphemeronPairsFlush = 4u;
- size_t steps_since_last_ephemeron_pairs_flush_ = 0;
- static constexpr size_t kStepsBeforeEphemeronProcessing = 16u;
- size_t steps_since_last_ephemeron_processing_ = 0;
-
- friend class incremental_marking_test::IncrementalMarkingScopeBase;
- template <typename T>
- friend class Member;
- friend class ThreadState;
-};
-
-template <typename T>
-class GarbageCollected {
- IS_GARBAGE_COLLECTED_TYPE();
-
- public:
- using ParentMostGarbageCollectedType = T;
-
- // Must use MakeGarbageCollected.
- void* operator new(size_t) = delete;
- void* operator new[](size_t) = delete;
- // The garbage collector is taking care of reclaiming the object. Also,
- // virtual destructor requires an unambiguous, accessible 'operator delete'.
- void operator delete(void*) { NOTREACHED(); }
- void operator delete[](void*) = delete;
-
- template <typename Derived>
- static void* AllocateObject(size_t size) {
- return ThreadHeap::Allocate<GCInfoFoldedType<Derived>>(size);
- }
-
- protected:
- // This trait in theory can be moved to gc_info.h, but that would cause
- // significant memory bloat caused by huge number of ThreadHeap::Allocate<>
- // instantiations, which linker is not able to fold.
- template <typename Derived>
- class GCInfoFolded {
- static constexpr bool is_virtual_destructor_at_base =
- std::has_virtual_destructor<ParentMostGarbageCollectedType>::value;
- static constexpr bool both_trivially_destructible =
- std::is_trivially_destructible<ParentMostGarbageCollectedType>::value &&
- std::is_trivially_destructible<Derived>::value;
- static constexpr bool has_custom_dispatch_at_base =
- internal::HasFinalizeGarbageCollectedObject<
- ParentMostGarbageCollectedType>::value;
-
- public:
- using Type = std::conditional_t<is_virtual_destructor_at_base ||
- both_trivially_destructible ||
- has_custom_dispatch_at_base,
- ParentMostGarbageCollectedType,
- Derived>;
- };
-
- template <typename Derived>
- using GCInfoFoldedType = typename GCInfoFolded<Derived>::Type;
-
- GarbageCollected() = default;
-
- DISALLOW_COPY_AND_ASSIGN(GarbageCollected);
-};
-
-// Used for passing custom sizes to MakeGarbageCollected.
-struct AdditionalBytes {
- explicit AdditionalBytes(size_t bytes) : value(bytes) {}
- const size_t value;
-};
-
-template <typename T>
-struct MakeGarbageCollectedTrait {
- template <typename... Args>
- static T* Call(Args&&... args) {
- static_assert(WTF::IsGarbageCollectedType<T>::value,
- "T needs to be a garbage collected object");
- static_assert(
- std::is_trivially_destructible<T>::value ||
- std::has_virtual_destructor<T>::value || std::is_final<T>::value ||
- internal::IsGarbageCollectedContainer<T>::value ||
- internal::HasFinalizeGarbageCollectedObject<T>::value,
- "Finalized GarbageCollected class should either have a virtual "
- "destructor or be marked as final");
- static_assert(!IsGarbageCollectedMixin<T>::value ||
- sizeof(T) <= kLargeObjectSizeThreshold,
- "GarbageCollectedMixin may not be a large object");
- void* memory = T::template AllocateObject<T>(sizeof(T));
- HeapObjectHeader* header = HeapObjectHeader::FromPayload(memory);
- // Placement new as regular operator new() is deleted.
- T* object = ::new (memory) T(std::forward<Args>(args)...);
- header->MarkFullyConstructed<HeapObjectHeader::AccessMode::kAtomic>();
- return object;
- }
-
- template <typename... Args>
- static T* Call(AdditionalBytes additional_bytes, Args&&... args) {
- static_assert(WTF::IsGarbageCollectedType<T>::value,
- "T needs to be a garbage collected object");
- static_assert(
- std::is_trivially_destructible<T>::value ||
- std::has_virtual_destructor<T>::value || std::is_final<T>::value ||
- internal::IsGarbageCollectedContainer<T>::value ||
- internal::HasFinalizeGarbageCollectedObject<T>::value,
- "Finalized GarbageCollected class should either have a virtual "
- "destructor or be marked as final.");
- const size_t size = sizeof(T) + additional_bytes.value;
- if (IsGarbageCollectedMixin<T>::value) {
- // Ban large mixin so we can use PageFromObject() on them.
- CHECK_GE(kLargeObjectSizeThreshold, size)
- << "GarbageCollectedMixin may not be a large object";
- }
- void* memory = T::template AllocateObject<T>(size);
- HeapObjectHeader* header = HeapObjectHeader::FromPayload(memory);
- // Placement new as regular operator new() is deleted.
- T* object = ::new (memory) T(std::forward<Args>(args)...);
- header->MarkFullyConstructed<HeapObjectHeader::AccessMode::kAtomic>();
- return object;
- }
-};
-
-template <typename T, typename = void>
-struct PostConstructionHookTrait {
- static void Call(T*) {}
-};
-
-// Default MakeGarbageCollected: Constructs an instance of T, which is a garbage
-// collected type.
-template <typename T, typename... Args>
-T* MakeGarbageCollected(Args&&... args) {
- T* object = MakeGarbageCollectedTrait<T>::Call(std::forward<Args>(args)...);
- PostConstructionHookTrait<T>::Call(object);
- return object;
-}
-
-// Constructs an instance of T, which is a garbage collected type. This special
-// version takes size which enables constructing inline objects.
-template <typename T, typename... Args>
-T* MakeGarbageCollected(AdditionalBytes additional_bytes, Args&&... args) {
- T* object = MakeGarbageCollectedTrait<T>::Call(additional_bytes,
- std::forward<Args>(args)...);
- PostConstructionHookTrait<T>::Call(object);
- return object;
-}
-
-// Assigning class types to their arenas.
-//
-// We use sized arenas for most 'normal' objects to improve memory locality.
-// It seems that the same type of objects are likely to be accessed together,
-// which means that we want to group objects by type. That's one reason
-// why we provide dedicated arenas for popular types (e.g., Node, CSSValue),
-// but it's not practical to prepare dedicated arenas for all types.
-// Thus we group objects by their sizes, hoping that this will approximately
-// group objects by their types.
-//
-
-inline int ThreadHeap::ArenaIndexForObjectSize(size_t size) {
- if (size < 64) {
- if (size < 32)
- return BlinkGC::kNormalPage1ArenaIndex;
- return BlinkGC::kNormalPage2ArenaIndex;
- }
- if (size < 128)
- return BlinkGC::kNormalPage3ArenaIndex;
- return BlinkGC::kNormalPage4ArenaIndex;
-}
-
-inline bool ThreadHeap::IsNormalArenaIndex(int index) {
- return index >= BlinkGC::kNormalPage1ArenaIndex &&
- index <= BlinkGC::kNormalPage4ArenaIndex;
-}
-
-inline Address ThreadHeap::AllocateOnArenaIndex(ThreadState* state,
- size_t size,
- int arena_index,
- uint32_t gc_info_index,
- const char* type_name) {
- DCHECK(state->IsAllocationAllowed());
- DCHECK_NE(arena_index, BlinkGC::kLargeObjectArenaIndex);
- NormalPageArena* arena = static_cast<NormalPageArena*>(Arena(arena_index));
- Address address =
- arena->AllocateObject(AllocationSizeFromSize(size), gc_info_index);
- HeapAllocHooks::AllocationHookIfEnabled(address, size, type_name);
- return address;
-}
-
-template <typename T>
-Address ThreadHeap::Allocate(size_t size) {
- ThreadState* state = ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
- const char* type_name = WTF_HEAP_PROFILER_TYPE_NAME(T);
- return state->Heap().AllocateOnArenaIndex(
- state, size, ThreadHeap::ArenaIndexForObjectSize(size),
- GCInfoTrait<T>::Index(), type_name);
-}
-
-inline bool ThreadHeap::IsInLastAllocatedRegion(Address address) const {
- return last_allocated_region_.start <= address &&
- address <
- (last_allocated_region_.start + last_allocated_region_.length);
-}
-
-inline void ThreadHeap::SetLastAllocatedRegion(Address start, size_t length) {
- last_allocated_region_.start = start;
- last_allocated_region_.length = length;
-}
-
-class PLATFORM_EXPORT LivenessBroker final {
- public:
- template <typename T>
- bool IsHeapObjectAlive(const T*) const;
- template <typename T>
- bool IsHeapObjectAlive(const WeakMember<T>&) const;
- template <typename T>
- bool IsHeapObjectAlive(const UntracedMember<T>&) const;
-
- private:
- LivenessBroker() = default;
- friend class internal::LivenessBrokerFactory;
-};
-
-template <typename T>
-bool LivenessBroker::IsHeapObjectAlive(const T* object) const {
- static_assert(sizeof(T), "T must be fully defined");
- // The strongification of collections relies on the fact that once a
- // collection has been strongified, there is no way that it can contain
- // non-live entries, so no entries will be removed. Since you can't set
- // the mark bit on a null pointer, that means that null pointers are
- // always 'alive'.
- if (!object)
- return true;
- // TODO(keishi): some tests create CrossThreadPersistent on non attached
- // threads.
- if (!ThreadState::Current())
- return true;
- DCHECK(&ThreadState::Current()->Heap() ==
- &PageFromObject(object)->Arena()->GetThreadState()->Heap());
- return internal::ObjectAliveTrait<T>::IsHeapObjectAlive(object);
-}
-
-template <typename T>
-bool LivenessBroker::IsHeapObjectAlive(const WeakMember<T>& weak_member) const {
- return IsHeapObjectAlive(weak_member.Get());
-}
-
-template <typename T>
-bool LivenessBroker::IsHeapObjectAlive(
- const UntracedMember<T>& untraced_member) const {
- return IsHeapObjectAlive(untraced_member.Get());
-}
-
-template <typename T>
-void Visitor::HandleWeakCell(const LivenessBroker& broker, const void* object) {
- WeakMember<T>* weak_member =
- reinterpret_cast<WeakMember<T>*>(const_cast<void*>(object));
- if (weak_member->Get()) {
- if (weak_member->IsHashTableDeletedValue()) {
- // This can happen when weak fields are deleted while incremental marking
- // is running. Deleted values need to be preserved to avoid reviving
- // objects in containers.
- return;
- }
- if (!broker.IsHeapObjectAlive(weak_member->Get()))
- weak_member->Clear();
- }
-}
-
-namespace internal {
-
-class LivenessBrokerFactory final {
- public:
- static LivenessBroker Create() { return LivenessBroker(); }
-};
-
-} // namespace internal
-
-} // namespace blink
+#if BUILDFLAG(BLINK_HEAP_USE_V8_OILPAN)
+#include "third_party/blink/renderer/platform/heap/v8_wrapper/heap.h"
+#else // !BLINK_HEAP_USE_V8_OILPAN
+#include "third_party/blink/renderer/platform/heap/impl/heap.h"
+#endif // !BLINK_HEAP_USE_V8_OILPAN
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_allocator.h b/chromium/third_party/blink/renderer/platform/heap/heap_allocator.h
index 1d49586e4b3..c90f1fc3535 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_allocator.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_allocator.h
@@ -1,919 +1,16 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
+// 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_HEAP_ALLOCATOR_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_ALLOCATOR_H_
-#include <type_traits>
-
-#include "build/build_config.h"
-#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h"
-#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-#include "third_party/blink/renderer/platform/heap/marking_visitor.h"
-#include "third_party/blink/renderer/platform/heap/thread_state_scopes.h"
-#include "third_party/blink/renderer/platform/heap/trace_traits.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/assertions.h"
-#include "third_party/blink/renderer/platform/wtf/construct_traits.h"
-#include "third_party/blink/renderer/platform/wtf/deque.h"
-#include "third_party/blink/renderer/platform/wtf/doubly_linked_list.h"
-#include "third_party/blink/renderer/platform/wtf/hash_counted_set.h"
-#include "third_party/blink/renderer/platform/wtf/hash_map.h"
-#include "third_party/blink/renderer/platform/wtf/hash_set.h"
-#include "third_party/blink/renderer/platform/wtf/hash_table.h"
-#include "third_party/blink/renderer/platform/wtf/linked_hash_set.h"
-#include "third_party/blink/renderer/platform/wtf/list_hash_set.h"
-#include "third_party/blink/renderer/platform/wtf/type_traits.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
-
-namespace blink {
-
-#define DISALLOW_IN_CONTAINER() \
- public: \
- using IsDisallowedInContainerMarker = int; \
- \
- private: \
- friend class ::WTF::internal::__thisIsHereToForceASemicolonAfterThisMacro
-
-// IsAllowedInContainer returns true if some type T supports being nested
-// arbitrarily in other containers. This is relevant for collections where some
-// collections assume that they are placed on a non-moving arena.
-template <typename T, typename = int>
-struct IsAllowedInContainer : std::true_type {};
-template <typename T>
-struct IsAllowedInContainer<T, typename T::IsDisallowedInContainerMarker>
- : std::false_type {};
-
-// This is a static-only class used as a trait on collections to make them heap
-// allocated. However see also HeapListHashSetAllocator.
-class PLATFORM_EXPORT HeapAllocator {
- STATIC_ONLY(HeapAllocator);
-
- public:
- using LivenessBroker = blink::LivenessBroker;
- using Visitor = blink::Visitor;
- static constexpr bool kIsGarbageCollected = true;
-
- template <typename T>
- static size_t MaxElementCountInBackingStore() {
- return kMaxHeapObjectSize / sizeof(T);
- }
-
- template <typename T>
- static size_t QuantizedSize(size_t count) {
- CHECK(count <= MaxElementCountInBackingStore<T>());
- return ThreadHeap::AllocationSizeFromSize(count * sizeof(T)) -
- sizeof(HeapObjectHeader);
- }
- template <typename T>
- static T* AllocateVectorBacking(size_t size) {
- return reinterpret_cast<T*>(
- MakeGarbageCollected<HeapVectorBacking<T>>(size / sizeof(T)));
- }
- static void FreeVectorBacking(void*);
- static bool ExpandVectorBacking(void*, size_t);
- static bool ShrinkVectorBacking(void* address,
- size_t quantized_current_size,
- size_t quantized_shrunk_size);
-
- template <typename T, typename HashTable>
- static T* AllocateHashTableBacking(size_t size) {
- return reinterpret_cast<T*>(
- MakeGarbageCollected<HeapHashTableBacking<HashTable>>(
- size / sizeof(typename HashTable::ValueType)));
- }
- template <typename T, typename HashTable>
- static T* AllocateZeroedHashTableBacking(size_t size) {
- return AllocateHashTableBacking<T, HashTable>(size);
- }
- static void FreeHashTableBacking(void* address);
- static bool ExpandHashTableBacking(void*, size_t);
-
- static void TraceBackingStoreIfMarked(const void* address) {
- // Trace backing store elements only if backing store was marked. The
- // sweeper may be active on the backing store which requires atomic mark bit
- // access. A precise filter is performed in
- // MarkingVisitor::TraceMarkedBackingStore.
- if (HeapObjectHeader::FromPayload(address)
- ->IsMarked<HeapObjectHeader::AccessMode::kAtomic>()) {
- MarkingVisitor::TraceMarkedBackingStore(address);
- }
- }
-
- template <typename T>
- static void BackingWriteBarrier(T** slot) {
- MarkingVisitor::WriteBarrier(slot);
- }
-
- template <typename Return, typename Metadata>
- static Return Malloc(size_t size, const char* type_name) {
- return reinterpret_cast<Return>(
- MarkAsConstructed(ThreadHeap::Allocate<Metadata>(size)));
- }
-
- // Compilers sometimes eagerly instantiates the unused 'operator delete', so
- // we provide a version that asserts and fails at run-time if used.
- static void Free(void*) { NOTREACHED(); }
-
- template <typename T>
- static void* NewArray(size_t bytes) {
- NOTREACHED();
- return nullptr;
- }
-
- static void DeleteArray(void* ptr) { NOTREACHED(); }
-
- static bool IsAllocationAllowed() {
- return ThreadState::Current()->IsAllocationAllowed();
- }
-
- static bool IsSweepForbidden() {
- return ThreadState::Current()->SweepForbidden();
- }
-
- static bool IsIncrementalMarking() {
- return ThreadState::IsAnyIncrementalMarking() &&
- ThreadState::Current()->IsIncrementalMarking();
- }
-
- template <typename T, typename Traits>
- static void Trace(Visitor* visitor, const T& t) {
- TraceCollectionIfEnabled<WTF::WeakHandlingTrait<T>::value, T,
- Traits>::Trace(visitor, &t);
- }
-
- static void EnterGCForbiddenScope() {
- ThreadState::Current()->EnterGCForbiddenScope();
- }
-
- static void LeaveGCForbiddenScope() {
- ThreadState::Current()->LeaveGCForbiddenScope();
- }
-
- template <typename T, typename Traits>
- static void NotifyNewObject(T* object) {
-#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
- ThreadState* const thread_state = ThreadState::Current();
- if (!thread_state->IsIncrementalMarking()) {
- MarkingVisitor::GenerationalBarrier(reinterpret_cast<Address>(object),
- thread_state);
- return;
- }
-#else
- if (!ThreadState::IsAnyIncrementalMarking())
- return;
- // The object may have been in-place constructed as part of a large object.
- // It is not safe to retrieve the page from the object here.
- ThreadState* const thread_state = ThreadState::Current();
- if (!thread_state->IsIncrementalMarking()) {
- return;
- }
-#endif // BLINK_HEAP_YOUNG_GENERATION
- // Eagerly trace the object ensuring that the object and all its children
- // are discovered by the marker.
- ThreadState::NoAllocationScope no_allocation_scope(thread_state);
- DCHECK(thread_state->CurrentVisitor());
- // No weak handling for write barriers. Modifying weakly reachable objects
- // strongifies them for the current cycle.
- DCHECK(!Traits::kCanHaveDeletedValue || !Traits::IsDeletedValue(*object));
- TraceCollectionIfEnabled<WTF::kNoWeakHandling, T, Traits>::Trace(
- thread_state->CurrentVisitor(), object);
- }
-
- template <typename T, typename Traits>
- static void NotifyNewObjects(T* array, size_t len) {
-#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
- ThreadState* const thread_state = ThreadState::Current();
- if (!thread_state->IsIncrementalMarking()) {
- MarkingVisitor::GenerationalBarrier(reinterpret_cast<Address>(array),
- thread_state);
- return;
- }
-#else
- if (!ThreadState::IsAnyIncrementalMarking())
- return;
- // The object may have been in-place constructed as part of a large object.
- // It is not safe to retrieve the page from the object here.
- ThreadState* const thread_state = ThreadState::Current();
- if (!thread_state->IsIncrementalMarking()) {
- return;
- }
-#endif // BLINK_HEAP_YOUNG_GENERATION
- // See |NotifyNewObject| for details.
- ThreadState::NoAllocationScope no_allocation_scope(thread_state);
- DCHECK(thread_state->CurrentVisitor());
- // No weak handling for write barriers. Modifying weakly reachable objects
- // strongifies them for the current cycle.
- while (len-- > 0) {
- DCHECK(!Traits::kCanHaveDeletedValue || !Traits::IsDeletedValue(*array));
- TraceCollectionIfEnabled<WTF::kNoWeakHandling, T, Traits>::Trace(
- thread_state->CurrentVisitor(), array);
- array++;
- }
- }
-
- template <typename T>
- static void TraceVectorBacking(Visitor* visitor,
- const T* backing,
- const T* const* backing_slot) {
- visitor->TraceMovablePointer(backing_slot);
- visitor->Trace(reinterpret_cast<const HeapVectorBacking<T>*>(backing));
- }
-
- template <typename T, typename HashTable>
- static void TraceHashTableBackingStrongly(Visitor* visitor,
- const T* backing,
- const T* const* backing_slot) {
- visitor->TraceMovablePointer(backing_slot);
- visitor->Trace(
- reinterpret_cast<const HeapHashTableBacking<HashTable>*>(backing));
- }
-
- template <typename T, typename HashTable>
- static void TraceHashTableBackingWeakly(Visitor* visitor,
- const T* backing,
- const T* const* backing_slot,
- WeakCallback callback,
- const void* parameter) {
- visitor->TraceMovablePointer(backing_slot);
- visitor->TraceWeakContainer(
- reinterpret_cast<const HeapHashTableBacking<HashTable>*>(backing),
- reinterpret_cast<const HeapHashTableBacking<HashTable>* const*>(
- backing_slot),
- TraceTrait<HeapHashTableBacking<HashTable>>::GetTraceDescriptor(
- backing),
- TraceTrait<HeapHashTableBacking<HashTable>>::GetWeakTraceDescriptor(
- backing),
- callback, parameter);
- }
-
- private:
- static Address MarkAsConstructed(Address address) {
- HeapObjectHeader::FromPayload(reinterpret_cast<void*>(address))
- ->MarkFullyConstructed<HeapObjectHeader::AccessMode::kAtomic>();
- return address;
- }
-
- static void BackingFree(void*);
- static bool BackingExpand(void*, size_t);
- static bool BackingShrink(void*,
- size_t quantized_current_size,
- size_t quantized_shrunk_size);
-
- template <typename T, wtf_size_t u, typename V>
- friend class WTF::Vector;
- template <typename T, typename U, typename V, typename W>
- friend class WTF::HashSet;
- template <typename T,
- typename U,
- typename V,
- typename W,
- typename X,
- typename Y>
- friend class WTF::HashMap;
-};
-
-template <typename VisitorDispatcher, typename Value>
-static void TraceListHashSetValue(VisitorDispatcher visitor,
- const Value& value) {
- // We use the default hash traits for the value in the node, because
- // ListHashSet does not let you specify any specific ones.
- // We don't allow ListHashSet of WeakMember, so we set that one false
- // (there's an assert elsewhere), but we have to specify some value for the
- // strongify template argument, so we specify WTF::WeakPointersActWeak,
- // arbitrarily.
- TraceCollectionIfEnabled<WTF::kNoWeakHandling, Value,
- WTF::HashTraits<Value>>::Trace(visitor, &value);
-}
-
-// The inline capacity is just a dummy template argument to match the off-heap
-// allocator.
-// This inherits from the static-only HeapAllocator trait class, but we do
-// declare pointers to instances. These pointers are always null, and no
-// objects are instantiated.
-template <typename ValueArg, wtf_size_t inlineCapacity>
-class HeapListHashSetAllocator : public HeapAllocator {
- DISALLOW_NEW();
-
- public:
- using TableAllocator = HeapAllocator;
- using Node = WTF::ListHashSetNode<ValueArg, HeapListHashSetAllocator>;
-
- class AllocatorProvider {
- DISALLOW_NEW();
-
- public:
- // For the heap allocation we don't need an actual allocator object, so
- // we just return null.
- HeapListHashSetAllocator* Get() const { return nullptr; }
-
- // No allocator object is needed.
- void CreateAllocatorIfNeeded() {}
- void ReleaseAllocator() {}
-
- // There is no allocator object in the HeapListHashSet (unlike in the
- // regular ListHashSet) so there is nothing to swap.
- void Swap(AllocatorProvider& other) {}
- };
-
- void Deallocate(void* dummy) {}
-
- // This is not a static method even though it could be, because it needs to
- // match the one that the (off-heap) ListHashSetAllocator has. The 'this'
- // pointer will always be null.
- void* AllocateNode() {
- // Consider using a LinkedHashSet instead if this compile-time assert fails:
- static_assert(!WTF::IsWeak<ValueArg>::value,
- "weak pointers in a ListHashSet will result in null entries "
- "in the set");
-
- return Malloc<void*, Node>(
- sizeof(Node),
- nullptr /* Oilpan does not use the heap profiler at the moment. */);
- }
-
- template <typename VisitorDispatcher>
- static void TraceValue(VisitorDispatcher visitor, const Node* node) {
- TraceListHashSetValue(visitor, node->value_);
- }
-};
-
-namespace internal {
-
-template <typename T>
-constexpr bool IsMember = WTF::IsSubclassOfTemplate<T, Member>::value;
-
-template <typename T>
-constexpr bool IsMemberOrWeakMemberType =
- WTF::IsSubclassOfTemplate<T, Member>::value ||
- WTF::IsSubclassOfTemplate<T, WeakMember>::value;
-
-} // namespace internal
-
-template <typename KeyArg,
- typename MappedArg,
- typename HashArg = typename DefaultHash<KeyArg>::Hash,
- typename KeyTraitsArg = HashTraits<KeyArg>,
- typename MappedTraitsArg = HashTraits<MappedArg>>
-class HeapHashMap : public HashMap<KeyArg,
- MappedArg,
- HashArg,
- KeyTraitsArg,
- MappedTraitsArg,
- HeapAllocator> {
- IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
- DISALLOW_NEW();
-
- static void CheckType() {
- static_assert(std::is_trivially_destructible<HeapHashMap>::value,
- "HeapHashMap must be trivially destructible.");
- static_assert(
- IsAllowedInContainer<KeyArg>::value,
- "Not allowed to directly nest type. Use Member<> indirection instead.");
- static_assert(
- IsAllowedInContainer<MappedArg>::value,
- "Not allowed to directly nest type. Use Member<> indirection instead.");
- static_assert(
- WTF::IsTraceable<KeyArg>::value || WTF::IsTraceable<MappedArg>::value,
- "For hash maps without traceable elements, use HashMap<> "
- "instead of HeapHashMap<>.");
- static_assert(internal::IsMemberOrWeakMemberType<KeyArg> ||
- !WTF::IsTraceable<KeyArg>::value,
- "HeapHashMap supports only Member, WeakMember and "
- "non-traceable types as keys.");
- static_assert(internal::IsMemberOrWeakMemberType<MappedArg> ||
- !WTF::IsTraceable<MappedArg>::value ||
- WTF::IsSubclassOfTemplate<MappedArg,
- TraceWrapperV8Reference>::value,
- "HeapHashMap supports only Member, WeakMember, "
- "TraceWrapperV8Reference and "
- "non-traceable types as values.");
- }
-
- public:
- template <typename>
- static void* AllocateObject(size_t size) {
- return ThreadHeap::Allocate<
- HeapHashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>>(
- size);
- }
-
- HeapHashMap() { CheckType(); }
-};
-
-template <typename T, typename U, typename V, typename W, typename X>
-struct GCInfoTrait<HeapHashMap<T, U, V, W, X>>
- : public GCInfoTrait<HashMap<T, U, V, W, X, HeapAllocator>> {};
-
-template <typename ValueArg,
- typename HashArg = typename DefaultHash<ValueArg>::Hash,
- typename TraitsArg = HashTraits<ValueArg>>
-class HeapHashSet
- : public HashSet<ValueArg, HashArg, TraitsArg, HeapAllocator> {
- IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
- DISALLOW_NEW();
-
- static void CheckType() {
- static_assert(internal::IsMemberOrWeakMemberType<ValueArg>,
- "HeapHashSet supports only Member and WeakMember.");
- static_assert(std::is_trivially_destructible<HeapHashSet>::value,
- "HeapHashSet must be trivially destructible.");
- static_assert(
- IsAllowedInContainer<ValueArg>::value,
- "Not allowed to directly nest type. Use Member<> indirection instead.");
- static_assert(WTF::IsTraceable<ValueArg>::value,
- "For hash sets without traceable elements, use HashSet<> "
- "instead of HeapHashSet<>.");
- }
-
- public:
- template <typename>
- static void* AllocateObject(size_t size) {
- return ThreadHeap::Allocate<HeapHashSet<ValueArg, HashArg, TraitsArg>>(
- size);
- }
-
- HeapHashSet() { CheckType(); }
-};
-
-template <typename T, typename U, typename V>
-struct GCInfoTrait<HeapHashSet<T, U, V>>
- : public GCInfoTrait<HashSet<T, U, V, HeapAllocator>> {};
-
-template <typename ValueArg, typename TraitsArg = HashTraits<ValueArg>>
-class HeapLinkedHashSet
- : public LinkedHashSet<ValueArg, TraitsArg, HeapAllocator> {
- IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
- DISALLOW_NEW();
-
- static void CheckType() {
- static_assert(internal::IsMemberOrWeakMemberType<ValueArg>,
- "HeapLinkedHashSet supports only Member and WeakMember.");
- // If not trivially destructible, we have to add a destructor which will
- // hinder performance.
- static_assert(std::is_trivially_destructible<HeapLinkedHashSet>::value,
- "HeapLinkedHashSet must be trivially destructible.");
- static_assert(
- IsAllowedInContainer<ValueArg>::value,
- "Not allowed to directly nest type. Use Member<> indirection instead.");
- static_assert(WTF::IsTraceable<ValueArg>::value,
- "For sets without traceable elements, use LinkedHashSet<> "
- "instead of HeapLinkedHashSet<>.");
- }
-
- public:
- template <typename>
- static void* AllocateObject(size_t size) {
- return ThreadHeap::Allocate<HeapLinkedHashSet<ValueArg, TraitsArg>>(size);
- }
-
- HeapLinkedHashSet() { CheckType(); }
-};
-
-template <typename T, typename U>
-struct GCInfoTrait<HeapLinkedHashSet<T, U>>
- : public GCInfoTrait<LinkedHashSet<T, U, HeapAllocator>> {};
-
-template <typename ValueArg,
- wtf_size_t inlineCapacity =
- 0, // The inlineCapacity is just a dummy to
- // match ListHashSet (off-heap).
- typename HashArg = typename DefaultHash<ValueArg>::Hash>
-class HeapListHashSet
- : public ListHashSet<ValueArg,
- inlineCapacity,
- HashArg,
- HeapListHashSetAllocator<ValueArg, inlineCapacity>> {
- IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
- DISALLOW_NEW();
-
- static void CheckType() {
- static_assert(internal::IsMemberOrWeakMemberType<ValueArg>,
- "HeapListHashSet supports only Member and WeakMember.");
- static_assert(std::is_trivially_destructible<HeapListHashSet>::value,
- "HeapListHashSet must be trivially destructible.");
- static_assert(
- IsAllowedInContainer<ValueArg>::value,
- "Not allowed to directly nest type. Use Member<> indirection instead.");
- static_assert(WTF::IsTraceable<ValueArg>::value,
- "For sets without traceable elements, use ListHashSet<> "
- "instead of HeapListHashSet<>.");
- }
-
- public:
- template <typename>
- static void* AllocateObject(size_t size) {
- return ThreadHeap::Allocate<
- HeapListHashSet<ValueArg, inlineCapacity, HashArg>>(size);
- }
-
- HeapListHashSet() { CheckType(); }
-};
-
-template <typename T, wtf_size_t inlineCapacity, typename U>
-struct GCInfoTrait<HeapListHashSet<T, inlineCapacity, U>>
- : public GCInfoTrait<
- ListHashSet<T,
- inlineCapacity,
- U,
- HeapListHashSetAllocator<T, inlineCapacity>>> {};
-
-template <typename Value,
- typename HashFunctions = typename DefaultHash<Value>::Hash,
- typename Traits = HashTraits<Value>>
-class HeapHashCountedSet
- : public HashCountedSet<Value, HashFunctions, Traits, HeapAllocator> {
- IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
- DISALLOW_NEW();
-
- static void CheckType() {
- static_assert(internal::IsMemberOrWeakMemberType<Value>,
- "HeapHashCountedSet supports only Member and WeakMember.");
- static_assert(std::is_trivially_destructible<HeapHashCountedSet>::value,
- "HeapHashCountedSet must be trivially destructible.");
- static_assert(
- IsAllowedInContainer<Value>::value,
- "Not allowed to directly nest type. Use Member<> indirection instead.");
- static_assert(WTF::IsTraceable<Value>::value,
- "For counted sets without traceable elements, use "
- "HashCountedSet<> instead of HeapHashCountedSet<>.");
- }
-
- public:
- template <typename>
- static void* AllocateObject(size_t size) {
- return ThreadHeap::Allocate<
- HeapHashCountedSet<Value, HashFunctions, Traits>>(size);
- }
-
- HeapHashCountedSet() { CheckType(); }
-};
-
-template <typename T, typename U, typename V>
-struct GCInfoTrait<HeapHashCountedSet<T, U, V>>
- : public GCInfoTrait<HashCountedSet<T, U, V, HeapAllocator>> {};
-
-template <typename T, wtf_size_t inlineCapacity = 0>
-class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> {
- IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
- DISALLOW_NEW();
-
- static void CheckType() {
- static_assert(
- std::is_trivially_destructible<HeapVector>::value || inlineCapacity,
- "HeapVector must be trivially destructible.");
- static_assert(
- IsAllowedInContainer<T>::value,
- "Not allowed to directly nest type. Use Member<> indirection instead.");
- static_assert(WTF::IsTraceable<T>::value,
- "For vectors without traceable elements, use Vector<> "
- "instead of HeapVector<>.");
- static_assert(!WTF::IsWeak<T>::value,
- "Weak types are not allowed in HeapVector.");
- static_assert(WTF::IsTraceableInCollectionTrait<VectorTraits<T>>::value,
- "Type must be traceable in collection");
- }
-
- public:
- template <typename>
- static void* AllocateObject(size_t size) {
- // On-heap HeapVectors generally should not have inline capacity, but it is
- // hard to avoid when using a type alias. Hence we only disallow the
- // VectorTraits<T>::kNeedsDestruction case for now.
- static_assert(inlineCapacity == 0 || !VectorTraits<T>::kNeedsDestruction,
- "on-heap HeapVector<> should not have an inline capacity");
- return ThreadHeap::Allocate<HeapVector<T, inlineCapacity>>(size);
- }
-
- HeapVector() { CheckType(); }
-
- explicit HeapVector(wtf_size_t size)
- : Vector<T, inlineCapacity, HeapAllocator>(size) {
- CheckType();
- }
-
- HeapVector(wtf_size_t size, const T& val)
- : Vector<T, inlineCapacity, HeapAllocator>(size, val) {
- CheckType();
- }
-
- template <wtf_size_t otherCapacity>
- HeapVector(const HeapVector<T, otherCapacity>& other)
- : Vector<T, inlineCapacity, HeapAllocator>(other) {
- CheckType();
- }
-
- HeapVector(std::initializer_list<T> elements)
- : Vector<T, inlineCapacity, HeapAllocator>(elements) {
- CheckType();
- }
-};
-
-template <typename T, wtf_size_t inlineCapacity>
-struct GCInfoTrait<HeapVector<T, inlineCapacity>>
- : public GCInfoTrait<Vector<T, inlineCapacity, HeapAllocator>> {};
-
-template <typename T>
-class HeapDeque : public Deque<T, 0, HeapAllocator> {
- IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
- DISALLOW_NEW();
-
- static void CheckType() {
- static_assert(internal::IsMember<T>, "HeapDeque supports only Member.");
- static_assert(std::is_trivially_destructible<HeapDeque>::value,
- "HeapDeque must be trivially destructible.");
- static_assert(
- IsAllowedInContainer<T>::value,
- "Not allowed to directly nest type. Use Member<> indirection instead.");
- static_assert(WTF::IsTraceable<T>::value,
- "For vectors without traceable elements, use Deque<> instead "
- "of HeapDeque<>");
- }
-
- public:
- template <typename>
- static void* AllocateObject(size_t size) {
- return ThreadHeap::Allocate<HeapDeque<T>>(size);
- }
-
- HeapDeque() { CheckType(); }
-
- explicit HeapDeque(wtf_size_t size) : Deque<T, 0, HeapAllocator>(size) {
- CheckType();
- }
-
- HeapDeque(wtf_size_t size, const T& val)
- : Deque<T, 0, HeapAllocator>(size, val) {
- CheckType();
- }
-
- HeapDeque& operator=(const HeapDeque& other) {
- HeapDeque<T> copy(other);
- Deque<T, 0, HeapAllocator>::Swap(copy);
- return *this;
- }
-
- HeapDeque(const HeapDeque<T>& other) : Deque<T, 0, HeapAllocator>(other) {}
-};
-
-template <typename T>
-struct GCInfoTrait<HeapDeque<T>>
- : public GCInfoTrait<Deque<T, 0, HeapAllocator>> {};
-
-} // namespace blink
-
-namespace WTF {
-
-template <typename T>
-struct VectorTraits<blink::Member<T>> : VectorTraitsBase<blink::Member<T>> {
- STATIC_ONLY(VectorTraits);
- static const bool kNeedsDestruction = false;
- static const bool kCanInitializeWithMemset = true;
- static const bool kCanClearUnusedSlotsWithMemset = true;
- static const bool kCanCopyWithMemcpy = true;
- static const bool kCanMoveWithMemcpy = true;
-
- static constexpr bool kCanTraceConcurrently = true;
-};
-
-// These traits are used in VectorBackedLinkedList to support WeakMember in
-// HeapLinkedHashSet though HeapVector<WeakMember> usage is still banned.
-// (See the discussion in https://crrev.com/c/2246014)
-template <typename T>
-struct VectorTraits<blink::WeakMember<T>>
- : VectorTraitsBase<blink::WeakMember<T>> {
- STATIC_ONLY(VectorTraits);
- static const bool kNeedsDestruction = false;
- static const bool kCanInitializeWithMemset = true;
- static const bool kCanClearUnusedSlotsWithMemset = true;
- static const bool kCanCopyWithMemcpy = true;
- static const bool kCanMoveWithMemcpy = true;
-
- static constexpr bool kCanTraceConcurrently = true;
-};
-
-template <typename T>
-struct VectorTraits<blink::UntracedMember<T>>
- : VectorTraitsBase<blink::UntracedMember<T>> {
- STATIC_ONLY(VectorTraits);
- static const bool kNeedsDestruction = false;
- static const bool kCanInitializeWithMemset = true;
- static const bool kCanClearUnusedSlotsWithMemset = true;
- static const bool kCanMoveWithMemcpy = true;
-};
-
-template <typename T>
-struct VectorTraits<blink::HeapVector<T, 0>>
- : VectorTraitsBase<blink::HeapVector<T, 0>> {
- STATIC_ONLY(VectorTraits);
- static const bool kNeedsDestruction = false;
- static const bool kCanInitializeWithMemset = true;
- static const bool kCanClearUnusedSlotsWithMemset = true;
- static const bool kCanMoveWithMemcpy = true;
-};
-
-template <typename T>
-struct VectorTraits<blink::HeapDeque<T>>
- : VectorTraitsBase<blink::HeapDeque<T>> {
- STATIC_ONLY(VectorTraits);
- static const bool kNeedsDestruction = false;
- static const bool kCanInitializeWithMemset = true;
- static const bool kCanClearUnusedSlotsWithMemset = true;
- static const bool kCanMoveWithMemcpy = true;
-};
-
-template <typename T, wtf_size_t inlineCapacity>
-struct VectorTraits<blink::HeapVector<T, inlineCapacity>>
- : VectorTraitsBase<blink::HeapVector<T, inlineCapacity>> {
- STATIC_ONLY(VectorTraits);
- static const bool kNeedsDestruction = VectorTraits<T>::kNeedsDestruction;
- static const bool kCanInitializeWithMemset =
- VectorTraits<T>::kCanInitializeWithMemset;
- static const bool kCanClearUnusedSlotsWithMemset =
- VectorTraits<T>::kCanClearUnusedSlotsWithMemset;
- static const bool kCanMoveWithMemcpy = VectorTraits<T>::kCanMoveWithMemcpy;
-};
-
-template <typename T>
-struct HashTraits<blink::Member<T>> : SimpleClassHashTraits<blink::Member<T>> {
- STATIC_ONLY(HashTraits);
- // FIXME: Implement proper const'ness for iterator types. Requires support
- // in the marking Visitor.
- using PeekInType = T*;
- using IteratorGetType = blink::Member<T>*;
- using IteratorConstGetType = const blink::Member<T>*;
- using IteratorReferenceType = blink::Member<T>&;
- using IteratorConstReferenceType = const blink::Member<T>&;
- static IteratorReferenceType GetToReferenceConversion(IteratorGetType x) {
- return *x;
- }
- static IteratorConstReferenceType GetToReferenceConstConversion(
- IteratorConstGetType x) {
- return *x;
- }
-
- using PeekOutType = T*;
-
- template <typename U>
- static void Store(const U& value, blink::Member<T>& storage) {
- storage = value;
- }
-
- static PeekOutType Peek(const blink::Member<T>& value) { return value; }
-
- static void ConstructDeletedValue(blink::Member<T>& slot, bool) {
- slot = WTF::kHashTableDeletedValue;
- }
-
- static constexpr bool kCanTraceConcurrently = true;
-};
-
-template <typename T>
-struct HashTraits<blink::WeakMember<T>>
- : SimpleClassHashTraits<blink::WeakMember<T>> {
- STATIC_ONLY(HashTraits);
- static const bool kNeedsDestruction = false;
- // FIXME: Implement proper const'ness for iterator types. Requires support
- // in the marking Visitor.
- using PeekInType = T*;
- using IteratorGetType = blink::WeakMember<T>*;
- using IteratorConstGetType = const blink::WeakMember<T>*;
- using IteratorReferenceType = blink::WeakMember<T>&;
- using IteratorConstReferenceType = const blink::WeakMember<T>&;
- static IteratorReferenceType GetToReferenceConversion(IteratorGetType x) {
- return *x;
- }
- static IteratorConstReferenceType GetToReferenceConstConversion(
- IteratorConstGetType x) {
- return *x;
- }
-
- using PeekOutType = T*;
-
- template <typename U>
- static void Store(const U& value, blink::WeakMember<T>& storage) {
- storage = value;
- }
-
- static PeekOutType Peek(const blink::WeakMember<T>& value) { return value; }
-
- static void ConstructDeletedValue(blink::WeakMember<T>& slot, bool) {
- slot = WTF::kHashTableDeletedValue;
- }
-
- static constexpr bool kCanTraceConcurrently = true;
-};
-
-template <typename T>
-struct HashTraits<blink::UntracedMember<T>>
- : SimpleClassHashTraits<blink::UntracedMember<T>> {
- STATIC_ONLY(HashTraits);
- static const bool kNeedsDestruction = false;
- // FIXME: Implement proper const'ness for iterator types.
- using PeekInType = T*;
- using IteratorGetType = blink::UntracedMember<T>*;
- using IteratorConstGetType = const blink::UntracedMember<T>*;
- using IteratorReferenceType = blink::UntracedMember<T>&;
- using IteratorConstReferenceType = const blink::UntracedMember<T>&;
- static IteratorReferenceType GetToReferenceConversion(IteratorGetType x) {
- return *x;
- }
- static IteratorConstReferenceType GetToReferenceConstConversion(
- IteratorConstGetType x) {
- return *x;
- }
- using PeekOutType = T*;
-
- template <typename U>
- static void Store(const U& value, blink::UntracedMember<T>& storage) {
- storage = value;
- }
-
- static PeekOutType Peek(const blink::UntracedMember<T>& value) {
- return value;
- }
-};
-
-template <typename T, wtf_size_t inlineCapacity>
-struct IsTraceable<
- ListHashSetNode<T, blink::HeapListHashSetAllocator<T, inlineCapacity>>*> {
- STATIC_ONLY(IsTraceable);
- static_assert(sizeof(T), "T must be fully defined");
- // All heap allocated node pointers need visiting to keep the nodes alive,
- // regardless of whether they contain pointers to other heap allocated
- // objects.
- static const bool value = true;
-};
-
-template <typename T, wtf_size_t inlineCapacity>
-struct IsGarbageCollectedType<
- ListHashSetNode<T, blink::HeapListHashSetAllocator<T, inlineCapacity>>> {
- static const bool value = true;
-};
-
-template <typename Set>
-struct IsGarbageCollectedType<ListHashSetIterator<Set>> {
- static const bool value = IsGarbageCollectedType<Set>::value;
-};
-
-template <typename Set>
-struct IsGarbageCollectedType<ListHashSetConstIterator<Set>> {
- static const bool value = IsGarbageCollectedType<Set>::value;
-};
-
-template <typename Set>
-struct IsGarbageCollectedType<ListHashSetReverseIterator<Set>> {
- static const bool value = IsGarbageCollectedType<Set>::value;
-};
-
-template <typename Set>
-struct IsGarbageCollectedType<ListHashSetConstReverseIterator<Set>> {
- static const bool value = IsGarbageCollectedType<Set>::value;
-};
-
-template <typename T, typename H>
-struct HandleHashTraits : SimpleClassHashTraits<H> {
- STATIC_ONLY(HandleHashTraits);
- // TODO: Implement proper const'ness for iterator types. Requires support
- // in the marking Visitor.
- using PeekInType = T*;
- using IteratorGetType = H*;
- using IteratorConstGetType = const H*;
- using IteratorReferenceType = H&;
- using IteratorConstReferenceType = const H&;
- static IteratorReferenceType GetToReferenceConversion(IteratorGetType x) {
- return *x;
- }
- static IteratorConstReferenceType GetToReferenceConstConversion(
- IteratorConstGetType x) {
- return *x;
- }
-
- using PeekOutType = T*;
-
- template <typename U>
- static void Store(const U& value, H& storage) {
- storage = value;
- }
-
- static PeekOutType Peek(const H& value) { return value; }
-};
-
-template <typename Value,
- typename HashFunctions,
- typename Traits,
- typename VectorType>
-inline void CopyToVector(
- const blink::HeapHashCountedSet<Value, HashFunctions, Traits>& set,
- VectorType& vector) {
- CopyToVector(static_cast<const HashCountedSet<Value, HashFunctions, Traits,
- blink::HeapAllocator>&>(set),
- vector);
-}
-} // namespace WTF
+#if BUILDFLAG(BLINK_HEAP_USE_V8_OILPAN)
+#include "third_party/blink/renderer/platform/heap/v8_wrapper/heap_allocator.h"
+#else // !BLINK_HEAP_USE_V8_OILPAN
+#include "third_party/blink/renderer/platform/heap/impl/heap_allocator.h"
+#endif // !BLINK_HEAP_USE_V8_OILPAN
-#endif
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_ALLOCATOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.h b/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.h
index 344d4394be6..1a6a45c023d 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.h
@@ -1,469 +1,16 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
+// 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_HEAP_STATS_COLLECTOR_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_STATS_COLLECTOR_H_
-#include <stddef.h>
+#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-#include "base/atomicops.h"
-#include "third_party/blink/renderer/platform/heap/blink_gc.h"
-#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-// Interface for observing changes to heap sizing.
-class PLATFORM_EXPORT ThreadHeapStatsObserver {
- public:
- // Called upon allocating/releasing chunks of memory that contain objects.
- //
- // Must not trigger GC or allocate.
- virtual void IncreaseAllocatedSpace(size_t) = 0;
- virtual void DecreaseAllocatedSpace(size_t) = 0;
-
- // Called once per GC cycle with the accurate number of live |bytes|.
- //
- // Must not trigger GC or allocate.
- virtual void ResetAllocatedObjectSize(size_t bytes) = 0;
-
- // Called after observing at least
- // |ThreadHeapStatsCollector::kUpdateThreshold| changed bytes through
- // allocation or explicit free. Reports both, negative and positive
- // increments, to allow observer to decide whether absolute values or only the
- // deltas is interesting.
- //
- // May trigger GC but most not allocate.
- virtual void IncreaseAllocatedObjectSize(size_t) = 0;
- virtual void DecreaseAllocatedObjectSize(size_t) = 0;
-};
-
-#define FOR_ALL_SCOPES(V) \
- V(AtomicPauseCompaction) \
- V(AtomicPauseMarkEpilogue) \
- V(AtomicPauseMarkPrologue) \
- V(AtomicPauseMarkRoots) \
- V(AtomicPauseMarkTransitiveClosure) \
- V(AtomicPauseSweepAndCompact) \
- V(CompleteSweep) \
- V(IncrementalMarkingFinalize) \
- V(IncrementalMarkingStartMarking) \
- V(IncrementalMarkingStep) \
- V(IncrementalMarkingWithDeadline) \
- V(InvokePreFinalizers) \
- V(LazySweepInIdle) \
- V(LazySweepOnAllocation) \
- V(MarkBailOutObjects) \
- V(MarkInvokeEphemeronCallbacks) \
- V(MarkFlushV8References) \
- V(MarkFlushEphemeronPairs) \
- V(MarkProcessWorklists) \
- V(MarkProcessMarkingWorklist) \
- V(MarkProcessWriteBarrierWorklist) \
- V(MarkProcessNotFullyconstructeddWorklist) \
- V(MarkNotFullyConstructedObjects) \
- V(MarkWeakProcessing) \
- V(UnifiedMarkingStep) \
- V(VisitCrossThreadPersistents) \
- V(VisitPersistentRoots) \
- V(VisitPersistents) \
- V(VisitRoots) \
- V(VisitStackRoots) \
- V(VisitRememberedSets)
-
-#define FOR_ALL_CONCURRENT_SCOPES(V) \
- V(ConcurrentMarkInvokeEphemeronCallbacks) \
- V(ConcurrentMarkingStep) \
- V(ConcurrentSweepingStep)
-
-// Manages counters and statistics across garbage collection cycles.
-//
-// Usage:
-// ThreadHeapStatsCollector stats_collector;
-// stats_collector.NotifyMarkingStarted(<BlinkGC::CollectionType>,
-// <BlinkGC::GCReason>);
-// // Use tracer.
-// stats_collector.NotifySweepingCompleted();
-// // Previous event is available using stats_collector.previous().
-class PLATFORM_EXPORT ThreadHeapStatsCollector {
- USING_FAST_MALLOC(ThreadHeapStatsCollector);
-
- public:
- // These ids will form human readable names when used in Scopes.
- enum Id {
-#define DECLARE_ENUM(name) k##name,
- FOR_ALL_SCOPES(DECLARE_ENUM)
-#undef DECLARE_ENUM
- kNumScopeIds,
- };
-
- enum ConcurrentId {
-#define DECLARE_ENUM(name) k##name,
- FOR_ALL_CONCURRENT_SCOPES(DECLARE_ENUM)
-#undef DECLARE_ENUM
- kNumConcurrentScopeIds
- };
-
- constexpr static const char* ToString(Id id, BlinkGC::CollectionType type) {
- switch (id) {
-#define CASE(name) \
- case k##name: \
- return type == BlinkGC::CollectionType::kMajor ? "BlinkGC." #name \
- : "BlinkGC." #name \
- ".Minor";
- FOR_ALL_SCOPES(CASE)
-#undef CASE
- default:
- NOTREACHED();
- }
- return nullptr;
- }
-
- constexpr static const char* ToString(ConcurrentId id,
- BlinkGC::CollectionType type) {
- switch (id) {
-#define CASE(name) \
- case k##name: \
- return type == BlinkGC::CollectionType::kMajor ? "BlinkGC." #name \
- : "BlinkGC." #name \
- ".Minor";
- FOR_ALL_CONCURRENT_SCOPES(CASE)
-#undef CASE
- default:
- NOTREACHED();
- }
- return nullptr;
- }
-
- enum TraceCategory { kEnabled, kDisabled };
- enum ScopeContext { kMutatorThread, kConcurrentThread };
-
- // Trace a particular scope. Will emit a trace event and record the time in
- // the corresponding ThreadHeapStatsCollector.
- template <TraceCategory trace_category = kDisabled,
- ScopeContext scope_category = kMutatorThread>
- class PLATFORM_EXPORT InternalScope {
- DISALLOW_NEW();
- DISALLOW_COPY_AND_ASSIGN(InternalScope);
-
- using IdType =
- std::conditional_t<scope_category == kMutatorThread, Id, ConcurrentId>;
-
- public:
- template <typename... Args>
- InternalScope(ThreadHeapStatsCollector* tracer, IdType id, Args... args)
- : tracer_(tracer), start_time_(base::TimeTicks::Now()), id_(id) {
- StartTrace(args...);
- }
-
- ~InternalScope() {
- StopTrace();
- IncreaseScopeTime(id_);
- }
-
- private:
- inline constexpr static const char* TraceCategory();
-
- inline void StartTrace();
- template <typename Value1>
- inline void StartTrace(const char* k1, Value1 v1);
- template <typename Value1, typename Value2>
- inline void StartTrace(const char* k1,
- Value1 v1,
- const char* k2,
- Value2 v2);
- inline void StopTrace();
-
- inline void IncreaseScopeTime(Id);
- inline void IncreaseScopeTime(ConcurrentId);
-
- ThreadHeapStatsCollector* const tracer_;
- const base::TimeTicks start_time_;
- const IdType id_;
- };
-
- using Scope = InternalScope<kDisabled>;
- using EnabledScope = InternalScope<kEnabled>;
- using ConcurrentScope = InternalScope<kDisabled, kConcurrentThread>;
- using EnabledConcurrentScope = InternalScope<kEnabled, kConcurrentThread>;
-
- // BlinkGCInV8Scope keeps track of time spent in Blink's GC when called by V8.
- // This is necessary to avoid double-accounting of Blink's time when computing
- // the overall time (V8 + Blink) spent in GC on the main thread.
- class PLATFORM_EXPORT BlinkGCInV8Scope {
- DISALLOW_NEW();
- DISALLOW_COPY_AND_ASSIGN(BlinkGCInV8Scope);
-
- public:
- template <typename... Args>
- BlinkGCInV8Scope(ThreadHeapStatsCollector* tracer)
- : tracer_(tracer), start_time_(base::TimeTicks::Now()) {}
-
- ~BlinkGCInV8Scope() {
- if (tracer_)
- tracer_->gc_nested_in_v8_ += base::TimeTicks::Now() - start_time_;
- }
-
- private:
- ThreadHeapStatsCollector* const tracer_;
- const base::TimeTicks start_time_;
- };
-
- // POD to hold interesting data accumulated during a garbage collection cycle.
- // The event is always fully populated when looking at previous events but
- // is only be partially populated when looking at the current event. See
- // members on when they are available.
- //
- // Note that all getters include time for stand-alone as well as unified heap
- // GCs. E.g., |atomic_marking_time()| report the marking time of the atomic
- // phase, independent of whether the GC was a stand-alone or unified heap GC.
- struct PLATFORM_EXPORT Event {
- Event();
-
- // Overall time spent in the GC cycle. This includes marking time as well as
- // sweeping time.
- base::TimeDelta gc_cycle_time() const;
-
- // Time spent in the final atomic pause of a GC cycle.
- base::TimeDelta atomic_pause_time() const;
-
- // Time spent in the final atomic pause for marking the heap.
- base::TimeDelta atomic_marking_time() const;
-
- // Time spent in the final atomic pause in sweeping and compacting the heap.
- base::TimeDelta atomic_sweep_and_compact_time() const;
-
- // Time spent marking the roots.
- base::TimeDelta roots_marking_time() const;
-
- // Time spent incrementally marking the heap.
- base::TimeDelta incremental_marking_time() const;
-
- // Time spent processing worklist in the foreground thread.
- base::TimeDelta worklist_processing_time_foreground() const;
-
- // Time spent flushing v8 references (this is done only in the foreground)
- base::TimeDelta flushing_v8_references_time() const;
-
- // Time spent in foreground tasks marking the heap.
- base::TimeDelta foreground_marking_time() const;
-
- // Time spent in background tasks marking the heap.
- base::TimeDelta background_marking_time() const;
-
- // Overall time spent marking the heap.
- base::TimeDelta marking_time() const;
-
- // Time spent in foreground tasks sweeping the heap.
- base::TimeDelta foreground_sweeping_time() const;
-
- // Time spent in background tasks sweeping the heap.
- base::TimeDelta background_sweeping_time() const;
-
- // Overall time spent sweeping the heap.
- base::TimeDelta sweeping_time() const;
-
- // Marked bytes collected during sweeping.
- size_t unique_id = -1;
- size_t marked_bytes = 0;
- size_t compaction_freed_bytes = 0;
- size_t compaction_freed_pages = 0;
- bool compaction_recorded_events = false;
- base::TimeDelta scope_data[kNumScopeIds];
- base::subtle::Atomic32 concurrent_scope_data[kNumConcurrentScopeIds]{0};
- BlinkGC::GCReason reason = static_cast<BlinkGC::GCReason>(0);
- BlinkGC::CollectionType collection_type = BlinkGC::CollectionType::kMajor;
- size_t object_size_in_bytes_before_sweeping = 0;
- size_t allocated_space_in_bytes_before_sweeping = 0;
- size_t partition_alloc_bytes_before_sweeping = 0;
- double live_object_rate = 0;
- base::TimeDelta gc_nested_in_v8;
- bool is_forced_gc = true;
- };
-
- // Indicates a new garbage collection cycle.
- void NotifyMarkingStarted(BlinkGC::CollectionType,
- BlinkGC::GCReason,
- bool is_forced_gc);
-
- // Indicates that marking of the current garbage collection cycle is
- // completed.
- void NotifyMarkingCompleted(size_t marked_bytes);
-
- // Indicates the end of a garbage collection cycle. This means that sweeping
- // is finished at this point.
- void NotifySweepingCompleted();
-
- void IncreaseScopeTime(Id id, base::TimeDelta time) {
- DCHECK(is_started_);
- current_.scope_data[id] += time;
- }
-
- void IncreaseConcurrentScopeTime(ConcurrentId id, base::TimeDelta time) {
- using Atomic32 = base::subtle::Atomic32;
- DCHECK(is_started_);
- const int64_t ms = time.InMicroseconds();
- DCHECK(ms <= std::numeric_limits<Atomic32>::max());
- base::subtle::NoBarrier_AtomicIncrement(&current_.concurrent_scope_data[id],
- static_cast<Atomic32>(ms));
- }
-
- void UpdateReason(BlinkGC::GCReason);
- void IncreaseCompactionFreedSize(size_t);
- void IncreaseCompactionFreedPages(size_t);
- void IncreaseAllocatedObjectSize(size_t);
- void DecreaseAllocatedObjectSize(size_t);
- void IncreaseAllocatedSpace(size_t);
- void DecreaseAllocatedSpace(size_t);
- void IncreaseWrapperCount(size_t);
- void DecreaseWrapperCount(size_t);
- void IncreaseCollectedWrapperCount(size_t);
-
- // Called by the GC when it hits a point where allocated memory may be
- // reported and garbage collection is possible. This is necessary, as
- // increments and decrements are reported as close to their actual
- // allocation/reclamation as possible.
- void AllocatedObjectSizeSafepoint();
-
- // Size of objects on the heap. Based on marked bytes in the previous cycle
- // and newly allocated bytes since the previous cycle.
- size_t object_size_in_bytes() const;
-
- size_t marked_bytes() const;
- base::TimeDelta marking_time_so_far() const;
-
- base::TimeDelta worklist_processing_time_foreground() const;
-
- base::TimeDelta flushing_v8_references_time() const;
-
- int64_t allocated_bytes_since_prev_gc() const;
-
- size_t allocated_space_bytes() const;
-
- size_t wrapper_count() const;
- size_t collected_wrapper_count() const;
-
- bool is_started() const { return is_started_; }
-
- // Statistics for the previously running garbage collection.
- const Event& previous() const { return previous_; }
-
- void RegisterObserver(ThreadHeapStatsObserver* observer);
- void UnregisterObserver(ThreadHeapStatsObserver* observer);
-
- void IncreaseAllocatedObjectSizeForTesting(size_t);
- void DecreaseAllocatedObjectSizeForTesting(size_t);
-
- private:
- // Observers are implemented using virtual calls. Avoid notifications below
- // reasonably interesting sizes.
- static constexpr int64_t kUpdateThreshold = 1024;
-
- // Invokes |callback| for all registered observers.
- template <typename Callback>
- void ForAllObservers(Callback callback);
-
- void AllocatedObjectSizeSafepointImpl();
-
- // Statistics for the currently running garbage collection. Note that the
- // Event may not be fully populated yet as some phase may not have been run.
- const Event& current() const { return current_; }
-
- Event current_;
- Event previous_;
-
- // Allocated bytes since the last garbage collection. These bytes are reset
- // after marking as they are accounted in marked_bytes then.
- int64_t allocated_bytes_since_prev_gc_ = 0;
- int64_t pos_delta_allocated_bytes_since_prev_gc_ = 0;
- int64_t neg_delta_allocated_bytes_since_prev_gc_ = 0;
-
- // Allocated space in bytes for all arenas.
- size_t allocated_space_bytes_ = 0;
-
- bool is_started_ = false;
-
- // base::TimeDelta for RawScope. These don't need to be nested within a
- // garbage collection cycle to make them easier to use.
- base::TimeDelta gc_nested_in_v8_;
-
- Vector<ThreadHeapStatsObserver*> observers_;
-
- FRIEND_TEST_ALL_PREFIXES(ThreadHeapStatsCollectorTest, InitialEmpty);
- FRIEND_TEST_ALL_PREFIXES(ThreadHeapStatsCollectorTest, IncreaseScopeTime);
- FRIEND_TEST_ALL_PREFIXES(ThreadHeapStatsCollectorTest, StopResetsCurrent);
-};
-
-template <ThreadHeapStatsCollector::TraceCategory trace_category,
- ThreadHeapStatsCollector::ScopeContext scope_category>
-constexpr const char*
-ThreadHeapStatsCollector::InternalScope<trace_category,
- scope_category>::TraceCategory() {
- switch (trace_category) {
- case kEnabled:
- return "blink_gc,devtools.timeline";
- case kDisabled:
- return TRACE_DISABLED_BY_DEFAULT("blink_gc");
- }
-}
-
-template <ThreadHeapStatsCollector::TraceCategory trace_category,
- ThreadHeapStatsCollector::ScopeContext scope_category>
-void ThreadHeapStatsCollector::InternalScope<trace_category,
- scope_category>::StartTrace() {
- TRACE_EVENT_BEGIN0(TraceCategory(),
- ToString(id_, tracer_->current_.collection_type));
-}
-
-template <ThreadHeapStatsCollector::TraceCategory trace_category,
- ThreadHeapStatsCollector::ScopeContext scope_category>
-template <typename Value1>
-void ThreadHeapStatsCollector::InternalScope<trace_category, scope_category>::
- StartTrace(const char* k1, Value1 v1) {
- TRACE_EVENT_BEGIN1(TraceCategory(),
- ToString(id_, tracer_->current_.collection_type), k1, v1);
-}
-
-template <ThreadHeapStatsCollector::TraceCategory trace_category,
- ThreadHeapStatsCollector::ScopeContext scope_category>
-template <typename Value1, typename Value2>
-void ThreadHeapStatsCollector::InternalScope<trace_category, scope_category>::
- StartTrace(const char* k1, Value1 v1, const char* k2, Value2 v2) {
- TRACE_EVENT_BEGIN2(TraceCategory(),
- ToString(id_, tracer_->current_.collection_type), k1, v1,
- k2, v2);
-}
-
-template <ThreadHeapStatsCollector::TraceCategory trace_category,
- ThreadHeapStatsCollector::ScopeContext scope_category>
-void ThreadHeapStatsCollector::InternalScope<trace_category,
- scope_category>::StopTrace() {
- TRACE_EVENT_END2(TraceCategory(),
- ToString(id_, tracer_->current_.collection_type), "epoch",
- tracer_->current_.unique_id, "forced",
- tracer_->current_.is_forced_gc);
-}
-
-template <ThreadHeapStatsCollector::TraceCategory trace_category,
- ThreadHeapStatsCollector::ScopeContext scope_category>
-void ThreadHeapStatsCollector::InternalScope<trace_category, scope_category>::
- IncreaseScopeTime(Id) {
- tracer_->IncreaseScopeTime(id_, base::TimeTicks::Now() - start_time_);
-}
-
-template <ThreadHeapStatsCollector::TraceCategory trace_category,
- ThreadHeapStatsCollector::ScopeContext scope_category>
-void ThreadHeapStatsCollector::InternalScope<trace_category, scope_category>::
- IncreaseScopeTime(ConcurrentId) {
- tracer_->IncreaseConcurrentScopeTime(id_,
- base::TimeTicks::Now() - start_time_);
-}
-
-#undef FOR_ALL_SCOPES
-#undef FOR_ALL_CONCURRENT_SCOPES
-
-} // namespace blink
+#if BUILDFLAG(BLINK_HEAP_USE_V8_OILPAN)
+#include "third_party/blink/renderer/platform/heap/v8_wrapper/heap_stats_collector.h"
+#else // !BLINK_HEAP_USE_V8_OILPAN
+#include "third_party/blink/renderer/platform/heap/impl/heap_stats_collector.h"
+#endif // !BLINK_HEAP_USE_V8_OILPAN
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_STATS_COLLECTOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.cc b/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.cc
index 4bf47d69328..3373e840c7c 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.cc
@@ -7,7 +7,7 @@
#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/heap_compact.h"
+#include "third_party/blink/renderer/platform/heap/impl/heap_compact.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.h b/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.h
index e4e3a4c4b51..f9214bbf8ed 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.h
@@ -14,7 +14,7 @@
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/trace_traits.h"
+#include "third_party/blink/renderer/platform/heap/impl/trace_traits.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_traits.h b/chromium/third_party/blink/renderer/platform/heap/heap_traits.h
index f72489def15..43245200945 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_traits.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_traits.h
@@ -1,40 +1,16 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// 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_HEAP_TRAITS_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_TRAITS_H_
-#include <type_traits>
-#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
-#include "third_party/blink/renderer/platform/heap/member.h"
-#include "third_party/blink/renderer/platform/wtf/type_traits.h"
+#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-namespace blink {
-
-// Given a type T, returns a type that is either Member<T> or just T depending
-// on whether T is a garbage-collected type.
-template <typename T>
-using AddMemberIfNeeded =
- std::conditional_t<WTF::IsGarbageCollectedType<T>::value, Member<T>, T>;
-
-// Given a type T, returns a type that is either HeapVector<T>,
-// HeapVector<Member<T>> or Vector<T> depending on T.
-template <typename T>
-using VectorOf = std::conditional_t<WTF::IsTraceable<T>::value,
- HeapVector<AddMemberIfNeeded<T>>,
- Vector<T>>;
-
-// Given types T and U, returns a type that is one of the following:
-// - HeapVector<std::pair<V, X>>
-// (where V is either T or Member<T> and X is either U or Member<U>)
-// - Vector<std::pair<T, U>>
-template <typename T, typename U>
-using VectorOfPairs = std::conditional_t<
- WTF::IsTraceable<T>::value || WTF::IsTraceable<U>::value,
- HeapVector<std::pair<AddMemberIfNeeded<T>, AddMemberIfNeeded<U>>>,
- Vector<std::pair<T, U>>>;
-
-} // namespace blink
+#if BUILDFLAG(BLINK_HEAP_USE_V8_OILPAN)
+#include "third_party/blink/renderer/platform/heap/v8_wrapper/heap_traits.h"
+#else // !BLINK_HEAP_USE_V8_OILPAN
+#include "third_party/blink/renderer/platform/heap/impl/heap_traits.h"
+#endif // !BLINK_HEAP_USE_V8_OILPAN
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_TRAITS_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/atomic_entry_flag.h b/chromium/third_party/blink/renderer/platform/heap/impl/atomic_entry_flag.h
index 07f013a5984..46342d94529 100644
--- a/chromium/third_party/blink/renderer/platform/heap/atomic_entry_flag.h
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/atomic_entry_flag.h
@@ -2,8 +2,8 @@
// 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_ATOMIC_ENTRY_FLAG_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_ATOMIC_ENTRY_FLAG_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_ATOMIC_ENTRY_FLAG_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_ATOMIC_ENTRY_FLAG_H_
#include <atomic>
@@ -48,4 +48,4 @@ class AtomicEntryFlag {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_ATOMIC_ENTRY_FLAG_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_ATOMIC_ENTRY_FLAG_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/blink_gc.cc b/chromium/third_party/blink/renderer/platform/heap/impl/blink_gc.cc
index 65881c15dca..58c86eb7a12 100644
--- a/chromium/third_party/blink/renderer/platform/heap/blink_gc.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/blink_gc.cc
@@ -4,7 +4,6 @@
#include "third_party/blink/renderer/platform/heap/blink_gc.h"
-
namespace blink {
const char* BlinkGC::ToString(BlinkGC::GCReason reason) {
diff --git a/chromium/third_party/blink/renderer/platform/heap/impl/blink_gc.h b/chromium/third_party/blink/renderer/platform/heap/impl/blink_gc.h
new file mode 100644
index 00000000000..1aa6ec6ad8c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/blink_gc.h
@@ -0,0 +1,126 @@
+// Copyright 2015 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_IMPL_BLINK_GC_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_BLINK_GC_H_
+
+// BlinkGC.h is a file that defines common things used by Blink GC.
+
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+#define PRINT_HEAP_STATS 0 // Enable this macro to print heap stats to stderr.
+
+namespace blink {
+
+class LivenessBroker;
+class MarkingVisitor;
+class Visitor;
+
+using Address = uint8_t*;
+using ConstAddress = const uint8_t*;
+
+using VisitorCallback = void (*)(Visitor*, const void*);
+using MarkingVisitorCallback = void (*)(MarkingVisitor*, const void*);
+using TraceCallback = VisitorCallback;
+using WeakCallback = void (*)(const LivenessBroker&, const void*);
+using EphemeronCallback = VisitorCallback;
+
+// Simple alias to avoid heap compaction type signatures turning into
+// a sea of generic |void*|s.
+using MovableReference = const void*;
+
+// List of all arenas. Includes typed arenas as well.
+#define FOR_EACH_ARENA(H) \
+ H(NormalPage1) \
+ H(NormalPage2) \
+ H(NormalPage3) \
+ H(NormalPage4) \
+ H(Vector) \
+ H(HashTable) \
+ H(Node) \
+ H(CSSValue) \
+ H(LargeObject)
+
+class PLATFORM_EXPORT WorklistTaskId {
+ public:
+ static constexpr int MutatorThread = 0;
+ static constexpr int ConcurrentThreadBase = 1;
+};
+
+class PLATFORM_EXPORT BlinkGC final {
+ STATIC_ONLY(BlinkGC);
+
+ public:
+ // CollectionType represents generational collection. kMinor collects objects
+ // in the young generation (i.e. allocated since the previous collection
+ // cycle, since we use sticky bits), kMajor collects the entire heap.
+ enum class CollectionType { kMinor, kMajor };
+
+ // When garbage collecting we need to know whether or not there
+ // can be pointers to Blink GC managed objects on the stack for
+ // each thread. When threads reach a safe point they record
+ // whether or not they have pointers on the stack.
+ enum StackState { kNoHeapPointersOnStack, kHeapPointersOnStack };
+
+ enum MarkingType {
+ // The marking completes synchronously.
+ kAtomicMarking,
+ // The marking task is split and executed in chunks (either on the mutator
+ // thread or concurrently).
+ kIncrementalAndConcurrentMarking
+ };
+
+ enum SweepingType {
+ // The sweeping task is split into chunks and scheduled lazily and
+ // concurrently.
+ kConcurrentAndLazySweeping,
+ // The sweeping task executes synchronously right after marking.
+ kEagerSweeping,
+ };
+
+ // Commented out reasons have been used in the past but are not used any
+ // longer. We keep them here as the corresponding UMA histograms cannot be
+ // changed.
+ enum class GCReason {
+ // kIdleGC = 0
+ // kPreciseGC = 1
+ // kConservativeGC = 2
+ kForcedGCForTesting = 3,
+ // kMemoryPressureGC = 4
+ // kPageNavigationGC = 5
+ kThreadTerminationGC = 6,
+ // kTesting = 7
+ // kIncrementalIdleGC = 8
+ // kIncrementalV8FollowupGC = 9
+ kUnifiedHeapGC = 10,
+ kUnifiedHeapForMemoryReductionGC = 11,
+ kUnifiedHeapForcedForTestingGC = 12,
+ // Used by UMA_HISTOGRAM_ENUMERATION macro.
+ kMaxValue = kUnifiedHeapForcedForTestingGC,
+ };
+
+#define DeclareArenaIndex(name) k##name##ArenaIndex,
+ enum ArenaIndices {
+ FOR_EACH_ARENA(DeclareArenaIndex)
+ // Values used for iteration of heap segments.
+ kNumberOfArenas,
+ };
+#undef DeclareArenaIndex
+
+ enum V8GCType {
+ kV8MinorGC,
+ kV8MajorGC,
+ };
+
+ static const char* ToString(GCReason);
+ static const char* ToString(MarkingType);
+ static const char* ToString(StackState);
+ static const char* ToString(SweepingType);
+ static const char* ToString(ArenaIndices);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_BLINK_GC_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.cc b/chromium/third_party/blink/renderer/platform/heap/impl/blink_gc_memory_dump_provider.cc
index d4105605814..cb8ce725ffa 100644
--- a/chromium/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/blink_gc_memory_dump_provider.cc
@@ -11,8 +11,8 @@
#include "base/trace_event/process_memory_dump.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/impl/thread_state_statistics.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/heap/thread_state_statistics.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/threading.h"
diff --git a/chromium/third_party/blink/renderer/platform/heap/impl/blink_gc_memory_dump_provider.h b/chromium/third_party/blink/renderer/platform/heap/impl/blink_gc_memory_dump_provider.h
new file mode 100644
index 00000000000..e730f8d58f0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/blink_gc_memory_dump_provider.h
@@ -0,0 +1,47 @@
+// Copyright 2015 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_IMPL_BLINK_GC_MEMORY_DUMP_PROVIDER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_BLINK_GC_MEMORY_DUMP_PROVIDER_H_
+
+#include "base/trace_event/memory_dump_provider.h"
+#include "third_party/blink/renderer/platform/heap/blink_gc.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+} // namespace base
+
+namespace blink {
+
+class ThreadState;
+
+class PLATFORM_EXPORT BlinkGCMemoryDumpProvider final
+ : public base::trace_event::MemoryDumpProvider {
+ USING_FAST_MALLOC(BlinkGCMemoryDumpProvider);
+
+ public:
+ enum class HeapType { kBlinkMainThread, kBlinkWorkerThread };
+
+ ~BlinkGCMemoryDumpProvider() final;
+ BlinkGCMemoryDumpProvider(
+ ThreadState* thread_state,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ HeapType heap_type);
+
+ // MemoryDumpProvider implementation.
+ bool OnMemoryDump(const base::trace_event::MemoryDumpArgs&,
+ base::trace_event::ProcessMemoryDump*) final;
+
+ private:
+ ThreadState* const thread_state_;
+ const HeapType heap_type_;
+ const std::string dump_base_name_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_BLINK_GC_MEMORY_DUMP_PROVIDER_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/impl/disallow_new_wrapper.h b/chromium/third_party/blink/renderer/platform/heap/impl/disallow_new_wrapper.h
new file mode 100644
index 00000000000..b6562e440e3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/disallow_new_wrapper.h
@@ -0,0 +1,53 @@
+// Copyright 2019 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_IMPL_DISALLOW_NEW_WRAPPER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_DISALLOW_NEW_WRAPPER_H_
+
+#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/heap/visitor.h"
+
+namespace blink {
+
+// DisallowNewWrapper wraps a disallow new type in a GarbageCollected class.
+template <typename T>
+class DisallowNewWrapper final
+ : public GarbageCollected<DisallowNewWrapper<T>> {
+ public:
+ explicit DisallowNewWrapper(const T& value) : value_(value) {
+ static_assert(WTF::IsDisallowNew<T>::value,
+ "T needs to be a disallow new type");
+ static_assert(WTF::IsTraceable<T>::value, "T needs to be traceable");
+ }
+ explicit DisallowNewWrapper(T&& value) : value_(std::forward<T>(value)) {
+ static_assert(WTF::IsDisallowNew<T>::value,
+ "T needs to be a disallow new type");
+ static_assert(WTF::IsTraceable<T>::value, "T needs to be traceable");
+ }
+
+ const T& Value() const { return value_; }
+ T&& TakeValue() { return std::move(value_); }
+
+ void Trace(Visitor* visitor) const { visitor->Trace(value_); }
+
+ private:
+ T value_;
+};
+
+// Wraps a disallow new type in a GarbageCollected class, making it possible to
+// be referenced off heap from a Persistent.
+template <typename T>
+DisallowNewWrapper<T>* WrapDisallowNew(const T& value) {
+ return MakeGarbageCollected<DisallowNewWrapper<T>>(value);
+}
+
+template <typename T>
+DisallowNewWrapper<T>* WrapDisallowNew(T&& value) {
+ return MakeGarbageCollected<DisallowNewWrapper<T>>(std::forward<T>(value));
+}
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_DISALLOW_NEW_WRAPPER_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/finalizer_traits.h b/chromium/third_party/blink/renderer/platform/heap/impl/finalizer_traits.h
index 1a450a480de..2f0e0ee9f44 100644
--- a/chromium/third_party/blink/renderer/platform/heap/finalizer_traits.h
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/finalizer_traits.h
@@ -2,8 +2,8 @@
// 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_FINALIZER_TRAITS_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_FINALIZER_TRAITS_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_FINALIZER_TRAITS_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_FINALIZER_TRAITS_H_
#include <type_traits>
@@ -92,4 +92,4 @@ struct FinalizerTrait {
} // namespace internal
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_FINALIZER_TRAITS_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_FINALIZER_TRAITS_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/impl/garbage_collected.h b/chromium/third_party/blink/renderer/platform/heap/impl/garbage_collected.h
new file mode 100644
index 00000000000..b7af662ed5d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/garbage_collected.h
@@ -0,0 +1,117 @@
+// Copyright 2015 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_IMPL_GARBAGE_COLLECTED_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_GARBAGE_COLLECTED_H_
+
+#include "base/macros.h"
+#include "third_party/blink/renderer/platform/heap/thread_state.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/assertions.h"
+#include "third_party/blink/renderer/platform/wtf/type_traits.h"
+
+namespace blink {
+
+template <typename T>
+class GarbageCollected;
+
+// GC_PLUGIN_IGNORE is used to make the plugin ignore a particular class or
+// field when checking for proper usage. When using GC_PLUGIN_IGNORE
+// a bug-number should be provided as an argument where the bug describes
+// what needs to happen to remove the GC_PLUGIN_IGNORE again.
+#if defined(__clang__)
+#define GC_PLUGIN_IGNORE(bug) \
+ __attribute__((annotate("blink_gc_plugin_ignore")))
+#else
+#define GC_PLUGIN_IGNORE(bug)
+#endif
+
+// Template to determine if a class is a GarbageCollectedMixin by checking if it
+// has IsGarbageCollectedMixinMarker
+template <typename T>
+struct IsGarbageCollectedMixin {
+ private:
+ typedef char YesType;
+ struct NoType {
+ char padding[8];
+ };
+
+ template <typename U>
+ static YesType CheckMarker(typename U::IsGarbageCollectedMixinMarker*);
+ template <typename U>
+ static NoType CheckMarker(...);
+
+ public:
+ static const bool value = sizeof(CheckMarker<T>(nullptr)) == sizeof(YesType);
+};
+
+// TraceDescriptor is used to describe how to trace an object.
+struct TraceDescriptor {
+ STACK_ALLOCATED();
+
+ public:
+ // The adjusted base pointer of the object that should be traced.
+ const void* base_object_payload;
+ // A callback for tracing the object.
+ TraceCallback callback;
+};
+
+// The GarbageCollectedMixin interface can be used to automatically define
+// TraceTrait/ObjectAliveTrait on non-leftmost deriving classes which need
+// to be garbage collected.
+class PLATFORM_EXPORT GarbageCollectedMixin {
+ public:
+ typedef int IsGarbageCollectedMixinMarker;
+ virtual void Trace(Visitor*) const {}
+};
+
+// Base class for objects allocated in the Blink garbage-collected heap.
+//
+// Instances of GarbageCollected will be finalized if they are non-trivially
+// destructible.
+template <typename T>
+class GarbageCollected;
+
+template <typename T,
+ bool = WTF::IsSubclassOfTemplate<typename std::remove_const<T>::type,
+ GarbageCollected>::value>
+class NeedsAdjustPointer;
+
+template <typename T>
+class NeedsAdjustPointer<T, true> {
+ static_assert(sizeof(T), "T must be fully defined");
+
+ public:
+ static const bool value = false;
+};
+
+template <typename T>
+class NeedsAdjustPointer<T, false> {
+ static_assert(sizeof(T), "T must be fully defined");
+
+ public:
+ static const bool value =
+ IsGarbageCollectedMixin<typename std::remove_const<T>::type>::value;
+};
+
+// TODO(sof): migrate to wtf/TypeTraits.h
+template <typename T>
+class IsFullyDefined {
+ using TrueType = char;
+ struct FalseType {
+ char dummy[2];
+ };
+
+ template <typename U, size_t sz = sizeof(U)>
+ static TrueType IsSizeofKnown(U*);
+ static FalseType IsSizeofKnown(...);
+ static T& t_;
+
+ public:
+ static const bool value = sizeof(TrueType) == sizeof(IsSizeofKnown(&t_));
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_GARBAGE_COLLECTED_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/gc_info.cc b/chromium/third_party/blink/renderer/platform/heap/impl/gc_info.cc
index a3187825c6d..14361c26f3c 100644
--- a/chromium/third_party/blink/renderer/platform/heap/gc_info.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/gc_info.cc
@@ -2,7 +2,7 @@
// 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/gc_info.h"
+#include "third_party/blink/renderer/platform/heap/impl/gc_info.h"
#include "base/allocator/partition_allocator/page_allocator.h"
#include "base/bits.h"
diff --git a/chromium/third_party/blink/renderer/platform/heap/gc_info.h b/chromium/third_party/blink/renderer/platform/heap/impl/gc_info.h
index 155b9164a4a..bec05ee6c1b 100644
--- a/chromium/third_party/blink/renderer/platform/heap/gc_info.h
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/gc_info.h
@@ -2,14 +2,14 @@
// 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_GC_INFO_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_GC_INFO_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_GC_INFO_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_GC_INFO_H_
#include <atomic>
#include "base/gtest_prod_util.h"
#include "third_party/blink/renderer/platform/heap/blink_gc.h"
-#include "third_party/blink/renderer/platform/heap/finalizer_traits.h"
-#include "third_party/blink/renderer/platform/heap/name_traits.h"
+#include "third_party/blink/renderer/platform/heap/impl/finalizer_traits.h"
+#include "third_party/blink/renderer/platform/heap/impl/name_traits.h"
#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
namespace blink {
@@ -125,4 +125,4 @@ class GCInfoTrait<const U> : public GCInfoTrait<U> {};
} // namespace blink
-#endif
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_GC_INFO_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/impl/gc_task_runner.h b/chromium/third_party/blink/renderer/platform/heap/impl/gc_task_runner.h
new file mode 100644
index 00000000000..1e93f7fcac5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/gc_task_runner.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_GC_TASK_RUNNER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_GC_TASK_RUNNER_H_
+
+#include <memory>
+#include "base/location.h"
+#include "third_party/blink/renderer/platform/heap/thread_state.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
+
+namespace blink {
+
+class GCTaskObserver final : public Thread::TaskObserver {
+ USING_FAST_MALLOC(GCTaskObserver);
+
+ public:
+ GCTaskObserver() : nesting_(0) {}
+
+ ~GCTaskObserver() override {
+ // m_nesting can be 1 if this was unregistered in a task and
+ // didProcessTask was not called.
+ DCHECK(!nesting_ || nesting_ == 1);
+ }
+
+ void WillProcessTask(const base::PendingTask&, bool) override { nesting_++; }
+
+ void DidProcessTask(const base::PendingTask&) override {
+ // In the production code WebKit::initialize is called from inside the
+ // message loop so we can get didProcessTask() without corresponding
+ // willProcessTask once. This is benign.
+ if (nesting_)
+ nesting_--;
+
+ ThreadState::Current()->SafePoint(nesting_
+ ? BlinkGC::kHeapPointersOnStack
+ : BlinkGC::kNoHeapPointersOnStack);
+ }
+
+ private:
+ int nesting_;
+};
+
+class GCTaskRunner final {
+ USING_FAST_MALLOC(GCTaskRunner);
+
+ public:
+ explicit GCTaskRunner(Thread* thread)
+ : gc_task_observer_(std::make_unique<GCTaskObserver>()), thread_(thread) {
+ thread_->AddTaskObserver(gc_task_observer_.get());
+ }
+
+ ~GCTaskRunner() { thread_->RemoveTaskObserver(gc_task_observer_.get()); }
+
+ private:
+ std::unique_ptr<GCTaskObserver> gc_task_observer_;
+ Thread* thread_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_GC_TASK_RUNNER_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap.cc b/chromium/third_party/blink/renderer/platform/heap/impl/heap.cc
index 2a5b1790935..2fa56d7d1d9 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/heap.cc
@@ -40,13 +40,13 @@
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h"
#include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h"
-#include "third_party/blink/renderer/platform/heap/heap_compact.h"
#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
-#include "third_party/blink/renderer/platform/heap/marking_scheduling_oracle.h"
-#include "third_party/blink/renderer/platform/heap/marking_visitor.h"
-#include "third_party/blink/renderer/platform/heap/page_bloom_filter.h"
-#include "third_party/blink/renderer/platform/heap/page_memory.h"
-#include "third_party/blink/renderer/platform/heap/page_pool.h"
+#include "third_party/blink/renderer/platform/heap/impl/heap_compact.h"
+#include "third_party/blink/renderer/platform/heap/impl/marking_scheduling_oracle.h"
+#include "third_party/blink/renderer/platform/heap/impl/marking_visitor.h"
+#include "third_party/blink/renderer/platform/heap/impl/page_bloom_filter.h"
+#include "third_party/blink/renderer/platform/heap/impl/page_memory.h"
+#include "third_party/blink/renderer/platform/heap/impl/page_pool.h"
#include "third_party/blink/renderer/platform/heap/thread_state_scopes.h"
#include "third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
@@ -180,6 +180,7 @@ void ThreadHeap::SetupWorklists(bool should_initialize_compaction_worklists) {
v8_references_worklist_ = std::make_unique<V8ReferencesWorklist>();
not_safe_to_concurrently_trace_worklist_ =
std::make_unique<NotSafeToConcurrentlyTraceWorklist>();
+ weak_containers_worklist_ = std::make_unique<WeakContainersWorklist>();
if (should_initialize_compaction_worklists) {
movable_reference_worklist_ = std::make_unique<MovableReferenceWorklist>();
}
@@ -193,6 +194,7 @@ void ThreadHeap::DestroyMarkingWorklists(BlinkGC::StackState stack_state) {
ephemeron_pairs_to_process_worklist_.reset();
v8_references_worklist_.reset();
not_safe_to_concurrently_trace_worklist_.reset();
+ weak_containers_worklist_.reset();
// The fixed point iteration may have found not-fully-constructed objects.
// Such objects should have already been found through the stack scan though
// and should thus already be marked.
@@ -376,8 +378,7 @@ bool ThreadHeap::InvokeEphemeronCallbacks(
return DrainWorklistWithDeadline(
deadline, ephemeron_pairs_to_process_worklist_.get(),
[visitor](EphemeronPairItem& item) {
- visitor->VisitEphemeron(item.key, item.value,
- item.value_trace_callback);
+ visitor->VisitEphemeron(item.key, item.value_desc);
},
WorklistTaskId::MutatorThread);
}
@@ -579,14 +580,12 @@ bool ThreadHeap::AdvanceConcurrentMarking(
// Callbacks found by the concurrent marking will be flushed eventually
// by the mutator thread and then invoked either concurrently or by the
// mutator thread (in the atomic pause at latest).
- finished =
- DrainWorklist<kDefaultConcurrentDeadlineCheckInterval>(
- ephemeron_pairs_to_process_worklist_.get(),
- [visitor](EphemeronPairItem& item) {
- visitor->VisitEphemeron(item.key, item.value,
- item.value_trace_callback);
- },
- should_yield_callback, visitor->task_id());
+ finished = DrainWorklist<kDefaultConcurrentDeadlineCheckInterval>(
+ ephemeron_pairs_to_process_worklist_.get(),
+ [visitor](EphemeronPairItem& item) {
+ visitor->VisitEphemeron(item.key, item.value_desc);
+ },
+ should_yield_callback, visitor->task_id());
if (!finished)
break;
}
@@ -711,8 +710,8 @@ void ThreadHeap::CompleteSweep() {
}
void ThreadHeap::InvokeFinalizersOnSweptPages() {
- for (size_t i = BlinkGC::kNormalPage1ArenaIndex;
- i < BlinkGC::kNumberOfArenas; i++)
+ for (size_t i = BlinkGC::kNormalPage1ArenaIndex; i < BlinkGC::kNumberOfArenas;
+ i++)
arenas_[i]->InvokeFinalizersOnSweptPages();
}
diff --git a/chromium/third_party/blink/renderer/platform/heap/impl/heap.h b/chromium/third_party/blink/renderer/platform/heap/impl/heap.h
new file mode 100644
index 00000000000..f1740aaa3e2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/heap.h
@@ -0,0 +1,757 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_H_
+
+#include <limits>
+#include <memory>
+#include <unordered_set>
+
+#include "base/macros.h"
+#include "build/build_config.h"
+#include "third_party/blink/renderer/platform/heap/impl/gc_info.h"
+#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
+#include "third_party/blink/renderer/platform/heap/impl/thread_state_statistics.h"
+#include "third_party/blink/renderer/platform/heap/impl/worklist.h"
+#include "third_party/blink/renderer/platform/heap/process_heap.h"
+#include "third_party/blink/renderer/platform/heap/thread_state.h"
+#include "third_party/blink/renderer/platform/heap/visitor.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/assertions.h"
+#include "third_party/blink/renderer/platform/wtf/forward.h"
+#include "third_party/blink/renderer/platform/wtf/sanitizers.h"
+#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
+
+namespace blink {
+
+namespace incremental_marking_test {
+class IncrementalMarkingScopeBase;
+} // namespace incremental_marking_test
+
+class ConcurrentMarkingVisitor;
+class ThreadHeapStatsCollector;
+class PageBloomFilter;
+class PagePool;
+class ProcessHeapReporter;
+class RegionTree;
+class MarkingSchedulingOracle;
+
+using MarkingItem = TraceDescriptor;
+using NotFullyConstructedItem = const void*;
+
+struct EphemeronPairItem {
+ const void* key;
+ TraceDescriptor value_desc;
+};
+
+struct CustomCallbackItem {
+ WeakCallback callback;
+ const void* parameter;
+};
+
+struct NotSafeToConcurrentlyTraceItem {
+ TraceDescriptor desc;
+ size_t bailout_size;
+};
+
+using V8Reference = const TraceWrapperV8Reference<v8::Value>*;
+
+// Segment size of 512 entries necessary to avoid throughput regressions. Since
+// the work list is currently a temporary object this is not a problem.
+using MarkingWorklist = Worklist<MarkingItem, 512 /* local entries */>;
+using WriteBarrierWorklist = Worklist<HeapObjectHeader*, 64>;
+using NotFullyConstructedWorklist =
+ Worklist<NotFullyConstructedItem, 16 /* local entries */>;
+using WeakCallbackWorklist =
+ Worklist<CustomCallbackItem, 64 /* local entries */>;
+// Using large local segments here (sized 512 entries) to avoid throughput
+// regressions.
+using MovableReferenceWorklist =
+ Worklist<const MovableReference*, 256 /* local entries */>;
+using EphemeronPairsWorklist =
+ Worklist<EphemeronPairItem, 64 /* local entries */>;
+using V8ReferencesWorklist = Worklist<V8Reference, 16 /* local entries */>;
+using NotSafeToConcurrentlyTraceWorklist =
+ Worklist<NotSafeToConcurrentlyTraceItem, 64 /* local entries */>;
+
+class WeakContainersWorklist {
+ public:
+ inline void Push(const HeapObjectHeader* object) {
+ DCHECK(object);
+ WTF::MutexLocker locker(lock_);
+ objects_.insert(object);
+ }
+
+ inline bool Contains(const HeapObjectHeader* object) {
+ // This method is called only during atomic pause, so lock is not needed.
+ DCHECK(object);
+ return objects_.find(object) != objects_.end();
+ }
+
+ private:
+ WTF::Mutex lock_;
+ std::unordered_set<const HeapObjectHeader*> objects_;
+};
+
+class PLATFORM_EXPORT HeapAllocHooks {
+ STATIC_ONLY(HeapAllocHooks);
+
+ public:
+ // TODO(hajimehoshi): Pass a type name of the allocated object.
+ typedef void AllocationHook(Address, size_t, const char*);
+ typedef void FreeHook(Address);
+
+ // Sets allocation hook. Only one hook is supported.
+ static void SetAllocationHook(AllocationHook* hook) {
+ CHECK(!allocation_hook_ || !hook);
+ allocation_hook_ = hook;
+ }
+
+ // Sets free hook. Only one hook is supported.
+ static void SetFreeHook(FreeHook* hook) {
+ CHECK(!free_hook_ || !hook);
+ free_hook_ = hook;
+ }
+
+ static void AllocationHookIfEnabled(Address address,
+ size_t size,
+ const char* type_name) {
+ AllocationHook* allocation_hook = allocation_hook_;
+ if (UNLIKELY(!!allocation_hook))
+ allocation_hook(address, size, type_name);
+ }
+
+ static void FreeHookIfEnabled(Address address) {
+ FreeHook* free_hook = free_hook_;
+ if (UNLIKELY(!!free_hook))
+ free_hook(address);
+ }
+
+ private:
+ static AllocationHook* allocation_hook_;
+ static FreeHook* free_hook_;
+};
+
+class HeapCompact;
+template <typename T>
+class Member;
+template <typename T>
+class WeakMember;
+template <typename T>
+class UntracedMember;
+
+namespace internal {
+
+class LivenessBrokerFactory;
+
+template <typename T, bool = NeedsAdjustPointer<T>::value>
+class ObjectAliveTrait;
+
+template <typename T>
+class ObjectAliveTrait<T, false> {
+ STATIC_ONLY(ObjectAliveTrait);
+
+ public:
+ static bool IsHeapObjectAlive(const T* object) {
+ static_assert(sizeof(T), "T must be fully defined");
+ return HeapObjectHeader::FromPayload(object)->IsMarked();
+ }
+};
+
+template <typename T>
+class ObjectAliveTrait<T, true> {
+ STATIC_ONLY(ObjectAliveTrait);
+
+ public:
+ NO_SANITIZE_ADDRESS
+ static bool IsHeapObjectAlive(const T* object) {
+ static_assert(sizeof(T), "T must be fully defined");
+ const HeapObjectHeader* header = HeapObjectHeader::FromPayload(
+ TraceTrait<T>::GetTraceDescriptor(object).base_object_payload);
+ DCHECK(!header->IsInConstruction() || header->IsMarked());
+ return header->IsMarked();
+ }
+};
+
+template <typename T, typename = int>
+struct IsGarbageCollectedContainer : std::false_type {};
+
+template <typename T>
+struct IsGarbageCollectedContainer<
+ T,
+ typename T::IsGarbageCollectedCollectionTypeMarker> : std::true_type {};
+
+} // namespace internal
+
+class PLATFORM_EXPORT ThreadHeap {
+ USING_FAST_MALLOC(ThreadHeap);
+
+ using EphemeronProcessing = ThreadState::EphemeronProcessing;
+
+ public:
+ explicit ThreadHeap(ThreadState*);
+ ~ThreadHeap();
+
+ MarkingWorklist* GetMarkingWorklist() const {
+ return marking_worklist_.get();
+ }
+
+ WriteBarrierWorklist* GetWriteBarrierWorklist() const {
+ return write_barrier_worklist_.get();
+ }
+
+ NotFullyConstructedWorklist* GetNotFullyConstructedWorklist() const {
+ return not_fully_constructed_worklist_.get();
+ }
+
+ NotFullyConstructedWorklist* GetPreviouslyNotFullyConstructedWorklist()
+ const {
+ return previously_not_fully_constructed_worklist_.get();
+ }
+
+ WeakCallbackWorklist* GetWeakCallbackWorklist() const {
+ return weak_callback_worklist_.get();
+ }
+
+ MovableReferenceWorklist* GetMovableReferenceWorklist() const {
+ return movable_reference_worklist_.get();
+ }
+
+ EphemeronPairsWorklist* GetDiscoveredEphemeronPairsWorklist() const {
+ return discovered_ephemeron_pairs_worklist_.get();
+ }
+
+ EphemeronPairsWorklist* GetEphemeronPairsToProcessWorklist() const {
+ return ephemeron_pairs_to_process_worklist_.get();
+ }
+
+ V8ReferencesWorklist* GetV8ReferencesWorklist() const {
+ return v8_references_worklist_.get();
+ }
+
+ NotSafeToConcurrentlyTraceWorklist* GetNotSafeToConcurrentlyTraceWorklist()
+ const {
+ return not_safe_to_concurrently_trace_worklist_.get();
+ }
+
+ WeakContainersWorklist* GetWeakContainersWorklist() const {
+ return weak_containers_worklist_.get();
+ }
+
+ // Register an ephemeron table for fixed-point iteration.
+ void RegisterWeakTable(void* container_object, EphemeronCallback);
+
+ // Heap compaction registration methods:
+
+ // Checks whether we need to register |addr| as a backing store or a slot
+ // containing reference to it.
+ bool ShouldRegisterMovingAddress();
+
+ RegionTree* GetRegionTree() { return region_tree_.get(); }
+
+ static inline size_t AllocationSizeFromSize(size_t size) {
+ // Add space for header.
+ size_t allocation_size = size + sizeof(HeapObjectHeader);
+ // The allocation size calculation can overflow for large sizes.
+ CHECK_GT(allocation_size, size);
+ // Align size with allocation granularity.
+ allocation_size = (allocation_size + kAllocationMask) & ~kAllocationMask;
+ return allocation_size;
+ }
+ Address AllocateOnArenaIndex(ThreadState*,
+ size_t,
+ int arena_index,
+ uint32_t gc_info_index,
+ const char* type_name);
+ template <typename T>
+ static Address Allocate(size_t);
+
+ void WeakProcessing(MarkingVisitor*);
+
+ // Moves not fully constructed objects to previously not fully constructed
+ // objects. Such objects can be iterated using the Trace() method and do
+ // not need to rely on conservative handling.
+ void FlushNotFullyConstructedObjects();
+
+ // Moves ephemeron pairs from |discovered_ephemeron_pairs_worklist_| to
+ // |ephemeron_pairs_to_process_worklist_|
+ void FlushEphemeronPairs(EphemeronProcessing);
+
+ // Marks not fully constructed objects.
+ void MarkNotFullyConstructedObjects(MarkingVisitor*);
+ // Marks the transitive closure including ephemerons.
+ bool AdvanceMarking(MarkingVisitor*, base::TimeTicks, EphemeronProcessing);
+ void VerifyMarking();
+
+ // Returns true if concurrent markers will have work to steal
+ bool HasWorkForConcurrentMarking() const;
+ // Returns the amount of work currently available for stealing (there could be
+ // work remaining even if this is 0).
+ size_t ConcurrentMarkingGlobalWorkSize() const;
+ // Returns true if marker is done
+ bool AdvanceConcurrentMarking(ConcurrentMarkingVisitor*,
+ base::JobDelegate*,
+ MarkingSchedulingOracle* marking_scheduler);
+
+ // Conservatively checks whether an address is a pointer in any of the
+ // thread heaps. If so marks the object pointed to as live.
+ Address CheckAndMarkPointer(MarkingVisitor*, Address);
+
+ // Visits remembered sets.
+ void VisitRememberedSets(MarkingVisitor*);
+
+ size_t ObjectPayloadSizeForTesting();
+ void ResetAllocationPointForTesting();
+
+ PagePool* GetFreePagePool() { return free_page_pool_.get(); }
+
+ // This look-up uses the region search tree and a negative contains cache to
+ // provide an efficient mapping from arbitrary addresses to the containing
+ // heap-page if one exists.
+ BasePage* LookupPageForAddress(ConstAddress);
+
+ HeapCompact* Compaction();
+
+ // Get one of the heap structures for this thread.
+ // The thread heap is split into multiple heap parts based on object types
+ // and object sizes.
+ BaseArena* Arena(int arena_index) const {
+ DCHECK_LE(0, arena_index);
+ DCHECK_LT(arena_index, BlinkGC::kNumberOfArenas);
+ return arenas_[arena_index];
+ }
+
+ static bool IsVectorArenaIndex(int arena_index) {
+ return BlinkGC::kVectorArenaIndex == arena_index;
+ }
+ static bool IsNormalArenaIndex(int);
+
+ void MakeConsistentForGC();
+ // MakeConsistentForMutator() drops marks from marked objects and rebuild
+ // free lists. This is called after taking a snapshot and before resuming
+ // the executions of mutators.
+ void MakeConsistentForMutator();
+
+ // Unmarks all objects in the entire heap. This is supposed to be called in
+ // the beginning of major GC.
+ void Unmark();
+
+ void Compact();
+
+ bool AdvanceLazySweep(base::TimeTicks deadline);
+ bool AdvanceConcurrentSweep(base::JobDelegate*);
+
+ void PrepareForSweep(BlinkGC::CollectionType);
+ void RemoveAllPages();
+ void InvokeFinalizersOnSweptPages();
+ void CompleteSweep();
+
+ void CollectStatistics(ThreadState::Statistics* statistics);
+
+ ThreadHeapStatsCollector* stats_collector() const {
+ return heap_stats_collector_.get();
+ }
+
+#if defined(ADDRESS_SANITIZER)
+ void PoisonUnmarkedObjects();
+#endif
+
+#if DCHECK_IS_ON()
+ // Infrastructure to determine if an address is within one of the
+ // address ranges for the Blink heap. If the address is in the Blink
+ // heap the containing heap page is returned.
+ BasePage* FindPageFromAddress(Address);
+ BasePage* FindPageFromAddress(const void* pointer) {
+ return FindPageFromAddress(
+ reinterpret_cast<Address>(const_cast<void*>(pointer)));
+ }
+#endif
+
+ PageBloomFilter* page_bloom_filter() { return page_bloom_filter_.get(); }
+
+ bool IsInLastAllocatedRegion(Address address) const;
+ void SetLastAllocatedRegion(Address start, size_t length);
+
+ private:
+ struct LastAllocatedRegion {
+ Address start = nullptr;
+ size_t length = 0;
+ };
+
+ static int ArenaIndexForObjectSize(size_t);
+
+ void SetupWorklists(bool);
+ void DestroyMarkingWorklists(BlinkGC::StackState);
+ void DestroyCompactionWorklists();
+
+ bool InvokeEphemeronCallbacks(EphemeronProcessing,
+ MarkingVisitor*,
+ base::TimeTicks);
+
+ bool FlushV8References(base::TimeTicks);
+
+ ThreadState* thread_state_;
+ std::unique_ptr<ThreadHeapStatsCollector> heap_stats_collector_;
+ std::unique_ptr<RegionTree> region_tree_;
+ std::unique_ptr<PageBloomFilter> page_bloom_filter_;
+ std::unique_ptr<PagePool> free_page_pool_;
+ std::unique_ptr<ProcessHeapReporter> process_heap_reporter_;
+
+ // All objects on this worklist have been fully initialized and assigned a
+ // trace callback for iterating the body of the object. This worklist should
+ // contain almost all objects.
+ std::unique_ptr<MarkingWorklist> marking_worklist_;
+
+ // Objects on this worklist have been collected in the write barrier. The
+ // worklist is different from |marking_worklist_| to minimize execution in the
+ // path where a write barrier is executed.
+ std::unique_ptr<WriteBarrierWorklist> write_barrier_worklist_;
+
+ // Objects on this worklist were observed to be in construction (in their
+ // constructor) and thus have been delayed for processing. They have not yet
+ // been assigned a valid header and trace callback.
+ std::unique_ptr<NotFullyConstructedWorklist> not_fully_constructed_worklist_;
+
+ // Objects on this worklist were previously in construction but have been
+ // moved here upon observing a safepoint, i.e., processing without stack. They
+ // have not yet been assigned a valid header and trace callback but are fully
+ // specified and can thus be iterated using the trace callback (which can be
+ // looked up dynamically).
+ std::unique_ptr<NotFullyConstructedWorklist>
+ previously_not_fully_constructed_worklist_;
+
+ // Worklist of weak callbacks accumulated for objects. Such callbacks are
+ // processed after finishing marking objects.
+ std::unique_ptr<WeakCallbackWorklist> weak_callback_worklist_;
+
+ // The worklist is to remember slots that are traced during
+ // marking phases. The mapping between the slots and the backing stores are
+ // created at the atomic pause phase.
+ std::unique_ptr<MovableReferenceWorklist> movable_reference_worklist_;
+
+ // Worklist of ephemeron callbacks. Used to pass new callbacks from
+ // MarkingVisitor to ThreadHeap.
+ std::unique_ptr<EphemeronPairsWorklist> discovered_ephemeron_pairs_worklist_;
+ std::unique_ptr<EphemeronPairsWorklist> ephemeron_pairs_to_process_worklist_;
+
+ // Worklist for storing the V8 references until ThreadHeap can flush them
+ // to V8.
+ std::unique_ptr<V8ReferencesWorklist> v8_references_worklist_;
+
+ std::unique_ptr<NotSafeToConcurrentlyTraceWorklist>
+ not_safe_to_concurrently_trace_worklist_;
+
+ std::unique_ptr<WeakContainersWorklist> weak_containers_worklist_;
+
+ std::unique_ptr<HeapCompact> compaction_;
+
+ LastAllocatedRegion last_allocated_region_;
+
+ BaseArena* arenas_[BlinkGC::kNumberOfArenas];
+
+ static ThreadHeap* main_thread_heap_;
+
+ static constexpr size_t kStepsBeforeEphemeronPairsFlush = 4u;
+ size_t steps_since_last_ephemeron_pairs_flush_ = 0;
+ static constexpr size_t kStepsBeforeEphemeronProcessing = 16u;
+ size_t steps_since_last_ephemeron_processing_ = 0;
+
+ friend class incremental_marking_test::IncrementalMarkingScopeBase;
+ template <typename T>
+ friend class Member;
+ friend class ThreadState;
+};
+
+template <typename T>
+class GarbageCollected {
+ IS_GARBAGE_COLLECTED_TYPE();
+
+ public:
+ using ParentMostGarbageCollectedType = T;
+
+ // Must use MakeGarbageCollected.
+ void* operator new(size_t) = delete;
+ void* operator new[](size_t) = delete;
+ // The garbage collector is taking care of reclaiming the object. Also,
+ // virtual destructor requires an unambiguous, accessible 'operator delete'.
+ void operator delete(void*) { NOTREACHED(); }
+ void operator delete[](void*) = delete;
+
+ template <typename Derived>
+ static void* AllocateObject(size_t size) {
+ return ThreadHeap::Allocate<GCInfoFoldedType<Derived>>(size);
+ }
+
+ protected:
+ // This trait in theory can be moved to gc_info.h, but that would cause
+ // significant memory bloat caused by huge number of ThreadHeap::Allocate<>
+ // instantiations, which linker is not able to fold.
+ template <typename Derived>
+ class GCInfoFolded {
+ static constexpr bool is_virtual_destructor_at_base =
+ std::has_virtual_destructor<ParentMostGarbageCollectedType>::value;
+ static constexpr bool both_trivially_destructible =
+ std::is_trivially_destructible<ParentMostGarbageCollectedType>::value &&
+ std::is_trivially_destructible<Derived>::value;
+ static constexpr bool has_custom_dispatch_at_base =
+ internal::HasFinalizeGarbageCollectedObject<
+ ParentMostGarbageCollectedType>::value;
+
+ public:
+ using Type = std::conditional_t<is_virtual_destructor_at_base ||
+ both_trivially_destructible ||
+ has_custom_dispatch_at_base,
+ ParentMostGarbageCollectedType,
+ Derived>;
+ };
+
+ template <typename Derived>
+ using GCInfoFoldedType = typename GCInfoFolded<Derived>::Type;
+
+ GarbageCollected() = default;
+
+ DISALLOW_COPY_AND_ASSIGN(GarbageCollected);
+};
+
+// Used for passing custom sizes to MakeGarbageCollected.
+struct AdditionalBytes {
+ explicit AdditionalBytes(size_t bytes) : value(bytes) {}
+ const size_t value;
+};
+
+template <typename T>
+struct MakeGarbageCollectedTrait {
+ template <typename... Args>
+ static T* Call(Args&&... args) {
+ static_assert(WTF::IsGarbageCollectedType<T>::value,
+ "T needs to be a garbage collected object");
+ static_assert(
+ std::is_trivially_destructible<T>::value ||
+ std::has_virtual_destructor<T>::value || std::is_final<T>::value ||
+ internal::IsGarbageCollectedContainer<T>::value ||
+ internal::HasFinalizeGarbageCollectedObject<T>::value,
+ "Finalized GarbageCollected class should either have a virtual "
+ "destructor or be marked as final");
+ static_assert(!IsGarbageCollectedMixin<T>::value ||
+ sizeof(T) <= kLargeObjectSizeThreshold,
+ "GarbageCollectedMixin may not be a large object");
+ void* memory = T::template AllocateObject<T>(sizeof(T));
+ HeapObjectHeader* header = HeapObjectHeader::FromPayload(memory);
+ // Placement new as regular operator new() is deleted.
+ T* object = ::new (memory) T(std::forward<Args>(args)...);
+ header->MarkFullyConstructed<HeapObjectHeader::AccessMode::kAtomic>();
+ return object;
+ }
+
+ template <typename... Args>
+ static T* Call(AdditionalBytes additional_bytes, Args&&... args) {
+ static_assert(WTF::IsGarbageCollectedType<T>::value,
+ "T needs to be a garbage collected object");
+ static_assert(
+ std::is_trivially_destructible<T>::value ||
+ std::has_virtual_destructor<T>::value || std::is_final<T>::value ||
+ internal::IsGarbageCollectedContainer<T>::value ||
+ internal::HasFinalizeGarbageCollectedObject<T>::value,
+ "Finalized GarbageCollected class should either have a virtual "
+ "destructor or be marked as final.");
+ const size_t size = sizeof(T) + additional_bytes.value;
+ if (IsGarbageCollectedMixin<T>::value) {
+ // Ban large mixin so we can use PageFromObject() on them.
+ CHECK_GE(kLargeObjectSizeThreshold, size)
+ << "GarbageCollectedMixin may not be a large object";
+ }
+ void* memory = T::template AllocateObject<T>(size);
+ HeapObjectHeader* header = HeapObjectHeader::FromPayload(memory);
+ // Placement new as regular operator new() is deleted.
+ T* object = ::new (memory) T(std::forward<Args>(args)...);
+ header->MarkFullyConstructed<HeapObjectHeader::AccessMode::kAtomic>();
+ return object;
+ }
+};
+
+template <typename T, typename = void>
+struct PostConstructionHookTrait {
+ static void Call(T*) {}
+};
+
+// Default MakeGarbageCollected: Constructs an instance of T, which is a garbage
+// collected type.
+template <typename T, typename... Args>
+T* MakeGarbageCollected(Args&&... args) {
+ T* object = MakeGarbageCollectedTrait<T>::Call(std::forward<Args>(args)...);
+ PostConstructionHookTrait<T>::Call(object);
+ return object;
+}
+
+// Constructs an instance of T, which is a garbage collected type. This special
+// version takes size which enables constructing inline objects.
+template <typename T, typename... Args>
+T* MakeGarbageCollected(AdditionalBytes additional_bytes, Args&&... args) {
+ T* object = MakeGarbageCollectedTrait<T>::Call(additional_bytes,
+ std::forward<Args>(args)...);
+ PostConstructionHookTrait<T>::Call(object);
+ return object;
+}
+
+// Assigning class types to their arenas.
+//
+// We use sized arenas for most 'normal' objects to improve memory locality.
+// It seems that the same type of objects are likely to be accessed together,
+// which means that we want to group objects by type. That's one reason
+// why we provide dedicated arenas for popular types (e.g., Node, CSSValue),
+// but it's not practical to prepare dedicated arenas for all types.
+// Thus we group objects by their sizes, hoping that this will approximately
+// group objects by their types.
+//
+
+inline int ThreadHeap::ArenaIndexForObjectSize(size_t size) {
+ if (size < 64) {
+ if (size < 32)
+ return BlinkGC::kNormalPage1ArenaIndex;
+ return BlinkGC::kNormalPage2ArenaIndex;
+ }
+ if (size < 128)
+ return BlinkGC::kNormalPage3ArenaIndex;
+ return BlinkGC::kNormalPage4ArenaIndex;
+}
+
+inline bool ThreadHeap::IsNormalArenaIndex(int index) {
+ return index >= BlinkGC::kNormalPage1ArenaIndex &&
+ index <= BlinkGC::kNormalPage4ArenaIndex;
+}
+
+inline Address ThreadHeap::AllocateOnArenaIndex(ThreadState* state,
+ size_t size,
+ int arena_index,
+ uint32_t gc_info_index,
+ const char* type_name) {
+ DCHECK(state->IsAllocationAllowed());
+ DCHECK_NE(arena_index, BlinkGC::kLargeObjectArenaIndex);
+ NormalPageArena* arena = static_cast<NormalPageArena*>(Arena(arena_index));
+ Address address =
+ arena->AllocateObject(AllocationSizeFromSize(size), gc_info_index);
+ HeapAllocHooks::AllocationHookIfEnabled(address, size, type_name);
+ return address;
+}
+
+template <typename T>
+Address ThreadHeap::Allocate(size_t size) {
+ ThreadState* state = ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
+ const char* type_name = WTF_HEAP_PROFILER_TYPE_NAME(T);
+ return state->Heap().AllocateOnArenaIndex(
+ state, size, ThreadHeap::ArenaIndexForObjectSize(size),
+ GCInfoTrait<T>::Index(), type_name);
+}
+
+inline bool ThreadHeap::IsInLastAllocatedRegion(Address address) const {
+ return last_allocated_region_.start <= address &&
+ address <
+ (last_allocated_region_.start + last_allocated_region_.length);
+}
+
+inline void ThreadHeap::SetLastAllocatedRegion(Address start, size_t length) {
+ last_allocated_region_.start = start;
+ last_allocated_region_.length = length;
+}
+
+class PLATFORM_EXPORT LivenessBroker final {
+ public:
+ template <typename T>
+ bool IsHeapObjectAlive(const T*) const;
+ template <typename T>
+ bool IsHeapObjectAlive(const WeakMember<T>&) const;
+ template <typename T>
+ bool IsHeapObjectAlive(const UntracedMember<T>&) const;
+
+ private:
+ LivenessBroker() = default;
+ friend class internal::LivenessBrokerFactory;
+};
+
+template <typename T>
+bool LivenessBroker::IsHeapObjectAlive(const T* object) const {
+ static_assert(sizeof(T), "T must be fully defined");
+ // The strongification of collections relies on the fact that once a
+ // collection has been strongified, there is no way that it can contain
+ // non-live entries, so no entries will be removed. Since you can't set
+ // the mark bit on a null pointer, that means that null pointers are
+ // always 'alive'.
+ if (!object)
+ return true;
+ // TODO(keishi): some tests create CrossThreadPersistent on non attached
+ // threads.
+ if (!ThreadState::Current())
+ return true;
+ DCHECK(&ThreadState::Current()->Heap() ==
+ &PageFromObject(object)->Arena()->GetThreadState()->Heap());
+ return internal::ObjectAliveTrait<T>::IsHeapObjectAlive(object);
+}
+
+template <typename T>
+bool LivenessBroker::IsHeapObjectAlive(const WeakMember<T>& weak_member) const {
+ return IsHeapObjectAlive(weak_member.Get());
+}
+
+template <typename T>
+bool LivenessBroker::IsHeapObjectAlive(
+ const UntracedMember<T>& untraced_member) const {
+ return IsHeapObjectAlive(untraced_member.Get());
+}
+
+template <typename T>
+void Visitor::HandleWeakCell(const LivenessBroker& broker, const void* object) {
+ WeakMember<T>* weak_member =
+ reinterpret_cast<WeakMember<T>*>(const_cast<void*>(object));
+ if (weak_member->Get()) {
+ if (weak_member->IsHashTableDeletedValue()) {
+ // This can happen when weak fields are deleted while incremental marking
+ // is running. Deleted values need to be preserved to avoid reviving
+ // objects in containers.
+ return;
+ }
+ if (!broker.IsHeapObjectAlive(weak_member->Get()))
+ weak_member->Clear();
+ }
+}
+
+namespace internal {
+
+class LivenessBrokerFactory final {
+ public:
+ static LivenessBroker Create() { return LivenessBroker(); }
+};
+
+} // namespace internal
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_allocator.cc b/chromium/third_party/blink/renderer/platform/heap/impl/heap_allocator.cc
index f4e2745e671..f4e2745e671 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_allocator.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/heap_allocator.cc
diff --git a/chromium/third_party/blink/renderer/platform/heap/impl/heap_allocator.h b/chromium/third_party/blink/renderer/platform/heap/impl/heap_allocator.h
new file mode 100644
index 00000000000..8fc46cb2a62
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/heap_allocator.h
@@ -0,0 +1,909 @@
+// Copyright 2015 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_IMPL_HEAP_ALLOCATOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_ALLOCATOR_H_
+
+#include <type_traits>
+
+#include "build/build_config.h"
+#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h"
+#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
+#include "third_party/blink/renderer/platform/heap/impl/marking_visitor.h"
+#include "third_party/blink/renderer/platform/heap/impl/trace_traits.h"
+#include "third_party/blink/renderer/platform/heap/thread_state_scopes.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/assertions.h"
+#include "third_party/blink/renderer/platform/wtf/construct_traits.h"
+#include "third_party/blink/renderer/platform/wtf/deque.h"
+#include "third_party/blink/renderer/platform/wtf/doubly_linked_list.h"
+#include "third_party/blink/renderer/platform/wtf/hash_counted_set.h"
+#include "third_party/blink/renderer/platform/wtf/hash_map.h"
+#include "third_party/blink/renderer/platform/wtf/hash_set.h"
+#include "third_party/blink/renderer/platform/wtf/hash_table.h"
+#include "third_party/blink/renderer/platform/wtf/linked_hash_set.h"
+#include "third_party/blink/renderer/platform/wtf/list_hash_set.h"
+#include "third_party/blink/renderer/platform/wtf/type_traits.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace blink {
+
+#define DISALLOW_IN_CONTAINER() \
+ public: \
+ using IsDisallowedInContainerMarker = int; \
+ \
+ private: \
+ friend class ::WTF::internal::__thisIsHereToForceASemicolonAfterThisMacro
+
+// IsAllowedInContainer returns true if some type T supports being nested
+// arbitrarily in other containers. This is relevant for collections where some
+// collections assume that they are placed on a non-moving arena.
+template <typename T, typename = int>
+struct IsAllowedInContainer : std::true_type {};
+template <typename T>
+struct IsAllowedInContainer<T, typename T::IsDisallowedInContainerMarker>
+ : std::false_type {};
+
+// This is a static-only class used as a trait on collections to make them heap
+// allocated. However see also HeapListHashSetAllocator.
+class PLATFORM_EXPORT HeapAllocator {
+ STATIC_ONLY(HeapAllocator);
+
+ public:
+ using LivenessBroker = blink::LivenessBroker;
+ using Visitor = blink::Visitor;
+ static constexpr bool kIsGarbageCollected = true;
+
+ template <typename T>
+ static size_t MaxElementCountInBackingStore() {
+ return kMaxHeapObjectSize / sizeof(T);
+ }
+
+ template <typename T>
+ static size_t QuantizedSize(size_t count) {
+ CHECK(count <= MaxElementCountInBackingStore<T>());
+ return ThreadHeap::AllocationSizeFromSize(count * sizeof(T)) -
+ sizeof(HeapObjectHeader);
+ }
+ template <typename T>
+ static T* AllocateVectorBacking(size_t size) {
+ return reinterpret_cast<T*>(
+ MakeGarbageCollected<HeapVectorBacking<T>>(size / sizeof(T)));
+ }
+ static void FreeVectorBacking(void*);
+ static bool ExpandVectorBacking(void*, size_t);
+ static bool ShrinkVectorBacking(void* address,
+ size_t quantized_current_size,
+ size_t quantized_shrunk_size);
+
+ template <typename T, typename HashTable>
+ static T* AllocateHashTableBacking(size_t size) {
+ return reinterpret_cast<T*>(
+ MakeGarbageCollected<HeapHashTableBacking<HashTable>>(
+ size / sizeof(typename HashTable::ValueType)));
+ }
+ template <typename T, typename HashTable>
+ static T* AllocateZeroedHashTableBacking(size_t size) {
+ return AllocateHashTableBacking<T, HashTable>(size);
+ }
+ static void FreeHashTableBacking(void* address);
+ static bool ExpandHashTableBacking(void*, size_t);
+
+ static void TraceBackingStoreIfMarked(const void* address) {
+ // Trace backing store elements only if backing store was marked. The
+ // sweeper may be active on the backing store which requires atomic mark bit
+ // access. A precise filter is performed in
+ // MarkingVisitor::TraceMarkedBackingStore.
+ if (HeapObjectHeader::FromPayload(address)
+ ->IsMarked<HeapObjectHeader::AccessMode::kAtomic>()) {
+ MarkingVisitor::TraceMarkedBackingStore(address);
+ }
+ }
+
+ template <typename T>
+ static void BackingWriteBarrier(T** slot) {
+ MarkingVisitor::WriteBarrier(slot);
+ }
+
+ template <typename Return, typename Metadata>
+ static Return Malloc(size_t size, const char* type_name) {
+ return reinterpret_cast<Return>(
+ MarkAsConstructed(ThreadHeap::Allocate<Metadata>(size)));
+ }
+
+ // Compilers sometimes eagerly instantiates the unused 'operator delete', so
+ // we provide a version that asserts and fails at run-time if used.
+ static void Free(void*) { NOTREACHED(); }
+
+ template <typename T>
+ static void* NewArray(size_t bytes) {
+ NOTREACHED();
+ return nullptr;
+ }
+
+ static void DeleteArray(void* ptr) { NOTREACHED(); }
+
+ static bool IsAllocationAllowed() {
+ return ThreadState::Current()->IsAllocationAllowed();
+ }
+
+ static bool IsIncrementalMarking() {
+ return ThreadState::IsAnyIncrementalMarking() &&
+ ThreadState::Current()->IsIncrementalMarking();
+ }
+
+ template <typename T, typename Traits>
+ static void Trace(Visitor* visitor, const T& t) {
+ TraceCollectionIfEnabled<WTF::WeakHandlingTrait<T>::value, T,
+ Traits>::Trace(visitor, &t);
+ }
+
+ static void EnterGCForbiddenScope() {
+ ThreadState::Current()->EnterGCForbiddenScope();
+ }
+
+ static void LeaveGCForbiddenScope() {
+ ThreadState::Current()->LeaveGCForbiddenScope();
+ }
+
+ template <typename T, typename Traits>
+ static void NotifyNewObject(T* object) {
+#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
+ ThreadState* const thread_state = ThreadState::Current();
+ if (!thread_state->IsIncrementalMarking()) {
+ MarkingVisitor::GenerationalBarrier(reinterpret_cast<Address>(object),
+ thread_state);
+ return;
+ }
+#else
+ if (!ThreadState::IsAnyIncrementalMarking())
+ return;
+ // The object may have been in-place constructed as part of a large object.
+ // It is not safe to retrieve the page from the object here.
+ ThreadState* const thread_state = ThreadState::Current();
+ if (!thread_state->IsIncrementalMarking()) {
+ return;
+ }
+#endif // BLINK_HEAP_YOUNG_GENERATION
+ // Eagerly trace the object ensuring that the object and all its children
+ // are discovered by the marker.
+ ThreadState::NoAllocationScope no_allocation_scope(thread_state);
+ DCHECK(thread_state->CurrentVisitor());
+ // No weak handling for write barriers. Modifying weakly reachable objects
+ // strongifies them for the current cycle.
+ DCHECK(!Traits::kCanHaveDeletedValue || !Traits::IsDeletedValue(*object));
+ TraceCollectionIfEnabled<WTF::kNoWeakHandling, T, Traits>::Trace(
+ thread_state->CurrentVisitor(), object);
+ }
+
+ template <typename T, typename Traits>
+ static void NotifyNewObjects(T* array, size_t len) {
+#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
+ ThreadState* const thread_state = ThreadState::Current();
+ if (!thread_state->IsIncrementalMarking()) {
+ MarkingVisitor::GenerationalBarrier(reinterpret_cast<Address>(array),
+ thread_state);
+ return;
+ }
+#else
+ if (!ThreadState::IsAnyIncrementalMarking())
+ return;
+ // The object may have been in-place constructed as part of a large object.
+ // It is not safe to retrieve the page from the object here.
+ ThreadState* const thread_state = ThreadState::Current();
+ if (!thread_state->IsIncrementalMarking()) {
+ return;
+ }
+#endif // BLINK_HEAP_YOUNG_GENERATION
+ // See |NotifyNewObject| for details.
+ ThreadState::NoAllocationScope no_allocation_scope(thread_state);
+ DCHECK(thread_state->CurrentVisitor());
+ // No weak handling for write barriers. Modifying weakly reachable objects
+ // strongifies them for the current cycle.
+ while (len-- > 0) {
+ DCHECK(!Traits::kCanHaveDeletedValue || !Traits::IsDeletedValue(*array));
+ TraceCollectionIfEnabled<WTF::kNoWeakHandling, T, Traits>::Trace(
+ thread_state->CurrentVisitor(), array);
+ array++;
+ }
+ }
+
+ template <typename T>
+ static void TraceVectorBacking(Visitor* visitor,
+ const T* backing,
+ const T* const* backing_slot) {
+ visitor->TraceMovablePointer(backing_slot);
+ visitor->Trace(reinterpret_cast<const HeapVectorBacking<T>*>(backing));
+ }
+
+ template <typename T, typename HashTable>
+ static void TraceHashTableBackingStrongly(Visitor* visitor,
+ const T* backing,
+ const T* const* backing_slot) {
+ visitor->TraceMovablePointer(backing_slot);
+ visitor->Trace(
+ reinterpret_cast<const HeapHashTableBacking<HashTable>*>(backing));
+ }
+
+ template <typename T, typename HashTable>
+ static void TraceHashTableBackingWeakly(Visitor* visitor,
+ const T* backing,
+ const T* const* backing_slot,
+ WeakCallback callback,
+ const void* parameter) {
+ visitor->TraceMovablePointer(backing_slot);
+ visitor->TraceWeakContainer(
+ reinterpret_cast<const HeapHashTableBacking<HashTable>*>(backing),
+ reinterpret_cast<const HeapHashTableBacking<HashTable>* const*>(
+ backing_slot),
+ TraceTrait<HeapHashTableBacking<HashTable>>::GetTraceDescriptor(
+ backing),
+ TraceTrait<HeapHashTableBacking<HashTable>>::GetWeakTraceDescriptor(
+ backing),
+ callback, parameter);
+ }
+
+ private:
+ static Address MarkAsConstructed(Address address) {
+ HeapObjectHeader::FromPayload(reinterpret_cast<void*>(address))
+ ->MarkFullyConstructed<HeapObjectHeader::AccessMode::kAtomic>();
+ return address;
+ }
+
+ static void BackingFree(void*);
+ static bool BackingExpand(void*, size_t);
+ static bool BackingShrink(void*,
+ size_t quantized_current_size,
+ size_t quantized_shrunk_size);
+
+ template <typename T, wtf_size_t u, typename V>
+ friend class WTF::Vector;
+ template <typename T, typename U, typename V, typename W>
+ friend class WTF::HashSet;
+ template <typename T,
+ typename U,
+ typename V,
+ typename W,
+ typename X,
+ typename Y>
+ friend class WTF::HashMap;
+};
+
+template <typename VisitorDispatcher, typename Value>
+static void TraceListHashSetValue(VisitorDispatcher visitor,
+ const Value& value) {
+ // We use the default hash traits for the value in the node, because
+ // ListHashSet does not let you specify any specific ones.
+ // We don't allow ListHashSet of WeakMember, so we set that one false
+ // (there's an assert elsewhere), but we have to specify some value for the
+ // strongify template argument, so we specify WTF::WeakPointersActWeak,
+ // arbitrarily.
+ TraceCollectionIfEnabled<WTF::kNoWeakHandling, Value,
+ WTF::HashTraits<Value>>::Trace(visitor, &value);
+}
+
+// The inline capacity is just a dummy template argument to match the off-heap
+// allocator.
+// This inherits from the static-only HeapAllocator trait class, but we do
+// declare pointers to instances. These pointers are always null, and no
+// objects are instantiated.
+template <typename ValueArg, wtf_size_t inlineCapacity>
+class HeapListHashSetAllocator : public HeapAllocator {
+ DISALLOW_NEW();
+
+ public:
+ using TableAllocator = HeapAllocator;
+ using Node = WTF::ListHashSetNode<ValueArg, HeapListHashSetAllocator>;
+
+ class AllocatorProvider {
+ DISALLOW_NEW();
+
+ public:
+ // For the heap allocation we don't need an actual allocator object, so
+ // we just return null.
+ HeapListHashSetAllocator* Get() const { return nullptr; }
+
+ // No allocator object is needed.
+ void CreateAllocatorIfNeeded() {}
+ void ReleaseAllocator() {}
+
+ // There is no allocator object in the HeapListHashSet (unlike in the
+ // regular ListHashSet) so there is nothing to swap.
+ void Swap(AllocatorProvider& other) {}
+ };
+
+ void Deallocate(void* dummy) {}
+
+ // This is not a static method even though it could be, because it needs to
+ // match the one that the (off-heap) ListHashSetAllocator has. The 'this'
+ // pointer will always be null.
+ void* AllocateNode() {
+ // Consider using a LinkedHashSet instead if this compile-time assert fails:
+ static_assert(!WTF::IsWeak<ValueArg>::value,
+ "weak pointers in a ListHashSet will result in null entries "
+ "in the set");
+
+ return Malloc<void*, Node>(
+ sizeof(Node),
+ nullptr /* Oilpan does not use the heap profiler at the moment. */);
+ }
+
+ template <typename VisitorDispatcher>
+ static void TraceValue(VisitorDispatcher visitor, const Node* node) {
+ TraceListHashSetValue(visitor, node->value_);
+ }
+};
+
+namespace internal {
+
+template <typename T>
+constexpr bool IsMember = WTF::IsSubclassOfTemplate<T, Member>::value;
+
+} // namespace internal
+
+template <typename KeyArg,
+ typename MappedArg,
+ typename HashArg = typename DefaultHash<KeyArg>::Hash,
+ typename KeyTraitsArg = HashTraits<KeyArg>,
+ typename MappedTraitsArg = HashTraits<MappedArg>>
+class HeapHashMap : public HashMap<KeyArg,
+ MappedArg,
+ HashArg,
+ KeyTraitsArg,
+ MappedTraitsArg,
+ HeapAllocator> {
+ IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
+ DISALLOW_NEW();
+
+ static void CheckType() {
+ static_assert(std::is_trivially_destructible<HeapHashMap>::value,
+ "HeapHashMap must be trivially destructible.");
+ static_assert(
+ IsAllowedInContainer<KeyArg>::value,
+ "Not allowed to directly nest type. Use Member<> indirection instead.");
+ static_assert(
+ IsAllowedInContainer<MappedArg>::value,
+ "Not allowed to directly nest type. Use Member<> indirection instead.");
+ static_assert(
+ WTF::IsTraceable<KeyArg>::value || WTF::IsTraceable<MappedArg>::value,
+ "For hash maps without traceable elements, use HashMap<> "
+ "instead of HeapHashMap<>.");
+ static_assert(WTF::IsMemberOrWeakMemberType<KeyArg>::value ||
+ !WTF::IsTraceable<KeyArg>::value,
+ "HeapHashMap supports only Member, WeakMember and "
+ "non-traceable types as keys.");
+ static_assert(WTF::IsMemberOrWeakMemberType<MappedArg>::value ||
+ !WTF::IsTraceable<MappedArg>::value ||
+ WTF::IsSubclassOfTemplate<MappedArg,
+ TraceWrapperV8Reference>::value,
+ "HeapHashMap supports only Member, WeakMember, "
+ "TraceWrapperV8Reference and "
+ "non-traceable types as values.");
+ }
+
+ public:
+ template <typename>
+ static void* AllocateObject(size_t size) {
+ return ThreadHeap::Allocate<
+ HeapHashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>>(
+ size);
+ }
+
+ HeapHashMap() { CheckType(); }
+};
+
+template <typename T, typename U, typename V, typename W, typename X>
+struct GCInfoTrait<HeapHashMap<T, U, V, W, X>>
+ : public GCInfoTrait<HashMap<T, U, V, W, X, HeapAllocator>> {};
+
+template <typename ValueArg,
+ typename HashArg = typename DefaultHash<ValueArg>::Hash,
+ typename TraitsArg = HashTraits<ValueArg>>
+class HeapHashSet
+ : public HashSet<ValueArg, HashArg, TraitsArg, HeapAllocator> {
+ IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
+ DISALLOW_NEW();
+
+ static void CheckType() {
+ static_assert(WTF::IsMemberOrWeakMemberType<ValueArg>::value,
+ "HeapHashSet supports only Member and WeakMember.");
+ static_assert(std::is_trivially_destructible<HeapHashSet>::value,
+ "HeapHashSet must be trivially destructible.");
+ static_assert(
+ IsAllowedInContainer<ValueArg>::value,
+ "Not allowed to directly nest type. Use Member<> indirection instead.");
+ static_assert(WTF::IsTraceable<ValueArg>::value,
+ "For hash sets without traceable elements, use HashSet<> "
+ "instead of HeapHashSet<>.");
+ }
+
+ public:
+ template <typename>
+ static void* AllocateObject(size_t size) {
+ return ThreadHeap::Allocate<HeapHashSet<ValueArg, HashArg, TraitsArg>>(
+ size);
+ }
+
+ HeapHashSet() { CheckType(); }
+};
+
+template <typename T, typename U, typename V>
+struct GCInfoTrait<HeapHashSet<T, U, V>>
+ : public GCInfoTrait<HashSet<T, U, V, HeapAllocator>> {};
+
+template <typename ValueArg, typename TraitsArg = HashTraits<ValueArg>>
+class HeapLinkedHashSet
+ : public LinkedHashSet<ValueArg, TraitsArg, HeapAllocator> {
+ IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
+ DISALLOW_NEW();
+
+ static void CheckType() {
+ static_assert(WTF::IsMemberOrWeakMemberType<ValueArg>::value,
+ "HeapLinkedHashSet supports only Member and WeakMember.");
+ // If not trivially destructible, we have to add a destructor which will
+ // hinder performance.
+ static_assert(std::is_trivially_destructible<HeapLinkedHashSet>::value,
+ "HeapLinkedHashSet must be trivially destructible.");
+ static_assert(
+ IsAllowedInContainer<ValueArg>::value,
+ "Not allowed to directly nest type. Use Member<> indirection instead.");
+ static_assert(WTF::IsTraceable<ValueArg>::value,
+ "For sets without traceable elements, use LinkedHashSet<> "
+ "instead of HeapLinkedHashSet<>.");
+ }
+
+ public:
+ template <typename>
+ static void* AllocateObject(size_t size) {
+ return ThreadHeap::Allocate<HeapLinkedHashSet<ValueArg, TraitsArg>>(size);
+ }
+
+ HeapLinkedHashSet() { CheckType(); }
+};
+
+template <typename T, typename U>
+struct GCInfoTrait<HeapLinkedHashSet<T, U>>
+ : public GCInfoTrait<LinkedHashSet<T, U, HeapAllocator>> {};
+
+template <typename ValueArg,
+ wtf_size_t inlineCapacity = 0, // The inlineCapacity is just a dummy
+ // to match ListHashSet (off-heap).
+ typename HashArg = typename DefaultHash<ValueArg>::Hash>
+class HeapListHashSet
+ : public ListHashSet<ValueArg,
+ inlineCapacity,
+ HashArg,
+ HeapListHashSetAllocator<ValueArg, inlineCapacity>> {
+ IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
+ DISALLOW_NEW();
+
+ static void CheckType() {
+ static_assert(WTF::IsMemberOrWeakMemberType<ValueArg>::value,
+ "HeapListHashSet supports only Member and WeakMember.");
+ static_assert(std::is_trivially_destructible<HeapListHashSet>::value,
+ "HeapListHashSet must be trivially destructible.");
+ static_assert(
+ IsAllowedInContainer<ValueArg>::value,
+ "Not allowed to directly nest type. Use Member<> indirection instead.");
+ static_assert(WTF::IsTraceable<ValueArg>::value,
+ "For sets without traceable elements, use ListHashSet<> "
+ "instead of HeapListHashSet<>.");
+ }
+
+ public:
+ template <typename>
+ static void* AllocateObject(size_t size) {
+ return ThreadHeap::Allocate<
+ HeapListHashSet<ValueArg, inlineCapacity, HashArg>>(size);
+ }
+
+ HeapListHashSet() { CheckType(); }
+};
+
+template <typename T, wtf_size_t inlineCapacity, typename U>
+struct GCInfoTrait<HeapListHashSet<T, inlineCapacity, U>>
+ : public GCInfoTrait<
+ ListHashSet<T,
+ inlineCapacity,
+ U,
+ HeapListHashSetAllocator<T, inlineCapacity>>> {};
+
+template <typename Value,
+ typename HashFunctions = typename DefaultHash<Value>::Hash,
+ typename Traits = HashTraits<Value>>
+class HeapHashCountedSet
+ : public HashCountedSet<Value, HashFunctions, Traits, HeapAllocator> {
+ IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
+ DISALLOW_NEW();
+
+ static void CheckType() {
+ static_assert(WTF::IsMemberOrWeakMemberType<Value>::value,
+ "HeapHashCountedSet supports only Member and WeakMember.");
+ static_assert(std::is_trivially_destructible<HeapHashCountedSet>::value,
+ "HeapHashCountedSet must be trivially destructible.");
+ static_assert(
+ IsAllowedInContainer<Value>::value,
+ "Not allowed to directly nest type. Use Member<> indirection instead.");
+ static_assert(WTF::IsTraceable<Value>::value,
+ "For counted sets without traceable elements, use "
+ "HashCountedSet<> instead of HeapHashCountedSet<>.");
+ }
+
+ public:
+ template <typename>
+ static void* AllocateObject(size_t size) {
+ return ThreadHeap::Allocate<
+ HeapHashCountedSet<Value, HashFunctions, Traits>>(size);
+ }
+
+ HeapHashCountedSet() { CheckType(); }
+};
+
+template <typename T, typename U, typename V>
+struct GCInfoTrait<HeapHashCountedSet<T, U, V>>
+ : public GCInfoTrait<HashCountedSet<T, U, V, HeapAllocator>> {};
+
+template <typename T, wtf_size_t inlineCapacity = 0>
+class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> {
+ IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
+ DISALLOW_NEW();
+
+ static void CheckType() {
+ static_assert(
+ std::is_trivially_destructible<HeapVector>::value || inlineCapacity,
+ "HeapVector must be trivially destructible.");
+ static_assert(
+ IsAllowedInContainer<T>::value,
+ "Not allowed to directly nest type. Use Member<> indirection instead.");
+ static_assert(WTF::IsTraceable<T>::value,
+ "For vectors without traceable elements, use Vector<> "
+ "instead of HeapVector<>.");
+ static_assert(!WTF::IsWeak<T>::value,
+ "Weak types are not allowed in HeapVector.");
+ static_assert(WTF::IsTraceableInCollectionTrait<VectorTraits<T>>::value,
+ "Type must be traceable in collection");
+ }
+
+ public:
+ template <typename>
+ static void* AllocateObject(size_t size) {
+ // On-heap HeapVectors generally should not have inline capacity, but it is
+ // hard to avoid when using a type alias. Hence we only disallow the
+ // VectorTraits<T>::kNeedsDestruction case for now.
+ static_assert(inlineCapacity == 0 || !VectorTraits<T>::kNeedsDestruction,
+ "on-heap HeapVector<> should not have an inline capacity");
+ return ThreadHeap::Allocate<HeapVector<T, inlineCapacity>>(size);
+ }
+
+ HeapVector() { CheckType(); }
+
+ explicit HeapVector(wtf_size_t size)
+ : Vector<T, inlineCapacity, HeapAllocator>(size) {
+ CheckType();
+ }
+
+ HeapVector(wtf_size_t size, const T& val)
+ : Vector<T, inlineCapacity, HeapAllocator>(size, val) {
+ CheckType();
+ }
+
+ template <wtf_size_t otherCapacity>
+ HeapVector(const HeapVector<T, otherCapacity>& other)
+ : Vector<T, inlineCapacity, HeapAllocator>(other) {
+ CheckType();
+ }
+
+ HeapVector(std::initializer_list<T> elements)
+ : Vector<T, inlineCapacity, HeapAllocator>(elements) {
+ CheckType();
+ }
+};
+
+template <typename T, wtf_size_t inlineCapacity>
+struct GCInfoTrait<HeapVector<T, inlineCapacity>>
+ : public GCInfoTrait<Vector<T, inlineCapacity, HeapAllocator>> {};
+
+template <typename T>
+class HeapDeque : public Deque<T, 0, HeapAllocator> {
+ IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
+ DISALLOW_NEW();
+
+ static void CheckType() {
+ static_assert(internal::IsMember<T>, "HeapDeque supports only Member.");
+ static_assert(std::is_trivially_destructible<HeapDeque>::value,
+ "HeapDeque must be trivially destructible.");
+ static_assert(
+ IsAllowedInContainer<T>::value,
+ "Not allowed to directly nest type. Use Member<> indirection instead.");
+ static_assert(WTF::IsTraceable<T>::value,
+ "For vectors without traceable elements, use Deque<> instead "
+ "of HeapDeque<>");
+ }
+
+ public:
+ template <typename>
+ static void* AllocateObject(size_t size) {
+ return ThreadHeap::Allocate<HeapDeque<T>>(size);
+ }
+
+ HeapDeque() { CheckType(); }
+
+ explicit HeapDeque(wtf_size_t size) : Deque<T, 0, HeapAllocator>(size) {
+ CheckType();
+ }
+
+ HeapDeque(wtf_size_t size, const T& val)
+ : Deque<T, 0, HeapAllocator>(size, val) {
+ CheckType();
+ }
+
+ HeapDeque& operator=(const HeapDeque& other) {
+ HeapDeque<T> copy(other);
+ Deque<T, 0, HeapAllocator>::Swap(copy);
+ return *this;
+ }
+
+ HeapDeque(const HeapDeque<T>& other) : Deque<T, 0, HeapAllocator>(other) {}
+};
+
+template <typename T>
+struct GCInfoTrait<HeapDeque<T>>
+ : public GCInfoTrait<Deque<T, 0, HeapAllocator>> {};
+
+} // namespace blink
+
+namespace WTF {
+
+template <typename T>
+struct VectorTraits<blink::Member<T>> : VectorTraitsBase<blink::Member<T>> {
+ STATIC_ONLY(VectorTraits);
+ static const bool kNeedsDestruction = false;
+ static const bool kCanInitializeWithMemset = true;
+ static const bool kCanClearUnusedSlotsWithMemset = true;
+ static const bool kCanCopyWithMemcpy = true;
+ static const bool kCanMoveWithMemcpy = true;
+
+ static constexpr bool kCanTraceConcurrently = true;
+};
+
+// These traits are used in VectorBackedLinkedList to support WeakMember in
+// HeapLinkedHashSet though HeapVector<WeakMember> usage is still banned.
+// (See the discussion in https://crrev.com/c/2246014)
+template <typename T>
+struct VectorTraits<blink::WeakMember<T>>
+ : VectorTraitsBase<blink::WeakMember<T>> {
+ STATIC_ONLY(VectorTraits);
+ static const bool kNeedsDestruction = false;
+ static const bool kCanInitializeWithMemset = true;
+ static const bool kCanClearUnusedSlotsWithMemset = true;
+ static const bool kCanCopyWithMemcpy = true;
+ static const bool kCanMoveWithMemcpy = true;
+
+ static constexpr bool kCanTraceConcurrently = true;
+};
+
+template <typename T>
+struct VectorTraits<blink::UntracedMember<T>>
+ : VectorTraitsBase<blink::UntracedMember<T>> {
+ STATIC_ONLY(VectorTraits);
+ static const bool kNeedsDestruction = false;
+ static const bool kCanInitializeWithMemset = true;
+ static const bool kCanClearUnusedSlotsWithMemset = true;
+ static const bool kCanMoveWithMemcpy = true;
+};
+
+template <typename T>
+struct VectorTraits<blink::HeapVector<T, 0>>
+ : VectorTraitsBase<blink::HeapVector<T, 0>> {
+ STATIC_ONLY(VectorTraits);
+ static const bool kNeedsDestruction = false;
+ static const bool kCanInitializeWithMemset = true;
+ static const bool kCanClearUnusedSlotsWithMemset = true;
+ static const bool kCanMoveWithMemcpy = true;
+};
+
+template <typename T>
+struct VectorTraits<blink::HeapDeque<T>>
+ : VectorTraitsBase<blink::HeapDeque<T>> {
+ STATIC_ONLY(VectorTraits);
+ static const bool kNeedsDestruction = false;
+ static const bool kCanInitializeWithMemset = true;
+ static const bool kCanClearUnusedSlotsWithMemset = true;
+ static const bool kCanMoveWithMemcpy = true;
+};
+
+template <typename T, wtf_size_t inlineCapacity>
+struct VectorTraits<blink::HeapVector<T, inlineCapacity>>
+ : VectorTraitsBase<blink::HeapVector<T, inlineCapacity>> {
+ STATIC_ONLY(VectorTraits);
+ static const bool kNeedsDestruction = VectorTraits<T>::kNeedsDestruction;
+ static const bool kCanInitializeWithMemset =
+ VectorTraits<T>::kCanInitializeWithMemset;
+ static const bool kCanClearUnusedSlotsWithMemset =
+ VectorTraits<T>::kCanClearUnusedSlotsWithMemset;
+ static const bool kCanMoveWithMemcpy = VectorTraits<T>::kCanMoveWithMemcpy;
+};
+
+template <typename T>
+struct HashTraits<blink::Member<T>> : SimpleClassHashTraits<blink::Member<T>> {
+ STATIC_ONLY(HashTraits);
+ // FIXME: Implement proper const'ness for iterator types. Requires support
+ // in the marking Visitor.
+ using PeekInType = T*;
+ using IteratorGetType = blink::Member<T>*;
+ using IteratorConstGetType = const blink::Member<T>*;
+ using IteratorReferenceType = blink::Member<T>&;
+ using IteratorConstReferenceType = const blink::Member<T>&;
+ static IteratorReferenceType GetToReferenceConversion(IteratorGetType x) {
+ return *x;
+ }
+ static IteratorConstReferenceType GetToReferenceConstConversion(
+ IteratorConstGetType x) {
+ return *x;
+ }
+
+ using PeekOutType = T*;
+
+ template <typename U>
+ static void Store(const U& value, blink::Member<T>& storage) {
+ storage = value;
+ }
+
+ static PeekOutType Peek(const blink::Member<T>& value) { return value; }
+
+ static void ConstructDeletedValue(blink::Member<T>& slot, bool) {
+ slot = WTF::kHashTableDeletedValue;
+ }
+
+ static constexpr bool kCanTraceConcurrently = true;
+};
+
+template <typename T>
+struct HashTraits<blink::WeakMember<T>>
+ : SimpleClassHashTraits<blink::WeakMember<T>> {
+ STATIC_ONLY(HashTraits);
+ static const bool kNeedsDestruction = false;
+ // FIXME: Implement proper const'ness for iterator types. Requires support
+ // in the marking Visitor.
+ using PeekInType = T*;
+ using IteratorGetType = blink::WeakMember<T>*;
+ using IteratorConstGetType = const blink::WeakMember<T>*;
+ using IteratorReferenceType = blink::WeakMember<T>&;
+ using IteratorConstReferenceType = const blink::WeakMember<T>&;
+ static IteratorReferenceType GetToReferenceConversion(IteratorGetType x) {
+ return *x;
+ }
+ static IteratorConstReferenceType GetToReferenceConstConversion(
+ IteratorConstGetType x) {
+ return *x;
+ }
+
+ using PeekOutType = T*;
+
+ template <typename U>
+ static void Store(const U& value, blink::WeakMember<T>& storage) {
+ storage = value;
+ }
+
+ static PeekOutType Peek(const blink::WeakMember<T>& value) { return value; }
+
+ static void ConstructDeletedValue(blink::WeakMember<T>& slot, bool) {
+ slot = WTF::kHashTableDeletedValue;
+ }
+
+ static constexpr bool kCanTraceConcurrently = true;
+};
+
+template <typename T>
+struct HashTraits<blink::UntracedMember<T>>
+ : SimpleClassHashTraits<blink::UntracedMember<T>> {
+ STATIC_ONLY(HashTraits);
+ static const bool kNeedsDestruction = false;
+ // FIXME: Implement proper const'ness for iterator types.
+ using PeekInType = T*;
+ using IteratorGetType = blink::UntracedMember<T>*;
+ using IteratorConstGetType = const blink::UntracedMember<T>*;
+ using IteratorReferenceType = blink::UntracedMember<T>&;
+ using IteratorConstReferenceType = const blink::UntracedMember<T>&;
+ static IteratorReferenceType GetToReferenceConversion(IteratorGetType x) {
+ return *x;
+ }
+ static IteratorConstReferenceType GetToReferenceConstConversion(
+ IteratorConstGetType x) {
+ return *x;
+ }
+ using PeekOutType = T*;
+
+ template <typename U>
+ static void Store(const U& value, blink::UntracedMember<T>& storage) {
+ storage = value;
+ }
+
+ static PeekOutType Peek(const blink::UntracedMember<T>& value) {
+ return value;
+ }
+};
+
+template <typename T, wtf_size_t inlineCapacity>
+struct IsTraceable<
+ ListHashSetNode<T, blink::HeapListHashSetAllocator<T, inlineCapacity>>*> {
+ STATIC_ONLY(IsTraceable);
+ static_assert(sizeof(T), "T must be fully defined");
+ // All heap allocated node pointers need visiting to keep the nodes alive,
+ // regardless of whether they contain pointers to other heap allocated
+ // objects.
+ static const bool value = true;
+};
+
+template <typename T, wtf_size_t inlineCapacity>
+struct IsGarbageCollectedType<
+ ListHashSetNode<T, blink::HeapListHashSetAllocator<T, inlineCapacity>>> {
+ static const bool value = true;
+};
+
+template <typename Set>
+struct IsGarbageCollectedType<ListHashSetIterator<Set>> {
+ static const bool value = IsGarbageCollectedType<Set>::value;
+};
+
+template <typename Set>
+struct IsGarbageCollectedType<ListHashSetConstIterator<Set>> {
+ static const bool value = IsGarbageCollectedType<Set>::value;
+};
+
+template <typename Set>
+struct IsGarbageCollectedType<ListHashSetReverseIterator<Set>> {
+ static const bool value = IsGarbageCollectedType<Set>::value;
+};
+
+template <typename Set>
+struct IsGarbageCollectedType<ListHashSetConstReverseIterator<Set>> {
+ static const bool value = IsGarbageCollectedType<Set>::value;
+};
+
+template <typename T, typename H>
+struct HandleHashTraits : SimpleClassHashTraits<H> {
+ STATIC_ONLY(HandleHashTraits);
+ // TODO: Implement proper const'ness for iterator types. Requires support
+ // in the marking Visitor.
+ using PeekInType = T*;
+ using IteratorGetType = H*;
+ using IteratorConstGetType = const H*;
+ using IteratorReferenceType = H&;
+ using IteratorConstReferenceType = const H&;
+ static IteratorReferenceType GetToReferenceConversion(IteratorGetType x) {
+ return *x;
+ }
+ static IteratorConstReferenceType GetToReferenceConstConversion(
+ IteratorConstGetType x) {
+ return *x;
+ }
+
+ using PeekOutType = T*;
+
+ template <typename U>
+ static void Store(const U& value, H& storage) {
+ storage = value;
+ }
+
+ static PeekOutType Peek(const H& value) { return value; }
+};
+
+template <typename Value,
+ typename HashFunctions,
+ typename Traits,
+ typename VectorType>
+inline void CopyToVector(
+ const blink::HeapHashCountedSet<Value, HashFunctions, Traits>& set,
+ VectorType& vector) {
+ CopyToVector(static_cast<const HashCountedSet<Value, HashFunctions, Traits,
+ blink::HeapAllocator>&>(set),
+ vector);
+}
+
+} // namespace WTF
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_ALLOCATOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_compact.cc b/chromium/third_party/blink/renderer/platform/heap/impl/heap_compact.cc
index f750406477e..411ea513c3e 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_compact.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/heap_compact.cc
@@ -2,7 +2,7 @@
// 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/heap_compact.h"
+#include "third_party/blink/renderer/platform/heap/impl/heap_compact.h"
#include <memory>
@@ -170,70 +170,70 @@ void HeapCompact::MovableObjectFixups::AddOrFilter(
void HeapCompact::MovableObjectFixups::Relocate(Address from, Address to) {
#if DCHECK_IS_ON()
- moved_objects_.insert(from);
+ moved_objects_.insert(from);
#endif // DCHECK_IS_ON()
- const HeapObjectHeader* header = HeapObjectHeader::FromPayload(to);
- const size_t size = header->PayloadSize();
+ const HeapObjectHeader* header = HeapObjectHeader::FromPayload(to);
+ const size_t size = header->PayloadSize();
- // Interior slots always need to be processed for moved objects.
- // Consider an object A with slot A.x pointing to value B where A is
- // allocated on a movable page itself. When B is finally moved, it needs to
- // find the corresponding slot A.x. Object A may be moved already and the
- // memory may have been freed, which would result in a crash.
- if (!interior_fixups_.empty()) {
- RelocateInteriorFixups(from, to, size);
- }
+ // Interior slots always need to be processed for moved objects.
+ // Consider an object A with slot A.x pointing to value B where A is
+ // allocated on a movable page itself. When B is finally moved, it needs to
+ // find the corresponding slot A.x. Object A may be moved already and the
+ // memory may have been freed, which would result in a crash.
+ if (!interior_fixups_.empty()) {
+ RelocateInteriorFixups(from, to, size);
+ }
- auto it = fixups_.find(from);
- // This means that there is no corresponding slot for a live backing store.
- // This may happen because a mutator may change the slot to point to a
- // different backing store because e.g. incremental marking marked a backing
- // store as live that was later on replaced.
- if (it == fixups_.end()) {
- return;
- }
+ auto it = fixups_.find(from);
+ // This means that there is no corresponding slot for a live backing store.
+ // This may happen because a mutator may change the slot to point to a
+ // different backing store because e.g. incremental marking marked a backing
+ // store as live that was later on replaced.
+ if (it == fixups_.end()) {
+ return;
+ }
#if DCHECK_IS_ON()
- BasePage* from_page = PageFromObject(from);
- DCHECK(relocatable_pages_.Contains(from_page));
+ BasePage* from_page = PageFromObject(from);
+ DCHECK(relocatable_pages_.Contains(from_page));
#endif
- // If the object is referenced by a slot that is contained on a compacted
- // area itself, check whether it can be updated already.
- MovableReference* slot = it->value;
- auto interior_it = interior_fixups_.find(slot);
- if (interior_it != interior_fixups_.end()) {
- MovableReference* slot_location =
- reinterpret_cast<MovableReference*>(interior_it->second);
- if (!slot_location) {
- interior_it->second = to;
+ // If the object is referenced by a slot that is contained on a compacted
+ // area itself, check whether it can be updated already.
+ MovableReference* slot = it->value;
+ auto interior_it = interior_fixups_.find(slot);
+ if (interior_it != interior_fixups_.end()) {
+ MovableReference* slot_location =
+ reinterpret_cast<MovableReference*>(interior_it->second);
+ if (!slot_location) {
+ interior_it->second = to;
#if DCHECK_IS_ON()
- // Check that the containing object has not been moved yet.
- auto reverse_it = interior_slot_to_object_.find(slot);
- DCHECK(interior_slot_to_object_.end() != reverse_it);
- DCHECK(moved_objects_.end() == moved_objects_.find(reverse_it->value));
+ // Check that the containing object has not been moved yet.
+ auto reverse_it = interior_slot_to_object_.find(slot);
+ DCHECK(interior_slot_to_object_.end() != reverse_it);
+ DCHECK(moved_objects_.end() == moved_objects_.find(reverse_it->value));
#endif // DCHECK_IS_ON()
- } else {
- LOG_HEAP_COMPACTION()
- << "Redirected slot: " << slot << " => " << slot_location;
- slot = slot_location;
- }
- }
-
- // If the slot has subsequently been updated, e.g. a destructor having
- // mutated and expanded/shrunk the collection, do not update and relocate
- // the slot -- |from| is no longer valid and referenced.
- if (UNLIKELY(*slot != from)) {
+ } else {
LOG_HEAP_COMPACTION()
- << "No relocation: slot = " << slot << ", *slot = " << *slot
- << ", from = " << from << ", to = " << to;
- VerifyUpdatedSlot(slot);
- return;
+ << "Redirected slot: " << slot << " => " << slot_location;
+ slot = slot_location;
}
+ }
+
+ // If the slot has subsequently been updated, e.g. a destructor having
+ // mutated and expanded/shrunk the collection, do not update and relocate
+ // the slot -- |from| is no longer valid and referenced.
+ if (UNLIKELY(*slot != from)) {
+ LOG_HEAP_COMPACTION() << "No relocation: slot = " << slot
+ << ", *slot = " << *slot << ", from = " << from
+ << ", to = " << to;
+ VerifyUpdatedSlot(slot);
+ return;
+ }
- // Update the slots new value.
- *slot = to;
+ // Update the slots new value.
+ *slot = to;
}
void HeapCompact::MovableObjectFixups::RelocateInteriorFixups(Address from,
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_compact.h b/chromium/third_party/blink/renderer/platform/heap/impl/heap_compact.h
index b241471ba4b..e39c9c57b88 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_compact.h
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/heap_compact.h
@@ -2,8 +2,8 @@
// 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_HEAP_COMPACT_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_COMPACT_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_COMPACT_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_COMPACT_H_
#include <memory>
@@ -164,4 +164,4 @@ class PLATFORM_EXPORT HeapCompact final {
#define LOG_HEAP_FREELIST_VERBOSE() EAT_STREAM_PARAMETERS
#endif
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_COMPACT_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_COMPACT_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_page.cc b/chromium/third_party/blink/renderer/platform/heap/impl/heap_page.cc
index 9ba8a2fac3a..1949d5c9921 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_page.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/heap_page.cc
@@ -28,7 +28,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/renderer/platform/heap/heap_page.h"
+#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
#include "base/allocator/partition_allocator/page_allocator.h"
#include "base/auto_reset.h"
@@ -36,12 +36,12 @@
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h"
-#include "third_party/blink/renderer/platform/heap/heap_compact.h"
#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
-#include "third_party/blink/renderer/platform/heap/marking_verifier.h"
-#include "third_party/blink/renderer/platform/heap/page_bloom_filter.h"
-#include "third_party/blink/renderer/platform/heap/page_memory.h"
-#include "third_party/blink/renderer/platform/heap/page_pool.h"
+#include "third_party/blink/renderer/platform/heap/impl/heap_compact.h"
+#include "third_party/blink/renderer/platform/heap/impl/marking_verifier.h"
+#include "third_party/blink/renderer/platform/heap/impl/page_bloom_filter.h"
+#include "third_party/blink/renderer/platform/heap/impl/page_memory.h"
+#include "third_party/blink/renderer/platform/heap/impl/page_pool.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.h"
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_page.h b/chromium/third_party/blink/renderer/platform/heap/impl/heap_page.h
index 98abc6bca72..1c26d4ffe20 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_page.h
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/heap_page.h
@@ -28,8 +28,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_PAGE_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_PAGE_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_PAGE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_PAGE_H_
#include <stdint.h>
#include <array>
@@ -40,11 +40,11 @@
#include "build/build_config.h"
#include "third_party/blink/renderer/platform/heap/blink_gc.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
-#include "third_party/blink/renderer/platform/heap/gc_info.h"
#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
+#include "third_party/blink/renderer/platform/heap/impl/gc_info.h"
+#include "third_party/blink/renderer/platform/heap/impl/thread_state_statistics.h"
+#include "third_party/blink/renderer/platform/heap/impl/unsanitized_atomic.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/heap/thread_state_statistics.h"
-#include "third_party/blink/renderer/platform/heap/unsanitized_atomic.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -968,9 +968,7 @@ class PLATFORM_EXPORT LargeObjectPage final : public BasePage {
#endif
// Remembers the page as containing inter-generational pointers.
- void SetRemembered(bool remembered) {
- is_remembered_ = remembered;
- }
+ void SetRemembered(bool remembered) { is_remembered_ = remembered; }
bool IsRemembered() const { return is_remembered_; }
private:
@@ -1613,4 +1611,4 @@ inline void NormalPage::MarkCard(Address address) {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_PAGE_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_PAGE_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.cc b/chromium/third_party/blink/renderer/platform/heap/impl/heap_stats_collector.cc
index 97590b912b2..97590b912b2 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/heap_stats_collector.cc
diff --git a/chromium/third_party/blink/renderer/platform/heap/impl/heap_stats_collector.h b/chromium/third_party/blink/renderer/platform/heap/impl/heap_stats_collector.h
new file mode 100644
index 00000000000..cbac7c3b8ac
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/heap_stats_collector.h
@@ -0,0 +1,469 @@
+// Copyright 2018 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_IMPL_HEAP_STATS_COLLECTOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_STATS_COLLECTOR_H_
+
+#include <stddef.h>
+
+#include "base/atomicops.h"
+#include "third_party/blink/renderer/platform/heap/blink_gc.h"
+#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+namespace blink {
+
+// Interface for observing changes to heap sizing.
+class PLATFORM_EXPORT ThreadHeapStatsObserver {
+ public:
+ // Called upon allocating/releasing chunks of memory that contain objects.
+ //
+ // Must not trigger GC or allocate.
+ virtual void IncreaseAllocatedSpace(size_t) = 0;
+ virtual void DecreaseAllocatedSpace(size_t) = 0;
+
+ // Called once per GC cycle with the accurate number of live |bytes|.
+ //
+ // Must not trigger GC or allocate.
+ virtual void ResetAllocatedObjectSize(size_t bytes) = 0;
+
+ // Called after observing at least
+ // |ThreadHeapStatsCollector::kUpdateThreshold| changed bytes through
+ // allocation or explicit free. Reports both, negative and positive
+ // increments, to allow observer to decide whether absolute values or only the
+ // deltas is interesting.
+ //
+ // May trigger GC but most not allocate.
+ virtual void IncreaseAllocatedObjectSize(size_t) = 0;
+ virtual void DecreaseAllocatedObjectSize(size_t) = 0;
+};
+
+#define FOR_ALL_SCOPES(V) \
+ V(AtomicPauseCompaction) \
+ V(AtomicPauseMarkEpilogue) \
+ V(AtomicPauseMarkPrologue) \
+ V(AtomicPauseMarkRoots) \
+ V(AtomicPauseMarkTransitiveClosure) \
+ V(AtomicPauseSweepAndCompact) \
+ V(CompleteSweep) \
+ V(IncrementalMarkingFinalize) \
+ V(IncrementalMarkingStartMarking) \
+ V(IncrementalMarkingStep) \
+ V(IncrementalMarkingWithDeadline) \
+ V(InvokePreFinalizers) \
+ V(LazySweepInIdle) \
+ V(LazySweepOnAllocation) \
+ V(MarkBailOutObjects) \
+ V(MarkInvokeEphemeronCallbacks) \
+ V(MarkFlushV8References) \
+ V(MarkFlushEphemeronPairs) \
+ V(MarkProcessWorklists) \
+ V(MarkProcessMarkingWorklist) \
+ V(MarkProcessWriteBarrierWorklist) \
+ V(MarkProcessNotFullyconstructeddWorklist) \
+ V(MarkNotFullyConstructedObjects) \
+ V(MarkWeakProcessing) \
+ V(UnifiedMarkingStep) \
+ V(VisitCrossThreadPersistents) \
+ V(VisitPersistentRoots) \
+ V(VisitPersistents) \
+ V(VisitRoots) \
+ V(VisitStackRoots) \
+ V(VisitRememberedSets)
+
+#define FOR_ALL_CONCURRENT_SCOPES(V) \
+ V(ConcurrentMarkInvokeEphemeronCallbacks) \
+ V(ConcurrentMarkingStep) \
+ V(ConcurrentSweepingStep)
+
+// Manages counters and statistics across garbage collection cycles.
+//
+// Usage:
+// ThreadHeapStatsCollector stats_collector;
+// stats_collector.NotifyMarkingStarted(<BlinkGC::CollectionType>,
+// <BlinkGC::GCReason>);
+// // Use tracer.
+// stats_collector.NotifySweepingCompleted();
+// // Previous event is available using stats_collector.previous().
+class PLATFORM_EXPORT ThreadHeapStatsCollector {
+ USING_FAST_MALLOC(ThreadHeapStatsCollector);
+
+ public:
+ // These ids will form human readable names when used in Scopes.
+ enum Id {
+#define DECLARE_ENUM(name) k##name,
+ FOR_ALL_SCOPES(DECLARE_ENUM)
+#undef DECLARE_ENUM
+ kNumScopeIds,
+ };
+
+ enum ConcurrentId {
+#define DECLARE_ENUM(name) k##name,
+ FOR_ALL_CONCURRENT_SCOPES(DECLARE_ENUM)
+#undef DECLARE_ENUM
+ kNumConcurrentScopeIds
+ };
+
+ constexpr static const char* ToString(Id id, BlinkGC::CollectionType type) {
+ switch (id) {
+#define CASE(name) \
+ case k##name: \
+ return type == BlinkGC::CollectionType::kMajor ? "BlinkGC." #name \
+ : "BlinkGC." #name \
+ ".Minor";
+ FOR_ALL_SCOPES(CASE)
+#undef CASE
+ default:
+ NOTREACHED();
+ }
+ return nullptr;
+ }
+
+ constexpr static const char* ToString(ConcurrentId id,
+ BlinkGC::CollectionType type) {
+ switch (id) {
+#define CASE(name) \
+ case k##name: \
+ return type == BlinkGC::CollectionType::kMajor ? "BlinkGC." #name \
+ : "BlinkGC." #name \
+ ".Minor";
+ FOR_ALL_CONCURRENT_SCOPES(CASE)
+#undef CASE
+ default:
+ NOTREACHED();
+ }
+ return nullptr;
+ }
+
+ enum TraceCategory { kEnabled, kDisabled };
+ enum ScopeContext { kMutatorThread, kConcurrentThread };
+
+ // Trace a particular scope. Will emit a trace event and record the time in
+ // the corresponding ThreadHeapStatsCollector.
+ template <TraceCategory trace_category = kDisabled,
+ ScopeContext scope_category = kMutatorThread>
+ class PLATFORM_EXPORT InternalScope {
+ DISALLOW_NEW();
+ DISALLOW_COPY_AND_ASSIGN(InternalScope);
+
+ using IdType =
+ std::conditional_t<scope_category == kMutatorThread, Id, ConcurrentId>;
+
+ public:
+ template <typename... Args>
+ InternalScope(ThreadHeapStatsCollector* tracer, IdType id, Args... args)
+ : tracer_(tracer), start_time_(base::TimeTicks::Now()), id_(id) {
+ StartTrace(args...);
+ }
+
+ ~InternalScope() {
+ StopTrace();
+ IncreaseScopeTime(id_);
+ }
+
+ private:
+ inline constexpr static const char* TraceCategory();
+
+ inline void StartTrace();
+ template <typename Value1>
+ inline void StartTrace(const char* k1, Value1 v1);
+ template <typename Value1, typename Value2>
+ inline void StartTrace(const char* k1,
+ Value1 v1,
+ const char* k2,
+ Value2 v2);
+ inline void StopTrace();
+
+ inline void IncreaseScopeTime(Id);
+ inline void IncreaseScopeTime(ConcurrentId);
+
+ ThreadHeapStatsCollector* const tracer_;
+ const base::TimeTicks start_time_;
+ const IdType id_;
+ };
+
+ using Scope = InternalScope<kDisabled>;
+ using EnabledScope = InternalScope<kEnabled>;
+ using ConcurrentScope = InternalScope<kDisabled, kConcurrentThread>;
+ using EnabledConcurrentScope = InternalScope<kEnabled, kConcurrentThread>;
+
+ // BlinkGCInV8Scope keeps track of time spent in Blink's GC when called by V8.
+ // This is necessary to avoid double-accounting of Blink's time when computing
+ // the overall time (V8 + Blink) spent in GC on the main thread.
+ class PLATFORM_EXPORT BlinkGCInV8Scope {
+ DISALLOW_NEW();
+ DISALLOW_COPY_AND_ASSIGN(BlinkGCInV8Scope);
+
+ public:
+ template <typename... Args>
+ BlinkGCInV8Scope(ThreadHeapStatsCollector* tracer)
+ : tracer_(tracer), start_time_(base::TimeTicks::Now()) {}
+
+ ~BlinkGCInV8Scope() {
+ if (tracer_)
+ tracer_->gc_nested_in_v8_ += base::TimeTicks::Now() - start_time_;
+ }
+
+ private:
+ ThreadHeapStatsCollector* const tracer_;
+ const base::TimeTicks start_time_;
+ };
+
+ // POD to hold interesting data accumulated during a garbage collection cycle.
+ // The event is always fully populated when looking at previous events but
+ // is only be partially populated when looking at the current event. See
+ // members on when they are available.
+ //
+ // Note that all getters include time for stand-alone as well as unified heap
+ // GCs. E.g., |atomic_marking_time()| report the marking time of the atomic
+ // phase, independent of whether the GC was a stand-alone or unified heap GC.
+ struct PLATFORM_EXPORT Event {
+ Event();
+
+ // Overall time spent in the GC cycle. This includes marking time as well as
+ // sweeping time.
+ base::TimeDelta gc_cycle_time() const;
+
+ // Time spent in the final atomic pause of a GC cycle.
+ base::TimeDelta atomic_pause_time() const;
+
+ // Time spent in the final atomic pause for marking the heap.
+ base::TimeDelta atomic_marking_time() const;
+
+ // Time spent in the final atomic pause in sweeping and compacting the heap.
+ base::TimeDelta atomic_sweep_and_compact_time() const;
+
+ // Time spent marking the roots.
+ base::TimeDelta roots_marking_time() const;
+
+ // Time spent incrementally marking the heap.
+ base::TimeDelta incremental_marking_time() const;
+
+ // Time spent processing worklist in the foreground thread.
+ base::TimeDelta worklist_processing_time_foreground() const;
+
+ // Time spent flushing v8 references (this is done only in the foreground)
+ base::TimeDelta flushing_v8_references_time() const;
+
+ // Time spent in foreground tasks marking the heap.
+ base::TimeDelta foreground_marking_time() const;
+
+ // Time spent in background tasks marking the heap.
+ base::TimeDelta background_marking_time() const;
+
+ // Overall time spent marking the heap.
+ base::TimeDelta marking_time() const;
+
+ // Time spent in foreground tasks sweeping the heap.
+ base::TimeDelta foreground_sweeping_time() const;
+
+ // Time spent in background tasks sweeping the heap.
+ base::TimeDelta background_sweeping_time() const;
+
+ // Overall time spent sweeping the heap.
+ base::TimeDelta sweeping_time() const;
+
+ // Marked bytes collected during sweeping.
+ size_t unique_id = -1;
+ size_t marked_bytes = 0;
+ size_t compaction_freed_bytes = 0;
+ size_t compaction_freed_pages = 0;
+ bool compaction_recorded_events = false;
+ base::TimeDelta scope_data[kNumScopeIds];
+ base::subtle::Atomic32 concurrent_scope_data[kNumConcurrentScopeIds]{0};
+ BlinkGC::GCReason reason = static_cast<BlinkGC::GCReason>(0);
+ BlinkGC::CollectionType collection_type = BlinkGC::CollectionType::kMajor;
+ size_t object_size_in_bytes_before_sweeping = 0;
+ size_t allocated_space_in_bytes_before_sweeping = 0;
+ size_t partition_alloc_bytes_before_sweeping = 0;
+ double live_object_rate = 0;
+ base::TimeDelta gc_nested_in_v8;
+ bool is_forced_gc = true;
+ };
+
+ // Indicates a new garbage collection cycle.
+ void NotifyMarkingStarted(BlinkGC::CollectionType,
+ BlinkGC::GCReason,
+ bool is_forced_gc);
+
+ // Indicates that marking of the current garbage collection cycle is
+ // completed.
+ void NotifyMarkingCompleted(size_t marked_bytes);
+
+ // Indicates the end of a garbage collection cycle. This means that sweeping
+ // is finished at this point.
+ void NotifySweepingCompleted();
+
+ void IncreaseScopeTime(Id id, base::TimeDelta time) {
+ DCHECK(is_started_);
+ current_.scope_data[id] += time;
+ }
+
+ void IncreaseConcurrentScopeTime(ConcurrentId id, base::TimeDelta time) {
+ using Atomic32 = base::subtle::Atomic32;
+ DCHECK(is_started_);
+ const int64_t ms = time.InMicroseconds();
+ DCHECK(ms <= std::numeric_limits<Atomic32>::max());
+ base::subtle::NoBarrier_AtomicIncrement(&current_.concurrent_scope_data[id],
+ static_cast<Atomic32>(ms));
+ }
+
+ void UpdateReason(BlinkGC::GCReason);
+ void IncreaseCompactionFreedSize(size_t);
+ void IncreaseCompactionFreedPages(size_t);
+ void IncreaseAllocatedObjectSize(size_t);
+ void DecreaseAllocatedObjectSize(size_t);
+ void IncreaseAllocatedSpace(size_t);
+ void DecreaseAllocatedSpace(size_t);
+ void IncreaseWrapperCount(size_t);
+ void DecreaseWrapperCount(size_t);
+ void IncreaseCollectedWrapperCount(size_t);
+
+ // Called by the GC when it hits a point where allocated memory may be
+ // reported and garbage collection is possible. This is necessary, as
+ // increments and decrements are reported as close to their actual
+ // allocation/reclamation as possible.
+ void AllocatedObjectSizeSafepoint();
+
+ // Size of objects on the heap. Based on marked bytes in the previous cycle
+ // and newly allocated bytes since the previous cycle.
+ size_t object_size_in_bytes() const;
+
+ size_t marked_bytes() const;
+ base::TimeDelta marking_time_so_far() const;
+
+ base::TimeDelta worklist_processing_time_foreground() const;
+
+ base::TimeDelta flushing_v8_references_time() const;
+
+ int64_t allocated_bytes_since_prev_gc() const;
+
+ size_t allocated_space_bytes() const;
+
+ size_t wrapper_count() const;
+ size_t collected_wrapper_count() const;
+
+ bool is_started() const { return is_started_; }
+
+ // Statistics for the previously running garbage collection.
+ const Event& previous() const { return previous_; }
+
+ void RegisterObserver(ThreadHeapStatsObserver* observer);
+ void UnregisterObserver(ThreadHeapStatsObserver* observer);
+
+ void IncreaseAllocatedObjectSizeForTesting(size_t);
+ void DecreaseAllocatedObjectSizeForTesting(size_t);
+
+ private:
+ // Observers are implemented using virtual calls. Avoid notifications below
+ // reasonably interesting sizes.
+ static constexpr int64_t kUpdateThreshold = 1024;
+
+ // Invokes |callback| for all registered observers.
+ template <typename Callback>
+ void ForAllObservers(Callback callback);
+
+ void AllocatedObjectSizeSafepointImpl();
+
+ // Statistics for the currently running garbage collection. Note that the
+ // Event may not be fully populated yet as some phase may not have been run.
+ const Event& current() const { return current_; }
+
+ Event current_;
+ Event previous_;
+
+ // Allocated bytes since the last garbage collection. These bytes are reset
+ // after marking as they are accounted in marked_bytes then.
+ int64_t allocated_bytes_since_prev_gc_ = 0;
+ int64_t pos_delta_allocated_bytes_since_prev_gc_ = 0;
+ int64_t neg_delta_allocated_bytes_since_prev_gc_ = 0;
+
+ // Allocated space in bytes for all arenas.
+ size_t allocated_space_bytes_ = 0;
+
+ bool is_started_ = false;
+
+ // base::TimeDelta for RawScope. These don't need to be nested within a
+ // garbage collection cycle to make them easier to use.
+ base::TimeDelta gc_nested_in_v8_;
+
+ Vector<ThreadHeapStatsObserver*> observers_;
+
+ FRIEND_TEST_ALL_PREFIXES(ThreadHeapStatsCollectorTest, InitialEmpty);
+ FRIEND_TEST_ALL_PREFIXES(ThreadHeapStatsCollectorTest, IncreaseScopeTime);
+ FRIEND_TEST_ALL_PREFIXES(ThreadHeapStatsCollectorTest, StopResetsCurrent);
+};
+
+template <ThreadHeapStatsCollector::TraceCategory trace_category,
+ ThreadHeapStatsCollector::ScopeContext scope_category>
+constexpr const char*
+ThreadHeapStatsCollector::InternalScope<trace_category,
+ scope_category>::TraceCategory() {
+ switch (trace_category) {
+ case kEnabled:
+ return "blink_gc,devtools.timeline";
+ case kDisabled:
+ return TRACE_DISABLED_BY_DEFAULT("blink_gc");
+ }
+}
+
+template <ThreadHeapStatsCollector::TraceCategory trace_category,
+ ThreadHeapStatsCollector::ScopeContext scope_category>
+void ThreadHeapStatsCollector::InternalScope<trace_category,
+ scope_category>::StartTrace() {
+ TRACE_EVENT_BEGIN0(TraceCategory(),
+ ToString(id_, tracer_->current_.collection_type));
+}
+
+template <ThreadHeapStatsCollector::TraceCategory trace_category,
+ ThreadHeapStatsCollector::ScopeContext scope_category>
+template <typename Value1>
+void ThreadHeapStatsCollector::InternalScope<trace_category, scope_category>::
+ StartTrace(const char* k1, Value1 v1) {
+ TRACE_EVENT_BEGIN1(TraceCategory(),
+ ToString(id_, tracer_->current_.collection_type), k1, v1);
+}
+
+template <ThreadHeapStatsCollector::TraceCategory trace_category,
+ ThreadHeapStatsCollector::ScopeContext scope_category>
+template <typename Value1, typename Value2>
+void ThreadHeapStatsCollector::InternalScope<trace_category, scope_category>::
+ StartTrace(const char* k1, Value1 v1, const char* k2, Value2 v2) {
+ TRACE_EVENT_BEGIN2(TraceCategory(),
+ ToString(id_, tracer_->current_.collection_type), k1, v1,
+ k2, v2);
+}
+
+template <ThreadHeapStatsCollector::TraceCategory trace_category,
+ ThreadHeapStatsCollector::ScopeContext scope_category>
+void ThreadHeapStatsCollector::InternalScope<trace_category,
+ scope_category>::StopTrace() {
+ TRACE_EVENT_END2(TraceCategory(),
+ ToString(id_, tracer_->current_.collection_type), "epoch",
+ tracer_->current_.unique_id, "forced",
+ tracer_->current_.is_forced_gc);
+}
+
+template <ThreadHeapStatsCollector::TraceCategory trace_category,
+ ThreadHeapStatsCollector::ScopeContext scope_category>
+void ThreadHeapStatsCollector::InternalScope<trace_category, scope_category>::
+ IncreaseScopeTime(Id) {
+ tracer_->IncreaseScopeTime(id_, base::TimeTicks::Now() - start_time_);
+}
+
+template <ThreadHeapStatsCollector::TraceCategory trace_category,
+ ThreadHeapStatsCollector::ScopeContext scope_category>
+void ThreadHeapStatsCollector::InternalScope<trace_category, scope_category>::
+ IncreaseScopeTime(ConcurrentId) {
+ tracer_->IncreaseConcurrentScopeTime(id_,
+ base::TimeTicks::Now() - start_time_);
+}
+
+#undef FOR_ALL_SCOPES
+#undef FOR_ALL_CONCURRENT_SCOPES
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_STATS_COLLECTOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/impl/heap_traits.h b/chromium/third_party/blink/renderer/platform/heap/impl/heap_traits.h
new file mode 100644
index 00000000000..36ac20e5710
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/heap_traits.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2018 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_IMPL_HEAP_TRAITS_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_TRAITS_H_
+
+#include <type_traits>
+#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
+#include "third_party/blink/renderer/platform/heap/member.h"
+#include "third_party/blink/renderer/platform/wtf/type_traits.h"
+
+namespace blink {
+
+// Given a type T, returns a type that is either Member<T> or just T depending
+// on whether T is a garbage-collected type.
+template <typename T>
+using AddMemberIfNeeded =
+ std::conditional_t<WTF::IsGarbageCollectedType<T>::value, Member<T>, T>;
+
+// Given a type T, returns a type that is either HeapVector<T>,
+// HeapVector<Member<T>> or Vector<T> depending on T.
+template <typename T>
+using VectorOf = std::conditional_t<WTF::IsTraceable<T>::value,
+ HeapVector<AddMemberIfNeeded<T>>,
+ Vector<T>>;
+
+// Given types T and U, returns a type that is one of the following:
+// - HeapVector<std::pair<V, X>>
+// (where V is either T or Member<T> and X is either U or Member<U>)
+// - Vector<std::pair<T, U>>
+template <typename T, typename U>
+using VectorOfPairs = std::conditional_t<
+ WTF::IsTraceable<T>::value || WTF::IsTraceable<U>::value,
+ HeapVector<std::pair<AddMemberIfNeeded<T>, AddMemberIfNeeded<U>>>,
+ Vector<std::pair<T, U>>>;
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_TRAITS_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.cc b/chromium/third_party/blink/renderer/platform/heap/impl/marking_scheduling_oracle.cc
index b140239e02c..8b05de2df81 100644
--- a/chromium/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/marking_scheduling_oracle.cc
@@ -2,7 +2,7 @@
// 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/marking_scheduling_oracle.h"
+#include "third_party/blink/renderer/platform/heap/impl/marking_scheduling_oracle.h"
#include "base/numerics/ranges.h"
diff --git a/chromium/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.h b/chromium/third_party/blink/renderer/platform/heap/impl/marking_scheduling_oracle.h
index f8634c45c89..19c9e0b68a0 100644
--- a/chromium/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.h
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/marking_scheduling_oracle.h
@@ -2,8 +2,8 @@
// 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_MARKING_SCHEDULING_ORACLE_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_MARKING_SCHEDULING_ORACLE_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MARKING_SCHEDULING_ORACLE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MARKING_SCHEDULING_ORACLE_H_
#include <atomic>
@@ -62,4 +62,4 @@ class PLATFORM_EXPORT MarkingSchedulingOracle {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_MARKING_SCHEDULING_ORACLE_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MARKING_SCHEDULING_ORACLE_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/marking_verifier.cc b/chromium/third_party/blink/renderer/platform/heap/impl/marking_verifier.cc
index 45067dfe9c4..58b049ef54a 100644
--- a/chromium/third_party/blink/renderer/platform/heap/marking_verifier.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/marking_verifier.cc
@@ -2,10 +2,10 @@
// 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/marking_verifier.h"
+#include "third_party/blink/renderer/platform/heap/impl/marking_verifier.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
-#include "third_party/blink/renderer/platform/heap/heap_page.h"
+#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/heap/marking_verifier.h b/chromium/third_party/blink/renderer/platform/heap/impl/marking_verifier.h
index f7ce363bf6c..ee4266a53f1 100644
--- a/chromium/third_party/blink/renderer/platform/heap/marking_verifier.h
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/marking_verifier.h
@@ -2,8 +2,8 @@
// 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_MARKING_VERIFIER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_MARKING_VERIFIER_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MARKING_VERIFIER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MARKING_VERIFIER_H_
#include "third_party/blink/renderer/platform/heap/visitor.h"
@@ -40,4 +40,4 @@ class MarkingVerifier final : public Visitor {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_MARKING_VERIFIER_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MARKING_VERIFIER_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/marking_visitor.cc b/chromium/third_party/blink/renderer/platform/heap/impl/marking_visitor.cc
index df3d97ef8c9..aca7b715e65 100644
--- a/chromium/third_party/blink/renderer/platform/heap/marking_visitor.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/marking_visitor.cc
@@ -2,11 +2,11 @@
// 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/marking_visitor.h"
+#include "third_party/blink/renderer/platform/heap/impl/marking_visitor.h"
#include "third_party/blink/renderer/platform/heap/blink_gc.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/heap_page.h"
+#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
namespace blink {
@@ -28,6 +28,7 @@ MarkingVisitorBase::MarkingVisitorBase(ThreadState* state,
ephemeron_pairs_to_process_worklist_(
Heap().GetEphemeronPairsToProcessWorklist(),
task_id),
+ weak_containers_worklist_(Heap().GetWeakContainersWorklist()),
marking_mode_(marking_mode),
task_id_(task_id) {}
@@ -69,19 +70,17 @@ void MarkingVisitorBase::VisitWeak(const void* object,
}
void MarkingVisitorBase::VisitEphemeron(const void* key,
- const void* value,
- TraceCallback value_trace_callback) {
+ TraceDescriptor value_desc) {
HeapObjectHeader* key_header = HeapObjectHeader::FromPayload(key);
if (!key_header->IsInConstruction<HeapObjectHeader::AccessMode::kAtomic>() &&
!key_header->IsMarked<HeapObjectHeader::AccessMode::kAtomic>()) {
// In construction keys are considered as marked because they are
// guaranteed to be marked by the end of GC (e.g. by write barrier
// on insertion to HashTable).
- discovered_ephemeron_pairs_worklist_.Push(
- {key, value, value_trace_callback});
+ discovered_ephemeron_pairs_worklist_.Push({key, value_desc});
return;
}
- value_trace_callback(this, value);
+ value_desc.callback(this, value_desc.base_object_payload);
}
void MarkingVisitorBase::VisitWeakContainer(
@@ -117,6 +116,7 @@ void MarkingVisitorBase::VisitWeakContainer(
// non-empty/deleted buckets have been moved to the new backing store.
MarkHeaderNoTracing(header);
AccountMarkedBytes(header);
+ weak_containers_worklist_->Push(header);
// Register final weak processing of the backing store.
RegisterWeakCallback(weak_callback, weak_callback_parameter);
@@ -228,6 +228,24 @@ void MarkingVisitor::TraceMarkedBackingStoreSlow(const void* value) {
.trace(thread_state->CurrentVisitor(), value);
}
+constexpr size_t MarkingVisitor::RecentlyRetracedWeakContainers::kMaxCacheSize;
+
+bool MarkingVisitor::RecentlyRetracedWeakContainers::Contains(
+ const HeapObjectHeader* header) {
+ return std::find(recently_retraced_cache_.begin(),
+ recently_retraced_cache_.end(),
+ header) != recently_retraced_cache_.end();
+}
+
+void MarkingVisitor::RecentlyRetracedWeakContainers::Insert(
+ const HeapObjectHeader* header) {
+ last_used_index_ = (last_used_index_ + 1) % kMaxCacheSize;
+ if (recently_retraced_cache_.size() <= last_used_index_)
+ recently_retraced_cache_.push_back(header);
+ else
+ recently_retraced_cache_[last_used_index_] = header;
+}
+
MarkingVisitor::MarkingVisitor(ThreadState* state, MarkingMode marking_mode)
: MarkingVisitorBase(state, marking_mode, WorklistTaskId::MutatorThread) {
DCHECK(state->InAtomicMarkingPause());
@@ -244,8 +262,24 @@ void MarkingVisitor::ConservativelyMarkAddress(BasePage* page,
? static_cast<LargeObjectPage*>(page)->ObjectHeader()
: static_cast<NormalPage*>(page)->ConservativelyFindHeaderFromAddress(
address);
- if (!header || header->IsMarked())
+ if (!header)
+ return;
+ if (header->IsMarked()) {
+ // Weak containers found through conservative GC need to be strongified. In
+ // case the container was previously marked and weakly traced, it should be
+ // retraced strongly now. Previously marked/traced weak containers are
+ // marked using the |weak_containers_worklist_|. Other marked object can be
+ // skipped.
+ if (weak_containers_worklist_->Contains(header) &&
+ !recently_retraced_weak_containers_.Contains(header)) {
+ DCHECK(!header->IsInConstruction());
+ // Record the weak container backing store to avoid retracing it again.
+ recently_retraced_weak_containers_.Insert(header);
+ marking_worklist_.Push(
+ {header->Payload(), GCInfo::From(header->GcInfoIndex()).trace});
+ }
return;
+ }
// Simple case for fully constructed objects. This just adds the object to the
// regular marking worklist.
diff --git a/chromium/third_party/blink/renderer/platform/heap/marking_visitor.h b/chromium/third_party/blink/renderer/platform/heap/impl/marking_visitor.h
index 6b472bde7a6..df17247076f 100644
--- a/chromium/third_party/blink/renderer/platform/heap/marking_visitor.h
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/marking_visitor.h
@@ -2,12 +2,12 @@
// 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_MARKING_VISITOR_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_MARKING_VISITOR_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MARKING_VISITOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MARKING_VISITOR_H_
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-#include "third_party/blink/renderer/platform/heap/heap_page.h"
+#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
namespace blink {
@@ -42,7 +42,7 @@ class PLATFORM_EXPORT MarkingVisitorBase : public Visitor {
TraceDescriptor,
WeakCallback,
const void*) final;
- void VisitEphemeron(const void*, const void*, TraceCallback) final;
+ void VisitEphemeron(const void*, TraceDescriptor) final;
// Marks an object dynamically using any address within its body and adds a
// tracing callback for processing of the object. The object is not allowed
@@ -86,6 +86,7 @@ class PLATFORM_EXPORT MarkingVisitorBase : public Visitor {
MovableReferenceWorklist::View movable_reference_worklist_;
EphemeronPairsWorklist::View discovered_ephemeron_pairs_worklist_;
EphemeronPairsWorklist::View ephemeron_pairs_to_process_worklist_;
+ WeakContainersWorklist* const weak_containers_worklist_;
size_t marked_bytes_ = 0;
const MarkingMode marking_mode_;
int task_id_;
@@ -173,6 +174,22 @@ class PLATFORM_EXPORT MarkingVisitor : public MarkingVisitorBase {
static bool MarkValue(void*, BasePage*, ThreadState*);
static void TraceMarkedBackingStoreSlow(const void*);
+ // Weak containers are strongly retraced during conservative stack scanning.
+ // Stack scanning happens once per GC at the start of the atomic pause.
+ // Because the visitor is not retained between GCs, there is no need to clear
+ // the set at the end of GC.
+ class RecentlyRetracedWeakContainers {
+ static constexpr size_t kMaxCacheSize = 8;
+
+ public:
+ bool Contains(const HeapObjectHeader*);
+ void Insert(const HeapObjectHeader*);
+
+ private:
+ std::vector<const HeapObjectHeader*> recently_retraced_cache_;
+ size_t last_used_index_ = -1;
+ } recently_retraced_weak_containers_;
+
friend class HeapAllocator;
template <typename T, TracenessMemberConfiguration tracenessConfiguration>
friend class MemberBase;
@@ -261,4 +278,4 @@ class PLATFORM_EXPORT ConcurrentMarkingVisitor : public MarkingVisitorBase {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_MARKING_VISITOR_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MARKING_VISITOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/impl/member.h b/chromium/third_party/blink/renderer/platform/heap/impl/member.h
new file mode 100644
index 00000000000..caf60bf1b23
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/member.h
@@ -0,0 +1,577 @@
+// Copyright 2016 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_IMPL_MEMBER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MEMBER_H_
+
+#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
+#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
+#include "third_party/blink/renderer/platform/heap/impl/marking_visitor.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/hash_functions.h"
+#include "third_party/blink/renderer/platform/wtf/hash_traits.h"
+
+namespace WTF {
+template <typename P, typename Traits, typename Allocator>
+class MemberConstructTraits;
+} // namespace WTF
+
+namespace blink {
+
+template <typename T>
+class Persistent;
+
+enum class TracenessMemberConfiguration {
+ kTraced,
+ kUntraced,
+};
+
+template <typename T,
+ TracenessMemberConfiguration tracenessConfiguration =
+ TracenessMemberConfiguration::kTraced>
+class MemberPointerVerifier {
+ public:
+ MemberPointerVerifier() = default;
+
+ void SaveCreationThreadState(T* pointer) {
+ if (tracenessConfiguration == TracenessMemberConfiguration::kUntraced) {
+ creation_thread_state_ = nullptr;
+ } else {
+ creation_thread_state_ = ThreadState::Current();
+ // Members should be created in an attached thread. But an empty
+ // value Member may be created on an unattached thread by a heap
+ // collection iterator.
+ DCHECK(creation_thread_state_ || !pointer);
+ }
+ }
+
+ void CheckPointer(T* pointer) {
+ if (!pointer)
+ return;
+
+ ThreadState* current = ThreadState::Current();
+ DCHECK(current);
+ if (tracenessConfiguration != TracenessMemberConfiguration::kUntraced) {
+ // creation_thread_state_ may be null when this is used in a heap
+ // collection which initialized the Member with memset and the
+ // constructor wasn't called.
+ if (creation_thread_state_) {
+ // Member should point to objects that belong in the same ThreadHeap.
+ DCHECK(creation_thread_state_->IsOnThreadHeap(pointer));
+ // Member should point to objects that belong in the same ThreadHeap.
+ DCHECK_EQ(&current->Heap(), &creation_thread_state_->Heap());
+ } else {
+ DCHECK(current->IsOnThreadHeap(pointer));
+ }
+ }
+
+ if (current->IsSweepingInProgress()) {
+ // During sweeping the object start bitmap is invalid. Check the header
+ // when the type is available and not pointing to a mixin.
+ if (IsFullyDefined<T>::value && !IsGarbageCollectedMixin<T>::value)
+ HeapObjectHeader::CheckFromPayload(pointer);
+ } else {
+ DCHECK(HeapObjectHeader::FromInnerAddress<
+ HeapObjectHeader::AccessMode::kAtomic>(pointer));
+ }
+ }
+
+ private:
+ const ThreadState* creation_thread_state_;
+};
+
+template <typename T,
+ TracenessMemberConfiguration tracenessConfiguration =
+ TracenessMemberConfiguration::kTraced>
+class MemberBase {
+ DISALLOW_NEW();
+
+ public:
+ MemberBase() : raw_(nullptr) { SaveCreationThreadState(); }
+
+ MemberBase(std::nullptr_t) : raw_(nullptr) { SaveCreationThreadState(); }
+
+ explicit MemberBase(T* raw) : raw_(raw) {
+ SaveCreationThreadState();
+ CheckPointer();
+ // No write barrier for initializing stores.
+ }
+
+ explicit MemberBase(T& raw) : raw_(&raw) {
+ SaveCreationThreadState();
+ CheckPointer();
+ // No write barrier for initializing stores.
+ }
+
+ MemberBase(WTF::HashTableDeletedValueType)
+ : raw_(reinterpret_cast<T*>(kHashTableDeletedRawValue)) {
+ SaveCreationThreadState();
+ }
+
+ MemberBase(const MemberBase& other) : raw_(other) {
+ SaveCreationThreadState();
+ CheckPointer();
+ // No write barrier for initializing stores.
+ }
+
+ template <typename U>
+ MemberBase(const Persistent<U>& other) : raw_(other) {
+ SaveCreationThreadState();
+ CheckPointer();
+ // No write barrier for initializing stores.
+ }
+
+ template <typename U>
+ MemberBase(const MemberBase<U>& other) : raw_(other) {
+ SaveCreationThreadState();
+ CheckPointer();
+ // No write barrier for initializing stores.
+ }
+
+ template <typename U>
+ MemberBase& operator=(const Persistent<U>& other) {
+ SetRaw(other);
+ CheckPointer();
+ WriteBarrier();
+ return *this;
+ }
+
+ MemberBase& operator=(const MemberBase& other) {
+ SetRaw(other);
+ CheckPointer();
+ WriteBarrier();
+ return *this;
+ }
+
+ template <typename U>
+ MemberBase& operator=(const MemberBase<U>& other) {
+ SetRaw(other);
+ CheckPointer();
+ WriteBarrier();
+ return *this;
+ }
+
+ template <typename U>
+ MemberBase& operator=(U* other) {
+ SetRaw(other);
+ CheckPointer();
+ WriteBarrier();
+ return *this;
+ }
+
+ MemberBase& operator=(WTF::HashTableDeletedValueType) {
+ SetRaw(reinterpret_cast<T*>(-1));
+ return *this;
+ }
+
+ MemberBase& operator=(std::nullptr_t) {
+ SetRaw(nullptr);
+ return *this;
+ }
+
+ void Swap(MemberBase<T>& other) {
+ T* tmp = GetRaw();
+ SetRaw(other.GetRaw());
+ other.SetRaw(tmp);
+ CheckPointer();
+ WriteBarrier();
+ other.WriteBarrier();
+ }
+
+ explicit operator bool() const { return GetRaw(); }
+ operator T*() const { return GetRaw(); }
+ T* operator->() const { return GetRaw(); }
+ T& operator*() const { return *GetRaw(); }
+
+ T* Get() const { return GetRaw(); }
+
+ void Clear() { SetRaw(nullptr); }
+
+ T* Release() {
+ T* result = GetRaw();
+ SetRaw(nullptr);
+ return result;
+ }
+
+ static bool IsMemberHashTableDeletedValue(const T* t) {
+ return t == reinterpret_cast<T*>(kHashTableDeletedRawValue);
+ }
+
+ bool IsHashTableDeletedValue() const {
+ return IsMemberHashTableDeletedValue(GetRaw());
+ }
+
+ protected:
+ static constexpr intptr_t kHashTableDeletedRawValue = -1;
+
+ enum class AtomicCtorTag { Atomic };
+
+ // MemberBase ctors that use atomic write to set raw_.
+
+ MemberBase(AtomicCtorTag, T* raw) {
+ SetRaw(raw);
+ SaveCreationThreadState();
+ CheckPointer();
+ // No write barrier for initializing stores.
+ }
+
+ MemberBase(AtomicCtorTag, T& raw) {
+ SetRaw(&raw);
+ SaveCreationThreadState();
+ CheckPointer();
+ // No write barrier for initializing stores.
+ }
+
+ void WriteBarrier() const {
+ MarkingVisitor::WriteBarrier(const_cast<std::remove_const_t<T>**>(&raw_));
+ }
+
+ void CheckPointer() {
+#if DCHECK_IS_ON()
+ // Should not be called for deleted hash table values. A value can be
+ // propagated here if a MemberBase containing the deleted value is copied.
+ if (IsHashTableDeletedValue())
+ return;
+ pointer_verifier_.CheckPointer(GetRaw());
+#endif // DCHECK_IS_ON()
+ }
+
+ void SaveCreationThreadState() {
+#if DCHECK_IS_ON()
+ pointer_verifier_.SaveCreationThreadState(GetRaw());
+#endif // DCHECK_IS_ON()
+ }
+
+ ALWAYS_INLINE void SetRaw(T* raw) {
+ if (tracenessConfiguration == TracenessMemberConfiguration::kUntraced)
+ raw_ = raw;
+ else
+ WTF::AsAtomicPtr(&raw_)->store(raw, std::memory_order_relaxed);
+ }
+ ALWAYS_INLINE T* GetRaw() const { return raw_; }
+
+ private:
+ // Thread safe version of Get() for marking visitors.
+ // This is used to prevent data races between concurrent marking visitors
+ // and writes on the main thread.
+ const T* GetSafe() const {
+ // TOOD(omerkatz): replace this cast with std::atomic_ref (C++20) once it
+ // becomes available
+ return WTF::AsAtomicPtr(&raw_)->load(std::memory_order_relaxed);
+ }
+
+ T* raw_;
+#if DCHECK_IS_ON()
+ MemberPointerVerifier<T, tracenessConfiguration> pointer_verifier_;
+#endif // DCHECK_IS_ON()
+
+ friend class Visitor;
+};
+
+// Members are used in classes to contain strong pointers to other oilpan heap
+// allocated objects.
+// All Member fields of a class must be traced in the class' trace method.
+// During the mark phase of the GC all live objects are marked as live and
+// all Member fields of a live object will be traced marked as live as well.
+template <typename T>
+class Member : public MemberBase<T, TracenessMemberConfiguration::kTraced> {
+ DISALLOW_NEW();
+ typedef MemberBase<T, TracenessMemberConfiguration::kTraced> Parent;
+
+ public:
+ Member() : Parent() {}
+ Member(std::nullptr_t) : Parent(nullptr) {}
+ Member(T* raw) : Parent(raw) {}
+ Member(T& raw) : Parent(raw) {}
+ Member(WTF::HashTableDeletedValueType x) : Parent(x) {}
+
+ Member(const Member& other) : Parent(other) {}
+
+ template <typename U>
+ Member(const Member<U>& other) : Parent(other) {}
+
+ template <typename U>
+ Member(const Persistent<U>& other) : Parent(other) {}
+
+ template <typename U>
+ Member& operator=(const Persistent<U>& other) {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ Member& operator=(const Member& other) {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ template <typename U>
+ Member& operator=(const Member<U>& other) {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ template <typename U>
+ Member& operator=(const WeakMember<U>& other) {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ template <typename U>
+ Member& operator=(U* other) {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ Member& operator=(WTF::HashTableDeletedValueType x) {
+ Parent::operator=(x);
+ return *this;
+ }
+
+ Member& operator=(std::nullptr_t) {
+ Parent::operator=(nullptr);
+ return *this;
+ }
+
+ private:
+ using typename Parent::AtomicCtorTag;
+ Member(AtomicCtorTag atomic, T* raw) : Parent(atomic, raw) {}
+ Member(AtomicCtorTag atomic, T& raw) : Parent(atomic, raw) {}
+
+ template <typename P, typename Traits, typename Allocator>
+ friend class WTF::MemberConstructTraits;
+};
+
+// WeakMember is similar to Member in that it is used to point to other oilpan
+// heap allocated objects.
+// However instead of creating a strong pointer to the object, the WeakMember
+// creates a weak pointer, which does not keep the pointee alive. Hence if all
+// pointers to to a heap allocated object are weak the object will be garbage
+// collected. At the time of GC the weak pointers will automatically be set to
+// null.
+template <typename T>
+class WeakMember : public MemberBase<T, TracenessMemberConfiguration::kTraced> {
+ typedef MemberBase<T, TracenessMemberConfiguration::kTraced> Parent;
+
+ public:
+ WeakMember() : Parent() {}
+
+ WeakMember(std::nullptr_t) : Parent(nullptr) {}
+
+ WeakMember(T* raw) : Parent(raw) {}
+
+ WeakMember(WTF::HashTableDeletedValueType x) : Parent(x) {}
+
+ template <typename U>
+ WeakMember(const Persistent<U>& other) : Parent(other) {}
+
+ template <typename U>
+ WeakMember(const Member<U>& other) : Parent(other) {}
+
+ template <typename U>
+ WeakMember& operator=(const Persistent<U>& other) {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ template <typename U>
+ WeakMember& operator=(const Member<U>& other) {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ template <typename U>
+ WeakMember& operator=(U* other) {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ WeakMember& operator=(std::nullptr_t) {
+ this->SetRaw(nullptr);
+ return *this;
+ }
+
+ private:
+ using typename Parent::AtomicCtorTag;
+ WeakMember(AtomicCtorTag atomic, T* raw) : Parent(atomic, raw) {}
+ WeakMember(AtomicCtorTag atomic, T& raw) : Parent(atomic, raw) {}
+
+ template <typename P, typename Traits, typename Allocator>
+ friend class WTF::MemberConstructTraits;
+};
+
+// UntracedMember is a pointer to an on-heap object that is not traced for some
+// reason. Please don't use this unless you understand what you're doing.
+// Basically, all pointers to on-heap objects must be stored in either of
+// Persistent, Member or WeakMember. It is not allowed to leave raw pointers to
+// on-heap objects. However, there can be scenarios where you have to use raw
+// pointers for some reason, and in that case you can use UntracedMember. Of
+// course, it must be guaranteed that the pointing on-heap object is kept alive
+// while the raw pointer is pointing to the object.
+template <typename T>
+class UntracedMember final
+ : public MemberBase<T, TracenessMemberConfiguration::kUntraced> {
+ typedef MemberBase<T, TracenessMemberConfiguration::kUntraced> Parent;
+
+ public:
+ UntracedMember() : Parent() {}
+
+ UntracedMember(std::nullptr_t) : Parent(nullptr) {}
+
+ UntracedMember(T* raw) : Parent(raw) {}
+
+ template <typename U>
+ UntracedMember(const Persistent<U>& other) : Parent(other) {}
+
+ template <typename U>
+ UntracedMember(const Member<U>& other) : Parent(other) {}
+
+ UntracedMember(WTF::HashTableDeletedValueType x) : Parent(x) {}
+
+ UntracedMember& operator=(const UntracedMember& other) {
+ this->SetRaw(other);
+ this->CheckPointer();
+ return *this;
+ }
+
+ template <typename U>
+ UntracedMember& operator=(const Persistent<U>& other) {
+ this->SetRaw(other);
+ this->CheckPointer();
+ return *this;
+ }
+
+ template <typename U>
+ UntracedMember& operator=(const Member<U>& other) {
+ this->SetRaw(other);
+ this->CheckPointer();
+ return *this;
+ }
+
+ template <typename U>
+ UntracedMember& operator=(U* other) {
+ this->SetRaw(other);
+ this->CheckPointer();
+ return *this;
+ }
+
+ UntracedMember& operator=(std::nullptr_t) {
+ this->SetRaw(nullptr);
+ return *this;
+ }
+};
+
+template <typename T>
+struct MemberTraceTraits {
+ STATIC_ONLY(MemberTraceTraits);
+
+ public:
+ static TraceDescriptor GetTraceDescriptor(const T* ref) {
+ return {ref, TraceTrait<T>::Trace};
+ }
+
+ static void Trace(Visitor* visitor, const void* ref) {
+ visitor->Trace(*static_cast<const T*>(ref));
+ }
+};
+
+template <typename T>
+struct TraceTrait<Member<T>> : public MemberTraceTraits<Member<T>> {};
+
+template <typename T>
+struct TraceTrait<WeakMember<T>> : public MemberTraceTraits<WeakMember<T>> {};
+
+} // namespace blink
+
+namespace WTF {
+
+// PtrHash is the default hash for hash tables with Member<>-derived elements.
+template <typename T>
+struct MemberHash : PtrHash<T> {
+ STATIC_ONLY(MemberHash);
+ template <typename U>
+ static unsigned GetHash(const U& key) {
+ return PtrHash<T>::GetHash(key);
+ }
+ template <typename U, typename V>
+ static bool Equal(const U& a, const V& b) {
+ return a == b;
+ }
+};
+
+template <typename T>
+struct DefaultHash<blink::Member<T>> {
+ STATIC_ONLY(DefaultHash);
+ using Hash = MemberHash<T>;
+};
+
+template <typename T>
+struct DefaultHash<blink::WeakMember<T>> {
+ STATIC_ONLY(DefaultHash);
+ using Hash = MemberHash<T>;
+};
+
+template <typename T>
+struct DefaultHash<blink::UntracedMember<T>> {
+ STATIC_ONLY(DefaultHash);
+ using Hash = MemberHash<T>;
+};
+
+template <typename T>
+struct IsTraceable<blink::Member<T>> {
+ STATIC_ONLY(IsTraceable);
+ static const bool value = true;
+};
+
+template <typename T>
+struct IsWeak<blink::WeakMember<T>> : std::true_type {};
+
+template <typename T>
+struct IsTraceable<blink::WeakMember<T>> {
+ STATIC_ONLY(IsTraceable);
+ static const bool value = true;
+};
+
+template <typename T, typename Traits, typename Allocator>
+class MemberConstructTraits {
+ STATIC_ONLY(MemberConstructTraits);
+
+ public:
+ template <typename... Args>
+ static T* Construct(void* location, Args&&... args) {
+ return new (NotNull, location) T(std::forward<Args>(args)...);
+ }
+
+ static void NotifyNewElement(T* element) { element->WriteBarrier(); }
+
+ template <typename... Args>
+ static T* ConstructAndNotifyElement(void* location, Args&&... args) {
+ // ConstructAndNotifyElement updates an existing Member which might
+ // also be comncurrently traced while we update it. The regular ctors
+ // for Member don't use an atomic write which can lead to data races.
+ T* object = Construct(location, T::AtomicCtorTag::Atomic,
+ std::forward<Args>(args)...);
+ NotifyNewElement(object);
+ return object;
+ }
+
+ static void NotifyNewElements(T* array, size_t len) {
+ while (len-- > 0) {
+ array->WriteBarrier();
+ array++;
+ }
+ }
+};
+
+template <typename T, typename Traits, typename Allocator>
+class ConstructTraits<blink::Member<T>, Traits, Allocator>
+ : public MemberConstructTraits<blink::Member<T>, Traits, Allocator> {};
+
+template <typename T, typename Traits, typename Allocator>
+class ConstructTraits<blink::WeakMember<T>, Traits, Allocator>
+ : public MemberConstructTraits<blink::WeakMember<T>, Traits, Allocator> {};
+
+} // namespace WTF
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MEMBER_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/name_traits.h b/chromium/third_party/blink/renderer/platform/heap/impl/name_traits.h
index 89961df0e4b..c44305ff234 100644
--- a/chromium/third_party/blink/renderer/platform/heap/name_traits.h
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/name_traits.h
@@ -2,8 +2,8 @@
// 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_NAME_TRAITS_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_NAME_TRAITS_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_NAME_TRAITS_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_NAME_TRAITS_H_
#include <cstring>
@@ -59,4 +59,4 @@ class NameTrait {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_NAME_TRAITS_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_NAME_TRAITS_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/page_bloom_filter.h b/chromium/third_party/blink/renderer/platform/heap/impl/page_bloom_filter.h
index 5e881212d91..19263ae332e 100644
--- a/chromium/third_party/blink/renderer/platform/heap/page_bloom_filter.h
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/page_bloom_filter.h
@@ -2,10 +2,10 @@
// 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_PAGE_BLOOM_FILTER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PAGE_BLOOM_FILTER_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PAGE_BLOOM_FILTER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PAGE_BLOOM_FILTER_H_
-#include "third_party/blink/renderer/platform/heap/heap_page.h"
+#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
#include "third_party/blink/renderer/platform/wtf/bloom_filter.h"
namespace blink {
@@ -45,4 +45,4 @@ class PageBloomFilter {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PAGE_BLOOM_FILTER_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PAGE_BLOOM_FILTER_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/page_memory.cc b/chromium/third_party/blink/renderer/platform/heap/impl/page_memory.cc
index 86445fa4d0d..4d3ffc1440d 100644
--- a/chromium/third_party/blink/renderer/platform/heap/page_memory.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/page_memory.cc
@@ -2,7 +2,7 @@
// 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/page_memory.h"
+#include "third_party/blink/renderer/platform/heap/impl/page_memory.h"
#include "base/allocator/partition_allocator/oom.h"
#include "base/allocator/partition_allocator/page_allocator.h"
diff --git a/chromium/third_party/blink/renderer/platform/heap/page_memory.h b/chromium/third_party/blink/renderer/platform/heap/impl/page_memory.h
index 249a1eb668c..ee13b210d59 100644
--- a/chromium/third_party/blink/renderer/platform/heap/page_memory.h
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/page_memory.h
@@ -2,13 +2,13 @@
// 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_PAGE_MEMORY_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PAGE_MEMORY_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PAGE_MEMORY_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PAGE_MEMORY_H_
#include "base/atomic_ref_count.h"
#include "base/containers/flat_map.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/heap_page.h"
+#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
@@ -183,4 +183,4 @@ class PageMemory {
} // namespace blink
-#endif
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PAGE_MEMORY_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/page_pool.cc b/chromium/third_party/blink/renderer/platform/heap/impl/page_pool.cc
index 100a7803614..b3c31417cfb 100644
--- a/chromium/third_party/blink/renderer/platform/heap/page_pool.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/page_pool.cc
@@ -2,10 +2,10 @@
// 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/page_pool.h"
+#include "third_party/blink/renderer/platform/heap/impl/page_pool.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/page_memory.h"
+#include "third_party/blink/renderer/platform/heap/impl/page_memory.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/heap/page_pool.h b/chromium/third_party/blink/renderer/platform/heap/impl/page_pool.h
index 753d2877778..fdf448f0200 100644
--- a/chromium/third_party/blink/renderer/platform/heap/page_pool.h
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/page_pool.h
@@ -2,8 +2,8 @@
// 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_PAGE_POOL_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PAGE_POOL_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PAGE_POOL_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PAGE_POOL_H_
#include "third_party/blink/renderer/platform/heap/thread_state.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -45,4 +45,4 @@ class PagePool {
} // namespace blink
-#endif
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PAGE_POOL_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/impl/persistent.h b/chromium/third_party/blink/renderer/platform/heap/impl/persistent.h
new file mode 100644
index 00000000000..00cff273e2f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/persistent.h
@@ -0,0 +1,971 @@
+// Copyright 2016 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_IMPL_PERSISTENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PERSISTENT_H_
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "third_party/blink/renderer/platform/bindings/buildflags.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
+#include "third_party/blink/renderer/platform/heap/impl/heap_compact.h"
+#include "third_party/blink/renderer/platform/heap/impl/persistent_node.h"
+#include "third_party/blink/renderer/platform/heap/member.h"
+#include "third_party/blink/renderer/platform/heap/visitor.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h"
+
+namespace blink {
+
+template <typename T>
+class CrossThreadWeakPersistent;
+
+// Wrapping type to force callers to go through macros that expand or drop
+// base::Location. This is needed to avoid adding the strings when not needed.
+// The type can be dropped once http://crbug.com/760702 is resolved and
+// ENABLE_LOCATION_SOURCE is disabled for release builds.
+class PersistentLocation final {
+ public:
+ PersistentLocation() = default;
+ explicit PersistentLocation(const base::Location& location)
+ : location_(location) {}
+ PersistentLocation(const PersistentLocation& other) = default;
+
+ const base::Location& get() const { return location_; }
+
+ private:
+ base::Location location_;
+};
+
+#if !BUILDFLAG(FROM_HERE_USES_LOCATION_BUILTINS) && \
+ BUILDFLAG(RAW_HEAP_SNAPSHOTS)
+#if !BUILDFLAG(ENABLE_LOCATION_SOURCE)
+#define PERSISTENT_FROM_HERE \
+ PersistentLocation(::base::Location::CreateFromHere(__FILE__))
+#else
+#define PERSISTENT_FROM_HERE \
+ PersistentLocation( \
+ ::base::Location::CreateFromHere(__func__, __FILE__, __LINE__))
+#endif
+#else
+#define PERSISTENT_FROM_HERE PersistentLocation()
+#endif // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
+
+template <typename T,
+ WeaknessPersistentConfiguration weaknessConfiguration,
+ CrossThreadnessPersistentConfiguration crossThreadnessConfiguration>
+class PersistentBase {
+ USING_FAST_MALLOC(PersistentBase);
+
+ public:
+ bool IsHashTableDeletedValue() const {
+ return raw_ == reinterpret_cast<T*>(-1);
+ }
+
+ T* Release() {
+ T* result = raw_;
+ AssignSafe(nullptr);
+ return result;
+ }
+
+ void Clear() {
+ // Note that this also frees up related data in the backend.
+ AssignSafe(nullptr);
+ }
+
+ T* Get() const {
+ CheckPointer();
+ return raw_;
+ }
+
+ // TODO(https://crbug.com/653394): Consider returning a thread-safe best
+ // guess of validity.
+ bool MaybeValid() const { return true; }
+
+ explicit operator bool() const { return Get(); }
+ T& operator*() const { return *Get(); }
+ operator T*() const { return Get(); }
+ T* operator->() const { return Get(); }
+
+ // Register the persistent node as a 'static reference',
+ // belonging to the current thread and a persistent that must
+ // be cleared when the ThreadState itself is cleared out and
+ // destructed.
+ //
+ // Static singletons arrange for this to happen, either to ensure
+ // clean LSan leak reports or to register a thread-local persistent
+ // needing to be cleared out before the thread is terminated.
+ PersistentBase* RegisterAsStaticReference() {
+ static_assert(weaknessConfiguration == kNonWeakPersistentConfiguration,
+ "Can only register non-weak Persistent references as static "
+ "references.");
+ if (PersistentNode* node = persistent_node_.Get()) {
+ ThreadState::Current()->RegisterStaticPersistentNode(node);
+ LEAK_SANITIZER_IGNORE_OBJECT(this);
+ }
+ return this;
+ }
+
+ NO_SANITIZE_ADDRESS
+ void ClearWithLockHeld() {
+ static_assert(
+ crossThreadnessConfiguration == kCrossThreadPersistentConfiguration,
+ "This Persistent does not require the cross-thread lock.");
+ PersistentMutexTraits<crossThreadnessConfiguration>::AssertAcquired();
+ raw_ = nullptr;
+ persistent_node_.ClearWithLockHeld();
+ }
+
+ void UpdateLocation(const PersistentLocation& other) {
+#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
+ location_ = other;
+#endif // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
+ }
+
+ protected:
+ ~PersistentBase() {
+ UninitializeSafe();
+ // Not resetting raw_ as it is not observable.
+ }
+
+ PersistentBase() : raw_(nullptr) {
+ SaveCreationThreadHeap();
+ // No initialization needed for empty handle.
+ }
+ PersistentBase(const PersistentLocation& location) : PersistentBase() {
+ UpdateLocation(location);
+ }
+
+ PersistentBase(std::nullptr_t) : raw_(nullptr) {
+ SaveCreationThreadHeap();
+ // No initialization needed for empty handle.
+ }
+ PersistentBase(const PersistentLocation& location, std::nullptr_t)
+ : PersistentBase(nullptr) {
+ UpdateLocation(location);
+ }
+
+ PersistentBase(T* raw) : raw_(raw) {
+ SaveCreationThreadHeap();
+ InitializeSafe();
+ CheckPointer();
+ }
+ PersistentBase(const PersistentLocation& location, T* raw)
+ : PersistentBase(raw) {
+ UpdateLocation(location);
+ }
+
+ PersistentBase(T& raw) : raw_(&raw) {
+ SaveCreationThreadHeap();
+ InitializeSafe();
+ CheckPointer();
+ }
+ PersistentBase(const PersistentLocation& location, T& raw)
+ : PersistentBase(raw) {
+ UpdateLocation(location);
+ }
+
+ PersistentBase(const PersistentBase& other) : raw_(other) {
+ SaveCreationThreadHeap();
+ InitializeSafe();
+ CheckPointer();
+ }
+ PersistentBase(const PersistentLocation& location, PersistentBase& other)
+ : PersistentBase(other) {
+ UpdateLocation(location);
+ }
+
+ template <typename U>
+ PersistentBase(const PersistentBase<U,
+ weaknessConfiguration,
+ crossThreadnessConfiguration>& other)
+ : raw_(other) {
+ SaveCreationThreadHeap();
+ InitializeSafe();
+ CheckPointer();
+ }
+ template <typename U>
+ PersistentBase(const PersistentLocation& location,
+ const PersistentBase<U,
+ weaknessConfiguration,
+ crossThreadnessConfiguration>& other)
+ : PersistentBase(other) {
+ UpdateLocation(location);
+ }
+
+ template <typename U>
+ PersistentBase(const Member<U>& other) : raw_(other) {
+ SaveCreationThreadHeap();
+ InitializeSafe();
+ CheckPointer();
+ }
+ template <typename U>
+ PersistentBase(const PersistentLocation& location, const Member<U>& other)
+ : PersistentBase(other) {
+ UpdateLocation(location);
+ }
+
+ PersistentBase(WTF::HashTableDeletedValueType)
+ : raw_(reinterpret_cast<T*>(-1)) {
+ SaveCreationThreadHeap();
+ // No initialization needed for empty handle.
+ }
+ PersistentBase(const PersistentLocation& location,
+ WTF::HashTableDeletedValueType)
+ : PersistentBase(WTF::kHashTableDeletedValue) {
+ UpdateLocation(location);
+ }
+
+ template <typename U>
+ PersistentBase& operator=(U* other) {
+ AssignSafe(other);
+ return *this;
+ }
+
+ PersistentBase& operator=(std::nullptr_t) {
+ AssignSafe(nullptr);
+ return *this;
+ }
+
+ template <typename U>
+ PersistentBase& operator=(const Member<U>& other) {
+ AssignSafe(other);
+ return *this;
+ }
+
+ // Using unsafe operations and assuming that caller acquires the lock for
+ // kCrossThreadPersistentConfiguration configuration.
+ PersistentBase& operator=(const PersistentBase& other) {
+ PersistentMutexTraits<crossThreadnessConfiguration>::AssertAcquired();
+ AssignUnsafe(other);
+ return *this;
+ }
+
+ // Using unsafe operations and assuming that caller acquires the lock for
+ // kCrossThreadPersistentConfiguration configuration.
+ template <typename U>
+ PersistentBase& operator=(
+ const PersistentBase<U,
+ weaknessConfiguration,
+ crossThreadnessConfiguration>& other) {
+ PersistentMutexTraits<crossThreadnessConfiguration>::AssertAcquired();
+ AssignUnsafe(other);
+ return *this;
+ }
+
+ // Using unsafe operations and assuming that caller acquires the lock for
+ // kCrossThreadPersistentConfiguration configuration.
+ template <typename U>
+ PersistentBase& operator=(
+ PersistentBase<U, weaknessConfiguration, crossThreadnessConfiguration>&&
+ other) {
+ PersistentMutexTraits<crossThreadnessConfiguration>::AssertAcquired();
+ if (persistent_node_.IsInitialized()) {
+ // Drop persistent node if present as it's always possible to reuse the
+ // node (if present) from |other|.
+ persistent_node_.Uninitialize();
+ }
+ // Explicit cast enabling downcasting.
+ raw_ = static_cast<T*>(other.raw_);
+ other.raw_ = nullptr;
+ // Efficiently move by just rewiring the node pointer.
+ persistent_node_ = std::move(other.persistent_node_);
+ DCHECK(!other.persistent_node_.Get());
+ if (persistent_node_.IsInitialized()) {
+ // If |raw_| points to a non-null or deleted value, just reuse the node.
+ TraceCallback trace_callback =
+ TraceMethodDelegate<PersistentBase,
+ &PersistentBase::TracePersistent>::Trampoline;
+ persistent_node_.Get()->Reinitialize(this, trace_callback);
+ }
+ CheckPointer();
+ return *this;
+ }
+
+ NO_SANITIZE_ADDRESS
+ bool IsNotNull() const { return raw_; }
+
+ NO_SANITIZE_ADDRESS
+ void AssignSafe(T* ptr) {
+ typename PersistentMutexTraits<crossThreadnessConfiguration>::Locker lock;
+ AssignUnsafe(ptr);
+ }
+
+ NO_SANITIZE_ADDRESS
+ void AssignUnsafe(T* ptr) {
+ raw_ = ptr;
+ CheckPointer();
+ if (raw_ && !IsHashTableDeletedValue()) {
+ if (!persistent_node_.IsInitialized())
+ InitializeUnsafe();
+ return;
+ }
+ UninitializeUnsafe();
+ }
+
+ void TracePersistent(Visitor* visitor) const {
+ static_assert(sizeof(T), "T must be fully defined");
+ static_assert(IsGarbageCollectedType<T>::value,
+ "T needs to be a garbage collected object");
+ DCHECK(!IsHashTableDeletedValue());
+ if (weaknessConfiguration == kWeakPersistentConfiguration) {
+ visitor->RegisterWeakCallback(HandleWeakPersistent, this);
+ } else {
+#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
+ visitor->TraceRoot(raw_, location_.get());
+#else
+ visitor->TraceRoot(raw_, base::Location());
+#endif // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
+ }
+ }
+
+ NO_SANITIZE_ADDRESS
+ void InitializeSafe() {
+ DCHECK(!persistent_node_.IsInitialized());
+ if (!raw_ || IsHashTableDeletedValue())
+ return;
+
+ TraceCallback trace_callback =
+ TraceMethodDelegate<PersistentBase,
+ &PersistentBase::TracePersistent>::Trampoline;
+ typename PersistentMutexTraits<crossThreadnessConfiguration>::Locker lock;
+ persistent_node_.Initialize(this, trace_callback);
+ }
+
+ NO_SANITIZE_ADDRESS
+ void InitializeUnsafe() {
+ DCHECK(!persistent_node_.IsInitialized());
+ if (!raw_ || IsHashTableDeletedValue())
+ return;
+
+ TraceCallback trace_callback =
+ TraceMethodDelegate<PersistentBase,
+ &PersistentBase::TracePersistent>::Trampoline;
+ persistent_node_.Initialize(this, trace_callback);
+ }
+
+ void UninitializeSafe() {
+ if (persistent_node_.IsInitialized()) {
+ typename PersistentMutexTraits<crossThreadnessConfiguration>::Locker lock;
+ persistent_node_.Uninitialize();
+ }
+ }
+
+ void UninitializeUnsafe() {
+ if (persistent_node_.IsInitialized())
+ persistent_node_.Uninitialize();
+ }
+
+ void CheckPointer() const {
+#if DCHECK_IS_ON()
+ if (!raw_ || IsHashTableDeletedValue())
+ return;
+
+ if (crossThreadnessConfiguration != kCrossThreadPersistentConfiguration) {
+ ThreadState* current = ThreadState::Current();
+ DCHECK(current);
+ // m_creationThreadState may be null when this is used in a heap
+ // collection which initialized the Persistent with memset and the
+ // constructor wasn't called.
+ if (creation_thread_state_) {
+ // Member should point to objects that belong in the same ThreadHeap.
+ DCHECK_EQ(&ThreadState::FromObject(raw_)->Heap(),
+ &creation_thread_state_->Heap());
+ // Member should point to objects that belong in the same ThreadHeap.
+ DCHECK_EQ(&current->Heap(), &creation_thread_state_->Heap());
+ }
+ }
+#endif
+ }
+
+ void SaveCreationThreadHeap() {
+#if DCHECK_IS_ON()
+ if (crossThreadnessConfiguration == kCrossThreadPersistentConfiguration) {
+ creation_thread_state_ = nullptr;
+ } else {
+ creation_thread_state_ = ThreadState::Current();
+ DCHECK(creation_thread_state_);
+ }
+#endif
+ }
+
+ static void HandleWeakPersistent(const LivenessBroker& broker,
+ const void* persistent_pointer) {
+ using Base =
+ PersistentBase<typename std::remove_const<T>::type,
+ weaknessConfiguration, crossThreadnessConfiguration>;
+ Base* persistent =
+ reinterpret_cast<Base*>(const_cast<void*>(persistent_pointer));
+ T* object = persistent->Get();
+ if (object && !broker.IsHeapObjectAlive(object))
+ ClearWeakPersistent(persistent);
+ }
+
+ static void ClearWeakPersistent(
+ PersistentBase<std::remove_const_t<T>,
+ kWeakPersistentConfiguration,
+ kCrossThreadPersistentConfiguration>* persistent) {
+ PersistentMutexTraits<crossThreadnessConfiguration>::AssertAcquired();
+ persistent->ClearWithLockHeld();
+ }
+
+ static void ClearWeakPersistent(
+ PersistentBase<std::remove_const_t<T>,
+ kWeakPersistentConfiguration,
+ kSingleThreadPersistentConfiguration>* persistent) {
+ persistent->Clear();
+ }
+
+ template <typename BadPersistent>
+ static void ClearWeakPersistent(BadPersistent* non_weak_persistent) {
+ NOTREACHED();
+ }
+
+ // raw_ is accessed most, so put it at the first field.
+ T* raw_;
+
+ // The pointer to the underlying persistent node.
+ //
+ // Since accesses are atomics in the cross-thread case, a different type is
+ // needed to prevent the compiler producing an error when it encounters
+ // operations that are legal on raw pointers but not on atomics, or
+ // vice-versa.
+ std::conditional_t<
+ crossThreadnessConfiguration == kCrossThreadPersistentConfiguration,
+ CrossThreadPersistentNodePtr<weaknessConfiguration>,
+ PersistentNodePtr<ThreadingTrait<T>::kAffinity, weaknessConfiguration>>
+ persistent_node_;
+
+#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
+ PersistentLocation location_;
+#endif // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
+
+#if DCHECK_IS_ON()
+ const ThreadState* creation_thread_state_;
+#endif
+
+ template <typename F,
+ WeaknessPersistentConfiguration,
+ CrossThreadnessPersistentConfiguration>
+ friend class PersistentBase;
+};
+
+// Persistent is a way to create a strong pointer from an off-heap object
+// to another on-heap object. As long as the Persistent handle is alive
+// the GC will keep the object pointed to alive. The Persistent handle is
+// always a GC root from the point of view of the GC.
+//
+// We have to construct and destruct Persistent in the same thread.
+template <typename T>
+class Persistent : public PersistentBase<T,
+ kNonWeakPersistentConfiguration,
+ kSingleThreadPersistentConfiguration> {
+ using Parent = PersistentBase<T,
+ kNonWeakPersistentConfiguration,
+ kSingleThreadPersistentConfiguration>;
+
+ public:
+ Persistent() : Parent() {}
+ Persistent(const PersistentLocation& location) : Parent(location) {}
+ Persistent(std::nullptr_t) : Parent(nullptr) {}
+ Persistent(const PersistentLocation& location, std::nullptr_t)
+ : Parent(location, nullptr) {}
+ Persistent(T* raw) : Parent(raw) {}
+ Persistent(const PersistentLocation& location, T* raw)
+ : Parent(location, raw) {}
+ Persistent(T& raw) : Parent(raw) {}
+ Persistent(const PersistentLocation& location, T& raw)
+ : Parent(location, raw) {}
+ Persistent(const Persistent& other) : Parent(other) {}
+ Persistent(const PersistentLocation& location, const Persistent& other)
+ : Parent(location, other) {}
+ template <typename U>
+ Persistent(const Persistent<U>& other) : Parent(other) {}
+ template <typename U>
+ Persistent(const PersistentLocation& location, const Persistent<U>& other)
+ : Parent(location, other) {}
+ template <typename U>
+ Persistent(const Member<U>& other) : Parent(other) {}
+ template <typename U>
+ Persistent(const PersistentLocation& location, const Member<U>& other)
+ : Parent(location, other) {}
+ Persistent(WTF::HashTableDeletedValueType x) : Parent(x) {}
+ Persistent(const PersistentLocation& location,
+ WTF::HashTableDeletedValueType x)
+ : Parent(location, x) {}
+
+ template <typename U>
+ Persistent& operator=(U* other) {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ Persistent& operator=(std::nullptr_t) {
+ Parent::operator=(nullptr);
+ return *this;
+ }
+
+ Persistent& operator=(const Persistent& other) {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ template <typename U>
+ Persistent& operator=(const Persistent<U>& other) {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ template <typename U>
+ Persistent& operator=(const Member<U>& other) {
+ Parent::operator=(other);
+ return *this;
+ }
+};
+
+// WeakPersistent is a way to create a weak pointer from an off-heap object
+// to an on-heap object. The m_raw is automatically cleared when the pointee
+// gets collected.
+//
+// We have to construct and destruct WeakPersistent in the same thread.
+//
+// Note that collections of WeakPersistents are not supported. Use a collection
+// of WeakMembers instead.
+//
+// HashSet<WeakPersistent<T>> m_set; // wrong
+// Persistent<HeapHashSet<WeakMember<T>>> m_set; // correct
+template <typename T>
+class WeakPersistent
+ : public PersistentBase<T,
+ kWeakPersistentConfiguration,
+ kSingleThreadPersistentConfiguration> {
+ using Parent = PersistentBase<T,
+ kWeakPersistentConfiguration,
+ kSingleThreadPersistentConfiguration>;
+
+ public:
+ WeakPersistent() : Parent() {}
+ WeakPersistent(std::nullptr_t) : Parent(nullptr) {}
+ WeakPersistent(T* raw) : Parent(raw) {}
+ WeakPersistent(T& raw) : Parent(raw) {}
+ WeakPersistent(const WeakPersistent& other) : Parent(other) {}
+ template <typename U>
+ WeakPersistent(const WeakPersistent<U>& other) : Parent(other) {}
+ template <typename U>
+ WeakPersistent(const Member<U>& other) : Parent(other) {}
+
+ template <typename U>
+ WeakPersistent& operator=(U* other) {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ WeakPersistent& operator=(std::nullptr_t) {
+ Parent::operator=(nullptr);
+ return *this;
+ }
+
+ WeakPersistent& operator=(const WeakPersistent& other) {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ template <typename U>
+ WeakPersistent& operator=(const WeakPersistent<U>& other) {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ template <typename U>
+ WeakPersistent& operator=(const Member<U>& other) {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ NO_SANITIZE_ADDRESS
+ bool IsClearedUnsafe() const { return this->IsNotNull(); }
+};
+
+// CrossThreadPersistent allows for holding onto an object strongly on a
+// different thread.
+//
+// Thread-safe operations:
+// - Construction
+// - Destruction
+// - Copy and move construction and assignment
+// - Clearing
+// - Deref if treated as immutable reference or if externally synchronized (e.g.
+// mutex, task). The current implementation of Get() uses a raw load (on
+// purpose) which prohibits mutation while accessing the reference on a
+// different thread.
+template <typename T>
+class CrossThreadPersistent
+ : public PersistentBase<T,
+ kNonWeakPersistentConfiguration,
+ kCrossThreadPersistentConfiguration> {
+ using Parent = PersistentBase<T,
+ kNonWeakPersistentConfiguration,
+ kCrossThreadPersistentConfiguration>;
+
+ public:
+ CrossThreadPersistent() : Parent() {}
+ CrossThreadPersistent(const PersistentLocation& location)
+ : Parent(location) {}
+ CrossThreadPersistent(std::nullptr_t) : Parent(nullptr) {}
+ CrossThreadPersistent(const PersistentLocation& location, std::nullptr_t)
+ : Parent(location, nullptr) {}
+ explicit CrossThreadPersistent(T* raw) : Parent(raw) {}
+ CrossThreadPersistent(const PersistentLocation& location, T* raw)
+ : Parent(location, raw) {}
+ explicit CrossThreadPersistent(T& raw) : Parent(raw) {}
+ CrossThreadPersistent(const PersistentLocation& location, T& raw)
+ : Parent(location, raw) {}
+ CrossThreadPersistent(const CrossThreadPersistent& other) { *this = other; }
+ CrossThreadPersistent(const PersistentLocation& location,
+ const CrossThreadPersistent& other) {
+ *this = other;
+ }
+ template <typename U>
+ CrossThreadPersistent(const CrossThreadPersistent<U>& other) {
+ *this = other;
+ }
+ template <typename U>
+ CrossThreadPersistent(const PersistentLocation& location,
+ const CrossThreadPersistent<U>& other) {
+ *this = other;
+ }
+ template <typename U>
+ CrossThreadPersistent(const Member<U>& other) : Parent(other) {}
+ template <typename U>
+ CrossThreadPersistent(const PersistentLocation& location,
+ const Member<U>& other)
+ : Parent(location, other) {}
+ CrossThreadPersistent(WTF::HashTableDeletedValueType x) : Parent(x) {}
+ CrossThreadPersistent(const PersistentLocation& location,
+ WTF::HashTableDeletedValueType x)
+ : Parent(location, x) {}
+ template <typename U>
+ CrossThreadPersistent(const CrossThreadWeakPersistent<U>& other) {
+ *this = other;
+ }
+
+ // Instead of using release(), assign then clear() instead.
+ // Using release() with per thread heap enabled can cause the object to be
+ // destroyed before assigning it to a new handle.
+ T* Release() = delete;
+
+ template <typename U>
+ CrossThreadPersistent& operator=(U* other) {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ CrossThreadPersistent& operator=(std::nullptr_t) {
+ Parent::operator=(nullptr);
+ return *this;
+ }
+
+ CrossThreadPersistent& operator=(const CrossThreadPersistent& other) {
+ MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
+ Parent::operator=(other);
+ return *this;
+ }
+
+ template <typename U>
+ CrossThreadPersistent& operator=(const CrossThreadPersistent<U>& other) {
+ MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
+ Parent::operator=(other);
+ return *this;
+ }
+
+ template <typename U>
+ CrossThreadPersistent& operator=(const CrossThreadWeakPersistent<U>&);
+};
+
+// CrossThreadWeakPersistent combines behavior of CrossThreadPersistent and
+// WeakPersistent, i.e., it allows holding onto an object weakly on a different
+// thread.
+//
+// Thread-safe operations:
+// - Construction
+// - Destruction
+// - Copy and move construction and assignment
+// - Clearing
+//
+// Note that this does not include dereferencing and using the raw pointer as
+// there is no guarantee that the object will be alive at the time it is used.
+template <typename T>
+class CrossThreadWeakPersistent
+ : public PersistentBase<T,
+ kWeakPersistentConfiguration,
+ kCrossThreadPersistentConfiguration> {
+ using Parent = PersistentBase<T,
+ kWeakPersistentConfiguration,
+ kCrossThreadPersistentConfiguration>;
+
+ public:
+ CrossThreadWeakPersistent() : Parent() {}
+ explicit CrossThreadWeakPersistent(T* raw) : Parent(raw) {}
+ explicit CrossThreadWeakPersistent(T& raw) : Parent(raw) {}
+ CrossThreadWeakPersistent(const CrossThreadWeakPersistent& other) {
+ *this = other;
+ }
+ template <typename U>
+ CrossThreadWeakPersistent(const CrossThreadWeakPersistent<U>& other) {
+ *this = other;
+ }
+ CrossThreadWeakPersistent(CrossThreadWeakPersistent&& other) {
+ *this = std::move(other);
+ }
+ template <typename U>
+ CrossThreadWeakPersistent(CrossThreadWeakPersistent<U>&& other) {
+ *this = std::move(other);
+ }
+
+ CrossThreadWeakPersistent& operator=(const CrossThreadWeakPersistent& other) {
+ MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
+ Parent::operator=(other);
+ return *this;
+ }
+
+ template <typename U>
+ CrossThreadWeakPersistent& operator=(
+ const CrossThreadWeakPersistent<U>& other) {
+ MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
+ Parent::operator=(other);
+ return *this;
+ }
+
+ CrossThreadWeakPersistent& operator=(CrossThreadWeakPersistent&& other) {
+ MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
+ Parent::operator=(std::move(other));
+ return *this;
+ }
+
+ template <typename U>
+ CrossThreadWeakPersistent& operator=(CrossThreadWeakPersistent<U>&& other) {
+ MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
+ Parent::operator=(std::move(other));
+ return *this;
+ }
+
+ template <typename U>
+ CrossThreadWeakPersistent& operator=(U* other) {
+ Parent::operator=(other);
+ return *this;
+ }
+
+ // Create a CrossThreadPersistent that keeps the underlying object alive if
+ // there is still on set. Can be used to work with an object on a different
+ // thread than it was allocated. Note that CTP does not block threads from
+ // terminating, in which case the reference would still be invalid.
+ const CrossThreadPersistent<T> Lock() const {
+ return CrossThreadPersistent<T>(*this);
+ }
+
+ // Disallow directly using CrossThreadWeakPersistent. Users must go through
+ // CrossThreadPersistent to access the pointee. Note that this does not
+ // guarantee that the object is still alive at that point. Users must check
+ // the state of CTP manually before invoking any calls.
+ T* operator->() const = delete;
+ T& operator*() const = delete;
+ operator T*() const = delete;
+ T* Get() const = delete;
+
+ private:
+ template <typename U>
+ friend class CrossThreadPersistent;
+};
+
+template <typename T>
+template <typename U>
+CrossThreadPersistent<T>& CrossThreadPersistent<T>::operator=(
+ const CrossThreadWeakPersistent<U>& other) {
+ MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
+ using ParentU = PersistentBase<U, kWeakPersistentConfiguration,
+ kCrossThreadPersistentConfiguration>;
+ this->AssignUnsafe(static_cast<const ParentU&>(other).Get());
+ return *this;
+}
+
+template <typename T>
+Persistent<T> WrapPersistentInternal(const PersistentLocation& location,
+ T* value) {
+ return Persistent<T>(location, value);
+}
+
+template <typename T>
+Persistent<T> WrapPersistentInternal(T* value) {
+ return Persistent<T>(value);
+}
+
+#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
+#define WrapPersistent(value) \
+ WrapPersistentInternal(PERSISTENT_FROM_HERE, value)
+#else
+#define WrapPersistent(value) WrapPersistentInternal(value)
+#endif // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
+
+template <typename T,
+ typename = std::enable_if_t<WTF::IsGarbageCollectedType<T>::value>>
+Persistent<T> WrapPersistentIfNeeded(T* value) {
+ return Persistent<T>(value);
+}
+
+template <typename T>
+T& WrapPersistentIfNeeded(T& value) {
+ return value;
+}
+
+template <typename T>
+WeakPersistent<T> WrapWeakPersistent(T* value) {
+ return WeakPersistent<T>(value);
+}
+
+template <typename T>
+CrossThreadPersistent<T> WrapCrossThreadPersistentInternal(
+ const PersistentLocation& location,
+ T* value) {
+ return CrossThreadPersistent<T>(location, value);
+}
+
+template <typename T>
+CrossThreadPersistent<T> WrapCrossThreadPersistentInternal(T* value) {
+ return CrossThreadPersistent<T>(value);
+}
+
+#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
+#define WrapCrossThreadPersistent(value) \
+ WrapCrossThreadPersistentInternal(PERSISTENT_FROM_HERE, value)
+#else
+#define WrapCrossThreadPersistent(value) \
+ WrapCrossThreadPersistentInternal(value)
+#endif // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
+
+template <typename T>
+CrossThreadWeakPersistent<T> WrapCrossThreadWeakPersistent(T* value) {
+ return CrossThreadWeakPersistent<T>(value);
+}
+
+// Comparison operators between (Weak)Members, Persistents, and UntracedMembers.
+template <typename T, typename U>
+inline bool operator==(const Member<T>& a, const Member<U>& b) {
+ return a.Get() == b.Get();
+}
+template <typename T, typename U>
+inline bool operator!=(const Member<T>& a, const Member<U>& b) {
+ return a.Get() != b.Get();
+}
+template <typename T, typename U>
+inline bool operator==(const Persistent<T>& a, const Persistent<U>& b) {
+ return a.Get() == b.Get();
+}
+template <typename T, typename U>
+inline bool operator!=(const Persistent<T>& a, const Persistent<U>& b) {
+ return a.Get() != b.Get();
+}
+
+template <typename T, typename U>
+inline bool operator==(const Member<T>& a, const Persistent<U>& b) {
+ return a.Get() == b.Get();
+}
+template <typename T, typename U>
+inline bool operator!=(const Member<T>& a, const Persistent<U>& b) {
+ return a.Get() != b.Get();
+}
+template <typename T, typename U>
+inline bool operator==(const Persistent<T>& a, const Member<U>& b) {
+ return a.Get() == b.Get();
+}
+template <typename T, typename U>
+inline bool operator!=(const Persistent<T>& a, const Member<U>& b) {
+ return a.Get() != b.Get();
+}
+
+} // namespace blink
+
+namespace WTF {
+
+template <
+ typename T,
+ blink::WeaknessPersistentConfiguration weaknessConfiguration,
+ blink::CrossThreadnessPersistentConfiguration crossThreadnessConfiguration>
+struct VectorTraits<blink::PersistentBase<T,
+ weaknessConfiguration,
+ crossThreadnessConfiguration>>
+ : VectorTraitsBase<blink::PersistentBase<T,
+ weaknessConfiguration,
+ crossThreadnessConfiguration>> {
+ STATIC_ONLY(VectorTraits);
+ static const bool kNeedsDestruction = true;
+ static const bool kCanInitializeWithMemset = true;
+ static const bool kCanClearUnusedSlotsWithMemset = false;
+ static const bool kCanMoveWithMemcpy = true;
+};
+
+template <typename T>
+struct HashTraits<blink::Persistent<T>>
+ : HandleHashTraits<T, blink::Persistent<T>> {};
+
+template <typename T>
+struct HashTraits<blink::CrossThreadPersistent<T>>
+ : HandleHashTraits<T, blink::CrossThreadPersistent<T>> {};
+
+template <typename T>
+struct DefaultHash<blink::Persistent<T>> {
+ STATIC_ONLY(DefaultHash);
+ using Hash = MemberHash<T>;
+};
+
+template <typename T>
+struct DefaultHash<blink::WeakPersistent<T>> {
+ STATIC_ONLY(DefaultHash);
+ using Hash = MemberHash<T>;
+};
+
+template <typename T>
+struct DefaultHash<blink::CrossThreadPersistent<T>> {
+ STATIC_ONLY(DefaultHash);
+ using Hash = MemberHash<T>;
+};
+
+template <typename T>
+struct DefaultHash<blink::CrossThreadWeakPersistent<T>> {
+ STATIC_ONLY(DefaultHash);
+ using Hash = MemberHash<T>;
+};
+
+template <typename T>
+struct CrossThreadCopier<blink::CrossThreadPersistent<T>>
+ : public CrossThreadCopierPassThrough<blink::CrossThreadPersistent<T>> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+template <typename T>
+struct CrossThreadCopier<blink::CrossThreadWeakPersistent<T>>
+ : public CrossThreadCopierPassThrough<blink::CrossThreadWeakPersistent<T>> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+} // namespace WTF
+
+namespace base {
+
+template <typename T>
+struct IsWeakReceiver<blink::WeakPersistent<T>> : std::true_type {};
+
+template <typename T>
+struct IsWeakReceiver<blink::CrossThreadWeakPersistent<T>> : std::true_type {};
+
+template <typename T>
+struct BindUnwrapTraits<blink::CrossThreadWeakPersistent<T>> {
+ static blink::CrossThreadPersistent<T> Unwrap(
+ const blink::CrossThreadWeakPersistent<T>& wrapped) {
+ return blink::CrossThreadPersistent<T>(wrapped);
+ }
+};
+} // namespace base
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PERSISTENT_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/persistent_node.cc b/chromium/third_party/blink/renderer/platform/heap/impl/persistent_node.cc
index 0dd7b23ae4c..64733dc57f6 100644
--- a/chromium/third_party/blink/renderer/platform/heap/persistent_node.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/persistent_node.cc
@@ -2,7 +2,7 @@
// 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/persistent_node.h"
+#include "third_party/blink/renderer/platform/heap/impl/persistent_node.h"
#include "base/debug/alias.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -17,7 +17,7 @@ class DummyGCBase final : public GarbageCollected<DummyGCBase> {
public:
void Trace(Visitor* visitor) const {}
};
-}
+} // namespace
PersistentRegionBase::~PersistentRegionBase() {
PersistentNodeSlots* slots = slots_;
diff --git a/chromium/third_party/blink/renderer/platform/heap/persistent_node.h b/chromium/third_party/blink/renderer/platform/heap/impl/persistent_node.h
index b591db1e793..d8c2b08471e 100644
--- a/chromium/third_party/blink/renderer/platform/heap/persistent_node.h
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/persistent_node.h
@@ -2,8 +2,8 @@
// 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_PERSISTENT_NODE_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PERSISTENT_NODE_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PERSISTENT_NODE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PERSISTENT_NODE_H_
#include <atomic>
#include <memory>
@@ -382,4 +382,4 @@ void CrossThreadPersistentNodePtr<weakness_configuration>::ClearWithLockHeld() {
} // namespace blink
-#endif
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PERSISTENT_NODE_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/process_heap.cc b/chromium/third_party/blink/renderer/platform/heap/impl/process_heap.cc
index df929e8dfd2..038a7385aad 100644
--- a/chromium/third_party/blink/renderer/platform/heap/process_heap.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/process_heap.cc
@@ -6,9 +6,9 @@
#include "base/sampling_heap_profiler/poisson_allocation_sampler.h"
#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/renderer/platform/heap/gc_info.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/persistent_node.h"
+#include "third_party/blink/renderer/platform/heap/impl/gc_info.h"
+#include "third_party/blink/renderer/platform/heap/impl/persistent_node.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/heap/impl/process_heap.h b/chromium/third_party/blink/renderer/platform/heap/impl/process_heap.h
new file mode 100644
index 00000000000..91112a7c039
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/process_heap.h
@@ -0,0 +1,69 @@
+// Copyright 2018 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_IMPL_PROCESS_HEAP_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PROCESS_HEAP_H_
+
+#include <atomic>
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
+
+namespace blink {
+
+class CrossThreadPersistentRegion;
+
+class PLATFORM_EXPORT ProcessHeap {
+ STATIC_ONLY(ProcessHeap);
+
+ public:
+ static void Init();
+
+ static CrossThreadPersistentRegion& GetCrossThreadPersistentRegion();
+ static CrossThreadPersistentRegion& GetCrossThreadWeakPersistentRegion();
+
+ // Access to the CrossThreadPersistentRegion from multiple threads has to be
+ // prevented as allocation, freeing, and iteration of nodes may otherwise
+ // cause data races.
+ //
+ // Examples include:
+ // - Iteration of strong cross-thread Persistents.
+ // - Iteration and processing of weak cross-thread Persistents. The lock
+ // needs to span both operations as iteration of weak persistents only
+ // registers memory regions that are then processed afterwards.
+ // - Marking phase in garbage collection: The whole phase requires locking
+ // as CrossThreadWeakPersistents may be converted to CrossThreadPersistent
+ // which must observe GC as an atomic operation.
+ static Mutex& CrossThreadPersistentMutex();
+
+ static void IncreaseTotalAllocatedObjectSize(size_t delta) {
+ total_allocated_object_size_.fetch_add(delta, std::memory_order_relaxed);
+ }
+ static void DecreaseTotalAllocatedObjectSize(size_t delta) {
+ total_allocated_object_size_.fetch_sub(delta, std::memory_order_relaxed);
+ }
+ static size_t TotalAllocatedObjectSize() {
+ return total_allocated_object_size_.load(std::memory_order_relaxed);
+ }
+ static void IncreaseTotalAllocatedSpace(size_t delta) {
+ total_allocated_space_.fetch_add(delta, std::memory_order_relaxed);
+ }
+ static void DecreaseTotalAllocatedSpace(size_t delta) {
+ total_allocated_space_.fetch_sub(delta, std::memory_order_relaxed);
+ }
+ static size_t TotalAllocatedSpace() {
+ return total_allocated_space_.load(std::memory_order_relaxed);
+ }
+ static void ResetHeapCounters();
+
+ private:
+ static std::atomic_size_t total_allocated_space_;
+ static std::atomic_size_t total_allocated_object_size_;
+
+ friend class ThreadState;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PROCESS_HEAP_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/thread_state.cc b/chromium/third_party/blink/renderer/platform/heap/impl/thread_state.cc
index bece34a9118..228902f91f7 100644
--- a/chromium/third_party/blink/renderer/platform/heap/thread_state.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/thread_state.cc
@@ -53,11 +53,11 @@
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-#include "third_party/blink/renderer/platform/heap/heap_compact.h"
#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
-#include "third_party/blink/renderer/platform/heap/marking_scheduling_oracle.h"
-#include "third_party/blink/renderer/platform/heap/marking_visitor.h"
-#include "third_party/blink/renderer/platform/heap/page_pool.h"
+#include "third_party/blink/renderer/platform/heap/impl/heap_compact.h"
+#include "third_party/blink/renderer/platform/heap/impl/marking_scheduling_oracle.h"
+#include "third_party/blink/renderer/platform/heap/impl/marking_visitor.h"
+#include "third_party/blink/renderer/platform/heap/impl/page_pool.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/heap/thread_state_scopes.h"
#include "third_party/blink/renderer/platform/heap/unified_heap_controller.h"
@@ -1153,8 +1153,8 @@ void ThreadState::IncrementalMarkingStep(BlinkGC::StackState stack_state) {
skip_incremental_marking_for_testing_ = false;
} else {
complete = MarkPhaseAdvanceMarking(
- marking_scheduling_->GetNextIncrementalStepDurationForTask(
- Heap().stats_collector()->object_size_in_bytes()),
+ marking_scheduling_->GetNextIncrementalStepDurationForTask(
+ Heap().stats_collector()->object_size_in_bytes()),
EphemeronProcessing::kPartialProcessing);
}
@@ -1638,7 +1638,6 @@ void ThreadState::MarkPhaseEpilogue(BlinkGC::MarkingType marking_type) {
incremental_marking_scheduler_->Cancel();
-
current_gc_data_.visitor->FlushCompactionWorklists();
current_gc_data_.visitor.reset();
diff --git a/chromium/third_party/blink/renderer/platform/heap/impl/thread_state.h b/chromium/third_party/blink/renderer/platform/heap/impl/thread_state.h
new file mode 100644
index 00000000000..ee318bd64bf
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/thread_state.h
@@ -0,0 +1,716 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREAD_STATE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREAD_STATE_H_
+
+#include <atomic>
+#include <memory>
+
+#include "base/macros.h"
+#include "base/synchronization/lock.h"
+#include "base/task/post_job.h"
+#include "third_party/blink/renderer/platform/heap/blink_gc.h"
+#include "third_party/blink/renderer/platform/heap/impl/atomic_entry_flag.h"
+#include "third_party/blink/renderer/platform/heap/impl/threading_traits.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/forward.h"
+#include "third_party/blink/renderer/platform/wtf/hash_map.h"
+#include "third_party/blink/renderer/platform/wtf/hash_set.h"
+#include "third_party/blink/renderer/platform/wtf/linked_hash_set.h"
+#include "third_party/blink/renderer/platform/wtf/sanitizers.h"
+#include "third_party/blink/renderer/platform/wtf/thread_specific.h"
+#include "third_party/blink/renderer/platform/wtf/threading.h"
+#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace v8 {
+class EmbedderGraph;
+class Isolate;
+} // namespace v8
+
+namespace blink {
+
+namespace incremental_marking_test {
+class IncrementalMarkingScope;
+} // namespace incremental_marking_test
+
+class MarkingVisitor;
+class MarkingSchedulingOracle;
+class PersistentNode;
+class PersistentRegion;
+class ThreadHeap;
+class ThreadState;
+template <ThreadAffinity affinity>
+class ThreadStateFor;
+class UnifiedHeapController;
+class Visitor;
+
+// Declare that a class has a pre-finalizer which gets invoked before objects
+// get swept. It is thus safe to touch on-heap objects that may be collected in
+// the same GC cycle. This is useful when it's not possible to avoid touching
+// on-heap objects in a destructor which is forbidden.
+//
+// Note that:
+// (a) Pre-finalizers *must* not resurrect dead objects.
+// (b) Run on the same thread they are registered.
+// (c) Decrease GC performance which means that they should only be used if
+// absolute necessary.
+//
+// Usage:
+// class Foo : GarbageCollected<Foo> {
+// USING_PRE_FINALIZER(Foo, Dispose);
+// private:
+// void Dispose() {
+// bar_->...; // It is safe to touch other on-heap objects.
+// }
+// Member<Bar> bar_;
+// };
+#define USING_PRE_FINALIZER(Class, PreFinalizer) \
+ public: \
+ static bool InvokePreFinalizer(const LivenessBroker& info, void* object) { \
+ Class* self = reinterpret_cast<Class*>(object); \
+ if (info.IsHeapObjectAlive(self)) \
+ return false; \
+ self->Class::PreFinalizer(); \
+ return true; \
+ } \
+ \
+ private: \
+ ThreadState::PrefinalizerRegistration<Class> prefinalizer_dummy_{this}; \
+ using UsingPreFinalizerMacroNeedsTrailingSemiColon = char
+
+class PLATFORM_EXPORT BlinkGCObserver {
+ USING_FAST_MALLOC(BlinkGCObserver);
+
+ public:
+ // The constructor automatically register this object to ThreadState's
+ // observer lists. The argument must not be null.
+ explicit BlinkGCObserver(ThreadState*);
+
+ // The destructor automatically unregister this object from ThreadState's
+ // observer lists.
+ virtual ~BlinkGCObserver();
+
+ virtual void OnCompleteSweepDone() = 0;
+
+ private:
+ // As a ThreadState must live when a BlinkGCObserver lives, holding a raw
+ // pointer is safe.
+ ThreadState* thread_state_;
+};
+
+class PLATFORM_EXPORT ThreadState final {
+ USING_FAST_MALLOC(ThreadState);
+
+ public:
+ // Register the pre-finalizer for the |self| object. The class T be using
+ // USING_PRE_FINALIZER() macro.
+ template <typename T>
+ class PrefinalizerRegistration final {
+ DISALLOW_NEW();
+
+ public:
+ PrefinalizerRegistration(T* self) { // NOLINT
+ static_assert(sizeof(&T::InvokePreFinalizer) > 0,
+ "USING_PRE_FINALIZER(T) must be defined.");
+ ThreadState* state =
+ ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
+#if DCHECK_IS_ON()
+ DCHECK(state->CheckThread());
+#endif
+ DCHECK(!state->SweepForbidden());
+ DCHECK(std::find(state->ordered_pre_finalizers_.begin(),
+ state->ordered_pre_finalizers_.end(),
+ PreFinalizer(self, T::InvokePreFinalizer)) ==
+ state->ordered_pre_finalizers_.end());
+ state->ordered_pre_finalizers_.emplace_back(self, T::InvokePreFinalizer);
+ }
+ };
+
+ // See setGCState() for possible state transitions.
+ enum GCState {
+ kNoGCScheduled,
+ kIncrementalMarkingStepPaused,
+ kIncrementalMarkingStepScheduled,
+ kIncrementalMarkingFinalizeScheduled,
+ kForcedGCForTestingScheduled,
+ kIncrementalGCScheduled,
+ };
+
+ // The phase that the GC is in. The GCPhase will not return kNone for mutators
+ // running during incremental marking and lazy sweeping. See SetGCPhase() for
+ // possible state transitions.
+ enum class GCPhase {
+ // GC is doing nothing.
+ kNone,
+ // GC is in marking phase.
+ kMarking,
+ // GC is in sweeping phase.
+ kSweeping,
+ };
+
+ enum class EphemeronProcessing {
+ kPartialProcessing, // Perofrm one ephemeron processing iteration every
+ // few step
+ kFullProcessing // Perofrm full fixed-point ephemeron processing on each
+ // step
+ };
+
+ class AtomicPauseScope;
+ class GCForbiddenScope;
+ class LsanDisabledScope;
+ class NoAllocationScope;
+ class StatisticsCollector;
+ struct Statistics;
+ class SweepForbiddenScope;
+ class HeapPointersOnStackScope;
+
+ using V8BuildEmbedderGraphCallback = void (*)(v8::Isolate*,
+ v8::EmbedderGraph*,
+ void*);
+
+ // Returns true if some thread (possibly the current thread) may be doing
+ // incremental marking. If false is returned, the *current* thread is
+ // definitely not doing incremental marking. See atomic_entry_flag.h for
+ // details.
+ //
+ // For an exact check, use ThreadState::IsIncrementalMarking.
+ ALWAYS_INLINE static bool IsAnyIncrementalMarking() {
+ return incremental_marking_flag_.MightBeEntered();
+ }
+
+ static ThreadState* AttachMainThread();
+
+ // Associate ThreadState object with the current thread. After this
+ // call thread can start using the garbage collected heap infrastructure.
+ // It also has to periodically check for safepoints.
+ static ThreadState* AttachCurrentThread();
+
+ // Disassociate attached ThreadState from the current thread. The thread
+ // can no longer use the garbage collected heap after this call.
+ //
+ // When ThreadState is detaching from non-main thread its heap is expected to
+ // be empty (because it is going away). Perform registered cleanup tasks and
+ // garbage collection to sweep away any objects that are left on this heap.
+ //
+ // This method asserts that no objects remain after this cleanup. If assertion
+ // does not hold we crash as we are potentially in the dangling pointer
+ // situation.
+ static void DetachCurrentThread();
+
+ static ThreadState* Current() { return **thread_specific_; }
+
+ static ThreadState* MainThreadState() {
+ return reinterpret_cast<ThreadState*>(main_thread_state_storage_);
+ }
+
+ static ThreadState* FromObject(const void*);
+
+ bool IsMainThread() const { return this == MainThreadState(); }
+ bool CheckThread() const { return thread_ == CurrentThread(); }
+
+ ThreadHeap& Heap() const { return *heap_; }
+ base::PlatformThreadId ThreadId() const { return thread_; }
+
+ // Associates |ThreadState| with a given |v8::Isolate|, essentially tying
+ // there garbage collectors together.
+ void AttachToIsolate(v8::Isolate*, V8BuildEmbedderGraphCallback);
+
+ // Removes the association from a potentially attached |v8::Isolate|.
+ void DetachFromIsolate();
+
+ // Returns an |UnifiedHeapController| if ThreadState is attached to a V8
+ // isolate (see |AttachToIsolate|) and nullptr otherwise.
+ UnifiedHeapController* unified_heap_controller() const {
+ DCHECK(isolate_);
+ return unified_heap_controller_.get();
+ }
+
+ void PerformIdleLazySweep(base::TimeTicks deadline);
+ void PerformConcurrentSweep(base::JobDelegate*);
+
+ void ScheduleForcedGCForTesting();
+ void ScheduleGCIfNeeded();
+ void SetGCState(GCState);
+ GCState GetGCState() const { return gc_state_; }
+ void SetGCPhase(GCPhase);
+
+ // Immediately starts incremental marking and schedules further steps if
+ // necessary.
+ void StartIncrementalMarking(BlinkGC::GCReason);
+
+ // Returns true if marking is in progress.
+ bool IsMarkingInProgress() const { return gc_phase_ == GCPhase::kMarking; }
+
+ // Returns true if unified heap marking is in progress.
+ bool IsUnifiedGCMarkingInProgress() const {
+ return IsMarkingInProgress() && IsUnifiedHeapGC();
+ }
+
+ // Returns true if sweeping is in progress.
+ bool IsSweepingInProgress() const { return gc_phase_ == GCPhase::kSweeping; }
+
+ // Returns true if the current GC is a memory reducing GC.
+ bool IsMemoryReducingGC() const {
+ return current_gc_data_.reason ==
+ BlinkGC::GCReason::kUnifiedHeapForMemoryReductionGC ||
+ current_gc_data_.reason ==
+ BlinkGC::GCReason::kUnifiedHeapForcedForTestingGC;
+ }
+
+ bool IsUnifiedHeapGC() const {
+ return current_gc_data_.reason == BlinkGC::GCReason::kUnifiedHeapGC ||
+ current_gc_data_.reason ==
+ BlinkGC::GCReason::kUnifiedHeapForMemoryReductionGC ||
+ current_gc_data_.reason ==
+ BlinkGC::GCReason::kUnifiedHeapForcedForTestingGC;
+ }
+
+ bool FinishIncrementalMarkingIfRunning(BlinkGC::CollectionType,
+ BlinkGC::StackState,
+ BlinkGC::MarkingType,
+ BlinkGC::SweepingType,
+ BlinkGC::GCReason);
+
+ void EnableIncrementalMarkingBarrier();
+ void DisableIncrementalMarkingBarrier();
+
+ void RestartIncrementalMarkingIfPaused();
+
+ void CompleteSweep();
+
+ // Returns whether it is currently allowed to allocate an object. Mainly used
+ // for sanity checks asserts.
+ bool IsAllocationAllowed() const {
+ // Allocation is not allowed during atomic marking pause, but it is allowed
+ // during atomic sweeping pause.
+ return !InAtomicMarkingPause() && !no_allocation_count_;
+ }
+
+ // Returns whether it is currently forbidden to trigger a GC.
+ bool IsGCForbidden() const { return gc_forbidden_count_; }
+
+ // Returns whether it is currently forbidden to sweep objects.
+ bool SweepForbidden() const { return sweep_forbidden_; }
+
+ bool in_atomic_pause() const { return in_atomic_pause_; }
+
+ bool InAtomicMarkingPause() const {
+ return in_atomic_pause() && IsMarkingInProgress();
+ }
+ bool InAtomicSweepingPause() const {
+ return in_atomic_pause() && IsSweepingInProgress();
+ }
+
+ bool IsIncrementalMarking() const { return incremental_marking_; }
+ void SetIncrementalMarking(bool value) { incremental_marking_ = value; }
+
+ void SafePoint(BlinkGC::StackState);
+
+ // A region of non-weak PersistentNodes allocated on the given thread.
+ PersistentRegion* GetPersistentRegion() const {
+ return persistent_region_.get();
+ }
+
+ // A region of PersistentNodes for WeakPersistents allocated on the given
+ // thread.
+ PersistentRegion* GetWeakPersistentRegion() const {
+ return weak_persistent_region_.get();
+ }
+
+ void RegisterStaticPersistentNode(PersistentNode*);
+ void ReleaseStaticPersistentNodes();
+ void FreePersistentNode(PersistentRegion*, PersistentNode*);
+
+ v8::Isolate* GetIsolate() const { return isolate_; }
+
+ // Returns |true| if |object| resides on this thread's heap.
+ // It is well-defined to call this method on any heap allocated
+ // reference, provided its associated heap hasn't been detached
+ // and shut down. Its behavior is undefined for any other pointer
+ // value.
+ bool IsOnThreadHeap(const void* object) const {
+ return &FromObject(object)->Heap() == &Heap();
+ }
+
+ ALWAYS_INLINE bool IsOnStack(Address address) const {
+ return reinterpret_cast<Address>(start_of_stack_) >= address &&
+ address >= (reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(
+ WTF::GetCurrentStackPosition())));
+ }
+
+ int GcAge() const { return gc_age_; }
+
+ MarkingVisitor* CurrentVisitor() const {
+ return current_gc_data_.visitor.get();
+ }
+
+ // Returns true if the marking verifier is enabled, false otherwise.
+ bool IsVerifyMarkingEnabled() const;
+
+ void SkipIncrementalMarkingForTesting() {
+ skip_incremental_marking_for_testing_ = true;
+ }
+
+ // Performs stand-alone garbage collections considering only C++ objects for
+ // testing.
+ //
+ // Since it only considers C++ objects this type of GC is mostly useful for
+ // unit tests.
+ void CollectGarbageForTesting(BlinkGC::CollectionType,
+ BlinkGC::StackState,
+ BlinkGC::MarkingType,
+ BlinkGC::SweepingType,
+ BlinkGC::GCReason);
+
+ // Forced garbage collection for testing:
+ // - Performs unified heap garbage collections if ThreadState is attached to a
+ // v8::Isolate using ThreadState::AttachToIsolate.
+ // - Otherwise, performs stand-alone garbage collections.
+ // - Collects garbage as long as live memory decreases (capped at 5).
+ void CollectAllGarbageForTesting(
+ BlinkGC::StackState stack_state =
+ BlinkGC::StackState::kNoHeapPointersOnStack);
+
+ // Enables compaction for next garbage collection.
+ void EnableCompactionForNextGCForTesting();
+
+ bool RequiresForcedGCForTesting() const {
+ return current_gc_data_.stack_state ==
+ BlinkGC::StackState::kHeapPointersOnStack &&
+ !forced_scheduled_gc_for_testing_;
+ }
+
+ void EnterNoHeapVerificationScopeForTesting() {
+ ++disable_heap_verification_scope_;
+ }
+ void LeaveNoHeapVerificationScopeForTesting() {
+ --disable_heap_verification_scope_;
+ }
+
+ private:
+ class IncrementalMarkingScheduler;
+
+ // Stores whether some ThreadState is currently in incremental marking.
+ static AtomicEntryFlag incremental_marking_flag_;
+
+ static WTF::ThreadSpecific<ThreadState*>* thread_specific_;
+
+ // We can't create a static member of type ThreadState here because it will
+ // introduce global constructor and destructor. We would like to manage
+ // lifetime of the ThreadState attached to the main thread explicitly instead
+ // and still use normal constructor and destructor for the ThreadState class.
+ // For this we reserve static storage for the main ThreadState and lazily
+ // construct ThreadState in it using placement new.
+ static uint8_t main_thread_state_storage_[];
+
+ // Callback executed directly after pushing all callee-saved registers.
+ // |end_of_stack| denotes the end of the stack that can hold references to
+ // managed objects.
+ static void VisitStackAfterPushingRegisters(ThreadState*,
+ intptr_t* end_of_stack);
+
+ static bool IsForcedGC(BlinkGC::GCReason reason) {
+ return reason == BlinkGC::GCReason::kThreadTerminationGC ||
+ reason == BlinkGC::GCReason::kForcedGCForTesting ||
+ reason == BlinkGC::GCReason::kUnifiedHeapForcedForTestingGC;
+ }
+
+ ThreadState();
+ ~ThreadState();
+
+ void EnterNoAllocationScope() { no_allocation_count_++; }
+ void LeaveNoAllocationScope() { no_allocation_count_--; }
+
+ void EnterAtomicPause() {
+ DCHECK(!in_atomic_pause_);
+ in_atomic_pause_ = true;
+ }
+ void LeaveAtomicPause() {
+ DCHECK(in_atomic_pause_);
+ in_atomic_pause_ = false;
+ }
+
+ void EnterGCForbiddenScope() { gc_forbidden_count_++; }
+ void LeaveGCForbiddenScope() {
+ DCHECK_GT(gc_forbidden_count_, 0u);
+ gc_forbidden_count_--;
+ }
+
+ void EnterStaticReferenceRegistrationDisabledScope();
+ void LeaveStaticReferenceRegistrationDisabledScope();
+
+ // Performs stand-alone garbage collections considering only C++ objects.
+ //
+ // Use the public *ForTesting calls for calling GC in tests.
+ void CollectGarbage(BlinkGC::CollectionType,
+ BlinkGC::StackState,
+ BlinkGC::MarkingType,
+ BlinkGC::SweepingType,
+ BlinkGC::GCReason);
+
+ // The following methods are used to compose RunAtomicPause. Public users
+ // should use the CollectGarbage entrypoint. Internal users should use these
+ // methods to compose a full garbage collection.
+ void AtomicPauseMarkPrologue(BlinkGC::CollectionType,
+ BlinkGC::StackState,
+ BlinkGC::MarkingType,
+ BlinkGC::GCReason);
+ void AtomicPauseMarkRoots(BlinkGC::StackState,
+ BlinkGC::MarkingType,
+ BlinkGC::GCReason);
+ void AtomicPauseMarkTransitiveClosure();
+ void AtomicPauseMarkEpilogue(BlinkGC::MarkingType);
+ void AtomicPauseSweepAndCompact(BlinkGC::CollectionType,
+ BlinkGC::MarkingType marking_type,
+ BlinkGC::SweepingType sweeping_type);
+ void AtomicPauseEpilogue();
+
+ // RunAtomicPause composes the final atomic pause that finishes a mark-compact
+ // phase of a garbage collection. Depending on SweepingType it may also finish
+ // sweeping or schedule lazy/concurrent sweeping.
+ void RunAtomicPause(BlinkGC::CollectionType,
+ BlinkGC::StackState,
+ BlinkGC::MarkingType,
+ BlinkGC::SweepingType,
+ BlinkGC::GCReason);
+
+ // The version is needed to be able to start incremental marking.
+ void MarkPhasePrologue(BlinkGC::CollectionType,
+ BlinkGC::StackState,
+ BlinkGC::MarkingType,
+ BlinkGC::GCReason);
+ void MarkPhaseEpilogue(BlinkGC::MarkingType);
+ void MarkPhaseVisitRoots();
+ void MarkPhaseVisitNotFullyConstructedObjects();
+ bool MarkPhaseAdvanceMarkingBasedOnSchedule(base::TimeDelta,
+ EphemeronProcessing);
+ bool MarkPhaseAdvanceMarking(base::TimeDelta, EphemeronProcessing);
+ void VerifyMarking(BlinkGC::MarkingType);
+
+ // Visit the stack after pushing registers onto the stack.
+ void PushRegistersAndVisitStack();
+
+ // Visit local thread stack and trace all pointers conservatively. Never call
+ // directly but always call through |PushRegistersAndVisitStack|.
+ void VisitStackImpl(MarkingVisitor*, Address*, Address*);
+ void VisitStack(MarkingVisitor*, Address*);
+ void VisitUnsafeStack(MarkingVisitor*);
+
+ // Visit the asan fake stack frame corresponding to a slot on the real machine
+ // stack if there is one. Never call directly but always call through
+ // |PushRegistersAndVisitStack|.
+ void VisitAsanFakeStackForPointer(MarkingVisitor*,
+ Address,
+ Address*,
+ Address*);
+
+ // Visit all non-weak persistents allocated on this thread.
+ void VisitPersistents(Visitor*);
+
+ // Visit all weak persistents allocated on this thread.
+ void VisitWeakPersistents(Visitor*);
+
+ // Visit card tables (remembered sets) containing inter-generational pointers.
+ void VisitRememberedSets(MarkingVisitor*);
+
+ // Incremental marking implementation functions.
+ void IncrementalMarkingStartForTesting();
+ void IncrementalMarkingStart(BlinkGC::GCReason);
+ // Incremental marking step advance marking on the mutator thread. This method
+ // also reschedules concurrent marking tasks if needed. The duration parameter
+ // applies only to incremental marking steps on the mutator thread.
+ void IncrementalMarkingStep(BlinkGC::StackState);
+ void IncrementalMarkingFinalize();
+
+ // Returns true if concurrent marking is finished (i.e. all current threads
+ // terminated and the worklist is empty)
+ bool ConcurrentMarkingStep();
+ void ScheduleConcurrentMarking();
+ void PerformConcurrentMark(base::JobDelegate* job);
+
+ // Schedule helpers.
+ void ScheduleIdleLazySweep();
+ void ScheduleConcurrentAndLazySweep();
+
+ void NotifySweepDone();
+ void PostSweep();
+
+ // See |DetachCurrentThread|.
+ void RunTerminationGC();
+
+ void RunScheduledGC(BlinkGC::StackState);
+
+ void SynchronizeAndFinishConcurrentSweeping();
+
+ void InvokePreFinalizers();
+
+ // Adds the given observer to the ThreadState's observer list. This doesn't
+ // take ownership of the argument. The argument must not be null. The argument
+ // must not be registered before calling this.
+ void AddObserver(BlinkGCObserver*);
+
+ // Removes the given observer from the ThreadState's observer list. This
+ // doesn't take ownership of the argument. The argument must not be null.
+ // The argument must be registered before calling this.
+ void RemoveObserver(BlinkGCObserver*);
+
+ bool IsForcedGC() const { return IsForcedGC(current_gc_data_.reason); }
+
+ // Returns whether stack scanning is forced. This is currently only used in
+ // platform tests where non nested tasks can be run with heap pointers on
+ // stack.
+ bool HeapPointersOnStackForced() const {
+ return heap_pointers_on_stack_forced_;
+ }
+
+#if defined(ADDRESS_SANITIZER)
+ // Poisons payload of unmarked objects.
+ //
+ // Also unpoisons memory areas for handles that may require resetting which
+ // can race with destructors. Note that cross-thread access still requires
+ // synchronization using a lock.
+ void PoisonUnmarkedObjects();
+#endif // ADDRESS_SANITIZER
+
+ std::unique_ptr<ThreadHeap> heap_;
+ base::PlatformThreadId thread_;
+ std::unique_ptr<PersistentRegion> persistent_region_;
+ std::unique_ptr<PersistentRegion> weak_persistent_region_;
+
+ // Start of the stack which is the boundary until conservative stack scanning
+ // needs to search for managed pointers.
+ Address* start_of_stack_;
+
+ bool in_atomic_pause_ = false;
+ bool sweep_forbidden_ = false;
+ bool heap_pointers_on_stack_forced_ = false;
+ bool incremental_marking_ = false;
+ bool should_optimize_for_load_time_ = false;
+ bool forced_scheduled_gc_for_testing_ = false;
+ size_t no_allocation_count_ = 0;
+ size_t gc_forbidden_count_ = 0;
+ size_t static_persistent_registration_disabled_count_ = 0;
+
+ GCState gc_state_ = GCState::kNoGCScheduled;
+ GCPhase gc_phase_ = GCPhase::kNone;
+ BlinkGC::GCReason reason_for_scheduled_gc_ =
+ BlinkGC::GCReason::kForcedGCForTesting;
+
+ using PreFinalizerCallback = bool (*)(const LivenessBroker&, void*);
+ using PreFinalizer = std::pair<void*, PreFinalizerCallback>;
+
+ // Pre-finalizers are called in the reverse order in which they are
+ // registered by the constructors (including constructors of Mixin objects)
+ // for an object, by processing the ordered_pre_finalizers_ back-to-front.
+ Deque<PreFinalizer> ordered_pre_finalizers_;
+
+ v8::Isolate* isolate_ = nullptr;
+ V8BuildEmbedderGraphCallback v8_build_embedder_graph_ = nullptr;
+ std::unique_ptr<UnifiedHeapController> unified_heap_controller_;
+
+#if defined(ADDRESS_SANITIZER)
+ void* asan_fake_stack_;
+#endif
+
+ HashSet<BlinkGCObserver*> observers_;
+
+ // PersistentNodes that are stored in static references;
+ // references that either have to be cleared upon the thread
+ // detaching from Oilpan and shutting down or references we
+ // have to clear before initiating LSan's leak detection.
+ HashSet<PersistentNode*> static_persistents_;
+
+ int gc_age_ = 0;
+
+ struct GCData {
+ BlinkGC::CollectionType collection_type;
+ BlinkGC::StackState stack_state;
+ BlinkGC::MarkingType marking_type;
+ BlinkGC::GCReason reason;
+ std::unique_ptr<MarkingVisitor> visitor;
+ };
+ GCData current_gc_data_;
+
+ std::unique_ptr<IncrementalMarkingScheduler> incremental_marking_scheduler_;
+ std::unique_ptr<MarkingSchedulingOracle> marking_scheduling_;
+
+ base::JobHandle marker_handle_;
+
+ base::JobHandle sweeper_handle_;
+ std::atomic_bool has_unswept_pages_{false};
+
+ size_t disable_heap_verification_scope_ = 0;
+
+ bool skip_incremental_marking_for_testing_ = false;
+
+ size_t last_concurrently_marked_bytes_ = 0;
+ base::TimeTicks last_concurrently_marked_bytes_update_;
+ bool concurrent_marking_priority_increased_ = false;
+
+ friend class BlinkGCObserver;
+ friend class incremental_marking_test::IncrementalMarkingScope;
+ friend class IncrementalMarkingTestDriver;
+ friend class HeapAllocator;
+ template <typename T>
+ friend class PrefinalizerRegistration;
+ friend class TestGCScope;
+ friend class TestSupportingGC;
+ friend class ThreadStateSchedulingTest;
+ friend class UnifiedHeapController;
+
+ DISALLOW_COPY_AND_ASSIGN(ThreadState);
+};
+
+template <>
+class ThreadStateFor<kMainThreadOnly> {
+ STATIC_ONLY(ThreadStateFor);
+
+ public:
+ static ThreadState* GetState() {
+ // This specialization must only be used from the main thread.
+ DCHECK(ThreadState::Current()->IsMainThread());
+ return ThreadState::MainThreadState();
+ }
+};
+
+template <>
+class ThreadStateFor<kAnyThread> {
+ STATIC_ONLY(ThreadStateFor);
+
+ public:
+ static ThreadState* GetState() { return ThreadState::Current(); }
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREAD_STATE_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/impl/thread_state_scopes.h b/chromium/third_party/blink/renderer/platform/heap/impl/thread_state_scopes.h
new file mode 100644
index 00000000000..07e22c95cae
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/thread_state_scopes.h
@@ -0,0 +1,128 @@
+// Copyright 2019 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_IMPL_THREAD_STATE_SCOPES_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREAD_STATE_SCOPES_H_
+
+#include "third_party/blink/renderer/platform/heap/thread_state.h"
+
+#if defined(LEAK_SANITIZER)
+#include "third_party/blink/renderer/platform/wtf/leak_annotations.h"
+#endif
+
+namespace blink {
+
+// The NoAllocationScope class is used in debug mode to catch unwanted
+// allocations. E.g. allocations during GC.
+class ThreadState::NoAllocationScope final {
+ STACK_ALLOCATED();
+ DISALLOW_COPY_AND_ASSIGN(NoAllocationScope);
+
+ public:
+ explicit NoAllocationScope(ThreadState* state) : state_(state) {
+ state_->EnterNoAllocationScope();
+ }
+ ~NoAllocationScope() { state_->LeaveNoAllocationScope(); }
+
+ private:
+ ThreadState* const state_;
+};
+
+class ThreadState::SweepForbiddenScope final {
+ STACK_ALLOCATED();
+ DISALLOW_COPY_AND_ASSIGN(SweepForbiddenScope);
+
+ public:
+ explicit SweepForbiddenScope(ThreadState* state) : state_(state) {
+ DCHECK(!state_->sweep_forbidden_);
+ state_->sweep_forbidden_ = true;
+ }
+ ~SweepForbiddenScope() {
+ DCHECK(state_->sweep_forbidden_);
+ state_->sweep_forbidden_ = false;
+ }
+
+ private:
+ ThreadState* const state_;
+};
+
+class ThreadState::GCForbiddenScope final {
+ STACK_ALLOCATED();
+
+ public:
+ explicit GCForbiddenScope(ThreadState* thread_state)
+ : thread_state_(thread_state) {
+ thread_state_->EnterGCForbiddenScope();
+ }
+ ~GCForbiddenScope() { thread_state_->LeaveGCForbiddenScope(); }
+
+ private:
+ ThreadState* const thread_state_;
+};
+
+// Used to mark when we are in an atomic pause for GC.
+class ThreadState::AtomicPauseScope final {
+ STACK_ALLOCATED();
+
+ public:
+ explicit AtomicPauseScope(ThreadState* thread_state)
+ : thread_state_(thread_state), gc_forbidden_scope(thread_state) {
+ thread_state_->EnterAtomicPause();
+ }
+ ~AtomicPauseScope() { thread_state_->LeaveAtomicPause(); }
+
+ private:
+ ThreadState* const thread_state_;
+ GCForbiddenScope gc_forbidden_scope;
+};
+
+class ThreadState::HeapPointersOnStackScope final {
+ STACK_ALLOCATED();
+
+ public:
+ explicit HeapPointersOnStackScope(ThreadState* state) : state_(state) {
+ DCHECK(!state_->heap_pointers_on_stack_forced_);
+ state_->heap_pointers_on_stack_forced_ = true;
+ }
+ ~HeapPointersOnStackScope() {
+ DCHECK(state_->heap_pointers_on_stack_forced_);
+ state_->heap_pointers_on_stack_forced_ = false;
+ }
+
+ private:
+ ThreadState* const state_;
+};
+
+#if defined(LEAK_SANITIZER)
+class ThreadState::LsanDisabledScope final {
+ STACK_ALLOCATED();
+ DISALLOW_COPY_AND_ASSIGN(LsanDisabledScope);
+
+ public:
+ explicit LsanDisabledScope(ThreadState* thread_state)
+ : thread_state_(thread_state) {
+ __lsan_disable();
+ if (thread_state_)
+ thread_state_->EnterStaticReferenceRegistrationDisabledScope();
+ }
+
+ ~LsanDisabledScope() {
+ __lsan_enable();
+ if (thread_state_)
+ thread_state_->LeaveStaticReferenceRegistrationDisabledScope();
+ }
+
+ private:
+ ThreadState* const thread_state_;
+};
+
+#define LEAK_SANITIZER_DISABLED_SCOPE \
+ ThreadState::LsanDisabledScope lsan_disabled_scope(ThreadState::Current())
+#else
+#define LEAK_SANITIZER_DISABLED_SCOPE
+#endif
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREAD_STATE_SCOPES_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/thread_state_statistics.cc b/chromium/third_party/blink/renderer/platform/heap/impl/thread_state_statistics.cc
index 90a684cb1c7..d845f85de2e 100644
--- a/chromium/third_party/blink/renderer/platform/heap/thread_state_statistics.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/thread_state_statistics.cc
@@ -2,7 +2,7 @@
// 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_statistics.h"
+#include "third_party/blink/renderer/platform/heap/impl/thread_state_statistics.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
diff --git a/chromium/third_party/blink/renderer/platform/heap/thread_state_statistics.h b/chromium/third_party/blink/renderer/platform/heap/impl/thread_state_statistics.h
index c2a3a6ff7b4..9eb1efa6d87 100644
--- a/chromium/third_party/blink/renderer/platform/heap/thread_state_statistics.h
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/thread_state_statistics.h
@@ -2,8 +2,8 @@
// 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_STATISTICS_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_STATISTICS_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREAD_STATE_STATISTICS_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREAD_STATE_STATISTICS_H_
#include "third_party/blink/renderer/platform/heap/thread_state.h"
@@ -64,4 +64,4 @@ class PLATFORM_EXPORT ThreadState::StatisticsCollector {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_STATISTICS_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREAD_STATE_STATISTICS_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/threading_traits.h b/chromium/third_party/blink/renderer/platform/heap/impl/threading_traits.h
index 95fa0c7e20a..bfae97b263b 100644
--- a/chromium/third_party/blink/renderer/platform/heap/threading_traits.h
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/threading_traits.h
@@ -2,8 +2,8 @@
// 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_THREADING_TRAITS_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREADING_TRAITS_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREADING_TRAITS_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREADING_TRAITS_H_
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/deque.h"
@@ -165,4 +165,4 @@ struct ThreadingTrait<HeapHashCountedSet<T, U, V>>
} // namespace blink
-#endif
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREADING_TRAITS_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/trace_traits.h b/chromium/third_party/blink/renderer/platform/heap/impl/trace_traits.h
index 59c97feb72b..668da565219 100644
--- a/chromium/third_party/blink/renderer/platform/heap/trace_traits.h
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/trace_traits.h
@@ -2,13 +2,13 @@
// 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_TRACE_TRAITS_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_TRACE_TRAITS_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_TRACE_TRAITS_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_TRACE_TRAITS_H_
#include "base/optional.h"
-#include "third_party/blink/renderer/platform/heap/gc_info.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/heap_page.h"
+#include "third_party/blink/renderer/platform/heap/impl/gc_info.h"
+#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
@@ -280,31 +280,10 @@ struct TraceInCollectionTrait<kNoWeakHandling, T, Traits> {
};
template <typename T, typename Traits>
-struct TraceInCollectionTrait<kNoWeakHandling, blink::Member<T>, Traits> {
- static bool IsAlive(const blink::LivenessBroker& info,
- const blink::Member<T>& t) {
- return true;
- }
- static void Trace(blink::Visitor* visitor, const blink::Member<T>& t) {
- visitor->TraceMaybeDeleted(t);
- }
-};
-
-template <typename T, typename Traits>
-struct TraceInCollectionTrait<kWeakHandling, blink::Member<T>, Traits> {
- static bool IsAlive(const blink::LivenessBroker& info,
- const blink::Member<T>& t) {
- return true;
- }
- static void Trace(blink::Visitor* visitor, const blink::Member<T>& t) {
- visitor->TraceMaybeDeleted(t);
- }
-};
-
-template <typename T, typename Traits>
struct TraceInCollectionTrait<kNoWeakHandling, blink::WeakMember<T>, Traits> {
static void Trace(blink::Visitor* visitor, const blink::WeakMember<T>& t) {
- visitor->TraceMaybeDeleted(t);
+ // Extract raw pointer to avoid using the WeakMember<> overload in Visitor.
+ visitor->TraceStrongly(t);
}
};
@@ -399,4 +378,4 @@ struct TraceInCollectionTrait<
} // namespace WTF
-#endif
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_TRACE_TRAITS_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/unified_heap_controller.cc b/chromium/third_party/blink/renderer/platform/heap/impl/unified_heap_controller.cc
index df02a2d90ec..43a4e292dbf 100644
--- a/chromium/third_party/blink/renderer/platform/heap/unified_heap_controller.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/unified_heap_controller.cc
@@ -12,7 +12,7 @@
#include "third_party/blink/renderer/platform/bindings/wrapper_type_info.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
-#include "third_party/blink/renderer/platform/heap/marking_visitor.h"
+#include "third_party/blink/renderer/platform/heap/impl/marking_visitor.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
diff --git a/chromium/third_party/blink/renderer/platform/heap/impl/unified_heap_controller.h b/chromium/third_party/blink/renderer/platform/heap/impl/unified_heap_controller.h
new file mode 100644
index 00000000000..c42283ca6c3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/unified_heap_controller.h
@@ -0,0 +1,75 @@
+// Copyright 2018 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_IMPL_UNIFIED_HEAP_CONTROLLER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_UNIFIED_HEAP_CONTROLLER_H_
+
+#include "base/macros.h"
+#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+class ThreadState;
+
+// UnifiedHeapController ties V8's garbage collector to Oilpan for performing a
+// garbage collection across both managed heaps.
+//
+// Unified heap garbage collections are triggered by V8 and mark the full
+// transitive closure of V8 and Blink (Oilpan) objects. The garbage collection
+// is initially triggered by V8. Both collecters report live references using
+// the EmbedderHeapTracer APIs. V8 and Blink both run separate incremental
+// marking steps to compute their live closures, respectively. The final atomic
+// pause is then initiated by V8 and triggers a fixed-point computation between
+// V8 and Blink where both GCs report live references to each other and drain
+// their marking work lists until they are empty and no new references are
+// found.
+//
+// Oilpan does not consider references from DOM wrappers (JavaScript objects on
+// V8's heap) as roots for such garbage collections.
+class PLATFORM_EXPORT UnifiedHeapController final
+ : public v8::EmbedderHeapTracer,
+ public ThreadHeapStatsObserver {
+ DISALLOW_IMPLICIT_CONSTRUCTORS(UnifiedHeapController);
+
+ public:
+ explicit UnifiedHeapController(ThreadState*);
+ ~UnifiedHeapController() override;
+
+ // v8::EmbedderHeapTracer implementation.
+ void TracePrologue(v8::EmbedderHeapTracer::TraceFlags) final;
+ void TraceEpilogue(v8::EmbedderHeapTracer::TraceSummary*) final;
+ void EnterFinalPause(EmbedderStackState) final;
+ void RegisterV8References(const std::vector<std::pair<void*, void*>>&) final;
+ bool AdvanceTracing(double) final;
+ bool IsTracingDone() final;
+ bool IsRootForNonTracingGC(const v8::TracedReference<v8::Value>&) final;
+ bool IsRootForNonTracingGC(const v8::TracedGlobal<v8::Value>&) final;
+ void ResetHandleInNonTracingGC(const v8::TracedReference<v8::Value>&) final;
+
+ ThreadState* thread_state() const { return thread_state_; }
+
+ // ThreadHeapStatsObserver implementation.
+ void IncreaseAllocatedObjectSize(size_t) final;
+ void DecreaseAllocatedObjectSize(size_t) final;
+ // Not needed.
+ void ResetAllocatedObjectSize(size_t) final {}
+ void IncreaseAllocatedSpace(size_t) final {}
+ void DecreaseAllocatedSpace(size_t) final {}
+
+ private:
+ void ReportBufferedAllocatedSizeIfPossible();
+
+ ThreadState* const thread_state_;
+ // Returns whether the Blink heap has been fully processed.
+ bool is_tracing_done_ = false;
+
+ // Buffered allocated size. Only positive values are forwarded to V8.
+ int64_t buffered_allocated_size_ = 0;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_UNIFIED_HEAP_CONTROLLER_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc b/chromium/third_party/blink/renderer/platform/heap/impl/unified_heap_marking_visitor.cc
index 00a9bc24826..00a9bc24826 100644
--- a/chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/unified_heap_marking_visitor.cc
diff --git a/chromium/third_party/blink/renderer/platform/heap/impl/unified_heap_marking_visitor.h b/chromium/third_party/blink/renderer/platform/heap/impl/unified_heap_marking_visitor.h
new file mode 100644
index 00000000000..8d589b4e52b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/unified_heap_marking_visitor.h
@@ -0,0 +1,89 @@
+// Copyright 2018 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_IMPL_UNIFIED_HEAP_MARKING_VISITOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_UNIFIED_HEAP_MARKING_VISITOR_H_
+
+#include "base/macros.h"
+#include "third_party/blink/renderer/platform/heap/impl/marking_visitor.h"
+
+namespace v8 {
+class EmbedderHeapTracer;
+}
+
+namespace blink {
+
+struct WrapperTypeInfo;
+
+// Marking visitor for unified heap garbage collections. Extends the regular
+// Oilpan marking visitor by also providing write barriers and visitation
+// methods that allow for announcing reachable objects to V8. Visitor can be
+// used from any thread.
+class PLATFORM_EXPORT UnifiedHeapMarkingVisitorBase {
+ public:
+ virtual ~UnifiedHeapMarkingVisitorBase() = default;
+
+ protected:
+ UnifiedHeapMarkingVisitorBase(ThreadState*, v8::Isolate*, int);
+
+ // Visitation methods that announce reachable wrappers to V8.
+ void VisitImpl(const TraceWrapperV8Reference<v8::Value>&);
+
+ v8::Isolate* const isolate_;
+ v8::EmbedderHeapTracer* const controller_;
+ V8ReferencesWorklist::View v8_references_worklist_;
+
+ private:
+ int task_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(UnifiedHeapMarkingVisitorBase);
+};
+
+// Same as the base visitor with the difference that it is bound to main thread.
+// Also implements various sorts of write barriers that should only be called
+// from the main thread.
+class PLATFORM_EXPORT UnifiedHeapMarkingVisitor
+ : public MarkingVisitor,
+ public UnifiedHeapMarkingVisitorBase {
+ public:
+ // Write barriers for annotating a write during incremental marking.
+ static void WriteBarrier(const TraceWrapperV8Reference<v8::Value>&);
+ static void WriteBarrier(v8::Isolate*, const WrapperTypeInfo*, const void*);
+
+ UnifiedHeapMarkingVisitor(ThreadState*, MarkingMode, v8::Isolate*);
+ ~UnifiedHeapMarkingVisitor() override = default;
+
+ protected:
+ using Visitor::Visit;
+ void Visit(const TraceWrapperV8Reference<v8::Value>&) final;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(UnifiedHeapMarkingVisitor);
+};
+
+// Same as the base visitor with the difference that it is bound to a
+// concurrent thread.
+class PLATFORM_EXPORT ConcurrentUnifiedHeapMarkingVisitor
+ : public ConcurrentMarkingVisitor,
+ public UnifiedHeapMarkingVisitorBase {
+ public:
+ ConcurrentUnifiedHeapMarkingVisitor(ThreadState*,
+ MarkingMode,
+ v8::Isolate*,
+ int task_id);
+ ~ConcurrentUnifiedHeapMarkingVisitor() override = default;
+
+ void FlushWorklists() override;
+
+ protected:
+ using Visitor::Visit;
+ void Visit(const TraceWrapperV8Reference<v8::Value>&) final;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ConcurrentUnifiedHeapMarkingVisitor);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_UNIFIED_HEAP_MARKING_VISITOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.cc b/chromium/third_party/blink/renderer/platform/heap/impl/unsanitized_atomic.cc
index c175fdb0a07..5bd25b96116 100644
--- a/chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/unsanitized_atomic.cc
@@ -2,7 +2,7 @@
// 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/unsanitized_atomic.h"
+#include "third_party/blink/renderer/platform/heap/impl/unsanitized_atomic.h"
#include "cstdint"
diff --git a/chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.h b/chromium/third_party/blink/renderer/platform/heap/impl/unsanitized_atomic.h
index 9242e9263a0..7c6828d9ee1 100644
--- a/chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.h
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/unsanitized_atomic.h
@@ -2,8 +2,8 @@
// 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_UNSANITIZED_ATOMIC_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_UNSANITIZED_ATOMIC_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_UNSANITIZED_ATOMIC_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_UNSANITIZED_ATOMIC_H_
#include <atomic>
@@ -62,4 +62,4 @@ const auto* AsUnsanitizedAtomic(const T* ptr) {
} // namespace internal
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_UNSANITIZED_ATOMIC_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_UNSANITIZED_ATOMIC_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/impl/visitor.h b/chromium/third_party/blink/renderer/platform/heap/impl/visitor.h
new file mode 100644
index 00000000000..434bf882da7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/visitor.h
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_VISITOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_VISITOR_H_
+
+#include <memory>
+#include "third_party/blink/renderer/platform/heap/blink_gc.h"
+#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/assertions.h"
+#include "third_party/blink/renderer/platform/wtf/forward.h"
+#include "third_party/blink/renderer/platform/wtf/hash_traits.h"
+#include "third_party/blink/renderer/platform/wtf/type_traits.h"
+
+namespace base {
+class Location;
+}
+
+namespace v8 {
+class Value;
+}
+
+namespace blink {
+
+class LivenessBroker;
+template <typename T>
+struct TraceTrait;
+class ThreadState;
+class Visitor;
+template <typename T>
+class TraceWrapperV8Reference;
+
+// The TraceMethodDelegate is used to convert a trace method for type T to a
+// TraceCallback. This allows us to pass a type's trace method as a parameter
+// to the PersistentNode constructor. The PersistentNode constructor needs the
+// specific trace method due an issue with the Windows compiler which
+// instantiates even unused variables. This causes problems
+// in header files where we have only forward declarations of classes.
+//
+// This interface is safe to use on concurrent threads. All accesses (reads)
+// from member are done atomically.
+template <typename T, void (T::*method)(Visitor*) const>
+struct TraceMethodDelegate {
+ STATIC_ONLY(TraceMethodDelegate);
+ static void Trampoline(Visitor* visitor, const void* self) {
+ (reinterpret_cast<const T*>(self)->*method)(visitor);
+ }
+};
+
+template <typename T, void (T::*method)(const LivenessBroker&)>
+struct WeakCallbackMethodDelegate {
+ STATIC_ONLY(WeakCallbackMethodDelegate);
+ static void Trampoline(const LivenessBroker& info, const void* self) {
+ (reinterpret_cast<T*>(const_cast<void*>(self))->*method)(info);
+ }
+};
+
+// Visitor is used to traverse Oilpan's object graph.
+class PLATFORM_EXPORT Visitor {
+ USING_FAST_MALLOC(Visitor);
+
+ public:
+ explicit Visitor(ThreadState* state) : state_(state) {}
+ virtual ~Visitor() = default;
+
+ inline ThreadState* State() const { return state_; }
+ inline ThreadHeap& Heap() const { return state_->Heap(); }
+
+ // Static visitor implementation forwarding to dynamic interface.
+
+ template <typename T>
+ void TraceRoot(const T* t, const base::Location& location) {
+ static_assert(sizeof(T), "T must be fully defined");
+ static_assert(IsGarbageCollectedType<T>::value,
+ "T needs to be a garbage collected object");
+ if (!t)
+ return;
+ VisitRoot(t, TraceDescriptorFor(t), location);
+ }
+
+ template <typename T>
+ void Trace(const Member<T>& t) {
+ const T* value = t.GetSafe();
+
+ DCHECK(!Member<T>::IsMemberHashTableDeletedValue(value));
+
+ Trace(value);
+ }
+
+ // TraceStrongly strongifies WeakMembers.
+ template <typename T>
+ ALWAYS_INLINE void TraceStrongly(const WeakMember<T>& t) {
+ const T* value = t.GetSafe();
+
+ DCHECK(!WeakMember<T>::IsMemberHashTableDeletedValue(value));
+
+ Trace<T>(value);
+ }
+ // Fallback methods used only when we need to trace raw pointers of T. This is
+ // the case when a member is a union where we do not support members.
+ template <typename T>
+ void Trace(T* t) {
+ Trace(const_cast<const T*>(t));
+ }
+ template <typename T>
+ void Trace(const T* t) {
+ static_assert(sizeof(T), "T must be fully defined");
+ static_assert(IsGarbageCollectedType<T>::value,
+ "T needs to be a garbage collected object");
+ if (!t)
+ return;
+ Visit(t, TraceDescriptorFor(t));
+ }
+
+ // WeakMember version of the templated trace method. It doesn't keep
+ // the traced thing alive, but will write null to the WeakMember later
+ // if the pointed-to object is dead. It's lying for this to be const,
+ // but the overloading resolver prioritizes constness too high when
+ // picking the correct overload, so all these trace methods have to have
+ // the same constness on their argument to allow the type to decide.
+ template <typename T>
+ void Trace(const WeakMember<T>& weak_member) {
+ static_assert(sizeof(T), "T must be fully defined");
+ static_assert(IsGarbageCollectedType<T>::value,
+ "T needs to be a garbage collected object");
+
+ const T* value = weak_member.GetSafe();
+
+ if (!value)
+ return;
+
+ DCHECK(!WeakMember<T>::IsMemberHashTableDeletedValue(value));
+ VisitWeak(value, &weak_member, TraceDescriptorFor(value),
+ &HandleWeakCell<T>);
+ }
+
+ // Fallback trace method for part objects to allow individual trace methods
+ // to trace through a part object with visitor->trace(m_partObject). This
+ // takes a const argument, because otherwise it will match too eagerly: a
+ // non-const argument would match a non-const Vector<T>& argument better
+ // than the specialization that takes const Vector<T>&. For a similar reason,
+ // the other specializations take a const argument even though they are
+ // usually used with non-const arguments, otherwise this function would match
+ // too well.
+ template <typename T>
+ void Trace(const T& t) {
+ static_assert(sizeof(T), "T must be fully defined");
+ if (std::is_polymorphic<T>::value) {
+ const intptr_t vtable = *reinterpret_cast<const intptr_t*>(&t);
+ if (!vtable)
+ return;
+ }
+ TraceTrait<T>::Trace(this, &t);
+ }
+
+ template <typename T, typename U>
+ void TraceEphemeron(const WeakMember<T>& key, const U* value) {
+ const T* t = key.GetSafe();
+ if (!t)
+ return;
+ VisitEphemeron(TraceDescriptorFor(t).base_object_payload,
+ TraceDescriptorFor(value));
+ }
+
+ template <typename T>
+ void TraceWeakContainer(const T* object,
+ const T* const* slot,
+ TraceDescriptor strong_desc,
+ TraceDescriptor weak_dec,
+ WeakCallback weak_callback,
+ const void* weak_callback_parameter) {
+ static_assert(sizeof(T), "T must be fully defined");
+ static_assert(IsGarbageCollectedType<T>::value,
+ "T needs to be a garbage collected object");
+ VisitWeakContainer(reinterpret_cast<const void*>(object),
+ reinterpret_cast<const void* const*>(slot), strong_desc,
+ weak_dec, weak_callback, weak_callback_parameter);
+ }
+
+ template <typename T>
+ void TraceMovablePointer(const T* const* slot) {
+ RegisterMovableSlot(reinterpret_cast<const void* const*>(slot));
+ }
+
+ // Cross-component tracing interface.
+ template <typename V8Type>
+ void Trace(const TraceWrapperV8Reference<V8Type>& v8reference) {
+ Visit(v8reference.template Cast<v8::Value>());
+ }
+
+ // Dynamic visitor interface.
+
+ // Adds a |callback| that is invoked with |parameter| after liveness has been
+ // computed on the whole object graph. The |callback| may use the provided
+ // |LivenessBroker| to determine whether an object is considered alive or
+ // dead.
+ //
+ // - Upon returning from the callback all references to dead objects must have
+ // been cleared.
+ // - Any operation that extends the object graph, including allocation
+ // or reviving objects, is prohibited.
+ // - Clearing out pointers is allowed.
+ // - Removing elements from heap collections is allowed as these collections
+ // are aware of custom weakness and won't resize their backings.
+ virtual void RegisterWeakCallback(WeakCallback callback,
+ const void* parameter) {}
+
+ // Registers an instance method using |RegisterWeakCallback|. See description
+ // below.
+ template <typename T, void (T::*method)(const LivenessBroker&)>
+ void RegisterWeakCallbackMethod(const T* obj) {
+ RegisterWeakCallback(&WeakCallbackMethodDelegate<T, method>::Trampoline,
+ obj);
+ }
+
+ // Returns whether the visitor is used in a concurrent setting.
+ virtual bool IsConcurrent() const { return false; }
+
+ // Defers invoking |desc| to the main thread when running concurrently.
+ // Returns true if |desc| has been queued for later processing and false if
+ // running in a non-concurrent setting.
+ //
+ // This can be used to defer processing data structures to the main thread
+ // when support for concurrent processing is missing.
+ virtual bool DeferredTraceIfConcurrent(TraceDescriptor, size_t) {
+ return false;
+ }
+
+ protected:
+ // Visits an object through a strong reference.
+ virtual void Visit(const void*, TraceDescriptor) {}
+
+ // Visits an object through a weak reference.
+ virtual void VisitWeak(const void*,
+ const void*,
+ TraceDescriptor,
+ WeakCallback) {}
+
+ // Visits cross-component references to V8.
+ virtual void Visit(const TraceWrapperV8Reference<v8::Value>&) {}
+
+ virtual void VisitRoot(const void* t,
+ TraceDescriptor desc,
+ const base::Location&) {
+ Visit(t, desc);
+ }
+
+ // Visits ephemeron pairs which are a combination of weak and strong keys and
+ // values.
+ virtual void VisitEphemeron(const void*, TraceDescriptor) {}
+
+ // Visits a container |object| holding ephemeron pairs held from |slot|. The
+ // descriptor |strong_desc| can be used to enforce strong treatment of
+ // |object|. The |weak_desc| descriptor is invoked repeatedly until no
+ // more new objects are found. It is expected that |weak_desc| processing
+ // ultimately yields in a call to VisitEphemeron. After marking all reachable
+ // objects, |weak_callback| is invoked with |weak_callback_parameter|. It is
+ // expected that this callback is used to reset non-live entries in the
+ // ephemeron container.
+ virtual void VisitWeakContainer(const void* object,
+ const void* const* slot,
+ TraceDescriptor strong_desc,
+ TraceDescriptor weak_desc,
+ WeakCallback weak_callback,
+ const void* weak_callback_parameter) {}
+
+ virtual void RegisterMovableSlot(const void* const* slot) {}
+
+ template <typename T>
+ static TraceDescriptor TraceDescriptorFor(const T* traceable) {
+ return TraceTrait<T>::GetTraceDescriptor(traceable);
+ }
+
+ private:
+ template <typename T>
+ static void HandleWeakCell(const LivenessBroker&, const void*);
+
+ ThreadState* const state_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_VISITOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/worklist.h b/chromium/third_party/blink/renderer/platform/heap/impl/worklist.h
index 6bce8f5808a..a26c61892f6 100644
--- a/chromium/third_party/blink/renderer/platform/heap/worklist.h
+++ b/chromium/third_party/blink/renderer/platform/heap/impl/worklist.h
@@ -8,8 +8,8 @@
// 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_WORKLIST_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_WORKLIST_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_WORKLIST_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_WORKLIST_H_
#include <atomic>
#include <cstddef>
@@ -466,4 +466,4 @@ class Worklist {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_WORKLIST_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_WORKLIST_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/member.h b/chromium/third_party/blink/renderer/platform/heap/member.h
index 6567c77f010..4dbf5fd1c44 100644
--- a/chromium/third_party/blink/renderer/platform/heap/member.h
+++ b/chromium/third_party/blink/renderer/platform/heap/member.h
@@ -1,558 +1,16 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
+// 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_MEMBER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_MEMBER_H_
-#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-#include "third_party/blink/renderer/platform/heap/heap_page.h"
-#include "third_party/blink/renderer/platform/heap/marking_visitor.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/hash_functions.h"
-#include "third_party/blink/renderer/platform/wtf/hash_traits.h"
-namespace WTF {
-template <typename P, typename Traits, typename Allocator>
-class MemberConstructTraits;
-} // namespace WTF
-
-namespace blink {
-
-template <typename T>
-class Persistent;
-
-enum class TracenessMemberConfiguration {
- kTraced,
- kUntraced,
-};
-
-template <typename T,
- TracenessMemberConfiguration tracenessConfiguration =
- TracenessMemberConfiguration::kTraced>
-class MemberPointerVerifier {
- public:
- MemberPointerVerifier() = default;
-
- void SaveCreationThreadState(T* pointer) {
- if (tracenessConfiguration == TracenessMemberConfiguration::kUntraced) {
- creation_thread_state_ = nullptr;
- } else {
- creation_thread_state_ = ThreadState::Current();
- // Members should be created in an attached thread. But an empty
- // value Member may be created on an unattached thread by a heap
- // collection iterator.
- DCHECK(creation_thread_state_ || !pointer);
- }
- }
-
- void CheckPointer(T* pointer) {
- if (!pointer)
- return;
-
- ThreadState* current = ThreadState::Current();
- DCHECK(current);
- if (tracenessConfiguration != TracenessMemberConfiguration::kUntraced) {
- // creation_thread_state_ may be null when this is used in a heap
- // collection which initialized the Member with memset and the
- // constructor wasn't called.
- if (creation_thread_state_) {
- // Member should point to objects that belong in the same ThreadHeap.
- DCHECK(creation_thread_state_->IsOnThreadHeap(pointer));
- // Member should point to objects that belong in the same ThreadHeap.
- DCHECK_EQ(&current->Heap(), &creation_thread_state_->Heap());
- } else {
- DCHECK(current->IsOnThreadHeap(pointer));
- }
- }
-
- if (current->IsSweepingInProgress()) {
- // During sweeping the object start bitmap is invalid. Check the header
- // when the type is available and not pointing to a mixin.
- if (IsFullyDefined<T>::value && !IsGarbageCollectedMixin<T>::value)
- HeapObjectHeader::CheckFromPayload(pointer);
- } else {
- DCHECK(HeapObjectHeader::FromInnerAddress<
- HeapObjectHeader::AccessMode::kAtomic>(pointer));
- }
- }
-
- private:
- const ThreadState* creation_thread_state_;
-};
-
-template <typename T,
- TracenessMemberConfiguration tracenessConfiguration =
- TracenessMemberConfiguration::kTraced>
-class MemberBase {
- DISALLOW_NEW();
-
- public:
- MemberBase() : raw_(nullptr) { SaveCreationThreadState(); }
-
- MemberBase(std::nullptr_t) : raw_(nullptr) { SaveCreationThreadState(); }
-
- explicit MemberBase(T* raw) : raw_(raw) {
- SaveCreationThreadState();
- CheckPointer();
- // No write barrier for initializing stores.
- }
-
- explicit MemberBase(T& raw) : raw_(&raw) {
- SaveCreationThreadState();
- CheckPointer();
- // No write barrier for initializing stores.
- }
-
- MemberBase(WTF::HashTableDeletedValueType)
- : raw_(reinterpret_cast<T*>(kHashTableDeletedRawValue)) {
- SaveCreationThreadState();
- }
-
- MemberBase(const MemberBase& other) : raw_(other) {
- SaveCreationThreadState();
- CheckPointer();
- // No write barrier for initializing stores.
- }
-
- template <typename U>
- MemberBase(const Persistent<U>& other) : raw_(other) {
- SaveCreationThreadState();
- CheckPointer();
- // No write barrier for initializing stores.
- }
-
- template <typename U>
- MemberBase(const MemberBase<U>& other) : raw_(other) {
- SaveCreationThreadState();
- CheckPointer();
- // No write barrier for initializing stores.
- }
-
- template <typename U>
- MemberBase& operator=(const Persistent<U>& other) {
- SetRaw(other);
- CheckPointer();
- WriteBarrier();
- return *this;
- }
-
- MemberBase& operator=(const MemberBase& other) {
- SetRaw(other);
- CheckPointer();
- WriteBarrier();
- return *this;
- }
-
- template <typename U>
- MemberBase& operator=(const MemberBase<U>& other) {
- SetRaw(other);
- CheckPointer();
- WriteBarrier();
- return *this;
- }
-
- template <typename U>
- MemberBase& operator=(U* other) {
- SetRaw(other);
- CheckPointer();
- WriteBarrier();
- return *this;
- }
-
- MemberBase& operator=(WTF::HashTableDeletedValueType) {
- SetRaw(reinterpret_cast<T*>(-1));
- return *this;
- }
-
- MemberBase& operator=(std::nullptr_t) {
- SetRaw(nullptr);
- return *this;
- }
-
- void Swap(MemberBase<T>& other) {
- T* tmp = GetRaw();
- SetRaw(other.GetRaw());
- other.SetRaw(tmp);
- CheckPointer();
- WriteBarrier();
- other.WriteBarrier();
- }
-
- explicit operator bool() const { return GetRaw(); }
- operator T*() const { return GetRaw(); }
- T* operator->() const { return GetRaw(); }
- T& operator*() const { return *GetRaw(); }
-
- T* Get() const { return GetRaw(); }
-
- void Clear() { SetRaw(nullptr); }
-
- T* Release() {
- T* result = GetRaw();
- SetRaw(nullptr);
- return result;
- }
-
- static bool IsMemberHashTableDeletedValue(const T* t) {
- return t == reinterpret_cast<T*>(kHashTableDeletedRawValue);
- }
-
- bool IsHashTableDeletedValue() const {
- return IsMemberHashTableDeletedValue(GetRaw());
- }
-
- protected:
- static constexpr intptr_t kHashTableDeletedRawValue = -1;
-
- enum class AtomicCtorTag { Atomic };
-
- // MemberBase ctors that use atomic write to set raw_.
-
- MemberBase(AtomicCtorTag, T* raw) {
- SetRaw(raw);
- SaveCreationThreadState();
- CheckPointer();
- // No write barrier for initializing stores.
- }
-
- MemberBase(AtomicCtorTag, T& raw) {
- SetRaw(&raw);
- SaveCreationThreadState();
- CheckPointer();
- // No write barrier for initializing stores.
- }
-
- void WriteBarrier() const {
- MarkingVisitor::WriteBarrier(const_cast<std::remove_const_t<T>**>(&raw_));
- }
-
- void CheckPointer() {
-#if DCHECK_IS_ON()
- // Should not be called for deleted hash table values. A value can be
- // propagated here if a MemberBase containing the deleted value is copied.
- if (IsHashTableDeletedValue())
- return;
- pointer_verifier_.CheckPointer(GetRaw());
-#endif // DCHECK_IS_ON()
- }
-
- void SaveCreationThreadState() {
-#if DCHECK_IS_ON()
- pointer_verifier_.SaveCreationThreadState(GetRaw());
-#endif // DCHECK_IS_ON()
- }
-
- ALWAYS_INLINE void SetRaw(T* raw) {
- if (tracenessConfiguration == TracenessMemberConfiguration::kUntraced)
- raw_ = raw;
- else
- WTF::AsAtomicPtr(&raw_)->store(raw, std::memory_order_relaxed);
- }
- ALWAYS_INLINE T* GetRaw() const { return raw_; }
-
- private:
- // Thread safe version of Get() for marking visitors.
- // This is used to prevent data races between concurrent marking visitors
- // and writes on the main thread.
- const T* GetSafe() const {
- // TOOD(omerkatz): replace this cast with std::atomic_ref (C++20) once it
- // becomes available
- return WTF::AsAtomicPtr(&raw_)->load(std::memory_order_relaxed);
- }
-
- T* raw_;
-#if DCHECK_IS_ON()
- MemberPointerVerifier<T, tracenessConfiguration> pointer_verifier_;
-#endif // DCHECK_IS_ON()
-
- friend class Visitor;
-};
-
-// Members are used in classes to contain strong pointers to other oilpan heap
-// allocated objects.
-// All Member fields of a class must be traced in the class' trace method.
-// During the mark phase of the GC all live objects are marked as live and
-// all Member fields of a live object will be traced marked as live as well.
-template <typename T>
-class Member : public MemberBase<T, TracenessMemberConfiguration::kTraced> {
- DISALLOW_NEW();
- typedef MemberBase<T, TracenessMemberConfiguration::kTraced> Parent;
-
- public:
- Member() : Parent() {}
- Member(std::nullptr_t) : Parent(nullptr) {}
- Member(T* raw) : Parent(raw) {}
- Member(T& raw) : Parent(raw) {}
- Member(WTF::HashTableDeletedValueType x) : Parent(x) {}
-
- Member(const Member& other) : Parent(other) {}
-
- template <typename U>
- Member(const Member<U>& other) : Parent(other) {
- }
-
- template <typename U>
- Member(const Persistent<U>& other) : Parent(other) {}
-
- template <typename U>
- Member& operator=(const Persistent<U>& other) {
- Parent::operator=(other);
- return *this;
- }
-
- Member& operator=(const Member& other) {
- Parent::operator=(other);
- return *this;
- }
-
- template <typename U>
- Member& operator=(const Member<U>& other) {
- Parent::operator=(other);
- return *this;
- }
-
- template <typename U>
- Member& operator=(const WeakMember<U>& other) {
- Parent::operator=(other);
- return *this;
- }
-
- template <typename U>
- Member& operator=(U* other) {
- Parent::operator=(other);
- return *this;
- }
-
- Member& operator=(WTF::HashTableDeletedValueType x) {
- Parent::operator=(x);
- return *this;
- }
-
- Member& operator=(std::nullptr_t) {
- Parent::operator=(nullptr);
- return *this;
- }
-
- private:
- using typename Parent::AtomicCtorTag;
- Member(AtomicCtorTag atomic, T* raw) : Parent(atomic, raw) {}
- Member(AtomicCtorTag atomic, T& raw) : Parent(atomic, raw) {}
-
- template <typename P, typename Traits, typename Allocator>
- friend class WTF::MemberConstructTraits;
-};
-
-// WeakMember is similar to Member in that it is used to point to other oilpan
-// heap allocated objects.
-// However instead of creating a strong pointer to the object, the WeakMember
-// creates a weak pointer, which does not keep the pointee alive. Hence if all
-// pointers to to a heap allocated object are weak the object will be garbage
-// collected. At the time of GC the weak pointers will automatically be set to
-// null.
-template <typename T>
-class WeakMember : public MemberBase<T, TracenessMemberConfiguration::kTraced> {
- typedef MemberBase<T, TracenessMemberConfiguration::kTraced> Parent;
-
- public:
- WeakMember() : Parent() {}
-
- WeakMember(std::nullptr_t) : Parent(nullptr) {}
-
- WeakMember(T* raw) : Parent(raw) {}
-
- WeakMember(WTF::HashTableDeletedValueType x) : Parent(x) {}
-
- template <typename U>
- WeakMember(const Persistent<U>& other) : Parent(other) {}
-
- template <typename U>
- WeakMember(const Member<U>& other) : Parent(other) {}
-
- template <typename U>
- WeakMember& operator=(const Persistent<U>& other) {
- Parent::operator=(other);
- return *this;
- }
-
- template <typename U>
- WeakMember& operator=(const Member<U>& other) {
- Parent::operator=(other);
- return *this;
- }
-
- template <typename U>
- WeakMember& operator=(U* other) {
- Parent::operator=(other);
- return *this;
- }
-
- WeakMember& operator=(std::nullptr_t) {
- this->SetRaw(nullptr);
- return *this;
- }
-
- private:
- using typename Parent::AtomicCtorTag;
- WeakMember(AtomicCtorTag atomic, T* raw) : Parent(atomic, raw) {}
- WeakMember(AtomicCtorTag atomic, T& raw) : Parent(atomic, raw) {}
-
- template <typename P, typename Traits, typename Allocator>
- friend class WTF::MemberConstructTraits;
-};
-
-// UntracedMember is a pointer to an on-heap object that is not traced for some
-// reason. Please don't use this unless you understand what you're doing.
-// Basically, all pointers to on-heap objects must be stored in either of
-// Persistent, Member or WeakMember. It is not allowed to leave raw pointers to
-// on-heap objects. However, there can be scenarios where you have to use raw
-// pointers for some reason, and in that case you can use UntracedMember. Of
-// course, it must be guaranteed that the pointing on-heap object is kept alive
-// while the raw pointer is pointing to the object.
-template <typename T>
-class UntracedMember final
- : public MemberBase<T, TracenessMemberConfiguration::kUntraced> {
- typedef MemberBase<T, TracenessMemberConfiguration::kUntraced> Parent;
-
- public:
- UntracedMember() : Parent() {}
-
- UntracedMember(std::nullptr_t) : Parent(nullptr) {}
-
- UntracedMember(T* raw) : Parent(raw) {}
-
- template <typename U>
- UntracedMember(const Persistent<U>& other) : Parent(other) {}
-
- template <typename U>
- UntracedMember(const Member<U>& other) : Parent(other) {}
-
- UntracedMember(WTF::HashTableDeletedValueType x) : Parent(x) {}
-
- UntracedMember& operator=(const UntracedMember& other) {
- this->SetRaw(other);
- this->CheckPointer();
- return *this;
- }
-
- template <typename U>
- UntracedMember& operator=(const Persistent<U>& other) {
- this->SetRaw(other);
- this->CheckPointer();
- return *this;
- }
-
- template <typename U>
- UntracedMember& operator=(const Member<U>& other) {
- this->SetRaw(other);
- this->CheckPointer();
- return *this;
- }
-
- template <typename U>
- UntracedMember& operator=(U* other) {
- this->SetRaw(other);
- this->CheckPointer();
- return *this;
- }
-
- UntracedMember& operator=(std::nullptr_t) {
- this->SetRaw(nullptr);
- return *this;
- }
-};
-
-} // namespace blink
-
-namespace WTF {
-
-// PtrHash is the default hash for hash tables with Member<>-derived elements.
-template <typename T>
-struct MemberHash : PtrHash<T> {
- STATIC_ONLY(MemberHash);
- template <typename U>
- static unsigned GetHash(const U& key) {
- return PtrHash<T>::GetHash(key);
- }
- template <typename U, typename V>
- static bool Equal(const U& a, const V& b) {
- return a == b;
- }
-};
-
-template <typename T>
-struct DefaultHash<blink::Member<T>> {
- STATIC_ONLY(DefaultHash);
- using Hash = MemberHash<T>;
-};
-
-template <typename T>
-struct DefaultHash<blink::WeakMember<T>> {
- STATIC_ONLY(DefaultHash);
- using Hash = MemberHash<T>;
-};
-
-template <typename T>
-struct DefaultHash<blink::UntracedMember<T>> {
- STATIC_ONLY(DefaultHash);
- using Hash = MemberHash<T>;
-};
-
-template <typename T>
-struct IsTraceable<blink::Member<T>> {
- STATIC_ONLY(IsTraceable);
- static const bool value = true;
-};
-
-template <typename T>
-struct IsWeak<blink::WeakMember<T>> : std::true_type {};
-
-template <typename T>
-struct IsTraceable<blink::WeakMember<T>> {
- STATIC_ONLY(IsTraceable);
- static const bool value = true;
-};
-
-template <typename T, typename Traits, typename Allocator>
-class MemberConstructTraits {
- STATIC_ONLY(MemberConstructTraits);
-
- public:
- template <typename... Args>
- static T* Construct(void* location, Args&&... args) {
- return new (NotNull, location) T(std::forward<Args>(args)...);
- }
-
- static void NotifyNewElement(T* element) { element->WriteBarrier(); }
-
- template <typename... Args>
- static T* ConstructAndNotifyElement(void* location, Args&&... args) {
- // ConstructAndNotifyElement updates an existing Member which might
- // also be comncurrently traced while we update it. The regular ctors
- // for Member don't use an atomic write which can lead to data races.
- T* object = Construct(location, T::AtomicCtorTag::Atomic,
- std::forward<Args>(args)...);
- NotifyNewElement(object);
- return object;
- }
-
- static void NotifyNewElements(T* array, size_t len) {
- while (len-- > 0) {
- array->WriteBarrier();
- array++;
- }
- }
-};
-
-template <typename T, typename Traits, typename Allocator>
-class ConstructTraits<blink::Member<T>, Traits, Allocator>
- : public MemberConstructTraits<blink::Member<T>, Traits, Allocator> {};
-
-template <typename T, typename Traits, typename Allocator>
-class ConstructTraits<blink::WeakMember<T>, Traits, Allocator>
- : public MemberConstructTraits<blink::WeakMember<T>, Traits, Allocator> {};
-
-} // namespace WTF
+#if BUILDFLAG(BLINK_HEAP_USE_V8_OILPAN)
+#include "third_party/blink/renderer/platform/heap/v8_wrapper/member.h"
+#else // !BLINK_HEAP_USE_V8_OILPAN
+#include "third_party/blink/renderer/platform/heap/impl/member.h"
+#endif // !BLINK_HEAP_USE_V8_OILPAN
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_MEMBER_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/persistent.h b/chromium/third_party/blink/renderer/platform/heap/persistent.h
index 32cadc008bf..77fd0d5cc7b 100644
--- a/chromium/third_party/blink/renderer/platform/heap/persistent.h
+++ b/chromium/third_party/blink/renderer/platform/heap/persistent.h
@@ -1,971 +1,16 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
+// 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_PERSISTENT_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PERSISTENT_H_
-#include "base/bind.h"
-#include "base/location.h"
-#include "third_party/blink/renderer/platform/bindings/buildflags.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
-#include "third_party/blink/renderer/platform/heap/heap_compact.h"
-#include "third_party/blink/renderer/platform/heap/member.h"
-#include "third_party/blink/renderer/platform/heap/persistent_node.h"
-#include "third_party/blink/renderer/platform/heap/visitor.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h"
+#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-namespace blink {
-
-template <typename T>
-class CrossThreadWeakPersistent;
-
-// Wrapping type to force callers to go through macros that expand or drop
-// base::Location. This is needed to avoid adding the strings when not needed.
-// The type can be dropped once http://crbug.com/760702 is resolved and
-// ENABLE_LOCATION_SOURCE is disabled for release builds.
-class PersistentLocation final {
- public:
- PersistentLocation() = default;
- explicit PersistentLocation(const base::Location& location)
- : location_(location) {}
- PersistentLocation(const PersistentLocation& other) = default;
-
- const base::Location& get() const { return location_; }
-
- private:
- base::Location location_;
-};
-
-#if !BUILDFLAG(FROM_HERE_USES_LOCATION_BUILTINS) && \
- BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-#if !BUILDFLAG(ENABLE_LOCATION_SOURCE)
-#define PERSISTENT_FROM_HERE \
- PersistentLocation(::base::Location::CreateFromHere(__FILE__))
-#else
-#define PERSISTENT_FROM_HERE \
- PersistentLocation( \
- ::base::Location::CreateFromHere(__func__, __FILE__, __LINE__))
-#endif
-#else
-#define PERSISTENT_FROM_HERE PersistentLocation()
-#endif // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-
-template <typename T,
- WeaknessPersistentConfiguration weaknessConfiguration,
- CrossThreadnessPersistentConfiguration crossThreadnessConfiguration>
-class PersistentBase {
- USING_FAST_MALLOC(PersistentBase);
-
- public:
- bool IsHashTableDeletedValue() const {
- return raw_ == reinterpret_cast<T*>(-1);
- }
-
- T* Release() {
- T* result = raw_;
- AssignSafe(nullptr);
- return result;
- }
-
- void Clear() {
- // Note that this also frees up related data in the backend.
- AssignSafe(nullptr);
- }
-
- T* Get() const {
- CheckPointer();
- return raw_;
- }
-
- // TODO(https://crbug.com/653394): Consider returning a thread-safe best
- // guess of validity.
- bool MaybeValid() const { return true; }
-
- explicit operator bool() const { return Get(); }
- T& operator*() const { return *Get(); }
- operator T*() const { return Get(); }
- T* operator->() const { return Get(); }
-
- // Register the persistent node as a 'static reference',
- // belonging to the current thread and a persistent that must
- // be cleared when the ThreadState itself is cleared out and
- // destructed.
- //
- // Static singletons arrange for this to happen, either to ensure
- // clean LSan leak reports or to register a thread-local persistent
- // needing to be cleared out before the thread is terminated.
- PersistentBase* RegisterAsStaticReference() {
- static_assert(weaknessConfiguration == kNonWeakPersistentConfiguration,
- "Can only register non-weak Persistent references as static "
- "references.");
- if (PersistentNode* node = persistent_node_.Get()) {
- ThreadState::Current()->RegisterStaticPersistentNode(node);
- LEAK_SANITIZER_IGNORE_OBJECT(this);
- }
- return this;
- }
-
- NO_SANITIZE_ADDRESS
- void ClearWithLockHeld() {
- static_assert(
- crossThreadnessConfiguration == kCrossThreadPersistentConfiguration,
- "This Persistent does not require the cross-thread lock.");
- PersistentMutexTraits<crossThreadnessConfiguration>::AssertAcquired();
- raw_ = nullptr;
- persistent_node_.ClearWithLockHeld();
- }
-
- void UpdateLocation(const PersistentLocation& other) {
-#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
- location_ = other;
-#endif // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
- }
-
- protected:
- ~PersistentBase() {
- UninitializeSafe();
- // Not resetting raw_ as it is not observable.
- }
-
- PersistentBase() : raw_(nullptr) {
- SaveCreationThreadHeap();
- // No initialization needed for empty handle.
- }
- PersistentBase(const PersistentLocation& location) : PersistentBase() {
- UpdateLocation(location);
- }
-
- PersistentBase(std::nullptr_t) : raw_(nullptr) {
- SaveCreationThreadHeap();
- // No initialization needed for empty handle.
- }
- PersistentBase(const PersistentLocation& location, std::nullptr_t)
- : PersistentBase(nullptr) {
- UpdateLocation(location);
- }
-
- PersistentBase(T* raw) : raw_(raw) {
- SaveCreationThreadHeap();
- InitializeSafe();
- CheckPointer();
- }
- PersistentBase(const PersistentLocation& location, T* raw)
- : PersistentBase(raw) {
- UpdateLocation(location);
- }
-
- PersistentBase(T& raw) : raw_(&raw) {
- SaveCreationThreadHeap();
- InitializeSafe();
- CheckPointer();
- }
- PersistentBase(const PersistentLocation& location, T& raw)
- : PersistentBase(raw) {
- UpdateLocation(location);
- }
-
- PersistentBase(const PersistentBase& other) : raw_(other) {
- SaveCreationThreadHeap();
- InitializeSafe();
- CheckPointer();
- }
- PersistentBase(const PersistentLocation& location, PersistentBase& other)
- : PersistentBase(other) {
- UpdateLocation(location);
- }
-
- template <typename U>
- PersistentBase(const PersistentBase<U,
- weaknessConfiguration,
- crossThreadnessConfiguration>& other)
- : raw_(other) {
- SaveCreationThreadHeap();
- InitializeSafe();
- CheckPointer();
- }
- template <typename U>
- PersistentBase(const PersistentLocation& location,
- const PersistentBase<U,
- weaknessConfiguration,
- crossThreadnessConfiguration>& other)
- : PersistentBase(other) {
- UpdateLocation(location);
- }
-
- template <typename U>
- PersistentBase(const Member<U>& other) : raw_(other) {
- SaveCreationThreadHeap();
- InitializeSafe();
- CheckPointer();
- }
- template <typename U>
- PersistentBase(const PersistentLocation& location, const Member<U>& other)
- : PersistentBase(other) {
- UpdateLocation(location);
- }
-
- PersistentBase(WTF::HashTableDeletedValueType)
- : raw_(reinterpret_cast<T*>(-1)) {
- SaveCreationThreadHeap();
- // No initialization needed for empty handle.
- }
- PersistentBase(const PersistentLocation& location,
- WTF::HashTableDeletedValueType)
- : PersistentBase(WTF::kHashTableDeletedValue) {
- UpdateLocation(location);
- }
-
- template <typename U>
- PersistentBase& operator=(U* other) {
- AssignSafe(other);
- return *this;
- }
-
- PersistentBase& operator=(std::nullptr_t) {
- AssignSafe(nullptr);
- return *this;
- }
-
- template <typename U>
- PersistentBase& operator=(const Member<U>& other) {
- AssignSafe(other);
- return *this;
- }
-
- // Using unsafe operations and assuming that caller acquires the lock for
- // kCrossThreadPersistentConfiguration configuration.
- PersistentBase& operator=(const PersistentBase& other) {
- PersistentMutexTraits<crossThreadnessConfiguration>::AssertAcquired();
- AssignUnsafe(other);
- return *this;
- }
-
- // Using unsafe operations and assuming that caller acquires the lock for
- // kCrossThreadPersistentConfiguration configuration.
- template <typename U>
- PersistentBase& operator=(
- const PersistentBase<U,
- weaknessConfiguration,
- crossThreadnessConfiguration>& other) {
- PersistentMutexTraits<crossThreadnessConfiguration>::AssertAcquired();
- AssignUnsafe(other);
- return *this;
- }
-
- // Using unsafe operations and assuming that caller acquires the lock for
- // kCrossThreadPersistentConfiguration configuration.
- template <typename U>
- PersistentBase& operator=(
- PersistentBase<U, weaknessConfiguration, crossThreadnessConfiguration>&&
- other) {
- PersistentMutexTraits<crossThreadnessConfiguration>::AssertAcquired();
- if (persistent_node_.IsInitialized()) {
- // Drop persistent node if present as it's always possible to reuse the
- // node (if present) from |other|.
- persistent_node_.Uninitialize();
- }
- // Explicit cast enabling downcasting.
- raw_ = static_cast<T*>(other.raw_);
- other.raw_ = nullptr;
- // Efficiently move by just rewiring the node pointer.
- persistent_node_ = std::move(other.persistent_node_);
- DCHECK(!other.persistent_node_.Get());
- if (persistent_node_.IsInitialized()) {
- // If |raw_| points to a non-null or deleted value, just reuse the node.
- TraceCallback trace_callback =
- TraceMethodDelegate<PersistentBase,
- &PersistentBase::TracePersistent>::Trampoline;
- persistent_node_.Get()->Reinitialize(this, trace_callback);
- }
- CheckPointer();
- return *this;
- }
-
- NO_SANITIZE_ADDRESS
- bool IsNotNull() const { return raw_; }
-
- NO_SANITIZE_ADDRESS
- void AssignSafe(T* ptr) {
- typename PersistentMutexTraits<crossThreadnessConfiguration>::Locker lock;
- AssignUnsafe(ptr);
- }
-
- NO_SANITIZE_ADDRESS
- void AssignUnsafe(T* ptr) {
- raw_ = ptr;
- CheckPointer();
- if (raw_ && !IsHashTableDeletedValue()) {
- if (!persistent_node_.IsInitialized())
- InitializeUnsafe();
- return;
- }
- UninitializeUnsafe();
- }
-
- void TracePersistent(Visitor* visitor) const {
- static_assert(sizeof(T), "T must be fully defined");
- static_assert(IsGarbageCollectedType<T>::value,
- "T needs to be a garbage collected object");
- DCHECK(!IsHashTableDeletedValue());
- if (weaknessConfiguration == kWeakPersistentConfiguration) {
- visitor->RegisterWeakCallback(HandleWeakPersistent, this);
- } else {
-#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
- visitor->TraceRoot(raw_, location_.get());
-#else
- visitor->TraceRoot(raw_, base::Location());
-#endif // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
- }
- }
-
- NO_SANITIZE_ADDRESS
- void InitializeSafe() {
- DCHECK(!persistent_node_.IsInitialized());
- if (!raw_ || IsHashTableDeletedValue())
- return;
-
- TraceCallback trace_callback =
- TraceMethodDelegate<PersistentBase,
- &PersistentBase::TracePersistent>::Trampoline;
- typename PersistentMutexTraits<crossThreadnessConfiguration>::Locker lock;
- persistent_node_.Initialize(this, trace_callback);
- }
-
- NO_SANITIZE_ADDRESS
- void InitializeUnsafe() {
- DCHECK(!persistent_node_.IsInitialized());
- if (!raw_ || IsHashTableDeletedValue())
- return;
-
- TraceCallback trace_callback =
- TraceMethodDelegate<PersistentBase,
- &PersistentBase::TracePersistent>::Trampoline;
- persistent_node_.Initialize(this, trace_callback);
- }
-
- void UninitializeSafe() {
- if (persistent_node_.IsInitialized()) {
- typename PersistentMutexTraits<crossThreadnessConfiguration>::Locker lock;
- persistent_node_.Uninitialize();
- }
- }
-
- void UninitializeUnsafe() {
- if (persistent_node_.IsInitialized())
- persistent_node_.Uninitialize();
- }
-
- void CheckPointer() const {
-#if DCHECK_IS_ON()
- if (!raw_ || IsHashTableDeletedValue())
- return;
-
- if (crossThreadnessConfiguration != kCrossThreadPersistentConfiguration) {
- ThreadState* current = ThreadState::Current();
- DCHECK(current);
- // m_creationThreadState may be null when this is used in a heap
- // collection which initialized the Persistent with memset and the
- // constructor wasn't called.
- if (creation_thread_state_) {
- // Member should point to objects that belong in the same ThreadHeap.
- DCHECK_EQ(&ThreadState::FromObject(raw_)->Heap(),
- &creation_thread_state_->Heap());
- // Member should point to objects that belong in the same ThreadHeap.
- DCHECK_EQ(&current->Heap(), &creation_thread_state_->Heap());
- }
- }
-#endif
- }
-
- void SaveCreationThreadHeap() {
-#if DCHECK_IS_ON()
- if (crossThreadnessConfiguration == kCrossThreadPersistentConfiguration) {
- creation_thread_state_ = nullptr;
- } else {
- creation_thread_state_ = ThreadState::Current();
- DCHECK(creation_thread_state_);
- }
-#endif
- }
-
- static void HandleWeakPersistent(const LivenessBroker& broker,
- const void* persistent_pointer) {
- using Base =
- PersistentBase<typename std::remove_const<T>::type,
- weaknessConfiguration, crossThreadnessConfiguration>;
- Base* persistent =
- reinterpret_cast<Base*>(const_cast<void*>(persistent_pointer));
- T* object = persistent->Get();
- if (object && !broker.IsHeapObjectAlive(object))
- ClearWeakPersistent(persistent);
- }
-
- static void ClearWeakPersistent(
- PersistentBase<std::remove_const_t<T>,
- kWeakPersistentConfiguration,
- kCrossThreadPersistentConfiguration>* persistent) {
- PersistentMutexTraits<crossThreadnessConfiguration>::AssertAcquired();
- persistent->ClearWithLockHeld();
- }
-
- static void ClearWeakPersistent(
- PersistentBase<std::remove_const_t<T>,
- kWeakPersistentConfiguration,
- kSingleThreadPersistentConfiguration>* persistent) {
- persistent->Clear();
- }
-
- template <typename BadPersistent>
- static void ClearWeakPersistent(BadPersistent* non_weak_persistent) {
- NOTREACHED();
- }
-
- // raw_ is accessed most, so put it at the first field.
- T* raw_;
-
- // The pointer to the underlying persistent node.
- //
- // Since accesses are atomics in the cross-thread case, a different type is
- // needed to prevent the compiler producing an error when it encounters
- // operations that are legal on raw pointers but not on atomics, or
- // vice-versa.
- std::conditional_t<
- crossThreadnessConfiguration == kCrossThreadPersistentConfiguration,
- CrossThreadPersistentNodePtr<weaknessConfiguration>,
- PersistentNodePtr<ThreadingTrait<T>::kAffinity, weaknessConfiguration>>
- persistent_node_;
-
-#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
- PersistentLocation location_;
-#endif // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-
-#if DCHECK_IS_ON()
- const ThreadState* creation_thread_state_;
-#endif
-
- template <typename F,
- WeaknessPersistentConfiguration,
- CrossThreadnessPersistentConfiguration>
- friend class PersistentBase;
-};
-
-// Persistent is a way to create a strong pointer from an off-heap object
-// to another on-heap object. As long as the Persistent handle is alive
-// the GC will keep the object pointed to alive. The Persistent handle is
-// always a GC root from the point of view of the GC.
-//
-// We have to construct and destruct Persistent in the same thread.
-template <typename T>
-class Persistent : public PersistentBase<T,
- kNonWeakPersistentConfiguration,
- kSingleThreadPersistentConfiguration> {
- using Parent = PersistentBase<T,
- kNonWeakPersistentConfiguration,
- kSingleThreadPersistentConfiguration>;
-
- public:
- Persistent() : Parent() {}
- Persistent(const PersistentLocation& location) : Parent(location) {}
- Persistent(std::nullptr_t) : Parent(nullptr) {}
- Persistent(const PersistentLocation& location, std::nullptr_t)
- : Parent(location, nullptr) {}
- Persistent(T* raw) : Parent(raw) {}
- Persistent(const PersistentLocation& location, T* raw)
- : Parent(location, raw) {}
- Persistent(T& raw) : Parent(raw) {}
- Persistent(const PersistentLocation& location, T& raw)
- : Parent(location, raw) {}
- Persistent(const Persistent& other) : Parent(other) {}
- Persistent(const PersistentLocation& location, const Persistent& other)
- : Parent(location, other) {}
- template <typename U>
- Persistent(const Persistent<U>& other) : Parent(other) {}
- template <typename U>
- Persistent(const PersistentLocation& location, const Persistent<U>& other)
- : Parent(location, other) {}
- template <typename U>
- Persistent(const Member<U>& other) : Parent(other) {}
- template <typename U>
- Persistent(const PersistentLocation& location, const Member<U>& other)
- : Parent(location, other) {}
- Persistent(WTF::HashTableDeletedValueType x) : Parent(x) {}
- Persistent(const PersistentLocation& location,
- WTF::HashTableDeletedValueType x)
- : Parent(location, x) {}
-
- template <typename U>
- Persistent& operator=(U* other) {
- Parent::operator=(other);
- return *this;
- }
-
- Persistent& operator=(std::nullptr_t) {
- Parent::operator=(nullptr);
- return *this;
- }
-
- Persistent& operator=(const Persistent& other) {
- Parent::operator=(other);
- return *this;
- }
-
- template <typename U>
- Persistent& operator=(const Persistent<U>& other) {
- Parent::operator=(other);
- return *this;
- }
-
- template <typename U>
- Persistent& operator=(const Member<U>& other) {
- Parent::operator=(other);
- return *this;
- }
-};
-
-// WeakPersistent is a way to create a weak pointer from an off-heap object
-// to an on-heap object. The m_raw is automatically cleared when the pointee
-// gets collected.
-//
-// We have to construct and destruct WeakPersistent in the same thread.
-//
-// Note that collections of WeakPersistents are not supported. Use a collection
-// of WeakMembers instead.
-//
-// HashSet<WeakPersistent<T>> m_set; // wrong
-// Persistent<HeapHashSet<WeakMember<T>>> m_set; // correct
-template <typename T>
-class WeakPersistent
- : public PersistentBase<T,
- kWeakPersistentConfiguration,
- kSingleThreadPersistentConfiguration> {
- using Parent = PersistentBase<T,
- kWeakPersistentConfiguration,
- kSingleThreadPersistentConfiguration>;
-
- public:
- WeakPersistent() : Parent() {}
- WeakPersistent(std::nullptr_t) : Parent(nullptr) {}
- WeakPersistent(T* raw) : Parent(raw) {}
- WeakPersistent(T& raw) : Parent(raw) {}
- WeakPersistent(const WeakPersistent& other) : Parent(other) {}
- template <typename U>
- WeakPersistent(const WeakPersistent<U>& other) : Parent(other) {}
- template <typename U>
- WeakPersistent(const Member<U>& other) : Parent(other) {}
-
- template <typename U>
- WeakPersistent& operator=(U* other) {
- Parent::operator=(other);
- return *this;
- }
-
- WeakPersistent& operator=(std::nullptr_t) {
- Parent::operator=(nullptr);
- return *this;
- }
-
- WeakPersistent& operator=(const WeakPersistent& other) {
- Parent::operator=(other);
- return *this;
- }
-
- template <typename U>
- WeakPersistent& operator=(const WeakPersistent<U>& other) {
- Parent::operator=(other);
- return *this;
- }
-
- template <typename U>
- WeakPersistent& operator=(const Member<U>& other) {
- Parent::operator=(other);
- return *this;
- }
-
- NO_SANITIZE_ADDRESS
- bool IsClearedUnsafe() const { return this->IsNotNull(); }
-};
-
-// CrossThreadPersistent allows for holding onto an object strongly on a
-// different thread.
-//
-// Thread-safe operations:
-// - Construction
-// - Destruction
-// - Copy and move construction and assignment
-// - Clearing
-// - Deref if treated as immutable reference or if externally synchronized (e.g.
-// mutex, task). The current implementation of Get() uses a raw load (on
-// purpose) which prohibits mutation while accessing the reference on a
-// different thread.
-template <typename T>
-class CrossThreadPersistent
- : public PersistentBase<T,
- kNonWeakPersistentConfiguration,
- kCrossThreadPersistentConfiguration> {
- using Parent = PersistentBase<T,
- kNonWeakPersistentConfiguration,
- kCrossThreadPersistentConfiguration>;
-
- public:
- CrossThreadPersistent() : Parent() {}
- CrossThreadPersistent(const PersistentLocation& location)
- : Parent(location) {}
- CrossThreadPersistent(std::nullptr_t) : Parent(nullptr) {}
- CrossThreadPersistent(const PersistentLocation& location, std::nullptr_t)
- : Parent(location, nullptr) {}
- explicit CrossThreadPersistent(T* raw) : Parent(raw) {}
- CrossThreadPersistent(const PersistentLocation& location, T* raw)
- : Parent(location, raw) {}
- explicit CrossThreadPersistent(T& raw) : Parent(raw) {}
- CrossThreadPersistent(const PersistentLocation& location, T& raw)
- : Parent(location, raw) {}
- CrossThreadPersistent(const CrossThreadPersistent& other) { *this = other; }
- CrossThreadPersistent(const PersistentLocation& location,
- const CrossThreadPersistent& other) {
- *this = other;
- }
- template <typename U>
- CrossThreadPersistent(const CrossThreadPersistent<U>& other) {
- *this = other;
- }
- template <typename U>
- CrossThreadPersistent(const PersistentLocation& location,
- const CrossThreadPersistent<U>& other) {
- *this = other;
- }
- template <typename U>
- CrossThreadPersistent(const Member<U>& other) : Parent(other) {}
- template <typename U>
- CrossThreadPersistent(const PersistentLocation& location,
- const Member<U>& other)
- : Parent(location, other) {}
- CrossThreadPersistent(WTF::HashTableDeletedValueType x) : Parent(x) {}
- CrossThreadPersistent(const PersistentLocation& location,
- WTF::HashTableDeletedValueType x)
- : Parent(location, x) {}
- template <typename U>
- CrossThreadPersistent(const CrossThreadWeakPersistent<U>& other) {
- *this = other;
- }
-
- // Instead of using release(), assign then clear() instead.
- // Using release() with per thread heap enabled can cause the object to be
- // destroyed before assigning it to a new handle.
- T* Release() = delete;
-
- template <typename U>
- CrossThreadPersistent& operator=(U* other) {
- Parent::operator=(other);
- return *this;
- }
-
- CrossThreadPersistent& operator=(std::nullptr_t) {
- Parent::operator=(nullptr);
- return *this;
- }
-
- CrossThreadPersistent& operator=(const CrossThreadPersistent& other) {
- MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
- Parent::operator=(other);
- return *this;
- }
-
- template <typename U>
- CrossThreadPersistent& operator=(const CrossThreadPersistent<U>& other) {
- MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
- Parent::operator=(other);
- return *this;
- }
-
- template <typename U>
- CrossThreadPersistent& operator=(const CrossThreadWeakPersistent<U>&);
-};
-
-// CrossThreadWeakPersistent combines behavior of CrossThreadPersistent and
-// WeakPersistent, i.e., it allows holding onto an object weakly on a different
-// thread.
-//
-// Thread-safe operations:
-// - Construction
-// - Destruction
-// - Copy and move construction and assignment
-// - Clearing
-//
-// Note that this does not include dereferencing and using the raw pointer as
-// there is no guarantee that the object will be alive at the time it is used.
-template <typename T>
-class CrossThreadWeakPersistent
- : public PersistentBase<T,
- kWeakPersistentConfiguration,
- kCrossThreadPersistentConfiguration> {
- using Parent = PersistentBase<T,
- kWeakPersistentConfiguration,
- kCrossThreadPersistentConfiguration>;
-
- public:
- CrossThreadWeakPersistent() : Parent() {}
- explicit CrossThreadWeakPersistent(T* raw) : Parent(raw) {}
- explicit CrossThreadWeakPersistent(T& raw) : Parent(raw) {}
- CrossThreadWeakPersistent(const CrossThreadWeakPersistent& other) {
- *this = other;
- }
- template <typename U>
- CrossThreadWeakPersistent(const CrossThreadWeakPersistent<U>& other) {
- *this = other;
- }
- CrossThreadWeakPersistent(CrossThreadWeakPersistent&& other) {
- *this = std::move(other);
- }
- template <typename U>
- CrossThreadWeakPersistent(CrossThreadWeakPersistent<U>&& other) {
- *this = std::move(other);
- }
-
- CrossThreadWeakPersistent& operator=(const CrossThreadWeakPersistent& other) {
- MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
- Parent::operator=(other);
- return *this;
- }
-
- template <typename U>
- CrossThreadWeakPersistent& operator=(
- const CrossThreadWeakPersistent<U>& other) {
- MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
- Parent::operator=(other);
- return *this;
- }
-
- CrossThreadWeakPersistent& operator=(CrossThreadWeakPersistent&& other) {
- MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
- Parent::operator=(std::move(other));
- return *this;
- }
-
- template <typename U>
- CrossThreadWeakPersistent& operator=(CrossThreadWeakPersistent<U>&& other) {
- MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
- Parent::operator=(std::move(other));
- return *this;
- }
-
- template <typename U>
- CrossThreadWeakPersistent& operator=(U* other) {
- Parent::operator=(other);
- return *this;
- }
-
- // Create a CrossThreadPersistent that keeps the underlying object alive if
- // there is still on set. Can be used to work with an object on a different
- // thread than it was allocated. Note that CTP does not block threads from
- // terminating, in which case the reference would still be invalid.
- const CrossThreadPersistent<T> Lock() const {
- return CrossThreadPersistent<T>(*this);
- }
-
- // Disallow directly using CrossThreadWeakPersistent. Users must go through
- // CrossThreadPersistent to access the pointee. Note that this does not
- // guarantee that the object is still alive at that point. Users must check
- // the state of CTP manually before invoking any calls.
- T* operator->() const = delete;
- T& operator*() const = delete;
- operator T*() const = delete;
- T* Get() const = delete;
-
- private:
- template <typename U>
- friend class CrossThreadPersistent;
-};
-
-template <typename T>
-template <typename U>
-CrossThreadPersistent<T>& CrossThreadPersistent<T>::operator=(
- const CrossThreadWeakPersistent<U>& other) {
- MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
- using ParentU = PersistentBase<U, kWeakPersistentConfiguration,
- kCrossThreadPersistentConfiguration>;
- this->AssignUnsafe(static_cast<const ParentU&>(other).Get());
- return *this;
-}
-
-template <typename T>
-Persistent<T> WrapPersistentInternal(const PersistentLocation& location,
- T* value) {
- return Persistent<T>(location, value);
-}
-
-template <typename T>
-Persistent<T> WrapPersistentInternal(T* value) {
- return Persistent<T>(value);
-}
-
-#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-#define WrapPersistent(value) \
- WrapPersistentInternal(PERSISTENT_FROM_HERE, value)
-#else
-#define WrapPersistent(value) WrapPersistentInternal(value)
-#endif // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-
-template <typename T,
- typename = std::enable_if_t<WTF::IsGarbageCollectedType<T>::value>>
-Persistent<T> WrapPersistentIfNeeded(T* value) {
- return Persistent<T>(value);
-}
-
-template <typename T>
-T& WrapPersistentIfNeeded(T& value) {
- return value;
-}
-
-template <typename T>
-WeakPersistent<T> WrapWeakPersistent(T* value) {
- return WeakPersistent<T>(value);
-}
-
-template <typename T>
-CrossThreadPersistent<T> WrapCrossThreadPersistentInternal(
- const PersistentLocation& location,
- T* value) {
- return CrossThreadPersistent<T>(location, value);
-}
-
-template <typename T>
-CrossThreadPersistent<T> WrapCrossThreadPersistentInternal(T* value) {
- return CrossThreadPersistent<T>(value);
-}
-
-#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-#define WrapCrossThreadPersistent(value) \
- WrapCrossThreadPersistentInternal(PERSISTENT_FROM_HERE, value)
-#else
-#define WrapCrossThreadPersistent(value) \
- WrapCrossThreadPersistentInternal(value)
-#endif // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-
-template <typename T>
-CrossThreadWeakPersistent<T> WrapCrossThreadWeakPersistent(T* value) {
- return CrossThreadWeakPersistent<T>(value);
-}
-
-// Comparison operators between (Weak)Members, Persistents, and UntracedMembers.
-template <typename T, typename U>
-inline bool operator==(const Member<T>& a, const Member<U>& b) {
- return a.Get() == b.Get();
-}
-template <typename T, typename U>
-inline bool operator!=(const Member<T>& a, const Member<U>& b) {
- return a.Get() != b.Get();
-}
-template <typename T, typename U>
-inline bool operator==(const Persistent<T>& a, const Persistent<U>& b) {
- return a.Get() == b.Get();
-}
-template <typename T, typename U>
-inline bool operator!=(const Persistent<T>& a, const Persistent<U>& b) {
- return a.Get() != b.Get();
-}
-
-template <typename T, typename U>
-inline bool operator==(const Member<T>& a, const Persistent<U>& b) {
- return a.Get() == b.Get();
-}
-template <typename T, typename U>
-inline bool operator!=(const Member<T>& a, const Persistent<U>& b) {
- return a.Get() != b.Get();
-}
-template <typename T, typename U>
-inline bool operator==(const Persistent<T>& a, const Member<U>& b) {
- return a.Get() == b.Get();
-}
-template <typename T, typename U>
-inline bool operator!=(const Persistent<T>& a, const Member<U>& b) {
- return a.Get() != b.Get();
-}
-
-} // namespace blink
-
-namespace WTF {
-
-template <
- typename T,
- blink::WeaknessPersistentConfiguration weaknessConfiguration,
- blink::CrossThreadnessPersistentConfiguration crossThreadnessConfiguration>
-struct VectorTraits<blink::PersistentBase<T,
- weaknessConfiguration,
- crossThreadnessConfiguration>>
- : VectorTraitsBase<blink::PersistentBase<T,
- weaknessConfiguration,
- crossThreadnessConfiguration>> {
- STATIC_ONLY(VectorTraits);
- static const bool kNeedsDestruction = true;
- static const bool kCanInitializeWithMemset = true;
- static const bool kCanClearUnusedSlotsWithMemset = false;
- static const bool kCanMoveWithMemcpy = true;
-};
-
-template <typename T>
-struct HashTraits<blink::Persistent<T>>
- : HandleHashTraits<T, blink::Persistent<T>> {};
-
-template <typename T>
-struct HashTraits<blink::CrossThreadPersistent<T>>
- : HandleHashTraits<T, blink::CrossThreadPersistent<T>> {};
-
-template <typename T>
-struct DefaultHash<blink::Persistent<T>> {
- STATIC_ONLY(DefaultHash);
- using Hash = MemberHash<T>;
-};
-
-template <typename T>
-struct DefaultHash<blink::WeakPersistent<T>> {
- STATIC_ONLY(DefaultHash);
- using Hash = MemberHash<T>;
-};
-
-template <typename T>
-struct DefaultHash<blink::CrossThreadPersistent<T>> {
- STATIC_ONLY(DefaultHash);
- using Hash = MemberHash<T>;
-};
-
-template <typename T>
-struct DefaultHash<blink::CrossThreadWeakPersistent<T>> {
- STATIC_ONLY(DefaultHash);
- using Hash = MemberHash<T>;
-};
-
-template <typename T>
-struct CrossThreadCopier<blink::CrossThreadPersistent<T>>
- : public CrossThreadCopierPassThrough<blink::CrossThreadPersistent<T>> {
- STATIC_ONLY(CrossThreadCopier);
-};
-
-template <typename T>
-struct CrossThreadCopier<blink::CrossThreadWeakPersistent<T>>
- : public CrossThreadCopierPassThrough<blink::CrossThreadWeakPersistent<T>> {
- STATIC_ONLY(CrossThreadCopier);
-};
-
-} // namespace WTF
-
-namespace base {
-
-template <typename T>
-struct IsWeakReceiver<blink::WeakPersistent<T>> : std::true_type {};
-
-template <typename T>
-struct IsWeakReceiver<blink::CrossThreadWeakPersistent<T>> : std::true_type {};
-
-template <typename T>
-struct BindUnwrapTraits<blink::CrossThreadWeakPersistent<T>> {
- static blink::CrossThreadPersistent<T> Unwrap(
- const blink::CrossThreadWeakPersistent<T>& wrapped) {
- return blink::CrossThreadPersistent<T>(wrapped);
- }
-};
-}
+#if BUILDFLAG(BLINK_HEAP_USE_V8_OILPAN)
+#include "third_party/blink/renderer/platform/heap/v8_wrapper/persistent.h"
+#else // !BLINK_HEAP_USE_V8_OILPAN
+#include "third_party/blink/renderer/platform/heap/impl/persistent.h"
+#endif // !BLINK_HEAP_USE_V8_OILPAN
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PERSISTENT_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/process_heap.h b/chromium/third_party/blink/renderer/platform/heap/process_heap.h
index 8217afd230d..5f8d21f5c5d 100644
--- a/chromium/third_party/blink/renderer/platform/heap/process_heap.h
+++ b/chromium/third_party/blink/renderer/platform/heap/process_heap.h
@@ -1,69 +1,16 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
+// 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_PROCESS_HEAP_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PROCESS_HEAP_H_
-#include <atomic>
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
+#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-namespace blink {
+#if BUILDFLAG(BLINK_HEAP_USE_V8_OILPAN)
+#include "third_party/blink/renderer/platform/heap/v8_wrapper/process_heap.h"
+#else // !BLINK_HEAP_USE_V8_OILPAN
+#include "third_party/blink/renderer/platform/heap/impl/process_heap.h"
+#endif // !BLINK_HEAP_USE_V8_OILPAN
-class CrossThreadPersistentRegion;
-
-class PLATFORM_EXPORT ProcessHeap {
- STATIC_ONLY(ProcessHeap);
-
- public:
- static void Init();
-
- static CrossThreadPersistentRegion& GetCrossThreadPersistentRegion();
- static CrossThreadPersistentRegion& GetCrossThreadWeakPersistentRegion();
-
- // Access to the CrossThreadPersistentRegion from multiple threads has to be
- // prevented as allocation, freeing, and iteration of nodes may otherwise
- // cause data races.
- //
- // Examples include:
- // - Iteration of strong cross-thread Persistents.
- // - Iteration and processing of weak cross-thread Persistents. The lock
- // needs to span both operations as iteration of weak persistents only
- // registers memory regions that are then processed afterwards.
- // - Marking phase in garbage collection: The whole phase requires locking
- // as CrossThreadWeakPersistents may be converted to CrossThreadPersistent
- // which must observe GC as an atomic operation.
- static Mutex& CrossThreadPersistentMutex();
-
- static void IncreaseTotalAllocatedObjectSize(size_t delta) {
- total_allocated_object_size_.fetch_add(delta, std::memory_order_relaxed);
- }
- static void DecreaseTotalAllocatedObjectSize(size_t delta) {
- total_allocated_object_size_.fetch_sub(delta, std::memory_order_relaxed);
- }
- static size_t TotalAllocatedObjectSize() {
- return total_allocated_object_size_.load(std::memory_order_relaxed);
- }
- static void IncreaseTotalAllocatedSpace(size_t delta) {
- total_allocated_space_.fetch_add(delta, std::memory_order_relaxed);
- }
- static void DecreaseTotalAllocatedSpace(size_t delta) {
- total_allocated_space_.fetch_sub(delta, std::memory_order_relaxed);
- }
- static size_t TotalAllocatedSpace() {
- return total_allocated_space_.load(std::memory_order_relaxed);
- }
- static void ResetHeapCounters();
-
- private:
- static std::atomic_size_t total_allocated_space_;
- static std::atomic_size_t total_allocated_object_size_;
-
- friend class ThreadState;
-};
-
-} // namespace blink
-
-#endif
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PROCESS_HEAP_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/thread_state.h b/chromium/third_party/blink/renderer/platform/heap/thread_state.h
index 41499ec2c46..050bac6b39b 100644
--- a/chromium/third_party/blink/renderer/platform/heap/thread_state.h
+++ b/chromium/third_party/blink/renderer/platform/heap/thread_state.h
@@ -1,717 +1,16 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
+// 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_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_H_
-#include <atomic>
-#include <memory>
+#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-#include "base/macros.h"
-#include "base/synchronization/lock.h"
-#include "base/task/post_job.h"
-#include "third_party/blink/renderer/platform/heap/atomic_entry_flag.h"
-#include "third_party/blink/renderer/platform/heap/blink_gc.h"
-#include "third_party/blink/renderer/platform/heap/threading_traits.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/forward.h"
-#include "third_party/blink/renderer/platform/wtf/hash_map.h"
-#include "third_party/blink/renderer/platform/wtf/hash_set.h"
-#include "third_party/blink/renderer/platform/wtf/linked_hash_set.h"
-#include "third_party/blink/renderer/platform/wtf/sanitizers.h"
-#include "third_party/blink/renderer/platform/wtf/thread_specific.h"
-#include "third_party/blink/renderer/platform/wtf/threading.h"
-#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
-
-namespace v8 {
-class EmbedderGraph;
-class Isolate;
-} // namespace v8
-
-namespace blink {
-
-namespace incremental_marking_test {
-class IncrementalMarkingScope;
-} // namespace incremental_marking_test
-
-class MarkingVisitor;
-class MarkingSchedulingOracle;
-class PersistentNode;
-class PersistentRegion;
-class ThreadHeap;
-class ThreadState;
-template <ThreadAffinity affinity>
-class ThreadStateFor;
-class UnifiedHeapController;
-class Visitor;
-
-// Declare that a class has a pre-finalizer which gets invoked before objects
-// get swept. It is thus safe to touch on-heap objects that may be collected in
-// the same GC cycle. This is useful when it's not possible to avoid touching
-// on-heap objects in a destructor which is forbidden.
-//
-// Note that:
-// (a) Pre-finalizers *must* not resurrect dead objects.
-// (b) Run on the same thread they are registered.
-// (c) Decrease GC performance which means that they should only be used if
-// absolute necessary.
-//
-// Usage:
-// class Foo : GarbageCollected<Foo> {
-// USING_PRE_FINALIZER(Foo, Dispose);
-// private:
-// void Dispose() {
-// bar_->...; // It is safe to touch other on-heap objects.
-// }
-// Member<Bar> bar_;
-// };
-#define USING_PRE_FINALIZER(Class, PreFinalizer) \
- public: \
- static bool InvokePreFinalizer(const LivenessBroker& info, void* object) { \
- Class* self = reinterpret_cast<Class*>(object); \
- if (info.IsHeapObjectAlive(self)) \
- return false; \
- self->Class::PreFinalizer(); \
- return true; \
- } \
- \
- private: \
- ThreadState::PrefinalizerRegistration<Class> prefinalizer_dummy_{this}; \
- using UsingPreFinalizerMacroNeedsTrailingSemiColon = char
-
-class PLATFORM_EXPORT BlinkGCObserver {
- USING_FAST_MALLOC(BlinkGCObserver);
-
- public:
- // The constructor automatically register this object to ThreadState's
- // observer lists. The argument must not be null.
- explicit BlinkGCObserver(ThreadState*);
-
- // The destructor automatically unregister this object from ThreadState's
- // observer lists.
- virtual ~BlinkGCObserver();
-
- virtual void OnCompleteSweepDone() = 0;
-
- private:
- // As a ThreadState must live when a BlinkGCObserver lives, holding a raw
- // pointer is safe.
- ThreadState* thread_state_;
-};
-
-class PLATFORM_EXPORT ThreadState final {
- USING_FAST_MALLOC(ThreadState);
-
- public:
- // Register the pre-finalizer for the |self| object. The class T be using
- // USING_PRE_FINALIZER() macro.
- template <typename T>
- class PrefinalizerRegistration final {
- DISALLOW_NEW();
-
- public:
- PrefinalizerRegistration(T* self) { // NOLINT
- static_assert(sizeof(&T::InvokePreFinalizer) > 0,
- "USING_PRE_FINALIZER(T) must be defined.");
- ThreadState* state =
- ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
-#if DCHECK_IS_ON()
- DCHECK(state->CheckThread());
-#endif
- DCHECK(!state->SweepForbidden());
- DCHECK(std::find(state->ordered_pre_finalizers_.begin(),
- state->ordered_pre_finalizers_.end(),
- PreFinalizer(self, T::InvokePreFinalizer)) ==
- state->ordered_pre_finalizers_.end());
- state->ordered_pre_finalizers_.emplace_back(self, T::InvokePreFinalizer);
- }
- };
-
- // See setGCState() for possible state transitions.
- enum GCState {
- kNoGCScheduled,
- kIncrementalMarkingStepPaused,
- kIncrementalMarkingStepScheduled,
- kIncrementalMarkingFinalizeScheduled,
- kForcedGCForTestingScheduled,
- kIncrementalGCScheduled,
- };
-
- // The phase that the GC is in. The GCPhase will not return kNone for mutators
- // running during incremental marking and lazy sweeping. See SetGCPhase() for
- // possible state transitions.
- enum class GCPhase {
- // GC is doing nothing.
- kNone,
- // GC is in marking phase.
- kMarking,
- // GC is in sweeping phase.
- kSweeping,
- };
-
- enum class EphemeronProcessing {
- kPartialProcessing, // Perofrm one ephemeron processing iteration every
- // few step
- kFullProcessing // Perofrm full fixed-point ephemeron processing on each
- // step
- };
-
- class AtomicPauseScope;
- class GCForbiddenScope;
- class LsanDisabledScope;
- class NoAllocationScope;
- class StatisticsCollector;
- struct Statistics;
- class SweepForbiddenScope;
- class HeapPointersOnStackScope;
-
- using V8BuildEmbedderGraphCallback = void (*)(v8::Isolate*,
- v8::EmbedderGraph*,
- void*);
-
- // Returns true if some thread (possibly the current thread) may be doing
- // incremental marking. If false is returned, the *current* thread is
- // definitely not doing incremental marking. See atomic_entry_flag.h for
- // details.
- //
- // For an exact check, use ThreadState::IsIncrementalMarking.
- ALWAYS_INLINE static bool IsAnyIncrementalMarking() {
- return incremental_marking_flag_.MightBeEntered();
- }
-
- static ThreadState* AttachMainThread();
-
- // Associate ThreadState object with the current thread. After this
- // call thread can start using the garbage collected heap infrastructure.
- // It also has to periodically check for safepoints.
- static ThreadState* AttachCurrentThread();
-
- // Disassociate attached ThreadState from the current thread. The thread
- // can no longer use the garbage collected heap after this call.
- //
- // When ThreadState is detaching from non-main thread its heap is expected to
- // be empty (because it is going away). Perform registered cleanup tasks and
- // garbage collection to sweep away any objects that are left on this heap.
- //
- // This method asserts that no objects remain after this cleanup. If assertion
- // does not hold we crash as we are potentially in the dangling pointer
- // situation.
- static void DetachCurrentThread();
-
- static ThreadState* Current() { return **thread_specific_; }
-
- static ThreadState* MainThreadState() {
- return reinterpret_cast<ThreadState*>(main_thread_state_storage_);
- }
-
- static ThreadState* FromObject(const void*);
-
- bool IsMainThread() const { return this == MainThreadState(); }
- bool CheckThread() const { return thread_ == CurrentThread(); }
-
- ThreadHeap& Heap() const { return *heap_; }
- base::PlatformThreadId ThreadId() const { return thread_; }
-
- // Associates |ThreadState| with a given |v8::Isolate|, essentially tying
- // there garbage collectors together.
- void AttachToIsolate(v8::Isolate*,
- V8BuildEmbedderGraphCallback);
-
- // Removes the association from a potentially attached |v8::Isolate|.
- void DetachFromIsolate();
-
- // Returns an |UnifiedHeapController| if ThreadState is attached to a V8
- // isolate (see |AttachToIsolate|) and nullptr otherwise.
- UnifiedHeapController* unified_heap_controller() const {
- DCHECK(isolate_);
- return unified_heap_controller_.get();
- }
-
- void PerformIdleLazySweep(base::TimeTicks deadline);
- void PerformConcurrentSweep(base::JobDelegate*);
-
- void ScheduleForcedGCForTesting();
- void ScheduleGCIfNeeded();
- void SetGCState(GCState);
- GCState GetGCState() const { return gc_state_; }
- void SetGCPhase(GCPhase);
-
- // Immediately starts incremental marking and schedules further steps if
- // necessary.
- void StartIncrementalMarking(BlinkGC::GCReason);
-
- // Returns true if marking is in progress.
- bool IsMarkingInProgress() const { return gc_phase_ == GCPhase::kMarking; }
-
- // Returns true if unified heap marking is in progress.
- bool IsUnifiedGCMarkingInProgress() const {
- return IsMarkingInProgress() && IsUnifiedHeapGC();
- }
-
- // Returns true if sweeping is in progress.
- bool IsSweepingInProgress() const { return gc_phase_ == GCPhase::kSweeping; }
-
- // Returns true if the current GC is a memory reducing GC.
- bool IsMemoryReducingGC() const {
- return current_gc_data_.reason ==
- BlinkGC::GCReason::kUnifiedHeapForMemoryReductionGC ||
- current_gc_data_.reason ==
- BlinkGC::GCReason::kUnifiedHeapForcedForTestingGC;
- }
-
- bool IsUnifiedHeapGC() const {
- return current_gc_data_.reason == BlinkGC::GCReason::kUnifiedHeapGC ||
- current_gc_data_.reason ==
- BlinkGC::GCReason::kUnifiedHeapForMemoryReductionGC ||
- current_gc_data_.reason ==
- BlinkGC::GCReason::kUnifiedHeapForcedForTestingGC;
- }
-
- bool FinishIncrementalMarkingIfRunning(BlinkGC::CollectionType,
- BlinkGC::StackState,
- BlinkGC::MarkingType,
- BlinkGC::SweepingType,
- BlinkGC::GCReason);
-
- void EnableIncrementalMarkingBarrier();
- void DisableIncrementalMarkingBarrier();
-
- void RestartIncrementalMarkingIfPaused();
-
- void CompleteSweep();
-
- // Returns whether it is currently allowed to allocate an object. Mainly used
- // for sanity checks asserts.
- bool IsAllocationAllowed() const {
- // Allocation is not allowed during atomic marking pause, but it is allowed
- // during atomic sweeping pause.
- return !InAtomicMarkingPause() && !no_allocation_count_;
- }
-
- // Returns whether it is currently forbidden to trigger a GC.
- bool IsGCForbidden() const { return gc_forbidden_count_; }
-
- // Returns whether it is currently forbidden to sweep objects.
- bool SweepForbidden() const { return sweep_forbidden_; }
-
- bool in_atomic_pause() const { return in_atomic_pause_; }
-
- bool InAtomicMarkingPause() const {
- return in_atomic_pause() && IsMarkingInProgress();
- }
- bool InAtomicSweepingPause() const {
- return in_atomic_pause() && IsSweepingInProgress();
- }
-
- bool IsIncrementalMarking() const { return incremental_marking_; }
- void SetIncrementalMarking(bool value) { incremental_marking_ = value; }
-
- void SafePoint(BlinkGC::StackState);
-
- // A region of non-weak PersistentNodes allocated on the given thread.
- PersistentRegion* GetPersistentRegion() const {
- return persistent_region_.get();
- }
-
- // A region of PersistentNodes for WeakPersistents allocated on the given
- // thread.
- PersistentRegion* GetWeakPersistentRegion() const {
- return weak_persistent_region_.get();
- }
-
- void RegisterStaticPersistentNode(PersistentNode*);
- void ReleaseStaticPersistentNodes();
- void FreePersistentNode(PersistentRegion*, PersistentNode*);
-
- v8::Isolate* GetIsolate() const { return isolate_; }
-
- // Returns |true| if |object| resides on this thread's heap.
- // It is well-defined to call this method on any heap allocated
- // reference, provided its associated heap hasn't been detached
- // and shut down. Its behavior is undefined for any other pointer
- // value.
- bool IsOnThreadHeap(const void* object) const {
- return &FromObject(object)->Heap() == &Heap();
- }
-
- ALWAYS_INLINE bool IsOnStack(Address address) const {
- return reinterpret_cast<Address>(start_of_stack_) >= address &&
- address >= (reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(
- WTF::GetCurrentStackPosition())));
- }
-
- int GcAge() const { return gc_age_; }
-
- MarkingVisitor* CurrentVisitor() const {
- return current_gc_data_.visitor.get();
- }
-
- // Returns true if the marking verifier is enabled, false otherwise.
- bool IsVerifyMarkingEnabled() const;
-
- void SkipIncrementalMarkingForTesting() {
- skip_incremental_marking_for_testing_ = true;
- }
-
- // Performs stand-alone garbage collections considering only C++ objects for
- // testing.
- //
- // Since it only considers C++ objects this type of GC is mostly useful for
- // unit tests.
- void CollectGarbageForTesting(BlinkGC::CollectionType,
- BlinkGC::StackState,
- BlinkGC::MarkingType,
- BlinkGC::SweepingType,
- BlinkGC::GCReason);
-
- // Forced garbage collection for testing:
- // - Performs unified heap garbage collections if ThreadState is attached to a
- // v8::Isolate using ThreadState::AttachToIsolate.
- // - Otherwise, performs stand-alone garbage collections.
- // - Collects garbage as long as live memory decreases (capped at 5).
- void CollectAllGarbageForTesting(
- BlinkGC::StackState stack_state =
- BlinkGC::StackState::kNoHeapPointersOnStack);
-
- // Enables compaction for next garbage collection.
- void EnableCompactionForNextGCForTesting();
-
- bool RequiresForcedGCForTesting() const {
- return current_gc_data_.stack_state ==
- BlinkGC::StackState::kHeapPointersOnStack &&
- !forced_scheduled_gc_for_testing_;
- }
-
- void EnterNoHeapVerificationScopeForTesting() {
- ++disable_heap_verification_scope_;
- }
- void LeaveNoHeapVerificationScopeForTesting() {
- --disable_heap_verification_scope_;
- }
-
- private:
- class IncrementalMarkingScheduler;
-
- // Stores whether some ThreadState is currently in incremental marking.
- static AtomicEntryFlag incremental_marking_flag_;
-
- static WTF::ThreadSpecific<ThreadState*>* thread_specific_;
-
- // We can't create a static member of type ThreadState here because it will
- // introduce global constructor and destructor. We would like to manage
- // lifetime of the ThreadState attached to the main thread explicitly instead
- // and still use normal constructor and destructor for the ThreadState class.
- // For this we reserve static storage for the main ThreadState and lazily
- // construct ThreadState in it using placement new.
- static uint8_t main_thread_state_storage_[];
-
- // Callback executed directly after pushing all callee-saved registers.
- // |end_of_stack| denotes the end of the stack that can hold references to
- // managed objects.
- static void VisitStackAfterPushingRegisters(ThreadState*,
- intptr_t* end_of_stack);
-
- static bool IsForcedGC(BlinkGC::GCReason reason) {
- return reason == BlinkGC::GCReason::kThreadTerminationGC ||
- reason == BlinkGC::GCReason::kForcedGCForTesting ||
- reason == BlinkGC::GCReason::kUnifiedHeapForcedForTestingGC;
- }
-
- ThreadState();
- ~ThreadState();
-
- void EnterNoAllocationScope() { no_allocation_count_++; }
- void LeaveNoAllocationScope() { no_allocation_count_--; }
-
- void EnterAtomicPause() {
- DCHECK(!in_atomic_pause_);
- in_atomic_pause_ = true;
- }
- void LeaveAtomicPause() {
- DCHECK(in_atomic_pause_);
- in_atomic_pause_ = false;
- }
-
- void EnterGCForbiddenScope() { gc_forbidden_count_++; }
- void LeaveGCForbiddenScope() {
- DCHECK_GT(gc_forbidden_count_, 0u);
- gc_forbidden_count_--;
- }
-
- void EnterStaticReferenceRegistrationDisabledScope();
- void LeaveStaticReferenceRegistrationDisabledScope();
-
- // Performs stand-alone garbage collections considering only C++ objects.
- //
- // Use the public *ForTesting calls for calling GC in tests.
- void CollectGarbage(BlinkGC::CollectionType,
- BlinkGC::StackState,
- BlinkGC::MarkingType,
- BlinkGC::SweepingType,
- BlinkGC::GCReason);
-
- // The following methods are used to compose RunAtomicPause. Public users
- // should use the CollectGarbage entrypoint. Internal users should use these
- // methods to compose a full garbage collection.
- void AtomicPauseMarkPrologue(BlinkGC::CollectionType,
- BlinkGC::StackState,
- BlinkGC::MarkingType,
- BlinkGC::GCReason);
- void AtomicPauseMarkRoots(BlinkGC::StackState,
- BlinkGC::MarkingType,
- BlinkGC::GCReason);
- void AtomicPauseMarkTransitiveClosure();
- void AtomicPauseMarkEpilogue(BlinkGC::MarkingType);
- void AtomicPauseSweepAndCompact(BlinkGC::CollectionType,
- BlinkGC::MarkingType marking_type,
- BlinkGC::SweepingType sweeping_type);
- void AtomicPauseEpilogue();
-
- // RunAtomicPause composes the final atomic pause that finishes a mark-compact
- // phase of a garbage collection. Depending on SweepingType it may also finish
- // sweeping or schedule lazy/concurrent sweeping.
- void RunAtomicPause(BlinkGC::CollectionType,
- BlinkGC::StackState,
- BlinkGC::MarkingType,
- BlinkGC::SweepingType,
- BlinkGC::GCReason);
-
- // The version is needed to be able to start incremental marking.
- void MarkPhasePrologue(BlinkGC::CollectionType,
- BlinkGC::StackState,
- BlinkGC::MarkingType,
- BlinkGC::GCReason);
- void MarkPhaseEpilogue(BlinkGC::MarkingType);
- void MarkPhaseVisitRoots();
- void MarkPhaseVisitNotFullyConstructedObjects();
- bool MarkPhaseAdvanceMarkingBasedOnSchedule(base::TimeDelta,
- EphemeronProcessing);
- bool MarkPhaseAdvanceMarking(base::TimeDelta, EphemeronProcessing);
- void VerifyMarking(BlinkGC::MarkingType);
-
- // Visit the stack after pushing registers onto the stack.
- void PushRegistersAndVisitStack();
-
- // Visit local thread stack and trace all pointers conservatively. Never call
- // directly but always call through |PushRegistersAndVisitStack|.
- void VisitStackImpl(MarkingVisitor*, Address*, Address*);
- void VisitStack(MarkingVisitor*, Address*);
- void VisitUnsafeStack(MarkingVisitor*);
-
- // Visit the asan fake stack frame corresponding to a slot on the real machine
- // stack if there is one. Never call directly but always call through
- // |PushRegistersAndVisitStack|.
- void VisitAsanFakeStackForPointer(MarkingVisitor*,
- Address,
- Address*,
- Address*);
-
- // Visit all non-weak persistents allocated on this thread.
- void VisitPersistents(Visitor*);
-
- // Visit all weak persistents allocated on this thread.
- void VisitWeakPersistents(Visitor*);
-
- // Visit card tables (remembered sets) containing inter-generational pointers.
- void VisitRememberedSets(MarkingVisitor*);
-
- // Incremental marking implementation functions.
- void IncrementalMarkingStartForTesting();
- void IncrementalMarkingStart(BlinkGC::GCReason);
- // Incremental marking step advance marking on the mutator thread. This method
- // also reschedules concurrent marking tasks if needed. The duration parameter
- // applies only to incremental marking steps on the mutator thread.
- void IncrementalMarkingStep(BlinkGC::StackState);
- void IncrementalMarkingFinalize();
-
- // Returns true if concurrent marking is finished (i.e. all current threads
- // terminated and the worklist is empty)
- bool ConcurrentMarkingStep();
- void ScheduleConcurrentMarking();
- void PerformConcurrentMark(base::JobDelegate* job);
-
- // Schedule helpers.
- void ScheduleIdleLazySweep();
- void ScheduleConcurrentAndLazySweep();
-
- void NotifySweepDone();
- void PostSweep();
-
- // See |DetachCurrentThread|.
- void RunTerminationGC();
-
- void RunScheduledGC(BlinkGC::StackState);
-
- void SynchronizeAndFinishConcurrentSweeping();
-
- void InvokePreFinalizers();
-
- // Adds the given observer to the ThreadState's observer list. This doesn't
- // take ownership of the argument. The argument must not be null. The argument
- // must not be registered before calling this.
- void AddObserver(BlinkGCObserver*);
-
- // Removes the given observer from the ThreadState's observer list. This
- // doesn't take ownership of the argument. The argument must not be null.
- // The argument must be registered before calling this.
- void RemoveObserver(BlinkGCObserver*);
-
- bool IsForcedGC() const { return IsForcedGC(current_gc_data_.reason); }
-
- // Returns whether stack scanning is forced. This is currently only used in
- // platform tests where non nested tasks can be run with heap pointers on
- // stack.
- bool HeapPointersOnStackForced() const {
- return heap_pointers_on_stack_forced_;
- }
-
-#if defined(ADDRESS_SANITIZER)
- // Poisons payload of unmarked objects.
- //
- // Also unpoisons memory areas for handles that may require resetting which
- // can race with destructors. Note that cross-thread access still requires
- // synchronization using a lock.
- void PoisonUnmarkedObjects();
-#endif // ADDRESS_SANITIZER
-
- std::unique_ptr<ThreadHeap> heap_;
- base::PlatformThreadId thread_;
- std::unique_ptr<PersistentRegion> persistent_region_;
- std::unique_ptr<PersistentRegion> weak_persistent_region_;
-
- // Start of the stack which is the boundary until conservative stack scanning
- // needs to search for managed pointers.
- Address* start_of_stack_;
-
- bool in_atomic_pause_ = false;
- bool sweep_forbidden_ = false;
- bool heap_pointers_on_stack_forced_ = false;
- bool incremental_marking_ = false;
- bool should_optimize_for_load_time_ = false;
- bool forced_scheduled_gc_for_testing_ = false;
- size_t no_allocation_count_ = 0;
- size_t gc_forbidden_count_ = 0;
- size_t static_persistent_registration_disabled_count_ = 0;
-
- GCState gc_state_ = GCState::kNoGCScheduled;
- GCPhase gc_phase_ = GCPhase::kNone;
- BlinkGC::GCReason reason_for_scheduled_gc_ =
- BlinkGC::GCReason::kForcedGCForTesting;
-
- using PreFinalizerCallback = bool (*)(const LivenessBroker&, void*);
- using PreFinalizer = std::pair<void*, PreFinalizerCallback>;
-
- // Pre-finalizers are called in the reverse order in which they are
- // registered by the constructors (including constructors of Mixin objects)
- // for an object, by processing the ordered_pre_finalizers_ back-to-front.
- Deque<PreFinalizer> ordered_pre_finalizers_;
-
- v8::Isolate* isolate_ = nullptr;
- V8BuildEmbedderGraphCallback v8_build_embedder_graph_ = nullptr;
- std::unique_ptr<UnifiedHeapController> unified_heap_controller_;
-
-#if defined(ADDRESS_SANITIZER)
- void* asan_fake_stack_;
-#endif
-
- HashSet<BlinkGCObserver*> observers_;
-
- // PersistentNodes that are stored in static references;
- // references that either have to be cleared upon the thread
- // detaching from Oilpan and shutting down or references we
- // have to clear before initiating LSan's leak detection.
- HashSet<PersistentNode*> static_persistents_;
-
- int gc_age_ = 0;
-
- struct GCData {
- BlinkGC::CollectionType collection_type;
- BlinkGC::StackState stack_state;
- BlinkGC::MarkingType marking_type;
- BlinkGC::GCReason reason;
- std::unique_ptr<MarkingVisitor> visitor;
- };
- GCData current_gc_data_;
-
- std::unique_ptr<IncrementalMarkingScheduler> incremental_marking_scheduler_;
- std::unique_ptr<MarkingSchedulingOracle> marking_scheduling_;
-
- base::JobHandle marker_handle_;
-
- base::JobHandle sweeper_handle_;
- std::atomic_bool has_unswept_pages_{false};
-
- size_t disable_heap_verification_scope_ = 0;
-
- bool skip_incremental_marking_for_testing_ = false;
-
- size_t last_concurrently_marked_bytes_ = 0;
- base::TimeTicks last_concurrently_marked_bytes_update_;
- bool concurrent_marking_priority_increased_ = false;
-
- friend class BlinkGCObserver;
- friend class incremental_marking_test::IncrementalMarkingScope;
- friend class IncrementalMarkingTestDriver;
- friend class HeapAllocator;
- template <typename T>
- friend class PrefinalizerRegistration;
- friend class TestGCScope;
- friend class TestSupportingGC;
- friend class ThreadStateSchedulingTest;
- friend class UnifiedHeapController;
-
- DISALLOW_COPY_AND_ASSIGN(ThreadState);
-};
-
-template <>
-class ThreadStateFor<kMainThreadOnly> {
- STATIC_ONLY(ThreadStateFor);
-
- public:
- static ThreadState* GetState() {
- // This specialization must only be used from the main thread.
- DCHECK(ThreadState::Current()->IsMainThread());
- return ThreadState::MainThreadState();
- }
-};
-
-template <>
-class ThreadStateFor<kAnyThread> {
- STATIC_ONLY(ThreadStateFor);
-
- public:
- static ThreadState* GetState() { return ThreadState::Current(); }
-};
-
-} // namespace blink
+#if BUILDFLAG(BLINK_HEAP_USE_V8_OILPAN)
+#include "third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.h"
+#else // !BLINK_HEAP_USE_V8_OILPAN
+#include "third_party/blink/renderer/platform/heap/impl/thread_state.h"
+#endif // !BLINK_HEAP_USE_V8_OILPAN
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/thread_state_scopes.h b/chromium/third_party/blink/renderer/platform/heap/thread_state_scopes.h
index bde958dc4ad..5abe13206e6 100644
--- a/chromium/third_party/blink/renderer/platform/heap/thread_state_scopes.h
+++ b/chromium/third_party/blink/renderer/platform/heap/thread_state_scopes.h
@@ -1,128 +1,16 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// 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_SCOPES_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_SCOPES_H_
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
+#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-#if defined(LEAK_SANITIZER)
-#include "third_party/blink/renderer/platform/wtf/leak_annotations.h"
-#endif
-
-namespace blink {
-
-// The NoAllocationScope class is used in debug mode to catch unwanted
-// allocations. E.g. allocations during GC.
-class ThreadState::NoAllocationScope final {
- STACK_ALLOCATED();
- DISALLOW_COPY_AND_ASSIGN(NoAllocationScope);
-
- public:
- explicit NoAllocationScope(ThreadState* state) : state_(state) {
- state_->EnterNoAllocationScope();
- }
- ~NoAllocationScope() { state_->LeaveNoAllocationScope(); }
-
- private:
- ThreadState* const state_;
-};
-
-class ThreadState::SweepForbiddenScope final {
- STACK_ALLOCATED();
- DISALLOW_COPY_AND_ASSIGN(SweepForbiddenScope);
-
- public:
- explicit SweepForbiddenScope(ThreadState* state) : state_(state) {
- DCHECK(!state_->sweep_forbidden_);
- state_->sweep_forbidden_ = true;
- }
- ~SweepForbiddenScope() {
- DCHECK(state_->sweep_forbidden_);
- state_->sweep_forbidden_ = false;
- }
-
- private:
- ThreadState* const state_;
-};
-
-class ThreadState::GCForbiddenScope final {
- STACK_ALLOCATED();
-
- public:
- explicit GCForbiddenScope(ThreadState* thread_state)
- : thread_state_(thread_state) {
- thread_state_->EnterGCForbiddenScope();
- }
- ~GCForbiddenScope() { thread_state_->LeaveGCForbiddenScope(); }
-
- private:
- ThreadState* const thread_state_;
-};
-
-// Used to mark when we are in an atomic pause for GC.
-class ThreadState::AtomicPauseScope final {
- STACK_ALLOCATED();
-
- public:
- explicit AtomicPauseScope(ThreadState* thread_state)
- : thread_state_(thread_state), gc_forbidden_scope(thread_state) {
- thread_state_->EnterAtomicPause();
- }
- ~AtomicPauseScope() { thread_state_->LeaveAtomicPause(); }
-
- private:
- ThreadState* const thread_state_;
- GCForbiddenScope gc_forbidden_scope;
-};
-
-class ThreadState::HeapPointersOnStackScope final {
- STACK_ALLOCATED();
-
- public:
- explicit HeapPointersOnStackScope(ThreadState* state) : state_(state) {
- DCHECK(!state_->heap_pointers_on_stack_forced_);
- state_->heap_pointers_on_stack_forced_ = true;
- }
- ~HeapPointersOnStackScope() {
- DCHECK(state_->heap_pointers_on_stack_forced_);
- state_->heap_pointers_on_stack_forced_ = false;
- }
-
- private:
- ThreadState* const state_;
-};
-
-#if defined(LEAK_SANITIZER)
-class ThreadState::LsanDisabledScope final {
- STACK_ALLOCATED();
- DISALLOW_COPY_AND_ASSIGN(LsanDisabledScope);
-
- public:
- explicit LsanDisabledScope(ThreadState* thread_state)
- : thread_state_(thread_state) {
- __lsan_disable();
- if (thread_state_)
- thread_state_->EnterStaticReferenceRegistrationDisabledScope();
- }
-
- ~LsanDisabledScope() {
- __lsan_enable();
- if (thread_state_)
- thread_state_->LeaveStaticReferenceRegistrationDisabledScope();
- }
-
- private:
- ThreadState* const thread_state_;
-};
-
-#define LEAK_SANITIZER_DISABLED_SCOPE \
- ThreadState::LsanDisabledScope lsan_disabled_scope(ThreadState::Current())
-#else
-#define LEAK_SANITIZER_DISABLED_SCOPE
-#endif
-
-} // namespace blink
+#if BUILDFLAG(BLINK_HEAP_USE_V8_OILPAN)
+#include "third_party/blink/renderer/platform/heap/v8_wrapper/thread_state_scopes.h"
+#else // !BLINK_HEAP_USE_V8_OILPAN
+#include "third_party/blink/renderer/platform/heap/impl/thread_state_scopes.h"
+#endif // !BLINK_HEAP_USE_V8_OILPAN
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_SCOPES_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/unified_heap_controller.h b/chromium/third_party/blink/renderer/platform/heap/unified_heap_controller.h
index 5ec55f91db5..9d197c495e9 100644
--- a/chromium/third_party/blink/renderer/platform/heap/unified_heap_controller.h
+++ b/chromium/third_party/blink/renderer/platform/heap/unified_heap_controller.h
@@ -1,75 +1,16 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
+// 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_UNIFIED_HEAP_CONTROLLER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_UNIFIED_HEAP_CONTROLLER_H_
-#include "base/macros.h"
-#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "v8/include/v8.h"
+#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-namespace blink {
-
-class ThreadState;
-
-// UnifiedHeapController ties V8's garbage collector to Oilpan for performing a
-// garbage collection across both managed heaps.
-//
-// Unified heap garbage collections are triggered by V8 and mark the full
-// transitive closure of V8 and Blink (Oilpan) objects. The garbage collection
-// is initially triggered by V8. Both collecters report live references using
-// the EmbedderHeapTracer APIs. V8 and Blink both run separate incremental
-// marking steps to compute their live closures, respectively. The final atomic
-// pause is then initiated by V8 and triggers a fixed-point computation between
-// V8 and Blink where both GCs report live references to each other and drain
-// their marking work lists until they are empty and no new references are
-// found.
-//
-// Oilpan does not consider references from DOM wrappers (JavaScript objects on
-// V8's heap) as roots for such garbage collections.
-class PLATFORM_EXPORT UnifiedHeapController final
- : public v8::EmbedderHeapTracer,
- public ThreadHeapStatsObserver {
- DISALLOW_IMPLICIT_CONSTRUCTORS(UnifiedHeapController);
-
- public:
- explicit UnifiedHeapController(ThreadState*);
- ~UnifiedHeapController() override;
-
- // v8::EmbedderHeapTracer implementation.
- void TracePrologue(v8::EmbedderHeapTracer::TraceFlags) final;
- void TraceEpilogue(v8::EmbedderHeapTracer::TraceSummary*) final;
- void EnterFinalPause(EmbedderStackState) final;
- void RegisterV8References(const std::vector<std::pair<void*, void*>>&) final;
- bool AdvanceTracing(double) final;
- bool IsTracingDone() final;
- bool IsRootForNonTracingGC(const v8::TracedReference<v8::Value>&) final;
- bool IsRootForNonTracingGC(const v8::TracedGlobal<v8::Value>&) final;
- void ResetHandleInNonTracingGC(const v8::TracedReference<v8::Value>&) final;
-
- ThreadState* thread_state() const { return thread_state_; }
-
- // ThreadHeapStatsObserver implementation.
- void IncreaseAllocatedObjectSize(size_t) final;
- void DecreaseAllocatedObjectSize(size_t) final;
- // Not needed.
- void ResetAllocatedObjectSize(size_t) final {}
- void IncreaseAllocatedSpace(size_t) final {}
- void DecreaseAllocatedSpace(size_t) final {}
-
- private:
- void ReportBufferedAllocatedSizeIfPossible();
-
- ThreadState* const thread_state_;
- // Returns whether the Blink heap has been fully processed.
- bool is_tracing_done_ = false;
-
- // Buffered allocated size. Only positive values are forwarded to V8.
- int64_t buffered_allocated_size_ = 0;
-};
-
-} // namespace blink
+#if BUILDFLAG(BLINK_HEAP_USE_V8_OILPAN)
+#include "third_party/blink/renderer/platform/heap/v8_wrapper/unified_heap_controller.h"
+#else // !BLINK_HEAP_USE_V8_OILPAN
+#include "third_party/blink/renderer/platform/heap/impl/unified_heap_controller.h"
+#endif // !BLINK_HEAP_USE_V8_OILPAN
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_UNIFIED_HEAP_CONTROLLER_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h b/chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h
index 6ff6cb6a75e..4d13146e071 100644
--- a/chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h
+++ b/chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h
@@ -1,90 +1,16 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
+// 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_UNIFIED_HEAP_MARKING_VISITOR_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_UNIFIED_HEAP_MARKING_VISITOR_H_
-#include "base/macros.h"
-#include "third_party/blink/renderer/platform/heap/marking_visitor.h"
+#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-namespace v8 {
-class EmbedderHeapTracer;
-}
-
-namespace blink {
-
-struct WrapperTypeInfo;
-
-// Marking visitor for unified heap garbage collections. Extends the regular
-// Oilpan marking visitor by also providing write barriers and visitation
-// methods that allow for announcing reachable objects to V8. Visitor can be
-// used from any thread.
-class PLATFORM_EXPORT UnifiedHeapMarkingVisitorBase {
- public:
- virtual ~UnifiedHeapMarkingVisitorBase() = default;
-
- protected:
- UnifiedHeapMarkingVisitorBase(ThreadState*, v8::Isolate*, int);
-
- // Visitation methods that announce reachable wrappers to V8.
- void VisitImpl(const TraceWrapperV8Reference<v8::Value>&);
-
- v8::Isolate* const isolate_;
- v8::EmbedderHeapTracer* const controller_;
- V8ReferencesWorklist::View v8_references_worklist_;
-
- private:
- int task_id_;
-
- DISALLOW_COPY_AND_ASSIGN(UnifiedHeapMarkingVisitorBase);
-};
-
-// Same as the base visitor with the difference that it is bound to main thread.
-// Also implements various sorts of write barriers that should only be called
-// from the main thread.
-class PLATFORM_EXPORT UnifiedHeapMarkingVisitor
- : public MarkingVisitor,
- public UnifiedHeapMarkingVisitorBase {
- public:
- // Write barriers for annotating a write during incremental marking.
- static void WriteBarrier(const TraceWrapperV8Reference<v8::Value>&);
- static void WriteBarrier(v8::Isolate*, const WrapperTypeInfo*, const void*);
-
- UnifiedHeapMarkingVisitor(ThreadState*, MarkingMode, v8::Isolate*);
- ~UnifiedHeapMarkingVisitor() override = default;
-
- protected:
- using Visitor::Visit;
- void Visit(const TraceWrapperV8Reference<v8::Value>&) final;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(UnifiedHeapMarkingVisitor);
-};
-
-// Same as the base visitor with the difference that it is bound to a
-// concurrent thread.
-class PLATFORM_EXPORT ConcurrentUnifiedHeapMarkingVisitor
- : public ConcurrentMarkingVisitor,
- public UnifiedHeapMarkingVisitorBase {
- public:
- ConcurrentUnifiedHeapMarkingVisitor(ThreadState*,
- MarkingMode,
- v8::Isolate*,
- int task_id);
- ~ConcurrentUnifiedHeapMarkingVisitor() override = default;
-
-
- void FlushWorklists() override;
-
- protected:
- using Visitor::Visit;
- void Visit(const TraceWrapperV8Reference<v8::Value>&) final;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ConcurrentUnifiedHeapMarkingVisitor);
-};
-
-} // namespace blink
+#if BUILDFLAG(BLINK_HEAP_USE_V8_OILPAN)
+#include "third_party/blink/renderer/platform/heap/v8_wrapper/unified_heap_marking_visitor.h"
+#else // !BLINK_HEAP_USE_V8_OILPAN
+#include "third_party/blink/renderer/platform/heap/impl/unified_heap_marking_visitor.h"
+#endif // !BLINK_HEAP_USE_V8_OILPAN
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_UNIFIED_HEAP_MARKING_VISITOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc.h b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc.h
new file mode 100644
index 00000000000..bf8602168fa
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc.h
@@ -0,0 +1,10 @@
+// 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_V8_WRAPPER_BLINK_GC_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_BLINK_GC_H_
+
+// TODO(chromium:1056170): Implement wrapper.
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_BLINK_GC_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.h b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.h
new file mode 100644
index 00000000000..8773bd7af3d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.h
@@ -0,0 +1,10 @@
+// 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_V8_WRAPPER_BLINK_GC_MEMORY_DUMP_PROVIDER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_BLINK_GC_MEMORY_DUMP_PROVIDER_H_
+
+// TODO(chromium:1056170): Implement wrapper.
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_BLINK_GC_MEMORY_DUMP_PROVIDER_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/disallow_new_wrapper.h b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/disallow_new_wrapper.h
new file mode 100644
index 00000000000..17471d3fd27
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/disallow_new_wrapper.h
@@ -0,0 +1,10 @@
+// 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_V8_WRAPPER_DISALLOW_NEW_WRAPPER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_DISALLOW_NEW_WRAPPER_H_
+
+// TODO(chromium:1056170): Implement wrapper.
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_DISALLOW_NEW_WRAPPER_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/garbage_collected.h b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/garbage_collected.h
new file mode 100644
index 00000000000..5867016b7a0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/garbage_collected.h
@@ -0,0 +1,9 @@
+// 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_V8_WRAPPER_GARBAGE_COLLECTED_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_GARBAGE_COLLECTED_H_
+// TODO(chromium:1056170): Implement wrapper.
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_GARBAGE_COLLECTED_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/gc_task_runner.h b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/gc_task_runner.h
new file mode 100644
index 00000000000..2ef207a7c66
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/gc_task_runner.h
@@ -0,0 +1,10 @@
+// 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_V8_WRAPPER_GC_TASK_RUNNER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_GC_TASK_RUNNER_H_
+
+// TODO(chromium:1056170): Implement wrapper.
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_GC_TASK_RUNNER_H_
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
new file mode 100644
index 00000000000..5aecfbbbeda
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap.h
@@ -0,0 +1,19 @@
+// 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_V8_WRAPPER_HEAP_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_HEAP_H_
+
+#include "v8/include/cppgc/garbage-collected.h"
+
+namespace blink {
+
+template <typename T>
+using GarbageCollected = cppgc::GarbageCollected<T>;
+
+using GarbageCollectedMixin = cppgc::GarbageCollectedMixin;
+
+} // 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.h b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap_allocator.h
new file mode 100644
index 00000000000..7c5cd8d4457
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap_allocator.h
@@ -0,0 +1,10 @@
+// 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_V8_WRAPPER_HEAP_ALLOCATOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_HEAP_ALLOCATOR_H_
+
+// TODO(chromium:1056170): Implement wrapper.
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_HEAP_ALLOCATOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap_stats_collector.h b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap_stats_collector.h
new file mode 100644
index 00000000000..042d806358e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap_stats_collector.h
@@ -0,0 +1,10 @@
+// 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_V8_WRAPPER_HEAP_STATS_COLLECTOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_HEAP_STATS_COLLECTOR_H_
+
+// TODO(chromium:1056170): Implement wrapper.
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_HEAP_STATS_COLLECTOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap_traits.h b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap_traits.h
new file mode 100644
index 00000000000..59d9b9e2d4f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/heap_traits.h
@@ -0,0 +1,10 @@
+// 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_V8_WRAPPER_HEAP_TRAITS_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_HEAP_TRAITS_H_
+
+// TODO(chromium:1056170): Implement wrapper.
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_HEAP_TRAITS_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/member.h b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/member.h
new file mode 100644
index 00000000000..78f61452561
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/member.h
@@ -0,0 +1,23 @@
+// 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_V8_WRAPPER_MEMBER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_MEMBER_H_
+
+#include "v8/include/cppgc/member.h"
+
+namespace blink {
+
+template <typename T>
+using Member = cppgc::Member<T>;
+
+template <typename T>
+using WeakMember = cppgc::WeakMember<T>;
+
+template <typename T>
+using UntracedMember = cppgc::UntracedMember<T>;
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_MEMBER_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/persistent.h b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/persistent.h
new file mode 100644
index 00000000000..a7d0bc305f9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/persistent.h
@@ -0,0 +1,20 @@
+// 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_V8_WRAPPER_PERSISTENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_PERSISTENT_H_
+
+#include "v8/include/cppgc/persistent.h"
+
+namespace blink {
+
+template <typename T>
+using Persistent = cppgc::Persistent<T>;
+
+template <typename T>
+using WeakPersistent = cppgc::WeakPersistent<T>;
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_PERSISTENT_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/process_heap.h b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/process_heap.h
new file mode 100644
index 00000000000..254f163b74b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/process_heap.h
@@ -0,0 +1,10 @@
+// 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_V8_WRAPPER_PROCESS_HEAP_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_PROCESS_HEAP_H_
+
+// TODO(chromium:1056170): Implement wrapper.
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_PROCESS_HEAP_H_
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
new file mode 100644
index 00000000000..eea17788057
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.h
@@ -0,0 +1,17 @@
+// 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_V8_WRAPPER_THREAD_STATE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_THREAD_STATE_H_
+
+#include "v8/include/cppgc/prefinalizer.h"
+
+namespace blink {
+
+#define USING_PRE_FINALIZER(Class, PreFinalizer) \
+ CPPGC_USING_PRE_FINALIZER(Class, PreFinalizer)
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_THREAD_STATE_H_
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
new file mode 100644
index 00000000000..8378cf6722f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/thread_state_scopes.h
@@ -0,0 +1,10 @@
+// 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_V8_WRAPPER_THREAD_STATE_SCOPES_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_THREAD_STATE_SCOPES_H_
+
+// TODO(chromium:1056170): Implement wrapper.
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_THREAD_STATE_SCOPES_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/unified_heap_controller.h b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/unified_heap_controller.h
new file mode 100644
index 00000000000..36fe078e8e8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/unified_heap_controller.h
@@ -0,0 +1,10 @@
+// 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_V8_WRAPPER_UNIFIED_HEAP_CONTROLLER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_UNIFIED_HEAP_CONTROLLER_H_
+
+// TODO(chromium:1056170): Implement wrapper.
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_UNIFIED_HEAP_CONTROLLER_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/unified_heap_marking_visitor.h b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/unified_heap_marking_visitor.h
new file mode 100644
index 00000000000..0a4d66e2fe4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/unified_heap_marking_visitor.h
@@ -0,0 +1,10 @@
+// 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_V8_WRAPPER_UNIFIED_HEAP_MARKING_VISITOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_UNIFIED_HEAP_MARKING_VISITOR_H_
+
+// TODO(chromium:1056170): Implement wrapper.
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_UNIFIED_HEAP_MARKING_VISITOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/visitor.h b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/visitor.h
new file mode 100644
index 00000000000..abb9204f467
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/visitor.h
@@ -0,0 +1,16 @@
+// 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_V8_WRAPPER_VISITOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_VISITOR_H_
+
+#include "v8/include/cppgc/visitor.h"
+
+namespace blink {
+
+using Visitor = cppgc::Visitor;
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_V8_WRAPPER_VISITOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/visitor.h b/chromium/third_party/blink/renderer/platform/heap/visitor.h
index 7ca6427bda6..31e342005ae 100644
--- a/chromium/third_party/blink/renderer/platform/heap/visitor.h
+++ b/chromium/third_party/blink/renderer/platform/heap/visitor.h
@@ -1,328 +1,16 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
+// 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_VISITOR_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_VISITOR_H_
-#include <memory>
-#include "third_party/blink/renderer/platform/heap/blink_gc.h"
-#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/assertions.h"
-#include "third_party/blink/renderer/platform/wtf/forward.h"
-#include "third_party/blink/renderer/platform/wtf/hash_traits.h"
-#include "third_party/blink/renderer/platform/wtf/type_traits.h"
+#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-namespace base {
-class Location;
-}
-
-namespace v8 {
-class Value;
-}
-
-namespace blink {
-
-template <typename T>
-class GarbageCollected;
-class LivenessBroker;
-template <typename T>
-struct TraceTrait;
-class ThreadState;
-class Visitor;
-template <typename T>
-class TraceWrapperV8Reference;
-
-// The TraceMethodDelegate is used to convert a trace method for type T to a
-// TraceCallback. This allows us to pass a type's trace method as a parameter
-// to the PersistentNode constructor. The PersistentNode constructor needs the
-// specific trace method due an issue with the Windows compiler which
-// instantiates even unused variables. This causes problems
-// in header files where we have only forward declarations of classes.
-//
-// This interface is safe to use on concurrent threads. All accesses (reads)
-// from member are done atomically.
-template <typename T, void (T::*method)(Visitor*) const>
-struct TraceMethodDelegate {
- STATIC_ONLY(TraceMethodDelegate);
- static void Trampoline(Visitor* visitor, const void* self) {
- (reinterpret_cast<const T*>(self)->*method)(visitor);
- }
-};
-
-template <typename T, void (T::*method)(const LivenessBroker&)>
-struct WeakCallbackMethodDelegate {
- STATIC_ONLY(WeakCallbackMethodDelegate);
- static void Trampoline(const LivenessBroker& info, const void* self) {
- (reinterpret_cast<T*>(const_cast<void*>(self))->*method)(info);
- }
-};
-
-// Visitor is used to traverse Oilpan's object graph.
-class PLATFORM_EXPORT Visitor {
- USING_FAST_MALLOC(Visitor);
-
- public:
- explicit Visitor(ThreadState* state) : state_(state) {}
- virtual ~Visitor() = default;
-
- inline ThreadState* State() const { return state_; }
- inline ThreadHeap& Heap() const { return state_->Heap(); }
-
- // Static visitor implementation forwarding to dynamic interface.
-
- template <typename T>
- void TraceRoot(const T* t, const base::Location& location) {
- static_assert(sizeof(T), "T must be fully defined");
- static_assert(IsGarbageCollectedType<T>::value,
- "T needs to be a garbage collected object");
- if (!t)
- return;
- VisitRoot(t, TraceDescriptorFor(t), location);
- }
-
- template <typename T>
- void Trace(const Member<T>& t) {
- const T* value = t.GetSafe();
-
- DCHECK(!Member<T>::IsMemberHashTableDeletedValue(value));
-
- Trace(value);
- }
-
- template <typename T>
- ALWAYS_INLINE void TraceMaybeDeleted(const Member<T>& t) {
- const T* value = t.GetSafe();
-
- if (Member<T>::IsMemberHashTableDeletedValue(value))
- return;
-
- Trace<T>(value);
- }
-
- // TraceMayBeDeleted strongifies WeakMembers.
- template <typename T>
- ALWAYS_INLINE void TraceMaybeDeleted(const WeakMember<T>& t) {
- const T* value = t.GetSafe();
-
- if (WeakMember<T>::IsMemberHashTableDeletedValue(value))
- return;
-
- Trace<T>(value);
- }
-
- // Fallback methods used only when we need to trace raw pointers of T. This is
- // the case when a member is a union where we do not support members.
- template <typename T>
- void Trace(T* t) {
- Trace(const_cast<const T*>(t));
- }
- template <typename T>
- void Trace(const T* t) {
- static_assert(sizeof(T), "T must be fully defined");
- static_assert(IsGarbageCollectedType<T>::value,
- "T needs to be a garbage collected object");
- if (!t)
- return;
- Visit(t, TraceDescriptorFor(t));
- }
-
- // WeakMember version of the templated trace method. It doesn't keep
- // the traced thing alive, but will write null to the WeakMember later
- // if the pointed-to object is dead. It's lying for this to be const,
- // but the overloading resolver prioritizes constness too high when
- // picking the correct overload, so all these trace methods have to have
- // the same constness on their argument to allow the type to decide.
- template <typename T>
- void Trace(const WeakMember<T>& weak_member) {
- static_assert(sizeof(T), "T must be fully defined");
- static_assert(IsGarbageCollectedType<T>::value,
- "T needs to be a garbage collected object");
-
- const T* value = weak_member.GetSafe();
-
- if (!value)
- return;
-
- DCHECK(!WeakMember<T>::IsMemberHashTableDeletedValue(value));
- VisitWeak(value, &weak_member, TraceDescriptorFor(value),
- &HandleWeakCell<T>);
- }
-
- // Fallback trace method for part objects to allow individual trace methods
- // to trace through a part object with visitor->trace(m_partObject). This
- // takes a const argument, because otherwise it will match too eagerly: a
- // non-const argument would match a non-const Vector<T>& argument better
- // than the specialization that takes const Vector<T>&. For a similar reason,
- // the other specializations take a const argument even though they are
- // usually used with non-const arguments, otherwise this function would match
- // too well.
- template <typename T>
- void Trace(const T& t) {
- static_assert(sizeof(T), "T must be fully defined");
- if (std::is_polymorphic<T>::value) {
- const intptr_t vtable = *reinterpret_cast<const intptr_t*>(&t);
- if (!vtable)
- return;
- }
- TraceTrait<T>::Trace(this, &t);
- }
-
- template <typename T>
- void TraceEphemeron(const WeakMember<T>& key,
- const void* value,
- TraceCallback value_trace_callback) {
- const T* t = key.GetSafe();
- if (!t)
- return;
- VisitEphemeron(TraceDescriptorFor(t).base_object_payload, value,
- value_trace_callback);
- }
-
- template <typename T>
- void TraceWeakContainer(const T* object,
- const T* const* slot,
- TraceDescriptor strong_desc,
- TraceDescriptor weak_dec,
- WeakCallback weak_callback,
- const void* weak_callback_parameter) {
- static_assert(sizeof(T), "T must be fully defined");
- static_assert(IsGarbageCollectedType<T>::value,
- "T needs to be a garbage collected object");
- VisitWeakContainer(reinterpret_cast<const void*>(object),
- reinterpret_cast<const void* const*>(slot), strong_desc,
- weak_dec, weak_callback, weak_callback_parameter);
- }
-
- template <typename T>
- void TraceMovablePointer(const T* const* slot) {
- RegisterMovableSlot(reinterpret_cast<const void* const*>(slot));
- }
-
- // Cross-component tracing interface.
- template <typename V8Type>
- void Trace(const TraceWrapperV8Reference<V8Type>& v8reference) {
- Visit(v8reference.template Cast<v8::Value>());
- }
-
- // Dynamic visitor interface.
-
- // Adds a |callback| that is invoked with |parameter| after liveness has been
- // computed on the whole object graph. The |callback| may use the provided
- // |LivenessBroker| to determine whether an object is considered alive or
- // dead.
- //
- // - Upon returning from the callback all references to dead objects must have
- // been cleared.
- // - Any operation that extends the object graph, including allocation
- // or reviving objects, is prohibited.
- // - Clearing out pointers is allowed.
- // - Removing elements from heap collections is allowed as these collections
- // are aware of custom weakness and won't resize their backings.
- virtual void RegisterWeakCallback(WeakCallback callback,
- const void* parameter) {}
-
- // Registers an instance method using |RegisterWeakCallback|. See description
- // below.
- template <typename T, void (T::*method)(const LivenessBroker&)>
- void RegisterWeakCallbackMethod(const T* obj) {
- RegisterWeakCallback(&WeakCallbackMethodDelegate<T, method>::Trampoline,
- obj);
- }
-
- // Returns whether the visitor is used in a concurrent setting.
- virtual bool IsConcurrent() const { return false; }
-
- // Defers invoking |desc| to the main thread when running concurrently.
- // Returns true if |desc| has been queued for later processing and false if
- // running in a non-concurrent setting.
- //
- // This can be used to defer processing data structures to the main thread
- // when support for concurrent processing is missing.
- virtual bool DeferredTraceIfConcurrent(TraceDescriptor, size_t) {
- return false;
- }
-
- protected:
- // Visits an object through a strong reference.
- virtual void Visit(const void*, TraceDescriptor) {}
-
- // Visits an object through a weak reference.
- virtual void VisitWeak(const void*,
- const void*,
- TraceDescriptor,
- WeakCallback) {}
-
- // Visits cross-component references to V8.
- virtual void Visit(const TraceWrapperV8Reference<v8::Value>&) {}
-
- virtual void VisitRoot(const void* t,
- TraceDescriptor desc,
- const base::Location&) {
- Visit(t, desc);
- }
-
- // Visits ephemeron pairs which are a combination of weak and strong keys and
- // values.
- virtual void VisitEphemeron(const void*, const void*, TraceCallback) {}
-
- // Visits a container |object| holding ephemeron pairs held from |slot|. The
- // descriptor |strong_desc| can be used to enforce strong treatment of
- // |object|. The |weak_desc| descriptor is invoked repeatedly until no
- // more new objects are found. It is expected that |weak_desc| processing
- // ultimately yields in a call to VisitEphemeron. After marking all reachable
- // objects, |weak_callback| is invoked with |weak_callback_parameter|. It is
- // expected that this callback is used to reset non-live entries in the
- // ephemeron container.
- virtual void VisitWeakContainer(const void* object,
- const void* const* slot,
- TraceDescriptor strong_desc,
- TraceDescriptor weak_desc,
- WeakCallback weak_callback,
- const void* weak_callback_parameter) {}
-
- virtual void RegisterMovableSlot(const void* const* slot) {}
-
- template <typename T>
- static TraceDescriptor TraceDescriptorFor(const T* traceable) {
- return TraceTrait<T>::GetTraceDescriptor(traceable);
- }
-
- private:
- template <typename T>
- static void HandleWeakCell(const LivenessBroker&, const void*);
-
- ThreadState* const state_;
-};
-
-} // namespace blink
+#if BUILDFLAG(BLINK_HEAP_USE_V8_OILPAN)
+#include "third_party/blink/renderer/platform/heap/v8_wrapper/visitor.h"
+#else // !BLINK_HEAP_USE_V8_OILPAN
+#include "third_party/blink/renderer/platform/heap/impl/visitor.h"
+#endif // !BLINK_HEAP_USE_V8_OILPAN
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_VISITOR_H_