Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 60.0% 3 / 0 / 5
Functions: 50.0% 2 / 1 / 5
Branches: -% 0 / 0 / 0

OMCompiler/Compiler/Util/MutableWeak.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 uniontype MutableWeak<T>
37 "A non-owning reference to a Mutable cell.
38
39 Breaks an ownership cycle so plain reference counting can reclaim it: a
40 child holds its parent weakly, the parent owns its children, and the whole
41 structure hangs off one strong root. Nothing here is reclaimed by a
42 collector — the point is that no collector is needed.
43
44 In the bootstrapped C compiler a weak reference *is* the strong one (Boehm
45 reclaims cycles by tracing, so there is nothing to break) and `upgrade` can
46 never fail. The Rust port gives it real weak semantics, and `upgrade` fails
47 if the referent is already gone. Only code that can hold a weak reference
48 past its owner's lifetime can observe the difference."
49
50 import Mutable;
51
52 15439893 impure function downgrade
53 "A reference that does not keep the cell alive. Never fails."
54 input Mutable<T> mutable;
55 output MutableWeak<T> weak;
56 external "C" weak=mutableWeakDowngrade(mutable) annotation(Include="
57 static inline void* mutableWeakDowngrade(void *mutable)
58 {
59 return mutable;
60 }
61 ");
62 end downgrade;
63
64 18578340 impure function upgrade
65 "An owning cell again. Fails if the referent is already gone — which means
66 a weak reference outlived the structure that owned it, so the ownership
67 split is wrong somewhere. Dereferencing a cell never fails; only this
68 conversion does."
69 input MutableWeak<T> weak;
70 output Mutable<T> mutable;
71 external "C" mutable=mutableWeakUpgrade(weak) annotation(Include="
72 static inline void* mutableWeakUpgrade(void *weak)
73 {
74 return weak;
75 }
76 ");
77 end upgrade;
78
79 3138447 impure function upgradeOwning
80 "As `upgrade`, for a read that takes ownership of the cell (`InstNode.
81 fromCell`, which then rebuilds the record to set its owner) rather than
82 merely looking at it (`InstNode.borrow`). Identical at run time; split out
83 so `OPENMODELICA_CELL_STATS` can tell the two apart, since only the owning
84 one pays for a record copy."
85 input MutableWeak<T> weak;
86 output Mutable<T> mutable;
87 external "C" mutable=mutableWeakUpgrade(weak) annotation(Include="
88 static inline void* mutableWeakUpgrade(void *weak)
89 {
90 return weak;
91 }
92 ");
93 end upgradeOwning;
94
95 ✗ impure function ofValue
96 "A handle that *is* the value. In the C compiler no cell is needed at all --
97 a weak reference there is the strong one -- so the node is stored directly
98 and `value` reads it straight back, which is what the frontend did before
99 any of this. Never reached where `GCExt.cellsNeedOwners` is true."
100 input T val;
101 output MutableWeak<T> weak;
102 external "C" weak=mutableWeakOfValue(val) annotation(Include="
103 static inline void* mutableWeakOfValue(void *val)
104 {
105 return val;
106 }
107 ");
108 end ofValue;
109
110 ✗ impure function value
111 "The value a handle made by `ofValue` holds."
112 input MutableWeak<T> weak;
113 output T val;
114 external "C" val=mutableWeakValue(weak) annotation(Include="
115 static inline void* mutableWeakValue(void *weak)
116 {
117 return weak;
118 }
119 ");
120 end value;
121
122 uniontype Roots
123 "The cells one structure keeps alive. Whatever owns that structure holds this
124 too, so the cells outlive every weak reference into it and die with it.
125 Empty in the C compiler, where a weak reference is the strong one."
126 record ROOTS end ROOTS;
127 end Roots;
128
129 function newRoots
130 "A fresh set, and the one `root` adds to from here on. The caller stores it
131 in whatever owns the cells about to be made."
132 output Roots roots = ROOTS();
133 end newRoots;
134
135 function useRoots
136 "Adds to `roots` again, for re-entering a structure built by an earlier run.
137 Inlined to nothing in the C compiler."
138 input Roots roots;
139 algorithm
140 annotation(__OpenModelica_EarlyInline = true);
141 end useRoots;
142
143 function root
144 "Adds a cell to the current set. Inlined to nothing in the C compiler, so the
145 call does not survive code generation."
146 input Mutable<T> mutable;
147 algorithm
148 annotation(__OpenModelica_EarlyInline = true);
149 end root;
150
151 function clearRoots
152 "Empties the current set. Its cells die with it, and a reference into them
153 outlives the tree by design, so only a caller that knows it is done with
154 them may do this. Inlined to nothing in the C compiler."
155 algorithm
156 annotation(__OpenModelica_EarlyInline = true);
157 end clearRoots;
158
159 annotation(__OpenModelica_Interface="util_datatypes_basic");
160 end MutableWeak;
161