[heap-snapshot] Preventing overflow in progress counter
This prevents an overflow to happen in the heap snapshot generator. Furthermore it changes the relation of progress_counter_ and progress_total_ to always adhere to: * progress_counter_ <= progress_total_, * if: progress_counter_ == progress_total_, then it is done. With this change, if progress_counter_ happens to be bigger than progress_total_ (latter is an estimate), it will continue to report the same progress (<100%) until it is done. Before, it would repeatedly report 100% until it is done. Fixed: chromium:1246860 Change-Id: Iffd3f52355632f2b35abdbb3752912ba7b8bd821 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3250310 Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Kim-Anh Tran <kimanh@chromium.org> Cr-Commit-Position: refs/heads/main@{#77589}
This commit is contained in:
parent
e00b23d16c
commit
0e006a1527
@ -711,10 +711,15 @@ const char* V8HeapExplorer::GetSystemEntryName(HeapObject object) {
|
||||
}
|
||||
}
|
||||
|
||||
int V8HeapExplorer::EstimateObjectsCount() {
|
||||
uint32_t V8HeapExplorer::EstimateObjectsCount() {
|
||||
CombinedHeapObjectIterator it(heap_, HeapObjectIterator::kFilterUnreachable);
|
||||
int objects_count = 0;
|
||||
while (!it.Next().is_null()) ++objects_count;
|
||||
uint32_t objects_count = 0;
|
||||
// Avoid overflowing the objects count. In worst case, we will show the same
|
||||
// progress for a longer period of time, but we do not expect to have that
|
||||
// many objects.
|
||||
while (!it.Next().is_null() &&
|
||||
objects_count != std::numeric_limits<uint32_t>::max())
|
||||
++objects_count;
|
||||
return objects_count;
|
||||
}
|
||||
|
||||
@ -2260,7 +2265,17 @@ bool HeapSnapshotGenerator::GenerateSnapshot() {
|
||||
}
|
||||
|
||||
void HeapSnapshotGenerator::ProgressStep() {
|
||||
++progress_counter_;
|
||||
// Only increment the progress_counter_ until
|
||||
// equal to progress_total -1 == progress_counter.
|
||||
// This ensures that intermediate ProgressReport calls will never signal
|
||||
// that the work is finished (i.e. progress_counter_ == progress_total_).
|
||||
// Only the forced ProgressReport() at the end of GenerateSnapshot() should,
|
||||
// after setting progress_counter_ = progress_total_, signal that the
|
||||
// work is finished because signalling finished twice
|
||||
// breaks the DevTools frontend.
|
||||
if (progress_total_ > progress_counter_ + 1) {
|
||||
++progress_counter_;
|
||||
}
|
||||
}
|
||||
|
||||
bool HeapSnapshotGenerator::ProgressReport(bool force) {
|
||||
@ -2275,12 +2290,7 @@ bool HeapSnapshotGenerator::ProgressReport(bool force) {
|
||||
|
||||
void HeapSnapshotGenerator::InitProgressCounter() {
|
||||
if (control_ == nullptr) return;
|
||||
// The +1 ensures that intermediate ProgressReport calls will never signal
|
||||
// that the work is finished (i.e. progress_counter_ == progress_total_).
|
||||
// Only the forced ProgressReport() at the end of GenerateSnapshot()
|
||||
// should signal that the work is finished because signalling finished twice
|
||||
// breaks the DevTools frontend.
|
||||
progress_total_ = v8_heap_explorer_.EstimateObjectsCount() + 1;
|
||||
progress_total_ = v8_heap_explorer_.EstimateObjectsCount();
|
||||
progress_counter_ = 0;
|
||||
}
|
||||
|
||||
|
@ -354,7 +354,7 @@ class V8_EXPORT_PRIVATE V8HeapExplorer : public HeapEntriesAllocator {
|
||||
|
||||
HeapEntry* AllocateEntry(HeapThing ptr) override;
|
||||
HeapEntry* AllocateEntry(Smi smi) override;
|
||||
int EstimateObjectsCount();
|
||||
uint32_t EstimateObjectsCount();
|
||||
bool IterateAndExtractReferences(HeapSnapshotGenerator* generator);
|
||||
void CollectGlobalObjectsTags();
|
||||
void MakeGlobalObjectTagMap(const SafepointScope& safepoint_scope);
|
||||
|
Loading…
Reference in New Issue
Block a user