Allow {$Optimization ORDERFIELDS} to be applied for objects, not just classes
Summary
FPC has long had an opt-in optimization for automatic field order reordering to reduce the memory footprint of user-defined types. But currently it applies only to classes, but not objects, even if definitely asked for it. However, the size concern for objects is especially important, since they are allocated on the stack by default, like regular records, which is what gives them a clear advantage over classes in certain use cases. In fact, objects provide the semantics of C++ classes here.
Example project
program orderfields;
{$MODE OBJFPC}
{$OPTIMIZATION ON} // enables -O2
type
// example of field alignment taken from here:
// https://stackoverflow.com/questions/2748995/struct-memory-layout-in-c/2749096#2749096
{$PUSH}
{$Optimization ORDERFIELDS}
cls_ba_opt = class
ch1: UInt8;
s: Int16;
ch2: UInt8;
ll: Int64;
i: UInt32;
end;
{$Optimization NOORDERFIELDS}
cls_ba_off = class
ch1: UInt8;
s: Int16;
ch2: UInt8;
ll: Int64;
i: UInt32;
end;
{$POP}
cls_ba_def = class
ch1: UInt8;
s: Int16;
ch2: UInt8;
ll: Int64;
i: UInt32;
end;
cls_ab = class
ll: Int64;
i: UInt32;
s: Int16;
ch1: UInt8;
ch2: UInt8;
end;
{$PUSH}
{$Optimization ORDERFIELDS}
obj_ba_opt = object
ch1: UInt8;
s: Int16;
ch2: UInt8;
ll: Int64;
i: UInt32;
end;
{$Optimization NOORDERFIELDS}
obj_ba_off = object
ch1: UInt8;
s: Int16;
ch2: UInt8;
ll: Int64;
i: UInt32;
end;
{$POP}
obj_ba_def = object
ch1: UInt8;
s: Int16;
ch2: UInt8;
ll: Int64;
i: UInt32;
end;
obj_ab = object
ll: Int64;
i: UInt32;
s: Int16;
ch1: UInt8;
ch2: UInt8;
end;
function DataSz(c: TClass): SizeUInt; inline;
begin
Result := c.InstanceSize() - SizeOf(PVmt);
end;
begin
Write(
DataSz(cls_ba_opt), ' ', DataSz(cls_ba_off), ' ', DataSz(cls_ba_def), ' ',
DataSz(cls_ab), LineEnding,
SizeOf(obj_ba_opt), ' ', SizeOf(obj_ba_off), ' ', SizeOf(obj_ba_def), ' ',
SizeOf(obj_ab), LineEnding
);
ReadLn();
end.
Current output
16 24 24 16
24 24 24 16
Expected output
16 24 24 16
16 24 24 16
Edited by Dmitry D. Chernov