[Memory] Treat AllocRange high_page_number as exclusive
The free-block tracker search in BaseHeap::AllocRange treats
high_page_number as inclusive, shifting allocator-returned addresses
by one stride relative to the old loop-based search. Some titles
encode allocator-returned addresses in PPC code and break when that
layout shifts (Far Cry 3, Far Cry 4, Watchdogs).
In addition, reapply xe::align on the high side of AllocRange
(essentially reverting c28019e33). Without the round-up, a caller
passing a min/max window exactly the size of its request loses a
stride at the top and fails the early page_count size check.
This commit is contained in:
@@ -85,14 +85,15 @@ TEST_CASE("heap_alloc_basic", "[heap]") {
|
||||
TEST_CASE("heap_alloc_top_down", "[heap]") {
|
||||
TestHeap h(0x80000000, 0x100000, 0x1000);
|
||||
|
||||
// Top-down treats high_page_number as exclusive, so the top page is
|
||||
// never handed out.
|
||||
uint32_t addr = 0;
|
||||
REQUIRE(h.Alloc(0x1000, 0x1000, true, &addr));
|
||||
// Top-down: should be at the highest aligned address.
|
||||
REQUIRE(addr == 0x800FF000);
|
||||
REQUIRE(addr == 0x800FE000);
|
||||
REQUIRE(h.unreserved_page_count() == 255);
|
||||
|
||||
REQUIRE(h.Alloc(0x2000, 0x1000, true, &addr));
|
||||
REQUIRE(addr == 0x800FD000);
|
||||
REQUIRE(addr == 0x800FC000);
|
||||
REQUIRE(h.unreserved_page_count() == 253);
|
||||
}
|
||||
|
||||
@@ -237,16 +238,18 @@ TEST_CASE("heap_alloc_alignment_top_down", "[heap]") {
|
||||
// 1MB heap, 4KB pages
|
||||
TestHeap h(0x80000000, 0x100000, 0x1000);
|
||||
|
||||
// Allocate 1 page at the top.
|
||||
// Top-down skips the top page (0x800FF000), so a 1-page allocation
|
||||
// lands on page 0xFE.
|
||||
uint32_t first = 0;
|
||||
REQUIRE(h.Alloc(0x1000, 0x1000, true, &first));
|
||||
REQUIRE(first == 0x800FF000);
|
||||
REQUIRE(first == 0x800FE000);
|
||||
|
||||
// Allocate with 64KB alignment top-down — should align down.
|
||||
// 64KB-aligned top-down: stride 16, exclusive high at page 0xFF, so
|
||||
// the highest aligned base is page 0xE0.
|
||||
uint32_t aligned = 0;
|
||||
REQUIRE(h.Alloc(0x1000, 0x10000, true, &aligned));
|
||||
REQUIRE((aligned % 0x10000) == 0);
|
||||
REQUIRE(aligned == 0x800F0000);
|
||||
REQUIRE(aligned == 0x800E0000);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user