Compare commits

...

10 Commits
Final ... main

Author SHA1 Message Date
Razor12911 9a1d5fafcf
0.7.9 hotfix 1 2023-09-18 02:43:52 +02:00
Razor12911 9d6a2d6e20
0.7.9 hotfix 1 2023-09-18 02:42:53 +02:00
Razor12911 16199e4908
0.7.9 hotfix 1 2023-09-18 02:42:01 +02:00
Razor12911 83e41efb88
0.7.9 hotfix 1 2023-09-14 23:04:54 +02:00
Razor12911 fde22c2c77 update to 0.7.9 2023-09-10 15:03:26 +02:00
Razor12911 30ce6f00fc update to 0.7.3 2023-06-30 05:02:05 +02:00
Razor12911 7e8bbfcd86 Merge branch 'main' of https://github.com/Razor12911/xtool 2023-06-12 16:28:12 +02:00
Razor12911 3b0bf1fe47 update to 0.7.2 2023-06-12 16:28:02 +02:00
Razor12911 6fbb1865e8
Delete README.md 2023-05-12 22:35:15 +02:00
Razor12911 50c7c248da update to 0.7.0 2023-04-29 22:51:51 +02:00
347 changed files with 90926 additions and 70586 deletions

View File

@ -4,11 +4,14 @@ interface
uses
Utils, LibImport,
System.SysUtils;
WinAPI.Windows,
System.SysUtils, System.Classes, System.Types, System.StrUtils;
const
PluginsParam1 = '--basedir=';
PluginsParam2 = '-bd';
PLUGIN_DATABASE = 0;
PLUGIN_CONFIG = 1;
PLUGIN_LIBRARY = 2;
PluginsParam = '-bd';
type
PUIFuncs = ^TUIFuncs;
@ -31,6 +34,7 @@ type
end;
var
DEBUG: Boolean = False;
UILib: TLibImport;
PluginsPath: String = '';
XTLUI1: procedure;
@ -44,7 +48,10 @@ implementation
procedure Init;
begin
UILib := TLibImport.Create(ChangeFileExt(Utils.GetModuleName, 'ui.dll'));
if Win32MajorVersion < 6 then
exit;
UILib := TLibImport.Create;
UILib.LoadLib(ChangeFileExt(Utils.GetModuleName, 'ui.dll'));
if UILib.Loaded then
begin
@XTLUI1 := UILib.GetProcAddr('XTLUI1');
@ -57,6 +64,8 @@ end;
procedure Deinit;
begin
if Win32MajorVersion < 6 then
exit;
UILib.Free;
end;
@ -65,28 +74,37 @@ var
initialization
Init;
if UIDLLLoaded and (ParamCount = 0) then
PluginsPath := IncludeTrailingBackSlash
(ExpandPath(GetIniString('UI', 'Plugins', '',
ChangeFileExt(Utils.GetModuleName, 'ui.ini'))));
for I := 1 to ParamCount do
if not IsLibrary then
begin
if ParamStr(I).StartsWith(PluginsParam1) then
for I := 1 to ParamCount do
begin
PluginsPath := ParamStr(I).Substring(PluginsParam1.Length);
break;
if (ParamStr(I) = '--debug') then
begin
DEBUG := True;
break;
end;
end;
if ParamStr(I).StartsWith(PluginsParam2) then
Init;
if UIDLLLoaded and (ParamCount = 0) then
PluginsPath := IncludeTrailingBackSlash
(ExpandPath(GetIniString('UI', 'Plugins', '',
ChangeFileExt(Utils.GetModuleName, 'ui.ini'))));
for I := 1 to ParamCount do
begin
PluginsPath := ParamStr(I).Substring(PluginsParam2.Length);
break;
if ParamStr(I).StartsWith(PluginsParam) then
begin
PluginsPath := ParamStr(I).Substring(PluginsParam.Length);
break;
end;
end;
end;
PluginsPath := IncludeTrailingBackSlash(ExpandPath(PluginsPath));
if not DirectoryExists(ExpandPath(PluginsPath, True)) then
PluginsPath := ExtractFilePath(Utils.GetModuleName);
finalization
Deinit;
if not IsLibrary then
Deinit;
end.

View File

@ -1 +0,0 @@
# xtool

2972
Unit1.fmx

File diff suppressed because it is too large Load Diff

728
Unit1.pas
View File

@ -8,15 +8,14 @@ uses
System.Variants, System.Math, System.StrUtils, System.IniFiles,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.TabControl,
FMX.Layouts, FMX.ListBox, FMX.Controls.Presentation, FMX.StdCtrls, FMX.Edit,
FMX.EditBox, FMX.SpinBox, FMX.Menus;
FMX.EditBox, FMX.SpinBox, FMX.Menus, FMX.ComboEdit, FMX.Memo.Types,
FMX.ScrollBox, FMX.Memo;
type
TForm1 = class(TForm)
StyleBook1: TStyleBook;
SaveDialog1: TSaveDialog;
OpenDialog1: TOpenDialog;
Layout4: TLayout;
Button1: TButton;
GroupBox1: TGroupBox;
ComboBox2: TComboBox;
Edit1: TEdit;
@ -34,42 +33,181 @@ type
SpinBox1: TSpinBox;
Label2: TLabel;
SpinBox2: TSpinBox;
CheckBox1: TCheckBox;
Layout2: TLayout;
Label3: TLabel;
SpinBox3: TSpinBox;
GroupBox4: TGroupBox;
Layout6: TLayout;
GroupBox5: TGroupBox;
Layout8: TLayout;
Label7: TLabel;
SpinBox7: TSpinBox;
CheckBox5: TCheckBox;
CheckBox3: TCheckBox;
Label4: TLabel;
SpinBox4: TSpinBox;
CheckBox4: TCheckBox;
PopupMenu1: TPopupMenu;
MenuItem1: TMenuItem;
GroupBox6: TGroupBox;
Layout5: TLayout;
Edit2: TEdit;
Button2: TButton;
GroupBox7: TGroupBox;
Layout9: TLayout;
Edit4: TEdit;
SearchEditButton2: TSearchEditButton;
ComboBox1: TComboBox;
CheckBox2: TCheckBox;
CheckBox6: TCheckBox;
GroupBox8: TGroupBox;
Layout10: TLayout;
Edit5: TEdit;
SearchEditButton4: TSearchEditButton;
ComboBox4: TComboBox;
ComboBox5: TComboBox;
ComboEdit1: TComboEdit;
Label6: TLabel;
TabControl1: TTabControl;
TabItem1: TTabItem;
TabItem2: TTabItem;
TabItem3: TTabItem;
GroupBox9: TGroupBox;
Layout11: TLayout;
Edit7: TEdit;
SearchEditButton6: TSearchEditButton;
ComboBox6: TComboBox;
GroupBox10: TGroupBox;
Layout12: TLayout;
Edit8: TEdit;
SearchEditButton7: TSearchEditButton;
ComboBox7: TComboBox;
GroupBox11: TGroupBox;
Layout13: TLayout;
Edit9: TEdit;
SearchEditButton8: TSearchEditButton;
ComboBox8: TComboBox;
GroupBox12: TGroupBox;
Layout14: TLayout;
Label9: TLabel;
SpinBox6: TSpinBox;
Label10: TLabel;
SpinBox8: TSpinBox;
VertScrollBox2: TVertScrollBox;
TabControl2: TTabControl;
TabItem4: TTabItem;
TabItem5: TTabItem;
TabItem6: TTabItem;
OpenDialog2: TOpenDialog;
Layout4: TLayout;
Button1: TButton;
Label5: TLabel;
Edit6: TEdit;
SearchEditButton5: TSearchEditButton;
Layout18: TLayout;
Button5: TButton;
TabItem9: TTabItem;
VertScrollBox4: TVertScrollBox;
GroupBox15: TGroupBox;
Layout20: TLayout;
Edit10: TEdit;
SearchEditButton9: TSearchEditButton;
ComboBox9: TComboBox;
GroupBox16: TGroupBox;
Layout21: TLayout;
Edit12: TEdit;
SearchEditButton11: TSearchEditButton;
ComboBox10: TComboBox;
GroupBox17: TGroupBox;
Layout22: TLayout;
Label12: TLabel;
SpinBox9: TSpinBox;
Label13: TLabel;
SpinBox10: TSpinBox;
GroupBox18: TGroupBox;
Layout23: TLayout;
Edit13: TEdit;
SearchEditButton12: TSearchEditButton;
ComboBox11: TComboBox;
Layout24: TLayout;
Button7: TButton;
VertScrollBox5: TVertScrollBox;
GroupBox19: TGroupBox;
Layout25: TLayout;
Edit14: TEdit;
SearchEditButton13: TSearchEditButton;
ComboBox12: TComboBox;
GroupBox20: TGroupBox;
Layout26: TLayout;
Edit15: TEdit;
SearchEditButton14: TSearchEditButton;
ComboBox13: TComboBox;
GroupBox21: TGroupBox;
Layout27: TLayout;
Label14: TLabel;
SpinBox11: TSpinBox;
Label15: TLabel;
SpinBox12: TSpinBox;
GroupBox22: TGroupBox;
Layout28: TLayout;
Edit16: TEdit;
SearchEditButton15: TSearchEditButton;
ComboBox14: TComboBox;
Layout29: TLayout;
Button8: TButton;
GroupBox23: TGroupBox;
Layout30: TLayout;
Edit17: TEdit;
SearchEditButton16: TSearchEditButton;
ComboBox15: TComboBox;
VertScrollBox7: TVertScrollBox;
GroupBox28: TGroupBox;
Layout36: TLayout;
Edit21: TEdit;
SearchEditButton20: TSearchEditButton;
ComboBox19: TComboBox;
GroupBox29: TGroupBox;
Layout37: TLayout;
Edit22: TEdit;
SearchEditButton21: TSearchEditButton;
GroupBox30: TGroupBox;
Layout38: TLayout;
Label18: TLabel;
SpinBox15: TSpinBox;
Label19: TLabel;
SpinBox16: TSpinBox;
GroupBox31: TGroupBox;
Layout39: TLayout;
Edit23: TEdit;
SearchEditButton22: TSearchEditButton;
ComboBox21: TComboBox;
GroupBox32: TGroupBox;
Layout40: TLayout;
Edit24: TEdit;
Layout41: TLayout;
Button10: TButton;
SaveDialog2: TSaveDialog;
VertScrollBox8: TVertScrollBox;
GroupBox33: TGroupBox;
Layout42: TLayout;
Edit25: TEdit;
SearchEditButton23: TSearchEditButton;
GroupBox34: TGroupBox;
Layout43: TLayout;
Edit26: TEdit;
SearchEditButton24: TSearchEditButton;
GroupBox35: TGroupBox;
Layout44: TLayout;
Label16: TLabel;
SpinBox13: TSpinBox;
GroupBox36: TGroupBox;
Layout45: TLayout;
Edit27: TEdit;
SearchEditButton25: TSearchEditButton;
Layout46: TLayout;
Button11: TButton;
ComboBox17: TComboBox;
ComboBox18: TComboBox;
CheckBox7: TCheckBox;
Label20: TLabel;
Edit28: TEdit;
SearchEditButton26: TSearchEditButton;
Label21: TLabel;
ComboEdit2: TComboEdit;
CheckBox1: TCheckBox;
Label3: TLabel;
SpinBox3: TSpinBox;
CheckBox6: TCheckBox;
Label8: TLabel;
ComboEdit3: TComboEdit;
procedure FormShow(Sender: TObject);
procedure SearchEditButton1Click(Sender: TObject);
procedure SearchEditButton3Click(Sender: TObject);
@ -77,13 +215,54 @@ type
procedure Button2Click(Sender: TObject);
procedure ComboBox2Change(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure ComboBox1Change(Sender: TObject);
procedure SearchEditButton2Click(Sender: TObject);
procedure ComboBox4Change(Sender: TObject);
procedure SearchEditButton4Click(Sender: TObject);
procedure Edit6Change(Sender: TObject);
procedure SearchEditButton5Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure ComboBox5Change(Sender: TObject);
procedure ComboBox7Change(Sender: TObject);
procedure ComboBox6Change(Sender: TObject);
procedure ComboBox8Change(Sender: TObject);
procedure SearchEditButton7Click(Sender: TObject);
procedure SearchEditButton6Click(Sender: TObject);
procedure SearchEditButton8Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure ComboBox9Change(Sender: TObject);
procedure ComboBox11Change(Sender: TObject);
procedure ComboBox10Change(Sender: TObject);
procedure SearchEditButton21Click(Sender: TObject);
procedure ComboBox19Change(Sender: TObject);
procedure ComboBox21Change(Sender: TObject);
procedure ComboBox12Change(Sender: TObject);
procedure ComboBox15Change(Sender: TObject);
procedure ComboBox14Change(Sender: TObject);
procedure ComboBox13Change(Sender: TObject);
procedure SearchEditButton20Click(Sender: TObject);
procedure SearchEditButton22Click(Sender: TObject);
procedure SearchEditButton9Click(Sender: TObject);
procedure SearchEditButton12Click(Sender: TObject);
procedure SearchEditButton11Click(Sender: TObject);
procedure SearchEditButton13Click(Sender: TObject);
procedure SearchEditButton16Click(Sender: TObject);
procedure SearchEditButton15Click(Sender: TObject);
procedure SearchEditButton14Click(Sender: TObject);
procedure Button10Click(Sender: TObject);
procedure Button7Click(Sender: TObject);
procedure Button8Click(Sender: TObject);
procedure SearchEditButton23Click(Sender: TObject);
procedure Button11Click(Sender: TObject);
procedure ComboBox18Change(Sender: TObject);
procedure ComboBox17Change(Sender: TObject);
procedure SearchEditButton25Click(Sender: TObject);
procedure SearchEditButton24Click(Sender: TObject);
procedure CheckBox4Change(Sender: TObject);
procedure Edit1Change(Sender: TObject);
procedure Edit21Change(Sender: TObject);
procedure Edit8Change(Sender: TObject);
procedure Edit10Change(Sender: TObject);
procedure Edit14Change(Sender: TObject);
procedure Edit25Change(Sender: TObject);
private
{ Private declarations }
public
@ -93,6 +272,8 @@ type
var
Form1: TForm1;
CmdStr: TArray<String>;
Init: Boolean = False;
DecodeMode: Integer = -1;
function GetModuleName: string;
function GetIniString(Section, Key, Default, FileName: string): string;
@ -140,7 +321,38 @@ begin
end;
end;
procedure TForm1.Button10Click(Sender: TObject);
begin
SetLength(CmdStr, 0);
Insert(ParamStr(0), CmdStr, Length(CmdStr));
Insert('generate', CmdStr, Length(CmdStr));
Insert('-c' + SpinBox15.Text + 'mb', CmdStr, Length(CmdStr));
Insert('-t' + SpinBox16.Text, CmdStr, Length(CmdStr));
Insert('-m' + Edit24.Text, CmdStr, Length(CmdStr));
Insert(Edit21.Text, CmdStr, Length(CmdStr));
Insert(Edit23.Text, CmdStr, Length(CmdStr));
Insert(Edit22.Text, CmdStr, Length(CmdStr));
end;
procedure TForm1.Button11Click(Sender: TObject);
begin
SetLength(CmdStr, 0);
Insert(ParamStr(0), CmdStr, Length(CmdStr));
Insert('decode', CmdStr, Length(CmdStr));
Insert('-t' + SpinBox13.Text, CmdStr, Length(CmdStr));
if CheckBox7.IsChecked then
Insert('-v', CmdStr, Length(CmdStr));
Insert('-bd' + Edit6.Text, CmdStr, Length(CmdStr));
Insert(Edit25.Text, CmdStr, Length(CmdStr));
case DecodeMode of
0:
Insert(Edit26.Text, CmdStr, Length(CmdStr));
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
S: String;
begin
SetLength(CmdStr, 0);
Insert(ParamStr(0), CmdStr, Length(CmdStr));
@ -155,19 +367,26 @@ begin
if CheckBox6.IsChecked then
Insert('-v', CmdStr, Length(CmdStr));
Insert('-m' + Edit2.Text, CmdStr, Length(CmdStr));
if ComboBox1.ItemIndex = 1 then
Insert('-db', CmdStr, Length(CmdStr))
else if ComboBox1.ItemIndex > 1 then
Insert('-db' + Edit4.Text, CmdStr, Length(CmdStr));
if CheckBox3.IsChecked then
if ComboBox5.ItemIndex > 0 then
Insert('-dd' + IfThen(SpinBox4.Enabled, SpinBox4.Text, ''), CmdStr,
Length(CmdStr));
if ComboEdit1.Enabled then
Insert('-sps' + ReplaceText(ComboEdit1.Text, ' ', ''), CmdStr,
Length(CmdStr));
if CheckBox4.IsChecked then
Insert('--compress=' + 't' + SpinBox2.Text + ':l' + SpinBox7.Text + ':hi' +
IfThen(CheckBox5.IsChecked, '1', '0'), CmdStr, Length(CmdStr));
Insert('--basedir=' + Edit6.Text, CmdStr, Length(CmdStr));
begin
S := '';
if not ComboEdit2.Text.StartsWith('Auto', False) then
S := S + ':d' + ReplaceText(ComboEdit2.Text, ' ', '');
// S := S + ':o8';
Insert('-l' + SpinBox7.Text + IfThen(SameText(ComboEdit2.Text, 'Auto'), '',
'x') + S, CmdStr, Length(CmdStr));
end;
Insert('-p' + ReplaceText(ReplaceText(ComboEdit3.Text, '%', 'p'), ' ', '')
.ToLower, CmdStr, Length(CmdStr));
Insert('-bd' + Edit6.Text, CmdStr, Length(CmdStr));
Insert(Edit1.Text, CmdStr, Length(CmdStr));
if ComboBox3.ItemIndex = 0 then
if ComboBox3.ItemIndex = 1 then
Insert(Edit3.Text, CmdStr, Length(CmdStr));
end;
@ -179,10 +398,100 @@ begin
Form2.Close;
end;
procedure TForm1.ComboBox1Change(Sender: TObject);
procedure TForm1.Button5Click(Sender: TObject);
begin
Edit4.Enabled := ComboBox1.ItemIndex in [2, 3];
Edit4.Text := '';
SetLength(CmdStr, 0);
Insert(ParamStr(0), CmdStr, Length(CmdStr));
Insert('find', CmdStr, Length(CmdStr));
Insert('-c' + SpinBox6.Text + 'mb', CmdStr, Length(CmdStr));
Insert('-t' + SpinBox8.Text, CmdStr, Length(CmdStr));
Insert(Edit8.Text, CmdStr, Length(CmdStr));
Insert(Edit7.Text, CmdStr, Length(CmdStr));
if ComboBox8.ItemIndex = 1 then
Insert(Edit9.Text, CmdStr, Length(CmdStr));
end;
procedure TForm1.Button7Click(Sender: TObject);
begin
SetLength(CmdStr, 0);
Insert(ParamStr(0), CmdStr, Length(CmdStr));
Insert('erase', CmdStr, Length(CmdStr));
Insert('-c' + SpinBox9.Text + 'mb', CmdStr, Length(CmdStr));
Insert('-t' + SpinBox10.Text, CmdStr, Length(CmdStr));
Insert(Edit10.Text, CmdStr, Length(CmdStr));
Insert(Edit13.Text, CmdStr, Length(CmdStr));
if ComboBox10.ItemIndex = 1 then
Insert(Edit12.Text, CmdStr, Length(CmdStr));
end;
procedure TForm1.Button8Click(Sender: TObject);
begin
SetLength(CmdStr, 0);
Insert(ParamStr(0), CmdStr, Length(CmdStr));
Insert('replace', CmdStr, Length(CmdStr));
Insert('-c' + SpinBox11.Text + 'mb', CmdStr, Length(CmdStr));
Insert('-t' + SpinBox12.Text, CmdStr, Length(CmdStr));
Insert(Edit14.Text, CmdStr, Length(CmdStr));
Insert(Edit17.Text, CmdStr, Length(CmdStr));
Insert(Edit16.Text, CmdStr, Length(CmdStr));
if ComboBox13.ItemIndex = 1 then
Insert(Edit15.Text, CmdStr, Length(CmdStr));
end;
procedure TForm1.CheckBox4Change(Sender: TObject);
begin
SpinBox7.Enabled := CheckBox4.IsChecked;
ComboEdit2.Enabled := CheckBox4.IsChecked;
end;
procedure TForm1.ComboBox10Change(Sender: TObject);
begin
Edit12.Enabled := ComboBox10.ItemIndex <> 0;
end;
procedure TForm1.ComboBox11Change(Sender: TObject);
begin
Edit13.Text := '';
end;
procedure TForm1.ComboBox12Change(Sender: TObject);
begin
Edit14.Text := '';
end;
procedure TForm1.ComboBox13Change(Sender: TObject);
begin
Edit15.Enabled := ComboBox13.ItemIndex <> 0;
end;
procedure TForm1.ComboBox14Change(Sender: TObject);
begin
Edit16.Text := '';
end;
procedure TForm1.ComboBox15Change(Sender: TObject);
begin
Edit17.Text := '';
end;
procedure TForm1.ComboBox17Change(Sender: TObject);
begin
Edit27.Text := '';
end;
procedure TForm1.ComboBox18Change(Sender: TObject);
begin
Edit26.Text := '';
end;
procedure TForm1.ComboBox19Change(Sender: TObject);
begin
Edit21.Text := '';
end;
procedure TForm1.ComboBox21Change(Sender: TObject);
begin
Edit23.Text := '';
end;
procedure TForm1.ComboBox2Change(Sender: TObject);
@ -197,7 +506,8 @@ end;
procedure TForm1.ComboBox3Change(Sender: TObject);
begin
Edit3.Enabled := ComboBox3.ItemIndex <> 1;
Edit3.Enabled := ComboBox3.ItemIndex <> 0;
ComboEdit1.Enabled := (ComboBox5.ItemIndex = 2) and (ComboBox3.ItemIndex = 0);
end;
procedure TForm1.ComboBox4Change(Sender: TObject);
@ -206,9 +516,73 @@ begin
Edit5.Text := '';
end;
procedure TForm1.ComboBox5Change(Sender: TObject);
begin
SpinBox4.Enabled := ComboBox5.ItemIndex = 2;
ComboEdit1.Enabled := (ComboBox5.ItemIndex = 2) and (ComboBox3.ItemIndex = 0);
end;
procedure TForm1.ComboBox6Change(Sender: TObject);
begin
Edit7.Text := '';
end;
procedure TForm1.ComboBox7Change(Sender: TObject);
begin
Edit8.Text := '';
end;
procedure TForm1.ComboBox8Change(Sender: TObject);
begin
Edit9.Enabled := ComboBox8.ItemIndex <> 0;
end;
procedure TForm1.ComboBox9Change(Sender: TObject);
begin
Edit10.Text := '';
end;
procedure TForm1.Edit10Change(Sender: TObject);
begin
Button7.Enabled := (Edit10.Text <> '') and (Edit13.Text <> '');;
end;
procedure TForm1.Edit14Change(Sender: TObject);
begin
Button8.Enabled := (Edit14.Text <> '') and (Edit17.Text <> '') and
(Edit16.Text <> '');
end;
procedure TForm1.Edit1Change(Sender: TObject);
begin
Button1.Enabled := Edit1.Text <> '';
end;
procedure TForm1.Edit21Change(Sender: TObject);
begin
Button10.Enabled := (Edit21.Text <> '') and (Edit23.Text <> '') and
(Edit22.Text <> '') and (Edit24.Text <> '');
end;
procedure TForm1.Edit25Change(Sender: TObject);
begin
Button11.Enabled := Edit25.Text <> '';
end;
procedure TForm1.Edit6Change(Sender: TObject);
begin
ShowMessage('Restart required to reload new plugins folder.');
if Sender = Edit6 then
begin
Edit28.Text := Edit6.Text;
ShowMessage('Restart required to reload new plugins folder.');
end
else
Edit6.Text := Edit28.Text;
end;
procedure TForm1.Edit8Change(Sender: TObject);
begin
Button5.Enabled := (Edit8.Text <> '') and (Edit7.Text <> '');
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
@ -223,11 +597,111 @@ procedure TForm1.FormShow(Sender: TObject);
var
I: Integer;
begin
for I := 0 to ComponentCount - 1 do
if Components[I] is TSpinBox then
TSpinBox(Components[I]).Cursor := crDefault;
SpinBox2.Max := CPUCount * 2;
SpinBox2.Value := Max(1, CPUCount div 2);
if not Init then
begin
Init := True;
for I := 0 to ComponentCount - 1 do
begin
if Components[I] is TSpinBox then
TSpinBox(Components[I]).Cursor := crDefault;
if Components[I] is TComboBox then
TComboBox(Components[I]).OnChange(nil);
end;
SpinBox2.Max := CPUCount * 2;
SpinBox2.Value := Max(1, CPUCount div 2);
SpinBox8.Max := CPUCount * 2;
SpinBox8.Value := Max(1, CPUCount div 2);
SpinBox10.Max := CPUCount * 2;
SpinBox10.Value := Max(1, CPUCount div 2);
SpinBox12.Max := CPUCount * 2;
SpinBox12.Value := Max(1, CPUCount div 2);
SpinBox16.Max := CPUCount * 2;
SpinBox16.Value := Max(1, CPUCount div 2);
SpinBox13.Max := CPUCount * 2;
SpinBox13.Value := Max(1, CPUCount div 2);
end;
end;
procedure TForm1.SearchEditButton11Click(Sender: TObject);
begin
SaveDialog1.FileName := '';
if SaveDialog1.Execute then
Edit12.Text := SaveDialog1.FileName;
end;
procedure TForm1.SearchEditButton12Click(Sender: TObject);
var
Dir: string;
begin
case ComboBox11.ItemIndex of
0:
begin
OpenDialog1.FileName := '';
if OpenDialog1.Execute then
Edit13.Text := OpenDialog1.FileName;
end;
1:
if SelectDirectory('', '', Dir) then
Edit13.Text := Dir;
end;
end;
procedure TForm1.SearchEditButton13Click(Sender: TObject);
var
Dir: string;
begin
case ComboBox12.ItemIndex of
0:
begin
OpenDialog1.FileName := '';
if OpenDialog1.Execute then
Edit14.Text := OpenDialog1.FileName;
end;
1:
if SelectDirectory('', '', Dir) then
Edit14.Text := Dir;
end;
end;
procedure TForm1.SearchEditButton14Click(Sender: TObject);
begin
SaveDialog1.FileName := '';
if SaveDialog1.Execute then
Edit15.Text := SaveDialog1.FileName;
end;
procedure TForm1.SearchEditButton15Click(Sender: TObject);
var
Dir: string;
begin
case ComboBox14.ItemIndex of
0:
begin
OpenDialog1.FileName := '';
if OpenDialog1.Execute then
Edit16.Text := OpenDialog1.FileName;
end;
1:
if SelectDirectory('', '', Dir) then
Edit16.Text := Dir;
end;
end;
procedure TForm1.SearchEditButton16Click(Sender: TObject);
var
Dir: string;
begin
case ComboBox15.ItemIndex of
0:
begin
OpenDialog1.FileName := '';
if OpenDialog1.Execute then
Edit17.Text := OpenDialog1.FileName;
end;
1:
if SelectDirectory('', '', Dir) then
Edit17.Text := Dir;
end;
end;
procedure TForm1.SearchEditButton1Click(Sender: TObject);
@ -247,19 +721,118 @@ begin
end;
end;
procedure TForm1.SearchEditButton2Click(Sender: TObject);
procedure TForm1.SearchEditButton20Click(Sender: TObject);
var
Dir: string;
begin
if ComboBox1.ItemIndex = 2 then
case ComboBox19.ItemIndex of
0:
begin
OpenDialog1.FileName := '';
if OpenDialog1.Execute then
Edit21.Text := OpenDialog1.FileName;
end;
1:
if SelectDirectory('', '', Dir) then
Edit21.Text := Dir;
end;
end;
procedure TForm1.SearchEditButton21Click(Sender: TObject);
begin
SaveDialog2.FileName := '';
if SaveDialog2.Execute then
Edit22.Text := SaveDialog2.FileName;
end;
procedure TForm1.SearchEditButton22Click(Sender: TObject);
var
Dir: string;
begin
case ComboBox21.ItemIndex of
0:
begin
OpenDialog1.FileName := '';
if OpenDialog1.Execute then
Edit23.Text := OpenDialog1.FileName;
end;
1:
if SelectDirectory('', '', Dir) then
Edit23.Text := Dir;
end;
end;
procedure TForm1.SearchEditButton23Click(Sender: TObject);
function IndexInt(AInteger: Integer; const AValues: array of Integer)
: Integer;
var
I: Integer;
begin
SaveDialog1.FileName := '';
if SaveDialog1.Execute then
Edit4.Text := SaveDialog1.FileName;
end
else if ComboBox1.ItemIndex = 3 then
Result := -1;
for I := Low(AValues) to High(AValues) do
if AInteger = AValues[I] then
begin
Result := I;
break;
end;
end;
const
XTOOL_PRECOMP = $304C5458;
XTOOL_IODEC = $314C5458;
XTOOL_EXEC = $324C5458;
var
I: Integer;
begin
OpenDialog1.FileName := '';
if OpenDialog1.Execute then
begin
OpenDialog1.FileName := '';
if OpenDialog1.Execute then
Edit4.Text := OpenDialog1.FileName;
with TFileStream.Create(OpenDialog1.FileName, fmShareDenyNone) do
try
ReadBuffer(I, I.Size);
finally
Free;
end;
DecodeMode := IndexInt(I, [XTOOL_PRECOMP, XTOOL_IODEC]);
if DecodeMode < 0 then
raise Exception.Create('Unsupported input');
SpinBox13.Enabled := DecodeMode in [0];
GroupBox36.Enabled := DecodeMode in [1, 2];
Edit25.Text := OpenDialog1.FileName;
end;
end;
procedure TForm1.SearchEditButton24Click(Sender: TObject);
var
Dir: string;
begin
case ComboBox18.ItemIndex of
0:
begin
SaveDialog1.FileName := '';
if SaveDialog1.Execute then
Edit26.Text := SaveDialog1.FileName;
end;
1:
if SelectDirectory('', '', Dir) then
Edit26.Text := Dir;
end;
end;
procedure TForm1.SearchEditButton25Click(Sender: TObject);
var
Dir: string;
begin
case ComboBox17.ItemIndex of
0:
begin
OpenDialog1.FileName := '';
if OpenDialog1.Execute then
Edit27.Text := OpenDialog1.FileName;
end;
1:
if SelectDirectory('', '', Dir) then
Edit27.Text := Dir;
end;
end;
@ -283,7 +856,68 @@ var
Dir: string;
begin
if SelectDirectory('', '', Dir) then
begin
Edit6.Text := Dir;
Edit28.Text := Dir;
end;
end;
procedure TForm1.SearchEditButton6Click(Sender: TObject);
var
Dir: string;
begin
case ComboBox6.ItemIndex of
0:
begin
OpenDialog1.FileName := '';
if OpenDialog1.Execute then
Edit7.Text := OpenDialog1.FileName;
end;
1:
if SelectDirectory('', '', Dir) then
Edit7.Text := Dir;
end;
end;
procedure TForm1.SearchEditButton7Click(Sender: TObject);
var
Dir: string;
begin
case ComboBox7.ItemIndex of
0:
begin
OpenDialog1.FileName := '';
if OpenDialog1.Execute then
Edit8.Text := OpenDialog1.FileName;
end;
1:
if SelectDirectory('', '', Dir) then
Edit8.Text := Dir;
end;
end;
procedure TForm1.SearchEditButton8Click(Sender: TObject);
begin
SaveDialog1.FileName := '';
if SaveDialog1.Execute then
Edit9.Text := SaveDialog1.FileName;
end;
procedure TForm1.SearchEditButton9Click(Sender: TObject);
var
Dir: string;
begin
case ComboBox9.ItemIndex of
0:
begin
OpenDialog1.FileName := '';
if OpenDialog1.Execute then
Edit10.Text := OpenDialog1.FileName;
end;
1:
if SelectDirectory('', '', Dir) then
Edit10.Text := Dir;
end;
end;
end.

View File

@ -63,7 +63,7 @@ object Form2: TForm2
Size.Height = 242.000000000000000000
Size.PlatformDefault = False
Text = 'ZLib'
TabOrder = 5
TabOrder = 6
ContentSize = '217'
object Layout6: TLayout
Align = Top
@ -471,7 +471,7 @@ object Form2: TForm2
Size.Height = 134.000000000000000000
Size.PlatformDefault = False
Text = 'LZO'
TabOrder = 4
TabOrder = 5
ContentSize = '109'
object Layout13: TLayout
Align = Top
@ -582,7 +582,7 @@ object Form2: TForm2
Size.Height = 98.000000000000000000
Size.PlatformDefault = False
Text = 'ZSTD'
TabOrder = 3
TabOrder = 4
ContentSize = '73'
object Layout16: TLayout
Align = Top
@ -1106,6 +1106,7 @@ object Form2: TForm2
object RadioButton4: TRadioButton
Align = Left
GroupName = 'WAV'
IsChecked = True
Margins.Left = 30.000000000000000000
Margins.Top = 8.000000000000000000
Margins.Bottom = 8.000000000000000000
@ -1150,6 +1151,7 @@ object Form2: TForm2
object RadioButton1: TRadioButton
Align = Client
GroupName = 'JPG'
IsChecked = True
Margins.Left = 30.000000000000000000
Margins.Top = 8.000000000000000000
Margins.Right = 8.000000000000000000
@ -1200,7 +1202,42 @@ object Form2: TForm2
Size.Height = 20.000000000000000000
Size.PlatformDefault = False
TabOrder = 2
Text = 'JoJpeg (Experimental)'
Text = 'JoJpeg'
end
end
end
object Expander7: TExpander
Align = Top
Margins.Left = 8.000000000000000000
Margins.Top = 8.000000000000000000
Margins.Right = 8.000000000000000000
Position.X = 8.000000000000000000
Position.Y = 1504.000000000000000000
ShowCheck = False
Size.Width = 252.000000000000000000
Size.Height = 62.000000000000000000
Size.PlatformDefault = False
Text = 'DirectStorage'
TabOrder = 3
ContentSize = '37'
object Layout38: TLayout
Align = Top
Size.Width = 252.000000000000000000
Size.Height = 36.000000000000000000
Size.PlatformDefault = False
TabOrder = 32
object CheckBox22: TCheckBox
Align = Client
Margins.Left = 8.000000000000000000
Margins.Top = 8.000000000000000000
Margins.Right = 8.000000000000000000
Margins.Bottom = 8.000000000000000000
Size.Width = 236.000000000000000000
Size.Height = 20.000000000000000000
Size.PlatformDefault = False
TabOrder = 3
Text = 'GDeflate'
OnChange = CheckBox8Change
end
end
end

View File

@ -115,6 +115,9 @@ type
VertScrollBox3: TVertScrollBox;
Expander10: TExpander;
ListBox2: TListBox;
Expander7: TExpander;
Layout38: TLayout;
CheckBox22: TCheckBox;
procedure FormShow(Sender: TObject);
procedure CheckBox3Change(Sender: TObject);
procedure CheckBox1Change(Sender: TObject);
@ -310,6 +313,8 @@ begin
FLayout1[I].Parent := FExpander;
FLayout1[I].Height := 64;
FLayout1[I].Align := TAlignLayout.Top;
// FLayout1[I].Align := TAlignLayout.None;
FLayout1[I].Position.Y := I * FLayout1[I].Height;
Insert(TCheckBox.Create(FLayout1[I]), FCheckBox, Length(FCheckBox));
FCheckBox[I].Parent := FLayout1[I];
FCheckBox[I].Height := 20;
@ -406,6 +411,8 @@ begin
AddMethod('packjpg', Res, [], []);
if CheckBox26.IsChecked and RadioButton3.IsChecked then
AddMethod('jojpeg', Res, [], []);
if CheckBox22.IsChecked then
AddMethod('gdeflate', Res, [], []);
for I := 0 to ListBox2.Items.Count - 1 do
if ListBox2.ItemByIndex(I).IsChecked then
AddMethod(ListBox2.Items[I], Res, [], []);

View File

@ -1,3 +1,88 @@
ES_R54 (0.7.9)
- added recompress streams feature
- added reassign streams feature
- added dummy codec
- added data transfer buffer for srep when dd# is used
- added memory checks to ensure memory usage does not run wild
- exectuable plugins (via xtool.ini) are no longer required when decoding if they were never used
- internal stream deduplication now reports speed and memory usage benefits
- configuration based plugins can now have multiple names (if multiple games use the same configuration)
- fixed xtool crash if an incorect path for plugins was provided
- fixed lz4/lz4hc codec bug when used directly without any plugin
- fixed an issue where using fast-lzma2 compression would crash when decoding
- fixed an issue in DirectStorage gdeflate codec
- fixed an issue with execute command in stdio mode
- deduplication memory requirements improved
- memory optimisations
- reduced memory requirements for large streams that require patching
- removed ability to inject libraries to exe (buggy)
- removed patch command (uses too much memory)
- removed archive command (no one uses it)
- updated oodle scanner
- updated lz4/lz4hc universal scanner
- updated lz4/lz4hc/lz4f codecs
- updated zlib codec
- updated zstd codec
- replaced gpu caching feature with normal system memory cache (it doesn't work well on AMD gpus), use -p#
- replaced xdelta3 with zstd patching engine
- srep64 executable considered in x64 build of xtool
ES_R53 (0.7.8)
- fixed an issue where xtool would crash on Windows XP and other systems upon closure
- memory optimisations
- improvements with database "based" plugins
ES_R52 (0.7.7)
- added universal scanner for DirectStorage gdeflate streams
- added the use of gpu for caching and virtual memory purposes
- updated depthing feature to improve stream detection when used by plugins
ES_R51 (0.7.6)
- minor bug fixes
ES_R50 (0.7.5)
- added footer feature in configuration plugins
- added thread priority controller via -T# parameter
ES_R49 (0.7.4)
- user can specify srep parameters to use via -sp#
- updated zlib codec
ES_R48 (0.7.3)
- minor bug fixes
ES_R47 (0.7.2)
- memory usage optimizations
ES_R46 (0.7.1)
- fixed issues with fast-lzma2 being unable to set correct compression level
- updated deflate stream scanner
ES_R45 (0.7.0)
- added ability to redirect base directory for plugins and libraries
- added restrictions to avoid errors with experimental codecs
- added optimize option to speed up the decoding process for zstd and oodle codecs
- added dictionary parameter for fast-lzma2
- added memory caching when decoding to alleviate speed bottleneck
- fixed bug with download feature for inputs in URL format
- fixed issues with exporting precompression database
- fixed issues with executable plugin support
- fixed issues advanced configuration based plugin support
- fixed potential decoding issue upon using plugin support functions
- fixed issues with deduplication feature
- fixed issues with jojpeg codec
- replaced crc32c with xxh3_128 to reduce collisions when using the database and deduplication feature
- replaced memory manager with FastMM4-AVX to improve scaling in multi threaded scenarios
- improved user interface
- improved oodle codec performance for 2.6.0+ libraries
- improved encoding speed when using internal codecs
- improved processing speed when depth is used
- removed fast lzma2 multi threaded decompression due to excessive memory requirements
- removed debugging information when using the patch function
- removed ability to toggle database feature and ability to export database files (now enabled by default)
- updated deduplication virtual memory allocation
- updated reflate codec to verify streams prone to data corruption
ES_R44 (0.6.9)
- added library checker (trial and error)
- improved user interface

136
cls_xtool.dpr Normal file
View File

@ -0,0 +1,136 @@
library cls_xtool;
{$R *.res}
{$WEAKLINKRTTI ON}
{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
{$DEFINE UseFastMM}
uses
{$IFDEF UseFastMM}
FastMM4 in 'contrib\FastMM4-AVX\FastMM4.pas',
FastMM4Messages in 'contrib\FastMM4-AVX\FastMM4Messages.pas',
{$ENDIF }
WinAPI.Windows,
System.SysUtils,
System.StrUtils,
System.Classes,
System.Types,
System.Math,
System.IOUtils,
System.SyncObjs,
CLS in 'common\CLS.pas',
DStorage in 'common\DStorage.pas',
LibImport in 'common\LibImport.pas',
Threading in 'common\Threading.pas',
Utils in 'common\Utils.pas',
libc in 'contrib\LIBC\libc.pas',
lz4lib in 'contrib\LZ4Delphi\lz4lib.pas',
FuncHook in 'contrib\Delphi_MemoryModule\FuncHook.pas',
MemoryModule in 'contrib\Delphi_MemoryModule\MemoryModule.pas',
MemoryModuleHook in 'contrib\Delphi_MemoryModule\MemoryModuleHook.pas',
SynCommons in 'contrib\mORMot\SynCommons.pas',
SynCrypto in 'contrib\mORMot\SynCrypto.pas',
SynLZ in 'contrib\mORMot\SynLZ.pas',
SynTable in 'contrib\mORMot\SynTable.pas',
oObjects in 'contrib\ParseExpression\oObjects.pas',
ParseClass in 'contrib\ParseExpression\ParseClass.pas',
ParseExpr in 'contrib\ParseExpression\ParseExpr.pas',
XXHASHLIB in 'contrib\XXHASH4Delphi\XXHASHLIB.pas',
ZSTDLib in 'contrib\ZSTD4Delphi\ZSTDLib.pas',
InitCode in 'InitCode.pas',
BrunsliDLL in 'imports\BrunsliDLL.pas',
FLACDLL in 'imports\FLACDLL.pas',
FLZMA2DLL in 'imports\FLZMA2DLL.pas',
JoJpegDLL in 'imports\JoJpegDLL.pas',
LZ4DLL in 'imports\LZ4DLL.pas',
LZODLL in 'imports\LZODLL.pas',
OodleDLL in 'imports\OodleDLL.pas',
PackJPGDLL in 'imports\PackJPGDLL.pas',
PreflateDLL in 'imports\PreflateDLL.pas',
ReflateDLL in 'imports\ReflateDLL.pas',
ZLibDLL in 'imports\ZLibDLL.pas',
ZSTDDLL in 'imports\ZSTDDLL.pas',
lz4 in 'sources\lz4.pas',
PrecompMain in 'precompressor\PrecompMain.pas',
PrecompUtils in 'precompressor\PrecompUtils.pas',
PrecompCrypto in 'precompressor\PrecompCrypto.pas',
PrecompZLib in 'precompressor\PrecompZLib.pas',
PrecompLZ4 in 'precompressor\PrecompLZ4.pas',
PrecompLZO in 'precompressor\PrecompLZO.pas',
PrecompZSTD in 'precompressor\PrecompZSTD.pas',
PrecompMedia in 'precompressor\PrecompMedia.pas',
PrecompOodle in 'precompressor\PrecompOodle.pas',
PrecompINI in 'precompressor\PrecompINI.pas',
PrecompINIEx in 'precompressor\PrecompINIEx.pas',
PrecompSearch in 'precompressor\PrecompSearch.pas',
PrecompDLL in 'precompressor\PrecompDLL.pas',
PrecompEXE in 'precompressor\PrecompEXE.pas',
PrecompDStorage in 'precompressor\PrecompDStorage.pas';
{$SETPEFLAGS IMAGE_FILE_LARGE_ADDRESS_AWARE}
function ClsMain(operation: Integer; Callback: CLS_CALLBACK; Instance: Pointer)
: Integer cdecl;
const
BufferSize = 1048576;
var
CLS: TCLSStream;
PrecompEnc: PrecompMain.TEncodeOptions;
PrecompDec: PrecompMain.TDecodeOptions;
I: Integer;
Str: array [0 .. 255] of AnsiChar;
StrArray: TArray<String>;
begin
Result := CLS_ERROR_GENERAL;
case (operation) of
CLS_COMPRESS:
begin
CLS := TCLSStream.Create(Callback, Instance);
try
FillChar(Str, Length(Str), 0);
Callback(Instance, CLS_GET_PARAMSTR, @Str[0], Length(Str));
StrArray := DecodeStr(String(Str), ':');
for I := Low(StrArray) to High(StrArray) do
StrArray[I] := '-' + StrArray[I];
PrecompMain.Parse(StrArray, PrecompEnc);
try
PrecompMain.Encode(CLS, CLS, PrecompEnc);
Result := CLS_OK;
except
Result := CLS_ERROR_GENERAL;
end;
finally
CLS.Free;
end;
end;
CLS_DECOMPRESS:
begin
CLS := TCLSStream.Create(Callback, Instance);
try
CLS.ReadBuffer(I, I.Size);
case I of
XTOOL_PRECOMP:
begin
PrecompMain.Parse(['-t100p'], PrecompDec);
try
PrecompMain.Decode(CLS, CLS, PrecompDec);
Result := CLS_OK;
except
Result := CLS_ERROR_GENERAL;
end;
end;
end;
finally
CLS.Free;
end;
end;
else
Result := CLS_ERROR_NOT_IMPLEMENTED;
end;
end;
exports ClsMain;
begin
end.

1148
cls_xtool.dproj Normal file

File diff suppressed because it is too large Load Diff

BIN
cls_xtool.res Normal file

Binary file not shown.

102
common/CLS.pas Normal file
View File

@ -0,0 +1,102 @@
unit CLS;
interface
uses
System.SysUtils, System.Classes;
type
CLS_CALLBACK = function(Instance: Pointer; callback_operation: Integer;
ptr: Pointer; n: Integer): Integer; cdecl;
CLS_MAIN = function(operation: Integer; Callback: CLS_CALLBACK;
Instance: Pointer): Integer; cdecl;
const
CLS_INIT = 1;
CLS_DONE = 2;
CLS_FLUSH = 6;
CLS_COMPRESS = 3;
CLS_DECOMPRESS = 4;
CLS_PREPARE_METHOD = 5;
CLS_FULL_READ = 4096;
CLS_PARTIAL_READ = 5120;
CLS_FULL_WRITE = 6144;
CLS_PARTIAL_WRITE = 7168;
CLS_MALLOC = 1;
CLS_FREE = 2;
CLS_GET_PARAMSTR = 3;
CLS_SET_PARAMSTR = 4;
CLS_THREADS = 5;
CLS_MEMORY = 6;
CLS_DECOMPRESSION_MEMORY = 7;
CLS_DECOMPRESSOR_VERSION = 8;
CLS_BLOCK = 9;
CLS_EXPAND_DATA = 10;
CLS_ID = 101;
CLS_VERSION = 102;
CLS_THREAD_SAFE = 103;
CLS_OK = 0;
CLS_ERROR_GENERAL = -1;
CLS_ERROR_NOT_IMPLEMENTED = -2;
CLS_ERROR_NOT_ENOUGH_MEMORY = -3;
CLS_ERROR_READ = -4;
CLS_ERROR_WRITE = -5;
CLS_ERROR_ONLY_DECOMPRESS = -6;
CLS_ERROR_INVALID_COMPRESSOR = -7;
CLS_ERROR_BAD_COMPRESSED_DATA = -8;
CLS_ERROR_NO_MORE_DATA_REQUIRED = -9;
CLS_ERROR_OUTBLOCK_TOO_SMALL = -10;
CLS_PARAM_INT = -1;
CLS_PARAM_STRING = -2;
CLS_PARAM_MEMORY_MB = -3;
CLS_MAX_PARAMSTR_SIZE = 256;
CLS_MAX_ERROR_MSG = 256;
type
TCLSStream = class(TStream)
protected
FInstance: Pointer;
FCallback: CLS_CALLBACK;
FDone: Boolean;
public
constructor Create(Callback: CLS_CALLBACK; Instance: Pointer);
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
end;
implementation
constructor TCLSStream.Create(Callback: CLS_CALLBACK; Instance: Pointer);
begin
inherited Create;
FCallback := Callback;
FInstance := Instance;
FDone := False;
end;
function TCLSStream.Read(var Buffer; Count: Longint): Longint;
begin
Result := FCallback(FInstance, CLS_FULL_READ, @Buffer, Count);
end;
function TCLSStream.Write(const Buffer; Count: Longint): Longint;
begin
Result := FCallback(FInstance, CLS_PARTIAL_WRITE, @Buffer, Count);
if (Result = CLS_ERROR_NO_MORE_DATA_REQUIRED) and (FDone = False) then
begin
Result := Count;
FDone := True;
end
else if Result < 0 then
Result := 0;
end;
end.

1147
common/DStorage.pas Normal file

File diff suppressed because it is too large Load Diff

View File

@ -5,20 +5,31 @@ interface
uses
MemoryModule,
WinAPI.Windows,
System.SysUtils, System.Classes, System.Character;
System.SysUtils, System.Classes, System.Character, System.RTLConsts;
type
TLibImport = class
private
FIsMemoryLib: Boolean;
FDLLLoaded: Boolean;
FDLLStream: TResourceStream;
FImageFileName: String;
FDLLStream: TCustomMemoryStream;
FDLLHandle: NativeUInt;
FImagePtr: Pointer;
FImageSize: NativeInt;
public
constructor Create(ALibrary: String);
constructor Create;
destructor Destroy; override;
procedure LoadLib(ALibrary: String)overload;
procedure LoadLib(AMemory: Pointer; ASize: NativeInt)overload;
procedure LoadLib(AStream: TStream; ASize: NativeInt)overload;
procedure UnloadLib;
function GetProcAddr(AProcName: PAnsiChar): Pointer;
property Loaded: Boolean read FDLLLoaded;
property IsMemory: Boolean read FIsMemoryLib;
property ImageFileName: String read FImageFileName;
property ImagePtr: Pointer read FImagePtr;
property ImageSize: NativeInt read FImageSize;
end;
procedure InjectLib(Source, Dest: String);
@ -34,7 +45,7 @@ function FileToResourceName(FileName: String): String;
var
I: Integer;
begin
Result := ChangeFileExt(ExtractFileName(FileName), '').ToUpper;
Result := ExtractFileName(FileName).ToUpper;
for I := 1 to Result.Length do
if not Result[I].IsLetterOrDigit then
Result[I] := '_';
@ -77,38 +88,91 @@ begin
end;
end;
constructor TLibImport.Create(ALibrary: String);
var
LResName: String;
constructor TLibImport.Create;
begin
inherited Create;
FDLLLoaded := False;
FImageFileName := '';
FImagePtr := nil;
FImageSize := 0;
end;
destructor TLibImport.Destroy;
begin
UnloadLib;
inherited Destroy;
end;
procedure TLibImport.LoadLib(ALibrary: String);
var
LResName: String;
szFileName: array [0 .. MAX_PATH] of char;
begin
UnloadLib;
LResName := FileToResourceName(ALibrary);
FIsMemoryLib := ResourceExists(LResName);
if FIsMemoryLib then
begin
FDLLStream := TResourceStream.Create(HInstance, LResName, RT_RCDATA);
WriteLn(ErrOutput, FDLLStream.Size.ToString);
FDLLHandle := NativeUInt(MemoryLoadLibary(FDLLStream.Memory));
FDLLLoaded := Assigned(Pointer(FDLLHandle));
end
else
begin
FDLLStream := TMemoryStream.Create;
FDLLHandle := LoadLibrary(PWideChar(ALibrary));
FDLLLoaded := FDLLHandle >= 32;
if FDLLLoaded then
begin
FillChar(szFileName, sizeof(szFileName), #0);
GetModuleFileName(FDLLHandle, szFileName, MAX_PATH);
end;
end;
FImageFileName := ALibrary;
FImagePtr := FDLLStream.Memory;
FImageSize := FDLLStream.Size;
end;
destructor TLibImport.Destroy;
procedure TLibImport.LoadLib(AMemory: Pointer; ASize: NativeInt);
begin
UnloadLib;
FIsMemoryLib := True;
FDLLStream := TMemoryStream.Create;
FDLLStream.WriteBuffer(AMemory, ASize);
FDLLHandle := NativeUInt(MemoryLoadLibary(FDLLStream.Memory));
FDLLLoaded := Assigned(Pointer(FDLLHandle));
FImageFileName := '';
FImagePtr := FDLLStream.Memory;
FImageSize := FDLLStream.Size;
end;
procedure TLibImport.LoadLib(AStream: TStream; ASize: NativeInt);
begin
UnloadLib;
FIsMemoryLib := True;
FDLLStream := TMemoryStream.Create;
FDLLStream.CopyFrom(AStream, ASize);
FDLLHandle := NativeUInt(MemoryLoadLibary(FDLLStream.Memory));
FDLLLoaded := Assigned(Pointer(FDLLHandle));
FImageFileName := '';
FImagePtr := FDLLStream.Memory;
FImageSize := FDLLStream.Size;
end;
procedure TLibImport.UnloadLib;
begin
if FIsMemoryLib then
begin
if FDLLLoaded then
MemoryFreeLibrary(Pointer(FDLLHandle));
FDLLStream.Free;
MemoryFreeLibrary(Pointer(FDLLHandle));
end
else if FDLLLoaded then
FreeLibrary(FDLLHandle);
inherited Destroy;
if FDLLLoaded then
FDLLStream.Free;
FDLLLoaded := False;
FImagePtr := nil;
FImageSize := 0;
end;
function TLibImport.GetProcAddr(AProcName: PAnsiChar): Pointer;
@ -125,6 +189,8 @@ procedure InjectLib(Source, Dest: String);
var
LResName: String;
begin
if not FileExists(Source) then
raise Exception.CreateRes(@SSpecifiedFileNotFound);
LResName := FileToResourceName(Source);
UpdateFileResource(Source, Dest, LResName);
end;

File diff suppressed because it is too large Load Diff

58
contrib/FastMM4-AVX/.gitignore vendored Normal file
View File

@ -0,0 +1,58 @@
# Uncomment these types if you want even more clean repository. But be careful.
# It can make harm to an existing project source. Read explanations below.
#
# Resource files are binaries containing manifest, project icon and version info.
# They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files.
*.res
#
# Type library file (binary). In old Delphi versions it should be stored.
# Since Delphi 2009 it is produced from .ridl file and can safely be ignored.
#*.tlb
#
# Diagram Portfolio file. Used by the diagram editor up to Delphi 7.
# Uncomment this if you are not using diagrams or use newer Delphi version.
#*.ddp
#
# Visual LiveBindings file. Added in Delphi XE2.
# Uncomment this if you are not using LiveBindings Designer.
#*.vlb
#
# Deployment Manager configuration file for your project. Added in Delphi XE2.
# Uncomment this if it is not mobile development and you do not use remote debug feature.
#*.deployproj
#
# Delphi compiler-generated binaries (safe to delete)
*.exe
*.dll
*.bpl
*.bpi
*.dcp
*.so
*.apk
*.drc
*.map
*.dres
*.rsm
*.tds
*.dcu
*.lib
# Delphi autogenerated files (duplicated info)
*.cfg
*Resource.rc
# Delphi local files (user-specific info)
*.local
*.identcache
*.projdata
*.tvsconfig
*.dsk
# Delphi history and backups
__history/
*.~*
*.bak
# Castalia statistics file
*.stat

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
nasm.exe -Ox -Ov -f win64 FastMM4_AVX512.asm

View File

@ -0,0 +1,47 @@
object fAppMain: TfAppMain
Left = 0
Top = 0
Caption = 'FastMM Sharing Test Application'
ClientHeight = 208
ClientWidth = 300
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
Position = poScreenCenter
PixelsPerInch = 96
TextHeight = 13
object Button1: TButton
Left = 8
Top = 172
Width = 281
Height = 25
Caption = 'Load DLL and Display DLL Form'
TabOrder = 0
OnClick = Button1Click
end
object Memo1: TMemo
Left = 8
Top = 8
Width = 281
Height = 157
Enabled = False
Lines.Strings = (
'This application shows how to share FastMM between '
'an application and dynamically loaded DLL, without '
'using the borlndmm.dll library.'
''
'Click the button to load the test DLL and display its '
'form.'
''
'The relevant settings for this application:'
'1) FastMM4.pas is the first unit in the uses clause '
'2) The "ShareMM" option is enabled'
'3) "Use Runtime Packages" is disabled'
'')
TabOrder = 1
end
end

View File

@ -0,0 +1,51 @@
unit ApplicationForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TfAppMain = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
fAppMain: TfAppMain;
implementation
{$R *.dfm}
procedure TfAppMain.Button1Click(Sender: TObject);
var
LDLLHandle: HModule;
LShowProc: TProcedure;
begin
LDLLHandle := LoadLibrary('TestDLL.dll');
if LDLLHandle <> 0 then
begin
try
LShowProc := GetProcAddress(LDLLHandle, 'ShowDLLForm');
if Assigned(LShowProc) then
begin
LShowProc;
end
else
ShowMessage('The ShowDLLForm procedure could not be found in the DLL.');
finally
FreeLibrary(LDLLHandle);
end;
end
else
ShowMessage('The DLL was not found. Please compile the DLL before running this application.');
end;
end.

View File

@ -0,0 +1,54 @@
object fDLLMain: TfDLLMain
Left = 0
Top = 0
Caption = 'FastMM Sharing DLL Form'
ClientHeight = 185
ClientWidth = 337
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Button1: TButton
Left = 8
Top = 152
Width = 165
Height = 25
Caption = 'Click to leak some memory'
TabOrder = 0
OnClick = Button1Click
end
object Memo1: TMemo
Left = 8
Top = 8
Width = 317
Height = 137
Enabled = False
Lines.Strings = (
'This DLL is sharing the memory manager of the main '
'application. '
''
'The following settings were used to achieve this:'
'1) FastMM4.pas is the first unit in the "uses" clause of the .dp' +
'r'
'2) The "ShareMM" option is enabled.'
'3) The "AttemptToUseSharedMM" option is enabled.'
''
'Click the button to leak some memory.')
TabOrder = 1
end
object Button2: TButton
Left = 180
Top = 152
Width = 145
Height = 25
Caption = 'Unload DLL'
TabOrder = 2
OnClick = Button2Click
end
end

View File

@ -0,0 +1,39 @@
unit DLLForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TfDLLMain = class(TForm)
Button1: TButton;
Memo1: TMemo;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
fDLLMain: TfDLLMain;
implementation
{$R *.dfm}
procedure TfDLLMain.Button1Click(Sender: TObject);
begin
TObject.Create;
end;
procedure TfDLLMain.Button2Click(Sender: TObject);
begin
Close;
end;
end.

View File

@ -0,0 +1,44 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{39e9f19f-728b-49d7-8ea1-18ef0776485d}</ProjectGuid>
</PropertyGroup>
<ItemGroup />
<ItemGroup>
<Projects Include="TestApplication.dproj" />
<Projects Include="TestDLL.dproj" />
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Default.Personality</Borland.Personality>
<Borland.ProjectType />
<BorlandProject>
<BorlandProject xmlns=""> <Default.Personality> </Default.Personality> </BorlandProject></BorlandProject>
</ProjectExtensions>
<Target Name="TestApplication">
<MSBuild Projects="TestApplication.dproj" Targets="" />
</Target>
<Target Name="TestApplication:Clean">
<MSBuild Projects="TestApplication.dproj" Targets="Clean" />
</Target>
<Target Name="TestApplication:Make">
<MSBuild Projects="TestApplication.dproj" Targets="Make" />
</Target>
<Target Name="TestDLL">
<MSBuild Projects="TestDLL.dproj" Targets="" />
</Target>
<Target Name="TestDLL:Clean">
<MSBuild Projects="TestDLL.dproj" Targets="Clean" />
</Target>
<Target Name="TestDLL:Make">
<MSBuild Projects="TestDLL.dproj" Targets="Make" />
</Target>
<Target Name="Build">
<CallTarget Targets="TestApplication;TestDLL" />
</Target>
<Target Name="Clean">
<CallTarget Targets="TestApplication:Clean;TestDLL:Clean" />
</Target>
<Target Name="Make">
<CallTarget Targets="TestApplication:Make;TestDLL:Make" />
</Target>
<Import Condition="Exists('$(MSBuildBinPath)\Borland.Group.Targets')" Project="$(MSBuildBinPath)\Borland.Group.Targets" />
</Project>

View File

@ -0,0 +1,14 @@
program TestApplication;
uses
FastMM4,
Forms,
ApplicationForm in 'ApplicationForm.pas' {fAppMain};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TfAppMain, fAppMain);
Application.Run;
end.

View File

@ -0,0 +1,71 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{ddb60ef2-54ec-4031-ade8-28222d2e51e3}</ProjectGuid>
<MainSource>TestApplication.dpr</MainSource>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
<DCC_DependencyCheckOutputName>TestApplication.exe</DCC_DependencyCheckOutputName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Version>7.0</Version>
<DCC_DebugInformation>False</DCC_DebugInformation>
<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>ShareMM;RELEASE</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<Version>7.0</Version>
<DCC_Define>ShareMM;DEBUG</DCC_Define>
</PropertyGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality</Borland.Personality>
<Borland.ProjectType />
<BorlandProject>
<BorlandProject xmlns=""> <Delphi.Personality> <Parameters>
<Parameters Name="UseLauncher">False</Parameters>
<Parameters Name="LoadAllSymbols">True</Parameters>
<Parameters Name="LoadUnspecifiedSymbols">False</Parameters>
</Parameters>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">7177</VersionInfo>
<VersionInfo Name="CodePage">1252</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"></VersionInfoKeys>
<VersionInfoKeys Name="FileDescription"></VersionInfoKeys>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"></VersionInfoKeys>
<VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys>
<VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys>
<VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys>
<VersionInfoKeys Name="ProductName"></VersionInfoKeys>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"></VersionInfoKeys>
</VersionInfoKeys>
<Source>
<Source Name="MainSource">TestApplication.dpr</Source>
</Source>
</Delphi.Personality> </BorlandProject></BorlandProject>
</ProjectExtensions>
<Import Project="$(MSBuildBinPath)\Borland.Delphi.Targets" />
<ItemGroup>
<DelphiCompile Include="TestApplication.dpr">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="ApplicationForm.pas">
<Form>fAppMain</Form>
</DCCReference>
</ItemGroup>
</Project>

View File

@ -0,0 +1,26 @@
library TestDLL;
uses
FastMM4,
SysUtils,
Classes,
DLLForm in 'DLLForm.pas' {fDLLMain};
{$R *.res}
procedure ShowDLLForm;
begin
with TfDLLMain.Create(nil) do
begin
try
ShowModal;
finally
Free;
end;
end;
end;
exports ShowDllForm;
begin
end.

View File

@ -0,0 +1,71 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{dc5ee909-443c-42e3-aed6-5b0de135122e}</ProjectGuid>
<MainSource>TestDLL.dpr</MainSource>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
<DCC_DependencyCheckOutputName>TestDLL.dll</DCC_DependencyCheckOutputName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Version>7.0</Version>
<DCC_DebugInformation>False</DCC_DebugInformation>
<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>ShareMM;AttemptToUseSharedMM;RELEASE</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<Version>7.0</Version>
<DCC_Define>ShareMM;AttemptToUseSharedMM;DEBUG</DCC_Define>
</PropertyGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality</Borland.Personality>
<Borland.ProjectType />
<BorlandProject>
<BorlandProject xmlns=""> <Delphi.Personality> <Parameters>
<Parameters Name="UseLauncher">False</Parameters>
<Parameters Name="LoadAllSymbols">True</Parameters>
<Parameters Name="LoadUnspecifiedSymbols">False</Parameters>
</Parameters>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">7177</VersionInfo>
<VersionInfo Name="CodePage">1252</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"></VersionInfoKeys>
<VersionInfoKeys Name="FileDescription"></VersionInfoKeys>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"></VersionInfoKeys>
<VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys>
<VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys>
<VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys>
<VersionInfoKeys Name="ProductName"></VersionInfoKeys>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"></VersionInfoKeys>
</VersionInfoKeys>
<Source>
<Source Name="MainSource">TestDLL.dpr</Source>
</Source>
</Delphi.Personality> </BorlandProject></BorlandProject>
</ProjectExtensions>
<Import Project="$(MSBuildBinPath)\Borland.Delphi.Targets" />
<ItemGroup>
<DelphiCompile Include="TestDLL.dpr">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="DLLForm.pas">
<Form>fDLLMain</Form>
</DCCReference>
</ItemGroup>
</Project>

View File

@ -0,0 +1,44 @@
object Form1: TForm1
Left = 0
Top = 0
Caption = 'borlndmm.dll using FullDebugMode'
ClientHeight = 146
ClientWidth = 369
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
Position = poScreenCenter
PixelsPerInch = 96
TextHeight = 13
object Button1: TButton
Left = 24
Top = 24
Width = 321
Height = 25
Caption = 'Click this button to leak a TObject'
TabOrder = 0
OnClick = Button1Click
end
object Button2: TButton
Left = 24
Top = 60
Width = 321
Height = 25
Caption = 'Click this button to test the allocation grouping functionality'
TabOrder = 1
OnClick = Button2Click
end
object Button3: TButton
Left = 24
Top = 96
Width = 321
Height = 25
Caption = 'Cause a "virtual method on freed object" error'
TabOrder = 2
OnClick = Button3Click
end
end

View File

@ -0,0 +1,76 @@
unit DemoForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, FastMMDebugSupport, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button3Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
TObject.Create;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
x, y, z: TObject;
begin
{Set the allocation group to 1}
PushAllocationGroup(1);
{Allocate an object}
x := TPersistent.Create;
{Set the allocation group to 2}
PushAllocationGroup(2);
{Allocate a TControl}
y := TControl.Create(nil);
{Go back to allocation group 1}
PopAllocationGroup;
{Allocate a TWinControl}
z := TWinControl.Create(nil);
{Pop the last group off the stack}
PopAllocationGroup;
{Specify the name of the log file}
SetMMLogFileName('AllocationGroupTest.log');
{Log all live blocks in groups 1 and 2}
LogAllocatedBlocksToFile(1, 2);
{Restore the default log file name}
SetMMLogFileName(nil);
{Free all the objects}
x.Free;
y.Free;
z.Free;
{Done}
ShowMessage('Allocation detail logged to file.');
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
with TObject.Create do
begin
Free;
Free;
end;
end;
end.

View File

@ -0,0 +1,15 @@
program FullDebugModeDemo;
uses
ShareMem,
Forms,
DemoForm in 'DemoForm.pas' {Form1},
FastMMDebugSupport in '..\..\Replacement BorlndMM DLL\Delphi\FastMMDebugSupport.pas';
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

View File

@ -0,0 +1,28 @@
object fDemo: TfDemo
Left = 199
Top = 114
BorderIcons = [biSystemMenu]
BorderStyle = bsSingle
Caption = 'Usage Tracker Demo'
ClientHeight = 53
ClientWidth = 239
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
Position = poScreenCenter
PixelsPerInch = 96
TextHeight = 13
object bShowTracker: TButton
Left = 8
Top = 8
Width = 221
Height = 37
Caption = 'Show Usage Tracker'
TabOrder = 0
OnClick = bShowTrackerClick
end
end

View File

@ -0,0 +1,31 @@
unit DemoForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, FastMMUsageTracker;
type
TfDemo = class(TForm)
bShowTracker: TButton;
procedure bShowTrackerClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
fDemo: TfDemo;
implementation
{$R *.dfm}
procedure TfDemo.bShowTrackerClick(Sender: TObject);
begin
ShowFastMMUsageTracker;
end;
end.

View File

@ -0,0 +1,264 @@
object fFastMMUsageTracker: TfFastMMUsageTracker
Left = 460
Top = 178
BorderIcons = [biSystemMenu]
BorderStyle = bsSingle
Caption = 'FastMM Memory Usage Tracker'
ClientHeight = 556
ClientWidth = 553
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
Position = poScreenCenter
OnClose = FormClose
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object bClose: TBitBtn
Left = 472
Top = 524
Width = 75
Height = 25
Caption = 'Close'
TabOrder = 0
OnClick = bCloseClick
Glyph.Data = {
76010000424D7601000000000000760000002800000020000000100000000100
04000000000000010000130B0000130B00001000000000000000000000000000
800000800000008080008000000080008000808000007F7F7F00BFBFBF000000
FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00333333333333
3333333333FFFFF3333333333999993333333333F77777FFF333333999999999
3333333777333777FF3333993333339993333377FF3333377FF3399993333339
993337777FF3333377F3393999333333993337F777FF333337FF993399933333
399377F3777FF333377F993339993333399377F33777FF33377F993333999333
399377F333777FF3377F993333399933399377F3333777FF377F993333339993
399377FF3333777FF7733993333339993933373FF3333777F7F3399933333399
99333773FF3333777733339993333339933333773FFFFFF77333333999999999
3333333777333777333333333999993333333333377777333333}
NumGlyphs = 2
end
object bUpdate: TBitBtn
Left = 392
Top = 524
Width = 75
Height = 25
Caption = 'Update'
TabOrder = 1
OnClick = bUpdateClick
Glyph.Data = {
76010000424D7601000000000000760000002800000020000000100000000100
04000000000000010000120B0000120B00001000000000000000000000000000
800000800000008080008000000080008000808000007F7F7F00BFBFBF000000
FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00370777033333
3330337F3F7F33333F3787070003333707303F737773333373F7007703333330
700077337F3333373777887007333337007733F773F333337733700070333333
077037773733333F7F37703707333300080737F373333377737F003333333307
78087733FFF3337FFF7F33300033330008073F3777F33F777F73073070370733
078073F7F7FF73F37FF7700070007037007837773777F73377FF007777700730
70007733FFF77F37377707700077033707307F37773F7FFF7337080777070003
3330737F3F7F777F333778080707770333333F7F737F3F7F3333080787070003
33337F73FF737773333307800077033333337337773373333333}
NumGlyphs = 2
end
object ChkAutoUpdate: TCheckBox
Left = 280
Top = 528
Width = 97
Height = 17
Caption = 'Auto Update'
TabOrder = 2
OnClick = ChkAutoUpdateClick
end
object pcUsageTracker: TPageControl
Left = 0
Top = 0
Width = 553
Height = 521
ActivePage = tsAllocation
Align = alTop
TabOrder = 3
object tsAllocation: TTabSheet
Caption = 'FastMM4 Allocation'
object sgBlockStatistics: TStringGrid
Left = 4
Top = 4
Width = 533
Height = 481
DefaultColWidth = 83
DefaultRowHeight = 17
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine]
PopupMenu = smMM4Allocation
ScrollBars = ssVertical
TabOrder = 0
OnDrawCell = sgBlockStatisticsDrawCell
ColWidths = (
83
104
106
106
108)
end
end
object tsVMGraph: TTabSheet
Caption = 'VM Graph'
ImageIndex = 1
object Label1: TLabel
Left = 8
Top = 440
Width = 38
Height = 13
Caption = 'Address'
end
object Label2: TLabel
Left = 152
Top = 440
Width = 25
Height = 13
Caption = 'State'
end
object Label3: TLabel
Left = 8
Top = 468
Width = 43
Height = 13
Caption = 'Exe/DLL'
end
object eAddress: TEdit
Left = 60
Top = 436
Width = 81
Height = 21
Enabled = False
TabOrder = 0
Text = '$00000000'
end
object eState: TEdit
Left = 184
Top = 436
Width = 105
Height = 21
Enabled = False
TabOrder = 1
Text = 'Unallocated'
end
object eDLLName: TEdit
Left = 60
Top = 464
Width = 477
Height = 21
ReadOnly = True
TabOrder = 2
end
object ChkSmallGraph: TCheckBox
Left = 304
Top = 436
Width = 97
Height = 21
Caption = 'Small Map'
Checked = True
State = cbChecked
TabOrder = 3
OnClick = ChkSmallGraphClick
end
object dgMemoryMap: TDrawGrid
Left = 4
Top = 4
Width = 533
Height = 425
ColCount = 64
DefaultColWidth = 8
DefaultRowHeight = 8
FixedCols = 0
RowCount = 1024
FixedRows = 0
GridLineWidth = 0
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine]
ScrollBars = ssVertical
TabOrder = 4
OnDrawCell = dgMemoryMapDrawCell
OnSelectCell = dgMemoryMapSelectCell
end
end
object tsVMDump: TTabSheet
Caption = 'VM Dump'
ImageIndex = 2
object sgVMDump: TStringGrid
Left = 4
Top = 4
Width = 533
Height = 481
DefaultColWidth = 83
DefaultRowHeight = 17
FixedCols = 0
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine]
PopupMenu = smVMDump
ScrollBars = ssVertical
TabOrder = 0
OnDrawCell = sgVMDumpDrawCell
OnMouseDown = sgVMDumpMouseDown
OnMouseUp = sgVMDumpMouseUp
ColWidths = (
83
96
60
58
209)
end
end
object tsGeneralInformation: TTabSheet
Caption = 'General Information'
ImageIndex = 3
object mVMStatistics: TMemo
Left = 4
Top = 4
Width = 533
Height = 481
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Courier New'
Font.Style = []
ParentFont = False
PopupMenu = smGeneralInformation
ReadOnly = True
ScrollBars = ssVertical
TabOrder = 0
end
end
end
object tTimer: TTimer
Enabled = False
Interval = 2000
OnTimer = tTimerTimer
Left = 128
Top = 512
end
object smVMDump: TPopupMenu
Left = 100
Top = 512
object miVMDumpCopyAlltoClipboard: TMenuItem
Caption = '&Copy All to Clipboard'
OnClick = miVMDumpCopyAlltoClipboardClick
end
end
object smGeneralInformation: TPopupMenu
Left = 68
Top = 512
object miGeneralInformationCopyAlltoClipboard: TMenuItem
Caption = '&Copy All to Clipboard'
OnClick = miGeneralInformationCopyAlltoClipboardClick
end
end
object smMM4Allocation: TPopupMenu
Left = 36
Top = 512
object siMM4AllocationCopyAlltoClipboard: TMenuItem
Caption = '&Copy All to Clipboard'
OnClick = siMM4AllocationCopyAlltoClipboardClick
end
end
end

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
program UsageTrackerDemo;
uses
FastMM4,
Forms,
DemoForm in 'DemoForm.pas' {fDemo};
{$R *.res}
{Enable large address space support for this demo}
{$SetPEFlags $20}
begin
Application.Initialize;
Application.CreateForm(TfDemo, fDemo);
Application.Run;
end.

View File

@ -0,0 +1,69 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{2d29cca4-0633-47dd-b826-c21a24d53d83}</ProjectGuid>
<MainSource>UsageTrackerDemo.dpr</MainSource>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
<DCC_DependencyCheckOutputName>UsageTrackerDemo.exe</DCC_DependencyCheckOutputName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Version>7.0</Version>
<DCC_DebugInformation>False</DCC_DebugInformation>
<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE</DCC_Define>
<DCC_UnitSearchPath>..\..</DCC_UnitSearchPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<Version>7.0</Version>
<DCC_Define>DEBUG</DCC_Define>
<DCC_UnitSearchPath>..\..</DCC_UnitSearchPath>
</PropertyGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality</Borland.Personality>
<Borland.ProjectType>VCLApplication</Borland.ProjectType>
<BorlandProject>
<BorlandProject><Delphi.Personality><Parameters><Parameters Name="UseLauncher">False</Parameters><Parameters Name="LoadAllSymbols">True</Parameters><Parameters Name="LoadUnspecifiedSymbols">False</Parameters></Parameters><VersionInfo><VersionInfo Name="IncludeVerInfo">False</VersionInfo><VersionInfo Name="AutoIncBuild">False</VersionInfo><VersionInfo Name="MajorVer">1</VersionInfo><VersionInfo Name="MinorVer">0</VersionInfo><VersionInfo Name="Release">0</VersionInfo><VersionInfo Name="Build">0</VersionInfo><VersionInfo Name="Debug">False</VersionInfo><VersionInfo Name="PreRelease">False</VersionInfo><VersionInfo Name="Special">False</VersionInfo><VersionInfo Name="Private">False</VersionInfo><VersionInfo Name="DLL">False</VersionInfo><VersionInfo Name="Locale">7177</VersionInfo><VersionInfo Name="CodePage">1252</VersionInfo></VersionInfo><VersionInfoKeys><VersionInfoKeys Name="CompanyName"></VersionInfoKeys><VersionInfoKeys Name="FileDescription"></VersionInfoKeys><VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="InternalName"></VersionInfoKeys><VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys><VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys><VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys><VersionInfoKeys Name="ProductName"></VersionInfoKeys><VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="Comments"></VersionInfoKeys></VersionInfoKeys><Excluded_Packages>
<Excluded_Packages Name="$(BDS)\bin\dclofficexp100.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDS)\bin\dcloffice2k100.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages><Source><Source Name="MainSource">UsageTrackerDemo.dpr</Source></Source></Delphi.Personality></BorlandProject></BorlandProject>
</ProjectExtensions>
<Import Project="$(MSBuildBinPath)\Borland.Delphi.Targets" />
<ItemGroup>
<DelphiCompile Include="UsageTrackerDemo.dpr">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="DemoForm.pas">
<Form>fDemo</Form>
</DCCReference>
</ItemGroup>
</Project>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,404 @@
unit FastMM4DataCollector;
{$I FastMM4Options.inc}
interface
type
TStaticCollector = record
strict private const
CDefaultPromoteGen1_sec = 1; // promote every second
CDefaultPromoteGen1Count = 1; // promote allocations with Count > 1
CGeneration1Size = 1024;
CGeneration2Size = 256;
CCollectedDataSize = CGeneration2Size;
CMaxPointers = 11; // same as in FastMM4
public type
TPointers = record
Pointers: array [1..CMaxPointers] of Pointer;
Count : integer;
class operator Equal(const a, b: TPointers): boolean;
end;
TDataInfo = record
Data : TPointers;
Count: integer;
end;
TCollectedData = array [1..CCollectedDataSize] of TDataInfo;
TGenerationOverflowCount = record
Generation1: integer;
Generation2: integer;
end;
strict private type
PDataInfo = ^TDataInfo;
TGenerationPlaceholder = array [1..1] of TDataInfo;
PGenerationPlaceholder = ^TGenerationPlaceholder;
TGenerationInfo = record
Data : PGenerationPlaceholder;
Size : integer;
Last : integer;
NextGeneration : integer;
PromoteEvery_sec: integer;
PromoteCountOver: integer;
OverflowCount : integer;
LastCheck_ms : int64;
end;
var
FGeneration1 : array [1..CGeneration1Size] of TDataInfo;
FGeneration2 : array [1..CGeneration2Size] of TDataInfo;
FGenerationInfo: array [0..2] of TGenerationInfo; //gen0 is used for merging
FLocked : ByteBool;
FPadding : array [1..3] of byte;
function GetGen1_PromoteCountOver: integer;
function GetGen1_PromoteEvery_sec: integer;
function GetOverflowCount: TGenerationOverflowCount;
procedure Lock;
function Now_ms: int64; inline;
procedure SetGen1_PromoteCountOver(const value: integer);
procedure SetGen1_PromoteEvery_sec(const value: integer);
private
procedure AddToGeneration(generation: integer; const aData: TPointers;
count: integer = 1);
procedure CheckPromoteGeneration(generation: integer); inline;
function FindInGeneration(generation: integer; const aData: TPointers): integer; inline;
function FindInsertionPoint(generation, count: integer): integer; inline;
procedure FlushAllGenerations;
function InsertIntoGeneration(generation: integer; const dataInfo: TDataInfo): boolean;
procedure PromoteGeneration(oldGen, newGen: integer);
procedure ResortGeneration(generation, idxData: integer);
public
procedure Initialize;
procedure Add(const pointers: pointer; count: integer);
procedure GetData(var data: TCollectedData; var count: integer);
procedure Merge(var mergedData: TCollectedData; var mergedCount: integer;
const newData: TCollectedData; newCount: integer);
property Gen1_PromoteCountOver: integer read GetGen1_PromoteCountOver
write SetGen1_PromoteCountOver;
property OverflowCount: TGenerationOverflowCount read GetOverflowCount;
property Gen1_PromoteEvery_sec: integer read GetGen1_PromoteEvery_sec write
SetGen1_PromoteEvery_sec;
end;
PStaticCollector = ^TStaticCollector;
implementation
uses
Winapi.Windows; //used in Now_ms
{$RANGECHECKS OFF}
type
PByteBool = ^ByteBool;
// Copied from FastMM4.pas
function LockCmpxchg8(CompareVal, NewVal: ByteBool; AAddress: PByteBool): ByteBool;
asm
{$if SizeOf(Pointer) = 4}
{On entry:
al = CompareVal,
dl = NewVal,
ecx = AAddress}
{$ifndef LINUX}
lock cmpxchg [ecx], dl
{$else}
{Workaround for Kylix compiler bug}
db $F0, $0F, $B0, $11
{$endif}
{$else}
{On entry:
cl = CompareVal
dl = NewVal
r8 = AAddress}
.noframe
mov rax, rcx
lock cmpxchg [r8], dl
{$ifend}
end;
{ TStaticCollector.TPointers }
class operator TStaticCollector.TPointers.Equal(const a, b: TPointers): boolean;
var
i: integer;
begin
Result := a.Count = b.Count;
if Result then
for i := 1 to a.Count do
if a.Pointers[i] <> b.Pointers[i] then
Exit(false);
end;
{ TStaticCollector }
procedure TStaticCollector.Add(const pointers: pointer; count: integer);
var
ptrData: TPointers;
begin
Lock;
ptrData.Count := CMaxPointers;
if count < CMaxPointers then
ptrData.Count := count;
Move(pointers^, ptrData.Pointers[1], ptrData.Count * SizeOf(pointer));
AddToGeneration(1, ptrData);
FLocked := false;
end;
procedure TStaticCollector.AddToGeneration(generation: integer; const aData: TPointers;
count: integer = 1);
var
dataInfo: TDataInfo;
idxData : integer;
begin
CheckPromoteGeneration(generation);
with FGenerationInfo[generation] do begin
idxData := FindInGeneration(generation, aData);
if idxData >= 1 then begin
Data^[idxData].Count := Data^[idxData].Count + count;
ResortGeneration(generation, idxData);
end
else begin
dataInfo.Data := aData;
dataInfo.Count := count;
InsertIntoGeneration(generation, dataInfo);
end;
end;
end; { TStaticCollector.AddToGeneration }
procedure TStaticCollector.CheckPromoteGeneration(generation: integer);
begin
with FGenerationInfo[generation] do begin
if NextGeneration > 0 then begin
if LastCheck_ms = 0 then
LastCheck_ms := Now_ms
else if ((Now_ms - LastCheck_ms) div 1000) >= PromoteEvery_sec then begin
PromoteGeneration(generation, NextGeneration);
LastCheck_ms := Now_ms;
end;
end;
end;
end;
function TStaticCollector.FindInGeneration(generation: integer; const aData: TPointers):
integer;
begin
with FGenerationInfo[generation] do begin
for Result := 1 to Last do
if Data^[Result].Data = aData then
Exit;
end;
Result := 0;
end;
function TStaticCollector.FindInsertionPoint(generation, count: integer): integer;
var
insert: integer;
begin
with FGenerationInfo[generation] do begin
for insert := Last downto 1 do begin
if Data^[insert].Count > count then
Exit(insert+1);
end;
Result := 1;
end;
end;
procedure TStaticCollector.FlushAllGenerations;
var
generation: integer;
nextGen : integer;
begin
generation := 1;
while generation <> 0 do begin
nextGen := FGenerationInfo[generation].NextGeneration;
if nextGen > 0 then
PromoteGeneration(generation, nextGen);
generation := nextGen;
end;
end;
procedure TStaticCollector.GetData(var data: TCollectedData; var count: integer);
begin
Lock;
FlushAllGenerations;
Assert(Length(data) = Length(FGeneration2));
count := FGenerationInfo[2].Last;
Move(FGeneration2[1], data[1], count * SizeOf(data[1]));
FLocked := false;
end;
function TStaticCollector.GetGen1_PromoteCountOver: integer;
begin
Result := FGenerationInfo[1].PromoteCountOver;
end;
function TStaticCollector.GetGen1_PromoteEvery_sec: integer;
begin
Result := FGenerationInfo[1].PromoteEvery_sec;
end;
function TStaticCollector.GetOverflowCount: TGenerationOverflowCount;
begin
Result.Generation1 := FGenerationInfo[1].OverflowCount;
Result.Generation2 := FGenerationInfo[2].OverflowCount;
end;
procedure TStaticCollector.Initialize;
begin
Assert(SizeOf(TStaticCollector) mod SizeOf(pointer) = 0);
with FGenerationInfo[1] do begin
Data := PGenerationPlaceholder(@FGeneration1);
Size := CGeneration1Size;
Last := 0;
NextGeneration := 2;
PromoteEvery_sec := CDefaultPromoteGen1_sec;
PromoteCountOver := CDefaultPromoteGen1Count;
LastCheck_ms := 0;
end;
with FGenerationInfo[2] do begin
Data := PGenerationPlaceholder(@FGeneration2);
Size := CGeneration2Size;
NextGeneration := 0;
end;
end;
function TStaticCollector.InsertIntoGeneration(generation: integer; const dataInfo:
TDataInfo): boolean;
var
idx: integer;
begin
// We already know that this element does not exist in the generation.
Result := true;
with FGenerationInfo[generation] do begin
idx := FindInsertionPoint(generation, dataInfo.Count);
if idx > Last then begin
if Last = Size then begin
Inc(OverflowCount);
Result := false;
end
else begin
Inc(Last);
Data^[Last] := dataInfo;
end;
end
else begin
if Last < Size then begin
Move(Data^[idx], Data^[idx+1], (Last-idx+1) * SizeOf(Data^[idx]));
Inc(Last);
end
else begin
if Last > idx then
Move(Data^[idx], Data^[idx+1], (Last-idx) * SizeOf(Data^[idx]));
Inc(OverflowCount);
end;
Data^[idx] := dataInfo;
end;
end;
end;
procedure TStaticCollector.Lock;
begin
{$ifndef AssumeMultiThreaded}
if IsMultiThread then
{$endif}
begin
while LockCmpxchg8(False, True, @FLocked) <> False do
begin
{$ifdef NeverSleepOnThreadContention}
{$ifdef UseSwitchToThread}
SwitchToThread;
{$endif}
{$else}
Sleep(0);
if LockCmpxchg8(False, True, @FLocked) = False then
Break;
Sleep(1);
{$endif}
end;
end;
end;
procedure TStaticCollector.Merge(var mergedData: TCollectedData;
var mergedCount: integer; const newData: TCollectedData; newCount: integer);
var
iNew: integer;
begin
// Merges two sorted arrays.
FGenerationInfo[0].Data := PGenerationPlaceholder(@mergedData);
FGenerationInfo[0].Last := mergedCount;
FGenerationInfo[0].Size := CCollectedDataSize;
FGenerationInfo[0].NextGeneration := 0;
for iNew := 1 to newCount do
AddToGeneration(0, newData[iNew].Data, newData[iNew].Count);
mergedCount := FGenerationInfo[0].Last;
end;
function TStaticCollector.Now_ms: int64;
var
st: TSystemTime;
begin
// We cannot use SysUtils as that gets memory allocator called before FastMM is initialized.
GetSystemTime(st);
SystemTimeToFileTime(st, TFileTime(Result));
Result := Result div 10000;
end;
procedure TStaticCollector.PromoteGeneration(oldGen, newGen: integer);
var
canInsert : boolean;
idxNew : integer;
idxOld : integer;
newGenData: PGenerationPlaceholder;
pOldData : PDataInfo;
begin
canInsert := true;
newGenData := FGenerationInfo[newGen].Data;
with FGenerationInfo[oldGen] do begin
for idxOld := 1 to Last do begin
pOldData := @Data^[idxOld];
if pOldData^.Count <= PromoteCountOver then
break; //for idxOld
idxNew := FindInGeneration(newGen, pOldData^.Data);
if idxNew > 0 then begin
newGenData^[idxNew].Count := newGenData^[idxNew].Count + pOldData^.Count;
ResortGeneration(newGen, idxNew);
end
else if canInsert then
canInsert := InsertIntoGeneration(newGen, pOldData^)
else with FGenerationInfo[newGen] do
Inc(OverflowCount);
end; //for idxOld
Last := 0;
end;
end;
procedure TStaticCollector.ResortGeneration(generation, idxData: integer);
var
dataInfo: TDataInfo;
idx : integer;
begin
// Data^[idxData].Count was just updated, resort the generation.
with FGenerationInfo[generation] do begin
idx := FindInsertionPoint(generation, Data^[idxData].Count);
if idx < idxData then begin
dataInfo := Data^[idxData];
Move(Data^[idx], Data^[idx+1], (idxData-idx) * SizeOf(Data^[idx]));
Data^[idx] := dataInfo;
end;
end;
end;
procedure TStaticCollector.SetGen1_PromoteCountOver(const value: integer);
begin
FGenerationInfo[1].PromoteCountOver := value;
end;
procedure TStaticCollector.SetGen1_PromoteEvery_sec(const value: integer);
begin
FGenerationInfo[1].PromoteEvery_sec := value;
end;
end.

View File

@ -0,0 +1,352 @@
// Based on TOmniBaseBoundedStack class from the OmniThreadLibrary,
// originally written by GJ and Primoz Gabrijelcic.
unit FastMM4LockFreeStack;
interface
type
PReferencedPtr = ^TReferencedPtr;
TReferencedPtr = record
PData : pointer;
Reference: NativeInt;
end;
PLinkedData = ^TLinkedData;
TLinkedData = packed record
Next: PLinkedData;
Data: record end; //user data, variable size
end;
TLFStack = record
strict private
FDataBuffer : pointer;
FElementSize : integer;
FNumElements : integer;
FPublicChainP : PReferencedPtr;
FRecycleChainP: PReferencedPtr;
class var
class var obsIsInitialized: boolean; //default is false
class var obsTaskPopLoops : NativeInt;
class var obsTaskPushLoops: NativeInt;
class function PopLink(var chain: TReferencedPtr): PLinkedData; static;
class procedure PushLink(const link: PLinkedData; var chain: TReferencedPtr); static;
procedure MeasureExecutionTimes;
public
procedure Empty;
procedure Initialize(numElements, elementSize: integer);
procedure Finalize;
function IsEmpty: boolean; inline;
function IsFull: boolean; inline;
function Pop(var value): boolean;
function Push(const value): boolean;
property ElementSize: integer read FElementSize;
property NumElements: integer read FNumElements;
end;
implementation
uses
Windows;
{$IF CompilerVersion < 23}
{$IFNDEF CPUX64}
type
NativeInt = integer;
NativeUInt = cardinal;
{$ENDIF}
{$IFEND}
var
CASAlignment: integer; //required alignment for the CAS function - 8 or 16, depending on the platform
function RoundUpTo(value: pointer; granularity: integer): pointer;
begin
Result := pointer((((NativeInt(value) - 1) div granularity) + 1) * granularity);
end;
function GetCPUTimeStamp: int64;
asm
rdtsc
{$IFDEF CPUX64}
shl rdx, 32
or rax, rdx
{$ENDIF CPUX64}
end;
function GetThreadId: NativeInt;
//result := GetCurrentThreadId;
asm
{$IFNDEF CPUX64}
mov eax, fs:[$18] //eax := thread information block
mov eax, [eax + $24] //eax := thread id
{$ELSE CPUX64}
mov rax, gs:[abs $30]
mov eax, [rax + $48]
{$ENDIF CPUX64}
end;
function CAS(const oldValue, newValue: NativeInt; var destination): boolean; overload;
asm
{$IFDEF CPUX64}
mov rax, oldValue
{$ENDIF CPUX64}
lock cmpxchg [destination], newValue
setz al
end;
function CAS(const oldValue, newValue: pointer; var destination): boolean; overload;
asm
{$IFDEF CPUX64}
mov rax, oldValue
{$ENDIF CPUX64}
lock cmpxchg [destination], newValue
setz al
end;
function CAS(const oldData: pointer; oldReference: NativeInt; newData: pointer;
newReference: NativeInt; var destination): boolean; overload;
asm
{$IFNDEF CPUX64}
push edi
push ebx
mov ebx, newData
mov ecx, newReference
mov edi, destination
lock cmpxchg8b qword ptr [edi]
pop ebx
pop edi
{$ELSE CPUX64}
.noframe
push rbx //rsp := rsp - 8 !
mov rax, oldData
mov rbx, newData
mov rcx, newReference
mov r8, [destination + 8] //+8 with respect to .noframe
lock cmpxchg16b [r8]
pop rbx
{$ENDIF CPUX64}
setz al
end;
{ TLFStack }
procedure TLFStack.Empty;
var
linkedData: PLinkedData;
begin
repeat
linkedData := PopLink(FPublicChainP^);
if not assigned(linkedData) then
break; //repeat
PushLink(linkedData, FRecycleChainP^);
until false;
end;
procedure TLFStack.Finalize;
begin
HeapFree(GetProcessHeap, 0, FDataBuffer);
end;
procedure TLFStack.Initialize(numElements, elementSize: integer);
var
bufferElementSize : integer;
currElement : PLinkedData;
dataBuffer : pointer;
iElement : integer;
nextElement : PLinkedData;
roundedElementSize: integer;
begin
Assert(SizeOf(NativeInt) = SizeOf(pointer));
Assert(numElements > 0);
Assert(elementSize > 0);
FNumElements := numElements;
FElementSize := elementSize;
//calculate element size, round up to next aligned value
roundedElementSize := (elementSize + SizeOf(pointer) - 1) AND NOT (SizeOf(pointer) - 1);
//calculate buffer element size, round up to next aligned value
bufferElementSize := ((SizeOf(TLinkedData) + roundedElementSize) + SizeOf(pointer) - 1) AND NOT (SizeOf(pointer) - 1);
//calculate DataBuffer
FDataBuffer := HeapAlloc(GetProcessHeap, HEAP_GENERATE_EXCEPTIONS, bufferElementSize * numElements + 2 * SizeOf(TReferencedPtr) + CASAlignment);
dataBuffer := RoundUpTo(FDataBuffer, CASAlignment);
if NativeInt(dataBuffer) AND (SizeOf(pointer) - 1) <> 0 then
// TODO 1 raise exception - how?
Halt; //raise Exception.Create('TOmniBaseContainer: obcBuffer is not aligned');
FPublicChainP := dataBuffer;
inc(NativeInt(dataBuffer), SizeOf(TReferencedPtr));
FRecycleChainP := dataBuffer;
inc(NativeInt(dataBuffer), SizeOf(TReferencedPtr));
//Format buffer to recycleChain, init obsRecycleChain and obsPublicChain.
//At the beginning, all elements are linked into the recycle chain.
FRecycleChainP^.PData := dataBuffer;
currElement := FRecycleChainP^.PData;
for iElement := 0 to FNumElements - 2 do begin
nextElement := PLinkedData(NativeInt(currElement) + bufferElementSize);
currElement.Next := nextElement;
currElement := nextElement;
end;
currElement.Next := nil; // terminate the chain
FPublicChainP^.PData := nil;
MeasureExecutionTimes;
end;
function TLFStack.IsEmpty: boolean;
begin
Result := not assigned(FPublicChainP^.PData);
end;
function TLFStack.IsFull: boolean;
begin
Result := not assigned(FRecycleChainP^.PData);
end;
procedure TLFStack.MeasureExecutionTimes;
const
NumOfSamples = 10;
var
TimeTestField: array [0..1] of array [1..NumOfSamples] of int64;
function GetMinAndClear(routine, count: cardinal): int64;
var
m: cardinal;
n: integer;
x: integer;
begin
Result := 0;
for m := 1 to count do begin
x:= 1;
for n:= 2 to NumOfSamples do
if TimeTestField[routine, n] < TimeTestField[routine, x] then
x := n;
Inc(Result, TimeTestField[routine, x]);
TimeTestField[routine, x] := MaxLongInt;
end;
end;
var
oldAffinity: NativeUInt;
currElement: PLinkedData;
n : integer;
begin
if not obsIsInitialized then begin
oldAffinity := SetThreadAffinityMask(GetCurrentThread, 1);
try
//Calculate TaskPopDelay and TaskPushDelay counter values depend on CPU speed!!!}
obsTaskPopLoops := 1;
obsTaskPushLoops := 1;
for n := 1 to NumOfSamples do begin
SwitchToThread;
//Measure RemoveLink rutine delay
TimeTestField[0, n] := GetCPUTimeStamp;
currElement := PopLink(FRecycleChainP^);
TimeTestField[0, n] := GetCPUTimeStamp - TimeTestField[0, n];
//Measure InsertLink rutine delay
TimeTestField[1, n] := GetCPUTimeStamp;
PushLink(currElement, FRecycleChainP^);
TimeTestField[1, n] := GetCPUTimeStamp - TimeTestField[1, n];
end;
//Calculate first 4 minimum average for RemoveLink rutine
obsTaskPopLoops := GetMinAndClear(0, 4) div 4;
//Calculate first 4 minimum average for InsertLink rutine
obsTaskPushLoops := GetMinAndClear(1, 4) div 4;
//This gives better performance (determined experimentally)
obsTaskPopLoops := obsTaskPopLoops * 2;
obsTaskPushLoops := obsTaskPushLoops * 2;
obsIsInitialized := true;
finally SetThreadAffinityMask(GetCurrentThread, oldAffinity); end;
end;
end;
function TLFStack.Pop(var value): boolean;
var
linkedData: PLinkedData;
begin
linkedData := PopLink(FPublicChainP^);
Result := assigned(linkedData);
if not Result then
Exit;
Move(linkedData.Data, value, ElementSize);
PushLink(linkedData, FRecycleChainP^);
end;
class function TLFStack.PopLink(var chain: TReferencedPtr): PLinkedData;
//nil << Link.Next << Link.Next << ... << Link.Next
// ^------ < chainHead
var
AtStartReference: NativeInt;
CurrentReference: NativeInt;
TaskCounter : NativeInt;
ThreadReference : NativeInt;
label
TryAgain;
begin
ThreadReference := GetThreadId + 1; //Reference.bit0 := 1
with chain do begin
TryAgain:
TaskCounter := obsTaskPopLoops;
AtStartReference := Reference OR 1; //Reference.bit0 := 1
repeat
CurrentReference := Reference;
Dec(TaskCounter);
until (TaskCounter = 0) or (CurrentReference AND 1 = 0);
if (CurrentReference AND 1 <> 0) and (AtStartReference <> CurrentReference) or
not CAS(CurrentReference, ThreadReference, Reference)
then
goto TryAgain;
//Reference is set...
Result := PData;
//Empty test
if result = nil then
CAS(ThreadReference, 0, Reference) //Clear Reference if task own reference
else if not CAS(Result, ThreadReference, Result.Next, 0, chain) then
goto TryAgain;
end; //with chain
end;
function TLFStack.Push(const value): boolean;
var
linkedData: PLinkedData;
begin
linkedData := PopLink(FRecycleChainP^);
Result := assigned(linkedData);
if not Result then
Exit;
Move(value, linkedData.Data, ElementSize);
PushLink(linkedData, FPublicChainP^);
end;
class procedure TLFStack.PushLink(const link: PLinkedData; var chain: TReferencedPtr);
var
PMemData : pointer;
TaskCounter: NativeInt;
begin
with chain do begin
for TaskCounter := 0 to obsTaskPushLoops do
if (Reference AND 1 = 0) then
break;
repeat
PMemData := PData;
link.Next := PMemData;
until CAS(PMemData, link, PData);
end;
end;
procedure InitializeTimingInfo;
var
stack: TLFStack;
begin
stack.Initialize(10, 4); // enough for initialization
stack.Finalize;
end;
initialization
{$IFDEF CPUX64}
CASAlignment := 16;
{$ELSE}
CASAlignment := 8;
{$ENDIF CPUX64}
InitializeTimingInfo;
end.

View File

@ -0,0 +1,158 @@
{
Fast Memory Manager: Messages
English translation by Pierre le Riche.
}
unit FastMM4Messages;
interface
{$Include FastMM4Options.inc}
const
{The name of the debug info support DLL}
{$IFDEF MACOS}
FullDebugModeLibraryName32Bit = 'libFastMM_FullDebugMode.dylib';
{$ELSE}
FullDebugModeLibraryName32Bit = 'FastMM_FullDebugMode.dll';
{$ENDIF}
FullDebugModeLibraryName64Bit = 'FastMM_FullDebugMode64.dll';
{Event log strings}
LogFileExtension = '_MemoryManager_EventLog.txt'#0;
CRLF = #13#10;
EventSeparator = '--------------------------------';
{Class name messages}
UnknownClassNameMsg = 'Unknown';
{Memory dump message}
MemoryDumpMsg = #13#10#13#10'Current memory dump of 256 bytes starting at pointer address ';
{Block Error Messages}
BlockScanLogHeader = 'Allocated block logged by LogAllocatedBlocksToFile. The size is: ';
ErrorMsgHeader = 'FastMM has detected an error during a ';
GetMemMsg = 'GetMem';
FreeMemMsg = 'FreeMem';
ReallocMemMsg = 'ReallocMem';
BlockCheckMsg = 'free block scan';
OperationMsg = ' operation. ';
BlockHeaderCorruptedMsg = 'The block header has been corrupted. ';
BlockFooterCorruptedMsg = 'The block footer has been corrupted. ';
FreeModifiedErrorMsg = 'FastMM detected that a block has been modified after being freed. ';
FreeModifiedDetailMsg = #13#10#13#10'Modified byte offsets (and lengths): ';
DoubleFreeErrorMsg = 'An attempt has been made to free/reallocate an unallocated block.';
WrongMMFreeErrorMsg = 'An attempt has been made to free/reallocate a block that was allocated through a different FastMM instance. Check your memory manager sharing settings.';
PreviousBlockSizeMsg = #13#10#13#10'The previous block size was: ';
CurrentBlockSizeMsg = #13#10#13#10'The block size is: ';
PreviousObjectClassMsg = #13#10#13#10'The block was previously used for an object of class: ';
CurrentObjectClassMsg = #13#10#13#10'The block is currently used for an object of class: ';
PreviousAllocationGroupMsg = #13#10#13#10'The allocation group was: ';
PreviousAllocationNumberMsg = #13#10#13#10'The allocation number was: ';
CurrentAllocationGroupMsg = #13#10#13#10'The allocation group is: ';
CurrentAllocationNumberMsg = #13#10#13#10'The allocation number is: ';
BlockErrorMsgTitle = 'Memory Error Detected';
VirtualMethodErrorHeader = 'FastMM has detected an attempt to call a virtual method on a freed object. An access violation will now be raised in order to abort the current operation.';
InterfaceErrorHeader = 'FastMM has detected an attempt to use an interface of a freed object. An access violation will now be raised in order to abort the current operation.';
BlockHeaderCorruptedNoHistoryMsg = ' Unfortunately the block header has been corrupted so no history is available.';
FreedObjectClassMsg = #13#10#13#10'Freed object class: ';
VirtualMethodName = #13#10#13#10'Virtual method: ';
VirtualMethodOffset = 'Offset +';
VirtualMethodAddress = #13#10#13#10'Virtual method address: ';
{Stack trace messages}
CurrentThreadIDMsg = #13#10#13#10'The current thread ID is 0x';
CurrentStackTraceMsg = ', and the stack trace (return addresses) leading to this error is:';
ThreadIDPrevAllocMsg = #13#10#13#10'This block was previously allocated by thread 0x';
ThreadIDAtAllocMsg = #13#10#13#10'This block was allocated by thread 0x';
ThreadIDAtFreeMsg = #13#10#13#10'The block was previously freed by thread 0x';
ThreadIDAtObjectAllocMsg = #13#10#13#10'The object was allocated by thread 0x';
ThreadIDAtObjectFreeMsg = #13#10#13#10'The object was subsequently freed by thread 0x';
StackTraceMsg = ', and the stack trace (return addresses) at the time was:';
{Installation Messages}
AlreadyInstalledMsg = 'FastMM4 is already installed.';
AlreadyInstalledTitle = 'Already installed.';
OtherMMInstalledMsg = 'FastMM4 cannot be installed since another third party memory '
+ 'manager has already installed itself.'#13#10'If you want to use FastMM4, '
+ 'please make sure that FastMM4.pas is the very first unit in the "uses"'
+ #13#10'section of your project''s .dpr file.';
OtherMMInstalledTitle = 'Cannot install FastMM4 - Another memory manager is already installed';
MemoryAllocatedMsg = 'FastMM4 cannot install since memory has already been '
+ 'allocated through the default memory manager.'#13#10'FastMM4.pas MUST '
+ 'be the first unit in your project''s .dpr file, otherwise memory may '
+ 'be allocated'#13#10'through the default memory manager before FastMM4 '
+ 'gains control. '#13#10#13#10'If you are using an exception trapper '
+ 'like MadExcept (or any tool that modifies the unit initialization '
+ 'order),'#13#10'go into its configuration page and ensure that the '
+ 'FastMM4.pas unit is initialized before any other unit.';
MemoryAllocatedTitle = 'Cannot install FastMM4 - Memory has already been allocated';
{Leak checking messages}
LeakLogHeader = 'A memory block has been leaked. The size is: ';
LeakMessageHeader = 'This application has leaked memory. ';
SmallLeakDetail = 'The small block leaks are'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (excluding expected leaks registered by pointer)'
{$endif}
+ ':'#13#10;
LargeLeakDetail = 'The sizes of leaked medium and large blocks are'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (excluding expected leaks registered by pointer)'
{$endif}
+ ': ';
BytesMessage = ' bytes: ';
AnsiStringBlockMessage = 'AnsiString';
UnicodeStringBlockMessage = 'UnicodeString';
LeakMessageFooter = #13#10
{$ifndef HideMemoryLeakHintMessage}
+ #13#10'Note: '
{$ifdef RequireIDEPresenceForLeakReporting}
+ 'This memory leak check is only performed if Delphi is currently running on the same computer. '
{$endif}
{$ifdef FullDebugMode}
{$ifdef LogMemoryLeakDetailToFile}
+ 'Memory leak detail is logged to a text file in the same folder as this application. '
{$else}
+ 'Enable the "LogMemoryLeakDetailToFile" to obtain a log file containing detail on memory leaks. '
{$endif}
{$else}
+ 'To obtain a log file containing detail on memory leaks, enable the "FullDebugMode" and "LogMemoryLeakDetailToFile" conditional defines. '
{$endif}
+ 'To disable this memory leak check, undefine "EnableMemoryLeakReporting".'#13#10
{$endif}
+ #0;
LeakMessageTitle = 'Memory Leak Detected';
{$ifdef UseOutputDebugString}
FastMMInstallMsg = 'FastMM has been installed.';
FastMMInstallSharedMsg = 'Sharing an existing instance of FastMM.';
FastMMUninstallMsg = 'FastMM has been uninstalled.';
FastMMUninstallSharedMsg = 'Stopped sharing an existing instance of FastMM.';
{$endif}
{$ifdef DetectMMOperationsAfterUninstall}
InvalidOperationTitle = 'MM Operation after uninstall.';
InvalidGetMemMsg = 'FastMM has detected a GetMem call after FastMM was uninstalled.';
InvalidFreeMemMsg = 'FastMM has detected a FreeMem call after FastMM was uninstalled.';
InvalidReallocMemMsg = 'FastMM has detected a ReallocMem call after FastMM was uninstalled.';
InvalidAllocMemMsg = 'FastMM has detected an AllocMem call after FastMM was uninstalled.';
{$endif}
{$ifdef LogLockContention}
LockingReportTitle = 'Locking Report';
LockingReportHeader = 'Top locking contention sites';
{$endif}
{$ifdef UseReleaseStack}
{$ifdef DebugReleaseStack}
ReleaseStackUsageHeader = 'Release stack usage statistics';
ReleaseStackUsageSmallBlocksMsg1 = 'Small blocks [';
ReleaseStackUsageSmallBlocksMsg2 = ']: ';
ReleaseStackUsageTotalSmallBlocksMsg = 'Total small blocks: ';
ReleaseStackUsageMediumBlocksMsg = 'Medium blocks: ';
ReleaseStackUsageLargeBlocksMsg = 'Large blocks: ';
ReleaseStackUsageTotalMemoryMsg = 'Total memory: ';
ReleaseStackUsageBuffers1Msg = ' in ';
ReleaseStackUsageBuffers2Msg = ' buffers [';
{$endif}
{$endif}
implementation
end.

View File

@ -0,0 +1,763 @@
{
Fast Memory Manager: Options Include File
Set the default options for FastMM here.
}
{---------------------------Miscellaneous Options-----------------------------}
{Enable Align16Bytes define to align all data blocks on 16 byte boundaries,
or enable Align32Bytes define to align all blocks on 32 byte boundaries,
so aligned SSE instructions can be used safely.
If neither of these options are enabled, then some of the
smallest block sizes will be 8-byte aligned instead which may result in a
reduction in memory usage.
Even when small blocks are aligned by 8 bytes
(no Align16Bytes or Align32Bytes are defined),
Medium and large blocks are always 16-byte aligned.
If you enable AVX, then the alignment will always be 32 bytes. However, if your
CPU supports "Fast Short REP MOVSB" (Ice Lake or newer), you can disable AVX,
and align by just 8 bytes, and this may even be faster because less memory is
wasted on alignment}
{.$define Align16Bytes}
{.$define Align32Bytes}
{Enable to use faster fixed-size move routines when upsizing small blocks.
These routines are much faster than the Borland RTL move procedure since they
are optimized to move a fixed number of bytes. This option may be used
together with the FastMove library for even better performance.}
{$define UseCustomFixedSizeMoveRoutines}
{Enable this option to use an optimized procedure for moving a memory block of
an arbitrary size. Disable this option when using the Fastcode move
("FastMove") library. Using the Fastcode move library allows your whole
application to gain from faster move routines, not just the memory manager. It
is thus recommended that you use the Fastcode move library in conjunction with
this memory manager and disable this option.}
{$define UseCustomVariableSizeMoveRoutines}
{Enable this option to only install FastMM as the memory manager when the
application is running inside the Delphi IDE. This is useful when you want
to deploy the same EXE that you use for testing, but only want the debugging
features active on development machines. When this option is enabled and
the application is not being run inside the IDE debugger, then the default
Delphi memory manager will be used (which, since Delphi 2006, is FastMM
without FullDebugMode.}
{.$define InstallOnlyIfRunningInIDE}
{Due to QC#14070 ("Delphi IDE attempts to free memory after the shutdown code
of borlndmm.dll has been called"), FastMM cannot be uninstalled safely when
used inside a replacement borlndmm.dll for the IDE. Setting this option will
circumvent this problem by never uninstalling the memory manager.}
{.$define NeverUninstall}
{Set this option when you use runtime packages in this application or library.
This will automatically set the "AssumeMultiThreaded" option. Note that you
have to ensure that FastMM is finalized after all live pointers have been
freed - failure to do so will result in a large leak report followed by a lot
of A/Vs. (See the FAQ for more detail.) You may have to combine this option
with the NeverUninstall option.}
{.$define UseRuntimePackages}
{-----------------------Concurrency Management Options------------------------}
{Enable to always assume that the application is multithreaded. Enabling this
option will cause a significant performance hit with single threaded
applications. Enable if you are using multi-threaded third-party tools that do
not properly set the IsMultiThread variable. Also set this option if you are
going to share this memory manager between a single threaded application and a
multi-threaded DLL. Since the primary goal of FastMM4-AVX is improvement in
multi-threaded applications, this option is enabled by default. However, if you
know for sure that your application is Single-Threaded, undefine this to improve
performance - this will save yo from unnecessary locking! }
{$define AssumeMultiThreaded}
{Enable to always assume that the CPU supports "pause" instruction and Windows
supports SwitchToThread() API call. This option has no effect for 64-bit target,
since it is always assumed under 64-bit that both "pause" and SwitchToThread()
are supported. So it is only relevant for 32-bit platforms with very old CPUs.
If you are sure that "pause" and SwithchToThread() are always avaialbe, the
program may skip checking and improve speed. However, if you define
"DisablePauseAndSwitchToThread", then "AssumePauseAndSwitchToThreadAvailable"
will be automatically undefined}
{.$define AssumePauseAndSwitchToThreadAvailable}
{ If you disable "pause" and SwitchToThread() by defining the
DisablePauseAndSwitchToThread, then EnterCriticalSection/LeaveCriticalSection
calls will be used instead }
{.$define DisablePauseAndSwitchToThread}
{Enable this option to not call Sleep when a thread contention occurs. This
option will improve performance if the ratio of the number of active threads
to the number of CPU cores is low (typically < 2). With this option set a
thread will usually enter a "busy waiting" loop instead of relinquishing its
timeslice when a thread contention occurs, unless UseSwitchToThread is
also defined (see below) in which case it will call SwitchToThread instead of
Sleep.
*** Note: This option was added in FastMM 4 version Version 4.68
on 3 July 2006, is provided only if you wish to restore old
functionality (e.g. for testing, etc.), and is not recommended
for FastMM4-AVX, since this it provides suboptimal performance compare
to the new locking mechanism implemented in the FastMM4-AVX.
This option has no effect when SmallBlocksLockedCriticalSection/
MediumBlocksLockedCriticalSection/LargeBlocksLockedCriticalSection is enabled}
{.$define NeverSleepOnThreadContention}
{Set this option to call SwitchToThread instead of sitting in a "busy waiting"
loop when a thread contention occurs. This is used in conjunction with the
NeverSleepOnThreadContention option, and has no effect unless
NeverSleepOnThreadContention is also defined. This option may improve
performance with many CPU cores and/or threads of different priorities. Note
that the SwitchToThread API call is only available on Windows 2000 and later,
but FastMM4 loads it dynamically, so it would not fail even under very old
versions of Windows.
*** Note: This option was added in FastMM 4 version Version 4.97
on 30 September 2010, is provided only if you wish to restore old
functionality (e.g. for testing, etc.), and is not recommended
for FastMM4-AVX, since this it provides suboptimal performance compare
to the new locking mechanism implemented in the FastMM4-AVX.
This option has no effect when SmallBlocksLockedCriticalSection/
MediumBlocksLockedCriticalSection/LargeBlocksLockedCriticalSection is enabled}
{.$define UseSwitchToThread}
{This option uses a simpler instruction to acquire a lock: "lock xchg",
instead of "lock cmpxchg" used in earlier versions of FastMM4: there is
actually no reason to use "cmpxchg", because the simple instruction - "xchg" -
perfectly suits our need. Although "xchg" has exactly the same latency and
costs in terms of CPU cycles as "cmpxghg", it is just simper way to do the
lock that we need, and, according to the Occam's razor principle, simple things
are better. If you wish to restore old functionality of FastMM4 version 4.992,
disable this option }
{$define SimplifiedInterlockedExchangeByte}
{These 3 options make FastMM4-AVX use a new approach to waiting for a lock:
CriticalSections or "pause"-based spin-wait loops instead of Sleep() or
SwitchToThread().
Using Sleep(0) or SwitchToThread() while waiting for a lock is a default
approach in the original version of FastMM.
With the new approach, the Sleep() will never be called, and SwitchToThread()
may only be called after 5000 cycles of "pause"-based spin-wait loop.
Testing has shown that the new approach provides significant gain in
multi-threaded scenarios, especially in situations when the number of threads
working with the memory manager is the same or higher than the number of
physical cores.
Critical Sections or "pause"-based spin-wait loops implemented as
"test, test-and-set" are much more CPU-friendly and have definitely lower
latency than Sleep() or SwitchToThread().
When these options are enabled, FastMM4-AVX checks:
- whether the CPU supports SSE2 and thus the "pause" instruction, and
- whether the operating system has the SwitchToThread() API call, and,
if both of the above conditions are met, uses
"pause"-based spin-wait loops for 5000 iterations and then
SwitchToThread() instead of critical sections; If a CPU doesn't have the
"pause" instrcution or Windows doesn't have the SwitchToThread() API
function, it will use EnterCriticalSection/LeaveCriticalSection.
If you wound not define the 3 options below, you will get the locking
mechanism from the original FastMM4}
{$define SmallBlocksLockedCriticalSection}
{$define MediumBlocksLockedCriticalSection}
{$define LargeBlocksLockedCriticalSection}
{ Use this option if you need that releasing a lock on data structure,
i.e. writing to a synchronization variable, to use bus-locking memory store
(lock xchg) rather than just the normal memory store (mov).
Using bus-locking memory store to release a lock on data structure is
an old approach of the original FastMM4, and is not recommended
for FastMM4-AVX. Look for "using normal memory store" in the comment section
at the beginning of the main .pas file for the discussion }
{.$define InterlockedRelease}
{-----------------------------Debugging Options-------------------------------}
{Enable this option to suppress the generation of debug info for the
FastMM4.pas unit. This will prevent the integrated debugger from stepping into
the memory manager code.}
{.$define NoDebugInfo}
{Enable this option to suppress the display of all message dialogs. This is
useful in service applications that should not be interrupted.}
{.$define NoMessageBoxes}
{Set this option to use the Windows API OutputDebugString procedure to output
debug strings on startup/shutdown and when errors occur.}
{.$define UseOutputDebugString}
{Set this option to use the assembly language version of GetMem and FreeMem
which is faster than the pascal version. Disable only for debugging purposes.
Setting the CheckHeapForCorruption option automatically disables this option.}
{$define ASMVersion}
{Set this option to disable any inline assembly at all. However, it would not
be able to use efficient locking without inline assembly.}
{.$define PurePascal}
{Define the "EnableAsmCodeAlign" to allow using ".align" assembler
directive for the 32-bit or 64-bit inline assembly.
Delphi 32-bit or 64-bit compiler incorrectly encodes conditional jumps
(used 6-byte instructions instead of just 2 bytes, so it prevents branch
predicions. So for Embarcadero (former Borland) 32-bit or 64-bit
Delphi, EnableAsmCodeAlign will have no effect. However, undre FreePascal
it turns on using the ".align". To force using it under Delphi, define
"ForceAsmCodeAlign" }
{$define EnableAsmCodeAlign}
{.$define ForceAsmCodeAlign}
{Allow pascal code alignment}
{$define PasCodeAlign}
{FastMM always catches attempts to free the same memory block twice, however it
can also check for corruption of the memory heap (typically due to the user
program overwriting the bounds of allocated memory). These checks are
expensive, and this option should thus only be used for debugging purposes.
If this option is set then the ASMVersion option is automatically disabled.}
{.$define CheckHeapForCorruption}
{Enable this option to catch attempts to perform MM operations after FastMM has
been uninstalled. With this option set when FastMM is uninstalled it will not
install the previous MM, but instead a dummy MM handler that throws an error
if any MM operation is attempted. This will catch attempts to use the MM
after FastMM has been uninstalled.}
{.$define DetectMMOperationsAfterUninstall}
{Set the following option to do extensive checking of all memory blocks. All
blocks are padded with both a header and trailer that are used to verify the
integrity of the heap. Freed blocks are also cleared to ensure that they
cannot be reused after being freed. This option slows down memory operations
dramatically and should only be used to debug an application that is
overwriting memory or reusing freed pointers. Setting this option
automatically enables CheckHeapForCorruption and disables ASMVersion.
Very important: If you enable this option your application will require the
FastMM_FullDebugMode.dll library. If this library is not available you will
get an error on startup.}
{.$define FullDebugMode}
{Set this option to perform "raw" stack traces, i.e. check all entries on the
stack for valid return addresses. Note that this is significantly slower
than using the stack frame tracing method, but is usually more complete. Has
no effect unless FullDebugMode is enabled}
{.$define RawStackTraces}
{Set this option to check for user code that uses an interface of a freed
object. Note that this will disable the checking of blocks modified after
being freed (the two are not compatible). This option has no effect if
FullDebugMode is not also enabled.}
{.$define CatchUseOfFreedInterfaces}
{Set this option to log all errors to a text file in the same folder as the
application. Memory errors (with the FullDebugMode option set) will be
appended to the log file. Has no effect if "FullDebugMode" is not set.}
{$define LogErrorsToFile}
{Set this option to log all memory leaks to a text file in the same folder as
the application. Memory leak reports (with the FullDebugMode option set)
will be appended to the log file. Has no effect if "LogErrorsToFile" and
"FullDebugMode" are not also set. Note that usually all leaks are always
logged, even if they are "expected" leaks registered through
AddExpectedMemoryLeaks. Expected leaks registered by pointer may be excluded
through the HideExpectedLeaksRegisteredByPointer option.}
{$define LogMemoryLeakDetailToFile}
{Deletes the error log file on startup. No effect if LogErrorsToFile is not
also set.}
{.$define ClearLogFileOnStartup}
{Loads the FASTMM_FullDebugMode.dll dynamically. If the DLL cannot be found
then stack traces will not be available. Note that this may cause problems
due to a changed DLL unload order when sharing the memory manager. Use with
care.}
{.$define LoadDebugDLLDynamically}
{.$define DoNotInstallIfDLLMissing}
{If the FastMM_FullDebugMode.dll file is not available then FastMM will not
install itself. No effect unless FullDebugMode and LoadDebugDLLDynamically
are also defined.}
{.$define RestrictDebugDLLLoadPath}
{Allow to load debug dll only from host module directory.}
{FastMM usually allocates large blocks from the topmost available address and
medium and small blocks from the lowest available address (This reduces
fragmentation somewhat). With this option set all blocks are always
allocated from the highest available address. If the process has a >2GB
address space and contains bad pointer arithmetic code, this option should
help to catch those errors sooner.}
{$define AlwaysAllocateTopDown}
{Disables the logging of memory dumps together with the other detail for
memory errors.}
{.$define DisableLoggingOfMemoryDumps}
{If FastMM encounters a problem with a memory block inside the FullDebugMode
FreeMem handler then an "invalid pointer operation" exception will usually
be raised. If the FreeMem occurs while another exception is being handled
(perhaps in the try.. finally code) then the original exception will be
lost. With this option set FastMM will ignore errors inside FreeMem when an
exception is being handled, thus allowing the original exception to
propagate.}
{$define SuppressFreeMemErrorsInsideException}
{Adds support for notification of memory manager events in FullDebugMode.
With this define set, the application may assign the OnDebugGetMemFinish,
OnDebugFreeMemStart, etc. callbacks in order to be notified when the
particular memory manager event occurs.}
{.$define FullDebugModeCallBacks}
{---------------------------Memory Leak Reporting-----------------------------}
{Set the option EnableMemoryLeakReporting to enable reporting of memory leaks.
Combine it with the two options below for further fine-tuning.}
{$ifndef DisableMemoryLeakReporting}
{$define EnableMemoryLeakReporting}
{$endif}
{Set this option to suppress the display and logging of expected memory leaks
that were registered by pointer. Leaks registered by size or class are often
ambiguous, so these expected leaks are always logged to file (in
FullDebugMode with the LogMemoryLeakDetailToFile option set) and are never
hidden from the leak display if there are more leaks than are expected.}
{$define HideExpectedLeaksRegisteredByPointer}
{Set this option to require the presence of the Delphi IDE to report memory
leaks. This option has no effect if the option "EnableMemoryLeakReporting"
is not also set.}
{.$define RequireIDEPresenceForLeakReporting}
{Set this option to require the program to be run inside the IDE debugger to
report memory leaks. This option has no effect if the option
"EnableMemoryLeakReporting" is not also set. Note that this option does not
work with libraries, only EXE projects.}
{$define RequireDebuggerPresenceForLeakReporting}
{Set this option to require the presence of debug info ($D+ option) in the
compiled unit to perform memory leak checking. This option has no effect if
the option "EnableMemoryLeakReporting" is not also set.}
{.$define RequireDebugInfoForLeakReporting}
{Set this option to enable manual control of the memory leak report. When
this option is set the ReportMemoryLeaksOnShutdown variable (default = false)
may be changed to select whether leak reporting should be done or not. When
this option is selected then both the variable must be set to true and the
other leak checking options must be applicable for the leak checking to be
done.}
{.$define ManualLeakReportingControl}
{Set this option to disable the display of the hint below the memory leak
message.}
{.$define HideMemoryLeakHintMessage}
{Set this option to use QualifiedClassName equivalent instead of ClassName
equivalent during memory leak reporting.
This is useful for duplicate class names (like EConversionError, which is in
units Data.DBXJSONReflect, REST.JsonReflect and System.ConvUtils,
or TClipboard being in Vcl.Clibprd and WinAPI.ApplicationModel.DataTransfer }
{$define EnableMemoryLeakReportingUsesQualifiedClassName}
{--------------------------Instruction Set Options----------------------------}
{Set this option to enable the use of MMX instructions. Disabling this option
will result in a slight performance hit, but will enable compatibility with
AMD K5, Pentium I and earlier CPUs. MMX is currently only used in the variable
size move routines, so if UseCustomVariableSizeMoveRoutines is not set then
this option has no effect.}
{$define EnableMMX}
{$ifndef DontForceMMX}
{Set this option (ForceMMX) to force the use of MMX instructions without checking
whether the CPU supports it. If this option is disabled then the CPU will be
checked for compatibility first, and if MMX is not supported it will fall
back to the FPU move code. Has no effect unless EnableMMX is also set.}
{$define ForceMMX}
{$endif}
{$ifndef DisableAVX}
{Set this option (EnableAVX) to enable use of AVX instructions under 64-bit mode.
This option has no effect under 32-bit mode. If enabled, the code will check
whether the CPU supports AVX or AVX2, and, if yes, will use the 32-byte YMM
registers for faster memory copy. Besides that, if this option is enabled,
all allocated memory blocks will be aligned by 32 bytes, that will incur
addition memory consumption overhead. Besides that, with this option, memory
copy will be slightly more secure, because all XMM/YMM registers used to copy
memory will be cleared by vxorps/vpxor at the end of a copy routine, so the
leftovers of the copied memory data will not be kept in the XMM/YMM registers
and will not be exposed. This option properly handles AVX-SSE transitions to not
incur the transition penalties, only calls vzeroupper under AVX1, but not under
AVX2, since it slows down subsequent SSE code under Kaby Lake}
{$define EnableAVX}
{$endif}
{$ifdef EnableAVX}
{If AVX is enabled, you can optionally disable one or more
of the following AVX modes:
- the first version - initial AVX (DisableAVX1); or
- the second version AVX2 (DisableAVX2); or
- AVX-512 (DisableAVX512);
but you cannot disable all of the above modes at once.
If you define DisableAVX1, it will not add to FastMM4 the instructions from
the initial (first) version of the Advanced Vector Extensions instruction set,
officially called just "AVX", proposed by Intel in March 2008 and first
supported by Intel with the Sandy Bridge processor shipping in Q1 2011
and later, on by AMD with the Bulldozer processor shipping in Q3 2011.
If you define DisableAVX2, it will not add to FastMM4 the instructions from
the second version of the Advanced Vector Extensions - officially called
"AVX2", also known as Haswell New Instructions, which is an expansion of the
AVX instruction set introduced in Intel's Haswell microarchitecture.
Intel has shipped first processors with AVX2 on June 2, 2013: Core i7 4770,
Core i5 4670, etc., and AMD has shipped first processors with AVX in Q2 2015
(Carrizo processor). AMD Ryzen processor (Q1 2017) also supports AVX2.
We use separate code for AVX1 and AVX2 because AVX2 doesn't use "vzeroupper"
and uses the new, faster instruction "vpxor" which was not available in the
initial AVX, which, in its turn, uses "vxorps" and "vzeroupper" before and
after any AVX code to counteract the AVX-SSE transition penalties.
FastMM4 checks whether AVX2 is supported by the CPU, and, if supported, never
calls AVX1 functions, since calling "vzeroupper" even once in a thread
significantly slows down all subsequent SSE code, which is not documented:
neither in the Intel 64 and IA-32 Architectures Software Developers Manual
nor in the Intel 64 and IA-32 Architectures Optimization Reference Manual.
The code of AVX1 is grouped separately from the code of AVX2, to not scatter
the cache}
{.$define DisableAVX1}
{.$define DisableAVX2}
{$define DisableAVX512}
{$endif}
{$ifndef DisableERMS}
{Set this option (EnableERMS) to enable Enhanced Rep Movsb/Stosb CPU feature,
which improves speed of medium and large block memory copy
under 32-bit or 64-bit modes after checking the corresponding CPUID bit}
{$define EnableERMS}
{$endif}
{$ifndef DisableFSRM}
{Set this option (EnableFSRM) to enable Fast Short REP MOVSB CPU feature,
introduced by the Ice Lake microarchitecture, which improves speed of small
block memory copy under 64-bit mode after checking the corresponding CPUID bit}
{$define EnableFSRM}
{$endif}
{-----------------------Memory Manager Sharing Options------------------------}
{Allow sharing of the memory manager between a main application and DLLs that
were also compiled with FastMM. This allows you to pass dynamic arrays and
long strings to DLL functions provided both are compiled to use FastMM.
Sharing will only work if the library that is supposed to share the memory
manager was compiled with the "AttemptToUseSharedMM" option set. Note that if
the main application is single threaded and the DLL is multi-threaded that you
have to set the IsMultiThread variable in the main application to true or it
will crash when a thread contention occurs. Note that statically linked DLL
files are initialized before the main application, so the main application may
well end up sharing a statically loaded DLL's memory manager and not the other
way around. }
{.$define ShareMM}
{Allow sharing of the memory manager by a DLL with other DLLs (or the main
application if this is a statically loaded DLL) that were also compiled with
FastMM. Set this option with care in dynamically loaded DLLs, because if the
DLL that is sharing its MM is unloaded and any other DLL is still sharing
the MM then the application will crash. This setting is only relevant for
DLL libraries and requires ShareMM to also be set to have any effect.
Sharing will only work if the library that is supposed to share the memory
manager was compiled with the "AttemptToUseSharedMM" option set. Note that
if DLLs are statically linked then they will be initialized before the main
application and then the DLL will in fact share its MM with the main
application. This option has no effect unless ShareMM is also set.}
{.$define ShareMMIfLibrary}
{Define this to attempt to share the MM of the main application or other loaded
DLLs in the same process that were compiled with ShareMM set. When sharing a
memory manager, memory leaks caused by the sharer will not be freed
automatically. Take into account that statically linked DLLs are initialized
before the main application, so set the sharing options accordingly.}
{.$define AttemptToUseSharedMM}
{Define this to enable backward compatibility for the memory manager sharing
mechanism used by Delphi 2006 and 2007, as well as older FastMM versions.}
{$define EnableBackwardCompatibleMMSharing}
{-----------------------Security Options------------------------}
{Windows clears physical memory before reusing it in another process. However,
it is not known how quickly this clearing is performed, so it is conceivable
that confidential data may linger in physical memory longer than absolutely
necessary. If you're paranoid about this kind of thing, enable this option to
clear all freed memory before returning it to the operating system. Note that
this incurs a noticeable performance hit.}
{.$define ClearMemoryBeforeReturningToOS}
{With this option enabled freed memory will immediately be cleared inside the
FreeMem routine. This incurs a big performance hit, but may be worthwhile for
additional peace of mind when working with highly sensitive data. This option
supersedes the ClearMemoryBeforeReturningToOS option.}
{.$define AlwaysClearFreedMemory}
{----------------------------Lock Contention Logging--------------------------}
{Define this to lock stack traces for all occasions where GetMem/FreeMem
go to sleep because of lock contention (IOW, when memory manager is already
locked by another thread). At the end of the program execution top 10 sites
(locations with highest occurrence) will be logged to the _MemoryManager_EventLog.txt
file.
This options works with FullDebugMode or without it, but requires
FastMM_FullDebugMode.dll to be present in both cases.}
{.$define LogLockContention}
{--------------------------------Option Grouping------------------------------}
{Enabling this option enables FullDebugMode, InstallOnlyIfRunningInIDE and
LoadDebugDLLDynamically. Consequently, FastMM will install itself in
FullDebugMode if the application is being debugged inside the Delphi IDE.
Otherwise the default Delphi memory manager will be used (which is equivalent
to the non-FullDebugMode FastMM since Delphi 2006.)}
{.$define FullDebugModeInIDE}
{Combines the FullDebugMode, LoadDebugDLLDynamically and
DoNotInstallIfDLLMissing options. Consequently FastMM will only be installed
(In FullDebugMode) when the FastMM_FullDebugMode.dll file is available. This
is useful when the same executable will be distributed for both debugging as
well as deployment.}
{.$define FullDebugModeWhenDLLAvailable}
{Group the options you use for release and debug versions below}
{$ifdef Release}
{Specify the options you use for release versions below}
{.$undef FullDebugMode}
{.$undef CheckHeapForCorruption}
{.$define ASMVersion}
{.$undef EnableMemoryLeakReporting}
{.$undef UseOutputDebugString}
{$else}
{Specify the options you use for debugging below}
{.$define FullDebugMode}
{.$define EnableMemoryLeakReporting}
{.$define UseOutputDebugString}
{$endif}
{--------------------Compilation Options For borlndmm.dll---------------------}
{If you're compiling the replacement borlndmm.dll, set the defines below
for the kind of dll you require.}
{Set this option when compiling the borlndmm.dll}
{.$define borlndmmdll}
{Set this option if the dll will be used by the Delphi IDE}
{.$define dllforide}
{Set this option if you're compiling a debug dll}
{.$define debugdll}
{Do not change anything below this line}
{$ifdef borlndmmdll}
{$define AssumeMultiThreaded}
{$undef HideExpectedLeaksRegisteredByPointer}
{$undef RequireDebuggerPresenceForLeakReporting}
{$undef RequireDebugInfoForLeakReporting}
{$define DetectMMOperationsAfterUninstall}
{$undef ManualLeakReportingControl}
{$undef ShareMM}
{$undef AttemptToUseSharedMM}
{$ifdef dllforide}
{$define NeverUninstall}
{$define HideMemoryLeakHintMessage}
{$undef RequireIDEPresenceForLeakReporting}
{$ifndef debugdll}
{$undef EnableMemoryLeakReporting}
{$endif}
{$else}
{$define EnableMemoryLeakReporting}
{$undef NeverUninstall}
{$undef HideMemoryLeakHintMessage}
{$define RequireIDEPresenceForLeakReporting}
{$endif}
{$ifdef debugdll}
{$define FullDebugMode}
{$define RawStackTraces}
{$undef CatchUseOfFreedInterfaces}
{$define LogErrorsToFile}
{$define LogMemoryLeakDetailToFile}
{$undef ClearLogFileOnStartup}
{$else}
{$undef FullDebugMode}
{$endif}
{$endif}
{Move BCB related definitions here, because CB2006/CB2007 can build borlndmm.dll
for tracing memory leaks in BCB applications with "Build with Dynamic RTL"
switched on}
{------------------------------Patch BCB Terminate----------------------------}
{To enable the patching for BCB to make uninstallation and leak reporting
possible, you may need to add "BCB" definition
in "Project Options->Pascal/Delphi Compiler->Defines".
(Thanks to JiYuan Xie for implementing this.)}
{$ifdef BCB}
{$ifdef CheckHeapForCorruption}
{$define PatchBCBTerminate}
{$else}
{$ifdef DetectMMOperationsAfterUninstall}
{$define PatchBCBTerminate}
{$else}
{$ifdef EnableMemoryLeakReporting}
{$define PatchBCBTerminate}
{$endif}
{$endif}
{$endif}
{$ifdef PatchBCBTerminate}
{$define CheckCppObjectType}
{$undef CheckCppObjectTypeEnabled}
{$ifdef CheckCppObjectType}
{$define CheckCppObjectTypeEnabled}
{$endif}
{Turn off "CheckCppObjectTypeEnabled" option if neither "CheckHeapForCorruption"
option or "EnableMemoryLeakReporting" option were defined.}
{$ifdef CheckHeapForCorruption}
{$else}
{$ifdef EnableMemoryLeakReporting}
{$else}
{$undef CheckCppObjectTypeEnabled}
{$endif}
{$endif}
{$endif}
{$endif}

View File

@ -0,0 +1,343 @@
; This file is needed to enable AVX-512 code for FastMM4-AVX.
; Use "nasm.exe -Ox -f win64 FastMM4_AVX512.asm" to compile this file
; You can get The Netwide Assembler (NASM) from http://www.nasm.us/
; This file is a part of FastMM4-AVX.
; - Copyright (C) 2017-2020 Ritlabs, SRL. All rights reserved.
; - Copyright (C) 2020-2021 Maxim Masiutin. All rights reserved.
; Written by Maxim Masiutin <maxim@masiutin.com>
; FastMM4-AVX is a fork of the Fast Memory Manager 4.992 by Pierre le Riche
; FastMM4-AVX is released under a dual license, and you may choose to use it
; under either the Mozilla Public License 2.0 (MPL 2.1, available from
; https://www.mozilla.org/en-US/MPL/2.0/) or the GNU Lesser General Public
; License Version 3, dated 29 June 2007 (LGPL 3, available from
; https://www.gnu.org/licenses/lgpl.html).
; This code uses zmm26 - zmm31 registers to avoid AVX-SSE transition penalty.
; These regsters (zmm16 - zmm31) have no non-VEX counterpart. According to the
; advise of Agner Fog, there is no state transition and no penalty for mixing
; zmm16 - zmm31 with non-VEX SSE code. By using these registers (zmm16 - zmm31)
; rather than zmm0-xmm15 we save us from calling "vzeroupper".
; Source:
; https://stackoverflow.com/questions/43879935/avoiding-avx-sse-vex-transition-penalties/54587480#54587480
%define EVEXR512N0 zmm31
%define EVEXR512N1 zmm30
%define EVEXR512N2 zmm29
%define EVEXR512N3 zmm28
%define EVEXR512N4 zmm27
%define EVEXR512N5 zmm26
%define EVEXR256N0 ymm31
%define EVEXR256N1 ymm30
%define EVEXR256N2 ymm29
%define EVEXR256N3 ymm28
%define EVEXR256N4 ymm27
%define EVEXR256N5 ymm26
%define EVEXR128N0 xmm31
%define EVEXR128N1 xmm30
%define EVEXR128N2 xmm29
%define EVEXR128N3 xmm28
%define EVEXR128N4 xmm27
%define EVEXR128N5 xmm26
section .text
global Move24AVX512
global Move56AVX512
global Move88AVX512
global Move120AVX512
global Move152AVX512
global Move184AVX512
global Move216AVX512
global Move248AVX512
global Move280AVX512
global Move312AVX512
global Move344AVX512
global MoveX32LpAvx512WithErms
%use smartalign
ALIGNMODE p6, 32 ; p6 NOP strategy, and jump over the NOPs only if they're 32B or larger.
align 16
Move24AVX512:
vmovdqa64 EVEXR128N0, [rcx]
mov r8, [rcx+10h]
vmovdqa64 [rdx], EVEXR128N0
mov [rdx+10h], r8
vpxord EVEXR128N0, EVEXR128N0, EVEXR128N0
ret
Move56AVX512:
vmovdqa64 EVEXR256N0, [rcx+00h]
vmovdqa64 EVEXR128N1, [rcx+20h]
mov r8, [rcx+30h]
vmovdqa64 [rdx+00h], EVEXR256N0
vmovdqa64 [rdx+20h], EVEXR128N1
mov [rdx + 48], r8
vpxord EVEXR256N0, EVEXR256N0, EVEXR256N0
vpxord EVEXR128N1, EVEXR128N1, EVEXR128N1
ret
align 16
Move88AVX512:
vmovdqu64 EVEXR512N0, [rcx]
vmovdqa64 EVEXR128N1, [rcx+40h]
mov rcx, [rcx+50h]
vmovdqu64 [rdx], EVEXR512N0
vmovdqa64 [rdx+40h], EVEXR128N1
mov [rdx+50h], rcx
vpxord EVEXR512N0,EVEXR512N0,EVEXR512N0
vpxord EVEXR128N1,EVEXR128N1,EVEXR128N1
ret
align 16
Move120AVX512:
vmovdqu64 EVEXR512N0, [rcx]
vmovdqa64 EVEXR256N1, [rcx+40h]
vmovdqa64 EVEXR128N2, [rcx+60h]
mov rcx, [rcx + 70h]
vmovdqu64 [rdx], EVEXR512N0
vmovdqa64 [rdx+40h], EVEXR256N1
vmovdqa64 [rdx+60h], EVEXR128N2
mov [rdx+70h], rcx
vpxord EVEXR512N0,EVEXR512N0,EVEXR512N0
vpxord EVEXR256N1,EVEXR256N1,EVEXR256N1
vpxord EVEXR128N2,EVEXR128N2,EVEXR128N2
ret
align 16
Move152AVX512:
vmovdqu64 EVEXR512N0, [rcx+00h]
vmovdqu64 EVEXR512N1, [rcx+40h]
vmovdqa64 EVEXR128N2, [rcx+80h]
mov rcx, [rcx+90h]
vmovdqu64 [rdx+00h], EVEXR512N0
vmovdqu64 [rdx+40h], EVEXR512N1
vmovdqa64 [rdx+80h], EVEXR128N2
mov [rdx+90h], rcx
vpxord EVEXR512N0,EVEXR512N0,EVEXR512N0
vpxord EVEXR512N1,EVEXR512N1,EVEXR512N1
vpxord EVEXR128N2,EVEXR128N2,EVEXR128N2
ret
align 16
Move184AVX512:
vmovdqu64 EVEXR512N0, [rcx+00h]
vmovdqu64 EVEXR512N1, [rcx+40h]
vmovdqa64 EVEXR256N2, [rcx+80h]
vmovdqa64 EVEXR128N3, [rcx+0A0h]
mov rcx, [rcx+0B0h]
vmovdqu64 [rdx+00h], EVEXR512N0
vmovdqu64 [rdx+40h], EVEXR512N1
vmovdqa64 [rdx+80h], EVEXR256N2
vmovdqa64 [rdx+0A0h],EVEXR128N3
mov [rdx+0B0h],rcx
vpxord EVEXR512N0,EVEXR512N0,EVEXR512N0
vpxord EVEXR512N1,EVEXR512N1,EVEXR512N1
vpxord EVEXR256N2,EVEXR256N2,EVEXR256N2
vpxord EVEXR128N3,EVEXR128N3,EVEXR128N3
ret
align 16
Move216AVX512:
vmovdqu64 EVEXR512N0, [rcx+00h]
vmovdqu64 EVEXR512N1, [rcx+40h]
vmovdqu64 EVEXR512N2, [rcx+80h]
vmovdqa64 EVEXR128N3, [rcx+0C0h]
mov rcx, [rcx+0D0h]
vmovdqu64 [rdx+00h], EVEXR512N0
vmovdqu64 [rdx+40h], EVEXR512N1
vmovdqu64 [rdx+80h], EVEXR512N2
vmovdqa64 [rdx+0C0h], EVEXR128N3
mov [rdx+0D0h], rcx
vpxord EVEXR512N0,EVEXR512N0,EVEXR512N0
vpxord EVEXR512N1,EVEXR512N1,EVEXR512N1
vpxord EVEXR512N2,EVEXR512N2,EVEXR512N2
vpxord EVEXR128N3,EVEXR128N3,EVEXR128N3
ret
align 16
Move248AVX512:
vmovdqu64 EVEXR512N0, [rcx+00h]
vmovdqu64 EVEXR512N1, [rcx+40h]
vmovdqu64 EVEXR512N2, [rcx+80h]
vmovdqa64 EVEXR256N3, [rcx+0C0h]
vmovdqa64 EVEXR128N4, [rcx+0E0h]
mov rcx, [rcx+0F0h]
vmovdqu64 [rdx+00h], EVEXR512N0
vmovdqu64 [rdx+40h], EVEXR512N1
vmovdqu64 [rdx+80h], EVEXR512N2
vmovdqa64 [rdx+0C0h], EVEXR256N3
vmovdqa64 [rdx+0E0h], EVEXR128N4
mov [rdx+0F0h], rcx
vpxord EVEXR512N0,EVEXR512N0,EVEXR512N0
vpxord EVEXR512N1,EVEXR512N1,EVEXR512N1
vpxord EVEXR512N2,EVEXR512N2,EVEXR512N2
vpxord EVEXR256N3,EVEXR256N3,EVEXR256N3
vpxord EVEXR128N4,EVEXR128N4,EVEXR128N4
ret
align 16
Move280AVX512:
vmovdqu64 EVEXR512N0, [rcx+00h]
vmovdqu64 EVEXR512N1, [rcx+40h]
vmovdqu64 EVEXR512N2, [rcx+80h]
vmovdqu64 EVEXR512N3, [rcx+0C0h]
vmovdqa64 EVEXR128N4, [rcx+100h]
mov rcx, [rcx+110h]
vmovdqu64 [rdx+00h], EVEXR512N0
vmovdqu64 [rdx+40h], EVEXR512N1
vmovdqu64 [rdx+80h], EVEXR512N2
vmovdqu64 [rdx+0C0h], EVEXR512N3
vmovdqa64 [rdx+100h], EVEXR128N4
mov [rdx+110h], rcx
vpxord EVEXR512N0,EVEXR512N0,EVEXR512N0
vpxord EVEXR512N1,EVEXR512N1,EVEXR512N1
vpxord EVEXR512N2,EVEXR512N2,EVEXR512N2
vpxord EVEXR512N3,EVEXR512N3,EVEXR512N3
vpxord EVEXR128N4,EVEXR128N4,EVEXR128N4
ret
align 16
Move312AVX512:
vmovdqu64 EVEXR512N0, [rcx+00h]
vmovdqu64 EVEXR512N1, [rcx+40h]
vmovdqu64 EVEXR512N2, [rcx+80h]
vmovdqu64 EVEXR512N3, [rcx+0C0h]
vmovdqa64 EVEXR256N4, [rcx+100h]
vmovdqa64 EVEXR128N5, [rcx+120h]
mov rcx, [rcx+130h]
vmovdqu64 [rdx+00h], EVEXR512N0
vmovdqu64 [rdx+40h], EVEXR512N1
vmovdqu64 [rdx+80h], EVEXR512N2
vmovdqu64 [rdx+0C0h], EVEXR512N3
vmovdqa64 [rdx+100h], EVEXR256N4
vmovdqa64 [rdx+120h], EVEXR128N5
mov [rdx+130h], rcx
vpxord EVEXR512N0,EVEXR512N0,EVEXR512N0
vpxord EVEXR512N1,EVEXR512N1,EVEXR512N1
vpxord EVEXR512N2,EVEXR512N2,EVEXR512N2
vpxord EVEXR512N3,EVEXR512N3,EVEXR512N3
vpxord EVEXR256N4,EVEXR256N4,EVEXR256N4
vpxord EVEXR128N5,EVEXR128N5,EVEXR128N5
ret
align 16
Move344AVX512:
vmovdqu64 EVEXR512N0, [rcx+00h]
vmovdqu64 EVEXR512N1, [rcx+40h]
vmovdqu64 EVEXR512N2, [rcx+80h]
vmovdqu64 EVEXR512N3, [rcx+0C0h]
vmovdqu64 EVEXR512N4, [rcx+100h]
vmovdqa64 EVEXR128N5, [rcx+140h]
mov rcx, [rcx+150h]
vmovdqu64 [rdx+00h], EVEXR512N0
vmovdqu64 [rdx+40h], EVEXR512N1
vmovdqu64 [rdx+80h], EVEXR512N2
vmovdqu64 [rdx+0C0h], EVEXR512N3
vmovdqu64 [rdx+100h], EVEXR512N4
vmovdqa64 [rdx+140h], EVEXR128N5
mov [rdx+150h], rcx
vpxord EVEXR512N0,EVEXR512N0,EVEXR512N0
vpxord EVEXR512N1,EVEXR512N1,EVEXR512N1
vpxord EVEXR512N2,EVEXR512N2,EVEXR512N2
vpxord EVEXR512N3,EVEXR512N3,EVEXR512N3
vpxord EVEXR512N4,EVEXR512N4,EVEXR512N4
vpxord EVEXR128N5,EVEXR128N5,EVEXR128N5
ret
align 16
MoveX32LpAvx512WithErms:
; Make the counter negative based: The last 24 bytes are moved separately
mov eax, 8
sub r8, rax
add rcx, r8
add rdx, r8
neg r8
jns @MoveLast8
cmp r8, -2048 ; According to the Intel Manual, rep movsb outperforms AVX copy on blocks of 2048 bytes and above
jg @DontDoRepMovsb
align 4
@DoRepMovsb:
mov r10, rsi
mov r9, rdi
lea rsi, [rcx+r8]
lea rdi, [rdx+r8]
neg r8
add r8, rax
mov rcx, r8
cld
rep movsb
mov rdi, r9
mov rsi, r10
jmp @exit
align 16
@DontDoRepMovsb:
cmp r8, -(128+64)
jg @SmallAvxMove
mov eax, 128
sub rcx, rax
sub rdx, rax
add r8, rax
lea r9, [rdx+r8]
test r9b, 63
jz @Avx512BigMoveDestAligned
; destination is already 32-bytes aligned, so we just align by 64 bytes
vmovdqa64 EVEXR256N0, [rcx+r8]
vmovdqa64 [rdx+r8], EVEXR256N0
add r8, 20h
align 16
@Avx512BigMoveDestAligned:
vmovdqu64 EVEXR512N0, [rcx+r8+00h]
vmovdqu64 EVEXR512N1, [rcx+r8+40h]
vmovdqa64 [rdx+r8+00h], EVEXR512N0
vmovdqa64 [rdx+r8+40h], EVEXR512N1
add r8, rax
js @Avx512BigMoveDestAligned
sub r8, rax
add rcx, rax
add rdx, rax
align 16
@SmallAvxMove:
@MoveLoopAvx:
; Move a 16 byte block
vmovdqa64 EVEXR128N0, [rcx+r8]
vmovdqa64 [rdx+r8], EVEXR128N0
; Are there another 16 bytes to move?
add r8, 16
js @MoveLoopAvx
vpxord EVEXR512N0,EVEXR512N0,EVEXR512N0
vpxord EVEXR512N1,EVEXR512N1,EVEXR512N1
align 8
@MoveLast8:
; Do the last 8 bytes
mov rcx, [rcx+r8]
mov [rdx+r8], rcx
@exit:
ret

View File

@ -0,0 +1,74 @@
Frequently Asked Questions
--------------------------
Q: When my program shuts down FastMM reports that it has leaked memory. Is it possible that FastMM is wrong?
A: Unfortunately, no. If FastMM reports that a block has been leaked, then it means that a block was allocated but never freed - thus leaked. You may use FullDebugMode to shed more light on the cause of the problem.
Q: When I enable the FullDebugMode option my application crashes during startup. What's wrong?
A: The FastMM_FullDebugMode.dll library is required for FullDebugMode. Please make sure it is either in the same folder as the application, or it is accessible on the path.
Q: When a memory error pops up in "FullDebugMode" there is no debug info in the stack traces, only addresses. Why?
A: For the FastMM_FullDebugMode.dll library to determine unit/line number information for stack traces any one of the following has to be available: TD32 debug info, a .map file, a .jdbg file or embedded JCL debug info. If none of these are available you will only get addresses in stack traces. For line numbers to be shown you also need to enable "Debug Information", "Reference Info" and "Use Debug DCUs". Also, if the addresses are inside a dynamically loaded DLL that was unloaded before shutdown then FastMM will not be able to determine unit/line number info for them.
Q: I have enable FullDebugMode and get a log file containing stack traces of memory leaks, but no line numbers. Why?
A: To get line numbers you also need to enable "Debug Information", "Reference Info" and "Use Debug DCUs" on the "Compiler" tab of the "Project Options" dialog.
Q: My program used to work fine with the Borland memory manager, but I get an "Invalid Pointer Operation" or "Access Violation" with FastMM. Is there a bug in FastMM?
A: Highly unlikely. The memory manager is such a critical part of any program and is subjected to such a large amount of traffic that it is rare that a bug of this nature will make it through testing. FastMM works differently than the default memory manager and does more pointer checking, so it will catch more errors. For example: The default MM may allow you to free the same pointer twice while FastMM will immediately raise an "Invalid Pointer Operation" if you try to do so. Compile your application with the "FullDebugMode" option set in FastMM4.pas - this should raise an error closer to the source of the problem.
Q: My program used to work with replacement memory manager X, but I get an access violation when I try to use FastMM. Why?
A: There may still be a reference to the old memory manager somewhere in the source. Do a "find in files" and check that the old memory manager is not referenced in any "uses" clause. FastMM checks that it is the first memory manager that is being installed, but many other memory managers don't, so it's quite possible that another MM may be installing itself after FastMM.
Q: FastMM doesn't make my program any faster. What's wrong?
A: If your program does not spend much time allocating and freeing memory, then there is little that FastMM can do to speed it up. For example: If your application spends only 1% of its time allocating memory using the default memory manager, a blazingly fast memory manager can at best make it 1% faster. FastMM is much faster than the default memory manager of Delphi 2005 (and older Delphi versions), but if the bottleneck in your program is not memory management then your gains may not be as great as you had hoped.
Q: I have added FastMM4.pas as the very first unit in my project's .dpr file, but when I try to run my program it still complains that it is not the first unit. Why?
A: If you are using an exception handler that modifies the unit initialization order (like MadExcept or EurekaLog), you have to change its configuration so that FastMM is initialized first.
Q: Delphi 2005 crashes with an error message "Class 'TApplication', already if class map" (sic) when I replace the default borlndmm.dll with the FastMM DLL. Why?
A: It is due to a bug in Delphi 2005 (QC#14007). There is an unofficial patch available that fixes this. Refer to FastMM4_Readme.txt for details.
Q: I am using the replacement borlndmm.dll together with the Delphi IDE. When I open up two copies of Delphi and then close one down I get a memory leak report. Why?
A: When compiling the DLL you should set the "NeverUninstall" option.
Q: I am using the replacement borlndmm.dll together with the Delphi 2005 IDE. When I close the IDE it remains in task manager. Why?
A: This is due to a bug (QC#14070). When compiling the DLL you should set the "NeverUninstall" option to work around it.
Q: My program used to work fine, but if I enable "FullDebugMode" and run it I get an access violation at address $8080xxxx. Why?
A: You are attempting to access properties of a freed object. When you free a block in "FullDebugMode", FastMM fills the freed memory area with a pattern of $80 bytes. If there were any pointers, long strings or object references inside the freed object they will now point to $80808080 which is in a reserved address space.
Q: In "FullDebugMode" when an error occurs the stack traces are very incomplete. Why?
A: You have probably disabled the "RawStackTraces" option. Without that option set, FastMM can only do a stack trace for routines that set up a stack frame. In the "Project Options" window on the "Compiler" tab, enable the "Stack Frames" option to create stack frames for all procedures. Note that the "RawStackTraces" option usually results in more complete stack traces, but may also introduce more (unavoidable) "false alarm" entries in the stack traces.
Q: How do I get my DLL and main application to share FastMM so I can safely pass long strings and dynamic arrays between them?
A: The easiest way is to define ShareMM, ShareMMIfLibrary and AttemptToUseSharedMM in FastMM4.pas and add FastMM4.pas to the top of the uses section of the .dpr for both the main application and the DLL.
Q: I am using Windows x64 edition. How do I enable my applications to address more than 2GB RAM?
A: Add a line containing {$SetPEFlags $20} to the .dpr file. This will set the LARGE_ADDRESS_AWARE flag in the executable and Windows x64 will consequently give the process a full 4GB user address space instead of the usual 2GB.
Q: I get the following error when I try to use FastMM with an application compiled to use packages: "[Error] Need imported data reference ($G) to access 'IsMultiThread' from unit 'FastMM4'". How do I get it to work?
A: Enable the "UseRuntimePackages" option in FastMM4Options.inc.
Q: I use runtime packages, and when my application shuts down I get a huge memory leak report followed by lots of access violations. Why?
A: This is most likely a package unload order problem: FastMM is uninstalled (and does the leak check) before all live pointers have been freed, and when the application subsequently tries to free the remaining live pointers the A/Vs occur. Either ensure that FastMM is unloaded last (using sharemem together with the replacement borlndmm.dll is one way), or use the "NeverUninstall" option and disable the memory leak report.
Q: Since version 4.29 "FullDebugMode" is really slow. Why?
A: It is because of the new "RawStackTraces" option. Switch it off and performance will be on par with previous versions, but stack traces will be less complete.
Q: I notice there is a precompiled debug borlndmm.dll for the IDE. Why would I need that?
A: You most likely won't. It's for hunting bugs in the IDE.
Q: If I replace the borlndmm.dll used by the IDE, how does this affect the memory manager used by my applications?
A: It doesn't. If your application has sharemem.pas as the first unit in the project's .dpr file then it will use the first borlndmm.dll it finds on the path. It does not have to be the same one that the IDE uses.
Q: Does enabling memory leak checking make my application slower?
A: No. Leak checking is only performed when the application shuts down.
Q: With both the FullDebugMode and RawStackTraces options enabled I sometimes get stack traces with entries in them that cannot possibly be correct. Why?
A: This is an unfortunate side-effect of doing a raw stack trace. While raw stack traces are usually more complete than the alternate frame-based tracing (used when the RawStackTraces option is disabled), it does sometimes raise false alarms when data entries on the stack happen to correspond to valid return addresses in program code. While the raw stack trace code does extensive tests to differentiate between data and return addresses, it does get it wrong sometimes and these incorrect entries are the result.
Q: I am trying to use FastMM inside a Kylix library, but I get a segmentation fault. Why?
A: Linux requires the code inside libraries to be position independent (with the base address indicated by ebx). The assembler code inside FastMM uses the ebx register for other purposes and is thus not position independent. If you want to use FastMM inside a Kylix library you have to disable the "ASMVersion" option in FastMM4Options.inc.
Q: How can I share the memory manager between BDS2006 applications that don't use FastMM and libraries that use FastMM (or vice versa)?
A: Add the SimpleShareMem.pas file as the first unit in the uses section of projects that use the default Delphi 2006 MM, and make sure that the sharing mechanism of FastMM ("ShareMM" and "AttemptToUseSharedMM" options) is enabled for projects that use FastMM, but also enable the "EnableSharingWithDefaultMM" option.

View File

@ -0,0 +1,125 @@
Fast Memory Manager - Readme
----------------------------
Description:
------------
A fast replacement memory manager for Embarcadero Delphi Win32 applications that scales well under multi-threaded usage, is not prone to memory fragmentation, and supports shared memory without the use of external .DLL files.
Homepage:
---------
https://github.com/pleriche/FastMM4
Usage:
------
Delphi: Place this unit as the very first unit under the "uses" section in your project's .dpr file. When sharing memory between an application and a DLL (e.g. when passing a long string or dynamic array to a DLL function), both the main application and the DLL must be compiled using this memory manager (with the required conditional defines set). There are some conditional defines (inside FastMM4Options.inc) that may be used to tweak the memory manager. To enable support for a user mode address space greater than 2GB you will have to use the EditBin* tool to set the LARGE_ADDRESS_AWARE flag in the EXE header. This informs Windows x64 or Windows 32-bit (with the /3GB option set) that the application supports an address space larger than 2GB (up to 4GB). In Delphi 6 and later you can also specify this flag through the compiler directive {$SetPEFlags $20}
*The EditBin tool ships with the MS Visual C compiler.
C++ Builder 6: Refer to the instructions inside FastMM4BCB.cpp.
License:
--------
This work is copyright Professional Software Development / Pierre le Riche. It is released under a dual license, and you may choose to use it under either the Mozilla Public License 1.1 (MPL 1.1, available from http://www.mozilla.org/MPL/MPL-1.1.html) or the GNU Lesser General Public License 2.1 (LGPL 2.1, available from http://www.opensource.org/licenses/lgpl-license.php). If you find FastMM useful or you would like to support further development, a donation would be much appreciated. My banking details are:
Country: South Africa
Bank: ABSA Bank Ltd
Branch: Somerset West
Branch Code: 334-712
Account Name: PSD (Distribution)
Account No.: 4041827693
Swift Code: ABSAZAJJ
My PayPal account is:
bof@psd.co.za
Contact Details:
----------------
My contact details are shown below if you would like to get in touch with me. If you use this memory manager I would like to hear from you: please e-mail me your comments - good and bad.
Snailmail:
PO Box 2514
Somerset West
7129
South Africa
E-mail:
plr@psd.co.za
Support:
--------
If you have trouble using FastMM, you are welcome to drop me an e-mail at the address above, or you may post your questions in the BASM newsgroup on the Embarcadero news server (which is where I hang out quite frequently).
Disclaimer:
-----------
FastMM has been tested extensively with both single and multithreaded applications on various hardware platforms, but unfortunately I am not in a position to make any guarantees. Use it at your own risk.
This archive contains:
----------------------
1) FastMM4.pas - The replacement memory manager (to speed up your applications)
2) CPP Builder Support\FastMM4BCB.cpp - The Borland C++ Builder 6 support unit for FastMM4
3) Replacement BorlndMM DLL\BorlndMM.dpr - The project to build a replacement borlndmm.dll (to speed up the Delphi IDE)
4) FullDebugMode DLL\FastMM_FullDebugMode.dpr - The project to build the FastMM_FullDebugMode.dll. This support DLL is required only when using "FullDebugMode".
5) Usage Tracker\FastMMUsageTracker.pas - The address space and memory manager state monitoring utility for FastMM. (A demo is included in the same folder.)
6) Translations - This folder contains FastMM4Messages.pas files translated to various languages. The default FastMM4Messages.pas (in this folder) is the English version.
Documentation for each part is available inside its folder and also as comments inside the source. Refer to the FAQ if you have any questions, or contact me via e-mail.
FastMM Optional Features (FastMM4Options.Inc):
----------------------------------------------
The default options in FastMM4Options.Inc are configured for optimal performance when FastMM4.pas is added as the first unit in the uses clause of the .dpr. There are various other options available that control the sharing of the memory manager between libraries and the main application, as well as the debugging features of FastMM. There is a short description for each option inside the FastMM4Options.inc file that explains what the option does.
By default, memory leak checking is enabled only if the application is being run inside the debugger, and on shutdown FastMM will report all unexpected memory leaks. (Expected memory leaks can be registered beforehand.)
"FullDebugMode" is a special mode that radically changes the way in which FastMM works, and is intended as an aid in debugging applications. When the "FullDebugMode" define is set, FastMM places a header and footer around every memory block in order to catch memory overwrite bugs. It also stores a stack trace whenever a block is allocated or freed, and these stack traces are displayed if FastMM detects an error involving the block. When blocks are freed they are filled with a special byte pattern that allows FastMM to detect blocks that were modified after being freed (blocks are checked before being reused, and also on shutdown), and also to detect when a virtual method of a freed object is called. FastMM can also be set to detect the use of an interface of a freed object, but this facility is mutually exclusive to the detection of invalid virtual method calls. When "FullDebugMode" is enabled then the FastMM_FullDebugMode.dll library will be required by the application, otherwise not.
FastMM Technical Details:
-------------------------
FastMM is actually three memory managers in one: small (<2.5K), medium (< 260K) and large (> 260K) blocks are managed separately.
Requests for large blocks are passed through to the operating system (VirtualAlloc) to be allocated from the top of the address space. (Medium and small blocks are allocated from the bottom of the address space - keeping them separate improves fragmentation behaviour).
The medium block manager obtains memory from the OS in 1.25MB chunks. These chunks are called "medium block pools" and are subdivided into medium blocks as the application requests them. Unused medium blocks are kept in double-linked lists. There are 1024 such lists, and since the medium block granularity is 256 bytes that means there is a bin for every possible medium block size. FastMM maintains a two-level "bitmap" of these lists, so there is never any need to step through them to find a suitable unused block - a few bitwise operations on the "bitmaps" is all that is required. Whenever a medium block is freed, FastMM checks the neighbouring blocks to determine whether they are unused and can thus be combined with the block that is being freed. (There may never be two neighbouring medium blocks that are both unused.) FastMM has no background "clean-up" thread, so everything must be done as part of the freemem/getmem/reallocmem call.
In an object oriented programming language like Delphi, most memory allocations and frees are usually for small objects. In practical tests with various Delphi applications it was found that, on average, over 99% of all memory operations involve blocks <2K. It thus makes sense to optimize specifically for these small blocks. Small blocks are allocated from "small block pools". Small block pools are actually medium blocks that are subdivided into equal sized small blocks. Since a particular small block pool contains only equal sized blocks, and adjacent free small blocks are never combined, it allows the small block allocator to be greatly simplified and thus much faster. FastMM maintains a double-linked list of pools with available blocks for every small block size, so finding an available block for the requested size when servicing a getmem request is very speedy.
Moving data around in memory is typically a very expensive operation. Consequently, FastMM thus an intelligent reallocation algorithm to avoid moving memory as much as possible. When a block is upsized FastMM adjusts the block size in anticipation of future upsizes, thus improving the odds that the next reallocation can be done in place. When a pointer is resized to a smaller size, FastMM requires the new size to be significantly smaller than the old size otherwise the block will not be moved.
Speed is further improved by an improved locking mechanism: Every small block size, the medium blocks and large blocks are locked individually. If, when servicing a getmem request, the optimal block type is locked by another thread, then FastMM will try up to three larger block sizes. This design drastically reduces the number of thread contentions and improves performance for multi-threaded applications.
Important Notes Regarding Delphi 2005:
--------------------------------------
Presently the latest service pack for Delphi 2005 is SP3, but unfortunately there are still bugs that prevent a replacement borlndmm.dll from working stably with the Delphi 2005 IDE. There is a collection of unofficial patches that need to be installed before you can use the replacement borlndmm.dll with the Delphi 2005 IDE. You can get it from:
http://cc.embarcadero.com/item.aspx?id=23618
Installing these patches together with the replacement borlndmm.dll should provide you with a faster and more stable Delphi 2005 IDE.

View File

@ -0,0 +1,328 @@
unit FastMM_OSXUtil;
interface
type
LPCSTR = PAnsiChar;
LPSTR = PAnsiChar;
DWORD = Cardinal;
BOOL = Boolean;
PSystemTime = ^TSystemTime;
_SYSTEMTIME = record
wYear: Word;
wMonth: Word;
wDayOfWeek: Word;
wDay: Word;
wHour: Word;
wMinute: Word;
wSecond: Word;
wMilliseconds: Word;
end;
TSystemTime = _SYSTEMTIME;
SYSTEMTIME = _SYSTEMTIME;
SIZE_T = NativeUInt;
PUINT_PTR = ^UIntPtr;
const
PAGE_NOACCESS = 1;
PAGE_READONLY = 2;
PAGE_READWRITE = 4;
PAGE_WRITECOPY = 8;
PAGE_EXECUTE = $10;
PAGE_EXECUTE_READ = $20;
PAGE_EXECUTE_READWRITE = $40;
PAGE_GUARD = $100;
PAGE_NOCACHE = $200;
MEM_COMMIT = $1000;
MEM_RESERVE = $2000;
MEM_DECOMMIT = $4000;
MEM_RELEASE = $8000;
MEM_FREE = $10000;
MEM_PRIVATE = $20000;
MEM_MAPPED = $40000;
MEM_RESET = $80000;
MEM_TOP_DOWN = $100000;
EXCEPTION_ACCESS_VIOLATION = DWORD($C0000005);
//function GetModuleHandleA(lpModuleName: LPCSTR): HMODULE; stdcall;
function GetEnvironmentVariableA(lpName: LPCSTR; lpBuffer: LPSTR; nSize: DWORD): DWORD; stdcall; overload;
function DeleteFileA(lpFileName: LPCSTR): BOOL; stdcall;
function VirtualAlloc(lpvAddress: Pointer; dwSize: SIZE_T; flAllocationType, flProtect: DWORD): Pointer; stdcall;
function VirtualFree(lpAddress: Pointer; dwSize, dwFreeType: Cardinal): LongBool; stdcall;
procedure RaiseException(dwExceptionCode, dwExceptionFlags, nNumberOfArguments: DWORD;
lpArguments: PUINT_PTR); stdcall;
type
PSecurityAttributes = ^TSecurityAttributes;
_SECURITY_ATTRIBUTES = record
nLength: DWORD;
lpSecurityDescriptor: Pointer;
bInheritHandle: BOOL;
end;
TSecurityAttributes = _SECURITY_ATTRIBUTES;
SECURITY_ATTRIBUTES = _SECURITY_ATTRIBUTES;
const
GENERIC_READ = DWORD($80000000);
GENERIC_WRITE = $40000000;
OPEN_ALWAYS = 4;
FILE_ATTRIBUTE_NORMAL = $00000080;
FILE_BEGIN = 0;
FILE_CURRENT = 1;
FILE_END = 2;
INVALID_SET_FILE_POINTER = DWORD(-1);
procedure GetLocalTime(var lpSystemTime: TSystemTime); stdcall;
function CreateFileA(lpFileName: LPCSTR; dwDesiredAccess, dwShareMode: DWORD;
lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD;
hTemplateFile: THandle): THandle; stdcall;
function SetFilePointer(hFile: THandle; lDistanceToMove: Longint;
lpDistanceToMoveHigh: PLongInt; dwMoveMethod: DWORD): DWORD; stdcall;
function CloseHandle(hObject: THandle): BOOL; stdcall;
implementation
uses
Posix.Stdlib, Posix.Unistd, Posix.SysMman, Posix.Fcntl, Posix.SysStat, Posix.SysTime, Posix.Time, Posix.Errno, Posix.Signal;
function CreateFileA(lpFileName: LPCSTR; dwDesiredAccess, dwShareMode: DWORD;
lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD;
hTemplateFile: THandle): THandle; stdcall;
var
Flags: Integer;
FileAccessRights: Integer;
begin
// O_RDONLY open for reading only
// O_WRONLY open for writing only
// O_RDWR open for reading and writing
// O_NONBLOCK do not block on open or for data to become available
// O_APPEND append on each write
// O_CREAT create file if it does not exist
// O_TRUNC truncate size to 0
// O_EXCL error if O_CREAT and the file exists
// O_SHLOCK atomically obtain a shared lock
// O_EXLOCK atomically obtain an exclusive lock
// O_NOFOLLOW do not follow symlinks
// O_SYMLINK allow open of symlinks
// O_EVTONLY descriptor requested for event notifications only
// O_CLOEXEC mark as close-on-exec
Flags := 0;
FileAccessRights := S_IRUSR or S_IWUSR or S_IRGRP or S_IWGRP or S_IROTH or S_IWOTH;
case dwDesiredAccess and (GENERIC_READ or GENERIC_WRITE) of //= (GENERIC_READ or GENERIC_WRITE) then
GENERIC_READ or GENERIC_WRITE: Flags := Flags or O_RDWR;
GENERIC_READ: Flags := Flags or O_RDONLY;
GENERIC_WRITE: Flags := Flags or O_WRONLY;
else
Exit(THandle(-1));
end;
case dwCreationDisposition of
// CREATE_NEW:
// CREATE_ALWAYS:
// OPEN_EXISTING:
OPEN_ALWAYS: Flags := Flags or O_CREAT;
// TRUNCATE_EXISTING:
end;
Result := THandle(__open(lpFileName, Flags, FileAccessRights));
// ShareMode
// smode := Mode and $F0 shr 4;
// if ShareMode[smode] <> 0 then
// begin
// LockVar.l_whence := SEEK_SET;
// LockVar.l_start := 0;
// LockVar.l_len := 0;
// LockVar.l_type := ShareMode[smode];
// Tvar := fcntl(FileHandle, F_SETLK, LockVar);
// Code := errno;
// if (Tvar = -1) and (Code <> EINVAL) and (Code <> ENOTSUP) then
// EINVAL/ENOTSUP - file doesn't support locking
// begin
// __close(FileHandle);
// Exit;
// end;
end;
type
_LARGE_INTEGER = record
case Integer of
0: (
LowPart: DWORD;
HighPart: Longint);
1: (
QuadPart: Int64);
end;
function SetFilePointer(hFile: THandle; lDistanceToMove: Longint;
lpDistanceToMoveHigh: PLongInt; dwMoveMethod: DWORD): DWORD; stdcall;
var
dist: _LARGE_INTEGER;
begin
dist.LowPart := lDistanceToMove;
if Assigned(lpDistanceToMoveHigh) then
dist.HighPart := lpDistanceToMoveHigh^
else
dist.HighPart := 0;
dist.QuadPart := lseek(hFile, dist.QuadPart, dwMoveMethod); // dwMoveMethod = same as in windows
if dist.QuadPart = -1 then
Result := DWORD(-1)
else
begin
Result := dist.LowPart;
if Assigned(lpDistanceToMoveHigh) then
lpDistanceToMoveHigh^ := dist.HighPart;
end;
end;
procedure GetLocalTime(var lpSystemTime: TSystemTime); stdcall;
var
T: time_t;
TV: timeval;
UT: tm;
begin
gettimeofday(TV, nil);
T := TV.tv_sec;
localtime_r(T, UT);
lpSystemTime.wYear := UT.tm_year;
lpSystemTime.wMonth := UT.tm_mon;
lpSystemTime.wDayOfWeek := UT.tm_wday;
lpSystemTime.wDay := UT.tm_mday;
lpSystemTime.wHour := UT.tm_hour;
lpSystemTime.wMinute := UT.tm_min;
lpSystemTime.wSecond := UT.tm_sec;
lpSystemTime.wMilliseconds := 0;
end;
function CloseHandle(hObject: THandle): BOOL; stdcall;
begin
Result := __close(hObject) = 0;
end;
function StrLen(const Str: PAnsiChar): Cardinal;
begin
Result := Length(Str);
end;
function StrLCopy(Dest: PAnsiChar; const Source: PAnsiChar; MaxLen: Cardinal): PAnsiChar;
var
Len: Cardinal;
begin
Result := Dest;
Len := StrLen(Source);
if Len > MaxLen then
Len := MaxLen;
Move(Source^, Dest^, Len * SizeOf(AnsiChar));
Dest[Len] := #0;
end;
function StrPLCopy(Dest: PAnsiChar; const Source: AnsiString; MaxLen: Cardinal): PAnsiChar;
begin
Result := StrLCopy(Dest, PAnsiChar(Source), MaxLen);
end;
function GetModuleHandle(lpModuleName: PWideChar): HMODULE;
begin
Result := 0;
if lpModuleName = 'kernel32' then
Result := 1;
end;
function GetModuleHandleA(lpModuleName: LPCSTR): HMODULE; stdcall;
begin
Result := GetModuleHandle(PChar(string(lpModuleName)));
end;
function GetEnvironmentVariableA(lpName: LPCSTR; lpBuffer: LPSTR; nSize: DWORD): DWORD; stdcall; overload;
var
Len: Integer;
Env: string;
begin
env := string(getenv(lpName));
Len := Length(env);
Result := Len;
if nSize < Result then
Result := nSize;
StrPLCopy(lpBuffer, env, Result);
if Len > nSize then
SetLastError(122) //ERROR_INSUFFICIENT_BUFFER)
else
SetLastError(0);
end;
function DeleteFileA(lpFileName: LPCSTR): BOOL; stdcall;
begin
Result := unlink(lpFileName) <> -1;
end;
// ReservedBlock := VirtualAlloc(Pointer(DebugReservedAddress), 65536, MEM_RESERVE, PAGE_NOACCESS);
function VirtualAlloc(lpvAddress: Pointer; dwSize: SIZE_T; flAllocationType, flProtect: DWORD): Pointer; stdcall;
var
PageSize: LongInt;
AllocSize: LongInt;
Protect: Integer;
begin
if lpvAddress <> nil then
begin
if flAllocationType <> MEM_RESERVE then
Exit(0);
if flProtect <> PAGE_NOACCESS then
Exit(0);
PageSize := sysconf(_SC_PAGESIZE);
AllocSize := dwSize - (dwSize mod PageSize) + PageSize;
Result := mmap(lpvAddress, AllocSize, PROT_NONE, MAP_PRIVATE or MAP_ANON, -1, 0);
Exit;
end;
Result := malloc(dwSize);
FillChar(Result^, dwSize, 0);
//Result := valloc(dwSize);
// FreeItem.Addr := mmap(nil, PageSize, PROT_WRITE or PROT_EXEC,
// MAP_PRIVATE or MAP_ANON, -1, 0);
end;
function VirtualFree(lpAddress: Pointer; dwSize, dwFreeType: Cardinal): LongBool; stdcall;
begin
Result := True;
if dwFreetype = MEM_RELEASE then
begin
if lpAddress = Pointer($80800000) then
munmap(lpAddress, dwSize)
else
free(lpAddress);
end;
end;
procedure RaiseException(dwExceptionCode, dwExceptionFlags, nNumberOfArguments: DWORD;
lpArguments: PUINT_PTR); stdcall;
begin
WriteLN('ACCESS VIOLATION (set breakpoint in FastMM_OSXUtil: RaiseException for easier debugging)');
kill(getppid, SIGSEGV);
asm int 3; end;
end;
end.

View File

@ -0,0 +1,3 @@
C++ Builder projects can statically link to FastMM_FullDebugMode.dll. For that FastMM_FullDebugMode.lib is needed.
- JiYuan Xie

View File

@ -0,0 +1,43 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Condition="Exists('$(BDS)\bin\CodeGear.Deployment.targets')" Project="$(BDS)\bin\CodeGear.Deployment.targets"/>
<ProjectExtensions>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<ItemGroup Condition="'$(Platform)'=='iOSDevice'"/>
<ItemGroup Condition="'$(Platform)'=='Android'"/>
<ItemGroup Condition="'$(Platform)'=='Win32'"/>
<ItemGroup Condition="'$(Platform)'=='OSX32'">
<DeployFile Include="libFastMM_FullDebugMode.dylib.rsm" Condition="'$(Config)'=='Debug'">
<RemoteDir>FastMM_FullDebugMode\</RemoteDir>
<RemoteName>libFastMM_FullDebugMode.dylib.rsm</RemoteName>
<Operation>1</Operation>
<LocalCommand/>
<RemoteCommand/>
</DeployFile>
<DeployFile Include="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib">
<RemoteDir>FastMM_FullDebugMode\</RemoteDir>
<RemoteName>libcgunwind.1.0.dylib</RemoteName>
<Operation>1</Operation>
<LocalCommand/>
<RemoteCommand/>
</DeployFile>
<DeployFile Include="libFastMM_FullDebugMode.dylib" Condition="'$(Config)'=='Debug'">
<RemoteDir>FastMM_FullDebugMode\</RemoteDir>
<RemoteName>libFastMM_FullDebugMode.dylib</RemoteName>
<Operation>1</Operation>
<LocalCommand/>
<RemoteCommand/>
<Required>True</Required>
</DeployFile>
</ItemGroup>
<ItemGroup Condition="'$(Platform)'=='Win64'"/>
<ItemGroup Condition="'$(Platform)'=='iOSSimulator'">
<DeployFile Include="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib">
<RemoteDir>FastMM_FullDebugMode.app\</RemoteDir>
<RemoteName>libcgunwind.1.0.dylib</RemoteName>
<Operation>0</Operation>
<LocalCommand/>
<RemoteCommand/>
</DeployFile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,748 @@
{
Fast Memory Manager: FullDebugMode Support DLL 1.62
Description:
Support DLL for FastMM. With this DLL available, FastMM will report debug info
(unit name, line numbers, etc.) for stack traces.
Usage:
1) To compile you will need the JCL library (http://sourceforge.net/projects/jcl/)
2) Place in the same location as the replacement borlndmm.dll or your
application's executable module.
Change log:
Version 1.00 (9 July 2005):
- Initial release.
Version 1.01 (13 July 2005):
- Added the option to use madExcept instead of the JCL Debug library. (Thanks
to Martin Aignesberger.)
Version 1.02 (30 September 2005):
- Changed options to display detail for addresses inside libraries as well.
Version 1.03 (13 October 2005):
- Added a raw stack trace procedure that implements raw stack traces.
Version 1.10 (14 October 2005):
- Improved the program logic behind the skipping of stack levels to cause
less incorrect entries in raw stack traces. (Thanks to Craig Peterson.)
Version 1.20 (17 October 2005):
- Improved support for madExcept stack traces. (Thanks to Mathias Rauen.)
Version 1.30 (26 October 2005):
- Changed name to FastMM_FullDebugMode to reflect the fact that there is now
a static dependency on this DLL for FullDebugMode. The static dependency
solves a DLL unload order issue. (Thanks to Bart van der Werf.)
Version 1.40 (31 October 2005):
- Added support for EurekaLog. (Thanks to Fabio Dell'Aria.)
Version 1.42 (23 June 2006):
- Fixed a bug in the RawStackTraces code that may have caused an A/V in some
rare circumstances. (Thanks to Primoz Gabrijelcic.)
Version 1.44 (16 November 2006):
- Changed the RawStackTraces code to prevent it from modifying the Windows
"GetLastError" error code. (Thanks to Primoz Gabrijelcic.)
Version 1.50 (14 August 2008):
- Added support for Delphi 2009. (Thanks to Mark Edington.)
Version 1.60 (5 May 2009):
- Improved the code used to identify call instructions in the stack trace
code. (Thanks to the JCL team.)
Version 1.61 (5 September 2010):
- Recompiled using the latest JCL in order to fix a possible crash on shutdown
when the executable contains no debug information. (Thanks to Hanspeter
Widmer.)
Version 1.62 (19 July 2012):
- Added a workaround for QC 107209 (Thanks to David Heffernan.)
Version 1.63 (14 September 2013):
- Added support for OSX (Thanks to Sebastian Zierer)
}
{$IFDEF MSWINDOWS}
{--------------------Start of options block-------------------------}
{Select the stack tracing library to use. The JCL, madExcept and EurekaLog are
supported. Only one can be used at a time.}
{$define JCLDebug}
{.$define madExcept}
{.$define EurekaLog}
{--------------------End of options block-------------------------}
{$ENDIF}
// JCL_DEBUG_EXPERT_INSERTJDBG OFF
library FastMM_FullDebugMode;
uses
{$ifdef JCLDebug}JCLDebug,{$endif}
{$ifdef madExcept}madStackTrace,{$endif}
{$ifdef EurekaLog}ExceptionLog,{$endif}
SysUtils, {$IFDEF MACOS}Posix.Base, SBMapFiles {$ELSE} Windows {$ENDIF};
{$R *.res}
{$stackframes on}
{The name of the 64-bit DLL has a '64' at the end.}
{$if SizeOf(Pointer) = 8}
{$LIBSUFFIX '64'}
{$ifend}
{$if CompilerVersion <= 20}
type
NativeUInt = Cardinal; // not available or cause for internal compiler errors (e.g. Delphi 2009)
PNativeUInt = ^NativeUInt;
{$ifend}
{--------------------------Stack Tracing Subroutines--------------------------}
procedure GetStackRange(var AStackBaseAddress, ACurrentStackPointer: NativeUInt);
asm
{$if SizeOf(Pointer) = 8}
mov rax, gs:[abs 8]
mov [rcx], rax
mov [rdx], rbp
{$else}
mov ecx, fs:[4]
mov [eax], ecx
mov [edx], ebp
{$ifend}
end;
{--------------------------Frame Based Stack Tracing--------------------------}
{$if SizeOf(Pointer) = 8}
function CaptureStackBackTrace(FramesToSkip, FramesToCapture: DWORD;
BackTrace: Pointer; BackTraceHash: PDWORD): Word;
external kernel32 name 'RtlCaptureStackBackTrace';
{We use the Windows API to do frame based stack tracing under 64-bit.}
procedure GetFrameBasedStackTrace(AReturnAddresses: PNativeUInt;
AMaxDepth, ASkipFrames: Cardinal);
begin
CaptureStackBackTrace(ASkipFrames, AMaxDepth, AReturnAddresses, nil);
end;
{$else}
{Dumps the call stack trace to the given address. Fills the list with the
addresses where the called addresses can be found. This is the fast stack
frame based tracing routine.}
procedure GetFrameBasedStackTrace(AReturnAddresses: PNativeUInt;
AMaxDepth, ASkipFrames: Cardinal);
var
LStackTop, LStackBottom, LCurrentFrame: NativeUInt;
begin
{Get the call stack top and current bottom}
GetStackRange(LStackTop, LStackBottom);
Dec(LStackTop, SizeOf(Pointer) - 1);
{Get the current frame start}
LCurrentFrame := LStackBottom;
{Fill the call stack}
while (AMaxDepth > 0)
and (LCurrentFrame >= LStackBottom)
and (LCurrentFrame < LStackTop) do
begin
{Ignore the requested number of levels}
if ASkipFrames = 0 then
begin
AReturnAddresses^ := PNativeUInt(LCurrentFrame + SizeOf(Pointer))^;
Inc(AReturnAddresses);
Dec(AMaxDepth);
end
else
Dec(ASkipFrames);
{Get the next frame}
LCurrentFrame := PNativeUInt(LCurrentFrame)^;
end;
{Clear the remaining entries}
while AMaxDepth > 0 do
begin
AReturnAddresses^ := 0;
Inc(AReturnAddresses);
Dec(AMaxDepth);
end;
end;
{$ifend}
{-----------------------------Raw Stack Tracing-----------------------------}
const
{Hexadecimal characters}
HexTable: array[0..15] of AnsiChar = '0123456789ABCDEF';
type
{The state of a memory page. Used by the raw stack tracing mechanism to
determine whether an address is a valid call site or not.}
TMemoryPageAccess = (mpaUnknown, mpaNotExecutable, mpaExecutable);
var
{There are a total of 1M x 4K pages in the (low) 4GB address space}
MemoryPageAccessMap: array[0..1024 * 1024 - 1] of TMemoryPageAccess;
{$IFDEF MSWINDOWS}
{Updates the memory page access map. Currently only supports the low 4GB of
address space.}
procedure UpdateMemoryPageAccessMap(AAddress: NativeUInt);
var
LMemInfo: TMemoryBasicInformation;
LAccess: TMemoryPageAccess;
LStartPage, LPageCount: NativeUInt;
begin
{Query the page}
if VirtualQuery(Pointer(AAddress), LMemInfo, SizeOf(LMemInfo)) <> 0 then
begin
{Get access type}
if (LMemInfo.State = MEM_COMMIT)
and (LMemInfo.Protect and (PAGE_EXECUTE_READ or PAGE_EXECUTE_READWRITE
or PAGE_EXECUTE_WRITECOPY or PAGE_EXECUTE) <> 0)
and (LMemInfo.Protect and PAGE_GUARD = 0) then
begin
LAccess := mpaExecutable
end
else
LAccess := mpaNotExecutable;
{Update the map}
LStartPage := NativeUInt(LMemInfo.BaseAddress) div 4096;
LPageCount := LMemInfo.RegionSize div 4096;
if LStartPage < NativeUInt(Length(MemoryPageAccessMap)) then
begin
if (LStartPage + LPageCount) >= NativeUInt(Length(MemoryPageAccessMap)) then
LPageCount := NativeUInt(Length(MemoryPageAccessMap)) - LStartPage;
FillChar(MemoryPageAccessMap[LStartPage], LPageCount, Ord(LAccess));
end;
end
else
begin
{Invalid address}
MemoryPageAccessMap[AAddress div 4096] := mpaNotExecutable;
end;
end;
{$ENDIF}
{Thread-safe version that avoids the global variable Default8087CW.}
procedure Set8087CW(ANewCW: Word);
var
L8087CW: Word;
asm
mov L8087CW, ANewCW
fnclex
fldcw L8087CW
end;
{$if CompilerVersion > 22}
{Thread-safe version that avoids the global variable DefaultMXCSR.}
procedure SetMXCSR(ANewMXCSR: Cardinal);
var
LMXCSR: Cardinal;
asm
{$if SizeOf(Pointer) <> 8}
cmp System.TestSSE, 0
je @exit
{$ifend}
{Remove the flag bits}
and ANewMXCSR, $ffc0
mov LMXCSR, ANewMXCSR
ldmxcsr LMXCSR
@exit:
end;
{$ifend}
{$IFDEF MSWINDOWS}
{Returns true if the return address is a valid call site. This function is only
safe to call while exceptions are being handled.}
function IsValidCallSite(AReturnAddress: NativeUInt): boolean;
var
LCallAddress: NativeUInt;
LCode8Back, LCode4Back, LTemp: Cardinal;
LOld8087CW: Word;
{$if CompilerVersion > 22}
LOldMXCSR: Cardinal;
{$ifend}
begin
{We assume (for now) that all code will execute within the first 4GB of
address space.}
if (AReturnAddress > $ffff) and (AReturnAddress <= $ffffffff) then
begin
{The call address is up to 8 bytes before the return address}
LCallAddress := AReturnAddress - 8;
{Update the page map}
if MemoryPageAccessMap[LCallAddress div 4096] = mpaUnknown then
UpdateMemoryPageAccessMap(LCallAddress);
{Check the page access}
if (MemoryPageAccessMap[LCallAddress div 4096] = mpaExecutable)
and (MemoryPageAccessMap[(LCallAddress + 8) div 4096] = mpaExecutable) then
begin
{Try to determine what kind of call it is (if any), more or less in order
of frequency of occurrence. (Code below taken from the Jedi Code Library
(jcl.sourceforge.net).) We need to retrieve the current floating point
control registers, since any external exception will reset it to the
DLL defaults which may not otherwise correspond to the defaults of the
main application (QC 107198).}
LOld8087CW := Get8087CW;
{$if CompilerVersion > 22}
LOldMXCSR := GetMXCSR;
{$ifend}
try
{5 bytes, CALL NEAR REL32}
if PByteArray(LCallAddress)[3] = $E8 then
begin
Result := True;
Exit;
end;
{Get the 4 bytes before the return address}
LCode4Back := PCardinal(LCallAddress + 4)^;
{2 byte call?}
LTemp := LCode4Back and $F8FF0000;
{2 bytes, CALL NEAR EAX}
if LTemp = $D0FF0000 then
begin
Result := True;
Exit;
end;
{2 bytes, CALL NEAR [EAX]}
if LTemp = $10FF0000 then
begin
LTemp := LCode4Back - LTemp;
if (LTemp <> $04000000) and (LTemp <> $05000000) then
begin
Result := True;
Exit;
end;
end;
{3 bytes, CALL NEAR [EAX+EAX*i]}
if (LCode4Back and $00FFFF00) = $0014FF00 then
begin
Result := True;
Exit;
end;
{3 bytes, CALL NEAR [EAX+$12]}
if ((LCode4Back and $00F8FF00) = $0050FF00)
and ((LCode4Back and $00070000) <> $00040000) then
begin
Result := True;
Exit;
end;
{4 bytes, CALL NEAR [EAX+EAX+$12]}
if Word(LCode4Back) = $54FF then
begin
Result := True;
Exit;
end;
{6 bytes, CALL NEAR [$12345678]}
LCode8Back := PCardinal(LCallAddress)^;
if (LCode8Back and $FFFF0000) = $15FF0000 then
begin
Result := True;
Exit;
end;
{6 bytes, CALL NEAR [EAX+$12345678]}
if ((LCode8Back and $F8FF0000) = $90FF0000)
and ((LCode8Back and $07000000) <> $04000000) then
begin
Result := True;
Exit;
end;
{7 bytes, CALL NEAR [EAX+EAX+$1234567]}
if (LCode8Back and $00FFFF00) = $0094FF00 then
begin
Result := True;
Exit;
end;
{7 bytes, CALL FAR $1234:12345678}
if (LCode8Back and $0000FF00) = $00009A00 then
begin
Result := True;
Exit;
end;
{Not a valid call site}
Result := False;
except
{The access has changed}
UpdateMemoryPageAccessMap(LCallAddress);
{The RTL sets the FPU control words to the default values if an
external exception occurs. Reset their values here to the values on
entry to this call.}
Set8087CW(LOld8087CW);
{$if CompilerVersion > 22}
SetMXCSR(LOldMXCSR);
{$ifend}
{Not executable}
Result := False;
end;
end
else
Result := False;
end
else
Result := False;
end;
{$ENDIF}
{Dumps the call stack trace to the given address. Fills the list with the
addresses where the called addresses can be found. This is the "raw" stack
tracing routine.}
{$IFDEF MACOS}
function backtrace(result: PNativeUInt; size: Integer): Integer; cdecl; external libc name '_backtrace';
function _NSGetExecutablePath(buf: PAnsiChar; BufSize: PCardinal): Integer; cdecl; external libc name '__NSGetExecutablePath';
{$ENDIF}
procedure GetRawStackTrace(AReturnAddresses: PNativeUInt;
AMaxDepth, ASkipFrames: Cardinal);
var
LStackTop, LStackBottom, LCurrentFrame, LNextFrame, LReturnAddress,
LStackAddress: NativeUInt;
LLastOSError: Cardinal;
{$IFDEF MACOS}
StackLog: PNativeUInt; //array[0..10] of Pointer;
Cnt: Integer;
I: Integer;
{$ENDIF}
begin
{$IFDEF MACOS}
{$POINTERMATH ON}
Cnt := AMaxDepth + ASkipFrames;
GetMem(StackLog, SizeOf(Pointer) * Cnt);
try
Cnt := backtrace(StackLog, Cnt);
for I := ASkipFrames to Cnt - 1 do
begin
// writeln('Stack: ', inttohex(NativeUInt(stacklog[I]), 8));
AReturnAddresses[I - ASkipFrames] := StackLog[I];
end;
finally
FreeMem(StackLog);
end;
{$POINTERMATH OFF}
{$ENDIF}
{Are exceptions being handled? Can only do a raw stack trace if the possible
access violations are going to be handled.}
{$IFDEF MSWINDOWS}
if Assigned(ExceptObjProc) then
begin
{Save the last Windows error code}
LLastOSError := GetLastError;
{Get the call stack top and current bottom}
GetStackRange(LStackTop, LStackBottom);
Dec(LStackTop, SizeOf(Pointer) - 1);
{Get the current frame start}
LCurrentFrame := LStackBottom;
{Fill the call stack}
while (AMaxDepth > 0)
and (LCurrentFrame < LStackTop) do
begin
{Get the next frame}
LNextFrame := PNativeUInt(LCurrentFrame)^;
{Is it a valid stack frame address?}
if (LNextFrame < LStackTop)
and (LNextFrame > LCurrentFrame) then
begin
{The pointer to the next stack frame appears valid: Get the return
address of the current frame}
LReturnAddress := PNativeUInt(LCurrentFrame + SizeOf(Pointer))^;
{Does this appear to be a valid return address}
if (LReturnAddress > $ffff) and (LReturnAddress <= $ffffffff) then
begin
{Is the map for this return address incorrect? It may be unknown or marked
as non-executable because a library was previously not yet loaded, or
perhaps this is not a valid stack frame.}
if MemoryPageAccessMap[(LReturnAddress - 8) div 4096] <> mpaExecutable then
UpdateMemoryPageAccessMap(LReturnAddress - 8);
{Is this return address actually valid?}
if IsValidCallSite(LReturnAddress) then
begin
{Ignore the requested number of levels}
if ASkipFrames = 0 then
begin
AReturnAddresses^ := LReturnAddress;
Inc(AReturnAddresses);
Dec(AMaxDepth);
end;
end
else
begin
{If the return address is invalid it implies this stack frame is
invalid after all.}
LNextFrame := LStackTop;
end;
end
else
begin
{The return address is bad - this is not a valid stack frame}
LNextFrame := LStackTop;
end;
end
else
begin
{This is not a valid stack frame}
LNextFrame := LStackTop;
end;
{Do not check intermediate entries if there are still frames to skip}
if ASkipFrames <> 0 then
begin
Dec(ASkipFrames);
end
else
begin
{Check all stack entries up to the next stack frame}
LStackAddress := LCurrentFrame + 2 * SizeOf(Pointer);
while (AMaxDepth > 0)
and (LStackAddress < LNextFrame) do
begin
{Get the return address}
LReturnAddress := PNativeUInt(LStackAddress)^;
{Is this a valid call site?}
if IsValidCallSite(LReturnAddress) then
begin
AReturnAddresses^ := LReturnAddress;
Inc(AReturnAddresses);
Dec(AMaxDepth);
end;
{Check the next stack address}
Inc(LStackAddress, SizeOf(Pointer));
end;
end;
{Do the next stack frame}
LCurrentFrame := LNextFrame;
end;
{Clear the remaining entries}
while AMaxDepth > 0 do
begin
AReturnAddresses^ := 0;
Inc(AReturnAddresses);
Dec(AMaxDepth);
end;
{Restore the last Windows error code, since a VirtualQuery call may have
modified it.}
SetLastError(LLastOSError);
end
else
begin
{Exception handling is not available - do a frame based stack trace}
GetFrameBasedStackTrace(AReturnAddresses, AMaxDepth, ASkipFrames);
end;
{$ENDIF}
end;
{-----------------------------Stack Trace Logging----------------------------}
{Gets the textual representation of the stack trace into ABuffer and returns
a pointer to the position just after the last character.}
{$ifdef JCLDebug}
{Converts an unsigned integer to a hexadecimal string at the buffer location,
returning the new buffer position.}
function NativeUIntToHexBuf(ANum: NativeUInt; APBuffer: PAnsiChar): PAnsiChar;
const
MaxDigits = 16;
var
LDigitBuffer: array[0..MaxDigits - 1] of AnsiChar;
LCount: Cardinal;
LDigit: NativeUInt;
begin
{Generate the digits in the local buffer}
LCount := 0;
repeat
LDigit := ANum;
ANum := ANum div 16;
LDigit := LDigit - ANum * 16;
Inc(LCount);
LDigitBuffer[MaxDigits - LCount] := HexTable[LDigit];
until ANum = 0;
{Add leading zeros}
while LCount < SizeOf(NativeUInt) * 2 do
begin
Inc(LCount);
LDigitBuffer[MaxDigits - LCount] := '0';
end;
{Copy the digits to the output buffer and advance it}
System.Move(LDigitBuffer[MaxDigits - LCount], APBuffer^, LCount);
Result := APBuffer + LCount;
end;
{Subroutine used by LogStackTrace}
procedure AppendInfoToString(var AString: string; const AInfo: string);
begin
if AInfo <> '' then
AString := Format('%s[%s]', [AString, AInfo]);
end;
function LogStackTrace(AReturnAddresses: PNativeUInt; AMaxDepth: Cardinal;
ABuffer: PAnsiChar): PAnsiChar;
var
LInd: Cardinal;
LAddress: NativeUInt;
LNumChars: Integer;
LInfo: TJCLLocationInfo;
LTempStr: string;
P: PChar;
begin
Result := ABuffer;
{$IFDEF CONDITIONALEXPRESSIONS} // Delphi 5+
{$IF declared(BeginGetLocationInfoCache)} // available depending on the JCL's version
BeginGetLocationInfoCache;
try
{$IFEND}
{$ENDIF}
for LInd := 0 to AMaxDepth - 1 do
begin
LAddress := AReturnAddresses^;
if LAddress = 0 then
Exit;
Result^ := #13;
Inc(Result);
Result^ := #10;
Inc(Result);
Result := NativeUIntToHexBuf(LAddress, Result);
{Get location info for the caller (at least one byte before the return
address).}
GetLocationInfo(Pointer(LAddress - 1), LInfo);
{Build the result string}
LTempStr := ' ';
AppendInfoToString(LTempStr, LInfo.SourceName);
AppendInfoToString(LTempStr, LInfo.UnitName);
{Remove UnitName from ProcedureName, no need to output it twice}
P := PChar(LInfo.ProcedureName);
if (StrLComp(P, PChar(LInfo.UnitName), Length(LInfo.UnitName)) = 0) and (P[Length(LInfo.UnitName)] = '.') then
AppendInfoToString(LTempStr, Copy(LInfo.ProcedureName, Length(LInfo.UnitName) + 2))
else
AppendInfoToString(LTempStr, LInfo.ProcedureName);
if LInfo.LineNumber <> 0 then
AppendInfoToString(LTempStr, IntToStr(LInfo.LineNumber));
{Return the result}
if Length(LTempStr) < 256 then
LNumChars := Length(LTempStr)
else
LNumChars := 255;
StrLCopy(Result, PAnsiChar(AnsiString(LTempStr)), LNumChars);
Inc(Result, LNumChars);
{Next address}
Inc(AReturnAddresses);
end;
{$IFDEF CONDITIONALEXPRESSIONS} // Delphi 5+
{$IF declared(BeginGetLocationInfoCache)} // available depending on the JCL's version
finally
EndGetLocationInfoCache;
end;
{$IFEND}
{$ENDIF}
end;
{$endif}
{$ifdef madExcept}
function LogStackTrace(AReturnAddresses: PNativeUInt;
AMaxDepth: Cardinal; ABuffer: PAnsiChar): PAnsiChar;
begin
{Needs madExcept 2.7i or madExcept 3.0a or a newer build}
Result := madStackTrace.FastMM_LogStackTrace(
AReturnAddresses,
AMaxDepth,
ABuffer,
{madExcept stack trace fine tuning}
false, //hide items which have no line number information?
true, //show relative address offset to procedure entrypoint?
true, //show relative line number offset to procedure entry point?
false //skip special noise reduction processing?
);
end;
{$endif}
{$ifdef EurekaLog}
function LogStackTrace(AReturnAddresses: PNativeUInt; AMaxDepth: Cardinal;
ABuffer: PAnsiChar): PAnsiChar;
begin
{Needs EurekaLog 5.0.5 or a newer build}
Result := ExceptionLog.FastMM_LogStackTrace(
AReturnAddresses, AMaxDepth, ABuffer,
{EurekaLog stack trace fine tuning}
False, // Show the DLLs functions call. <--|
// |-- See the note below!
False, // Show the BPLs functions call. <--|
True // Show relative line no. offset to procedure start point.
);
// NOTE:
// -----
// With these values set both to "False", EurekaLog try to returns the best
// call-stack available.
//
// To do this EurekaLog execute the following points:
// --------------------------------------------------
// 1)...try to fill all call-stack items using only debug data with line no.
// 2)...if remains some empty call-stack items from the previous process (1),
// EurekaLog try to fill these with the BPLs functions calls;
// 3)...if remains some empty call-stack items from the previous process (2),
// EurekaLog try to fill these with the DLLs functions calls;
end;
{$endif}
{$IFDEF MACOS}
{Appends the source text to the destination and returns the new destination
position}
function AppendStringToBuffer(const ASource, ADestination: PAnsiChar; ACount: Cardinal): PAnsiChar;
begin
System.Move(ASource^, ADestination^, ACount);
Result := Pointer(PByte(ADestination) + ACount);
end;
var
MapFile: TSBMapFile;
function LogStackTrace(AReturnAddresses: PNativeUInt;
AMaxDepth: Cardinal; ABuffer: PAnsiChar): PAnsiChar;
var
s1: AnsiString;
I: Integer;
FileName: array[0..255] of AnsiChar;
Len: Cardinal;
begin
{$POINTERMATH ON}
// writelN('LogStackTrace');
// for I := 0 to AMaxDepth - 1 do
// Writeln(IntToHex(AReturnAddresses[I], 8));
// s1 := IntToHex(Integer(AReturnAddresses[0]), 8);
// result := ABuffer;
// Move(pointer(s1)^, result^, Length(s1));
// inc(result, Length(s1));
if MapFile = nil then
begin
MapFile := TSBMapFile.Create;
Len := Length(FileName);
_NSGetExecutablePath(@FileName[0], @Len);
if FileExists(ChangeFileExt(FileName, '.map')) then
MapFile.LoadFromFile(ChangeFileExt(FileName, '.map'));
end;
Result := ABuffer;
s1 := #13#10;
Result := AppendStringToBuffer(PAnsiChar(s1), Result, Length(s1));
for I := 0 to AMaxDepth - 1 do
begin
s1 := IntToHex(AReturnAddresses[I], 8);
s1 := s1 + ' ' + MapFile.GetFunctionName(AReturnAddresses[I]) + #13#10;
Result := AppendStringToBuffer(PAnsiChar(s1), Result, Length(s1));
end;
{$POINTERMATH OFF}
end;
{$ENDIF}
{-----------------------------Exported Functions----------------------------}
exports
GetFrameBasedStackTrace,
GetRawStackTrace,
LogStackTrace;
begin
{$ifdef JCLDebug}
JclStackTrackingOptions := JclStackTrackingOptions + [stAllModules];
{$endif}
end.

View File

@ -0,0 +1,475 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{990612ba-64b5-4560-bc82-798c7cdf11d3}</ProjectGuid>
<MainSource>FastMM_FullDebugMode.dpr</MainSource>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
<DCC_DependencyCheckOutputName>FastMM_FullDebugMode.dll</DCC_DependencyCheckOutputName>
<FrameworkType>None</FrameworkType>
<ProjectVersion>15.3</ProjectVersion>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Release</Config>
<Platform Condition="'$(Platform)'==''">OSX32</Platform>
<TargetedPlatforms>7</TargetedPlatforms>
<AppType>Library</AppType>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='OSX32' and '$(Base)'=='true') or '$(Base_OSX32)'!=''">
<Base_OSX32>true</Base_OSX32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='OSX32' and '$(Cfg_1)'=='true') or '$(Cfg_1_OSX32)'!=''">
<Cfg_1_OSX32>true</Cfg_1_OSX32>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
<Cfg_1_Win32>true</Cfg_1_Win32>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win64)'!=''">
<Cfg_1_Win64>true</Cfg_1_Win64>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='OSX32' and '$(Cfg_2)'=='true') or '$(Cfg_2_OSX32)'!=''">
<Cfg_2_OSX32>true</Cfg_2_OSX32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win64)'!=''">
<Cfg_2_Win64>true</Cfg_2_Win64>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<Manifest_File>None</Manifest_File>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_MinorVer>61</VerInfo_MinorVer>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Build>6</VerInfo_Build>
<GenDll>true</GenDll>
<VerInfo_Locale>7177</VerInfo_Locale>
<VerInfo_Keys>CompanyName=PSD / Pierre le Riche;FileDescription=FastMM FullDebugMode Support DLL;FileVersion=1.61.0.6;InternalName=;LegalCopyright=(c) Professional Software Development;LegalTrademarks=Licence: MPL 1.1;OriginalFilename=FastMM_FullDebugMode.dll;ProductName=FastMM FullDebugMode Support DLL;ProductVersion=1.60;Comments=</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_OSX32)'!=''">
<Debugger_Launcher>/usr/X11/bin/xterm -e &quot;%debuggee%&quot;</Debugger_Launcher>
<VerInfo_IncludeVerInfo>false</VerInfo_IncludeVerInfo>
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<VerInfo_Build>0</VerInfo_Build>
<VerInfo_MinorVer>0</VerInfo_MinorVer>
<Debugger_HostApplication>FullDebugMode_DLL_TestApp.exe</Debugger_HostApplication>
<DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<VerInfo_Build>0</VerInfo_Build>
<VerInfo_MinorVer>0</VerInfo_MinorVer>
<Debugger_HostApplication>C:\Projects\CIMSO\Components\Current\PSD40\FastMM4\FullDebugMode DLL\FullDebugMode_DLL_TestApp.exe</Debugger_HostApplication>
<DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<Version>7.0</Version>
<DCC_DebugInformation>0</DCC_DebugInformation>
<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_MapFile>3</DCC_MapFile>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_OSX32)'!=''">
<VerInfo_IncludeVerInfo>false</VerInfo_IncludeVerInfo>
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_MinorVer>0</VerInfo_MinorVer>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Build>0</VerInfo_Build>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_MinorVer>0</VerInfo_MinorVer>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Build>0</VerInfo_Build>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<Version>7.0</Version>
<DCC_MapFile>3</DCC_MapFile>
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_OSX32)'!=''">
<Debugger_HostApplication>/Users/Sebastian/RADPAServer/scratch-dir/Sebastian-lsbx/Bug_DoubleFree/Bug_DoubleFree</Debugger_HostApplication>
<DCC_RemoteDebug>true</DCC_RemoteDebug>
<Debugger_Launcher>/usr/X11/bin/xterm -e &quot;%debuggee%&quot;</Debugger_Launcher>
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities</VerInfo_Keys>
<VerInfo_IncludeVerInfo>false</VerInfo_IncludeVerInfo>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win64)'!=''">
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
<DCC_RemoteDebug>true</DCC_RemoteDebug>
</PropertyGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType>VCLApplication</Borland.ProjectType>
<BorlandProject>
<Delphi.Personality>
<Parameters>
<Parameters Name="UseLauncher">False</Parameters>
<Parameters Name="LoadAllSymbols">True</Parameters>
<Parameters Name="LoadUnspecifiedSymbols">False</Parameters>
</Parameters>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">True</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">61</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">6</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">7177</VersionInfo>
<VersionInfo Name="CodePage">1252</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName">PSD / Pierre le Riche</VersionInfoKeys>
<VersionInfoKeys Name="FileDescription">FastMM FullDebugMode Support DLL</VersionInfoKeys>
<VersionInfoKeys Name="FileVersion">1.61.0.6</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright">(c) Professional Software Development</VersionInfoKeys>
<VersionInfoKeys Name="LegalTrademarks">Licence: MPL 1.1</VersionInfoKeys>
<VersionInfoKeys Name="OriginalFilename">FastMM_FullDebugMode.dll</VersionInfoKeys>
<VersionInfoKeys Name="ProductName">FastMM FullDebugMode Support DLL</VersionInfoKeys>
<VersionInfoKeys Name="ProductVersion">1.60</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
</VersionInfoKeys>
<Source>
<Source Name="MainSource">FastMM_FullDebugMode.dpr</Source>
</Source>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k190.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp190.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Platforms>
<Platform value="OSX32">True</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">True</Platform>
</Platforms>
<Deployment>
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="OSX32"/>
<Platform Name="iOSSimulator"/>
</DeployFile>
<DeployFile LocalName="libFastMM_FullDebugMode.dylib" Configuration="Debug" Class="ProjectOutput">
<Platform Name="OSX32"/>
</DeployFile>
<DeployFile LocalName="libFastMM_FullDebugMode.dylib.rsm" Configuration="Debug" Class="DebugSymbols">
<Platform Name="OSX32">
<RemoteName>libFastMM_FullDebugMode.dylib.rsm</RemoteName>
</Platform>
</DeployFile>
<DeployClass Required="true" Name="DependencyPackage">
<Platform Name="iOSDevice">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="DependencyModule">
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048">
<Platform Name="iOSDevice">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXInfoPList"/>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSDevice">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXEntitlements"/>
<DeployClass Name="AndroidGDBServer">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640">
<Platform Name="iOSDevice">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch320">
<Platform Name="iOSDevice">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon144">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyFramework">
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSEntitlements"/>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClassesDexFile">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceInfoPList"/>
<DeployClass Name="iPad_Launch1024">
<Platform Name="iOSDevice">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSSimulatorInfoPList"/>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXResource">
<Platform Name="OSX32">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceResourceRules"/>
<DeployClass Name="iPad_Launch768">
<Platform Name="iOSDevice">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="iOSDevice">
<Operation>1</Operation>
</Platform>
<Platform Name="Android">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="File">
<Platform Name="iOSDevice">
<Operation>0</Operation>
</Platform>
<Platform Name="Android">
<Operation>0</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640x1136">
<Platform Name="iOSDevice">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1536">
<Platform Name="iOSDevice">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectAndroidManifest">
<Platform Name="Android">
<Operation>1</Operation>
</Platform>
</DeployClass>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
</Deployment>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
<Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
</Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View File

@ -0,0 +1,70 @@
// JCL_DEBUG_EXPERT_INSERTJDBG ON
program FullDebugMode_DLL_TestApp;
{$APPTYPE CONSOLE}
{$R *.res}
{$stackframes on}
uses
System.SysUtils;
const
{$if SizeOf(Pointer) = 8}
FullDebugModeLibraryName = 'FastMM_FullDebugMode64.dll';
{$else}
FullDebugModeLibraryName = 'FastMM_FullDebugMode.dll';
{$ifend}
const
MaxEntries = 20;
SkipFrames = 0;
TextBufSize = 64 * 1024;
var
LReturnAddresses: array[0..MaxEntries - 1] of NativeUInt;
LTextBuffer: array[0..TextBufSize - 1] of AnsiChar;
{Procedures exported by the DLL that should be tested.}
procedure GetFrameBasedStackTrace(AReturnAddresses: PNativeUInt;
AMaxDepth, ASkipFrames: Cardinal); external FullDebugModeLibraryName;
procedure GetRawStackTrace(AReturnAddresses: PNativeUInt;
AMaxDepth, ASkipFrames: Cardinal); external FullDebugModeLibraryName;
function LogStackTrace(AReturnAddresses: PNativeUInt; AMaxDepth: Cardinal;
ABuffer: PAnsiChar): PAnsiChar; external FullDebugModeLibraryName;
procedure TestFrameBasedStackTrace;
begin
FillChar(LReturnAddresses, SizeOf(LReturnAddresses), 0);
FillChar(LTextBuffer, SizeOf(LTextBuffer), 0);
GetFrameBasedStackTrace(@LReturnAddresses, MaxEntries, SkipFrames);
LogStackTrace(@LReturnAddresses, MaxEntries, @LTextBuffer);
WriteLn(LTextBuffer);
end;
procedure TestRawStackTrace;
begin
FillChar(LReturnAddresses, SizeOf(LReturnAddresses), 0);
FillChar(LTextBuffer, SizeOf(LTextBuffer), 0);
GetRawStackTrace(@LReturnAddresses, MaxEntries, SkipFrames);
LogStackTrace(@LReturnAddresses, MaxEntries, @LTextBuffer);
WriteLn(LTextBuffer);
end;
procedure RunTest;
begin
TestFrameBasedStackTrace;
TestRawStackTrace;
end;
begin
try
RunTest;
ReadLn;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

View File

@ -0,0 +1,160 @@
 <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{C707C87D-D87C-425C-865F-60ADA26CA5BC}</ProjectGuid>
<ProjectVersion>13.4</ProjectVersion>
<FrameworkType>None</FrameworkType>
<MainSource>FullDebugMode_DLL_TestApp.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win64</Platform>
<TargetedPlatforms>3</TargetedPlatforms>
<AppType>Console</AppType>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win64)'!=''">
<Cfg_1_Win64>true</Cfg_1_Win64>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
<Cfg_1_Win32>true</Cfg_1_Win32>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<Manifest_File>None</Manifest_File>
<VerInfo_Locale>7177</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<DCC_UsePackage>bindcompfmx;fmx;rtl;dbrtl;IndySystem;DbxClientDriver;bindcomp;inetdb;DBXInterBaseDriver;DataSnapCommon;DataSnapClient;DataSnapServer;DataSnapProviderClient;xmlrtl;DbxCommonDriver;IndyProtocols;DBXMySQLDriver;dbxcds;soaprtl;bindengine;DBXOracleDriver;dsnap;DBXInformixDriver;IndyCore;fmxase;DBXFirebirdDriver;inet;fmxobj;inetdbxpress;DBXSybaseASADriver;fmxdae;dbexpress;DataSnapIndy10ServerTransport;IPIndyImpl;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<DCC_UsePackage>DBXOdbcDriver;DBXSybaseASEDriver;vclimg;vclactnband;vcldb;bindcompvcl;vcldsnap;Jcl;vclie;vcltouch;DBXDb2Driver;websnap;VclSmp;vcl;DBXMSSQLDriver;dsnapcon;vclx;webdsnap;JclDeveloperTools;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_UsePackage>vcldbx;TeeDB;vclib;inetdbbde;Tee;DBXOdbcDriver;svnui;ibxpress;DBXSybaseASEDriver;vclimg;vclactnband;FMXTee;vcldb;TeeUI;bindcompvcl;vcldsnap;Jcl;vclie;vcltouch;DBXDb2Driver;websnap;vclribbon;VclSmp;vcl;DataSnapConnectors;CloudService;DBXMSSQLDriver;FmxTeeUI;dsnapcon;vclx;webdsnap;svn;JclDeveloperTools;bdertl;adortl;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<DCC_RemoteDebug>true</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
<DCC_MapFile>3</DCC_MapFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<DCC_MapFile>3</DCC_MapFile>
<Manifest_File>None</Manifest_File>
<VerInfo_Locale>1033</VerInfo_Locale>
<DCC_RemoteDebug>false</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_DebugInformation>false</DCC_DebugInformation>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Debug">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">7177</VersionInfo>
<VersionInfo Name="CodePage">1252</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
</VersionInfoKeys>
<Source>
<Source Name="MainSource">FullDebugMode_DLL_TestApp.dpr</Source>
</Source>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k160.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp160.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Deployment/>
<Platforms>
<Platform value="Win64">True</Platform>
<Platform value="Win32">True</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
</Project>

View File

@ -0,0 +1,416 @@
# FastMM4-AVX
FastMM4-AVX (efficient synchronization and AVX1/AVX2/AVX512/ERMS/FSRM support for FastMM4)
- Copyright (C) 2017-2020 Ritlabs, SRL. All rights reserved.
- Copyright (C) 2020-2021 Maxim Masiutin. All rights reserved.
Written by Maxim Masiutin <maxim@masiutin.com>
Version 1.0.6
This is a fork of the "Fast Memory Manager" (FastMM) v4.993 by Pierre le Riche
(see below for the original FastMM4 description)
What was added to FastMM4-AVX in comparison to the original FastMM4:
- Efficient synchronization
- improved synchronization between the threads; proper synchronization
techniques are used depending on context and availability, i.e., spin-wait
loops, SwitchToThread, critical sections, etc.;
- used the "test, test-and-set" technique for the spin-wait loops; this
technique is recommended by Intel (see Section 11.4.3 "Optimization with
Spin-Locks" of the Intel 64 and IA-32 Architectures Optimization Reference
Manual) to determine the availability of the synchronization variable;
according to this technique, the first "test" is done via the normal
(non-locking) memory load to prevent excessive bus locking on each
iteration of the spin-wait loop; if the variable is available upon
the normal memory load of the first step ("test"), proceed to the
second step ("test-and-set") which is done via the bus-locking atomic
"xchg" instruction; however, this two-steps approach of using "test" before
"test-and-set" can increase the cost for the un-contended case comparing
to just single-step "test-and-set", this may explain why the speed benefits
of the FastMM4-AVX are more pronounced when the memory manager is called
from multiple threads in parallel, while in single-threaded use scenario
there may be no benefit compared to the original FastMM4;
- the number of iterations of "pause"-based spin-wait loops is 5000,
before relinquishing to SwitchToThread();
- see https://stackoverflow.com/a/44916975 for more details on the
implementation of the "pause"-based spin-wait loops;
- using normal memory store to release a lock:
FastMM4-AVX uses normal memory store, i.e., the "mov" instruction, rather
then the bus-locking "xchg" instruction to write into the synchronization
variable (LockByte) to "release a lock" on a data structure,
see https://stackoverflow.com/a/44959764
for discussion on releasing a lock;
you man define "InterlockedRelease" to get the old behavior of the original
FastMM4.
- implemented dedicated lock and unlock procedures that operate with
synchronization variables (LockByte);
before that, locking operations were scattered throughout the code;
now the locking functions have meaningful names:
AcquireLockByte and ReleaseLockByte;
the values of the lock byte are now checked for validity when
FullDebugMode or DEBUG is defined, to detect cases when the same lock is
released twice, and other improper use of the lock bytes;
- added compile-time options "SmallBlocksLockedCriticalSection",
"MediumBlocksLockedCriticalSection" and "LargeBlocksLockedCriticalSection"
which are set by default (inside the FastMM4Options.inc file) as
conditional defines. If you undefine these options, you will get the
old locking mechanism of the original FastMM4 based on loops of Sleep() or
SwitchToThread().
- AVX, AVX2 or AVX512 instructions for faster memory copy
- if the CPU supports AVX or AVX2, use the 32-byte YMM registers
for faster memory copy, and if the CPU supports AVX-512,
use the 64-byte ZMM registers for even faster memory copy;
- please note that the effect of using AVX instruction in speed improvement is
negligible, compared to the effect brought by efficient synchronization;
sometimes AVX instructions can even slow down the program because of AVX-SSE
transition penalties and reduced CPU frequency caused by AVX-512
instructions in some processors; use DisableAVX to turn AVX off completely
or use DisableAVX1/DisableAVX2/DisableAVX512 to disable separately certain
AVX-related instruction set from being compiled);
- if EnableAVX is defined, all memory blocks are aligned by 32 bytes, but
you can also use Align32Bytes define without AVX; please note that the memory
overhead is higher when the blocks are aligned by 32 bytes, because some
memory is lost by padding; however, if your CPU supports
"Fast Short REP MOVSB" (Ice Lake or newer), you can disable AVX, and align
by just 8 bytes, and this may even be faster because less memory is wasted
on alignment;
- with AVX, memory copy is secure - all XMM/YMM/ZMM registers used to copy
memory are cleared by vxorps/vpxor, so the leftovers of the copied memory
are not exposed in the XMM/YMM/ZMM registers;
- the code attempts to properly handle AVX-SSE transitions to not incur the
transition penalties, only call vzeroupper under AVX1, but not under AVX2
since it slows down subsequent SSE code under Skylake / Kaby Lake;
- on AVX-512, writing to xmm16-xmm31 registers will not affect the turbo
clocks, and will not impose AVX-SSE transition penalties; therefore, when we
have AVX-512, we now only use x(y/z)mm16-31 registers.
- Speed improvements due to code optimization and proper techniques
- if the CPU supports Enhanced REP MOVSB/STOSB (ERMS), use this feature
for faster memory copy (under 32 bit or 64-bit) (see the EnableERMS define,
on by default, use DisableERMS to turn it off);
- if the CPU supports Fast Short REP MOVSB (FSRM), uses this feature instead
of AVX;
- branch target alignment in assembly routines is only used when
EnableAsmCodeAlign is defined; Delphi incorrectly encodes conditional
jumps, i.e., use long, 6-byte instructions instead of just short, 2-byte,
and this may affect branch prediction, so the benefits of branch target
alignment may not outweigh the disadvantage of affected branch prediction,
see https://stackoverflow.com/q/45112065
- compare instructions + conditional jump instructions are put together
to allow macro-op fusion (which happens since Core2 processors, when
the first instruction is a CMP or TEST instruction and the second
instruction is a conditional jump instruction);
- multiplication and division by a constant, which is a power of 2
replaced to shl/shr, because Delphi64 compiler doesn't replace such
multiplications and divisions to shl/shr processor instructions,
and, according to the Intel Optimization Reference Manual, shl/shr is
faster than imul/idiv, at least for some processors.
- Safer, cleaner code with stricter type adherence and better compatibility
- names assigned to some constants that used to be "magic constants",
i.e., unnamed numerical constants - plenty of them were present
throughout the whole code;
- removed some typecasts; the code is stricter to let the compiler
do the job, check everything and mitigate probable error. You can
even compile the code with "integer overflow checking" and
"range checking", as well as with "typed @ operator" - for safer
code. Also added round bracket in the places where the typed @ operator
was used, to better emphasize on who's address is taken;
- the compiler environment is more flexible now: you can now compile FastMM4
with, for example, typed "@" operator or any other option. Almost all
externally-set compiler directives are honored by FastMM except a few
(currently just one) - look for the "Compiler options for FastMM4" section
below to see what options cannot be externally set and are always
redefined by FastMM4 for itself - even if you set up these compiler options
differently outside FastMM4, they will be silently
redefined, and the new values will be used for FastMM4 only;
- the type of one-byte synchronization variables (accessed via "lock cmpxchg"
or "lock xchg") replaced from Boolean to Byte for stricter type checking;
- those fixed-block-size memory move procedures that are not needed
(under the current bitness and alignment combinations) are
explicitly excluded from compiling, to not rely on the compiler
that is supposed to remove these function after compilation;
- added length parameter to what were the dangerous null-terminated string
operations via PAnsiChar, to prevent potential stack buffer overruns
(or maybe even stack-based exploitation?), and there some Pascal functions
also left, the argument is not yet checked. See the "todo" comments
to figure out where the length is not yet checked. Anyway, since these
memory functions are only used in Debug mode, i.e., in development
environment, not in Release (production), the impact of this
"vulnerability" is minimal (albeit this is a questionable statement);
- removed all non-US-ASCII characters, to avoid using UTF-8 BOM, for
better compatibility with very early versions of Delphi (e.g., Delphi 5),
thanks to Valts Silaputnins;
- support for Lazarus 1.6.4 with FreePascal (the original FastMM4 4.992
requires modifications, it doesn't work under Lazarus 1.6.4 with FreePascal
out-of-the-box, also tested under Lazarus 1.8.2 / FPC 3.0.4 with Win32
target; later versions should be also supported.
Here are the comparison of the Original FastMM4 version 4.992, with default
options compiled for Win64 by Delphi 10.2 Tokyo (Release with Optimization),
and the current FastMM4-AVX branch ("AVX-br."). Under some multi-threading
scenarios, the FastMM4-AVX branch is more than twice as fast compared to the
Original FastMM4. The tests have been run on two different computers: one
under Xeon E5-2543v2 with 2 CPU sockets, each has 6 physical cores
(12 logical threads) - with only 5 physical core per socket enabled for the
test application. Another test was done under an i7-7700K CPU.
Used the "Multi-threaded allocate, use and free" and "NexusDB"
test cases from the FastCode Challenge Memory Manager test suite,
modified to run under 64-bit.
Xeon E5-2543v2 2*CPU i7-7700K CPU
(allocated 20 logical (8 logical threads,
threads, 10 physical 4 physical cores),
cores, NUMA), AVX-1 AVX-2
Orig. AVX-br. Ratio Orig. AVX-br. Ratio
------ ----- ------ ----- ----- ------
02-threads realloc 96552 59951 62.09% 65213 49471 75.86%
04-threads realloc 97998 39494 40.30% 64402 47714 74.09%
08-threads realloc 98325 33743 34.32% 64796 58754 90.68%
16-threads realloc 116273 45161 38.84% 70722 60293 85.25%
31-threads realloc 122528 53616 43.76% 70939 62962 88.76%
64-threads realloc 137661 54330 39.47% 73696 64824 87.96%
NexusDB 02 threads 122846 90380 73.72% 79479 66153 83.23%
NexusDB 04 threads 122131 53103 43.77% 69183 43001 62.16%
NexusDB 08 threads 124419 40914 32.88% 64977 33609 51.72%
NexusDB 12 threads 181239 55818 30.80% 83983 44658 53.18%
NexusDB 16 threads 135211 62044 43.61% 59917 32463 54.18%
NexusDB 31 threads 134815 48132 33.46% 54686 31184 57.02%
NexusDB 64 threads 187094 57672 30.25% 63089 41955 66.50%
The above tests have been run on 14-Jul-2017.
Here are some more test results (Compiled by Delphi 10.2 Update 3):
Xeon E5-2667v4 2*CPU i9-7900X CPU
(allocated 32 logical (20 logical threads,
threads, 16 physical 10 physical cores),
cores, NUMA), AVX-2 AVX-512
Orig. AVX-br. Ratio Orig. AVX-br. Ratio
------ ----- ------ ----- ----- ------
02-threads realloc 80544 60025 74.52% 66100 55854 84.50%
04-threads realloc 80751 47743 59.12% 64772 40213 62.08%
08-threads realloc 82645 32691 39.56% 62246 27056 43.47%
12-threads realloc 89951 43270 48.10% 65456 25853 39.50%
16-threads realloc 95729 56571 59.10% 67513 27058 40.08%
31-threads realloc 109099 97290 89.18% 63180 28408 44.96%
64-threads realloc 118589 104230 87.89% 57974 28951 49.94%
NexusDB 01 thread 160100 121961 76.18% 93341 95807 102.64%
NexusDB 02 threads 115447 78339 67.86% 77034 70056 90.94%
NexusDB 04 threads 107851 49403 45.81% 73162 50039 68.39%
NexusDB 08 threads 111490 36675 32.90% 70672 42116 59.59%
NexusDB 12 threads 148148 46608 31.46% 92693 53900 58.15%
NexusDB 16 threads 111041 38461 34.64% 66549 37317 56.07%
NexusDB 31 threads 123496 44232 35.82% 62552 34150 54.60%
NexusDB 64 threads 179924 62414 34.69% 83914 42915 51.14%
The above tests (on Xeon E5-2667v4 and i9) have been done on 03-May-2018.
Here is the single-threading performance comparison in some selected
scenarios between FastMM v5.03 dated May 12, 2021 and FastMM4-AVX v1.05
dated May 20, 2021. FastMM4-AVX is compiled with default optinos. This
test is run on May 20, 2021, under Intel Core i7-1065G7 CPU, Ice Lake
microarchitecture, base frequency: 1.3 GHz, max turbo frequencey: 3.90 GHz,
4 cores, 8 threads. Compiled under Delphi 10.3 Update 3, 64-bit target.
Please note that these are the selected scenarios where FastMM4-AVX is
faster then FastMM5. In other scenarios, especially in multi-threaded
with heavy contention, FastMM5 is faster.
FastMM5 AVX-br. Ratio
------ ------ ------
ReallocMem Small (1-555b) benchmark 1425 1135 79.65%
ReallocMem Medium (1-4039b) benchmark 3834 3309 86.31%
Block downsize 12079 10305 85.31%
Address space creep benchmark 13283 12571 94.64%
Address space creep (larger blocks) 16066 13879 86.39%
Single-threaded reallocate and use 4395 3960 90.10%
Single-threaded tiny reallocate and use 8766 7097 80.96%
Single-threaded allocate, use and free 13912 13248 95.23%
You can find the program, used to generate the benchmark data,
at https://github.com/maximmasiutin/FastCodeBenchmark
You can find the program, used to generate the benchmark data,
at https://github.com/maximmasiutin/FastCodeBenchmark
FastMM4-AVX is released under a dual license, and you may choose to use it
under either the Mozilla Public License 2.0 (MPL 2.1, available from
https://www.mozilla.org/en-US/MPL/2.0/) or the GNU Lesser General Public
License Version 3, dated 29 June 2007 (LGPL 3, available from
https://www.gnu.org/licenses/lgpl.html).
FastMM4-AVX is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
FastMM4-AVX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with FastMM4-AVX (see license_lgpl.txt and license_gpl.txt)
If not, see <http://www.gnu.org/licenses/>.
FastMM4-AVX Version History:
- 1.0.6 (25 August 2021) - it can now be compiled with any alignment (8, 16, 32)
regardless of the target (x86, x64) and whether inline assembly is used
or not; the "PurePascal" conditional define to disable inline assembly at
all, however, in this case, efficient locking would not work since it
uses inline assembly; FreePascal now uses the original FreePascal compiler
mode, rather than the Delphi compatibility mode as before; resolved many
FreePascal compiler warnings; supported branch target alignment
in FreePascal inline assembly; small block types now always have
block sizes of 1024 and 2048 bytes, while in previous versions
instead of 1024-byte blocks there were 1056-byte blocks,
and instead of 2048-byte blocks were 2176-byte blocks;
fixed Delphi compiler hints for 64-bit Release mode; Win32 and Win64
versions compiled under Delphi and FreePascal passed the all the FastCode
validation suites.
- 1.05 (20 May 2021) - improved speed of releasing memory blocks on higher thread
contention. It is also possible to compile FastMM4-AVX without a single
inline assembly code. Renamed some conditional defines to be self-explaining.
Rewritten some comments to be meaningful. Made it compile under FreePascal
for Linux 64-bit and 32-bit. Also made it compile under FreePascal for
Windows 32-bit and 64-bit. Memory move functions for 152, 184 and 216 bytes
were incorrect Linux. Move216AVX1 and Move216AVX2 Linux implementation had
invalid opcodes. Added support for the GetFPCHeapStatus(). Optimizations on
single-threaded performance. If you define DisablePauseAndSwitchToThread,
it will use EnterCriticalSection/LeaveCriticalSectin. An attempt to free a
memory block twice was not caught under 32-bit Delphi. Added SSE fixed block
copy routines for 32-bit targets. Added support for the "Fast Short REP MOVSB"
CPU feature. Removed redundant SSE code from 64-bit targets.
- 1.04 (O6 October 2020) - improved use of AVX-512 instructions to avoid turbo
clock reduction and SSE/AVX transition penalty; made explicit order of
parameters for GetCPUID to avoid calling convention ambiguity that could
lead to incorrect use of registers and finally crashes, i.e., under Linux;
improved explanations and comments, i.e., about the use of the
synchronization techniques.
- 1.03 (04 May 2018) - minor fixes for the debug mode, FPC compatibility
and code readability cosmetic fixes.
- 1.02 (07 November 2017) - added and tested support for the AVX-512
instruction set.
- 1.01 (10 October 2017) - made the source code compile under Delphi5,
thanks to Valts Silaputnins.
- 1.00 (27 July 2017) - initial revision.
The original FastMM4 description follows:
# FastMM4
Fast Memory Manager
Description:
A fast replacement memory manager for Embarcadero Delphi applications
that scales well under multi-threaded usage, is not prone to memory
fragmentation, and supports shared memory without the use of external .DLL
files.
Homepage:
https://github.com/pleriche/FastMM4
Advantages:
- Fast
- Low overhead. FastMM is designed for an average of 5% and maximum of 10%
overhead per block.
- Supports up to 3GB of user mode address space under Windows 32-bit and 4GB
under Windows 64-bit. Add the "$SetPEFlags $20" option (in curly braces)
to your .dpr to enable this.
- Highly aligned memory blocks. Can be configured for either 8-byte or 16-byte
alignment.
- Good scaling under multi-threaded applications
- Intelligent reallocations. Avoids slow memory move operations through
not performing unneccesary downsizes and by having a minimum percentage
block size growth factor when an in-place block upsize is not possible.
- Resistant to address space fragmentation
- No external DLL required when sharing memory between the application and
external libraries (provided both use this memory manager)
- Optionally reports memory leaks on program shutdown. (This check can be set
to be performed only if Delphi is currently running on the machine, so end
users won't be bothered by the error message.)
- Supports Delphi 4 (or later), C++ Builder 4 (or later), Kylix 3.
Usage:
Delphi:
Place this unit as the very first unit under the "uses" section in your
project's .dpr file. When sharing memory between an application and a DLL
(e.g. when passing a long string or dynamic array to a DLL function), both the
main application and the DLL must be compiled using this memory manager (with
the required conditional defines set). There are some conditional defines
(inside FastMM4Options.inc) that may be used to tweak the memory manager. To
enable support for a user mode address space greater than 2GB you will have to
use the EditBin* tool to set the LARGE_ADDRESS_AWARE flag in the EXE header.
This informs Windows x64 or Windows 32-bit (with the /3GB option set) that the
application supports an address space larger than 2GB (up to 4GB). In Delphi 6
and later you can also specify this flag through the compiler directive
{$SetPEFlags $20}
*The EditBin tool ships with the MS Visual C compiler.
C++ Builder:
Refer to the instructions inside FastMM4BCB.cpp.
# FastMM4
Fast Memory Manager
![FastMM-Title.jpg with title only](images/FastMM-Title.jpg "FastMM-Title.jpg with title only")
## Description:
A fast replacement memory manager for Embarcadero Delphi applications
that scales well under multi-threaded usage, is not prone to memory
fragmentation, and supports shared memory without the use of external .DLL
files.
## Homepage:
https://github.com/pleriche/FastMM4
## Advantages:
* Fast
* Low overhead. FastMM is designed for an average of 5% and maximum of 10%
overhead per block.
* Supports up to 3GB of user mode address space under Windows 32-bit and 4GB
under Windows 64-bit. Add the "$SetPEFlags $20" option (in curly braces)
to your .dpr to enable this.
* Highly aligned memory blocks. Can be configured for either 8-byte or 16-byte
alignment.
* Good scaling under multi-threaded applications
* Intelligent reallocations. Avoids slow memory move operations through
not performing unneccesary downsizes and by having a minimum percentage
block size growth factor when an in-place block upsize is not possible.
* Resistant to address space fragmentation
* No external DLL required when sharing memory between the application and
external libraries (provided both use this memory manager)
* Optionally reports memory leaks on program shutdown. (This check can be set
to be performed only if Delphi is currently running on the machine, so end
users won't be bothered by the error message.)
* Supports Delphi 4 (or later), C++ Builder 4 (or later), Kylix 3.
## Usage:
### Delphi:
Place this unit as the very first unit under the "uses" section in your
project's .dpr file. When sharing memory between an application and a DLL
(e.g. when passing a long string or dynamic array to a DLL function), both the
main application and the DLL must be compiled using this memory manager (with
the required conditional defines set).
There are some conditional defines
(inside `FastMM4Options.inc`) that may be used to tweak the memory manager. To
enable support for a user mode address space greater than 2GB you will have to
use the EditBin* tool to set the `LARGE_ADDRESS_AWARE` flag in the EXE header.
This informs Windows x64 or Windows 32-bit (with the /3GB option set) that the
application supports an address space larger than 2GB (up to 4GB). In Delphi 6
and later you can also specify this flag through the compiler directive
`{$SetPEFlags $20}`
*The EditBin tool ships with the MS Visual C compiler.
### C++ Builder:
Refer to the instructions inside `FastMM4BCB.cpp`.

View File

@ -0,0 +1,9 @@
USEUNIT("DLLEntry.cpp");
USEUNIT("FastMM4BCB.cpp");
USEUNIT("FastMM4.pas");
USEUNIT("BorlndMM_.pas");
USEDEF("Export.def");
//---------------------------------------------------------------------------
This file is used by the project manager only and should be treated like the project file
DllEntryPoint

View File

@ -0,0 +1,118 @@
<?xml version='1.0' encoding='utf-8' ?>
<!-- C++Builder XML Project -->
<PROJECT>
<MACROS>
<VERSION value="BCB.05.03"/>
<PROJECT value="BorlndMM.dll"/>
<OBJFILES value="FastMM4.obj BorlndMM_.obj DLLEntry.obj FastMM4BCB.obj"/>
<RESFILES value=""/>
<IDLFILES value=""/>
<IDLGENFILES value=""/>
<DEFFILE value="Export.def"/>
<RESDEPEN value="$(RESFILES)"/>
<LIBFILES value=""/>
<LIBRARIES value="Vcl50.lib"/>
<SPARELIBS value="Vcl50.lib"/>
<PACKAGES value="Vcl50.bpi Vclx50.bpi bcbsmp50.bpi Vcldb50.bpi vclado50.bpi ibsmp50.bpi
VCLBDE50.bpi vcldbx50.bpi Qrpt50.bpi TeeUI50.bpi TeeDB50.bpi Tee50.bpi
Dss50.bpi TeeQR50.bpi VCLIB50.bpi Vclmid50.bpi vclie50.bpi Inetdb50.bpi
Inet50.bpi NMFast50.bpi webmid50.bpi bcbie50.bpi dclocx50.bpi
bcb2kaxserver50.bpi"/>
<PATHCPP value=".;"/>
<PATHPAS value=".;"/>
<PATHRC value=".;"/>
<PATHASM value=".;"/>
<DEBUGLIBPATH value="$(BCB)\lib\debug"/>
<RELEASELIBPATH value="$(BCB)\lib\release"/>
<LINKER value="tlink32"/>
<USERDEFINES value="_DEBUG"/>
<SYSDEFINES value="NO_STRICT;_NO_VCL"/>
<MAINSOURCE value="BorlndMM.bpf"/>
<INCLUDEPATH value="$(BCB)\include;$(BCB)\include\vcl"/>
<LIBPATH value="$(BCB)\lib\obj;$(BCB)\lib"/>
<WARNINGS value="-w-par"/>
</MACROS>
<OPTIONS>
<IDLCFLAGS value="-I$(BCB)\include -I$(BCB)\include\vcl -src_suffix cpp -D_DEBUG -boa"/>
<CFLAG1 value="-WD -O2 -H=$(BCB)\lib\vcl50.csm -Hc -Vx -Ve -X- -r- -a8 -b- -k- -y -v -vi-
-tWD -tWM -c"/>
<PFLAGS value="-$YD -v -JPHNE -M"/>
<RFLAGS value=""/>
<AFLAGS value="/mx /w2 /zi"/>
<LFLAGS value="-D&quot;&quot; -B:0x41000000 -aa -Tpd -x -Gn -v"/>
</OPTIONS>
<LINKER>
<ALLOBJ value="c0d32.obj $(OBJFILES)"/>
<ALLRES value="$(RESFILES)"/>
<ALLLIB value="$(LIBFILES) $(LIBRARIES) import32.lib cw32mt.lib"/>
</LINKER>
<IDEOPTIONS>
[Version Info]
IncludeVerInfo=0
AutoIncBuild=0
MajorVer=1
MinorVer=0
Release=0
Build=0
Debug=0
PreRelease=0
Special=0
Private=0
DLL=0
Locale=2052
CodePage=936
[Version Info Keys]
CompanyName=
FileDescription=
FileVersion=1.0.0.0
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=1.0.0.0
Comments=
[HistoryLists\hlIncludePath]
Count=1
Item0=$(BCB)\include;$(BCB)\include\vcl
[HistoryLists\hlLibraryPath]
Count=1
Item0=$(BCB)\lib\obj;$(BCB)\lib
[HistoryLists\hlDebugSourcePath]
Count=1
Item0=$(BCB)\source\vcl
[HistoryLists\hlConditionals]
Count=1
Item0=_DEBUG
[Debugging]
DebugSourceDirs=$(BCB)\source\vcl
[Parameters]
RunParams=
HostApplication=F:\FastMM492\FastMM4\Replacement BorlndMM DLL\BCB5\Project1.exe
RemoteHost=
RemotePath=
RemoteDebug=0
[Compiler]
ShowInfoMsgs=0
LinkDebugVcl=1
LinkCGLIB=0
[CORBA]
AddServerUnit=1
AddClientUnit=1
PrecompiledHeaders=1
[Language]
ActiveLang=
ProjectLang=
RootDir=
</IDEOPTIONS>
</PROJECT>

View File

@ -0,0 +1,254 @@
unit BorlndMM_;
interface
{--------------------Start of options block-------------------------}
{Set the following option to use the RTL MM instead of FastMM. Setting this
option makes this replacement DLL almost identical to the default
borlndmm.dll, unless the "FullDebugMode" option is also set.}
{.$define UseRTLMM}
{--------------------End of options block-------------------------}
{$Include FastMM4Options.inc}
{Cannot use the RTL MM with full debug mode}
{$ifdef FullDebugMode}
{$undef UseRTLMM}
{$endif}
{$OBJEXPORTALL OFF}
function GetAllocMemCount: integer;
function GetAllocMemSize: integer;
procedure DumpBlocks;
function HeapRelease: Integer;
function HeapAddRef: Integer;
function SysReallocMem(P: Pointer; Size: Integer): Pointer;
function SysFreeMem(P: Pointer): Integer;
function SysGetMem(Size: Integer): Pointer;
{$ifdef BDS2006AndUp}
function SysAllocMem(Size: Cardinal): Pointer;
{$endif}
function ReallocMemory(P: Pointer; Size: Integer): Pointer; cdecl;
function FreeMemory(P: Pointer): Integer; cdecl;
function GetMemory(Size: Integer): Pointer; cdecl;
function GetHeapStatus: THeapStatus;
{$ifdef BDS2006AndUp}
function RegisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean;
function UnregisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean;
{$endif}
implementation
{$ifndef UseRTLMM}
uses
FastMM4;
{$endif}
{$OPTIMIZATION ON}
{$STACKFRAMES OFF}
{$RANGECHECKS OFF}
{$OVERFLOWCHECKS OFF}
{$ifdef NoDebugInfo}
{$DEBUGINFO OFF}
{$endif}
//Export: GetAllocMemCount
//Symbol: @Borlndmm@GetAllocMemCount$qqrv
function GetAllocMemCount: integer;
begin
{Return stats for the RTL MM only}
{$ifdef UseRTLMM}
Result := System.AllocMemCount;
{$else}
Result := 0;
{$endif}
end;
//Export: GetAllocMemSize
//Symbol: @Borlndmm@GetAllocMemSize$qqrv
function GetAllocMemSize: integer;
begin
{Return stats for the RTL MM only}
{$ifdef UseRTLMM}
Result := System.AllocMemSize;
{$else}
Result := 0;
{$endif}
end;
//Export: DumpBlocks
//Symbol: @Borlndmm@DumpBlocks$qqrv
procedure DumpBlocks;
begin
{Do nothing}
end;
//Export: @Borlndmm@HeapRelease$qqrv
//Symbol: @Borlndmm@HeapRelease$qqrv
function HeapRelease: Integer;
begin
{Do nothing}
Result := 2;
end;
//Export: @Borlndmm@HeapAddRef$qqrv
//Symbol: @Borlndmm@HeapAddRef$qqrv
function HeapAddRef: Integer;
begin
{Do nothing}
Result := 2;
end;
//Export: GetHeapStatus
//Symbol: @Borlndmm@GetHeapStatus$qqrv
function GetHeapStatus: THeapStatus;
begin
{$ifndef UseRTLMM}
Result := FastGetHeapStatus;
{$else}
Result := System.GetHeapStatus;
{$endif}
end;
//Export: ReallocMemory
//Symbol: @Borlndmm@ReallocMemory$qpvi
function ReallocMemory(P: Pointer; Size: Integer): Pointer; cdecl;
begin
Result := System.ReallocMemory(P, Size);
end;
//Export: FreeMemory
//Symbol: @Borlndmm@FreeMemory$qpv
function FreeMemory(P: Pointer): Integer; cdecl;
begin
Result := System.FreeMemory(P);
end;
//Export: GetMemory
//Symbol: @Borlndmm@GetMemory$qi
function GetMemory(Size: Integer): Pointer; cdecl;
begin
Result := System.GetMemory(Size);
end;
//Export: @Borlndmm@SysReallocMem$qqrpvi
//Symbol: @Borlndmm@SysReallocMem$qqrpvi
function SysReallocMem(P: Pointer; Size: Integer): Pointer;
begin
{$ifndef UseRTLMM}
{$ifndef FullDebugMode}
Result := FastReallocMem(P, Size);
{$else}
Result := DebugReallocMem(P, Size);
{$endif}
{$else}
Result := System.SysReallocMem(P, Size);
{$endif}
end;
//Export: @Borlndmm@SysFreeMem$qqrpv
//Symbol: @Borlndmm@SysFreeMem$qqrpv
function SysFreeMem(P: Pointer): Integer;
begin
{$ifndef UseRTLMM}
{$ifndef FullDebugMode}
Result := FastFreeMem(P);
{$else}
Result := DebugFreeMem(P);
{$endif}
{$else}
Result := System.SysFreeMem(P);
{$endif}
end;
//Export: @Borlndmm@SysGetMem$qqri
//Symbol: @Borlndmm@SysGetMem$qqri
function SysGetMem(Size: Integer): Pointer;
begin
{$ifndef UseRTLMM}
{$ifndef FullDebugMode}
Result := FastGetMem(Size);
{$else}
Result := DebugGetMem(Size);
{$endif}
{$else}
Result := System.SysGetMem(Size);
{$endif}
end;
//Export: @Borlndmm@SysAllocMem$qqri
//Symbol: @Borlndmm@SysAllocMem$qqrui
function SysAllocMem(Size: Cardinal): Pointer;
begin
{$ifndef UseRTLMM}
{$ifndef FullDebugMode}
Result := FastAllocMem(Size);
{$else}
Result := DebugAllocMem(Size);
{$endif}
{$else}
//{$ifdef VER180}
{$if RTLVersion >= 18}
Result := System.SysAllocMem(Size);
{$ifend}
{$if RTLVersion < 18}
Result := System.AllocMem(Size);
{$ifend}
{$endif}
end;
//Export: @Borlndmm@SysUnregisterExpectedMemoryLeak$qqrpi
//Symbol: @Borlndmm@UnregisterExpectedMemoryLeak$qqrpv
function UnregisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean;
begin
{$ifndef UseRTLMM}
{$ifdef EnableMemoryLeakReporting}
Result := UnregisterExpectedMemoryLeak(ALeakedPointer);
{$else}
Result := False;
{$endif}
{$else}
//{$ifdef VER180}
{$if RTLVersion >= 18}
Result := System.SysUnregisterExpectedMemoryLeak(ALeakedPointer);
{$ifend}
{$if RTLVersion < 18}
Result := False;
{$ifend}
{$endif}
end;
//Export: @Borlndmm@SysRegisterExpectedMemoryLeak$qqrpi
//Symbol: @Borlndmm@RegisterExpectedMemoryLeak$qqrpv
function RegisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean;
begin
{$ifndef UseRTLMM}
{$ifdef EnableMemoryLeakReporting}
Result := RegisterExpectedMemoryLeak(ALeakedPointer);
{$else}
Result := False;
{$endif}
{$else}
//{$ifdef VER180}
{$if RTLVersion >= 18}
Result := System.SysRegisterExpectedMemoryLeak(ALeakedPointer);
{$ifend}
{$if RTLVersion < 18}
Result := False;
{$ifend}
{$endif}
end;
initialization
IsMultiThread := True;
finalization
end.

View File

@ -0,0 +1,31 @@
//---------------------------------------------------------------------------
#include <windows.h>
//---------------------------------------------------------------------------
// Important note about DLL memory management when your DLL uses the
// static version of the RunTime Library:
//
// If your DLL exports any functions that pass String objects (or structs/
// classes containing nested Strings) as parameter or function results,
// you will need to add the library MEMMGR.LIB to both the DLL project and
// any other projects that use the DLL. You will also need to use MEMMGR.LIB
// if any other projects which use the DLL will be performing new or delete
// operations on any non-TObject-derived classes which are exported from the
// DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
// EXE's to use the BORLNDMM.DLL as their memory manager. In these cases,
// the file BORLNDMM.DLL should be deployed along with your DLL.
//
// To avoid using BORLNDMM.DLL, pass string information using "char *" or
// ShortString parameters.
//
// If your DLL uses the dynamic version of the RTL, you do not need to
// explicitly add MEMMGR.LIB as this will be done implicitly for you
//---------------------------------------------------------------------------
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
//---------------------------------------------------------------------------

View File

@ -0,0 +1,29 @@
LIBRARY BORLNDMM.DLL
EXPORTS
GetAllocMemCount = @Borlndmm_@GetAllocMemCount$qqrv ;To make it the 2nd export, ___CPPdebugHook always the 1st export
GetAllocMemSize = @Borlndmm_@GetAllocMemSize$qqrv
GetHeapStatus = @Borlndmm_@GetHeapStatus$qqrv
DumpBlocks = @Borlndmm_@DumpBlocks$qqrv
ReallocMemory = @Borlndmm_@ReallocMemory$qpvi
FreeMemory = @Borlndmm_@FreeMemory$qpv
GetMemory = @Borlndmm_@GetMemory$qi
;@Borlndmm@SysUnregisterExpectedMemoryLeak$qqrpi = @Borlndmm_@UnregisterExpectedMemoryLeak$qqrpv
;@Borlndmm@SysRegisterExpectedMemoryLeak$qqrpi = @Borlndmm_@RegisterExpectedMemoryLeak$qqrpv
;@Borlndmm@SysAllocMem$qqri = @Borlndmm_@SysAllocMem$qqrui
@Borlndmm@SysReallocMem$qqrpvi = @Borlndmm_@SysReallocMem$qqrpvi
@Borlndmm@SysFreeMem$qqrpv = @Borlndmm_@SysFreeMem$qqrpv
@Borlndmm@SysGetMem$qqri = @Borlndmm_@SysGetMem$qqri
@Borlndmm@HeapRelease$qqrv = @Borlndmm_@HeapRelease$qqrv
@Borlndmm@HeapAddRef$qqrv = @Borlndmm_@HeapAddRef$qqrv
;SetMMLogFileName = @Fastmm4@SetMMLogFileName$qqrpc
;GetCurrentAllocationGroup = @Fastmm4@GetCurrentAllocationGroup$qqrv
;PushAllocationGroup = @Fastmm4@PushAllocationGroup$qqrui
;PopAllocationGroup = @Fastmm4@PopAllocationGroup$qqrv
;LogAllocatedBlocksToFile = @Fastmm4@LogAllocatedBlocksToFile$qqruiui

View File

@ -0,0 +1,3 @@
This file is used by the project manager only and should be treated like the project file
DllEntryPoint

View File

@ -0,0 +1,140 @@
<?xml version='1.0' encoding='utf-8' ?>
<!-- C++Builder XML Project -->
<PROJECT>
<MACROS>
<VERSION value="BCB.06.00"/>
<PROJECT value="BorlndMM.dll"/>
<OBJFILES value="DLLEntry.obj BorlndMM_.obj FastMM4.obj FastMM4BCB.obj"/>
<RESFILES value="BorlndMM.res"/>
<IDLFILES value=""/>
<IDLGENFILES value=""/>
<DEFFILE value="Export.def"/>
<RESDEPEN value="$(RESFILES)"/>
<LIBFILES value=""/>
<LIBRARIES value=""/>
<SPARELIBS value="vcldb.lib dbrtl.lib adortl.lib bdertl.lib vcldbx.lib ibxpress.lib cds.lib
dsnap.lib bdecds.lib qrpt.lib teeui.lib teedb.lib tee.lib dss.lib
teeqr.lib visualdbclx.lib dsnapcrba.lib dsnapcon.lib bcbsmp.lib"/>
<PACKAGES value="vcl.bpi rtl.bpi dbrtl.bpi adortl.bpi vcldb.bpi vclx.bpi bdertl.bpi
vcldbx.bpi ibxpress.bpi cds.bpi dsnap.bpi bdecds.bpi qrpt.bpi teeui.bpi
teedb.bpi tee.bpi dss.bpi teeqr.bpi visualclx.bpi visualdbclx.bpi
dsnapcrba.bpi dsnapcon.bpi bcbsmp.bpi"/>
<PATHCPP value=".;"/>
<PATHPAS value=".;"/>
<PATHRC value=".;"/>
<PATHASM value=".;"/>
<DEBUGLIBPATH value="$(BCB)\lib\debug"/>
<RELEASELIBPATH value="$(BCB)\lib\release"/>
<LINKER value="ilink32"/>
<USERDEFINES value="_DEBUG"/>
<SYSDEFINES value="NO_STRICT;_NO_VCL;USEPACKAGES"/>
<MAINSOURCE value="BorlndMM.bpf"/>
<INCLUDEPATH value="&quot;F:\FastMM492\FastMM4\Replacement BorlndMM DLL\BCB6&quot;;$(BCB)\include;$(BCB)\include\vcl"/>
<LIBPATH value="&quot;F:\FastMM492\FastMM4\Replacement BorlndMM DLL\BCB6&quot;;$(BCB)\lib\obj;$(BCB)\lib"/>
<WARNINGS value="-w-par"/>
<OTHERFILES value=""/>
</MACROS>
<OPTIONS>
<IDLCFLAGS value="-I&quot;F:\FastMM492\FastMM4\Replacement BorlndMM DLL\BCB6&quot; -I$(BCB)\include
-I$(BCB)\include\vcl -src_suffix cpp -D_DEBUG -boa"/>
<CFLAG1 value="-WD -O2 -H=$(BCB)\lib\vcl60.csm -Hc -Vx -Ve -X- -r- -a8 -b- -k- -y -v -vi-
-tWD -tWM -c"/>
<PFLAGS value="-$YD -$W -$O- -$A8 -v -JPHNE -M"/>
<RFLAGS value=""/>
<AFLAGS value="/mx /w2 /zi"/>
<LFLAGS value="-D&quot;&quot; -B:0x1190000 -aa -Tpd -x -Gn -v"/>
<OTHERFILES value=""/>
</OPTIONS>
<LINKER>
<ALLOBJ value="c0d32.obj $(PACKAGES) $(OBJFILES)"/>
<ALLRES value="$(RESFILES)"/>
<ALLLIB value="$(LIBFILES) $(LIBRARIES) import32.lib cw32mt.lib"/>
<OTHERFILES value=""/>
</LINKER>
<FILELIST>
<FILE FILENAME="BorlndMM.res" FORMNAME="" UNITNAME="BorlndMM.res" CONTAINERID="ResTool" DESIGNCLASS="" LOCALCOMMAND=""/>
<FILE FILENAME="BorlndMM.bpf" FORMNAME="" UNITNAME="BorlndMM" CONTAINERID="BPF" DESIGNCLASS="" LOCALCOMMAND=""/>
<FILE FILENAME="DLLEntry.cpp" FORMNAME="" UNITNAME="DLLEntry" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
<FILE FILENAME="BorlndMM_.pas" FORMNAME="" UNITNAME="BorlndMM_" CONTAINERID="PascalCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
<FILE FILENAME="FastMM4.pas" FORMNAME="" UNITNAME="FastMM4" CONTAINERID="PascalCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
<FILE FILENAME="FastMM4BCB.cpp" FORMNAME="" UNITNAME="FastMM4BCB" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
<FILE FILENAME="Export.def" FORMNAME="" UNITNAME="Export.def" CONTAINERID="DefTool" DESIGNCLASS="" LOCALCOMMAND=""/>
</FILELIST>
<BUILDTOOLS>
</BUILDTOOLS>
<IDEOPTIONS>
[Version Info]
IncludeVerInfo=0
AutoIncBuild=0
MajorVer=1
MinorVer=0
Release=0
Build=0
Debug=0
PreRelease=0
Special=0
Private=0
DLL=0
Locale=2052
CodePage=936
[Version Info Keys]
CompanyName=
FileDescription=
FileVersion=1.0.0.0
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=1.0.0.0
Comments=
[HistoryLists\hlIncludePath]
Count=1
Item0=F:\FastMM492\FastMM4\Replacement BorlndMM DLL\BCB6;$(BCB)\include;$(BCB)\include\vcl
[HistoryLists\hlLibraryPath]
Count=1
Item0=F:\FastMM492\FastMM4\Replacement BorlndMM DLL\BCB6;$(BCB)\lib\obj;$(BCB)\lib
[HistoryLists\hlDebugSourcePath]
Count=1
Item0=$(BCB)\source\vcl
[HistoryLists\hlConditionals]
Count=1
Item0=_DEBUG
[Debugging]
DebugSourceDirs=$(BCB)\source\vcl
[Parameters]
RunParams=
Launcher=
UseLauncher=0
DebugCWD=
HostApplication=
RemoteHost=
RemotePath=
RemoteLauncher=
RemoteCWD=
RemoteDebug=0
[Compiler]
ShowInfoMsgs=0
LinkDebugVcl=1
LinkCGLIB=0
[CORBA]
AddServerUnit=1
AddClientUnit=1
PrecompiledHeaders=1
[Linker]
LibPrefix=
LibSuffix=
LibVersion=
</IDEOPTIONS>
</PROJECT>

View File

@ -0,0 +1,254 @@
unit BorlndMM_;
interface
{--------------------Start of options block-------------------------}
{Set the following option to use the RTL MM instead of FastMM. Setting this
option makes this replacement DLL almost identical to the default
borlndmm.dll, unless the "FullDebugMode" option is also set.}
{.$define UseRTLMM}
{--------------------End of options block-------------------------}
{$Include FastMM4Options.inc}
{Cannot use the RTL MM with full debug mode}
{$ifdef FullDebugMode}
{$undef UseRTLMM}
{$endif}
{$OBJEXPORTALL OFF}
function GetAllocMemCount: integer;
function GetAllocMemSize: integer;
procedure DumpBlocks;
function HeapRelease: Integer;
function HeapAddRef: Integer;
function SysReallocMem(P: Pointer; Size: Integer): Pointer;
function SysFreeMem(P: Pointer): Integer;
function SysGetMem(Size: Integer): Pointer;
{$ifdef BDS2006AndUp}
function SysAllocMem(Size: Cardinal): Pointer;
{$endif}
function ReallocMemory(P: Pointer; Size: Integer): Pointer; cdecl;
function FreeMemory(P: Pointer): Integer; cdecl;
function GetMemory(Size: Integer): Pointer; cdecl;
function GetHeapStatus: THeapStatus;
{$ifdef BDS2006AndUp}
function RegisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean;
function UnregisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean;
{$endif}
implementation
{$ifndef UseRTLMM}
uses
FastMM4;
{$endif}
{$OPTIMIZATION ON}
{$STACKFRAMES OFF}
{$RANGECHECKS OFF}
{$OVERFLOWCHECKS OFF}
{$ifdef NoDebugInfo}
{$DEBUGINFO OFF}
{$endif}
//Export: GetAllocMemCount
//Symbol: @Borlndmm@GetAllocMemCount$qqrv
function GetAllocMemCount: integer;
begin
{Return stats for the RTL MM only}
{$ifdef UseRTLMM}
Result := System.AllocMemCount;
{$else}
Result := 0;
{$endif}
end;
//Export: GetAllocMemSize
//Symbol: @Borlndmm@GetAllocMemSize$qqrv
function GetAllocMemSize: integer;
begin
{Return stats for the RTL MM only}
{$ifdef UseRTLMM}
Result := System.AllocMemSize;
{$else}
Result := 0;
{$endif}
end;
//Export: DumpBlocks
//Symbol: @Borlndmm@DumpBlocks$qqrv
procedure DumpBlocks;
begin
{Do nothing}
end;
//Export: @Borlndmm@HeapRelease$qqrv
//Symbol: @Borlndmm@HeapRelease$qqrv
function HeapRelease: Integer;
begin
{Do nothing}
Result := 2;
end;
//Export: @Borlndmm@HeapAddRef$qqrv
//Symbol: @Borlndmm@HeapAddRef$qqrv
function HeapAddRef: Integer;
begin
{Do nothing}
Result := 2;
end;
//Export: GetHeapStatus
//Symbol: @Borlndmm@GetHeapStatus$qqrv
function GetHeapStatus: THeapStatus;
begin
{$ifndef UseRTLMM}
Result := FastGetHeapStatus;
{$else}
Result := System.GetHeapStatus;
{$endif}
end;
//Export: ReallocMemory
//Symbol: @Borlndmm@ReallocMemory$qpvi
function ReallocMemory(P: Pointer; Size: Integer): Pointer; cdecl;
begin
Result := System.ReallocMemory(P, Size);
end;
//Export: FreeMemory
//Symbol: @Borlndmm@FreeMemory$qpv
function FreeMemory(P: Pointer): Integer; cdecl;
begin
Result := System.FreeMemory(P);
end;
//Export: GetMemory
//Symbol: @Borlndmm@GetMemory$qi
function GetMemory(Size: Integer): Pointer; cdecl;
begin
Result := System.GetMemory(Size);
end;
//Export: @Borlndmm@SysReallocMem$qqrpvi
//Symbol: @Borlndmm@SysReallocMem$qqrpvi
function SysReallocMem(P: Pointer; Size: Integer): Pointer;
begin
{$ifndef UseRTLMM}
{$ifndef FullDebugMode}
Result := FastReallocMem(P, Size);
{$else}
Result := DebugReallocMem(P, Size);
{$endif}
{$else}
Result := System.SysReallocMem(P, Size);
{$endif}
end;
//Export: @Borlndmm@SysFreeMem$qqrpv
//Symbol: @Borlndmm@SysFreeMem$qqrpv
function SysFreeMem(P: Pointer): Integer;
begin
{$ifndef UseRTLMM}
{$ifndef FullDebugMode}
Result := FastFreeMem(P);
{$else}
Result := DebugFreeMem(P);
{$endif}
{$else}
Result := System.SysFreeMem(P);
{$endif}
end;
//Export: @Borlndmm@SysGetMem$qqri
//Symbol: @Borlndmm@SysGetMem$qqri
function SysGetMem(Size: Integer): Pointer;
begin
{$ifndef UseRTLMM}
{$ifndef FullDebugMode}
Result := FastGetMem(Size);
{$else}
Result := DebugGetMem(Size);
{$endif}
{$else}
Result := System.SysGetMem(Size);
{$endif}
end;
//Export: @Borlndmm@SysAllocMem$qqri
//Symbol: @Borlndmm@SysAllocMem$qqrui
function SysAllocMem(Size: Cardinal): Pointer;
begin
{$ifndef UseRTLMM}
{$ifndef FullDebugMode}
Result := FastAllocMem(Size);
{$else}
Result := DebugAllocMem(Size);
{$endif}
{$else}
//{$ifdef VER180}
{$if RTLVersion >= 18}
Result := System.SysAllocMem(Size);
{$ifend}
{$if RTLVersion < 18}
Result := System.AllocMem(Size);
{$ifend}
{$endif}
end;
//Export: @Borlndmm@SysUnregisterExpectedMemoryLeak$qqrpi
//Symbol: @Borlndmm@UnregisterExpectedMemoryLeak$qqrpv
function UnregisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean;
begin
{$ifndef UseRTLMM}
{$ifdef EnableMemoryLeakReporting}
Result := UnregisterExpectedMemoryLeak(ALeakedPointer);
{$else}
Result := False;
{$endif}
{$else}
//{$ifdef VER180}
{$if RTLVersion >= 18}
Result := System.SysUnregisterExpectedMemoryLeak(ALeakedPointer);
{$ifend}
{$if RTLVersion < 18}
Result := False;
{$ifend}
{$endif}
end;
//Export: @Borlndmm@SysRegisterExpectedMemoryLeak$qqrpi
//Symbol: @Borlndmm@RegisterExpectedMemoryLeak$qqrpv
function RegisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean;
begin
{$ifndef UseRTLMM}
{$ifdef EnableMemoryLeakReporting}
Result := RegisterExpectedMemoryLeak(ALeakedPointer);
{$else}
Result := False;
{$endif}
{$else}
//{$ifdef VER180}
{$if RTLVersion >= 18}
Result := System.SysRegisterExpectedMemoryLeak(ALeakedPointer);
{$ifend}
{$if RTLVersion < 18}
Result := False;
{$ifend}
{$endif}
end;
initialization
IsMultiThread := True;
finalization
end.

View File

@ -0,0 +1,31 @@
//---------------------------------------------------------------------------
#include <windows.h>
//---------------------------------------------------------------------------
// Important note about DLL memory management when your DLL uses the
// static version of the RunTime Library:
//
// If your DLL exports any functions that pass String objects (or structs/
// classes containing nested Strings) as parameter or function results,
// you will need to add the library MEMMGR.LIB to both the DLL project and
// any other projects that use the DLL. You will also need to use MEMMGR.LIB
// if any other projects which use the DLL will be performing new or delete
// operations on any non-TObject-derived classes which are exported from the
// DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
// EXE's to use the BORLNDMM.DLL as their memory manager. In these cases,
// the file BORLNDMM.DLL should be deployed along with your DLL.
//
// To avoid using BORLNDMM.DLL, pass string information using "char *" or
// ShortString parameters.
//
// If your DLL uses the dynamic version of the RTL, you do not need to
// explicitly add MEMMGR.LIB as this will be done implicitly for you
//---------------------------------------------------------------------------
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
//---------------------------------------------------------------------------

View File

@ -0,0 +1,29 @@
LIBRARY BORLNDMM.DLL
EXPORTS
GetAllocMemCount = @Borlndmm_@GetAllocMemCount$qqrv ;To make it the 2nd export, ___CPPdebugHook always the 1st export
GetAllocMemSize = @Borlndmm_@GetAllocMemSize$qqrv
GetHeapStatus = @Borlndmm_@GetHeapStatus$qqrv
DumpBlocks = @Borlndmm_@DumpBlocks$qqrv
ReallocMemory = @Borlndmm_@ReallocMemory$qpvi
FreeMemory = @Borlndmm_@FreeMemory$qpv
GetMemory = @Borlndmm_@GetMemory$qi
;@Borlndmm@SysUnregisterExpectedMemoryLeak$qqrpi = @Borlndmm_@UnregisterExpectedMemoryLeak$qqrpv
;@Borlndmm@SysRegisterExpectedMemoryLeak$qqrpi = @Borlndmm_@RegisterExpectedMemoryLeak$qqrpv
;@Borlndmm@SysAllocMem$qqri = @Borlndmm_@SysAllocMem$qqrui
@Borlndmm@SysReallocMem$qqrpvi = @Borlndmm_@SysReallocMem$qqrpvi
@Borlndmm@SysFreeMem$qqrpv = @Borlndmm_@SysFreeMem$qqrpv
@Borlndmm@SysGetMem$qqri = @Borlndmm_@SysGetMem$qqri
@Borlndmm@HeapRelease$qqrv = @Borlndmm_@HeapRelease$qqrv
@Borlndmm@HeapAddRef$qqrv = @Borlndmm_@HeapAddRef$qqrv
;SetMMLogFileName = @Fastmm4@SetMMLogFileName$qqrpc
;GetCurrentAllocationGroup = @Fastmm4@GetCurrentAllocationGroup$qqrv
;PushAllocationGroup = @Fastmm4@PushAllocationGroup$qqrui
;PopAllocationGroup = @Fastmm4@PopAllocationGroup$qqrv
;LogAllocatedBlocksToFile = @Fastmm4@LogAllocatedBlocksToFile$qqruiui

View File

@ -0,0 +1,263 @@
<?xml version="1.0" encoding="utf-8"?>
<BorlandProject>
<PersonalityInfo>
<Option>
<Option Name="Personality">CPlusPlusBuilder.Personality</Option>
<Option Name="ProjectType">CppDynamicLibrary</Option>
<Option Name="Version">1.0</Option>
<Option Name="GUID">{8CAC3371-4081-47E8-B126-3D87B7662AF9}</Option>
</Option>
</PersonalityInfo>
<CPlusPlusBuilder.Personality>
<Source>
<Source Name="MainSource">BorlndMM.bpf</Source>
</Source>
<BCBPROJECT>
<project version="10.0">
<property category="build.config" name="active" value="0"/>
<property category="build.config" name="count" value="1"/>
<property category="build.config" name="excludedefaultforzero" value="0"/>
<property category="build.config.0" name="builddir" value="Debug"/>
<property category="build.config.0" name="key" value="Debug_Build"/>
<property category="build.config.0" name="name" value="Debug Build"/>
<property category="build.config.0" name="settings.win32b" value="default"/>
<property category="build.config.0" name="type" value="Toolset"/>
<property category="build.config.0" name="win32.win32b.builddir" value="Debug_Build"/>
<property category="build.config.1" name="key" value="Release_Build"/>
<property category="build.config.1" name="name" value="Release Build"/>
<property category="build.config.1" name="settings.win32b" value="default"/>
<property category="build.config.1" name="type" value="Toolset"/>
<property category="build.config.1" name="win32.win32b.builddir" value="Release_Build"/>
<property category="build.node" name="libraries" value="rtl.lib"/>
<property category="build.node" name="name" value="BorlndMM.dll"/>
<property category="build.node" name="packages" value="rtl;vclx;vcl;dbrtl;vcldb;vclactnband;xmlrtl;bcbsmp;dsnap;bdertl;vcldbx"/>
<property category="build.node" name="sparelibs" value="rtl.lib"/>
<property category="build.node" name="use_packages" value="0"/>
<property category="build.platform" name="active" value="win32"/>
<property category="build.platform" name="win32.Debug_Build.toolset" value="win32b"/>
<property category="build.platform" name="win32.Release_Build.toolset" value="win32b"/>
<property category="build.platform" name="win32.default" value="win32b"/>
<property category="build.platform" name="win32.enabled" value="1"/>
<property category="build.platform" name="win32.win32b.enabled" value="1"/>
<property category="win32.*.win32b.dcc32" name="param.filenames.merge" value="1"/>
<property category="win32.*.win32b.tasm32" name="param.listfile.merge" value="1"/>
<property category="win32.*.win32b.tasm32" name="param.objfile.merge" value="1"/>
<property category="win32.*.win32b.tasm32" name="param.xreffile.merge" value="1"/>
<property category="win32.Debug_Build.win32b.bcc32" name="option.D.arg.1" value="_DEBUG"/>
<property category="win32.Debug_Build.win32b.bcc32" name="option.D.arg.merge" value="1"/>
<property category="win32.Debug_Build.win32b.bcc32" name="option.D.enabled" value="1"/>
<property category="win32.Debug_Build.win32b.bcc32" name="option.Od.enabled" value="1"/>
<property category="win32.Debug_Build.win32b.bcc32" name="option.k.enabled" value="1"/>
<property category="win32.Debug_Build.win32b.bcc32" name="option.r.enabled" value="0"/>
<property category="win32.Debug_Build.win32b.bcc32" name="option.v.enabled" value="1"/>
<property category="win32.Debug_Build.win32b.bcc32" name="option.vi.enabled" value="0"/>
<property category="win32.Debug_Build.win32b.bcc32" name="option.y.enabled" value="1"/>
<property category="win32.Debug_Build.win32b.dcc32" name="option.$D.enabled" value="1"/>
<property category="win32.Debug_Build.win32b.dcc32" name="option.$O.enabled" value="0"/>
<property category="win32.Debug_Build.win32b.dcc32" name="option.D.arg.1" value="DEBUG"/>
<property category="win32.Debug_Build.win32b.dcc32" name="option.D.arg.merge" value="1"/>
<property category="win32.Debug_Build.win32b.dcc32" name="option.D.enabled" value="1"/>
<property category="win32.Debug_Build.win32b.dcc32" name="param.filenames.merge" value="1"/>
<property category="win32.Debug_Build.win32b.ilink32" name="option.L.arg.1" value="$(BDS)\lib\debug"/>
<property category="win32.Debug_Build.win32b.ilink32" name="option.L.arg.merge" value="1"/>
<property category="win32.Debug_Build.win32b.ilink32" name="option.L.enabled" value="1"/>
<property category="win32.Debug_Build.win32b.tasm32" name="option.z.enabled" value="1"/>
<property category="win32.Debug_Build.win32b.tasm32" name="option.zd.enabled" value="0"/>
<property category="win32.Debug_Build.win32b.tasm32" name="option.zi.enabled" value="1"/>
<property category="win32.Debug_Build.win32b.tasm32" name="param.listfile.merge" value="1"/>
<property category="win32.Debug_Build.win32b.tasm32" name="param.objfile.merge" value="1"/>
<property category="win32.Debug_Build.win32b.tasm32" name="param.xreffile.merge" value="1"/>
<property category="win32.Release_Build.win32b.bcc32" name="option.D.arg.1" value="NDEBUG"/>
<property category="win32.Release_Build.win32b.bcc32" name="option.D.arg.merge" value="1"/>
<property category="win32.Release_Build.win32b.bcc32" name="option.D.enabled" value="1"/>
<property category="win32.Release_Build.win32b.bcc32" name="option.O2.enabled" value="1"/>
<property category="win32.Release_Build.win32b.bcc32" name="option.k.enabled" value="0"/>
<property category="win32.Release_Build.win32b.bcc32" name="option.r.enabled" value="1"/>
<property category="win32.Release_Build.win32b.bcc32" name="option.vi.enabled" value="1"/>
<property category="win32.Release_Build.win32b.dcc32" name="option.$D.enabled" value="0"/>
<property category="win32.Release_Build.win32b.dcc32" name="option.V.enabled" value="0"/>
<property category="win32.Release_Build.win32b.dcc32" name="param.filenames.merge" value="1"/>
<property category="win32.Release_Build.win32b.ilink32" name="option.L.arg.1" value="$(BDS)\lib\release"/>
<property category="win32.Release_Build.win32b.ilink32" name="option.L.arg.merge" value="1"/>
<property category="win32.Release_Build.win32b.ilink32" name="option.L.enabled" value="1"/>
<property category="win32.Release_Build.win32b.tasm32" name="option.z.enabled" value="0"/>
<property category="win32.Release_Build.win32b.tasm32" name="option.zd.enabled" value="0"/>
<property category="win32.Release_Build.win32b.tasm32" name="option.zi.enabled" value="0"/>
<property category="win32.Release_Build.win32b.tasm32" name="option.zn.enabled" value="1"/>
<property category="win32.Release_Build.win32b.tasm32" name="param.listfile.merge" value="1"/>
<property category="win32.Release_Build.win32b.tasm32" name="param.objfile.merge" value="1"/>
<property category="win32.Release_Build.win32b.tasm32" name="param.xreffile.merge" value="1"/>
<optionset name="all_configurations">
<property category="node" name="displayname" value="All Configurations"/>
<property category="win32.*.win32b.bcc32" name="container.SelectedOptimizations.containerenabled" value="1"/>
<property category="win32.*.win32b.bcc32" name="container.SelectedWarnings.containerenabled" value="1"/>
<property category="win32.*.win32b.bcc32" name="option.4.enabled" value="0"/>
<property category="win32.*.win32b.bcc32" name="option.5.enabled" value="0"/>
<property category="win32.*.win32b.bcc32" name="option.6.enabled" value="0"/>
<property category="win32.*.win32b.bcc32" name="option.H=.arg.1" value="$(BDS)\lib\vcl100.csm"/>
<property category="win32.*.win32b.bcc32" name="option.H=.arg.merge" value="1"/>
<property category="win32.*.win32b.bcc32" name="option.H=.enabled" value="1"/>
<property category="win32.*.win32b.bcc32" name="option.Hc.enabled" value="1"/>
<property category="win32.*.win32b.bcc32" name="option.I.arg.1" value="BorlndMM"/>
<property category="win32.*.win32b.bcc32" name="option.I.arg.2" value="$(BDS)\include"/>
<property category="win32.*.win32b.bcc32" name="option.I.arg.3" value="$(BDS)\include\dinkumware"/>
<property category="win32.*.win32b.bcc32" name="option.I.arg.4" value="$(BDS)\include\vcl"/>
<property category="win32.*.win32b.bcc32" name="option.I.arg.merge" value="1"/>
<property category="win32.*.win32b.bcc32" name="option.I.enabled" value="1"/>
<property category="win32.*.win32b.bcc32" name="option.O1.enabled" value="0"/>
<property category="win32.*.win32b.bcc32" name="option.O2.enabled" value="0"/>
<property category="win32.*.win32b.bcc32" name="option.Od.enabled" value="0"/>
<property category="win32.*.win32b.bcc32" name="option.Ve.enabled" value="0"/>
<property category="win32.*.win32b.bcc32" name="option.b.enabled" value="0"/>
<property category="win32.*.win32b.bcc32" name="option.disablewarns.enabled" value="0"/>
<property category="win32.*.win32b.bcc32" name="option.sysdefines.arg.1" value="_RTLDLL"/>
<property category="win32.*.win32b.bcc32" name="option.sysdefines.arg.2" value="NO_STRICT"/>
<property category="win32.*.win32b.bcc32" name="option.sysdefines.arg.3" value="_NO_VCL"/>
<property category="win32.*.win32b.bcc32" name="option.sysdefines.arg.merge" value="1"/>
<property category="win32.*.win32b.bcc32" name="option.sysdefines.enabled" value="1"/>
<property category="win32.*.win32b.bcc32" name="option.tW.enabled" value="0"/>
<property category="win32.*.win32b.bcc32" name="option.tWC.enabled" value="0"/>
<property category="win32.*.win32b.bcc32" name="option.tWD.enabled" value="1"/>
<property category="win32.*.win32b.bcc32" name="option.tWM.enabled" value="1"/>
<property category="win32.*.win32b.bcc32" name="option.w.enabled" value="0"/>
<property category="win32.*.win32b.dcc32" name="option.$A1.enabled" value="0"/>
<property category="win32.*.win32b.dcc32" name="option.$A2.enabled" value="0"/>
<property category="win32.*.win32b.dcc32" name="option.$A4.enabled" value="0"/>
<property category="win32.*.win32b.dcc32" name="option.$W.enabled" value="0"/>
<property category="win32.*.win32b.dcc32" name="option.$Z2.enabled" value="0"/>
<property category="win32.*.win32b.dcc32" name="option.$Z4.enabled" value="0"/>
<property category="win32.*.win32b.dcc32" name="option.D.arg.1" value="BCB"/>
<property category="win32.*.win32b.dcc32" name="option.D.arg.merge" value="1"/>
<property category="win32.*.win32b.dcc32" name="option.D.enabled" value="1"/>
<property category="win32.*.win32b.dcc32" name="option.GD.enabled" value="0"/>
<property category="win32.*.win32b.dcc32" name="option.GP.enabled" value="0"/>
<property category="win32.*.win32b.dcc32" name="option.GS.enabled" value="0"/>
<property category="win32.*.win32b.dcc32" name="option.I.arg.1" value="BorlndMM"/>
<property category="win32.*.win32b.dcc32" name="option.I.arg.merge" value="1"/>
<property category="win32.*.win32b.dcc32" name="option.I.enabled" value="0"/>
<property category="win32.*.win32b.dcc32" name="option.J.enabled" value="0"/>
<property category="win32.*.win32b.dcc32" name="option.JP.enabled" value="0"/>
<property category="win32.*.win32b.dcc32" name="option.JPH.enabled" value="0"/>
<property category="win32.*.win32b.dcc32" name="option.JPHN.enabled" value="1"/>
<property category="win32.*.win32b.dcc32" name="option.JPHNE.enabled" value="0"/>
<property category="win32.*.win32b.dcc32" name="option.O.arg.1" value="BorlndMM"/>
<property category="win32.*.win32b.dcc32" name="option.O.arg.merge" value="1"/>
<property category="win32.*.win32b.dcc32" name="option.O.enabled" value="0"/>
<property category="win32.*.win32b.dcc32" name="option.R.arg.1" value="BorlndMM"/>
<property category="win32.*.win32b.dcc32" name="option.R.arg.merge" value="1"/>
<property category="win32.*.win32b.dcc32" name="option.R.enabled" value="0"/>
<property category="win32.*.win32b.dcc32" name="option.U.arg.1" value="BorlndMM"/>
<property category="win32.*.win32b.dcc32" name="option.U.arg.2" value=".."/>
<property category="win32.*.win32b.dcc32" name="option.U.arg.3" value="$(BDS)\lib"/>
<property category="win32.*.win32b.dcc32" name="option.U.arg.4" value="$(BDS)\lib\obj"/>
<property category="win32.*.win32b.dcc32" name="option.U.arg.merge" value="1"/>
<property category="win32.*.win32b.dcc32" name="option.U.enabled" value="1"/>
<property category="win32.*.win32b.dcc32" name="param.filenames.merge" value="1"/>
<property category="win32.*.win32b.idl2cpp" name="option.I.arg.1" value="BorlndMM"/>
<property category="win32.*.win32b.idl2cpp" name="option.I.arg.merge" value="1"/>
<property category="win32.*.win32b.idl2cpp" name="option.I.enabled" value="1"/>
<property category="win32.*.win32b.ilink32" name="container.SelectedWarnings.containerenabled" value="1"/>
<property category="win32.*.win32b.ilink32" name="option.-w-.enabled" value="0"/>
<property category="win32.*.win32b.ilink32" name="option.Gi.enabled" value="0"/>
<property category="win32.*.win32b.ilink32" name="option.Gpd.enabled" value="0"/>
<property category="win32.*.win32b.ilink32" name="option.Gpr.enabled" value="0"/>
<property category="win32.*.win32b.ilink32" name="option.I.arg.merge" value="0"/>
<property category="win32.*.win32b.ilink32" name="option.I.enabled" value="0"/>
<property category="win32.*.win32b.ilink32" name="option.L.arg.1" value="BorlndMM"/>
<property category="win32.*.win32b.ilink32" name="option.L.arg.2" value="$(BDS)\lib"/>
<property category="win32.*.win32b.ilink32" name="option.L.arg.3" value="$(BDS)\lib\obj"/>
<property category="win32.*.win32b.ilink32" name="option.L.arg.4" value="$(BDS)\lib\psdk"/>
<property category="win32.*.win32b.ilink32" name="option.L.arg.merge" value="1"/>
<property category="win32.*.win32b.ilink32" name="option.L.enabled" value="1"/>
<property category="win32.*.win32b.ilink32" name="option.Tpd.enabled" value="1"/>
<property category="win32.*.win32b.ilink32" name="option.Tpe.enabled" value="0"/>
<property category="win32.*.win32b.ilink32" name="option.Tpp.enabled" value="0"/>
<property category="win32.*.win32b.ilink32" name="option.aa.enabled" value="0"/>
<property category="win32.*.win32b.ilink32" name="option.ap.enabled" value="0"/>
<property category="win32.*.win32b.ilink32" name="option.b:xxxx.arg" value="0x211D0000"/>
<property category="win32.*.win32b.ilink32" name="option.b:xxxx.arg.merge" value="0"/>
<property category="win32.*.win32b.ilink32" name="option.b:xxxx.enabled" value="1"/>
<property category="win32.*.win32b.ilink32" name="option.dynamicrtl.enabled" value="0"/>
<property category="win32.*.win32b.ilink32" name="option.j.arg.1" value="BorlndMM"/>
<property category="win32.*.win32b.ilink32" name="option.j.arg.merge" value="1"/>
<property category="win32.*.win32b.ilink32" name="option.j.enabled" value="0"/>
<property category="win32.*.win32b.ilink32" name="option.m.enabled" value="0"/>
<property category="win32.*.win32b.ilink32" name="option.map_segments.enabled" value="0"/>
<property category="win32.*.win32b.ilink32" name="option.outputdir.arg.merge" value="0"/>
<property category="win32.*.win32b.ilink32" name="option.outputdir.enabled" value="0"/>
<property category="win32.*.win32b.ilink32" name="option.s.enabled" value="0"/>
<property category="win32.*.win32b.ilink32" name="option.w.enabled" value="0"/>
<property category="win32.*.win32b.ilink32" name="param.libfiles.1" value="import32.lib"/>
<property category="win32.*.win32b.ilink32" name="param.libfiles.2" value="cw32mti.lib"/>
<property category="win32.*.win32b.ilink32" name="param.libfiles.merge" value="1"/>
<property category="win32.*.win32b.ilink32" name="param.objfiles.1" value="c0d32.obj"/>
<property category="win32.*.win32b.ilink32" name="param.objfiles.2" value="$(PACKAGES)"/>
<property category="win32.*.win32b.ilink32" name="param.objfiles.merge" value="1"/>
</optionset>
</project>
<FILELIST>
<FILE FILENAME="BorlndMM.bpf" CONTAINERID="BPF" LOCALCOMMAND="" UNITNAME="BorlndMM" FORMNAME="" DESIGNCLASS=""/>
<FILE FILENAME="DLLEntry.cpp" CONTAINERID="CCompiler" LOCALCOMMAND="" UNITNAME="DLLEntry" FORMNAME="" DESIGNCLASS=""/>
<FILE FILENAME="FastMM4BCB.cpp" CONTAINERID="CCompiler" LOCALCOMMAND="" UNITNAME="FastMM4BCB" FORMNAME="" DESIGNCLASS=""/>
<FILE FILENAME="FastMM4.pas" CONTAINERID="PascalCompiler" LOCALCOMMAND="" UNITNAME="FastMM4" FORMNAME="" DESIGNCLASS=""/>
<FILE FILENAME="BorlndMM.pas" CONTAINERID="PascalCompiler" LOCALCOMMAND="" UNITNAME="PasImpl" FORMNAME="" DESIGNCLASS=""/>
<FILE FILENAME="Export.def" CONTAINERID="DefTool" LOCALCOMMAND="" UNITNAME="Export" FORMNAME="" DESIGNCLASS=""/>
</FILELIST>
<IDEOPTIONS>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">2052</VersionInfo>
<VersionInfo Name="CodePage">936</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"></VersionInfoKeys>
<VersionInfoKeys Name="FileDescription"></VersionInfoKeys>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"></VersionInfoKeys>
<VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys>
<VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys>
<VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys>
<VersionInfoKeys Name="ProductName"></VersionInfoKeys>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"></VersionInfoKeys>
</VersionInfoKeys>
<Debugging>
<Debugging Name="DebugSourceDirs"></Debugging>
</Debugging>
<Parameters>
<Parameters Name="RunParams"></Parameters>
<Parameters Name="Launcher"></Parameters>
<Parameters Name="UseLauncher">False</Parameters>
<Parameters Name="DebugCWD"></Parameters>
<Parameters Name="HostApplication"></Parameters>
<Parameters Name="RemoteHost"></Parameters>
<Parameters Name="RemotePath"></Parameters>
<Parameters Name="RemoteParams"></Parameters>
<Parameters Name="RemoteLauncher"></Parameters>
<Parameters Name="UseRemoteLauncher">False</Parameters>
<Parameters Name="RemoteCWD"></Parameters>
<Parameters Name="RemoteDebug">False</Parameters>
<Parameters Name="Debug Symbols Search Path"></Parameters>
<Parameters Name="LoadAllSymbols">True</Parameters>
<Parameters Name="LoadUnspecifiedSymbols">False</Parameters>
</Parameters>
<Linker>
<Linker Name="LibPrefix"></Linker>
<Linker Name="LibSuffix"></Linker>
<Linker Name="LibVersion"></Linker>
</Linker>
</IDEOPTIONS>
</BCBPROJECT>
<buildevents/>
</CPlusPlusBuilder.Personality>
</BorlandProject>

View File

@ -0,0 +1,5 @@
This file is used by the project manager only and should be treated like the project file
To add a file to this project use the Project menu 'Add to Project'
DllEntryPoint

View File

@ -0,0 +1,248 @@
unit BorlndMM;
interface
{--------------------Start of options block-------------------------}
{Set the following option to use the RTL MM instead of FastMM. Setting this
option makes this replacement DLL almost identical to the default
borlndmm.dll, unless the "FullDebugMode" option is also set.}
{.$define UseRTLMM}
{--------------------End of options block-------------------------}
{$Include FastMM4Options.inc}
{Cannot use the RTL MM with full debug mode}
{$ifdef FullDebugMode}
{$undef UseRTLMM}
{$endif}
function GetAllocMemCount: integer;
function GetAllocMemSize: integer;
procedure DumpBlocks;
function HeapRelease: Integer;
function HeapAddRef: Integer;
function SysReallocMem(P: Pointer; Size: Integer): Pointer;
function SysFreeMem(P: Pointer): Integer;
function SysGetMem(Size: Integer): Pointer;
function SysAllocMem(Size: Cardinal): Pointer;
function ReallocMemory(P: Pointer; Size: Integer): Pointer; cdecl;
function FreeMemory(P: Pointer): Integer; cdecl;
function GetMemory(Size: Integer): Pointer; cdecl;
function GetHeapStatus: THeapStatus; deprecated; platform;
function RegisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean;
function UnregisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean;
implementation
{$ifndef UseRTLMM}
uses
FastMM4;
{$endif}
{$OPTIMIZATION ON}
{$STACKFRAMES OFF}
{$RANGECHECKS OFF}
{$OVERFLOWCHECKS OFF}
{$ifdef NoDebugInfo}
{$DEBUGINFO OFF}
{$endif}
//Export: GetAllocMemCount
//Symbol: @Borlndmm@GetAllocMemCount$qqrv
function GetAllocMemCount: integer;
begin
{Return stats for the RTL MM only}
{$ifdef UseRTLMM}
Result := System.AllocMemCount;
{$else}
Result := 0;
{$endif}
end;
//Export: GetAllocMemSize
//Symbol: @Borlndmm@GetAllocMemSize$qqrv
function GetAllocMemSize: integer;
begin
{Return stats for the RTL MM only}
{$ifdef UseRTLMM}
Result := System.AllocMemSize;
{$else}
Result := 0;
{$endif}
end;
//Export: DumpBlocks
//Symbol: @Borlndmm@DumpBlocks$qqrv
procedure DumpBlocks;
begin
{Do nothing}
end;
//Export: @Borlndmm@HeapRelease$qqrv
//Symbol: @Borlndmm@HeapRelease$qqrv
function HeapRelease: Integer;
begin
{Do nothing}
Result := 2;
end;
//Export: @Borlndmm@HeapAddRef$qqrv
//Symbol: @Borlndmm@HeapAddRef$qqrv
function HeapAddRef: Integer;
begin
{Do nothing}
Result := 2;
end;
//Export: GetHeapStatus
//Symbol: @Borlndmm@GetHeapStatus$qqrv
function GetHeapStatus: THeapStatus; deprecated; platform;
begin
{$ifndef UseRTLMM}
Result := FastGetHeapStatus;
{$else}
Result := System.GetHeapStatus;
{$endif}
end;
//Export: ReallocMemory
//Symbol: @Borlndmm@ReallocMemory$qpvi
function ReallocMemory(P: Pointer; Size: Integer): Pointer; cdecl;
begin
Result := System.ReallocMemory(P, Size);
end;
//Export: FreeMemory
//Symbol: @Borlndmm@FreeMemory$qpv
function FreeMemory(P: Pointer): Integer; cdecl;
begin
Result := System.FreeMemory(P);
end;
//Export: GetMemory
//Symbol: @Borlndmm@GetMemory$qi
function GetMemory(Size: Integer): Pointer; cdecl;
begin
Result := System.GetMemory(Size);
end;
//Export: @Borlndmm@SysReallocMem$qqrpvi
//Symbol: @Borlndmm@SysReallocMem$qqrpvi
function SysReallocMem(P: Pointer; Size: Integer): Pointer;
begin
{$ifndef UseRTLMM}
{$ifndef FullDebugMode}
Result := FastReallocMem(P, Size);
{$else}
Result := DebugReallocMem(P, Size);
{$endif}
{$else}
Result := System.SysReallocMem(P, Size);
{$endif}
end;
//Export: @Borlndmm@SysFreeMem$qqrpv
//Symbol: @Borlndmm@SysFreeMem$qqrpv
function SysFreeMem(P: Pointer): Integer;
begin
{$ifndef UseRTLMM}
{$ifndef FullDebugMode}
Result := FastFreeMem(P);
{$else}
Result := DebugFreeMem(P);
{$endif}
{$else}
Result := System.SysFreeMem(P);
{$endif}
end;
//Export: @Borlndmm@SysGetMem$qqri
//Symbol: @Borlndmm@SysGetMem$qqri
function SysGetMem(Size: Integer): Pointer;
begin
{$ifndef UseRTLMM}
{$ifndef FullDebugMode}
Result := FastGetMem(Size);
{$else}
Result := DebugGetMem(Size);
{$endif}
{$else}
Result := System.SysGetMem(Size);
{$endif}
end;
//Export: @Borlndmm@SysAllocMem$qqri
//Symbol: @Borlndmm@SysAllocMem$qqrui
function SysAllocMem(Size: Cardinal): Pointer;
begin
{$ifndef UseRTLMM}
{$ifndef FullDebugMode}
Result := FastAllocMem(Size);
{$else}
Result := DebugAllocMem(Size);
{$endif}
{$else}
//{$ifdef VER180}
{$if RTLVersion >= 18}
Result := System.SysAllocMem(Size);
{$ifend}
{$if RTLVersion < 18}
Result := System.AllocMem(Size);
{$ifend}
{$endif}
end;
//Export: @Borlndmm@SysUnregisterExpectedMemoryLeak$qqrpi
//Symbol: @Borlndmm@UnregisterExpectedMemoryLeak$qqrpv
function UnregisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean;
begin
{$ifndef UseRTLMM}
{$ifdef EnableMemoryLeakReporting}
Result := UnregisterExpectedMemoryLeak(ALeakedPointer);
{$else}
Result := False;
{$endif}
{$else}
//{$ifdef VER180}
{$if RTLVersion >= 18}
Result := System.SysUnregisterExpectedMemoryLeak(ALeakedPointer);
{$ifend}
{$if RTLVersion < 18}
Result := False;
{$ifend}
{$endif}
end;
//Export: @Borlndmm@SysRegisterExpectedMemoryLeak$qqrpi
//Symbol: @Borlndmm@RegisterExpectedMemoryLeak$qqrpv
function RegisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean;
begin
{$ifndef UseRTLMM}
{$ifdef EnableMemoryLeakReporting}
Result := RegisterExpectedMemoryLeak(ALeakedPointer);
{$else}
Result := False;
{$endif}
{$else}
//{$ifdef VER180}
{$if RTLVersion >= 18}
Result := System.SysRegisterExpectedMemoryLeak(ALeakedPointer);
{$ifend}
{$if RTLVersion < 18}
Result := False;
{$ifend}
{$endif}
end;
initialization
IsMultiThread := True;
finalization
end.

View File

@ -0,0 +1,30 @@
//---------------------------------------------------------------------------
#include <windows.h>
//---------------------------------------------------------------------------
// Important note about DLL memory management when your DLL uses the
// static version of the RunTime Library:
//
// If your DLL exports any functions that pass String objects (or structs/
// classes containing nested Strings) as parameter or function results,
// you will need to add the library MEMMGR.LIB to both the DLL project and
// any other projects that use the DLL. You will also need to use MEMMGR.LIB
// if any other projects which use the DLL will be performing new or delete
// operations on any non-TObject-derived classes which are exported from the
// DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
// EXE's to use the BORLNDMM.DLL as their memory manager. In these cases,
// the file BORLNDMM.DLL should be deployed along with your DLL.
//
// To avoid using BORLNDMM.DLL, pass string information using "char *" or
// ShortString parameters.
//
// If your DLL uses the dynamic version of the RTL, you do not need to
// explicitly add MEMMGR.LIB as this will be done implicitly for you
//---------------------------------------------------------------------------
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
//---------------------------------------------------------------------------

View File

@ -0,0 +1,29 @@
LIBRARY BORLNDMM.DLL
EXPORTS
GetAllocMemCount = @Borlndmm@GetAllocMemCount$qqrv ;To make it the 2nd export, ___CPPdebugHook always the 1st export
GetAllocMemSize = @Borlndmm@GetAllocMemSize$qqrv
GetHeapStatus = @Borlndmm@GetHeapStatus$qqrv
DumpBlocks = @Borlndmm@DumpBlocks$qqrv
ReallocMemory = @Borlndmm@ReallocMemory$qpvi
FreeMemory = @Borlndmm@FreeMemory$qpv
GetMemory = @Borlndmm@GetMemory$qi
@Borlndmm@SysUnregisterExpectedMemoryLeak$qqrpi = @Borlndmm@UnregisterExpectedMemoryLeak$qqrpv
@Borlndmm@SysRegisterExpectedMemoryLeak$qqrpi = @Borlndmm@RegisterExpectedMemoryLeak$qqrpv
@Borlndmm@SysAllocMem$qqri = @Borlndmm@SysAllocMem$qqrui
@Borlndmm@SysReallocMem$qqrpvi
@Borlndmm@SysFreeMem$qqrpv
@Borlndmm@SysGetMem$qqri
@Borlndmm@HeapRelease$qqrv
@Borlndmm@HeapAddRef$qqrv
SetMMLogFileName = @Fastmm4@SetMMLogFileName$qqrpc
GetCurrentAllocationGroup = @Fastmm4@GetCurrentAllocationGroup$qqrv
PushAllocationGroup = @Fastmm4@PushAllocationGroup$qqrui
PopAllocationGroup = @Fastmm4@PopAllocationGroup$qqrv
LogAllocatedBlocksToFile = @Fastmm4@LogAllocatedBlocksToFile$qqruiui

View File

@ -0,0 +1 @@
LoadDebugDLLDynamically must be defined.

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,248 @@
unit BorlndMM;
interface
{--------------------Start of options block-------------------------}
{Set the following option to use the RTL MM instead of FastMM. Setting this
option makes this replacement DLL almost identical to the default
borlndmm.dll, unless the "FullDebugMode" option is also set.}
{.$define UseRTLMM}
{--------------------End of options block-------------------------}
{$Include FastMM4Options.inc}
{Cannot use the RTL MM with full debug mode}
{$ifdef FullDebugMode}
{$undef UseRTLMM}
{$endif}
function GetAllocMemCount: integer;
function GetAllocMemSize: integer;
procedure DumpBlocks;
function HeapRelease: Integer;
function HeapAddRef: Integer;
function SysReallocMem(P: Pointer; Size: Integer): Pointer;
function SysFreeMem(P: Pointer): Integer;
function SysGetMem(Size: Integer): Pointer;
function SysAllocMem(Size: Cardinal): Pointer;
function ReallocMemory(P: Pointer; Size: Integer): Pointer; cdecl;
function FreeMemory(P: Pointer): Integer; cdecl;
function GetMemory(Size: Integer): Pointer; cdecl;
function GetHeapStatus: THeapStatus; deprecated; platform;
function RegisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean;
function UnregisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean;
implementation
{$ifndef UseRTLMM}
uses
FastMM4;
{$endif}
{$OPTIMIZATION ON}
{$STACKFRAMES OFF}
{$RANGECHECKS OFF}
{$OVERFLOWCHECKS OFF}
{$ifdef NoDebugInfo}
{$DEBUGINFO OFF}
{$endif}
//Export: GetAllocMemCount
//Symbol: @Borlndmm@GetAllocMemCount$qqrv
function GetAllocMemCount: integer;
begin
{Return stats for the RTL MM only}
{$ifdef UseRTLMM}
Result := System.AllocMemCount;
{$else}
Result := 0;
{$endif}
end;
//Export: GetAllocMemSize
//Symbol: @Borlndmm@GetAllocMemSize$qqrv
function GetAllocMemSize: integer;
begin
{Return stats for the RTL MM only}
{$ifdef UseRTLMM}
Result := System.AllocMemSize;
{$else}
Result := 0;
{$endif}
end;
//Export: DumpBlocks
//Symbol: @Borlndmm@DumpBlocks$qqrv
procedure DumpBlocks;
begin
{Do nothing}
end;
//Export: @Borlndmm@HeapRelease$qqrv
//Symbol: @Borlndmm@HeapRelease$qqrv
function HeapRelease: Integer;
begin
{Do nothing}
Result := 2;
end;
//Export: @Borlndmm@HeapAddRef$qqrv
//Symbol: @Borlndmm@HeapAddRef$qqrv
function HeapAddRef: Integer;
begin
{Do nothing}
Result := 2;
end;
//Export: GetHeapStatus
//Symbol: @Borlndmm@GetHeapStatus$qqrv
function GetHeapStatus: THeapStatus; deprecated; platform;
begin
{$ifndef UseRTLMM}
Result := FastGetHeapStatus;
{$else}
Result := System.GetHeapStatus;
{$endif}
end;
//Export: ReallocMemory
//Symbol: @Borlndmm@ReallocMemory$qpvi
function ReallocMemory(P: Pointer; Size: Integer): Pointer; cdecl;
begin
Result := System.ReallocMemory(P, Size);
end;
//Export: FreeMemory
//Symbol: @Borlndmm@FreeMemory$qpv
function FreeMemory(P: Pointer): Integer; cdecl;
begin
Result := System.FreeMemory(P);
end;
//Export: GetMemory
//Symbol: @Borlndmm@GetMemory$qi
function GetMemory(Size: Integer): Pointer; cdecl;
begin
Result := System.GetMemory(Size);
end;
//Export: @Borlndmm@SysReallocMem$qqrpvi
//Symbol: @Borlndmm@SysReallocMem$qqrpvi
function SysReallocMem(P: Pointer; Size: Integer): Pointer;
begin
{$ifndef UseRTLMM}
{$ifndef FullDebugMode}
Result := FastReallocMem(P, Size);
{$else}
Result := DebugReallocMem(P, Size);
{$endif}
{$else}
Result := System.SysReallocMem(P, Size);
{$endif}
end;
//Export: @Borlndmm@SysFreeMem$qqrpv
//Symbol: @Borlndmm@SysFreeMem$qqrpv
function SysFreeMem(P: Pointer): Integer;
begin
{$ifndef UseRTLMM}
{$ifndef FullDebugMode}
Result := FastFreeMem(P);
{$else}
Result := DebugFreeMem(P);
{$endif}
{$else}
Result := System.SysFreeMem(P);
{$endif}
end;
//Export: @Borlndmm@SysGetMem$qqri
//Symbol: @Borlndmm@SysGetMem$qqri
function SysGetMem(Size: Integer): Pointer;
begin
{$ifndef UseRTLMM}
{$ifndef FullDebugMode}
Result := FastGetMem(Size);
{$else}
Result := DebugGetMem(Size);
{$endif}
{$else}
Result := System.SysGetMem(Size);
{$endif}
end;
//Export: @Borlndmm@SysAllocMem$qqri
//Symbol: @Borlndmm@SysAllocMem$qqrui
function SysAllocMem(Size: Cardinal): Pointer;
begin
{$ifndef UseRTLMM}
{$ifndef FullDebugMode}
Result := FastAllocMem(Size);
{$else}
Result := DebugAllocMem(Size);
{$endif}
{$else}
//{$ifdef VER180}
{$if RTLVersion >= 18}
Result := System.SysAllocMem(Size);
{$ifend}
{$if RTLVersion < 18}
Result := System.AllocMem(Size);
{$ifend}
{$endif}
end;
//Export: @Borlndmm@SysUnregisterExpectedMemoryLeak$qqrpi
//Symbol: @Borlndmm@UnregisterExpectedMemoryLeak$qqrpv
function UnregisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean;
begin
{$ifndef UseRTLMM}
{$ifdef EnableMemoryLeakReporting}
Result := UnregisterExpectedMemoryLeak(ALeakedPointer);
{$else}
Result := False;
{$endif}
{$else}
//{$ifdef VER180}
{$if RTLVersion >= 18}
Result := System.SysUnregisterExpectedMemoryLeak(ALeakedPointer);
{$ifend}
{$if RTLVersion < 18}
Result := False;
{$ifend}
{$endif}
end;
//Export: @Borlndmm@SysRegisterExpectedMemoryLeak$qqrpi
//Symbol: @Borlndmm@RegisterExpectedMemoryLeak$qqrpv
function RegisterExpectedMemoryLeak(ALeakedPointer: Pointer): Boolean;
begin
{$ifndef UseRTLMM}
{$ifdef EnableMemoryLeakReporting}
Result := RegisterExpectedMemoryLeak(ALeakedPointer);
{$else}
Result := False;
{$endif}
{$else}
//{$ifdef VER180}
{$if RTLVersion >= 18}
Result := System.SysRegisterExpectedMemoryLeak(ALeakedPointer);
{$ifend}
{$if RTLVersion < 18}
Result := False;
{$ifend}
{$endif}
end;
initialization
IsMultiThread := True;
finalization
end.

View File

@ -0,0 +1,30 @@
//---------------------------------------------------------------------------
#include <windows.h>
//---------------------------------------------------------------------------
// Important note about DLL memory management when your DLL uses the
// static version of the RunTime Library:
//
// If your DLL exports any functions that pass String objects (or structs/
// classes containing nested Strings) as parameter or function results,
// you will need to add the library MEMMGR.LIB to both the DLL project and
// any other projects that use the DLL. You will also need to use MEMMGR.LIB
// if any other projects which use the DLL will be performing new or delete
// operations on any non-TObject-derived classes which are exported from the
// DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
// EXE's to use the BORLNDMM.DLL as their memory manager. In these cases,
// the file BORLNDMM.DLL should be deployed along with your DLL.
//
// To avoid using BORLNDMM.DLL, pass string information using "char *" or
// ShortString parameters.
//
// If your DLL uses the dynamic version of the RTL, you do not need to
// explicitly add MEMMGR.LIB as this will be done implicitly for you
//---------------------------------------------------------------------------
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
//---------------------------------------------------------------------------

View File

@ -0,0 +1,29 @@
LIBRARY BORLNDMM.DLL
EXPORTS
GetAllocMemCount = @Borlndmm@GetAllocMemCount$qqrv ;To make it the 2nd export, ___CPPdebugHook always the 1st export
GetAllocMemSize = @Borlndmm@GetAllocMemSize$qqrv
GetHeapStatus = @Borlndmm@GetHeapStatus$qqrv
DumpBlocks = @Borlndmm@DumpBlocks$qqrv
ReallocMemory = @Borlndmm@ReallocMemory$qpvi
FreeMemory = @Borlndmm@FreeMemory$qpv
GetMemory = @Borlndmm@GetMemory$qi
@Borlndmm@SysUnregisterExpectedMemoryLeak$qqrpi = @Borlndmm@UnregisterExpectedMemoryLeak$qqrpv
@Borlndmm@SysRegisterExpectedMemoryLeak$qqrpi = @Borlndmm@RegisterExpectedMemoryLeak$qqrpv
@Borlndmm@SysAllocMem$qqri = @Borlndmm@SysAllocMem$qqrui
@Borlndmm@SysReallocMem$qqrpvi
@Borlndmm@SysFreeMem$qqrpv
@Borlndmm@SysGetMem$qqri
@Borlndmm@HeapRelease$qqrv
@Borlndmm@HeapAddRef$qqrv
SetMMLogFileName = @Fastmm4@SetMMLogFileName$qqrpc
GetCurrentAllocationGroup = @Fastmm4@GetCurrentAllocationGroup$qqrv
PushAllocationGroup = @Fastmm4@PushAllocationGroup$qqrui
PopAllocationGroup = @Fastmm4@PopAllocationGroup$qqrv
LogAllocatedBlocksToFile = @Fastmm4@LogAllocatedBlocksToFile$qqruiui

View File

@ -0,0 +1 @@
LoadDebugDLLDynamically must be defined.

View File

@ -0,0 +1,182 @@
{
Fast Memory Manager: Replacement BorlndMM.DLL 1.05
Description:
A replacement borlndmm.dll using FastMM instead of the RTL MM. This DLL may be
used instead of the default DLL together with your own applications or the
Delphi IDE, making the benefits of FastMM available to them.
Usage:
1) Make sure the "NeverUninstall" conditional define is set in FastMM4.pas if
you intend to use the DLL with the Delphi IDE, otherwise it must be off.
2) Compile this DLL
3) Ship it with your existing applications that currently uses the borlndmm.dll
file that ships with Delphi for an improvement in speed.
4) Copy it over the current borlndmm.dll in the Delphi \Bin\ directory (after
renaming the old one) to speed up the IDE.*
Acknowledgements:
- Arthur Hoornweg for notifying me of the image base being incorrect for
borlndmm.dll.
- Cord Schneider for notifying me of the compilation error under Delphi 5.
Change log:
Version 1.00 (28 June 2005):
- Initial release.
Version 1.01 (30 June 2005):
- Added an unofficial patch for QC#14007 that prevented a replacement
borlndmm.dll from working together with Delphi 2005.
- Added the "NeverUninstall" option in FastMM4.pas to circumvent QC#14070,
which causes an A/V on shutdown of Delphi if FastMM uninstalls itself in the
finalization code of FastMM4.pas.
Version 1.02 (19 July 2005):
- Set the imagebase to $00D20000 to avoid relocation on load (and thus allow
sharing of the DLL between processes). (Thanks to Arthur Hoornweg.)
Version 1.03 (10 November 2005):
- Added exports for AllocMem and leak (un)registration
Version 1.04 (22 December 2005):
- Fixed the compilation error under Delphi 5. (Thanks to Cord Schneider.)
Version 1.05 (23 February 2006):
- Added some exports to allow access to the extended FullDebugMode
functionality in FastMM.
*For this replacement borlndmm.dll to work together with Delphi 2005, you will
need to apply the unofficial patch for QC#14007. To compile a replacement
borlndmm.dll for use with the Delphi IDE the "NeverUninstall" option must be
set (to circumvent QC#14070). For other uses the "NeverUninstall" option
should be disabled. For a list of unofficial patches for Delphi 2005 (and
where to get them), refer to the FastMM4_Readme.txt file.
}
{--------------------Start of options block-------------------------}
{Set the following option to use the RTL MM instead of FastMM. Setting this
option makes this replacement DLL almost identical to the default
borlndmm.dll, unless the "FullDebugMode" option is also set.}
{.$define UseRTLMM}
{--------------------End of options block-------------------------}
{$Include FastMM4Options.inc}
{Cannot use the RTL MM with full debug mode}
{$ifdef FullDebugMode}
{$undef UseRTLMM}
{$endif}
{Set the correct image base}
{$IMAGEBASE $00D20000}
library BorlndMM;
{$ifndef UseRTLMM}
uses
FastMM4 in 'FastMM4.pas',
FastMM4Messages in 'FastMM4Messages.pas';
{$endif}
{$R *.RES}
function GetAllocMemCount: integer;
begin
{Return stats for the RTL MM only}
{$ifdef UseRTLMM}
Result := System.AllocMemCount;
{$else}
Result := 0;
{$endif}
end;
function GetAllocMemSize: integer;
begin
{Return stats for the RTL MM only}
{$ifdef UseRTLMM}
Result := System.AllocMemSize;
{$else}
Result := 0;
{$endif}
end;
procedure DumpBlocks;
begin
{Do nothing}
end;
function HeapRelease: Integer;
begin
{Do nothing}
Result := 2;
end;
function HeapAddRef: Integer;
begin
{Do nothing}
Result := 2;
end;
function DummyRegisterAndUnregisterExpectedMemoryLeak(ALeakedPointer: Pointer): boolean;
begin
Result := False;
end;
exports
GetAllocMemSize name 'GetAllocMemSize',
GetAllocMemCount name 'GetAllocMemCount',
{$ifndef UseRTLMM}
FastGetHeapStatus name 'GetHeapStatus',
{$else}
System.GetHeapStatus name 'GetHeapStatus',
{$endif}
DumpBlocks name 'DumpBlocks',
System.ReallocMemory name 'ReallocMemory',
System.FreeMemory name 'FreeMemory',
System.GetMemory name 'GetMemory',
{$ifndef UseRTLMM}
{$ifndef FullDebugMode}
FastReallocMem name '@Borlndmm@SysReallocMem$qqrpvi',
FastFreeMem name '@Borlndmm@SysFreeMem$qqrpv',
FastGetMem name '@Borlndmm@SysGetMem$qqri',
FastAllocMem name '@Borlndmm@SysAllocMem$qqri',
{$else}
DebugReallocMem name '@Borlndmm@SysReallocMem$qqrpvi',
DebugFreeMem name '@Borlndmm@SysFreeMem$qqrpv',
DebugGetMem name '@Borlndmm@SysGetMem$qqri',
DebugAllocMem name '@Borlndmm@SysAllocMem$qqri',
{$endif}
{$ifdef EnableMemoryLeakReporting}
RegisterExpectedMemoryLeak(ALeakedPointer: Pointer) name '@Borlndmm@SysRegisterExpectedMemoryLeak$qqrpi',
UnregisterExpectedMemoryLeak(ALeakedPointer: Pointer) name '@Borlndmm@SysUnregisterExpectedMemoryLeak$qqrpi',
{$else}
DummyRegisterAndUnregisterExpectedMemoryLeak name '@Borlndmm@SysRegisterExpectedMemoryLeak$qqrpi',
DummyRegisterAndUnregisterExpectedMemoryLeak name '@Borlndmm@SysUnregisterExpectedMemoryLeak$qqrpi',
{$endif}
{$else}
System.SysReallocMem name '@Borlndmm@SysReallocMem$qqrpvi',
System.SysFreeMem name '@Borlndmm@SysFreeMem$qqrpv',
System.SysGetMem name '@Borlndmm@SysGetMem$qqri',
{$ifdef VER180};
System.SysAllocMem name '@Borlndmm@SysAllocMem$qqri',
System.SysRegisterExpectedMemoryLeak name '@Borlndmm@SysRegisterExpectedMemoryLeak$qqrpi',
System.SysUnregisterExpectedMemoryLeak name '@Borlndmm@SysUnregisterExpectedMemoryLeak$qqrpi',
{$else}
System.AllocMem name '@Borlndmm@SysAllocMem$qqri',
DummyRegisterAndUnregisterExpectedMemoryLeak name '@Borlndmm@SysRegisterExpectedMemoryLeak$qqrpi',
DummyRegisterAndUnregisterExpectedMemoryLeak name '@Borlndmm@SysUnregisterExpectedMemoryLeak$qqrpi',
{$endif}
{$endif}
{$ifdef FullDebugMode}
SetMMLogFileName,
GetCurrentAllocationGroup,
PushAllocationGroup,
PopAllocationGroup,
LogAllocatedBlocksToFile,
{$endif}
HeapRelease name '@Borlndmm@HeapRelease$qqrv',
HeapAddRef name '@Borlndmm@HeapAddRef$qqrv';
begin
IsMultiThread := True;
end.

View File

@ -0,0 +1,74 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{b2046f52-e024-4415-9fc4-47822f5d8392}</ProjectGuid>
<MainSource>BorlndMM.dpr</MainSource>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
<DCC_DependencyCheckOutputName>BorlndMM.dll</DCC_DependencyCheckOutputName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Version>7.0</Version>
<DCC_DebugInformation>False</DCC_DebugInformation>
<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_MapFile>3</DCC_MapFile>
<DCC_ImageBase>D20000</DCC_ImageBase>
<DCC_Define>borlndmmdll;debugdll;dllforide;RELEASE</DCC_Define>
<DCC_SYMBOL_PLATFORM>False</DCC_SYMBOL_PLATFORM>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<Version>7.0</Version>
<DCC_MapFile>3</DCC_MapFile>
<DCC_ImageBase>D20000</DCC_ImageBase>
<DCC_Define>borlndmmdll;debugdll;dllforide;DEBUG</DCC_Define>
<DCC_SYMBOL_PLATFORM>False</DCC_SYMBOL_PLATFORM>
</PropertyGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality</Borland.Personality>
<Borland.ProjectType>VCLApplication</Borland.ProjectType>
<BorlandProject>
<BorlandProject xmlns=""> <Delphi.Personality> <Parameters>
<Parameters Name="UseLauncher">False</Parameters>
<Parameters Name="LoadAllSymbols">True</Parameters>
<Parameters Name="LoadUnspecifiedSymbols">False</Parameters>
</Parameters>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">True</VersionInfo>
<VersionInfo Name="AutoIncBuild">True</VersionInfo>
<VersionInfo Name="MajorVer">4</VersionInfo>
<VersionInfo Name="MinorVer">76</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">179</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">7177</VersionInfo>
<VersionInfo Name="CodePage">1252</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName">Pierre le Riche / Professional Software Development</VersionInfoKeys>
<VersionInfoKeys Name="FileDescription">Replacement Memory Manager for Delphi IDE and Applications</VersionInfoKeys>
<VersionInfoKeys Name="FileVersion">4.76.0.179</VersionInfoKeys>
<VersionInfoKeys Name="InternalName">Fast Memory Manager</VersionInfoKeys>
<VersionInfoKeys Name="LegalCopyright">License: MPL 1.1</VersionInfoKeys>
<VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys>
<VersionInfoKeys Name="OriginalFilename">BorlndMM.DLL</VersionInfoKeys>
<VersionInfoKeys Name="ProductName">FastMM</VersionInfoKeys>
<VersionInfoKeys Name="ProductVersion">4</VersionInfoKeys>
</VersionInfoKeys>
<Source>
<Source Name="MainSource">BorlndMM.dpr</Source>
</Source>
</Delphi.Personality> </BorlandProject></BorlandProject>
</ProjectExtensions>
<ItemGroup />
<ItemGroup>
<DelphiCompile Include="BorlndMM.dpr">
<MainSource>MainSource</MainSource>
</DelphiCompile>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Borland.Delphi.Targets" />
</Project>

View File

@ -0,0 +1,50 @@
{
Fast Memory Manager: FullDebugMode Borlndmm.dll support unit
If you use the replacement Borlndmm.dll compiled in FullDebugMode, and you need
access to some of the extended functionality that is not imported by
sharemem.pas, then you may use this unit to get access to it. Please note that
you will still need to add sharemem.pas as the first unit in the "uses"
section of the .dpr, and the FastMM_FullDebugMode.dll must be available on the
path. Also, the borlndmm.dll that you will be using *must* be compiled using
FullDebugMode.}
unit FastMMDebugSupport;
interface
{Specify the full path and name for the filename to be used for logging memory
errors, etc. If ALogFileName is nil or points to an empty string it will
revert to the default log file name.}
procedure SetMMLogFileName(ALogFileName: PAnsiChar = nil);
{Returns the current "allocation group". Whenever a GetMem request is serviced
in FullDebugMode, the current "allocation group" is stored in the block header.
This may help with debugging. Note that if a block is subsequently reallocated
that it keeps its original "allocation group" and "allocation number" (all
allocations are also numbered sequentially).}
function GetCurrentAllocationGroup: Cardinal;
{Allocation groups work in a stack like fashion. Group numbers are pushed onto
and popped off the stack. Note that the stack size is limited, so every push
should have a matching pop.}
procedure PushAllocationGroup(ANewCurrentAllocationGroup: Cardinal);
procedure PopAllocationGroup;
{Logs detail about currently allocated memory blocks for the specified range of
allocation groups. if ALastAllocationGroupToLog is less than
AFirstAllocationGroupToLog or it is zero, then all allocation groups are
logged. This routine also checks the memory pool for consistency at the same
time.}
procedure LogAllocatedBlocksToFile(AFirstAllocationGroupToLog, ALastAllocationGroupToLog: Cardinal);
implementation
const
borlndmm = 'borlndmm.dll';
procedure SetMMLogFileName; external borlndmm;
function GetCurrentAllocationGroup; external borlndmm;
procedure PushAllocationGroup; external borlndmm;
procedure PopAllocationGroup; external borlndmm;
procedure LogAllocatedBlocksToFile; external borlndmm;
end.

View File

@ -0,0 +1,134 @@
{
Fast Memory Manager: Messages
Afrikaans translation by Pierre le Riche.
}
unit FastMM4Messages;
interface
{$Include FastMM4Options.inc}
const
{The name of the debug info support DLL}
FullDebugModeLibraryName32Bit = 'FastMM_FullDebugMode.dll';
FullDebugModeLibraryName64Bit = 'FastMM_FullDebugMode64.dll';
{Event log strings}
LogFileExtension = '_MemoryManager_EventLog.txt'#0;
CRLF = #13#10;
EventSeparator = '--------------------------------';
{Class name messages}
UnknownClassNameMsg = 'Onbekend';
{Memory dump message}
MemoryDumpMsg = #13#10#13#10'Huidige geheue inhoud: 256 grepe vanaf adres ';
{Block Error Messages}
BlockScanLogHeader = 'Geallokeerde blok gelys deur LogAllocatedBlocksToFile. The grootte is: ';
ErrorMsgHeader = 'FastMM het ''n fout teegekom in die uitvoer van ''n ';
GetMemMsg = 'GetMem';
FreeMemMsg = 'FreeMem';
ReallocMemMsg = 'ReallocMem';
BlockCheckMsg = 'ongebruikte blok toets';
OperationMsg = ' proses. ';
BlockHeaderCorruptedMsg = 'Die merker voor die blok is beskadig. ';
BlockFooterCorruptedMsg = 'Die merker na die blok is beskadig. ';
FreeModifiedErrorMsg = 'FastMM het gevind dat ''n blok verander is sedert dit vrygestel is. ';
FreeModifiedDetailMsg = #13#10#13#10'Die veranderde grepe begin posisies (en aantal) is: ';
DoubleFreeErrorMsg = '''n Poging is aangewend om ''n ongebruikte blok vry te stel of te herallokeer.';
WrongMMFreeErrorMsg = '''n Poging is aangewend om ''n blok vry te stel of te herallokeer wat deur ''n ander FastMM instansie geallokeer is. Ondersoek jou FastMM deel verstellings.';
PreviousBlockSizeMsg = #13#10#13#10'Die vorige blok grootte was: ';
CurrentBlockSizeMsg = #13#10#13#10'Die blok grootte is: ';
PreviousObjectClassMsg = #13#10#13#10'Die blok is voorheen gebruik vir ''n objek van die klas: ';
CurrentObjectClassMsg = #13#10#13#10'Die blok word huidiglik gebruik vir ''n objek van die klas: ';
PreviousAllocationGroupMsg = #13#10#13#10'Die allokasie groep was: ';
PreviousAllocationNumberMsg = #13#10#13#10'Die allokasie nommer was: ';
CurrentAllocationGroupMsg = #13#10#13#10'Die allokasie groep is: ';
CurrentAllocationNumberMsg = #13#10#13#10'Die allokasie nommer is: ';
BlockErrorMsgTitle = 'Geheue Fout';
VirtualMethodErrorHeader = 'FastMM het ''n poging onderskep om ''n virtuele funksie of prosedure van ''n vrygestelde objek te roep. ''n Toegangsfout sal nou veroorsaak word om die proses te onderbreek.';
InterfaceErrorHeader = 'FastMM het ''n poging onderskep om ''n koppelvlak van ''n vrygestelde objek te gebruik. ''n Toegangsfout sal nou veroorsaak word om die proses te onderbreek.';
BlockHeaderCorruptedNoHistoryMsg = ' Ongelukkig is die merker voor die blok beskadig en dus is geen blok geskiedenis beskikbaar nie.';
FreedObjectClassMsg = #13#10#13#10'Vrygestelde objek klas: ';
VirtualMethodName = #13#10#13#10'Virtuele funksie/prosedure: ';
VirtualMethodOffset = 'VMT Adres +';
VirtualMethodAddress = #13#10#13#10'Virtuele funksie/prosedure address: ';
{Stack trace messages}
CurrentThreadIDMsg = #13#10#13#10'Die huidige thread ID is 0x';
CurrentStackTraceMsg = ', en die stapel spoor (terugkeer adresse) wat gelei het tot die fout is:';
ThreadIDPrevAllocMsg = #13#10#13#10'Die blok is voorheen geallokeer deur thread 0x';
ThreadIDAtAllocMsg = #13#10#13#10'Die blok is geallokeer deur thread 0x';
ThreadIDAtFreeMsg = #13#10#13#10'Die blok is voorheen vrygestel deur thread 0x';
ThreadIDAtObjectAllocMsg = #13#10#13#10'Die objek is geallokeer deur thread 0x';
ThreadIDAtObjectFreeMsg = #13#10#13#10'Die objek is daarna vrygestel deur thread 0x';
StackTraceMsg = ', en die stapel spoor (terugkeer adresse) was toe:';
{Installation Messages}
AlreadyInstalledMsg = 'FastMM4 is alreeds geïnstalleer.';
AlreadyInstalledTitle = 'Alreeds geïnstalleer.';
OtherMMInstalledMsg = 'FastMM4 kan nie geïnstalleer word nie, want ''n ander '
+ 'derde party geheuebestuurder is alreeds geïnstalleer.'#13#10'Indien jy FastMM4 wil gebruik, '
+ 'verseker asb. dat FastMM4.pas die eerste leêr is in die "uses"'
+ #13#10'afdeling van jou projek se .dpr leêr.';
OtherMMInstalledTitle = 'FastMM4 kan nie geïnstalleer word nie - ''n ander geheue bestuurder is alreeds geïnstalleer';
MemoryAllocatedMsg = 'FastMM4 kan nie geïnstalleer word nie aangesien geheue reeds '
+ 'geallokeer is deur die verstek geheue bestuurder.'#13#10'FastMM4.pas MOET '
+ 'die eerste leêr wees in jou projek se .dpr leêr, andersins mag geheie geallokeer word'
+ ''#13#10'deur die verstek geheue bestuurder voordat FastMM4 '
+ 'beheer verkry. '#13#10#13#10'As jy ''n foutvanger soos MadExcept gebruik '
+ '(of enigiets wat die peuter met die inisialiseringsvolgorder van eenhede),'
+ #13#10' gaan in sy opstelling bladsy in en verseker dat FastMM4.pas eerste geïnisialiseer word.';
MemoryAllocatedTitle = 'FastMM4 kan nie geïnstalleer word nie - geheue is alreeds geallokeer';
{Leak checking messages}
LeakLogHeader = '''n Geheue blok het gelek. Die grootte is: ';
LeakMessageHeader = 'Hierdie program het geheue gelek. ';
SmallLeakDetail = 'Die klein blok lekkasies is'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (verwagte lekkasies geregistreer deur wyser is uitgesluit)'
{$endif}
+ ':'#13#10;
LargeLeakDetail = 'Die groottes van medium en groot blok lekkasies is'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (verwagte lekkasies geregistreer deur wyser is uitgesluit)'
{$endif}
+ ': ';
BytesMessage = ' grepe: ';
AnsiStringBlockMessage = 'AnsiString';
UnicodeStringBlockMessage = 'UnicodeString';
LeakMessageFooter = #13#10
{$ifndef HideMemoryLeakHintMessage}
+ #13#10'Nota: '
{$ifdef RequireIDEPresenceForLeakReporting}
+ 'Die geheie lekkasie toets word slegs gedoen indien Delphi op daardie tydstip op die masjien loop. '
{$endif}
{$ifdef FullDebugMode}
{$ifdef LogMemoryLeakDetailToFile}
+ 'Lekkasie detail word gelog na ''n teks leêr in dieselfde gids as hierdie program. '
{$else}
+ 'Sit "LogMemoryLeakDetailToFile" aan om ''n gedetailleerde verslag oor al die geheue lekkasies na teksleêr te skryf. '
{$endif}
{$else}
+ 'Sit die "FullDebugMode" en "LogMemoryLeakDetailToFile" opsies aan om ''n gedetailleerde verslag oor al die geheue lekkasies na teksleêr te skryf. '
{$endif}
+ 'Om die lekkasie toets te deaktiveer, sit die "EnableMemoryLeakReporting" opsie af.'#13#10
{$endif}
+ #0;
LeakMessageTitle = 'Geheue Lekkasie';
{$ifdef UseOutputDebugString}
FastMMInstallMsg = 'FastMM has been installed.';
FastMMInstallSharedMsg = 'Sharing an existing instance of FastMM.';
FastMMUninstallMsg = 'FastMM has been uninstalled.';
FastMMUninstallSharedMsg = 'Stopped sharing an existing instance of FastMM.';
{$endif}
{$ifdef DetectMMOperationsAfterUninstall}
InvalidOperationTitle = 'MM Operation after uninstall.';
InvalidGetMemMsg = 'FastMM has detected a GetMem call after FastMM was uninstalled.';
InvalidFreeMemMsg = 'FastMM has detected a FreeMem call after FastMM was uninstalled.';
InvalidReallocMemMsg = 'FastMM has detected a ReallocMem call after FastMM was uninstalled.';
InvalidAllocMemMsg = 'FastMM has detected an AllocMem call after FastMM was uninstalled.';
{$endif}
implementation
end.

View File

@ -0,0 +1,136 @@
{
Fast Memory Manager: Messages
belarussian translation by dzmitry[li]
mailto:dzmitry@biz.by
Ýëåêòðîííàÿ êàðòà ãîðàäà ˳äà
}
unit FastMM4Messages;
interface
{$Include FastMM4Options.inc}
const
{The name of the debug info support DLL}
FullDebugModeLibraryName32Bit = 'FastMM_FullDebugMode.dll';
FullDebugModeLibraryName64Bit = 'FastMM_FullDebugMode64.dll';
{Event log strings}
LogFileExtension = '_MemoryManager_EventLog.txt'#0;
CRLF = #13#10;
EventSeparator = '--------------------------------';
{Class name messages}
UnknownClassNameMsg = 'Unknown';
{Memory dump message}
MemoryDumpMsg = #13#10#13#10'Áÿãó÷û äàìï ïàìÿö³ ç 256 áàéò ïà÷ûíàëüíà ç àäðàñó ';
{Block Error Messages}
BlockScanLogHeader = 'Allocated block logged by LogAllocatedBlocksToFile. The size is: ';
ErrorMsgHeader = 'FastMM âûÿâ³¢ ïàìûëêó ïàä÷àñ ';
GetMemMsg = 'GetMem';
FreeMemMsg = 'FreeMem';
ReallocMemMsg = 'ReallocMem';
BlockCheckMsg = 'ñêàíàâàííÿ âûçâàëåíàãà áëîêó';
OperationMsg = ' àïåðàöûÿ. ';
BlockHeaderCorruptedMsg = 'Çàãàëîâàê áëîêà ïàøêîäæàíû. ';
BlockFooterCorruptedMsg = 'ͳæíÿÿ ÷àñòêà áëîêà ïàøêîäæàíà. ';
FreeModifiedErrorMsg = 'FastMM âûÿâ³¢ øòî áëîê áû¢ ìàäûô³êàâàíû ïàñëÿ ÿãî âûçâàëåííÿ. ';
FreeModifiedDetailMsg = #13#10#13#10'Modified byte offsets (and lengths): ';
DoubleFreeErrorMsg = 'Áûëà ðàñïà÷àòà ñïðîáà âûçâàë³öü/ïåðàâûçâàë³öü íåâûëó÷àíû áëîê.';
WrongMMFreeErrorMsg = 'An attempt has been made to free/reallocate a block that was allocated through a different FastMM instance. Check your memory manager sharing settings.';
PreviousBlockSizeMsg = #13#10#13#10'Ïàìåð ïàïÿðýäíÿãà áëîêà áû¢: ';
CurrentBlockSizeMsg = #13#10#13#10'Ïàìåð áëîêà: ';
PreviousObjectClassMsg = #13#10#13#10'Áëîê áû¢ ðàíåé ñêàðûñòàíû äëÿ àá''åêòà êëàñà: ';
CurrentObjectClassMsg = #13#10#13#10'Áëîê ó öÿïåðàøí³ ÷àñ âûêàðûñòî¢âàåööà äëÿ àá''åêòà êëàñà: ';
PreviousAllocationGroupMsg = #13#10#13#10'The allocation group was: ';
PreviousAllocationNumberMsg = #13#10#13#10'The allocation number was: ';
CurrentAllocationGroupMsg = #13#10#13#10'The allocation group is: ';
CurrentAllocationNumberMsg = #13#10#13#10'The allocation number is: ';
BlockErrorMsgTitle = 'Âûÿ¢ëåíàÿ ïàìûëêà ïàìÿö³.';
VirtualMethodErrorHeader = 'FastMM âûÿâ³¢ ñïðîáó âûêë³êàöü â³ðòóàëüíû ìåòàä âûçâàëåíàãà àá''åêòà. Çàðàç áóäçå âûêë³êàíà ïàðóøýííå äîñòóïó äëÿ ïåðàïûíåííÿ áÿãó÷àé àïåðàöû³.';
InterfaceErrorHeader = 'FastMM âûÿâ³¢ ñïðîáó âûêàðûñòàöü ³íòýðôåéñ âûçâàëåíàãà àá''åêòà. Çàðàç áóäçå âûêë³êàíà ïàðóøýííå äîñòóïó äëÿ ïåðàïûíåííÿ áÿãó÷àé àïåðàöû³.';
BlockHeaderCorruptedNoHistoryMsg = ' Íàæàëü çàãàëîâàê áëîêà ïàøêîäæàíû ³ ã³ñòîðûÿ íå äàñòóïíàÿ.';
FreedObjectClassMsg = #13#10#13#10'Êëàñ âûçâàëåíàãà àá''åêòà: ';
VirtualMethodName = #13#10#13#10'³ðòóàëüíû ìåòàä: ';
VirtualMethodOffset = 'Çðóøýííå +';
VirtualMethodAddress = #13#10#13#10'Àäðàñ â³ðòóàëüíàãà ìåòàäó: ';
{Stack trace messages}
CurrentThreadIDMsg = #13#10#13#10'The current thread ID is 0x';
CurrentStackTraceMsg = ', and the stack trace (return addresses) leading to this error is:';
ThreadIDPrevAllocMsg = #13#10#13#10'This block was previously allocated by thread 0x';
ThreadIDAtAllocMsg = #13#10#13#10'This block was allocated by thread 0x';
ThreadIDAtFreeMsg = #13#10#13#10'The block was previously freed by thread 0x';
ThreadIDAtObjectAllocMsg = #13#10#13#10'The object was allocated by thread 0x';
ThreadIDAtObjectFreeMsg = #13#10#13#10'The object was subsequently freed by thread 0x';
StackTraceMsg = ', and the stack trace (return addresses) at the time was:';
{Installation Messages}
AlreadyInstalledMsg = 'FastMM4 óæî ¢ñòàëÿâàíû.';
AlreadyInstalledTitle = 'Óæî ¢ñòàëÿâàíû.';
OtherMMInstalledMsg = 'FastMM4 íå ìîæà áûöü óñòàëÿâàíû ïðû ¢ñòàëÿâàíûì ³íøûì ìýíýäæýðó ïàìÿö³.'
+ #13#10'Êàë³ âû æàäàåöå âûêàðûñòî¢âàöü FastMM4, êàë³ ëàñêà ¢ïý¢í³öåñÿ øòî FastMM4.pas ç''ÿ¢ëÿåööà ñàìûì ïåðøûì ìîäóëåì ó'
+ #13#10'ñåêöû³ "uses" âàøàãà ''s .dpr ôàéëà ïðàåêòó.';
OtherMMInstalledTitle = 'Íåìàã÷ûìà ¢ñòàëÿâàöü FastMM4 - óæî ¢ñòàëÿâàíû ³íøû ìýíýäæýð ïàìÿö³.';
MemoryAllocatedMsg = 'FastMM4 íåìàã÷ûìà ¢ñòàëÿâàöü êàë³ ïàìÿöü óæî áûëà '
+ 'âûëó÷àíàÿ ñòàíäàðòíûì ìýíýäæýðàì ïàìÿö³.'#13#10'FastMM4.pas ÏÀ²ÍÅÍ '
+ 'áûöü ïåðøûì ìîäóëåì ó âàøûì ôàéëå''s .dpr ôàéëå ïðàåêòó, ³íàêø ïàìÿöü ìîæà '
+ 'áûöü âûëó÷àíà'#13#10'ïðàç ñòàíäàðòíû ìýíýäæýð ïàìÿö³ ïåðàä òûì ÿê FastMM4 '
+ 'àòðûìàå êàíòðîëü. '#13#10#13#10'Êàë³ âû âûêàðûñòàåöå àïðàöî¢ø÷ûê âûêëþ÷ýííÿ¢ '
+ 'òûïó MadExcept (àáî ëþáóþ ³íøàÿ ïðûëàäó, ÿêàÿ ìàäûô³êóå ïàðàäàê ³í³öûÿë³çàöû³ '
+ 'ìîäóëÿ¢),'#13#10'òî ïåðàéäç³öå ¢ ñòàðîíêó ÿãî êàíô³ãóðàöû³ ³ ¢ïý¢í³öåñÿ, øòî '
+ 'FastMM4.pas ìîäóëü ³í³öûÿë³çóåööà ïåðàä ëþáûì ³íøûì ìîäóëåì.';
MemoryAllocatedTitle = 'Íå ìàã÷ûìà ¢ñòàëÿâàöü FastMM4 - Ïàìÿöü óæî áûëà âûëó÷àíà';
{Leak checking messages}
LeakLogHeader = 'Áëîê ïàìÿö³ áû¢ âûëó÷àíû ³ íå âûçâàëåíû. Ïàìåð: ';
LeakMessageHeader = 'Ó ãýòàé ïðàãðàìå àäáûâàþööà ¢öå÷ê³ ïàìÿö³. ';
SmallLeakDetail = 'Óöå÷ê³ áëîêࢠìàëàãà ïàìåðó'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (âûêëþ÷àþ÷û ÷àêàíûÿ ¢öå÷ê³ çàðýã³ñòðàâàíûÿ ïà ïàêàçàëüí³êó)'
{$endif}
+ ':'#13#10;
LargeLeakDetail = 'Ïàìåðû ¢öå÷àê áëîêࢠñÿðýäíÿãà ïàìåðó'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (âûêëþ÷àþ÷û ÷àêàíûÿ ¢öå÷ê³ çàðýã³ñòðàâàíûÿ ïà ïàêàçàëüí³êó)'
{$endif}
+ ': ';
BytesMessage = ' áàéòà¢: ';
AnsiStringBlockMessage = 'AnsiString';
UnicodeStringBlockMessage = 'UnicodeString';
LeakMessageFooter = #13#10
{$ifndef HideMemoryLeakHintMessage}
+ #13#10'Note: '
{$ifdef RequireIDEPresenceForLeakReporting}
+ 'Ãýòàÿ ïðàâåðêà ¢öå÷ê³ ïàìÿö³ âûðàáëÿåööà òîëüê³ ¢ âûïàäêó àäíà÷àñîâàé ïðàöû Delphi íà òûì æà êàìïóòàðû. '
{$endif}
{$ifdef FullDebugMode}
{$ifdef LogMemoryLeakDetailToFile}
+ 'Äýòàë¸âàÿ ³íôàðìàöûÿ àá óöå÷êàõ ïàìÿö³ æóðíàëþåööà ¢ òýêñòàâû ôàéë ó òûì æà êàòàëîãó, øòî ³ ïðàãðàìà. '
{$else}
+ 'Óêëþ÷ûöå "LogMemoryLeakDetailToFile" äëÿ àòðûìàííÿ ÷àñîï³ñà, ÿê³ çìÿø÷àå äýòàë¸âóþ ³íôàðìàöûþ àá óöå÷êàõ ïàìÿö³. '
{$endif}
{$else}
+ 'Äëÿ àòðûìàííÿ ÷àñîï³ñà, ÿê³ çìÿø÷àå äýòàë¸âóþ ³íôàðìàöûþ àá óöå÷êàõ ïàìÿö³, óêëþ÷ûöå ¢ìîâû êàìï³ëÿöû³ "FullDebugMode" ³ "LogMemoryLeakDetailToFile". '
{$endif}
+ 'Äëÿ âûêëþ÷ýííÿ ãýòûõ ïðàâåðàê óöå÷ê³ ïàìÿö³, ïðûáÿðûöå çíà÷ýííå "EnableMemoryLeakReporting".'#13#10
{$endif}
+ #0;
LeakMessageTitle = 'Âûÿ¢ëåíà ¢öå÷êà ïàìÿö³';
{$ifdef UseOutputDebugString}
FastMMInstallMsg = 'FastMM áû¢ óñòàëÿâàíû.';
FastMMInstallSharedMsg = 'Sharing an existing instance of FastMM.';
FastMMUninstallMsg = 'FastMM áû¢ äý³íñòàëÿâàíû.';
FastMMUninstallSharedMsg = 'Stopped sharing an existing instance of FastMM.';
{$endif}
{$ifdef DetectMMOperationsAfterUninstall}
InvalidOperationTitle = 'MM àïåðàöû³ ïàñëÿ äý³íñòàëÿöû³.';
InvalidGetMemMsg = 'FastMM âûçíà÷û¢, øòî GetMem âûêë³êàööà ïàñëÿ òàãî ÿê FastMM áû¢ äý³íñòàëÿâàíû.';
InvalidFreeMemMsg = 'FastMM âûçíà÷û¢, øòî FreeMem âûêë³êàööà ïàñëÿ òàãî ÿê FastMM áû¢ äý³íñòàëÿâàíû.';
InvalidReallocMemMsg = 'FastMM âûçíà÷û¢, øòî ReallocMem âûêë³êàööà ïàñëÿ òàãî ÿê FastMM áû¢ äý³íñòàëÿâàíû.';
InvalidAllocMemMsg = 'FastMM âûçíà÷û¢, øòî ReallocMem âûêë³êàööà ïàñëÿ òàãî ÿê FastMM áû¢ äý³íñòàëÿâàíû.';
{$endif}
implementation
end.

View File

@ -0,0 +1,131 @@
{
Fast Memory Manager: Messages
Simplified Chinese translation by JiYuan Xie.
}
unit FastMM4Messages;
interface
{$Include FastMM4Options.inc}
const
{The name of the debug info support DLL}
FullDebugModeLibraryName32Bit = 'FastMM_FullDebugMode.dll';
FullDebugModeLibraryName64Bit = 'FastMM_FullDebugMode64.dll';
{Event log strings}
LogFileExtension = '_MemoryManager_EventLog.txt'#0;
CRLF = #13#10;
EventSeparator = '--------------------------------';
{Class name messages}
UnknownClassNameMsg = '未知';
{Memory dump message}
MemoryDumpMsg = #13#10#13#10'由指针所指地址开始, 256 个字节的内存当前的内容 ';
{Block Error Messages}
BlockScanLogHeader = '被 LogAllocatedBlocksToFile 记录的已分配内存块. 大小是: ';
ErrorMsgHeader = 'FastMM 已检测到一个错误, 当时正在进行 ';
GetMemMsg = 'GetMem';
FreeMemMsg = 'FreeMem';
ReallocMemMsg = 'ReallocMem';
BlockCheckMsg = '扫描自由内存块';
OperationMsg = ' 操作. ';
BlockHeaderCorruptedMsg = '内存块头部内容已被破坏. ';
BlockFooterCorruptedMsg = '内存块尾部内容已被破坏. ';
FreeModifiedErrorMsg = 'FastMM 检测到对已释放内存块内容的修改. ';
FreeModifiedDetailMsg = #13#10#13#10'被修改字节的偏移地址(以及长度): ';
DoubleFreeErrorMsg = '试图释放/重新分配一个尚未分配的内存块.';
WrongMMFreeErrorMsg = 'An attempt has been made to free/reallocate a block that was allocated through a different FastMM instance. Check your memory manager sharing settings.';
PreviousBlockSizeMsg = #13#10#13#10'上次使用时的内存块大小是: ';
CurrentBlockSizeMsg = #13#10#13#10'内存块的大小是: ';
PreviousObjectClassMsg = #13#10#13#10'该内存块上次被用于一个属于以下类的对象: ';
CurrentObjectClassMsg = #13#10#13#10'该内存块当前被用于一个属于以下类的对象: ';
PreviousAllocationGroupMsg = #13#10#13#10'分配组是: ';
PreviousAllocationNumberMsg = #13#10#13#10'分配号码是: ';
CurrentAllocationGroupMsg = #13#10#13#10'分配组是: ';
CurrentAllocationNumberMsg = #13#10#13#10'分配号码是: ';
BlockErrorMsgTitle = '检测到内存错误';
VirtualMethodErrorHeader = 'FastMM 检测到对已释放对象的虚方法的调用. 一个访问冲突异常现在将被引发以中止当前的操作.';
InterfaceErrorHeader = 'FastMM 检测到对已释放对象的接口的使用. 一个访问冲突异常现在将被引发以中止当前的操作.';
BlockHeaderCorruptedNoHistoryMsg = ' 不幸地, 由于内存块头部的内容已被破坏, 无法得到该内存块的使用历史.';
FreedObjectClassMsg = #13#10#13#10'被释放的对象所属的类: ';
VirtualMethodName = #13#10#13#10'虚方法: ';
VirtualMethodOffset = '偏移地址 +';
VirtualMethodAddress = #13#10#13#10'虚方法的地址: ';
{Stack trace messages}
CurrentThreadIDMsg = #13#10#13#10'当前线程的 ID 是 0x';
CurrentStackTraceMsg = ', 导致该错误的堆栈跟踪(返回地址): ';
ThreadIDPrevAllocMsg = #13#10#13#10'该内存块上一次分配于线程 0x';
ThreadIDAtAllocMsg = #13#10#13#10'该内存块分配于线程 0x';
ThreadIDAtFreeMsg = #13#10#13#10'该内存块上一次释放于线程 0x';
ThreadIDAtObjectAllocMsg = #13#10#13#10'该对象分配于线程 0x';
ThreadIDAtObjectFreeMsg = #13#10#13#10'该对象随后释放于线程 0x';
StackTraceMsg = ', 当时的堆栈跟踪(返回地址): ';
{Installation Messages}
AlreadyInstalledMsg = 'FastMM4 已经被安装';
AlreadyInstalledTitle = '已经加载';
OtherMMInstalledMsg = 'FastMM4 无法被安装, 因为其他第三方内存管理器已先自行安装.'
+ #13#10'如果你想使用 FastMM4, 请确认在你项目的 .dpr 文件的 "uses" 部分中, '
+ #13#10'FastMM4.pas 是第一个被使用的单元.';
OtherMMInstalledTitle = '无法安装 FastMM4 - 其他内存管理器已先被安装';
MemoryAllocatedMsg = 'FastMM4 无法安装, 因为此前已通过默认内存管理器分配了内存.'
+ #13#10'FastMM4.pas 必须是你项目的 .dpr 文件中第一个被使用的单元, 否则可能在'
+ #13#10'FastMM4 得到控制权之前, 应用程序已经通过默认内存管理器分配了内存.'
+ #13#10#13#10'如果你使用了异常捕捉工具, 象 MadExcept(或任何将修改单元初始化顺序的工具),'
+ #13#10'请到它的配置页面,确保 FastMM4.pas 单元在任何其他单元之前被初始化.';
MemoryAllocatedTitle = '无法安装 FastMM4 - 之前已经分配了内存';
{Leak checking messages}
LeakLogHeader = '一个内存块已泄露. 大小是: ';
LeakMessageHeader = '这个应用程序存在内存泄露. ';
SmallLeakDetail = '小内存块的泄露有'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (不包括已按指针注册的预知泄露)'
{$endif}
+ ':'#13#10;
LargeLeakDetail = '已泄露的中等及大内存块的大小是'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (不包括已按指针注册的预知泄露)'
{$endif}
+ ': ';
BytesMessage = ' 字节: ';
AnsiStringBlockMessage = 'AnsiString';
UnicodeStringBlockMessage = 'UnicodeString';
LeakMessageFooter = #13#10
{$ifndef HideMemoryLeakHintMessage}
+ #13#10'注意: '
{$ifdef RequireIDEPresenceForLeakReporting}
+ '只有当 Delphi 同时运行在同一计算机上时才会进行内存泄露检查. '
{$endif}
{$ifdef FullDebugMode}
{$ifdef LogMemoryLeakDetailToFile}
+ '内存泄露的详细信息已经被记录到与本应用程序同一目录下的一个文本文件中. '
{$else}
+ '请启用 "LogMemoryLeakDetailToFile" 条件编译开关以得到一个包含关于内存泄露的详细信息的日志文件. '
{$endif}
{$else}
+ '要得到一个包含关于内存泄露的详细信息的日志文件, 请启用 "FullDebugMode" 和 "LogMemoryLeakDetailToFile" 条件编译开关. '
{$endif}
+ '要禁止内存泄露检查, 请关闭 "EnableMemoryLeakReporting" 条件编译开关.'#13#10
{$endif}
+ #0;
LeakMessageTitle = '检测到内存泄露';
{$ifdef UseOutputDebugString}
FastMMInstallMsg = 'FastMM 已被安装.';
FastMMInstallSharedMsg = '正共用一个已存在的 FastMM 实例.';
FastMMUninstallMsg = 'FastMM 已被卸载.';
FastMMUninstallSharedMsg = '已停止共用一个已存在的 FastMM 实例.';
{$endif}
{$ifdef DetectMMOperationsAfterUninstall}
InvalidOperationTitle = '卸载之后发生了 MM 操作.';
InvalidGetMemMsg = 'FastMM 检测到在 FastMM 被卸载之后调用了 GetMem.';
InvalidFreeMemMsg = 'FastMM 检测到在 FastMM 被卸载之后调用了 FreeMem.';
InvalidReallocMemMsg = 'FastMM 检测到在 FastMM 被卸载之后调用了 ReallocMem.';
InvalidAllocMemMsg = 'FastMM 检测到在 FastMM 被卸载之后调用了 AllocMem.';
{$endif}
implementation
end.

View File

@ -0,0 +1,372 @@
{
Fast Memory Manager: 选项配置文件
在这里为FastMM设置默认选项
FastMM 4.97
}
{
Simplified Chinese translation by QianYuan Wang
Contact me if you find any improper translation.
如果翻译上有任何不恰当的地方请和我联系。
E-Mail: wqyfavor@qq.com
}
{
对各编译选项的翻译(不解释术语)
Align16Bytes 按16字节对齐
UseCustomFixedSizeMoveRoutines 使用固定尺寸内存移动函数
UseCustomVariableSizeMoveRoutines 使用可变尺寸内存移动函数
AssumeMultiThreaded 按多线程处理
NeverSleepOnThreadContention 线程冲突时不暂停进程
InstallOnlyIfRunningInIDE 仅在Delphi开发环境中加载内存管理器
NeverUninstall 不卸载FastMM
UseRuntimePackages 使用运行期包
NoDebugInfo 无调试信息
NoMessageBoxes 不显示信息
UseOutputDebugString 使用Windows API OutputDebugString
ASMVersion 汇编版本
CheckHeapForCorruption 检测堆错误
DetectMMOperationsAfterUninstall 检测在管理器卸载后对其的引用操作
FullDebugMode 全调试模式
RawStackTraces 彻底的栈追踪
CatchUseOfFreedInterfaces 捕捉对已销毁对象的引用
LogErrorsToFile 记录错误到文件
LogMemoryLeakDetailToFile 记录内存泄露细节到文件
ClearLogFileOnStartup 启动时清空日志文件
LoadDebugDLLDynamically 动态加载调试Dll
AlwaysAllocateTopDown 总从最顶端分配内存
EnableMemoryLeakReporting 允许内存泄露报告
HideExpectedLeaksRegisteredByPointer 隐藏由指针记录的可能的内存泄露
RequireIDEPresenceForLeakReporting 仅在IDE存在时进行泄露报告
RequireDebuggerPresenceForLeakReporting 仅在调试器存在时进行泄露报告
RequireDebugInfoForLeakReporting 泄露报告需要调试信息
ManualLeakReportingControl 手工控制泄露报告
HideMemoryLeakHintMessage 隐藏内存泄露提示信息
EnableMMX 允许使用MMX
ForceMMX 强制使用MMX
ShareMM 共享内存管理器
ShareMMIfLibrary 允许在Dll中共享内存管理器
AttemptToUseSharedMM 尝试共享内存管理器
EnableBackwardCompatibleMMSharing 允许向后兼容的内存管理器共享
FullDebugModeInIDE 在Delphi开发环境中进行全调试
}
{--------------------------- 综合选项 -----------------------------}
{开启此选项会将所有内存块按16字节对齐以便SSE指令可以安全使用。如果此选项关闭一些
最小的内存块会按8字节方式对齐这将减少内存使用。不管是否开启此选项中等和大的内
存块都将按照16字节方式对齐。}
{.$define Align16Bytes}
{允许在增大小内存块时使用更快的定尺寸内存移动函数。因为这些函数被设计为移动固定尺寸
内存所以效率大幅高于Borland的RTL中的内存移动函数。这一选项可与FastMove库配合使用
来达到更高的效率。}
{$define UseCustomFixedSizeMoveRoutines}
{开启此选项以使用优化的函数来移动任意大小的内存块。使用Fastcode的FastMove函数时禁用
此选项。使用FastMove代码可以使整个程序都使用到更快的内存移动函数而不仅仅是内存管理
器。因此建议将FastMM和FastMove代码相结合并关闭此选项。}
{$define UseCustomVariableSizeMoveRoutines}
{开启此选项会使程序仅在Delphi IDE内运行时才加裁FastMM作为内存管理器。当你希望发布的
Exe就是你调试的Exe但只希望在开发主机上使用调试时请开启此选项。当开启后程序又并不
在开发主机上运行它会使用默认的Delphi内存管理器在Delphi2006以后是不开启FullDebugMode
的FastMM}
{.$define InstallOnlyIfRunningInIDE}
{由于QC#14070Delphi尝试在borlandmm.dll的关闭指令执行后释放内存当使用了FastMM
为核心的borlandmm.dll的替代品FastMM不能被正常卸载。开启此选项会不卸载内存管理器
而避开这个错误。}
{.$define NeverUninstall}
{如果在当前工程中使用了运行期的包需要启动这个选项。会自动开启AssumeMultiThreaded。
注意你必须确保在所有指针都释放后FastMM被卸载。如果不这么做会产生一个有很多A/V的巨
大的内存泄露报告。参考常见问题你必须同时启动此选项和NeverUninstall选项。}
{.$define UseRuntimePackages}
{-----------------------Concurrency Management Options------------------------}
{开启后将默认程序是多线程的,但会导致单线程程序速度明显下降。在使用可能未正确设
置IsMultiThread变量的多线程的第三方工具时请开启此选项。在单线程主程序和多线程Dll
间共享内存管理器时也需开启。}
{.$define AssumeMultiThreaded}
{开启此选项将不会在线程冲突时让一个线程暂停在活动进程与CPU核心数目比低小于2
将会提升速度。开启后,冲突时一个线程将会进入“等待”循环而不是交出时间片。}
{.$define NeverSleepOnThreadContention}
{开启后当线程冲突时会调用SwitchToThread而不是一直停留在“等待”循环中。这个选项需要
配合NeverSleepOnThreadContention一起使用并且必须在前者开启时才有效。当系统有多个
CPU核心或线程有不同的优先级时开启此选项可提高效率。SwitchToThread调用只在Windows2000
及以后版本有效。}
{.$define UseSwitchToThread}
{----------------------------- 调试选项 -------------------------------}
{开启此选项将不会为FastMM4.pas单元产生调试代码也将同时阻止调试器进入FastMM4.pas单元}
{.$define NoDebugInfo}
{开启下面选项将不显示任何信息,在不可中止的服务器程序中比较有用}
{.$define NoMessageBoxes}
{如果要使用Windows API OutputDebugString过程来显示调试信息请开启下面选项}
{.$define UseOutputDebugString}
{开启此选项会使用汇编语言版本的FastMM这比Pascal版本的要快。仅在调试时关闭此选项。
开启CheckHeapForCorruption会自动关闭此设置}
{$define ASMVersion}
{FastMM总会捕捉到两次释放的同一内存区域的糟糕操作它也可以检测堆的错误通常是由
于程序越界读写内存)。这些检测很耗费时间,所以这个选项应仅当调试时使用。如果此选项
开启ASMVersion会自动关闭}
{.$define CheckHeapForCorruption}
{开启此选项会检测在FastMM已卸载后对用户对FastMM的引用操作。开启后当FastMM被卸载
将不会重新启动先前的内存管理器,而是假想存在一个内存管理器,并且一旦有内存操作便
抛出错误。这会捕捉到当FastMM已被卸载而程序仍进行内存操作的错误。}
{$define DetectMMOperationsAfterUninstall}
{设置以下选项来对内存泄露进行广泛检测。所有内存块都会设置块首和跟踪器来校验堆的完
整性。释放的内存块(指针)也会被清空以保证它们不会被再次使用。这一选项会大幅度降
低内存操作速度,仅当调试一个会越界读写内存或重复使用已被释放的指针的程序时才使用。
开启此选项会进而自动开启CheckHeapForCorruption并自动关闭ASMVersion。提示当开启
此选项时程序需要使用FastMM_FullDebugMode.dll文件。如果此文件丢失程序将无法启动。}
{.$define FullDebugMode}
{开启此选项以进行彻底的栈追踪:检测所有栈条目以寻找合法的返回地址。注意这比使用
主栈帧的方法要慢很多但更彻底。仅当开启FullDebugMode时此选项有效。}
{$define RawStackTraces}
{开启此选项会检测程序中对已销毁对象的引用。注意这会使对已释放而又修改过(内容被
覆盖的内存块的检测无法进行两者无法共存。仅当开启FullDebugMode时此选项有效。}
{.$define CatchUseOfFreedInterfaces}
{开启此选项以记录所有的错误到一个与程序同目录的文本文件中。内存分配错误(当开启
FullDebugMode将会添加到这个日志里。如果FullDebugMode关闭此选项无效}
{$define LogErrorsToFile}
{开启此选项将会记录所有泄露到一个与程序同目录的文本文件中。内存泄露报告(当开启
FullDebugMode将会添加到这个日志里。如果"LogErrorsToFile""FullDebugMode"未开
启此选项无效。注意通常所有泄露都会被记录甚至那些AddExpectedMemoryLeaks标识的
可能的内存泄露。那些由指针引起的可能的泄露可能会由于开启HideExpectedLeaks-
RegisteredByPointer而不显示。}
{$define LogMemoryLeakDetailToFile}
{程序启动时删除日志文件。当LogErrorsToFile不开启时无效}
{.$define ClearLogFileOnStartup}
{是否动态链接FASTMM_FullDebugMode.dll。如果找不到该Dll栈追踪将无法进行。注意
当共享内存管理器时由于Dll卸载顺序改变可能会发生错误。}
{.$define LoadDebugDLLDynamically}
{.$define DoNotInstallIfDLLMissing}
{开启此选项后并且开启FullDebugMode和LoadDebugDLLDynamically时如果
FastMM_FullDebugMode.dll文件丢失那么FastMM将不会加载。}
{FastMM通常会使用最顶端的可用地址来分配大的内存块而在最低端的可用地址上分配
中、小内存块(这在一定程度上减少碎片)。开启此选项会使内存分配总优先使用最顶
端的可用地址。如果过程使用了大于2GB的内存并且算法存在糟糕的指针分配 ,这个选
项会帮助尽早发现错误}
{$define AlwaysAllocateTopDown}
{开启后将不会对内存转储进行日志记录,其它记录正常。}
{.$define DisableLoggingOfMemoryDumps}
{FullDebugMode模式下当FreeMem调用失败时通常会返回一个“指针操作无效”的
错误。如果此时另一个异常正在被处理比如在“try..finally”中),那原先的异常就会丢失。
开启此选项后如果此时正有别的异常被处理那么FastMM将忽略FreeMem中发生错误。}
{$define SuppressFreeMemErrorsInsideException}
{--------------------------- 内存泄露报告 -----------------------------}
{开启此选项以允许内存泄露报告,与下面两个选项组合使用。}
{$define EnableMemoryLeakReporting}
{开启下面选项将不会显示和记录由指针类型导致的可能的内存泄露。由类(指针)引起
的可能的内存泄露经常不明确所以这些可能的泄露总是会记录到日志在FullDebugMode
与LogMemoryLeakDetailToFile开启时并且当实际泄露比期待的多时一定会显示。}
{$define HideExpectedLeaksRegisteredByPointer}
{开启下面选项以实现仅在Delphi在主机上存在时才报告内存泄露。当"EnableMemoryLeakReporting"
关闭时此选项无效。}
{.$define RequireIDEPresenceForLeakReporting}
{开启下面选项以实现仅在Delphi中调试程序时才报告内存泄露。当"EnableMemoryLeakReporting"
关闭时此选项无效。此选项仅在调试EXE工程时有效不支持Dll}
{$define RequireDebuggerPresenceForLeakReporting}
{开启下面选项以实现仅在被编译单元中存在调试指示符($D时才进行泄露检测。当
"EnableMemoryLeakReporting"关闭时此选项无效。}
{.$define RequireDebugInfoForLeakReporting}
{开启此选项以手工控制内存泄露报告。当开启时ReportMemoryLeaksOnShutdown程序
关闭时报告内存泄露,默认关闭)会改为选择是否生成报告。开启时,其它泄露检测选项
也必须正确设置才能进行检测}
{.$define ManualLeakReportingControl}
{开启下面选项将不显示内存泄露信息下面的提示语}
{.$define HideMemoryLeakHintMessage}
{-------------------------- 指令集设置 ----------------------------}
{开启下面选项以使用MMX指令集。关闭此选项会导致性能略微下降但会与AMD K5、
Pentium I等早期处理器保持兼容。目前MMX指令只在可变尺寸的内存移动中使用所以如
果UseCustomVariableSizeMoveRoutines关闭此选项无效。}
{.$define EnableMMX}
{开启下面选项以强制使用MMX指令集而不管CPU是否支持。如果这一选项被关闭
将会首先检查CPU是否支持MMX指令。当EnabledMMX关闭时无效。}
{$define ForceMMX}
{----------------------- 共享内存管理器设置 ------------------------}
{允许共同使用FastMM编译的主程序和Dll之间共享内存管理器。你可以向Dll中的函数传递
动态数组和长字符串。需要编译Dll时开启AttemptToUseSharedMM才可以真正实现内存共享。
注意如果主程序是单线程而Dll是多线程的你必须在主程序里开启IsMultiThread,否则在
线程冲突时程序会崩溃。注意静态链接的Dll会在主程序之前初始化所以主程序实际会与
Dll共享内存管理器。
}
{.$define ShareMM}
{允许Dll之间或静态链接Dll时与主程序之间共享内存管理器,要求共同使用FastMM编译。
在使用动态链接的Dll时需要注意因为如果Dll被卸载而其它Dll仍在共享内存管理器
序将会崩溃。这个选项只与Dll库相关而且需要ShareMM与AttemptToUseSharedMM开启。注意
如果Dll是静态链接的它们会在主程序之前初始化实际是主程序与它们共享管理器。当
ShareMM关闭时此选项无效}
{.$define ShareMMIfLibrary}
{开启下面选项会尝试在主程序和与之共同编译的Dll也开启此选项之间共享内存管理
器。当共享时由使用共享者产生的泄露将不会自动清除。由于静态链接的Dll是在主程序
之前初始化的,所以根据情况设置共享选项}
{.$define AttemptToUseSharedMM}
{开启下面编译选项以保证内存管理器的向后兼容性。对Delphi2006与Delphi2007与老版本
FastMM有效}
{$define EnableBackwardCompatibleMMSharing}
{-------------------------------- 组合设置 ------------------------------}
{开启此选项将激活FullDebugMode、InstallOnlyIfRunningInIDE、LoadDebugDLLDynamically。
如果程序正在Delphi中进行调试运行FastMM将会进行完全调试开启FullDebugMode否则
将使用默认内存管理器Delphi2006版本以后是未开启FullDebugMode的FastMM}
{.$define FullDebugModeInIDE}
{该选项搭配FullDebugMode、LoadDebugDLLDynamically和DoNotInstallIfDLLMissing一起
使用。开启后如果有FastMM_FullDebugMode.dll文件并且开启了FullDebugMode那么将进入全
调试模式。这样用于发布的exe和调试的exe可以是同一个文件发布时只要去掉FastMM_FullDebugMode.dll
文件就可以了。}
{.$define FullDebugModeWhenDLLAvailable}
{快速配置发布版本和调试版本}
{$ifdef Release}
{发布版本请设置}
{.$undef FullDebugMode}
{.$undef CheckHeapForCorruption}
{.$define ASMVersion}
{.$undef EnableMemoryLeakReporting}
{.$undef UseOutputDebugString}
{$else}
{调试版本请设置}
{.$define FullDebugMode}
{.$define EnableMemoryLeakReporting}
{.$define UseOutputDebugString}
{$endif}
{-------------------- borlndmm.dll 编译选项 ---------------------}
{如果正在重编译borlandmm.dll文件请根据需要设置以下选项}
{当编译borlandmm.dll时请开启此选项}
{.$define borlndmmdll}
{如果dll被Delphi本身使用请开启此选项}
{.$define dllforide}
{编译调试dll文件时请开启此选项}
{.$define debugdll}
{以下内容请不要改动}
{$ifdef borlndmmdll}
{$define AssumeMultiThreaded}
{$undef HideExpectedLeaksRegisteredByPointer}
{$undef RequireDebuggerPresenceForLeakReporting}
{$undef RequireDebugInfoForLeakReporting}
{$define DetectMMOperationsAfterUninstall}
{$undef ManualLeakReportingControl}
{$undef ShareMM}
{$undef AttemptToUseSharedMM}
{$ifdef dllforide}
{$define NeverUninstall}
{$define HideMemoryLeakHintMessage}
{$undef RequireIDEPresenceForLeakReporting}
{$ifndef debugdll}
{$undef EnableMemoryLeakReporting}
{$endif}
{$else}
{$define EnableMemoryLeakReporting}
{$undef NeverUninstall}
{$undef HideMemoryLeakHintMessage}
{$define RequireIDEPresenceForLeakReporting}
{$endif}
{$ifdef debugdll}
{$define FullDebugMode}
{$define RawStackTraces}
{$undef CatchUseOfFreedInterfaces}
{$define LogErrorsToFile}
{$define LogMemoryLeakDetailToFile}
{$undef ClearLogFileOnStartup}
{$else}
{$undef FullDebugMode}
{$endif}
{$endif}
{把BCB的相关设置都放在这里。在“Build with Dynamic RTL”选项开启的情况下
CB2006/CB2007可以编译borlandmm.dll文件以追踪内存泄露。}
{------------------------------ 专为BCB设置 ----------------------------}
{要开启为BCB准备的补丁你需要在"Project Options->Pascal/Delphi Compiler->Defines"
中添加BCB的定义。感谢JiYuan Xie实现这一部分}
{$ifdef BCB}
{$ifdef CheckHeapForCorruption}
{$define PatchBCBTerminate}
{$else}
{$ifdef DetectMMOperationsAfterUninstall}
{$define PatchBCBTerminate}
{$else}
{$ifdef EnableMemoryLeakReporting}
{$define PatchBCBTerminate}
{$endif}
{$endif}
{$endif}
{$ifdef PatchBCBTerminate}
{$define CheckCppObjectType}
{$undef CheckCppObjectTypeEnabled}
{$ifdef CheckCppObjectType}
{$define CheckCppObjectTypeEnabled}
{$endif}
{如果"CheckHeapForCorruption""EnableMemoryLeakReporting"都未开启,请关闭
"CheckCppObjectTypeEnabled"}
{$ifdef CheckHeapForCorruption}
{$else}
{$ifdef EnableMemoryLeakReporting}
{$else}
{$undef CheckCppObjectTypeEnabled}
{$endif}
{$endif}
{$endif}
{$endif}

View File

@ -0,0 +1,138 @@
{
Fast Memory Manager: Messages
Czech translation by Rene Mihula.
Modifications:
25.04.2005 rm Added resource strings for FastMM v4.64 compilability
01.03.2007 rm Corrections of keying mistakes
17.03.2007 rm Update to version FastMM v4.90
}
unit FastMM4Messages;
interface
{$Include FastMM4Options.inc}
const
{The name of the debug info support DLL}
FullDebugModeLibraryName32Bit = 'FastMM_FullDebugMode.dll';
FullDebugModeLibraryName64Bit = 'FastMM_FullDebugMode64.dll';
{Event log strings}
LogFileExtension = '_MemoryManager_EventLog.txt'#0;
CRLF = #13#10;
EventSeparator = '--------------------------------';
{Class name messages}
UnknownClassNameMsg = 'Neznámá třída';
{Memory dump message}
MemoryDumpMsg = #13#10#13#10'Výpis prvních 256 bytů paměti, které začínají na adrese ';
{Block Error Messages}
BlockScanLogHeader = 'Alokované bloky byly zalogovány pomocí LogAllocatedBlocksToFile. Velikost je: ';
ErrorMsgHeader = 'FastMM detekoval chyby během operace ';
GetMemMsg = 'GetMem';
FreeMemMsg = 'FreeMem';
ReallocMemMsg = 'ReallocMem';
BlockCheckMsg = 'hledání prázdných bloků';
OperationMsg = ' . ';
BlockHeaderCorruptedMsg = 'Hlavička bloku byla poškozena. ';
BlockFooterCorruptedMsg = 'Patička bloku byla poškozena. ';
FreeModifiedErrorMsg = 'FastMM detekoval modifikaci bloku po jeho uvolnění. ';
FreeModifiedDetailMsg = #13#10#13#10'Modified byte offsets (and lengths): ';
DoubleFreeErrorMsg = 'Proběhl pokus o uvolnění / realokaci již uvolněného bloku.';
WrongMMFreeErrorMsg = 'An attempt has been made to free/reallocate a block that was allocated through a different FastMM instance. Check your memory manager sharing settings.';
PreviousBlockSizeMsg = #13#10#13#10'Předchozí velikost bloku: ';
CurrentBlockSizeMsg = #13#10#13#10'Velikost bloku: ';
PreviousObjectClassMsg = #13#10#13#10'Blok byl již využit pro objekt typu: ';
CurrentObjectClassMsg = #13#10#13#10'Blok je aktuálně využíván pro objekt typu: ';
PreviousAllocationGroupMsg = #13#10#13#10'Alokační skupina byla: '; //
PreviousAllocationNumberMsg = #13#10#13#10'Alokační číslo bylo: ';
CurrentAllocationGroupMsg = #13#10#13#10'Alokační skupina je: ';
CurrentAllocationNumberMsg = #13#10#13#10'Alokační číslo je: ';
BlockErrorMsgTitle = 'Detekována chyba práce s pamětí';
VirtualMethodErrorHeader = 'FastMM detekoval pokus o volání virtuální metody již uvolněného objektu. Pro ukončení této operace bude nyní vyhozena vyjímka (access violation).';
InterfaceErrorHeader = 'FastMM detekoval pokus o přístup k interface již uvolněného objektu. Pro ukončení této operace bude nyní vyhozena vyjímka (access violation).';
BlockHeaderCorruptedNoHistoryMsg = ' Historie je nedostupná z důvodu poškození hlavičky bloku.';
FreedObjectClassMsg = #13#10#13#10'Typ uvolňovaného objektu: ';
VirtualMethodName = #13#10#13#10'Název virtuální metody: ';
VirtualMethodOffset = 'Offset +';
VirtualMethodAddress = #13#10#13#10'Adresa virtuální metody: ';
{Stack trace messages}
CurrentThreadIDMsg = #13#10#13#10'ID aktivního vlákna (thread ID) je 0x';
CurrentStackTraceMsg = ' a stav na zásobníku volání (návratové adresy) je následující:';
ThreadIDPrevAllocMsg = #13#10#13#10'Tento blok byl již jednou alokován vláknem 0x';
ThreadIDAtAllocMsg = #13#10#13#10'Tento blok byl alokován vláknem 0x';
ThreadIDAtFreeMsg = #13#10#13#10'Blok již byl jednou uvolněn vláknem 0x';
ThreadIDAtObjectAllocMsg = #13#10#13#10'Objekt byl alokován vláknem 0x';
ThreadIDAtObjectFreeMsg = #13#10#13#10'Objekt byl opakovaně uvolněn vláknem 0x';
StackTraceMsg = ' v okamžiku, kdy zásobník volání obsahoval tyto návratové adresy:';
{Installation Messages}
AlreadyInstalledMsg = 'FastMM4 již byl nainstalován.';
AlreadyInstalledTitle = 'Nainstalováno.';
OtherMMInstalledMsg = 'FastMM4 nemohl být nainstalován, protože jiný memory '
+ 'manager (MM třetí strany) již byl nainstalován.'#13#10'Pro použití FastMM4 '
+ 'zkontrolujte, zda je unita FastMM4.pas první unitou v sekci "uses" tohoto '
+ 'projektu (.dpr soubor).';
OtherMMInstalledTitle = 'Nelze nainstalovat FastMM4 - Jiný memory manager je již nainstalován';
MemoryAllocatedMsg = 'FastMM4 nemohl být nainstalován, protože jiný memory '
+ 'manager (standardní MM) již byl nainstalován.'#13#10'Pro použití FastMM4 '
+ 'zkontrolujte, zda je unita FastMM4.pas první unitou v sekci "uses" tohoto '
+ 'projektu (.dpr soubor).'#13#10#13#10
+ 'Pokud používáte nějaký exception trapper (např. MadExcept) nebo libovolný '
+ 'jiný nástroj, který modifikuje pořadí sekcí initialization, nakonfigurujte '
+ 'jej tak, aby unita FastMM4.pas byla inicializována před všemi ostatními unitami.';
MemoryAllocatedTitle = 'Nelze nainstalovat FastMM4 - Paměť již byla alokována';
{Leak checking messages}
LeakLogHeader = 'Blok paměti zůstal neuvolněn. Velikost(i): ';
LeakMessageHeader = 'Aplikace neuvolnila používanou paměť. ';
SmallLeakDetail = 'Bloky malé velikosti'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (vyjma chyb registrovaných pomocí ukazatelů)'
{$endif}
+ ':'#13#10;
LargeLeakDetail = 'Bloky střední a velké velikosti'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (vyjma chyb registrovaných pomocí ukazatelů)'
{$endif}
+ ': ';
BytesMessage = ' bytů: ';
AnsiStringBlockMessage = 'AnsiString';
UnicodeStringBlockMessage = 'UnicodeString';
LeakMessageFooter = #13#10
{$ifndef HideMemoryLeakHintMessage}
+ #13#10'Poznámka: '
{$ifdef RequireIDEPresenceForLeakReporting}
+ 'Kontrola neuvolněné paměti je prováděna pouze pokud je prostředí Delphi aktivní na tomtéž systému. '
{$endif}
{$ifdef FullDebugMode}
{$ifdef LogMemoryLeakDetailToFile}
+ 'Detailní informace o neuvolněné paměti jsou zapsány do textového souboru v adresáři aplikace. '
{$else}
+ 'Povolením direktivy "LogMemoryLeakDetailToFile" lze do souboru logu zapsat detailní informace o neuvolněné paměti. '
{$endif}
{$else}
+ 'Pro získání logu s detailními informacemi o neuvolněné paměti je potřeba povolit direktivy "FullDebugMode" a "LogMemoryLeakDetailToFile". '
{$endif}
+ 'Vypnutím direktivy "EnableMemoryLeakReporting" lze deaktivovat tuto kontrolu neuvolněné paměti.'#13#10
{$endif}
+ #0;
LeakMessageTitle = 'Byla detekována neuvolněná paměť (Memory Leak)';
{$ifdef UseOutputDebugString}
FastMMInstallMsg = 'FastMM byl natažen.';
FastMMInstallSharedMsg = 'Sdílení existující instance FastMM.';
FastMMUninstallMsg = 'FastMM byl odinstalován.';
FastMMUninstallSharedMsg = 'Zastaveno sdílení existující instance FastMM.';
{$endif}
{$ifdef DetectMMOperationsAfterUninstall}
InvalidOperationTitle = 'Detekce MM volání po odinstalování FastMM.';
InvalidGetMemMsg = 'FastMM detekoval volání GetMem, které proběhlo po odinstalaci FastMM.';
InvalidFreeMemMsg = 'FastMM detekoval volání FreeMem, které proběhlo po odinstalaci FastMM.';
InvalidReallocMemMsg = 'FastMM detekoval volání ReallocMem, které proběhlo po odinstalaci FastMM.';
InvalidAllocMemMsg = 'FastMM detekoval volání ReallocMem, které proběhlo po odinstalaci FastMM.';
{$endif}
implementation
end.

View File

@ -0,0 +1,135 @@
{
Fast Memory Manager: Messages
English translation by Pierre le Riche.
}
unit FastMM4Messages;
interface
{$Include FastMM4Options.inc}
const
{The name of the debug info support DLL}
FullDebugModeLibraryName32Bit = 'FastMM_FullDebugMode.dll';
FullDebugModeLibraryName64Bit = 'FastMM_FullDebugMode64.dll';
{Event log strings}
LogFileExtension = '_MemoryManager_EventLog.txt'#0;
CRLF = #13#10;
EventSeparator = '--------------------------------';
{Class name messages}
UnknownClassNameMsg = 'Unknown';
{Memory dump message}
MemoryDumpMsg = #13#10#13#10'Current memory dump of 256 bytes starting at pointer address ';
{Block Error Messages}
BlockScanLogHeader = 'Allocated block logged by LogAllocatedBlocksToFile. The size is: ';
ErrorMsgHeader = 'FastMM has detected an error during a ';
GetMemMsg = 'GetMem';
FreeMemMsg = 'FreeMem';
ReallocMemMsg = 'ReallocMem';
BlockCheckMsg = 'free block scan';
OperationMsg = ' operation. ';
BlockHeaderCorruptedMsg = 'The block header has been corrupted. ';
BlockFooterCorruptedMsg = 'The block footer has been corrupted. ';
FreeModifiedErrorMsg = 'FastMM detected that a block has been modified after being freed. ';
FreeModifiedDetailMsg = #13#10#13#10'Modified byte offsets (and lengths): ';
DoubleFreeErrorMsg = 'An attempt has been made to free/reallocate an unallocated block.';
WrongMMFreeErrorMsg = 'An attempt has been made to free/reallocate a block that was allocated through a different FastMM instance. Check your memory manager sharing settings.';
PreviousBlockSizeMsg = #13#10#13#10'The previous block size was: ';
CurrentBlockSizeMsg = #13#10#13#10'The block size is: ';
PreviousObjectClassMsg = #13#10#13#10'The block was previously used for an object of class: ';
CurrentObjectClassMsg = #13#10#13#10'The block is currently used for an object of class: ';
PreviousAllocationGroupMsg = #13#10#13#10'The allocation group was: ';
PreviousAllocationNumberMsg = #13#10#13#10'The allocation number was: ';
CurrentAllocationGroupMsg = #13#10#13#10'The allocation group is: ';
CurrentAllocationNumberMsg = #13#10#13#10'The allocation number is: ';
BlockErrorMsgTitle = 'Memory Error Detected';
VirtualMethodErrorHeader = 'FastMM has detected an attempt to call a virtual method on a freed object. An access violation will now be raised in order to abort the current operation.';
InterfaceErrorHeader = 'FastMM has detected an attempt to use an interface of a freed object. An access violation will now be raised in order to abort the current operation.';
BlockHeaderCorruptedNoHistoryMsg = ' Unfortunately the block header has been corrupted so no history is available.';
FreedObjectClassMsg = #13#10#13#10'Freed object class: ';
VirtualMethodName = #13#10#13#10'Virtual method: ';
VirtualMethodOffset = 'Offset +';
VirtualMethodAddress = #13#10#13#10'Virtual method address: ';
{Stack trace messages}
CurrentThreadIDMsg = #13#10#13#10'The current thread ID is 0x';
CurrentStackTraceMsg = ', and the stack trace (return addresses) leading to this error is:';
ThreadIDPrevAllocMsg = #13#10#13#10'This block was previously allocated by thread 0x';
ThreadIDAtAllocMsg = #13#10#13#10'This block was allocated by thread 0x';
ThreadIDAtFreeMsg = #13#10#13#10'The block was previously freed by thread 0x';
ThreadIDAtObjectAllocMsg = #13#10#13#10'The object was allocated by thread 0x';
ThreadIDAtObjectFreeMsg = #13#10#13#10'The object was subsequently freed by thread 0x';
StackTraceMsg = ', and the stack trace (return addresses) at the time was:';
{Installation Messages}
AlreadyInstalledMsg = 'FastMM4 is already installed.';
AlreadyInstalledTitle = 'Already installed.';
OtherMMInstalledMsg = 'FastMM4 cannot be installed since another third party memory '
+ 'manager has already installed itself.'#13#10'If you want to use FastMM4, '
+ 'please make sure that FastMM4.pas is the very first unit in the "uses"'
+ #13#10'section of your project''s .dpr file.';
OtherMMInstalledTitle = 'Cannot install FastMM4 - Another memory manager is already installed';
MemoryAllocatedMsg = 'FastMM4 cannot install since memory has already been '
+ 'allocated through the default memory manager.'#13#10'FastMM4.pas MUST '
+ 'be the first unit in your project''s .dpr file, otherwise memory may '
+ 'be allocated'#13#10'through the default memory manager before FastMM4 '
+ 'gains control. '#13#10#13#10'If you are using an exception trapper '
+ 'like MadExcept (or any tool that modifies the unit initialization '
+ 'order),'#13#10'go into its configuration page and ensure that the '
+ 'FastMM4.pas unit is initialized before any other unit.';
MemoryAllocatedTitle = 'Cannot install FastMM4 - Memory has already been allocated';
{Leak checking messages}
LeakLogHeader = 'A memory block has been leaked. The size is: ';
LeakMessageHeader = 'This application has leaked memory. ';
SmallLeakDetail = 'The small block leaks are'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (excluding expected leaks registered by pointer)'
{$endif}
+ ':'#13#10;
LargeLeakDetail = 'The sizes of leaked medium and large blocks are'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (excluding expected leaks registered by pointer)'
{$endif}
+ ': ';
BytesMessage = ' bytes: ';
AnsiStringBlockMessage = 'AnsiString';
UnicodeStringBlockMessage = 'UnicodeString';
LeakMessageFooter = #13#10
{$ifndef HideMemoryLeakHintMessage}
+ #13#10'Note: '
{$ifdef RequireIDEPresenceForLeakReporting}
+ 'This memory leak check is only performed if Delphi is currently running on the same computer. '
{$endif}
{$ifdef FullDebugMode}
{$ifdef LogMemoryLeakDetailToFile}
+ 'Memory leak detail is logged to a text file in the same folder as this application. '
{$else}
+ 'Enable the "LogMemoryLeakDetailToFile" to obtain a log file containing detail on memory leaks. '
{$endif}
{$else}
+ 'To obtain a log file containing detail on memory leaks, enable the "FullDebugMode" and "LogMemoryLeakDetailToFile" conditional defines. '
{$endif}
+ 'To disable this memory leak check, undefine "EnableMemoryLeakReporting".'#13#10
{$endif}
+ #0;
LeakMessageTitle = 'Memory Leak Detected';
{$ifdef UseOutputDebugString}
FastMMInstallMsg = 'FastMM has been installed.';
FastMMInstallSharedMsg = 'Sharing an existing instance of FastMM.';
FastMMUninstallMsg = 'FastMM has been uninstalled.';
FastMMUninstallSharedMsg = 'Stopped sharing an existing instance of FastMM.';
{$endif}
{$ifdef DetectMMOperationsAfterUninstall}
InvalidOperationTitle = 'MM Operation after uninstall.';
InvalidGetMemMsg = 'FastMM has detected a GetMem call after FastMM was uninstalled.';
InvalidFreeMemMsg = 'FastMM has detected a FreeMem call after FastMM was uninstalled.';
InvalidReallocMemMsg = 'FastMM has detected a ReallocMem call after FastMM was uninstalled.';
InvalidAllocMemMsg = 'FastMM has detected an AllocMem call after FastMM was uninstalled.';
{$endif}
implementation
end.

View File

@ -0,0 +1,130 @@
{
Fast Memory Manager: Messages
French translation by Florent Ouchet.
}
unit FastMM4Messages;
interface
{$Include FastMM4Options.inc}
const
{The name of the debug info support DLL}
FullDebugModeLibraryName32Bit = 'FastMM_FullDebugMode.dll';
FullDebugModeLibraryName64Bit = 'FastMM_FullDebugMode64.dll';
{Event log strings}
LogFileExtension = '_MemoryManager_Rapport.txt'#0;
CRLF = #13#10;
EventSeparator = '--------------------------------';
{Class name messages}
UnknownClassNameMsg = 'Inconnu';
{Memory dump message}
MemoryDumpMsg = #13#10#13#10'Contenu des 256 octets commençant à l''adresse ';
{Block Error Messages}
BlockScanLogHeader = 'Bloc alloué rapporté par LogAllocatedBlocksToFile. Sa taille est: ';
ErrorMsgHeader = 'FastMM a détecté une erreur pendant un ';
GetMemMsg = 'appel à GetMem';
FreeMemMsg = 'appel à FreeMem';
ReallocMemMsg = 'appel à ReallocMem';
BlockCheckMsg = 'scan des blocs libres';
OperationMsg = '. ';
BlockHeaderCorruptedMsg = 'L''en-tête du bloc a été corrompue. ';
BlockFooterCorruptedMsg = 'La fin du bloc a été corrompue. ';
FreeModifiedErrorMsg = 'FastMM a détecté qu''un bloc a été modifié après avoir été libéré. ';
FreeModifiedDetailMsg = #13#10#13#10'Modified byte offsets (and lengths): ';
DoubleFreeErrorMsg = 'Tentative d''appeler free ou reallocate pour un bloc déjà libéré.';
WrongMMFreeErrorMsg = 'An attempt has been made to free/reallocate a block that was allocated through a different FastMM instance. Check your memory manager sharing settings.';
PreviousBlockSizeMsg = #13#10#13#10'La taille précédente du bloc était: ';
CurrentBlockSizeMsg = #13#10#13#10'La taille du bloc est: ';
PreviousObjectClassMsg = #13#10#13#10'Le bloc était précédemment utilisé pour un objet de la classe: ';
CurrentObjectClassMsg = #13#10#13#10'Le bloc était actuellement utilisé pour un objet de la classe: ';
PreviousAllocationGroupMsg = #13#10#13#10'Le groupe d''allocations était: ';
PreviousAllocationNumberMsg = #13#10#13#10'Le nombre d''allocations était: ';
CurrentAllocationGroupMsg = #13#10#13#10'Le groupe d''allocation est: ';
CurrentAllocationNumberMsg = #13#10#13#10'Le nombre d''allocations est: ';
BlockErrorMsgTitle = 'Erreur mémoire détectée';
VirtualMethodErrorHeader = 'FastMM a détecté une tentative d''appel d''une méthode virtuelle d''un objet libéré. Une violation d''accès va maintenant être levée dans le but d''annuler l''opération courante.';
InterfaceErrorHeader = 'FastMM a détecté une tentative d''utilisation d''une interface d''un objet libéré. Une violation d''accès va maintenant être levée dans le but d''annuler l''opération courante.';
BlockHeaderCorruptedNoHistoryMsg = ' La corruption de l''entête du bloc ne permet pas l''obtention de l''historique.';
FreedObjectClassMsg = #13#10#13#10'Classe de l''objet libéré: ';
VirtualMethodName = #13#10#13#10'Méthode virtuelle: ';
VirtualMethodOffset = 'Décalage +';
VirtualMethodAddress = #13#10#13#10'Adresse de la méthode virtuelle: ';
{Stack trace messages}
CurrentThreadIDMsg = #13#10#13#10'The current thread ID is 0x';
CurrentStackTraceMsg = ', and the stack trace (return addresses) leading to this error is:';
ThreadIDPrevAllocMsg = #13#10#13#10'This block was previously allocated by thread 0x';
ThreadIDAtAllocMsg = #13#10#13#10'This block was allocated by thread 0x';
ThreadIDAtFreeMsg = #13#10#13#10'The block was previously freed by thread 0x';
ThreadIDAtObjectAllocMsg = #13#10#13#10'The object was allocated by thread 0x';
ThreadIDAtObjectFreeMsg = #13#10#13#10'The object was subsequently freed by thread 0x';
StackTraceMsg = ', and the stack trace (return addresses) at the time was:';
{Installation Messages}
AlreadyInstalledMsg = 'FastMM4 est déjà installé.';
AlreadyInstalledTitle = 'Déjà installé.';
OtherMMInstalledMsg = 'FastMM4 ne peut pas être installé puisqu''un autre gestionnaire de mémoire s''est déjà installé.'#13#10
+ 'Pour utiliser FastMM4, FastMM4.pas doit être la toute première unité dans la section "uses" du fichier projet .dpr';
OtherMMInstalledTitle = 'Impossible d''installer FastMM4 - un autre gestionnaire de mémoire est déjà installé';
MemoryAllocatedMsg = 'FastMM4 ne peut pas être installé puisque des blocs de mémoire ont déjà été alloué par le gestionnaire de mémoire par défaut.'#13#10
+ 'FastMM4.pas DOIT être la première unité dans la section "uses" du fichier projet .dpr; dans le cas contraire, des blocs de mémoire '#1310
+ 'peuvent être alloués avant que FastMM4 ne prenne le contrôle, si vous utilisez un gestionnaire d''exception comme MadExcept '#1310
+ '(ou tout autre outil qui modifie l''ordre d''initialisation des unités). Veuillez modifier sur la page de configuration de cet outil'#1310
+ 'l''ordre d''initialisation des unités pour que FastMM4.pas soit initialisée avant tout autre unité';
MemoryAllocatedTitle = 'Impossible d''installer FastMM4 - des blocs de mémoire ont déjà été alloués';
{Leak checking messages}
LeakLogHeader = 'Une fuite mémoire a été détectée. Sa taille est: ';
LeakMessageHeader = 'Cette application a fuit de la mémoire. ';
SmallLeakDetail = 'Les fuites de petits blocs sont'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (excluant toutes les fuites masquées)'
{$endif}
+ ':'#13#10;
LargeLeakDetail = 'Les tailles des blocs moyens et grands sont'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (excluant toutes les fuites masquées)'
{$endif}
+ ': ';
BytesMessage = ' octets: ';
AnsiStringBlockMessage = 'AnsiString';
UnicodeStringBlockMessage = 'UnicodeString';
LeakMessageFooter = #13#10
{$ifndef HideMemoryLeakHintMessage}
+ #13#10'Conseil: '
{$ifdef RequireIDEPresenceForLeakReporting}
+ 'Cette vérification des fuites mémoire n''est effectué que si Delphi est actuellement exécuté sur la même machine. '
{$endif}
{$ifdef FullDebugMode}
{$ifdef LogMemoryLeakDetailToFile}
+ 'Les détails des fuites de mémoire sont rapportés dans un fichier texte dans le même répertoire que l''application. '
{$else}
+ 'Activez l''option "LogMemoryLeakDetailToFile" pour obtenir un fichier rapportant les détails des fuites de mémoire. '
{$endif}
{$else}
+ 'Pour obtenir un fichier rapport contenant les détails des fuites de mémoire, activez les options de compilation "FullDebugMode" et "LogMemoryLeakDetailToFile". '
{$endif}
+ 'Pour désactiver cette vérification des fuites mémoires, désactivez l''option de compilation "EnableMemoryLeakReporting".'#13#10
{$endif}
+ #0;
LeakMessageTitle = 'Fuite mémoire détectée';
{$ifdef UseOutputDebugString}
FastMMInstallMsg = 'FastMM a été installé.';
FastMMInstallSharedMsg = 'Partageant un exemplaire existant de FastMM.';
FastMMUninstallMsg = 'FastMM a été désinstallé.';
FastMMUninstallSharedMsg = 'Fin du partage avec un exemplaire existant de FastMM.';
{$endif}
{$ifdef DetectMMOperationsAfterUninstall}
InvalidOperationTitle = 'Operation MM après la désinstallation.';
InvalidGetMemMsg = 'FastMM a détecté un appel à GetMem après que FastMM ait été désinstallé.';
InvalidFreeMemMsg = 'FastMM a détecté un appel à FreeMem après que FastMM ait été désinstallé.';
InvalidReallocMemMsg = 'FastMM a détecté un appel à ReallocMem après que FastMM ait été désinstallé.';
InvalidAllocMemMsg = 'FastMM a détecté un appel à AllocMem après que FastMM ait été désinstallé.';
{$endif}
implementation
end.

View File

@ -0,0 +1,135 @@
{
Fast Memory Manager: Messages
German Translation by Thomas Speck (thomas.speck@tssoft.de).
}
unit FastMM4Messages;
interface
{$Include FastMM4Options.inc}
const
{The name of the debug info support DLL}
FullDebugModeLibraryName32Bit = 'FastMM_FullDebugMode.dll';
FullDebugModeLibraryName64Bit = 'FastMM_FullDebugMode64.dll';
{Event log strings}
LogFileExtension = '_MemoryManager_EventLog.txt'#0;
CRLF = #13#10;
EventSeparator = '--------------------------------';
{Class name messages}
UnknownClassNameMsg = 'Unbekannt';
{Memory dump message}
MemoryDumpMsg = #13#10#13#10'Aktueller Speicherauszug von 256 Bytes, beginnend ab Zeigeradresse ';
{Block Error Messages}
BlockScanLogHeader = 'Allocated block logged by LogAllocatedBlocksToFile. The size is: ';
ErrorMsgHeader = 'FastMM hat einen Fehler entdeckt während einem / einer';
GetMemMsg = 'GetMem';
FreeMemMsg = 'FreeMem';
ReallocMemMsg = 'ReallocMem';
BlockCheckMsg = 'Freien Block-Scan';
OperationMsg = ' Operation. ';
BlockHeaderCorruptedMsg = 'Der Block-Beginn ist defekt. ';
BlockFooterCorruptedMsg = 'Das Block-Ende ist defekt. ';
FreeModifiedErrorMsg = 'FastMM entdeckte einen Block, der nach der Freigabe verändert wurde. ';
FreeModifiedDetailMsg = #13#10#13#10'Modified byte offsets (and lengths): ';
DoubleFreeErrorMsg = 'Es wurde versucht, einen unbelegten Block freizugeben bzw. zu belegen.';
WrongMMFreeErrorMsg = 'An attempt has been made to free/reallocate a block that was allocated through a different FastMM instance. Check your memory manager sharing settings.';
PreviousBlockSizeMsg = #13#10#13#10'Die vorherige Blockgröße war: ';
CurrentBlockSizeMsg = #13#10#13#10'Die Blockgröße ist: ';
PreviousObjectClassMsg = #13#10#13#10'Der Block wurde vorher für eine Objektklasse benutzt: ';
CurrentObjectClassMsg = #13#10#13#10'Der Block wird momentan für eine Objektklasse benutzt ';
PreviousAllocationGroupMsg = #13#10#13#10'The allocation group was: ';
PreviousAllocationNumberMsg = #13#10#13#10'The allocation number was: ';
CurrentAllocationGroupMsg = #13#10#13#10'The allocation group is: ';
CurrentAllocationNumberMsg = #13#10#13#10'The allocation number is: ';
BlockErrorMsgTitle = 'Speicherfehler entdeckt';
VirtualMethodErrorHeader = 'FastMM hat einen Versuch entdeckt, eine virtuelle Methode eines freigegebenen Objektes aufzurufen. Eine Schutzverletzung wird nun aufgerufen, um die aktuelle Operation abzubrechen.';
InterfaceErrorHeader = 'FastMM hat einen Versuch entdeckt, ein Interface eines freigegebenen Objektes aufzurufen. Eine Schutzverletzung wird nun aufgerufen, um die aktuelle Operation abzubrechen.';
BlockHeaderCorruptedNoHistoryMsg = ' Unglücklicherweise wurde der Block-Beginn beschädigt, so daß keine Historie verfügbar ist.';
FreedObjectClassMsg = #13#10#13#10'Freigegebene Objekt-Klasse: ';
VirtualMethodName = #13#10#13#10'Virtuelle Methode: ';
VirtualMethodOffset = 'Offset +';
VirtualMethodAddress = #13#10#13#10'Adresse der virtuellen Methode: ';
{Stack trace messages}
CurrentThreadIDMsg = #13#10#13#10'The current thread ID is 0x';
CurrentStackTraceMsg = ', and the stack trace (return addresses) leading to this error is:';
ThreadIDPrevAllocMsg = #13#10#13#10'This block was previously allocated by thread 0x';
ThreadIDAtAllocMsg = #13#10#13#10'This block was allocated by thread 0x';
ThreadIDAtFreeMsg = #13#10#13#10'The block was previously freed by thread 0x';
ThreadIDAtObjectAllocMsg = #13#10#13#10'The object was allocated by thread 0x';
ThreadIDAtObjectFreeMsg = #13#10#13#10'The object was subsequently freed by thread 0x';
StackTraceMsg = ', and the stack trace (return addresses) at the time was:';
{Installation Messages}
AlreadyInstalledMsg = 'FastMM4 ist installiert.';
AlreadyInstalledTitle = 'Schon installiert.';
OtherMMInstalledMsg = 'FastMM4 kann nicht installiert werden, weil ein schon ein anderer '
+ 'Memory Manager installiert wurde.'#13#10'Wenn Sie FastMM4 benutzen wollen, '
+ 'dann vergewissern Sie sich, daß FastMM4.pas die allererste Unit in der "uses"'
+ #13#10'Sektion Ihrer Projektdatei ist.';
OtherMMInstalledTitle = 'Kann FastMM4 nicht installieren - Ein anderer Memory Manager ist schon installiert.';
MemoryAllocatedMsg = 'FastMM4 kann nicht installiert werden, weil schon Speicher'
+ 'durch den Default Memory Manager belegt wurde.'#13#10'FastMM4.pas MUSS '
+ 'die allererste Unit in Ihrer Projektdatei sein, sonst wird der Speicher '
+ 'durch den Default Memory Manager belegt, bevor FastMM4 die Kontrolle übernimmt. '
+ #13#10#13#10'Wenn Sie ein Programm benutzen, welches Exceptions abfängt '
+ 'z.B. MadExcept (oder ein anderes Tool, das die Reihenfolge der Unit Initialisierung '
+ 'verändert),'#13#10'dann gehen Sie in seine Konfiguration und stellen Sie sicher, daß '
+ 'FastMM4.pas Unit vor jeder anderen Unit initialisiert wird.';
MemoryAllocatedTitle = 'Kann FastMM4nicht installieren - Speicher wurde schon belegt.';
{Leak checking messages}
LeakLogHeader = 'Ein Speicherblock hat Speicher verloren. Die Größe ist: ';
LeakMessageHeader = 'Diese Anwendung hat Speicher verloren. ';
SmallLeakDetail = 'Die Größen von kleinen Speicherblöcken, die verlorengegangen sind, betragen'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (ausgenommen erwartete Speicherlecks, die durch Zeiger registriert wurden)'
{$endif}
+ ':'#13#10;
LargeLeakDetail = 'Die Größen von mittleren und großen Speicherblöcken, die verlorengegangen sind, betragen'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (ausgenommen erwartete Speicherlecks, die durch Zeiger registriert wurden)'
{$endif}
+ ': ';
BytesMessage = ' Bytes: ';
AnsiStringBlockMessage = 'AnsiString';
UnicodeStringBlockMessage = 'UnicodeString';
LeakMessageFooter = #13#10
{$ifndef HideMemoryLeakHintMessage}
+ #13#10'Notiz: '
{$ifdef RequireIDEPresenceForLeakReporting}
+ 'Diese Überprüfung auf Speicherlecks wird nur durchgeführt, wenn Delphi auf dem selben Computer gestartet ist. '
{$endif}
{$ifdef FullDebugMode}
{$ifdef LogMemoryLeakDetailToFile}
+ 'Speicherleck-Details werden in eine Textdatei geschrieben, die sich im selben Verzeichnis wie diese Anwendung befindet. '
{$else}
+ 'Aktiviere "LogMemoryLeakDetailToFile", um eine detaillierte Log-Datei zu erhalten, die Details zu Speicherlecks enthält. '
{$endif}
{$else}
+ 'Um eine Log-Datei zu erhalten, die Details zu Speicherlecks enthält, aktivieren Sie "FullDebugMode" und "LogMemoryLeakDetailToFile" in der Options-Datei. '
{$endif}
+ 'Um diese Speicherleck-Überprüfung abzuschalten, kommentieren Sie "EnableMemoryLeakReporting" aus.'#13#10
{$endif}
+ #0;
LeakMessageTitle = 'Speicherleck entdeckt';
{$ifdef UseOutputDebugString}
FastMMInstallMsg = 'FastMM wurde installiert.';
FastMMInstallSharedMsg = 'Benutzung einer existierenden Instanz von FastMM wurde gestartet.';
FastMMUninstallMsg = 'FastMM wurde deinstalliert.';
FastMMUninstallSharedMsg = 'Benutzung einer existierenden Instanz von FastMM wurde gestoppt.';
{$endif}
{$ifdef DetectMMOperationsAfterUninstall}
InvalidOperationTitle = 'MM Operation nach der Deinstallierung.';
InvalidGetMemMsg = 'FastMM hat einen GetMem-Aufruf nach der Deinstallation von FastMM entdeckt.';
InvalidFreeMemMsg = 'FastMM hat einen FreeMem-Aufruf nach der Deinstallation von FastMM entdeckt.';
InvalidReallocMemMsg = 'FastMM hat einen ReAllocMem-Aufruf nach der Deinstallation von FastMM entdeckt.';
InvalidAllocMemMsg = 'FastMM hat einen AllocMem-Aufruf nach der Deinstallation von FastMM entdeckt.';
{$endif}
implementation
end.

View File

@ -0,0 +1,131 @@
{Fast Memory Manager: Meldungen
Deutsche Übersetzung von Uwe Queisser [uweq]
}
unit FastMM4Messages;
interface
{$Include FastMM4Options.inc}
const
{Der Name der Debug-Info-DLL}
FullDebugModeLibraryName32Bit = 'FastMM_FullDebugMode.dll';
FullDebugModeLibraryName64Bit = 'FastMM_FullDebugMode64.dll';
{Protokollaufzeichungs Erweiterung}
LogFileExtension = '_FastMM_Log.txt'#0; {*** (changed) geaendert 31.01.06 (to long) zu lang *** [uweq] ***}
CRLF = #13#10;
EventSeparator = '--------------------------------';
{Klassenbezeichner Meldung}
UnknownClassNameMsg = 'Unbekannt';
{Speicherauszugsnachricht}
MemoryDumpMsg = #13#10#13#10'Aktueller Speicherauszug von 256 Byte, angefangen an der Zeigeradresse: ';
{Block Fehlermeldungen}
BlockScanLogHeader = 'Allocated block logged by LogAllocatedBlocksToFile. The size is: ';
ErrorMsgHeader = 'FastMM hat einen Fehler erkannt, während ein';
GetMemMsg = ' GetMem';
FreeMemMsg = ' FreeMem';
ReallocMemMsg = ' ReallocMem';
BlockCheckMsg = 'er freier SpeicherBlocküberprüfung';
OperationMsg = ' Operation. ';
BlockHeaderCorruptedMsg = 'Der Block-Header ist fehlerhaft. ';
BlockFooterCorruptedMsg = 'Der Block-Footer (Line) ist fehlerhaft. ';
FreeModifiedErrorMsg = 'FastMM hat festgestellt, daß ein Speicherblock modifiziert worden ist, nachdem er freigegeben wurde. ';
FreeModifiedDetailMsg = #13#10#13#10'Modified byte offsets (and lengths): ';
DoubleFreeErrorMsg = 'Es wurde ein Versuch unternommen, einen freigegebenen Speicherblock freizugeben / wiederzuverwenden.';
WrongMMFreeErrorMsg = 'An attempt has been made to free/reallocate a block that was allocated through a different FastMM instance. Check your memory manager sharing settings.';
PreviousBlockSizeMsg = #13#10#13#10'Die vorherige Speicherblockgröße war: ';
CurrentBlockSizeMsg = #13#10#13#10'Die Speicherblockgröße ist: ';
PreviousObjectClassMsg = #13#10#13#10'Der Speicherpuffer wurde zuvor für ein Objekt der folgenden Klasse verwendet: ';
CurrentObjectClassMsg = #13#10#13#10'Der Speicherpuffer wird gegenwärtig für ein Objekt der folgenden Klasse verwendet: ';
PreviousAllocationGroupMsg = #13#10#13#10'The allocation group was: ';
PreviousAllocationNumberMsg = #13#10#13#10'The allocation number was: ';
CurrentAllocationGroupMsg = #13#10#13#10'The allocation group is: ';
CurrentAllocationNumberMsg = #13#10#13#10'The allocation number is: ';
BlockErrorMsgTitle = 'Speicherfehler gefunden';
VirtualMethodErrorHeader = 'FastMM hat einen Versuch festgestellt, eine virtuelle Methode eines freigegebenen Objekts aufzurufen.'+CRLF
+'Es wird jetzt eine Zugriffsverletzung erzeugt, um den aktuellen Betrieb abzubrechen.';
InterfaceErrorHeader = 'FastMM hat einen Versuch festgestellt, eine Schnittstelle eines freigegebenen Objekts zu verwenden.'+CRLF
+'Es wird jetzt eine Zugriffsverletzung erzeugt, um den aktuellen Betrieb abzubrechen.';
BlockHeaderCorruptedNoHistoryMsg = ' Leider ist der Speicherbereich fehlerhaft, so daß kein Protokoll verfügbar ist.';
FreedObjectClassMsg = #13#10#13#10'Freigegebene Objektklasse: ';
VirtualMethodName = #13#10#13#10'Virtuelle Methode: ';
VirtualMethodOffset = 'Relative Position +';
VirtualMethodAddress = #13#10#13#10'Virtuelle Methodenadresse: ';
{Stack trace messages}
CurrentThreadIDMsg = #13#10#13#10'The current thread ID is 0x';
CurrentStackTraceMsg = ', and the stack trace (return addresses) leading to this error is:';
ThreadIDPrevAllocMsg = #13#10#13#10'This block was previously allocated by thread 0x';
ThreadIDAtAllocMsg = #13#10#13#10'This block was allocated by thread 0x';
ThreadIDAtFreeMsg = #13#10#13#10'The block was previously freed by thread 0x';
ThreadIDAtObjectAllocMsg = #13#10#13#10'The object was allocated by thread 0x';
ThreadIDAtObjectFreeMsg = #13#10#13#10'The object was subsequently freed by thread 0x';
StackTraceMsg = ', and the stack trace (return addresses) at the time was:';
{Installationsmeldungen}
AlreadyInstalledMsg = 'FastMM4 ist bereits installiert.';
AlreadyInstalledTitle = 'schon installiert.';
OtherMMInstalledMsg = 'FastMM4 kann nicht noch einmal in den Speicher geladen werden. '
+ 'Manager hat sich bereits installiert.'#13#10'Wenn Sie FastMM4 verwenden wollen,'
+ 'vergewissern sie sich, daß FastMM4.pas die allererste Unit in der "uses"'
+ #13#10'-Anweisung ihrer Projekt-.dpr Datei ist.';
OtherMMInstalledTitle = 'Kann die Installation von FastMM4 nicht fortsetzen - da ein anderer Speichermanager bereits geladen wurde';
MemoryAllocatedMsg = 'FastMM4 kann sich nicht installieren, da der Speicher schon'
+ ' von einem anderen Speichermanager zugeordnet wurde.'#13#10'FastMM4.pas muß'
+ ' die erste Unit in Ihrer Projekt-.dpr sein, sonst wird Speicher, '
+ 'vor Benutzung des FastMM4 '#13#10' durch den Standardspeichermanager zugeordnet'
+ ' und übernommen. '#13#10#13#10'Wenn Sie eine Fehlerbehandlung benutzen '
+ 'möchten, sollten Sie MadExcept (oder ein anderes Hilfsprogramm, das die Unit-Initialisierung modifiziert'
+ ' bestellen), '#13#10' und stellen in der Konfiguration sicher, daß die '
+ 'FastMM4.pas Unit vor jeder anderen Unit initialisiert wird.';
MemoryAllocatedTitle = 'Keine Installation von FastMM4 - Speicher ist bereits zugeordnet worden.';
{Speicherleck Meldungen}
LeakLogHeader = 'Ein Speicher-Leck hat folgende Größe : ';
LeakMessageHeader = 'Diese Anwendung hat Speicher-Lecks. ';
SmallLeakDetail = 'Die kleineren Speicher-Lecks sind'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (ausschließlich von Zeigern registrierte Lecks)'
{$endif}
+ ':'#13#10;
LargeLeakDetail = 'Die größeren Speicher-Lecks sind'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (ausschließlich von Zeiger registrierte Lecks)'
{$endif}
+ ': ';
BytesMessage = ' bytes: ';
AnsiStringBlockMessage = 'AnsiString';
UnicodeStringBlockMessage = 'UnicodeString';
LeakMessageFooter = #13#10
{$ifndef HideMemoryLeakHintMessage}
+ #13#10'Hinweis: '
{$ifdef RequireIDEPresenceForLeakReporting}
+ 'Diese Speicherleckprüfung wird nur ausgeführt, wenn Delphi gegenwärtig auf demselben Computer läuft. '
{$endif}
{$ifdef FullDebugMode}
{$ifdef LogMemoryLeakDetailToFile}
+ 'Speicherlecks werden in einer Textdatei im selben Ordner wie diese Anwendung protokolliert. '
{$else}
+ 'Wenn Sie "{$ LogMemoryLeakDetailToFile}" aktivieren, erhalten sie in der Protokolldatei die Details über Speicherlecks. '
{$endif}
{$else}
+ 'Um eine Protokolldatei zu erhalten, die Details über Speicherlecks enthält, aktivieren Sie die "{$ FullDebugMode}" und "{$ LogMemoryLeakDetailToFile}" Definitionen. '
{$endif}
+ 'Um die Speicherleckprüfung zu deaktivieren, deaktivieren sie die "{$ EnableMemoryLeakReporting} -Option".'#13#10
{$endif}
+ #0;
LeakMessageTitle = 'Speicherleck entdeckt';
{$ifdef UseOutputDebugString}
FastMMInstallMsg = 'FastMM ist wurde geladen.';
FastMMInstallSharedMsg = 'Eine bereits vorhandene Instanz von FastMM wird gemeinsam benutzt.';
FastMMUninstallMsg = 'FastMM ist aus dem Speicher entladen worden.';
FastMMUninstallSharedMsg = 'Eine gemeinsam benutzte Instanz von FastMM wurde angehalten.';
{$endif}
{$ifdef DetectMMOperationsAfterUninstall}
InvalidOperationTitle = 'MM nach dem Betrieb der Installation.';
InvalidGetMemMsg = 'FastMM hat einen GetMem Aufruf gefunden, nachdem FastMM deinstalliert wurde.';
InvalidFreeMemMsg = 'FastMM hat einen FreeMem Aufruf gefunden, nachdem FastMM deinstalliert wurde.';
InvalidReallocMemMsg = 'FastMM hat einen ReallocMem Aufruf gefunden, nachdem FastMM deinstalliert wurde.';
InvalidAllocMemMsg = 'FastMM hat einen ReallocMem Aufruf gefunden, nachdem FastMM deinstalliert wurde.';
{$endif}
implementation
end.

View File

@ -0,0 +1,135 @@
{
Fast Memory Manager: Messages
Indonesian translation by Zaenal Mutaqin.
}
unit FastMM4Messages;
interface
{$Include FastMM4Options.inc}
const
{The name of the debug info support DLL}
FullDebugModeLibraryName32Bit = 'FastMM_FullDebugMode.dll';
FullDebugModeLibraryName64Bit = 'FastMM_FullDebugMode64.dll';
{Event log strings}
LogFileExtension = '_Laporan_ManajerMemori.txt'#0;
CRLF = #13#10;
EventSeparator = '--------------------------------';
{Class name messages}
UnknownClassNameMsg = 'Tidak dikenal';
{Memory dump message}
MemoryDumpMsg = #13#10#13#10'Dump memori saat ini dari 256 byte dimulai pada alamat pointer ';
{Block Error Messages}
BlockScanLogHeader = 'Allocated block logged by LogAllocatedBlocksToFile. The size is: ';
ErrorMsgHeader = 'FastMM mendeteksi terjadi kesalahan sewaktu ';
GetMemMsg = 'GetMem';
FreeMemMsg = 'FreeMem';
ReallocMemMsg = 'ReallocMem';
BlockCheckMsg = 'membebaskan pemantauan blok';
OperationMsg = ' operasi. ';
BlockHeaderCorruptedMsg = 'Kepala blok sudah terkorupsi. ';
BlockFooterCorruptedMsg = 'Kaki blok sudah terkorupsi. ';
FreeModifiedErrorMsg = 'FastMM mendeteksi bahwa blok sudah diubah setelah dibebaskan. ';
FreeModifiedDetailMsg = #13#10#13#10'Modified byte offsets (and lengths): ';
DoubleFreeErrorMsg = 'Percobaan dilakukan untuk membebaskan/realokasi blok yang tidak dialokasikan';
WrongMMFreeErrorMsg = 'An attempt has been made to free/reallocate a block that was allocated through a different FastMM instance. Check your memory manager sharing settings.';
PreviousBlockSizeMsg = #13#10#13#10'Besar blok sebelumnya adalah: ';
CurrentBlockSizeMsg = #13#10#13#10'Besar blok adalah: ';
PreviousObjectClassMsg = #13#10#13#10'Blok yang sebelumnya digunakan untuk obyek dari kelas: ';
CurrentObjectClassMsg = #13#10#13#10'Blok yang digunakan saat ini untuk obyek dari kelas: ';
PreviousAllocationGroupMsg = #13#10#13#10'The allocation group was: ';
PreviousAllocationNumberMsg = #13#10#13#10'The allocation number was: ';
CurrentAllocationGroupMsg = #13#10#13#10'The allocation group is: ';
CurrentAllocationNumberMsg = #13#10#13#10'The allocation number is: ';
BlockErrorMsgTitle = 'Kesalahan Memori Terdeteksi';
VirtualMethodErrorHeader = 'FastMM mendeteksi percobaan pemanggilan metode virtual pada obyek yang dibebaskan. Pelanggaran akses akan ditampilkan sekarang untuk membatalkan operasi saat ini.';
InterfaceErrorHeader = 'FastMM mendeteksi percobaan penggunaan antar muka dari obyek yang sudah dibebaskan. Pelanggaran akses akan ditampilkan sekarang untuk membatalkan operasi saat ini.';
BlockHeaderCorruptedNoHistoryMsg = ' Kebetulan kepala blok sudah terkorupsi oleh karenanya tidak ada histori yang tersedia.';
FreedObjectClassMsg = #13#10#13#10'Kelas obyek yang dibebaskan: ';
VirtualMethodName = #13#10#13#10'Metode virtual: ';
VirtualMethodOffset = 'Ofset +';
VirtualMethodAddress = #13#10#13#10'Alamat metode virtual: ';
{Stack trace messages}
CurrentThreadIDMsg = #13#10#13#10'The current thread ID is 0x';
CurrentStackTraceMsg = ', and the stack trace (return addresses) leading to this error is:';
ThreadIDPrevAllocMsg = #13#10#13#10'This block was previously allocated by thread 0x';
ThreadIDAtAllocMsg = #13#10#13#10'This block was allocated by thread 0x';
ThreadIDAtFreeMsg = #13#10#13#10'The block was previously freed by thread 0x';
ThreadIDAtObjectAllocMsg = #13#10#13#10'The object was allocated by thread 0x';
ThreadIDAtObjectFreeMsg = #13#10#13#10'The object was subsequently freed by thread 0x';
StackTraceMsg = ', and the stack trace (return addresses) at the time was:';
{Installation Messages}
AlreadyInstalledMsg = 'FastMM4 sudah diinstalasi.';
AlreadyInstalledTitle = 'Sudah terinstalasi.';
OtherMMInstalledMsg = 'FastMM4 tidak bisa diinstalasi karena manajer memori pihak ketiga '
+ 'sudah menginstalasi dirinya sendiri.'#13#10'Jika anda ingin menggunakan FastMM4, '
+ 'pastikan bahwa FastMM4.pas adalah untit paling pertama dalam seksi "uses"'
+ #13#10'dari file proyek .dpr anda.';
OtherMMInstalledTitle = 'Tidak bisa menginstalasi FastMM4 - Manajer memori lain sudah diinstalasi';
MemoryAllocatedMsg = 'FastMM4 tidak bisa menginstalasi karena memori sudah '
+ 'dialokasikan melalui manajer memori default.'#13#10'FastMM4.pas HARUS '
+ 'unit pertama dalam file proyek .dpr anda, sebaliknya memori bisa '
+ 'dialokasikan '#13#10'melalui manajer memori default sebelum FastMM4 '
+ 'mendapatkan kontrolnya. '#13#10#13#10'Jika anda menggunakan penjebak kekecualian '
+ 'seperti MadExcept (atau piranti lain yang mengubah urutan inisialiasai unit, '
+ #13#10'lihat ke dalam halaman konfigurasinya dan pastikan bahwa '
+ 'unit FastMM4.pas diinisialisasi sebelum unit lainnya.';
MemoryAllocatedTitle = 'Tidak bisa menginstalasi FastMM4 - Memori sudah dialokasikan';
{Leak checking messages}
LeakLogHeader = 'Blok memori sudah bocor. Besarnya adalah: ';
LeakMessageHeader = 'Aplikasi ini mempunyai kebocoran memori. ';
SmallLeakDetail = 'Blok kecil kebocoran adalah'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (tidak termasuk kebocoran yang didaftarkan oleh pointer)'
{$endif}
+ ':'#13#10;
LargeLeakDetail = 'Besar dari kebocoran blok medium dan besar adalah'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (tidak termasuk kebocoran yang terdaftar oleh pointer)'
{$endif}
+ ': ';
BytesMessage = ' byte: ';
AnsiStringBlockMessage = 'AnsiString';
UnicodeStringBlockMessage = 'UnicodeString';
LeakMessageFooter = #13#10
{$ifndef HideMemoryLeakHintMessage}
+ #13#10'Catatan: '
{$ifdef RequireIDEPresenceForLeakReporting}
+ 'Kebocoran memori ini hanya ditampilkan jika Delphi saat ini berjalan pada komputer yang sama. '
{$endif}
{$ifdef FullDebugMode}
{$ifdef LogMemoryLeakDetailToFile}
+ 'Perincian kebocoran memori dicatat ke file teks dalam folder yang sama dengan aplikasi ini. '
{$else}
+ 'Hidupkan "LogMemoryLeakDetailToFile" untuk mendapatkan file log yang berisi perincian kebocoran memori. '
{$endif}
{$else}
+ 'Untuk mendapatkan file log yang berisi perincian kebocoran memori, hidupkan definisi kondisional "FullDebugMode" dan "LogMemoryLeakDetailToFile". '
{$endif}
+ 'Untuk mematikan pemeriksaan kebocoran, jangan definisikan "EnableMemoryLeakReporting".'#13#10
{$endif}
+ #0;
LeakMessageTitle = 'Kebocoran Memori Terdeteksi';
{$ifdef UseOutputDebugString}
FastMMInstallMsg = 'FastMM sudah diinstalasi.';
FastMMInstallSharedMsg = 'Membagi instan FastMM yang sudah ada.';
FastMMUninstallMsg = 'FastMM sudah di deinstalasi.';
FastMMUninstallSharedMsg = 'Pembagian instan FastMM yang ada dihentikan.';
{$endif}
{$ifdef DetectMMOperationsAfterUninstall}
InvalidOperationTitle = 'Operasi MM setelah deinstalasi.';
InvalidGetMemMsg = 'FastMM mendeteksi pemanggilan GetMem setelah FastMM di deinstalasi.';
InvalidFreeMemMsg = 'FastMM mendeteksi pemanggilan FreeMem setelah FastMM di deinstalasi.';
InvalidReallocMemMsg = 'FastMM mendeteksi pemanggilan ReallocMem setelah FastMM di deinstalasi.';
InvalidAllocMemMsg = 'FastMM mendeteksi pemanggilan ReallocMem setelah FastMM di deinstalasi.';
{$endif}
implementation
end.

View File

@ -0,0 +1,136 @@
{
Fast Memory Manager: Messages
Italian translation by Luigi D. Sandon.
}
unit FastMM4Messages;
interface
{$Include FastMM4Options.inc}
const
{The name of the debug info support DLL}
FullDebugModeLibraryName32Bit = 'FastMM_FullDebugMode.dll';
FullDebugModeLibraryName64Bit = 'FastMM_FullDebugMode64.dll';
{Event log strings}
LogFileExtension = '_MemoryManager_EventLog.txt'#0;
CRLF = #13#10;
EventSeparator = '--------------------------------';
{Class name messages}
UnknownClassNameMsg = 'Sconosciuta';
{Memory dump message}
MemoryDumpMsg = #13#10#13#10'Dump della memoria di 256 byte partendo dall''indirizzo del puntatore ';
{Block Error Messages}
BlockScanLogHeader = 'Blocco allocato registrato da LogAllocatedBlocksToFile. La dimensione è: ';
ErrorMsgHeader = 'FastMM ha rilevato un errore durante ';
GetMemMsg = 'GetMem';
FreeMemMsg = 'FreeMem';
ReallocMemMsg = 'ReallocMem';
BlockCheckMsg = 'scansione blocco libero';
OperationMsg = ' operazione. ';
BlockHeaderCorruptedMsg = 'L''intestazione del blocco è stata corrotta. ';
BlockFooterCorruptedMsg = 'Il terminatore del blocco è stato corrotto. ';
FreeModifiedErrorMsg = 'FastMM ha rilevato che un blocco è stato modificato dopo essere stato disallocato. ';
FreeModifiedDetailMsg = #13#10#13#10'Modified byte offsets (and lengths): ';
DoubleFreeErrorMsg = 'Tentativo di disallocare/reallocare un blocco non allocato.';
WrongMMFreeErrorMsg = 'An attempt has been made to free/reallocate a block that was allocated through a different FastMM instance. Check your memory manager sharing settings.';
PreviousBlockSizeMsg = #13#10#13#10'La dimensione precedente del blocco era: ';
CurrentBlockSizeMsg = #13#10#13#10'La dimensione del blocco è: ';
PreviousObjectClassMsg = #13#10#13#10'Il blocco è stato usato in precedenza per una istanza della classe: ';
CurrentObjectClassMsg = #13#10#13#10'Il blocco è attualmente usato da una istanza della classe: ';
PreviousAllocationGroupMsg = #13#10#13#10'Il gruppo di allocazione era: ';
PreviousAllocationNumberMsg = #13#10#13#10'Il numero di allocazione era: ';
CurrentAllocationGroupMsg = #13#10#13#10'Il gruppo di allocazione è: ';
CurrentAllocationNumberMsg = #13#10#13#10'Il numero di allocazione è: ';
BlockErrorMsgTitle = 'Rilevato Errore di Memoria';
VirtualMethodErrorHeader = 'FastMM ha rilevato un tentativo di chiamare un metodo virtuale di una istanza deallocata. Sarà generata una eccezione di Violazione di Accesso per abortire l''operazione corrente.';
InterfaceErrorHeader = 'FastMM ha rilevato un tentativo di usare una interfaccia di una istanza deallocata. Sarà generata una eccezione di Violazione di Accesso per abortire l''operazione corrente.';
BlockHeaderCorruptedNoHistoryMsg = ' Sfortunametamente l''intestazione del blocco è stata corrotta, quindi non è disponibile alcuna storia.';
FreedObjectClassMsg = #13#10#13#10'Deallocata istanza della classe: ';
VirtualMethodName = #13#10#13#10'Metodo virtuale: ';
VirtualMethodOffset = 'Offset +';
VirtualMethodAddress = #13#10#13#10'Indirizzo metodo virtuale: ';
{Stack trace messages}
CurrentThreadIDMsg = #13#10#13#10'The current thread ID is 0x';
CurrentStackTraceMsg = ', and the stack trace (return addresses) leading to this error is:';
ThreadIDPrevAllocMsg = #13#10#13#10'This block was previously allocated by thread 0x';
ThreadIDAtAllocMsg = #13#10#13#10'This block was allocated by thread 0x';
ThreadIDAtFreeMsg = #13#10#13#10'The block was previously freed by thread 0x';
ThreadIDAtObjectAllocMsg = #13#10#13#10'The object was allocated by thread 0x';
ThreadIDAtObjectFreeMsg = #13#10#13#10'The object was subsequently freed by thread 0x';
StackTraceMsg = ', and the stack trace (return addresses) at the time was:';
{Installation Messages}
AlreadyInstalledMsg = 'FastMM4 è già installato.';
AlreadyInstalledTitle = 'Già installato.';
OtherMMInstalledMsg = 'FastMM4 non può essere installato perché un altro gestore della memoria '
+ 'ha già installato sé stesso.'#13#10'Se volete usare FastMM4, '
+ 'assicuratevi che FastMM4.pas sia la prima unit nella sezione "uses"'
+ #13#10'del file .dpr del vostro progetto.';
OtherMMInstalledTitle = 'Impossibile installare FastMM4 - un altro gestore della memoria è già installato';
MemoryAllocatedMsg =
'FastMM4 non può essere installato perché della memoria è già ' +
'stata allocata dal gestore della memoria di default.'#13#10 +
'FastMM4.pas DEVE essere la prima unit nel file .dpr del progetto, ' +
'altrimenti la memoria può essere allocata dal gestore di default ' +
'prima che FastMM4 ottenga il controllo.'#13#10#13#10 +
'Se state usando un gestore delle eccezioni come MadExcept (o qualsiasi ' +
'altro tool che modifichi l''ordine di inizializzazione delle unit), ' +
'configurarlo in modo che la unit FastMM4.pas sia inizializzata prima di qualsiasi altra.';
MemoryAllocatedTitle = 'Impossibile installare FastMM4 - La memoria è già stata allocata';
{Leak checking messages}
LeakLogHeader = 'Leak di un blocco. La dimensione è: ';
LeakMessageHeader = 'L''applicazione ha dei leak di memoria. ';
SmallLeakDetail = 'I leak di piccoli blocchi sono'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (sono esclusi i leak attesi registrati da puntatori)'
{$endif}
+ ':'#13#10;
LargeLeakDetail = 'Le dimensioni dei leak di blocchi medi e grandi sono'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (sono esclusi i leak attesi registrati da puntatori)'
{$endif}
+ ': ';
BytesMessage = ' byte: ';
AnsiStringBlockMessage = 'AnsiString';
UnicodeStringBlockMessage = 'UnicodeString';
LeakMessageFooter = #13#10
{$ifndef HideMemoryLeakHintMessage}
+ #13#10'Nota: '
{$ifdef RequireIDEPresenceForLeakReporting}
+ 'Questi controlli di leak della memoria sono effettuati solo se Delphi è in funzione sullo stesso computer. '
{$endif}
{$ifdef FullDebugMode}
{$ifdef LogMemoryLeakDetailToFile}
+ 'I dettagli sui leak della memoria sono registrati in un file di testo nella stessa cartella di questa applicazione. '
{$else}
+ 'Abilitare "LogMemoryLeakDetailToFile" per ottenere un file di log contenente i dettagli sui leak della memoria. '
{$endif}
{$else}
+ 'Per ottenere un file di log contenente i dettagli sui leak della memoria, abilitate le direttive condizionali "FullDebugMode" e "LogMemoryLeakDetailToFile". '
{$endif}
+ 'Per disabilitare i controlli dei leak della memoria, non definire la direttiva "EnableMemoryLeakReporting".'#13#10
{$endif}
+ #0;
LeakMessageTitle = 'Rilevato leak della memoria';
{$ifdef UseOutputDebugString}
FastMMInstallMsg = 'FastMM è stato installato.';
FastMMInstallSharedMsg = 'Inizio condivisione di una istanza esistente di FastMM.';
FastMMUninstallMsg = 'FastMM è stato disinstallato.';
FastMMUninstallSharedMsg = 'Termine della condivisione di una istanza esistente di FastMM.';
{$endif}
{$ifdef DetectMMOperationsAfterUninstall}
InvalidOperationTitle = 'MM operazione dopo la disinstallazione.';
InvalidGetMemMsg = 'FastMM ha rilevato una chiamata a GetMem dopo che FastMM è stato disinstallato.';
InvalidFreeMemMsg = 'FastMM ha rilevato una chiamata a FreeMem dopo che FastMM è stato disinstallato.';
InvalidReallocMemMsg = 'FastMM ha rilevato una chiamata a ReallocMem dopo che FastMM è stato disinstallato.';
InvalidAllocMemMsg = 'FastMM ha rilevato una chiamata ad AllocMem dopo che FastMM è stato disinstallato.';
{$endif}
implementation
end.

View File

@ -0,0 +1,134 @@
{
Fast Memory Manager: Messages
Polish translation by Artur Redźko (arturr@opegieka.pl).
}
unit FastMM4Messages;
interface
{$Include FastMM4Options.inc}
const
{The name of the debug info support DLL}
FullDebugModeLibraryName32Bit = 'FastMM_FullDebugMode.dll';
FullDebugModeLibraryName64Bit = 'FastMM_FullDebugMode64.dll';
{Event log strings}
LogFileExtension = '_MemoryManager_raport.txt'#0;
CRLF = #13#10;
EventSeparator = '--------------------------------';
{Class name messages}
UnknownClassNameMsg = 'Nieznany';
{Memory dump message}
MemoryDumpMsg = #13#10#13#10'Aktualny zrzut pamięci 256 bajtów zaczynający się od adresu ';
{Block Error Messages}
BlockScanLogHeader = 'Zaalokowany blok zapisany przez LogAllocatedBlocksToFile. Rozmiar : ';
ErrorMsgHeader = 'FastMM wykrył błąd podczas operacji ';
GetMemMsg = 'GetMem';
FreeMemMsg = 'FreeMem';
ReallocMemMsg = 'ReallocMem';
BlockCheckMsg = 'skanowania wolnego bloku';
OperationMsg = '. ';
BlockHeaderCorruptedMsg = 'Nagłówek bloku jest uszkodzony. ';
BlockFooterCorruptedMsg = 'Stopka bloku jest uszkodzona. ';
FreeModifiedErrorMsg = 'FastMM wykrył że blok został zmodyfikowany po tym jak został zwolniony. ';
FreeModifiedDetailMsg = #13#10#13#10'Modified byte offsets (and lengths): ';
DoubleFreeErrorMsg = 'Wykryto próbę zwolnienia/realokacji niezaalokowanego bloku.';
WrongMMFreeErrorMsg = 'An attempt has been made to free/reallocate a block that was allocated through a different FastMM instance. Check your memory manager sharing settings.';
PreviousBlockSizeMsg = #13#10#13#10'Poprzedni rozmiar bloku był: ';
CurrentBlockSizeMsg = #13#10#13#10'Rozmiar bloku jest: ';
PreviousObjectClassMsg = #13#10#13#10'Blok został poprzednio użyty w obiekcie klasy: ';
CurrentObjectClassMsg = #13#10#13#10'Blok jest aktualnie używany w obiekcie klasy: ';
PreviousAllocationGroupMsg = #13#10#13#10'Była grupa alokacji : ';
PreviousAllocationNumberMsg = #13#10#13#10'Była ilość alokacji : ';
CurrentAllocationGroupMsg = #13#10#13#10'Jest grupa alokacji : ';
CurrentAllocationNumberMsg = #13#10#13#10'Jest ilość alokacji : ';
BlockErrorMsgTitle = 'Wykryto błąd pamięci';
VirtualMethodErrorHeader = 'FastMM wykrył próbę użycia wirtualnej metody zwolnionego obiektu. Zostanie wygenerowany teraz wyjątek w celu przerwania aktualnej operacji.';
InterfaceErrorHeader = 'FastMM wykrył próbę użycia interfejsu zwolnionego obiektu. Zostanie wygenerowany teraz wyjątek w celu przerwania aktualnej operacji.';
BlockHeaderCorruptedNoHistoryMsg = ' Niestety nagłówek bloku został uszkodzony więc historia nie jest dostępna.';
FreedObjectClassMsg = #13#10#13#10'Klasa zwolnionego obiektu: ';
VirtualMethodName = #13#10#13#10'Metoda wirtualna: ';
VirtualMethodOffset = 'przesunięcie +';
VirtualMethodAddress = #13#10#13#10'Adres metody wirtualnej: ';
{Stack trace messages}
CurrentThreadIDMsg = #13#10#13#10'The current thread ID is 0x';
CurrentStackTraceMsg = ', and the stack trace (return addresses) leading to this error is:';
ThreadIDPrevAllocMsg = #13#10#13#10'This block was previously allocated by thread 0x';
ThreadIDAtAllocMsg = #13#10#13#10'This block was allocated by thread 0x';
ThreadIDAtFreeMsg = #13#10#13#10'The block was previously freed by thread 0x';
ThreadIDAtObjectAllocMsg = #13#10#13#10'The object was allocated by thread 0x';
ThreadIDAtObjectFreeMsg = #13#10#13#10'The object was subsequently freed by thread 0x';
StackTraceMsg = ', and the stack trace (return addresses) at the time was:';
{Installation Messages}
AlreadyInstalledMsg = 'FastMM4 jest już zainstalowany.';
AlreadyInstalledTitle = 'Już zainstalowany.';
OtherMMInstalledMsg = 'FastMM4 nie może być zainstalowany ponieważ inny menedżer pamięci '
+ 'został już zainstalowany.'#13#10'Jeśli chcesz użyć FastMM4, '
+ 'zapewniając aby moduł FastMM4.pas był zainicjowany jako pierwszy moduł w twoim projekcie.';
OtherMMInstalledTitle = 'Nie można zainstalować FastMM4 - inny menedżer pamięci jest już zainstalowany';
MemoryAllocatedMsg = 'FastMM4 nie może być zainstalowany ponieważ pamięć została '
+ 'juz zaalokowana przez domyślny menedżer pamięci.'#13#10'FastMM4.pas MUSI '
+ 'być pierwszym modułem w twoim projekcie, w przeciwnym wypadku pamięć może '
+ 'być zaalokowana'#13#10'przez domyślny menedżer pamięci zanim FastMM4 '
+ 'przejmie kontrolę.'#13#10#13#10'Jeśli używasz aplikacji do przechwytywania wyjątków '
+ 'takich jak MadExcept,'#13#10'zmień jego konfigurację zapewniając aby moduł '
+ 'FastMM4.pas był zainicjowany jako pierwszy moduł.';
MemoryAllocatedTitle = 'Nie można zainstalować FastMM4 - pamięć została już zaalokowana.'
+ 'FastMM4.pas jest inicjowany jako pierwszy moduł.';
{Leak checking messages}
LeakLogHeader = 'Wyciekł blok pamięci. Rozmiar wynosi: ';
LeakMessageHeader = 'Aplikacja wykryła wycieki pamięci. ';
SmallLeakDetail = 'Małe bloki wycieków są'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (wyłączając oczekiwane wycieki zarejestrowane przez wskaźnik)'
{$endif}
+ ':'#13#10;
LargeLeakDetail = 'Rozmiary średnich i dużych wycieków wynoszą'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (wyłączając oczekiwane wycieki zarejestrowane przez wskaźnik)'
{$endif}
+ ': ';
BytesMessage = ' bajtów: ';
AnsiStringBlockMessage = 'AnsiString';
UnicodeStringBlockMessage = 'UnicodeString';
LeakMessageFooter = #13#10
{$ifndef HideMemoryLeakHintMessage}
+ #13#10'Uwaga: '
{$ifdef RequireIDEPresenceForLeakReporting}
+ 'Sprawdzenie wycieków pamięci występuje tylko gdy Delphi jest uruchomione na tym samych komputerze. '
{$endif}
{$ifdef FullDebugMode}
{$ifdef LogMemoryLeakDetailToFile}
+ 'Szczegóły wycieków są rejestrowane w pliku tekstowym w tym samym katalogu co aplikacja. '
{$else}
+ 'Włącz "LogMemoryLeakDetailToFile" aby uzyskać szczegółowy plik z wyciekami pamięci. '
{$endif}
{$else}
+ 'Aby uzyskać plik ze szczegółami wycieków pamięci, włącz definicje warunkowe "FullDebugMode" i "LogMemoryLeakDetailToFile". '
{$endif}
+ 'Aby wyłączyć raportowanie wycieków, wyłącz "EnableMemoryLeakReporting".'#13#10
{$endif}
+ #0;
LeakMessageTitle = 'Wykryto wyciek pamięci';
{$ifdef UseOutputDebugString}
FastMMInstallMsg = 'FastMM został zainstalowany.';
FastMMInstallSharedMsg = 'Rozpoczęcie współdzielenia istniejącej instancji FastMM.';
FastMMUninstallMsg = 'FastMM został odinstalowany.';
FastMMUninstallSharedMsg = 'Zakończenie współdzielenia istniejącej instancji FastMM.';
{$endif}
{$ifdef DetectMMOperationsAfterUninstall}
InvalidOperationTitle = 'Operacja MM po deinstalacji.';
InvalidGetMemMsg = 'FastMM wykrył wywołanie GetMem po tym jak FastMM został odinstalowany.';
InvalidFreeMemMsg = 'FastMM wykrył wywołanie FreeMem po tym jak FastMM został odinstalowany.';
InvalidReallocMemMsg = 'FastMM wykrył wywołanie ReallocMem po tym jak FastMM został odinstalowany.';
InvalidAllocMemMsg = 'FastMM wykrył wywołanie AllocMem po tym jak FastMM został odinstalowany.';
{$endif}
implementation
end.

View File

@ -0,0 +1,135 @@
{
Fast Memory Manager: Messages
Portuguese (Brazil) translation by Johni Jeferson Capeletto (capeletto@gmail.com) - Love you Julia.
}
unit FastMM4Messages;
interface
{$Include FastMM4Options.inc}
const
{The name of the debug info support DLL}
FullDebugModeLibraryName32Bit = 'FastMM_FullDebugMode.dll';
FullDebugModeLibraryName64Bit = 'FastMM_FullDebugMode64.dll';
{Event log strings}
LogFileExtension = '_MemoryManager_EventosLog.txt'#0;
CRLF = #13#10;
EventSeparator = '--------------------------------';
{Class name messages}
UnknownClassNameMsg = 'Desconhecida';
{Memory dump message}
MemoryDumpMsg = #13#10#13#10'Dump de memória atual de 256 bytes iniciando no endereço ';
{Block Error Messages}
BlockScanLogHeader = 'Bloco alocado logado por LogAllocatedBlocksToFile. O tamanho é: ';
ErrorMsgHeader = 'FastMM detectou um erro durante ';
GetMemMsg = 'GetMem';
FreeMemMsg = 'FreeMem';
ReallocMemMsg = 'ReallocMem';
BlockCheckMsg = 'busca de bloco livre';
OperationMsg = ' operação. ';
BlockHeaderCorruptedMsg = 'O cabeçalho do bloco foi corrompido. ';
BlockFooterCorruptedMsg = 'O rodapé do bloco foi corrompido. ';
FreeModifiedErrorMsg = 'FastMM detectou que um bloco foi modificado após ter sido liberado. ';
FreeModifiedDetailMsg = #13#10#13#10'Modified byte offsets (and lengths): ';
DoubleFreeErrorMsg = 'Uma tentativa foi feita para liberar/realocar um bloco não alocado.';
WrongMMFreeErrorMsg = 'An attempt has been made to free/reallocate a block that was allocated through a different FastMM instance. Check your memory manager sharing settings.';
PreviousBlockSizeMsg = #13#10#13#10'O tamanho anterior do bloco era: ';
CurrentBlockSizeMsg = #13#10#13#10'O tamanho do bloco é: ';
PreviousObjectClassMsg = #13#10#13#10'O bloco foi usado anteriormente por um objeto da classe: ';
CurrentObjectClassMsg = #13#10#13#10'O bloco está sendo usado por um objeto da classe: ';
PreviousAllocationGroupMsg = #13#10#13#10'O grupo de alocação era: ';
PreviousAllocationNumberMsg = #13#10#13#10'O número da alocação era: ';
CurrentAllocationGroupMsg = #13#10#13#10'O grupo de alocação é: ';
CurrentAllocationNumberMsg = #13#10#13#10'O número da alocação é: ';
BlockErrorMsgTitle = 'Erro de memória detectado';
VirtualMethodErrorHeader = 'FastMM detectou uma tentativa de chamada a um método virtual de um objeto liberado. Uma violação de acesso será disparada para abortar a operação corrente.';
InterfaceErrorHeader = 'FastMM detectou uma tentativa de uso de uma interface de um objeto liberado. Uma violação de acesso será disparada para abortar a operação corrente.';
BlockHeaderCorruptedNoHistoryMsg = ' Infelizmente o cabeçalho do bloco foi corrompido e a história não está disponível.';
FreedObjectClassMsg = #13#10#13#10'Classe do objeto liberado: ';
VirtualMethodName = #13#10#13#10'Método virtual: ';
VirtualMethodOffset = 'Offset +';
VirtualMethodAddress = #13#10#13#10'Endereço do método virtual: ';
{Stack trace messages}
CurrentThreadIDMsg = #13#10#13#10'O ID da thread atual é 0x';
CurrentStackTraceMsg = ', e a análise da pilha interna (endereços de retorno) que levaram a este erro é:';
ThreadIDPrevAllocMsg = #13#10#13#10'Este bloco foi criado anteriormente pela thread 0x';
ThreadIDAtAllocMsg = #13#10#13#10'Este bloco foi alocado pela thread 0x';
ThreadIDAtFreeMsg = #13#10#13#10'Este bloco foi liberado anteriormente pela thread 0x';
ThreadIDAtObjectAllocMsg = #13#10#13#10'O objeto foi alocado pela thread 0x';
ThreadIDAtObjectFreeMsg = #13#10#13#10'O objeto foi liberado posteriormente pela thread 0x';
StackTraceMsg = ', e a análise da pilha interna (endereços de retorno) no momento era:';
{Installation Messages}
AlreadyInstalledMsg = 'FastMM4 já foi instalado.';
AlreadyInstalledTitle = 'Já foi instalado.';
OtherMMInstalledMsg = 'FastMM4 não pode ser instalado já que outro gerenciador externo '
+ 'de memória já foi instalado.'#13#10'Se você quer usar o FastMM4, '
+ 'tenha certeza que a unit FastMM4.pas seja a primeira na seção "uses"'
+ #13#10'do arquivo .dpr do seu projeto.';
OtherMMInstalledTitle = 'Impossível instalar FastMM4 - Outro gerenciador de memória já está instalado';
MemoryAllocatedMsg = 'O FastMM4 não pode ser instalado já que a memória já foi '
+ 'alocada através do gerenciador de memória padrão.'#13#10'FastMM4.pas DEVE '
+ 'ser a primeira unit no arquivo .dpr do seu projeto, caso contrário a memória pode '
+ 'ser alocada'#13#10'através do gerenciador de memória padrão antes que o FastMM '
+ 'ganhe o controle. '#13#10#13#10'Se você estiver usando um interceptador de exceções '
+ 'como MadExcept (ou qualquer outra ferramenta que modifica a ordem de inicialização da '
+ 'unit),'#13#10'vá para sua página de configuração e tenha certeza que a unit '
+ 'FastMM4.pas seja inicializada antes de qualquer outra unit.';
MemoryAllocatedTitle = 'Impossível instalar FastMM4 - A memória já foi alocada';
{Leak checking messages}
LeakLogHeader = 'Um bloco de memória vazou. O tamanho é: ';
LeakMessageHeader = 'Essa aplicação teve vazamentos de memória. ';
SmallLeakDetail = 'Os vazamentos dos blocos pequenos são'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (excluindo os vazamentos esperados registrados por ponteiro)'
{$endif}
+ ':'#13#10;
LargeLeakDetail = 'O tamanho dos vazamentos dos blocos médios e grandes são'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (excluindo os vazamentos esperados registrados por ponteiro)'
{$endif}
+ ': ';
BytesMessage = ' bytes: ';
AnsiStringBlockMessage = 'AnsiString';
UnicodeStringBlockMessage = 'UnicodeString';
LeakMessageFooter = #13#10
{$ifndef HideMemoryLeakHintMessage}
+ #13#10'Nota: '
{$ifdef RequireIDEPresenceForLeakReporting}
+ 'Essa checagem de vazamento de memória somente é feita se o Delphi está rodando atualmente no mesmo computador. '
{$endif}
{$ifdef FullDebugMode}
{$ifdef LogMemoryLeakDetailToFile}
+ 'O detalhe do vazamento de memória está logado em um arquivo texto na mesma pasta que essa aplicação. '
{$else}
+ 'Habilite o DEFINE "LogMemoryLeakDetailToFile" para obter um arquivo de log contendo detalhes dos vazamentos de memória. '
{$endif}
{$else}
+ 'Para obter um arquivo de log contendo detalhes dos vazamentos de memória, habilite os DEFINES "FullDebugMode" e "LogMemoryLeakDetailToFile". '
{$endif}
+ 'Para desabilitar essa checagem de vazamento de memória, desabilite o DEFINE "EnableMemoryLeakReporting".'#13#10
{$endif}
+ #0;
LeakMessageTitle = 'Vazamento de memória detectado';
{$ifdef UseOutputDebugString}
FastMMInstallMsg = 'FastMM foi instalado.';
FastMMInstallSharedMsg = 'Compartilhando uma instancia existente do FastMM.';
FastMMUninstallMsg = 'FastMM foi desinstalado.';
FastMMUninstallSharedMsg = 'Parando de compartilhar uma instancia existente do FastMM.';
{$endif}
{$ifdef DetectMMOperationsAfterUninstall}
InvalidOperationTitle = 'Operação no Gerenciador de Memória após desinstalação.';
InvalidGetMemMsg = 'FastMM detectou uma chamada GetMem depois que o FastMM foi desinstalado.';
InvalidFreeMemMsg = 'FastMM detectou uma chamada FreeMem depois que o FastMM foi desinstalado.';
InvalidReallocMemMsg = 'FastMM detectou uma chamada ReallocMem depois que o FastMM foi desinstalado.';
InvalidAllocMemMsg = 'FastMM detectou uma chamada ReallocMem depois que o FastMM foi desinstalado.';
{$endif}
implementation
end.

View File

@ -0,0 +1,135 @@
{
Fast Memory Manager: Messages
Portuguese translation by Carlos Mação (Carlos.Macao@gmail.com).
}
unit FastMM4Messages;
interface
{$Include FastMM4Options.inc}
const
{The name of the debug info support DLL}
FullDebugModeLibraryName32Bit = 'FastMM_FullDebugMode.dll';
FullDebugModeLibraryName64Bit = 'FastMM_FullDebugMode64.dll';
{Event log strings}
LogFileExtension = '_MemoryManager_EventosLog.txt'#0;
CRLF = #13#10;
EventSeparator = '--------------------------------';
{Class name messages}
UnknownClassNameMsg = 'Desconhecida';
{Memory dump message}
MemoryDumpMsg = #13#10#13#10'O Dump de memória actual de 256 bytes tem inicio no endereço ';
{Block Error Messages}
BlockScanLogHeader = 'Bloco atribuído registado por LogAllocatedBlocksToFile. O Tamanho é: ';
ErrorMsgHeader = 'FastMM detectou um erro durante ';
GetMemMsg = 'GetMem';
FreeMemMsg = 'FreeMem';
ReallocMemMsg = 'ReallocMem';
BlockCheckMsg = 'procura de bloco livre';
OperationMsg = ' operação. ';
BlockHeaderCorruptedMsg = 'O cabeçalho do bloco foi corrompido. ';
BlockFooterCorruptedMsg = 'O rodapé do bloco foi corrompido. ';
FreeModifiedErrorMsg = 'FastMM detectou que um bloco de memória foi modificado após ter sido libertado. ';
FreeModifiedDetailMsg = #13#10#13#10'Modified byte offsets (and lengths): ';
DoubleFreeErrorMsg = 'Foi feita uma tentativa para libertar/atribuir um bloco não atribuido.';
WrongMMFreeErrorMsg = 'An attempt has been made to free/reallocate a block that was allocated through a different FastMM instance. Check your memory manager sharing settings.';
PreviousBlockSizeMsg = #13#10#13#10'O tamanho anterior do bloco era: ';
CurrentBlockSizeMsg = #13#10#13#10'O tamanho do bloco é: ';
PreviousObjectClassMsg = #13#10#13#10'O bloco foi usado anteriormente por um objecto da classe: ';
CurrentObjectClassMsg = #13#10#13#10'O bloco está sendo usado por um objecto da classe: ';
PreviousAllocationGroupMsg = #13#10#13#10'O grupo de atribuição era: ';
PreviousAllocationNumberMsg = #13#10#13#10'O número de atribuição era: ';
CurrentAllocationGroupMsg = #13#10#13#10'O grupo de atribuição é: ';
CurrentAllocationNumberMsg = #13#10#13#10'O número de atribuição era: ';
BlockErrorMsgTitle = 'Erro de memória detectado';
VirtualMethodErrorHeader = 'FastMM detectou uma tentativa de chamada a um método virtual de um objecto libertado. Uma violação de acesso será iniciada para abortar a operação corrente.';
InterfaceErrorHeader = 'FastMM detectou uma tentativa de uso de uma interface de um objecto libertado. Uma violação de acesso será iniciada para abortar a operação corrente.';
BlockHeaderCorruptedNoHistoryMsg = ' Infelizmente o cabeçalho do bloco foi corrompido e o histórico não está disponível.';
FreedObjectClassMsg = #13#10#13#10'Classe do objecto libertado: ';
VirtualMethodName = #13#10#13#10'Método virtual: ';
VirtualMethodOffset = 'Deslocamento +';
VirtualMethodAddress = #13#10#13#10'Endereço do método virtual: ';
{Stack trace messages}
CurrentThreadIDMsg = #13#10#13#10'O ID da thread actual é 0x';
CurrentStackTraceMsg = ', e a análise da pilha interna (endereços de retorno) que conduziram a este erro é:';
ThreadIDPrevAllocMsg = #13#10#13#10'Este bloco foi préviamente criado pela thread 0x';
ThreadIDAtAllocMsg = #13#10#13#10'Este bloco foi criado pela thread 0x';
ThreadIDAtFreeMsg = #13#10#13#10'Este bloco foi préviamente libertado pela thread 0x';
ThreadIDAtObjectAllocMsg = #13#10#13#10'O objecto foi criado pela thread 0x';
ThreadIDAtObjectFreeMsg = #13#10#13#10'O objecto foi posteriormente libertado pela thread 0x';
StackTraceMsg = ', e a análise da pilha interna (endereços de retorno) nesse momento era:';
{Installation Messages}
AlreadyInstalledMsg = 'FastMM4 já se encontra instalado.';
AlreadyInstalledTitle = 'Já se encontra instalado.';
OtherMMInstalledMsg = 'FastMM4 não pôde ser instalado já que outro gestor '
+ 'de memória externo já foi instalado.'#13#10'Se você quer usar o FastMM4, '
+ 'garanta que a unit FastMM4.pas é a primeira na secção "uses"'
+ #13#10'do ficheiro .dpr do seu projecto.';
OtherMMInstalledTitle = 'Impossível instalar FastMM4 - Outro gestor de memória já se encontra instalado';
MemoryAllocatedMsg = 'O FastMM4 não pode ser instalado já que a memória já foi '
+ 'atribuida através do gestor de memória padrão.'#13#10'FastMM4.pas DEVE '
+ 'ser a primeira unit no arquivo .dpr do seu projecto, caso contrário a memória pode '
+ 'ser atribuida'#13#10'através do gestor de memória padrão antes que o FastMM '
+ 'obtenha o controle. '#13#10#13#10'Se você estiver usando um interceptador de excepções '
+ 'como MadExcept (ou qualquer outra ferramenta que modifica a ordem de inicialização da '
+ 'unit),'#13#10'vá para sua página de configuração e assegure-se que a unit '
+ 'FastMM4.pas ''é inicializada antes de qualquer outra unit.';
MemoryAllocatedTitle = 'Impossível instalar FastMM4 - A memória já foi atribuida';
{Leak checking messages}
LeakLogHeader = 'Um bloco de memória não foi libertado. O tamanho é: ';
LeakMessageHeader = 'Esta aplicação teve fugas de memória. ';
SmallLeakDetail = 'As fugas dos blocos pequenos são'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (excluindo as fugas esperadas, registadas por ponteiro)'
{$endif}
+ ':'#13#10;
LargeLeakDetail = 'O tamanho das fugas dos blocos médios e grandes é'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (excluindo as fugas esperadas registadas por ponteiro)'
{$endif}
+ ': ';
BytesMessage = ' bytes: ';
AnsiStringBlockMessage = 'AnsiString';
UnicodeStringBlockMessage = 'UnicodeString';
LeakMessageFooter = #13#10
{$ifndef HideMemoryLeakHintMessage}
+ #13#10'Nota: '
{$ifdef RequireIDEPresenceForLeakReporting}
+ 'Os testes de fugas de memória só serão efectuados se o Delphi estiver activo no mesmo computador. '
{$endif}
{$ifdef FullDebugMode}
{$ifdef LogMemoryLeakDetailToFile}
+ 'O detalhe da fuga de memória foi registado num ficheiro de texto na mesma pasta desta aplicação. '
{$else}
+ 'Active o DEFINE "LogMemoryLeakDetailToFile" para obter um ficheiro de registos contendo detalhes das fugas de memória. '
{$endif}
{$else}
+ 'Para obter um ficheiro de registo contendo detalhes das fugas de memória, active os DEFINES "FullDebugMode" e "LogMemoryLeakDetailToFile". '
{$endif}
+ 'Para activar a detecção de fugas de memória, active o DEFINE "EnableMemoryLeakReporting".'#13#10
{$endif}
+ #0;
LeakMessageTitle = 'Fuga de memória detectada';
{$ifdef UseOutputDebugString}
FastMMInstallMsg = 'FastMM foi instalado.';
FastMMInstallSharedMsg = 'Partilhando uma instância já existente do FastMM.';
FastMMUninstallMsg = 'FastMM foi removido.';
FastMMUninstallSharedMsg = 'Parando a partilha duma instância existente do FastMM.';
{$endif}
{$ifdef DetectMMOperationsAfterUninstall}
InvalidOperationTitle = 'Operação com o gestor de Memória após a sua remoção.';
InvalidGetMemMsg = 'FastMM detectou uma chamada a GetMem após a remoção do FastMM.';
InvalidFreeMemMsg = 'FastMM detectou uma chamada a FreeMem após a remoção do FastMM.';
InvalidReallocMemMsg = 'FastMM detectou uma chamada a ReallocMem após a remoção do FastMM.';
InvalidAllocMemMsg = 'FastMM detectou uma chamada a ReallocMem após a remoção do FastMM.';
{$endif}
implementation
end.

View File

@ -0,0 +1,143 @@
{
Fast Memory Manager: Messages
Romanian translation by Ionut Muntean
}
unit FastMM4Messages;
interface
{$Include FastMM4Options.inc}
const
{The name of the debug info support DLL}
FullDebugModeLibraryName32Bit = 'FastMM_FullDebugMode.dll';
FullDebugModeLibraryName64Bit = 'FastMM_FullDebugMode64.dll';
{Event log strings}
LogFileExtension = '_MemoryManager_EventLog.txt'#0;
CRLF = #13#10;
EventSeparator = '--------------------------------';
{Class name messages}
UnknownClassNameMsg = 'Necunoscut';
{Memory dump message}
MemoryDumpMsg = #13#10#13#10'Dump curent 256 bytes incepand cu adresa pointerului: ';
{Block Error Messages}
BlockScanLogHeader = 'Bloc memorie alocat de LogAllocatedBlocksToFile. Dimensiunea este de: ';
ErrorMsgHeader = 'FastMM a detectat o eroare in ';
GetMemMsg = 'GetMem';
FreeMemMsg = 'FreeMem';
ReallocMemMsg = 'ReallocMem';
BlockCheckMsg = 'scanarea blocurilor libere';
OperationMsg = ' operatie. ';
BlockHeaderCorruptedMsg = 'Inceputul (header) de bloc este corupt. ';
BlockFooterCorruptedMsg = 'Sfarsitul (footer) de bloc este corupt. ';
FreeModifiedErrorMsg = 'FastMM a detectat ca un bloc a fost modificat dupa eliberare. ';
FreeModifiedDetailMsg = #13#10#13#10'Modified byte offsets (and lengths): ';
DoubleFreeErrorMsg = 'A fost detectata o incercare de eliberare/realocare a unui bloc nealocat.';
WrongMMFreeErrorMsg = 'An attempt has been made to free/reallocate a block that was allocated through a different FastMM instance. Check your memory manager sharing settings.';
PreviousBlockSizeMsg = #13#10#13#10'Dimensiunea precedenta a blocului a fost de: ';
CurrentBlockSizeMsg = #13#10#13#10'Dimensiunea blocului este de: ';
PreviousObjectClassMsg = #13#10#13#10'Blocul de memorie a fost folosit inainte pentru un obiect de clasa: ';
CurrentObjectClassMsg = #13#10#13#10'Blocul de memorie este folosit pentru un obiect de clasa: ';
PreviousAllocationGroupMsg = #13#10#13#10'Grupul de alocare a fost: ';
PreviousAllocationNumberMsg = #13#10#13#10': Numarul de alocare a fost';
CurrentAllocationGroupMsg = #13#10#13#10'Grupul de alocare este: ';
CurrentAllocationNumberMsg = #13#10#13#10'Numarul de alocare este: ';
BlockErrorMsgTitle = 'A fost detectata o eroare de memorie';
VirtualMethodErrorHeader = 'FastMM a detectat o incercare de apel a unei proceduri virtuale dupa ce obiectul a fost eliberat. O exceptie de tip "Access violation" va fi alocata pentru a stopa operatia curenta.';
InterfaceErrorHeader = 'FastMM a detectat o incercare de utilizare a unei interfete a unui obiect deja eliberat. O exceptie de tip "Access violation" va fi alocata pentru a stopa operatia curenta.';
BlockHeaderCorruptedNoHistoryMsg = ' Din pacate, inceputul (headerul) de bloc este atat de corupt incat nici un istoric pentru acesta nu poate fi stabilit.';
FreedObjectClassMsg = #13#10#13#10'Clasa obiectului eliberat: ';
VirtualMethodName = #13#10#13#10'Metoda virtuala: ';
VirtualMethodOffset = 'Offset +';
VirtualMethodAddress = #13#10#13#10'Adresa metoda virtuala: ';
{Stack trace messages}
CurrentThreadIDMsg = #13#10#13#10'The current thread ID is 0x';
CurrentStackTraceMsg = ', and the stack trace (return addresses) leading to this error is:';
ThreadIDPrevAllocMsg = #13#10#13#10'This block was previously allocated by thread 0x';
ThreadIDAtAllocMsg = #13#10#13#10'This block was allocated by thread 0x';
ThreadIDAtFreeMsg = #13#10#13#10'The block was previously freed by thread 0x';
ThreadIDAtObjectAllocMsg = #13#10#13#10'The object was allocated by thread 0x';
ThreadIDAtObjectFreeMsg = #13#10#13#10'The object was subsequently freed by thread 0x';
StackTraceMsg = ', and the stack trace (return addresses) at the time was:';
{Installation Messages}
AlreadyInstalledMsg = 'FastMM4 este deja instalat.';
AlreadyInstalledTitle = 'Deja instalat.';
OtherMMInstalledMsg = 'FastMM4 nu poate fi instalat din cauza unui alt Memory Manager '
+ 'care este deja instalat in contextul curent.'#13#10'Daca doriti utilizarea FastMM4, '
+ 'asigurati-va ca FastMM4.pas este primul unit inclus in clauza "uses"'
+ 'din fisierul .dpr a proiectului Dvs..';
OtherMMInstalledTitle = 'Nu pot instala FastMM4 - Un alt Memory Manager este deja instalat.';
//******************************************************************************************************
MemoryAllocatedMsg =
'FastMM4 nu poate fi instalat din cauza faptului ca memorie a fost deja alocata print MM implicit.'
+ #13#10'FastMM4.pas TREBUIE sa fie primul unit in fisierul .dpr al proiectului Dvs.'
+ #13#10#13#10'Daca utilizati un program de control al exceptiilor, cum ar fi '
+ 'MadExcept (ori orice alt instrument care modifica ordinea initializarii uniturilor'
+ 'FastMM4.pas ny other unit.';
//******************************************************************************************************
MemoryAllocatedTitle = 'Nu pot instala FastMM4 - memorie deja alocata prin alte cai.';
{Leak checking messages}
LeakLogHeader = 'A aparut o pierdere de memorie alocata. Adresa este: ';
LeakMessageHeader = 'Aceasta aplicatie pierde memorie. ';
SmallLeakDetail = 'Pierderile de memorie in blocurile mici sunt:';
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (excluzand pierderile normale inregistrate de pointeri)'
{$endif}
+ ':'#13#10;
LargeLeakDetail = 'Dimensiunile blocurilor medii si mari sunt'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (excluzand pierderile normale inregistrate de pointeri)'
{$endif}
+ ': ';
BytesMessage = ' bytes: ';
AnsiStringBlockMessage = 'AnsiString';
UnicodeStringBlockMessage = 'UnicodeString';
LeakMessageFooter = #13#10
{$ifndef HideMemoryLeakHintMessage}
+ #13#10'Nota: '
{$ifdef RequireIDEPresenceForLeakReporting}
+ 'Testele de pierdere de memorie alocata sunt facute numai daca Delphi ruleaza pe acelasi computer.'
{$endif}
{$ifdef FullDebugMode}
{$ifdef LogMemoryLeakDetailToFile}
+ 'Detaliile sunt inregistrate intr-un fisier text in acelasi director cu aplicatia.'
{$else}
+ 'Utilizati optiunea "LogMemoryLeakDetailsToFile" pentru a obtine inregistrarile despre pierderile de memorie alocata.'
{$endif}
{$else}
+ 'Pentru a obtine inregistrarile continand detalii despre pierderile de memorie, utilizati definirile conditionale "FullDebugMode" si "LogMemoryLeakDetailToFile"';
{$endif}
+ 'Pentru a dezactiva testele de meorie, nu folositi definitia conditionala "LogMemoryLeakDetailToFile"';
{$endif}
+ #0;
LeakMessageTitle = 'Pierderi de memorie alocata';
{$ifdef UseOutputDebugString}
FastMMInstallMsg = 'FastMM a fost instalat.';
FastMMInstallSharedMsg = 'Start al impartirii accesului la o instanta a FastMM.';
FastMMUninstallMsg = 'FastMM a fost dezinstalat.';
FastMMUninstallSharedMsg = 'Stop al impartirii accesului la o instanta a FastMM.';
{$endif}
{$ifdef DetectMMOperationsAfterUninstall}
InvalidOperationTitle = 'Operatie Memory manager DUPA dezinstalater.';
InvalidGetMemMsg = 'FastMM a detectat un apel GetMem dupa ce FastMM a fost dezinstalat.';
InvalidFreeMemMsg = 'FastMM a detectat un apel FreeMem dupa ce FastMM a fost dezinstalat.';
InvalidReallocMemMsg = 'FastMM a detectat un apel ReAllocMem dupa ce FastMM a fost dezinstalat.';
InvalidAllocMemMsg = 'FastMM a detectat un apel GetMem dupa ce AllocMem a fost dezinstalat.';
{$endif}
implementation
end.

View File

@ -0,0 +1,137 @@
{
Fast Memory Manager: Messages
Russian translation by Paul Ishenin.
2006-07-18
Some minor updates by Andrey V. Shtukaturov.
}
unit FastMM4Messages;
interface
{$Include FastMM4Options.inc}
const
{The name of the debug info support DLL}
FullDebugModeLibraryName32Bit = 'FastMM_FullDebugMode.dll';
FullDebugModeLibraryName64Bit = 'FastMM_FullDebugMode64.dll';
{Event log strings}
LogFileExtension = '_MemoryManager_EventLog.txt'#0;
CRLF = #13#10;
EventSeparator = '--------------------------------';
{Class name messages}
UnknownClassNameMsg = 'Unknown';
{Memory dump message}
MemoryDumpMsg = #13#10#13#10'Текущий дамп памяти из 256 байт начиная с адреса ';
{Block Error Messages}
BlockScanLogHeader = 'Выделенный блок запротоколирован процедурой LogAllocatedBlocksToFile. Размер: ';
ErrorMsgHeader = 'FastMM обнаружил ошибку во время ';
GetMemMsg = 'GetMem';
FreeMemMsg = 'FreeMem';
ReallocMemMsg = 'ReallocMem';
BlockCheckMsg = 'сканирования освобожденного блока';
OperationMsg = ' операция. ';
BlockHeaderCorruptedMsg = 'Заголовок блока поврежден. ';
BlockFooterCorruptedMsg = 'Нижняя часть блока повреждена. ';
FreeModifiedErrorMsg = 'FastMM обнаружил что блок был модифицирован после его освобождения. ';
FreeModifiedDetailMsg = #13#10#13#10'Modified byte offsets (and lengths): ';
DoubleFreeErrorMsg = 'Была предпринята попытка освободить/перевыделить не выделенный блок.';
WrongMMFreeErrorMsg = 'An attempt has been made to free/reallocate a block that was allocated through a different FastMM instance. Check your memory manager sharing settings.';
PreviousBlockSizeMsg = #13#10#13#10'Размер предыдущего блока был: ';
CurrentBlockSizeMsg = #13#10#13#10'Размер блока: ';
PreviousObjectClassMsg = #13#10#13#10'Блок был ранее использован для объекта класса: ';
CurrentObjectClassMsg = #13#10#13#10'Блок в настоящее время используется для объекта класса: ';
PreviousAllocationGroupMsg = #13#10#13#10'Выделенная группа была: ';
PreviousAllocationNumberMsg = #13#10#13#10'Выделенный номер был: ';
CurrentAllocationGroupMsg = #13#10#13#10'Выделенная группа стала: ';
CurrentAllocationNumberMsg = #13#10#13#10'Выделенный номер стал: ';
BlockErrorMsgTitle = 'Обнаружена ошибка памяти.';
VirtualMethodErrorHeader = 'FastMM обнаружил попытку вызвать виртуальный метод освобожденного объекта. Сейчас будет вызвано нарушение доступа для прерывания текущей операции.';
InterfaceErrorHeader = 'FastMM обнаружил попытку использовать интерфейс освобожденного объекта. Сейчас будет вызвано нарушение доступа для прерывания текущей операции.';
BlockHeaderCorruptedNoHistoryMsg = ' К сожалению заголовок блока поврежден и история не доступна.';
FreedObjectClassMsg = #13#10#13#10'Класс освобожденного объекта: ';
VirtualMethodName = #13#10#13#10'Виртуальный метод: ';
VirtualMethodOffset = 'Смещение +';
VirtualMethodAddress = #13#10#13#10'Адрес виртуального метода: ';
{Stack trace messages}
CurrentThreadIDMsg = #13#10#13#10'The current thread ID is 0x';
CurrentStackTraceMsg = ', and the stack trace (return addresses) leading to this error is:';
ThreadIDPrevAllocMsg = #13#10#13#10'This block was previously allocated by thread 0x';
ThreadIDAtAllocMsg = #13#10#13#10'This block was allocated by thread 0x';
ThreadIDAtFreeMsg = #13#10#13#10'The block was previously freed by thread 0x';
ThreadIDAtObjectAllocMsg = #13#10#13#10'The object was allocated by thread 0x';
ThreadIDAtObjectFreeMsg = #13#10#13#10'The object was subsequently freed by thread 0x';
StackTraceMsg = ', and the stack trace (return addresses) at the time was:';
{Installation Messages}
AlreadyInstalledMsg = 'FastMM4 уже установлен.';
AlreadyInstalledTitle = 'Уже установлен.';
OtherMMInstalledMsg = 'FastMM4 не может быть установлен при установленном другом менеджере памяти.'
+ #13#10'Если вы желаете использовать FastMM4, пожалуйста убедитесь что FastMM4.pas является самым первым модулем в'
+ #13#10'секции "uses" вашего ''s .dpr файла проекта.';
OtherMMInstalledTitle = 'Невозможно установить FastMM4 - уже установлен другой менеджер памяти.';
MemoryAllocatedMsg = 'FastMM4 невозможно установить когда память уже была '
+ 'выделена стандартным менеджером памяти.'#13#10'FastMM4.pas ДОЛЖЕН '
+ 'быть первым модулем в вашем файле .dpr файле проекта, иначе память может '
+ 'быть выделена'#13#10'через стандартный менеджер памяти перед тем как FastMM4 '
+ 'получит контроль. '#13#10#13#10'Если вы используете обработчик исключений '
+ 'типа MadExcept (или любой другой инструмент модифицирующий порядок инициализации '
+ 'модулей),'#13#10'то перейдите в страницу его конфигурации и убедитесь, что '
+ 'FastMM4.pas модуль инициализируется перед любым другим модулем.';
MemoryAllocatedTitle = 'Не возможно установить FastMM4 - Память уже была выделена';
{Leak checking messages}
LeakLogHeader = 'Блок памяти был выделен и не освобожден. Размер: ';
LeakMessageHeader = 'В этом приложении происходят утечки памяти. ';
SmallLeakDetail = 'Утечки блоков маленького размера'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (исключая ожидаемые утечки зарегистрированные по указателю)'
{$endif}
+ ':'#13#10;
LargeLeakDetail = 'Размеры утечек блоков среднего размера'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (исключая ожидаемые утечки зарегистрированные по указателю)'
{$endif}
+ ': ';
BytesMessage = ' байт: ';
AnsiStringBlockMessage = 'AnsiString';
UnicodeStringBlockMessage = 'UnicodeString';
LeakMessageFooter = #13#10
{$ifndef HideMemoryLeakHintMessage}
+ #13#10'Note: '
{$ifdef RequireIDEPresenceForLeakReporting}
+ 'Эта проверка утечки памяти производится только в случае одновременной работы Delphi на том же компьютере. '
{$endif}
{$ifdef FullDebugMode}
{$ifdef LogMemoryLeakDetailToFile}
+ 'Детальная информация об утечках памяти журналируется в текстовый файл в том же каталоге, что и приложение. '
{$else}
+ 'Включите "LogMemoryLeakDetailToFile" для получения журнала, содержащего детальную информацию об утечках памяти. '
{$endif}
{$else}
+ 'Для получения журнала, содержащего детальную информацию об утечках памяти, включите условия компиляции "FullDebugMode" и "LogMemoryLeakDetailToFile". '
{$endif}
+ 'Для выключения этих проверок утечки памяти, уберите определение "EnableMemoryLeakReporting".'#13#10
{$endif}
+ #0;
LeakMessageTitle = 'Обнаружена утечка памяти';
{$ifdef UseOutputDebugString}
FastMMInstallMsg = 'FastMM has been installed.';
FastMMInstallSharedMsg = 'Sharing an existing instance of FastMM.';
FastMMUninstallMsg = 'FastMM has been uninstalled.';
FastMMUninstallSharedMsg = 'Stopped sharing an existing instance of FastMM.';
{$endif}
{$ifdef DetectMMOperationsAfterUninstall}
InvalidOperationTitle = 'MM Operation after uninstall.';
InvalidGetMemMsg = 'FastMM has detected a GetMem call after FastMM was uninstalled.';
InvalidFreeMemMsg = 'FastMM has detected a FreeMem call after FastMM was uninstalled.';
InvalidReallocMemMsg = 'FastMM has detected a ReallocMem call after FastMM was uninstalled.';
InvalidAllocMemMsg = 'FastMM has detected a ReallocMem call after FastMM was uninstalled.';
{$endif}
implementation
end.

View File

@ -0,0 +1,139 @@
{
Fast Memory Manager: Messages
Spanish translation by JRG (TheDelphiGuy@gmail.com).
Change Log:
15 Feb 2006: Updated by Marcelo Montenegro.
}
unit FastMM4Messages;
interface
{$Include FastMM4Options.inc}
const
{The name of the debug info support DLL}
FullDebugModeLibraryName32Bit = 'FastMM_FullDebugMode.dll';
FullDebugModeLibraryName64Bit = 'FastMM_FullDebugMode64.dll';
{Event log strings}
LogFileExtension = '_ManipuladorMemoria_Reporte.txt'#0;
CRLF = #13#10;
EventSeparator = '--------------------------------';
{Class name messages}
UnknownClassNameMsg = 'Desconocida';
{Memory dump message}
MemoryDumpMsg = #13#10#13#10'Vaciado de memoria actual de 256 bytes en la dirección ';
{Block Error Messages}
BlockScanLogHeader = 'El bloque reservado fue registrado por LogAllocatedBlocksToFile. El tamaño es: ';
ErrorMsgHeader = 'FastMM ha detectado un error durante una operación ';
GetMemMsg = 'GetMem';
FreeMemMsg = 'FreeMem';
ReallocMemMsg = 'ReallocMem';
BlockCheckMsg = 'de búsqueda de bloque libre';
OperationMsg = '. ';
BlockHeaderCorruptedMsg = 'El encabezamiento de bloque ha sido corrompido. ';
BlockFooterCorruptedMsg = 'La terminación de bloque ha sido corrompida. ';
FreeModifiedErrorMsg = 'FastMM detectó que un bloque ha sido modificado luego de liberarse. ';
FreeModifiedDetailMsg = #13#10#13#10'Modified byte offsets (and lengths): ';
DoubleFreeErrorMsg = 'Se realizó un intento de liberar/reasignar un bloque no reservado.';
WrongMMFreeErrorMsg = 'Se realizó un intento de liberar/reasignar un bloque reservado a través de una instancia distinta de FastMM. Chequee las opciones de uso compartido de su manipulador de memoria.';
PreviousBlockSizeMsg = #13#10#13#10'El tamaño anterior del bloque era: ';
CurrentBlockSizeMsg = #13#10#13#10'El tamaño del bloque es: ';
PreviousObjectClassMsg = #13#10#13#10'El bloque estuvo anteriormente reservado para un objeto de clase: ';
CurrentObjectClassMsg = #13#10#13#10'El bloque está reservado para un objeto de clase: ';
PreviousAllocationGroupMsg = #13#10#13#10'El grupo de la reservación fue: ';
PreviousAllocationNumberMsg = #13#10#13#10'El número de la reservación fue: ';
CurrentAllocationGroupMsg = #13#10#13#10'El grupo de la reservación es: ';
CurrentAllocationNumberMsg = #13#10#13#10'El número de la reservación es: ';
BlockErrorMsgTitle = 'Detectado error de memoria';
VirtualMethodErrorHeader =
'FastMM ha detectado un intento de ejecutar un método virtual de un objeto liberado. Una violación de acceso se generará ahora para abortar la operación.';
InterfaceErrorHeader =
'FastMM ha detectado un intento de utlización de una interfaz de un objeto liberado. Una violación de acceso se generará ahora para abortar la operación.';
BlockHeaderCorruptedNoHistoryMsg =
' Desafortunadamente el encabezamiento de bloque ha sido corrompido, así que no hay historia disponible.';
FreedObjectClassMsg = #13#10#13#10'Clase del objeto liberado: ';
VirtualMethodName = #13#10#13#10'Método virtual: ';
VirtualMethodOffset = 'Desplazamiento +';
VirtualMethodAddress = #13#10#13#10'Dirección del método virtual: ';
{Stack trace messages}
CurrentThreadIDMsg = #13#10#13#10'El ID del hilo actual es 0x';
CurrentStackTraceMsg = ', y el vaciado del stack (direcciones de retorno) que conduce a este error es:';
ThreadIDPrevAllocMsg = #13#10#13#10'Este bloque fue previamente reservado por el hilo 0x';
ThreadIDAtAllocMsg = #13#10#13#10'Este bloque fue reservado por el hilo 0x';
ThreadIDAtFreeMsg = #13#10#13#10'Este bloque fue previamente liberado por el hilo 0x';
ThreadIDAtObjectAllocMsg = #13#10#13#10'El objeto fue reservado por el hilo 0x';
ThreadIDAtObjectFreeMsg = #13#10#13#10'El objeto fue posteriormente liberado por el hilo 0x';
StackTraceMsg = ', y el vaciado del stack (direcciones de retorno) en ese momento es:';
{Installation Messages}
AlreadyInstalledMsg = 'FastMM4 ya ha sido instalado.';
AlreadyInstalledTitle = 'Ya instalado.';
OtherMMInstalledMsg =
'FastMM4 no puede instalarse ya que otro manipulador de memoria alternativo se ha instalado anteriormente.'#13#10 +
'Si desea utilizar FastMM4, por favor asegúrese de que FastMM4.pas es la primera unit en la sección "uses"'#13#10 +
'del .DPR de su proyecto.';
OtherMMInstalledTitle = 'FastMM4 no se puede instalar - Otro manipulador de memoria instalado';
MemoryAllocatedMsg =
'FastMM4 no puede instalarse ya que se ha reservado memoria mediante el manipulador de memoria estándar.'#13#10 +
'FastMM4.pas TIENE que ser la primera unit en el fichero .DPR de su proyecto, de otra manera podría reservarse memoria'#13#10 +
'mediante el manipulador de memoria estándar antes de que FastMM4 pueda ganar el control. '#13#10#13#10 +
'Si está utilizando un interceptor de excepciones como MadExcept (o cualquier otra herramienta que modifique el orden de inicialización de las units),'#13#10 + //Fixed by MFM
'vaya a su página de configuración y asegúrese de que FastMM4.pas es inicializada antes que cualquier otra unit.';
MemoryAllocatedTitle = 'FastMM4 no se puede instalar - Ya se ha reservado memoria';
{Leak checking messages}
LeakLogHeader = 'Ha habido una fuga de memoria. El tamaño del bloque es: ';
LeakMessageHeader = 'Esta aplicación ha tenido fugas de memoria. ';
SmallLeakDetail = 'Las fugas de memoria en los bloques pequeños son'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (excluyendo las fugas esperadas registradas por apuntador)'
{$endif}
+ ':'#13#10;
LargeLeakDetail = 'Las fugas de memoria de bloques medianos y grandes son'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (excluyendo las fugas esperadas registrados por apuntador)'
{$endif}
+ ': ';
BytesMessage = ' bytes: ';
AnsiStringBlockMessage = 'AnsiString';
UnicodeStringBlockMessage = 'UnicodeString';
LeakMessageFooter = #13#10
{$ifndef HideMemoryLeakHintMessage}
+ #13#10'Nota: '
{$ifdef RequireIDEPresenceForLeakReporting}
+ 'Este chequeo de escape de memoria sólo se realiza si Delphi está ejecutándose en el mismo ordenador. '
{$endif}
{$ifdef FullDebugMode}
{$ifdef LogMemoryLeakDetailToFile}
+ 'Los detalles del escape de memoria se salvan a un fichero texto en la misma carpeta donde reside esta aplicación. '
{$else}
+ 'Habilite "LogMemoryLeakDetailToFile" para obtener un *log* con los detalles de los escapes de memoria. '
{$endif}
{$else}
+ 'Para obtener un *log* con los detalles de los escapes de memoria, abilite las definiciones condicionales "FullDebugMode" y "LogMemoryLeakDetailToFile". '
{$endif}
+ 'Para deshabilitar este chequeo de fugas de memoria, indefina "EnableMemoryLeakReporting".'#13#10
{$endif}
+ #0;
LeakMessageTitle = 'Detectada fuga de memoria';
{$ifdef UseOutputDebugString}
FastMMInstallMsg = 'FastMM ha sido instalado.';
FastMMInstallSharedMsg = 'Compartiendo una instancia existente de FastMM.';
FastMMUninstallMsg = 'FastMM ha sido desinstalado.';
FastMMUninstallSharedMsg = 'Cesando de compartir una instancia existente de FastMM.';
{$endif}
{$ifdef DetectMMOperationsAfterUninstall}
InvalidOperationTitle = 'Operación en el MM luego de desinstalarlo.';
InvalidGetMemMsg = 'FastMM ha detectado una llamada a GetMem luego de desinstalar FastMM.';
InvalidFreeMemMsg = 'FastMM ha detectado una llamada a FreeMem luego de desinstalar FastMM.';
InvalidReallocMemMsg = 'FastMM ha detectado una llamada a ReallocMem luego de desinstalar FastMM.';
InvalidAllocMemMsg = 'FastMM ha detectado una llamada a ReallocMem luego de desinstalar FastMM.';
{$endif}
implementation
end.

View File

@ -0,0 +1,135 @@
{
Fast Memory Manager: Messages
2006-07-18
Ukrainian translation by Andrey V. Shtukaturov.
}
unit FastMM4Messages;
interface
{$Include FastMM4Options.inc}
const
{The name of the debug info support DLL}
FullDebugModeLibraryName32Bit = 'FastMM_FullDebugMode.dll';
FullDebugModeLibraryName64Bit = 'FastMM_FullDebugMode64.dll';
{Event log strings}
LogFileExtension = '_MemoryManager_EventLog.txt'#0;
CRLF = #13#10;
EventSeparator = '--------------------------------';
{Class name messages}
UnknownClassNameMsg = 'Unknown';
{Memory dump message}
MemoryDumpMsg = #13#10#13#10'Ïîòî÷íèé äàìï ïàì’’ÿò³ ç 256 áàéò ïî÷èíàþ÷è ç àäðåñè ';
{Block Error Messages}
BlockScanLogHeader = ' Âèä³ëåíèé áëîê çàïðîòîêîëüîâàíî ïðîöåäóðîþ LogAllocatedBlocksToFile. Ðîçì³ð: ';
ErrorMsgHeader = 'FastMM âèÿâèâ ïîìèëêó ï³ä ÷àñ ';
GetMemMsg = 'GetMem';
FreeMemMsg = 'FreeMem';
ReallocMemMsg = 'ReallocMem';
BlockCheckMsg = 'ñêàíóâàííÿ çâ³ëüíåíîãî áëîêó ';
OperationMsg = ' îïåðàö³ÿ. ';
BlockHeaderCorruptedMsg = ' Çàãîëîâîê áëîêó óøêîäæåíèé. ';
BlockFooterCorruptedMsg = ' Íèæíÿ ÷àñòèíà áëîêó óøêîäæåíà. ';
FreeModifiedErrorMsg = 'FastMM âèÿâèâ ùî áëîê áóëî ìîäèô³êîâàíî ï³ñëÿ éîãî çâ³ëüíåííÿ. ';
FreeModifiedDetailMsg = #13#10#13#10'Modified byte offsets (and lengths): ';
DoubleFreeErrorMsg = ' Áóëà ñïðîáà çâ³ëüíèòè/ïåðåâèä³ëèòè íå âèä³ëåíèé áëîê.';
WrongMMFreeErrorMsg = 'An attempt has been made to free/reallocate a block that was allocated through a different FastMM instance. Check your memory manager sharing settings.';
PreviousBlockSizeMsg = #13#10#13#10'Ðîçì³ð ïîïåðåäíüîãî áëîêó áóâ: ';
CurrentBlockSizeMsg = #13#10#13#10'Ðîçì³ð áëîêó: ';
PreviousObjectClassMsg = #13#10#13#10'Áëîê áóâ ðàí³øå âèêîðèñòàíèé äëÿ îá’’ºêòà êëàñó: ';
CurrentObjectClassMsg = #13#10#13#10'Áëîê íà äàíèé ìîìåíò âèêîðèñòîâóºòüñÿ äëÿ îá’’ºêòà êëàñó: ';
PreviousAllocationGroupMsg = #13#10#13#10'Âèä³ëåíà ãðóïà áóëà: ';
PreviousAllocationNumberMsg = #13#10#13#10'Âèä³ëåíèé íîìåð áóâ: ';
CurrentAllocationGroupMsg = #13#10#13#10'Âèä³ëåíà ãðóïà ñòàëà: ';
CurrentAllocationNumberMsg = #13#10#13#10'Âèä³ëåíèé íîìåð ñòàâ: ';
BlockErrorMsgTitle = 'Âèÿâëåíî ïîìèëêó ïàì’’ÿò³.';
VirtualMethodErrorHeader = 'FastMM âèÿâèâ ñïðîáó âèêëèêàòè â³ðòóàëüíèé ìåòîä çâ³ëüíåíîãî îá’’ºêòó. Çàðàç áóäå âèêëèêàíå ïîðóøåííÿ äîñòóïó äëÿ ïåðåðèâàííÿ ïîòî÷íî¿ îïåðàö³¿.';
InterfaceErrorHeader = 'FastMM âèÿâèâ ñïðîáó âèêîðèñòàòè ³íòåðôåéñ çâ³ëüíåíîãî îá’’ºêòó. Çàðàç áóäå âèêëèêàíå ïîðóøåííÿ äîñòóïó äëÿ ïåðåðèâàííÿ ïîòî÷íî¿ îïåðàö³¿.';
BlockHeaderCorruptedNoHistoryMsg = ' Íà æàëü çàãîëîâîê áëîêó óøêîäæåíèé ³ ³ñòîð³ÿ íåäîñòóïíà.';
FreedObjectClassMsg = #13#10#13#10'Êëàñ çâ³ëüíåíîãî îá’’ºêòó: ';
VirtualMethodName = #13#10#13#10'³ðòóàëüíèé ìåòîä: ';
VirtualMethodOffset = 'Çñóâ +';
VirtualMethodAddress = #13#10#13#10'Àäðåñà â³ðòóàëüíîãî ìåòîäó: ';
{Stack trace messages}
CurrentThreadIDMsg = #13#10#13#10'The current thread ID is 0x';
CurrentStackTraceMsg = ', and the stack trace (return addresses) leading to this error is:';
ThreadIDPrevAllocMsg = #13#10#13#10'This block was previously allocated by thread 0x';
ThreadIDAtAllocMsg = #13#10#13#10'This block was allocated by thread 0x';
ThreadIDAtFreeMsg = #13#10#13#10'The block was previously freed by thread 0x';
ThreadIDAtObjectAllocMsg = #13#10#13#10'The object was allocated by thread 0x';
ThreadIDAtObjectFreeMsg = #13#10#13#10'The object was subsequently freed by thread 0x';
StackTraceMsg = ', and the stack trace (return addresses) at the time was:';
{Installation Messages}
AlreadyInstalledMsg = 'FastMM4 âæå âñòàíîâëåíî.';
AlreadyInstalledTitle = 'Âæå âñòàíîâëåíî.';
OtherMMInstalledMsg = 'FastMM4 íå ìîæå áóòè âñòàíîâëåíî ÿêùî âæå âñòàíîâëåíî ³íøèé ìåíåäæåð ïàì’’ÿò³.'
+ #13#10'ßêùî âè áàæàºòå âèêîðèñòîâóâàòè FastMM4, áóäü-ëàñêà ïåðåêîíàéòåñü ùî FastMM4.pas º ñàìèì ïåðøèì ìîäóëåì â'
+ #13#10'ñåêö³¿ "uses" âàøîãî .dpr ôàéëó ïðîåêòó.';
OtherMMInstalledTitle = 'Íåìîæëèâî âñòàíîâèòè FastMM4 - âæå âñòàíîâëåíî ³íøèé ìåíåäæåð ïàì’’ÿò³.';
MemoryAllocatedMsg = 'FastMM4 íåìîæëèâî âñòàíîâèòè êîëè ïàì’’ÿòü âæå áóëà '
+ 'âèä³ëåíà ñòàíäàðòíèì ìåíåäæåðîì ïàì’’ÿòè.'#13#10'FastMM4.pas ÏÎÂÈÍÅÍ '
+ 'áóòè ïåðøèì ìîäóëåì ó âàøîìó ôàéë³ .dpr ôàéë³ ïðîåêòó, ³íàêøå ïàì’’ÿòü ìîæå '
+ 'áóòè âèä³ëåíà'#13#10'÷åðåç ñòàíäàðòíèé ìåíåäæåð ïàì’’ÿò³ ïåðåä òèì ÿê FastMM4 '
+ 'îòðèìຠêîíòðîëü. '#13#10#13#10'ßêùî âè âèêîðèñòîâóºòå îáðîáíèê îñîáëèâèõ ñèòóàö³é, '
+ 'íàïðèêëàä MadExcept (àáî áóäü-ÿêèé ³íøèé ³íñòðóìåíò ùî ìîäèô³êóº ïîðÿäîê ³í³ö³àë³çàö³¿ '
+ 'ìîäóëåé),'#13#10'òîä³ ïåðåéä³òü íà ñòîð³íêó éîãî êîíô³ãóðàö³¿ òà ïåðåêîíàéòåñÿ, ùî '
+ 'FastMM4.pas ìîäóëü ³í³ö³àë³çóºòüñÿ ïåðåä áóäü-ÿêèì ³íøèì ìîäóëåì.';
MemoryAllocatedTitle = 'Íåìîæëèâî âñòàíîâèòè FastMM4 - Ïàì’’ÿòü âæå áóëà âèä³ëåíà';
{Leak checking messages}
LeakLogHeader = 'Áëîê ïàì’’ÿò³ áóâ âèä³ëåíèé òà íå çâ³ëüíåíèé. Ðîçì³ð: ';
LeakMessageHeader = ' öüîìó äîäàòêó â³äáóâàþòüñÿ âòðàòè ïàì’’ÿò³.';
SmallLeakDetail = 'Âòðàòè áëîê³â ïàì''ÿò³ ìàëåíüêîãî ðîçì³ðó'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (çà âèíÿòêîì î÷³êóâàíèõ âòðàò ïàì''ÿò³ çàðåºñòðîâàíèõ ïî âêàç³âíèêó)'
{$endif}
+ ':'#13#10;
LargeLeakDetail = 'Ðîçì³ðè âòðàò áëîê³â ïàì''ÿò³ ñåðåäíüîãî ðîçì³ðó'
{$ifdef HideExpectedLeaksRegisteredByPointer}
+ ' (çà âèíÿòêîì î÷³êóâàíèõ âòðàò ïàì''ÿò³ çàðåºñòðîâàíèõ ïî âêàç³âíèêó)'
{$endif}
+ ': ';
BytesMessage = ' áàéò: ';
AnsiStringBlockMessage = 'AnsiString';
UnicodeStringBlockMessage = 'UnicodeString';
LeakMessageFooter = #13#10
{$ifndef HideMemoryLeakHintMessage}
+ #13#10'Note: '
{$ifdef RequireIDEPresenceForLeakReporting}
+ 'Öÿ ïåðåâ³ðêà âòðàòè ïàì’’ÿò³ âèêîíóºòüñÿ ëèøå ó âèïàäêó îäíî÷àñíî¿ ðîáîòè Delphi íà òîìó æ êîìï’’þòåð³. '
{$endif}
{$ifdef FullDebugMode}
{$ifdef LogMemoryLeakDetailToFile}
+ 'Äåòàëüíà ³íôîðìàö³ÿ ïðî âòðàòó è ïàì’’ÿò³ æóðíàëþºòüñÿ ó òåêñòîâèé ôàéë â òîìó æ êàòàëîç³, ùî é äîäàòîê. '
{$else}
+ 'Âêëþ÷³òü "LogMemoryLeakDetailToFile" äëÿ òîãî ùîá îòðèìàòè æóðíàë, ùî ì³ñòèòü äåòàëüíó ³íôîðìàö³þ ïðî âòðàòó ïàì’’ÿò³. '
{$endif}
{$else}
+ 'Äëÿ òîãî ùîá îòðèìàòè æóðíàë, ùî ì³ñòèòü äåòàëüíó ³íôîðìàö³þ ïðî âòðàòó ïàì’’ÿò³, âêëþ÷³òü óìîâè êîìï³ëÿö³¿ "FullDebugMode" òà "LogMemoryLeakDetailToFile". '
{$endif}
+ 'Äëÿ òîãî ùîá âèêëþ÷èòè ö³ ïåðåâ³ðêè âòðàò ïàì’’ÿò³, íåîáõ³äíî âèäàëèòè âèçíà÷åííÿ "EnableMemoryLeakReporting".'#13#10
{$endif}
+ #0;
LeakMessageTitle = 'Âèÿâëåíî âòðàòó ïàì’’ÿò³';
{$ifdef UseOutputDebugString}
FastMMInstallMsg = 'FastMM has been installed.';
FastMMInstallSharedMsg = 'Sharing an existing instance of FastMM.';
FastMMUninstallMsg = 'FastMM has been uninstalled.';
FastMMUninstallSharedMsg = 'Stopped sharing an existing instance of FastMM.';
{$endif}
{$ifdef DetectMMOperationsAfterUninstall}
InvalidOperationTitle = 'MM Operation after uninstall.';
InvalidGetMemMsg = 'FastMM has detected a GetMem call after FastMM was uninstalled.';
InvalidFreeMemMsg = 'FastMM has detected a FreeMem call after FastMM was uninstalled.';
InvalidReallocMemMsg = 'FastMM has detected a ReallocMem call after FastMM was uninstalled.';
InvalidAllocMemMsg = 'FastMM has detected a ReallocMem call after FastMM was uninstalled.';
{$endif}
implementation
end.

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 KiB

Some files were not shown because too many files have changed in this diff Show More