Merge dmd upstream 6243fa6d2
[official-gcc.git] / gcc / d / dmd / root / rmem.c
blobd24e0126b375e56f0b5195a7ce69660c3a57b6c4
2 /* Copyright (C) 2000-2018 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 */
9 #include "dsystem.h"
10 #include "rmem.h"
12 /* This implementation of the storage allocator uses the standard C allocation package.
15 Mem mem;
17 char *Mem::xstrdup(const char *s)
19 char *p;
21 if (s)
23 #ifdef IN_GCC
24 p = ::xstrdup(s);
25 #else
26 p = strdup(s);
27 #endif
28 if (p)
29 return p;
30 error();
32 return NULL;
35 void *Mem::xmalloc(size_t size)
36 { void *p;
38 if (!size)
39 p = NULL;
40 else
42 #ifdef IN_GCC
43 p = ::xmalloc(size);
44 #else
45 p = malloc(size);
46 #endif
47 if (!p)
48 error();
50 return p;
53 void *Mem::xcalloc(size_t size, size_t n)
54 { void *p;
56 if (!size || !n)
57 p = NULL;
58 else
60 #ifdef IN_GCC
61 p = ::xcalloc(size, n);
62 #else
63 p = calloc(size, n);
64 #endif
65 if (!p)
66 error();
68 return p;
71 void *Mem::xrealloc(void *p, size_t size)
73 if (!size)
74 { if (p)
76 free(p);
77 p = NULL;
80 else if (!p)
82 #ifdef IN_GCC
83 p = ::xmalloc(size);
84 #else
85 p = malloc(size);
86 #endif
87 if (!p)
88 error();
90 else
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();
103 return p;
106 void Mem::xfree(void *p)
108 if (p)
109 free(p);
112 void *Mem::xmallocdup(void *o, size_t size)
113 { void *p;
115 if (!size)
116 p = NULL;
117 else
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);
129 return p;
132 void Mem::error()
134 printf("Error: out of memory\n");
135 exit(EXIT_FAILURE);
138 /* =================================================== */
140 /* Allocate, but never release
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)
147 static size_t heapleft = 0;
148 static void *heapp;
150 extern "C" void *allocmemory(size_t m_size)
152 // 16 byte alignment is better (and sometimes needed) for doubles
153 m_size = (m_size + 15) & ~15;
155 // The layout of the code is selected so the most common case is straight through
156 if (m_size <= heapleft)
159 heapleft -= m_size;
160 void *p = heapp;
161 heapp = (void *)((char *)heapp + m_size);
162 return p;
165 if (m_size > CHUNK_SIZE)
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;
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)
187 printf("Error: out of memory\n");
188 exit(EXIT_FAILURE);
190 goto L1;