Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(515)

Side by Side Diff: content/common/discardable_shared_memory_heap.cc

Issue 1100073004: Adding discardable memory dump provider. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed comments. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/common/discardable_shared_memory_heap.h" 5 #include "content/common/discardable_shared_memory_heap.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/atomic_sequence_num.h"
9 #include "base/memory/discardable_shared_memory.h" 10 #include "base/memory/discardable_shared_memory.h"
11 #include "base/strings/stringprintf.h"
10 12
11 namespace content { 13 namespace content {
12 namespace { 14 namespace {
13 15
16 const char kMemoryAllocatorHeapNamePrefix[] = "segment_%zu";
17 const char kMemoryAllocatorName[] = "discardable";
18
19 // Global atomic to generate unique discardable shared memory IDs.
20 base::StaticAtomicSequenceNumber g_next_discardable_shared_memory_id;
21
14 bool IsPowerOfTwo(size_t x) { 22 bool IsPowerOfTwo(size_t x) {
15 return (x & (x - 1)) == 0; 23 return (x & (x - 1)) == 0;
16 } 24 }
17 25
18 bool IsInFreeList(DiscardableSharedMemoryHeap::Span* span) { 26 bool IsInFreeList(DiscardableSharedMemoryHeap::Span* span) {
19 return span->previous() || span->next(); 27 return span->previous() || span->next();
20 } 28 }
21 29
22 } // namespace 30 } // namespace
23 31
24 DiscardableSharedMemoryHeap::Span::Span( 32 DiscardableSharedMemoryHeap::Span::Span(
25 base::DiscardableSharedMemory* shared_memory, 33 base::DiscardableSharedMemory* shared_memory,
26 size_t start, 34 size_t start,
27 size_t length) 35 size_t length)
28 : shared_memory_(shared_memory), start_(start), length_(length) { 36 : shared_memory_(shared_memory), start_(start), length_(length) {
29 } 37 }
30 38
31 DiscardableSharedMemoryHeap::Span::~Span() { 39 DiscardableSharedMemoryHeap::Span::~Span() {
32 } 40 }
33 41
34 DiscardableSharedMemoryHeap::ScopedMemorySegment::ScopedMemorySegment( 42 DiscardableSharedMemoryHeap::ScopedMemorySegment::ScopedMemorySegment(
35 DiscardableSharedMemoryHeap* heap, 43 DiscardableSharedMemoryHeap* heap,
36 scoped_ptr<base::DiscardableSharedMemory> shared_memory, 44 scoped_ptr<base::DiscardableSharedMemory> shared_memory,
37 size_t size, 45 size_t size,
46 DiscardableSharedMemoryId id,
38 const base::Closure& deleted_callback) 47 const base::Closure& deleted_callback)
39 : heap_(heap), 48 : heap_(heap),
40 shared_memory_(shared_memory.Pass()), 49 shared_memory_(shared_memory.Pass()),
41 size_(size), 50 size_(size),
51 id_(id),
42 deleted_callback_(deleted_callback) { 52 deleted_callback_(deleted_callback) {
43 } 53 }
44 54
45 DiscardableSharedMemoryHeap::ScopedMemorySegment::~ScopedMemorySegment() { 55 DiscardableSharedMemoryHeap::ScopedMemorySegment::~ScopedMemorySegment() {
46 heap_->ReleaseMemory(shared_memory_.get(), size_); 56 heap_->ReleaseMemory(shared_memory_.get(), size_);
47 deleted_callback_.Run(); 57 deleted_callback_.Run();
48 } 58 }
49 59
50 bool DiscardableSharedMemoryHeap::ScopedMemorySegment::IsUsed() const { 60 bool DiscardableSharedMemoryHeap::ScopedMemorySegment::IsUsed() const {
51 return heap_->IsMemoryUsed(shared_memory_.get(), size_); 61 return heap_->IsMemoryUsed(shared_memory_.get(), size_);
52 } 62 }
53 63
54 bool DiscardableSharedMemoryHeap::ScopedMemorySegment::IsResident() const { 64 bool DiscardableSharedMemoryHeap::ScopedMemorySegment::IsResident() const {
55 return heap_->IsMemoryResident(shared_memory_.get()); 65 return heap_->IsMemoryResident(shared_memory_.get());
56 } 66 }
57 67
68 void DiscardableSharedMemoryHeap::ScopedMemorySegment::DumpMemoryStatisticsInto(
69 base::trace_event::ProcessMemoryDump* pmd) const {
70 heap_->DumpSegmentStatistics(shared_memory_.get(), size_, id_, pmd);
71 }
72
58 DiscardableSharedMemoryHeap::DiscardableSharedMemoryHeap(size_t block_size) 73 DiscardableSharedMemoryHeap::DiscardableSharedMemoryHeap(size_t block_size)
59 : block_size_(block_size), num_blocks_(0), num_free_blocks_(0) { 74 : block_size_(block_size), num_blocks_(0), num_free_blocks_(0) {
60 DCHECK_NE(block_size_, 0u); 75 DCHECK_NE(block_size_, 0u);
61 DCHECK(IsPowerOfTwo(block_size_)); 76 DCHECK(IsPowerOfTwo(block_size_));
62 } 77 }
63 78
64 DiscardableSharedMemoryHeap::~DiscardableSharedMemoryHeap() { 79 DiscardableSharedMemoryHeap::~DiscardableSharedMemoryHeap() {
65 memory_segments_.clear(); 80 memory_segments_.clear();
66 DCHECK_EQ(num_blocks_, 0u); 81 DCHECK_EQ(num_blocks_, 0u);
67 DCHECK_EQ(num_free_blocks_, 0u); 82 DCHECK_EQ(num_free_blocks_, 0u);
(...skipping 17 matching lines...) Expand all
85 scoped_ptr<Span> span( 100 scoped_ptr<Span> span(
86 new Span(shared_memory.get(), 101 new Span(shared_memory.get(),
87 reinterpret_cast<size_t>(shared_memory->memory()) / block_size_, 102 reinterpret_cast<size_t>(shared_memory->memory()) / block_size_,
88 size / block_size_)); 103 size / block_size_));
89 DCHECK(spans_.find(span->start_) == spans_.end()); 104 DCHECK(spans_.find(span->start_) == spans_.end());
90 DCHECK(spans_.find(span->start_ + span->length_ - 1) == spans_.end()); 105 DCHECK(spans_.find(span->start_ + span->length_ - 1) == spans_.end());
91 RegisterSpan(span.get()); 106 RegisterSpan(span.get());
92 107
93 num_blocks_ += span->length_; 108 num_blocks_ += span->length_;
94 109
110 DiscardableSharedMemoryId new_id =
111 g_next_discardable_shared_memory_id.GetNext();
reveman 2015/04/27 13:28:11 Please pass the ID as a parameter instead. ChildDi
ssid 2015/04/27 14:27:01 Oh i dint realize, thanks.
112
95 // Start tracking if segment is resident by adding it to |memory_segments_|. 113 // Start tracking if segment is resident by adding it to |memory_segments_|.
96 memory_segments_.push_back(new ScopedMemorySegment(this, shared_memory.Pass(), 114 memory_segments_.push_back(new ScopedMemorySegment(
97 size, deleted_callback)); 115 this, shared_memory.Pass(), size, new_id, deleted_callback));
98 116
99 return span.Pass(); 117 return span.Pass();
100 } 118 }
101 119
102 void DiscardableSharedMemoryHeap::MergeIntoFreeLists(scoped_ptr<Span> span) { 120 void DiscardableSharedMemoryHeap::MergeIntoFreeLists(scoped_ptr<Span> span) {
103 DCHECK(span->shared_memory_); 121 DCHECK(span->shared_memory_);
104 122
105 // First add length of |span| to |num_free_blocks_|. 123 // First add length of |span| to |num_free_blocks_|.
106 num_free_blocks_ += span->length_; 124 num_free_blocks_ += span->length_;
107 125
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 } 223 }
206 224
207 size_t DiscardableSharedMemoryHeap::GetSize() const { 225 size_t DiscardableSharedMemoryHeap::GetSize() const {
208 return num_blocks_ * block_size_; 226 return num_blocks_ * block_size_;
209 } 227 }
210 228
211 size_t DiscardableSharedMemoryHeap::GetSizeOfFreeLists() const { 229 size_t DiscardableSharedMemoryHeap::GetSizeOfFreeLists() const {
212 return num_free_blocks_ * block_size_; 230 return num_free_blocks_ * block_size_;
213 } 231 }
214 232
233 bool DiscardableSharedMemoryHeap::DumpMemoryStatisticsInto(
234 base::trace_event::ProcessMemoryDump* pmd) {
235 std::for_each(memory_segments_.begin(), memory_segments_.end(),
236 [pmd](const ScopedMemorySegment* segment) {
237 segment->DumpMemoryStatisticsInto(pmd);
238 });
239 return true;
240 }
241
215 void DiscardableSharedMemoryHeap::InsertIntoFreeList( 242 void DiscardableSharedMemoryHeap::InsertIntoFreeList(
216 scoped_ptr<DiscardableSharedMemoryHeap::Span> span) { 243 scoped_ptr<DiscardableSharedMemoryHeap::Span> span) {
217 DCHECK(!IsInFreeList(span.get())); 244 DCHECK(!IsInFreeList(span.get()));
218 size_t index = std::min(span->length_, arraysize(free_spans_)) - 1; 245 size_t index = std::min(span->length_, arraysize(free_spans_)) - 1;
219 free_spans_[index].Append(span.release()); 246 free_spans_[index].Append(span.release());
220 } 247 }
221 248
222 scoped_ptr<DiscardableSharedMemoryHeap::Span> 249 scoped_ptr<DiscardableSharedMemoryHeap::Span>
223 DiscardableSharedMemoryHeap::RemoveFromFreeList(Span* span) { 250 DiscardableSharedMemoryHeap::RemoveFromFreeList(Span* span) {
224 DCHECK(IsInFreeList(span)); 251 DCHECK(IsInFreeList(span));
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 336
310 // If |span| is in the free list, remove it and update |num_free_blocks_|. 337 // If |span| is in the free list, remove it and update |num_free_blocks_|.
311 if (IsInFreeList(span)) { 338 if (IsInFreeList(span)) {
312 DCHECK_GE(num_free_blocks_, span->length_); 339 DCHECK_GE(num_free_blocks_, span->length_);
313 num_free_blocks_ -= span->length_; 340 num_free_blocks_ -= span->length_;
314 RemoveFromFreeList(span); 341 RemoveFromFreeList(span);
315 } 342 }
316 } 343 }
317 } 344 }
318 345
346 void DiscardableSharedMemoryHeap::DumpSegmentStatistics(
347 const base::DiscardableSharedMemory* shared_memory,
348 size_t segment_size,
reveman 2015/04/27 13:28:11 nit: s/segment_size/size/ to be consistent with Re
ssid 2015/04/27 14:27:01 Done.
349 DiscardableSharedMemoryId id,
350 base::trace_event::ProcessMemoryDump* pmd) {
351 std::string segment_id =
reveman 2015/04/27 13:28:11 nit: maybe heap_name instead
ssid 2015/04/27 14:27:01 Done.
352 base::StringPrintf(kMemoryAllocatorHeapNamePrefix, id);
353 base::trace_event::MemoryAllocatorDump* segment_dump =
reveman 2015/04/27 13:28:11 fyi, "dump" is enough if the cleans things up, up
ssid 2015/04/27 14:27:01 Done.
354 pmd->CreateAllocatorDump(kMemoryAllocatorName, segment_id.c_str());
reveman 2015/04/27 13:28:11 What if this fails? Looks like other dump provider
ssid 2015/04/27 14:27:01 The check is unnecessary, will be removed in other
reveman 2015/04/27 15:08:58 Acknowledged.
355
356 size_t allocated_objects_count = 0;
357 size_t allocated_objects_size_in_bytes = 0;
358 size_t offset =
359 reinterpret_cast<size_t>(shared_memory->memory()) / block_size_;
360 size_t end = offset + segment_size / block_size_;
361 while (offset < end) {
362 Span* span = spans_[offset];
363 if (!IsInFreeList(span)) {
364 allocated_objects_count++;
365 allocated_objects_size_in_bytes += span->length_;
366 }
367 offset += span->length_;
368 }
369
370 segment_dump->set_physical_size_in_bytes(static_cast<uint64>(segment_size));
371 segment_dump->set_allocated_objects_count(
372 static_cast<uint64>(allocated_objects_count));
373 segment_dump->set_allocated_objects_size_in_bytes(
374 static_cast<uint64>(allocated_objects_size_in_bytes));
reveman 2015/04/27 13:28:11 are these static_casts really needed?
ssid 2015/04/27 14:27:01 yes, since windows build gives conversion error fr
reveman 2015/04/27 15:08:58 hm, I would expect size_t to uint64 to always be o
375 }
376
319 } // namespace content 377 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698