Commit 5c56e27d authored by Michal Majewski's avatar Michal Majewski Committed by Commit Bot

[test] Introduce flag for fuzzer analysis phase.

--stress-marking and --stress-scavenge flags with the value
greater than 0 enable additional tracking, allocation observers etc.

--fuzzer-analysis switches --stress-* flags into analysis mode,
which means that all allocation observers and additional checks
are still executed, but GC is not influenced by them. It also
provides analysis information needed by the fuzzer on the stdout.

Bug: v8:6972
Change-Id: I5ac45adb311441d57d5b951aeec036e689930e9f
Reviewed-on: https://chromium-review.googlesource.com/814536Reviewed-by: 's avatarHannes Payer <hpayer@chromium.org>
Reviewed-by: 's avatarMichael Achenbach <machenbach@chromium.org>
Commit-Queue: Michał Majewski <majeski@google.com>
Cr-Commit-Position: refs/heads/master@{#50453}
parent bf4cc9ee
...@@ -656,6 +656,8 @@ DEFINE_BOOL(parallel_pointer_update, true, ...@@ -656,6 +656,8 @@ DEFINE_BOOL(parallel_pointer_update, true,
"use parallel pointer update during compaction") "use parallel pointer update during compaction")
DEFINE_BOOL(trace_incremental_marking, false, DEFINE_BOOL(trace_incremental_marking, false,
"trace progress of the incremental marking") "trace progress of the incremental marking")
DEFINE_BOOL(trace_stress_marking, false, "trace stress marking progress")
DEFINE_BOOL(trace_stress_scavenge, false, "trace stress scavenge progress")
DEFINE_BOOL(track_gc_object_stats, false, DEFINE_BOOL(track_gc_object_stats, false,
"track object counts and memory usage") "track object counts and memory usage")
DEFINE_BOOL(trace_gc_object_stats, false, DEFINE_BOOL(trace_gc_object_stats, false,
...@@ -705,13 +707,18 @@ DEFINE_BOOL(stress_compaction_random, false, ...@@ -705,13 +707,18 @@ DEFINE_BOOL(stress_compaction_random, false,
"evacuation candidates. It overrides stress_compaction.") "evacuation candidates. It overrides stress_compaction.")
DEFINE_BOOL(stress_incremental_marking, false, DEFINE_BOOL(stress_incremental_marking, false,
"force incremental marking for small heaps and run it more often") "force incremental marking for small heaps and run it more often")
DEFINE_BOOL(fuzzer_gc_analysis, false,
"enables analysis mode for gc fuzz testing, e.g. --stress-marking, "
"--stress-scavenge")
DEFINE_INT(stress_marking, 0, DEFINE_INT(stress_marking, 0,
"force marking at random points between 0 and X (inclusive) percent " "force marking at random points between 0 and X (inclusive) percent "
"of the regular marking start limit") "of the regular marking start limit")
DEFINE_INT(stress_scavenge, 0, DEFINE_INT(stress_scavenge, 0,
"force scavenge at random points between 0 and X (inclusive) " "force scavenge at random points between 0 and X (inclusive) "
"percent of the new space capacity") "percent of the new space capacity")
DEFINE_BOOL(stress_scavenge_analysis, false, "enables stress-scavenge logging.") DEFINE_IMPLICATION(fuzzer_gc_analysis, stress_marking)
DEFINE_IMPLICATION(fuzzer_gc_analysis, stress_scavenge)
DEFINE_BOOL(manual_evacuation_candidates_selection, false, DEFINE_BOOL(manual_evacuation_candidates_selection, false,
"Test mode only flag. It allows an unit test to select evacuation " "Test mode only flag. It allows an unit test to select evacuation "
......
...@@ -177,6 +177,7 @@ Heap::Heap() ...@@ -177,6 +177,7 @@ Heap::Heap()
raw_allocations_hash_(0), raw_allocations_hash_(0),
stress_marking_observer_(nullptr), stress_marking_observer_(nullptr),
stress_scavenge_observer_(nullptr), stress_scavenge_observer_(nullptr),
max_marking_limit_reached_(0.0),
ms_count_(0), ms_count_(0),
gc_count_(0), gc_count_(0),
mmap_region_base_(0), mmap_region_base_(0),
...@@ -5448,13 +5449,20 @@ Heap::IncrementalMarkingLimit Heap::IncrementalMarkingLimitReached() { ...@@ -5448,13 +5449,20 @@ Heap::IncrementalMarkingLimit Heap::IncrementalMarkingLimitReached() {
if (bytes_to_limit > 0) { if (bytes_to_limit > 0) {
double current_percent = (gained_since_last_gc / bytes_to_limit) * 100.0; double current_percent = (gained_since_last_gc / bytes_to_limit) * 100.0;
if (FLAG_trace_incremental_marking) { if (FLAG_trace_stress_marking) {
isolate()->PrintWithTimestamp( isolate()->PrintWithTimestamp(
"[IncrementalMarking] %.2lf%% of the memory limit reached\n", "[IncrementalMarking] %.2lf%% of the memory limit reached\n",
current_percent); current_percent);
} }
if (static_cast<int>(current_percent) >= stress_marking_percentage_) { if (FLAG_fuzzer_gc_analysis) {
// Skips values >=100% since they already trigger marking.
if (current_percent < 100.0) {
max_marking_limit_reached_ =
std::max(max_marking_limit_reached_, current_percent);
}
} else if (static_cast<int>(current_percent) >=
stress_marking_percentage_) {
stress_marking_percentage_ = NextStressMarkingLimit(); stress_marking_percentage_ = NextStressMarkingLimit();
return IncrementalMarkingLimit::kHardLimit; return IncrementalMarkingLimit::kHardLimit;
} }
...@@ -5610,12 +5618,11 @@ bool Heap::SetUp() { ...@@ -5610,12 +5618,11 @@ bool Heap::SetUp() {
if (FLAG_stress_marking > 0) { if (FLAG_stress_marking > 0) {
stress_marking_percentage_ = NextStressMarkingLimit(); stress_marking_percentage_ = NextStressMarkingLimit();
stress_marking_observer_ = new StressMarkingObserver(*this); stress_marking_observer_ = new StressMarkingObserver(*this);
AddAllocationObserversToAllSpaces(stress_marking_observer_, AddAllocationObserversToAllSpaces(stress_marking_observer_,
stress_marking_observer_); stress_marking_observer_);
} }
if (FLAG_stress_scavenge_analysis || FLAG_stress_scavenge > 0) { if (FLAG_stress_scavenge > 0) {
stress_scavenge_observer_ = new StressScavengeObserver(*this); stress_scavenge_observer_ = new StressScavengeObserver(*this);
new_space()->AddAllocationObserver(stress_scavenge_observer_); new_space()->AddAllocationObserver(stress_scavenge_observer_);
} }
...@@ -5658,6 +5665,16 @@ void Heap::PrintAllocationsHash() { ...@@ -5658,6 +5665,16 @@ void Heap::PrintAllocationsHash() {
PrintF("\n### Allocations = %u, hash = 0x%08x\n", allocations_count(), hash); PrintF("\n### Allocations = %u, hash = 0x%08x\n", allocations_count(), hash);
} }
void Heap::PrintMaxMarkingLimitReached() {
PrintF("\n### Maximum marking limit reached = %.02lf\n",
max_marking_limit_reached_);
}
void Heap::PrintMaxNewSpaceSizeReached() {
PrintF("\n### Maximum new space size reached = %.02lf\n",
stress_scavenge_observer_->MaxNewSpaceSizeReached());
}
int Heap::NextStressMarkingLimit() { int Heap::NextStressMarkingLimit() {
return isolate()->fuzzer_rng()->NextInt(FLAG_stress_marking + 1); return isolate()->fuzzer_rng()->NextInt(FLAG_stress_marking + 1);
} }
...@@ -5724,6 +5741,15 @@ void Heap::TearDown() { ...@@ -5724,6 +5741,15 @@ void Heap::TearDown() {
PrintAllocationsHash(); PrintAllocationsHash();
} }
if (FLAG_fuzzer_gc_analysis) {
if (FLAG_stress_marking > 0) {
PrintMaxMarkingLimitReached();
}
if (FLAG_stress_scavenge > 0) {
PrintMaxNewSpaceSizeReached();
}
}
new_space()->RemoveAllocationObserver(idle_scavenge_observer_); new_space()->RemoveAllocationObserver(idle_scavenge_observer_);
delete idle_scavenge_observer_; delete idle_scavenge_observer_;
idle_scavenge_observer_ = nullptr; idle_scavenge_observer_ = nullptr;
...@@ -5734,7 +5760,7 @@ void Heap::TearDown() { ...@@ -5734,7 +5760,7 @@ void Heap::TearDown() {
delete stress_marking_observer_; delete stress_marking_observer_;
stress_marking_observer_ = nullptr; stress_marking_observer_ = nullptr;
} }
if (FLAG_stress_scavenge_analysis || FLAG_stress_scavenge > 0) { if (FLAG_stress_scavenge > 0) {
new_space()->RemoveAllocationObserver(stress_scavenge_observer_); new_space()->RemoveAllocationObserver(stress_scavenge_observer_);
delete stress_scavenge_observer_; delete stress_scavenge_observer_;
stress_scavenge_observer_ = nullptr; stress_scavenge_observer_ = nullptr;
......
...@@ -1869,6 +1869,9 @@ class Heap { ...@@ -1869,6 +1869,9 @@ class Heap {
inline void UpdateAllocationsHash(uint32_t value); inline void UpdateAllocationsHash(uint32_t value);
void PrintAllocationsHash(); void PrintAllocationsHash();
void PrintMaxMarkingLimitReached();
void PrintMaxNewSpaceSizeReached();
int NextStressMarkingLimit(); int NextStressMarkingLimit();
void AddToRingBuffer(const char* string); void AddToRingBuffer(const char* string);
...@@ -2394,6 +2397,10 @@ class Heap { ...@@ -2394,6 +2397,10 @@ class Heap {
// Observer that can cause early scavenge start. // Observer that can cause early scavenge start.
StressScavengeObserver* stress_scavenge_observer_; StressScavengeObserver* stress_scavenge_observer_;
// The maximum percent of the marking limit reached wihout causing marking.
// This is tracked when specyfing --fuzzer-gc-analysis.
double max_marking_limit_reached_;
// How many mark-sweep collections happened. // How many mark-sweep collections happened.
unsigned int ms_count_; unsigned int ms_count_;
......
...@@ -14,14 +14,15 @@ namespace internal { ...@@ -14,14 +14,15 @@ namespace internal {
// TODO(majeski): meaningful step_size // TODO(majeski): meaningful step_size
StressScavengeObserver::StressScavengeObserver(Heap& heap) StressScavengeObserver::StressScavengeObserver(Heap& heap)
: AllocationObserver(64), heap_(heap), has_requested_gc_(false) { : AllocationObserver(64),
if (FLAG_stress_scavenge > 0) { heap_(heap),
limit_percentage_ = NextLimit(); has_requested_gc_(false),
max_new_space_size_reached_(0.0) {
limit_percentage_ = NextLimit();
if (FLAG_stress_scavenge_analysis) { if (FLAG_trace_stress_scavenge && !FLAG_fuzzer_gc_analysis) {
heap_.isolate()->PrintWithTimestamp( heap_.isolate()->PrintWithTimestamp(
"[StressScavenge] %d%% is the new limit\n", limit_percentage_); "[StressScavenge] %d%% is the new limit\n", limit_percentage_);
}
} }
} }
...@@ -34,19 +35,21 @@ void StressScavengeObserver::Step(int bytes_allocated, Address soon_object, ...@@ -34,19 +35,21 @@ void StressScavengeObserver::Step(int bytes_allocated, Address soon_object,
double current_percent = double current_percent =
heap_.new_space()->Size() * 100.0 / heap_.new_space()->Capacity(); heap_.new_space()->Size() * 100.0 / heap_.new_space()->Capacity();
if (FLAG_stress_scavenge_analysis) { if (FLAG_trace_stress_scavenge) {
heap_.isolate()->PrintWithTimestamp( heap_.isolate()->PrintWithTimestamp(
"[StressScavenge] %.2lf%% of the new space capacity reached\n", "[Scavenge] %.2lf%% of the new space capacity reached\n",
current_percent); current_percent);
} }
if (!FLAG_stress_scavenge) { if (FLAG_fuzzer_gc_analysis) {
max_new_space_size_reached_ =
std::max(max_new_space_size_reached_, current_percent);
return; return;
} }
if (static_cast<int>(current_percent) >= limit_percentage_) { if (static_cast<int>(current_percent) >= limit_percentage_) {
if (FLAG_stress_scavenge_analysis) { if (FLAG_trace_stress_scavenge) {
heap_.isolate()->PrintWithTimestamp("[StressScavenge] GC requested\n"); heap_.isolate()->PrintWithTimestamp("[Scavenge] GC requested\n");
} }
has_requested_gc_ = true; has_requested_gc_ = true;
...@@ -63,17 +66,21 @@ void StressScavengeObserver::RequestedGCDone() { ...@@ -63,17 +66,21 @@ void StressScavengeObserver::RequestedGCDone() {
heap_.new_space()->Size() * 100.0 / heap_.new_space()->Capacity(); heap_.new_space()->Size() * 100.0 / heap_.new_space()->Capacity();
limit_percentage_ = NextLimit(static_cast<int>(current_percent)); limit_percentage_ = NextLimit(static_cast<int>(current_percent));
if (FLAG_stress_scavenge_analysis) { if (FLAG_trace_stress_scavenge) {
heap_.isolate()->PrintWithTimestamp( heap_.isolate()->PrintWithTimestamp(
"[StressScavenge] %.2lf%% of the new space capacity reached\n", "[Scavenge] %.2lf%% of the new space capacity reached\n",
current_percent); current_percent);
heap_.isolate()->PrintWithTimestamp( heap_.isolate()->PrintWithTimestamp("[Scavenge] %d%% is the new limit\n",
"[StressScavenge] %d%% is the new limit\n", limit_percentage_); limit_percentage_);
} }
has_requested_gc_ = false; has_requested_gc_ = false;
} }
double StressScavengeObserver::MaxNewSpaceSizeReached() const {
return max_new_space_size_reached_;
}
int StressScavengeObserver::NextLimit(int min) { int StressScavengeObserver::NextLimit(int min) {
int max = FLAG_stress_scavenge; int max = FLAG_stress_scavenge;
if (min >= max) { if (min >= max) {
......
...@@ -19,11 +19,17 @@ class StressScavengeObserver : public AllocationObserver { ...@@ -19,11 +19,17 @@ class StressScavengeObserver : public AllocationObserver {
bool HasRequestedGC() const; bool HasRequestedGC() const;
void RequestedGCDone(); void RequestedGCDone();
// The maximum percent of the newspace capacity reached. This is tracked when
// specyfing --fuzzer-gc-analysis.
double MaxNewSpaceSizeReached() const;
private: private:
Heap& heap_; Heap& heap_;
int limit_percentage_; int limit_percentage_;
bool has_requested_gc_; bool has_requested_gc_;
double max_new_space_size_reached_;
int NextLimit(int min = 0); int NextLimit(int min = 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