Commit 9cdaf33e authored by reveman's avatar reveman Committed by Commit bot

content: Update crash key and discardable memory usage counter in child process.

This is useful when analyzing the discardable memory usage of a specific
renderer and the crash key is useful to have in crash reports.

BUG=460995

Review URL: https://codereview.chromium.org/952273005

Cr-Commit-Position: refs/heads/master@{#318253}
parent f95b436f
...@@ -4,8 +4,11 @@ ...@@ -4,8 +4,11 @@
#include "content/child/child_discardable_shared_memory_manager.h" #include "content/child/child_discardable_shared_memory_manager.h"
#include "base/debug/crash_logging.h"
#include "base/memory/discardable_shared_memory.h" #include "base/memory/discardable_shared_memory.h"
#include "base/process/process_metrics.h" #include "base/process/process_metrics.h"
#include "base/strings/string_number_conversions.h"
#include "base/trace_event/trace_event.h"
#include "content/common/child_process_messages.h" #include "content/common/child_process_messages.h"
namespace content { namespace content {
...@@ -43,10 +46,12 @@ class DiscardableMemoryShmemChunkImpl ...@@ -43,10 +46,12 @@ class DiscardableMemoryShmemChunkImpl
ChildDiscardableSharedMemoryManager::ChildDiscardableSharedMemoryManager( ChildDiscardableSharedMemoryManager::ChildDiscardableSharedMemoryManager(
ThreadSafeSender* sender) ThreadSafeSender* sender)
: heap_(base::GetPageSize()), sender_(sender) { : heap_(base::GetPageSize()), sender_(sender), bytes_allocated_(0) {
} }
ChildDiscardableSharedMemoryManager::~ChildDiscardableSharedMemoryManager() { ChildDiscardableSharedMemoryManager::~ChildDiscardableSharedMemoryManager() {
if (bytes_allocated_)
BytesAllocatedChanged(0);
} }
scoped_ptr<base::DiscardableMemoryShmemChunk> scoped_ptr<base::DiscardableMemoryShmemChunk>
...@@ -75,7 +80,11 @@ ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory( ...@@ -75,7 +80,11 @@ ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(
base::DiscardableSharedMemory::FAILED) { base::DiscardableSharedMemory::FAILED) {
DCHECK(!free_span->shared_memory()->IsMemoryResident()); DCHECK(!free_span->shared_memory()->IsMemoryResident());
// We have to release free memory before |free_span| can be destroyed. // We have to release free memory before |free_span| can be destroyed.
heap_.ReleaseFreeMemory(); size_t bytes_released = heap_.ReleaseFreeMemory();
DCHECK_NE(bytes_released, 0u);
DCHECK_LE(bytes_released, bytes_allocated_);
bytes_allocated_ -= bytes_released;
BytesAllocatedChanged(bytes_allocated_);
DCHECK(!free_span->shared_memory()); DCHECK(!free_span->shared_memory());
continue; continue;
} }
...@@ -86,7 +95,12 @@ ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory( ...@@ -86,7 +95,12 @@ ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(
// Release free memory and free up the address space. Failing to do this // Release free memory and free up the address space. Failing to do this
// can result in the child process running out of address space. // can result in the child process running out of address space.
heap_.ReleaseFreeMemory(); size_t bytes_released = heap_.ReleaseFreeMemory();
if (bytes_released) {
DCHECK_LE(bytes_released, bytes_allocated_);
bytes_allocated_ -= bytes_released;
BytesAllocatedChanged(bytes_allocated_);
}
size_t pages_to_allocate = size_t pages_to_allocate =
std::max(kAllocationSize / base::GetPageSize(), pages); std::max(kAllocationSize / base::GetPageSize(), pages);
...@@ -96,6 +110,11 @@ ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory( ...@@ -96,6 +110,11 @@ ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(
scoped_ptr<base::DiscardableSharedMemory> shared_memory( scoped_ptr<base::DiscardableSharedMemory> shared_memory(
AllocateLockedDiscardableSharedMemory(allocation_size_in_bytes)); AllocateLockedDiscardableSharedMemory(allocation_size_in_bytes));
// Note: use mapped size rather than |allocation_size_in_bytes| as
// the latter only represent the amount of memory available for usage.
bytes_allocated_ += shared_memory->mapped_size();
BytesAllocatedChanged(bytes_allocated_);
// Create span for allocated memory. // Create span for allocated memory.
scoped_ptr<DiscardableSharedMemoryHeap::Span> new_span( scoped_ptr<DiscardableSharedMemoryHeap::Span> new_span(
heap_.Grow(shared_memory.Pass(), allocation_size_in_bytes)); heap_.Grow(shared_memory.Pass(), allocation_size_in_bytes));
...@@ -118,7 +137,12 @@ ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory( ...@@ -118,7 +137,12 @@ ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(
void ChildDiscardableSharedMemoryManager::ReleaseFreeMemory() { void ChildDiscardableSharedMemoryManager::ReleaseFreeMemory() {
base::AutoLock lock(lock_); base::AutoLock lock(lock_);
heap_.ReleaseFreeMemory(); size_t bytes_released = heap_.ReleaseFreeMemory();
if (bytes_released) {
DCHECK_LE(bytes_released, bytes_allocated_);
bytes_allocated_ -= bytes_released;
BytesAllocatedChanged(bytes_allocated_);
}
} }
bool ChildDiscardableSharedMemoryManager::LockSpan( bool ChildDiscardableSharedMemoryManager::LockSpan(
...@@ -194,4 +218,14 @@ ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory( ...@@ -194,4 +218,14 @@ ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory(
return memory.Pass(); return memory.Pass();
} }
void ChildDiscardableSharedMemoryManager::BytesAllocatedChanged(
size_t new_bytes_allocated) const {
TRACE_COUNTER_ID1("renderer", "DiscardableMemoryUsage", this,
new_bytes_allocated);
static const char kDiscardableMemoryUsageKey[] = "dm-usage";
base::debug::SetCrashKeyValue(kDiscardableMemoryUsageKey,
base::Uint64ToString(new_bytes_allocated));
}
} // namespace content } // namespace content
...@@ -36,10 +36,12 @@ class CONTENT_EXPORT ChildDiscardableSharedMemoryManager ...@@ -36,10 +36,12 @@ class CONTENT_EXPORT ChildDiscardableSharedMemoryManager
private: private:
scoped_ptr<base::DiscardableSharedMemory> scoped_ptr<base::DiscardableSharedMemory>
AllocateLockedDiscardableSharedMemory(size_t size); AllocateLockedDiscardableSharedMemory(size_t size);
void BytesAllocatedChanged(size_t new_bytes_allocated) const;
mutable base::Lock lock_; mutable base::Lock lock_;
DiscardableSharedMemoryHeap heap_; DiscardableSharedMemoryHeap heap_;
scoped_refptr<ThreadSafeSender> sender_; scoped_refptr<ThreadSafeSender> sender_;
size_t bytes_allocated_;
DISALLOW_COPY_AND_ASSIGN(ChildDiscardableSharedMemoryManager); DISALLOW_COPY_AND_ASSIGN(ChildDiscardableSharedMemoryManager);
}; };
......
...@@ -142,7 +142,8 @@ DiscardableSharedMemoryHeap::SearchFreeList(size_t blocks) { ...@@ -142,7 +142,8 @@ DiscardableSharedMemoryHeap::SearchFreeList(size_t blocks) {
return best ? Carve(best, blocks) : nullptr; return best ? Carve(best, blocks) : nullptr;
} }
void DiscardableSharedMemoryHeap::ReleaseFreeMemory() { size_t DiscardableSharedMemoryHeap::ReleaseFreeMemory() {
size_t bytes_released = 0;
size_t i = 0; size_t i = 0;
// Release memory for all non-resident segments. // Release memory for all non-resident segments.
...@@ -155,12 +156,16 @@ void DiscardableSharedMemoryHeap::ReleaseFreeMemory() { ...@@ -155,12 +156,16 @@ void DiscardableSharedMemoryHeap::ReleaseFreeMemory() {
continue; continue;
} }
bytes_released += shared_memory->mapped_size();
// Release the memory and unregistering all associated spans. // Release the memory and unregistering all associated spans.
ReleaseMemory(shared_memory); ReleaseMemory(shared_memory);
std::swap(shared_memory_segments_[i], shared_memory_segments_.back()); std::swap(shared_memory_segments_[i], shared_memory_segments_.back());
shared_memory_segments_.pop_back(); shared_memory_segments_.pop_back();
} }
return bytes_released;
} }
scoped_ptr<DiscardableSharedMemoryHeap::Span> scoped_ptr<DiscardableSharedMemoryHeap::Span>
......
...@@ -68,8 +68,9 @@ class CONTENT_EXPORT DiscardableSharedMemoryHeap { ...@@ -68,8 +68,9 @@ class CONTENT_EXPORT DiscardableSharedMemoryHeap {
// memory. If found, the span is removed from the free list and returned. // memory. If found, the span is removed from the free list and returned.
scoped_ptr<Span> SearchFreeList(size_t blocks); scoped_ptr<Span> SearchFreeList(size_t blocks);
// Release shared memory segments that have been purged. // Release shared memory segments that have been purged. Returns bytes of
void ReleaseFreeMemory(); // memory that were released.
size_t ReleaseFreeMemory();
private: private:
scoped_ptr<Span> RemoveFromFreeList(Span* span); scoped_ptr<Span> RemoveFromFreeList(Span* span);
......
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