📄 fastobj.pas
字号:
end;
// NewInstanceCopyLargeSizeNoFill
// Large copy without filling
function TObjectAccelerator.NewInstanceCopyLargeSizeNoFill: TObject;
asm
push esi
push edi
mov edi, eax //save self
mov eax, [eax + FInstanceSize]
mov esi, eax //save FInstanceSize
{$ifdef UseFastMM}
call FastGetMem
{$else}
call System.@GetMem
{$endif}
mov ecx, esi
mov esi, [edi + FTemplate] //esi = FTemplate
mov edi, eax //edi = NewInstance
{$ifndef ForceMMX}
{$ifdef EnableMMX}
cmp UseMMX, True
je @@MMXMove
{$endif}
shr ecx, 2
rep movsd
{$ifdef EnableMMX}
pop edi
pop esi
ret
{$endif}
{$endif} //ForceMMX
{$ifdef EnableMMX}
@@MMXMove:
//GC: the fastmove code using edx as source,
//TODO: could change to esi, because it already contains the source
//any points against? Delphi 5 code must be adapted
mov edx, esi
add edi, ecx //edi now is the start address
add edx, ecx
neg ecx
add ecx, 32
@@MMXMove32Loop:
{$ifndef Delphi6_Up}
db $0F, $6F, $44, $11, $E0
db $0F, $6F, $4C, $11, $E8
db $0F, $6F, $54, $11, $F0
db $0F, $6F, $5C, $11, $F8
db $0F, $7F, $44, $39, $E0
db $0F, $7F, $4C, $39, $E8
db $0F, $7F, $54, $39, $F0
db $0F, $7F, $5C, $39, $F8
{$else}
movq mm0, [edx + ecx - 32]
movq mm1, [edx + ecx - 24]
movq mm2, [edx + ecx - 16]
movq mm3, [edx + ecx - 8]
movq [edi + ecx - 32], mm0
movq [edi + ecx - 24], mm1
movq [edi + ecx - 16], mm2
movq [edi + ecx - 8], mm3
{$endif}
add ecx, 32
jle @@MMXMove32Loop
nop
nop
nop
@@MMXMoveDWords:
jmp dword ptr [@@MMXMoveJumpTable + ecx]
nop
nop
nop
@@MMXMoveJumpTable:
dd @@MMXMove32
dd @@MMXMove28
dd @@MMXMove24
dd @@MMXMove20
dd @@MMXMove16
dd @@MMXMove12
dd @@MMXMove8
dd @@MMXMove4
dd @@MMXMove0
//Exit mmx state
//will be called later in clear part
//emms
@@MMXMove28:
{$ifndef Delphi6_Up}
db $0F, $6F, $44, $11, $E0
db $0F, $6F, $4C, $11, $E8
db $0F, $6F, $54, $11, $F0
{$else}
movq mm0, [edx + ecx - 32]
movq mm1, [edx + ecx - 24]
movq mm2, [edx + ecx - 16]
{$endif}
mov edx, [edx + ecx - 8]
{$ifndef Delphi6_Up}
db $0F, $7F, $44, $39, $E0
db $0F, $7F, $4C, $39, $E8
db $0F, $7F, $54, $39, $F0
{$else}
movq [edi + ecx - 32], mm0
movq [edi + ecx - 24], mm1
movq [edi + ecx - 16], mm2
{$endif}
mov [edi + ecx - 8], edx
jmp @@MMXMoveDone
nop
@@MMXMove24:
{$ifndef Delphi6_Up}
db $0F, $6F, $44, $11, $E0
db $0F, $6F, $4C, $11, $E8
db $0F, $6F, $54, $11, $F0
db $0F, $7F, $44, $39, $E0
db $0F, $7F, $4C, $39, $E8
db $0F, $7F, $54, $39, $F0
{$else}
movq mm0, [edx + ecx - 32]
movq mm1, [edx + ecx - 24]
movq mm2, [edx + ecx - 16]
movq [edi + ecx - 32], mm0
movq [edi + ecx - 24], mm1
movq [edi + ecx - 16], mm2
{$endif}
jmp @@MMXMoveDone
@@MMXMove20:
{$ifndef Delphi6_Up}
db $0F, $6F, $44, $11, $E0
db $0F, $6F, $4C, $11, $E8
{$else}
movq mm0, [edx + ecx - 32]
movq mm1, [edx + ecx - 24]
{$endif}
mov edx, [edx + ecx - 16]
{$ifndef Delphi6_Up}
db $0F, $7F, $44, $39, $E0
db $0F, $7F, $4C, $39, $E8
{$else}
movq [edi + ecx - 32], mm0
movq [edi + ecx - 24], mm1
{$endif}
mov [edi + ecx - 16], edx
jmp @@MMXMoveDone
nop
nop
@@MMXMove16:
{$ifndef Delphi6_Up}
db $0F, $6F, $44, $11, $E0
db $0F, $6F, $4C, $11, $E8
db $0F, $7F, $44, $39, $E0
db $0F, $7F, $4C, $39, $E8
{$else}
movq mm0, [edx + ecx - 32]
movq mm1, [edx + ecx - 24]
movq [edi + ecx - 32], mm0
movq [edi + ecx - 24], mm1
{$endif}
jmp @@MMXMoveDone
nop
nop
@@MMXMove12:
{$ifndef Delphi6_Up}
db $0F, $6F, $44, $11, $E0
{$else}
movq mm0, [edx + ecx - 32]
{$endif}
mov edx, [edx + ecx - 24]
{$ifndef Delphi6_Up}
db $0F, $7F, $44, $39, $E0
{$else}
movq [edi + ecx - 32], mm0
{$endif}
mov [edi + ecx - 24], edx
jmp @@MMXMoveDone
@@MMXMove8:
{$ifndef Delphi6_Up}
db $0F, $6F, $44, $11, $E0
db $0F, $7F, $44, $39, $E0
{$else}
movq mm0, [edx + ecx - 32]
movq [edi + ecx - 32], mm0
{$endif}
jmp @@MMXMoveDone
@@MMXMove4:
mov edx, [edx + ecx - 32]
mov [edi + ecx - 32], edx
@@MMXMove32:
@@MMXMove0:
@@MMXMoveDone:
{Exit mmx state}
{$ifndef Delphi6_Up}
db $0F, $77
{$else}
emms
{$endif}
{$endif}
@@Exit:
pop edi
pop esi
end;
// NewInstanceCopyLargeSizeWithFill
// Intended for larger amount of data to copy
function TObjectAccelerator.NewInstanceCopyLargeSizeWithFill: TObject;
// Result:=TObject(FastGetMem(FInstanceSize));
// Move(Pointer(FTemplate)^, Pointer(Result)^, FHeaderDWords*4);
// FillChar(Pointer(FTemplate)^, FInstanceSize - FHeaderDWords*4);
asm
push esi
push edi
mov edi, eax //save self
mov eax, [eax + FInstanceSize]
mov esi, eax //save FInstanceSize
{$ifdef UseFastMM}
call FastGetMem
{$else}
call System.@GetMem
{$endif}
{$ifndef ForceMMX}
{$ifdef EnableMMX}
cmp UseMMX, True
je @@MMXMove
{$endif}
mov edx, esi
shr edx, 2
mov esi, [edi + FTemplate] //esi = FTemplate
mov ecx, [edi + FHeaderDWords] //ecx = FHeaderDWords
sub edx, ecx //edx = size to fill
mov edi, eax //edi = NewInstance
rep movsd
mov ecx, edx //ecx = size to fill
mov edx, eax //edx = NewInstance
xor eax, eax //eax = 0
rep stosd
mov eax, edx
{$endif} //ForceMMX
{$ifdef EnableMMX}
@@MMXMove:
//move part
mov ecx, [edi + FHeaderDWords]
shl ecx, 2
sub esi, ecx //size to fill
mov edx, [edi + FTemplate]
mov edi, eax
add edx, ecx
add edi, ecx //edi now is the start address
neg ecx
add ecx, 32
jnle @@MMXMoveDWords
@@MMXMove32Loop:
{$ifndef Delphi6_Up}
db $0F, $6F, $44, $11, $E0
db $0F, $6F, $4C, $11, $E8
db $0F, $6F, $54, $11, $F0
db $0F, $6F, $5C, $11, $F8
db $0F, $7F, $44, $39, $E0
db $0F, $7F, $4C, $39, $E8
db $0F, $7F, $54, $39, $F0
db $0F, $7F, $5C, $39, $F8
{$else}
movq mm0, [edx + ecx - 32]
movq mm1, [edx + ecx - 24]
movq mm2, [edx + ecx - 16]
movq mm3, [edx + ecx - 8]
movq [edi + ecx - 32], mm0
movq [edi + ecx - 24], mm1
movq [edi + ecx - 16], mm2
movq [edi + ecx - 8], mm3
{$endif}
add ecx, 32
jle @@MMXMove32Loop
nop
nop
nop
@@MMXMoveDWords:
jmp dword ptr [@@MMXMoveJumpTable + ecx]
nop
nop
nop
@@MMXMoveJumpTable:
dd @@MMXMove32
dd @@MMXMove28
dd @@MMXMove24
dd @@MMXMove20
dd @@MMXMove16
dd @@MMXMove12
dd @@MMXMove8
dd @@MMXMove4
dd @@MMXMove0
//Exit mmx state
//will be called later in clear part
//emms
@@MMXMove28:
{$ifndef Delphi6_Up}
db $0F, $6F, $44, $11, $E0
db $0F, $6F, $4C, $11, $E8
db $0F, $6F, $54, $11, $F0
{$else}
movq mm0, [edx + ecx - 32]
movq mm1, [edx + ecx - 24]
movq mm2, [edx + ecx - 16]
{$endif}
mov edx, [edx + ecx - 8]
{$ifndef Delphi6_Up}
db $0F, $7F, $44, $39, $E0
db $0F, $7F, $4C, $39, $E8
db $0F, $7F, $54, $39, $F0
{$else}
movq [edi + ecx - 32], mm0
movq [edi + ecx - 24], mm1
movq [edi + ecx - 16], mm2
{$endif}
mov [edi + ecx - 8], edx
jmp @@MMXMoveDone
nop
@@MMXMove24:
{$ifndef Delphi6_Up}
db $0F, $6F, $44, $11, $E0
db $0F, $6F, $4C, $11, $E8
db $0F, $6F, $54, $11, $F0
db $0F, $7F, $44, $39, $E0
db $0F, $7F, $4C, $39, $E8
db $0F, $7F, $54, $39, $F0
{$else}
movq mm0, [edx + ecx - 32]
movq mm1, [edx + ecx - 24]
movq mm2, [edx + ecx - 16]
movq [edi + ecx - 32], mm0
movq [edi + ecx - 24], mm1
movq [edi + ecx - 16], mm2
{$endif}
jmp @@MMXMoveDone
@@MMXMove20:
{$ifndef Delphi6_Up}
db $0F, $6F, $44, $11, $E0
db $0F, $6F, $4C, $11, $E8
{$else}
movq mm0, [edx + ecx - 32]
movq mm1, [edx + ecx - 24]
{$endif}
mov edx, [edx + ecx - 16]
{$ifndef Delphi6_Up}
db $0F, $7F, $44, $39, $E0
db $0F, $7F, $4C, $39, $E8
{$else}
movq [edi + ecx - 32], mm0
movq [edi + ecx - 24], mm1
{$endif}
mov [edi + ecx - 16], edx
jmp @@MMXMoveDone
nop
nop
@@MMXMove16:
{$ifndef Delphi6_Up}
db $0F, $6F, $44, $11, $E0
db $0F, $6F, $4C, $11, $E8
db $0F, $7F, $44, $39, $E0
db $0F, $7F, $4C, $39, $E8
{$else}
movq mm0, [edx + ecx - 32]
movq mm1, [edx + ecx - 24]
movq [edi + ecx - 32], mm0
movq [edi + ecx - 24], mm1
{$endif}
jmp @@MMXMoveDone
nop
nop
@@MMXMove12:
{$ifndef Delphi6_Up}
db $0F, $6F, $44, $11, $E0
{$else}
movq mm0, [edx + ecx - 32]
{$endif}
mov edx, [edx + ecx - 24]
{$ifndef Delphi6_Up}
db $0F, $7F, $44, $39, $E0
{$else}
movq [edi + ecx - 32], mm0
{$endif}
mov [edi + ecx - 24], edx
jmp @@MMXMoveDone
@@MMXMove8:
{$ifndef Delphi6_Up}
db $0F, $6F, $44, $11, $E0
db $0F, $7F, $44, $39, $E0
{$else}
movq mm0, [edx + ecx - 32]
movq [edi + ecx - 32], mm0
{$endif}
jmp @@MMXMoveDone
@@MMXMove4:
mov edx, [edx + ecx - 32]
mov [edi + ecx - 32], edx
@@MMXMove32:
@@MMXMove0:
@@MMXMoveDone:
//clear part
//should ensure size to fill multiple of 32 bytes
//fill start addr
@@MMXClear:
//gc: xor was missing!
{$ifndef Delphi6_Up}
xor edx, edx
db $0F, $6E, $C2
{$else}
pxor mm0, mm0
{$endif}
mov ecx, esi //size to fill
add edi, ecx
neg ecx
add ecx, 32
jnle @@MMXClearDWords
@@MMXClear32Loop:
{$ifndef Delphi6_Up}
db $0F, $7F, $44, $39, $E0
db $0F, $7F, $44, $39, $E8
db $0F, $7F, $44, $39, $F0
db $0F, $7F, $44, $39, $F8
{$else}
movq [edi + ecx - 32], mm0
movq [edi + ecx - 24], mm0
movq [edi + ecx - 16], mm0
movq [edi + ecx - 8], mm0
{$endif}
add ecx, 32
jle @@MMXClear32Loop
@@MMXClearDWords:
//nothig here! all clear should be 32 byte
@@MMXClearDone:
{Exit mmx state}
{$ifndef Delphi6_Up}
db $0F, $77
{$else}
emms
{$endif}
{$endif}
@@Exit:
pop edi
pop esi
end;
// NewInstanceNoHeader
//
function TObjectAccelerator.NewInstanceNoHeader : TObject;
asm
push eax
mov eax, [eax + offset FInstanceSize]
{$ifdef UseFastMM}
call FastGetMem
{$else}
call system.@GetMem
{$endif}
pop edx
mov ecx, [edx + offset FClass]
mov [eax], ecx
mov ecx, [edx + offset FInstanceSize]
xor edx, edx
sub ecx, SizePtr
@@RAZLoop:
mov [eax+ecx], edx
sub ecx, SizePtr
jnz @@RAZLoop
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -