Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Insert end_cow_mutation_addr for lifetime dependent values dependent on mutable addresses #81043

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

Merged
merged 4 commits into from
May 1, 2025

Conversation

meg-gupta
Copy link
Contributor

@meg-gupta meg-gupta commented Apr 23, 2025

Array/ArraySlice/ContiguousArray have support for mutableSpan property. These types are "optimized COW" types, we use compiler builtins begin_cow_mutation/end_cow_mutation to optimize uniqueness checks. Since mutableSpan is a property and not a coroutine there is no way to schedule the end_cow_mutaton operation at the end of the access.
This can lead to miscompiles in rare cases where we can end up using a stale storage buffer after a cow.

This PR inserts end_cow_mutation_addr to avoid this issue.

Note: We can end up with unnecessary end_cow_mutation_addr. But it is just a barrier to prevent invalid optimizations
and has no impact.

Fixes rdar://146785284

@meg-gupta meg-gupta changed the title Insert end_cow_mutation for lifetime dependent values dependent on modify accesses of optimized COW types Insert end_cow_mutation_addr for lifetime dependent values dependent on modify accesses Apr 24, 2025
@meg-gupta meg-gupta force-pushed the fixcow branch 2 times, most recently from 67eef7c to c24853c Compare April 29, 2025 13:25
@meg-gupta meg-gupta changed the title Insert end_cow_mutation_addr for lifetime dependent values dependent on modify accesses Insert end_cow_mutation_addr for lifetime dependent values dependent on mutable addresses Apr 29, 2025
@meg-gupta
Copy link
Contributor Author

@swift-ci test

@meg-gupta meg-gupta marked this pull request as ready for review April 29, 2025 17:20
@meg-gupta meg-gupta requested a review from atrick April 29, 2025 17:20
end_cow_mutation_addr %0 : $*T
// %0 must be of an address $*T type
```

Copy link
Contributor

Choose a reason for hiding this comment

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

IIUC, the operand is not necessarily the address of a single class reference. It can e.g. be an opaque archetype or a structure, etc.
Can you point that out? And describe what it means, e.g. that it refers to all class instances contained in the type, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated to:

sil-instruction ::= 'end_cow_mutation_addr' sil-operand

end_cow_mutation_addr %0 : $*T
// %0 must be of an address $*T type

This instruction marks the end of mutation of an address that may contain MutableSpan.
The address could be an opaque archetype, a struct type, tuple type or enum type and
the end_cow_mutation_addr will apply to all members contained within these types.
It is currently only generated in cases where is it is not possible to schedule an
end_cow_mutation in the standard library automatically. Ex: Array.mutableSpan

Copy link
Contributor

Choose a reason for hiding this comment

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

We should be clear that the type of %0 could be anything that an Array might depend on. Whether it contains MutableSpan seems irrelevant. You could talk about MutableSpan just to describe why the instruction is needed, but make it clear that the dependent value is different from %0!

@@ -1735,10 +1746,12 @@ extension Array {
@lifetime(&self)
@_alwaysEmitIntoClient
mutating get {
#if INTERNAL_CHECKS_ENABLED && COW_CHECKS_ENABLED
Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't make sense. If checks are enabled then you call the unchecked version?
This completely disables the checks in all cases.
Is this intention?

Copy link
Contributor Author

@meg-gupta meg-gupta Apr 30, 2025

Choose a reason for hiding this comment

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

Yes. This is disabling runtime verification for mutableSpan property completely. I kept the #else parts so that we don't have new "unchecked" entry points in the stdlib.

Copy link
Contributor

Choose a reason for hiding this comment

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

It might help to have a short comment explaining when the check needs to be disabled whenever checks are enabled.

@meg-gupta meg-gupta force-pushed the fixcow branch 2 times, most recently from f03435e to fad3ea2 Compare April 30, 2025 19:35
Copy link
Contributor

@atrick atrick left a comment

Choose a reason for hiding this comment

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

Thanks! Only a few comments.

@@ -1735,10 +1746,12 @@ extension Array {
@lifetime(&self)
@_alwaysEmitIntoClient
mutating get {
#if INTERNAL_CHECKS_ENABLED && COW_CHECKS_ENABLED
Copy link
Contributor

Choose a reason for hiding this comment

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

It might help to have a short comment explaining when the check needs to be disabled whenever checks are enabled.

end_cow_mutation_addr %0 : $*T
// %0 must be of an address $*T type
```

Copy link
Contributor

Choose a reason for hiding this comment

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

We should be clear that the type of %0 could be anything that an Array might depend on. Whether it contains MutableSpan seems irrelevant. You could talk about MutableSpan just to describe why the instruction is needed, but make it clear that the dependent value is different from %0!

@meg-gupta meg-gupta force-pushed the fixcow branch 2 times, most recently from 9797647 to 4df2bb4 Compare April 30, 2025 20:32
…on mutable addresses

Array/ArraySlice/ContiguousArray have support for mutableSpan property.
These types are "optimized COW" types, we use compiler builtins begin_cow_mutation/end_cow_mutation to
optimize uniqueness checks. Since mutableSpan is a property and not a coroutine there is
no way to schedule the end_cow_mutaton operation at the end of the access.
This can lead to miscompiles in rare cases where we can end up using a stale storage buffer after a cow.

This PR inserts end_cow_mutation_addr to avoid this issue.

Note: We can end up with unnecessary end_cow_mutation_addr. But it is just a barrier to prevent invalid optimizations
and has no impact.
@meg-gupta
Copy link
Contributor Author

@swift-ci test

@meg-gupta meg-gupta enabled auto-merge April 30, 2025 21:33
@meg-gupta
Copy link
Contributor Author

@swift-ci test

@meg-gupta meg-gupta merged commit 3cad5c5 into swiftlang:main May 1, 2025
4 of 5 checks passed
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.

3 participants