Skip to content

Commit b5f1e50

Browse files
committed
optimize msanGetStatus and msanValidateWrite
1 parent e857cc5 commit b5f1e50

File tree

4 files changed

+50
-34
lines changed

4 files changed

+50
-34
lines changed

src/core/gpu.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ uint32_t PCSX::GPU::gpuDmaChainSize(uint32_t addr) {
448448
uint32_t header;
449449
if (usingMsan && PCSX::Memory::inMsanRange(addr)) {
450450
addr &= 0xfffffffc;
451-
switch (g_emulator->m_mem->msanGetStatus(addr, 4)) {
451+
switch (g_emulator->m_mem->msanGetStatus<4>(addr)) {
452452
case PCSX::MsanStatus::UNINITIALIZED:
453453
g_system->log(LogClass::GPU, _("GPU DMA went into usable but uninitialized msan memory: %8.8lx\n"), addr);
454454
g_system->pause();
@@ -714,7 +714,7 @@ void PCSX::GPU::chainedDMAWrite(const uint32_t *memory, uint32_t hwAddr) {
714714
if (usingMsan && PCSX::Memory::inMsanRange(addr)) {
715715
addr &= 0xfffffffc;
716716
const uint32_t *headerPtr = (uint32_t *) (g_emulator->m_mem->m_msanRAM + (addr - PCSX::Memory::c_msanStart));
717-
switch (g_emulator->m_mem->msanGetStatus(addr, 4)) {
717+
switch (g_emulator->m_mem->msanGetStatus<4>(addr)) {
718718
case PCSX::MsanStatus::UNINITIALIZED:
719719
g_system->log(LogClass::GPU, _("GPU DMA went into usable but uninitialized msan memory: %8.8lx\n"), addr);
720720
g_system->pause();

src/core/psxhw.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class HW {
7777
do {
7878
if (usingMsan && PCSX::Memory::inMsanRange(madr)) {
7979
madr &= 0xfffffffc;
80-
switch (g_emulator->m_mem->msanGetStatus(madr, 4)) {
80+
switch (g_emulator->m_mem->msanGetStatus<4>(madr)) {
8181
case PCSX::MsanStatus::UNINITIALIZED:
8282
g_system->log(LogClass::GPU, _("GPU DMA went into usable but uninitialized msan memory: %8.8lx\n"), madr);
8383
g_system->pause();

src/core/psxmem.cc

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,10 @@ PCSX::Memory::Memory() : m_listener(g_system->m_eventBus) {
8989
m_listener.listen<Events::ExecutionFlow::Reset>([this](auto &) {
9090
free(m_msanRAM);
9191
free(m_msanUsableBitmap);
92-
free(m_msanWrittenBitmap);
92+
free(m_msanInitializedBitmap);
9393
m_msanRAM = nullptr;
9494
m_msanUsableBitmap = nullptr;
95-
m_msanWrittenBitmap = nullptr;
95+
m_msanInitializedBitmap = nullptr;
9696
m_msanAllocs.clear();
9797
});
9898
}
@@ -265,10 +265,10 @@ void PCSX::Memory::shutdown() {
265265

266266
free(m_msanRAM);
267267
free(m_msanUsableBitmap);
268-
free(m_msanWrittenBitmap);
268+
free(m_msanInitializedBitmap);
269269
m_msanRAM = nullptr;
270270
m_msanUsableBitmap = nullptr;
271-
m_msanWrittenBitmap = nullptr;
271+
m_msanInitializedBitmap = nullptr;
272272
m_msanAllocs.clear();
273273
}
274274

@@ -280,7 +280,7 @@ uint8_t PCSX::Memory::read8(uint32_t address) {
280280

281281
if (pointer != nullptr) {
282282
if (msanInitialized() && inMsanRange(address)) [[unlikely]] {
283-
switch (msanGetStatus(address, 1)) {
283+
switch (msanGetStatus<1>(address)) {
284284
case MsanStatus::UNINITIALIZED:
285285
g_system->log(LogClass::CPU, _("8-bit read from usable but uninitialized msan memory: %8.8lx\n"), address);
286286
break;
@@ -330,7 +330,7 @@ uint16_t PCSX::Memory::read16(uint32_t address) {
330330

331331
if (pointer != nullptr) {
332332
if (msanInitialized() && inMsanRange(address)) {
333-
switch (msanGetStatus(address, 2)) {
333+
switch (msanGetStatus<2>(address)) {
334334
case MsanStatus::UNINITIALIZED:
335335
g_system->log(LogClass::CPU, _("16-bit read from usable but uninitialized msan memory: %8.8lx\n"), address);
336336
break;
@@ -377,7 +377,7 @@ uint32_t PCSX::Memory::read32(uint32_t address, ReadType readType) {
377377

378378
if (pointer != nullptr) {
379379
if (msanInitialized() && inMsanRange(address)) {
380-
switch (msanGetStatus(address, 4)) {
380+
switch (msanGetStatus<4>(address)) {
381381
case MsanStatus::UNINITIALIZED:
382382
g_system->log(LogClass::CPU, _("32-bit read from usable but uninitialized msan memory: %8.8lx\n"), address);
383383
break;
@@ -500,7 +500,7 @@ void PCSX::Memory::write8(uint32_t address, uint32_t value) {
500500

501501
if (pointer != nullptr) {
502502
if (msanInitialized() && inMsanRange(address)) {
503-
if (msanValidateWrite(address, 1)) {
503+
if (msanValidateWrite<1>(address)) {
504504
m_msanRAM[address - c_msanStart] = value;
505505
} else {
506506
g_system->log(LogClass::CPU, _("8-bit write to unusable msan memory: %8.8lx\n"), address);
@@ -537,7 +537,7 @@ void PCSX::Memory::write16(uint32_t address, uint32_t value) {
537537

538538
if (pointer != nullptr) {
539539
if (msanInitialized() && inMsanRange(address)) {
540-
if (msanValidateWrite(address, 2)) {
540+
if (msanValidateWrite<2>(address)) {
541541
*(uint16_t *)&m_msanRAM[address - c_msanStart] = SWAP_LEu16(value);
542542
} else {
543543
g_system->log(LogClass::CPU, _("16-bit write to unusable msan memory: %8.8lx\n"), address);
@@ -575,7 +575,7 @@ void PCSX::Memory::write32(uint32_t address, uint32_t value) {
575575

576576
if (pointer != nullptr) {
577577
if (msanInitialized() && inMsanRange(address)) {
578-
if (msanValidateWrite(address, 4)) {
578+
if (msanValidateWrite<4>(address)) {
579579
*(uint32_t *)&m_msanRAM[address - c_msanStart] = SWAP_LEu32(value);
580580
} else {
581581
g_system->log(LogClass::CPU, _("32-bit write to unusable msan memory: %8.8lx\n"), address);
@@ -814,10 +814,10 @@ void PCSX::Memory::initMsan(bool reset) {
814814
if (reset) {
815815
free(m_msanRAM);
816816
free(m_msanUsableBitmap);
817-
free(m_msanWrittenBitmap);
817+
free(m_msanInitializedBitmap);
818818
m_msanRAM = nullptr;
819819
m_msanUsableBitmap = nullptr;
820-
m_msanWrittenBitmap = nullptr;
820+
m_msanInitializedBitmap = nullptr;
821821
m_msanAllocs.clear();
822822
m_msanChainRegistry.clear();
823823
}
@@ -830,7 +830,7 @@ void PCSX::Memory::initMsan(bool reset) {
830830
// 1.5GB of RAM, with 384MB worth of bitmap, between 0x20000000 and 0x80000000
831831
m_msanRAM = (uint8_t *)calloc(c_msanSize, 1);
832832
m_msanUsableBitmap = (uint8_t *)calloc(c_msanSize / 8, 1);
833-
m_msanWrittenBitmap = (uint8_t *)calloc(c_msanSize / 8, 1);
833+
m_msanInitializedBitmap = (uint8_t *)calloc(c_msanSize / 8, 1);
834834
m_msanPtr = 1024;
835835
for (uint32_t segment = c_msanStart; segment < c_msanEnd; segment += 0x10000) {
836836
m_readLUT[segment >> 16] = m_msanRAM + (segment - c_msanStart);
@@ -928,7 +928,7 @@ uint32_t PCSX::Memory::msanRealloc(uint32_t ptr, uint32_t size) {
928928
// Mark the new allocation as written to
929929
auto toCopy = std::min(size, oldSize);
930930
for (uint32_t i = 0; i < toCopy; i++) {
931-
m_msanWrittenBitmap[(newPtr + i) / 8] |= 1 << ((newPtr + i) % 8);
931+
m_msanInitializedBitmap[(newPtr + i) / 8] |= 1 << ((newPtr + i) % 8);
932932
}
933933
// Remove the allocation from the list of allocations.
934934
m_msanAllocs.erase(ptr);

src/core/psxmem.h

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -91,29 +91,45 @@ class Memory {
9191
uint32_t msanSetChainPtr(uint32_t headerAddr, uint32_t ptrToNext, uint32_t size);
9292
uint32_t msanGetChainPtr(uint32_t addr) const;
9393

94-
inline MsanStatus msanGetStatus(uint32_t addr, uint32_t size) const {
95-
uint32_t msanAddr = addr - c_msanStart;
96-
if (!(m_msanUsableBitmap[msanAddr / 8] & (1 << msanAddr % 8))) {
97-
[[unlikely]];
98-
return MsanStatus::UNUSABLE;
94+
template<uint32_t length>
95+
MsanStatus msanGetStatus(uint32_t addr) const {
96+
uint32_t bitmapIndex = (addr - c_msanStart) / 8;
97+
uint32_t bitmask = ((1 << length) - 1) << addr % 8;
98+
MsanStatus bestCase = MsanStatus::OK;
99+
if (uint32_t nextBitmask = bitmask >> 8) [[unlikely]] {
100+
if ((m_msanInitializedBitmap[bitmapIndex + 1] & nextBitmask) != nextBitmask) {
101+
if ((m_msanUsableBitmap[bitmapIndex + 1] & nextBitmask) != nextBitmask) {
102+
return MsanStatus::UNUSABLE;
103+
}
104+
bestCase = MsanStatus::UNINITIALIZED;
105+
}
106+
bitmask &= 0xFF;
99107
}
100-
for (uint32_t checkAddr = msanAddr; checkAddr < msanAddr + size; checkAddr++) {
101-
if (!(m_msanWrittenBitmap[checkAddr / 8] & (1 << checkAddr % 8))) {
102-
return MsanStatus::UNINITIALIZED;
108+
if ((m_msanInitializedBitmap[bitmapIndex] & bitmask) != bitmask) [[unlikely]] {
109+
if ((m_msanUsableBitmap[bitmapIndex] & bitmask) != bitmask) {
110+
return MsanStatus::UNUSABLE;
103111
}
112+
return MsanStatus::UNINITIALIZED;
104113
}
105-
return MsanStatus::OK;
114+
return bestCase;
106115
}
107116

108-
inline bool msanValidateWrite(uint32_t addr, uint32_t size) {
109-
uint32_t msanAddr = addr - c_msanStart;
110-
if (!(m_msanUsableBitmap[msanAddr / 8] & (1 << msanAddr % 8))) {
111-
[[unlikely]];
112-
return false;
117+
// if the write is valid, marks the address as initialized, otherwise returns false
118+
template<uint32_t length>
119+
bool msanValidateWrite(uint32_t addr) {
120+
uint32_t bitmapIndex = (addr - c_msanStart) / 8;
121+
uint32_t bitmask = ((1 << length) - 1) << addr % 8;
122+
if (uint32_t nextBitmask = bitmask >> 8) [[unlikely]] {
123+
if ((m_msanUsableBitmap[bitmapIndex + 1] & nextBitmask) != nextBitmask) {
124+
return false;
125+
}
126+
m_msanInitializedBitmap[bitmapIndex + 1] |= nextBitmask;
127+
bitmask &= 0xFF;
113128
}
114-
for (uint32_t checkAddr = msanAddr; checkAddr < msanAddr + size; checkAddr++) {
115-
m_msanWrittenBitmap[checkAddr / 8] |= 1 << checkAddr % 8;
129+
if ((m_msanUsableBitmap[bitmapIndex] & bitmask) != bitmask) [[unlikely]] {
130+
return false;
116131
}
132+
m_msanInitializedBitmap[bitmapIndex] |= bitmask;
117133
return true;
118134
}
119135

@@ -304,7 +320,7 @@ class Memory {
304320
static constexpr uint32_t c_msanEnd = c_msanStart + c_msanSize;
305321
uint8_t *m_msanRAM = nullptr;
306322
uint8_t *m_msanUsableBitmap = nullptr;
307-
uint8_t *m_msanWrittenBitmap = nullptr;
323+
uint8_t *m_msanInitializedBitmap = nullptr;
308324
uint32_t m_msanPtr = 1024;
309325
EventBus::Listener m_listener;
310326

0 commit comments

Comments
 (0)