From 17ed49b5605ed9b9fcf7fbef8a59ca9594dfef01 Mon Sep 17 00:00:00 2001 From: Michael Lippautz Date: Mon, 30 Nov 2020 22:30:55 +0100 Subject: [PATCH] heap, cppgc: Add write barrier for TracedReference Adds publicly callable version of write barrier for TracedReferenceBase. Bug: chromium:1056170 Change-Id: Ie45b4ebbe91d9f0e8f76b521dcbfd931232adcf6 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2565248 Reviewed-by: Ulan Degenbaev Commit-Queue: Michael Lippautz Cr-Commit-Position: refs/heads/master@{#71524} --- include/DEPS | 1 + include/cppgc/internal/write-barrier.h | 12 ++--- include/v8-cppgc.h | 61 +++++++++++++++++++++++++- src/heap/cppgc-js/cpp-heap.cc | 6 +++ 4 files changed, 73 insertions(+), 7 deletions(-) diff --git a/include/DEPS b/include/DEPS index c5b95537d9..9f4002059b 100644 --- a/include/DEPS +++ b/include/DEPS @@ -4,5 +4,6 @@ include_rules = [ "+cppgc/common.h", # Used by v8-cppgc.h to bridge to cppgc. "+cppgc/custom-space.h", + "+cppgc/internal/write-barrier.h", "+cppgc/visitor.h", ] diff --git a/include/cppgc/internal/write-barrier.h b/include/cppgc/internal/write-barrier.h index 5edd04caab..e3cc4c989d 100644 --- a/include/cppgc/internal/write-barrier.h +++ b/include/cppgc/internal/write-barrier.h @@ -73,6 +73,12 @@ class V8_EXPORT WriteBarrier final { const void* slot) {} #endif // CPPGC_YOUNG_GENERATION +#if V8_ENABLE_CHECKS + static void CheckParams(Type expected_type, const Params& params); +#else // !V8_ENABLE_CHECKS + static void CheckParams(Type expected_type, const Params& params) {} +#endif // !V8_ENABLE_CHECKS + private: WriteBarrier() = delete; @@ -92,12 +98,6 @@ class V8_EXPORT WriteBarrier final { static void SteeleMarkingBarrierSlow(const void* value); static void SteeleMarkingBarrierSlowWithSentinelCheck(const void* value); -#if V8_ENABLE_CHECKS - static void CheckParams(Type expected_type, const Params& params); -#else // !V8_ENABLE_CHECKS - static void CheckParams(Type expected_type, const Params& params) {} -#endif // !V8_ENABLE_CHECKS - #if defined(CPPGC_YOUNG_GENERATION) static void GenerationalBarrierSlow(const CagedHeapLocalData& local_data, const AgeTable& ageTable, diff --git a/include/v8-cppgc.h b/include/v8-cppgc.h index 01ded7f622..8a0d9cb9a0 100644 --- a/include/v8-cppgc.h +++ b/include/v8-cppgc.h @@ -9,9 +9,10 @@ #include #include "cppgc/custom-space.h" +#include "cppgc/internal/write-barrier.h" #include "cppgc/visitor.h" #include "v8-internal.h" // NOLINT(build/include_directory) -#include "v8.h" // NOLINT(build/include_directory) +#include "v8.h" // NOLINT(build/include_directory) namespace cppgc { class AllocationHandle; @@ -68,6 +69,64 @@ class JSVisitor : public cppgc::Visitor { virtual void Visit(const TracedReferenceBase& ref) {} }; +/** + * **DO NOT USE: Use the appropriate managed types.** + * + * Consistency helpers that aid in maintaining a consistent internal state of + * the garbage collector. + */ +class JSHeapConsistency final { + public: + using WriteBarrierParams = cppgc::internal::WriteBarrier::Params; + using WriteBarrierType = cppgc::internal::WriteBarrier::Type; + + /** + * Gets the required write barrier type for a specific write. + * + * \param ref The reference being written to. + * \param params Parameters that may be used for actual write barrier calls. + * Only filled if return value indicates that a write barrier is needed. The + * contents of the `params` are an implementation detail. + * \returns whether a write barrier is needed and which barrier to invoke. + */ + static V8_INLINE WriteBarrierType GetWriteBarrierType( + const TracedReferenceBase& ref, WriteBarrierParams& params) { + if (ref.IsEmpty()) return WriteBarrierType::kNone; + return cppgc::internal::WriteBarrier::GetWriteBarrierType(&ref, params); + } + + /** + * Conservative Dijkstra-style write barrier that processes an object if it + * has not yet been processed. + * + * \param params The parameters retrieved from `GetWriteBarrierType()`. + * \param ref The reference being written to. + */ + static V8_INLINE void DijkstraMarkingBarrier(const WriteBarrierParams& params, + cppgc::HeapHandle& heap_handle, + const TracedReferenceBase& ref) { + cppgc::internal::WriteBarrier::CheckParams(WriteBarrierType::kMarking, + params); + DijkstraMarkingBarrierSlow(heap_handle, ref); + } + + /** + * Generational barrier for maintaining consistency when running with multiple + * generations. + * + * \param params The parameters retrieved from `GetWriteBarrierType()`. + * \param ref The reference being written to. + */ + static V8_INLINE void GenerationalBarrier(const WriteBarrierParams& params, + const TracedReferenceBase& ref) {} + + private: + JSHeapConsistency() = delete; + + static void DijkstraMarkingBarrierSlow(cppgc::HeapHandle&, + const TracedReferenceBase& ref); +}; + } // namespace v8 namespace cppgc { diff --git a/src/heap/cppgc-js/cpp-heap.cc b/src/heap/cppgc-js/cpp-heap.cc index 34449032f2..c8f62c89e5 100644 --- a/src/heap/cppgc-js/cpp-heap.cc +++ b/src/heap/cppgc-js/cpp-heap.cc @@ -42,6 +42,12 @@ cppgc::HeapHandle& CppHeap::GetHeapHandle() { return *internal::CppHeap::From(this); } +void JSHeapConsistency::DijkstraMarkingBarrierSlow( + cppgc::HeapHandle& heap_handle, const TracedReferenceBase& ref) { + auto& heap_base = cppgc::internal::HeapBase::From(heap_handle); + static_cast(&heap_base.marker()->Visitor())->Trace(ref); +} + namespace internal { namespace {