Skip to content

weak_ptr conversions can sometimes avoid locking - #2282

Merged
Stephan T. Lavavej (StephanTLavavej) merged 28 commits into
microsoft:mainfrom
AlexGuteniev:sometimes_avoid_locking
Nov 3, 2021
Merged

Stephan T. Lavavej (StephanTLavavej) merged 28 commits into
microsoft:mainfrom
AlexGuteniev:sometimes_avoid_locking

Conversation

@AlexGuteniev

Copy link
Copy Markdown
Contributor

Resolves #258

Test happen to recreate the issue for me on attempt #0
if unconditionally avoid locking

Resolves microsoft#258

Test happen to recreate the issue for me on attempt #0
if unconditionally avoid locking
@AlexGuteniev
Alex Guteniev (AlexGuteniev) requested a review from a team as a code owner October 17, 2021 18:22
rather than C-style casts
because we don't need to punch through accessibility
Comment thread stl/inc/memory Outdated
Comment thread tests/std/tests/Dev10_851347_weak_ptr_virtual_inheritance/test.cpp
Comment thread stl/inc/memory Outdated
@StephanTLavavej Stephan T. Lavavej (StephanTLavavej) changed the title Sometimes avoid locking weak_ptr conversions can sometimes avoid locking Oct 20, 2021
@cpplearner

Copy link
Copy Markdown
Contributor

IIUC this does not optimize for the X -> const X case mentioned in #258 (since static_cast(declval()) is invalid). Maybe also consider is_convertible<_Ty2(*)[], _Ty(*)[]>?

@AlexGuteniev

Copy link
Copy Markdown
Contributor Author

IIUC this does not optimize for the X -> const X case mentioned in #258 (since static_cast(declval()) is invalid). Maybe also consider is_convertible<_Ty2(*)[], _Ty(*)[]>?

Good point, but I preferred to update the existing check to cover Derived -> const Base as well

Comment thread tests/std/tests/Dev10_851347_weak_ptr_virtual_inheritance/test.cpp Outdated
Comment thread stl/inc/memory Outdated
@StephanTLavavej

Copy link
Copy Markdown
Member

S. B. Tam (@cpplearner) I think that Alex Guteniev (@AlexGuteniev)'s code does handle X -> const X, although (as I mentioned in my review) the logic is very subtle.

Suppose that we're constructing a weak_ptr from weak_ptr. The constructor is weak_ptr(const weak_ptr<_Ty2>& _Other), so "our" _Ty is const int and "their" _Ty2 is int. The type trait's static_cast is intentionally reversed:

template <class _Ty2>
static constexpr bool _Is_virtual_base_cast<_Ty2, decltype(static_cast<const _Ty2*>(_STD declval<_Ty*>()))> = false;

This starts with declval<_Ty*>(), i.e. declval(), and asks whether we can static_cast, i.e. static_cast. So we've formed the same type, the static_cast is well-formed, and the type trait returns false (saying "we don't need the expensive machinery to avoid virtual inheritance weirdness").

At a high level, the technique is saying that when implicitly converting from source-to-dest (whether adding constness or converting derived-to-base), a static_cast from dest-to-const source is valid except in the virtual inheritance case we care about.

(Aside: I noticed that this doesn't consider volatile and I'm fine with that, it'll select the slow path.)

@AlexGuteniev

Copy link
Copy Markdown
Contributor Author

For the record, S. B. Tam (@cpplearner) comment was useful, as I added const after it

@StephanTLavavej

Copy link
Copy Markdown
Member

Thanks for finding the EDG bug! I reported it as DevCom-1564433 and pushed a perma-workaround after discovering that changing _STD declval<_Ty*>() to static_cast<_Ty*>(nullptr) avoids the bug.

As we don't need to skip EDG here
@CaseyCarter Casey Carter (CaseyCarter) removed their assignment Oct 27, 2021
@StephanTLavavej

Copy link
Copy Markdown
Member

I'm mirroring this to the MSVC-internal repo - please notify me if any further changes are pushed.

@StephanTLavavej

Copy link
Copy Markdown
Member

Alex Guteniev (@AlexGuteniev) Casey Carter (@CaseyCarter) I've pushed changes to fix test failures for /clr:pure, the Betrayer of Hope - the simplest thing is to entirely disable this optimization.

@CaseyCarter

Copy link
Copy Markdown
Contributor

Alex Guteniev (@AlexGuteniev) Casey Carter (@CaseyCarter) I've pushed changes to fix test failures for /clr:pure, the Betrayer of Hope - the simplest thing is to entirely disable this optimization.

Having recently begun my fourth trip through the Wheel of Time, I'm deeply offended that you would liken /clr:pure to Ishamael. Not even one of the Forsaken is as dark and twisted as /clr:pure!

@StephanTLavavej
Stephan T. Lavavej (StephanTLavavej) merged commit 3279b7c into microsoft:main Nov 3, 2021
@StephanTLavavej

Copy link
Copy Markdown
Member

Thanks for implementing this long-dreamed-of optimization! 🐈 💤 😻

@AlexGuteniev
Alex Guteniev (AlexGuteniev) deleted the sometimes_avoid_locking branch November 3, 2021 05:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance Must go faster

Projects

None yet

Development

Successfully merging this pull request may close these issues.

: weak_ptr's converting constructors could sometimes avoid locking

5 participants