Compare commits
12 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
9a1d5fafcf | |
![]() |
9d6a2d6e20 | |
![]() |
16199e4908 | |
![]() |
83e41efb88 | |
![]() |
fde22c2c77 | |
![]() |
30ce6f00fc | |
![]() |
7e8bbfcd86 | |
![]() |
3b0bf1fe47 | |
![]() |
6fbb1865e8 | |
![]() |
50c7c248da | |
![]() |
552a733296 | |
![]() |
722279aad5 |
|
@ -0,0 +1,110 @@
|
|||
unit InitCode;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Utils, LibImport,
|
||||
WinAPI.Windows,
|
||||
System.SysUtils, System.Classes, System.Types, System.StrUtils;
|
||||
|
||||
const
|
||||
PLUGIN_DATABASE = 0;
|
||||
PLUGIN_CONFIG = 1;
|
||||
PLUGIN_LIBRARY = 2;
|
||||
PluginsParam = '-bd';
|
||||
|
||||
type
|
||||
PUIFuncs = ^TUIFuncs;
|
||||
|
||||
TUIFuncs = record
|
||||
IsZlibLoaded: Boolean;
|
||||
IsReflateLoaded: Boolean;
|
||||
IsPreflateLoaded: Boolean;
|
||||
IsLZ4Loaded: Boolean;
|
||||
IsLZOLoaded: Boolean;
|
||||
IsZSTDLoaded: Boolean;
|
||||
IsOodleLoaded: Boolean;
|
||||
IsFLACLoaded: Boolean;
|
||||
IsBrunsliLoaded: Boolean;
|
||||
IsPackJPGLoaded: Boolean;
|
||||
IsJoJpegLoaded: Boolean;
|
||||
IsXDeltaLoaded: Boolean;
|
||||
IsLZMALoaded: Boolean;
|
||||
IsSrepAvailable: Boolean;
|
||||
end;
|
||||
|
||||
var
|
||||
DEBUG: Boolean = False;
|
||||
UILib: TLibImport;
|
||||
PluginsPath: String = '';
|
||||
XTLUI1: procedure;
|
||||
XTLUI2: function(Funcs: PUIFuncs; var Params: TArray<String>;
|
||||
out LibType: Integer; out LibPath: String): Boolean;
|
||||
XTLAddPlugin: procedure(S: String; I: Integer);
|
||||
XTLAddCodec: procedure(S: String);
|
||||
UIDLLLoaded: Boolean = False;
|
||||
|
||||
implementation
|
||||
|
||||
procedure Init;
|
||||
begin
|
||||
if Win32MajorVersion < 6 then
|
||||
exit;
|
||||
UILib := TLibImport.Create;
|
||||
UILib.LoadLib(ChangeFileExt(Utils.GetModuleName, 'ui.dll'));
|
||||
if UILib.Loaded then
|
||||
begin
|
||||
@XTLUI1 := UILib.GetProcAddr('XTLUI1');
|
||||
@XTLUI2 := UILib.GetProcAddr('XTLUI2');
|
||||
@XTLAddPlugin := UILib.GetProcAddr('XTLAddPlugin');
|
||||
@XTLAddCodec := UILib.GetProcAddr('XTLAddCodec');
|
||||
UIDLLLoaded := Assigned(XTLUI1);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Deinit;
|
||||
begin
|
||||
if Win32MajorVersion < 6 then
|
||||
exit;
|
||||
UILib.Free;
|
||||
end;
|
||||
|
||||
var
|
||||
I: Integer;
|
||||
|
||||
initialization
|
||||
|
||||
if not IsLibrary then
|
||||
begin
|
||||
for I := 1 to ParamCount do
|
||||
begin
|
||||
if (ParamStr(I) = '--debug') then
|
||||
begin
|
||||
DEBUG := True;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
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
|
||||
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
|
||||
|
||||
if not IsLibrary then
|
||||
Deinit;
|
||||
|
||||
end.
|
|
@ -0,0 +1,923 @@
|
|||
unit Unit1;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
WinAPI.Windows,
|
||||
System.SysUtils, System.Types, System.UITypes, System.Classes,
|
||||
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.ComboEdit, FMX.Memo.Types,
|
||||
FMX.ScrollBox, FMX.Memo;
|
||||
|
||||
type
|
||||
TForm1 = class(TForm)
|
||||
StyleBook1: TStyleBook;
|
||||
SaveDialog1: TSaveDialog;
|
||||
OpenDialog1: TOpenDialog;
|
||||
GroupBox1: TGroupBox;
|
||||
ComboBox2: TComboBox;
|
||||
Edit1: TEdit;
|
||||
SearchEditButton1: TSearchEditButton;
|
||||
Layout1: TLayout;
|
||||
GroupBox2: TGroupBox;
|
||||
Layout3: TLayout;
|
||||
VertScrollBox1: TVertScrollBox;
|
||||
GroupBox3: TGroupBox;
|
||||
Layout7: TLayout;
|
||||
Edit3: TEdit;
|
||||
SearchEditButton3: TSearchEditButton;
|
||||
ComboBox3: TComboBox;
|
||||
Label1: TLabel;
|
||||
SpinBox1: TSpinBox;
|
||||
Label2: TLabel;
|
||||
SpinBox2: TSpinBox;
|
||||
Layout2: TLayout;
|
||||
GroupBox4: TGroupBox;
|
||||
Layout6: TLayout;
|
||||
GroupBox5: TGroupBox;
|
||||
Layout8: TLayout;
|
||||
Label7: TLabel;
|
||||
SpinBox7: TSpinBox;
|
||||
Label4: TLabel;
|
||||
SpinBox4: TSpinBox;
|
||||
CheckBox4: TCheckBox;
|
||||
GroupBox6: TGroupBox;
|
||||
Layout5: TLayout;
|
||||
Edit2: TEdit;
|
||||
Button2: TButton;
|
||||
CheckBox2: 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);
|
||||
procedure ComboBox3Change(Sender: TObject);
|
||||
procedure Button2Click(Sender: TObject);
|
||||
procedure ComboBox2Change(Sender: TObject);
|
||||
procedure Button1Click(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
|
||||
{ Public declarations }
|
||||
end;
|
||||
|
||||
var
|
||||
Form1: TForm1;
|
||||
CmdStr: TArray<String>;
|
||||
Init: Boolean = False;
|
||||
DecodeMode: Integer = -1;
|
||||
|
||||
function GetModuleName: string;
|
||||
function GetIniString(Section, Key, Default, FileName: string): string;
|
||||
procedure SetIniString(Section, Key, Value, FileName: string);
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.fmx}
|
||||
|
||||
uses
|
||||
Unit2;
|
||||
|
||||
function GetModuleName: string;
|
||||
var
|
||||
szFileName: array [0 .. MAX_PATH] of char;
|
||||
begin
|
||||
FillChar(szFileName, sizeof(szFileName), #0);
|
||||
GetModuleFileName(hInstance, szFileName, MAX_PATH);
|
||||
Result := szFileName;
|
||||
end;
|
||||
|
||||
function GetIniString(Section, Key, Default, FileName: string): string;
|
||||
var
|
||||
Ini: TIniFile;
|
||||
begin
|
||||
Ini := TIniFile.Create(FileName);
|
||||
with Ini do
|
||||
try
|
||||
Result := Ini.ReadString(Section, Key, Default);
|
||||
finally
|
||||
Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure SetIniString(Section, Key, Value, FileName: string);
|
||||
var
|
||||
Ini: TIniFile;
|
||||
begin
|
||||
Ini := TIniFile.Create(FileName);
|
||||
with Ini do
|
||||
try
|
||||
Ini.WriteString(Section, Key, Value);
|
||||
finally
|
||||
Free;
|
||||
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));
|
||||
Insert('precomp', CmdStr, Length(CmdStr));
|
||||
Insert('-c' + SpinBox1.Text + 'mb', CmdStr, Length(CmdStr));
|
||||
Insert('-t' + SpinBox2.Text, CmdStr, Length(CmdStr));
|
||||
if CheckBox1.IsChecked then
|
||||
Insert('-lm', CmdStr, Length(CmdStr));
|
||||
Insert('-d' + SpinBox3.Text, CmdStr, Length(CmdStr));
|
||||
if CheckBox2.IsChecked then
|
||||
Insert('-s', CmdStr, Length(CmdStr));
|
||||
if CheckBox6.IsChecked then
|
||||
Insert('-v', CmdStr, Length(CmdStr));
|
||||
Insert('-m' + Edit2.Text, CmdStr, Length(CmdStr));
|
||||
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
|
||||
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 = 1 then
|
||||
Insert(Edit3.Text, CmdStr, Length(CmdStr));
|
||||
end;
|
||||
|
||||
procedure TForm1.Button2Click(Sender: TObject);
|
||||
begin
|
||||
Form2.Left := Form1.Left + (Form1.Width div 2) - (Form2.Width div 2);
|
||||
Form2.Top := Form1.Top + (Form1.Height div 2) - (Form2.Height div 2);
|
||||
Form2.ShowModal;
|
||||
Form2.Close;
|
||||
end;
|
||||
|
||||
procedure TForm1.Button5Click(Sender: TObject);
|
||||
begin
|
||||
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);
|
||||
begin
|
||||
SearchEditButton1.Enabled := ComboBox2.ItemIndex <> 2;
|
||||
Edit1.ReadOnly := ComboBox2.ItemIndex <> 2;
|
||||
if ComboBox2.ItemIndex = 2 then
|
||||
Edit1.Text := 'http://mattmahoney.net/dc/silesia.zip'
|
||||
else
|
||||
Edit1.Text := '';
|
||||
end;
|
||||
|
||||
procedure TForm1.ComboBox3Change(Sender: TObject);
|
||||
begin
|
||||
Edit3.Enabled := ComboBox3.ItemIndex <> 0;
|
||||
ComboEdit1.Enabled := (ComboBox5.ItemIndex = 2) and (ComboBox3.ItemIndex = 0);
|
||||
end;
|
||||
|
||||
procedure TForm1.ComboBox4Change(Sender: TObject);
|
||||
begin
|
||||
Edit5.Enabled := ComboBox4.ItemIndex > 0;
|
||||
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
|
||||
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);
|
||||
begin
|
||||
if Edit6.Text <> GetIniString('UI', 'Plugins', '',
|
||||
ChangeFileExt(GetModuleName, '.ini')) then
|
||||
SetIniString('UI', 'Plugins', Edit6.Text,
|
||||
ChangeFileExt(GetModuleName, '.ini'));
|
||||
end;
|
||||
|
||||
procedure TForm1.FormShow(Sender: TObject);
|
||||
var
|
||||
I: Integer;
|
||||
begin
|
||||
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);
|
||||
var
|
||||
Dir: string;
|
||||
begin
|
||||
case ComboBox2.ItemIndex of
|
||||
0:
|
||||
begin
|
||||
OpenDialog1.FileName := '';
|
||||
if OpenDialog1.Execute then
|
||||
Edit1.Text := OpenDialog1.FileName;
|
||||
end;
|
||||
1:
|
||||
if SelectDirectory('', '', Dir) then
|
||||
Edit1.Text := Dir;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TForm1.SearchEditButton20Click(Sender: TObject);
|
||||
var
|
||||
Dir: string;
|
||||
begin
|
||||
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
|
||||
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
|
||||
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;
|
||||
|
||||
procedure TForm1.SearchEditButton3Click(Sender: TObject);
|
||||
begin
|
||||
SaveDialog1.FileName := '';
|
||||
if SaveDialog1.Execute then
|
||||
Edit3.Text := SaveDialog1.FileName;
|
||||
end;
|
||||
|
||||
procedure TForm1.SearchEditButton4Click(Sender: TObject);
|
||||
var
|
||||
Dir: string;
|
||||
begin
|
||||
if SelectDirectory('', '', Dir) then
|
||||
Edit5.Text := Dir;
|
||||
end;
|
||||
|
||||
procedure TForm1.SearchEditButton5Click(Sender: TObject);
|
||||
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.
|
|
@ -0,0 +1,569 @@
|
|||
unit Unit2;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
System.SysUtils, System.Types, System.UITypes, System.Classes,
|
||||
System.Variants, System.Math, System.StrUtils,
|
||||
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.TabControl,
|
||||
FMX.StdCtrls, FMX.Edit, FMX.EditBox, FMX.SpinBox, FMX.Controls.Presentation,
|
||||
FMX.Layouts, FMX.ListBox;
|
||||
|
||||
type
|
||||
TForm2 = class(TForm)
|
||||
TabControl1: TTabControl;
|
||||
TabItem1: TTabItem;
|
||||
TabItem2: TTabItem;
|
||||
Expander1: TExpander;
|
||||
Layout6: TLayout;
|
||||
CheckBox3: TCheckBox;
|
||||
Layout1: TLayout;
|
||||
Label4: TLabel;
|
||||
SpinBox4: TSpinBox;
|
||||
Layout2: TLayout;
|
||||
CheckBox1: TCheckBox;
|
||||
Layout3: TLayout;
|
||||
Label1: TLabel;
|
||||
SpinBox1: TSpinBox;
|
||||
Layout4: TLayout;
|
||||
CheckBox2: TCheckBox;
|
||||
Expander2: TExpander;
|
||||
Layout5: TLayout;
|
||||
CheckBox4: TCheckBox;
|
||||
Layout7: TLayout;
|
||||
Label2: TLabel;
|
||||
SpinBox2: TSpinBox;
|
||||
Layout8: TLayout;
|
||||
CheckBox5: TCheckBox;
|
||||
Layout9: TLayout;
|
||||
SpinBox3: TSpinBox;
|
||||
Layout10: TLayout;
|
||||
CheckBox6: TCheckBox;
|
||||
VertScrollBox1: TVertScrollBox;
|
||||
Layout11: TLayout;
|
||||
SpinBox5: TSpinBox;
|
||||
Layout12: TLayout;
|
||||
Label6: TLabel;
|
||||
SpinBox6: TSpinBox;
|
||||
Expander3: TExpander;
|
||||
Layout13: TLayout;
|
||||
CheckBox7: TCheckBox;
|
||||
Layout14: TLayout;
|
||||
Label7: TLabel;
|
||||
Layout15: TLayout;
|
||||
SpinBox8: TSpinBox;
|
||||
ComboBox1: TComboBox;
|
||||
Expander4: TExpander;
|
||||
Layout16: TLayout;
|
||||
CheckBox8: TCheckBox;
|
||||
Layout18: TLayout;
|
||||
SpinBox7: TSpinBox;
|
||||
CheckBox9: TCheckBox;
|
||||
Expander5: TExpander;
|
||||
Layout17: TLayout;
|
||||
CheckBox10: TCheckBox;
|
||||
Layout19: TLayout;
|
||||
SpinBox9: TSpinBox;
|
||||
CheckBox11: TCheckBox;
|
||||
Layout20: TLayout;
|
||||
CheckBox12: TCheckBox;
|
||||
Layout21: TLayout;
|
||||
SpinBox10: TSpinBox;
|
||||
CheckBox13: TCheckBox;
|
||||
Layout22: TLayout;
|
||||
CheckBox14: TCheckBox;
|
||||
Layout23: TLayout;
|
||||
SpinBox11: TSpinBox;
|
||||
CheckBox15: TCheckBox;
|
||||
Layout24: TLayout;
|
||||
CheckBox16: TCheckBox;
|
||||
Layout25: TLayout;
|
||||
SpinBox12: TSpinBox;
|
||||
CheckBox17: TCheckBox;
|
||||
Layout26: TLayout;
|
||||
CheckBox18: TCheckBox;
|
||||
Layout27: TLayout;
|
||||
SpinBox13: TSpinBox;
|
||||
CheckBox19: TCheckBox;
|
||||
Layout28: TLayout;
|
||||
CheckBox20: TCheckBox;
|
||||
Expander6: TExpander;
|
||||
Layout29: TLayout;
|
||||
CheckBox21: TCheckBox;
|
||||
Layout30: TLayout;
|
||||
SpinBox14: TSpinBox;
|
||||
CheckBox23: TCheckBox;
|
||||
CheckBox24: TCheckBox;
|
||||
CheckBox25: TCheckBox;
|
||||
Layout31: TLayout;
|
||||
Label3: TLabel;
|
||||
SpinBox15: TSpinBox;
|
||||
Layout32: TLayout;
|
||||
CheckBox26: TCheckBox;
|
||||
Layout33: TLayout;
|
||||
RadioButton1: TRadioButton;
|
||||
Layout34: TLayout;
|
||||
RadioButton2: TRadioButton;
|
||||
Layout35: TLayout;
|
||||
RadioButton3: TRadioButton;
|
||||
Layout36: TLayout;
|
||||
Label5: TLabel;
|
||||
SpinBox16: TSpinBox;
|
||||
Layout37: TLayout;
|
||||
Button1: TButton;
|
||||
RadioButton4: TRadioButton;
|
||||
VertScrollBox3: TVertScrollBox;
|
||||
Expander10: TExpander;
|
||||
ListBox2: TListBox;
|
||||
Expander7: TExpander;
|
||||
Layout38: TLayout;
|
||||
CheckBox22: TCheckBox;
|
||||
procedure FormShow(Sender: TObject);
|
||||
procedure CheckBox3Change(Sender: TObject);
|
||||
procedure CheckBox1Change(Sender: TObject);
|
||||
procedure CheckBox4Change(Sender: TObject);
|
||||
procedure CheckBox5Change(Sender: TObject);
|
||||
procedure CheckBox6Change(Sender: TObject);
|
||||
procedure CheckBox7Change(Sender: TObject);
|
||||
procedure CheckBox10Change(Sender: TObject);
|
||||
procedure CheckBox8Change(Sender: TObject);
|
||||
procedure CheckBox12Change(Sender: TObject);
|
||||
procedure CheckBox14Change(Sender: TObject);
|
||||
procedure CheckBox16Change(Sender: TObject);
|
||||
procedure CheckBox18Change(Sender: TObject);
|
||||
procedure CheckBox21Change(Sender: TObject);
|
||||
procedure CheckBox26Change(Sender: TObject);
|
||||
procedure CheckBox24Change(Sender: TObject);
|
||||
procedure CheckBox23Change(Sender: TObject);
|
||||
procedure CheckBox25Change(Sender: TObject);
|
||||
procedure CheckBox9Change(Sender: TObject);
|
||||
procedure CheckBox11Change(Sender: TObject);
|
||||
procedure CheckBox13Change(Sender: TObject);
|
||||
procedure CheckBox15Change(Sender: TObject);
|
||||
procedure CheckBox17Change(Sender: TObject);
|
||||
procedure CheckBox19Change(Sender: TObject);
|
||||
procedure Button1Click(Sender: TObject);
|
||||
procedure RadioButton4Change(Sender: TObject);
|
||||
private
|
||||
{ Private declarations }
|
||||
public
|
||||
{ Public declarations }
|
||||
end;
|
||||
|
||||
TMethod = record
|
||||
FName: String;
|
||||
FType: Integer;
|
||||
Codecs: TArray<String>;
|
||||
end;
|
||||
|
||||
TConfigCtrl = class(TObject)
|
||||
private
|
||||
FOwner, FParent: TFmxObject;
|
||||
FExpander: TExpander;
|
||||
FListBox: TListBox;
|
||||
public
|
||||
constructor Create(AOwner, AParent: TFmxObject);
|
||||
destructor Destroy; override;
|
||||
procedure SetText(AText: String);
|
||||
procedure AddCodec(ACodec: String);
|
||||
function GetCodec(out Codec: String): Boolean;
|
||||
end;
|
||||
|
||||
TLibraryCtrl = class(TObject)
|
||||
private
|
||||
FOwner, FParent: TFmxObject;
|
||||
FExpander: TExpander;
|
||||
FCheckBox: TArray<TCheckBox>;
|
||||
FLayout1, FLayout2: TArray<TLayout>;
|
||||
FLabel: TArray<TLabel>;
|
||||
FEdit: TArray<TEdit>;
|
||||
procedure OnCheckBoxChange(Sender: TObject);
|
||||
public
|
||||
constructor Create(AOwner, AParent: TFmxObject);
|
||||
destructor Destroy; override;
|
||||
procedure SetText(AText: String);
|
||||
procedure AddCodec(ACodec: String);
|
||||
function GetCodec(out Codec: String): Boolean;
|
||||
end;
|
||||
|
||||
var
|
||||
Form2: TForm2;
|
||||
Methods: TArray<TMethod>;
|
||||
CfgCtrls: TArray<TConfigCtrl>;
|
||||
LibCtrls: TArray<TLibraryCtrl>;
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.fmx}
|
||||
|
||||
uses Unit1;
|
||||
|
||||
procedure AddMethod(const SubStr: String; var ResStr: String;
|
||||
ParamStr: TArray<String>; ParamBool: TArray<Boolean>);
|
||||
var
|
||||
I: Integer;
|
||||
S: String;
|
||||
begin
|
||||
if ResStr = '' then
|
||||
ResStr := SubStr
|
||||
else
|
||||
ResStr := ResStr + '+' + SubStr;
|
||||
S := '';
|
||||
for I := Low(ParamStr) to High(ParamStr) do
|
||||
if ParamBool[I] then
|
||||
S := S + ':' + ParamStr[I];
|
||||
ResStr := ResStr + S;
|
||||
end;
|
||||
|
||||
constructor TConfigCtrl.Create(AOwner, AParent: TFmxObject);
|
||||
begin
|
||||
inherited Create;
|
||||
FOwner := AOwner;
|
||||
FParent := AParent;
|
||||
FExpander := TExpander.Create(FOwner);
|
||||
FExpander.Parent := FParent;
|
||||
FExpander.Height := 130;
|
||||
FExpander.Margins.Top := 8;
|
||||
FExpander.Margins.Left := 8;
|
||||
FExpander.Margins.Right := 8;
|
||||
FExpander.Align := TAlignLayout.Top;
|
||||
FListBox := TListBox.Create(FExpander);
|
||||
FListBox.Parent := FExpander;
|
||||
FListBox.Margins.Bottom := 8;
|
||||
FListBox.Margins.Left := 8;
|
||||
FListBox.Margins.Right := 8;
|
||||
FListBox.Align := TAlignLayout.Client;
|
||||
FListBox.ShowCheckboxes := True;
|
||||
end;
|
||||
|
||||
destructor TConfigCtrl.Destroy;
|
||||
begin
|
||||
FListBox.Free;
|
||||
FExpander.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TConfigCtrl.SetText(AText: String);
|
||||
begin
|
||||
FExpander.Text := AText;
|
||||
end;
|
||||
|
||||
procedure TConfigCtrl.AddCodec(ACodec: String);
|
||||
begin
|
||||
FListBox.Items.Add(ACodec);
|
||||
end;
|
||||
|
||||
function TConfigCtrl.GetCodec(out Codec: String): Boolean;
|
||||
var
|
||||
I: Integer;
|
||||
S: String;
|
||||
begin
|
||||
Result := False;
|
||||
S := '';
|
||||
for I := 0 to FListBox.Items.Count - 1 do
|
||||
if FListBox.ItemByIndex(I).IsChecked then
|
||||
begin
|
||||
S := S + ':' + FListBox.Items[I];
|
||||
Result := True;
|
||||
end;
|
||||
if Result then
|
||||
Codec := FExpander.Text + S;
|
||||
end;
|
||||
|
||||
constructor TLibraryCtrl.Create(AOwner, AParent: TFmxObject);
|
||||
begin
|
||||
inherited Create;
|
||||
FOwner := AOwner;
|
||||
FParent := AParent;
|
||||
FExpander := TExpander.Create(FOwner);
|
||||
FExpander.Parent := FParent;
|
||||
FExpander.Height := 25;
|
||||
FExpander.Margins.Top := 8;
|
||||
FExpander.Margins.Left := 8;
|
||||
FExpander.Margins.Right := 8;
|
||||
FExpander.Align := TAlignLayout.Top;
|
||||
end;
|
||||
|
||||
destructor TLibraryCtrl.Destroy;
|
||||
begin
|
||||
FExpander.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TLibraryCtrl.OnCheckBoxChange(Sender: TObject);
|
||||
var
|
||||
I: Integer;
|
||||
begin
|
||||
for I := Low(FCheckBox) to High(FCheckBox) do
|
||||
if Sender = FCheckBox[I] then
|
||||
FEdit[I].Enabled := FCheckBox[I].IsChecked;
|
||||
end;
|
||||
|
||||
procedure TLibraryCtrl.SetText(AText: String);
|
||||
begin
|
||||
FExpander.Text := AText;
|
||||
end;
|
||||
|
||||
procedure TLibraryCtrl.AddCodec(ACodec: String);
|
||||
var
|
||||
I: Integer;
|
||||
begin
|
||||
I := Length(FLayout1);
|
||||
Insert(TLayout.Create(FExpander), FLayout1, Length(FLayout1));
|
||||
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;
|
||||
FCheckBox[I].Margins.Top := 8;
|
||||
FCheckBox[I].Margins.Left := 8;
|
||||
FCheckBox[I].Margins.Right := 8;
|
||||
FCheckBox[I].Align := TAlignLayout.Top;
|
||||
FCheckBox[I].Text := ACodec;
|
||||
FCheckBox[I].OnChange := OnCheckBoxChange;
|
||||
Insert(TLayout.Create(FLayout1[I]), FLayout2, Length(FLayout2));
|
||||
FLayout2[I].Parent := FLayout1[I];
|
||||
FLayout2[I].Align := TAlignLayout.Client;
|
||||
Insert(TLabel.Create(FLayout2[I]), FLabel, Length(FLabel));
|
||||
FLabel[I].Parent := FLayout2[I];
|
||||
FLabel[I].Width := 40;
|
||||
FLabel[I].Margins.Top := 8;
|
||||
FLabel[I].Margins.Bottom := 8;
|
||||
FLabel[I].Margins.Left := 8;
|
||||
FLabel[I].Align := TAlignLayout.Left;
|
||||
FLabel[I].Text := 'Param';
|
||||
Insert(TEdit.Create(FLayout2[I]), FEdit, Length(FEdit));
|
||||
FEdit[I].Parent := FLayout2[I];
|
||||
FEdit[I].Enabled := False;
|
||||
FEdit[I].Margins.Top := 8;
|
||||
FEdit[I].Margins.Bottom := 8;
|
||||
FEdit[I].Margins.Left := 8;
|
||||
FEdit[I].Margins.Right := 8;
|
||||
FEdit[I].Align := TAlignLayout.Client;
|
||||
FExpander.Height := FExpander.Height + 64;
|
||||
end;
|
||||
|
||||
function TLibraryCtrl.GetCodec(out Codec: String): Boolean;
|
||||
var
|
||||
I: Integer;
|
||||
S: String;
|
||||
begin
|
||||
Result := False;
|
||||
S := '';
|
||||
for I := Low(FCheckBox) to High(FCheckBox) do
|
||||
if FCheckBox[I].IsChecked then
|
||||
begin
|
||||
AddMethod(FCheckBox[I].Text, S, [FEdit[I].Text], [FEdit[I].Text <> '']);
|
||||
Result := True;
|
||||
end;
|
||||
if Result then
|
||||
Codec := S;
|
||||
end;
|
||||
|
||||
procedure TForm2.Button1Click(Sender: TObject);
|
||||
var
|
||||
I: Integer;
|
||||
S, Res: String;
|
||||
begin
|
||||
Res := '';
|
||||
if CheckBox3.IsChecked then
|
||||
AddMethod('zlib', Res, ['w' + SpinBox4.Text], [True]);
|
||||
if CheckBox1.IsChecked then
|
||||
AddMethod('reflate', Res, ['l' + SpinBox1.Text], [True]);
|
||||
if CheckBox2.IsChecked then
|
||||
AddMethod('preflate', Res, [], []);
|
||||
if CheckBox20.IsChecked then
|
||||
AddMethod('png', Res, [], []);
|
||||
if CheckBox4.IsChecked then
|
||||
AddMethod('lz4', Res, ['a' + SpinBox2.Text], [True]);
|
||||
if CheckBox5.IsChecked then
|
||||
AddMethod('lz4hc', Res, ['l' + SpinBox3.Text], [CheckBox24.IsChecked]);
|
||||
if CheckBox6.IsChecked then
|
||||
AddMethod('lz4f', Res, ['l' + SpinBox5.Text, 'd' + SpinBox6.Text],
|
||||
[CheckBox23.IsChecked, True]);
|
||||
if CheckBox7.IsChecked then
|
||||
AddMethod('lzo1x', Res, ['l' + SpinBox8.Text], [CheckBox25.IsChecked]);
|
||||
if CheckBox8.IsChecked then
|
||||
AddMethod('zstd', Res, ['l' + SpinBox7.Text], [CheckBox9.IsChecked]);
|
||||
if CheckBox10.IsChecked then
|
||||
AddMethod('kraken', Res, ['l' + SpinBox9.Text, 'n' + SpinBox15.Text,
|
||||
't' + SpinBox16.Text], [CheckBox11.IsChecked, True, True]);
|
||||
if CheckBox12.IsChecked then
|
||||
AddMethod('mermaid', Res, ['l' + SpinBox10.Text, 'n' + SpinBox15.Text,
|
||||
't' + SpinBox16.Text], [CheckBox13.IsChecked, True, True]);
|
||||
if CheckBox14.IsChecked then
|
||||
AddMethod('selkie', Res, ['l' + SpinBox11.Text, 'n' + SpinBox15.Text,
|
||||
't' + SpinBox16.Text], [CheckBox15.IsChecked, True, True]);
|
||||
if CheckBox16.IsChecked then
|
||||
AddMethod('hydra', Res, ['l' + SpinBox12.Text, 'n' + SpinBox15.Text,
|
||||
't' + SpinBox16.Text], [CheckBox17.IsChecked, True, True]);
|
||||
if CheckBox18.IsChecked then
|
||||
AddMethod('leviathan', Res, ['l' + SpinBox13.Text, 'n' + SpinBox15.Text,
|
||||
't' + SpinBox16.Text], [CheckBox19.IsChecked, True, True]);
|
||||
if CheckBox21.IsChecked then
|
||||
AddMethod('flac', Res, ['l' + SpinBox14.Text], [RadioButton4.IsChecked]);
|
||||
if CheckBox26.IsChecked and RadioButton1.IsChecked then
|
||||
AddMethod('brunsli', Res, [], []);
|
||||
if CheckBox26.IsChecked and RadioButton2.IsChecked then
|
||||
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, [], []);
|
||||
for I := Low(CfgCtrls) to High(CfgCtrls) do
|
||||
if CfgCtrls[I].GetCodec(S) then
|
||||
AddMethod(S, Res, [], []);
|
||||
for I := Low(LibCtrls) to High(LibCtrls) do
|
||||
if LibCtrls[I].GetCodec(S) then
|
||||
AddMethod(S, Res, [], []);
|
||||
Form1.Edit2.Text := Res;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox10Change(Sender: TObject);
|
||||
begin
|
||||
Layout19.Enabled := CheckBox10.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox11Change(Sender: TObject);
|
||||
begin
|
||||
SpinBox9.Enabled := CheckBox11.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox12Change(Sender: TObject);
|
||||
begin
|
||||
Layout21.Enabled := CheckBox12.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox13Change(Sender: TObject);
|
||||
begin
|
||||
SpinBox10.Enabled := CheckBox13.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox14Change(Sender: TObject);
|
||||
begin
|
||||
Layout23.Enabled := CheckBox14.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox15Change(Sender: TObject);
|
||||
begin
|
||||
SpinBox11.Enabled := CheckBox15.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox16Change(Sender: TObject);
|
||||
begin
|
||||
Layout25.Enabled := CheckBox16.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox17Change(Sender: TObject);
|
||||
begin
|
||||
SpinBox12.Enabled := CheckBox17.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox18Change(Sender: TObject);
|
||||
begin
|
||||
Layout27.Enabled := CheckBox18.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox19Change(Sender: TObject);
|
||||
begin
|
||||
SpinBox13.Enabled := CheckBox19.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox1Change(Sender: TObject);
|
||||
begin
|
||||
Layout3.Enabled := CheckBox1.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox21Change(Sender: TObject);
|
||||
begin
|
||||
Layout30.Enabled := CheckBox21.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox23Change(Sender: TObject);
|
||||
begin
|
||||
SpinBox5.Enabled := CheckBox23.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox24Change(Sender: TObject);
|
||||
begin
|
||||
SpinBox3.Enabled := CheckBox24.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox25Change(Sender: TObject);
|
||||
begin
|
||||
SpinBox8.Enabled := CheckBox25.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox26Change(Sender: TObject);
|
||||
begin
|
||||
Layout33.Enabled := CheckBox26.IsChecked;
|
||||
Layout34.Enabled := CheckBox26.IsChecked;
|
||||
Layout35.Enabled := CheckBox26.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox3Change(Sender: TObject);
|
||||
begin
|
||||
Layout1.Enabled := CheckBox3.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox4Change(Sender: TObject);
|
||||
begin
|
||||
Layout7.Enabled := CheckBox4.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox5Change(Sender: TObject);
|
||||
begin
|
||||
Layout9.Enabled := CheckBox5.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox6Change(Sender: TObject);
|
||||
begin
|
||||
Layout11.Enabled := CheckBox6.IsChecked;
|
||||
Layout12.Enabled := CheckBox6.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox7Change(Sender: TObject);
|
||||
begin
|
||||
Layout14.Enabled := CheckBox7.IsChecked;
|
||||
Layout15.Enabled := CheckBox7.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox8Change(Sender: TObject);
|
||||
begin
|
||||
Layout18.Enabled := CheckBox8.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.CheckBox9Change(Sender: TObject);
|
||||
begin
|
||||
SpinBox7.Enabled := CheckBox9.IsChecked;
|
||||
end;
|
||||
|
||||
procedure TForm2.FormShow(Sender: TObject);
|
||||
var
|
||||
I: Integer;
|
||||
begin
|
||||
for I := 0 to ComponentCount - 1 do
|
||||
begin
|
||||
if Components[I] is TSpinBox then
|
||||
TSpinBox(Components[I]).Cursor := crDefault;
|
||||
if Components[I] is TCheckBox then
|
||||
if Assigned(TCheckBox(Components[I]).OnChange) then
|
||||
TCheckBox(Components[I]).OnChange(nil);
|
||||
if Components[I] is TRadioButton then
|
||||
if Assigned(TRadioButton(Components[I]).OnChange) then
|
||||
TRadioButton(Components[I]).OnChange(nil);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TForm2.RadioButton4Change(Sender: TObject);
|
||||
begin
|
||||
SpinBox14.Enabled := RadioButton4.IsChecked;
|
||||
end;
|
||||
|
||||
end.
|
106
changes.txt
106
changes.txt
|
@ -1,3 +1,107 @@
|
|||
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
|
||||
- fixed bugs related to oodle scanner
|
||||
- skip verification no longer applies to encryption codecs
|
||||
|
||||
ES_R43 (0.6.8)
|
||||
- added advanced configuration based plugin support
|
||||
- added UI mode when xtool.exe is launched with xtoolui.dll present
|
||||
- added skip verification mode
|
||||
- xtool now enforces w15 deflate stream detection by default
|
||||
- fixed oodle scanner exceptions when incomplete stream is detected
|
||||
- fixed issue with zlib codec not accepting streams from database plugins
|
||||
- updated command line syntax
|
||||
|
||||
ES_R42 (0.6.7)
|
||||
- fixed oodle scanner exceptions when incorrect library is used
|
||||
- fixed issues with deduplication feature
|
||||
|
||||
ES_R41 (0.6.6)
|
||||
- fixed issues with exporting precompression database
|
||||
- fixed issues with deduplication feature consuming a lot of system memory
|
||||
|
@ -6,7 +110,7 @@
|
|||
|
||||
ES_R40 (0.6.5)
|
||||
- updated oodle scanner
|
||||
- remove xdelta support from oodle and lzo codecs (crc mismatch often generates large diff files)
|
||||
- removed xdelta support from oodle and lzo codecs (crc mismatch often generates large diff files)
|
||||
|
||||
ES_R39 (0.6.4)
|
||||
- fixed issues with lzo2a and lzo1c codecs
|
||||
|
|
|
@ -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.
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -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.
|
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||
|
|
1940
common/Utils.pas
1940
common/Utils.pas
File diff suppressed because it is too large
Load Diff
|
@ -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
|
@ -0,0 +1 @@
|
|||
nasm.exe -Ox -Ov -f win64 FastMM4_AVX512.asm
|
|
@ -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
|
|
@ -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.
|
|
@ -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
|
|
@ -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.
|
|
@ -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>
|
|
@ -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.
|
|
@ -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>
|
|
@ -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.
|
|
@ -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>
|
|
@ -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
|
|
@ -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.
|
|
@ -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.
|
|
@ -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
|
|
@ -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.
|
|
@ -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
|
@ -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.
|
|
@ -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
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
||||
|
|
@ -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}
|
|
@ -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
|
|
@ -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.
|
|
@ -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.
|
||||
|
|
@ -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.
|
|
@ -0,0 +1,3 @@
|
|||
C++ Builder projects can statically link to FastMM_FullDebugMode.dll. For that FastMM_FullDebugMode.lib is needed.
|
||||
|
||||
- JiYuan Xie
|
|
@ -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>
|
|
@ -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.
|
|
@ -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 "%debuggee%"</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 "%debuggee%"</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 |
|
@ -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.
|
|
@ -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>
|
Binary file not shown.
|
@ -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
|
||||

|
||||
|
||||
## 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`.
|
||||
|
|
@ -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
|
|
@ -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"" -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>
|
|
@ -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.
|
|
@ -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;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
This file is used by the project manager only and should be treated like the project file
|
||||
|
||||
DllEntryPoint
|
|
@ -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=""F:\FastMM492\FastMM4\Replacement BorlndMM DLL\BCB6";$(BCB)\include;$(BCB)\include\vcl"/>
|
||||
<LIBPATH value=""F:\FastMM492\FastMM4\Replacement BorlndMM DLL\BCB6";$(BCB)\lib\obj;$(BCB)\lib"/>
|
||||
<WARNINGS value="-w-par"/>
|
||||
<OTHERFILES value=""/>
|
||||
</MACROS>
|
||||
<OPTIONS>
|
||||
<IDLCFLAGS value="-I"F:\FastMM492\FastMM4\Replacement BorlndMM DLL\BCB6" -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"" -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>
|
|
@ -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.
|
|
@ -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;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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>
|
|
@ -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
|
|
@ -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.
|
|
@ -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;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
|
@ -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
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
LoadDebugDLLDynamically must be defined.
|
File diff suppressed because one or more lines are too long
|
@ -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.
|
|
@ -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;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
|
@ -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
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
LoadDebugDLLDynamically must be defined.
|
|
@ -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.
|
|
@ -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>
|
|
@ -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.
|
|
@ -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.
|
||||
|
|
@ -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.
|
|
@ -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.
|
||||
|
|
@ -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#14070(Delphi尝试在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}
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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
Loading…
Reference in New Issue