mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-13 21:11:23 +02:00
* fixed genmultistringadd() optimization for jvm and enabled it
* created separate version of fpc_AnsiStr_Concat_multi() after all because it contains a punicodechar(unicodestring) typecast, which can't be supported on the JVM target (and splitting it out in the generic code seems like a bit overkill), and restored original generic version of fpc_AnsiStr_Concat_multi() (slightly faster than version partially adapted for jvm) git-svn-id: branches/jvmbackend@20903 -
This commit is contained in:
parent
1efee1d2eb
commit
8e3d7fe8d3
@ -2733,16 +2733,14 @@ implementation
|
||||
{$endif cpuneedsmulhelper}
|
||||
begin
|
||||
result:=nil;
|
||||
{$ifndef jvm}
|
||||
{ Can we optimize multiple string additions into a single call?
|
||||
This need to be done on a complete tree to detect the multiple
|
||||
add nodes and is therefor done before the subtrees are processed }
|
||||
if canbemultistringadd(self) then
|
||||
begin
|
||||
result := genmultistringadd(self);
|
||||
result:=genmultistringadd(self);
|
||||
exit;
|
||||
end;
|
||||
{$endif jvm}
|
||||
{ first do the two subtrees }
|
||||
firstpass(left);
|
||||
firstpass(right);
|
||||
|
@ -86,7 +86,9 @@ var
|
||||
|
||||
implementation
|
||||
|
||||
uses cutils, htypechk, defutil, defcmp, globtype, globals, cpubase, ncnv, ncon,ncal,nld,nmem,
|
||||
uses cutils, systems,
|
||||
htypechk, defutil, defcmp, globtype, globals, cpubase,
|
||||
ncnv, ncon, ncal, ninl, nld, nmem,
|
||||
verbose, symconst,symdef, cgbase, procinfo;
|
||||
|
||||
|
||||
@ -320,12 +322,9 @@ begin
|
||||
inserttypeconv(sn,p.resultdef);
|
||||
if is_shortstr then
|
||||
begin
|
||||
{$ifndef jvm}
|
||||
sn:=caddrnode.create(sn);
|
||||
include(sn.flags,nf_typedaddr);
|
||||
include(sn.flags,nf_internal);
|
||||
{$else not jvm}
|
||||
inserttypeconv_internal(sn,java_shortstring);
|
||||
{$endif jvm}
|
||||
end;
|
||||
arrp:=carrayconstructornode.create(sn,arrp);
|
||||
hp:=taddnode(hp).left;
|
||||
@ -367,6 +366,16 @@ begin
|
||||
result:=internalstatements(newstatement);
|
||||
tempnode:=ctempcreatenode.create(p.resultdef,p.resultdef.size,tt_persistent ,true);
|
||||
addstatement(newstatement,tempnode);
|
||||
{ initialize the temp, since it will be passed to a
|
||||
var-parameter (and finalization, which is performed by the
|
||||
ttempcreate node and which takes care of the initialization
|
||||
on native targets, is a noop on managed VM targets) }
|
||||
if (target_info.system in systems_managed_vm) and
|
||||
is_managed_type(p.resultdef) then
|
||||
addstatement(newstatement,cinlinenode.create(in_setlength_x,
|
||||
false,
|
||||
ccallparanode.create(genintconstnode(0),
|
||||
ccallparanode.create(ctemprefnode.create(tempnode),nil))));
|
||||
para:=ccallparanode.create(
|
||||
arrp,
|
||||
ccallparanode.create(ctemprefnode.create(tempnode),nil)
|
||||
|
@ -275,7 +275,7 @@ Var
|
||||
p,pc : pointer;
|
||||
Size,NewLen,
|
||||
OldDestLen : SizeInt;
|
||||
destcopy : RawByteString;
|
||||
destcopy : pointer;
|
||||
DestCP : TSystemCodePage;
|
||||
U : UnicodeString;
|
||||
sameCP : Boolean;
|
||||
@ -327,9 +327,10 @@ begin
|
||||
|
||||
DestS:='';
|
||||
widestringmanager.Unicode2AnsiMoveProc(PUnicodeChar(Pointer(U)),DestS,DestCP,Length(U));
|
||||
exit;
|
||||
exit;
|
||||
end;
|
||||
|
||||
destcopy:=nil;
|
||||
lowstart:=low(sarr);
|
||||
if Pointer(DestS)=Pointer(sarr[lowstart]) then
|
||||
inc(lowstart);
|
||||
@ -342,7 +343,8 @@ begin
|
||||
{ if DestS is used somewhere in the middle of the expression,
|
||||
we need to make sure the original string still exists after
|
||||
we empty/modify DestS }
|
||||
destcopy:=dests;
|
||||
destcopy:=pointer(dests);
|
||||
fpc_AnsiStr_Incr_Ref(destcopy);
|
||||
lowstart:=low(sarr);
|
||||
break;
|
||||
end;
|
||||
@ -362,18 +364,18 @@ begin
|
||||
SetCodePage(DestS,DestCP,False);
|
||||
{ Concat all strings, except the string we already
|
||||
copied in DestS }
|
||||
NewLen:=OldDestLen;
|
||||
pc:=Pointer(DestS);
|
||||
pc:=Pointer(DestS)+OldDestLen;
|
||||
for i:=lowstart to high(sarr) do
|
||||
begin
|
||||
p:=pointer(sarr[i]);
|
||||
if assigned(p) then
|
||||
begin
|
||||
Size:=length(ansistring(p));
|
||||
fpc_pchar_pchar_intern_charmove(pchar(p),0,pchar(pc),NewLen,Size+1);
|
||||
inc(NewLen,size);
|
||||
Move(p^,pc^,Size+1);
|
||||
inc(pc,size);
|
||||
end;
|
||||
end;
|
||||
fpc_AnsiStr_Decr_Ref(destcopy);
|
||||
end;
|
||||
{$endif FPC_HAS_ANSISTR_CONCAT_MULTI}
|
||||
|
||||
|
@ -298,13 +298,120 @@ begin
|
||||
temp:=S;
|
||||
Size:=Length(temp);
|
||||
widestringmanager.Unicode2AnsiMoveProc(PUnicodeChar(JLString(temp).toCharArray),result,cp,Size);
|
||||
AnsistringClass(result).fCodePage:=cp;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
Function fpc_AnsiStr_To_AnsiStr (const S : RawByteString;cp : TSystemCodePage): RawByteString; [external name 'fpc_ansistr_to_ansistr'];
|
||||
|
||||
{$define FPC_HAS_ANSISTR_CONCAT_MULTI}
|
||||
procedure fpc_AnsiStr_Concat_multi (var DestS:RawByteString;const sarr:array of RawByteString{$ifdef FPC_HAS_CPSTRING};cp : TSystemCodePage{$endif FPC_HAS_CPSTRING}); compilerproc;
|
||||
Var
|
||||
lowstart,i : Longint;
|
||||
p : pointer;
|
||||
Size,NewLen,
|
||||
OldDestLen : SizeInt;
|
||||
destcopy : RawByteString;
|
||||
DestCP : TSystemCodePage;
|
||||
U : UnicodeString;
|
||||
sameCP : Boolean;
|
||||
tmpStr : RawByteString;
|
||||
tmpCP : TSystemCodePage;
|
||||
begin
|
||||
if high(sarr)=0 then
|
||||
begin
|
||||
DestS:='';
|
||||
exit;
|
||||
end;
|
||||
{$ifdef FPC_HAS_CPSTRING}
|
||||
if (Pointer(DestS)=nil) then
|
||||
DestCP:=cp
|
||||
else
|
||||
DestCP:=StringCodePage(DestS);
|
||||
{$else FPC_HAS_CPSTRING}
|
||||
DestCP:=StringCodePage(DestS);
|
||||
{$endif FPC_HAS_CPSTRING}
|
||||
if (DestCP=CP_ACP) then
|
||||
DestCP:=DefaultSystemCodePage;
|
||||
sameCP:=true;
|
||||
lowstart:=low(sarr);
|
||||
for i:=lowstart to high(sarr) do
|
||||
begin
|
||||
tmpCP:=StringCodePage(sarr[i]);
|
||||
if tmpCP=CP_ACP then
|
||||
tmpCP:=DefaultSystemCodePage;
|
||||
if (DestCP<>tmpCp) then
|
||||
begin
|
||||
sameCP:=false;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
if not sameCP then
|
||||
begin
|
||||
U:='';
|
||||
for i:=lowstart to high(sarr) do begin
|
||||
tmpCP:=StringCodePage(sarr[i]);
|
||||
if (tmpCP=CP_ACP) then
|
||||
begin
|
||||
tmpStr:=sarr[i];
|
||||
SetCodePage(tmpStr,DefaultSystemCodePage,False);
|
||||
U:=U+UnicodeString(tmpStr);
|
||||
end
|
||||
else
|
||||
U:=U+UnicodeString(sarr[i]);
|
||||
end;
|
||||
|
||||
DestS:='';
|
||||
widestringmanager.Unicode2AnsiMoveProc(PUnicodeChar(JLString(U).toCharArray),DestS,DestCP,Length(U));
|
||||
exit;
|
||||
end;
|
||||
|
||||
lowstart:=low(sarr);
|
||||
if Pointer(DestS)=Pointer(sarr[lowstart]) then
|
||||
inc(lowstart);
|
||||
{ Check for another reuse, then we can't use
|
||||
the append optimization }
|
||||
for i:=lowstart to high(sarr) do
|
||||
begin
|
||||
if Pointer(DestS)=Pointer(sarr[i]) then
|
||||
begin
|
||||
{ if DestS is used somewhere in the middle of the expression,
|
||||
we need to make sure the original string still exists after
|
||||
we empty/modify DestS -- not necessary on JVM platform, ansistrings
|
||||
are not explicitly refrence counted there }
|
||||
lowstart:=low(sarr);
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
{ Start with empty DestS if we start with concatting
|
||||
the first array element }
|
||||
if lowstart=low(sarr) then
|
||||
DestS:='';
|
||||
OldDestLen:=length(DestS);
|
||||
{ Calculate size of the result so we can do
|
||||
a single call to SetLength() }
|
||||
NewLen:=0;
|
||||
for i:=low(sarr) to high(sarr) do
|
||||
inc(NewLen,length(sarr[i]));
|
||||
SetLength(DestS,NewLen);
|
||||
if (StringCodePage(DestS) <> DestCP) then
|
||||
SetCodePage(DestS,DestCP,False);
|
||||
{ Concat all strings, except the string we already
|
||||
copied in DestS }
|
||||
NewLen:=OldDestLen;
|
||||
for i:=lowstart to high(sarr) do
|
||||
begin
|
||||
p:=pointer(sarr[i]);
|
||||
if assigned(p) then
|
||||
begin
|
||||
Size:=length(ansistring(p));
|
||||
fpc_pchar_pchar_intern_charmove(pchar(ansistring(p)),0,pchar(DestS),NewLen,Size+1);
|
||||
inc(NewLen,size);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{$define FPC_HAS_ANSISTR_TO_SHORTSTR}
|
||||
procedure fpc_AnsiStr_To_ShortStr (out res: shortstring; const S2 : RawByteString);[Public, alias: 'FPC_ANSISTR_TO_SHORTSTR']; compilerproc;
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user