libv8-node 15.14.0.1-x86_64-linux → 17.9.1.0-x86_64-linux

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libv8-node/location.rb +1 -1
  3. data/ext/libv8-node/paths.rb +5 -1
  4. data/lib/libv8/node/version.rb +3 -3
  5. data/vendor/v8/include/cppgc/allocation.h +110 -44
  6. data/vendor/v8/include/cppgc/common.h +9 -6
  7. data/vendor/v8/include/cppgc/cross-thread-persistent.h +465 -0
  8. data/vendor/v8/include/cppgc/custom-space.h +37 -2
  9. data/vendor/v8/include/cppgc/default-platform.h +47 -48
  10. data/vendor/v8/include/cppgc/ephemeron-pair.h +30 -0
  11. data/vendor/v8/include/cppgc/explicit-management.h +82 -0
  12. data/vendor/v8/include/cppgc/garbage-collected.h +4 -3
  13. data/vendor/v8/include/cppgc/heap-consistency.h +253 -0
  14. data/vendor/v8/include/cppgc/heap-state.h +70 -0
  15. data/vendor/v8/include/cppgc/heap-statistics.h +120 -0
  16. data/vendor/v8/include/cppgc/heap.h +68 -6
  17. data/vendor/v8/include/cppgc/internal/api-constants.h +3 -3
  18. data/vendor/v8/include/cppgc/internal/caged-heap-local-data.h +4 -3
  19. data/vendor/v8/include/cppgc/internal/compiler-specific.h +2 -2
  20. data/vendor/v8/include/cppgc/internal/finalizer-trait.h +2 -0
  21. data/vendor/v8/include/cppgc/internal/gc-info.h +124 -13
  22. data/vendor/v8/include/cppgc/internal/name-trait.h +122 -0
  23. data/vendor/v8/include/cppgc/internal/persistent-node.h +94 -6
  24. data/vendor/v8/include/cppgc/internal/pointer-policies.h +81 -29
  25. data/vendor/v8/include/cppgc/internal/prefinalizer-handler.h +1 -1
  26. data/vendor/v8/include/cppgc/internal/write-barrier.h +398 -35
  27. data/vendor/v8/include/cppgc/liveness-broker.h +11 -2
  28. data/vendor/v8/include/cppgc/macros.h +2 -0
  29. data/vendor/v8/include/cppgc/member.h +87 -25
  30. data/vendor/v8/include/cppgc/name-provider.h +65 -0
  31. data/vendor/v8/include/cppgc/object-size-trait.h +58 -0
  32. data/vendor/v8/include/cppgc/persistent.h +41 -11
  33. data/vendor/v8/include/cppgc/platform.h +49 -25
  34. data/vendor/v8/include/cppgc/prefinalizer.h +2 -2
  35. data/vendor/v8/include/cppgc/process-heap-statistics.h +36 -0
  36. data/vendor/v8/include/cppgc/sentinel-pointer.h +32 -0
  37. data/vendor/v8/include/cppgc/source-location.h +2 -1
  38. data/vendor/v8/include/cppgc/testing.h +99 -0
  39. data/vendor/v8/include/cppgc/trace-trait.h +8 -3
  40. data/vendor/v8/include/cppgc/type-traits.h +157 -19
  41. data/vendor/v8/include/cppgc/visitor.h +194 -28
  42. data/vendor/v8/include/libplatform/libplatform.h +11 -0
  43. data/vendor/v8/include/libplatform/v8-tracing.h +2 -0
  44. data/vendor/v8/include/v8-array-buffer.h +433 -0
  45. data/vendor/v8/include/v8-callbacks.h +377 -0
  46. data/vendor/v8/include/v8-container.h +129 -0
  47. data/vendor/v8/include/v8-context.h +418 -0
  48. data/vendor/v8/include/v8-cppgc.h +261 -159
  49. data/vendor/v8/include/v8-data.h +65 -0
  50. data/vendor/v8/include/v8-date.h +43 -0
  51. data/vendor/v8/include/v8-debug.h +151 -0
  52. data/vendor/v8/include/v8-embedder-heap.h +238 -0
  53. data/vendor/v8/include/v8-exception.h +224 -0
  54. data/vendor/v8/include/v8-extension.h +62 -0
  55. data/vendor/v8/include/v8-external.h +37 -0
  56. data/vendor/v8/include/v8-fast-api-calls.h +652 -152
  57. data/vendor/v8/include/v8-forward.h +81 -0
  58. data/vendor/v8/include/v8-function-callback.h +475 -0
  59. data/vendor/v8/include/v8-function.h +122 -0
  60. data/vendor/v8/include/v8-initialization.h +282 -0
  61. data/vendor/v8/include/v8-inspector.h +33 -25
  62. data/vendor/v8/include/v8-internal.h +178 -31
  63. data/vendor/v8/include/v8-isolate.h +1662 -0
  64. data/vendor/v8/include/v8-json.h +47 -0
  65. data/vendor/v8/include/v8-local-handle.h +459 -0
  66. data/vendor/v8/include/v8-locker.h +148 -0
  67. data/vendor/v8/include/v8-maybe.h +137 -0
  68. data/vendor/v8/include/v8-memory-span.h +43 -0
  69. data/vendor/v8/include/v8-message.h +241 -0
  70. data/vendor/v8/include/v8-metrics.h +114 -9
  71. data/vendor/v8/include/v8-microtask-queue.h +152 -0
  72. data/vendor/v8/include/v8-microtask.h +28 -0
  73. data/vendor/v8/include/v8-object.h +770 -0
  74. data/vendor/v8/include/v8-persistent-handle.h +590 -0
  75. data/vendor/v8/include/v8-platform.h +74 -25
  76. data/vendor/v8/include/v8-primitive-object.h +118 -0
  77. data/vendor/v8/include/v8-primitive.h +858 -0
  78. data/vendor/v8/include/v8-profiler.h +72 -9
  79. data/vendor/v8/include/v8-promise.h +174 -0
  80. data/vendor/v8/include/v8-proxy.h +50 -0
  81. data/vendor/v8/include/v8-regexp.h +105 -0
  82. data/vendor/v8/include/v8-script.h +771 -0
  83. data/vendor/v8/include/v8-snapshot.h +198 -0
  84. data/vendor/v8/include/v8-statistics.h +215 -0
  85. data/vendor/v8/include/v8-template.h +1052 -0
  86. data/vendor/v8/include/v8-traced-handle.h +605 -0
  87. data/vendor/v8/include/v8-typed-array.h +282 -0
  88. data/vendor/v8/include/v8-unwinder-state.h +31 -0
  89. data/vendor/v8/include/v8-unwinder.h +129 -0
  90. data/vendor/v8/include/v8-util.h +8 -2
  91. data/vendor/v8/include/v8-value-serializer.h +249 -0
  92. data/vendor/v8/include/v8-value.h +526 -0
  93. data/vendor/v8/include/v8-version.h +3 -3
  94. data/vendor/v8/include/v8-wasm.h +245 -0
  95. data/vendor/v8/include/v8-weak-callback-info.h +73 -0
  96. data/vendor/v8/include/v8.h +41 -12050
  97. data/vendor/v8/include/v8config.h +87 -11
  98. data/vendor/v8/{out.gn → x86_64-linux}/libv8/obj/libv8_monolith.a +0 -0
  99. metadata +60 -6
  100. data/vendor/v8/include/cppgc/internal/process-heap.h +0 -34
@@ -10,6 +10,7 @@
10
10
  #include "cppgc/internal/api-constants.h"
11
11
  #include "cppgc/internal/logging.h"
12
12
  #include "cppgc/platform.h"
13
+ #include "v8config.h" // NOLINT(build/include_directory)
13
14
 
14
15
  namespace cppgc {
15
16
  namespace internal {
@@ -52,10 +53,10 @@ static_assert(sizeof(AgeTable) == 1 * api_constants::kMB,
52
53
  #endif // CPPGC_YOUNG_GENERATION
53
54
 
54
55
  struct CagedHeapLocalData final {
55
- explicit CagedHeapLocalData(HeapBase* heap_base) : heap_base(heap_base) {}
56
+ CagedHeapLocalData(HeapBase&, PageAllocator&);
56
57
 
57
- bool is_marking_in_progress = false;
58
- HeapBase* heap_base = nullptr;
58
+ bool is_incremental_marking_in_progress = false;
59
+ HeapBase& heap_base;
59
60
  #if defined(CPPGC_YOUNG_GENERATION)
60
61
  AgeTable age_table;
61
62
  #endif
@@ -21,13 +21,13 @@ namespace cppgc {
21
21
 
22
22
  // [[no_unique_address]] comes in C++20 but supported in clang with -std >=
23
23
  // c++11.
24
- #if CPPGC_HAS_CPP_ATTRIBUTE(no_unique_address) // NOLINTNEXTLINE
24
+ #if CPPGC_HAS_CPP_ATTRIBUTE(no_unique_address)
25
25
  #define CPPGC_NO_UNIQUE_ADDRESS [[no_unique_address]]
26
26
  #else
27
27
  #define CPPGC_NO_UNIQUE_ADDRESS
28
28
  #endif
29
29
 
30
- #if CPPGC_HAS_ATTRIBUTE(unused) // NOLINTNEXTLINE
30
+ #if CPPGC_HAS_ATTRIBUTE(unused)
31
31
  #define CPPGC_UNUSED __attribute__((unused))
32
32
  #else
33
33
  #define CPPGC_UNUSED
@@ -76,6 +76,8 @@ struct FinalizerTrait {
76
76
  }
77
77
 
78
78
  public:
79
+ static constexpr bool HasFinalizer() { return kNonTrivialFinalizer; }
80
+
79
81
  // The callback used to finalize an object of type T.
80
82
  static constexpr FinalizationCallback kCallback =
81
83
  kNonTrivialFinalizer ? Finalize : nullptr;
@@ -5,9 +5,12 @@
5
5
  #ifndef INCLUDE_CPPGC_INTERNAL_GC_INFO_H_
6
6
  #define INCLUDE_CPPGC_INTERNAL_GC_INFO_H_
7
7
 
8
- #include <stdint.h>
8
+ #include <atomic>
9
+ #include <cstdint>
10
+ #include <type_traits>
9
11
 
10
12
  #include "cppgc/internal/finalizer-trait.h"
13
+ #include "cppgc/internal/name-trait.h"
11
14
  #include "cppgc/trace-trait.h"
12
15
  #include "v8config.h" // NOLINT(build/include_directory)
13
16
 
@@ -16,26 +19,134 @@ namespace internal {
16
19
 
17
20
  using GCInfoIndex = uint16_t;
18
21
 
19
- class V8_EXPORT RegisteredGCInfoIndex final {
20
- public:
21
- RegisteredGCInfoIndex(FinalizationCallback finalization_callback,
22
- TraceCallback trace_callback, bool has_v_table);
23
- GCInfoIndex GetIndex() const { return index_; }
22
+ struct V8_EXPORT EnsureGCInfoIndexTrait final {
23
+ // Acquires a new GC info object and returns the index. In addition, also
24
+ // updates `registered_index` atomically.
25
+ template <typename T>
26
+ V8_INLINE static GCInfoIndex EnsureIndex(
27
+ std::atomic<GCInfoIndex>& registered_index) {
28
+ return EnsureGCInfoIndexTraitDispatch<T>{}(registered_index);
29
+ }
24
30
 
25
31
  private:
26
- const GCInfoIndex index_;
32
+ template <typename T, bool = std::is_polymorphic<T>::value,
33
+ bool = FinalizerTrait<T>::HasFinalizer(),
34
+ bool = NameTrait<T>::HasNonHiddenName()>
35
+ struct EnsureGCInfoIndexTraitDispatch;
36
+
37
+ static GCInfoIndex EnsureGCInfoIndexPolymorphic(std::atomic<GCInfoIndex>&,
38
+ TraceCallback,
39
+ FinalizationCallback,
40
+ NameCallback);
41
+ static GCInfoIndex EnsureGCInfoIndexPolymorphic(std::atomic<GCInfoIndex>&,
42
+ TraceCallback,
43
+ FinalizationCallback);
44
+ static GCInfoIndex EnsureGCInfoIndexPolymorphic(std::atomic<GCInfoIndex>&,
45
+ TraceCallback, NameCallback);
46
+ static GCInfoIndex EnsureGCInfoIndexPolymorphic(std::atomic<GCInfoIndex>&,
47
+ TraceCallback);
48
+ static GCInfoIndex EnsureGCInfoIndexNonPolymorphic(std::atomic<GCInfoIndex>&,
49
+ TraceCallback,
50
+ FinalizationCallback,
51
+
52
+ NameCallback);
53
+ static GCInfoIndex EnsureGCInfoIndexNonPolymorphic(std::atomic<GCInfoIndex>&,
54
+ TraceCallback,
55
+ FinalizationCallback);
56
+ static GCInfoIndex EnsureGCInfoIndexNonPolymorphic(std::atomic<GCInfoIndex>&,
57
+ TraceCallback,
58
+ NameCallback);
59
+ static GCInfoIndex EnsureGCInfoIndexNonPolymorphic(std::atomic<GCInfoIndex>&,
60
+ TraceCallback);
61
+ };
62
+
63
+ #define DISPATCH(is_polymorphic, has_finalizer, has_non_hidden_name, function) \
64
+ template <typename T> \
65
+ struct EnsureGCInfoIndexTrait::EnsureGCInfoIndexTraitDispatch< \
66
+ T, is_polymorphic, has_finalizer, has_non_hidden_name> { \
67
+ V8_INLINE GCInfoIndex \
68
+ operator()(std::atomic<GCInfoIndex>& registered_index) { \
69
+ return function; \
70
+ } \
71
+ };
72
+
73
+ // --------------------------------------------------------------------- //
74
+ // DISPATCH(is_polymorphic, has_finalizer, has_non_hidden_name, function)
75
+ // --------------------------------------------------------------------- //
76
+ DISPATCH(true, true, true, //
77
+ EnsureGCInfoIndexPolymorphic(registered_index, //
78
+ TraceTrait<T>::Trace, //
79
+ FinalizerTrait<T>::kCallback, //
80
+ NameTrait<T>::GetName)) //
81
+ DISPATCH(true, true, false, //
82
+ EnsureGCInfoIndexPolymorphic(registered_index, //
83
+ TraceTrait<T>::Trace, //
84
+ FinalizerTrait<T>::kCallback)) //
85
+ DISPATCH(true, false, true, //
86
+ EnsureGCInfoIndexPolymorphic(registered_index, //
87
+ TraceTrait<T>::Trace, //
88
+ NameTrait<T>::GetName)) //
89
+ DISPATCH(true, false, false, //
90
+ EnsureGCInfoIndexPolymorphic(registered_index, //
91
+ TraceTrait<T>::Trace)) //
92
+ DISPATCH(false, true, true, //
93
+ EnsureGCInfoIndexNonPolymorphic(registered_index, //
94
+ TraceTrait<T>::Trace, //
95
+ FinalizerTrait<T>::kCallback, //
96
+ NameTrait<T>::GetName)) //
97
+ DISPATCH(false, true, false, //
98
+ EnsureGCInfoIndexNonPolymorphic(registered_index, //
99
+ TraceTrait<T>::Trace, //
100
+ FinalizerTrait<T>::kCallback)) //
101
+ DISPATCH(false, false, true, //
102
+ EnsureGCInfoIndexNonPolymorphic(registered_index, //
103
+ TraceTrait<T>::Trace, //
104
+ NameTrait<T>::GetName)) //
105
+ DISPATCH(false, false, false, //
106
+ EnsureGCInfoIndexNonPolymorphic(registered_index, //
107
+ TraceTrait<T>::Trace)) //
108
+
109
+ #undef DISPATCH
110
+
111
+ // Fold types based on finalizer behavior. Note that finalizer characteristics
112
+ // align with trace behavior, i.e., destructors are virtual when trace methods
113
+ // are and vice versa.
114
+ template <typename T, typename ParentMostGarbageCollectedType>
115
+ struct GCInfoFolding {
116
+ static constexpr bool kHasVirtualDestructorAtBase =
117
+ std::has_virtual_destructor<ParentMostGarbageCollectedType>::value;
118
+ static constexpr bool kBothTypesAreTriviallyDestructible =
119
+ std::is_trivially_destructible<ParentMostGarbageCollectedType>::value &&
120
+ std::is_trivially_destructible<T>::value;
121
+ static constexpr bool kHasCustomFinalizerDispatchAtBase =
122
+ internal::HasFinalizeGarbageCollectedObject<
123
+ ParentMostGarbageCollectedType>::value;
124
+ #ifdef CPPGC_SUPPORTS_OBJECT_NAMES
125
+ static constexpr bool kWantsDetailedObjectNames = true;
126
+ #else // !CPPGC_SUPPORTS_OBJECT_NAMES
127
+ static constexpr bool kWantsDetailedObjectNames = false;
128
+ #endif // !CPPGC_SUPPORTS_OBJECT_NAMES
129
+
130
+ // Folding would regresses name resolution when deriving names from C++
131
+ // class names as it would just folds a name to the base class name.
132
+ using ResultType = std::conditional_t<(kHasVirtualDestructorAtBase ||
133
+ kBothTypesAreTriviallyDestructible ||
134
+ kHasCustomFinalizerDispatchAtBase) &&
135
+ !kWantsDetailedObjectNames,
136
+ ParentMostGarbageCollectedType, T>;
27
137
  };
28
138
 
29
139
  // Trait determines how the garbage collector treats objects wrt. to traversing,
30
140
  // finalization, and naming.
31
141
  template <typename T>
32
- struct GCInfoTrait {
33
- static GCInfoIndex Index() {
142
+ struct GCInfoTrait final {
143
+ V8_INLINE static GCInfoIndex Index() {
34
144
  static_assert(sizeof(T), "T must be fully defined");
35
- static const RegisteredGCInfoIndex registered_index(
36
- FinalizerTrait<T>::kCallback, TraceTrait<T>::Trace,
37
- std::is_polymorphic<T>::value);
38
- return registered_index.GetIndex();
145
+ static std::atomic<GCInfoIndex>
146
+ registered_index; // Uses zero initialization.
147
+ const GCInfoIndex index = registered_index.load(std::memory_order_acquire);
148
+ return index ? index
149
+ : EnsureGCInfoIndexTrait::EnsureIndex<T>(registered_index);
39
150
  }
40
151
  };
41
152
 
@@ -0,0 +1,122 @@
1
+ // Copyright 2020 the V8 project authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ #ifndef INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_
6
+ #define INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_
7
+
8
+ #include <cstddef>
9
+ #include <type_traits>
10
+
11
+ #include "cppgc/name-provider.h"
12
+ #include "v8config.h" // NOLINT(build/include_directory)
13
+
14
+ namespace cppgc {
15
+ namespace internal {
16
+
17
+ #if CPPGC_SUPPORTS_OBJECT_NAMES && defined(__clang__)
18
+ #define CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME 1
19
+
20
+ // Provides constexpr c-string storage for a name of fixed |Size| characters.
21
+ // Automatically appends terminating 0 byte.
22
+ template <size_t Size>
23
+ struct NameBuffer {
24
+ char name[Size + 1]{};
25
+
26
+ static constexpr NameBuffer FromCString(const char* str) {
27
+ NameBuffer result;
28
+ for (size_t i = 0; i < Size; ++i) result.name[i] = str[i];
29
+ result.name[Size] = 0;
30
+ return result;
31
+ }
32
+ };
33
+
34
+ template <typename T>
35
+ const char* GetTypename() {
36
+ static constexpr char kSelfPrefix[] =
37
+ "const char *cppgc::internal::GetTypename() [T =";
38
+ static_assert(__builtin_strncmp(__PRETTY_FUNCTION__, kSelfPrefix,
39
+ sizeof(kSelfPrefix) - 1) == 0,
40
+ "The prefix must match");
41
+ static constexpr const char* kTypenameStart =
42
+ __PRETTY_FUNCTION__ + sizeof(kSelfPrefix);
43
+ static constexpr size_t kTypenameSize =
44
+ __builtin_strlen(__PRETTY_FUNCTION__) - sizeof(kSelfPrefix) - 1;
45
+ // NameBuffer is an indirection that is needed to make sure that only a
46
+ // substring of __PRETTY_FUNCTION__ gets materialized in the binary.
47
+ static constexpr auto buffer =
48
+ NameBuffer<kTypenameSize>::FromCString(kTypenameStart);
49
+ return buffer.name;
50
+ }
51
+
52
+ #else
53
+ #define CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME 0
54
+ #endif
55
+
56
+ struct HeapObjectName {
57
+ const char* value;
58
+ bool name_was_hidden;
59
+ };
60
+
61
+ class V8_EXPORT NameTraitBase {
62
+ protected:
63
+ static HeapObjectName GetNameFromTypeSignature(const char*);
64
+ };
65
+
66
+ // Trait that specifies how the garbage collector retrieves the name for a
67
+ // given object.
68
+ template <typename T>
69
+ class NameTrait final : public NameTraitBase {
70
+ public:
71
+ static constexpr bool HasNonHiddenName() {
72
+ #if CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME
73
+ return true;
74
+ #elif CPPGC_SUPPORTS_OBJECT_NAMES
75
+ return true;
76
+ #else // !CPPGC_SUPPORTS_OBJECT_NAMES
77
+ return std::is_base_of<NameProvider, T>::value;
78
+ #endif // !CPPGC_SUPPORTS_OBJECT_NAMES
79
+ }
80
+
81
+ static HeapObjectName GetName(const void* obj) {
82
+ return GetNameFor(static_cast<const T*>(obj));
83
+ }
84
+
85
+ private:
86
+ static HeapObjectName GetNameFor(const NameProvider* name_provider) {
87
+ return {name_provider->GetHumanReadableName(), false};
88
+ }
89
+
90
+ static HeapObjectName GetNameFor(...) {
91
+ #if CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME
92
+ return {GetTypename<T>(), false};
93
+ #elif CPPGC_SUPPORTS_OBJECT_NAMES
94
+
95
+ #if defined(V8_CC_GNU)
96
+ #define PRETTY_FUNCTION_VALUE __PRETTY_FUNCTION__
97
+ #elif defined(V8_CC_MSVC)
98
+ #define PRETTY_FUNCTION_VALUE __FUNCSIG__
99
+ #else
100
+ #define PRETTY_FUNCTION_VALUE nullptr
101
+ #endif
102
+
103
+ static const HeapObjectName leaky_name =
104
+ GetNameFromTypeSignature(PRETTY_FUNCTION_VALUE);
105
+ return {leaky_name, false};
106
+
107
+ #undef PRETTY_FUNCTION_VALUE
108
+
109
+ #else // !CPPGC_SUPPORTS_OBJECT_NAMES
110
+ return {NameProvider::kHiddenName, true};
111
+ #endif // !CPPGC_SUPPORTS_OBJECT_NAMES
112
+ }
113
+ };
114
+
115
+ using NameCallback = HeapObjectName (*)(const void*);
116
+
117
+ } // namespace internal
118
+ } // namespace cppgc
119
+
120
+ #undef CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME
121
+
122
+ #endif // INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_
@@ -19,7 +19,9 @@ class Visitor;
19
19
 
20
20
  namespace internal {
21
21
 
22
- // PersistentNode represesents a variant of two states:
22
+ class CrossThreadPersistentRegion;
23
+
24
+ // PersistentNode represents a variant of two states:
23
25
  // 1) traceable node with a back pointer to the Persistent object;
24
26
  // 2) freelist entry.
25
27
  class PersistentNode final {
@@ -30,6 +32,7 @@ class PersistentNode final {
30
32
  PersistentNode& operator=(const PersistentNode&) = delete;
31
33
 
32
34
  void InitializeAsUsedNode(void* owner, TraceCallback trace) {
35
+ CPPGC_DCHECK(trace);
33
36
  owner_ = owner;
34
37
  trace_ = trace;
35
38
  }
@@ -72,16 +75,16 @@ class PersistentNode final {
72
75
  TraceCallback trace_ = nullptr;
73
76
  };
74
77
 
75
- class V8_EXPORT PersistentRegion final {
78
+ class V8_EXPORT PersistentRegionBase {
76
79
  using PersistentNodeSlots = std::array<PersistentNode, 256u>;
77
80
 
78
81
  public:
79
- PersistentRegion() = default;
82
+ PersistentRegionBase() = default;
80
83
  // Clears Persistent fields to avoid stale pointers after heap teardown.
81
- ~PersistentRegion();
84
+ ~PersistentRegionBase();
82
85
 
83
- PersistentRegion(const PersistentRegion&) = delete;
84
- PersistentRegion& operator=(const PersistentRegion&) = delete;
86
+ PersistentRegionBase(const PersistentRegionBase&) = delete;
87
+ PersistentRegionBase& operator=(const PersistentRegionBase&) = delete;
85
88
 
86
89
  PersistentNode* AllocateNode(void* owner, TraceCallback trace) {
87
90
  if (!free_list_head_) {
@@ -89,24 +92,109 @@ class V8_EXPORT PersistentRegion final {
89
92
  }
90
93
  PersistentNode* node = free_list_head_;
91
94
  free_list_head_ = free_list_head_->FreeListNext();
95
+ CPPGC_DCHECK(!node->IsUsed());
92
96
  node->InitializeAsUsedNode(owner, trace);
97
+ nodes_in_use_++;
93
98
  return node;
94
99
  }
95
100
 
96
101
  void FreeNode(PersistentNode* node) {
102
+ CPPGC_DCHECK(node);
103
+ CPPGC_DCHECK(node->IsUsed());
97
104
  node->InitializeAsFreeNode(free_list_head_);
98
105
  free_list_head_ = node;
106
+ CPPGC_DCHECK(nodes_in_use_ > 0);
107
+ nodes_in_use_--;
99
108
  }
100
109
 
101
110
  void Trace(Visitor*);
102
111
 
103
112
  size_t NodesInUse() const;
104
113
 
114
+ void ClearAllUsedNodes();
115
+
105
116
  private:
106
117
  void EnsureNodeSlots();
107
118
 
119
+ template <typename PersistentBaseClass>
120
+ void ClearAllUsedNodes();
121
+
108
122
  std::vector<std::unique_ptr<PersistentNodeSlots>> nodes_;
109
123
  PersistentNode* free_list_head_ = nullptr;
124
+ size_t nodes_in_use_ = 0;
125
+
126
+ friend class CrossThreadPersistentRegion;
127
+ };
128
+
129
+ // Variant of PersistentRegionBase that checks whether the allocation and
130
+ // freeing happens only on the thread that created the region.
131
+ class V8_EXPORT PersistentRegion final : public PersistentRegionBase {
132
+ public:
133
+ PersistentRegion();
134
+ // Clears Persistent fields to avoid stale pointers after heap teardown.
135
+ ~PersistentRegion() = default;
136
+
137
+ PersistentRegion(const PersistentRegion&) = delete;
138
+ PersistentRegion& operator=(const PersistentRegion&) = delete;
139
+
140
+ V8_INLINE PersistentNode* AllocateNode(void* owner, TraceCallback trace) {
141
+ #if V8_ENABLE_CHECKS
142
+ CheckIsCreationThread();
143
+ #endif // V8_ENABLE_CHECKS
144
+ return PersistentRegionBase::AllocateNode(owner, trace);
145
+ }
146
+
147
+ V8_INLINE void FreeNode(PersistentNode* node) {
148
+ #if V8_ENABLE_CHECKS
149
+ CheckIsCreationThread();
150
+ #endif // V8_ENABLE_CHECKS
151
+ PersistentRegionBase::FreeNode(node);
152
+ }
153
+
154
+ private:
155
+ void CheckIsCreationThread();
156
+
157
+ int creation_thread_id_;
158
+ };
159
+
160
+ // CrossThreadPersistent uses PersistentRegionBase but protects it using this
161
+ // lock when needed.
162
+ class V8_EXPORT PersistentRegionLock final {
163
+ public:
164
+ PersistentRegionLock();
165
+ ~PersistentRegionLock();
166
+
167
+ static void AssertLocked();
168
+ };
169
+
170
+ // Variant of PersistentRegionBase that checks whether the PersistentRegionLock
171
+ // is locked.
172
+ class V8_EXPORT CrossThreadPersistentRegion final
173
+ : protected PersistentRegionBase {
174
+ public:
175
+ CrossThreadPersistentRegion() = default;
176
+ // Clears Persistent fields to avoid stale pointers after heap teardown.
177
+ ~CrossThreadPersistentRegion();
178
+
179
+ CrossThreadPersistentRegion(const CrossThreadPersistentRegion&) = delete;
180
+ CrossThreadPersistentRegion& operator=(const CrossThreadPersistentRegion&) =
181
+ delete;
182
+
183
+ V8_INLINE PersistentNode* AllocateNode(void* owner, TraceCallback trace) {
184
+ PersistentRegionLock::AssertLocked();
185
+ return PersistentRegionBase::AllocateNode(owner, trace);
186
+ }
187
+
188
+ V8_INLINE void FreeNode(PersistentNode* node) {
189
+ PersistentRegionLock::AssertLocked();
190
+ PersistentRegionBase::FreeNode(node);
191
+ }
192
+
193
+ void Trace(Visitor*);
194
+
195
+ size_t NodesInUse() const;
196
+
197
+ void ClearAllUsedNodes();
110
198
  };
111
199
 
112
200
  } // namespace internal
@@ -9,13 +9,17 @@
9
9
  #include <type_traits>
10
10
 
11
11
  #include "cppgc/internal/write-barrier.h"
12
+ #include "cppgc/sentinel-pointer.h"
12
13
  #include "cppgc/source-location.h"
14
+ #include "cppgc/type-traits.h"
13
15
  #include "v8config.h" // NOLINT(build/include_directory)
14
16
 
15
17
  namespace cppgc {
16
18
  namespace internal {
17
19
 
20
+ class HeapBase;
18
21
  class PersistentRegion;
22
+ class CrossThreadPersistentRegion;
19
23
 
20
24
  // Tags to distinguish between strong and weak member types.
21
25
  class StrongMemberTag;
@@ -28,7 +32,17 @@ struct DijkstraWriteBarrierPolicy {
28
32
  // barrier doesn't break the tri-color invariant.
29
33
  }
30
34
  static void AssigningBarrier(const void* slot, const void* value) {
31
- WriteBarrier::MarkingBarrier(slot, value);
35
+ WriteBarrier::Params params;
36
+ switch (WriteBarrier::GetWriteBarrierType(slot, value, params)) {
37
+ case WriteBarrier::Type::kGenerational:
38
+ WriteBarrier::GenerationalBarrier(params, slot);
39
+ break;
40
+ case WriteBarrier::Type::kMarking:
41
+ WriteBarrier::DijkstraMarkingBarrier(params, value);
42
+ break;
43
+ case WriteBarrier::Type::kNone:
44
+ break;
45
+ }
32
46
  }
33
47
  };
34
48
 
@@ -37,31 +51,69 @@ struct NoWriteBarrierPolicy {
37
51
  static void AssigningBarrier(const void*, const void*) {}
38
52
  };
39
53
 
40
- class V8_EXPORT EnabledCheckingPolicy {
54
+ class V8_EXPORT SameThreadEnabledCheckingPolicyBase {
41
55
  protected:
42
- EnabledCheckingPolicy();
43
- void CheckPointer(const void* ptr);
56
+ void CheckPointerImpl(const void* ptr, bool points_to_payload,
57
+ bool check_off_heap_assignments);
58
+
59
+ const HeapBase* heap_ = nullptr;
60
+ };
61
+
62
+ template <bool kCheckOffHeapAssignments>
63
+ class V8_EXPORT SameThreadEnabledCheckingPolicy
64
+ : private SameThreadEnabledCheckingPolicyBase {
65
+ protected:
66
+ template <typename T>
67
+ void CheckPointer(const T* ptr) {
68
+ if (!ptr || (kSentinelPointer == ptr)) return;
69
+
70
+ CheckPointersImplTrampoline<T>::Call(this, ptr);
71
+ }
44
72
 
45
73
  private:
46
- void* impl_;
74
+ template <typename T, bool = IsCompleteV<T>>
75
+ struct CheckPointersImplTrampoline {
76
+ static void Call(SameThreadEnabledCheckingPolicy* policy, const T* ptr) {
77
+ policy->CheckPointerImpl(ptr, false, kCheckOffHeapAssignments);
78
+ }
79
+ };
80
+
81
+ template <typename T>
82
+ struct CheckPointersImplTrampoline<T, true> {
83
+ static void Call(SameThreadEnabledCheckingPolicy* policy, const T* ptr) {
84
+ policy->CheckPointerImpl(ptr, IsGarbageCollectedTypeV<T>,
85
+ kCheckOffHeapAssignments);
86
+ }
87
+ };
47
88
  };
48
89
 
49
90
  class DisabledCheckingPolicy {
50
91
  protected:
51
- void CheckPointer(const void* raw) {}
92
+ void CheckPointer(const void*) {}
52
93
  };
53
94
 
54
95
  #if V8_ENABLE_CHECKS
55
- using DefaultCheckingPolicy = EnabledCheckingPolicy;
96
+ // Off heap members are not connected to object graph and thus cannot ressurect
97
+ // dead objects.
98
+ using DefaultMemberCheckingPolicy =
99
+ SameThreadEnabledCheckingPolicy<false /* kCheckOffHeapAssignments*/>;
100
+ using DefaultPersistentCheckingPolicy =
101
+ SameThreadEnabledCheckingPolicy<true /* kCheckOffHeapAssignments*/>;
56
102
  #else
57
- using DefaultCheckingPolicy = DisabledCheckingPolicy;
103
+ using DefaultMemberCheckingPolicy = DisabledCheckingPolicy;
104
+ using DefaultPersistentCheckingPolicy = DisabledCheckingPolicy;
58
105
  #endif
106
+ // For CT(W)P neither marking information (for value), nor objectstart bitmap
107
+ // (for slot) are guaranteed to be present because there's no synchonization
108
+ // between heaps after marking.
109
+ using DefaultCrossThreadPersistentCheckingPolicy = DisabledCheckingPolicy;
59
110
 
60
111
  class KeepLocationPolicy {
61
112
  public:
62
113
  constexpr const SourceLocation& Location() const { return location_; }
63
114
 
64
115
  protected:
116
+ constexpr KeepLocationPolicy() = default;
65
117
  constexpr explicit KeepLocationPolicy(const SourceLocation& location)
66
118
  : location_(location) {}
67
119
 
@@ -82,6 +134,7 @@ class IgnoreLocationPolicy {
82
134
  constexpr SourceLocation Location() const { return {}; }
83
135
 
84
136
  protected:
137
+ constexpr IgnoreLocationPolicy() = default;
85
138
  constexpr explicit IgnoreLocationPolicy(const SourceLocation&) {}
86
139
  };
87
140
 
@@ -93,42 +146,41 @@ using DefaultLocationPolicy = IgnoreLocationPolicy;
93
146
 
94
147
  struct StrongPersistentPolicy {
95
148
  using IsStrongPersistent = std::true_type;
96
-
97
- static V8_EXPORT PersistentRegion& GetPersistentRegion(void* object);
149
+ static V8_EXPORT PersistentRegion& GetPersistentRegion(const void* object);
98
150
  };
99
151
 
100
152
  struct WeakPersistentPolicy {
101
153
  using IsStrongPersistent = std::false_type;
154
+ static V8_EXPORT PersistentRegion& GetPersistentRegion(const void* object);
155
+ };
102
156
 
103
- static V8_EXPORT PersistentRegion& GetPersistentRegion(void* object);
157
+ struct StrongCrossThreadPersistentPolicy {
158
+ using IsStrongPersistent = std::true_type;
159
+ static V8_EXPORT CrossThreadPersistentRegion& GetPersistentRegion(
160
+ const void* object);
161
+ };
162
+
163
+ struct WeakCrossThreadPersistentPolicy {
164
+ using IsStrongPersistent = std::false_type;
165
+ static V8_EXPORT CrossThreadPersistentRegion& GetPersistentRegion(
166
+ const void* object);
104
167
  };
105
168
 
106
- // Persistent/Member forward declarations.
169
+ // Forward declarations setting up the default policies.
170
+ template <typename T, typename WeaknessPolicy,
171
+ typename LocationPolicy = DefaultLocationPolicy,
172
+ typename CheckingPolicy = DefaultCrossThreadPersistentCheckingPolicy>
173
+ class BasicCrossThreadPersistent;
107
174
  template <typename T, typename WeaknessPolicy,
108
175
  typename LocationPolicy = DefaultLocationPolicy,
109
- typename CheckingPolicy = DefaultCheckingPolicy>
176
+ typename CheckingPolicy = DefaultPersistentCheckingPolicy>
110
177
  class BasicPersistent;
111
178
  template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
112
- typename CheckingPolicy = DefaultCheckingPolicy>
179
+ typename CheckingPolicy = DefaultMemberCheckingPolicy>
113
180
  class BasicMember;
114
181
 
115
- // Special tag type used to denote some sentinel member. The semantics of the
116
- // sentinel is defined by the embedder.
117
- struct SentinelPointer {
118
- template <typename T>
119
- operator T*() const { // NOLINT
120
- static constexpr intptr_t kSentinelValue = 1;
121
- return reinterpret_cast<T*>(kSentinelValue);
122
- }
123
- // Hidden friends.
124
- friend bool operator==(SentinelPointer, SentinelPointer) { return true; }
125
- friend bool operator!=(SentinelPointer, SentinelPointer) { return false; }
126
- };
127
-
128
182
  } // namespace internal
129
183
 
130
- constexpr internal::SentinelPointer kSentinelPointer;
131
-
132
184
  } // namespace cppgc
133
185
 
134
186
  #endif // INCLUDE_CPPGC_INTERNAL_POINTER_POLICIES_H_
@@ -18,7 +18,7 @@ class V8_EXPORT PreFinalizerRegistrationDispatcher final {
18
18
  void* object;
19
19
  PreFinalizerCallback callback;
20
20
 
21
- bool operator==(const PreFinalizer& other);
21
+ bool operator==(const PreFinalizer& other) const;
22
22
  };
23
23
 
24
24
  static void RegisterPrefinalizer(PreFinalizer pre_finalizer);