-
Notifications
You must be signed in to change notification settings - Fork 10.5k
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
Conversation
67eef7c
to
c24853c
Compare
@swift-ci test |
SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LifetimeDependenceScopeFixup.swift
Outdated
Show resolved
Hide resolved
SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LifetimeDependenceScopeFixup.swift
Show resolved
Hide resolved
SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LifetimeDependenceScopeFixup.swift
Show resolved
Hide resolved
SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LifetimeDependenceScopeFixup.swift
Outdated
Show resolved
Hide resolved
SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LifetimeDependenceScopeFixup.swift
Outdated
Show resolved
Hide resolved
SwiftCompilerSources/Sources/SIL/Utilities/SequenceUtilities.swift
Outdated
Show resolved
Hide resolved
end_cow_mutation_addr %0 : $*T | ||
// %0 must be of an address $*T type | ||
``` | ||
|
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LifetimeDependenceScopeFixup.swift
Outdated
Show resolved
Hide resolved
f03435e
to
fad3ea2
Compare
There was a problem hiding this 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.
SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LifetimeDependenceScopeFixup.swift
Outdated
Show resolved
Hide resolved
@@ -1735,10 +1746,12 @@ extension Array { | |||
@lifetime(&self) | |||
@_alwaysEmitIntoClient | |||
mutating get { | |||
#if INTERNAL_CHECKS_ENABLED && COW_CHECKS_ENABLED |
There was a problem hiding this comment.
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 | ||
``` | ||
|
There was a problem hiding this comment.
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
!
9797647
to
4df2bb4
Compare
…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.
@swift-ci test |
@swift-ci test |
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