Commit 756e029c authored by Michael Lippautz's avatar Michael Lippautz Committed by Commit Bot

[oilpan] Add heap stats collection mechanism

This CL introduces HeapTracer which a single concept to track interesting
garbage collection numbers across garbage collections.

This allows for unit testing measurements and unifying the histogram
logic into a single place.

Bug: chromium:840789
Change-Id: Ie36d6f9cc973f0dec28a3305b2d0def59bafe135
Reviewed-on: https://chromium-review.googlesource.com/1046647
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarKeishi Hattori <keishi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#556885}
parent 75b2f822
......@@ -51,6 +51,8 @@ blink_platform_sources("heap") {
"heap_linked_stack.h",
"heap_page.cc",
"heap_page.h",
"heap_stats_collector.cc",
"heap_stats_collector.h",
"heap_terminated_array.h",
"heap_terminated_array_builder.h",
"heap_traits.h",
......@@ -111,6 +113,7 @@ jumbo_source_set("blink_heap_unittests_sources") {
"address_cache_test.cc",
"blink_gc_memory_dump_provider_test.cc",
"heap_compact_test.cc",
"heap_stats_collector_test.cc",
"heap_test.cc",
"heap_test_utilities.cc",
"heap_test_utilities.h",
......
......@@ -97,14 +97,15 @@ class PLATFORM_EXPORT BlinkGC final {
};
enum GCReason {
kIdleGC,
kPreciseGC,
kConservativeGC,
kForcedGC,
kMemoryPressureGC,
kPageNavigationGC,
kThreadTerminationGC,
kLastGCReason = kThreadTerminationGC,
kIdleGC = 0,
kPreciseGC = 1,
kConservativeGC = 2,
kForcedGC = 3,
kMemoryPressureGC = 4,
kPageNavigationGC = 5,
kThreadTerminationGC = 6,
kTesting = 7,
kLastGCReason = kTesting,
};
enum ArenaIndices {
......
......@@ -40,6 +40,7 @@
#include "third_party/blink/renderer/platform/heap/address_cache.h"
#include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h"
#include "third_party/blink/renderer/platform/heap/heap_compact.h"
#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
#include "third_party/blink/renderer/platform/heap/marking_visitor.h"
#include "third_party/blink/renderer/platform/heap/page_memory.h"
#include "third_party/blink/renderer/platform/heap/page_pool.h"
......@@ -128,6 +129,7 @@ double ThreadHeapStats::LiveObjectRateSinceLastGC() const {
ThreadHeap::ThreadHeap(ThreadState* thread_state)
: thread_state_(thread_state),
heap_stats_collector_(std::make_unique<ThreadHeapStatsCollector>()),
region_tree_(std::make_unique<RegionTree>()),
address_cache_(std::make_unique<AddressCache>()),
free_page_pool_(std::make_unique<PagePool>()),
......
......@@ -56,6 +56,7 @@ class IncrementalMarkingScopeBase;
} // namespace incremental_marking_test
class AddressCache;
class ThreadHeapStatsCollector;
class PagePool;
class RegionTree;
......@@ -463,6 +464,10 @@ class PLATFORM_EXPORT ThreadHeap {
enum SnapshotType { kHeapSnapshot, kFreelistSnapshot };
void TakeSnapshot(SnapshotType);
ThreadHeapStatsCollector* stats_collector() const {
return heap_stats_collector_.get();
}
#if defined(ADDRESS_SANITIZER)
void PoisonEagerArena();
void PoisonAllHeaps();
......@@ -496,6 +501,7 @@ class PLATFORM_EXPORT ThreadHeap {
ThreadState* thread_state_;
ThreadHeapStats stats_;
std::unique_ptr<ThreadHeapStatsCollector> heap_stats_collector_;
std::unique_ptr<RegionTree> region_tree_;
std::unique_ptr<AddressCache> address_cache_;
std::unique_ptr<PagePool> free_page_pool_;
......
......@@ -36,6 +36,7 @@
#include "third_party/blink/renderer/platform/heap/address_cache.h"
#include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h"
#include "third_party/blink/renderer/platform/heap/heap_compact.h"
#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
#include "third_party/blink/renderer/platform/heap/marking_verifier.h"
#include "third_party/blink/renderer/platform/heap/page_memory.h"
#include "third_party/blink/renderer/platform/heap/page_pool.h"
......@@ -265,16 +266,16 @@ Address BaseArena::LazySweep(size_t allocation_size, size_t gc_info_index) {
if (GetThreadState()->SweepForbidden())
return nullptr;
TRACE_EVENT0("blink_gc", "BaseArena::lazySweepPages");
Address result = nullptr;
{
ThreadHeapStatsCollector::Scope stats_scope(
GetThreadState()->Heap().stats_collector(),
ThreadHeapStatsCollector::Scope::kLazySweepOnAllocation);
ThreadState::SweepForbiddenScope sweep_forbidden(GetThreadState());
ScriptForbiddenScope script_forbidden;
double start_time = WTF::CurrentTimeTicksInMilliseconds();
Address result = LazySweepPages(allocation_size, gc_info_index);
GetThreadState()->AccumulateSweepingTime(
WTF::CurrentTimeTicksInMilliseconds() - start_time);
result = LazySweepPages(allocation_size, gc_info_index);
}
ThreadHeap::ReportMemoryUsageForTracing();
return result;
}
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
#include "base/logging.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
namespace blink {
ThreadHeapStatsCollector::Scope::Scope(ThreadHeapStatsCollector* tracer,
ThreadHeapStatsCollector::Scope::Id id)
: tracer_(tracer),
start_time_(WTF::CurrentTimeTicksInMilliseconds()),
id_(id) {
TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("blink_gc"),
ThreadHeapStatsCollector::Scope::ToString(id_));
}
ThreadHeapStatsCollector::Scope::~Scope() {
TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("blink_gc"),
ThreadHeapStatsCollector::Scope::ToString(id_));
tracer_->IncreaseScopeTime(
id_, WTF::CurrentTimeTicksInMilliseconds() - start_time_);
}
const char* ThreadHeapStatsCollector::Scope::ToString(
ThreadHeapStatsCollector::Scope::Id id) {
switch (id) {
case Scope::kCompleteSweep:
return "BlinkGC.CompleteSweep";
case Scope::kEagerSweep:
return "BlinkGC.EagerSweep";
case Scope::kIncrementalMarkingStartMarking:
return "BlinkGC.IncrementalMarkingStartMarking";
case Scope::kIncrementalMarkingStep:
return "BlinkGC.IncrementalMarkingStep";
case Scope::kIncrementalMarkingFinalize:
return "BlinkGC.IncrementalMarkingFinalize";
case Scope::kIncrementalMarkingFinalizeMarking:
return "BlinkGC.IncrementalMarkingFinalizeMarking";
case Scope::kLazySweepInIdle:
return "BlinkGC.LazySweepInIdle";
case Scope::kLazySweepOnAllocation:
return "BlinkGC.LazySweepOnAllocation";
case Scope::kFullGCMarking:
return "BlinkGC.FullGCMarking";
case Scope::kNumIds:
break;
}
CHECK(false);
return nullptr;
}
void ThreadHeapStatsCollector::IncreaseScopeTime(
ThreadHeapStatsCollector::Scope::Id id,
double time) {
DCHECK(is_started_);
current_.scope_data[id] += time;
}
void ThreadHeapStatsCollector::IncreaseMarkedObjectSize(size_t size) {
DCHECK(is_started_);
current_.marked_object_size += size;
}
void ThreadHeapStatsCollector::Start(BlinkGC::GCReason reason) {
DCHECK(!is_started_);
is_started_ = true;
current_.reason = reason;
}
void ThreadHeapStatsCollector::Stop() {
is_started_ = false;
previous_ = std::move(current_);
current_.reset();
}
void ThreadHeapStatsCollector::Event::reset() {
marked_object_size = 0;
memset(scope_data, 0, sizeof(scope_data));
reason = BlinkGC::kTesting;
}
double ThreadHeapStatsCollector::Event::marking_time_in_ms() const {
return scope_data[Scope::kIncrementalMarkingStartMarking] +
scope_data[Scope::kIncrementalMarkingStep] +
scope_data[Scope::kIncrementalMarkingFinalizeMarking] +
scope_data[Scope::kFullGCMarking];
}
double ThreadHeapStatsCollector::Event::marking_time_per_byte_in_s() const {
return marked_object_size ? marking_time_in_ms() / 1000 / marked_object_size
: 0.0;
}
double ThreadHeapStatsCollector::Event::sweeping_time_in_ms() const {
return scope_data[Scope::kCompleteSweep] + scope_data[Scope::kEagerSweep] +
scope_data[Scope::kLazySweepInIdle] +
scope_data[Scope::kLazySweepOnAllocation];
}
} // namespace blink
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_STATS_COLLECTOR_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_STATS_COLLECTOR_H_
#include <stddef.h>
#include "third_party/blink/renderer/platform/heap/blink_gc.h"
#include "third_party/blink/renderer/platform/platform_export.h"
namespace blink {
// Manages counters and statistics across garbage collection cycles.
//
// Usage:
// ThreadHeapStatsCollector stats_collector;
// stats_collector.Start(<BlinkGC::GCReason>);
// // Use tracer.
// // Current event is available using stats_collector.current().
// stats_collector.Stop();
// // Previous event is available using stats_collector.previous().
class PLATFORM_EXPORT ThreadHeapStatsCollector {
public:
// Trace a particular scope. Will emit a trace event and record the time in
// the corresponding ThreadHeapStatsCollector.
class PLATFORM_EXPORT Scope {
public:
// These ids will form human readable names when used in Scopes.
enum Id {
kCompleteSweep,
kEagerSweep,
kIncrementalMarkingStartMarking,
kIncrementalMarkingStep,
kIncrementalMarkingFinalize,
kIncrementalMarkingFinalizeMarking,
kLazySweepInIdle,
kLazySweepOnAllocation,
kFullGCMarking,
kNumIds,
};
static const char* ToString(Id);
Scope(ThreadHeapStatsCollector*, Id);
~Scope();
private:
ThreadHeapStatsCollector* const tracer_;
const double start_time_;
const Id id_;
};
struct PLATFORM_EXPORT Event {
void reset();
double marking_time_in_ms() const;
double marking_time_per_byte_in_s() const;
double sweeping_time_in_ms() const;
size_t marked_object_size = 0;
double scope_data[Scope::kNumIds] = {0};
BlinkGC::GCReason reason;
};
void Start(BlinkGC::GCReason);
void Stop();
void IncreaseScopeTime(Scope::Id, double);
void IncreaseMarkedObjectSize(size_t);
bool is_started() const { return is_started_; }
const Event& current() const { return current_; }
const Event& previous() const { return previous_; }
private:
Event current_;
Event previous_;
bool is_started_ = false;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_STATS_COLLECTOR_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace blink {
// =============================================================================
// ThreadHeapStatsCollector. ===================================================
// =============================================================================
TEST(ThreadHeapStatsCollectorTest, InitialEmpty) {
ThreadHeapStatsCollector stats_collector;
stats_collector.Start(BlinkGC::kTesting);
for (int i = 0; i < ThreadHeapStatsCollector::Scope::Id::kNumIds; i++) {
EXPECT_DOUBLE_EQ(0.0, stats_collector.current().scope_data[i]);
}
stats_collector.Stop();
}
TEST(ThreadHeapStatsCollectorTest, IncreaseScopeTime) {
ThreadHeapStatsCollector stats_collector;
stats_collector.Start(BlinkGC::kTesting);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::Scope::kIncrementalMarkingStep, 1.0);
EXPECT_DOUBLE_EQ(
1.0, stats_collector.current().scope_data
[ThreadHeapStatsCollector::Scope::kIncrementalMarkingStep]);
}
TEST(ThreadHeapStatsCollectorTest, StopMovesCurrentToPrevious) {
ThreadHeapStatsCollector stats_collector;
stats_collector.Start(BlinkGC::kTesting);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::Scope::kIncrementalMarkingStep, 1.0);
stats_collector.Stop();
EXPECT_DOUBLE_EQ(
1.0, stats_collector.previous().scope_data
[ThreadHeapStatsCollector::Scope::kIncrementalMarkingStep]);
}
TEST(ThreadHeapStatsCollectorTest, StopResetsCurrent) {
ThreadHeapStatsCollector stats_collector;
stats_collector.Start(BlinkGC::kTesting);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::Scope::kIncrementalMarkingStep, 1.0);
stats_collector.Stop();
EXPECT_DOUBLE_EQ(
0.0, stats_collector.current().scope_data
[ThreadHeapStatsCollector::Scope::kIncrementalMarkingStep]);
}
TEST(ThreadHeapStatsCollectorTest, StartStop) {
ThreadHeapStatsCollector stats_collector;
EXPECT_FALSE(stats_collector.is_started());
stats_collector.Start(BlinkGC::kTesting);
EXPECT_TRUE(stats_collector.is_started());
stats_collector.Stop();
EXPECT_FALSE(stats_collector.is_started());
}
// =============================================================================
// ThreadHeapStatsCollector::Scope. ============================================
// =============================================================================
TEST(ThreadHeapStatsCollectorTest, ScopeToString) {
EXPECT_STREQ(
"BlinkGC.IncrementalMarkingStartMarking",
ThreadHeapStatsCollector::Scope::ToString(
ThreadHeapStatsCollector::Scope::kIncrementalMarkingStartMarking));
}
// =============================================================================
// ThreadHeapStatsCollector::Event. ============================================
// =============================================================================
TEST(ThreadHeapStatsCollectorTest, EventMarkedObjectSize) {
ThreadHeapStatsCollector stats_collector;
stats_collector.Start(BlinkGC::kTesting);
stats_collector.IncreaseMarkedObjectSize(1024);
stats_collector.Stop();
EXPECT_EQ(1024u, stats_collector.previous().marked_object_size);
}
TEST(ThreadHeapStatsCollectorTest, EventMarkingTimeInMsFromIncrementalGC) {
ThreadHeapStatsCollector stats_collector;
stats_collector.Start(BlinkGC::kTesting);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::Scope::kIncrementalMarkingStartMarking, 7.0);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::Scope::kIncrementalMarkingStep, 2.0);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::Scope::kIncrementalMarkingFinalizeMarking, 1.0);
// Ignore the full finalization.
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::Scope::kIncrementalMarkingFinalize, 3.0);
stats_collector.Stop();
EXPECT_DOUBLE_EQ(10.0, stats_collector.previous().marking_time_in_ms());
}
TEST(ThreadHeapStatsCollectorTest, EventMarkingTimeInMsFromFullGC) {
ThreadHeapStatsCollector stats_collector;
stats_collector.Start(BlinkGC::kTesting);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::Scope::kFullGCMarking, 11.0);
stats_collector.Stop();
EXPECT_DOUBLE_EQ(11.0, stats_collector.previous().marking_time_in_ms());
}
TEST(ThreadHeapStatsCollectorTest, EventMarkingTimePerByteInS) {
ThreadHeapStatsCollector stats_collector;
stats_collector.Start(BlinkGC::kTesting);
stats_collector.IncreaseMarkedObjectSize(1000);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::Scope::kFullGCMarking, 1000.0);
stats_collector.Stop();
EXPECT_DOUBLE_EQ(.001,
stats_collector.previous().marking_time_per_byte_in_s());
}
TEST(ThreadHeapStatsCollectorTest, SweepingTimeInMs) {
ThreadHeapStatsCollector stats_collector;
stats_collector.Start(BlinkGC::kTesting);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::Scope::kLazySweepInIdle, 1.0);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::Scope::kLazySweepInIdle, 2.0);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::Scope::kLazySweepInIdle, 3.0);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::Scope::kLazySweepOnAllocation, 4.0);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::Scope::kCompleteSweep, 5.0);
stats_collector.Stop();
EXPECT_DOUBLE_EQ(15.0, stats_collector.previous().sweeping_time_in_ms());
}
} // namespace blink
......@@ -42,6 +42,7 @@
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/heap_linked_stack.h"
#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
#include "third_party/blink/renderer/platform/heap/heap_terminated_array_builder.h"
#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
#include "third_party/blink/renderer/platform/heap/marking_visitor.h"
......@@ -365,6 +366,7 @@ class TestGCMarkingScope : public TestGCCollectGarbageScope {
: TestGCCollectGarbageScope(state),
atomic_pause_scope_(ThreadState::Current()),
persistent_lock_(ProcessHeap::CrossThreadPersistentMutex()) {
ThreadState::Current()->Heap().stats_collector()->Start(BlinkGC::kTesting);
ThreadState::Current()->MarkPhasePrologue(state, BlinkGC::kAtomicMarking,
BlinkGC::kPreciseGC);
}
......
......@@ -49,6 +49,7 @@
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
#include "third_party/blink/renderer/platform/heap/heap_compact.h"
#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
#include "third_party/blink/renderer/platform/heap/marking_visitor.h"
#include "third_party/blink/renderer/platform/heap/page_pool.h"
#include "third_party/blink/renderer/platform/heap/safe_point.h"
......@@ -106,6 +107,8 @@ const char* GcReasonString(BlinkGC::GCReason reason) {
return "PageNavigationGC";
case BlinkGC::kThreadTerminationGC:
return "ThreadTerminationGC";
case BlinkGC::kTesting:
return "TestingGC";
}
return "<Unknown>";
}
......@@ -155,7 +158,6 @@ ThreadState::ThreadState()
no_allocation_count_(0),
gc_forbidden_count_(0),
mixins_being_constructed_count_(0),
accumulated_sweeping_time_(0),
object_resurrection_forbidden_(false),
in_atomic_pause_(false),
gc_mixin_marker_(nullptr),
......@@ -655,20 +657,22 @@ void ThreadState::PerformIdleLazySweep(double deadline_seconds) {
RUNTIME_CALL_TIMER_SCOPE_IF_ISOLATE_EXISTS(
GetIsolate(), RuntimeCallStats::CounterId::kPerformIdleLazySweep);
bool sweep_completed = false;
{
AtomicPauseScope atomic_pause_scope(this);
SweepForbiddenScope scope(this);
ThreadHeapStatsCollector::Scope stats_scope(
Heap().stats_collector(),
ThreadHeapStatsCollector::Scope::kLazySweepInIdle);
TRACE_EVENT1("blink_gc,devtools.timeline",
"ThreadState::performIdleLazySweep", "idleDeltaInSeconds",
deadline_seconds - CurrentTimeTicksInSeconds());
AtomicPauseScope atomic_pause_scope(this);
SweepForbiddenScope scope(this);
double start_time = WTF::CurrentTimeTicksInMilliseconds();
bool sweep_completed = Heap().AdvanceLazySweep(deadline_seconds);
sweep_completed = Heap().AdvanceLazySweep(deadline_seconds);
// We couldn't finish the sweeping within the deadline.
// We request another idle task for the remaining sweeping.
if (!sweep_completed)
ScheduleIdleLazySweep();
AccumulateSweepingTime(WTF::CurrentTimeTicksInMilliseconds() - start_time);
}
if (sweep_completed)
PostSweep();
......@@ -882,6 +886,7 @@ void ThreadState::PreSweep(BlinkGC::MarkingType marking_type,
gc_state_ = kNoGCScheduled;
SetGCPhase(GCPhase::kSweeping);
SetGCPhase(GCPhase::kNone);
Heap().stats_collector()->Stop();
return;
}
......@@ -894,8 +899,6 @@ void ThreadState::PreSweep(BlinkGC::MarkingType marking_type,
// a dead object gets resurrected.
InvokePreFinalizers();
accumulated_sweeping_time_ = 0;
EagerSweep();
// Any sweep compaction must happen after pre-finalizers and eager
......@@ -925,12 +928,10 @@ void ThreadState::EagerSweep() {
// by lazy sweeping. Keep those in a designated heap and sweep it
// eagerly.
DCHECK(IsSweepingInProgress());
SweepForbiddenScope scope(this);
double start_time = WTF::CurrentTimeTicksInMilliseconds();
ThreadHeapStatsCollector::Scope stats_scope(
Heap().stats_collector(), ThreadHeapStatsCollector::Scope::kEagerSweep);
Heap().Arena(BlinkGC::kEagerSweepArenaIndex)->CompleteSweep();
AccumulateSweepingTime(WTF::CurrentTimeTicksInMilliseconds() - start_time);
}
void ThreadState::CompleteSweep() {
......@@ -945,24 +946,15 @@ void ThreadState::CompleteSweep() {
if (SweepForbidden())
return;
{
AtomicPauseScope atomic_pause_scope(this);
SweepForbiddenScope scope(this);
ThreadHeapStatsCollector::Scope stats_scope(
Heap().stats_collector(),
ThreadHeapStatsCollector::Scope::kCompleteSweep);
TRACE_EVENT0("blink_gc,devtools.timeline", "ThreadState::completeSweep");
double start_time = WTF::CurrentTimeTicksInMilliseconds();
Heap().CompleteSweep();
double time_for_complete_sweep =
WTF::CurrentTimeTicksInMilliseconds() - start_time;
AccumulateSweepingTime(time_for_complete_sweep);
if (IsMainThread()) {
DEFINE_STATIC_LOCAL(CustomCountHistogram, complete_sweep_histogram,
("BlinkGC.CompleteSweep", 1, 10 * 1000, 50));
complete_sweep_histogram.Count(time_for_complete_sweep);
}
PostSweep();
}
......@@ -975,6 +967,31 @@ BlinkGCObserver::~BlinkGCObserver() {
thread_state_->RemoveObserver(this);
}
namespace {
void UpdateHistograms(const ThreadHeapStatsCollector::Event& event) {
DEFINE_THREAD_SAFE_STATIC_LOCAL(
EnumerationHistogram, gc_reason_histogram,
("BlinkGC.GCReason", BlinkGC::kLastGCReason + 1));
gc_reason_histogram.Count(event.reason);
// TODO(mlippautz): Update name of this histogram.
DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, marking_time_histogram,
("BlinkGC.CollectGarbage", 0, 10 * 1000, 50));
marking_time_histogram.Count(event.marking_time_in_ms());
DEFINE_STATIC_LOCAL(CustomCountHistogram, complete_sweep_histogram,
("BlinkGC.CompleteSweep", 1, 10 * 1000, 50));
complete_sweep_histogram.Count(
event.scope_data[ThreadHeapStatsCollector::Scope::kCompleteSweep]);
DEFINE_STATIC_LOCAL(CustomCountHistogram, time_for_sweep_histogram,
("BlinkGC.TimeForSweepingAllObjects", 1, 10 * 1000, 50));
time_for_sweep_histogram.Count(event.sweeping_time_in_ms());
}
} // namespace
void ThreadState::PostSweep() {
DCHECK(CheckThread());
ThreadHeap::ReportMemoryUsageForTracing();
......@@ -1007,10 +1024,6 @@ void ThreadState::PostSweep() {
DEFINE_STATIC_LOCAL(CustomCountHistogram, collection_rate_histogram,
("BlinkGC.CollectionRate", 1, 100, 20));
collection_rate_histogram.Count(static_cast<int>(100 * collection_rate));
DEFINE_STATIC_LOCAL(
CustomCountHistogram, time_for_sweep_histogram,
("BlinkGC.TimeForSweepingAllObjects", 1, 10 * 1000, 50));
time_for_sweep_histogram.Count(accumulated_sweeping_time_);
#define COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(GCReason) \
case BlinkGC::k##GCReason: { \
......@@ -1040,6 +1053,10 @@ void ThreadState::PostSweep() {
for (auto* const observer : observers_)
observer->OnCompleteSweepDone();
Heap().stats_collector()->Stop();
if (IsMainThread())
UpdateHistograms(Heap().stats_collector()->previous());
}
void ThreadState::SafePoint(BlinkGC::StackState stack_state) {
......@@ -1274,16 +1291,27 @@ void ThreadState::IncrementalMarkingStart() {
VLOG(2) << "[state:" << this << "] "
<< "IncrementalMarking: Start";
CompleteSweep();
// TODO(mlippautz): Replace this with a proper reason once incremental marking
// is actually scheduled in production.
Heap().stats_collector()->Start(BlinkGC::kTesting);
{
ThreadHeapStatsCollector::Scope stats_scope(
Heap().stats_collector(),
ThreadHeapStatsCollector::Scope::kIncrementalMarkingStartMarking);
AtomicPauseScope atomic_pause_scope(this);
MarkPhasePrologue(BlinkGC::kNoHeapPointersOnStack,
BlinkGC::kIncrementalMarking, BlinkGC::kIdleGC);
BlinkGC::kIncrementalMarking, BlinkGC::kTesting);
MarkPhaseVisitRoots();
EnableIncrementalMarkingBarrier();
ScheduleIncrementalMarkingStep();
DCHECK(IsMarkingInProgress());
}
}
void ThreadState::IncrementalMarkingStep() {
ThreadHeapStatsCollector::Scope stats_scope(
Heap().stats_collector(),
ThreadHeapStatsCollector::Scope::kIncrementalMarkingStep);
VLOG(2) << "[state:" << this << "] "
<< "IncrementalMarking: Step";
AtomicPauseScope atomic_pause_scope(this);
......@@ -1298,20 +1326,30 @@ void ThreadState::IncrementalMarkingStep() {
}
void ThreadState::IncrementalMarkingFinalize() {
{
ThreadHeapStatsCollector::Scope stats_scope(
Heap().stats_collector(),
ThreadHeapStatsCollector::Scope::kIncrementalMarkingFinalize);
VLOG(2) << "[state:" << this << "] "
<< "IncrementalMarking: Finalize";
SetGCState(kNoGCScheduled);
DisableIncrementalMarkingBarrier();
AtomicPauseScope atomic_pause_scope(this);
DCHECK(IsMarkingInProgress());
{
ThreadHeapStatsCollector::Scope stats_scope(
Heap().stats_collector(),
ThreadHeapStatsCollector::Scope::kIncrementalMarkingFinalizeMarking);
MarkPhaseVisitRoots();
bool complete =
MarkPhaseAdvanceMarking(std::numeric_limits<double>::infinity());
CHECK(complete);
MarkPhaseEpilogue(current_gc_data_.marking_type);
}
PreSweep(current_gc_data_.marking_type, BlinkGC::kLazySweeping);
DCHECK(IsSweepingInProgress());
DCHECK_EQ(GcState(), kNoGCScheduled);
}
}
void ThreadState::CollectGarbage(BlinkGC::StackState stack_state,
......@@ -1327,7 +1365,6 @@ void ThreadState::CollectGarbage(BlinkGC::StackState stack_state,
double start_total_collect_garbage_time =
WTF::CurrentTimeTicksInMilliseconds();
RUNTIME_CALL_TIMER_SCOPE_IF_ISOLATE_EXISTS(
GetIsolate(), RuntimeCallStats::CounterId::kCollectGarbage);
......@@ -1341,8 +1378,8 @@ void ThreadState::CollectGarbage(BlinkGC::StackState stack_state,
}
// We don't want floating garbage for the specific garbage collection types
// mentioned below. In this case we will follow up with a regular full garbage
// collection.
// mentioned below. In this case we will follow up with a regular full
// garbage collection.
const bool should_do_full_gc = !was_incremental_marking ||
reason == BlinkGC::kForcedGC ||
reason == BlinkGC::kMemoryPressureGC ||
......@@ -1350,8 +1387,12 @@ void ThreadState::CollectGarbage(BlinkGC::StackState stack_state,
if (should_do_full_gc) {
CompleteSweep();
SetGCState(kNoGCScheduled);
Heap().stats_collector()->Start(reason);
AtomicPauseScope atomic_pause_scope(this);
{
ThreadHeapStatsCollector::Scope stats_scope(
Heap().stats_collector(),
ThreadHeapStatsCollector::Scope::kFullGCMarking);
TRACE_EVENT2("blink_gc,devtools.timeline", "BlinkGCMarking",
"lazySweeping", sweeping_type == BlinkGC::kLazySweeping,
"gcReason", GcReasonString(reason));
......@@ -1498,9 +1539,6 @@ void ThreadState::MarkPhaseEpilogue(BlinkGC::MarkingType marking_type) {
if (invalidate_dead_objects_in_wrappers_marking_deque_)
invalidate_dead_objects_in_wrappers_marking_deque_(isolate_);
DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, marking_time_histogram,
("BlinkGC.CollectGarbage", 0, 10 * 1000, 50));
marking_time_histogram.Count(current_gc_data_.marking_time_in_milliseconds);
DEFINE_THREAD_SAFE_STATIC_LOCAL(
CustomCountHistogram, total_object_space_histogram,
("BlinkGC.TotalObjectSpace", 0, 4 * 1024 * 1024, 50));
......@@ -1511,10 +1549,6 @@ void ThreadState::MarkPhaseEpilogue(BlinkGC::MarkingType marking_type) {
("BlinkGC.TotalAllocatedSpace", 0, 4 * 1024 * 1024, 50));
total_allocated_space_histogram.Count(ProcessHeap::TotalAllocatedSpace() /
1024);
DEFINE_THREAD_SAFE_STATIC_LOCAL(
EnumerationHistogram, gc_reason_histogram,
("BlinkGC.GCReason", BlinkGC::kLastGCReason + 1));
gc_reason_histogram.Count(current_gc_data_.reason);
}
void ThreadState::VerifyMarking(BlinkGC::MarkingType marking_type) {
......
......@@ -530,10 +530,6 @@ class PLATFORM_EXPORT ThreadState {
}
}
void AccumulateSweepingTime(double time) {
accumulated_sweeping_time_ += time;
}
void FreePersistentNode(PersistentRegion*, PersistentNode*);
using PersistentClearCallback = void (*)(void*);
......@@ -700,7 +696,6 @@ class PLATFORM_EXPORT ThreadState {
size_t no_allocation_count_;
size_t gc_forbidden_count_;
size_t mixins_being_constructed_count_;
double accumulated_sweeping_time_;
bool object_resurrection_forbidden_;
bool in_atomic_pause_;
......
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