]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/d/dmd/root/rmem.c
ipa-param-manip: Be careful about a reallocating hash_map
[thirdparty/gcc.git] / gcc / d / dmd / root / rmem.c
CommitLineData
b4c522fa 1
a3b38b77 2/* Copyright (C) 2000-2021 by The D Language Foundation, All Rights Reserved
b4c522fa
IB
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
f9ab59ff 9#include "dsystem.h"
b4c522fa
IB
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 {
f9ab59ff
IB
23#ifdef IN_GCC
24 p = ::xstrdup(s);
25#else
b4c522fa 26 p = strdup(s);
f9ab59ff 27#endif
b4c522fa
IB
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 {
f9ab59ff
IB
42#ifdef IN_GCC
43 p = ::xmalloc(size);
44#else
b4c522fa 45 p = malloc(size);
f9ab59ff 46#endif
b4c522fa
IB
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 {
f9ab59ff
IB
60#ifdef IN_GCC
61 p = ::xcalloc(size, n);
62#else
b4c522fa 63 p = calloc(size, n);
f9ab59ff 64#endif
b4c522fa
IB
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 {
f9ab59ff
IB
82#ifdef IN_GCC
83 p = ::xmalloc(size);
84#else
b4c522fa 85 p = malloc(size);
f9ab59ff 86#endif
b4c522fa
IB
87 if (!p)
88 error();
89 }
90 else
91 {
92 void *psave = p;
f9ab59ff
IB
93#ifdef IN_GCC
94 p = ::xrealloc(psave, size);
95#else
b4c522fa 96 p = realloc(psave, size);
f9ab59ff 97#endif
b4c522fa
IB
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 {
f9ab59ff
IB
119#ifdef IN_GCC
120 p = ::xmalloc(size);
121#else
b4c522fa 122 p = malloc(size);
f9ab59ff 123#endif
b4c522fa
IB
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 {
f9ab59ff
IB
167#ifdef IN_GCC
168 void *p = xmalloc(m_size);
169#else
b4c522fa 170 void *p = malloc(m_size);
f9ab59ff 171#endif
b4c522fa
IB
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;
f9ab59ff
IB
180#ifdef IN_GCC
181 heapp = xmalloc(CHUNK_SIZE);
182#else
b4c522fa 183 heapp = malloc(CHUNK_SIZE);
f9ab59ff 184#endif
b4c522fa
IB
185 if (!heapp)
186 {
187 printf("Error: out of memory\n");
188 exit(EXIT_FAILURE);
189 }
190 goto L1;
191}