Fix sjiswrap GetProcAddress regressions; cut per-compile overhead ~2x for MWCC workloads - #145
Open
fjooord wants to merge 4 commits into
Open
Fix sjiswrap GetProcAddress regressions; cut per-compile overhead ~2x for MWCC workloads#145fjooord wants to merge 4 commits into
fjooord wants to merge 4 commits into
Conversation
sjiswrap.exe resolves mwcceppc.exe's imports via GetProcAddress and requests lmgr11.dll ordinal 191, which the builtin lmgr stub does not implement. wibo 1.1.0 returned a lazy missing-function stub (aborting only if actually called); the module refactor changed this to NULL, which makes sjiswrap abort at load with PeLoaderErr(GetProcAddressFail). Restore the 1.1.0 behavior, scoped to the builtin lmgr module: it is a deliberately fake, pinned module, so any name/ordinal a real FlexLM DLL would export should resolve to a callable-abort stub. Other builtin modules keep NULL + ERROR_PROC_NOT_FOUND for feature detection.
…yscalls An MWCC compile through wibo issued ~182k syscalls for ~360 real file opens: every failed include probe walked each path component with a directory enumeration (no cache), CreateFile performed exists+status+ open+fstat+weakly_canonical+lseek per open, GetFileAttributes stat'd resolved paths a second time, and GetFullPathNameA hit the filesystem for what Win32 defines as a lexical operation. - per-directory case-insensitive lookup cache (one enumeration per directory, first-seen-wins to preserve readdir-order tie-breaks) with negative caching, revalidated by directory stat identity and invalidated on wibo-initiated create/rename/delete - CreateFile: single open with disposition-derived flags + one fstat; canonicalization is now lazy (only delete-on-close/name queries) - GetFileAttributes[Ex] reuses the stat gathered during resolution - GetFullPathNameA/W is purely lexical per the Win32 contract Syscalls per MWCC compile drop from ~182k to ~18k; wall clock for a full melee (doldecomp) build drops ~2x. All 2135 objects verified byte-identical before/after.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two regression fixes that unblock sjiswrap.exe on wibo ≥ 1.2.0, plus two performance commits that roughly halve wall-clock for MWCC compiler workloads. All four verified against the melee (doldecomp) build: full build of 2135 objects, every object byte-identical, 100.9s → 51.4s (macOS x86_64 host; similar ratios measured on Linux i686).
Regression fixes (why projects are stuck on old versions)
FormatMessageAexport lost — implemented inwinbase.cppbut its header declaration was commented out, so the trampoline generator never emitted a resolver entry.GetProcAddress(kernel32, "FormatMessageA")returns NULL and sjiswrap aborts withPeLoaderErr(GetProcAddressFail). Restored + regression test.GetProcAddressby ordinal on the builtin lmgr stub returns NULL — sjiswrap resolves mwcceppc.exe's imports itself and requestslmgr11.dllordinal 191. wibo 1.1.0 returned a lazy missing-function stub (abort only if called; MWCC never calls it). Restored that behavior, scoped to the pinned/fake lmgr module only — other builtins keep NULL +ERROR_PROC_NOT_FOUNDfor feature detection.Together these are why doldecomp/melee still pins 0.7.0 (see also #104, whose lmgr-from-disk mechanism the existing pinning already mitigates).
Performance
GetTickCount×135,731,GetLastError×101,434,IsDBCSLeadByte×100,553 — each a full guest↔host trampoline round-trip for what Windows serves from userland. These now execute entirely in 32-bit guest mode:GetLastError/SetLastErrorread/writefs:[0x34](TEB.LastErrorValue, already the source of truth),GetCurrentThreadIdreads the TEB,IsDBCSLeadByteis constant-FALSE only when the ACP has no DBCS lead bytes, andGetTickCountreads a KUSER_SHARED_DATA-style tick page maintained at 1ms by a lazily-started updater (Windows itself has 10–16ms granularity).WIBO_DEBUG=1falls back to host thunks so debug traces still show these calls.CreateFile, double-stats inGetFileAttributes, and filesystem access in the lexically-definedGetFullPathName. With a per-directory case-insensitive cache (readdir-order tie-breaks preserved, negative caching, stat-identity revalidation, invalidation on wibo-initiated mutations), lazy canonicalization, and a lexicalGetFullPathName: ~182k → ~18k syscalls per compile (QEMU_STRACE, Linux i686). For reference, wibo 0.7.0 issues ~44k on the same TU — this branch is ~1.6x faster than 0.7.0 wall-clock in the same container.Verification
.ofiles sha256-identical;.doutputs identical.release-macospreset).Happy to split this into separate PRs (fixes vs perf) if you prefer.
🤖 Generated with Claude Code