cppgc: Add WasConservativeGC to HeapState

This CL adds WasConservativeGC to HeapState which reports whether the
last GC was finalized conservatively. The state is updated at the end of
marking atomic pause.

Currently the library integration in Blink ignores the stack state when
scheduling a forced GC for testing. That means that we always schedule
another GC after a forced GC.
This causes a crash in web_tests which assume no GC is happening
between forced GCs if the thread is not idle and no new allocations
happen.

Usage CL: https://crrev.com/c/2720201

Drive by: Fix stack state for MarkingVerifier in CppHeap.

Bug: chromium:1056170
Change-Id: I6ad23ed7c1a53fae96425b968bc4b3eb18ce80b7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2720279
Commit-Queue: Omer Katz <omerkatz@chromium.org>
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73064}
This commit is contained in:
Omer Katz 2021-02-25 22:14:14 +01:00 committed by Commit Bot
parent dc05afd164
commit 199359da18
5 changed files with 32 additions and 7 deletions

View File

@ -49,6 +49,17 @@ class V8_EXPORT HeapState final {
*/
static bool IsInAtomicPause(const HeapHandle& heap_handle);
/**
* Returns whether the last garbage collection was finalized conservatively
* (i.e., with a non-empty stack). This API is experimental and is expected to
* be removed in future.
*
* \param heap_handle The corresponding heap.
* \returns true if the last garbage collection was finalized conservatively,
* and false otherwise.
*/
static bool PreviousGCWasConservative(const HeapHandle& heap_handle);
private:
HeapState() = delete;
};

View File

@ -343,7 +343,7 @@ void CppHeap::TraceEpilogue(TraceSummary* trace_summary) {
// TODO(chromium:1056170): replace build flag with dedicated flag.
#if DEBUG
UnifiedHeapMarkingVerifier verifier(*this);
verifier.Run(cppgc::Heap::StackState::kNoHeapPointers);
verifier.Run(stack_state_of_prev_gc_);
#endif
{

View File

@ -165,6 +165,13 @@ class V8_EXPORT_PRIVATE HeapBase : public cppgc::HeapHandle {
size_t epoch() const { return epoch_; }
EmbedderStackState stack_state_of_prev_gc() const {
return stack_state_of_prev_gc_;
}
void SetStackStateOfPrevGC(EmbedderStackState stack_state) {
stack_state_of_prev_gc_ = stack_state;
}
protected:
// Starts and finalizes stand-alone garbage collections.
void StartStandAloneGarbageCollection(GarbageCollector::Config);
@ -211,6 +218,8 @@ class V8_EXPORT_PRIVATE HeapBase : public cppgc::HeapHandle {
size_t disallow_gc_scope_ = 0;
const StackSupport stack_support_;
EmbedderStackState stack_state_of_prev_gc_ =
EmbedderStackState::kNoHeapPointers;
std::unique_ptr<EmbedderStackState> override_stack_state_;
bool in_atomic_pause_ = false;

View File

@ -11,21 +11,25 @@ namespace subtle {
// static
bool HeapState::IsMarking(const HeapHandle& heap_handle) {
const auto& heap_base = internal::HeapBase::From(heap_handle);
const internal::MarkerBase* marker = heap_base.marker();
const internal::MarkerBase* marker =
internal::HeapBase::From(heap_handle).marker();
return marker && marker->IsMarking();
}
// static
bool HeapState::IsSweeping(const HeapHandle& heap_handle) {
const auto& heap_base = internal::HeapBase::From(heap_handle);
return heap_base.sweeper().IsSweepingInProgress();
return internal::HeapBase::From(heap_handle).sweeper().IsSweepingInProgress();
}
// static
bool HeapState::IsInAtomicPause(const HeapHandle& heap_handle) {
const auto& heap_base = internal::HeapBase::From(heap_handle);
return heap_base.in_atomic_pause();
return internal::HeapBase::From(heap_handle).in_atomic_pause();
}
// static
bool HeapState::PreviousGCWasConservative(const HeapHandle& heap_handle) {
return internal::HeapBase::From(heap_handle).stack_state_of_prev_gc() ==
EmbedderStackState::kMayContainHeapPointers;
}
} // namespace subtle

View File

@ -275,6 +275,7 @@ void MarkerBase::LeaveAtomicPause() {
ProcessWeakness();
}
g_process_mutex.Pointer()->Unlock();
heap().SetStackStateOfPrevGC(config_.stack_state);
}
void MarkerBase::FinishMarking(MarkingConfig::StackState stack_state) {