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

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, 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 | Annotate | Revision Log
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/platform_file.h"
12
13 namespace courgette {
14
15 #ifdef OS_WIN
16
17 // Manages a temporary file. The file is created in the %TEMP% folder and
18 // is deleted when the file handle is closed.
19 class TempFile {
20 public:
21 TempFile();
22 ~TempFile();
23
24 bool Create();
25 void Close();
26 bool SetSize(size_t size);
27
28 // Returns true iff the temp file is currently open.
29 bool valid() const;
30
31 // Returns the handle of the temporary file or INVALID_HANDLE_VALUE if
32 // a temp file has not been created.
33 base::PlatformFile handle() const;
34
35 // Returns the size of the temp file. If the temp file doesn't exist,
36 // the return value is 0.
37 size_t size() const;
38
39 protected:
40 base::PlatformFile file_;
41 size_t size_;
42 };
43
44 // Manages a read/write virtual mapping of a physical file.
45 class FileMapping {
46 public:
47 FileMapping();
48 ~FileMapping();
49
50 // Map a file from beginning to |size|.
51 bool Create(HANDLE file, size_t size);
52 void Close();
53
54 // Returns true iff a mapping has been created.
55 bool valid() const;
56
57 // Returns a writable pointer to the beginning of the memory mapped file.
58 // If Create has not been called successfully, return value is NULL.
59 void* view() const;
60
61 protected:
62 HANDLE mapping_;
63 void* view_;
64 };
65
66 // Manages a temporary file and a memory mapping of the temporary file.
67 // The memory that this class manages holds a pointer back to the TempMapping
68 // object itself, so that given a memory pointer allocated by this class,
69 // you can get a pointer to the TempMapping instance that owns that memory.
70 class TempMapping {
71 public:
72 TempMapping();
73 ~TempMapping();
74
75 // Creates a temporary file of size |size| and maps it into the current
76 // process' address space.
77 bool Initialize(size_t size);
78
79 // Returns a writable pointer to the reserved memory.
80 void* memory() const;
81
82 // Returns a pointer to the TempMapping instance that allocated the |mem|
83 // block of memory. It's the callers responsibility to make sure that
84 // the memory block was allocated by the TempMapping class.
85 static TempMapping* GetMappingFromPtr(void* mem);
86
87 protected:
88 TempFile file_;
89 FileMapping mapping_;
90 };
91
92 // An STL compatible memory allocator class that allocates memory either
93 // from the heap or via a temporary file. A file allocation will be made
94 // if either the requested memory size exceeds |kMaxHeapAllocationSize|
95 // or if a heap allocation fails.
96 template<class T>
97 class MemoryAllocator : public std::_Allocator_base<T> {
grt (UTC plus 2) 2011/02/28 15:06:41 Does deriving from an implementation detail of Mic
tommi (sloooow) - chröme 2011/02/28 17:50:00 removed. Also updated the types accordingly.
98 public:
99 typedef _Allocator_base<T> Mybase;
100 typedef typename Mybase::value_type value_type;
101 typedef value_type _FARQ* pointer;
102 typedef value_type _FARQ& reference;
103 typedef const value_type _FARQ* const_pointer;
104 typedef const value_type _FARQ& const_reference;
105 typedef _SIZT size_type;
106 typedef _PDFT 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 well attempt.
grt (UTC plus 2) 2011/02/28 15:06:41 well -> we'll
tommi (sloooow) - chröme 2011/02/28 17:50:00 Done.
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--;
140 if (mem[0] == HEAP_ALLOCATION) {
141 delete [] mem;
142 } else {
143 TempMapping* mapping = TempMapping::GetMappingFromPtr(mem);
grt (UTC plus 2) 2011/02/28 15:06:41 DCHECK_EQ(FILE_ALLOCATION, mem[0])?
tommi (sloooow) - chröme 2011/02/28 17:50:00 Done.
144 delete mapping;
145 }
146 }
147
148 pointer allocate(size_type count) {
149 size_type bytes = count * sizeof(T);
grt (UTC plus 2) 2011/02/28 15:06:41 check for overflow (count > max_size()), throwing
tommi (sloooow) - chröme 2011/02/28 17:50:00 Done.
150 uint8* mem = NULL;
151 // First see if we can do this allocation on the heap.
152 if (count < kMaxHeapAllocationSize)
153 mem = new(std::nothrow) uint8[bytes + 1];
154 if (mem != NULL) {
155 mem[0] = static_cast<uint8>(HEAP_ALLOCATION);
156 } else {
157 // If either the heap allocation failed or the request exceeds the
158 // max heap allocation threshold, we back the allocation with a temp file.
159 TempMapping* mapping = new TempMapping();
160 mapping->Initialize(bytes + 1);
grt (UTC plus 2) 2011/02/28 15:06:41 what if this returns false?
tommi (sloooow) - chröme 2011/02/28 17:50:00 added check+throw bad_alloc
161 mem = reinterpret_cast<uint8*>(mapping->memory());
162 mem[0] = static_cast<uint8>(FILE_ALLOCATION);
163 }
164 return reinterpret_cast<pointer>(mem + 1);
grt (UTC plus 2) 2011/02/28 15:06:41 C++-03 20.4.1.1 says that this must return "a poin
tommi (sloooow) - chröme 2011/02/28 17:50:00 fixed so that heap allocations are always correctl
165 }
166
167 pointer allocate(size_type count, const void _FARQ* hint) {
168 return allocate(count);
169 }
170
171 void construct(pointer _Ptr, const T& _Val) {
172 std::_Construct(_Ptr, _Val);
grt (UTC plus 2) 2011/02/28 15:06:41 Another implementation detail used here.
tommi (sloooow) - chröme 2011/02/28 17:50:00 Done.
173 }
174
175 void destroy(pointer _Ptr) {
176 std::_Destroy(_Ptr);
grt (UTC plus 2) 2011/02/28 15:06:41 And here.
tommi (sloooow) - chröme 2011/02/28 17:50:00 Done.
177 }
178
179 _SIZT max_size() const _THROW0() {
180 size_type count = static_cast<size_type>(-1) / sizeof(T);
181 return (0 < count ? count : 1);
182 }
183 };
184
185 #else // OS_WIN
186
187 // On Mac, Linux, we just use the default STL allocator.
188 template<class T>
189 class MemoryAllocator : public std::allocator<T> {
190 public:
191 };
192
193 #endif // OS_WIN
194
195 } // namespace courgette
196
197 #endif // COURGETTE_MEMORY_ALLOCATOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698