From b0c80a93e41548bf706dc886b8875952f6456b0c Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Thu, 11 May 2017 23:09:31 +0300 Subject: [PATCH] remove the #[inline] attribute from drop_in_place Apparently LLVM has exponential code growth while inlining landing pads if that attribute is present. Fixes #41696. --- src/libcore/ptr.rs | 1 - src/librustc_trans/common.rs | 6 ++++ src/test/run-pass/issue-41696.rs | 60 ++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/issue-41696.rs diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index a60abefc07650..0944e74f6f18a 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -56,7 +56,6 @@ pub use intrinsics::write_bytes; /// invalid pointers, types, and double drops. #[stable(feature = "drop_in_place", since = "1.8.0")] #[lang="drop_in_place"] -#[inline] #[allow(unconditional_recursion)] pub unsafe fn drop_in_place(to_drop: *mut T) { // Code here does not matter - this is replaced by the diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 025062f7ddef9..efd4f13678502 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -537,6 +537,12 @@ pub fn requests_inline<'a, 'tcx>( if is_inline_instance(tcx, instance) { return true } + if let ty::InstanceDef::DropGlue(..) = instance.def { + // Drop glue wants to be instantiated at every translation + // unit, but without an #[inline] hint. We should make this + // available to normal end-users. + return true + } attr::requests_inline(&instance.def.attrs(tcx)[..]) } diff --git a/src/test/run-pass/issue-41696.rs b/src/test/run-pass/issue-41696.rs new file mode 100644 index 0000000000000..1888be58c57d0 --- /dev/null +++ b/src/test/run-pass/issue-41696.rs @@ -0,0 +1,60 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// this used to cause exponential code-size blowup during LLVM passes. + +#![feature(test)] + +extern crate test; + +struct MayUnwind; + +impl Drop for MayUnwind { + fn drop(&mut self) { + if test::black_box(false) { + panic!() + } + } +} + +struct DS { + may_unwind: MayUnwind, + name: String, + next: U, +} + +fn add(ds: DS, name: String) -> DS> { + DS { + may_unwind: MayUnwind, + name: "?".to_owned(), + next: ds, + } +} + +fn main() { + let deserializers = DS { may_unwind: MayUnwind, name: "?".to_owned(), next: () }; + let deserializers = add(deserializers, "?".to_owned()); + let deserializers = add(deserializers, "?".to_owned()); + let deserializers = add(deserializers, "?".to_owned()); + let deserializers = add(deserializers, "?".to_owned()); + let deserializers = add(deserializers, "?".to_owned()); + let deserializers = add(deserializers, "?".to_owned()); + let deserializers = add(deserializers, "?".to_owned()); // 0.7s + let deserializers = add(deserializers, "?".to_owned()); // 1.3s + let deserializers = add(deserializers, "?".to_owned()); // 2.4s + let deserializers = add(deserializers, "?".to_owned()); // 6.7s + let deserializers = add(deserializers, "?".to_owned()); // 26.0s + let deserializers = add(deserializers, "?".to_owned()); // 114.0s + let deserializers = add(deserializers, "?".to_owned()); // 228.0s + let deserializers = add(deserializers, "?".to_owned()); // 400.0s + let deserializers = add(deserializers, "?".to_owned()); // 800.0s + let deserializers = add(deserializers, "?".to_owned()); // 1600.0s + let deserializers = add(deserializers, "?".to_owned()); // 3200.0s +}