| OLD | NEW |
| 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 #include <utility> |
| 8 | 9 |
| 9 #include "base/format_macros.h" | 10 #include "base/format_macros.h" |
| 10 #include "base/macros.h" | 11 #include "base/macros.h" |
| 11 #include "base/memory/discardable_shared_memory.h" | 12 #include "base/memory/discardable_shared_memory.h" |
| 12 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
| 13 #include "base/trace_event/memory_dump_manager.h" | 14 #include "base/trace_event/memory_dump_manager.h" |
| 14 | 15 |
| 15 namespace content { | 16 namespace content { |
| 16 namespace { | 17 namespace { |
| 17 | 18 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 37 DiscardableSharedMemoryHeap::Span::~Span() { | 38 DiscardableSharedMemoryHeap::Span::~Span() { |
| 38 } | 39 } |
| 39 | 40 |
| 40 DiscardableSharedMemoryHeap::ScopedMemorySegment::ScopedMemorySegment( | 41 DiscardableSharedMemoryHeap::ScopedMemorySegment::ScopedMemorySegment( |
| 41 DiscardableSharedMemoryHeap* heap, | 42 DiscardableSharedMemoryHeap* heap, |
| 42 scoped_ptr<base::DiscardableSharedMemory> shared_memory, | 43 scoped_ptr<base::DiscardableSharedMemory> shared_memory, |
| 43 size_t size, | 44 size_t size, |
| 44 int32_t id, | 45 int32_t id, |
| 45 const base::Closure& deleted_callback) | 46 const base::Closure& deleted_callback) |
| 46 : heap_(heap), | 47 : heap_(heap), |
| 47 shared_memory_(shared_memory.Pass()), | 48 shared_memory_(std::move(shared_memory)), |
| 48 size_(size), | 49 size_(size), |
| 49 id_(id), | 50 id_(id), |
| 50 deleted_callback_(deleted_callback) { | 51 deleted_callback_(deleted_callback) {} |
| 51 } | |
| 52 | 52 |
| 53 DiscardableSharedMemoryHeap::ScopedMemorySegment::~ScopedMemorySegment() { | 53 DiscardableSharedMemoryHeap::ScopedMemorySegment::~ScopedMemorySegment() { |
| 54 heap_->ReleaseMemory(shared_memory_.get(), size_); | 54 heap_->ReleaseMemory(shared_memory_.get(), size_); |
| 55 deleted_callback_.Run(); | 55 deleted_callback_.Run(); |
| 56 } | 56 } |
| 57 | 57 |
| 58 bool DiscardableSharedMemoryHeap::ScopedMemorySegment::IsUsed() const { | 58 bool DiscardableSharedMemoryHeap::ScopedMemorySegment::IsUsed() const { |
| 59 return heap_->IsMemoryUsed(shared_memory_.get(), size_); | 59 return heap_->IsMemoryUsed(shared_memory_.get(), size_); |
| 60 } | 60 } |
| 61 | 61 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 reinterpret_cast<size_t>(shared_memory->memory()) / block_size_, | 124 reinterpret_cast<size_t>(shared_memory->memory()) / block_size_, |
| 125 size / block_size_)); | 125 size / block_size_)); |
| 126 DCHECK(spans_.find(span->start_) == spans_.end()); | 126 DCHECK(spans_.find(span->start_) == spans_.end()); |
| 127 DCHECK(spans_.find(span->start_ + span->length_ - 1) == spans_.end()); | 127 DCHECK(spans_.find(span->start_ + span->length_ - 1) == spans_.end()); |
| 128 RegisterSpan(span.get()); | 128 RegisterSpan(span.get()); |
| 129 | 129 |
| 130 num_blocks_ += span->length_; | 130 num_blocks_ += span->length_; |
| 131 | 131 |
| 132 // Start tracking if segment is resident by adding it to |memory_segments_|. | 132 // Start tracking if segment is resident by adding it to |memory_segments_|. |
| 133 memory_segments_.push_back(new ScopedMemorySegment( | 133 memory_segments_.push_back(new ScopedMemorySegment( |
| 134 this, shared_memory.Pass(), size, id, deleted_callback)); | 134 this, std::move(shared_memory), size, id, deleted_callback)); |
| 135 | 135 |
| 136 return span.Pass(); | 136 return span; |
| 137 } | 137 } |
| 138 | 138 |
| 139 void DiscardableSharedMemoryHeap::MergeIntoFreeLists(scoped_ptr<Span> span) { | 139 void DiscardableSharedMemoryHeap::MergeIntoFreeLists(scoped_ptr<Span> span) { |
| 140 DCHECK(span->shared_memory_); | 140 DCHECK(span->shared_memory_); |
| 141 | 141 |
| 142 // First add length of |span| to |num_free_blocks_|. | 142 // First add length of |span| to |num_free_blocks_|. |
| 143 num_free_blocks_ += span->length_; | 143 num_free_blocks_ += span->length_; |
| 144 | 144 |
| 145 // Merge with previous span if possible. | 145 // Merge with previous span if possible. |
| 146 SpanMap::iterator prev_it = spans_.find(span->start_ - 1); | 146 SpanMap::iterator prev_it = spans_.find(span->start_ - 1); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 160 if (next_it != spans_.end() && IsInFreeList(next_it->second)) { | 160 if (next_it != spans_.end() && IsInFreeList(next_it->second)) { |
| 161 scoped_ptr<Span> next = RemoveFromFreeList(next_it->second); | 161 scoped_ptr<Span> next = RemoveFromFreeList(next_it->second); |
| 162 DCHECK_EQ(next->start_, span->start_ + span->length_); | 162 DCHECK_EQ(next->start_, span->start_ + span->length_); |
| 163 UnregisterSpan(next.get()); | 163 UnregisterSpan(next.get()); |
| 164 if (span->length_ > 1) | 164 if (span->length_ > 1) |
| 165 spans_.erase(span->start_ + span->length_ - 1); | 165 spans_.erase(span->start_ + span->length_ - 1); |
| 166 span->length_ += next->length_; | 166 span->length_ += next->length_; |
| 167 spans_[span->start_ + span->length_ - 1] = span.get(); | 167 spans_[span->start_ + span->length_ - 1] = span.get(); |
| 168 } | 168 } |
| 169 | 169 |
| 170 InsertIntoFreeList(span.Pass()); | 170 InsertIntoFreeList(std::move(span)); |
| 171 } | 171 } |
| 172 | 172 |
| 173 scoped_ptr<DiscardableSharedMemoryHeap::Span> | 173 scoped_ptr<DiscardableSharedMemoryHeap::Span> |
| 174 DiscardableSharedMemoryHeap::Split(Span* span, size_t blocks) { | 174 DiscardableSharedMemoryHeap::Split(Span* span, size_t blocks) { |
| 175 DCHECK(blocks); | 175 DCHECK(blocks); |
| 176 DCHECK_LT(blocks, span->length_); | 176 DCHECK_LT(blocks, span->length_); |
| 177 | 177 |
| 178 scoped_ptr<Span> leftover(new Span( | 178 scoped_ptr<Span> leftover(new Span( |
| 179 span->shared_memory_, span->start_ + blocks, span->length_ - blocks)); | 179 span->shared_memory_, span->start_ + blocks, span->length_ - blocks)); |
| 180 DCHECK(leftover->length_ == 1 || | 180 DCHECK(leftover->length_ == 1 || |
| 181 spans_.find(leftover->start_) == spans_.end()); | 181 spans_.find(leftover->start_) == spans_.end()); |
| 182 RegisterSpan(leftover.get()); | 182 RegisterSpan(leftover.get()); |
| 183 spans_[span->start_ + blocks - 1] = span; | 183 spans_[span->start_ + blocks - 1] = span; |
| 184 span->length_ = blocks; | 184 span->length_ = blocks; |
| 185 return leftover.Pass(); | 185 return leftover; |
| 186 } | 186 } |
| 187 | 187 |
| 188 scoped_ptr<DiscardableSharedMemoryHeap::Span> | 188 scoped_ptr<DiscardableSharedMemoryHeap::Span> |
| 189 DiscardableSharedMemoryHeap::SearchFreeLists(size_t blocks, size_t slack) { | 189 DiscardableSharedMemoryHeap::SearchFreeLists(size_t blocks, size_t slack) { |
| 190 DCHECK(blocks); | 190 DCHECK(blocks); |
| 191 | 191 |
| 192 size_t length = blocks; | 192 size_t length = blocks; |
| 193 size_t max_length = blocks + slack; | 193 size_t max_length = blocks + slack; |
| 194 | 194 |
| 195 // Search array of free lists for a suitable span. | 195 // Search array of free lists for a suitable span. |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 if (extra) { | 281 if (extra) { |
| 282 scoped_ptr<Span> leftover( | 282 scoped_ptr<Span> leftover( |
| 283 new Span(serving->shared_memory_, serving->start_ + blocks, extra)); | 283 new Span(serving->shared_memory_, serving->start_ + blocks, extra)); |
| 284 leftover->set_is_locked(false); | 284 leftover->set_is_locked(false); |
| 285 DCHECK(extra == 1 || spans_.find(leftover->start_) == spans_.end()); | 285 DCHECK(extra == 1 || spans_.find(leftover->start_) == spans_.end()); |
| 286 RegisterSpan(leftover.get()); | 286 RegisterSpan(leftover.get()); |
| 287 | 287 |
| 288 // No need to coalesce as the previous span of |leftover| was just split | 288 // No need to coalesce as the previous span of |leftover| was just split |
| 289 // and the next span of |leftover| was not previously coalesced with | 289 // and the next span of |leftover| was not previously coalesced with |
| 290 // |span|. | 290 // |span|. |
| 291 InsertIntoFreeList(leftover.Pass()); | 291 InsertIntoFreeList(std::move(leftover)); |
| 292 | 292 |
| 293 serving->length_ = blocks; | 293 serving->length_ = blocks; |
| 294 spans_[serving->start_ + blocks - 1] = serving.get(); | 294 spans_[serving->start_ + blocks - 1] = serving.get(); |
| 295 } | 295 } |
| 296 | 296 |
| 297 // |serving| is no longer in the free list, remove its length from | 297 // |serving| is no longer in the free list, remove its length from |
| 298 // |num_free_blocks_|. | 298 // |num_free_blocks_|. |
| 299 DCHECK_GE(num_free_blocks_, serving->length_); | 299 DCHECK_GE(num_free_blocks_, serving->length_); |
| 300 num_free_blocks_ -= serving->length_; | 300 num_free_blocks_ -= serving->length_; |
| 301 | 301 |
| 302 return serving.Pass(); | 302 return serving; |
| 303 } | 303 } |
| 304 | 304 |
| 305 void DiscardableSharedMemoryHeap::RegisterSpan(Span* span) { | 305 void DiscardableSharedMemoryHeap::RegisterSpan(Span* span) { |
| 306 spans_[span->start_] = span; | 306 spans_[span->start_] = span; |
| 307 if (span->length_ > 1) | 307 if (span->length_ > 1) |
| 308 spans_[span->start_ + span->length_ - 1] = span; | 308 spans_[span->start_ + span->length_ - 1] = span; |
| 309 } | 309 } |
| 310 | 310 |
| 311 void DiscardableSharedMemoryHeap::UnregisterSpan(Span* span) { | 311 void DiscardableSharedMemoryHeap::UnregisterSpan(Span* span) { |
| 312 DCHECK(spans_.find(span->start_) != spans_.end()); | 312 DCHECK(spans_.find(span->start_) != spans_.end()); |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 ScopedVector<ScopedMemorySegment>::const_iterator it = | 463 ScopedVector<ScopedMemorySegment>::const_iterator it = |
| 464 std::find_if(memory_segments_.begin(), memory_segments_.end(), | 464 std::find_if(memory_segments_.begin(), memory_segments_.end(), |
| 465 [span](const ScopedMemorySegment* segment) { | 465 [span](const ScopedMemorySegment* segment) { |
| 466 return segment->ContainsSpan(span); | 466 return segment->ContainsSpan(span); |
| 467 }); | 467 }); |
| 468 DCHECK(it != memory_segments_.end()); | 468 DCHECK(it != memory_segments_.end()); |
| 469 return (*it)->CreateMemoryAllocatorDump(span, block_size_, name, pmd); | 469 return (*it)->CreateMemoryAllocatorDump(span, block_size_, name, pmd); |
| 470 } | 470 } |
| 471 | 471 |
| 472 } // namespace content | 472 } // namespace content |
| OLD | NEW |