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 @@
#include "content/child/child_discardable_shared_memory_manager.h"
#include "base/debug/crash_logging.h"
#include "base/memory/discardable_shared_memory.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"
namespace content {
......@@ -43,10 +46,12 @@ class DiscardableMemoryShmemChunkImpl
ChildDiscardableSharedMemoryManager::ChildDiscardableSharedMemoryManager(
ThreadSafeSender* sender)
: heap_(base::GetPageSize()), sender_(sender) {
: heap_(base::GetPageSize()), sender_(sender), bytes_allocated_(0) {
}
ChildDiscardableSharedMemoryManager::~ChildDiscardableSharedMemoryManager() {
if (bytes_allocated_)
BytesAllocatedChanged(0);
}
scoped_ptr<base::DiscardableMemoryShmemChunk>
......@@ -75,7 +80,11 @@ ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(
base::DiscardableSharedMemory::FAILED) {
DCHECK(!free_span->shared_memory()->IsMemoryResident());
// 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());
continue;
}
......@@ -86,7 +95,12 @@ ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(
// Release free memory and free up the address space. Failing to do this
// 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 =
std::max(kAllocationSize / base::GetPageSize(), pages);
......@@ -96,6 +110,11 @@ ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(
scoped_ptr<base::DiscardableSharedMemory> shared_memory(
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.
scoped_ptr<DiscardableSharedMemoryHeap::Span> new_span(
heap_.Grow(shared_memory.Pass(), allocation_size_in_bytes));
......@@ -118,7 +137,12 @@ ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(
void ChildDiscardableSharedMemoryManager::ReleaseFreeMemory() {
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(
......@@ -194,4 +218,14 @@ ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory(
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
......@@ -36,10 +36,12 @@ class CONTENT_EXPORT ChildDiscardableSharedMemoryManager
private:
scoped_ptr<base::DiscardableSharedMemory>
AllocateLockedDiscardableSharedMemory(size_t size);
void BytesAllocatedChanged(size_t new_bytes_allocated) const;
mutable base::Lock lock_;
DiscardableSharedMemoryHeap heap_;
scoped_refptr<ThreadSafeSender> sender_;
size_t bytes_allocated_;
DISALLOW_COPY_AND_ASSIGN(ChildDiscardableSharedMemoryManager);
};
......
......@@ -142,7 +142,8 @@ DiscardableSharedMemoryHeap::SearchFreeList(size_t blocks) {
return best ? Carve(best, blocks) : nullptr;
}
void DiscardableSharedMemoryHeap::ReleaseFreeMemory() {
size_t DiscardableSharedMemoryHeap::ReleaseFreeMemory() {
size_t bytes_released = 0;
size_t i = 0;
// Release memory for all non-resident segments.
......@@ -155,12 +156,16 @@ void DiscardableSharedMemoryHeap::ReleaseFreeMemory() {
continue;
}
bytes_released += shared_memory->mapped_size();
// Release the memory and unregistering all associated spans.
ReleaseMemory(shared_memory);
std::swap(shared_memory_segments_[i], shared_memory_segments_.back());
shared_memory_segments_.pop_back();
}
return bytes_released;
}
scoped_ptr<DiscardableSharedMemoryHeap::Span>
......
......@@ -68,8 +68,9 @@ class CONTENT_EXPORT DiscardableSharedMemoryHeap {
// memory. If found, the span is removed from the free list and returned.
scoped_ptr<Span> SearchFreeList(size_t blocks);
// Release shared memory segments that have been purged.
void ReleaseFreeMemory();
// Release shared memory segments that have been purged. Returns bytes of
// memory that were released.
size_t ReleaseFreeMemory();
private:
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