Skip to content
Merged
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
83 changes: 59 additions & 24 deletions src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5493,21 +5493,38 @@ private static bool TryCompareStrings(CpuContext ctx, ulong left, ulong right, u
}

var max = limit == ulong.MaxValue ? 1_048_576UL : Math.Min(limit, 1_048_576UL);
Span<byte> leftByte = stackalloc byte[1];
Span<byte> rightByte = stackalloc byte[1];
for (ulong i = 0; i < max; i++)
// OPTIMIZATION: Read in chunks to minimize VirtualMemory lookups and lock contention.
const int maxChunkSize = 4096;
Span<byte> leftChunk = stackalloc byte[maxChunkSize];
Span<byte> rightChunk = stackalloc byte[maxChunkSize];
ulong offset = 0;

while (offset < max)
{
if (!TryReadCompat(ctx, left + i, leftByte) ||
!TryReadCompat(ctx, right + i, rightByte))
var currentLeft = left + offset;
var currentRight = right + offset;
var leftRemainingInPage = (int)(maxChunkSize - (currentLeft & (maxChunkSize - 1)));
var rightRemainingInPage = (int)(maxChunkSize - (currentRight & (maxChunkSize - 1)));
var readLength = (int)Math.Min((long)(max - offset), Math.Min(leftRemainingInPage, rightRemainingInPage));
var leftSlice = leftChunk[..readLength];
var rightSlice = rightChunk[..readLength];

if (!TryReadCompat(ctx, currentLeft, leftSlice) ||
!TryReadCompat(ctx, currentRight, rightSlice))
{
return false;
}

compare = leftByte[0] - rightByte[0];
if (compare != 0 || leftByte[0] == 0 || rightByte[0] == 0)
for (int i = 0; i < readLength; i++)
{
return true;
compare = leftSlice[i] - rightSlice[i];
if (compare != 0 || leftSlice[i] == 0 || rightSlice[i] == 0)
{
return true;
}
}

offset += (ulong)readLength;
}

compare = 0;
Expand Down Expand Up @@ -7882,30 +7899,48 @@ private static bool TryCompareStringsCaseInsensitive(
out int compare)
{
compare = 0;
Span<byte> leftBuffer = stackalloc byte[1];
Span<byte> rightBuffer = stackalloc byte[1];
for (ulong index = 0; index < limit; index++)
var max = limit == ulong.MaxValue ? 1_048_576UL : Math.Min(limit, 1_048_576UL);
// OPTIMIZATION: Read in chunks to minimize VirtualMemory lookups and lock contention.
const int maxChunkSize = 4096;
Span<byte> leftChunk = stackalloc byte[maxChunkSize];
Span<byte> rightChunk = stackalloc byte[maxChunkSize];
ulong offset = 0;

while (offset < max)
{
if (!TryReadCompat(ctx, left + index, leftBuffer) ||
!TryReadCompat(ctx, right + index, rightBuffer))
var currentLeft = left + offset;
var currentRight = right + offset;
var leftRemainingInPage = (int)(maxChunkSize - (currentLeft & (maxChunkSize - 1)));
var rightRemainingInPage = (int)(maxChunkSize - (currentRight & (maxChunkSize - 1)));
var readLength = (int)Math.Min((long)(max - offset), Math.Min(leftRemainingInPage, rightRemainingInPage));
var leftSlice = leftChunk[..readLength];
var rightSlice = rightChunk[..readLength];

if (!TryReadCompat(ctx, currentLeft, leftSlice) ||
!TryReadCompat(ctx, currentRight, rightSlice))
{
return false;
}

var leftValue = leftBuffer[0];
var rightValue = rightBuffer[0];
var leftLower = ToAsciiLower(leftValue);
var rightLower = ToAsciiLower(rightValue);
if (leftLower != rightLower)
for (int i = 0; i < readLength; i++)
{
compare = leftLower - rightLower;
return true;
}
var leftValue = leftSlice[i];
var rightValue = rightSlice[i];
var leftLower = ToAsciiLower(leftValue);
var rightLower = ToAsciiLower(rightValue);
if (leftLower != rightLower)
{
compare = leftLower - rightLower;
return true;
}

if (leftValue == 0)
{
return true;
if (leftValue == 0)
{
return true;
}
}

offset += (ulong)readLength;
}

return true;
Expand Down