Browse Source

Use FillChar in InitializeArray.

Rika Ichinose 10 months ago
parent
commit
91d3746adf
3 changed files with 41 additions and 58 deletions
  1. 3 3
      rtl/inc/dynarr.inc
  2. 37 53
      rtl/inc/rtti.inc
  3. 1 2
      rtl/inc/rttidecl.inc

+ 3 - 3
rtl/inc/dynarr.inc

@@ -182,7 +182,7 @@ procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
        begin
        begin
           newp:=AllocMem(size);
           newp:=AllocMem(size);
           { call int_InitializeArray for management operators; not required if no operators as memory is already zeroed }
           { call int_InitializeArray for management operators; not required if no operators as memory is already zeroed }
-          if assigned(eletypemngd) and (PTypeKind(eletype)^ in [tkRecord, tkObject, tkArray]) and (RTTIManagementAndSize(eletype, rotInitialize, _size, manCustom)=manCustom) then
+          if assigned(eletypemngd) and (PTypeKind(eletype)^ in [tkRecord, tkObject, tkArray]) and (RTTIManagementAndSize(eletype, rotInitialize, _size, true)) then
             int_InitializeArray(pointer(newp)+sizeof(tdynarray), eletype, dims[0]);
             int_InitializeArray(pointer(newp)+sizeof(tdynarray), eletype, dims[0]);
        end
        end
      else
      else
@@ -204,7 +204,7 @@ procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
                if size-sizeof(tdynarray)>movsize then
                if size-sizeof(tdynarray)>movsize then
                  begin
                  begin
                    fillchar((pointer(newp)+sizeof(tdynarray)+movsize)^,size-sizeof(tdynarray)-movsize,0);
                    fillchar((pointer(newp)+sizeof(tdynarray)+movsize)^,size-sizeof(tdynarray)-movsize,0);
-                   if assigned(eletypemngd) and (PTypeKind(eletype)^ in [tkRecord, tkObject, tkArray]) and (RTTIManagementAndSize(eletype, rotInitialize, _size, manCustom)=manCustom) then
+                   if assigned(eletypemngd) and (PTypeKind(eletype)^ in [tkRecord, tkObject, tkArray]) and (RTTIManagementAndSize(eletype, rotInitialize, _size, true)) then
                      int_InitializeArray(pointer(newp)+sizeof(tdynarray)+movsize, eletype, dims[0]-movelen);
                      int_InitializeArray(pointer(newp)+sizeof(tdynarray)+movsize, eletype, dims[0]-movelen);
                  end;
                  end;
 
 
@@ -238,7 +238,7 @@ procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
                newp := realp;
                newp := realp;
                fillchar((pointer(newp)+sizeof(tdynarray)+elesize*(newp^.high+1))^,
                fillchar((pointer(newp)+sizeof(tdynarray)+elesize*(newp^.high+1))^,
                  (dims[0]-newp^.high-1)*elesize,0);
                  (dims[0]-newp^.high-1)*elesize,0);
-               if assigned(eletypemngd) and (PTypeKind(eletype)^ in [tkRecord, tkObject, tkArray]) and (RTTIManagementAndSize(eletype, rotInitialize, _size, manCustom)=manCustom) then
+               if assigned(eletypemngd) and (PTypeKind(eletype)^ in [tkRecord, tkObject, tkArray]) and (RTTIManagementAndSize(eletype, rotInitialize, _size, true)) then
                  int_InitializeArray(pointer(newp)+sizeof(tdynarray)+elesize*(newp^.high+1),
                  int_InitializeArray(pointer(newp)+sizeof(tdynarray)+elesize*(newp^.high+1),
                    eletype, dims[0]-newp^.high-1);
                    eletype, dims[0]-newp^.high-1);
             end;
             end;

+ 37 - 53
rtl/inc/rtti.inc

@@ -29,56 +29,52 @@ begin
   end
   end
 end;
 end;
 
 
-{ result = manBuiltin means e.g. that initialization is simply zeroing and can be omitted if the memory is already zeroed, as in dynarr.inc. }
-function RTTIManagementAndSize(typeInfo: Pointer; op: TRTTIRecOpType; out size: SizeInt; maxInteresting: TRTTIManagement): TRTTIManagement;
 const
 const
-  Special = 49;
-  ManagedSizes: array[TTypeKind] of uint8 = { 0 — unmanaged, Special — special, otherwise manBuiltin of that size. }
+  RTTISpecialSize = 49;
+  RTTIManagedSizes: array[TTypeKind] of uint8 = { 0 — unmanaged, RTTISpecialSize — special (array/record/object), otherwise manBuiltin of that size. }
   (
   (
     {tkUnknown} 0, {tkInteger} 0, {tkChar} 0, {tkEnumeration} 0, {tkFloat} 0,
     {tkUnknown} 0, {tkInteger} 0, {tkChar} 0, {tkEnumeration} 0, {tkFloat} 0,
     {tkSet} 0, {tkMethod} 0, {tkSString} 0, {tkLString} 0, {tkAString} sizeof(pointer),
     {tkSet} 0, {tkMethod} 0, {tkSString} 0, {tkLString} 0, {tkAString} sizeof(pointer),
-    {tkWString} sizeof(pointer), {tkVariant} {$ifdef FPC_HAS_FEATURE_VARIANTS} sizeof(TVarData) {$else} 0 {$endif}, {tkArray} Special, {tkRecord} Special, {tkInterface} sizeof(pointer),
-    {tkClass} 0, {tkObject} Special, {tkWChar} 0, {tkBool} 0, {tkInt64} 0, {tkQWord} 0,
+    {tkWString} sizeof(pointer), {tkVariant} {$ifdef FPC_HAS_FEATURE_VARIANTS} sizeof(TVarData) {$else} 0 {$endif}, {tkArray} RTTISpecialSize, {tkRecord} RTTISpecialSize, {tkInterface} sizeof(pointer),
+    {tkClass} 0, {tkObject} RTTISpecialSize, {tkWChar} 0, {tkBool} 0, {tkInt64} 0, {tkQWord} 0,
     {tkDynArray} sizeof(pointer), {tkInterfaceRaw} 0, {tkProcVar} 0, {tkUString} sizeof(pointer), {tkUChar} 0,
     {tkDynArray} sizeof(pointer), {tkInterfaceRaw} 0, {tkProcVar} 0, {tkUString} sizeof(pointer), {tkUChar} 0,
     {tkHelper} 0, {tkFile} 0, {tkClassRef} 0, {tkPointer} 0
     {tkHelper} 0, {tkFile} 0, {tkClassRef} 0, {tkPointer} 0
   );
   );
+
+{ onlyCustomOps = false: returns true if the type requires any management regarding op.
+  onlyCustomOps = true: returns true if the type has custom op, used in dynarr.inc to avoid initialization of zeroed memory. }
+function RTTIManagementAndSize(typeInfo: Pointer; op: TRTTIRecOpType; out size: SizeInt; onlyCustomOps: boolean): boolean;
 var
 var
   ri: PRecordInfoInit;
   ri: PRecordInfoInit;
   elem: PRecordElement;
   elem: PRecordElement;
-  newMan: TRTTIManagement;
   elemCount,sample,_size: SizeInt;
   elemCount,sample,_size: SizeInt;
 begin
 begin
-  sample:=ManagedSizes[PTypeKind(typeinfo)^];
+  sample:=RTTIManagedSizes[PTypeKind(typeinfo)^];
   size:=sample;
   size:=sample;
-  if sample<>Special then
-    result:=TRTTIManagement(ord(sample<>0)) { manNone(0) if sample = 0, manBuiltin(1) otherwise. }
+  if sample<>RTTISpecialSize then
+    result:=not onlyCustomOps and (sample<>0)
   else if PTypeKind(typeinfo)^=tkArray then
   else if PTypeKind(typeinfo)^=tkArray then
     begin
     begin
       typeInfo:=aligntoqword(typeInfo+2+PByte(typeInfo)[1]);
       typeInfo:=aligntoqword(typeInfo+2+PByte(typeInfo)[1]);
       size:=PArrayInfo(typeInfo)^.Size;
       size:=PArrayInfo(typeInfo)^.Size;
-      result:=RTTIManagementAndSize(PArrayInfo(typeInfo)^.ElInfo^, op, _size, maxInteresting);
+      result:=RTTIManagementAndSize(PArrayInfo(typeInfo)^.ElInfo^, op, _size, onlyCustomOps);
     end
     end
   else {tkObject, tkRecord}
   else {tkObject, tkRecord}
     begin
     begin
       ri:=RTTIRecordInfoInit(typeInfo);
       ri:=RTTIRecordInfoInit(typeInfo);
       size:=ri^.Size;
       size:=ri^.Size;
-      if Assigned(ri^.RecordOp) and Assigned(ri^.RecordOp^.Ops[op]) then
-        exit(manCustom);
-      result:=manNone;
+      result:=Assigned(ri^.RecordOp) and Assigned(ri^.RecordOp^.Ops[op]);
+      if result then
+        exit;
       elem:=AlignTypeData(Pointer(@ri^.Count)+SizeOf(ri^.Count));
       elem:=AlignTypeData(Pointer(@ri^.Count)+SizeOf(ri^.Count));
       for elemCount:=ri^.Count downto 1 do
       for elemCount:=ri^.Count downto 1 do
         begin
         begin
-          sample:=ManagedSizes[PTypeKind(elem^.TypeInfo^)^];
-          if sample<>Special then
-            newMan:=TRTTIManagement(ord(sample<>0)) { Avoid recursive call for simple fields. }
-          else
-            newMan:=RTTIManagementAndSize(elem^.TypeInfo^, op, _size, maxInteresting);
-          if newMan>result then
-            begin
-              result:=newMan;
-              if newMan>=maxInteresting then
-                break;
-            end;
+          sample:=RTTIManagedSizes[PTypeKind(elem^.TypeInfo^)^]; { Avoid recursive call for simple fields. }
+          result:=not onlyCustomOps and (sample<>0); { And generally speculate simple field. }
+          if sample=RTTISpecialSize then
+            result:=RTTIManagementAndSize(elem^.TypeInfo^, op, _size, onlyCustomOps);
+          if result then
+            exit;
           inc(elem);
           inc(elem);
         end;
         end;
     end;
     end;
@@ -106,24 +102,6 @@ begin
   Result:=PRecordInfoInit(ti)^.InitRecordOpTable;
   Result:=PRecordInfoInit(ti)^.InitRecordOpTable;
 end;
 end;
 
 
-{ if you modify this procedure, fpc_copy must be probably modified as well }
-procedure ArrayRTTI(Data,TypeInfo:Pointer;rttiproc:TRTTIProc);
-var
-  i,Count,ElSize: SizeInt;
-  Info: Pointer;
-begin
-  typeInfo:=aligntoqword(typeInfo+2+PByte(typeInfo)[1]);
-  Count:=PArrayInfo(typeInfo)^.ElCount;
-  { no elements to process => exit }
-  if Count = 0 then
-    Exit;
-  ElSize:=PArrayInfo(typeInfo)^.Size div Count;
-  Info:=PArrayInfo(typeInfo)^.ElInfo^;
-  { Process elements }
-  for I:=0 to Count-1 do
-    rttiproc(Data+(I*ElSize),Info);
-end;
-
 Procedure fpc_Initialize (Data,TypeInfo : pointer);[Public,Alias : 'FPC_INITIALIZE'];  compilerproc;
 Procedure fpc_Initialize (Data,TypeInfo : pointer);[Public,Alias : 'FPC_INITIALIZE'];  compilerproc;
 var
 var
   ri: PRecordInfoInit;
   ri: PRecordInfoInit;
@@ -141,7 +119,8 @@ begin
     tkInterface:
     tkInterface:
       PPAnsiChar(Data)^:=Nil;
       PPAnsiChar(Data)^:=Nil;
     tkArray:
     tkArray:
-      arrayrtti(data,typeinfo,@int_initialize);
+      with PArrayInfo(aligntoqword(typeInfo+2+PByte(typeInfo)[1]))^ do
+        int_InitializeArray(data,ElInfo^,ElCount);
 {$ifdef FPC_HAS_FEATURE_OBJECTS}
 {$ifdef FPC_HAS_FEATURE_OBJECTS}
     tkObject,
     tkObject,
 {$endif FPC_HAS_FEATURE_OBJECTS}
 {$endif FPC_HAS_FEATURE_OBJECTS}
@@ -178,7 +157,8 @@ begin
   {$endif FPC_WIDESTRING_EQUAL_UNICODESTRING}
   {$endif FPC_WIDESTRING_EQUAL_UNICODESTRING}
 {$endif FPC_HAS_FEATURE_WIDESTRINGS}
 {$endif FPC_HAS_FEATURE_WIDESTRINGS}
     tkArray :
     tkArray :
-      arrayrtti(data,typeinfo,@int_finalize);
+      with PArrayInfo(aligntoqword(typeInfo+2+PByte(typeInfo)[1]))^ do
+        int_FinalizeArray(data,ElInfo^,ElCount);
 {$ifdef FPC_HAS_FEATURE_OBJECTS}
 {$ifdef FPC_HAS_FEATURE_OBJECTS}
     tkObject,
     tkObject,
 {$endif FPC_HAS_FEATURE_OBJECTS}
 {$endif FPC_HAS_FEATURE_OBJECTS}
@@ -223,7 +203,8 @@ begin
       fpc_UnicodeStr_Incr_Ref(PPointer(Data)^);
       fpc_UnicodeStr_Incr_Ref(PPointer(Data)^);
 {$endif FPC_HAS_FEATURE_WIDESTRINGS}
 {$endif FPC_HAS_FEATURE_WIDESTRINGS}
     tkArray :
     tkArray :
-      arrayrtti(data,typeinfo,@int_addref);
+      with PArrayInfo(aligntoqword(typeInfo+2+PByte(typeInfo)[1]))^ do
+        int_AddRefArray(data,ElInfo^,ElCount);
 {$ifdef FPC_HAS_FEATURE_OBJECTS}
 {$ifdef FPC_HAS_FEATURE_OBJECTS}
     tkobject,
     tkobject,
 {$endif FPC_HAS_FEATURE_OBJECTS}
 {$endif FPC_HAS_FEATURE_OBJECTS}
@@ -373,9 +354,12 @@ end;
 
 
 procedure fpc_initialize_array(data,typeinfo : pointer;count : SizeInt); [public,alias:'FPC_INITIALIZE_ARRAY']; compilerproc;
 procedure fpc_initialize_array(data,typeinfo : pointer;count : SizeInt); [public,alias:'FPC_INITIALIZE_ARRAY']; compilerproc;
   var
   var
-    i, size : SizeInt;
+    sample,size,i : SizeInt;
   begin
   begin
-    if RTTIManagementAndSize(typeinfo, rotInitialize, size, manBuiltin)<>manNone then
+    sample:=RTTIManagedSizes[PTypeKind(typeinfo)^];
+    if sample<>RTTISpecialSize then
+      FillChar(data^,sample*count,0)
+    else if RTTIManagementAndSize(typeinfo, rotInitialize, size, false) then
       for i:=0 to count-1 do
       for i:=0 to count-1 do
         int_initialize(data+size*i,typeinfo);
         int_initialize(data+size*i,typeinfo);
   end;
   end;
@@ -383,9 +367,9 @@ procedure fpc_initialize_array(data,typeinfo : pointer;count : SizeInt); [public
 
 
 procedure fpc_finalize_array(data,typeinfo : pointer;count : SizeInt); [Public,Alias:'FPC_FINALIZE_ARRAY'];  compilerproc;
 procedure fpc_finalize_array(data,typeinfo : pointer;count : SizeInt); [Public,Alias:'FPC_FINALIZE_ARRAY'];  compilerproc;
   var
   var
-    i, size : SizeInt;
+    size,i : SizeInt;
   begin
   begin
-    if RTTIManagementAndSize(typeinfo, rotFinalize, size, manBuiltin)<>manNone then
+    if RTTIManagementAndSize(typeinfo, rotFinalize, size, false) then
       for i:=0 to count-1 do
       for i:=0 to count-1 do
         int_finalize(data+size*i,typeinfo);
         int_finalize(data+size*i,typeinfo);
   end;
   end;
@@ -393,9 +377,9 @@ procedure fpc_finalize_array(data,typeinfo : pointer;count : SizeInt); [Public,A
 
 
 procedure fpc_addref_array(data,typeinfo: pointer; count: SizeInt); [public,alias:'FPC_ADDREF_ARRAY']; compilerproc;
 procedure fpc_addref_array(data,typeinfo: pointer; count: SizeInt); [public,alias:'FPC_ADDREF_ARRAY']; compilerproc;
   var
   var
-    i, size : SizeInt;
+    size,i : SizeInt;
   begin
   begin
-    if RTTIManagementAndSize(typeinfo, rotAddRef, size, manBuiltin)<>manNone then
+    if RTTIManagementAndSize(typeinfo, rotAddRef, size, false) then
       for i:=0 to count-1 do
       for i:=0 to count-1 do
         int_addref(data+size*i,typeinfo);
         int_addref(data+size*i,typeinfo);
   end;
   end;
@@ -421,7 +405,7 @@ procedure CopyArray(dest, source, typeInfo: Pointer; count: SizeInt);
   var
   var
     i, size: SizeInt;
     i, size: SizeInt;
   begin
   begin
-    if RTTIManagementAndSize(typeinfo, rotCopy, size, manBuiltin)<>manNone then
+    if RTTIManagementAndSize(typeinfo, rotCopy, size, false) then
       for i:=0 to count-1 do
       for i:=0 to count-1 do
         int_Copy(source+size*i, dest+size*i, typeInfo);
         int_Copy(source+size*i, dest+size*i, typeInfo);
   end;
   end;

+ 1 - 2
rtl/inc/rttidecl.inc

@@ -74,7 +74,6 @@ type
   TRTTIRecVarOp=procedure(ARec: Pointer);
   TRTTIRecVarOp=procedure(ARec: Pointer);
   TRTTIRecCopyOp=procedure(ASrc, ADest: Pointer);
   TRTTIRecCopyOp=procedure(ASrc, ADest: Pointer);
   TRTTIRecOpType=(rotInitialize, rotFinalize, rotAddRef, rotCopy);
   TRTTIRecOpType=(rotInitialize, rotFinalize, rotAddRef, rotCopy);
-  TRTTIManagement=(manNone, manBuiltin, manCustom);
   PRTTIRecordOpVMT=^TRTTIRecordOpVMT;
   PRTTIRecordOpVMT=^TRTTIRecordOpVMT;
   TRTTIRecordOpVMT=
   TRTTIRecordOpVMT=
 {$ifdef USE_PACKED}
 {$ifdef USE_PACKED}
@@ -157,7 +156,7 @@ type
       );
       );
   end;
   end;
 
 
-function RTTIManagementAndSize(typeInfo: Pointer; op: TRTTIRecOpType; out size: SizeInt; maxInteresting: TRTTIManagement): TRTTIManagement; forward;
+function RTTIManagementAndSize(typeInfo: Pointer; op: TRTTIRecOpType; out size: SizeInt; onlyCustomOps: boolean): boolean; forward;
 function RTTIRecordMopInitTable(ti: Pointer): PRTTIRecordOpOffsetTable; forward;
 function RTTIRecordMopInitTable(ti: Pointer): PRTTIRecordOpOffsetTable; forward;
 
 
 {$pop}
 {$pop}