1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sw=4 et tw=99 ft=cpp:
3 : *
4 : * ***** BEGIN LICENSE BLOCK *****
5 : * Copyright (C) 2010 Apple Inc. All rights reserved.
6 : *
7 : * Redistribution and use in source and binary forms, with or without
8 : * modification, are permitted provided that the following conditions
9 : * are met:
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * 2. Redistributions in binary form must reproduce the above copyright
13 : * notice, this list of conditions and the following disclaimer in the
14 : * documentation and/or other materials provided with the distribution.
15 : *
16 : * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
17 : * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
20 : * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 : * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 : * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24 : * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 : * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 : *
28 : * ***** END LICENSE BLOCK ***** */
29 :
30 : #ifndef PageAllocation_h
31 : #define PageAllocation_h
32 :
33 : #include "wtfbridge.h"
34 : #include "OSAllocator.h"
35 : #include "PageBlock.h"
36 : #include "assembler/wtf/VMTags.h"
37 :
38 : #if WTF_OS_DARWIN
39 : #include <mach/mach_init.h>
40 : #include <mach/vm_map.h>
41 : #endif
42 :
43 : #if WTF_OS_HAIKU
44 : #include <OS.h>
45 : #endif
46 :
47 : #if WTF_OS_WINDOWS
48 : #include <malloc.h>
49 : #include <windows.h>
50 : #endif
51 :
52 : #if WTF_OS_SYMBIAN
53 : #include <e32hal.h>
54 : #include <e32std.h>
55 : #endif
56 :
57 : #if WTF_HAVE_ERRNO_H
58 : #include <errno.h>
59 : #endif
60 :
61 : #if WTF_HAVE_MMAP
62 : #include <sys/mman.h>
63 : #include <unistd.h>
64 : #endif
65 :
66 : namespace WTF {
67 :
68 : /*
69 : PageAllocation
70 :
71 : The PageAllocation class provides a cross-platform memory allocation interface
72 : with similar capabilities to posix mmap/munmap. Memory is allocated by calling
73 : PageAllocation::allocate, and deallocated by calling deallocate on the
74 : PageAllocation object. The PageAllocation holds the allocation's base pointer
75 : and size.
76 :
77 : The allocate method is passed the size required (which must be a multiple of
78 : the system page size, which can be accessed using PageAllocation::pageSize).
79 : Callers may also optinally provide a flag indicating the usage (for use by
80 : system memory usage tracking tools, where implemented), and boolean values
81 : specifying the required protection (defaulting to writable, non-executable).
82 : */
83 :
84 62718 : class PageAllocation : private PageBlock {
85 : public:
86 31359 : PageAllocation()
87 31359 : {
88 31359 : }
89 :
90 : using PageBlock::size;
91 : using PageBlock::base;
92 :
93 : #ifndef __clang__
94 : using PageBlock::operator bool;
95 : #else
96 : // FIXME: This is a workaround for <rdar://problem/8876150>, wherein Clang incorrectly emits an access
97 : // control warning when a client tries to use operator bool exposed above via "using PageBlock::operator bool".
98 : operator bool() const { return PageBlock::operator bool(); }
99 : #endif
100 :
101 31359 : static PageAllocation allocate(size_t size, OSAllocator::Usage usage = OSAllocator::UnknownUsage, bool writable = true, bool executable = false)
102 : {
103 31359 : ASSERT(isPageAligned(size));
104 31359 : return PageAllocation(OSAllocator::reserveAndCommit(size, usage, writable, executable), size);
105 : }
106 :
107 31359 : void deallocate()
108 : {
109 : // Clear base & size before calling release; if this is *inside* allocation
110 : // then we won't be able to clear then after deallocating the memory.
111 31359 : PageAllocation tmp;
112 31359 : JSC::std::swap(tmp, *this);
113 :
114 31359 : ASSERT(tmp);
115 31359 : ASSERT(!*this);
116 :
117 31359 : OSAllocator::decommitAndRelease(tmp.base(), tmp.size());
118 31359 : }
119 :
120 : private:
121 31359 : PageAllocation(void* base, size_t size)
122 31359 : : PageBlock(base, size)
123 : {
124 31359 : }
125 : };
126 :
127 : } // namespace WTF
128 :
129 : using WTF::PageAllocation;
130 :
131 : #endif // PageAllocation_h
|