Technically it is all passed around by pointer, which is synonymous to by reference. Logically that makes no difference whatsoever as it all happens under the hood. Data going into a subVI through the connector into a control is consumed by that subVI and considered to be private to the VI. If LabVIEW needs that data somewhere else, it will make a copy, but it has optimizing measures in place that may schedule different functions consuming the same data in a way that they can not stomp on each others data. Data coming through an indicator out of a subVI is from that point owned by the caller and the VI better doesn't try to change it after the fact. For LabVIEW VIs that is not a possibility at all as LabVIEW takes care of that. For data returned from external code through a Call Library Node, it is a grave violation of the LabVIEW memory management contract to try to modify the data in the background once the Call Library Node call has returned control to the diagram.
LabVIEW is a managed environment just like .Net but has different management rules. As far as LabVIEW diagrams are concerned there is virtually no way to violate those rules since the dataflow determines everything. If you interface to external code then you could violate that management contract in the external code but doing so is equivalent to placing a bomb in your PC! 💣