summaryrefslogtreecommitdiff
path: root/chromium/v8/include/cppgc/internal
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/v8/include/cppgc/internal
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-85-based.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/v8/include/cppgc/internal')
-rw-r--r--chromium/v8/include/cppgc/internal/accessors.h26
-rw-r--r--chromium/v8/include/cppgc/internal/api-constants.h17
-rw-r--r--chromium/v8/include/cppgc/internal/atomic-entry-flag.h48
-rw-r--r--chromium/v8/include/cppgc/internal/caged-heap-local-data.h67
-rw-r--r--chromium/v8/include/cppgc/internal/compiler-specific.h12
-rw-r--r--chromium/v8/include/cppgc/internal/gc-info.h6
-rw-r--r--chromium/v8/include/cppgc/internal/persistent-node.h9
-rw-r--r--chromium/v8/include/cppgc/internal/pointer-policies.h7
-rw-r--r--chromium/v8/include/cppgc/internal/prefinalizer-handler.h7
-rw-r--r--chromium/v8/include/cppgc/internal/process-heap.h34
-rw-r--r--chromium/v8/include/cppgc/internal/write-barrier.h78
11 files changed, 268 insertions, 43 deletions
diff --git a/chromium/v8/include/cppgc/internal/accessors.h b/chromium/v8/include/cppgc/internal/accessors.h
deleted file mode 100644
index ee0a0042fe0..00000000000
--- a/chromium/v8/include/cppgc/internal/accessors.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2020 the V8 project 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 INCLUDE_CPPGC_INTERNAL_ACCESSORS_H_
-#define INCLUDE_CPPGC_INTERNAL_ACCESSORS_H_
-
-#include "cppgc/internal/api-constants.h"
-
-namespace cppgc {
-
-class Heap;
-
-namespace internal {
-
-inline cppgc::Heap* GetHeapFromPayload(const void* payload) {
- return *reinterpret_cast<cppgc::Heap**>(
- ((reinterpret_cast<uintptr_t>(payload) & api_constants::kPageBaseMask) +
- api_constants::kGuardPageSize) +
- api_constants::kHeapOffset);
-}
-
-} // namespace internal
-} // namespace cppgc
-
-#endif // INCLUDE_CPPGC_INTERNAL_ACCESSORS_H_
diff --git a/chromium/v8/include/cppgc/internal/api-constants.h b/chromium/v8/include/cppgc/internal/api-constants.h
index ef910a48571..1303b8b861f 100644
--- a/chromium/v8/include/cppgc/internal/api-constants.h
+++ b/chromium/v8/include/cppgc/internal/api-constants.h
@@ -17,6 +17,11 @@ namespace internal {
// Internal constants to avoid exposing internal types on the API surface.
namespace api_constants {
+
+constexpr size_t kKB = 1024;
+constexpr size_t kMB = kKB * 1024;
+constexpr size_t kGB = kMB * 1024;
+
// Offset of the uint16_t bitfield from the payload contaning the
// in-construction bit. This is subtracted from the payload pointer to get
// to the right bitfield.
@@ -25,17 +30,15 @@ static constexpr size_t kFullyConstructedBitFieldOffsetFromPayload =
// Mask for in-construction bit.
static constexpr size_t kFullyConstructedBitMask = size_t{1};
-// Page constants used to align pointers to page begin.
static constexpr size_t kPageSize = size_t{1} << 17;
-static constexpr size_t kPageAlignment = kPageSize;
-static constexpr size_t kPageBaseMask = ~(kPageAlignment - 1);
-static constexpr size_t kGuardPageSize = 4096;
-
-// Offset of the Heap backref.
-static constexpr size_t kHeapOffset = 0;
static constexpr size_t kLargeObjectSizeThreshold = kPageSize / 2;
+#if defined(CPPGC_CAGED_HEAP)
+constexpr size_t kCagedHeapReservationSize = static_cast<size_t>(4) * kGB;
+constexpr size_t kCagedHeapReservationAlignment = kCagedHeapReservationSize;
+#endif
+
} // namespace api_constants
} // namespace internal
diff --git a/chromium/v8/include/cppgc/internal/atomic-entry-flag.h b/chromium/v8/include/cppgc/internal/atomic-entry-flag.h
new file mode 100644
index 00000000000..5a7d3b8f8ac
--- /dev/null
+++ b/chromium/v8/include/cppgc/internal/atomic-entry-flag.h
@@ -0,0 +1,48 @@
+// Copyright 2020 the V8 project 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 INCLUDE_CPPGC_INTERNAL_ATOMIC_ENTRY_FLAG_H_
+#define INCLUDE_CPPGC_INTERNAL_ATOMIC_ENTRY_FLAG_H_
+
+#include <atomic>
+
+namespace cppgc {
+namespace internal {
+
+// A flag which provides a fast check whether a scope may be entered on the
+// current thread, without needing to access thread-local storage or mutex. Can
+// have false positives (i.e., spuriously report that it might be entered), so
+// it is expected that this will be used in tandem with a precise check that the
+// scope is in fact entered on that thread.
+//
+// Example:
+// g_frobnicating_flag.MightBeEntered() &&
+// ThreadLocalFrobnicator().IsFrobnicating()
+//
+// Relaxed atomic operations are sufficient, since:
+// - all accesses remain atomic
+// - each thread must observe its own operations in order
+// - no thread ever exits the flag more times than it enters (if used correctly)
+// And so if a thread observes zero, it must be because it has observed an equal
+// number of exits as entries.
+class AtomicEntryFlag final {
+ public:
+ void Enter() { entries_.fetch_add(1, std::memory_order_relaxed); }
+ void Exit() { entries_.fetch_sub(1, std::memory_order_relaxed); }
+
+ // Returns false only if the current thread is not between a call to Enter
+ // and a call to Exit. Returns true if this thread or another thread may
+ // currently be in the scope guarded by this flag.
+ bool MightBeEntered() const {
+ return entries_.load(std::memory_order_relaxed) != 0;
+ }
+
+ private:
+ std::atomic_int entries_{0};
+};
+
+} // namespace internal
+} // namespace cppgc
+
+#endif // INCLUDE_CPPGC_INTERNAL_ATOMIC_ENTRY_FLAG_H_
diff --git a/chromium/v8/include/cppgc/internal/caged-heap-local-data.h b/chromium/v8/include/cppgc/internal/caged-heap-local-data.h
new file mode 100644
index 00000000000..8c421477384
--- /dev/null
+++ b/chromium/v8/include/cppgc/internal/caged-heap-local-data.h
@@ -0,0 +1,67 @@
+// Copyright 2020 the V8 project 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 INCLUDE_CPPGC_INTERNAL_CAGED_HEAP_LOCAL_DATA_H_
+#define INCLUDE_CPPGC_INTERNAL_CAGED_HEAP_LOCAL_DATA_H_
+
+#include <array>
+
+#include "cppgc/internal/api-constants.h"
+#include "cppgc/internal/logging.h"
+#include "cppgc/platform.h"
+
+namespace cppgc {
+namespace internal {
+
+class HeapBase;
+
+#if defined(CPPGC_YOUNG_GENERATION)
+
+// AgeTable contains entries that correspond to 4KB memory regions. Each entry
+// can be in one of three states: kOld, kYoung or kUnknown.
+class AgeTable final {
+ static constexpr size_t kGranularityBits = 12; // 4KiB per byte.
+
+ public:
+ enum class Age : uint8_t { kOld, kYoung, kUnknown };
+
+ static constexpr size_t kEntrySizeInBytes = 1 << kGranularityBits;
+
+ Age& operator[](uintptr_t offset) { return table_[entry(offset)]; }
+ Age operator[](uintptr_t offset) const { return table_[entry(offset)]; }
+
+ void Reset(PageAllocator* allocator);
+
+ private:
+ static constexpr size_t kAgeTableSize =
+ api_constants::kCagedHeapReservationSize >> kGranularityBits;
+
+ size_t entry(uintptr_t offset) const {
+ const size_t entry = offset >> kGranularityBits;
+ CPPGC_DCHECK(table_.size() > entry);
+ return entry;
+ }
+
+ std::array<Age, kAgeTableSize> table_;
+};
+
+static_assert(sizeof(AgeTable) == 1 * api_constants::kMB,
+ "Size of AgeTable is 1MB");
+
+#endif // CPPGC_YOUNG_GENERATION
+
+struct CagedHeapLocalData final {
+ explicit CagedHeapLocalData(HeapBase* heap_base) : heap_base(heap_base) {}
+
+ bool is_marking_in_progress = false;
+ HeapBase* heap_base = nullptr;
+#if defined(CPPGC_YOUNG_GENERATION)
+ AgeTable age_table;
+#endif
+};
+
+} // namespace internal
+} // namespace cppgc
+
+#endif // INCLUDE_CPPGC_INTERNAL_CAGED_HEAP_LOCAL_DATA_H_
diff --git a/chromium/v8/include/cppgc/internal/compiler-specific.h b/chromium/v8/include/cppgc/internal/compiler-specific.h
index e1f5c1d57fb..c580894b35d 100644
--- a/chromium/v8/include/cppgc/internal/compiler-specific.h
+++ b/chromium/v8/include/cppgc/internal/compiler-specific.h
@@ -7,6 +7,12 @@
namespace cppgc {
+#if defined(__has_attribute)
+#define CPPGC_HAS_ATTRIBUTE(FEATURE) __has_attribute(FEATURE)
+#else
+#define CPPGC_HAS_ATTRIBUTE(FEATURE) 0
+#endif
+
#if defined(__has_cpp_attribute)
#define CPPGC_HAS_CPP_ATTRIBUTE(FEATURE) __has_cpp_attribute(FEATURE)
#else
@@ -21,6 +27,12 @@ namespace cppgc {
#define CPPGC_NO_UNIQUE_ADDRESS
#endif
+#if CPPGC_HAS_ATTRIBUTE(unused) // NOLINTNEXTLINE
+#define CPPGC_UNUSED __attribute__((unused))
+#else
+#define CPPGC_UNUSED
+#endif
+
} // namespace cppgc
#endif // INCLUDE_CPPGC_INTERNAL_COMPILER_SPECIFIC_H_
diff --git a/chromium/v8/include/cppgc/internal/gc-info.h b/chromium/v8/include/cppgc/internal/gc-info.h
index 9aac1361c61..3d361e6d71a 100644
--- a/chromium/v8/include/cppgc/internal/gc-info.h
+++ b/chromium/v8/include/cppgc/internal/gc-info.h
@@ -8,6 +8,7 @@
#include <stdint.h>
#include "cppgc/internal/finalizer-trait.h"
+#include "cppgc/trace-trait.h"
#include "v8config.h" // NOLINT(build/include_directory)
namespace cppgc {
@@ -18,7 +19,7 @@ using GCInfoIndex = uint16_t;
class V8_EXPORT RegisteredGCInfoIndex final {
public:
RegisteredGCInfoIndex(FinalizationCallback finalization_callback,
- bool has_v_table);
+ TraceCallback trace_callback, bool has_v_table);
GCInfoIndex GetIndex() const { return index_; }
private:
@@ -32,7 +33,8 @@ struct GCInfoTrait {
static GCInfoIndex Index() {
static_assert(sizeof(T), "T must be fully defined");
static const RegisteredGCInfoIndex registered_index(
- FinalizerTrait<T>::kCallback, std::is_polymorphic<T>::value);
+ FinalizerTrait<T>::kCallback, TraceTrait<T>::Trace,
+ std::is_polymorphic<T>::value);
return registered_index.GetIndex();
}
};
diff --git a/chromium/v8/include/cppgc/internal/persistent-node.h b/chromium/v8/include/cppgc/internal/persistent-node.h
index 11cf69623e8..e05efe36213 100644
--- a/chromium/v8/include/cppgc/internal/persistent-node.h
+++ b/chromium/v8/include/cppgc/internal/persistent-node.h
@@ -56,6 +56,11 @@ class PersistentNode final {
bool IsUsed() const { return trace_; }
+ void* owner() const {
+ CPPGC_DCHECK(IsUsed());
+ return owner_;
+ }
+
private:
// PersistentNode acts as a designated union:
// If trace_ != nullptr, owner_ points to the corresponding Persistent handle.
@@ -67,11 +72,13 @@ class PersistentNode final {
TraceCallback trace_ = nullptr;
};
-class V8_EXPORT PersistentRegion {
+class V8_EXPORT PersistentRegion final {
using PersistentNodeSlots = std::array<PersistentNode, 256u>;
public:
PersistentRegion() = default;
+ // Clears Persistent fields to avoid stale pointers after heap teardown.
+ ~PersistentRegion();
PersistentRegion(const PersistentRegion&) = delete;
PersistentRegion& operator=(const PersistentRegion&) = delete;
diff --git a/chromium/v8/include/cppgc/internal/pointer-policies.h b/chromium/v8/include/cppgc/internal/pointer-policies.h
index fe8d94b57a6..a6cd4e8586d 100644
--- a/chromium/v8/include/cppgc/internal/pointer-policies.h
+++ b/chromium/v8/include/cppgc/internal/pointer-policies.h
@@ -8,6 +8,7 @@
#include <cstdint>
#include <type_traits>
+#include "cppgc/internal/write-barrier.h"
#include "cppgc/source-location.h"
#include "v8config.h" // NOLINT(build/include_directory)
@@ -26,8 +27,8 @@ struct DijkstraWriteBarrierPolicy {
// Since in initializing writes the source object is always white, having no
// barrier doesn't break the tri-color invariant.
}
- static void AssigningBarrier(const void*, const void*) {
- // TODO(chromium:1056170): Add actual implementation.
+ static void AssigningBarrier(const void* slot, const void* value) {
+ WriteBarrier::MarkingBarrier(slot, value);
}
};
@@ -116,7 +117,7 @@ class BasicMember;
struct SentinelPointer {
template <typename T>
operator T*() const { // NOLINT
- static constexpr intptr_t kSentinelValue = -1;
+ static constexpr intptr_t kSentinelValue = 1;
return reinterpret_cast<T*>(kSentinelValue);
}
// Hidden friends.
diff --git a/chromium/v8/include/cppgc/internal/prefinalizer-handler.h b/chromium/v8/include/cppgc/internal/prefinalizer-handler.h
index 939a9b8ff0a..ea0eca02a0e 100644
--- a/chromium/v8/include/cppgc/internal/prefinalizer-handler.h
+++ b/chromium/v8/include/cppgc/internal/prefinalizer-handler.h
@@ -15,14 +15,13 @@ class V8_EXPORT PreFinalizerRegistrationDispatcher final {
public:
using PreFinalizerCallback = bool (*)(const LivenessBroker&, void*);
struct PreFinalizer {
- void* object_;
- PreFinalizerCallback callback_;
+ void* object;
+ PreFinalizerCallback callback;
bool operator==(const PreFinalizer& other);
};
- static void RegisterPrefinalizer(cppgc::Heap* heap,
- PreFinalizer prefinalzier);
+ static void RegisterPrefinalizer(PreFinalizer pre_finalizer);
};
} // namespace internal
diff --git a/chromium/v8/include/cppgc/internal/process-heap.h b/chromium/v8/include/cppgc/internal/process-heap.h
new file mode 100644
index 00000000000..0f742a50a9c
--- /dev/null
+++ b/chromium/v8/include/cppgc/internal/process-heap.h
@@ -0,0 +1,34 @@
+// Copyright 2020 the V8 project 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 INCLUDE_CPPGC_INTERNAL_PROCESS_HEAP_H_
+#define INCLUDE_CPPGC_INTERNAL_PROCESS_HEAP_H_
+
+#include "cppgc/internal/atomic-entry-flag.h"
+#include "v8config.h" // NOLINT(build/include_directory)
+
+namespace cppgc {
+namespace internal {
+
+class V8_EXPORT ProcessHeap final {
+ public:
+ static void EnterIncrementalOrConcurrentMarking() {
+ concurrent_marking_flag_.Enter();
+ }
+ static void ExitIncrementalOrConcurrentMarking() {
+ concurrent_marking_flag_.Exit();
+ }
+
+ static bool IsAnyIncrementalOrConcurrentMarking() {
+ return concurrent_marking_flag_.MightBeEntered();
+ }
+
+ private:
+ static AtomicEntryFlag concurrent_marking_flag_;
+};
+
+} // namespace internal
+} // namespace cppgc
+
+#endif // INCLUDE_CPPGC_INTERNAL_PROCESS_HEAP_H_
diff --git a/chromium/v8/include/cppgc/internal/write-barrier.h b/chromium/v8/include/cppgc/internal/write-barrier.h
new file mode 100644
index 00000000000..5bf550b0261
--- /dev/null
+++ b/chromium/v8/include/cppgc/internal/write-barrier.h
@@ -0,0 +1,78 @@
+// Copyright 2020 the V8 project 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 INCLUDE_CPPGC_INTERNAL_WRITE_BARRIER_H_
+#define INCLUDE_CPPGC_INTERNAL_WRITE_BARRIER_H_
+
+#include "cppgc/internal/api-constants.h"
+#include "cppgc/internal/process-heap.h"
+#include "v8config.h" // NOLINT(build/include_directory)
+
+#if defined(CPPGC_CAGED_HEAP)
+#include "cppgc/internal/caged-heap-local-data.h"
+#endif
+
+namespace cppgc {
+namespace internal {
+
+class V8_EXPORT WriteBarrier final {
+ public:
+ static V8_INLINE void MarkingBarrier(const void* slot, const void* value) {
+#if defined(CPPGC_CAGED_HEAP)
+ const uintptr_t start =
+ reinterpret_cast<uintptr_t>(value) &
+ ~(api_constants::kCagedHeapReservationAlignment - 1);
+ const uintptr_t slot_offset = reinterpret_cast<uintptr_t>(slot) - start;
+ if (slot_offset > api_constants::kCagedHeapReservationSize) {
+ // Check if slot is on stack or value is sentinel or nullptr. This relies
+ // on the fact that kSentinelPointer is encoded as 0x1.
+ return;
+ }
+
+ CagedHeapLocalData* local_data =
+ reinterpret_cast<CagedHeapLocalData*>(start);
+ if (V8_UNLIKELY(local_data->is_marking_in_progress)) {
+ MarkingBarrierSlow(value);
+ return;
+ }
+#if defined(CPPGC_YOUNG_GENERATION)
+ GenerationalBarrier(local_data, slot, slot_offset,
+ reinterpret_cast<uintptr_t>(value) - start);
+#endif
+#else
+ if (V8_LIKELY(!ProcessHeap::IsAnyIncrementalOrConcurrentMarking())) return;
+
+ MarkingBarrierSlowWithSentinelCheck(value);
+#endif // CPPGC_CAGED_HEAP
+ }
+
+ private:
+ WriteBarrier() = delete;
+
+ static void MarkingBarrierSlow(const void* value);
+ static void MarkingBarrierSlowWithSentinelCheck(const void* value);
+
+#if defined(CPPGC_YOUNG_GENERATION)
+ static V8_INLINE void GenerationalBarrier(CagedHeapLocalData* local_data,
+ const void* slot,
+ uintptr_t slot_offset,
+ uintptr_t value_offset) {
+ const AgeTable& age_table = local_data->age_table;
+
+ // Bail out if the slot is in young generation.
+ if (V8_LIKELY(age_table[slot_offset] == AgeTable::Age::kYoung)) return;
+
+ GenerationalBarrierSlow(local_data, age_table, slot, value_offset);
+ }
+
+ static void GenerationalBarrierSlow(CagedHeapLocalData* local_data,
+ const AgeTable& ageTable,
+ const void* slot, uintptr_t value_offset);
+#endif
+};
+
+} // namespace internal
+} // namespace cppgc
+
+#endif // INCLUDE_CPPGC_INTERNAL_WRITE_BARRIER_H_