Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
c50597c9
Commit
c50597c9
authored
Aug 12, 2005
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Converted the heap free lists to standard lists.
parent
b480a3c5
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
35 additions
and
47 deletions
+35
-47
heap.c
dlls/ntdll/heap.c
+35
-47
No files found.
dlls/ntdll/heap.c
View file @
c50597c9
...
...
@@ -36,9 +36,10 @@
#include "windef.h"
#include "winternl.h"
#include "winnt.h"
#include "wine/debug.h"
#include "winternl.h"
#include "wine/server_protocol.h"
#include "wine/list.h"
#include "wine/debug.h"
#include "wine/server.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
heap
);
...
...
@@ -63,8 +64,7 @@ typedef struct tagARENA_FREE
{
DWORD
size
;
/* Block size; must be the first field */
DWORD
magic
;
/* Magic number */
struct
tagARENA_FREE
*
next
;
/* Next free arena */
struct
tagARENA_FREE
*
prev
;
/* Prev free arena */
struct
list
entry
;
/* Entry in free list */
}
ARENA_FREE
;
#define ARENA_FLAG_FREE 0x00000001
/* flags OR'ed with arena size */
...
...
@@ -201,9 +201,9 @@ static void HEAP_Dump( HEAP *heap )
DPRINTF
(
"
\n
Free lists:
\n
Block Stat Size Id
\n
"
);
for
(
i
=
0
;
i
<
HEAP_NB_FREE_LISTS
;
i
++
)
DPRINTF
(
"%p free %08lx prev=%p next=%p
\n
"
,
&
heap
->
freeList
[
i
].
arena
,
heap
->
freeList
[
i
].
size
,
heap
->
freeList
[
i
].
arena
.
prev
,
heap
->
freeList
[
i
].
arena
.
next
);
&
heap
->
freeList
[
i
].
arena
,
heap
->
freeList
[
i
].
size
,
LIST_ENTRY
(
heap
->
freeList
[
i
].
arena
.
entry
.
prev
,
ARENA_FREE
,
entry
)
,
LIST_ENTRY
(
heap
->
freeList
[
i
].
arena
.
entry
.
next
,
ARENA_FREE
,
entry
)
);
subheap
=
&
heap
->
subheap
;
while
(
subheap
)
...
...
@@ -220,8 +220,9 @@ static void HEAP_Dump( HEAP *heap )
{
ARENA_FREE
*
pArena
=
(
ARENA_FREE
*
)
ptr
;
DPRINTF
(
"%p free %08lx prev=%p next=%p
\n
"
,
pArena
,
pArena
->
size
&
ARENA_SIZE_MASK
,
pArena
->
prev
,
pArena
->
next
);
pArena
,
pArena
->
size
&
ARENA_SIZE_MASK
,
LIST_ENTRY
(
pArena
->
entry
.
prev
,
ARENA_FREE
,
entry
),
LIST_ENTRY
(
pArena
->
entry
.
next
,
ARENA_FREE
,
entry
)
);
ptr
+=
sizeof
(
*
pArena
)
+
(
pArena
->
size
&
ARENA_SIZE_MASK
);
arenaSize
+=
sizeof
(
ARENA_FREE
);
freeSize
+=
pArena
->
size
&
ARENA_SIZE_MASK
;
...
...
@@ -332,18 +333,12 @@ static inline void HEAP_InsertFreeBlock( HEAP *heap, ARENA_FREE *pArena, BOOL la
/* insert at end of free list, i.e. before the next free list entry */
pEntry
++
;
if
(
pEntry
==
&
heap
->
freeList
[
HEAP_NB_FREE_LISTS
])
pEntry
=
heap
->
freeList
;
pArena
->
prev
=
pEntry
->
arena
.
prev
;
pArena
->
prev
->
next
=
pArena
;
pArena
->
next
=
&
pEntry
->
arena
;
pEntry
->
arena
.
prev
=
pArena
;
list_add_before
(
&
pEntry
->
arena
.
entry
,
&
pArena
->
entry
);
}
else
{
/* insert at head of free list */
pArena
->
next
=
pEntry
->
arena
.
next
;
pArena
->
next
->
prev
=
pArena
;
pArena
->
prev
=
&
pEntry
->
arena
;
pEntry
->
arena
.
next
=
pArena
;
list_add_after
(
&
pEntry
->
arena
.
entry
,
&
pArena
->
entry
);
}
pArena
->
size
|=
ARENA_FLAG_FREE
;
}
...
...
@@ -455,8 +450,7 @@ static void HEAP_CreateFreeBlock( SUBHEAP *subheap, void *ptr, SIZE_T size )
{
/* Remove the next arena from the free list */
ARENA_FREE
*
pNext
=
(
ARENA_FREE
*
)((
char
*
)
ptr
+
size
);
pNext
->
next
->
prev
=
pNext
->
prev
;
pNext
->
prev
->
next
=
pNext
->
next
;
list_remove
(
&
pNext
->
entry
);
size
+=
(
pNext
->
size
&
ARENA_SIZE_MASK
)
+
sizeof
(
*
pNext
);
mark_block_free
(
pNext
,
sizeof
(
ARENA_FREE
)
);
}
...
...
@@ -497,8 +491,7 @@ static void HEAP_MakeInUseBlockFree( SUBHEAP *subheap, ARENA_INUSE *pArena )
pFree
=
*
((
ARENA_FREE
**
)
pArena
-
1
);
size
+=
(
pFree
->
size
&
ARENA_SIZE_MASK
)
+
sizeof
(
ARENA_FREE
);
/* Remove it from the free list */
pFree
->
next
->
prev
=
pFree
->
prev
;
pFree
->
prev
->
next
=
pFree
->
next
;
list_remove
(
&
pFree
->
entry
);
}
else
pFree
=
(
ARENA_FREE
*
)
pArena
;
...
...
@@ -517,8 +510,7 @@ static void HEAP_MakeInUseBlockFree( SUBHEAP *subheap, ARENA_INUSE *pArena )
SIZE_T
size
=
0
;
SUBHEAP
*
pPrev
=
&
subheap
->
heap
->
subheap
;
/* Remove the free block from the list */
pFree
->
next
->
prev
=
pFree
->
prev
;
pFree
->
prev
->
next
=
pFree
->
next
;
list_remove
(
&
pFree
->
entry
);
/* Remove the subheap from the list */
while
(
pPrev
&&
(
pPrev
->
next
!=
subheap
))
pPrev
=
pPrev
->
next
;
if
(
pPrev
)
pPrev
->
next
=
subheap
->
next
;
...
...
@@ -606,15 +598,13 @@ static BOOL HEAP_InitSubHeap( HEAP *heap, LPVOID address, DWORD flags,
/* Build the free lists */
list_init
(
&
heap
->
freeList
[
0
].
arena
.
entry
);
for
(
i
=
0
,
pEntry
=
heap
->
freeList
;
i
<
HEAP_NB_FREE_LISTS
;
i
++
,
pEntry
++
)
{
pEntry
->
size
=
HEAP_freeListSizes
[
i
];
pEntry
->
arena
.
size
=
0
|
ARENA_FLAG_FREE
;
pEntry
->
arena
.
next
=
i
<
HEAP_NB_FREE_LISTS
-
1
?
&
heap
->
freeList
[
i
+
1
].
arena
:
&
heap
->
freeList
[
0
].
arena
;
pEntry
->
arena
.
prev
=
i
?
&
heap
->
freeList
[
i
-
1
].
arena
:
&
heap
->
freeList
[
HEAP_NB_FREE_LISTS
-
1
].
arena
;
pEntry
->
arena
.
magic
=
ARENA_FREE_MAGIC
;
if
(
i
)
list_add_after
(
&
pEntry
[
-
1
].
arena
.
entry
,
&
pEntry
->
arena
.
entry
);
}
/* Initialize critical section */
...
...
@@ -703,15 +693,16 @@ static ARENA_FREE *HEAP_FindFreeBlock( HEAP *heap, SIZE_T size,
SUBHEAP
**
ppSubHeap
)
{
SUBHEAP
*
subheap
;
ARENA_FREE
*
pArena
;
struct
list
*
ptr
;
FREE_LIST_ENTRY
*
pEntry
=
heap
->
freeList
;
/* Find a suitable free list, and in it find a block large enough */
while
(
pEntry
->
size
<
size
)
pEntry
++
;
p
Arena
=
pEntry
->
arena
.
next
;
while
(
pArena
!=
&
heap
->
freeList
[
0
].
arena
)
p
tr
=
&
pEntry
->
arena
.
entry
;
while
(
(
ptr
=
list_next
(
&
heap
->
freeList
[
0
].
arena
.
entry
,
ptr
))
)
{
ARENA_FREE
*
pArena
=
LIST_ENTRY
(
ptr
,
ARENA_FREE
,
entry
);
SIZE_T
arena_size
=
(
pArena
->
size
&
ARENA_SIZE_MASK
)
+
sizeof
(
ARENA_FREE
)
-
sizeof
(
ARENA_INUSE
);
if
(
arena_size
>=
size
)
...
...
@@ -723,7 +714,6 @@ static ARENA_FREE *HEAP_FindFreeBlock( HEAP *heap, SIZE_T size,
*
ppSubHeap
=
subheap
;
return
pArena
;
}
pArena
=
pArena
->
next
;
}
/* If no block was found, attempt to grow the heap */
...
...
@@ -774,6 +764,7 @@ static BOOL HEAP_IsValidArenaPtr( const HEAP *heap, const void *ptr )
*/
static
BOOL
HEAP_ValidateFreeArena
(
SUBHEAP
*
subheap
,
ARENA_FREE
*
pArena
)
{
ARENA_FREE
*
prev
,
*
next
;
char
*
heapEnd
=
(
char
*
)
subheap
+
subheap
->
size
;
/* Check for unaligned pointers */
...
...
@@ -805,35 +796,35 @@ static BOOL HEAP_ValidateFreeArena( SUBHEAP *subheap, ARENA_FREE *pArena )
return
FALSE
;
}
/* Check that next pointer is valid */
if
(
!
HEAP_IsValidArenaPtr
(
subheap
->
heap
,
pArena
->
next
))
next
=
LIST_ENTRY
(
pArena
->
entry
.
next
,
ARENA_FREE
,
entry
);
if
(
!
HEAP_IsValidArenaPtr
(
subheap
->
heap
,
next
))
{
ERR
(
"Heap %p: bad next ptr %p for arena %p
\n
"
,
subheap
->
heap
,
pArena
->
next
,
pArena
);
subheap
->
heap
,
next
,
pArena
);
return
FALSE
;
}
/* Check that next arena is free */
if
(
!
(
pArena
->
next
->
size
&
ARENA_FLAG_FREE
)
||
(
pArena
->
next
->
magic
!=
ARENA_FREE_MAGIC
))
if
(
!
(
next
->
size
&
ARENA_FLAG_FREE
)
||
(
next
->
magic
!=
ARENA_FREE_MAGIC
))
{
ERR
(
"Heap %p: next arena %p invalid for %p
\n
"
,
subheap
->
heap
,
pArena
->
next
,
pArena
);
subheap
->
heap
,
next
,
pArena
);
return
FALSE
;
}
/* Check that prev pointer is valid */
if
(
!
HEAP_IsValidArenaPtr
(
subheap
->
heap
,
pArena
->
prev
))
prev
=
LIST_ENTRY
(
pArena
->
entry
.
prev
,
ARENA_FREE
,
entry
);
if
(
!
HEAP_IsValidArenaPtr
(
subheap
->
heap
,
prev
))
{
ERR
(
"Heap %p: bad prev ptr %p for arena %p
\n
"
,
subheap
->
heap
,
p
Arena
->
p
rev
,
pArena
);
subheap
->
heap
,
prev
,
pArena
);
return
FALSE
;
}
/* Check that prev arena is free */
if
(
!
(
pArena
->
prev
->
size
&
ARENA_FLAG_FREE
)
||
(
pArena
->
prev
->
magic
!=
ARENA_FREE_MAGIC
))
if
(
!
(
prev
->
size
&
ARENA_FLAG_FREE
)
||
(
prev
->
magic
!=
ARENA_FREE_MAGIC
))
{
/* this often means that the prev arena got overwritten
* by a memory write before that prev arena */
ERR
(
"Heap %p: prev arena %p invalid for %p
\n
"
,
subheap
->
heap
,
p
Arena
->
p
rev
,
pArena
);
subheap
->
heap
,
prev
,
pArena
);
return
FALSE
;
}
/* Check that next block has PREV_FREE flag */
...
...
@@ -1172,8 +1163,7 @@ PVOID WINAPI RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_T size )
/* Remove the arena from the free list */
pArena
->
next
->
prev
=
pArena
->
prev
;
pArena
->
prev
->
next
=
pArena
->
next
;
list_remove
(
&
pArena
->
entry
);
/* Build the in-use arena */
...
...
@@ -1316,8 +1306,7 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, SIZE_T size
{
/* The next block is free and large enough */
ARENA_FREE
*
pFree
=
(
ARENA_FREE
*
)
pNext
;
pFree
->
next
->
prev
=
pFree
->
prev
;
pFree
->
prev
->
next
=
pFree
->
next
;
list_remove
(
&
pFree
->
entry
);
pArena
->
size
+=
(
pFree
->
size
&
ARENA_SIZE_MASK
)
+
sizeof
(
*
pFree
);
if
(
!
HEAP_Commit
(
subheap
,
(
char
*
)
pArena
+
sizeof
(
ARENA_INUSE
)
+
rounded_size
+
HEAP_MIN_BLOCK_SIZE
))
...
...
@@ -1346,8 +1335,7 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, SIZE_T size
/* Build the in-use arena */
pNew
->
next
->
prev
=
pNew
->
prev
;
pNew
->
prev
->
next
=
pNew
->
next
;
list_remove
(
&
pNew
->
entry
);
pInUse
=
(
ARENA_INUSE
*
)
pNew
;
pInUse
->
size
=
(
pInUse
->
size
&
~
ARENA_FLAG_FREE
)
+
sizeof
(
ARENA_FREE
)
-
sizeof
(
ARENA_INUSE
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment