IDE Fix Pack 6.2

By | January 25, 2018

Delphi 10.2 Tokyo changed how the files for units that are explicitly specified in the project file (dpr/dpk) are found. The IDE Fix Pack’s directory file search cache still made assumptions that were correct in Delphi 2009-10.1 Seattle but aren’t in Tokyo. This could result in an “program or unit xxx recursively uses itself” error messages if you had a relative path in the filename that is specified in the project file.

This release also adds another option to the compiler codegen optimizations. The new -x-orc / -x-orc=n option allows you to eliminate temporary record copies for functions like “begin Result := FRedirect.GetRecord; end;”. This optimization allows the compiler to skip the try/finally block with InitializeRecord/CopyRecord/FinalizeRecord calls for the temporary record variable that is then copied to the actual result record.

  • Fixed: Directory search cache failed if project units had “..\” in it (Delphi 10.2 only)
  • Fixed: Some VirtualProtect calls specified nil as last argument what Windows 10 1709 doesn’t like if a debugger is attached.
  • Added: Option -x-orc and -x-orc=n to remove temporary record variables for function results (n=1: only if the assignment is the last statement, n=2 for all)

Download:

Name IDE Version File Size Downloads Added
IDE Fix Pack 6.4.2 2009 (UP4) IDEFixPack2009Reg64.2.7z 242.75 KB 1349 times 2019-03-23
IDE Fix Pack 6.4.2 2010 (UP5) IDEFixPack2010Reg64.2.7z 237.09 KB 1571 times 2019-03-23
IDE Fix Pack 6.4.2 XE (UP1) IDEFixPackXEReg64.2.7z 221.38 KB 774 times 2019-03-23
IDE Fix Pack 6.4.2 XE2 (UP4+HF1) IDEFixPackXE2Reg64.2.7z 316.78 KB 869 times 2019-03-23
IDE Fix Pack 6.4.2 XE3 (UP2) IDEFixPackXE3Reg64.2.7z 257.4 KB 653 times 2019-03-23
IDE Fix Pack 6.4.2 XE4 (UP1) IDEFixPackXE4Reg64.2.7z 260.1 KB 511 times 2019-03-23
IDE Fix Pack 6.4.2 XE5 (UP2) IDEFixPackXE5Reg64.2.7z 257.7 KB 623 times 2019-03-23
IDE Fix Pack 6.4.2 XE6 (UP1) IDEFixPackXE6Reg64.2.7z 423 KB 548 times 2019-03-23
IDE Fix Pack 6.4.2 XE7 (UP1) IDEFixPackXE7Reg64.2.7z 429.48 KB 806 times 2019-03-23
IDE Fix Pack 6.4.2 XE8 (UP1) IDEFixPackXE8Reg64.2.7z 431.7 KB 677 times 2019-03-23
IDE Fix Pack 6.4.2 10 Seattle (RTM/UP1) IDEFixPackD10Reg64.2.7z 428.33 KB 1202 times 2019-03-23
IDE Fix Pack 6.4.2 10.1 Berlin IDEFixPackD101Reg64.2.7z 430.65 KB 1442 times 2019-03-23
IDE Fix Pack 6.4.2 10.2 (RTM/UP1/2/3) IDEFixPackD102Reg64.2.7z 426.27 KB 2932 times 2019-03-23
IDE Fix Pack 6.4.4 10.3 (RTM/UP1/2) IDEFixPackD103Reg64.4.7z 444.98 KB 4251 times 2019-08-01

Download (fastdcc for the command line compiler):

Name IDE Version File Size Downloads Added
fastdcc 6.4.2 2009 (UP4) fastdcc2009v64.2.7z 112.87 KB 486 times 2019-03-23
fastdcc 6.4.2 2010 (UP5) fastdcc2010v64.2.7z 120.38 KB 472 times 2019-03-23
fastdcc 6.4.2 XE (UP1) fastdccXEv64.2.7z 121.36 KB 385 times 2019-03-23
fastdcc 6.4.2 XE2 (UP4+HF1) fastdccXE2v64.2.7z 166.48 KB 388 times 2019-03-23
fastdcc 6.4.2 XE3 (UP2) fastdccXE3v64.2.7z 150.88 KB 366 times 2019-03-23
fastdcc 6.4.2 XE4 (UP1) fastdccXE4v64.2.7z 153.55 KB 334 times 2019-03-23
fastdcc 6.4.2 XE5 (UP2) fastdccXE5v64.2.7z 151.87 KB 400 times 2019-03-23
fastdcc 6.4.2 XE6 (UP1) fastdccXE6v64.2.7z 198.67 KB 367 times 2019-03-23
fastdcc 6.4.2 XE7 (UP1) fastdccXE7v64.2.7z 219.84 KB 402 times 2019-03-23
fastdcc 6.4.2 XE8 (UP1) fastdccXE8v64.2.7z 224.67 KB 391 times 2019-03-23
fastdcc 6.4.2 10 Seattle (RTM/UP1) fastdccD10v64.2.7z 219.65 KB 504 times 2019-03-23
fastdcc 6.4.2 10.1 Berlin fastdccD101v64.2.7z 223.52 KB 553 times 2019-03-23
fastdcc 6.4.2 10.2 (RTM/UP1/2/3) fastdccD102v64.2.7z 219.06 KB 905 times 2019-03-23
fastdcc 6.4.4 10.3 (RTM/UP1/2) fastdccD103v64.4.7z 228.61 KB 992 times 2019-07-31

IDE Fix Pack 6.1.2 (supports Delphi 10.2.2)

By | December 15, 2017

A small update for IDE Fix Pack that adds support for the just released Delphi 10.2.2.

  • Added: Support for Delphi 10.2 Update 2
  • Added: Fix for unnecessary temporary variable if an empty open array argument is part of a function call (Delphi 2009-10.1)

Download:

Name IDE Version File Size Downloads Added
IDE Fix Pack 6.4.2 2009 (UP4) IDEFixPack2009Reg64.2.7z 242.75 KB 1349 times 2019-03-23
IDE Fix Pack 6.4.2 2010 (UP5) IDEFixPack2010Reg64.2.7z 237.09 KB 1571 times 2019-03-23
IDE Fix Pack 6.4.2 XE (UP1) IDEFixPackXEReg64.2.7z 221.38 KB 774 times 2019-03-23
IDE Fix Pack 6.4.2 XE2 (UP4+HF1) IDEFixPackXE2Reg64.2.7z 316.78 KB 869 times 2019-03-23
IDE Fix Pack 6.4.2 XE3 (UP2) IDEFixPackXE3Reg64.2.7z 257.4 KB 653 times 2019-03-23
IDE Fix Pack 6.4.2 XE4 (UP1) IDEFixPackXE4Reg64.2.7z 260.1 KB 511 times 2019-03-23
IDE Fix Pack 6.4.2 XE5 (UP2) IDEFixPackXE5Reg64.2.7z 257.7 KB 623 times 2019-03-23
IDE Fix Pack 6.4.2 XE6 (UP1) IDEFixPackXE6Reg64.2.7z 423 KB 548 times 2019-03-23
IDE Fix Pack 6.4.2 XE7 (UP1) IDEFixPackXE7Reg64.2.7z 429.48 KB 806 times 2019-03-23
IDE Fix Pack 6.4.2 XE8 (UP1) IDEFixPackXE8Reg64.2.7z 431.7 KB 677 times 2019-03-23
IDE Fix Pack 6.4.2 10 Seattle (RTM/UP1) IDEFixPackD10Reg64.2.7z 428.33 KB 1202 times 2019-03-23
IDE Fix Pack 6.4.2 10.1 Berlin IDEFixPackD101Reg64.2.7z 430.65 KB 1442 times 2019-03-23
IDE Fix Pack 6.4.2 10.2 (RTM/UP1/2/3) IDEFixPackD102Reg64.2.7z 426.27 KB 2932 times 2019-03-23
IDE Fix Pack 6.4.4 10.3 (RTM/UP1/2) IDEFixPackD103Reg64.4.7z 444.98 KB 4251 times 2019-08-01

Download (fastdcc for the command line compiler):

Name IDE Version File Size Downloads Added
fastdcc 6.4.2 2009 (UP4) fastdcc2009v64.2.7z 112.87 KB 486 times 2019-03-23
fastdcc 6.4.2 2010 (UP5) fastdcc2010v64.2.7z 120.38 KB 472 times 2019-03-23
fastdcc 6.4.2 XE (UP1) fastdccXEv64.2.7z 121.36 KB 385 times 2019-03-23
fastdcc 6.4.2 XE2 (UP4+HF1) fastdccXE2v64.2.7z 166.48 KB 388 times 2019-03-23
fastdcc 6.4.2 XE3 (UP2) fastdccXE3v64.2.7z 150.88 KB 366 times 2019-03-23
fastdcc 6.4.2 XE4 (UP1) fastdccXE4v64.2.7z 153.55 KB 334 times 2019-03-23
fastdcc 6.4.2 XE5 (UP2) fastdccXE5v64.2.7z 151.87 KB 400 times 2019-03-23
fastdcc 6.4.2 XE6 (UP1) fastdccXE6v64.2.7z 198.67 KB 367 times 2019-03-23
fastdcc 6.4.2 XE7 (UP1) fastdccXE7v64.2.7z 219.84 KB 402 times 2019-03-23
fastdcc 6.4.2 XE8 (UP1) fastdccXE8v64.2.7z 224.67 KB 391 times 2019-03-23
fastdcc 6.4.2 10 Seattle (RTM/UP1) fastdccD10v64.2.7z 219.65 KB 504 times 2019-03-23
fastdcc 6.4.2 10.1 Berlin fastdccD101v64.2.7z 223.52 KB 553 times 2019-03-23
fastdcc 6.4.2 10.2 (RTM/UP1/2/3) fastdccD102v64.2.7z 219.06 KB 905 times 2019-03-23
fastdcc 6.4.4 10.3 (RTM/UP1/2) fastdccD103v64.4.7z 228.61 KB 992 times 2019-07-31

Technical the same but different generated code

By | October 31, 2017

While debugging the String4D code to hunt down a bug in the CompilerSpeedPack, I saw a lot of CopyRecord/FinalizeRecord calls with a try/finally that the compiler generated.

If you have a record with managed fields (string, interface, …) and use it as a function return type the Delphi compiler will change the function into a procedure with an extra var-parameter. So you would think that the compiler treats the result-parameter like a normal var-parameter, but that isn’t the case. The compiler will generate code that guarantees that the result record isn’t changed if the called function throws an exception. For this is adds a temporary record that is used for the function result and then copies it to the target record.

type
  TMyRec = record
    Value: string;
  end;

function InternalGetRec: TMyRec;
begin
  Result.Value := 'Hello';
end;

function GetRec: TMyRec;
begin
  Result := InternalGetRec;
end;

procedure Test;
var
  R: TMyRec;
begin
  R := GetRec;
end;

The compiler rewrites the “Test” function to:

procedure Test;
var
  R, TempR: TMyRec;
begin
  try
    GetRec(TempR);
    CopyRecord(TempR, R, TypeInfo(TMyRec));
  finally
    FinalizeArray([TempR, R], TypeInfo(TMyRec));
  end;
end;

The same happens if you assign another function’s record result value to your own record result value. The compiler rewrites the “GetRec” function’s code to:

function GetRec: TMyRec;
var
  TempResult: TMyRec;
begin
  try
    InternalGetRec(TempResult);
    CopyRecord(TempResult, Result, TypeInfo(TMyRec));
  finally
    FinalizeRecord(TempRecord, TypeInfo(TMyRec));
  end;
end;

Because the compiler assumes that you may want to use “Result” in the function after the call, it has to guarantee that it is unchanged if an exception is thrown. But if it is the last statement in the function and not secured by an explicit try/finally/except where “Result” is used again, an optimization could be to omit the temporary record, making the code a lot faster.

IDE Fix Pack 6.1 released

By | October 29, 2017

With the release of IDE Fix Pack 6.1, the Compiler Speed Pack not only makes the compiler compile faster but it can now also change the generated code, something that IDE Fix Pack has never done before. For this, new command line compiler options are introduced. They all start with “-x” (eXtension) followed by the Compiler Speed Pack option (-x-ff -x-fdi -x-fvs -x-fpr) and if you want to use them from the command line compiler you need to use fastdcc32/fastdcc64.
You can specify these options in the “Project/Options…” dialog under “Delphi Compiler/Compiling/Additional options to pass to the compiler”. You may need to rebuild the project to see an effect as only then the compiler will generate new code.

AdditionalOptions

Windows 10 Creators Update 1703 caused issues with all Delphi programs, libraries and packages because it changed how Windows loads imported DLLs in such a way that it causes performance issues and can crash the debugger. Delphi 10.2 Tokyo Update 2 fixed this by not producing multiple dll import sections for one DLL anymore. IDE Fix Pack 6.1 implements that “feature” for all previous Delphi versions (2009-10.1 Berlin) and extends it to not only eliminate duplicate dll imports but also duplicate delay dll imports.
This patch changes the generated binary, the Win32 and Win64 compiler outputs, and it can be disabled by using the new “-x-fdi-“ option.

The next patch that changes the Win32 code generator is the “fast floating point” option that C++Builder users may know from the “bcc32.exe -ff” option. It removes all “fwait” instructions that the compiler usually emits after floating point operations. Removing “fwait” may cause FPU exceptions to be thrown at the wrong source code line.
This option is disabled by default and can be enabled by specifying the new option “-x-ff”.

When calling virtual methods through an interface the Win32 Delphi compiler has to route that call through a helper function that translates the interface reference into an object reference and calls the virtual method. For this helper the compiler uses the XCHG instruction that has an implicit CPU LOCK.
The new “-x-fvs” / “-x-fvs=1” option replaces the XCHG instruction with an alternative code and if the called virtual function doesn’t use the ECX register for the 3rd parameter, it generates a direct jump into the virtual method.
The “-x-fvs=2” option replaces the XCHG and uses ECX if available but if ECX is not available it keeps the CPU’s “return stack cache” valid by replacing the RET with a JMP instructions. For this it uses stack memory below ESP.

For some functions that meet special conditions the Win32 compiler emits stack frame code that fills the stack with zeros to clear variables with managed types. If there are too many of those the compiler uses a loop and the XCHG instruction to restore the ECX register that is used as the loop counter.
The option “-x-fpr” replaces the XCHG with an alternative code.

 

Changelog:

  • Added: Option -x-ff to enable “fast floating point” (like Borland C++’s -ff command line option)
  • Added: Option -x-fvs and -x-fvs=n to enable fast interface virtual stub (n=1: replace XCHG, n=2: keep the CPU’s return stack buffer in order)
  • Added: Option -x-fpr to remove XCHG from the function prolog code.
  • Added: DLL import table section folding and duplicate name/ordinal elimination, also for delay dll imports
  • Changed: Split “Compiler64.X86″ patch into multiple smaller patches and removed the “Compiler64.X86” patch name
  • Changed: EditorFocusFix now skips the SetActiveWindow call if the mainform (undocked) is not the active window

Download:

Name IDE Version File Size Downloads Added
IDE Fix Pack 6.4.2 2009 (UP4) IDEFixPack2009Reg64.2.7z 242.75 KB 1349 times 2019-03-23
IDE Fix Pack 6.4.2 2010 (UP5) IDEFixPack2010Reg64.2.7z 237.09 KB 1571 times 2019-03-23
IDE Fix Pack 6.4.2 XE (UP1) IDEFixPackXEReg64.2.7z 221.38 KB 774 times 2019-03-23
IDE Fix Pack 6.4.2 XE2 (UP4+HF1) IDEFixPackXE2Reg64.2.7z 316.78 KB 869 times 2019-03-23
IDE Fix Pack 6.4.2 XE3 (UP2) IDEFixPackXE3Reg64.2.7z 257.4 KB 653 times 2019-03-23
IDE Fix Pack 6.4.2 XE4 (UP1) IDEFixPackXE4Reg64.2.7z 260.1 KB 511 times 2019-03-23
IDE Fix Pack 6.4.2 XE5 (UP2) IDEFixPackXE5Reg64.2.7z 257.7 KB 623 times 2019-03-23
IDE Fix Pack 6.4.2 XE6 (UP1) IDEFixPackXE6Reg64.2.7z 423 KB 548 times 2019-03-23
IDE Fix Pack 6.4.2 XE7 (UP1) IDEFixPackXE7Reg64.2.7z 429.48 KB 806 times 2019-03-23
IDE Fix Pack 6.4.2 XE8 (UP1) IDEFixPackXE8Reg64.2.7z 431.7 KB 677 times 2019-03-23
IDE Fix Pack 6.4.2 10 Seattle (RTM/UP1) IDEFixPackD10Reg64.2.7z 428.33 KB 1202 times 2019-03-23
IDE Fix Pack 6.4.2 10.1 Berlin IDEFixPackD101Reg64.2.7z 430.65 KB 1442 times 2019-03-23
IDE Fix Pack 6.4.2 10.2 (RTM/UP1/2/3) IDEFixPackD102Reg64.2.7z 426.27 KB 2932 times 2019-03-23
IDE Fix Pack 6.4.4 10.3 (RTM/UP1/2) IDEFixPackD103Reg64.4.7z 444.98 KB 4251 times 2019-08-01

Download (fastdcc):

Name IDE Version File Size Downloads Added
fastdcc 6.4.2 2009 (UP4) fastdcc2009v64.2.7z 112.87 KB 486 times 2019-03-23
fastdcc 6.4.2 2010 (UP5) fastdcc2010v64.2.7z 120.38 KB 472 times 2019-03-23
fastdcc 6.4.2 XE (UP1) fastdccXEv64.2.7z 121.36 KB 385 times 2019-03-23
fastdcc 6.4.2 XE2 (UP4+HF1) fastdccXE2v64.2.7z 166.48 KB 388 times 2019-03-23
fastdcc 6.4.2 XE3 (UP2) fastdccXE3v64.2.7z 150.88 KB 366 times 2019-03-23
fastdcc 6.4.2 XE4 (UP1) fastdccXE4v64.2.7z 153.55 KB 334 times 2019-03-23
fastdcc 6.4.2 XE5 (UP2) fastdccXE5v64.2.7z 151.87 KB 400 times 2019-03-23
fastdcc 6.4.2 XE6 (UP1) fastdccXE6v64.2.7z 198.67 KB 367 times 2019-03-23
fastdcc 6.4.2 XE7 (UP1) fastdccXE7v64.2.7z 219.84 KB 402 times 2019-03-23
fastdcc 6.4.2 XE8 (UP1) fastdccXE8v64.2.7z 224.67 KB 391 times 2019-03-23
fastdcc 6.4.2 10 Seattle (RTM/UP1) fastdccD10v64.2.7z 219.65 KB 504 times 2019-03-23
fastdcc 6.4.2 10.1 Berlin fastdccD101v64.2.7z 223.52 KB 553 times 2019-03-23
fastdcc 6.4.2 10.2 (RTM/UP1/2/3) fastdccD102v64.2.7z 219.06 KB 905 times 2019-03-23
fastdcc 6.4.4 10.3 (RTM/UP1/2) fastdccD103v64.4.7z 228.61 KB 992 times 2019-07-31

IDE Fix Pack 6.0 released – dcc64 and 10.2 Update 1 support

By | September 28, 2017

The new IDE Fix Pack version 6.0 is available. It supports Delphi 10.2 RTM and 10.2 Update 1. And after over a year of being in BETA testing without any bug reports, I also included all the Win64 compiler performance optimizations. Thus the jump to version 6.0 can finally be done as they make the Win64 compiler up to 50% faster.

Changelog:

  • Added: Win64 compile speed optimizations
  • Added: Delphi 10.2 Update 1 support
  • Added: Editor Block Completion UTF8 fix (Delphi 2009 only)

Download:

Name IDE Version File Size Downloads Added
IDE Fix Pack 6.4.2 2009 (UP4) IDEFixPack2009Reg64.2.7z 242.75 KB 1349 times 2019-03-23
IDE Fix Pack 6.4.2 2010 (UP5) IDEFixPack2010Reg64.2.7z 237.09 KB 1571 times 2019-03-23
IDE Fix Pack 6.4.2 XE (UP1) IDEFixPackXEReg64.2.7z 221.38 KB 774 times 2019-03-23
IDE Fix Pack 6.4.2 XE2 (UP4+HF1) IDEFixPackXE2Reg64.2.7z 316.78 KB 869 times 2019-03-23
IDE Fix Pack 6.4.2 XE3 (UP2) IDEFixPackXE3Reg64.2.7z 257.4 KB 653 times 2019-03-23
IDE Fix Pack 6.4.2 XE4 (UP1) IDEFixPackXE4Reg64.2.7z 260.1 KB 511 times 2019-03-23
IDE Fix Pack 6.4.2 XE5 (UP2) IDEFixPackXE5Reg64.2.7z 257.7 KB 623 times 2019-03-23
IDE Fix Pack 6.4.2 XE6 (UP1) IDEFixPackXE6Reg64.2.7z 423 KB 548 times 2019-03-23
IDE Fix Pack 6.4.2 XE7 (UP1) IDEFixPackXE7Reg64.2.7z 429.48 KB 806 times 2019-03-23
IDE Fix Pack 6.4.2 XE8 (UP1) IDEFixPackXE8Reg64.2.7z 431.7 KB 677 times 2019-03-23
IDE Fix Pack 6.4.2 10 Seattle (RTM/UP1) IDEFixPackD10Reg64.2.7z 428.33 KB 1202 times 2019-03-23
IDE Fix Pack 6.4.2 10.1 Berlin IDEFixPackD101Reg64.2.7z 430.65 KB 1442 times 2019-03-23
IDE Fix Pack 6.4.2 10.2 (RTM/UP1/2/3) IDEFixPackD102Reg64.2.7z 426.27 KB 2932 times 2019-03-23
IDE Fix Pack 6.4.4 10.3 (RTM/UP1/2) IDEFixPackD103Reg64.4.7z 444.98 KB 4251 times 2019-08-01

Download (fastdcc):

Name IDE Version File Size Downloads Added
fastdcc 6.4.2 2009 (UP4) fastdcc2009v64.2.7z 112.87 KB 486 times 2019-03-23
fastdcc 6.4.2 2010 (UP5) fastdcc2010v64.2.7z 120.38 KB 472 times 2019-03-23
fastdcc 6.4.2 XE (UP1) fastdccXEv64.2.7z 121.36 KB 385 times 2019-03-23
fastdcc 6.4.2 XE2 (UP4+HF1) fastdccXE2v64.2.7z 166.48 KB 388 times 2019-03-23
fastdcc 6.4.2 XE3 (UP2) fastdccXE3v64.2.7z 150.88 KB 366 times 2019-03-23
fastdcc 6.4.2 XE4 (UP1) fastdccXE4v64.2.7z 153.55 KB 334 times 2019-03-23
fastdcc 6.4.2 XE5 (UP2) fastdccXE5v64.2.7z 151.87 KB 400 times 2019-03-23
fastdcc 6.4.2 XE6 (UP1) fastdccXE6v64.2.7z 198.67 KB 367 times 2019-03-23
fastdcc 6.4.2 XE7 (UP1) fastdccXE7v64.2.7z 219.84 KB 402 times 2019-03-23
fastdcc 6.4.2 XE8 (UP1) fastdccXE8v64.2.7z 224.67 KB 391 times 2019-03-23
fastdcc 6.4.2 10 Seattle (RTM/UP1) fastdccD10v64.2.7z 219.65 KB 504 times 2019-03-23
fastdcc 6.4.2 10.1 Berlin fastdccD101v64.2.7z 223.52 KB 553 times 2019-03-23
fastdcc 6.4.2 10.2 (RTM/UP1/2/3) fastdccD102v64.2.7z 219.06 KB 905 times 2019-03-23
fastdcc 6.4.4 10.3 (RTM/UP1/2) fastdccD103v64.4.7z 228.61 KB 992 times 2019-07-31

Debugger Callstack Resolver released

By | August 15, 2017

Debugger Callstack Resolver is a Delphi IDE plugin that I wrote in 2011 to make the IDE’s CPU View more readable. It colors different instructions, resolves absolute and memory address jump and call targets and shows their function name if available. It also uses the *.jdbg to show more information (the dcc32 compiler’s jdbg files are for the debug build of the compiler and haven’t match the deployed version since jdbg files exist)

This plugin supports Delphi 2009 – 10.1 Berlin.

[Download]

IDE Fix Pack 5.96, DDevExtensions, DFMCheck for Delphi 10.2

By | April 9, 2017

Due to many requests, I took the time to update my tools (IDE Fix Pack, DDevExtensions, DFMCheck) for the newest Delphi version. Delphi 10.2 RTM will be the last version that all my tools support. I won’t be able to recompiled them for any 10.2 Update because my update subscription has expired and I didn’t (intentionally) renew it. Coincidentally I didn’t get a renewal message this time either.

This doesn’t mean that I won’t release newer versions of my tools, but I can’t support newer Delphi versions or 10.2 updates if the tools need to be recompiled. When I find some new possible optimizations or fixes for annoying bugs and time to work on them, Delphi 2009-10.2 RTM users will be able to use them.

Changelog:

  • Fixed: Disable DynArraySetLength patch if 10.1 Berlin Update 2 is detected.
  • Fixed: “clang template debug symbol bloat” disabled for 10 Seattle and newer.
  • Added: IDE minimize doesn’t shrink main window to width and height zero.
  • Added: RAD Studio 10.2 support

Download:

Name IDE Version File Size Downloads Added
IDE Fix Pack 6.4.2 2009 (UP4) IDEFixPack2009Reg64.2.7z 242.75 KB 1349 times 2019-03-23
IDE Fix Pack 6.4.2 2010 (UP5) IDEFixPack2010Reg64.2.7z 237.09 KB 1571 times 2019-03-23
IDE Fix Pack 6.4.2 XE (UP1) IDEFixPackXEReg64.2.7z 221.38 KB 774 times 2019-03-23
IDE Fix Pack 6.4.2 XE2 (UP4+HF1) IDEFixPackXE2Reg64.2.7z 316.78 KB 869 times 2019-03-23
IDE Fix Pack 6.4.2 XE3 (UP2) IDEFixPackXE3Reg64.2.7z 257.4 KB 653 times 2019-03-23
IDE Fix Pack 6.4.2 XE4 (UP1) IDEFixPackXE4Reg64.2.7z 260.1 KB 511 times 2019-03-23
IDE Fix Pack 6.4.2 XE5 (UP2) IDEFixPackXE5Reg64.2.7z 257.7 KB 623 times 2019-03-23
IDE Fix Pack 6.4.2 XE6 (UP1) IDEFixPackXE6Reg64.2.7z 423 KB 548 times 2019-03-23
IDE Fix Pack 6.4.2 XE7 (UP1) IDEFixPackXE7Reg64.2.7z 429.48 KB 806 times 2019-03-23
IDE Fix Pack 6.4.2 XE8 (UP1) IDEFixPackXE8Reg64.2.7z 431.7 KB 677 times 2019-03-23
IDE Fix Pack 6.4.2 10 Seattle (RTM/UP1) IDEFixPackD10Reg64.2.7z 428.33 KB 1202 times 2019-03-23
IDE Fix Pack 6.4.2 10.1 Berlin IDEFixPackD101Reg64.2.7z 430.65 KB 1442 times 2019-03-23
IDE Fix Pack 6.4.2 10.2 (RTM/UP1/2/3) IDEFixPackD102Reg64.2.7z 426.27 KB 2932 times 2019-03-23
IDE Fix Pack 6.4.4 10.3 (RTM/UP1/2) IDEFixPackD103Reg64.4.7z 444.98 KB 4251 times 2019-08-01

Download (fastdcc):

Name IDE Version File Size Downloads Added
fastdcc 6.4.2 2009 (UP4) fastdcc2009v64.2.7z 112.87 KB 486 times 2019-03-23
fastdcc 6.4.2 2010 (UP5) fastdcc2010v64.2.7z 120.38 KB 472 times 2019-03-23
fastdcc 6.4.2 XE (UP1) fastdccXEv64.2.7z 121.36 KB 385 times 2019-03-23
fastdcc 6.4.2 XE2 (UP4+HF1) fastdccXE2v64.2.7z 166.48 KB 388 times 2019-03-23
fastdcc 6.4.2 XE3 (UP2) fastdccXE3v64.2.7z 150.88 KB 366 times 2019-03-23
fastdcc 6.4.2 XE4 (UP1) fastdccXE4v64.2.7z 153.55 KB 334 times 2019-03-23
fastdcc 6.4.2 XE5 (UP2) fastdccXE5v64.2.7z 151.87 KB 400 times 2019-03-23
fastdcc 6.4.2 XE6 (UP1) fastdccXE6v64.2.7z 198.67 KB 367 times 2019-03-23
fastdcc 6.4.2 XE7 (UP1) fastdccXE7v64.2.7z 219.84 KB 402 times 2019-03-23
fastdcc 6.4.2 XE8 (UP1) fastdccXE8v64.2.7z 224.67 KB 391 times 2019-03-23
fastdcc 6.4.2 10 Seattle (RTM/UP1) fastdccD10v64.2.7z 219.65 KB 504 times 2019-03-23
fastdcc 6.4.2 10.1 Berlin fastdccD101v64.2.7z 223.52 KB 553 times 2019-03-23
fastdcc 6.4.2 10.2 (RTM/UP1/2/3) fastdccD102v64.2.7z 219.06 KB 905 times 2019-03-23
fastdcc 6.4.4 10.3 (RTM/UP1/2) fastdccD103v64.4.7z 228.61 KB 992 times 2019-07-31

 


There is also a new IDE Fix Pack 6.0 Beta 4 that contains all the above and the experimental 64 bit compiler performance optimizations.

Download:

Name IDE Version File Size Downloads Added

Castalia’s Clipboard history + TRichEdit = IDE deadlock

By | August 15, 2016

Eugene Kotlyarov found a problem with Castalia’s clipboard history feature combined with a TRichEdit in a debugged application. If you copy text from the RichEdit to the clipboard the first time, the IDE and the debugged application stop responding and start reacting after a ~30 seconds timeout. After that, copy to clipboard works until you restart the debugged application. Win32 and Win64 have the same problem.
https://plus.google.com/+EugeneKotlyarovPlus/posts/R783AB3DfYL

What happens:

  • The debugged application invokes WM_COPY by Ctrl+C/Ctrl+Insert/Context-menu “Copy”.
  • WM_COPY set the RichEdit as clipboard renderer without putting the actual data into the clipboard.
  • Castalia’s TClipboardHistoryForm receives the WM_CLIPBOARDUPDATE message in the main thread and calls GetClipboardData (via Clipboard.AsText).
  • The debugged application’s RichEdit loads a DLL to provide the actual clipboard data for the GetClipboardData call.
  • The debugger receives a LOAD_DLL_DEBUG_EVENT for the DLL.
  • The debugger posts a message to the debugger window in the main thread and goes to sleep with WaitForSingleObject to wait for the debugger window to process the DLL load event.

Now everything waits. GetClipboardData is blocked because the clipboard owner, the debugged application, is trapped in a debugger event. The debugger is blocked because the debugger window doesn’t get the posted message because the blocked GetClipboardData prevents the main thread from processing messages.

Fortunately a Microsoft developer knew about this possible deadlock and put a timeout into GetClipboardData.

 

A solution that I’ve put into the IDE Fix Pack development version (not available) moves the WM_CLIPBOARDUPDATE message handling into a thread window, so that the call to GetClipboardData doesn’t block the main thread and the debugger can process the DLL load event.

What’s wrong with virtual methods called through an interface

By | May 31, 2016

Calling a virtual method through an interface always was a lot slower than calling a static method through an interface. But why is that? Sure, the virtual method call costs some time, but comparing it with the difference of a normal static and virtual method call shows that the timings diverge too much.

i7-4790 3.6GHz
10,000,000 calls to empty method
Instance call Interface call
Static method 12 ms 17 ms
Virtual method 17 ms 164 ms

Let’s assume we have this declaration:

type
  IMyInterface = interface
    procedure Test(A, B: Integer);
  end;
  TTest = class(TInterfacedObject, IMyInterface)
  public
    procedure Test(A, B: Integer); virtual;
  end;

The compiler will generate a helper function for the interface method “Test”. This helper converts the “MyIntf” interface reference in the call “MyIntf.Test()” to the object reference behind the interface and then jumps to the virtual method.

add eax,-$0C   // convert the interface reference to the object reference
push eax       // save the object reference on the stack
mov eax,[eax]  // access the VMT
mov eax,[eax]  // get the “Test” VMT method address
xchg [esp],eax // swap the object ref on the stack with the method address
ret            // do the jump to the method address

This is very slow as you can see in the table above. If you know the “XCHG mem,reg” instruction, then you also know that it has an implicit “CPU LOCK” that slows down the method call a lot. But why is it using the XCHG instruction in the first place? Well, we are in between a method call. All the parameters are already loaded in to EAX, EDX and ECX. So we can’t use those to do the swap. The only way is to use the stack as temporary variable, and XCHG seemed to be the choice of the compiler engineer at the time interfaces were introduced to Delphi.

Let’s change that code to not use XCHG.

add eax,-$0 C      // convert the interface reference to the object reference
push eax           // reserve space for the method address used by RET
push eax           // save the object reference on the stack
mov eax,[eax]      // access the VMT
mov eax,[eax]      // get the “Test” VMT method address
mov [esp+04],eax   // write the method address to the reserved space
pop eax            // restore the object reference
ret                // do the jump to the method address

i7-4790 3.6GHz
10,000,000 calls to empty method
Instance call Interface call
Static method 12 ms 17 ms
Virtual method 17 ms 99 ms
Virtual method (XCHG) 164 ms

This is a lot faster, but still slow compared to the “Instance call”. The helper has a lot of memory accesses, but they shouldn’t slow it that much down, especially not in a tight loop when everything comes from the CPU’s cache.

So where does the code spend the time? Well, modern CPUs (after P1) have a feature called “return stack buffer”. The CPU puts the return address on the “return stack buffer” for every CALL instruction so it can predict where the RET instruction will jump to. This requires that every CALL is matched by a RET. But wait, the helper uses a RET for an indirect jump. We have the CALL from the interface method call, the RET in the helper and the RET in the actual method. That doesn’t match up. In other words, this helper renders the “return stack buffer” invalid what comes with a performance hit because the CPU can’t predict where to jump.

Let’s see what happens if we replace the RET with a JMP.

add eax,-$0C        // convert the interface reference to the object reference
push eax            // save the object reference on the stack
mov eax,[eax]       // access the VMT
push DWORD PTR [eax]// save the “Test” VMT entry method address on the stack
add esp,$04         // skip the method address stack entry
pop eax             // restore the object reference
jmp [esp-$08]       // jump to the method address

i7-4790 3.6GHz
10,000,000 calls to empty method
Instance call Interface call
Static method 12 ms 17 ms
Virtual method 17 ms 24 ms
Virtual method (RET) 99 ms
Virtual method (XCHG) 164 ms

UPDATE: As fast as this implementation may be, it has a problem. As Allen and Mark pointed out, it accesses memory on the stack that is treated as free memory from the system. So if a hardware interrupt is triggered between the “add esp,$04” and the “jmp [esp-$08]”, the data on the stack is overwritten and the jump will end somewhere but not where it should be.

UPDATE 2: Thorsten Engler sent me an e-mail that invalidates the “hardware interrupt problem”. All interrupts are handled in kernel mode and kernel mode code doesn’t touch the user stack. The CPU itself switches the SS:ESP before invoking the interrupt handler.

Based on AMD64 Architecture Programmer’s Manual Volume 2 – System Programming Rev.3.22 Section 8.7.3 Interrupt To Higher Privilege:

When a control transfer to an exception or interrupt handler running at a higher privilege occurs (numerically lower CPL value), the processor performs a stack switch using the following steps:

  1. The target CPL is read by the processor from the target code-segment DPL and used as an index into the TSS for selecting the new stack pointer (SS:ESP). For example, if the target CPL is 1, the processor selects the SS:ESP for privilege-level 1 from the TSS.
  2. Pushes the return stack pointer (old SS:ESP) onto the new stack. The SS value is padded with two bytes to form a doubleword.