2 * This module contains a minimal garbage collector implementation according to
3 * Tango requirements. This library is mostly intended to serve as an example,
4 * but it is usable in applications which do not rely on a garbage collector
5 * to clean up memory (ie. when dynamic array resizing is not used, and all
6 * memory allocated with 'new' is freed deterministically with 'delete').
8 * Please note that block attribute data must be tracked, or at a minimum, the
9 * FINALIZE bit must be tracked for any allocated memory block because calling
10 * rt_finalize on a non-object block can result in an access violation. In the
11 * allocator below, this tracking is done via a leading uint bitmask. A real
12 * allocator may do better to store this data separately, similar to the basic
13 * GC normally used by Tango.
15 * Copyright: Public Domain
17 * Authors: Leandro Lucarella
24 private import tango.sys.win32.UserGdi;
28 private import tango.stdc.posix.sys.mman;
29 private import tango.stdc.stdlib;
33 private import tango.stdc.stdlib;
36 static if (is(typeof(VirtualAlloc)))
39 void* mem_alloc(size_t size)
41 return VirtualAlloc(null, size, MEM_RESERVE, PAGE_READWRITE);
45 * Free memory allocated with alloc().
50 int mem_free(void* ptr, size_t size)
52 return cast(int)(VirtualFree(ptr, 0, MEM_RELEASE) == 0);
56 else static if (is(typeof(mmap)))
59 void* mem_alloc(size_t size)
61 void* ptr = mmap(null, size, PROT_READ | PROT_WRITE,
62 MAP_PRIVATE | MAP_ANON, -1, 0);
63 if (ptr == MAP_FAILED)
68 int mem_free(void* ptr, size_t size)
70 return munmap(ptr, size);
74 else static if (is(typeof(valloc)))
77 void* mem_alloc(size_t size)
82 int mem_free(void* ptr, size_t size)
88 else static if (is(typeof(malloc)))
91 // NOTE: This assumes malloc granularity is at least size_t.sizeof. If
92 // (req_size + PAGESIZE) is allocated, and the pointer is rounded up
93 // to PAGESIZE alignment, there will be space for a void* at the end
94 // after PAGESIZE bytes used by the GC.
97 enum { PAGESIZE = 4096 }
99 const size_t PAGE_MASK = PAGESIZE - 1;
101 void* mem_alloc(size_t size)
104 p = cast(byte *) malloc(size + PAGESIZE);
105 q = p + ((PAGESIZE - ((cast(size_t) p & PAGE_MASK))) & PAGE_MASK);
106 * cast(void**)(q + size) = p;
110 int mem_free(void* ptr, size_t size)
112 free(*cast(void**)(cast(byte*) ptr + size));
120 static assert(false, "No supported allocation methods available.");
124 // vim: set et sw=4 sts=4 :