1 2/* Copyright (C) 2000-2019 by The D Language Foundation, All Rights Reserved 3 * http://www.digitalmars.com 4 * Distributed under the Boost Software License, Version 1.0. 5 * (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) 6 * https://github.com/D-Programming-Language/dmd/blob/master/src/root/rmem.c 7 */ 8 9#include "dsystem.h" 10#include "rmem.h" 11 12/* This implementation of the storage allocator uses the standard C allocation package. 13 */ 14 15Mem mem; 16 17char *Mem::xstrdup(const char *s) 18{ 19 char *p; 20 21 if (s) 22 { 23#ifdef IN_GCC 24 p = ::xstrdup(s); 25#else 26 p = strdup(s); 27#endif 28 if (p) 29 return p; 30 error(); 31 } 32 return NULL; 33} 34 35void *Mem::xmalloc(size_t size) 36{ void *p; 37 38 if (!size) 39 p = NULL; 40 else 41 { 42#ifdef IN_GCC 43 p = ::xmalloc(size); 44#else 45 p = malloc(size); 46#endif 47 if (!p) 48 error(); 49 } 50 return p; 51} 52 53void *Mem::xcalloc(size_t size, size_t n) 54{ void *p; 55 56 if (!size || !n) 57 p = NULL; 58 else 59 { 60#ifdef IN_GCC 61 p = ::xcalloc(size, n); 62#else 63 p = calloc(size, n); 64#endif 65 if (!p) 66 error(); 67 } 68 return p; 69} 70 71void *Mem::xrealloc(void *p, size_t size) 72{ 73 if (!size) 74 { if (p) 75 { 76 free(p); 77 p = NULL; 78 } 79 } 80 else if (!p) 81 { 82#ifdef IN_GCC 83 p = ::xmalloc(size); 84#else 85 p = malloc(size); 86#endif 87 if (!p) 88 error(); 89 } 90 else 91 { 92 void *psave = p; 93#ifdef IN_GCC 94 p = ::xrealloc(psave, size); 95#else 96 p = realloc(psave, size); 97#endif 98 if (!p) 99 { xfree(psave); 100 error(); 101 } 102 } 103 return p; 104} 105 106void Mem::xfree(void *p) 107{ 108 if (p) 109 free(p); 110} 111 112void *Mem::xmallocdup(void *o, size_t size) 113{ void *p; 114 115 if (!size) 116 p = NULL; 117 else 118 { 119#ifdef IN_GCC 120 p = ::xmalloc(size); 121#else 122 p = malloc(size); 123#endif 124 if (!p) 125 error(); 126 else 127 memcpy(p,o,size); 128 } 129 return p; 130} 131 132void Mem::error() 133{ 134 printf("Error: out of memory\n"); 135 exit(EXIT_FAILURE); 136} 137 138/* =================================================== */ 139 140/* Allocate, but never release 141 */ 142 143// Allocate a little less than 1Mb because the C runtime adds some overhead that 144// causes the actual memory block to be larger than 1Mb otherwise. 145#define CHUNK_SIZE (256 * 4096 - 64) 146 147static size_t heapleft = 0; 148static void *heapp; 149 150extern "C" void *allocmemory(size_t m_size) 151{ 152 // 16 byte alignment is better (and sometimes needed) for doubles 153 m_size = (m_size + 15) & ~15; 154 155 // The layout of the code is selected so the most common case is straight through 156 if (m_size <= heapleft) 157 { 158 L1: 159 heapleft -= m_size; 160 void *p = heapp; 161 heapp = (void *)((char *)heapp + m_size); 162 return p; 163 } 164 165 if (m_size > CHUNK_SIZE) 166 { 167#ifdef IN_GCC 168 void *p = xmalloc(m_size); 169#else 170 void *p = malloc(m_size); 171#endif 172 if (p) 173 return p; 174 printf("Error: out of memory\n"); 175 exit(EXIT_FAILURE); 176 return p; 177 } 178 179 heapleft = CHUNK_SIZE; 180#ifdef IN_GCC 181 heapp = xmalloc(CHUNK_SIZE); 182#else 183 heapp = malloc(CHUNK_SIZE); 184#endif 185 if (!heapp) 186 { 187 printf("Error: out of memory\n"); 188 exit(EXIT_FAILURE); 189 } 190 goto L1; 191} 192