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

Side by Side Diff: components/html_viewer/discardable_memory_allocator.cc

Issue 1677293002: Bye bye Mandoline (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: moar Created 4 years, 10 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
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/html_viewer/discardable_memory_allocator.h"
6
7 #include <stdint.h>
8 #include <utility>
9
10 #include "base/macros.h"
11 #include "base/memory/discardable_memory.h"
12 #include "base/stl_util.h"
13 #include "base/trace_event/memory_allocator_dump.h"
14 #include "base/trace_event/memory_dump_manager.h"
15 #include "base/trace_event/process_memory_dump.h"
16
17 namespace html_viewer {
18
19 // Interface to the rest of the program. These objects are owned outside of the
20 // allocator.
21 class DiscardableMemoryAllocator::DiscardableMemoryChunkImpl
22 : public base::DiscardableMemory {
23 public:
24 DiscardableMemoryChunkImpl(size_t size, DiscardableMemoryAllocator* allocator)
25 : is_locked_(true),
26 size_(size),
27 data_(new uint8_t[size]),
28 allocator_(allocator) {}
29
30 ~DiscardableMemoryChunkImpl() override {
31 base::AutoLock lock(allocator_->lock_);
32 // Either the memory is discarded or the memory chunk is unlocked.
33 DCHECK(data_ || !is_locked_);
34 if (!is_locked_ && data_)
35 allocator_->NotifyDestructed(unlocked_position_);
36 }
37
38 // Overridden from DiscardableMemoryChunk:
39 bool Lock() override {
40 base::AutoLock lock(allocator_->lock_);
41 DCHECK(!is_locked_);
42 if (!data_)
43 return false;
44
45 is_locked_ = true;
46 allocator_->NotifyLocked(unlocked_position_);
47 return true;
48 }
49
50 void Unlock() override {
51 base::AutoLock lock(allocator_->lock_);
52 DCHECK(is_locked_);
53 DCHECK(data_);
54 is_locked_ = false;
55 unlocked_position_ = allocator_->NotifyUnlocked(this);
56 }
57
58 void* data() const override {
59 if (data_) {
60 DCHECK(is_locked_);
61 return data_.get();
62 }
63 return nullptr;
64 }
65
66 base::trace_event::MemoryAllocatorDump* CreateMemoryAllocatorDump(
67 const char* name,
68 base::trace_event::ProcessMemoryDump* pmd) const override {
69 base::trace_event::MemoryAllocatorDump* dump =
70 pmd->CreateAllocatorDump(name);
71 dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
72 base::trace_event::MemoryAllocatorDump::kUnitsBytes, size_);
73
74 // Memory is allocated from system allocator (malloc).
75 pmd->AddSuballocation(dump->guid(),
76 base::trace_event::MemoryDumpManager::GetInstance()
77 ->system_allocator_pool_name());
78 return dump;
79 }
80
81 size_t size() const { return size_; }
82
83 void Discard() {
84 allocator_->lock_.AssertAcquired();
85 DCHECK(!is_locked_);
86 data_.reset();
87 }
88
89 private:
90 bool is_locked_;
91 size_t size_;
92 scoped_ptr<uint8_t[]> data_;
93 DiscardableMemoryAllocator* allocator_;
94
95 std::list<DiscardableMemoryChunkImpl*>::iterator unlocked_position_;
96
97 DISALLOW_IMPLICIT_CONSTRUCTORS(DiscardableMemoryChunkImpl);
98 };
99
100 DiscardableMemoryAllocator::DiscardableMemoryAllocator(
101 size_t desired_max_memory)
102 : desired_max_memory_(desired_max_memory),
103 total_live_memory_(0u),
104 locked_chunks_(0) {
105 }
106
107 DiscardableMemoryAllocator::~DiscardableMemoryAllocator() {
108 DCHECK_EQ(0, locked_chunks_);
109 STLDeleteElements(&live_unlocked_chunks_);
110 }
111
112 scoped_ptr<base::DiscardableMemory>
113 DiscardableMemoryAllocator::AllocateLockedDiscardableMemory(size_t size) {
114 base::AutoLock lock(lock_);
115 scoped_ptr<DiscardableMemoryChunkImpl> chunk(
116 new DiscardableMemoryChunkImpl(size, this));
117 total_live_memory_ += size;
118 locked_chunks_++;
119
120 // Go through the list of unlocked live chunks starting from the least
121 // recently used, freeing as many as we can until we get our size under the
122 // desired maximum.
123 auto it = live_unlocked_chunks_.begin();
124 while (total_live_memory_ > desired_max_memory_ &&
125 it != live_unlocked_chunks_.end()) {
126 total_live_memory_ -= (*it)->size();
127 (*it)->Discard();
128 it = live_unlocked_chunks_.erase(it);
129 }
130
131 return std::move(chunk);
132 }
133
134 std::list<DiscardableMemoryAllocator::DiscardableMemoryChunkImpl*>::iterator
135 DiscardableMemoryAllocator::NotifyUnlocked(DiscardableMemoryChunkImpl* chunk) {
136 lock_.AssertAcquired();
137 locked_chunks_--;
138 return live_unlocked_chunks_.insert(live_unlocked_chunks_.end(), chunk);
139 }
140
141 void DiscardableMemoryAllocator::NotifyLocked(
142 std::list<DiscardableMemoryChunkImpl*>::iterator it) {
143 lock_.AssertAcquired();
144 locked_chunks_++;
145 live_unlocked_chunks_.erase(it);
146 }
147
148 void DiscardableMemoryAllocator::NotifyDestructed(
149 std::list<DiscardableMemoryChunkImpl*>::iterator it) {
150 lock_.AssertAcquired();
151 live_unlocked_chunks_.erase(it);
152 }
153
154 } // namespace html_viewer
OLDNEW
« no previous file with comments | « components/html_viewer/discardable_memory_allocator.h ('k') | components/html_viewer/discardable_memory_allocator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698