It looks like this is related to the size of the record, for
procedure test(const x : TMyRec);
the type
type
TMyRec = record
x : Array[1..4] of byte;
end;
would be passed by value, and
type
TMyRec = record
x : Array[1..5] of byte
end;
would be passed by reference on 32 bit, for 64 bit we would need a record of 9 bytes to be passed by reference on Tokyo (10.2.3) or earlier, Rio (10.3) behaves the same on both 32 and 64 bit. Thanks to everyone who comment on my question, and provided additional references/suggestions.
See the Tokyo Documentation here. In particular
Value and constant (const) parameters are passed by value or by reference, depending on the type and size of the parameter:
...
Sets, records, and static arrays of 1, 2, or 4 bytes are passed as
8-bit, 16-bit, and 32bit values. Larger sets, records, and static
arrays are passed as 32-bit pointers to the value. An exception to
this rule is that records are always passed directly on the stack
under the cdecl, stdcall, and safecall conventions; the size of a
record passed this way is rounded upward to the nearest double-word
boundary.
If you want to force a pass-by-reference, you can declare your parameter as const [ref]
, like so:
procedure test(const [ref] x : TMyRec);