I did not suspect that the subroutine made a copy of the memory address.
It doesn't (though you did in the first line of the sub).
I figured that by passing in a reference, then whatever I did to the reference would reflect the new state of the reference.
You didn't do anything to the reference. (You changed the value of $data.)
Also, there isn't really anything you can do to a reference. You can't change a reference any more than you can change 5.
Suppose the variable passing used some sort of "slot based" mechanism where the caller/sub could agree on variables (references) in and their value (slot) on return?
That is what happens. You didn't change any of the slots (elements of @_).