1 // Compiler implementation of the D programming language 2 // Copyright (c) 1999-2015 by Digital Mars 3 // All Rights Reserved 4 // written by Walter Bright 5 // http://www.digitalmars.com 6 // Distributed under the Boost Software License, Version 1.0. 7 // http://www.boost.org/LICENSE_1_0.txt 8 9 module ddmd.root.rmem; 10 11 import core.stdc..string; 12 13 version (GC) 14 { 15 import core.memory : GC; 16 17 extern (C++) struct Mem 18 { 19 static char* xstrdup(const(char)* p) nothrow 20 { 21 return p[0 .. strlen(p) + 1].dup.ptr; 22 } 23 24 static void xfree(void* p) nothrow 25 { 26 } 27 28 static void* xmalloc(size_t n) nothrow 29 { 30 return GC.malloc(n); 31 } 32 33 static void* xcalloc(size_t size, size_t n) nothrow 34 { 35 return GC.calloc(size * n); 36 } 37 38 static void* xrealloc(void* p, size_t size) nothrow 39 { 40 return GC.realloc(p, size); 41 } 42 } 43 44 extern (C++) __gshared Mem mem; 45 } 46 else 47 { 48 import core.stdc.stdlib; 49 import core.stdc.stdio; 50 51 extern (C++) struct Mem 52 { 53 static char* xstrdup(const(char)* s) nothrow 54 { 55 if (s) 56 { 57 auto p = .strdup(s); 58 if (p) 59 return p; 60 error(); 61 } 62 return null; 63 } 64 65 static void xfree(void* p) nothrow 66 { 67 if (p) 68 .free(p); 69 } 70 71 static void* xmalloc(size_t size) nothrow 72 { 73 if (!size) 74 return null; 75 76 auto p = .malloc(size); 77 if (!p) 78 error(); 79 return p; 80 } 81 82 static void* xcalloc(size_t size, size_t n) nothrow 83 { 84 if (!size || !n) 85 return null; 86 87 auto p = .calloc(size, n); 88 if (!p) 89 error(); 90 return p; 91 } 92 93 static void* xrealloc(void* p, size_t size) nothrow 94 { 95 if (!size) 96 { 97 if (p) 98 .free(p); 99 return null; 100 } 101 102 if (!p) 103 { 104 p = .malloc(size); 105 if (!p) 106 error(); 107 return p; 108 } 109 110 p = .realloc(p, size); 111 if (!p) 112 error(); 113 return p; 114 } 115 116 static void error() nothrow 117 { 118 printf("Error: out of memory\n"); 119 exit(EXIT_FAILURE); 120 } 121 } 122 123 extern (C++) __gshared Mem mem; 124 125 enum CHUNK_SIZE = (256 * 4096 - 64); 126 127 __gshared size_t heapleft = 0; 128 __gshared void* heapp; 129 130 extern (C) void* allocmemory(size_t m_size) nothrow 131 { 132 // 16 byte alignment is better (and sometimes needed) for doubles 133 m_size = (m_size + 15) & ~15; 134 135 // The layout of the code is selected so the most common case is straight through 136 if (m_size <= heapleft) 137 { 138 L1: 139 heapleft -= m_size; 140 auto p = heapp; 141 heapp = cast(void*)(cast(char*)heapp + m_size); 142 return p; 143 } 144 145 if (m_size > CHUNK_SIZE) 146 { 147 auto p = malloc(m_size); 148 if (p) 149 { 150 return p; 151 } 152 printf("Error: out of memory\n"); 153 exit(EXIT_FAILURE); 154 } 155 156 heapleft = CHUNK_SIZE; 157 heapp = malloc(CHUNK_SIZE); 158 if (!heapp) 159 { 160 printf("Error: out of memory\n"); 161 exit(EXIT_FAILURE); 162 } 163 goto L1; 164 } 165 166 version(DigitalMars) 167 { 168 extern (C) void* _d_allocmemory(size_t m_size) nothrow 169 { 170 return allocmemory(m_size); 171 } 172 173 extern (C) Object _d_newclass(const ClassInfo ci) nothrow 174 { 175 auto p = allocmemory(ci.init.length); 176 p[0 .. ci.init.length] = cast(void[])ci.init[]; 177 return cast(Object)p; 178 } 179 180 extern (C) void* _d_newitemT(TypeInfo ti) nothrow 181 { 182 auto p = allocmemory(ti.tsize); 183 (cast(ubyte*)p)[0 .. ti.init.length] = 0; 184 return p; 185 } 186 187 extern (C) void* _d_newitemiT(TypeInfo ti) nothrow 188 { 189 auto p = allocmemory(ti.tsize); 190 p[0 .. ti.init.length] = ti.init[]; 191 return p; 192 } 193 } 194 }