set subsections_via_symbols for ld64 helper sections#139752
set subsections_via_symbols for ld64 helper sections#139752bors merged 1 commit intorust-lang:masterfrom
Conversation
|
r? @Nadrieril rustbot has assigned @Nadrieril. Use |
|
Some changes occurred in compiler/rustc_codegen_ssa |
This comment was marked as outdated.
This comment was marked as outdated.
| if binary_format == BinaryFormat::MachO { | ||
| file.set_subsections_via_symbols(); | ||
| } |
There was a problem hiding this comment.
It's not clear to me that this needs to be in create_object_file? Maybe it would be better to only use it in add_linked_symbol_object?
Also, MH_SUBSECTIONS_VIA_SYMBOLS is vastly under-documented, I'd really like to see a comment here explaining why it's safe for us to use.
There was a problem hiding this comment.
Object::set_subsections_via_symbols says it should be called before add_section or add_subsection, so I feel it better to put it here (not error-prone).
I don't know whether it's safe or not, either. I searched on the Internet and found that this is the only way for Mach-O to implement GC.
There was a problem hiding this comment.
My problem with having it in create_object_file is that it may negatively affect the other object files we create (which again is hard to tell for sure, since the docs around it are so limited).
There was a problem hiding this comment.
Ah! I didn't notice that this function has multiple callers.
I will add a parameter to control this behavior.
There was a problem hiding this comment.
Eh, I'd still have preferred to just change add_linked_symbol_object, it'd be unexpected if create_object_file added any sections or subsections, it's literally prefixed "create" as in "only create, do not fill".
But will leave it up to the compiler reviewer to decide, this is a nit anyhow.
| unsafe extern "C" { | ||
| unsafe static UNDEFINED: usize; | ||
| } | ||
|
|
||
| #[unsafe(no_mangle)] | ||
| pub fn used() { | ||
| println!("UNDEFINED = {}", unsafe { UNDEFINED }); | ||
| } |
There was a problem hiding this comment.
Honestly, I'm kind of surprised that this worked in the past. Could you describe the use-case?
I'd also be interested, does this pattern work on other platforms?
There was a problem hiding this comment.
It's used by https://github.com/pgcentralfoundation/pgrx. It's a framework for developing PostgreSQL extensions. This trick is used for writing hybrid (dylib and SQL generation) code in a library. Code about SQL generation could be compiled to an executable, since dylib-related code are GC-ed.
This should be reasonable usage. Please see #95604 and #95363 (comment).
Yes. It works for Linux, FreeBSD, and Windows, too.
There was a problem hiding this comment.
Thanks for the answer. Might make sense to leave a comment in the file about this, and perhaps link to #139744, stating that it is a regression test for that?
There was a problem hiding this comment.
Also, is the expected behaviour for the symbol to still be present, or do we expect the linker to completely strip it out? E.g. would dlsym(RTLD_DEFAULT, "used") work?
There was a problem hiding this comment.
The symbol is present in fhe dynamic library. It's GC-ed iff the final artifact is the executable.
There was a problem hiding this comment.
An idea then would perhaps be to add another test (or use UI-test revisions) with #![crate_type = "dylib"] and //@ dont-check-compiler-stderr that expectedly fails?
There was a problem hiding this comment.
I think it's alreay tested in https://github.com/rust-lang/rust/tree/master/tests/run-make/c-link-to-rust-dylib.
There was a problem hiding this comment.
No, I meant having test that fails when trying to link undefined symbols in a dylib
|
cc @bjorn3 @petrochenkov in case this is problematic |
| #[unsafe(no_mangle)] | ||
| pub unsafe fn used() { | ||
| println!("THIS_SYMBOL_SHOULD_BE_UNDEFINED = {}", unsafe { THIS_SYMBOL_SHOULD_BE_UNDEFINED }); | ||
| } |
There was a problem hiding this comment.
Nit: I know that #[no_mangle] implies it, but could we also add an explicit test for #[used]?
There was a problem hiding this comment.
#[used] emits errors, while #[no_mangle] does not, on MacOS.
Don't know why.
Edit: using pr + lld, nightly + lld, stable + lld, stable + ld64, #[used] emits errors, too.
There was a problem hiding this comment.
I know why now.
On MacOS, #[used] emits llvm.used. So #[used(compiler)] is needed here. Is it expected behavior?
There was a problem hiding this comment.
TIL that #[used] is an alias for #[used(linker)] on some platforms:
rust/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
Lines 195 to 223 in f836ae4
#[used] should be changed to #[used(linker)] unconditionally anyway. Gold is deprecated upstream and broken with current rustc versions anyway: #139425
Edit: Opened #140872 for making #[used] an alias for #[used(linker)] unconditionally.
6e175fc to
7d10cf7
Compare
|
r? codegen |
| } | ||
| if binary_format == BinaryFormat::MachO { | ||
| if set_subsections_via_symbols { | ||
| file.set_subsections_via_symbols(); |
There was a problem hiding this comment.
Still needs a documentation comment IMO explaining why we do this.
|
On windows-gnu, the linker removes statics marked with |
|
Can you add the reason windows-gnu is special for this test to the magic comment? |
|
@bors r=saethlin,madsmtm |
|
☀️ Test successful - checks-actions |
What is this?This is an experimental post-merge analysis report that shows differences in test outcomes between the merged PR and its parent PR.Comparing d7ea436 (parent) -> 847e3ee (this PR) Test differencesShow 6 test diffsStage 1
Stage 2
Job group index
Test dashboardRun cargo run --manifest-path src/ci/citool/Cargo.toml -- \
test-dashboard 847e3ee6b0e614937eee4e6d8f61094411eadcc0 --output-dir test-dashboardAnd then open Job duration changes
How to interpret the job duration changes?Job durations can vary a lot, based on the actual runner instance |
|
Finished benchmarking commit (847e3ee): comparison URL. Overall result: ❌✅ regressions and improvements - please read the text belowOur benchmarks found a performance regression caused by this PR. Next Steps:
@rustbot label: +perf-regression Instruction countThis is the most reliable metric that we have; it was used to determine the overall result at the top of this comment. However, even this metric can sometimes exhibit noise.
Max RSS (memory usage)Results (primary -0.4%, secondary -1.7%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResults (primary 0.7%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 777.966s -> 776.153s (-0.23%) |
|
I don't really understand how this change could have the performance impact seen here. Some of the regressions do seem like pure noise (with the next run returning back to the previous baseline), but not all of them. @usamoi @saethlin would you agree that the regressions here are unlikely to be actually caused by this change? |
|
This should only affect macOS/Apple platforms, and I don't think the benchmarks are run on those? |
|
That is correct. I'll mark this as triaged @rustbot label: +perf-regression-triaged |
|
This was discussed in today's compiler triage meeting. Beta backport was approved, thanks! @rustbot label: +beta-accepted |
[beta] backports - Don't allow flattened format_args in const. rust-lang#139624 - set subsections_via_symbols for ld64 helper sections rust-lang#139752 - Fix detection of `main` function if there are expressions around it rust-lang#140220 - rustdoc: Fix doctest heuristic for main fn wrapping rust-lang#140420 - extend the list of registered dylibs on `test::prepare_cargo_test` rust-lang#140563 r? cuviper
closes #139744
cc @madsmtm