1 /** 2 Memory provider allocators to be used in templated composition 3 within other, designated allocators. 4 5 Copyright: © 2012-2013 RejectedSoftware e.K. 6 © 2014-2015 Etienne Cimon 7 License: Subject to the terms of the MIT license. 8 Authors: Sönke Ludwig, Etienne Cimon 9 */ 10 module memutils.memory; 11 12 import memutils.allocators; 13 import memutils.helpers; 14 import std.algorithm : min; 15 import core.stdc.stdlib; 16 17 final class GCAllocator : Allocator { 18 import core.memory : GC; 19 void[] alloc(size_t sz) 20 { 21 auto mem = GC.malloc(sz+Allocator.alignment); 22 auto alignedmem = adjustPointerAlignment(mem); 23 assert(alignedmem - mem <= Allocator.alignment); 24 auto ret = alignedmem[0 .. sz]; 25 ensureValidMemory(ret); 26 return ret; 27 } 28 29 void[] realloc(void[] mem, size_t new_size) 30 { 31 size_t csz = min(mem.length, new_size); 32 33 auto p = extractUnalignedPointer(mem.ptr); 34 size_t misalign = mem.ptr - p; 35 assert(misalign <= Allocator.alignment); 36 37 void[] ret; 38 auto extended = GC.extend(p, new_size - mem.length, new_size - mem.length); 39 if (extended) { 40 assert(extended >= new_size+Allocator.alignment); 41 ret = p[misalign .. new_size+misalign]; 42 } else { 43 ret = alloc(new_size); 44 ret[0 .. csz] = mem[0 .. csz]; 45 } 46 ensureValidMemory(ret); 47 return ret; 48 } 49 50 /// calls to free are optional if stability is favored over speed 51 void free(void[] mem) 52 { 53 GC.free(extractUnalignedPointer(mem.ptr)); 54 } 55 } 56 57 final class MallocAllocator : Allocator { 58 import core.exception : OutOfMemoryError; 59 60 void[] alloc(size_t sz) 61 { 62 static err = new immutable OutOfMemoryError; 63 auto ptr = .malloc(sz + Allocator.alignment); 64 if (ptr is null) throw err; 65 return adjustPointerAlignment(ptr)[0 .. sz]; 66 } 67 68 void[] realloc(void[] mem, size_t new_size) 69 { 70 size_t csz = min(mem.length, new_size); 71 auto p = extractUnalignedPointer(mem.ptr); 72 size_t oldmisalign = mem.ptr - p; 73 ubyte misalign; 74 auto pn = cast(ubyte*).realloc(p, new_size+Allocator.alignment); 75 if (p == pn) return pn[oldmisalign .. new_size+oldmisalign]; 76 77 auto pna = cast(ubyte*)adjustPointerAlignment(pn, &misalign); 78 scope(exit) 79 *(cast(ubyte*)pna-1) = misalign; 80 auto newmisalign = pna - pn; 81 82 // account for changed alignment after realloc (move memory back to aligned position) 83 if (oldmisalign != newmisalign) { 84 if (newmisalign > oldmisalign) { 85 foreach_reverse (i; 0 .. csz) 86 pn[i + newmisalign] = pn[i + oldmisalign]; 87 } else { 88 foreach (i; 0 .. csz) 89 pn[i + newmisalign] = pn[i + oldmisalign]; 90 } 91 } 92 93 return pna[0 .. new_size]; 94 } 95 96 void free(void[] mem) 97 { 98 .free(extractUnalignedPointer(mem.ptr)); 99 } 100 }