As soon as you have mutable fields in your immutable it will be heap allocated, at that point you can check for yourself what’s going on as you pass it through functions by looking at pointers I think. Base.pointer_from_objref
should help you out.
From what I understand everything that’s always allocated on the heap will be passed as a reference rather than by value, since how would it know exactly how to make those copies. Please correct me if I’m wrong, this is partly from my own experience testing some behavior that was discussed here: Memory layout of structs with mutable fields.