diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/v8/include/cppgc/internal | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-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')
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_ |