Skip to content
Permalink
Browse files

new MoveFast() x86_64 optimized assembly function

  • Loading branch information
Arnaud Bouchez
Arnaud Bouchez committed Feb 13, 2020
1 parent 30815ab commit 1557a367f776fcc38e84f839798bc73d568cfc52
Showing with 408 additions and 537 deletions.
  1. +25 −30 SQLite3/mORMot.pas
  2. +346 −474 SynCommons.pas
  3. +24 −27 SynTable.pas
  4. +12 −5 Synopse.inc
  5. +1 −1 SynopseCommit.inc
DestInfo: TSQLPropInfo; Dest: TObject);
begin
if TSQLPropInfoRecordFixedSize(DestInfo).fTypeInfo=fTypeInfo then
{$ifdef FPC}Move{$else}MoveFast{$endif}(GetFieldAddr(Source)^,
MoveFast(GetFieldAddr(Source)^,
TSQLPropInfoRecordFixedSize(DestInfo).GetFieldAddr(Dest)^,fRecordSize) else
inherited CopySameClassProp(Source,DestInfo,Dest);
end;
const Source: Variant);
begin
if TVarData(Source).VType=varString then
{$ifdef FPC}Move{$else}MoveFast{$endif}(
TVarData(Source).VAny^,GetFieldAddr(Instance)^,fRecordSize) else
MoveFast(TVarData(Source).VAny^,GetFieldAddr(Instance)^,fRecordSize) else
FillCharFast(GetFieldAddr(Instance)^,fRecordSize,0);
end;
{$endif NOVARIANTS}
result := P+fRecordSize;
if result>PEnd then
result := nil else
{$ifdef FPC}Move{$else}MoveFast{$endif}(P^,GetFieldAddr(Instance)^,fRecordSize);
MoveFast(P^,GetFieldAddr(Instance)^,fRecordSize);
end;

procedure TSQLPropInfoRecordFixedSize.SetValue(Instance: TObject; Value: PUTF8Char;
Value := pointer(data);
if Value=nil then
FillCharFast(GetFieldAddr(Instance)^,fRecordSize,0) else
{$ifdef FPC}Move{$else}MoveFast{$endif}(Value^,GetFieldAddr(Instance)^,fRecordSize);
MoveFast(Value^,GetFieldAddr(Instance)^,fRecordSize);
end;

function TSQLPropInfoRecordFixedSize.SetFieldSQLVar(Instance: TObject; const aValue: TSQLVar): boolean;
begin
if aValue.VType=ftBlob then begin
result := aValue.VBlobLen=fRecordSize;
if result then
{$ifdef FPC}Move{$else}MoveFast{$endif}(aValue.VBlob^,GetFieldAddr(Instance)^,fRecordSize)
MoveFast(aValue.VBlob^,GetFieldAddr(Instance)^,fRecordSize)
end else
result := inherited SetFieldSQLVar(Instance,aValue);
end;
end;
// TEXT format
SetLength(Result,Len);
{$ifdef FPC}Move{$else}MoveFast{$endif}(P^,pointer(Result)^,Len);
MoveFast(P^,pointer(Result)^,Len);
end;

function TSQLRawBlobToBlob(const RawBlob: TSQLRawBlob): RawUTF8;
U := @fResults[FieldCount+Field]; // start reading after first Row (= Field Names)
len := tmp.buf;
for i := 2 to fRowCount do begin
{$ifdef FPC}Move{$else}MoveFast{$endif}(U^^,P^,len^);
MoveFast(U^^,P^,len^);
inc(P,len^);
if SepLen>0 then begin
MoveSmall(pointer(Sep),P,SepLen);
inc(len);
inc(U,FieldCount); // go to next row
end;
{$ifdef FPC}Move{$else}MoveFast{$endif}(U^^,P^,len^); // last row without Sep
MoveFast(U^^,P^,len^); // last row without Sep
if Trail<>'' then
{$ifdef FPC}Move{$else}MoveFast{$endif}(pointer(Trail)^,P[len^],length(Trail));
MoveFast(pointer(Trail)^,P[len^],length(Trail));
tmp.Done;
end;

n := length(Tables);
if n>0 then begin
SetLength(fQueryTables,n);
{$ifdef FPC}Move{$else}MoveFast{$endif}(Tables[0],fQueryTables[0],n*SizeOf(TClass));
MoveFast(Tables[0],fQueryTables[0],n*SizeOf(TClass));
end;
end;

S := pointer(prev);
D := pointer(fJSONResults);
rowlen := result*SizeOf(pointer);
{$ifdef FPC}Move{$else}MoveFast{$endif}(S^,D^,rowlen);
MoveFast(S^,D^,rowlen);
inc(S,rowlen);
inc(D,rowlen);
PPUTF8Char(D)^ := pointer(FieldName);
inc(D,SizeOf(pointer));
for i := 1 to fRowCount do begin
{$ifdef FPC}Move{$else}MoveFast{$endif}(S^,D^,rowlen);
MoveFast(S^,D^,rowlen);
inc(S,rowlen);
inc(D,rowlen+SizeOf(pointer)); // leave new field value as D^=nil
end;
P := @V^[1];
end;
Line[L] := #0; // GetCaptionFromPCharLen() expect it as ASCIIZ
{$ifdef FPC}Move{$else}MoveFast{$endif}(P^,Line,L);
MoveFast(P^,Line,L);
GetCaptionFromPCharLen(Line,s);
Strings.AddObject(s,pointer(i));
end;
repeat
L := Lens[i-1];
if L<>0 then begin
{$ifdef FPC}Move{$else}MoveFast{$endif}(T.fResults[i]^,P^,L);
MoveFast(T.fResults[i]^,P^,L);
inc(P,L);
end;
if i=T.fRowCount then
break;
{$ifdef FPC}Move{$else}MoveFast{$endif}(pointer(Separator)^,P^,SepLen);
MoveFast(pointer(Separator)^,P^,SepLen);
inc(P,SepLen);
inc(i);
until false;
end;
dec(Count);
if index<Count then
{$ifdef FPC}Move{$else}MoveFast{$endif}(
List[index+1],List[index],(Count-index)*SizeOf(List[index]));
MoveFast(List[index+1],List[index],(Count-index)*SizeOf(List[index]));
end;

function TSQLRestClientCallbacks.UnRegister(aInstance: pointer): boolean;
result := pointer(GlobalAlloc(GMEM_FIXED,L)) else
{$endif}
GetMem(result,L);
{$ifdef FPC}Move{$else}MoveFast{$endif}(pointer(s)^,result^,L);
MoveFast(pointer(s)^,result^,L);
end;
end;
var call: TSQLRestURIParams;
class procedure TSQLRecordRTree.BlobToCoord(const InBlob;
var OutCoord: TSQLRecordTreeCoords);
begin // direct memory copy with no memory check
{$ifdef FPC}Move{$else}MoveFast{$endif}(
InBlob,OutCoord,(RecordProps.RTreeCoordBoundaryFields shr 1)*SizeOf(double));
MoveFast(InBlob,OutCoord,(RecordProps.RTreeCoordBoundaryFields shr 1)*SizeOf(double));
end;

class function TSQLRecordRTree.ContainedIn(const BlobA,BlobB): boolean;
class procedure TSQLRecordRTreeInteger.BlobToCoord(const InBlob;
var OutCoord: TSQLRecordTreeCoordsInteger);
begin // direct memory copy with no memory check
{$ifdef FPC}Move{$else}MoveFast{$endif}(
InBlob,OutCoord,(RecordProps.RTreeCoordBoundaryFields shr 1)*SizeOf(integer));
MoveFast(InBlob,OutCoord,(RecordProps.RTreeCoordBoundaryFields shr 1)*SizeOf(integer));
end;

class function TSQLRecordRTreeInteger.ContainedIn(const BlobA,BlobB): boolean;
resultType := ValueType;
if ValueType in [smvBoolean..smvCurrency] then
// ordinal/real result values to CPU/FPU registers
{$ifdef FPC}Move{$else}MoveFast{$endif}(V^,Result,SizeInStorage);
MoveFast(V^,Result,SizeInStorage);
end;
end;
if R=nil then
[self,aInterface^.Name]);
Instance := nil; // avoid GPF
if n>i then
{$ifdef FPC}Move{$else}MoveFast{$endif}(
GlobalInterfaceResolution[i+1],GlobalInterfaceResolution[i],
MoveFast(GlobalInterfaceResolution[i+1],GlobalInterfaceResolution[i],
(n-i)*SizeOf(GlobalInterfaceResolution[i]));
SetLength(GlobalInterfaceResolution,n);
exit;
s := ord(source[0]);
if d+s<254 then begin
dest[d+1] := ' ';
{$ifdef FPC}Move{$else}MoveFast{$endif}(source[1],dest[d+2],s);
MoveFast(source[1],dest[d+2],s);
inc(dest[0],s+1);
end;
end;
(ValueType in [smvRecord{$ifndef NOVARIANTS},smvVariant{$endif}]) then begin
// pass by reference
if (RegisterIdent=0) and (FPRegisterIdent=0) and (SizeInStack>0) then
{$ifdef FPC}Move{$else}MoveFast{$endif}(Value,Stack[InStackOffset],SizeInStack) else begin
MoveFast(Value,Stack[InStackOffset],SizeInStack) else begin
if RegisterIdent>0 then
call.ParamRegs[RegisterIdent] := PtrInt(Value);
if FPRegisterIdent>0 then
else begin
// pass by value
if (RegisterIdent=0) AND (FPRegisterIdent=0) AND (SizeInStack>0) then
{$ifdef FPC}Move{$else}MoveFast{$endif}(Value^,Stack[InStackOffset],SizeInStack) else begin
MoveFast(Value^,Stack[InStackOffset],SizeInStack) else begin
if (RegisterIdent>0) then begin
call.ParamRegs[RegisterIdent] := PPtrInt(Value)^;
{$ifdef CPUARM}
tmp.Init(n+2);
try
PAnsiChar(tmp.buf)[0] := '[';
{$ifdef FPC}Move{$else}MoveFast{$endif}(pointer(params)^,PAnsiChar(tmp.buf)[1],n);
MoveFast(pointer(params)^,PAnsiChar(tmp.buf)[1],n);
PWord(PAnsiChar(tmp.buf)+n+1)^ := ord(']'); // ']'#0
if output<>nil then begin
WR := TempTextWriter;

0 comments on commit 1557a36

Please sign in to comment.
You can’t perform that action at this time.