mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 05:19:56 +00:00
Remove allocation from the heaviest MemBlockInfo path (BlockTransfer). Required some refactoring.
This commit is contained in:
parent
7bced814ce
commit
ecb84987ef
@ -44,15 +44,16 @@
|
||||
#include "Common/Buffer.h"
|
||||
#include "Common/StringUtils.h"
|
||||
|
||||
void truncate_cpy(char *dest, size_t destSize, const char *src) {
|
||||
size_t truncate_cpy(char *dest, size_t destSize, const char *src) {
|
||||
size_t len = strlen(src);
|
||||
if (len >= destSize - 1) {
|
||||
memcpy(dest, src, destSize - 1);
|
||||
dest[destSize - 1] = '\0';
|
||||
len = destSize - 1;
|
||||
} else {
|
||||
memcpy(dest, src, len);
|
||||
dest[len] = '\0';
|
||||
}
|
||||
dest[len] = '\0';
|
||||
return len;
|
||||
}
|
||||
|
||||
const char* safe_string(const char* s) {
|
||||
|
@ -78,10 +78,10 @@ std::string ReplaceAll(std::string input, const std::string& src, const std::str
|
||||
|
||||
void SkipSpace(const char **ptr);
|
||||
|
||||
void truncate_cpy(char *dest, size_t destSize, const char *src);
|
||||
size_t truncate_cpy(char *dest, size_t destSize, const char *src);
|
||||
template<size_t Count>
|
||||
inline void truncate_cpy(char(&out)[Count], const char *src) {
|
||||
truncate_cpy(out, Count, src);
|
||||
inline size_t truncate_cpy(char(&out)[Count], const char *src) {
|
||||
return truncate_cpy(out, Count, src);
|
||||
}
|
||||
|
||||
const char* safe_string(const char* s);
|
||||
|
@ -37,7 +37,8 @@ public:
|
||||
|
||||
bool Mark(uint32_t addr, uint32_t size, uint64_t ticks, uint32_t pc, bool allocated, const char *tag);
|
||||
bool Find(MemBlockFlags flags, uint32_t addr, uint32_t size, std::vector<MemBlockInfo> &results);
|
||||
bool FastFindWriteTag(MemBlockFlags flags, uint32_t addr, uint32_t size, std::string &result);
|
||||
// Note that the returned pointer gets invalidated as soon as Mark is called.
|
||||
const char *FastFindWriteTag(MemBlockFlags flags, uint32_t addr, uint32_t size);
|
||||
void Reset();
|
||||
void DoState(PointerWrap &p);
|
||||
|
||||
@ -151,17 +152,16 @@ bool MemSlabMap::Find(MemBlockFlags flags, uint32_t addr, uint32_t size, std::ve
|
||||
return found;
|
||||
}
|
||||
|
||||
bool MemSlabMap::FastFindWriteTag(MemBlockFlags flags, uint32_t addr, uint32_t size, std::string &result) {
|
||||
const char *MemSlabMap::FastFindWriteTag(MemBlockFlags flags, uint32_t addr, uint32_t size) {
|
||||
uint32_t end = addr + size;
|
||||
Slab *slab = FindSlab(addr);
|
||||
while (slab != nullptr && slab->start < end) {
|
||||
if (slab->pc != 0 || slab->tag[0] != '\0') {
|
||||
result = slab->tag;
|
||||
return true;
|
||||
return slab->tag;
|
||||
}
|
||||
slab = slab->next;
|
||||
}
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void MemSlabMap::Reset() {
|
||||
@ -485,7 +485,7 @@ std::vector<MemBlockInfo> FindMemInfoByFlag(MemBlockFlags flags, uint32_t start,
|
||||
return results;
|
||||
}
|
||||
|
||||
static std::string FindWriteTagByFlag(MemBlockFlags flags, uint32_t start, uint32_t size) {
|
||||
static const char *FindWriteTagByFlag(MemBlockFlags flags, uint32_t start, uint32_t size) {
|
||||
start &= ~0xC0000000;
|
||||
|
||||
if (pendingNotifyMinAddr1 < start + size && pendingNotifyMaxAddr1 >= start)
|
||||
@ -493,37 +493,51 @@ static std::string FindWriteTagByFlag(MemBlockFlags flags, uint32_t start, uint3
|
||||
if (pendingNotifyMinAddr2 < start + size && pendingNotifyMaxAddr2 >= start)
|
||||
FlushPendingMemInfo();
|
||||
|
||||
std::string tag;
|
||||
if (flags & MemBlockFlags::ALLOC) {
|
||||
if (allocMap.FastFindWriteTag(MemBlockFlags::ALLOC, start, size, tag))
|
||||
const char *tag = allocMap.FastFindWriteTag(MemBlockFlags::ALLOC, start, size);
|
||||
if (tag)
|
||||
return tag;
|
||||
}
|
||||
if (flags & MemBlockFlags::SUB_ALLOC) {
|
||||
if (suballocMap.FastFindWriteTag(MemBlockFlags::SUB_ALLOC, start, size, tag))
|
||||
const char *tag = suballocMap.FastFindWriteTag(MemBlockFlags::SUB_ALLOC, start, size);
|
||||
if (tag)
|
||||
return tag;
|
||||
}
|
||||
if (flags & MemBlockFlags::WRITE) {
|
||||
if (writeMap.FastFindWriteTag(MemBlockFlags::WRITE, start, size, tag))
|
||||
const char *tag = writeMap.FastFindWriteTag(MemBlockFlags::WRITE, start, size);
|
||||
if (tag)
|
||||
return tag;
|
||||
}
|
||||
if (flags & MemBlockFlags::TEXTURE) {
|
||||
if (textureMap.FastFindWriteTag(MemBlockFlags::TEXTURE, start, size, tag))
|
||||
const char *tag = textureMap.FastFindWriteTag(MemBlockFlags::TEXTURE, start, size);
|
||||
if (tag)
|
||||
return tag;
|
||||
}
|
||||
return "";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string GetMemWriteTagAt(uint32_t start, uint32_t size) {
|
||||
std::string tag = FindWriteTagByFlag(MemBlockFlags::WRITE, start, size);
|
||||
if (!tag.empty() && tag != "MemInit")
|
||||
return tag;
|
||||
|
||||
std::string GetMemWriteTagAt(const char *prefix, uint32_t start, uint32_t size) {
|
||||
const char *tag = FindWriteTagByFlag(MemBlockFlags::WRITE, start, size);
|
||||
if (tag && strcmp(tag, "MemInit") != 0)
|
||||
return std::string(prefix) + tag;
|
||||
// Fall back to alloc and texture, especially for VRAM. We prefer write above.
|
||||
tag = FindWriteTagByFlag(MemBlockFlags::ALLOC | MemBlockFlags::TEXTURE, start, size);
|
||||
if (!tag.empty())
|
||||
return tag;
|
||||
if (tag)
|
||||
return std::string(prefix) + tag;
|
||||
return StringFromFormat("%s%08x_size_%08x", prefix, start, size);
|
||||
}
|
||||
|
||||
return StringFromFormat("%08x_size_%08x", start, size);
|
||||
size_t FormatMemWriteTagAt(char *buf, size_t sz, const char *prefix, uint32_t start, uint32_t size) {
|
||||
const char *tag = FindWriteTagByFlag(MemBlockFlags::WRITE, start, size);
|
||||
if (tag && strcmp(tag, "MemInit") != 0) {
|
||||
return snprintf(buf, sz, "%s%s", prefix, tag);
|
||||
}
|
||||
// Fall back to alloc and texture, especially for VRAM. We prefer write above.
|
||||
tag = FindWriteTagByFlag(MemBlockFlags::ALLOC | MemBlockFlags::TEXTURE, start, size);
|
||||
if (tag) {
|
||||
return snprintf(buf, sz, "%s%s", prefix, tag);
|
||||
}
|
||||
return snprintf(buf, sz, "%s%08x_size_%08x", prefix, start, size);
|
||||
}
|
||||
|
||||
void MemBlockInfoInit() {
|
||||
|
@ -68,7 +68,9 @@ inline void NotifyMemInfo(MemBlockFlags flags, uint32_t start, uint32_t size, co
|
||||
std::vector<MemBlockInfo> FindMemInfo(uint32_t start, uint32_t size);
|
||||
std::vector<MemBlockInfo> FindMemInfoByFlag(MemBlockFlags flags, uint32_t start, uint32_t size);
|
||||
|
||||
std::string GetMemWriteTagAt(uint32_t start, uint32_t size);
|
||||
std::string GetMemWriteTagAt(const char *prefix, uint32_t start, uint32_t size);
|
||||
// Same as above but allocation-free.
|
||||
size_t FormatMemWriteTagAt(char *buf, size_t sz, const char *prefix, uint32_t start, uint32_t size);
|
||||
|
||||
void MemBlockInfoInit();
|
||||
void MemBlockInfoShutdown();
|
||||
|
@ -159,7 +159,7 @@ static int Replace_memcpy() {
|
||||
RETURN(destPtr);
|
||||
|
||||
if (MemBlockInfoDetailed(bytes)) {
|
||||
const std::string tag = "ReplaceMemcpy/" + GetMemWriteTagAt(srcPtr, bytes);
|
||||
const std::string tag = GetMemWriteTagAt("ReplaceMemcpy/", srcPtr, bytes);
|
||||
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, tag.c_str(), tag.size());
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, tag.c_str(), tag.size());
|
||||
|
||||
@ -211,7 +211,7 @@ static int Replace_memcpy_jak() {
|
||||
RETURN(destPtr);
|
||||
|
||||
if (MemBlockInfoDetailed(bytes)) {
|
||||
const std::string tag = "ReplaceMemcpy/" + GetMemWriteTagAt(srcPtr, bytes);
|
||||
const std::string tag = GetMemWriteTagAt("ReplaceMemcpy/", srcPtr, bytes);
|
||||
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, tag.c_str(), tag.size());
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, tag.c_str(), tag.size());
|
||||
|
||||
@ -249,7 +249,7 @@ static int Replace_memcpy16() {
|
||||
RETURN(destPtr);
|
||||
|
||||
if (MemBlockInfoDetailed(bytes)) {
|
||||
const std::string tag = "ReplaceMemcpy16/" + GetMemWriteTagAt(srcPtr, bytes);
|
||||
const std::string tag = GetMemWriteTagAt("ReplaceMemcpy16/", srcPtr, bytes);
|
||||
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, tag.c_str(), tag.size());
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, tag.c_str(), tag.size());
|
||||
}
|
||||
@ -290,7 +290,7 @@ static int Replace_memcpy_swizzled() {
|
||||
RETURN(0);
|
||||
|
||||
if (MemBlockInfoDetailed(pitch * h)) {
|
||||
const std::string tag = "ReplaceMemcpySwizzle/" + GetMemWriteTagAt(srcPtr, pitch * h);
|
||||
const std::string tag = GetMemWriteTagAt("ReplaceMemcpySwizzle/", 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());
|
||||
}
|
||||
@ -321,7 +321,7 @@ static int Replace_memmove() {
|
||||
RETURN(destPtr);
|
||||
|
||||
if (MemBlockInfoDetailed(bytes)) {
|
||||
const std::string tag = "ReplaceMemmove/" + GetMemWriteTagAt(srcPtr, bytes);
|
||||
const std::string tag = GetMemWriteTagAt("ReplaceMemmove/", srcPtr, bytes);
|
||||
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, tag.c_str(), tag.size());
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, tag.c_str(), tag.size());
|
||||
}
|
||||
|
@ -1268,7 +1268,7 @@ u32 _AtracDecodeData(int atracID, u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u3
|
||||
if (outbufPtr != 0) {
|
||||
u32 outBytes = numSamples * atrac->outputChannels_ * sizeof(s16);
|
||||
if (packetAddr != 0 && MemBlockInfoDetailed()) {
|
||||
const std::string tag = "AtracDecode/" + GetMemWriteTagAt(packetAddr, packetSize);
|
||||
const std::string tag = GetMemWriteTagAt("AtracDecode/", packetAddr, packetSize);
|
||||
NotifyMemInfo(MemBlockFlags::READ, packetAddr, packetSize, tag.c_str(), tag.size());
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, outbufPtr, outBytes, tag.c_str(), tag.size());
|
||||
} else {
|
||||
|
@ -59,7 +59,7 @@ static int CommonDecompress(int windowBits, u32 OutBuffer, int OutBufferLength,
|
||||
}
|
||||
|
||||
if (MemBlockInfoDetailed(stream.total_in, stream.total_out)) {
|
||||
const std::string tag = "sceDeflt/" + GetMemWriteTagAt(InBuffer, stream.total_in);
|
||||
const std::string tag = GetMemWriteTagAt("sceDeflt/", 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());
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ static int __DmacMemcpy(u32 dst, u32 src, u32 size) {
|
||||
if (!skip) {
|
||||
currentMIPS->InvalidateICache(src, size);
|
||||
if (MemBlockInfoDetailed(size)) {
|
||||
const std::string tag = "DmacMemcpy/" + GetMemWriteTagAt(src, size);
|
||||
const std::string tag = GetMemWriteTagAt("DmacMemcpy/", src, size);
|
||||
Memory::Memcpy(dst, src, size, tag.c_str(), tag.size());
|
||||
} else {
|
||||
Memory::Memcpy(dst, src, size, "DmacMemcpy");
|
||||
|
@ -656,7 +656,7 @@ static u32 sceKernelMemcpy(u32 dst, u32 src, u32 size)
|
||||
}
|
||||
|
||||
if (MemBlockInfoDetailed(size)) {
|
||||
const std::string tag = "KernelMemcpy/" + GetMemWriteTagAt(src, size);
|
||||
const std::string tag = GetMemWriteTagAt("KernelMemcpy/", src, size);
|
||||
NotifyMemInfo(MemBlockFlags::READ, src, size, tag.c_str(), tag.size());
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, dst, size, tag.c_str(), tag.size());
|
||||
}
|
||||
@ -691,7 +691,7 @@ static u32 sysclib_memcpy(u32 dst, u32 src, u32 size) {
|
||||
memcpy(Memory::GetPointerWriteUnchecked(dst), Memory::GetPointerUnchecked(src), size);
|
||||
}
|
||||
if (MemBlockInfoDetailed(size)) {
|
||||
const std::string tag = "KernelMemcpy/" + GetMemWriteTagAt(src, size);
|
||||
const std::string tag = GetMemWriteTagAt("KernelMemcpy/", src, size);
|
||||
NotifyMemInfo(MemBlockFlags::READ, src, size, tag.c_str(), tag.size());
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, dst, size, tag.c_str(), tag.size());
|
||||
}
|
||||
@ -794,7 +794,7 @@ static u32 sysclib_memmove(u32 dst, u32 src, u32 size) {
|
||||
memmove(Memory::GetPointerWriteUnchecked(dst), Memory::GetPointerUnchecked(src), size);
|
||||
}
|
||||
if (MemBlockInfoDetailed(size)) {
|
||||
const std::string tag = "KernelMemmove/" + GetMemWriteTagAt(src, size);
|
||||
const std::string tag = GetMemWriteTagAt("KernelMemmove/", src, size);
|
||||
NotifyMemInfo(MemBlockFlags::READ, src, size, tag.c_str(), tag.size());
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, dst, size, tag.c_str(), tag.size());
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <cstring>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Core/Debugger/MemBlockInfo.h"
|
||||
#include "Core/MemMap.h"
|
||||
#include "Core/MIPS/MIPS.h"
|
||||
@ -70,9 +71,9 @@ inline void Memcpy(const u32 to_address, const u32 from_address, const u32 len,
|
||||
if (MemBlockInfoDetailed(len)) {
|
||||
char tagData[128];
|
||||
if (!tag) {
|
||||
const std::string srcTag = GetMemWriteTagAt(from_address, len);
|
||||
const std::string srcTag = GetMemWriteTagAt("Memcpy/", from_address, len);
|
||||
tag = tagData;
|
||||
tagLen = snprintf(tagData, sizeof(tagData), "Memcpy/%s", srcTag.c_str());
|
||||
tagLen = truncate_cpy(tagData, srcTag.c_str());
|
||||
}
|
||||
NotifyMemInfo(MemBlockFlags::READ, from_address, len, tag, tagLen);
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, to_address, len, tag, tagLen);
|
||||
|
@ -2864,9 +2864,10 @@ void GPUCommon::DoBlockTransfer(u32 skipDrawReason) {
|
||||
if (MemBlockInfoDetailed(numBytes, numBytes)) {
|
||||
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());
|
||||
char tag[128];
|
||||
size_t tagSize = FormatMemWriteTagAt(tag, sizeof(tag), "GPUBlockTransfer/", src, srcSize);
|
||||
NotifyMemInfo(MemBlockFlags::READ, src, srcSize, tag, tagSize);
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, dst, dstSize, tag, tagSize);
|
||||
}
|
||||
|
||||
// TODO: Correct timing appears to be 1.9, but erring a bit low since some of our other timing is inaccurate.
|
||||
@ -2881,7 +2882,7 @@ bool GPUCommon::PerformMemoryCopy(u32 dest, u32 src, int size) {
|
||||
// Since they're identical we don't need to copy.
|
||||
if (!Memory::IsVRAMAddress(dest) || (dest ^ 0x00400000) != src) {
|
||||
if (MemBlockInfoDetailed(size)) {
|
||||
const std::string tag = "GPUMemcpy/" + GetMemWriteTagAt(src, size);
|
||||
const std::string tag = GetMemWriteTagAt("GPUMemcpy/", src, size);
|
||||
Memory::Memcpy(dest, src, size, tag.c_str(), tag.size());
|
||||
} else {
|
||||
Memory::Memcpy(dest, src, size, "GPUMemcpy");
|
||||
@ -2893,7 +2894,7 @@ bool GPUCommon::PerformMemoryCopy(u32 dest, u32 src, int size) {
|
||||
}
|
||||
|
||||
if (MemBlockInfoDetailed(size)) {
|
||||
const std::string tag = "GPUMemcpy/" + GetMemWriteTagAt(src, size);
|
||||
const std::string tag = GetMemWriteTagAt("GPUMemcpy/", src, size);
|
||||
NotifyMemInfo(MemBlockFlags::READ, src, size, tag.c_str(), tag.size());
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, dest, size, tag.c_str(), tag.size());
|
||||
}
|
||||
|
@ -813,7 +813,7 @@ void SoftGPU::Execute_BlockTransferStart(u32 op, u32 diff) {
|
||||
}
|
||||
|
||||
if (MemBlockInfoDetailed(srcSize, dstSize)) {
|
||||
const std::string tag = "GPUBlockTransfer/" + GetMemWriteTagAt(src, srcSize);
|
||||
const std::string tag = GetMemWriteTagAt("GPUBlockTransfer/", src, srcSize);
|
||||
NotifyMemInfo(MemBlockFlags::READ, src, srcSize, tag.c_str(), tag.size());
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, dst, dstSize, tag.c_str(), tag.size());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user