2 * This module contains allocation functions for the garbage collector.
4 * Copyright: Copyright (C) 2005-2006 Digital Mars, www.digitalmars.com.
7 * This software is provided 'as-is', without any express or implied
8 * warranty. In no event will the authors be held liable for any damages
9 * arising from the use of this software.
11 * Permission is granted to anyone to use this software for any purpose,
12 * including commercial applications, and to alter it and redistribute it
13 * freely, in both source and binary form, subject to the following
16 * o The origin of this software must not be misrepresented; you must not
17 * claim that you wrote the original software. If you use this software
18 * in a product, an acknowledgment in the product documentation would be
19 * appreciated but is not required.
20 * o Altered source versions must be plainly marked as such, and must not
21 * be misrepresented as being the original software.
22 * o This notice may not be removed or altered from any source
24 * Authors: Walter Bright, David Friedman, Sean Kelly
43 LPVOID VirtualAlloc(LPVOID, DWORD, DWORD, DWORD);
44 WINBOOL VirtualFree(LPVOID, DWORD, DWORD);
46 else version (Posix) {
47 version (linux) enum: bool { OPTIONAL_LARGEFILE_SUPPORT = true }
48 else version (solaris) enum: bool { OPTIONAL_LARGEFILE_SUPPORT = true }
49 else enum: bool { OPTIONAL_LARGEFILE_SUPPORT = false }
50 static if (OPTIONAL_LARGEFILE_SUPPORT)
51 enum: bool { USE_LARGEFILE64 = ((void*).sizeof == 4) }
53 enum: bool { USE_LARGEFILE64 = false }
54 static if (USE_LARGEFILE64 || (void*).sizeof > int.sizeof)
67 const MAP_FAILED = cast(void*) -1;
68 // Non-standard, but needed
69 version (linux) { enum: int { MAP_ANON = 0x20 } }
70 else version (darwin) { enum: int { MAP_ANON = 0x1000 } }
71 else version (freebsd) { enum: int { MAP_ANON = 0x1000 } }
72 else version (solaris) { enum: int { MAP_ANON = 0x100 } }
73 void* mmap(void*, size_t, int, int, int, off_t);
74 int munmap(void*, size_t);
83 static if(is(typeof(VirtualAlloc)))
84 version = GC_Use_Alloc_Win32;
85 else static if (is(typeof(mmap)))
86 version = GC_Use_Alloc_MMap;
87 else static if (is(typeof(valloc)))
88 version = GC_Use_Alloc_Valloc;
89 else static if (is(typeof(malloc)))
90 version = GC_Use_Alloc_Malloc;
91 else static assert(false, "No supported allocation methods available.");
94 static if (is(typeof(VirtualAlloc))) // version (GC_Use_Alloc_Win32)
99 void *os_mem_map(size_t nbytes)
101 return VirtualAlloc(null, nbytes, MEM_RESERVE, PAGE_READWRITE);
111 int os_mem_commit(void *base, size_t offset, size_t nbytes)
114 p = VirtualAlloc(base + offset, nbytes, MEM_COMMIT, PAGE_READWRITE);
115 return cast(int)(p is null);
125 int os_mem_decommit(void *base, size_t offset, size_t nbytes)
127 return cast(int)(VirtualFree(base + offset, nbytes, MEM_DECOMMIT) == 0);
132 * Unmap memory allocated with os_mem_map().
133 * Memory must have already been decommitted.
138 int os_mem_unmap(void *base, size_t nbytes)
140 return cast(int)(VirtualFree(base, 0, MEM_RELEASE) == 0);
143 else static if (is(typeof(mmap))) // else version (GC_Use_Alloc_MMap)
145 void *os_mem_map(size_t nbytes)
148 p = mmap(null, nbytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
149 return (p == MAP_FAILED) ? null : p;
153 int os_mem_commit(void *base, size_t offset, size_t nbytes)
159 int os_mem_decommit(void *base, size_t offset, size_t nbytes)
165 int os_mem_unmap(void *base, size_t nbytes)
167 return munmap(base, nbytes);
170 else static if (is(typeof(valloc))) // else version (GC_Use_Alloc_Valloc)
172 void *os_mem_map(size_t nbytes)
174 return valloc(nbytes);
178 int os_mem_commit(void *base, size_t offset, size_t nbytes)
184 int os_mem_decommit(void *base, size_t offset, size_t nbytes)
190 int os_mem_unmap(void *base, size_t nbytes)
196 else static if (is(typeof(malloc))) // else version (GC_Use_Alloc_Malloc)
198 // NOTE: This assumes malloc granularity is at least (void*).sizeof. If
199 // (req_size + PAGESIZE) is allocated, and the pointer is rounded up
200 // to PAGESIZE alignment, there will be space for a void* at the end
201 // after PAGESIZE bytes used by the GC.
204 import gcx; // for PAGESIZE
207 const size_t PAGE_MASK = PAGESIZE - 1;
210 void *os_mem_map(size_t nbytes)
212 p = cast(byte *) malloc(nbytes + PAGESIZE);
213 q = p + ((PAGESIZE - ((cast(size_t) p & PAGE_MASK))) & PAGE_MASK);
214 * cast(void**)(q + nbytes) = p;
219 int os_mem_commit(void *base, size_t offset, size_t nbytes)
225 int os_mem_decommit(void *base, size_t offset, size_t nbytes)
231 int os_mem_unmap(void *base, size_t nbytes)
233 free( *cast(void**)( cast(byte*) base + nbytes ) );
239 static assert(false, "No supported allocation methods available.");