Commit a1e49bf8 authored by Michael Lippautz's avatar Michael Lippautz Committed by V8 LUCI CQ

cppgc: Allow querying whether sweeping is active on owning thread

This allows the embedder to determine whether some function has been
called from a destructor.

See discussion in
  https://crrev.com/c/3302810

Bug: chromium:1273928
Change-Id: Icb5d98eff777574488a7d6de5e693c502c2fb53e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3303793Reviewed-by: 's avatarOmer Katz <omerkatz@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78113}
parent de058e54
...@@ -38,6 +38,18 @@ class V8_EXPORT HeapState final { ...@@ -38,6 +38,18 @@ class V8_EXPORT HeapState final {
*/ */
static bool IsSweeping(const HeapHandle& heap_handle); static bool IsSweeping(const HeapHandle& heap_handle);
/*
* Returns whether the garbage collector is currently sweeping on the thread
* owning this heap. This API allows the caller to determine whether it has
* been called from a destructor of a managed object. This API is experimental
* and may be removed in future.
*
* \param heap_handle The corresponding heap.
* \returns true if the garbage collector is currently sweeping on this
* thread, and false otherwise.
*/
static bool IsSweepingOnOwningThread(const HeapHandle& heap_handle);
/** /**
* Returns whether the garbage collector is in the atomic pause, i.e., the * Returns whether the garbage collector is in the atomic pause, i.e., the
* mutator is stopped from running. This API is experimental and is expected * mutator is stopped from running. This API is experimental and is expected
......
...@@ -21,6 +21,13 @@ bool HeapState::IsSweeping(const HeapHandle& heap_handle) { ...@@ -21,6 +21,13 @@ bool HeapState::IsSweeping(const HeapHandle& heap_handle) {
return internal::HeapBase::From(heap_handle).sweeper().IsSweepingInProgress(); return internal::HeapBase::From(heap_handle).sweeper().IsSweepingInProgress();
} }
// static
bool HeapState::IsSweepingOnOwningThread(const HeapHandle& heap_handle) {
return internal::HeapBase::From(heap_handle)
.sweeper()
.IsSweepingOnMutatorThread();
}
// static // static
bool HeapState::IsInAtomicPause(const HeapHandle& heap_handle) { bool HeapState::IsInAtomicPause(const HeapHandle& heap_handle) {
return internal::HeapBase::From(heap_handle).in_atomic_pause(); return internal::HeapBase::From(heap_handle).in_atomic_pause();
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "include/cppgc/allocation.h" #include "include/cppgc/allocation.h"
#include "include/cppgc/cross-thread-persistent.h" #include "include/cppgc/cross-thread-persistent.h"
#include "include/cppgc/heap-consistency.h" #include "include/cppgc/heap-consistency.h"
#include "include/cppgc/heap-state.h"
#include "include/cppgc/persistent.h" #include "include/cppgc/persistent.h"
#include "include/cppgc/prefinalizer.h" #include "include/cppgc/prefinalizer.h"
#include "src/heap/cppgc/globals.h" #include "src/heap/cppgc/globals.h"
...@@ -261,6 +262,40 @@ TEST_F(GCHeapTest, IsSweeping) { ...@@ -261,6 +262,40 @@ TEST_F(GCHeapTest, IsSweeping) {
namespace { namespace {
class GCedExpectSweepingOnOwningThread final
: public GarbageCollected<GCedExpectSweepingOnOwningThread> {
public:
explicit GCedExpectSweepingOnOwningThread(const HeapHandle& heap_handle)
: heap_handle_(heap_handle) {}
~GCedExpectSweepingOnOwningThread() {
EXPECT_TRUE(subtle::HeapState::IsSweepingOnOwningThread(heap_handle_));
}
void Trace(Visitor*) const {}
private:
const HeapHandle& heap_handle_;
};
} // namespace
TEST_F(GCHeapTest, IsSweepingOnOwningThread) {
GarbageCollector::Config config = GarbageCollector::Config::
PreciseIncrementalMarkingConcurrentSweepingConfig();
auto* heap = Heap::From(GetHeap());
MakeGarbageCollected<GCedExpectSweepingOnOwningThread>(
heap->GetAllocationHandle(), *heap);
EXPECT_FALSE(subtle::HeapState::IsSweepingOnOwningThread(*heap));
heap->StartIncrementalGarbageCollection(config);
EXPECT_FALSE(subtle::HeapState::IsSweepingOnOwningThread(*heap));
heap->FinalizeIncrementalGarbageCollectionIfRunning(config);
EXPECT_FALSE(subtle::HeapState::IsSweepingOnOwningThread(*heap));
heap->AsBase().sweeper().FinishIfRunning();
EXPECT_FALSE(subtle::HeapState::IsSweepingOnOwningThread(*heap));
}
namespace {
class ExpectAtomicPause final : public GarbageCollected<ExpectAtomicPause> { class ExpectAtomicPause final : public GarbageCollected<ExpectAtomicPause> {
CPPGC_USING_PRE_FINALIZER(ExpectAtomicPause, PreFinalizer); CPPGC_USING_PRE_FINALIZER(ExpectAtomicPause, PreFinalizer);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment