1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
5 -- G N A T . D E B U G _ P O O L S --
9 -- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 2, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, USA. --
22 -- As a special exception, if other files instantiate generics from this --
23 -- unit, or you link this unit with other files to produce an executable, --
24 -- this unit does not by itself cause the resulting executable to be --
25 -- covered by the GNU General Public License. This exception does not --
26 -- however invalidate any other reasons why the executable file might be --
27 -- covered by the GNU Public License. --
29 -- GNAT was originally developed by the GNAT team at New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
32 ------------------------------------------------------------------------------
34 with Unchecked_Conversion
;
38 pragma Elaborate_All
(GNAT
.HTable
);
40 package body GNAT
.Debug_Pools
is
43 use System
.Storage_Elements
;
45 -- Definition of a H-table storing the status of each storage chunck
48 type State
is (Not_Allocated
, Deallocated
, Allocated
);
50 type Header
is range 1 .. 1023;
51 function H
(F
: Address
) return Header
;
53 package Table
is new GNAT
.HTable
.Simple_HTable
(
56 No_Element
=> Not_Allocated
,
66 (Pool
: in out Debug_Pool
;
67 Storage_Address
: out Address
;
68 Size_In_Storage_Elements
: Storage_Count
;
69 Alignment
: Storage_Count
)
71 pragma Warnings
(Off
, Alignment
);
74 Storage_Address
:= Alloc
(size_t
(Size_In_Storage_Elements
));
76 if Storage_Address
= Null_Address
then
79 Table
.Set
(Storage_Address
, Allocated
);
80 Pool
.Allocated
:= Pool
.Allocated
+ Size_In_Storage_Elements
;
82 if Pool
.Allocated
- Pool
.Deallocated
> Pool
.High_Water
then
83 Pool
.High_Water
:= Pool
.Allocated
- Pool
.Deallocated
;
93 (Pool
: in out Debug_Pool
;
94 Storage_Address
: Address
;
95 Size_In_Storage_Elements
: Storage_Count
;
96 Alignment
: Storage_Count
)
98 pragma Warnings
(Off
, Alignment
);
100 procedure Free
(Address
: System
.Address
; Siz
: Storage_Count
);
101 -- Fake free, that resets all the deallocated storage to "DEADBEEF"
103 procedure Free
(Address
: System
.Address
; Siz
: Storage_Count
) is
104 DB1
: constant Integer := 16#DEAD#
;
105 DB2
: constant Integer := 16#BEEF#
;
107 type Dead_Memory
is array (1 .. Siz
/ 4) of Integer;
108 type Mem_Ptr
is access all Dead_Memory
;
111 new Unchecked_Conversion
(System
.Address
, Mem_Ptr
);
116 J
:= Dead_Memory
'First;
117 while J
< Dead_Memory
'Last loop
118 From_Ptr
(Address
) (J
) := DB1
;
119 From_Ptr
(Address
) (J
+ 1) := DB2
;
123 if J
= Dead_Memory
'Last then
124 From_Ptr
(Address
) (J
) := DB1
;
128 S
: State
:= Table
.Get
(Storage_Address
);
130 -- Start of processing for Deallocate
134 when Not_Allocated
=>
135 raise Freeing_Not_Allocated_Storage
;
138 raise Freeing_Deallocated_Storage
;
141 Free
(Storage_Address
, Size_In_Storage_Elements
);
142 Table
.Set
(Storage_Address
, Deallocated
);
143 Pool
.Deallocated
:= Pool
.Deallocated
+ Size_In_Storage_Elements
;
151 procedure Dereference
152 (Pool
: in out Debug_Pool
;
153 Storage_Address
: Address
;
154 Size_In_Storage_Elements
: Storage_Count
;
155 Alignment
: Storage_Count
)
157 pragma Warnings
(Off
, Pool
);
158 pragma Warnings
(Off
, Size_In_Storage_Elements
);
159 pragma Warnings
(Off
, Alignment
);
161 S
: State
:= Table
.Get
(Storage_Address
);
162 Max_Dim
: constant := 3;
167 -- If this is not a known address, maybe it is because is is an
168 -- unconstained array. In which case, the bounds have used the
169 -- 2 first words (per dimension) of the allocated spot.
171 while S
= Not_Allocated
and then Dim
<= Max_Dim
loop
172 S
:= Table
.Get
(Storage_Address
- Storage_Offset
(Dim
* 2 * 4));
177 when Not_Allocated
=>
178 raise Accessing_Not_Allocated_Storage
;
181 raise Accessing_Deallocated_Storage
;
192 function H
(F
: Address
) return Header
is
195 Header
(1 + (To_Integer
(F
) mod Integer_Address
(Header
'Last)));
202 procedure Print_Info
(Pool
: Debug_Pool
) is
203 use System
.Storage_Elements
;
206 Put_Line
("Debug Pool info:");
207 Put_Line
(" Total allocated bytes : "
208 & Storage_Offset
'Image (Pool
.Allocated
));
210 Put_Line
(" Total deallocated bytes : "
211 & Storage_Offset
'Image (Pool
.Deallocated
));
213 Put_Line
(" Current Water Mark: "
214 & Storage_Offset
'Image (Pool
.Allocated
- Pool
.Deallocated
));
216 Put_Line
(" High Water Mark: "
217 & Storage_Offset
'Image (Pool
.High_Water
));
225 function Storage_Size
(Pool
: Debug_Pool
) return Storage_Count
is
226 pragma Warnings
(Off
, Pool
);
229 return Storage_Count
'Last;
232 end GNAT
.Debug_Pools
;