From b0ff571307d1dd850265f5a6e8890a8a1ec14827 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 24 Jul 2026 20:22:30 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Optimize=20guest=20string?= =?UTF-8?q?=20comparison=20allocations=20and=20lock=20contention?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Updated `TryCompareStrings` and `TryCompareStringsCaseInsensitive` in `KernelMemoryCompatExports.cs`. - Replaced per-byte `TryReadCompat` loops with 4KB chunked stack allocations. - Ensures zero allocations while minimizing lock contention on `VirtualMemory` accesses during HLE syscall string operations. Co-authored-by: manupawickramasinghe <73810867+manupawickramasinghe@users.noreply.github.com> --- .../Kernel/KernelMemoryCompatExports.cs | 83 +++++++++++++------ 1 file changed, 59 insertions(+), 24 deletions(-) diff --git a/src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs b/src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs index 218ebf239..93c953337 100644 --- a/src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs +++ b/src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs @@ -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 leftByte = stackalloc byte[1]; - Span 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 leftChunk = stackalloc byte[maxChunkSize]; + Span 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; @@ -7882,30 +7899,48 @@ private static bool TryCompareStringsCaseInsensitive( out int compare) { compare = 0; - Span leftBuffer = stackalloc byte[1]; - Span 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 leftChunk = stackalloc byte[maxChunkSize]; + Span 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;