1

I'm using the tool MapFileStats to inspect generated map files from delphi. I found that anonymous methods generate some kind of metadata, which doesn't seem to be related with RTTI. What kind of metadata is it? It would be nice to remove it because in our production environment it sums up to a very large size.

Example code:

program RttiDemo;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils;

{$RTTI EXPLICIT METHODS([]) FIELDS([]) PROPERTIES([])}
{$WEAKLINKRTTI OFF}   

var
  AProc: TProc;

begin
  try

    AProc := procedure()
      begin
        // ...
      end;

  except
    on E: Exception do
      WriteLn(E.ClassName, ': ', E.Message);
  end;

end.

Screenshot from MapFileStats:

Screenshot displaying MailFileStats

Another example:

program RttiDemo;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils;

{$RTTI EXPLICIT METHODS([]) FIELDS([]) PROPERTIES([])}
{$WEAKLINKRTTI OFF}

type

  TDemo = class
    procedure Demo();
  end;

procedure TDemo.Demo;
var
  AProc: TProc;
begin
  AProc := procedure()
    var
      i: Integer;
    begin
      i := 5;
      WriteLn(i);
    end;

  AProc();
end;

var
  Demo: TDemo;

begin
  Demo := TDemo.Create();
  try
    Demo.Demo;
  finally
    FreeAndNil(Demo);
  end;
end.

Screenshot:

another MapFileStats screenshot

Free Consulting
  • 4,300
  • 1
  • 29
  • 50
ventiseis
  • 3,029
  • 11
  • 32
  • 49

1 Answers1

2

An anonymous function is backed by a class that implements the interfaces needed for the anonymous function to work. The meta data reported here represents the information needed for that class. I do not believe that you can remove it from your executable.

The following will emit the name of the class of the object that implements the anonymous method:

Writeln((IInterface(Pointer(@AProc)^) as TObject).ClassName);

When added to your second program, the output is:

TDemo.Demo$0$ActRec

This is the same name as you highlighted in the question.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • At the first glance, this question looks silly. But: we do use generic lists and according to the tool `TList.Pack` generates a lot of this metadata, because its instantiated for every generic list type. I think for such a basic generic class this should be implemented without that overhead! – ventiseis Jan 20 '16 at 11:22
  • I can understand where you are comping from. However, I really don't think that there's a lot that you can do about it. Have you reported this to Embarcadero? What proportion of your executable size is made up of anon method classes? – David Heffernan Jan 20 '16 at 11:25
  • I can't give you an exact number, there is no export function in this tool. The biggest unit (compiled size ca. 1.8 MB according to the tool) get up to 5% of metadata and implementation (combined) only for the `Pack` method. But I don't understand another thing: for this specific unit (which has no .dfm file) the file size on disk is 17 MB. So there seems to be another difference between map file and dcu. Is there a tool to analyze compiled dcu files? – ventiseis Jan 20 '16 at 11:45
  • Well, what are you looking for in the .dcu files? I don't think they are documented anywhere so any tool would be based on reverse engineering. I think I explained what the anon method meta data is. – David Heffernan Jan 20 '16 at 11:49
  • I'm afraid that you're correct and there is no way to opimize or further analyze this behavior. – ventiseis Jan 20 '16 at 12:02