1 /**
2  * Allocate and free code blocks
3  *
4  * Compiler implementation of the
5  * $(LINK2 https://www.dlang.org, D programming language).
6  *
7  * Copyright:   Copyright (C) 1987-1998 by Symantec
8  *              Copyright (C) 2000-2023 by The D Language Foundation, All Rights Reserved
9  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
10  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
11  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/dcode.d, backend/dcode.d)
12  */
13 
14 module dmd.backend.dcode;
15 
16 import core.stdc.stdio;
17 import core.stdc.stdlib;
18 import core.stdc.string;
19 
20 import dmd.backend.cc;
21 import dmd.backend.cdef;
22 import dmd.backend.code;
23 import dmd.backend.code_x86;
24 import dmd.backend.global;
25 import dmd.backend.mem;
26 
27 
28 nothrow:
29 @safe:
30 
31 __gshared
32 code *code_list = null;
33 
34 /************************************
35  * Allocate a chunk of code's and add them to
36  * code_list.
37  */
38 @trusted
39 code *code_chunk_alloc()
40 {
41     const size_t n = 4096 / code.sizeof;
42     //printf("code_chunk_alloc() n = %d\n", n);
43     code *chunk = cast(code *)mem_fmalloc(n * code.sizeof);
44     for (size_t i = 0; i < n - 1; ++i)
45     {
46         chunk[i].next = &chunk[i + 1];
47     }
48     chunk[n - 1].next = null;
49     code_list = chunk;
50     return chunk;
51 }
52 
53 /*****************
54  * Allocate code
55  */
56 
57 @trusted
58 code *code_calloc()
59 {
60     //printf("code %d\n", code.sizeof);
61     code *c = code_list ? code_list : code_chunk_alloc();
62     code_list = code_next(c);
63     memset(c, 0, code.sizeof);
64 
65     //dbg_printf("code_calloc: %p\n",c);
66     return c;
67 }
68 
69 
70 /*****************
71  * Free code
72  */
73 
74 @trusted
75 void code_free(code *cstart)
76 {
77     if (cstart)
78     {
79         code *c = cstart;
80         while (1)
81         {
82             if (c.Iop == ASM)
83             {
84                 mem_free(c.IEV1.bytes);
85             }
86             code *cnext = code_next(c);
87             if (!cnext)
88                 break;
89             c = cnext;
90         }
91         c.next = code_list;
92         code_list = cstart;
93     }
94 }
95 
96 /*****************
97  * Terminate code
98  */
99 
100 @trusted
101 void code_term()
102 {
103 static if (TERMCODE)
104 {
105     code *cn;
106     int count = 0;
107 
108     while (code_list)
109     {   cn = code_next(code_list);
110         //mem_ffree(code_list);
111         code_list = cn;
112         count++;
113     }
114     debug printf("Max # of codes = %d\n",count);
115 }
116 else
117 {
118 debug
119 {
120     int count = 0;
121 
122     for (code *cn = code_list; cn; cn = code_next(cn))
123         count++;
124     printf("Max # of codes = %d\n",count);
125 }
126 }
127 }