Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debugger: Avoid mem write tag lookup on small alloc #15377

Merged
merged 2 commits into from
Feb 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions Core/Debugger/Breakpoints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "Common/Log.h"
#include "Core/Core.h"
#include "Core/Debugger/Breakpoints.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/Debugger/SymbolMap.h"
#include "Core/Host.h"
#include "Core/MemMap.h"
Expand Down Expand Up @@ -389,15 +390,19 @@ void CBreakPoints::AddMemCheck(u32 start, u32 end, MemCheckCondition cond, Break
check.result = result;

memChecks_.push_back(check);
anyMemChecks_ = true;
bool hadAny = anyMemChecks_.exchange(true);
if (!hadAny)
MemBlockOverrideDetailed();
guard.unlock();
Update();
}
else
{
memChecks_[mc].cond = (MemCheckCondition)(memChecks_[mc].cond | cond);
memChecks_[mc].result = (BreakAction)(memChecks_[mc].result | result);
anyMemChecks_ = true;
bool hadAny = anyMemChecks_.exchange(true);
if (!hadAny)
MemBlockOverrideDetailed();
guard.unlock();
Update();
}
Expand All @@ -413,7 +418,9 @@ void CBreakPoints::RemoveMemCheck(u32 start, u32 end)
if (mc != INVALID_MEMCHECK)
{
memChecks_.erase(memChecks_.begin() + mc);
anyMemChecks_ = !memChecks_.empty();
bool hadAny = anyMemChecks_.exchange(!memChecks_.empty());
if (hadAny)
MemBlockReleaseDetailed();
guard.unlock();
Update();
}
Expand Down Expand Up @@ -441,6 +448,9 @@ void CBreakPoints::ClearAllMemChecks()
if (!memChecks_.empty())
{
memChecks_.clear();
bool hadAny = anyMemChecks_.exchange(false);
if (hadAny)
MemBlockReleaseDetailed();
guard.unlock();
Update();
}
Expand Down
2 changes: 1 addition & 1 deletion Core/Debugger/MemBlockInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ void NotifyMemInfoPC(MemBlockFlags flags, uint32_t start, uint32_t size, uint32_

bool needFlush = false;
// When the setting is off, we skip smaller info to keep things fast.
if (size >= 0x100 || MemBlockInfoDetailed()) {
if (MemBlockInfoDetailed(size)) {
PendingNotifyMem info{ flags, start, size };
info.ticks = CoreTiming::GetTicks();
info.pc = pc;
Expand Down
10 changes: 10 additions & 0 deletions Core/Debugger/MemBlockInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

class PointerWrap;

static constexpr uint32_t MEMINFO_MIN_SIZE = 0x100;

enum class MemBlockFlags {
ALLOC = 0x0001,
SUB_ALLOC = 0x0002,
Expand Down Expand Up @@ -75,3 +77,11 @@ void MemBlockInfoDoState(PointerWrap &p);
void MemBlockOverrideDetailed();
void MemBlockReleaseDetailed();
bool MemBlockInfoDetailed();

static inline bool MemBlockInfoDetailed(uint32_t size) {
return size >= MEMINFO_MIN_SIZE || MemBlockInfoDetailed();
}

static inline bool MemBlockInfoDetailed(uint32_t size1, uint32_t size2) {
return size1 >= MEMINFO_MIN_SIZE || size2 >= MEMINFO_MIN_SIZE || MemBlockInfoDetailed();
}
58 changes: 34 additions & 24 deletions Core/HLE/ReplaceTables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,14 +156,16 @@ static int Replace_memcpy() {
}
RETURN(destPtr);

const std::string tag = "ReplaceMemcpy/" + GetMemWriteTagAt(srcPtr, bytes);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, tag.c_str(), tag.size());

// It's pretty common that games will copy video data.
if (tag == "ReplaceMemcpy/VideoDecode" || tag == "ReplaceMemcpy/VideoDecodeRange") {
if (bytes == 512 * 272 * 4) {
gpu->NotifyVideoUpload(destPtr, bytes, 512, GE_FORMAT_8888);
if (MemBlockInfoDetailed(bytes)) {
const std::string tag = "ReplaceMemcpy/" + GetMemWriteTagAt(srcPtr, bytes);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, tag.c_str(), tag.size());

// It's pretty common that games will copy video data.
if (tag == "ReplaceMemcpy/VideoDecode" || tag == "ReplaceMemcpy/VideoDecodeRange") {
if (bytes == 512 * 272 * 4) {
gpu->NotifyVideoUpload(destPtr, bytes, 512, GE_FORMAT_8888);
}
}
}

Expand Down Expand Up @@ -206,14 +208,16 @@ static int Replace_memcpy_jak() {
currentMIPS->r[MIPS_REG_A3] = destPtr + bytes;
RETURN(destPtr);

const std::string tag = "ReplaceMemcpy/" + GetMemWriteTagAt(srcPtr, bytes);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, tag.c_str(), tag.size());
if (MemBlockInfoDetailed(bytes)) {
const std::string tag = "ReplaceMemcpy/" + GetMemWriteTagAt(srcPtr, bytes);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, tag.c_str(), tag.size());

// It's pretty common that games will copy video data.
if (tag == "ReplaceMemcpy/VideoDecode" || tag == "ReplaceMemcpy/VideoDecodeRange") {
if (bytes == 512 * 272 * 4) {
gpu->NotifyVideoUpload(destPtr, bytes, 512, GE_FORMAT_8888);
// It's pretty common that games will copy video data.
if (tag == "ReplaceMemcpy/VideoDecode" || tag == "ReplaceMemcpy/VideoDecodeRange") {
if (bytes == 512 * 272 * 4) {
gpu->NotifyVideoUpload(destPtr, bytes, 512, GE_FORMAT_8888);
}
}
}

Expand Down Expand Up @@ -242,9 +246,11 @@ static int Replace_memcpy16() {
}
RETURN(destPtr);

const std::string tag = "ReplaceMemcpy16/" + GetMemWriteTagAt(srcPtr, bytes);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, tag.c_str(), tag.size());
if (MemBlockInfoDetailed(bytes)) {
const std::string tag = "ReplaceMemcpy16/" + GetMemWriteTagAt(srcPtr, bytes);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, tag.c_str(), tag.size());
}

return 10 + bytes / 4; // approximation
}
Expand Down Expand Up @@ -281,9 +287,11 @@ static int Replace_memcpy_swizzled() {

RETURN(0);

const std::string tag = "ReplaceMemcpySwizzle/" + GetMemWriteTagAt(srcPtr, pitch * h);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, pitch * h, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, pitch * h, tag.c_str(), tag.size());
if (MemBlockInfoDetailed(pitch * h)) {
const std::string tag = "ReplaceMemcpySwizzle/" + GetMemWriteTagAt(srcPtr, pitch * h);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, pitch * h, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, pitch * h, tag.c_str(), tag.size());
}

return 10 + (pitch * h) / 4; // approximation
}
Expand All @@ -310,9 +318,11 @@ static int Replace_memmove() {
}
RETURN(destPtr);

const std::string tag = "ReplaceMemmove/" + GetMemWriteTagAt(srcPtr, bytes);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, tag.c_str(), tag.size());
if (MemBlockInfoDetailed(bytes)) {
const std::string tag = "ReplaceMemmove/" + GetMemWriteTagAt(srcPtr, bytes);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, tag.c_str(), tag.size());
}

return 10 + bytes / 4; // approximation
}
Expand Down
8 changes: 5 additions & 3 deletions Core/HLE/sceDeflt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ static int CommonDecompress(int windowBits, u32 OutBuffer, int OutBufferLength,
*crc32Addr = crc32(crc, outBufferPtr, stream.total_out);
}

const std::string tag = "sceDeflt/" + GetMemWriteTagAt(InBuffer, stream.total_in);
NotifyMemInfo(MemBlockFlags::READ, InBuffer, stream.total_in, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, OutBuffer, stream.total_out, tag.c_str(), tag.size());
if (MemBlockInfoDetailed(stream.total_in, stream.total_out)) {
const std::string tag = "sceDeflt/" + GetMemWriteTagAt(InBuffer, stream.total_in);
NotifyMemInfo(MemBlockFlags::READ, InBuffer, stream.total_in, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, OutBuffer, stream.total_out, tag.c_str(), tag.size());
}

return hleLogSuccessI(HLE, stream.total_out);
}
Expand Down
8 changes: 6 additions & 2 deletions Core/HLE/sceDmac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,12 @@ static int __DmacMemcpy(u32 dst, u32 src, u32 size) {
}
if (!skip) {
currentMIPS->InvalidateICache(src, size);
const std::string tag = "DmacMemcpy/" + GetMemWriteTagAt(src, size);
Memory::Memcpy(dst, src, size, tag.c_str(), tag.size());
if (MemBlockInfoDetailed(size)) {
const std::string tag = "DmacMemcpy/" + GetMemWriteTagAt(src, size);
Memory::Memcpy(dst, src, size, tag.c_str(), tag.size());
} else {
Memory::Memcpy(dst, src, size, "DmacMemcpy");
}
currentMIPS->InvalidateICache(dst, size);
}

Expand Down
24 changes: 15 additions & 9 deletions Core/HLE/sceKernelInterrupt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -655,9 +655,11 @@ static u32 sceKernelMemcpy(u32 dst, u32 src, u32 size)
}
}

const std::string tag = "KernelMemcpy/" + GetMemWriteTagAt(src, size);
NotifyMemInfo(MemBlockFlags::READ, src, size, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dst, size, tag.c_str(), tag.size());
if (MemBlockInfoDetailed(size)) {
const std::string tag = "KernelMemcpy/" + GetMemWriteTagAt(src, size);
NotifyMemInfo(MemBlockFlags::READ, src, size, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dst, size, tag.c_str(), tag.size());
}

return dst;
}
Expand Down Expand Up @@ -688,9 +690,11 @@ static u32 sysclib_memcpy(u32 dst, u32 src, u32 size) {
if (Memory::IsValidRange(dst, size) && Memory::IsValidRange(src, size)) {
memcpy(Memory::GetPointer(dst), Memory::GetPointer(src), size);
}
const std::string tag = "KernelMemcpy/" + GetMemWriteTagAt(src, size);
NotifyMemInfo(MemBlockFlags::READ, src, size, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dst, size, tag.c_str(), tag.size());
if (MemBlockInfoDetailed(size)) {
const std::string tag = "KernelMemcpy/" + GetMemWriteTagAt(src, size);
NotifyMemInfo(MemBlockFlags::READ, src, size, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dst, size, tag.c_str(), tag.size());
}
return dst;
}

Expand Down Expand Up @@ -789,9 +793,11 @@ static u32 sysclib_memmove(u32 dst, u32 src, u32 size) {
if (Memory::IsValidRange(dst, size) && Memory::IsValidRange(src, size)) {
memmove(Memory::GetPointer(dst), Memory::GetPointer(src), size);
}
const std::string tag = "KernelMemmove/" + GetMemWriteTagAt(src, size);
NotifyMemInfo(MemBlockFlags::READ, src, size, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dst, size, tag.c_str(), tag.size());
if (MemBlockInfoDetailed(size)) {
const std::string tag = "KernelMemmove/" + GetMemWriteTagAt(src, size);
NotifyMemInfo(MemBlockFlags::READ, src, size, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dst, size, tag.c_str(), tag.size());
}
return 0;
}

Expand Down
30 changes: 17 additions & 13 deletions Core/MemMapHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,21 +58,25 @@ inline void Memcpy(void *to_data, const u32 from_address, const u32 len, const c

inline void Memcpy(const u32 to_address, const u32 from_address, const u32 len, const char *tag, size_t tagLen) {
u8 *to = GetPointer(to_address);
if (to) {
const u8 *from = GetPointer(from_address);
if (from) {
memcpy(to, from, len);
char tagData[128];
if (!tag) {
const std::string srcTag = GetMemWriteTagAt(from_address, len);
tag = tagData;
tagLen = snprintf(tagData, sizeof(tagData), "Memcpy/%s", srcTag.c_str());
}
NotifyMemInfo(MemBlockFlags::READ, from_address, len, tag, tagLen);
NotifyMemInfo(MemBlockFlags::WRITE, to_address, len, tag, tagLen);
// If not, GetPointer will log.
if (!to)
return;
const u8 *from = GetPointer(from_address);
if (!from)
return;

memcpy(to, from, len);

if (MemBlockInfoDetailed(len)) {
char tagData[128];
if (!tag) {
const std::string srcTag = GetMemWriteTagAt(from_address, len);
tag = tagData;
tagLen = snprintf(tagData, sizeof(tagData), "Memcpy/%s", srcTag.c_str());
}
NotifyMemInfo(MemBlockFlags::READ, from_address, len, tag, tagLen);
NotifyMemInfo(MemBlockFlags::WRITE, to_address, len, tag, tagLen);
}
// if not, GetPointer will log.
}

template<size_t tagLen>
Expand Down
28 changes: 19 additions & 9 deletions GPU/GPUCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2767,11 +2767,15 @@ void GPUCommon::DoBlockTransfer(u32 skipDrawReason) {
framebufferManager_->NotifyBlockTransferAfter(dstBasePtr, dstStride, dstX, dstY, srcBasePtr, srcStride, srcX, srcY, width, height, bpp, skipDrawReason);
}

const uint32_t src = srcBasePtr + (srcY * srcStride + srcX) * bpp;
const uint32_t srcSize = height * srcStride * bpp;
const std::string tag = "GPUBlockTransfer/" + GetMemWriteTagAt(src, srcSize);
NotifyMemInfo(MemBlockFlags::READ, src, srcSize, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dstBasePtr + (dstY * dstStride + dstX) * bpp, height * dstStride * bpp, tag.c_str(), tag.size());
const uint32_t dstSize = height * dstStride * bpp;
if (MemBlockInfoDetailed(srcSize, dstSize)) {
const uint32_t src = srcBasePtr + (srcY * srcStride + srcX) * bpp;
const uint32_t dst = dstBasePtr + (dstY * dstStride + dstX) * bpp;
const std::string tag = "GPUBlockTransfer/" + GetMemWriteTagAt(src, srcSize);
NotifyMemInfo(MemBlockFlags::READ, src, srcSize, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dst, dstSize, tag.c_str(), tag.size());
}

// TODO: Correct timing appears to be 1.9, but erring a bit low since some of our other timing is inaccurate.
cyclesExecuted += ((height * width * bpp) * 16) / 10;
Expand All @@ -2784,17 +2788,23 @@ bool GPUCommon::PerformMemoryCopy(u32 dest, u32 src, int size) {
// We use a little hack for PerformMemoryDownload/PerformMemoryUpload using a VRAM mirror.
// Since they're identical we don't need to copy.
if (!Memory::IsVRAMAddress(dest) || (dest ^ 0x00400000) != src) {
const std::string tag = "GPUMemcpy/" + GetMemWriteTagAt(src, size);
Memory::Memcpy(dest, src, size, tag.c_str(), tag.size());
if (MemBlockInfoDetailed(size)) {
const std::string tag = "GPUMemcpy/" + GetMemWriteTagAt(src, size);
Memory::Memcpy(dest, src, size, tag.c_str(), tag.size());
} else {
Memory::Memcpy(dest, src, size, "GPUMemcpy");
}
}
}
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
return true;
}

const std::string tag = "GPUMemcpy/" + GetMemWriteTagAt(src, size);
NotifyMemInfo(MemBlockFlags::READ, src, size, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dest, size, tag.c_str(), tag.size());
if (MemBlockInfoDetailed(size)) {
const std::string tag = "GPUMemcpy/" + GetMemWriteTagAt(src, size);
NotifyMemInfo(MemBlockFlags::READ, src, size, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dest, size, tag.c_str(), tag.size());
}
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
GPURecord::NotifyMemcpy(dest, src, size);
return false;
Expand Down
8 changes: 5 additions & 3 deletions GPU/Software/SoftGpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -745,9 +745,11 @@ void SoftGPU::Execute_BlockTransferStart(u32 op, u32 diff) {
memcpy(dstp, srcp, width * bpp);
}

const std::string tag = "GPUBlockTransfer/" + GetMemWriteTagAt(src, srcSize);
NotifyMemInfo(MemBlockFlags::READ, src, srcSize, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dst, dstSize, tag.c_str(), tag.size());
if (MemBlockInfoDetailed(srcSize, dstSize)) {
const std::string tag = "GPUBlockTransfer/" + GetMemWriteTagAt(src, srcSize);
NotifyMemInfo(MemBlockFlags::READ, src, srcSize, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dst, dstSize, tag.c_str(), tag.size());
}

// TODO: Correct timing appears to be 1.9, but erring a bit low since some of our other timing is inaccurate.
cyclesExecuted += ((height * width * bpp) * 16) / 10;
Expand Down