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/+/3303793
Reviewed-by: Omer Katz <omerkatz@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78113}
This commit is contained in:
Michael Lippautz 2021-11-26 16:02:38 +01:00 committed by V8 LUCI CQ
parent de058e5497
commit a1e49bf85b
3 changed files with 54 additions and 0 deletions

View File

@ -38,6 +38,18 @@ class V8_EXPORT HeapState final {
*/
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
* mutator is stopped from running. This API is experimental and is expected

View File

@ -21,6 +21,13 @@ bool HeapState::IsSweeping(const HeapHandle& heap_handle) {
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
bool HeapState::IsInAtomicPause(const HeapHandle& heap_handle) {
return internal::HeapBase::From(heap_handle).in_atomic_pause();

View File

@ -11,6 +11,7 @@
#include "include/cppgc/allocation.h"
#include "include/cppgc/cross-thread-persistent.h"
#include "include/cppgc/heap-consistency.h"
#include "include/cppgc/heap-state.h"
#include "include/cppgc/persistent.h"
#include "include/cppgc/prefinalizer.h"
#include "src/heap/cppgc/globals.h"
@ -261,6 +262,40 @@ TEST_F(GCHeapTest, IsSweeping) {
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> {
CPPGC_USING_PRE_FINALIZER(ExpectAtomicPause, PreFinalizer);