cppgc: Add HeapState API
The API allows for querying - IsAllocationAllowed: Certain GC phases prohibit allocation which can be queried; Should be mostly used for debugging checks. - IsMarking: Allows for querying whether the garbage collector is currently marking. Bug: chromium:1056170 Change-Id: I20ba5fb5be9de6694e8418fa885920eb04bd75ad Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2649257 Commit-Queue: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Cr-Commit-Position: refs/heads/master@{#72359}
This commit is contained in:
parent
4b03f02467
commit
35dcecf607
@ -132,6 +132,31 @@ class HeapConsistency final {
|
||||
HeapConsistency() = delete;
|
||||
};
|
||||
|
||||
/**
|
||||
* Helpers to peek into heap-internal state.
|
||||
*/
|
||||
class V8_EXPORT HeapState final {
|
||||
public:
|
||||
/**
|
||||
* Returns whether the garbage collector is marking. This API is experimental
|
||||
* and is expected to be removed in future.
|
||||
*
|
||||
* \param heap_handle The corresponding heap.
|
||||
* \returns true if the garbage collector is currently marking, and false
|
||||
* otherwise.
|
||||
*/
|
||||
static bool IsMarking(HeapHandle& heap_handle);
|
||||
|
||||
/**
|
||||
* \param heap_handle The corresponding heap.
|
||||
* \returns true if allocations are allowed, and false otherwise.
|
||||
*/
|
||||
static bool IsAllocationAllowed(HeapHandle& heap_handle);
|
||||
|
||||
private:
|
||||
HeapState() = delete;
|
||||
};
|
||||
|
||||
/**
|
||||
* Avoids invoking garbage collection finalizations. Already running garbage
|
||||
* collection phase are unaffected by this scope.
|
||||
|
@ -104,6 +104,7 @@ class V8_EXPORT_PRIVATE HeapBase : public cppgc::HeapHandle {
|
||||
Compactor& compactor() { return compactor_; }
|
||||
|
||||
ObjectAllocator& object_allocator() { return object_allocator_; }
|
||||
const ObjectAllocator& object_allocator() const { return object_allocator_; }
|
||||
|
||||
Sweeper& sweeper() { return sweeper_; }
|
||||
|
||||
|
@ -32,5 +32,17 @@ NoGarbageCollectionScope::NoGarbageCollectionScope(
|
||||
|
||||
NoGarbageCollectionScope::~NoGarbageCollectionScope() { Leave(heap_handle_); }
|
||||
|
||||
// static
|
||||
bool HeapState::IsMarking(HeapHandle& heap_handle) {
|
||||
const auto& heap_base = internal::HeapBase::From(heap_handle);
|
||||
return heap_base.marker();
|
||||
}
|
||||
|
||||
// static
|
||||
bool HeapState::IsAllocationAllowed(HeapHandle& heap_handle) {
|
||||
const auto& heap_base = internal::HeapBase::From(heap_handle);
|
||||
return heap_base.object_allocator().is_allocation_allowed();
|
||||
}
|
||||
|
||||
} // namespace subtle
|
||||
} // namespace cppgc
|
||||
|
@ -59,14 +59,14 @@ class V8_EXPORT_PRIVATE ObjectAllocator final : public cppgc::AllocationHandle {
|
||||
// Terminate the allocator. Subsequent allocation calls result in a crash.
|
||||
void Terminate();
|
||||
|
||||
bool is_allocation_allowed() const { return no_allocation_scope_ == 0; }
|
||||
|
||||
private:
|
||||
// Returns the initially tried SpaceType to allocate an object of |size| bytes
|
||||
// on. Returns the largest regular object size bucket for large objects.
|
||||
inline static RawHeap::RegularSpaceType GetInitialSpaceIndexForSize(
|
||||
size_t size);
|
||||
|
||||
bool is_allocation_allowed() const { return no_allocation_scope_ == 0; }
|
||||
|
||||
inline void* AllocateObjectOnSpace(NormalPageSpace* space, size_t size,
|
||||
GCInfoIndex gcinfo);
|
||||
void* OutOfLineAllocate(NormalPageSpace*, size_t, GCInfoIndex);
|
||||
|
@ -174,6 +174,28 @@ TEST_F(GCHeapTest, NoGarbageCollectionScope) {
|
||||
EXPECT_EQ(epoch_after_gc, epoch_before);
|
||||
}
|
||||
|
||||
TEST_F(GCHeapTest, IsAllocationAllowed) {
|
||||
EXPECT_TRUE(
|
||||
subtle::HeapState::IsAllocationAllowed(GetHeap()->GetHeapHandle()));
|
||||
{
|
||||
ObjectAllocator::NoAllocationScope no_allocation(
|
||||
Heap::From(GetHeap())->object_allocator());
|
||||
EXPECT_FALSE(
|
||||
subtle::HeapState::IsAllocationAllowed(GetHeap()->GetHeapHandle()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(GCHeapTest, IsIncrementalMarking) {
|
||||
GarbageCollector::Config config =
|
||||
GarbageCollector::Config::PreciseIncrementalConfig();
|
||||
auto* heap = Heap::From(GetHeap());
|
||||
EXPECT_FALSE(subtle::HeapState::IsMarking(*heap));
|
||||
heap->StartIncrementalGarbageCollection(config);
|
||||
EXPECT_TRUE(subtle::HeapState::IsMarking(*heap));
|
||||
heap->FinalizeIncrementalGarbageCollectionIfRunning(config);
|
||||
EXPECT_FALSE(subtle::HeapState::IsMarking(*heap));
|
||||
}
|
||||
|
||||
TEST_F(GCHeapTest, TerminateEmptyHeap) { Heap::From(GetHeap())->Terminate(); }
|
||||
|
||||
TEST_F(GCHeapTest, TerminateClearsPersistent) {
|
||||
|
Loading…
Reference in New Issue
Block a user