-
-
Notifications
You must be signed in to change notification settings - Fork 748
variant: Value semantics for big payloads #10925
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
Conversation
VariantN structs contain a buffer to store the payload. The size of that buffer is determined by a template argument and thus part of the type. If you try to store a bigger payload in the same variable, the buffer size can't change, so what is done instead is that Variant will store a pointer to the data on the heap. The problem is that now we have to update this pointer on every copy operation, otherwise Variant switches from Value semantics to reference semantics. This can either be done in the actual postblit of variant or the handler function on the operation OpID.postblit. I chose the handler, because it access to the type of the payload, the Variant postblit function would have dispatch to the handler every time otherwise to get the typeinfo and thus the size of the payload at runtime. Fixes dlang#10062 Fixes dlang#9783 Bug dlang#9783 had the same root cause. The reduction from that issue became the testcase for this and has been modified it to hit all branches in the OpID.postblit handling.
std.variant didn't compile when the payload was a struct that was bigger than its internal buffer and had to be allocated on the heap if that struct `@disabled this()`. The new handling now always skips the constructor and just copies the directly to the allocated regions.
|
Thanks for your pull request and interest in making D better, @Inkrementator! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. Bugzilla referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.
|
The condition that lead to postblit creation contained a typo which sadly didn't trigger a compiler error. Fix that and also verify in unittests that postblit is only generated when necessary. handler(OpID.postblit) would've probably still be a no-op, so this is technically just a performance optimization.
Only generate handler for OpID.postblit if it is possible for it to be called.
No need to generate it for each different VariantN instantiation.
|
Does this fix #9783 ? |
|
Yes |
VariantN structs contain a buffer to store the payload. The size of that
buffer is determined by a template argument and thus part of the type.
If you try to store a bigger payload in the same variable, the buffer
size can't change, so what is done instead is that Variant will store a
pointer to the data on the heap.
The problem is that now we have to update this pointer on every copy
operation, otherwise Variant switches from Value semantics to reference
semantics.
This can either be done in the actual postblit of variant or the handler
function on the operation OpID.postblit. I chose the handler, because it
access to the type of the payload, the Variant postblit function would
have dispatch to the handler every time otherwise to get the typeinfo
and thus the size of the payload at runtime.
Fixes #10062
Fixes #9783
Bug #9783 had the same root cause. The reduction from that issue became the testcase for this and has been modified it to hit all branches in the OpID.postblit handling.