-
-
Notifications
You must be signed in to change notification settings - Fork 594
/
ph2.d
140 lines (115 loc) · 2.6 KB
/
ph2.d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/**
* Compiler implementation of the
* $(LINK2 http://www.dlang.org, D programming language).
*
* Copyright: Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
* Authors: $(LINK2 http://www.digitalmars.com, Walter Bright)
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/ph2.d, backend/ph2.d)
*/
/* This is only for dmd, not dmc.
* It implements a heap allocator that never frees.
*/
module dmd.backend.ph2;
import core.stdc.stdio;
import core.stdc.stdlib;
import core.stdc.string;
import dmd.backend.cc;
import dmd.backend.global;
extern (C++):
nothrow:
/**********************************************
* Do our own storage allocator, a replacement
* for malloc/free.
*/
struct Heap
{
Heap *prev; // previous heap
ubyte *buf; // buffer
ubyte *p; // high water mark
uint nleft; // number of bytes left
}
__gshared Heap *heap=null;
void ph_init()
{
if (!heap) {
heap = cast(Heap *)calloc(1,Heap.sizeof);
}
assert(heap);
}
void ph_term()
{
//printf("ph_term()\n");
debug
{
Heap *h;
Heap *hprev;
for (h = heap; h; h = hprev)
{
hprev = h.prev;
free(h.buf);
free(h);
}
}
}
void ph_newheap(size_t nbytes)
{ uint newsize;
Heap *h;
h = cast(Heap *) malloc(Heap.sizeof);
if (!h)
err_nomem();
newsize = (nbytes > 0xFF00) ? cast(uint)nbytes : 0xFF00;
h.buf = cast(ubyte *) malloc(newsize);
if (!h.buf)
{
free(h);
err_nomem();
}
h.nleft = newsize;
h.p = h.buf;
h.prev = heap;
heap = h;
}
void *ph_malloc(size_t nbytes)
{ ubyte *p;
nbytes += uint.sizeof * 2;
nbytes &= ~(uint.sizeof - 1);
if (nbytes >= heap.nleft)
ph_newheap(nbytes);
p = heap.p;
heap.p += nbytes;
heap.nleft -= nbytes;
*cast(uint *)p = cast(uint)(nbytes - uint.sizeof);
p += uint.sizeof;
return p;
}
void *ph_calloc(size_t nbytes)
{ void *p;
p = ph_malloc(nbytes);
return p ? memset(p,0,nbytes) : p;
}
void ph_free(void *p)
{
}
void *ph_realloc(void *p,size_t nbytes)
{
//printf("ph_realloc(%p,%d)\n",p,cast(int)nbytes);
if (!p)
return ph_malloc(nbytes);
if (!nbytes)
{ ph_free(p);
return null;
}
void *newp = ph_malloc(nbytes);
if (newp)
{ uint oldsize = (cast(uint *)p)[-1];
memcpy(newp,p,oldsize);
ph_free(p);
}
return newp;
}
void err_nomem()
{
printf("Error: out of memory\n");
err_exit();
}