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). -- βþ
# 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
_______________________________________________ fpc-devel maillist - fpc-devel@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel