| 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 | 8 |
| 9 #include "base/memory/discardable_shared_memory.h" | 9 #include "base/memory/discardable_shared_memory.h" |
| 10 | 10 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 size_t length) | 27 size_t length) |
| 28 : shared_memory_(shared_memory), start_(start), length_(length) { | 28 : shared_memory_(shared_memory), start_(start), length_(length) { |
| 29 } | 29 } |
| 30 | 30 |
| 31 DiscardableSharedMemoryHeap::Span::~Span() { | 31 DiscardableSharedMemoryHeap::Span::~Span() { |
| 32 } | 32 } |
| 33 | 33 |
| 34 DiscardableSharedMemoryHeap::ScopedMemorySegment::ScopedMemorySegment( | 34 DiscardableSharedMemoryHeap::ScopedMemorySegment::ScopedMemorySegment( |
| 35 DiscardableSharedMemoryHeap* heap, | 35 DiscardableSharedMemoryHeap* heap, |
| 36 scoped_ptr<base::DiscardableSharedMemory> shared_memory, | 36 scoped_ptr<base::DiscardableSharedMemory> shared_memory, |
| 37 size_t size) | 37 size_t size, |
| 38 : heap_(heap), shared_memory_(shared_memory.Pass()), size_(size) { | 38 const base::Closure& deleted_callback) |
| 39 : heap_(heap), |
| 40 shared_memory_(shared_memory.Pass()), |
| 41 size_(size), |
| 42 deleted_callback_(deleted_callback) { |
| 39 } | 43 } |
| 40 | 44 |
| 41 DiscardableSharedMemoryHeap::ScopedMemorySegment::~ScopedMemorySegment() { | 45 DiscardableSharedMemoryHeap::ScopedMemorySegment::~ScopedMemorySegment() { |
| 42 heap_->ReleaseMemory(shared_memory_.get(), size_); | 46 heap_->ReleaseMemory(shared_memory_.get(), size_); |
| 43 // Purge memory. This has no effect if already purged. | 47 deleted_callback_.Run(); |
| 44 shared_memory_->Purge(base::Time::Now()); | |
| 45 } | 48 } |
| 46 | 49 |
| 47 bool DiscardableSharedMemoryHeap::ScopedMemorySegment::IsUsed() const { | 50 bool DiscardableSharedMemoryHeap::ScopedMemorySegment::IsUsed() const { |
| 48 return heap_->IsMemoryUsed(shared_memory_.get(), size_); | 51 return heap_->IsMemoryUsed(shared_memory_.get(), size_); |
| 49 } | 52 } |
| 50 | 53 |
| 51 bool DiscardableSharedMemoryHeap::ScopedMemorySegment::IsResident() const { | 54 bool DiscardableSharedMemoryHeap::ScopedMemorySegment::IsResident() const { |
| 52 return heap_->IsMemoryResident(shared_memory_.get()); | 55 return heap_->IsMemoryResident(shared_memory_.get()); |
| 53 } | 56 } |
| 54 | 57 |
| 55 DiscardableSharedMemoryHeap::DiscardableSharedMemoryHeap(size_t block_size) | 58 DiscardableSharedMemoryHeap::DiscardableSharedMemoryHeap(size_t block_size) |
| 56 : block_size_(block_size), num_blocks_(0), num_free_blocks_(0) { | 59 : block_size_(block_size), num_blocks_(0), num_free_blocks_(0) { |
| 57 DCHECK_NE(block_size_, 0u); | 60 DCHECK_NE(block_size_, 0u); |
| 58 DCHECK(IsPowerOfTwo(block_size_)); | 61 DCHECK(IsPowerOfTwo(block_size_)); |
| 59 } | 62 } |
| 60 | 63 |
| 61 DiscardableSharedMemoryHeap::~DiscardableSharedMemoryHeap() { | 64 DiscardableSharedMemoryHeap::~DiscardableSharedMemoryHeap() { |
| 62 memory_segments_.clear(); | 65 memory_segments_.clear(); |
| 63 DCHECK_EQ(num_blocks_, 0u); | 66 DCHECK_EQ(num_blocks_, 0u); |
| 64 DCHECK_EQ(num_free_blocks_, 0u); | 67 DCHECK_EQ(num_free_blocks_, 0u); |
| 65 DCHECK_EQ(std::count_if(free_spans_, free_spans_ + arraysize(free_spans_), | 68 DCHECK_EQ(std::count_if(free_spans_, free_spans_ + arraysize(free_spans_), |
| 66 [](const base::LinkedList<Span>& free_spans) { | 69 [](const base::LinkedList<Span>& free_spans) { |
| 67 return !free_spans.empty(); | 70 return !free_spans.empty(); |
| 68 }), | 71 }), |
| 69 0); | 72 0); |
| 70 } | 73 } |
| 71 | 74 |
| 72 scoped_ptr<DiscardableSharedMemoryHeap::Span> DiscardableSharedMemoryHeap::Grow( | 75 scoped_ptr<DiscardableSharedMemoryHeap::Span> DiscardableSharedMemoryHeap::Grow( |
| 73 scoped_ptr<base::DiscardableSharedMemory> shared_memory, | 76 scoped_ptr<base::DiscardableSharedMemory> shared_memory, |
| 74 size_t size) { | 77 size_t size, |
| 78 const base::Closure& deleted_callback) { |
| 75 // Memory must be aligned to block size. | 79 // Memory must be aligned to block size. |
| 76 DCHECK_EQ( | 80 DCHECK_EQ( |
| 77 reinterpret_cast<size_t>(shared_memory->memory()) & (block_size_ - 1), | 81 reinterpret_cast<size_t>(shared_memory->memory()) & (block_size_ - 1), |
| 78 0u); | 82 0u); |
| 79 DCHECK_EQ(size & (block_size_ - 1), 0u); | 83 DCHECK_EQ(size & (block_size_ - 1), 0u); |
| 80 | 84 |
| 81 scoped_ptr<Span> span( | 85 scoped_ptr<Span> span( |
| 82 new Span(shared_memory.get(), | 86 new Span(shared_memory.get(), |
| 83 reinterpret_cast<size_t>(shared_memory->memory()) / block_size_, | 87 reinterpret_cast<size_t>(shared_memory->memory()) / block_size_, |
| 84 size / block_size_)); | 88 size / block_size_)); |
| 85 DCHECK(spans_.find(span->start_) == spans_.end()); | 89 DCHECK(spans_.find(span->start_) == spans_.end()); |
| 86 DCHECK(spans_.find(span->start_ + span->length_ - 1) == spans_.end()); | 90 DCHECK(spans_.find(span->start_ + span->length_ - 1) == spans_.end()); |
| 87 RegisterSpan(span.get()); | 91 RegisterSpan(span.get()); |
| 88 | 92 |
| 89 num_blocks_ += span->length_; | 93 num_blocks_ += span->length_; |
| 90 | 94 |
| 91 // Start tracking if segment is resident by adding it to |memory_segments_|. | 95 // Start tracking if segment is resident by adding it to |memory_segments_|. |
| 92 memory_segments_.push_back( | 96 memory_segments_.push_back(new ScopedMemorySegment(this, shared_memory.Pass(), |
| 93 new ScopedMemorySegment(this, shared_memory.Pass(), size)); | 97 size, deleted_callback)); |
| 94 | 98 |
| 95 return span.Pass(); | 99 return span.Pass(); |
| 96 } | 100 } |
| 97 | 101 |
| 98 void DiscardableSharedMemoryHeap::MergeIntoFreeLists(scoped_ptr<Span> span) { | 102 void DiscardableSharedMemoryHeap::MergeIntoFreeLists(scoped_ptr<Span> span) { |
| 99 DCHECK(span->shared_memory_); | 103 DCHECK(span->shared_memory_); |
| 100 | 104 |
| 101 // First add length of |span| to |num_free_blocks_|. | 105 // First add length of |span| to |num_free_blocks_|. |
| 102 num_free_blocks_ += span->length_; | 106 num_free_blocks_ += span->length_; |
| 103 | 107 |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 // If |span| is in the free list, remove it and update |num_free_blocks_|. | 310 // If |span| is in the free list, remove it and update |num_free_blocks_|. |
| 307 if (IsInFreeList(span)) { | 311 if (IsInFreeList(span)) { |
| 308 DCHECK_GE(num_free_blocks_, span->length_); | 312 DCHECK_GE(num_free_blocks_, span->length_); |
| 309 num_free_blocks_ -= span->length_; | 313 num_free_blocks_ -= span->length_; |
| 310 RemoveFromFreeList(span); | 314 RemoveFromFreeList(span); |
| 311 } | 315 } |
| 312 } | 316 } |
| 313 } | 317 } |
| 314 | 318 |
| 315 } // namespace content | 319 } // namespace content |
| OLD | NEW |