Browse Source

* optimize class initialization by calling RTTIRecord() only when required for a non-trivial initialization

git-svn-id: trunk@39256 -
svenbarth 7 years ago
parent
commit
4d0ab82ef7
3 changed files with 27 additions and 4 deletions
  1. 14 4
      rtl/inc/objpas.inc
  2. 9 0
      rtl/inc/rtti.inc
  3. 4 0
      rtl/inc/rttidecl.inc

+ 14 - 4
rtl/inc/objpas.inc

@@ -383,6 +383,7 @@
         var
            vmt  : PVmt;
            temp : pointer;
+           flags : TRecordInfoInitFlags;
 {$endif FPC_HAS_MANAGEMENT_OPERATORS}
         begin
            { the size is saved at offset 0 }
@@ -399,10 +400,19 @@
            while vmt<>nil do
              begin
                Temp:= vmt^.vInitTable;
-               { The RTTI format matches one for records, except the type is tkClass.
-                 Since RecordRTTI does not check the type, calling it yields the desired result. }
-               if Assigned(Temp) then
-                 RecordRTTI(Instance,Temp,@int_initialize);
+               if assigned(Temp) then
+                 begin
+                   flags:=RecordRTTIInitFlags(Temp);
+                   if riifNonTrivialChild in flags then
+                     { The RTTI format matches one for records, except the type
+                       is tkClass. Since RecordRTTI does not check the type,
+                       calling it yields the desired result. }
+                     RecordRTTI(Instance,Temp,@int_initialize);
+                   { no need to continue complex initializing up the inheritance
+                     tree if none of the parents require it anyway }
+                   if not (riifParentHasNonTrivialChild in flags) then
+                     break;
+                 end;
                vmt:= vmt^.vParent;
              end;
 {$endif FPC_HAS_MANAGEMENT_OPERATORS}

+ 9 - 0
rtl/inc/rtti.inc

@@ -137,6 +137,15 @@ begin
 end;
 
 
+{$ifndef VER3_0}
+function RecordRTTIInitFlags(ti: Pointer): TRecordInfoInitFlags;
+begin
+  ti:=aligntoqword(ti+2+PByte(ti)[1]);
+  Result:=PRecordInfoInit(ti)^.Flags;
+end;
+{$endif VER3_0}
+
+
 { if you modify this procedure, fpc_copy must be probably modified as well }
 {$ifdef VER2_6}
 procedure ArrayRTTI(Data,TypeInfo:Pointer;rttiproc:TRTTIProc);

+ 4 - 0
rtl/inc/rttidecl.inc

@@ -149,6 +149,10 @@ type
   end;
 
 
+{$ifndef VER3_0}
+function RecordRTTIInitFlags(ti: Pointer): TRecordInfoInitFlags; forward;
+{$endif VER3_0}
+
 {$ifdef VER3_0}
 {$MINENUMSIZE DEFAULT}
 {$PACKSET DEFAULT}