Skip to content

Instantly share code, notes, and snippets.

@anp
Last active April 5, 2020 20:11
Show Gist options
  • Save anp/2137aec0bb2aa6a8cd6d70f5d6cea762 to your computer and use it in GitHub Desktop.
Save anp/2137aec0bb2aa6a8cd6d70f5d6cea762 to your computer and use it in GitHub Desktop.
rustc binary bloat from `#[track_caller]`
[llvm]
assertions = true
ninja = true
[build]
docs = false
low-priority = true
[rust]
debug-assertions = true
debuginfo-level = 1
verify-llvm-ir = true
diff --git i/src/librustc_codegen_llvm/common.rs w/src/librustc_codegen_llvm/common.rs
index 1415fedf11a..6d7f1197919 100644
--- i/src/librustc_codegen_llvm/common.rs
+++ w/src/librustc_codegen_llvm/common.rs
@@ -12,6 +12,7 @@ use crate::value::Value;
use rustc_ast::ast::Mutability;
use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::*;
+use rustc_data_structures::small_c_str::SmallCStr;
use rustc_middle::bug;
use rustc_middle::mir::interpret::{Allocation, GlobalAlloc, Scalar};
use rustc_middle::ty::layout::TyAndLayout;
@@ -255,6 +256,12 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
if !self.sess().fewer_names() {
llvm::set_value_name(value, format!("{:?}", ptr.alloc_id).as_bytes());
}
+ if alloc.is_track_caller {
+ unsafe {
+ let buf = SmallCStr::new(".track_caller");
+ llvm::LLVMSetSection(value, buf.as_ptr());
+ }
+ }
value
}
Some(GlobalAlloc::Function(fn_instance)) => self.get_fn_addr(fn_instance),
diff --git i/src/librustc_middle/mir/interpret/allocation.rs w/src/librustc_middle/mir/interpret/allocation.rs
index 8b9f0977485..2d0ee8b21b0 100644
--- i/src/librustc_middle/mir/interpret/allocation.rs
+++ w/src/librustc_middle/mir/interpret/allocation.rs
@@ -37,6 +37,8 @@ pub struct Allocation<Tag = (), Extra = ()> {
/// Also used by codegen to determine if a static should be put into mutable memory,
/// which happens for `static mut` and `static` with interior mutability.
pub mutability: Mutability,
+ /// The requested kind of the allocation. Used by codegen for instrumenting static data sizes.
+ pub is_track_caller: bool,
/// Extra state for the machine.
pub extra: Extra,
}
@@ -98,6 +100,7 @@ impl<Tag> Allocation<Tag> {
size,
align,
mutability: Mutability::Not,
+ is_track_caller: false,
extra: (),
}
}
@@ -114,6 +117,7 @@ impl<Tag> Allocation<Tag> {
size,
align,
mutability: Mutability::Mut,
+ is_track_caller: false,
extra: (),
}
}
@@ -143,6 +147,7 @@ impl Allocation<(), ()> {
undef_mask: self.undef_mask,
align: self.align,
mutability: self.mutability,
+ is_track_caller: false,
extra,
}
}
diff --git i/src/librustc_mir/interpret/memory.rs w/src/librustc_mir/interpret/memory.rs
index 04a927c69a6..65543ebfca3 100644
--- i/src/librustc_mir/interpret/memory.rs
+++ w/src/librustc_mir/interpret/memory.rs
@@ -173,7 +173,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
pub fn allocate_with(
&mut self,
- alloc: Allocation,
+ mut alloc: Allocation,
kind: MemoryKind<M::MemoryKind>,
) -> Pointer<M::PointerTag> {
let id = self.tcx.alloc_map.lock().reserve();
@@ -182,6 +182,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
M::GLOBAL_KIND.map(MemoryKind::Machine),
"dynamically allocating global memory"
);
+ if kind == MemoryKind::CallerLocation {
+ alloc.is_track_caller = true;
+ }
let (alloc, tag) = M::init_allocation_extra(&self.extra, id, Cow::Owned(alloc), Some(kind));
self.alloc_map.insert(id, (kind, alloc.into_owned()));
Pointer::from(id).with_tag(tag)

Local checkout: cff07db629d

Here's the baseline stage1 size without instrumentation:

rust master *$ > $ llvm-size --format=sysv .\build\x86_64-pc-windows-msvc\stage1\bin\rustc_driver-6bca00ecd48151cb.dll     
.\build\x86_64-pc-windows-msvc\stage1\bin\rustc_driver-6bca00ecd48151cb.dll  :
section         size         addr
.text       93358380   6442455040
.rdata      31787826   6535815168
.data         327168   6567604224
.pdata       3726012   6568206336
.rustc         99696   6571933696
_RDATA           148   6572036096
.reloc        482128   6572040192
Total      129781358

In a stage2 build with instrumentation.diff applied, the .track_caller section is 0.68% of the final binary size:

rust master *$ > $ llvm-size --format=sysv .\build\x86_64-pc-windows-msvc\stage2\bin\rustc_driver-2b6f3871b4cd6007.dll     
.\build\x86_64-pc-windows-msvc\stage2\bin\rustc_driver-2b6f3871b4cd6007.dll  :
section          size         addr
.text        85435900   6442455040
.rdata       30815430   6527893504
.data          327168   6558711808
.pdata        3775608   6559313920
.track_c       829904   6563090432
.rustc          98108   6563921920
_RDATA            148   6564020224
.reloc         487072   6564024320
Total       121769338

Note that the stage2 binary is 93.8% the size of the stage1 binary. I assume the >6% reduction in size between stage1 and stage2 builds is due to changes between beta and the current nightly that are not related to implicit caller location.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment