-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathHeapMM.pas
More file actions
122 lines (102 loc) · 3.83 KB
/
Copy pathHeapMM.pas
File metadata and controls
122 lines (102 loc) · 3.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
{
Alternative memory manager. To use it, just place a reference to this
unit *FIRST* in the uses clause of your project (dpr-file). It is a good idea
to use this memory manager with system dcu replacement by Vladimir Kladov.
Heap API used, which is fast and very effective (allocated block granularity
is 16 bytes). One additional benefit is that some proofing tools (MemProof)
do not detect API failures, which those can find when standard Delphi memory
manager used.
=====================================================================
Copyright (C) by Vladimir Kladov, 2001
---------------------------------------------------------------------
http://xcl.cjb.net
mailto: bonanzas@xcl.cjb.net
}
unit HeapMM;
interface
uses windows;
const
HEAP_NO_SERIALIZE = $00001;
HEAP_GROWABLE = $00002;
HEAP_GENERATE_EXCEPTIONS = $00004;
HEAP_ZERO_MEMORY = $00008;
HEAP_REALLOC_IN_PLACE_ONLY = $00010;
HEAP_TAIL_CHECKING_ENABLED = $00020;
HEAP_FREE_CHECKING_ENABLED = $00040;
HEAP_DISABLE_COALESCE_ON_FREE = $00080;
HEAP_CREATE_ALIGN_16 = $10000;
HEAP_CREATE_ENABLE_TRACING = $20000;
HEAP_MAXIMUM_TAG = $00FFF;
HEAP_PSEUDO_TAG_FLAG = $08000;
HEAP_TAG_SHIFT = 16 ;
{$DEFINE USE_PROCESS_HEAP}
var
HeapHandle: THandle;
{* Global handle to the heap. Do not change it! }
HeapFlags: DWORD = 0;
{* Possible flags are:
HEAP_GENERATE_EXCEPTIONS - system will raise an exception to indicate a
function failure, such as an out-of-memory
condition, instead of returning NULL.
HEAP_NO_SERIALIZE - mutual exclusion will not be used while the HeapAlloc
function is accessing the heap. Be careful!
Not recommended for multi-thread applications.
But faster.
HEAP_ZERO_MEMORY - obviously. (Slower!)
}
{ Note from MSDN:
The granularity of heap allocations in Win32 is 16 bytes. So if you
request a global memory allocation of 1 byte, the heap returns a pointer
to a chunk of memory, guaranteeing that the 1 byte is available. Chances
are, 16 bytes will actually be available because the heap cannot allocate
less than 16 bytes at a time.
}
implementation
function HeapGetMem(size: Integer): Pointer;
// Allocate memory block.
begin
Result := HeapAlloc( HeapHandle, HeapFlags, size );
end;
function HeapFreeMem(p: Pointer): Integer;
// Deallocate memory block.
begin
Result := Integer( not HeapFree( HeapHandle, HeapFlags and HEAP_NO_SERIALIZE,
p ) );
end;
function HeapReallocMem(p: Pointer; size: Integer): Pointer;
// Resize memory block.
begin
Result := HeapRealloc( HeapHandle, HeapFlags and (HEAP_NO_SERIALIZE and
HEAP_GENERATE_EXCEPTIONS and HEAP_ZERO_MEMORY),
// (Prevent using flag HEAP_REALLOC_IN_PLACE_ONLY here - to allow
// system to move the block if necessary).
p, size );
end;
{function HeapMemoryManagerSet: Boolean;
begin
Result := TRUE;
end;}
const
HeapMemoryManager: TMemoryManager = (
GetMem: HeapGetMem;
FreeMem: HeapFreeMem;
ReallocMem: HeapReallocMem);
var OldMM: TMemoryManager;
//OldIsMMset: function : Boolean;
initialization
{$IFDEF USE_PROCESS_HEAP}
HeapHandle := GetProcessHeap;
{$ELSE}
HeapHandle := HeapCreate( 0, 0, 0 );
{$ENDIF}
GetMemoryManager( OldMM );
//OldIsMMset := IsMemoryManagerSet;
//IsMemoryManagerSet := HeapMemoryManagerSet;
SetMemoryManager( HeapMemoryManager );
finalization
SetMemoryManager( OldMM );
//IsMemoryManagerSet := OldIsMMset;
{$IFNDEF USE_PROCESS_HEAP}
HeapDestroy( HeapHandle );
{$ENDIF}
end.