Commit 574c2809 authored by Anton Bikineev's avatar Anton Bikineev Committed by V8 LUCI CQ

cppgc: young-gen: Fix allocated object size accounting with young-gen

Currently, we assume:
  allocated-object-size = marked-bytes-on-previous-cycle + k,
which is not the case for the sticky bits (with the young generation
enabled). The CL introduces a variable
StatsCollector::marked_bytes_so_far_ that keeps track of marked bytes
across GCs.

Bug: chromium:1029379
Change-Id: I749c8c0174889c10093c75f88c096c68905bf36e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3545167Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Anton Bikineev <bikineev@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79588}
parent 542a7845
......@@ -613,9 +613,9 @@ void CppHeap::TraceEpilogue() {
const size_t bytes_allocated_in_prefinalizers = ExecutePreFinalizers();
#if CPPGC_VERIFY_HEAP
UnifiedHeapMarkingVerifier verifier(*this, *collection_type_);
verifier.Run(
stack_state_of_prev_gc(), stack_end_of_current_gc(),
stats_collector()->marked_bytes() + bytes_allocated_in_prefinalizers);
verifier.Run(stack_state_of_prev_gc(), stack_end_of_current_gc(),
stats_collector()->marked_bytes_on_current_cycle() +
bytes_allocated_in_prefinalizers);
#endif // CPPGC_VERIFY_HEAP
USE(bytes_allocated_in_prefinalizers);
......
......@@ -180,9 +180,9 @@ void Heap::FinalizeGarbageCollection(Config::StackState stack_state) {
const size_t bytes_allocated_in_prefinalizers = ExecutePreFinalizers();
#if CPPGC_VERIFY_HEAP
MarkingVerifier verifier(*this, config_.collection_type);
verifier.Run(
config_.stack_state, stack_end_of_current_gc(),
stats_collector()->marked_bytes() + bytes_allocated_in_prefinalizers);
verifier.Run(config_.stack_state, stack_end_of_current_gc(),
stats_collector()->marked_bytes_on_current_cycle() +
bytes_allocated_in_prefinalizers);
#endif // CPPGC_VERIFY_HEAP
#ifndef CPPGC_ALLOW_ALLOCATIONS_IN_PREFINALIZERS
DCHECK_EQ(0u, bytes_allocated_in_prefinalizers);
......
......@@ -120,13 +120,18 @@ void StatsCollector::NotifyMarkingCompleted(size_t marked_bytes) {
gc_state_ = GarbageCollectionState::kSweeping;
current_.marked_bytes = marked_bytes;
current_.object_size_before_sweep_bytes =
previous_.marked_bytes + allocated_bytes_since_end_of_marking_ +
marked_bytes_so_far_ + allocated_bytes_since_end_of_marking_ +
allocated_bytes_since_safepoint_ -
explicitly_freed_bytes_since_safepoint_;
allocated_bytes_since_safepoint_ = 0;
explicitly_freed_bytes_since_safepoint_ = 0;
if (current_.collection_type == CollectionType::kMajor)
marked_bytes_so_far_ = 0;
marked_bytes_so_far_ += marked_bytes;
#ifdef CPPGC_VERIFY_HEAP
tracked_live_bytes_ = marked_bytes;
tracked_live_bytes_ = marked_bytes_so_far_;
#endif // CPPGC_VERIFY_HEAP
DCHECK_LE(memory_freed_bytes_since_end_of_marking_, memory_allocated_bytes_);
......@@ -134,8 +139,8 @@ void StatsCollector::NotifyMarkingCompleted(size_t marked_bytes) {
current_.memory_size_before_sweep_bytes = memory_allocated_bytes_;
memory_freed_bytes_since_end_of_marking_ = 0;
ForAllAllocationObservers([marked_bytes](AllocationObserver* observer) {
observer->ResetAllocatedObjectSize(marked_bytes);
ForAllAllocationObservers([this](AllocationObserver* observer) {
observer->ResetAllocatedObjectSize(marked_bytes_so_far_);
});
// HeapGrowing would use the below fields to estimate allocation rate during
......@@ -233,9 +238,9 @@ void StatsCollector::NotifySweepingCompleted() {
previous_.concurrent_scope_data[kConcurrentMark],
previous_.concurrent_scope_data[kConcurrentSweep],
previous_.object_size_before_sweep_bytes /* objects_before */,
previous_.marked_bytes /* objects_after */,
marked_bytes_so_far_ /* objects_after */,
previous_.object_size_before_sweep_bytes -
previous_.marked_bytes /* objects_freed */,
marked_bytes_so_far_ /* objects_freed */,
previous_.memory_size_before_sweep_bytes /* memory_before */,
previous_.memory_size_before_sweep_bytes -
memory_freed_bytes_since_end_of_marking_ /* memory_after */,
......@@ -249,26 +254,17 @@ size_t StatsCollector::allocated_memory_size() const {
}
size_t StatsCollector::allocated_object_size() const {
// During sweeping we refer to the current Event as that already holds the
// correct marking information. In all other phases, the previous event holds
// the most up-to-date marking information.
const Event& event =
gc_state_ == GarbageCollectionState::kSweeping ? current_ : previous_;
DCHECK_GE(static_cast<int64_t>(event.marked_bytes) +
allocated_bytes_since_end_of_marking_,
0);
return static_cast<size_t>(static_cast<int64_t>(event.marked_bytes) +
allocated_bytes_since_end_of_marking_);
return marked_bytes_so_far_ + allocated_bytes_since_end_of_marking_;
}
size_t StatsCollector::marked_bytes() const {
DCHECK_NE(GarbageCollectionState::kMarking, gc_state_);
// During sweeping we refer to the current Event as that already holds the
// correct marking information. In all other phases, the previous event holds
// the most up-to-date marking information.
const Event& event =
gc_state_ == GarbageCollectionState::kSweeping ? current_ : previous_;
return event.marked_bytes;
return marked_bytes_so_far_;
}
size_t StatsCollector::marked_bytes_on_current_cycle() const {
DCHECK_NE(GarbageCollectionState::kNotRunning, gc_state_);
return marked_bytes_so_far_;
}
v8::base::TimeDelta StatsCollector::marking_time() const {
......
......@@ -281,9 +281,15 @@ class V8_EXPORT_PRIVATE StatsCollector final {
// bytes and the bytes allocated since last marking.
size_t allocated_object_size() const;
// Returns the most recent marked bytes count. Should not be called during
// Returns the overall marked bytes count, i.e. if young generation is
// enabled, it returns the accumulated number. Should not be called during
// marking.
size_t marked_bytes() const;
// Returns the marked bytes for the current cycle. Should only be called
// within GC cycle.
size_t marked_bytes_on_current_cycle() const;
// Returns the overall duration of the most recent marking phase. Should not
// be called during marking.
v8::base::TimeDelta marking_time() const;
......@@ -340,6 +346,10 @@ class V8_EXPORT_PRIVATE StatsCollector final {
size_t tracked_live_bytes_ = 0;
#endif // CPPGC_VERIFY_HEAP
// The number of bytes marked so far. For young generation (with sticky bits)
// keeps track of marked bytes across multiple GC cycles.
size_t marked_bytes_so_far_ = 0;
int64_t memory_allocated_bytes_ = 0;
int64_t memory_freed_bytes_since_end_of_marking_ = 0;
std::atomic<size_t> discarded_bytes_{0};
......
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