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 version (SCPP)
17     version = COMPILE;
18 version (MARS)
19     version = COMPILE;
20 
21 version (COMPILE)
22 {
23 
24 import core.stdc.stdio;
25 import core.stdc.stdlib;
26 import core.stdc.string;
27 
28 import dmd.backend.cc;
29 import dmd.backend.cdef;
30 import dmd.backend.code;
31 import dmd.backend.code_x86;
32 import dmd.backend.global;
33 import dmd.backend.mem;
34 
35 extern (C++):
36 
37 nothrow:
38 @safe:
39 
40 __gshared
41 code *code_list = null;
42 
43 /************************************
44  * Allocate a chunk of code's and add them to
45  * code_list.
46  */
47 @trusted
48 code *code_chunk_alloc()
49 {
50     const size_t n = 4096 / code.sizeof;
51     //printf("code_chunk_alloc() n = %d\n", n);
52     code *chunk = cast(code *)mem_fmalloc(n * code.sizeof);
53     for (size_t i = 0; i < n - 1; ++i)
54     {
55         chunk[i].next = &chunk[i + 1];
56     }
57     chunk[n - 1].next = null;
58     code_list = chunk;
59     return chunk;
60 }
61 
62 /*****************
63  * Allocate code
64  */
65 
66 @trusted
67 code *code_calloc()
68 {
69     //printf("code %d\n", code.sizeof);
70     code *c = code_list ? code_list : code_chunk_alloc();
71     code_list = code_next(c);
72     memset(c, 0, code.sizeof);
73 
74     //dbg_printf("code_calloc: %p\n",c);
75     return c;
76 }
77 
78 
79 /*****************
80  * Free code
81  */
82 
83 @trusted
84 void code_free(code *cstart)
85 {
86     if (cstart)
87     {
88         code *c = cstart;
89         while (1)
90         {
91             if (c.Iop == ASM)
92             {
93                 mem_free(c.IEV1.bytes);
94             }
95             code *cnext = code_next(c);
96             if (!cnext)
97                 break;
98             c = cnext;
99         }
100         c.next = code_list;
101         code_list = cstart;
102     }
103 }
104 
105 /*****************
106  * Terminate code
107  */
108 
109 @trusted
110 void code_term()
111 {
112 static if (TERMCODE)
113 {
114     code *cn;
115     int count = 0;
116 
117     while (code_list)
118     {   cn = code_next(code_list);
119         //mem_ffree(code_list);
120         code_list = cn;
121         count++;
122     }
123     debug printf("Max # of codes = %d\n",count);
124 }
125 else
126 {
127 debug
128 {
129     int count = 0;
130 
131     for (code *cn = code_list; cn; cn = code_next(cn))
132         count++;
133     printf("Max # of codes = %d\n",count);
134 }
135 }
136 }
137 
138 }