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

Side by Side Diff: courgette/memory_allocator.h

Issue 6597038: Implementation of an STL compatible allocator for Courgette on Windows.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « courgette/ensemble_apply.cc ('k') | courgette/memory_allocator.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 #ifndef COURGETTE_MEMORY_ALLOCATOR_H_
6 #define COURGETTE_MEMORY_ALLOCATOR_H_
7
8 #include <memory>
9
10 #include "base/basictypes.h"
11 #include "base/logging.h"
12 #include "base/platform_file.h"
13
14 namespace courgette {
15
16 #ifdef OS_WIN
17
18 // Manages a temporary file. The file is created in the %TEMP% folder and
19 // is deleted when the file handle is closed.
20 class TempFile {
21 public:
22 TempFile();
23 ~TempFile();
24
25 bool Create();
26 void Close();
27 bool SetSize(size_t size);
28
29 // Returns true iff the temp file is currently open.
30 bool valid() const;
31
32 // Returns the handle of the temporary file or INVALID_HANDLE_VALUE if
33 // a temp file has not been created.
34 base::PlatformFile handle() const;
35
36 // Returns the size of the temp file. If the temp file doesn't exist,
37 // the return value is 0.
38 size_t size() const;
39
40 protected:
41 base::PlatformFile file_;
42 size_t size_;
43 };
44
45 // Manages a read/write virtual mapping of a physical file.
46 class FileMapping {
47 public:
48 FileMapping();
49 ~FileMapping();
50
51 // Map a file from beginning to |size|.
52 bool Create(HANDLE file, size_t size);
53 void Close();
54
55 // Returns true iff a mapping has been created.
56 bool valid() const;
57
58 // Returns a writable pointer to the beginning of the memory mapped file.
59 // If Create has not been called successfully, return value is NULL.
60 void* view() const;
61
62 protected:
63 HANDLE mapping_;
64 void* view_;
65 };
66
67 // Manages a temporary file and a memory mapping of the temporary file.
68 // The memory that this class manages holds a pointer back to the TempMapping
69 // object itself, so that given a memory pointer allocated by this class,
70 // you can get a pointer to the TempMapping instance that owns that memory.
71 class TempMapping {
72 public:
73 TempMapping();
74 ~TempMapping();
75
76 // Creates a temporary file of size |size| and maps it into the current
77 // process' address space.
78 bool Initialize(size_t size);
79
80 // Returns a writable pointer to the reserved memory.
81 void* memory() const;
82
83 // Returns a pointer to the TempMapping instance that allocated the |mem|
84 // block of memory. It's the callers responsibility to make sure that
85 // the memory block was allocated by the TempMapping class.
86 static TempMapping* GetMappingFromPtr(void* mem);
87
88 protected:
89 TempFile file_;
90 FileMapping mapping_;
91 };
92
93 // An STL compatible memory allocator class that allocates memory either
94 // from the heap or via a temporary file. A file allocation will be made
95 // if either the requested memory size exceeds |kMaxHeapAllocationSize|
96 // or if a heap allocation fails.
97 template<class T>
98 class MemoryAllocator {
99 public:
100 typedef T value_type;
101 typedef value_type* pointer;
102 typedef value_type& reference;
103 typedef const value_type* const_pointer;
104 typedef const value_type& const_reference;
105 typedef size_t size_type;
106 typedef ptrdiff_t difference_type;
107
108 // Each allocation is tagged with a single byte so that we know how to
109 // deallocate it.
110 enum AllocationType {
111 HEAP_ALLOCATION,
112 FILE_ALLOCATION,
113 };
114
115 // 4MB is the maximum heap allocation size that we'll attempt.
116 static const size_t kMaxHeapAllocationSize = 1024 * 1024 * 4;
117
118 template<class OtherT>
119 struct rebind {
120 // convert an MemoryAllocator<T> to a MemoryAllocator<OtherT>
121 typedef MemoryAllocator<OtherT> other;
122 };
123
124 MemoryAllocator() _THROW0() {
125 }
126
127 explicit MemoryAllocator(const MemoryAllocator<T>& other) _THROW0() {
128 }
129
130 template<class OtherT>
131 explicit MemoryAllocator(const MemoryAllocator<OtherT>& other) _THROW0() {
132 }
133
134 ~MemoryAllocator() {
135 }
136
137 void deallocate(pointer ptr, size_type size) {
138 uint8* mem = reinterpret_cast<uint8*>(ptr);
139 mem -= sizeof(T);
140 if (mem[0] == HEAP_ALLOCATION) {
141 delete [] mem;
142 } else {
143 DCHECK_EQ(static_cast<uint8>(FILE_ALLOCATION), mem[0]);
144 TempMapping* mapping = TempMapping::GetMappingFromPtr(mem);
145 delete mapping;
146 }
147 }
148
149 pointer allocate(size_type count) {
150 // We use the first byte of each allocation to mark the allocation type.
151 // However, so that the allocation is properly aligned, we allocate an
152 // extra element and then use the first byte of the first element
153 // to mark the allocation type.
154 count++;
grt (UTC plus 2) 2011/02/28 18:08:34 check for overflow.
155
156 if (count > max_size())
157 throw std::length_error("overflow");
158
159 size_type bytes = count * sizeof(T);
160 uint8* mem = NULL;
161
162 // First see if we can do this allocation on the heap.
163 if (count < kMaxHeapAllocationSize)
164 mem = new(std::nothrow) uint8[bytes];
165 if (mem != NULL) {
166 mem[0] = static_cast<uint8>(HEAP_ALLOCATION);
167 } else {
168 // If either the heap allocation failed or the request exceeds the
169 // max heap allocation threshold, we back the allocation with a temp file.
170 TempMapping* mapping = new TempMapping();
171 if (!mapping->Initialize(bytes + 1)) {
grt (UTC plus 2) 2011/02/28 18:08:34 Initialize(bytes) now that bytes includes the extr
tommi (sloooow) - chröme 2011/02/28 18:15:16 Doh, thanks
172 delete mapping;
173 throw std::bad_alloc("TempMapping::Initialize");
174 }
175 mem = reinterpret_cast<uint8*>(mapping->memory());
176 mem[0] = static_cast<uint8>(FILE_ALLOCATION);
177 }
178 return reinterpret_cast<pointer>(mem + sizeof(T));
179 }
180
181 pointer allocate(size_type count, const void* hint) {
182 return allocate(count);
183 }
184
185 void construct(pointer ptr, const T& value) {
186 ::new(ptr) T(value);
187 }
188
189 void destroy(pointer ptr) {
190 ptr->~T();
191 }
192
193 size_t max_size() const _THROW0() {
194 size_type count = static_cast<size_type>(-1) / sizeof(T);
195 return (0 < count ? count : 1);
196 }
197 };
198
199 #else // OS_WIN
200
201 // On Mac, Linux, we just use the default STL allocator.
202 template<class T>
203 class MemoryAllocator : public std::allocator<T> {
204 public:
205 };
206
207 #endif // OS_WIN
208
209 } // namespace courgette
210
211 #endif // COURGETTE_MEMORY_ALLOCATOR_H_
OLDNEW
« no previous file with comments | « courgette/ensemble_apply.cc ('k') | courgette/memory_allocator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698