Previously. Contributes towards #31131
The dependency on advapi32.dll actually silently brings along 3 other dlls at runtime (msvcrt.dll, sechost.dll, bcrypt.dll), even if no advapi32 APIs are called. So, this commit actually reduces the number of dlls loaded at runtime by 4 (but only when LLVM is not linked, since LLVM has its own dependency on advapi32.dll).
The data is not super conclusive, but the ntdll version of WindowsSdk appears to run slightly faster than the previous advapi32 version:
Benchmark 1: libc-ntdll.exe ..
Time (mean ± σ): 6.0 ms ± 0.6 ms [User: 3.9 ms, System: 7.1 ms]
Range (min ... max): 4.8 ms ... 7.9 ms 112 runs
Benchmark 2: libc-advapi32.exe ..
Time (mean ± σ): 7.2 ms ± 0.5 ms [User: 5.4 ms, System: 9.2 ms]
Range (min ... max): 6.1 ms ... 8.9 ms 103 runs
Summary
'libc-ntdll.exe ..' ran
1.21 ± 0.15 times faster than 'libc-advapi32.exe ..'
and this mostly seems to be due to changes in the implementation (the advapi32 APIs do a lot of NtQueryKey calls that the new implementation doesn't do) rather than due to the decrease in dll loading. LLVM-less zig binaries don't show the same reduction (the only difference here is the DLLs being loaded):
Benchmark 1: stage4-ntdll\bin\zig.exe version
Time (mean ± σ): 3.0 ms ± 0.6 ms [User: 5.3 ms, System: 4.8 ms]
Range (min ... max): 1.3 ms ... 4.2 ms 112 runs
Benchmark 2: stage4-advapi32\bin\zig.exe version
Time (mean ± σ): 3.5 ms ± 0.6 ms [User: 6.9 ms, System: 5.5 ms]
Range (min ... max): 2.5 ms ... 5.9 ms 111 runs
Summary
'stage4-ntdll\bin\zig.exe version' ran
1.16 ± 0.28 times faster than 'stage4-advapi32\bin\zig.exe version'
With the removal of the advapi32 dependency, the non-ntdll dependencies that remain in an LLVM-less Zig binary are ws2_32.dll (which brings along rpcrt4.dll at runtime), kernel32.dll (which brings along kernelbase.dll at runtime), and crypt32.dll (which brings along ucrtbase.dll at runtime).
For anyone that wants to audit the syscalls before/after, here's the output of compiling lib/compiler/libc.zig and running it via NtTrace for my setup:
https://gist.github.com/squeek502/d57a2f0133164c3149222e3987b10079
Comparison of syscall counts
Before:
COUNT | LINE
-----------------------------------------------------
70 | NtProtectVirtualMemory
64 | NtAllocateVirtualMemory
46 | NtClose
29 | NtTraceControl
20 | NtQueryKey
14 | NtOpenKey
14 | NtOpenKeyEx
14 | NtQueryValueKey
12 | NtMapViewOfSection
11 | NtCreateFile
11 | NtQuerySystemInformation
10 | NtQueryInformationToken
9 | NtApphelpCacheControl
9 | NtOpenSection
9 | NtQueryPerformanceCounter
9 | NtSetInformationVirtualMemory
8 | NtQueryWnfStateData
7 | NtSetInformationWorkerFactory
6 | NtAssociateWaitCompletionPacket
6 | NtCreateEvent
6 | NtCreateWaitCompletionPacket
6 | NtQueryInformationProcess
5 | NtFreeVirtualMemory
5 | NtQuerySystemInformationEx
5 | NtQueryVirtualMemory
5 | NtSetEvent
5 | NtSetInformationProcess
4 | NtCreateSemaphore
4 | NtCreateTimer2
4 | NtQueryAttributesFile
4 | NtQueryDirectoryFile
4 | NtQuerySecurityAttributesToken
4 | NtQueryVolumeInformationFile
4 | NtReadFile
3 | NtAllocateVirtualMemoryEx
3 | NtDeviceIoControlFile
3 | NtSubscribeWnfStateChange
2 | NtCreateIoCompletion
2 | NtCreateWorkerFactory
2 | NtOpenDirectoryObject
2 | NtOpenFile
2 | NtQueryInformationFile
2 | NtSetInformationKey
1 | NtConnectPort
1 | NtCreateMutant
1 | NtCreateSection
1 | NtInitializeNlsFiles
1 | NtOpenProcessToken
1 | NtOpenSemaphore
1 | NtOpenSymbolicLinkObject
1 | NtQueryInformationThread
1 | NtQuerySymbolicLinkObject
1 | NtReleaseMutant
1 | NtSetTimer2
1 | NtSetWnfProcessNotificationEvent
1 | NtTerminateProcess
1 | NtTestAlert
1 | NtWaitForSingleObject
1 | NtWriteFile
-----------------------------------------------------
480 | TOTAL
After:
COUNT | LINE
-----------------------------------------------------
55 | NtAllocateVirtualMemory
51 | NtProtectVirtualMemory
41 | NtClose
16 | NtTraceControl
14 | NtOpenKeyEx
13 | NtOpenKey
11 | NtCreateFile
11 | NtQuerySystemInformation
9 | NtQueryValueKey
8 | NtMapViewOfSection
8 | NtQueryWnfStateData
7 | NtSetInformationWorkerFactory
6 | NtAssociateWaitCompletionPacket
6 | NtCreateWaitCompletionPacket
6 | NtQueryInformationToken
5 | NtApphelpCacheControl
5 | NtCreateEvent
5 | NtOpenSection
5 | NtQueryPerformanceCounter
5 | NtSetEvent
5 | NtSetInformationVirtualMemory
4 | NtCreateTimer2
4 | NtQueryAttributesFile
4 | NtQueryDirectoryFile
4 | NtQueryInformationProcess
4 | NtQuerySecurityAttributesToken
4 | NtReadFile
4 | NtSetInformationProcess
3 | NtAllocateVirtualMemoryEx
3 | NtFreeVirtualMemory
3 | NtQuerySystemInformationEx
3 | NtQueryVirtualMemory
3 | NtSubscribeWnfStateChange
2 | NtCreateIoCompletion
2 | NtCreateSemaphore
2 | NtCreateWorkerFactory
2 | NtDeviceIoControlFile
2 | NtOpenDirectoryObject
2 | NtQueryInformationFile
1 | NtConnectPort
1 | NtCreateMutant
1 | NtCreateSection
1 | NtInitializeNlsFiles
1 | NtOpenFile
1 | NtOpenProcessToken
1 | NtOpenSemaphore
1 | NtOpenSymbolicLinkObject
1 | NtQueryInformationThread
1 | NtQuerySymbolicLinkObject
1 | NtQueryVolumeInformationFile
1 | NtReleaseMutant
1 | NtSetTimer2
1 | NtSetWnfProcessNotificationEvent
1 | NtTerminateProcess
1 | NtTestAlert
1 | NtWaitForSingleObject
1 | NtWriteFile
-----------------------------------------------------
365 | TOTAL