annotate gcc/ada/libgnat/s-secsta.adb @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT COMPILER COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- S Y S T E M . S E C O N D A R Y _ S T A C K --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- B o d y --
kono
parents:
diff changeset
8 -- --
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
9 -- Copyright (C) 1992-2019, Free Software Foundation, Inc. --
111
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
12 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
kono
parents:
diff changeset
17 -- --
kono
parents:
diff changeset
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
kono
parents:
diff changeset
19 -- additional permissions described in the GCC Runtime Library Exception, --
kono
parents:
diff changeset
20 -- version 3.1, as published by the Free Software Foundation. --
kono
parents:
diff changeset
21 -- --
kono
parents:
diff changeset
22 -- You should have received a copy of the GNU General Public License and --
kono
parents:
diff changeset
23 -- a copy of the GCC Runtime Library Exception along with this program; --
kono
parents:
diff changeset
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
kono
parents:
diff changeset
25 -- <http://www.gnu.org/licenses/>. --
kono
parents:
diff changeset
26 -- --
kono
parents:
diff changeset
27 -- GNAT was originally developed by the GNAT team at New York University. --
kono
parents:
diff changeset
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
kono
parents:
diff changeset
29 -- --
kono
parents:
diff changeset
30 ------------------------------------------------------------------------------
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 pragma Compiler_Unit_Warning;
kono
parents:
diff changeset
33
kono
parents:
diff changeset
34 with Ada.Unchecked_Conversion;
kono
parents:
diff changeset
35 with Ada.Unchecked_Deallocation;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
36
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
37 with System; use System;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
38 with System.Parameters; use System.Parameters;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
39 with System.Soft_Links; use System.Soft_Links;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
40 with System.Storage_Elements; use System.Storage_Elements;
111
kono
parents:
diff changeset
41
kono
parents:
diff changeset
42 package body System.Secondary_Stack is
kono
parents:
diff changeset
43
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
44 ------------------------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
45 -- Binder Allocated Stack Support --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
46 ------------------------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
47
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
48 -- When at least one of the following restrictions
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
49 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
50 -- No_Implicit_Heap_Allocations
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
51 -- No_Implicit_Task_Allocations
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
52 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
53 -- is in effect, the binder creates a static secondary stack pool, where
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
54 -- each stack has a default size. Assignment of these stacks to tasks is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
55 -- performed by SS_Init. The following variables are defined in this unit
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
56 -- in order to avoid depending on the binder. Their values are set by the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
57 -- binder.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
58
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
59 Binder_SS_Count : Natural;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
60 pragma Export (Ada, Binder_SS_Count, "__gnat_binder_ss_count");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
61 -- The number of secondary stacks in the pool created by the binder
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
62
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
63 Binder_Default_SS_Size : Size_Type;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
64 pragma Export (Ada, Binder_Default_SS_Size, "__gnat_default_ss_size");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
65 -- The default secondary stack size as specified by the binder. The value
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
66 -- is defined here rather than in init.c or System.Init because the ZFP and
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
67 -- Ravenscar-ZFP run-times lack these locations.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
68
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
69 Binder_Default_SS_Pool : Address;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
70 pragma Export (Ada, Binder_Default_SS_Pool, "__gnat_default_ss_pool");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
71 -- The address of the secondary stack pool created by the binder
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
72
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
73 Binder_Default_SS_Pool_Index : Natural := 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
74 -- Index into the secondary stack pool created by the binder
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
75
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
76 -----------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
77 -- Local subprograms --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
78 -----------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
79
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
80 procedure Allocate_Dynamic
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
81 (Stack : SS_Stack_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
82 Mem_Size : Memory_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
83 Addr : out Address);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
84 pragma Inline (Allocate_Dynamic);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
85 -- Allocate enough space on dynamic secondary stack Stack to fit a request
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
86 -- of size Mem_Size. Addr denotes the address of the first byte of the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
87 -- allocation.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
88
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
89 procedure Allocate_On_Chunk
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
90 (Stack : SS_Stack_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
91 Prev_Chunk : SS_Chunk_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
92 Chunk : SS_Chunk_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
93 Byte : Memory_Index;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
94 Mem_Size : Memory_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
95 Addr : out Address);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
96 pragma Inline (Allocate_On_Chunk);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
97 -- Allocate enough space on chunk Chunk to fit a request of size Mem_Size.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
98 -- Stack is the owner of the allocation Chunk. Prev_Chunk is the preceding
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
99 -- chunk of Chunk. Byte indicates the first free byte within Chunk. Addr
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
100 -- denotes the address of the first byte of the allocation. This routine
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
101 -- updates the state of Stack.all to reflect the side effects of the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
102 -- allocation.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
103
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
104 procedure Allocate_Static
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
105 (Stack : SS_Stack_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
106 Mem_Size : Memory_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
107 Addr : out Address);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
108 pragma Inline (Allocate_Static);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
109 -- Allocate enough space on static secondary stack Stack to fit a request
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
110 -- of size Mem_Size. Addr denotes the address of the first byte of the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
111 -- allocation.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
112
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
113 procedure Free is new Ada.Unchecked_Deallocation (SS_Chunk, SS_Chunk_Ptr);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
114 -- Free a dynamically allocated chunk
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
115
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
116 procedure Free is new Ada.Unchecked_Deallocation (SS_Stack, SS_Stack_Ptr);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
117 -- Free a dynamically allocated secondary stack
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
118
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
119 function Has_Enough_Free_Memory
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
120 (Chunk : SS_Chunk_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
121 Byte : Memory_Index;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
122 Mem_Size : Memory_Size) return Boolean;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
123 pragma Inline (Has_Enough_Free_Memory);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
124 -- Determine whether chunk Chunk has enough room to fit a memory request of
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
125 -- size Mem_Size, starting from the first free byte of the chunk denoted by
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
126 -- Byte.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
127
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
128 function Number_Of_Chunks (Stack : SS_Stack_Ptr) return Chunk_Count;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
129 pragma Inline (Number_Of_Chunks);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
130 -- Count the number of static and dynamic chunks of secondary stack Stack
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
132 function Size_Up_To_And_Including (Chunk : SS_Chunk_Ptr) return Memory_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
133 pragma Inline (Size_Up_To_And_Including);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
134 -- Calculate the size of secondary stack which houses chunk Chunk, from the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
135 -- start of the secondary stack up to and including Chunk itself. The size
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
136 -- includes the following kinds of memory:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
137 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
138 -- * Free memory in used chunks due to alignment holes
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
139 -- * Occupied memory by allocations
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
140 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
141 -- This is a constant time operation, regardless of the secondary stack's
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
142 -- nature.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
143
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
144 function Top_Chunk_Id (Stack : SS_Stack_Ptr) return Chunk_Id_With_Invalid;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
145 pragma Inline (Top_Chunk_Id);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
146 -- Obtain the Chunk_Id of the chunk indicated by secondary stack Stack's
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
147 -- pointer.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
148
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
149 function Used_Memory_Size (Stack : SS_Stack_Ptr) return Memory_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
150 pragma Inline (Used_Memory_Size);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
151 -- Calculate the size of stack Stack's occupied memory usage. This includes
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
152 -- the following kinds of memory:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
153 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
154 -- * Free memory in used chunks due to alignment holes
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
155 -- * Occupied memory by allocations
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
156 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
157 -- This is a constant time operation, regardless of the secondary stack's
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
158 -- nature.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
159
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
160 ----------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
161 -- Allocate_Dynamic --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
162 ----------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
163
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
164 procedure Allocate_Dynamic
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
165 (Stack : SS_Stack_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
166 Mem_Size : Memory_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
167 Addr : out Address)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
168 is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
169 function Allocate_New_Chunk return SS_Chunk_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
170 pragma Inline (Allocate_New_Chunk);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
171 -- Create a new chunk which is big enough to fit a request of size
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
172 -- Mem_Size.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
173
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
174 ------------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
175 -- Allocate_New_Chunk --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
176 ------------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
177
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
178 function Allocate_New_Chunk return SS_Chunk_Ptr is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
179 Chunk_Size : Memory_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
180
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
181 begin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
182 -- The size of the new chunk must fit the memory request precisely.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
183 -- In the case where the memory request is way too small, use the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
184 -- default chunk size. This avoids creating multiple tiny chunks.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
185
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
186 Chunk_Size := Mem_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
187
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
188 if Chunk_Size < Stack.Default_Chunk_Size then
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
189 Chunk_Size := Stack.Default_Chunk_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
190 end if;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
191
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
192 return new SS_Chunk (Chunk_Size);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
193
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
194 -- The creation of the new chunk may exhaust the heap. Raise a new
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
195 -- Storage_Error to indicate that the secondary stack is exhausted
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
196 -- as well.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
197
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
198 exception
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
199 when Storage_Error =>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
200 raise Storage_Error with "secondary stack exhausted";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
201 end Allocate_New_Chunk;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
202
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
203 -- Local variables
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
204
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
205 Next_Chunk : SS_Chunk_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
206
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
207 -- Start of processing for Allocate_Dynamic
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
208
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
209 begin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
210 -- Determine whether the chunk indicated by the stack pointer is big
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
211 -- enough to fit the memory request and if it is, allocate on it.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
212
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
213 if Has_Enough_Free_Memory
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
214 (Chunk => Stack.Top.Chunk,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
215 Byte => Stack.Top.Byte,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
216 Mem_Size => Mem_Size)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
217 then
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
218 Allocate_On_Chunk
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
219 (Stack => Stack,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
220 Prev_Chunk => null,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
221 Chunk => Stack.Top.Chunk,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
222 Byte => Stack.Top.Byte,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
223 Mem_Size => Mem_Size,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
224 Addr => Addr);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
225
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
226 return;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
227 end if;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
228
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
229 -- At this point it is known that the chunk indicated by the stack
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
230 -- pointer is not big enough to fit the memory request. Examine all
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
231 -- subsequent chunks, and apply the following criteria:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
232 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
233 -- * If the current chunk is too small, free it
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
234 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
235 -- * If the current chunk is big enough, allocate on it
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
236 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
237 -- This ensures that no space is wasted. The process is costly, however
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
238 -- allocation is costly in general. Paying the price here keeps routines
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
239 -- SS_Mark and SS_Release cheap.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
240
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
241 while Stack.Top.Chunk.Next /= null loop
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
242
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
243 -- The current chunk is big enough to fit the memory request,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
244 -- allocate on it.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
245
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
246 if Has_Enough_Free_Memory
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
247 (Chunk => Stack.Top.Chunk.Next,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
248 Byte => Stack.Top.Chunk.Next.Memory'First,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
249 Mem_Size => Mem_Size)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
250 then
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
251 Allocate_On_Chunk
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
252 (Stack => Stack,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
253 Prev_Chunk => Stack.Top.Chunk,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
254 Chunk => Stack.Top.Chunk.Next,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
255 Byte => Stack.Top.Chunk.Next.Memory'First,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
256 Mem_Size => Mem_Size,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
257 Addr => Addr);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
258
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
259 return;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
260
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
261 -- Otherwise the chunk is too small, free it
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
262
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
263 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
264 Next_Chunk := Stack.Top.Chunk.Next.Next;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
265
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
266 -- Unchain the chunk from the stack. This keeps the next candidate
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
267 -- chunk situated immediately after Top.Chunk.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
268 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
269 -- Top.Chunk Top.Chunk.Next Top.Chunk.Next.Next
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
270 -- | | (Next_Chunk)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
271 -- v v v
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
272 -- +-------+ +------------+ +--------------+
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
273 -- | | --> | | --> | |
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
274 -- +-------+ +------------+ +--------------+
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
275 -- to be freed
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
276
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
277 Free (Stack.Top.Chunk.Next);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
278 Stack.Top.Chunk.Next := Next_Chunk;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
279 end if;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
280 end loop;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
281
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
282 -- At this point one of the following outcomes took place:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
283 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
284 -- * Top.Chunk is the last chunk in the stack
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
285 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
286 -- * Top.Chunk was not the last chunk originally. It was followed by
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
287 -- chunks which were too small and as a result were deleted, thus
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
288 -- making Top.Chunk the last chunk in the stack.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
289 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
290 -- Either way, nothing should be hanging off the chunk indicated by the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
291 -- stack pointer.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
292
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
293 pragma Assert (Stack.Top.Chunk.Next = null);
111
kono
parents:
diff changeset
294
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
295 -- Create a new chunk big enough to fit the memory request, and allocate
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
296 -- on it.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
297
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
298 Stack.Top.Chunk.Next := Allocate_New_Chunk;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
299
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
300 Allocate_On_Chunk
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
301 (Stack => Stack,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
302 Prev_Chunk => Stack.Top.Chunk,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
303 Chunk => Stack.Top.Chunk.Next,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
304 Byte => Stack.Top.Chunk.Next.Memory'First,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
305 Mem_Size => Mem_Size,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
306 Addr => Addr);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
307 end Allocate_Dynamic;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
308
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
309 -----------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
310 -- Allocate_On_Chunk --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
311 -----------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
312
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
313 procedure Allocate_On_Chunk
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
314 (Stack : SS_Stack_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
315 Prev_Chunk : SS_Chunk_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
316 Chunk : SS_Chunk_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
317 Byte : Memory_Index;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
318 Mem_Size : Memory_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
319 Addr : out Address)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
320 is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
321 New_High_Water_Mark : Memory_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
322
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
323 begin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
324 -- The allocation occurs on a reused or a brand new chunk. Such a chunk
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
325 -- must always be connected to some previous chunk.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
326
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
327 if Prev_Chunk /= null then
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
328 pragma Assert (Prev_Chunk.Next = Chunk);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
329
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
330 -- Update the Size_Up_To_Chunk because this value is invalidated for
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
331 -- reused and new chunks.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
332 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
333 -- Prev_Chunk Chunk
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
334 -- v v
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
335 -- . . . . . . . +--------------+ +--------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
336 -- . --> |##############| --> |
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
337 -- . . . . . . . +--------------+ +--------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
338 -- | |
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
339 -- -------------------+------------+
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
340 -- Size_Up_To_Chunk Size
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
341 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
342 -- The Size_Up_To_Chunk is equal to the size of the whole stack up to
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
343 -- the previous chunk, plus the size of the previous chunk itself.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
344
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
345 Chunk.Size_Up_To_Chunk := Size_Up_To_And_Including (Prev_Chunk);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
346 end if;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
347
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
348 -- The chunk must have enough room to fit the memory request. If this is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
349 -- not the case, then a previous step picked the wrong chunk.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
350
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
351 pragma Assert (Has_Enough_Free_Memory (Chunk, Byte, Mem_Size));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
352
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
353 -- The first byte of the allocation is the first free byte within the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
354 -- chunk.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
355
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
356 Addr := Chunk.Memory (Byte)'Address;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
357
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
358 -- The chunk becomes the chunk indicated by the stack pointer. This is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
359 -- either the currently indicated chunk, an existing chunk, or a brand
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
360 -- new chunk.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
361
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
362 Stack.Top.Chunk := Chunk;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
363
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
364 -- The next free byte is immediately after the memory request
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
365 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
366 -- Addr Top.Byte
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
367 -- | |
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
368 -- +-----|--------|----+
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
369 -- |##############| |
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
370 -- +-------------------+
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
371
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
372 -- ??? this calculation may overflow on 32bit targets
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
373
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
374 Stack.Top.Byte := Byte + Mem_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
375
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
376 -- At this point the next free byte cannot go beyond the memory capacity
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
377 -- of the chunk indicated by the stack pointer, except when the chunk is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
378 -- full, in which case it indicates the byte beyond the chunk. Ensure
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
379 -- that the occupied memory is at most as much as the capacity of the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
380 -- chunk. Top.Byte - 1 denotes the last occupied byte.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
381
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
382 pragma Assert (Stack.Top.Byte - 1 <= Stack.Top.Chunk.Size);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
383
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
384 -- Calculate the new high water mark now that the memory request has
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
385 -- been fulfilled, and update if necessary. The new high water mark is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
386 -- technically the size of the used memory by the whole stack.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
387
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
388 New_High_Water_Mark := Used_Memory_Size (Stack);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
389
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
390 if New_High_Water_Mark > Stack.High_Water_Mark then
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
391 Stack.High_Water_Mark := New_High_Water_Mark;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
392 end if;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
393 end Allocate_On_Chunk;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
394
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
395 ---------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
396 -- Allocate_Static --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
397 ---------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
398
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
399 procedure Allocate_Static
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
400 (Stack : SS_Stack_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
401 Mem_Size : Memory_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
402 Addr : out Address)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
403 is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
404 begin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
405 -- Static secondary stack allocations are performed only on the static
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
406 -- chunk. There should be no dynamic chunks following the static chunk.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
407
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
408 pragma Assert (Stack.Top.Chunk = Stack.Static_Chunk'Access);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
409 pragma Assert (Stack.Top.Chunk.Next = null);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
410
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
411 -- Raise Storage_Error if the static chunk does not have enough room to
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
412 -- fit the memory request. This indicates that the stack is about to be
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
413 -- depleted.
111
kono
parents:
diff changeset
414
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
415 if not Has_Enough_Free_Memory
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
416 (Chunk => Stack.Top.Chunk,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
417 Byte => Stack.Top.Byte,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
418 Mem_Size => Mem_Size)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
419 then
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
420 raise Storage_Error with "secondary stack exhaused";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
421 end if;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
422
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
423 Allocate_On_Chunk
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
424 (Stack => Stack,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
425 Prev_Chunk => null,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
426 Chunk => Stack.Top.Chunk,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
427 Byte => Stack.Top.Byte,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
428 Mem_Size => Mem_Size,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
429 Addr => Addr);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
430 end Allocate_Static;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
431
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
432 --------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
433 -- Get_Chunk_Info --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
434 --------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
435
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
436 function Get_Chunk_Info
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
437 (Stack : SS_Stack_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
438 C_Id : Chunk_Id) return Chunk_Info
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
439 is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
440 function Find_Chunk return SS_Chunk_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
441 pragma Inline (Find_Chunk);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
442 -- Find the chunk which corresponds to Id. Return null if no such chunk
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
443 -- exists.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
444
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
445 ----------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
446 -- Find_Chunk --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
447 ----------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
448
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
449 function Find_Chunk return SS_Chunk_Ptr is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
450 Chunk : SS_Chunk_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
451 Id : Chunk_Id;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
452
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
453 begin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
454 Chunk := Stack.Static_Chunk'Access;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
455 Id := 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
456 while Chunk /= null loop
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
457 if Id = C_Id then
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
458 return Chunk;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
459 end if;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
460
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
461 Chunk := Chunk.Next;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
462 Id := Id + 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
463 end loop;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
464
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
465 return null;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
466 end Find_Chunk;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
467
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
468 -- Local variables
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
469
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
470 Chunk : constant SS_Chunk_Ptr := Find_Chunk;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
471
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
472 -- Start of processing for Get_Chunk_Info
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
473
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
474 begin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
475 if Chunk = null then
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
476 return Invalid_Chunk;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
477
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
478 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
479 return (Size => Chunk.Size,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
480 Size_Up_To_Chunk => Chunk.Size_Up_To_Chunk);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
481 end if;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
482 end Get_Chunk_Info;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
483
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
484 --------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
485 -- Get_Stack_Info --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
486 --------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
487
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
488 function Get_Stack_Info (Stack : SS_Stack_Ptr) return Stack_Info is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
489 Info : Stack_Info;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
490
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
491 begin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
492 Info.Default_Chunk_Size := Stack.Default_Chunk_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
493 Info.Freeable := Stack.Freeable;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
494 Info.High_Water_Mark := Stack.High_Water_Mark;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
495 Info.Number_Of_Chunks := Number_Of_Chunks (Stack);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
496 Info.Top.Byte := Stack.Top.Byte;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
497 Info.Top.Chunk := Top_Chunk_Id (Stack);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
498
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
499 return Info;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
500 end Get_Stack_Info;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
501
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
502 ----------------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
503 -- Has_Enough_Free_Memory --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
504 ----------------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
505
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
506 function Has_Enough_Free_Memory
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
507 (Chunk : SS_Chunk_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
508 Byte : Memory_Index;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
509 Mem_Size : Memory_Size) return Boolean
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
510 is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
511 begin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
512 -- Byte - 1 denotes the last occupied byte. Subtracting that byte from
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
513 -- the memory capacity of the chunk yields the size of the free memory
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
514 -- within the chunk. The chunk can fit the request as long as the free
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
515 -- memory is as big as the request.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
516
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
517 return Chunk.Size - (Byte - 1) >= Mem_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
518 end Has_Enough_Free_Memory;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
519
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
520 ----------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
521 -- Number_Of_Chunks --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
522 ----------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
523
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
524 function Number_Of_Chunks (Stack : SS_Stack_Ptr) return Chunk_Count is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
525 Chunk : SS_Chunk_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
526 Count : Chunk_Count;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
527
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
528 begin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
529 Chunk := Stack.Static_Chunk'Access;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
530 Count := 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
531 while Chunk /= null loop
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
532 Chunk := Chunk.Next;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
533 Count := Count + 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
534 end loop;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
535
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
536 return Count;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
537 end Number_Of_Chunks;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
538
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
539 ------------------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
540 -- Size_Up_To_And_Including --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
541 ------------------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
542
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
543 function Size_Up_To_And_Including
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
544 (Chunk : SS_Chunk_Ptr) return Memory_Size
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
545 is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
546 begin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
547 return Chunk.Size_Up_To_Chunk + Chunk.Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
548 end Size_Up_To_And_Including;
111
kono
parents:
diff changeset
549
kono
parents:
diff changeset
550 -----------------
kono
parents:
diff changeset
551 -- SS_Allocate --
kono
parents:
diff changeset
552 -----------------
kono
parents:
diff changeset
553
kono
parents:
diff changeset
554 procedure SS_Allocate
kono
parents:
diff changeset
555 (Addr : out Address;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
556 Storage_Size : Storage_Count)
111
kono
parents:
diff changeset
557 is
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
558 function Round_Up (Size : Storage_Count) return Memory_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
559 pragma Inline (Round_Up);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
560 -- Round Size up to the nearest multiple of the maximum alignment
111
kono
parents:
diff changeset
561
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
562 --------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
563 -- Round_Up --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
564 --------------
111
kono
parents:
diff changeset
565
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
566 function Round_Up (Size : Storage_Count) return Memory_Size is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
567 Algn_MS : constant Memory_Size := Standard'Maximum_Alignment;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
568 Size_MS : constant Memory_Size := Memory_Size (Size);
111
kono
parents:
diff changeset
569
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
570 begin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
571 -- Detect a case where the Storage_Size is very large and may yield
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
572 -- a rounded result which is outside the range of Chunk_Memory_Size.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
573 -- Treat this case as secondary-stack depletion.
111
kono
parents:
diff changeset
574
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
575 if Memory_Size'Last - Algn_MS < Size_MS then
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
576 raise Storage_Error with "secondary stack exhaused";
111
kono
parents:
diff changeset
577 end if;
kono
parents:
diff changeset
578
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
579 return ((Size_MS + Algn_MS - 1) / Algn_MS) * Algn_MS;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
580 end Round_Up;
111
kono
parents:
diff changeset
581
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
582 -- Local variables
111
kono
parents:
diff changeset
583
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
584 Stack : constant SS_Stack_Ptr := Get_Sec_Stack.all;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
585 Mem_Size : Memory_Size;
111
kono
parents:
diff changeset
586
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
587 -- Start of processing for SS_Allocate
111
kono
parents:
diff changeset
588
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
589 begin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
590 -- It should not be possible to request an allocation of negative or
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
591 -- zero size.
111
kono
parents:
diff changeset
592
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
593 pragma Assert (Storage_Size > 0);
111
kono
parents:
diff changeset
594
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
595 -- Round the requested size up to the nearest multiple of the maximum
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
596 -- alignment to ensure efficient access.
111
kono
parents:
diff changeset
597
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
598 Mem_Size := Round_Up (Storage_Size);
111
kono
parents:
diff changeset
599
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
600 if Sec_Stack_Dynamic then
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
601 Allocate_Dynamic (Stack, Mem_Size, Addr);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
602 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
603 Allocate_Static (Stack, Mem_Size, Addr);
111
kono
parents:
diff changeset
604 end if;
kono
parents:
diff changeset
605 end SS_Allocate;
kono
parents:
diff changeset
606
kono
parents:
diff changeset
607 -------------
kono
parents:
diff changeset
608 -- SS_Free --
kono
parents:
diff changeset
609 -------------
kono
parents:
diff changeset
610
kono
parents:
diff changeset
611 procedure SS_Free (Stack : in out SS_Stack_Ptr) is
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
612 Static_Chunk : constant SS_Chunk_Ptr := Stack.Static_Chunk'Access;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
613 Next_Chunk : SS_Chunk_Ptr;
111
kono
parents:
diff changeset
614
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
615 begin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
616 -- Free all dynamically allocated chunks. The first dynamic chunk is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
617 -- found immediately after the static chunk of the stack.
111
kono
parents:
diff changeset
618
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
619 while Static_Chunk.Next /= null loop
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
620 Next_Chunk := Static_Chunk.Next.Next;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
621 Free (Static_Chunk.Next);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
622 Static_Chunk.Next := Next_Chunk;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
623 end loop;
111
kono
parents:
diff changeset
624
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
625 -- At this point one of the following outcomes has taken place:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
626 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
627 -- * The stack lacks any dynamic chunks
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
628 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
629 -- * The stack had dynamic chunks which were all freed
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
630 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
631 -- Either way, there should be nothing hanging off the static chunk
111
kono
parents:
diff changeset
632
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
633 pragma Assert (Static_Chunk.Next = null);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
634
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
635 -- Free the stack only when it was dynamically allocated
111
kono
parents:
diff changeset
636
kono
parents:
diff changeset
637 if Stack.Freeable then
kono
parents:
diff changeset
638 Free (Stack);
kono
parents:
diff changeset
639 end if;
kono
parents:
diff changeset
640 end SS_Free;
kono
parents:
diff changeset
641
kono
parents:
diff changeset
642 ----------------
kono
parents:
diff changeset
643 -- SS_Get_Max --
kono
parents:
diff changeset
644 ----------------
kono
parents:
diff changeset
645
kono
parents:
diff changeset
646 function SS_Get_Max return Long_Long_Integer is
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
647 Stack : constant SS_Stack_Ptr := Get_Sec_Stack.all;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
648
111
kono
parents:
diff changeset
649 begin
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
650 return Long_Long_Integer (Stack.High_Water_Mark);
111
kono
parents:
diff changeset
651 end SS_Get_Max;
kono
parents:
diff changeset
652
kono
parents:
diff changeset
653 -------------
kono
parents:
diff changeset
654 -- SS_Info --
kono
parents:
diff changeset
655 -------------
kono
parents:
diff changeset
656
kono
parents:
diff changeset
657 procedure SS_Info is
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
658 procedure SS_Info_Dynamic (Stack : SS_Stack_Ptr);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
659 pragma Inline (SS_Info_Dynamic);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
660 -- Output relevant information concerning dynamic secondary stack Stack
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
661
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
662 function Total_Memory_Size (Stack : SS_Stack_Ptr) return Memory_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
663 pragma Inline (Total_Memory_Size);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
664 -- Calculate the size of stack Stack's total memory usage. This includes
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
665 -- the following kinds of memory:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
666 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
667 -- * Free memory in used chunks due to alignment holes
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
668 -- * Free memory in the topmost chunk due to partial usage
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
669 -- * Free memory in unused chunks following the chunk indicated by the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
670 -- stack pointer.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
671 -- * Memory occupied by allocations
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
672 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
673 -- This is a linear-time operation on the number of chunks.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
674
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
675 ---------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
676 -- SS_Info_Dynamic --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
677 ---------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
678
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
679 procedure SS_Info_Dynamic (Stack : SS_Stack_Ptr) is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
680 begin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
681 Put_Line
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
682 (" Number of Chunks : " & Number_Of_Chunks (Stack)'Img);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
683
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
684 Put_Line
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
685 (" Default size of Chunks : " & Stack.Default_Chunk_Size'Img);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
686 end SS_Info_Dynamic;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
687
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
688 -----------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
689 -- Total_Memory_Size --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
690 -----------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
691
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
692 function Total_Memory_Size (Stack : SS_Stack_Ptr) return Memory_Size is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
693 Chunk : SS_Chunk_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
694 Total : Memory_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
695
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
696 begin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
697 -- The total size of the stack is equal to the size of the stack up
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
698 -- to the chunk indicated by the stack pointer, plus the size of the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
699 -- indicated chunk, plus the size of any subsequent chunks.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
700
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
701 Total := Size_Up_To_And_Including (Stack.Top.Chunk);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
702
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
703 Chunk := Stack.Top.Chunk.Next;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
704 while Chunk /= null loop
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
705 Total := Total + Chunk.Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
706 Chunk := Chunk.Next;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
707 end loop;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
708
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
709 return Total;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
710 end Total_Memory_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
711
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
712 -- Local variables
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
713
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
714 Stack : constant SS_Stack_Ptr := Get_Sec_Stack.all;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
715
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
716 -- Start of processing for SS_Info
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
717
111
kono
parents:
diff changeset
718 begin
kono
parents:
diff changeset
719 Put_Line ("Secondary Stack information:");
kono
parents:
diff changeset
720
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
721 Put_Line
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
722 (" Total size : "
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
723 & Total_Memory_Size (Stack)'Img
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
724 & " bytes");
111
kono
parents:
diff changeset
725
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
726 Put_Line
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
727 (" Current allocated space : "
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
728 & Used_Memory_Size (Stack)'Img
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
729 & " bytes");
111
kono
parents:
diff changeset
730
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
731 if Sec_Stack_Dynamic then
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
732 SS_Info_Dynamic (Stack);
111
kono
parents:
diff changeset
733 end if;
kono
parents:
diff changeset
734 end SS_Info;
kono
parents:
diff changeset
735
kono
parents:
diff changeset
736 -------------
kono
parents:
diff changeset
737 -- SS_Init --
kono
parents:
diff changeset
738 -------------
kono
parents:
diff changeset
739
kono
parents:
diff changeset
740 procedure SS_Init
kono
parents:
diff changeset
741 (Stack : in out SS_Stack_Ptr;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
742 Size : Size_Type := Unspecified_Size)
111
kono
parents:
diff changeset
743 is
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
744 function Next_Available_Binder_Sec_Stack return SS_Stack_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
745 pragma Inline (Next_Available_Binder_Sec_Stack);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
746 -- Return a pointer to the next available stack from the pool created by
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
747 -- the binder. This routine updates global Default_Sec_Stack_Pool_Index.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
748
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
749 -------------------------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
750 -- Next_Available_Binder_Sec_Stack --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
751 -------------------------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
752
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
753 function Next_Available_Binder_Sec_Stack return SS_Stack_Ptr is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
754
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
755 -- The default-sized secondary stack pool generated by the binder
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
756 -- is passed to this unit as an Address because it is not possible
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
757 -- to define a pointer to an array of unconstrained components. The
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
758 -- pointer is instead obtained using an unchecked conversion to a
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
759 -- constrained array of secondary stacks with the same size as that
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
760 -- specified by the binder.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
761
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
762 -- WARNING: The following data structure must be synchronized with
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
763 -- the one created in Bindgen.Gen_Output_File_Ada. The version in
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
764 -- bindgen is called Sec_Default_Sized_Stacks.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
765
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
766 type SS_Pool is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
767 array (1 .. Binder_SS_Count)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
768 of aliased SS_Stack (Binder_Default_SS_Size);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
769
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
770 type SS_Pool_Ptr is access SS_Pool;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
771 -- A reference to the secondary stack pool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
772
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
773 function To_SS_Pool_Ptr is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
774 new Ada.Unchecked_Conversion (Address, SS_Pool_Ptr);
111
kono
parents:
diff changeset
775
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
776 -- Use an unchecked conversion to obtain a pointer to one of the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
777 -- secondary stacks from the pool generated by the binder. There
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
778 -- are several reasons for using the conversion:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
779 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
780 -- * Accessibility checks prevent a value of a local pointer to be
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
781 -- stored outside this scope. The conversion is safe because the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
782 -- pool is global to the whole application.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
783 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
784 -- * Unchecked_Access may circumvent the accessibility checks, but
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
785 -- it is incompatible with restriction No_Unchecked_Access.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
786 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
787 -- * Unrestricted_Access may circumvent the accessibility checks,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
788 -- but it is incompatible with pure Ada constructs.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
789 -- ??? cannot find the restriction or switch
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
790
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
791 pragma Warnings (Off);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
792 function To_SS_Stack_Ptr is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
793 new Ada.Unchecked_Conversion (Address, SS_Stack_Ptr);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
794 pragma Warnings (On);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
795
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
796 Pool : SS_Pool_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
797
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
798 begin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
799 -- Obtain a typed view of the pool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
800
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
801 Pool := To_SS_Pool_Ptr (Binder_Default_SS_Pool);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
802
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
803 -- Advance the stack index to the next available stack
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
804
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
805 Binder_Default_SS_Pool_Index := Binder_Default_SS_Pool_Index + 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
806
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
807 -- Return a pointer to the next available stack
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
808
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
809 return To_SS_Stack_Ptr (Pool (Binder_Default_SS_Pool_Index)'Address);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
810 end Next_Available_Binder_Sec_Stack;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
811
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
812 -- Local variables
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
813
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
814 Stack_Size : Memory_Size_With_Invalid;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
815
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
816 -- Start of processing for SS_Init
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
817
111
kono
parents:
diff changeset
818 begin
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
819 -- Allocate a new stack on the heap or use one from the pool created by
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
820 -- the binder.
111
kono
parents:
diff changeset
821
kono
parents:
diff changeset
822 if Stack = null then
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
823
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
824 -- The caller requested a pool-allocated stack. Determine the proper
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
825 -- size of the stack based on input from the binder or the runtime in
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
826 -- case the pool is exhausted.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
827
111
kono
parents:
diff changeset
828 if Size = Unspecified_Size then
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
829
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
830 -- Use the default secondary stack size as specified by the binder
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
831 -- only when it has been set. This prevents a bootstrap issue with
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
832 -- older compilers where the size is never set.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
833
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
834 if Binder_Default_SS_Size > 0 then
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
835 Stack_Size := Binder_Default_SS_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
836
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
837 -- Otherwise use the default stack size of the particular runtime
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
838
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
839 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
840 Stack_Size := Runtime_Default_Sec_Stack_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
841 end if;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
842
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
843 -- Otherwise the caller requested a heap-allocated stack. Use the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
844 -- specified size directly.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
845
111
kono
parents:
diff changeset
846 else
kono
parents:
diff changeset
847 Stack_Size := Size;
kono
parents:
diff changeset
848 end if;
kono
parents:
diff changeset
849
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
850 -- The caller requested a pool-allocated stack. Use one as long as
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
851 -- the pool created by the binder has available stacks. This stack
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
852 -- cannot be deallocated.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
853
111
kono
parents:
diff changeset
854 if Size = Unspecified_Size
kono
parents:
diff changeset
855 and then Binder_SS_Count > 0
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
856 and then Binder_Default_SS_Pool_Index < Binder_SS_Count
111
kono
parents:
diff changeset
857 then
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
858 Stack := Next_Available_Binder_Sec_Stack;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
859 Stack.Freeable := False;
111
kono
parents:
diff changeset
860
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
861 -- Otherwise the caller requested a heap-allocated stack, or the pool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
862 -- created by the binder ran out of available stacks. This stack can
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
863 -- be deallocated.
111
kono
parents:
diff changeset
864
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
865 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
866 -- It should not be possible to create a stack with a negative
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
867 -- default chunk size.
111
kono
parents:
diff changeset
868
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
869 pragma Assert (Stack_Size in Memory_Size);
111
kono
parents:
diff changeset
870
kono
parents:
diff changeset
871 Stack := new SS_Stack (Stack_Size);
kono
parents:
diff changeset
872 Stack.Freeable := True;
kono
parents:
diff changeset
873 end if;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
874
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
875 -- Otherwise the stack was already created either by the compiler or by
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
876 -- the user, and is about to be reused.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
877
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
878 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
879 null;
111
kono
parents:
diff changeset
880 end if;
kono
parents:
diff changeset
881
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
882 -- The static chunk becomes the chunk indicated by the stack pointer.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
883 -- Note that the stack may still hold dynamic chunks, which in turn may
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
884 -- be reused or freed.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
885
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
886 Stack.Top.Chunk := Stack.Static_Chunk'Access;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
887
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
888 -- The first free byte is the first free byte of the chunk indicated by
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
889 -- the stack pointer.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
890
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
891 Stack.Top.Byte := Stack.Top.Chunk.Memory'First;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
892
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
893 -- Since the chunk indicated by the stack pointer is also the first
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
894 -- chunk in the stack, there are no prior chunks, therefore the size
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
895 -- of the stack up to the chunk is zero.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
896
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
897 Stack.Top.Chunk.Size_Up_To_Chunk := 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
898
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
899 -- Reset the high water mark to account for brand new allocations
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
900
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
901 Stack.High_Water_Mark := 0;
111
kono
parents:
diff changeset
902 end SS_Init;
kono
parents:
diff changeset
903
kono
parents:
diff changeset
904 -------------
kono
parents:
diff changeset
905 -- SS_Mark --
kono
parents:
diff changeset
906 -------------
kono
parents:
diff changeset
907
kono
parents:
diff changeset
908 function SS_Mark return Mark_Id is
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
909 Stack : constant SS_Stack_Ptr := Get_Sec_Stack.all;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
910
111
kono
parents:
diff changeset
911 begin
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
912 return (Stack => Stack, Top => Stack.Top);
111
kono
parents:
diff changeset
913 end SS_Mark;
kono
parents:
diff changeset
914
kono
parents:
diff changeset
915 ----------------
kono
parents:
diff changeset
916 -- SS_Release --
kono
parents:
diff changeset
917 ----------------
kono
parents:
diff changeset
918
kono
parents:
diff changeset
919 procedure SS_Release (M : Mark_Id) is
kono
parents:
diff changeset
920 begin
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
921 M.Stack.Top := M.Top;
111
kono
parents:
diff changeset
922 end SS_Release;
kono
parents:
diff changeset
923
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
924 ------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
925 -- Top_Chunk_Id --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
926 ------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
927
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
928 function Top_Chunk_Id (Stack : SS_Stack_Ptr) return Chunk_Id_With_Invalid is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
929 Chunk : SS_Chunk_Ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
930 Id : Chunk_Id;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
931
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
932 begin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
933 Chunk := Stack.Static_Chunk'Access;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
934 Id := 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
935 while Chunk /= null loop
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
936 if Chunk = Stack.Top.Chunk then
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
937 return Id;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
938 end if;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
939
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
940 Chunk := Chunk.Next;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
941 Id := Id + 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
942 end loop;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
943
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
944 return Invalid_Chunk_Id;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
945 end Top_Chunk_Id;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
946
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
947 ----------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
948 -- Used_Memory_Size --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
949 ----------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
950
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
951 function Used_Memory_Size (Stack : SS_Stack_Ptr) return Memory_Size is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
952 begin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
953 -- The size of the occupied memory is equal to the size up to the chunk
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
954 -- indicated by the stack pointer, plus the size in use by the indicated
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
955 -- chunk itself. Top.Byte - 1 is the last occupied byte.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
956 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
957 -- Top.Byte
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
958 -- |
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
959 -- . . . . . . . +--------------|----+
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
960 -- . ..> |##############| |
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
961 -- . . . . . . . +-------------------+
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
962 -- | |
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
963 -- -------------------+-------------+
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
964 -- Size_Up_To_Chunk size in use
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
965
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
966 -- ??? this calculation may overflow on 32bit targets
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
967
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
968 return Stack.Top.Chunk.Size_Up_To_Chunk + Stack.Top.Byte - 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
969 end Used_Memory_Size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
970
111
kono
parents:
diff changeset
971 end System.Secondary_Stack;