Skip to content
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

Implement -Z oom=panic #88098

Merged
merged 2 commits into from
Mar 18, 2022
Merged

Implement -Z oom=panic #88098

merged 2 commits into from
Mar 18, 2022

Conversation

Amanieu
Copy link
Member

@Amanieu Amanieu commented Aug 17, 2021

This PR removes the #[rustc_allocator_nounwind] attribute on alloc_error_handler which allows it to unwind with a panic instead of always aborting. This is then used to implement -Z oom=panic as per RFC 2116 (tracking issue #43596).

Perf and binary size tests show negligible impact.

@rust-highfive
Copy link
Collaborator

r? @kennytm

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 17, 2021
@Amanieu
Copy link
Member Author

Amanieu commented Aug 17, 2021

@bors try @rust-timer queue

@rust-timer
Copy link
Collaborator

Awaiting bors try build completion.

@rustbot label: +S-waiting-on-perf

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Aug 17, 2021
@bors
Copy link
Contributor

bors commented Aug 17, 2021

⌛ Trying commit 97c23fdb1834d1669314cc73b3b31a9cb451e28a with merge 14b72f38ec9756851f7af637cd45f181890e3bd7...

@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Contributor

bors commented Aug 17, 2021

☀️ Try build successful - checks-actions
Build commit: 14b72f38ec9756851f7af637cd45f181890e3bd7 (14b72f38ec9756851f7af637cd45f181890e3bd7)

@rust-timer
Copy link
Collaborator

Queued 14b72f38ec9756851f7af637cd45f181890e3bd7 with parent 0035d9d, future comparison URL.

@rust-log-analyzer

This comment has been minimized.

@rust-timer
Copy link
Collaborator

Finished benchmarking try commit (14b72f38ec9756851f7af637cd45f181890e3bd7): comparison url.

Summary: This change led to moderate relevant mixed results 🤷 in compiler performance.

  • Small improvement in instruction counts (up to -0.3% on full builds of helloworld)
  • Moderate regression in instruction counts (up to 1.1% on incr-full builds of inflate)

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR led to changes in compiler perf.

Next Steps: If you can justify the regressions found in this perf run, please indicate this with @rustbot label: +perf-regression-triaged along with sufficient written justification. If you cannot justify the regressions please fix the regressions and do another perf run. If the next run shows neutral or positive results, the label will be automatically removed.

@bors rollup=never
@rustbot label: +S-waiting-on-review -S-waiting-on-perf +perf-regression

@rustbot rustbot added perf-regression Performance regression. and removed S-waiting-on-perf Status: Waiting on a perf run to be completed. labels Aug 17, 2021
@Amanieu
Copy link
Member Author

Amanieu commented Aug 17, 2021

There seems to be no impact on performance and binary size increases by only 0.1%, so I think we can simply remove #[rustc_allocator_nounwind] from alloc_error_handler and allow it to safely unwind.

The only remaining issue is deciding how we should expose the ability to have OOM unwind to users:

  • The original RFC suggested a compiler option -C oom=unwind similar to -C panic=unwind.
  • We have an (unstable) OOM hook (Tracking issue for the OOM hook (alloc_error_hook) #51245) similar to the panic hook which aborts by default but could be overridden to panic instead.
  • We also have an unstable #[alloc_error_handler] attribute, but this is already used within std to implement OOM hooks and provide the default hook that aborts.

@mati865
Copy link
Contributor

mati865 commented Aug 17, 2021

I think benchmarking compiler is not very relevant here. Std's microbenchmarks should give more meaningful results.

@Amanieu
Copy link
Member Author

Amanieu commented Aug 17, 2021

I disagree, the compiler is a great benchmark because it makes a lot of memory allocations as part of the compilation process (usually through Vec, Box and HashMap). The aim of this PR is to evaluate what impact removing #[rustc_allocator_nounwind] has on codegen for allocation-heavy code.

@Amanieu Amanieu changed the title [WIP] Add oom-panic feature to libstd Allow handle_alloc_error to unwind Aug 17, 2021
@Amanieu Amanieu marked this pull request as ready for review August 17, 2021 22:25
@Amanieu Amanieu added T-libs Relevant to the library team, which will review and decide on the PR/issue. I-nominated labels Aug 17, 2021
@yaahc
Copy link
Member

yaahc commented Aug 18, 2021

This issue documented the binary size blowup that happened the first time they started allowing unwinding on oom: #42808. We should do all the same checks they did to make sure we're not reintroducing the same issues.

@Amanieu
Copy link
Member Author

Amanieu commented Aug 19, 2021

I ran the same tests: on the serde one the size increase was only 0.8%, on the main-only one is 4KB larger (1.4%) but that could be due to rounding to the page size.

In conclusion I think this is an entirely reasonable tradeoff for allowing OOM to be handled in user code.

@nbdd0121
Copy link
Contributor

That's a surprisingly small overhead.

I am uncertain if there are any code currently assuming that handle_alloc_error won't unwind though, since Box is kind of special in MIR.

@nbdd0121
Copy link
Contributor

One particular worry is that Box is a NullaryOp in MIR instead of a terminator.

@Amanieu
Copy link
Member Author

Amanieu commented Aug 23, 2021

You're right, the drop isn't getting called in this example:

#![feature(box_syntax)]
use std::panic::catch_unwind;

struct Foo;

impl Drop for Foo {
    fn drop(&mut self) {
        println!("Foo dropped");
    }
}

fn main() {
    catch_unwind(|| {
        let foo = Foo;
        let a = box [0u8; 1024*1024*1024];
        let b = box [0u8; 1024*1024*1024];
        let c = box [0u8; 1024*1024*1024];
        let d = box [0u8; 1024*1024*1024];
        println!("No oom");
    });
    println!("Caught unwind!");
}

I'm not sure how difficult it would be to make box support unwinding...

@bjorn3
Copy link
Member

bjorn3 commented Aug 25, 2021

I think

pub unsafe extern "C" fn __rg_oom(size: usize, align: usize) -> ! {
needs to be changed to use C-unwind as abi.

Edit: __rdl_oom needs to be changed too.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 17, 2022
@bors
Copy link
Contributor

bors commented Mar 17, 2022

⌛ Testing commit 0254e31 with merge a8f752f012f12dbeff295ee772d568ebc1d9b08a...

@bors
Copy link
Contributor

bors commented Mar 17, 2022

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Mar 17, 2022
@rust-log-analyzer
Copy link
Collaborator

A job failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)

@ehuss
Copy link
Contributor

ehuss commented Mar 17, 2022

@bors retry

Waiting on getting CI working.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 17, 2022
@Dylan-DPC
Copy link
Member

@bors treeclosed-

@bors
Copy link
Contributor

bors commented Mar 18, 2022

⌛ Testing commit 0254e31 with merge d6f3a4e...

@bors
Copy link
Contributor

bors commented Mar 18, 2022

☀️ Test successful - checks-actions
Approved by: nagisa
Pushing d6f3a4e to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Mar 18, 2022
@bors bors merged commit d6f3a4e into rust-lang:master Mar 18, 2022
@rustbot rustbot added this to the 1.61.0 milestone Mar 18, 2022
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (d6f3a4e): comparison url.

Summary: This benchmark run did not return any relevant results.

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

@rustbot label: -perf-regression

@rustbot rustbot removed the perf-regression Performance regression. label Mar 18, 2022
bjorn3 pushed a commit to bjorn3/rust that referenced this pull request Mar 20, 2022
Implement -Z oom=panic

This PR removes the `#[rustc_allocator_nounwind]` attribute on `alloc_error_handler` which allows it to unwind with a panic instead of always aborting. This is then used to implement `-Z oom=panic` as per RFC 2116 (tracking issue rust-lang#43596).

Perf and binary size tests show negligible impact.
bjorn3 pushed a commit to bjorn3/rust that referenced this pull request Mar 26, 2022
Implement -Z oom=panic

This PR removes the `#[rustc_allocator_nounwind]` attribute on `alloc_error_handler` which allows it to unwind with a panic instead of always aborting. This is then used to implement `-Z oom=panic` as per RFC 2116 (tracking issue rust-lang#43596).

Perf and binary size tests show negligible impact.
bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 16, 2022
… r=oli-obk

Stabilize default_alloc_error_handler

Tracking issue: rust-lang#66741

This turns `feature(default_alloc_error_handler)` on by default, which causes the compiler to automatically generate a default OOM handler which panics if `#[alloc_error_handler]` is not provided.

The FCP completed over 2 years ago but the stabilization was blocked due to an issue with unwinding. This was fixed by rust-lang#88098 so stabilization can be unblocked.

Closes rust-lang#66741
Aaron1011 pushed a commit to Aaron1011/rust that referenced this pull request Jan 6, 2023
… r=oli-obk

Stabilize default_alloc_error_handler

Tracking issue: rust-lang#66741

This turns `feature(default_alloc_error_handler)` on by default, which causes the compiler to automatically generate a default OOM handler which panics if `#[alloc_error_handler]` is not provided.

The FCP completed over 2 years ago but the stabilization was blocked due to an issue with unwinding. This was fixed by rust-lang#88098 so stabilization can be unblocked.

Closes rust-lang#66741
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.