| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2010 Apple Inc. All rights reserved. | |
| 3 * | |
| 4 * Redistribution and use in source and binary forms, with or without | |
| 5 * modification, are permitted provided that the following conditions | |
| 6 * are met: | |
| 7 * 1. Redistributions of source code must retain the above copyright | |
| 8 * notice, this list of conditions and the following disclaimer. | |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | |
| 10 * notice, this list of conditions and the following disclaimer in the | |
| 11 * documentation and/or other materials provided with the distribution. | |
| 12 * | |
| 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY | |
| 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
| 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR | |
| 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
| 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
| 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
| 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | |
| 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 24 */ | |
| 25 | |
| 26 #ifndef PageReservation_h | |
| 27 #define PageReservation_h | |
| 28 | |
| 29 #include <wtf/PageAllocation.h> | |
| 30 | |
| 31 namespace WTF { | |
| 32 | |
| 33 /* | |
| 34 PageReservation | |
| 35 | |
| 36 Like PageAllocation, the PageReservation class provides a cross-platform mem
ory | |
| 37 allocation interface, but with a set of capabilities more similar to that of | |
| 38 VirtualAlloc than posix mmap. PageReservation can be used to allocate virtu
al | |
| 39 memory without committing physical memory pages using PageReservation::reser
ve. | |
| 40 Following a call to reserve all memory in the region is in a decommited stat
e, | |
| 41 in which the memory should not be used (accessing the memory may cause a fau
lt). | |
| 42 | |
| 43 Before using memory it must be committed by calling commit, which is passed
start | |
| 44 and size values (both of which require system page size granularity). One t
he | |
| 45 committed memory is no longer needed 'decommit' may be called to return the | |
| 46 memory to its devommitted state. Commit should only be called on memory tha
t is | |
| 47 currently decommitted, and decommit should only be called on memory regions
that | |
| 48 are currently committed. All memory should be decommited before the reserva
tion | |
| 49 is deallocated. Values in memory may not be retained accross a pair of call
s if | |
| 50 the region of memory is decommitted and then committed again. | |
| 51 | |
| 52 Memory protection should not be changed on decommitted memory, and if protec
tion | |
| 53 is changed on memory while it is committed it should be returned to the orig
nal | |
| 54 protection before decommit is called. | |
| 55 */ | |
| 56 | |
| 57 class PageReservation : private PageBlock { | |
| 58 public: | |
| 59 PageReservation() | |
| 60 : m_committed(0) | |
| 61 , m_writable(false) | |
| 62 , m_executable(false) | |
| 63 { | |
| 64 } | |
| 65 | |
| 66 using PageBlock::base; | |
| 67 using PageBlock::size; | |
| 68 | |
| 69 #ifndef __clang__ | |
| 70 using PageBlock::operator bool; | |
| 71 #else | |
| 72 // FIXME: This is a workaround for <rdar://problem/8876150>, wherein Clang i
ncorrectly emits an access | |
| 73 // control warning when a client tries to use operator bool exposed above vi
a "using PageBlock::operator bool". | |
| 74 operator bool() const { return PageBlock::operator bool(); } | |
| 75 #endif | |
| 76 | |
| 77 void commit(void* start, size_t size) | |
| 78 { | |
| 79 ASSERT(*this); | |
| 80 ASSERT(isPageAligned(start)); | |
| 81 ASSERT(isPageAligned(size)); | |
| 82 ASSERT(contains(start, size)); | |
| 83 | |
| 84 m_committed += size; | |
| 85 OSAllocator::commit(start, size, m_writable, m_executable); | |
| 86 } | |
| 87 | |
| 88 void decommit(void* start, size_t size) | |
| 89 { | |
| 90 ASSERT(*this); | |
| 91 ASSERT(isPageAligned(start)); | |
| 92 ASSERT(isPageAligned(size)); | |
| 93 ASSERT(contains(start, size)); | |
| 94 | |
| 95 m_committed -= size; | |
| 96 OSAllocator::decommit(start, size); | |
| 97 } | |
| 98 | |
| 99 size_t committed() | |
| 100 { | |
| 101 return m_committed; | |
| 102 } | |
| 103 | |
| 104 static PageReservation reserve(size_t size, OSAllocator::Usage usage = OSAll
ocator::UnknownUsage, bool writable = true, bool executable = false) | |
| 105 { | |
| 106 ASSERT(isPageAligned(size)); | |
| 107 return PageReservation(OSAllocator::reserveUncommitted(size, usage, writ
able, executable), size, writable, executable, false); | |
| 108 } | |
| 109 | |
| 110 static PageReservation reserveWithGuardPages(size_t size, OSAllocator::Usage
usage = OSAllocator::UnknownUsage, bool writable = true, bool executable = fals
e) | |
| 111 { | |
| 112 ASSERT(isPageAligned(size)); | |
| 113 return PageReservation(OSAllocator::reserveUncommitted(size + pageSize()
* 2, usage, writable, executable, true), size, writable, executable, true); | |
| 114 } | |
| 115 | |
| 116 void deallocate() | |
| 117 { | |
| 118 ASSERT(!m_committed); | |
| 119 | |
| 120 // Clear base & size before calling release; if this is *inside* allocat
ion | |
| 121 // then we won't be able to clear then after deallocating the memory. | |
| 122 PageReservation tmp; | |
| 123 std::swap(tmp, *this); | |
| 124 | |
| 125 ASSERT(tmp); | |
| 126 ASSERT(!*this); | |
| 127 | |
| 128 OSAllocator::releaseDecommitted(tmp.base(), tmp.size()); | |
| 129 } | |
| 130 | |
| 131 private: | |
| 132 PageReservation(void* base, size_t size, bool writable, bool executable, boo
l hasGuardPages) | |
| 133 : PageBlock(base, size, hasGuardPages) | |
| 134 , m_committed(0) | |
| 135 , m_writable(writable) | |
| 136 , m_executable(executable) | |
| 137 { | |
| 138 } | |
| 139 | |
| 140 size_t m_committed; | |
| 141 bool m_writable; | |
| 142 bool m_executable; | |
| 143 }; | |
| 144 | |
| 145 } | |
| 146 | |
| 147 using WTF::PageReservation; | |
| 148 | |
| 149 #endif // PageReservation_h | |
| OLD | NEW |