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