runtime_loader: Resize heap areas instead of creating new ones.

This is more efficient and works most of the time. Additionally,
we can potentially join with a previous free chunk in the allocator,
avoiding extra fragmentation on the heap.

app_server (on x86_64) only has 1 "rld heap" area after this change
with a size of 0x50000 (320KB), whereas previously it had around 7
with a total size of 0x80000 (512KB).
This commit is contained in:
Augustin Cavalier
2025-01-07 17:30:29 -05:00
parent 7137fc03b2
commit babcaa3c29
2 changed files with 45 additions and 22 deletions
+24 -21
View File
@@ -220,13 +220,10 @@ public:
{
FreeChunk* chunk = (FreeChunk*)base;
chunk->SetTo(size);
fFreeChunkTree.Insert(chunk);
fAvailable += chunk->Size();
#ifdef DEBUG_MAX_HEAP_USAGE
fMaxHeapSize += chunk->Size();
fMaxHeapUsage = fMaxHeapSize - fAvailable;
#endif
_InsertChunk(chunk);
}
uint32 Available() const { return fAvailable; }
@@ -329,13 +326,35 @@ public:
((uint32*)allocated)[i] = 0xdeadbeef;
#endif
_InsertChunk(freedChunk);
}
#ifdef DEBUG_MAX_HEAP_USAGE
uint32 MaxHeapSize() const { return fMaxHeapSize; }
uint32 MaxHeapUsage() const { return fMaxHeapUsage; }
#endif
void DumpChunks()
{
FreeChunk* chunk = fFreeChunkTree.FindMin();
while (chunk != NULL) {
printf("\t%p: chunk size = %ld, end = %p, next = %p\n", chunk,
chunk->Size(), (uint8*)chunk + chunk->CompleteSize(),
chunk->Next());
chunk = chunk->Next();
}
}
private:
void _InsertChunk(FreeChunk* freedChunk)
{
// try to join the new free chunk with an existing one
// it may be joined with up to two chunks
FreeChunk* chunk = fFreeChunkTree.FindMin();
int32 joinCount = 0;
while (chunk) {
while (chunk != NULL) {
FreeChunk* nextChunk = chunk->Next();
if (chunk->IsTouching(freedChunk)) {
@@ -358,22 +377,6 @@ public:
#endif
}
#ifdef DEBUG_MAX_HEAP_USAGE
uint32 MaxHeapSize() const { return fMaxHeapSize; }
uint32 MaxHeapUsage() const { return fMaxHeapUsage; }
#endif
void DumpChunks()
{
FreeChunk* chunk = fFreeChunkTree.FindMin();
while (chunk != NULL) {
printf("\t%p: chunk size = %ld, end = %p, next = %p\n", chunk,
chunk->Size(), (uint8*)chunk + chunk->CompleteSize(),
chunk->Next());
chunk = chunk->Next();
}
}
private:
FreeChunkTree fFreeChunkTree;
uint32 fAvailable;