bootloader: Actually release the heap.
This avoids leaking the bootloader heap memory into the kernel. Ideally it'd be dropped automatically, but in seems in many cases it isn't (even on EFI). Adjust platform logic to always remove the physical allocated range, and ignore the return code and reuse the memory anyway if we can.
This commit is contained in:
@@ -385,6 +385,8 @@ FreeChunk::SetToAllocated(void* allocated)
|
||||
void
|
||||
heap_release(stage2_args* args)
|
||||
{
|
||||
heap_print_statistics();
|
||||
|
||||
LargeAllocation* allocation = sLargeAllocations.Clear(true);
|
||||
while (allocation != NULL) {
|
||||
LargeAllocation* next = allocation->HashNext();
|
||||
@@ -393,6 +395,10 @@ heap_release(stage2_args* args)
|
||||
}
|
||||
|
||||
platform_free_heap_region(sHeapBase, (addr_t)sHeapEnd - (addr_t)sHeapBase);
|
||||
|
||||
sHeapBase = sHeapEnd = NULL;
|
||||
memset((void*)&sFreeChunkTree, 0, sizeof(sFreeChunkTree));
|
||||
memset((void*)&sLargeAllocations, 0, sizeof(sLargeAllocations));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -162,8 +162,7 @@ main(stage2_args *args)
|
||||
gKernelArgs.boot_volume_size = gBootVolume.ContentSize();
|
||||
|
||||
platform_cleanup_devices();
|
||||
// TODO: cleanup, heap_release() etc.
|
||||
heap_print_statistics();
|
||||
heap_release(args);
|
||||
platform_start_kernel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -682,8 +682,8 @@ void
|
||||
platform_free_heap_region(void *_base, size_t size)
|
||||
{
|
||||
addr_t base = (addr_t)_base;
|
||||
status_t status = remove_physical_allocated_range(base, size);
|
||||
if (status == B_OK && sNextPhysicalAddress == (base + size))
|
||||
remove_physical_allocated_range(base, size);
|
||||
if (sNextPhysicalAddress == (base + size))
|
||||
sNextPhysicalAddress -= size;
|
||||
|
||||
// Failures don't matter very much as regions should be freed automatically,
|
||||
|
||||
@@ -687,8 +687,8 @@ void
|
||||
platform_free_heap_region(void *_base, size_t size)
|
||||
{
|
||||
addr_t base = (addr_t)_base;
|
||||
status_t status = remove_physical_allocated_range(base, size);
|
||||
if (status == B_OK && sNextPhysicalAddress == (base + size))
|
||||
remove_physical_allocated_range(base, size);
|
||||
if (sNextPhysicalAddress == (base + size))
|
||||
sNextPhysicalAddress -= size;
|
||||
|
||||
// Failures don't matter very much as regions should be freed automatically,
|
||||
|
||||
@@ -829,10 +829,9 @@ void
|
||||
platform_free_heap_region(void *_base, size_t size)
|
||||
{
|
||||
addr_t base = (addr_t)_base;
|
||||
if (sNextPhysicalAddress == (base + size)) {
|
||||
remove_physical_allocated_range(base, size);
|
||||
if (sNextPhysicalAddress == (base + size))
|
||||
sNextPhysicalAddress -= size;
|
||||
remove_physical_allocated_range(sNextPhysicalAddress, size);
|
||||
}
|
||||
|
||||
// Failures don't matter very much as regions should be freed automatically,
|
||||
// since they're in the identity map and not stored in the kernel's page tables.
|
||||
|
||||
Reference in New Issue
Block a user