-
Notifications
You must be signed in to change notification settings - Fork 8.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ensure equality when hashing default args and no args in actions #10341
Conversation
This can't be serviced to Stable as that code doesn't exist in Stable. Be careful with those servicing tags... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woops I meant to comment and not approve.
I'll request changes, since I can't undo an approval.
It seems |
My bad. Wasn't sure if |
Yeah. This is where I wish I took a course on cryptography and hashing in college haha. I don't think that theoretically there could be no collisions. That said, in practice, we haven't seen any so we're probably fine for now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Long term a more robust equality-solution would be nice, but that's for another day.
Until then: LGTM.
#define ON_ALL_ACTIONS_WITH_ARGS(action) \ | ||
case ShortcutAction::action: \ | ||
/* If it does, hash the default values for the args.*/ \ | ||
hashedArgs = gsl::narrow_cast<size_t>(make<action##Args>().Hash()); \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I low-key hate that this requires constructing an entire object filled with default values to calculate a hash; it could be wildly expensive. Can you profile to make sure we're not making a bunch of objects just to destroy them moments later? Both CPU and memory-wise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like we could get around this by maintaining a static .Empty singleton of each of these if this is what we need to Hash... or cache the hash of the empty one as a singleton...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be fair though none of the ActionArgs constructors are complex at the moment.
As such I "propose" the following solution:
- add
constexpr
to the default constructors of all ActionArgs classes - add
constexpr
to all theirHash()
member functions - add
constexpr
to the getters of theACTION_ARG
andWINRT_PROPERTY
macros - write:
case ShortcutAction::action: hashedArgs = implementation::action##Args{}.Hash(); break;
This will probably compile to constants in release mode and in debug mode it won't allocate anything on the heap.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That will be illegal because we're not using winrt::make
for something that's known to be a runtimeclass.
03dd81d
to
a5e6d46
Compare
a5e6d46
to
d83a764
Compare
Added Took the average of 5 perf traces in VS:
With this change, we see an average increase of 756.8 Allocations and 70.82 Heap Size. Scenario:
These hashes are always first used in |
Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
Hello @DHowett! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
) ## Summary of the Pull Request #10297 found a bug in `ActionMap` where the `ToggleCommandPalette` key chord could not be found using `GetKeyBindingForAction`. This was caused by the following: - `AddAction`: when adding the action, the `ActionAndArgs` is basically added as `{ToggleCommandPalette, ToggleCommandLineArgs{}}` (Note the default ctor used for the action args) - `GetKeyBindingForAction`: we're searching for an `ActionAndArgs` structured as `{ToggleCommandPalette, nullptr}` - Since these are _technically_ two different actions, we are unable to find it. This issue was fixed by making the `Hash(ActionAndArgs)` function smarter! If the `ActionAndArgs` has no args, but the `ShortcutAction` _supports_ args, generate the args using the default ctor. By making `Hash()` smarter, everybody benefits from this logic! We can basically now enforce that `ActionAndArgs{ <X>, nullptr } == ActionAndArgs{ <X>, <default_ctor> }`. ## Validation Steps Performed - Added a test. - Tested this on #10297's branch and this does fix the bug (cherry picked from commit b3b6484)
Summary of the Pull Request
#10297 found a bug in
ActionMap
where theToggleCommandPalette
key chord could not be found usingGetKeyBindingForAction
.This was caused by the following:
AddAction
: when adding the action, theActionAndArgs
is basically added as{ToggleCommandPalette, ToggleCommandLineArgs{}}
(Note the default ctor used for the action args)GetKeyBindingForAction
: we're searching for anActionAndArgs
structured as{ToggleCommandPalette, nullptr}
This issue was fixed by making the
Hash(ActionAndArgs)
function smarter! If theActionAndArgs
has no args, but theShortcutAction
supports args, generate the args using the default ctor.By making
Hash()
smarter, everybody benefits from this logic! We can basically now enforce thatActionAndArgs{ <X>, nullptr } == ActionAndArgs{ <X>, <default_ctor> }
.Validation Steps Performed