[fpc-devel] Remnants of VMT regeneration

Blaise at blaise.ru Blaise at blaise.ru
Sun Dec 1 19:33:56 CET 2019


TVMTBuilder.generate_vmt has
> 	_class.resetvmtentries;
and TVMTBuilder.generate_vmt_def has
> 	{ the VMT definition may already exist in case of generics }
> 	if assigned(try_search_current_module_type(vmtdefname)) then
> 	  exit;
Thus, it appears that VMT regeneration used to be supported/required.

1) In actuality, such regeneration does not currently happen: generate_vmt_def is private and is only invoked from generate_vmt, and generate_vmt is only invoked from:
	types_dec :objectdef
	generate_specialization_phase2 :objectdef
	jvm_maybe_create_enum_class
	jvm_create_procvar_class_intern
I.e. for any given def VMT generation happens only once.
2) Since SVN r41884, in which the insertion of hidden parameters was tightly coupled with VMT generation, the regeneration as-is cannot happen anyway: the call to insert_struct_hidden_paras from generate_vmt would yield
> Error: Duplicate identifier "$self"
3) From the performance standpoint, VMT regeneration is bad.

Given the above, I propose the remnants of VMT regeneration (or whatever this is) be removed.
Aside from leaner code, we will get a speed-up from not invoking try_search_current_module_type(vmtdefname) for every VMT generation (which would do addsymref, which looks suspicious to me in the context of skipping the creation of vmtdef in case of VMT regeneration).

-- 
βþ
-------------- next part --------------
# HG changeset patch
# User Blaise.ru
# Date 1565738542 -10800
#      14.08.2019 02:22:22 2019 +0300
# Node ID cd0e8ddf1ff089d8d0d1bcb2866de6b967298407
# Parent  932f6f48e6c6a5726ff45882e9e64db773a9b979
- remnants of VMT regeneration

diff -r 932f6f48e6c6 -r cd0e8ddf1ff0 nobj.pas
--- a/nobj.pas	01.12.2019 18:53:23 +0300
+++ b/nobj.pas	14.08.2019 02:22:22 +0300
@@ -801,7 +801,6 @@
         vmtdef: trecorddef;
         systemvmt: tdef;
         sym: tsym;
-        vmtdefname: TIDString;
       begin
         { these types don't have an actual VMT, we only use the other methods
           in TVMTBuilder to determine duplicates/overrides }
@@ -826,13 +825,9 @@
         if _class.objecttype = odt_cppclass then
           exit;
 
-        { the VMT definition may already exist in case of generics }
-        vmtdefname:=internaltypeprefixName[itp_vmtdef]+_class.mangledparaname;
-        if assigned(try_search_current_module_type(vmtdefname)) then
-          exit;
         { create VMT type definition }
         vmtdef:=crecorddef.create_global_internal(
-          vmtdefname,
+          internaltypeprefixName[itp_vmtdef]+_class.mangledparaname,
           0,
           target_info.alignment.recordalignmin);
 {$ifdef llvm}
@@ -906,8 +901,6 @@
         old_current_structdef:=current_structdef;
         current_structdef:=_class;
 
-        _class.resetvmtentries;
-
         { inherit (copy) VMT from parent object }
         if assigned(_class.childof) then
           _class.copyvmtentries(_class.childof);
diff -r 932f6f48e6c6 -r cd0e8ddf1ff0 symdef.pas
--- a/symdef.pas	01.12.2019 18:53:23 +0300
+++ b/symdef.pas	14.08.2019 02:22:22 +0300
@@ -493,7 +493,6 @@
           procedure buildderef;override;
           procedure deref;override;
           procedure derefimpl;override;
-          procedure resetvmtentries;
           procedure copyvmtentries(objdef:tobjectdef);
           function  getparentdef:tdef;override;
           function  size : asizeint;override;
@@ -7266,6 +7265,8 @@
 
 
     destructor tobjectdef.destroy;
+      var
+        i : longint;
       begin
          if assigned(symtable) then
            begin
@@ -7286,7 +7287,8 @@
            end;
          if assigned(vmtentries) then
            begin
-             resetvmtentries;
+             for i:=0 to vmtentries.Count-1 do
+               Dispose(pvmtentry(vmtentries[i]));
              vmtentries.Destroy;
              vmtentries:=nil;
            end;
@@ -7531,22 +7533,14 @@
       end;
 
 
-    procedure tobjectdef.resetvmtentries;
-      var
-        i : longint;
-      begin
-        for i:=0 to vmtentries.Count-1 do
-          Dispose(pvmtentry(vmtentries[i]));
-        vmtentries.clear;
-      end;
-
-
     procedure tobjectdef.copyvmtentries(objdef:tobjectdef);
       var
         i : longint;
         vmtentry : pvmtentry;
       begin
-        resetvmtentries;
+        if vmtentries.Count<>0 then
+          internalerror(2019081401);
+
         vmtentries.count:=objdef.vmtentries.count;
         for i:=0 to objdef.vmtentries.count-1 do
           begin


More information about the fpc-devel mailing list