Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
221 commits
Select commit Hold shift + click to select a range
0945b2c
[VideoPresenter] Fix logical width/height calculation
par274 Jul 20, 2026
fe643fc
perf: Optimize CollectAbandonedGuestImageVersions to avoid ToArray()
google-labs-jules[bot] Jul 22, 2026
9458e71
Merge pull request #1 from Zektopic/perf/vulkan-guest-image-versions-…
manupawickramasinghe Jul 22, 2026
a04d48d
Merge branch 'sharpemu:main' into main
manupawickramasinghe Jul 22, 2026
7bdc08e
⚡ Bolt: Optimize Kernel string memory operations
google-labs-jules[bot] Jul 22, 2026
3828c44
Merge branch 'sharpemu:main' into main
ManupaKDU Jul 22, 2026
aa79fb3
Merge pull request #2 from Zektopic/kernel-memory-opt-116025294922250…
ManupaKDU Jul 22, 2026
eb32d89
Refactor HostMainThread to use block bodies for side-effect methods
google-labs-jules[bot] Jul 23, 2026
cd132dc
Refactor: Convert HostMainThread side-effect methods to block body
google-labs-jules[bot] Jul 23, 2026
3722da6
⚡ Optimize hex logging allocations using string.Create
google-labs-jules[bot] Jul 23, 2026
7367a39
Merge pull request #5 from Zektopic/perf/hex-logging-allocations-1254…
manupawickramasinghe Jul 23, 2026
0073891
Add unit tests for CpuContext register bounds checking
google-labs-jules[bot] Jul 23, 2026
fa0c144
Add tests for CpuContext.ClearAllYmmUpper
google-labs-jules[bot] Jul 23, 2026
79a9b18
Add comprehensive tests for CpuContext
google-labs-jules[bot] Jul 23, 2026
d680ee6
🧹 Refactor expression-bodied methods with side effects to block bodie…
google-labs-jules[bot] Jul 23, 2026
bf12d85
🧪 Add unit tests for GuestDataPool.Trim
google-labs-jules[bot] Jul 23, 2026
cdd2bcf
Refactor VulkanVideoHost expression-bodied methods to use block bodies
google-labs-jules[bot] Jul 23, 2026
035f326
Refactor SelfLoader to eliminate LINQ allocations and switch to O(1) …
google-labs-jules[bot] Jul 23, 2026
6876079
Merge pull request #12 from Zektopic/optimize-selfloader-linq-1774887…
manupawickramasinghe Jul 24, 2026
758b08e
Merge branch 'sharpemu:main' into main
manupawickramasinghe Jul 24, 2026
37b672d
Merge pull request #11 from Zektopic/refactor-block-bodies-vulkanhost…
manupawickramasinghe Jul 24, 2026
cafc24b
Merge pull request #10 from Zektopic/test-guest-data-pool-trim-144293…
manupawickramasinghe Jul 24, 2026
bbb68b8
Merge pull request #9 from Zektopic/jules-1130903938053319600-73e41ddf
manupawickramasinghe Jul 24, 2026
664dea2
Merge pull request #8 from Zektopic/tests/add-cpu-context-tests-15981…
manupawickramasinghe Jul 24, 2026
27d90f4
Merge pull request #6 from Zektopic/testing-cpucontext-xmm-9135406824…
manupawickramasinghe Jul 24, 2026
644ff48
Merge pull request #4 from Zektopic/refactor/host-main-thread-block-b…
manupawickramasinghe Jul 24, 2026
4358475
Merge pull request #3 from Zektopic/code-health-refactor-hostmainthre…
manupawickramasinghe Jul 24, 2026
b0ff571
⚡ Bolt: Optimize guest string comparison allocations and lock contention
google-labs-jules[bot] Jul 24, 2026
c3718f5
⚡ Bolt: Optimize VulkanVideoPresenter allocations
google-labs-jules[bot] Jul 24, 2026
c3e2790
Merge branch 'sharpemu:main' into main
manupawickramasinghe Jul 25, 2026
aff510b
Merge pull request #14 from Zektopic/jules-vulkan-video-presenter-per…
manupawickramasinghe Jul 25, 2026
d39adee
Merge pull request #13 from Zektopic/bolt/perf-kernel-strcmp-chunking…
manupawickramasinghe Jul 25, 2026
e2eaf43
Optimize Metal PSO caching by using zero-allocation struct key
google-labs-jules[bot] Jul 25, 2026
91c8b36
Optimize Metal PSO caching by using zero-allocation struct key
google-labs-jules[bot] Jul 25, 2026
50e12e9
⚡ Bolt: Optimize Metal PSO caching by using zero-allocation struct key
google-labs-jules[bot] Jul 25, 2026
6ed2ced
Add unit tests for GenerateAerolibBinaryTask
google-labs-jules[bot] Jul 26, 2026
cd14a7d
Add unit tests for Gen5ShaderIr
google-labs-jules[bot] Jul 26, 2026
e7fc564
Add unit tests for MetalGuestGpuBackend.TryCompileVertexShader
google-labs-jules[bot] Jul 26, 2026
be82d27
Test KernelFileExtendedExports file stream flush failure
google-labs-jules[bot] Jul 26, 2026
fa32f00
Fix REUSE compliance issues
google-labs-jules[bot] Jul 26, 2026
2c59578
🧪 Add test coverage for SysAbiExportGenerator
google-labs-jules[bot] Jul 26, 2026
10dc787
🔒 Fix potential command injection in AvPlayer
google-labs-jules[bot] Jul 26, 2026
bdb72aa
Fix REUSE compliance and Add unit tests for MetalGuestGpuBackend.TryC…
google-labs-jules[bot] Jul 26, 2026
bf05e12
Add missing REUSE copyright and license headers
google-labs-jules[bot] Jul 26, 2026
045b8d9
Fix missing copyright and licensing information
google-labs-jules[bot] Jul 26, 2026
9909ac2
🧪 Add tests for Gen5ComputeSystemRegisters.TryGetExpression
google-labs-jules[bot] Jul 26, 2026
0cfc287
Add a test to verify KernelSocketCompatExports handles dispose except…
google-labs-jules[bot] Jul 26, 2026
341c1d2
Add tests for MetalGuestGpuBackend.IsGpuGuestImageAvailable
google-labs-jules[bot] Jul 26, 2026
861fa06
🔒 Fix potential command injection in AvPlayer
google-labs-jules[bot] Jul 26, 2026
b95a226
🧪 Add tests for Gen5ComputeSystemRegisters.TryGetExpression
google-labs-jules[bot] Jul 26, 2026
3b05235
Fix REUSE compliance and Add unit tests for MetalGuestGpuBackend.TryC…
google-labs-jules[bot] Jul 26, 2026
5648f1f
Add tests for MetalGuestGpuBackend.IsGpuGuestImageAvailable
google-labs-jules[bot] Jul 26, 2026
2998617
Fix REUSE compliance and Add unit tests for MetalGuestGpuBackend.TryC…
google-labs-jules[bot] Jul 26, 2026
cff37f9
🧪 Add tests for Gen5ComputeSystemRegisters.TryGetExpression
google-labs-jules[bot] Jul 26, 2026
7854085
Add tests for MetalGuestGpuBackend.IsGpuGuestImageAvailable
google-labs-jules[bot] Jul 26, 2026
3eff710
Merge branch 'sharpemu:main' into main
manupawickramasinghe Jul 26, 2026
8c92e50
Merge branch 'pr-7'
manupawickramasinghe Jul 26, 2026
d8a6530
Merge branch 'pr-15'
manupawickramasinghe Jul 26, 2026
bad23dd
fix(reuse): add .reuse/dep5 to declare license headers for benchmark …
manupawickramasinghe Jul 26, 2026
8b9f5ab
Merge branch 'pr-16'
manupawickramasinghe Jul 26, 2026
1050ead
Merge branch 'pr-17'
manupawickramasinghe Jul 26, 2026
4e27fd4
Merge branch 'pr-18'
manupawickramasinghe Jul 26, 2026
37a3113
Merge branch 'pr-19'
manupawickramasinghe Jul 26, 2026
37daa18
Merge branch 'pr-20'
manupawickramasinghe Jul 26, 2026
683529a
Merge branch 'pr-21'
manupawickramasinghe Jul 26, 2026
0aeb5a7
Merge branch 'pr-22'
manupawickramasinghe Jul 26, 2026
c4ce20a
Merge branch 'pr-23'
manupawickramasinghe Jul 26, 2026
f72c5d5
Merge branch 'pr-24'
manupawickramasinghe Jul 26, 2026
c54a019
Merge branch 'main' of github.com:Zektopic/sharpemu
manupawickramasinghe Jul 26, 2026
1b886f4
Merge upstream sharpemu/sharpemu main into fork
manupawickramasinghe Jul 30, 2026
d9f8d46
Merge pull request #26 from Zektopic/sync-upstream
manupawickramasinghe Jul 30, 2026
5e328c7
Add comprehensive tests for Ps5ParamJsonReader
google-labs-jules[bot] Aug 14, 2026
273a902
Replace `BitConverter.Int64BitsToDouble` with `BitConverter.UInt64Bit…
google-labs-jules[bot] Aug 14, 2026
6c067dd
Add tests for PhysicalFileSystem class
google-labs-jules[bot] Aug 14, 2026
bb8493f
🧹 [Code Health] Use BitConverter.UInt64BitsToDouble
google-labs-jules[bot] Aug 14, 2026
ec09935
fix: prevent argument injection via double quotes in AvPlayer paths
google-labs-jules[bot] Aug 14, 2026
2f01d87
Optimize LINQ allocations in Gen5 pixel output validation
google-labs-jules[bot] Aug 14, 2026
c76914d
Fix command injection via Process.Start in AvPlayer
google-labs-jules[bot] Aug 14, 2026
0a801e2
🔒 Fix Command Injection via Process.Start in AvPlayerExports
google-labs-jules[bot] Aug 14, 2026
da6e4b9
fix: use SHA-256 for pseudo-NID generation instead of weak SHA-1
google-labs-jules[bot] Aug 14, 2026
6027443
⚡ Bolt: Remove LINQ allocations in NGS2 system and rack destruction
google-labs-jules[bot] Aug 14, 2026
5928ea3
⚡ Bolt: Use asynchronous signaling in Pthread test
google-labs-jules[bot] Aug 14, 2026
c576f5b
Fix whole-word bug hallucinated test method name
google-labs-jules[bot] Aug 14, 2026
8fe4fe3
Merge branch 'pr-28'
manupawickramasinghe Aug 15, 2026
44c50b8
Merge branch 'pr-29'
manupawickramasinghe Aug 15, 2026
636c543
Merge branch 'pr-30'
manupawickramasinghe Aug 15, 2026
ddcd7d5
Merge branch 'pr-31'
manupawickramasinghe Aug 15, 2026
e63ff37
Merge branch 'pr-32'
manupawickramasinghe Aug 15, 2026
78a4ee1
Merge branch 'pr-33'
manupawickramasinghe Aug 15, 2026
b33cde7
Merge branch 'pr-34'
manupawickramasinghe Aug 15, 2026
bdc0332
Merge branch 'pr-35'
manupawickramasinghe Aug 15, 2026
22aaeed
Merge branch 'pr-36'
manupawickramasinghe Aug 15, 2026
a6e95d5
Merge branch 'pr-37'
manupawickramasinghe Aug 15, 2026
d64fbd3
Merge branch 'pr-38'
manupawickramasinghe Aug 15, 2026
b7d5978
⚡ Bolt: Optimize `PhysicalVirtualMemory.FindRegion` with `Collections…
google-labs-jules[bot] Aug 18, 2026
daade46
⚡ Bolt: Eliminate GC allocation in SnapshotRegions hot path
google-labs-jules[bot] Aug 21, 2026
0724284
⚡ Bolt: Eliminate GC allocation in SnapshotRegions hot path
google-labs-jules[bot] Aug 21, 2026
b3a4c5c
Merge PR #39
Aug 22, 2026
f70089d
Merge PR #40 (resolved)
Aug 22, 2026
e4ebeff
🧪 Add unit tests for GpuWaitRegistry.SnapshotInRange
google-labs-jules[bot] Aug 22, 2026
763274e
🧪 Add unit tests for GpuWaitRegistry.CollectSatisfied and waiting que…
google-labs-jules[bot] Aug 22, 2026
a7996f6
🧪 Unit test GpuWaitRegistry public static methods
google-labs-jules[bot] Aug 22, 2026
3a6135a
Fix empty catch block in PhysicalVirtualMemory.cs
google-labs-jules[bot] Aug 22, 2026
f8d7aca
🧹 Document empty catch blocks in NativeWorker
google-labs-jules[bot] Aug 22, 2026
2dcff12
Add unit tests for GpuWaitRegistry.Compare
google-labs-jules[bot] Aug 22, 2026
65f293a
⚡ Bolt: Eliminate unnecessary array allocation in SaveDataStorage.Mig…
google-labs-jules[bot] Aug 22, 2026
d0aaf84
🧹 Fix empty catch blocks in native worker prologue and epilogue error…
google-labs-jules[bot] Aug 22, 2026
6580544
🧪 Add comprehensive unit tests for GpuWaitRegistry
google-labs-jules[bot] Aug 22, 2026
252e74b
🧪 [testing improvement] Add unit tests for GpuWaitRegistry
google-labs-jules[bot] Aug 22, 2026
e49bd2d
test: Add unit tests for GpuWaitRegistry.CollectDeadlockBroken
google-labs-jules[bot] Aug 22, 2026
7599b11
test: Add unit tests for GpuWaitRegistry and SnapshotOutstanding
google-labs-jules[bot] Aug 22, 2026
0cf294d
🧪 test(agc): add unit tests for GpuWaitRegistry.RecordProduced
google-labs-jules[bot] Aug 22, 2026
314c1c6
🧪 Add unit tests for GpuWaitRegistry methods including CollectAllForM…
google-labs-jules[bot] Aug 22, 2026
d58a621
🧹 Handle exception in UnhandledExceptionFilter catch block
google-labs-jules[bot] Aug 22, 2026
97710bb
Log exceptions when guest thread search fails in DirectExecutionBackend
google-labs-jules[bot] Aug 22, 2026
844878f
🧪 Add unit tests for GpuWaitRegistry and LatchSatisfiedByValue
google-labs-jules[bot] Aug 22, 2026
712c1f1
🧪 Add unit tests for GpuWaitRegistry.CollectUnreportedStale
google-labs-jules[bot] Aug 22, 2026
9f1cc47
🧪 Add unit tests for GpuWaitRegistry
google-labs-jules[bot] Aug 22, 2026
16f3b59
Add unit tests for GpuWaitRegistry.CollectExpiredRetries
google-labs-jules[bot] Aug 22, 2026
08845d1
Fix XXE vulnerability in PlayGo XML parsing
google-labs-jules[bot] Aug 22, 2026
109f3fa
🧪 Add unit test coverage for GpuWaitRegistry
google-labs-jules[bot] Aug 22, 2026
4c63e65
⚡ Bolt: Remove unnecessary array allocation in Agc image bindings col…
google-labs-jules[bot] Aug 22, 2026
78718e0
⚡ Bolt: Optimize file name sanitization using SearchValues<char> and …
google-labs-jules[bot] Aug 22, 2026
69cc2d1
🧹 Fix swallowed ObjectDisposedException in NativeGuestExecutor.Dispose
google-labs-jules[bot] Aug 22, 2026
c264b05
fix(gui): use unpredictable temp path in Updater
google-labs-jules[bot] Aug 22, 2026
9c8ac08
⚡ Bolt: Replace LINQ tuple allocation in TraceAstroTitlePixelGlobalProbe
google-labs-jules[bot] Aug 22, 2026
4ca2c3d
⚡ Bolt: Optimize GetPerAppWritableRoot string sanitization
google-labs-jules[bot] Aug 22, 2026
d6aa738
Sync upstream/main into main (conflict resolved)
Aug 22, 2026
b562aee
Merge PR #41
Aug 22, 2026
51ee328
Merge PR (conflict resolved)
Aug 22, 2026
cb75d8a
Merge PR (conflict resolved)
Aug 22, 2026
fdc785b
Merge PR #44
Aug 22, 2026
3671e32
Merge PR #45
Aug 22, 2026
e1ad1ac
Merge PR (conflict resolved)
Aug 22, 2026
3a52914
Merge PR #47
Aug 22, 2026
e5f36c6
Merge PR (conflict resolved)
Aug 22, 2026
b3e375a
Merge PR (conflict resolved)
Aug 22, 2026
6db2c2a
Merge PR (conflict resolved)
Aug 22, 2026
1d3888c
Merge PR (conflict resolved)
Aug 22, 2026
825ac7b
Merge PR (conflict resolved)
Aug 22, 2026
6c3398f
Merge PR (conflict resolved)
Aug 22, 2026
cb9cff5
Merge PR (conflict resolved)
Aug 22, 2026
e2ffa59
Merge PR #55
Aug 22, 2026
54998f2
Merge PR #56
Aug 22, 2026
2f0fb36
Merge PR (conflict resolved)
Aug 22, 2026
7fc4c26
Merge PR (conflict resolved)
Aug 22, 2026
edb0f69
Merge PR (conflict resolved)
Aug 22, 2026
9e36b8e
Merge PR #60
Aug 22, 2026
c364663
Merge PR #61
Aug 22, 2026
b060170
Merge PR (conflict resolved)
Aug 22, 2026
8560d15
Merge PR (conflict resolved)
Aug 22, 2026
0001dbf
Merge PR (conflict resolved)
Aug 22, 2026
9a0141f
Merge PR #65
Aug 22, 2026
6e22350
Merge PR #66
Aug 22, 2026
7deda98
Merge PR #67
Aug 22, 2026
da932ae
Merge PR #68
Aug 22, 2026
f014108
fix(build): resolve upstream refactor API breaks in Agc, VideoOut, an…
manupawickramasinghe Aug 22, 2026
1bca6a3
fix(gpu): correct GuestDataPool DiagnosticStats member visibility and…
manupawickramasinghe Aug 22, 2026
406bf50
test(avplayer): remove obsolete stub tests superseded by ffmpeg bridge
manupawickramasinghe Aug 22, 2026
4bdf82a
fix(memory): handle Windows 64KB allocation granularity in WindowsHos…
manupawickramasinghe Aug 22, 2026
ff1864d
fix(vmem): support sharing host allocation granules in AllocateAt and…
manupawickramasinghe Aug 22, 2026
ad2472b
fix(vmem): correct lazy reservation gating and fully occupied range d…
manupawickramasinghe Aug 22, 2026
bf09f07
test(memory): align reservation bounds to Granularity in GranularityA…
manupawickramasinghe Aug 22, 2026
9158b50
fix(vmem): support contiguous region checks in IsAccessible
manupawickramasinghe Aug 22, 2026
980b47b
fix(loader): measure total image size from base to highest segment ad…
manupawickramasinghe Aug 22, 2026
19468cb
perf(mmu): Optimize VirtualMemory translation loops with CollectionsM…
google-labs-jules[bot] Aug 25, 2026
f301db5
perf(mmu): Optimize VirtualMemory translation loops with CollectionsM…
google-labs-jules[bot] Aug 25, 2026
1fbbb72
perf(core): optimize FindInsertionIndex via CollectionsMarshal.AsSpan
google-labs-jules[bot] Aug 26, 2026
491084c
Merge branch fix_logical_w_h into main with conflict resolution
manupawickramasinghe Aug 27, 2026
5ca4215
Merge pull request #70 into main
manupawickramasinghe Aug 27, 2026
6d8c2ce
Merge pull request #71 with conflict resolution
manupawickramasinghe Aug 27, 2026
e263feb
Merge upstream changes from sharpemu/sharpemu with conflict resolution
manupawickramasinghe Aug 30, 2026
c234ff2
⚡ Bolt: Optimize LINQ FirstOrDefault in GuestDepthExtentResolver
google-labs-jules[bot] Sep 7, 2026
4a150cf
Optimize SnapshotRegions cache access by using volatile read
google-labs-jules[bot] Sep 7, 2026
bd9d1b3
Merge pull request #78 from Zektopic/perf/depth-extent-resolver-51822…
manupawickramasinghe Sep 8, 2026
a851b7e
Merge pull request #80 from Zektopic/bolt-optimize-snapshot-regions-1…
manupawickramasinghe Sep 8, 2026
a4176c1
fix(videoout): stub TryTakeHostMovieFrame to fix build
manupawickramasinghe Sep 9, 2026
640c5a1
perf(videoout): optimize RecordGuestImageWritersLocked to zero alloca…
manupawickramasinghe Sep 9, 2026
9949fed
perf(memory): optimize VirtualMemory via CollectionsMarshal.AsSpan an…
manupawickramasinghe Sep 9, 2026
d7d9759
perf(loader): eliminate diagnostic string allocations via FormatHexBy…
manupawickramasinghe Sep 9, 2026
26f0fa6
Merge branch 'sharpemu:main' into main
manupawickramasinghe Sep 9, 2026
46a3987
⚡ Bolt: Optimize bounds checking in VirtualMemory hot loops
google-labs-jules[bot] Sep 13, 2026
b72e8d8
⚡ Bolt: Fix ExportModel reflection signature in tests
google-labs-jules[bot] Sep 13, 2026
0c27c55
Merge pull request #86 from Zektopic/bolt-virtualmemory-bounds-elisio…
manupawickramasinghe Sep 17, 2026
8e0dcaa
Add test for VirtualMemory.Map when fileData exceeds memorySize
google-labs-jules[bot] Sep 21, 2026
b2277aa
chore: remove unused System.Linq using from SelfLoader.cs
google-labs-jules[bot] Sep 21, 2026
b1b7c90
Add VirtualMemory.Map memorySize == 0 error test
google-labs-jules[bot] Sep 21, 2026
f518779
Add test for TryGetName empty string edge case
google-labs-jules[bot] Sep 21, 2026
3b1e6f6
Add tests for Aerolib.TryGetByNid ArgumentException
google-labs-jules[bot] Sep 21, 2026
665f58d
Add test for Aerolib.ContainsNid empty string edge case
google-labs-jules[bot] Sep 21, 2026
5a67b74
Add test for Aerolib.TryGetByExportName with empty string
google-labs-jules[bot] Sep 21, 2026
9109dc1
Remove unused System.Linq directive and fix Count usage in JsonExports
google-labs-jules[bot] Sep 21, 2026
47c57ab
Optimize AgcExports.GetRenderTargets duplicate check
google-labs-jules[bot] Sep 21, 2026
f12600a
Optimize Videodec2Decoder scheduler delay
google-labs-jules[bot] Sep 21, 2026
0cb7343
perf: Remove LINQ and ToArray allocations in CollectAbandonedGuestIma…
google-labs-jules[bot] Sep 21, 2026
7046a82
Perf: Refactor synchronous ValueTask waits in Videodec2Decoder to avo…
google-labs-jules[bot] Sep 21, 2026
9a425d5
Fix command injection in Process.Start via game directory
google-labs-jules[bot] Sep 21, 2026
32cede9
perf: Remove LINQ and ToArray allocations in CollectAbandonedGuestIma…
google-labs-jules[bot] Sep 21, 2026
7d7e82d
Perf: Refactor synchronous ValueTask waits in Videodec2Decoder to avo…
google-labs-jules[bot] Sep 21, 2026
ad85d06
Merge pull request #90
manupawickramasinghe Sep 21, 2026
edbb07b
Merge pull request #91
manupawickramasinghe Sep 21, 2026
81664c3
Merge pull request #92
manupawickramasinghe Sep 21, 2026
fc51e94
Merge pull request #93
manupawickramasinghe Sep 21, 2026
a15dcc4
Merge pull request #94
manupawickramasinghe Sep 21, 2026
205da65
Merge pull request #95
manupawickramasinghe Sep 21, 2026
7a15dd1
Merge pull request #96
manupawickramasinghe Sep 21, 2026
7bf6233
Merge pull request #97
manupawickramasinghe Sep 21, 2026
2c170de
Merge pull request #98
manupawickramasinghe Sep 21, 2026
56b7e48
Merge pull request #99
manupawickramasinghe Sep 21, 2026
5c0683b
Merge pull request #101
manupawickramasinghe Sep 21, 2026
ce9b1c3
Merge pull request #102
manupawickramasinghe Sep 21, 2026
017cba0
Fix CI issues related to warnings and source generators
google-labs-jules[bot] Sep 21, 2026
ceb8ec5
Fix TryGetByExportName method name in AerolibCatalogTests
manupawickramasinghe Sep 21, 2026
ab2f45b
Merge pull request #98 from Zektopic/optimize-videodec2-scheduler-sle…
manupawickramasinghe Sep 21, 2026
483f132
Optimize VirtualMemory fast-path sequential span access
google-labs-jules[bot] Sep 24, 2026
ffedaf1
Optimize VirtualMemory copy methods using Span slice-reassignment
google-labs-jules[bot] Sep 25, 2026
5f6af6f
Merge pull request #104 from Zektopic/bolt-virtualmemory-fastpath
manupawickramasinghe Sep 26, 2026
c205903
Merge pull request #105 from Zektopic/bolt-span-slicing
manupawickramasinghe Sep 26, 2026
275eb88
⚡ Bolt: Eliminate LINQ allocations in KernelMemoryCompatExports
google-labs-jules[bot] Sep 30, 2026
c4da2b8
Merge pull request #110 from sharpemu/main: Update REPo
manupawickramasinghe Oct 11, 2026
7815efe
⚡ Bolt: Optimize guest memory string comparison zero-allocation hot p…
google-labs-jules[bot] Oct 12, 2026
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
Binary file removed .github/images/astro-bot.jpg
Binary file not shown.
Binary file removed .github/images/astros-playroom.jpg
Binary file not shown.
Binary file removed .github/images/cult-of-the-lamb.jpg
Binary file not shown.
Binary file modified .github/images/dead-cells.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified .github/images/demons-souls.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed .github/images/gow-sos.jpg
Binary file not shown.
Binary file removed .github/images/hades.jpg
Binary file not shown.
Binary file removed .github/images/pac-man-world-re-pac.jpg
Binary file not shown.
Binary file removed .github/images/tomb-raider-v-remastered.jpg
Binary file not shown.
2 changes: 1 addition & 1 deletion .github/workflows/notify-site.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ on:

jobs:
dispatch:
runs-on: ubuntu-26.04
runs-on: ubuntu-latest
steps:
- name: Trigger sharpemu-site rebuild
env:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-build-links.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ permissions:
jobs:
comment:
name: Post artifact links
runs-on: ubuntu-26.04
runs-on: ubuntu-latest
# Only for successful PR builds — artifacts exist only when the build passed.
if: >-
github.event.workflow_run.event == 'pull_request' &&
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ concurrency:
jobs:
init:
name: Init
runs-on: ubuntu-26.04
runs-on: ubuntu-latest
outputs:
release-name: ${{ steps.vars.outputs.release-name }}
release-tag: ${{ steps.vars.outputs.release-tag }}
Expand Down Expand Up @@ -71,7 +71,7 @@ jobs:
reuse:
name: REUSE Compliance
needs: init
runs-on: ubuntu-26.04
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
Expand All @@ -80,7 +80,7 @@ jobs:
uses: fsfe/reuse-action@v6

build:
name: Build win-x64
name: Build Archive
needs:
- init
- reuse
Expand Down Expand Up @@ -138,7 +138,7 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-26.04
- os: ubuntu-latest
rid: linux-x64
- os: macos-latest
rid: osx-x64
Expand Down Expand Up @@ -227,7 +227,7 @@ jobs:
# Versioned releases are immutable and tag-driven. Branch and manual runs
# still produce Actions artifacts without modifying a published release.
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-26.04
runs-on: ubuntu-latest
permissions:
contents: write
steps:
Expand Down
60 changes: 60 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<!--
Copyright (C) 2026 SharpEmu Emulator Project
SPDX-License-Identifier: GPL-2.0-or-later
-->

## 2026-07-25 - Replace reference records with readonly structs for Dictionary keys
**Context:** Metal Video Presenter / PSO Cache (`PipelineKey`)
**Learning:** Using `sealed record` for Dictionary keys causes implicit heap allocations on every lookup (due to it being a class reference type). Since PSO caching lookups happen per-frame or per-draw, this creates significant GC pressure.
**Action:** Replace `sealed record` with `readonly struct` implementing `IEquatable<T>` and explicitly overriding `GetHashCode()` with `HashCode.Combine()` to eliminate allocations in hot dictionary lookups.

## 2024-05-30 - [Kernel String Reading Optimization]
**Context:** src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs
**Learning:** Guest string reading operations (TryCompareStrings, Strchr, Strrchr, Memchr, TryCompareStringsCaseInsensitive) read character by character in loops, making a new TryReadCompat call (which grabs locks and searches trees in VirtualMemory) for every single byte. This creates huge overhead for long strings, which could be reduced with chunked reads or reading the whole thing using the existing CString functions.
**Action:** Use TryReadCString or chunked reads instead of 1-byte read loops.

## 2026-07-26 - Testing Roslyn Incremental Generator Equality Models

**Context:** When working with C# Source Generators, `IIncrementalGenerator` caching relies heavily on the `Equals` and `GetHashCode` implementations of intermediate data models. If these methods are incomplete or flawed, Roslyn will incorrectly cache or regenerate output, leading to performance issues or stale state. In the context of `SysAbiExportGenerator`, the `ExportModel` is a private, nested type that was largely untested for equality logic.

**Learning:** To guarantee 100% line and branch coverage on these critical internal data models, the most direct and reliable approach is to use reflection within standard xUnit tests. This circumvents the need to construct complex `CSharpCompilation` trees and invoke `CSharpGeneratorDriver` incrementally just to trigger `IEquatable` calls, reducing test brittleness and focusing on structural equality.

**Action:** Created `ExportModelEqualityTests` in `SysAbiExportGeneratorTests.cs` using `GetNestedType` and `Activator.CreateInstance` to thoroughly test all branches of `ExportModel` equality logic, improving code reliability for the generator pipeline.

## 2024-05-18 - Optimize PhysicalVirtualMemory FindRegion Bottleneck
**Context:** `src/SharpEmu.Core/Memory/PhysicalVirtualMemory.cs`
**Learning:** The `List<T>` indexer inside the `FindRegion` binary search hot path incurred bounds-checking and method-call overhead. Accessing it via `CollectionsMarshal.AsSpan` yielded a measurable decrease in execution time on millions of iterations.
**Action:** Use `CollectionsMarshal.AsSpan` for hot path reads of `List<T>` instead of indexers when zero-allocation and bounds-checking elision is needed.

## 2026-08-26 - Direct Span Access in Virtual Memory Search
**Context:** `src/SharpEmu.Core/Memory/VirtualMemory.cs` (`FindInsertionIndex`)
**Learning:** Standard C# `List<T>` accesses inside high-frequency binary searches introduce unnecessary overhead via indexer property access and bounds checking. The same optimization pattern recently used in `PhysicalVirtualMemory.cs` (commit 980b47b) applies directly to `VirtualMemory.cs`. Bypassing this via `CollectionsMarshal.AsSpan(list)` completely elides these checks, turning the operation into direct O(1) span memory access.
**Action:** When optimizing binary search loops or hot paths over `List<T>`, immediately refactor to use `CollectionsMarshal.AsSpan()` to access elements and `span.Length` for bounds, alongside the `>>> 1` operator for division.
## 2026-09-13 - Bounds Check Elision in Guest MMU Read/Write Loops
**Context:** Guest MMU Address Translation / `VirtualMemory.cs`
**Learning:** The C# JIT compiler cannot elide array bounds checks for `Span<T>` or arrays when using a `while` loop with a manually managed index. This introduces silent branching overhead in memory-intensive hot paths (like `TryValidateRange`, `CopyFromRegions`).
**Action:** Always replace `while` loops iterating over sequential buffers with standard `for (var i = start; i < span.Length; i++)` loops to guarantee RyuJIT bounds check elimination in high-frequency emulation paths.

## 2026-09-13 - SysAbiExportGenerator.ExportModel Constructor Signature Updates
**Context:** Unit Tests / `SysAbiExportGeneratorTests.cs`
**Learning:** When internal models like `ExportModel` are modified with new parameters (e.g., adding `bool preferLle`), reflection-based unit tests creating instances via `Activator.CreateInstance` will fail with `MissingMethodException` if the test arguments are not updated to match the new constructor signature.
**Action:** Always verify and update reflection-based test factories whenever internal constructor signatures change to maintain test suite stability.
## 2026-09-24 - Span Slicing & Bound Check Elision in Guest Memory Hot Paths
**Context:** Guest MMU / `VirtualMemory.cs`
**Learning:** Sequential memory chunking operations over spans can be significantly optimized by re-slicing the target spans (`destination = destination.Slice(...)`) instead of manually tracking offset counters and lengths. This enables tighter MSIL generation, reduces stack pressure, and removes redundant arithmetic in tight memory loops. Combined with standard for-loops, this allows the .NET JIT to reliably elide bounds checks.
**Action:** Use idiomatic `Span.Slice` reassignment instead of indexer tracking for sequential chunked memory operations in C# hot paths.

## 2026-09-26 - Span Slicing Reassignment in Hot Loops
**Context:** Guest MMU / `VirtualMemory.cs` (`CopyFromRegions`, `CopyToRegions`)
**Learning:** Sequential tracking over Spans with an external `copied` counter and range indexer (`span[copied..]`) introduces local bounds check validation overhead. Reassigning the span reference in place via `span = span.Slice(chunkLength)` eliminates this and simplifies hot loops into `!span.IsEmpty` checks.
**Action:** Use idiomatic slice-reassignment (`span = span.Slice(length)`) instead of external integer trackers in loop conditions over `Span<T>` sequential memory operations to reduce arithmetic overhead.

## 2023-10-25 - Kernel Memory Subsystem Allocation Elimination
**Context:** `KernelMemoryCompatExports.cs`
**Learning:** LINQ `Where(...).ToArray()` and `Where(...).OrderBy(...).FirstOrDefault()` chains inside the `_memoryGate` lock caused severe GC pressure during guest memory unmapping and querying. Because the critical section naturally isolates concurrent access, we can safely share a single static `List<T>` to collect unmapped regions, eliminating closures, enumerators, and per-call array allocations.
**Action:** When filtering collections inside an existing critical section (`lock`), aggressively replace LINQ with manual `foreach` loops and cache results in static thread-safe buffers protected by the same lock.

## 2026-10-25 - Chunked Guest Memory String Reading Optimization
**Context:** src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs (`TryCompareStrings`, `TryCompareStringsCaseInsensitive`)
**Learning:** Guest string reading operations for comparison previously read character by character in loops. This creates a new `TryReadCompat` call per byte, which means repeated page table lookups, locks, and bounds checks in the memory subsystem.
**Action:** When optimizing guest memory string reading operations, replace 1-byte read loops with chunk-based reads (e.g. `stackalloc byte[128]`) and `Span<byte>`, reducing tree traversal overhead. Always include a fallback to byte-wise reads to correctly handle strings that terminate right before unmapped page boundaries without throwing false positives.
1 change: 1 addition & 0 deletions SharpEmu.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
<Project Path="src/SharpEmu.SourceGenerators/SharpEmu.SourceGenerators.csproj" />
</Folder>
<Folder Name="/tests/">
<Project Path="tests/SharpEmu.Core.Tests/SharpEmu.Core.Tests.csproj" />
<Project Path="tests/SharpEmu.Libs.Tests/SharpEmu.Libs.Tests.csproj" />
<Project Path="tests/SharpEmu.ShaderCompiler.Metal.Tests/SharpEmu.ShaderCompiler.Metal.Tests.csproj" />
<Project Path="tests/SharpEmu.ShaderCompiler.Tests/SharpEmu.ShaderCompiler.Tests.csproj" />
Expand Down
53 changes: 46 additions & 7 deletions src/SharpEmu.Core/Cpu/Native/DirectExecutionBackend.Diagnostics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ private void ProbeReturnRip(ulong returnRip, long dispatchIndex)
{
Console.Error.WriteLine(
$"[LOADER][TRACE] Import#{dispatchIndex} pre-return bytes @0x{returnRip - preludeSize:X16}: " +
BitConverter.ToString(prelude.ToArray()).Replace("-", " "));
FormatHexBytes(prelude));

List<DecodedInst>? bestCallChain = null;
var preludeAddress = returnRip - preludeSize;
Expand Down Expand Up @@ -294,11 +294,17 @@ private void ProbeReturnRip(ulong returnRip, long dispatchIndex)
Span<byte> destination = stackalloc byte[128];
if (!cpuContext.Memory.TryRead(returnRip, destination))
{
Log.Debug($"Import#{dispatchIndex} return-rip probe: unreadable @0x{returnRip:X16}");
if (Log.IsEnabled(LogLevel.Debug))
{
Log.Debug($"Import#{dispatchIndex} return-rip probe: unreadable @0x{returnRip:X16}");
}
return;
}
string value = BitConverter.ToString(destination.ToArray()).Replace("-", " ");
Log.Debug($"Import#{dispatchIndex} return-rip bytes @0x{returnRip:X16}: {value}");
if (Log.IsEnabled(LogLevel.Debug))
{
string value = FormatHexBytes(destination);
Log.Debug($"Import#{dispatchIndex} return-rip bytes @0x{returnRip:X16}: {value}");
}
if (destination[0] == byte.MaxValue && (destination[1] == 21 || destination[1] == 37))
{
int num = BitConverter.ToInt32(destination.Slice(2, 4));
Expand Down Expand Up @@ -365,9 +371,12 @@ private void ProbeReturnRip(ulong returnRip, long dispatchIndex)

if (cpuContext.Memory.TryRead(target, targetBytes))
{
Log.Debug(
$"Import#{dispatchIndex} near-call target bytes @0x{target:X16}: " +
BitConverter.ToString(targetBytes.ToArray()).Replace("-", " "));
if (Log.IsEnabled(LogLevel.Debug))
{
Log.Debug(
$"Import#{dispatchIndex} near-call target bytes @0x{target:X16}: " +
FormatHexBytes(targetBytes));
}
if (targetBytes[0] == 0xFF && targetBytes[1] == 0x25)
{
int slotRel32 = BitConverter.ToInt32(targetBytes.Slice(2, 4));
Expand Down Expand Up @@ -402,6 +411,36 @@ private void ProbeReturnRip(ulong returnRip, long dispatchIndex)
}
}

private unsafe static string FormatHexBytes(ReadOnlySpan<byte> bytes)
{
if (bytes.Length == 0) return string.Empty;

fixed (byte* ptr = &MemoryMarshal.GetReference(bytes))
{
var ptrCopy = (IntPtr)ptr;
int length = bytes.Length;
return string.Create(length * 3 - 1, (ptrCopy, length), (span, state) =>
{
var (p, len) = state;
var readSpan = new ReadOnlySpan<byte>((void*)p, len);
for (int i = 0; i < readSpan.Length; i++)
{
byte b = readSpan[i];
int highNibble = b >> 4;
int lowNibble = b & 0x0F;

span[i * 3] = (char)(highNibble < 10 ? highNibble + '0' : highNibble - 10 + 'A');
span[i * 3 + 1] = (char)(lowNibble < 10 ? lowNibble + '0' : lowNibble - 10 + 'A');

if (i < readSpan.Length - 1)
{
span[i * 3 + 2] = ' ';
}
}
});
}
}

private static bool IsUnresolvedSentinel(ulong value)
{
return value == 65534 || value == 4294967294u || value == 18446744073709551614uL;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,9 @@ private unsafe int UnhandledExceptionFilter(void* exceptionInfo)
Console.Error.WriteLine($"[LOADER][FATAL] RSP: 0x{rsp:X16}");
Console.Error.Flush();
}
catch
catch (Exception ex)
{
Console.Error.WriteLine($"[LOADER][FATAL] Unhandled exception filter logging failed: {ex.Message}");
}

return 0;
Expand Down Expand Up @@ -373,7 +374,7 @@ private unsafe int VectoredHandler(void* exceptionInfo)
// exactly the faults that need it.
if (TryReadGuestOrHostBytes(rip, code))
{
Console.Error.WriteLine("[LOADER][INFO] Code at RIP: " + BitConverter.ToString(code).Replace("-", " "));
Console.Error.WriteLine("[LOADER][INFO] Code at RIP: " + FormatHexBytes(code));
if (code[0] == 100)
{
Console.Error.WriteLine("[LOADER][ERROR] Detected FS segment prefix - TLS access not patched!");
Expand All @@ -391,12 +392,12 @@ private unsafe int VectoredHandler(void* exceptionInfo)
byte[] before = new byte[16];
if (rip > 16 && TryReadGuestOrHostBytes(rip - 16, before))
{
Console.Error.WriteLine("[LOADER][INFO] Code before RIP: " + BitConverter.ToString(before).Replace("-", " "));
Console.Error.WriteLine("[LOADER][INFO] Code before RIP: " + FormatHexBytes(before));
}
byte[] window = new byte[64];
if (rip > 32 && TryReadGuestOrHostBytes(rip - 32, window))
{
Console.Error.WriteLine("[LOADER][INFO] Code window [RIP-0x20..]: " + BitConverter.ToString(window).Replace("-", " "));
Console.Error.WriteLine("[LOADER][INFO] Code window [RIP-0x20..]: " + FormatHexBytes(window));
}
for (var stackIndex = 0; stackIndex < 16; stackIndex++)
{
Expand All @@ -415,7 +416,7 @@ private unsafe int VectoredHandler(void* exceptionInfo)
{
Console.Error.WriteLine(
$"[LOADER][INFO] Stack guest-code candidate [rsp+0x{stackIndex * 8:X2}]=0x{candidate:X16}, bytes [-0x18..]: " +
BitConverter.ToString(callSiteWindow).Replace("-", " "));
FormatHexBytes(callSiteWindow));
}
}
}
Expand Down Expand Up @@ -450,7 +451,7 @@ private unsafe int VectoredHandler(void* exceptionInfo)
byte[] illegalCode = new byte[16];
if (TryReadHostBytes(rip, illegalCode))
{
Console.Error.WriteLine("[LOADER][INFO] Code at RIP: " + BitConverter.ToString(illegalCode).Replace("-", " "));
Console.Error.WriteLine("[LOADER][INFO] Code at RIP: " + FormatHexBytes(illegalCode));
}
DumpRecentImportTrace();
DumpGuestDisasmDiagnostics(rip, rbp, rsp);
Expand Down Expand Up @@ -597,8 +598,9 @@ private unsafe bool TryRecoverAuxiliaryThreadExecuteFault(
}
}
}
catch
catch (Exception ex)
{
Log.Error($"Failed to search guest threads by host thread ID {hostThreadId}", ex);
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ private unsafe ulong DispatchImport(int importIndex, nint argPackPtr)
{
byte[] array = new byte[64];
Marshal.Copy((nint)(num7 - 32), array, 0, array.Length);
Console.Error.WriteLine($"[LOADER][TRACE] __stack_chk_fail return-site @0x{num7:X16}: {BitConverter.ToString(array).Replace("-", " ")}");
Console.Error.WriteLine($"[LOADER][TRACE] __stack_chk_fail return-site @0x{num7:X16}: {FormatHexBytes(array)}");
}
catch
{
Expand Down Expand Up @@ -2318,8 +2318,8 @@ private static string ComputePsNid(string symbolName)
var input = new byte[nameBytes.Length + salt.Length];
nameBytes.CopyTo(input, 0);
salt.CopyTo(input.AsSpan(nameBytes.Length));
Span<byte> digest = stackalloc byte[20];
SHA1.HashData(input, digest);
Span<byte> digest = stackalloc byte[32];
SHA256.HashData(input, digest);
var value = BinaryPrimitives.ReadUInt64LittleEndian(digest);
Span<byte> bigEndianValue = stackalloc byte[sizeof(ulong)];
BinaryPrimitives.WriteUInt64BigEndian(bigEndianValue, value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,7 @@ private static nint RunPrologue(nint executorHandle)
}
catch
{
// Ignore failures while writing error diagnostic logs to prevent unhandled exceptions in unmanaged callbacks.
}
return 0;
}
Expand All @@ -723,6 +724,7 @@ private static void RunEpilogue(nint executorHandle, ulong nativeResult)
}
catch
{
// Ignore failures while writing error diagnostic logs to prevent unhandled exceptions in unmanaged callbacks.
}
}
}
Expand Down Expand Up @@ -836,8 +838,12 @@ public void Dispose()
{
SignalWorkAvailable();
}
catch (ObjectDisposedException)
catch (ObjectDisposedException ex)
{
// The synchronization event handle (_workAvailable / _workSemaphore) may be disposed
// before or concurrently with the native guest worker executor teardown. Log the expected
// disposal exception at debug level to retain visibility while allowing cleanup to proceed.
Log.Debug($"Work available signal handle was already disposed during native worker disposal: {ex.Message}");
}
var exited = _threadHandle == 0;
if (_threadHandle != 0)
Expand Down
4 changes: 2 additions & 2 deletions src/SharpEmu.Core/Cpu/Native/DirectExecutionBackend.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7339,11 +7339,11 @@ private void LogStallWatchdogSnapshot()
Span<byte> destination = stackalloc byte[16];
if (cpuContext.Memory.TryRead(cpuContext.Rip, destination))
{
Console.Error.WriteLine($"[LOADER][ERROR] Stall bytes @rip: {BitConverter.ToString(destination.ToArray()).Replace("-", " ")}");
Console.Error.WriteLine($"[LOADER][ERROR] Stall bytes @rip: {FormatHexBytes(destination)}");
}
else if (cpuContext.Memory.TryRead(num, destination))
{
Console.Error.WriteLine($"[LOADER][ERROR] Stall bytes @rip_align: {BitConverter.ToString(destination.ToArray()).Replace("-", " ")}");
Console.Error.WriteLine($"[LOADER][ERROR] Stall bytes @rip_align: {FormatHexBytes(destination)}");
}
if (rsp != 0 && cpuContext.TryReadUInt64(rsp, out var value) && cpuContext.TryReadUInt64(rsp + 8, out var value2))
{
Expand Down
Loading
Loading