How can I know Whether a certain type were saved in the stack,or in the heap?


#1

How can I know Whether a certain type were saved in the stack,or in the heap? Must the type saved in the stack implements copy trait?


#2

As a general rule, your struct will be saved onto the stack unless it’s put inside something which does dynamic allocation. These containers are usually things like:

  • Box<T>
  • Rc<T>
  • Vec<T>
  • most things in the std::collections module

Where the Box or Vec structs are stored on the stack and contain pointers to your T which is located on the heap.


#3

I’ll add that there are other types in the standard library (String and PathBuf come to mind) that use heap allocation as well. I’d say that any type that can have arbitrary size (and is “owned”, not a reference or slice of other data) must be allocated on the heap. I don’t have an exhaustive list.


#4

I think this is an implementation detail. If the allocation is small and does not escape, I’d expect compilers to allocate them on the stack eventually. Future implementations of String and perhaps even Vec might use the small string optimization, too, so that the contents effectively lands on the stack.


#5

Actually the Vec documentation explicitly stated that it won’t ever do small vector optimization, as that could mess up unsafe code.


#6

I think we should try to invent ways to allow both escape analysis (and stack allocation when it succeeds) in some parts of the code and unsafe code elsewhere. Perhaps an annotation that allows escape analysis for a specific heap allocation, plus warnings/errors if you try to assume inside unsafe code where that pointer is allocated?


#7

What would the benefit be of doing small size optimisation on Vec over creating a new SmallVec type like what servo does? I reckon you’d need a pretty advanced solution to implement SSO in a way which isn’t a leaky abstraction. Plus it’s pushing a lot of (perhaps unwanted?) complexity out of the compiler/language/std and into the crates ecosystem.


#8

I agree it’s not easy to not make it a leaky abstraction where unsafe code is present. Both the escape analysis and the annotation machinery is inside the language. What’s in the library code are the annotations that allow the optimization to happen. Using this over SmallVec / SmallMap / SmallBox / SmallString / SmallSomething is that it’s meant to be more generic.