-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Fix potentially undefined behavior in StringObject.nativeStorage and document Builtin.unsafeBitCast #63631
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
Speculatively fixing this to rule out potential miscompiles. The compiler needs to know if a reference is being materialized out of thin air. The proper way to do that is with the Unmanaged API. Under the hood, this forces the reference into an "unowned(unsafe)" variable which the reference must be reloaded from. That tells the compiler that it can't optimize some seemingly unrelated object which the reference may happen to refer to at runtime. /// Warning: Casting from an integer or a pointer type to a reference type /// is undefined behavior. It may result in incorrect code in any future /// compiler release. To convert a bit pattern to a reference type: /// 1. convert the bit pattern to an UnsafeRawPointer. /// 2. create an unmanaged reference using Unmanaged.fromOpaque() /// 3. obtain a managed reference using Unmanaged.takeUnretainedValue() /// The programmer must ensure that the resulting reference has already been /// manually retained.
@swift-ci test |
@swift-ci benchmark |
This is increasing my anxiety about some unsafeBitCasts I introduced in #62717: 🤔
|
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 for the forceful unsafeBitCast
clarification.
Benchmark results: Performance (x86_64): -O
Code size: -OPerformance (x86_64): -Osize
Code size: -OsizePerformance (x86_64): -Onone
Code size: -swiftlibsHow 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
|
Don't merge this. We need to figure out how to recover performance first. |
Huh, did the old code somehow manage to avoid retaining the storage object? 🤯 If that's what causing the perf regressions, one unimaginative way to fix that would be to have |
Fixed in #63646 |
Speculatively fixing this to rule out potential miscompiles.
The compiler needs to know if a reference is being materialized out of thin air. The proper way to do that is with the Unmanaged API.
Under the hood, this forces the reference into an "unowned(unsafe)" variable which the reference must be reloaded from. That tells the compiler that it can't optimize some seemingly unrelated object which the reference may happen to refer to at runtime.
/// Warning: Casting from an integer or a pointer type to a reference type
/// is undefined behavior. It may result in incorrect code in any future
/// compiler release. To convert a bit pattern to a reference type:
/// 1. convert the bit pattern to an UnsafeRawPointer.
/// 2. create an unmanaged reference using Unmanaged.fromOpaque()
/// 3. obtain a managed reference using Unmanaged.takeUnretainedValue()
/// The programmer must ensure that the resulting reference has already been
/// manually retained.