ART: Log approximate arena usage for slow verifier runs
Add ArenaStack::ApproximatePeakBytes and ScopedArenaAllocator::ApproximatePeakBytes
to get an approximate use when arena tracking is not enabled.
Print the approximate use for slow verifications.
Bug: 110852609
Test: m test-art-host
Test: manual
Change-Id: I529838410cdf4fe8247ddf4a6196a8186b0c4f3a
diff --git a/libartbase/base/scoped_arena_allocator.cc b/libartbase/base/scoped_arena_allocator.cc
index a54f350..a87064f 100644
--- a/libartbase/base/scoped_arena_allocator.cc
+++ b/libartbase/base/scoped_arena_allocator.cc
@@ -106,6 +106,15 @@
return ptr;
}
+size_t ArenaStack::ApproximatePeakBytes() {
+ UpdateBytesAllocated();
+ size_t sum = 0;
+ for (Arena* arena = bottom_arena_; arena != nullptr; arena = arena->next_) {
+ sum += arena->bytes_allocated_;
+ }
+ return sum;
+}
+
ScopedArenaAllocator::ScopedArenaAllocator(ScopedArenaAllocator&& other) noexcept
: DebugStackReference(std::move(other)),
DebugStackRefCounter(),
@@ -158,4 +167,29 @@
}
}
+size_t ScopedArenaAllocator::ApproximatePeakBytes() {
+ size_t subtract;
+ Arena* start;
+ if (LIKELY(mark_arena_ != nullptr)) {
+ start = mark_arena_;
+ size_t mark_free = static_cast<size_t>(mark_end_ - mark_ptr_);
+ DCHECK_GE(mark_arena_->bytes_allocated_, mark_arena_->size_ - mark_free);
+ subtract = mark_arena_->bytes_allocated_ - (mark_arena_->size_ - mark_free);
+ } else {
+ start = arena_stack_->bottom_arena_;
+ subtract = 0;
+ }
+
+ size_t sum = 0;
+ for (Arena* arena = start; arena != nullptr; arena = arena->next_) {
+ if (arena == arena_stack_->top_arena_) {
+ sum += static_cast<size_t>(arena_stack_->top_ptr_ - arena->Begin());
+ break;
+ } else {
+ sum += arena->bytes_allocated_;
+ }
+ }
+ return sum - subtract;
+}
+
} // namespace art
diff --git a/libartbase/base/scoped_arena_allocator.h b/libartbase/base/scoped_arena_allocator.h
index 52d0361..6de0192 100644
--- a/libartbase/base/scoped_arena_allocator.h
+++ b/libartbase/base/scoped_arena_allocator.h
@@ -59,6 +59,8 @@
return PeakStats()->BytesAllocated();
}
+ size_t ApproximatePeakBytes();
+
MemStats GetPeakStats() const;
// Return the arena tag associated with a pointer.
@@ -166,6 +168,8 @@
// Get adapter for use in STL containers. See scoped_arena_containers.h .
ScopedArenaAllocatorAdapter<void> Adapter(ArenaAllocKind kind = kArenaAllocSTL);
+ size_t ApproximatePeakBytes();
+
// Allow a delete-expression to destroy but not deallocate allocators created by Create().
static void operator delete(void* ptr ATTRIBUTE_UNUSED) {}
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index ee91efa..4a3b5d1 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -5348,7 +5348,9 @@
LOG(WARNING) << "Verification of " << dex_file->PrettyMethod(method_idx)
<< " took " << PrettyDuration(duration_ns)
<< (impl::IsLargeMethod(verifier.CodeItem()) ? " (large method)" : "")
- << " (" << StringPrintf("%.2f", bytecodes_per_second) << " bytecodes/s)";
+ << " (" << StringPrintf("%.2f", bytecodes_per_second) << " bytecodes/s)"
+ << " (" << verifier.allocator_.ApproximatePeakBytes()
+ << "B approximate peak alloc)";
}
}
result.types = verifier.encountered_failure_types_;