Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 54.3% 19 / 0 / 35
Functions: 29.4% 5 / 1 / 18
Branches: -% 0 / 0 / 0

OMCompiler/Compiler/Util/GCExt.mo
Line Branch Exec Source
1 /*
2 * This file is part of OpenModelica.
3 *
4 * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC),
5 * c/o Linköpings universitet, Department of Computer and Information Science,
6 * SE-58183 Linköping, Sweden.
7 *
8 * All rights reserved.
9 *
10 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR
11 * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8.
12 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
13 * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL
14 * VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
15 *
16 * The OpenModelica software and the OSMC (Open Source Modelica Consortium)
17 * Public License (OSMC-PL) are obtained from OSMC, either from the above
18 * address, from the URLs:
19 * http://www.openmodelica.org or
20 * https://github.com/OpenModelica/ or
21 * http://www.ida.liu.se/projects/OpenModelica,
22 * and in the OpenModelica distribution.
23 *
24 * GNU AGPL version 3 is obtained from:
25 * https://www.gnu.org/licenses/licenses.html#GPL
26 *
27 * This program is distributed WITHOUT ANY WARRANTY; without
28 * even the implied warranty of MERCHANTABILITY or FITNESS
29 * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
30 * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
31 *
32 * See the full OSMC Public License conditions for more details.
33 *
34 */
35
36 encapsulated package GCExt
37
38 constant Boolean cellsNeedOwners = false
39 "True where a weak cell needs an explicit owner to stay alive, so `InstNode`
40 copies a record to set and clear one. A constant, so the C compiler folds
41 it and drops both the branch and the rooting call inside it: Boehm keeps
42 the cell alive by tracing, and an owner there would only build the cycle
43 the collector then has to reclaim. The Rust port sets it true -- `GCExt`
44 is hand-written there.";
45
46 ✗ function gcollect
47 external "C" GC_gcollect() annotation(Include="#include <gc.h>", Library = {"omcgc"});
48 end gcollect;
49
50 ✗ function gcollectAndUnmap
51 external "C" GC_gcollect_and_unmap() annotation(Include="#include <gc.h>", Library = {"omcgc"});
52 end gcollectAndUnmap;
53
54 ✗ function enable
55 external "C" GC_enable() annotation(Include="#include <gc.h>", Library = {"omcgc"});
56 end enable;
57
58 ✗ function disable
59 external "C" GC_disable() annotation(Include="#include <gc.h>", Library = {"omcgc"});
60 end disable;
61
62 ✗ function free<T>
63 input T data;
64 external "C" omc_GC_free_ext(data) annotation(Include="
65 ✗ void omc_GC_free_ext(void *data)
66 {
67 /* */
68 ✗ GC_free(MMC_UNTAGPTR(data));
69 ✗ }
70 ",
71 Library = {"omcgc"}, Documentation(info="<html>
72 <p>GC_free requires \"a pointer to the base of an object\".</p>
73 <p>So the object passed to free must not be allocated by any of the list
74 routines that allocate multiple elements with a single malloc call.</p>
75 <p>Calling GCExt.free is very dangerous. You might be better off trying to
76 set variables to a constant value if you want to GC them. Use this if
77 you are concerned about temporary variables, etc remaining on the stack
78 and not cleared for a long time.</p>
79 </html>"));
80 end free;
81
82 607811 function expandHeap
83 input Real sz "To avoid the 32-bit signed limit on sizes";
84 output Boolean success;
85 external "C" success=GC_expand_hp_dbl(sz) annotation(Include="#define GC_expand_hp_dbl(sz) GC_expand_hp(sz)",Library = {"omcgc"});
86 end expandHeap;
87
88 140 function setFreeSpaceDivisor
89 input Integer divisor = 3;
90 external "C" GC_set_free_space_divisor(divisor) annotation(Include="#define GC_set_free_space_divisor_int(divisor) GC_set_free_space_divisor(divisor)",Library = {"omcgc"},Documentation(info="<html>
91 <p>NOTE: Do not set <3 as that seems to interfere with parallel threads.</p>
92 </html>"));
93 end setFreeSpaceDivisor;
94
95 ✗ function getForceUnmapOnGcollect
96 output Boolean res;
97 external "C" res=GC_get_force_unmap_on_gcollect() annotation(Include="#include <gc.h>", Library = {"omcgc"});
98 end getForceUnmapOnGcollect;
99
100 ✗ function setForceUnmapOnGcollect
101 input Boolean forceUnmap;
102 external "C" GC_set_force_unmap_on_gcollect(forceUnmap) annotation(Include="#include <gc.h>", Library = {"omcgc"});
103 end setForceUnmapOnGcollect;
104
105 2677 function setMaxHeapSize
106 input Real sz "To avoid the 32-bit signed limit on sizes";
107 external "C" GC_set_max_heap_size_dbl(sz) annotation(Include="#define GC_set_max_heap_size_dbl(sz) omc_GC_set_max_heap_size((size_t)sz)",Library = {"omcgc"});
108 end setMaxHeapSize;
109
110 uniontype ProfStats "TODO: Support regular records in the bootstrapped compiler to avoid allocation to return the stats in the GCExt..."
111 record PROFSTATS
112 Integer heapsize_full, free_bytes_full, unmapped_bytes, bytes_allocd_since_gc, allocd_bytes_before_gc, non_gc_bytes, gc_no, markers_m1, bytes_reclaimed_since_gc, reclaimed_bytes_before_gc;
113 end PROFSTATS;
114 end ProfStats;
115
116 function profStatsStr
117 input ProfStats stats;
118 input String head = "GC Profiling Stats: ";
119 input String delimiter = "\n ";
120 output String str;
121 algorithm
122 str := match stats
123 ✗ case PROFSTATS() then
124 head + delimiter +
125 "heapsize_full: " + intString(stats.heapsize_full) + delimiter +
126 "free_bytes_full: " + intString(stats.free_bytes_full) + delimiter +
127 "unmapped_bytes: " + intString(stats.unmapped_bytes) + delimiter +
128 "bytes_allocd_since_gc: " + intString(stats.bytes_allocd_since_gc) + delimiter +
129 "allocd_bytes_before_gc: " + intString(stats.allocd_bytes_before_gc) + delimiter +
130 "total_allocd_bytes: " + intString(stats.bytes_allocd_since_gc+stats.allocd_bytes_before_gc) + delimiter +
131 "non_gc_bytes: " + intString(stats.non_gc_bytes) + delimiter +
132 "gc_no: " + intString(stats.gc_no) + delimiter +
133 "markers_m1: " + intString(stats.markers_m1) + delimiter +
134 "bytes_reclaimed_since_gc: " + intString(stats.bytes_reclaimed_since_gc) + delimiter +
135 "reclaimed_bytes_before_gc: " + intString(stats.reclaimed_bytes_before_gc);
136 end match;
137 end profStatsStr;
138
139 function getProfStats
140 output ProfStats stats;
141 protected
142 Integer heapsize_full, free_bytes_full, unmapped_bytes, bytes_allocd_since_gc, allocd_bytes_before_gc, non_gc_bytes, gc_no, markers_m1, bytes_reclaimed_since_gc, reclaimed_bytes_before_gc;
143 protected
144 16070 function GC_get_prof_stats_modelica "Inner, dummy function to preserve the full integer sizes"
145 output tuple<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer> stats;
146 external "C" stats=GC_get_prof_stats_modelica()
147 annotation(Include="
148 8035 static inline modelica_metatype GC_get_prof_stats_modelica()
149 {
150 #if ((GC_VERSION_MAJOR == 7) && (GC_VERSION_MINOR >= 5)) || (GC_VERSION_MAJOR >= 8)
151 struct GC_prof_stats_s info;
152 8035 GC_get_prof_stats(&info,sizeof(struct GC_prof_stats_s));
153 16070 return mmc_mk_box10(
154 0,
155 8035 mmc_mk_icon(info.heapsize_full),
156 8035 mmc_mk_icon(info.free_bytes_full),
157 8035 mmc_mk_icon(info.unmapped_bytes),
158 8035 mmc_mk_icon(info.bytes_allocd_since_gc),
159 8035 mmc_mk_icon(info.allocd_bytes_before_gc),
160 8035 mmc_mk_icon(info.non_gc_bytes),
161 8035 mmc_mk_icon(info.gc_no),
162 8035 mmc_mk_icon(info.markers_m1),
163 8035 mmc_mk_icon(info.bytes_reclaimed_since_gc),
164 8035 mmc_mk_icon(info.reclaimed_bytes_before_gc));
165 #else /* GC_prof_stats_s NOT available */
166 return mmc_mk_box10(
167 0,
168 mmc_mk_icon(0),
169 mmc_mk_icon(0),
170 mmc_mk_icon(0),
171 mmc_mk_icon(0),
172 mmc_mk_icon(0),
173 mmc_mk_icon(0),
174 mmc_mk_icon(0),
175 mmc_mk_icon(0),
176 mmc_mk_icon(0),
177 mmc_mk_icon(0));
178 #endif
179 }
180
181 ",Library = {"omcgc"});
182 end GC_get_prof_stats_modelica;
183 algorithm
184 8035 (heapsize_full, free_bytes_full, unmapped_bytes, bytes_allocd_since_gc, allocd_bytes_before_gc, non_gc_bytes, gc_no, markers_m1, bytes_reclaimed_since_gc, reclaimed_bytes_before_gc) := GC_get_prof_stats_modelica();
185 8035 stats := PROFSTATS(heapsize_full, free_bytes_full, unmapped_bytes, bytes_allocd_since_gc, allocd_bytes_before_gc, non_gc_bytes, gc_no, markers_m1, bytes_reclaimed_since_gc, reclaimed_bytes_before_gc);
186 annotation(Documentation(info="<html>
187 <p>Query GC profiling information.</p>
188 </html>"));
189 end getProfStats;
190
191 annotation(__OpenModelica_Interface="util_datatypes_basic");
192 end GCExt;
193