@ -256,39 +256,37 @@ ResultCode VMManager::ReprotectRange(VAddr target, u64 size, VMAPermission new_p
return RESULT_SUCCESS ;
return RESULT_SUCCESS ;
}
}
ResultVal < VAddr > VMManager : : HeapAllocate ( VAddr target , u64 size , VMAPermission perms ) {
ResultVal < VAddr > VMManager : : HeapAllocate ( u64 size ) {
if ( ! IsWithinHeapRegion ( target , size ) ) {
if ( size > GetHeapRegionSize ( ) ) {
return ERR_ INVALID_ADDRESS ;
return ERR_ OUT_OF_MEMORY ;
}
}
if ( heap_memory = = nullptr ) {
if ( heap_memory = = nullptr ) {
// Initialize heap
// Initialize heap
heap_memory = std : : make_shared < std : : vector < u8 > > ( ) ;
heap_memory = std : : make_shared < std : : vector < u8 > > ( size ) ;
heap_ start = heap_end = target ;
heap_ end = heap_region_base + size ;
} else {
} else {
UnmapRange ( heap_ start, heap_end - heap_start ) ;
UnmapRange ( heap_ region_base, GetCurrentHeapSize ( ) ) ;
}
}
// If necessary, expand backing vector to cover new heap extents.
// If necessary, expand backing vector to cover new heap extents.
if ( target < heap_start ) {
if ( size > GetCurrentHeapSize ( ) ) {
heap_memory - > insert ( begin ( * heap_memory ) , heap_start - target , 0 ) ;
const u64 alloc_size = size - GetCurrentHeapSize ( ) ;
heap_start = target ;
RefreshMemoryBlockMappings ( heap_memory . get ( ) ) ;
}
if ( target + size > heap_end ) {
heap_memory - > insert ( end ( * heap_memory ) , ( target + size ) - heap_end , 0 ) ;
heap_end = target + size ;
RefreshMemoryBlockMappings ( heap_memory . get ( ) ) ;
}
ASSERT ( heap_end - heap_start = = heap_memory - > size ( ) ) ;
CASCADE_RESULT ( auto vma , MapMemoryBlock ( target , heap_memory , target - heap_start , size ,
heap_memory - > insert ( heap_memory - > end ( ) , alloc_size , 0 ) ;
MemoryState : : Heap ) ) ;
heap_end = heap_region_base + size ;
Reprotect ( vma , perms ) ;
RefreshMemoryBlockMappings ( heap_memory . get ( ) ) ;
}
ASSERT ( GetCurrentHeapSize ( ) = = heap_memory - > size ( ) ) ;
const auto mapping_result =
MapMemoryBlock ( heap_region_base , heap_memory , 0 , size , MemoryState : : Heap ) ;
if ( mapping_result . Failed ( ) ) {
return mapping_result . Code ( ) ;
}
heap_used = size ;
heap_used = size ;
return MakeResult < VAddr > ( heap_region_base ) ;
return MakeResult < VAddr > ( heap_end - size ) ;
}
}
ResultCode VMManager : : HeapFree ( VAddr target , u64 size ) {
ResultCode VMManager : : HeapFree ( VAddr target , u64 size ) {
@ -778,6 +776,10 @@ u64 VMManager::GetHeapRegionSize() const {
return heap_region_end - heap_region_base ;
return heap_region_end - heap_region_base ;
}
}
u64 VMManager : : GetCurrentHeapSize ( ) const {
return heap_end - heap_region_base ;
}
bool VMManager : : IsWithinHeapRegion ( VAddr address , u64 size ) const {
bool VMManager : : IsWithinHeapRegion ( VAddr address , u64 size ) const {
return IsInsideAddressRange ( address , size , GetHeapRegionBaseAddress ( ) ,
return IsInsideAddressRange ( address , size , GetHeapRegionBaseAddress ( ) ,
GetHeapRegionEndAddress ( ) ) ;
GetHeapRegionEndAddress ( ) ) ;