-
Notifications
You must be signed in to change notification settings - Fork 10.5k
ARCAnalysis: fix canNeverUseObject to correctly handle builtins. #25985
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
@swift-ci test. |
@swift-ci test source compatibility |
@swift-ci benchmark |
Performance: -O
Code size: -O
Performance: -Osize
Code size: -OsizePerformance: -Onone
Code size: -swiftlibs
How to read the dataThe tables contain differences in performance which are larger than 8% and differences in code size which are larger than 1%.If you see any unexpected regressions, you should consider fixing the Noise: Sometimes the performance results (not code size!) contain false Hardware Overview
|
Build failed |
Nice catch! |
if (!canNeverUseValues(&I) || I.mayReleaseOrReadRefCount() || | ||
// FIXME: mayReleaseOrReadRefCount should be a strict subset of | ||
// canUseObject. If not, there is a bug in canUseObject. | ||
if (canUseObject(&I) || I.mayReleaseOrReadRefCount() || |
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.
If it should be a strict subset, why not just put in an assert (maybe you do not feel comfortable with relying since you haven't done a go over?).
Even if you don't feel comfortable with that (i.e. you want us to be conservatively correct in non-asserts builds), we should have an assert here to track down the issues.
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.
The code is currently dead and the FIXME is just speculation. I added it as a note to whomever looks at the code again soon in case we temporarily resurrect it. I think that will be the time to clean it up. I didn't want to potentially change the original behavior without testing it. At some not-to-distant point the code will be deleted anyway.
This analysis helper was inverting the result for builtins. Builtins such as "copyMemory" were treated as never using a value. This manifested in a crash in TestFoundation. NSDictionary's initializer released the incoming array before copying it. This crashed later during dictionary destruction. The crash was hidden by a secondary bug in mayHaveSymmetricInterference that effectively ignored the result from canNeverUseValue. Rename the helper to canUseObject, invert the result for builtins, and fix mayHaveSymmetricInterference to respect the result of canUseObject. Note that instructions that cannot access a referenced object obviously cannot not "interfere" with a release. Fixing these bugs now allows ARC optimization around dealloc_stack and other operations that don't care about the reference count.
@swift-ci test |
Build failed |
Build failed |
@swift-ci smoke test linux |
1 similar comment
@swift-ci smoke test linux |
This analysis helper was inverting the result for builtins. Builtins
such as "copyMemory" were treated as never using a value.
This manifested in a crash in TestFoundation. NSDictionary's
initializer released the incoming array before copying it. This
crashed later during dictionary destruction.
The crash was hidden by a secondary bug in mayHaveSymmetricInterference
that effectively ignored the result from canNeverUseValue.
Rename the helper to canUseObject, invert the result for builtins, and
fix mayHaveSymmetricInterference to respect the result of
canUseObject.
Note that instructions that cannot access a referenced object
obviously cannot not "interfere" with a release.
Fixing these bugs now allows ARC optimization around dealloc_stack and
other operations that don't care about the reference count.