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

Use empty alignment bits of pointers to store Result state #401

Open
danakj opened this issue Oct 16, 2023 · 2 comments
Open

Use empty alignment bits of pointers to store Result state #401

danakj opened this issue Oct 16, 2023 · 2 comments
Labels
enhancement New feature or request

Comments

@danakj
Copy link
Collaborator

danakj commented Oct 16, 2023

For Dawn, a Result<ptr, ptr> can be stored in a single pointer (cc: @Kangz) when their values are known to never overlap.

While we can't hold two different newtype wrappers in the same storage, and drop the boolean. We can drop the E storage if it can be held in the T.

This is similar to Option representation but it requires two types, and they must share compatible storage. We may not need the types to opt in at all even, just compatible storage. To be constexpr we can't use reinterpret_cast, so for pointers they would need to be the same or related (static_cast).

@danakj danakj added the design Design of the library systems as a whole, such as concepts label Oct 16, 2023
@danakj danakj added this to the stable-numerics milestone Oct 17, 2023
@danakj
Copy link
Collaborator Author

danakj commented Dec 3, 2023

First, an optimization for pointer/reference T:

What we can do for Result<T*, E> in general, where alignof(T) >= 4, is use the lowest 2 bits to store the state: https://source.chromium.org/chromium/chromium/src/+/main:third_party/dawn/src/dawn/common/Result.h;l=129-130;bpv=1;bpt=1?q=f:dawn%20result&ss=chromium

We can do the same for Result<T&, E>.

This can be done by choosing a separate implementation of storage for the Result here:

using Storage = std::conditional_t< //
std::is_void_v<T>, //
__private::StorageVoid<E>, //
__private::StorageNonVoid<OkStorageType, E>>;

Next, an optimization for pointer E:

Errors are not raw pointers normally, but can be Box<DynError> which has a never value. But that's not enough to implement Result, as Result needs two states beyond if the Err is present (Ok is present, Moved).

Dawn does this by taking the raw pointer out and storing it as an intptr: https://source.chromium.org/chromium/chromium/src/+/main:third_party/dawn/src/dawn/common/Result.h;l=315-316;drc=8e78783dc1f7007bad46d657c9f332614e240fd8;bpv=1;bpt=1?q=f:dawn%20result&ss=chromium

We could unwrap the Box into a raw pointer and use the low bits when alignment of alignof(DynError) >= 4.

Once we see this, we can do the same for Result<Box<T>, E> as well.

These can also be done by choosing a separate implementation of storage for the Result here:

using Storage = std::conditional_t< //
std::is_void_v<T>, //
__private::StorageVoid<E>, //
__private::StorageNonVoid<OkStorageType, E>>;

Single pointer storage

As noted, we want Result to be constexpr, so static_cast only. If T and E are both pointers (or are T* and Box) and they are compatible then we can make a single storage field if the type also provides a disambiguator function though the Result template.

This seems the least likely to happen in practice as error types are not raw pointers, and would grow the type signature like Result<class T, class E, class Disambiguator = void>. So I am not sure this one is worth persuing.

@danakj danakj added enhancement New feature or request and removed design Design of the library systems as a whole, such as concepts labels Dec 3, 2023
@danakj danakj changed the title Result optimization of storage Use empty alignment bits of pointers to store Result state Dec 3, 2023
@danakj danakj removed this from the stable-numerics milestone Dec 3, 2023
@Ananyasingh2002
Copy link

Please assign me this task!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants