Skip to content
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

Add a utility for comparing and hashing rec group shapes #6808

Merged
merged 5 commits into from
Aug 8, 2024
Merged

Conversation

tlively
Copy link
Member

@tlively tlively commented Aug 3, 2024

This is very similar to the internal utilities for canonicalizing rec
groups in the type system implementation, except that the new utility
also supports ordered comparison of rec groups, and of course the new
utility only uses the public type API.

A follow-up PR will replace the internal implementation of rec group
comparison and hashing in the type system with this one.

Another follow-up PR will use this new utility in a type optimization.

@tlively tlively requested a review from kripken August 3, 2024 01:09
std::unordered_map<HeapType, Index> typeIndices;
for (auto type : types) {
typeIndices.insert({type, typeIndices.size()});
if (type.getRecGroupIndex() == 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does index 0 mean that is special? I looked at the definition of the function in wasm-type.h and don't see an explanation. In fact I'm not sure what the index means - is it some kind of global unique index?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getRecGroupIndex gives the index of type within its rec group, so whenever it is zero, we know we are starting a new rec group.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add a comment.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Please also add a comment to wasm-types.h.

std::unordered_map<HeapType, Index> typeIndices;
for (auto type : types) {
typeIndices.insert({type, typeIndices.size()});
if (type.getRecGroupIndex() == 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Please also add a comment to wasm-types.h.

}
} else {
// Hash collisions are technically possible, but should be rare enough
// that we can consider them bugs if the fuzzer finds them.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤞

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually did find one in practice, but then I generated some random numbers to mix in for the different type kinds and I didn't see one after that.

src/wasm-type-shape.h Show resolved Hide resolved
Base automatically changed from fix-type-fuzzer-shared to main August 6, 2024 17:23
This is very similar to the internal utilities for canonicalizing rec
groups in the type system implementation, except that the new utility
also supports ordered comparison of rec groups, and of course the new
utility only uses the public type API.

A follow-up PR will replace the internal implementation of rec group
comparison and hashing in the type system with this one.

Another follow-up PR will use this new utility in a type optimization.
// and equality differentiate the top-level structure of each type in the
// sequence and the equality of referenced heap types that are not in the
// recursion group, but for references to types that are in the recursion group,
// it considers only the index of the referenced type within the group. That
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it considers the index in the group, wouldn't these end up different?

(rec
  (type $A (sub (struct (field (ref $B)))))
  (type $B (sub (struct)))
)
(rec
  (type $B (sub (struct)))
  (type $A (sub (struct (field (ref $B)))))
)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes indeed, although those rec groups are already different just by looking at their top-level shapes. It would consider these different as well, where the top-level shapes are all the same:

(rec
  (type $A (struct (field (ref $A))))
  (type $B (struct (field (ref $B))))
)
(rec
  (type $A (struct (field (ref $A))))
  (type $B (struct (field (ref $A))))
)

This precisely matches the spec's notion of rec group identity.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, thanks, that's what I was missing. So this is matching the spec behavior, and not defining another notion. I thought a broader notion might make sense when looking at permutations of rec groups but I may have misunderstood the connection of this PR to your other work.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, this PR is providing the tools for detecting when the spec would consider two rec groups to the be same so we can then take action to differentiate them.

Copy link
Member

@kripken kripken left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it not worth testing this independently?

@tlively
Copy link
Member Author

tlively commented Aug 8, 2024

I think the type fuzzer is sufficient for now. It gets great coverage very easily, whereas we would have to have very many unit tests to get full coverage. I also aim to use this new code in the type system implementation soon, where it will be exercised by all of our existing tests.

@tlively tlively merged commit 2397f2a into main Aug 8, 2024
13 checks passed
@tlively tlively deleted the type-shape branch August 8, 2024 00:49
@gkdn gkdn mentioned this pull request Aug 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants