فهرست منبع

+ i386 assembler versions of decr_ansistring and unique_ansistring

git-svn-id: trunk@1963 -
florian 19 سال پیش
والد
کامیت
e2a4dac215
4فایلهای تغییر یافته به همراه89 افزوده شده و 5 حذف شده
  1. 77 0
      rtl/i386/i386.inc
  2. 9 3
      rtl/inc/astrings.inc
  3. 1 1
      rtl/inc/compproc.inc
  4. 2 1
      rtl/inc/heap.inc

+ 77 - 0
rtl/i386/i386.inc

@@ -1145,5 +1145,82 @@ asm
     fwait
 end;
 
+{$define FPC_SYSTEM_HAS_ANSISTR_DECR_REF}
+function fpc_freemem_x(p:pointer):ptrint; [external name 'FPC_FREEMEM_X'];
 
+Procedure fpc_AnsiStr_Decr_Ref (Var S : Pointer); [Public,Alias:'FPC_ANSISTR_DECR_REF']; compilerproc; nostackframe; assembler;
+asm
+  cmpl $0,(%eax)
+  jne .Ldecr_ref_continue
+  ret
+.Ldecr_ref_continue:
+// Temps allocated between ebp-24 and ebp+0
+	subl	$4,%esp
+// Var S located in register
+// Var l located in register
+	movl	%eax,(%esp)
+.Lj3599:
+// [101] l:=@PAnsiRec(S-FirstOff)^.Ref;
+	movl	(%esp),%edx
+	movl	(%edx),%edx
+	subl	$8,%edx
+// [102] If l^<0 then exit;
+	movl	(%edx),%eax
+	testl	%eax,%eax
+	jl	.Lj3596
+.Lj3603:
+// [104] If declocked(l^) then	
+	movb	ismultithread,%al
+	testb	%al,%al
+	jne	.Lj3610
+	decl	(%edx)
+	je .Lj3620
+	addl $4,%esp
+	ret
+.Lj3610:
+	movl	%edx,%eax
+	call	cpudeclocked
+	movb	%al,%cl
+.Lj3613:
+	testb	%cl,%cl
+	je	.Lj3605
+.Lj3620:
+	movl	(%esp),%eax
+	movl	(%eax),%eax
+	subl  $8,%eax
+	call	FPC_FREEMEM_X
+	movl	(%esp),%eax
+	movl	$0,(%eax)
+.Lj3618:
+.Lj3605:
+.Lj3596:
+// [107] end;
+  addl $4,%esp
+end;
+
+function fpc_truely_ansistr_unique(Var S : Pointer): Pointer; forward;
+
+{$define FPC_SYSTEM_HAS_ANSISTR_UNIQUE}
+Function fpc_ansistr_Unique(Var S : Pointer): Pointer; [Public,Alias : 'FPC_ANSISTR_UNIQUE']; compilerproc; nostackframe;assembler;
+asm
+// Var S located in register
+// Var $result located in register
+	movl	%eax,%edx
+// [437] pointer(result) := pointer(s);
+	movl	(%eax),%eax
+// [438] If Pointer(S)=Nil then
+	testl	%eax,%eax
+	je	.Lj4031
+.Lj4036:
+// [440] if PAnsiRec(Pointer(S)-Firstoff)^.Ref<>1 then	
+	movl	-8(%eax),%ecx
+	cmpl	$1,%ecx
+	je	.Lj4038
+// [441] result:=fpc_truely_ansistr_unique(s);
+	movl	%edx,%eax
+	call	fpc_truely_ansistr_unique
+.Lj4038:
+.Lj4031:
+// [442] end;
+end;
 

+ 9 - 3
rtl/inc/astrings.inc

@@ -85,6 +85,7 @@ begin
   S:=Nil;
 end;
 
+{$ifndef FPC_SYSTEM_HAS_ANSISTR_DECR_REF}
 Procedure fpc_AnsiStr_Decr_Ref (Var S : Pointer); [Public,Alias:'FPC_ANSISTR_DECR_REF'];  compilerproc;
 {
   Decreases the ReferenceCount of a non constant ansistring;
@@ -106,6 +107,8 @@ Begin
     DisposeAnsiString (S);        { Remove...}
 end;
 
+{$endif FPC_SYSTEM_HAS_ANSISTR_DECR_REF}
+
 { also define alias for internal use in the system unit }
 Procedure fpc_AnsiStr_Decr_Ref (Var S : Pointer); [external name 'FPC_ANSISTR_DECR_REF'];
 
@@ -118,6 +121,7 @@ Begin
   inclocked(PAnsiRec(S-FirstOff)^.Ref);
 end;
 
+
 { also define alias which can be used inside the system unit }
 Procedure fpc_AnsiStr_Incr_Ref (S : Pointer); [external name 'FPC_ANSISTR_INCR_REF'];
 
@@ -410,12 +414,10 @@ end;
                      Public functions, In interface.
 *****************************************************************************}
 
-function fpc_truely_ansistr_unique(Var S : Pointer): Pointer;
-
+function fpc_truely_ansistr_unique(Var S : Pointer): Pointer; 
 Var
   SNew : Pointer;
   L    : SizeInt;
-
 begin
   L:=PAnsiRec(Pointer(S)-FirstOff)^.len;
   SNew:=NewAnsiString (L);
@@ -426,6 +428,8 @@ begin
   pointer(result):=SNew;
 end;
 
+
+{$ifndef FPC_SYSTEM_HAS_ANSISTR_UNIQUE}
 // MV: inline the basic checks for case that S is already unique.
 // Rest is too complex to inline, so factor that out as a call.
 Function fpc_ansistr_Unique(Var S : Pointer): Pointer; [Public,Alias : 'FPC_ANSISTR_UNIQUE']; compilerproc; {$IFNDEF VER2_0} Inline; {$ENDIF}
@@ -440,6 +444,8 @@ begin
   if PAnsiRec(Pointer(S)-Firstoff)^.Ref<>1 then
     result:=fpc_truely_ansistr_unique(s);
 end;
+{$endif FPC_SYSTEM_HAS_ANSISTR_UNIQUE}
+
 
 Procedure fpc_ansistr_append_char(Var S : AnsiString;c : char); [Public,Alias : 'FPC_ANSISTR_APPEND_CHAR']; compilerproc;
 begin

+ 1 - 1
rtl/inc/compproc.inc

@@ -131,7 +131,7 @@ Function fpc_AnsiStr_ShortStr_Compare (Var S1 : Pointer; Var S2 : ShortString):
 { pointer argument because otherwise when calling this, we get }
 { an endless loop since a 'var s: ansistring' must be made     }
 { unique as well                                               }
-Function fpc_ansistr_Unique(Var S : Pointer): Pointer; compilerproc;
+Function fpc_ansistr_Unique(Var S : Pointer): Pointer; compilerproc; {$IFNDEF VER2_0} Inline; {$ENDIF}
 
 Procedure fpc_WideStr_Decr_Ref (Var S : Pointer); compilerproc;
 Procedure fpc_WideStr_Incr_Ref (S : Pointer); compilerproc;

+ 2 - 1
rtl/inc/heap.inc

@@ -315,7 +315,7 @@ end;
 
 
 { Delphi style }
-function FreeMem(p:pointer):ptrint;
+function FreeMem(p:pointer):ptrint;[Public,Alias:'FPC_FREEMEM_X'];
 begin
   if IsMultiThread and MemoryManager.NeedLock then
    begin
@@ -332,6 +332,7 @@ begin
    end;
 end;
 
+
 function FreeMemory(p:pointer):ptrint;
 
 begin