* If DEBUG_ALLOCATIONS is defined, freed memory is now filled with 0xcc,

and it's checked if a chunk is already in the free list, and if any chunk
  has an invalid size. It's defined for now.
* Minor cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23171 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2007-12-27 16:56:28 +00:00
parent 6fd8b07afc
commit 96689a5cb8
+40 -24
View File
@@ -1,7 +1,7 @@
/* /*
** Copyright 2003, Axel Dörfler, [email protected]. All rights reserved. * Copyright 2003-2007, Axel Dörfler, [email protected]. All rights reserved.
** Distributed under the terms of the OpenBeOS License. * Distributed under the terms of the MIT License.
*/ */
#include <boot/heap.h> #include <boot/heap.h>
@@ -31,6 +31,8 @@
* size 0 that can't be allocated. * size 0 that can't be allocated.
*/ */
#define DEBUG_ALLOCATIONS
// if defined, freed memory is filled with 0xcc
struct free_chunk { struct free_chunk {
uint32 size; uint32 size;
@@ -53,10 +55,9 @@ static uint32 /*sHeapSize,*/ sMaxHeapSize, sAvailable;
static free_chunk sFreeAnchor; static free_chunk sFreeAnchor;
/** Returns the amount of bytes that can be allocated /*! Returns the amount of bytes that can be allocated
* in this chunk. in this chunk.
*/ */
uint32 uint32
free_chunk::Size() const free_chunk::Size() const
{ {
@@ -64,10 +65,9 @@ free_chunk::Size() const
} }
/** Splits the upper half at the requested location /*! Splits the upper half at the requested location
* and returns it. and returns it.
*/ */
free_chunk * free_chunk *
free_chunk::Split(uint32 splitSize) free_chunk::Split(uint32 splitSize)
{ {
@@ -81,10 +81,9 @@ free_chunk::Split(uint32 splitSize)
} }
/** Checks if the specified chunk touches this chunk, so /*! Checks if the specified chunk touches this chunk, so
* that they could be joined. that they could be joined.
*/ */
bool bool
free_chunk::IsTouching(free_chunk *chunk) free_chunk::IsTouching(free_chunk *chunk)
{ {
@@ -94,14 +93,13 @@ free_chunk::IsTouching(free_chunk *chunk)
} }
/** Joins the chunk to this chunk and returns the pointer /*! Joins the chunk to this chunk and returns the pointer
* to the new chunk - which will either be one of the to the new chunk - which will either be one of the
* two chunks. two chunks.
* Note, the chunks must be joinable, or else this method Note, the chunks must be joinable, or else this method
* doesn't work correctly. Use free_chunk::IsTouching() doesn't work correctly. Use free_chunk::IsTouching()
* to check if this method can be applied. to check if this method can be applied.
*/ */
free_chunk * free_chunk *
free_chunk::Join(free_chunk *chunk) free_chunk::Join(free_chunk *chunk)
{ {
@@ -151,6 +149,10 @@ free_chunk::Enqueue()
this->next = chunk; this->next = chunk;
last->next = this; last->next = this;
#ifdef DEBUG_ALLOCATIONS
memset((uint8*)this + sizeof(free_chunk), 0xcc, this->size - sizeof(free_chunk));
#endif
} }
@@ -322,6 +324,20 @@ free(void *allocated)
return; return;
free_chunk *freedChunk = free_chunk::SetToAllocated(allocated); free_chunk *freedChunk = free_chunk::SetToAllocated(allocated);
#ifdef DEBUG_ALLOCATIONS
if (freedChunk->size > 65536)
panic("freed chunk %p clobbered (%lx)!\n", freedChunk, freedChunk->size);
{
free_chunk *chunk = sFreeAnchor.next;
while (chunk) {
if (chunk->size > 65536 || freedChunk == chunk)
panic("invalid chunk in free list, or double free\n");
chunk = chunk->next;
}
}
#endif
sAvailable += freedChunk->size; sAvailable += freedChunk->size;
// try to join the new free chunk with an existing one // try to join the new free chunk with an existing one