From 780d350fbbba02202a08c8d1ffc8affdfea218ca Mon Sep 17 00:00:00 2001 From: hugodearaujo Date: Thu, 29 Oct 2026 13:07:12 -0300 Subject: [PATCH] perf(agc): decode a label write without allocating before noting a taken store noteLabelIssue runs for every executed store packet. RELEASE_MEM and WRITE_DATA, the common label writes, now go through DecodeLabelWrite, which DecodeStores already used for them and which allocates nothing, and stores the label history doesn't keep are dropped before labelStoresMutex is taken. --- .../Driver/Synchronization/LabelHistory.cpp | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Synchronization/LabelHistory.cpp b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Synchronization/LabelHistory.cpp index 3bac0c6355..db078dae9d 100644 --- a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Synchronization/LabelHistory.cpp +++ b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Synchronization/LabelHistory.cpp @@ -39,21 +39,28 @@ void Driver::noteLabelPass(std::span packet, std::uint32_t } void Driver::noteLabelIssue(std::span packet, std::uint32_t queue) { - switch ((packet[0] >> 8u) & 0xffu) { - case 0x37: case 0x40: case 0x49: case 0x50: case 0x83: break; - default: return; - } - const auto stores = Pm4::DecodeStores(packet); - if (stores.empty()) return; - std::lock_guard lock(labelStoresMutex); - if (labelPasses.empty()) return; - for (const auto& store : stores) { - if (store.conditional || !KeepsLabelStore(store.address, static_cast(store.bytes))) continue; - for (std::uint64_t offset = 0; offset < store.bytes; offset += 4) { - const auto key = queueDword(queue, store.address + offset); + const auto take = [&](std::uint64_t address, std::uint64_t bytes) { + for (std::uint64_t offset = 0; offset < bytes; offset += 4) { + const auto key = queueDword(queue, address + offset); if (const auto pass = labelPasses.find(key); pass != labelPasses.end()) labelTaken[key] = pass->second; } + }; + switch ((packet[0] >> 8u) & 0xffu) { + case 0x37: case 0x49: { + const auto label = Pm4::DecodeLabelWrite(packet); + if (!label.has_value() || !KeepsLabelStore(label->address, label->Bytes().size())) return; + std::lock_guard lock(labelStoresMutex); + take(label->address, label->Bytes().size()); + return; + } + case 0x40: case 0x50: case 0x83: break; + default: return; } + auto stores = Pm4::DecodeStores(packet); + std::erase_if(stores, [](const Pm4::PacketStore& store) { return store.conditional || !KeepsLabelStore(store.address, static_cast(store.bytes)); }); + if (stores.empty()) return; + std::lock_guard lock(labelStoresMutex); + for (const auto& store : stores) take(store.address, store.bytes); } bool Driver::storedSince(std::span packet, std::uint64_t address, std::size_t bytes, std::uint64_t received, std::uint32_t queue, std::uint32_t* writer) {