Skip to content

singleton!()'s use of Option can have nasty optimization results #364

Closed
@Rahix

Description

@Rahix

I was trying to store some large buffers inside of a cortex_m::singleton!() when I noticed that suddenly my flash usage increased dramatically. As some (contrived) examples, the following works (variable ends up in .bss):

cortex_m::singleton!(: [u8; 2048] = [0xff; 2048]);

but this doesn't (variable ends up in .data):

cortex_m::singleton!(: [bool; 2048] = [true; 2048]);

The reason is the Option inside the singleton!() macro:

static mut VAR: Option<$ty> = None;

Normally, the None value which is stored here has a bitpattern of all zeros, leading to it being stored in .bss. But when the given type has a niche (like bool above does), the None variant is "optimized" into it. This means it then has non-zero bits and cannot be stored in .bss anymore, leading to it getting moved to .data...

A quick solution is to "reimplement" the Option:

	static mut VAR: (MaybeUninit<$ty>, bool) = (MaybeUninit::uninit(), false);

This will always end up in .bss because no niche optimization exists for such types (yet). Before opening a PR, I wanted to discuss whether there are any objections to changing to such an implementation?

Side Note: I think it would be nice to allow users to overwrite the name of the static. When looking at nm or bloaty output, only seeing a bunch of symbols named __cortex_m_rt_main::{{closure}}::VAR is not great...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions