Fix interface table hash-multiplier selection, and grow the multiplier pool#11335
Merged
riknoll merged 3 commits intoMay 29, 2026
Merged
Conversation
Contributor
Author
|
@microsoft-github-policy-service agree |
Member
|
Eric!!! So good to see you back in this repo! We miss you! |
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.
Hey guys it's eanders! I have a compiler bugfix + an optimization here for your consideration. It is very safe.
Summary
Interface dispatch table packing is done using a pow2 algorithm.
computeHashMultiplier(in pxtcompiler/emitter/hexfile.ts) sizes each class's dispatch table by searching for the smallest power-of-two for which some candidate hash multiplier can place all of the class's members within 3vtLookupsprobes. A comparison bug was causing a failing multiplier to be treated as better than a succeeding one, which made the search needlessly double many tables to the next power of two, leading to large voids in the resulting hex file.This PR contains two commits:
The change is purely a size optimization, it does not alter program behavior. I've been testing on microcode -- a relatively large and complex app. On that build, it reduces the hex file size by ~7.6 KB.
The bug
The compiler picks a size for each class's dispatch table by trying every hash multiplier and keeping the best one. The bug made a failed multiplier look better than a successful one, so one failure erased the memory of a multiplier that had already worked. A table size was only kept if the very last multiplier tried happened to succeed, otherwise the table was needlessly doubled, even though an earlier one fit fine.
The fix
The fix was to simply ignore failures and remember only successes with a better fit than the last. Among multipliers that fully placed the class's members: keep the one with the fewest collisions, and accept the smallest size at which any succeeds.
Why this is safe
The format of the emitted table is preserved. It's the same packing algorithm, just a bit more efficient. The only difference is the choice of valid hash multiplier.
Second commit: Enlarge the prime pool
With the selection bug fix in place, adding more multiplier candidates increases the search space for finding a more optimal hash. This is how I found the bug, in fact. I was adding more primes to increase the search space, and it ended up inexplicably increasing the hex file size. Increasing the space made it more likely it would fail into table-doubling.
Measured impact
The microcode build I was testing with had 1023 interface members. Here are the resulting dispatch table utilization measurements:
cc: @thomasjball