* removed the DWARF label fields from tdef/tobjectdef, and dynamically

allocate them only while necessary
   o also unified the conditions under which we allocate a separate
     struct label

git-svn-id: trunk@32045 -
This commit is contained in:
Jonas Maebe 2015-10-13 15:59:03 +00:00
parent 67b958bb32
commit 91be1d0f2d
3 changed files with 66 additions and 35 deletions

View File

@ -276,6 +276,17 @@ interface
bit8: boolean; bit8: boolean;
end; end;
TDwarfHashSetItem = record
HashSetItem: THashSetItem;
lab, ref_lab: tasmsymbol;
struct_lab: tasmsymbol;
end;
PDwarfHashSetItem = ^TDwarfHashSetItem;
TDwarfLabHashSet = class(THashSet)
class function SizeOfItem: Integer; override;
end;
{ TDebugInfoDwarf } { TDebugInfoDwarf }
TDebugInfoDwarf = class(TDebugInfo) TDebugInfoDwarf = class(TDebugInfo)
@ -293,6 +304,9 @@ interface
loclist: tdynamicarray; loclist: tdynamicarray;
asmline: TAsmList; asmline: TAsmList;
{ lookup table for def -> DWARF-labels }
dwarflabels: TDwarfLabHashSet;
// The current entry in dwarf_info with the link to the abbrev-section // The current entry in dwarf_info with the link to the abbrev-section
dwarf_info_abbref_tai: tai_const; dwarf_info_abbref_tai: tai_const;
// Empty start-item of the abbrev-searchtree // Empty start-item of the abbrev-searchtree
@ -328,7 +342,7 @@ interface
procedure set_use_64bit_headers(state: boolean); procedure set_use_64bit_headers(state: boolean);
property use_64bit_headers: Boolean read _use_64bit_headers write set_use_64bit_headers; property use_64bit_headers: Boolean read _use_64bit_headers write set_use_64bit_headers;
procedure set_def_dwarf_labs(def:tdef); function get_def_dwarf_labs(def:tdef): PDwarfHashSetItem;
{ Convenience version of the method below, so the compiler creates the { Convenience version of the method below, so the compiler creates the
tvarrec for us (must only pass one element in the last parameter). } tvarrec for us (must only pass one element in the last parameter). }
@ -719,6 +733,16 @@ implementation
Dispose(SI); Dispose(SI);
end; end;
{****************************************************************************
TDwarfLabHashSet
****************************************************************************}
class function TDwarfLabHashSet.SizeOfItem: Integer;
begin
Result:=sizeof(TDwarfHashSetItem);
end;
{**************************************************************************** {****************************************************************************
TDirIndexItem TDirIndexItem
****************************************************************************} ****************************************************************************}
@ -915,7 +939,9 @@ implementation
end; end;
procedure TDebugInfoDwarf.set_def_dwarf_labs(def:tdef); function TDebugInfoDwarf.get_def_dwarf_labs(def:tdef): PDwarfHashSetItem;
var
needstructdeflab: boolean;
begin begin
{ Keep track of used dwarf entries, this info is only useful for dwarf entries { Keep track of used dwarf entries, this info is only useful for dwarf entries
referenced by the symbols. Definitions will always include all referenced by the symbols. Definitions will always include all
@ -923,18 +949,23 @@ implementation
if def.dbg_state=dbg_state_unused then if def.dbg_state=dbg_state_unused then
def.dbg_state:=dbg_state_used; def.dbg_state:=dbg_state_used;
{ Need a new label? } { Need a new label? }
if not assigned(def.dwarf_lab) then result:=PDwarfHashSetItem(dwarflabels.FindOrAdd(@def,sizeof(def)));
{ the other fields besides Data are not initialised }
if not assigned(result^.HashSetItem.Data) then
begin begin
{ Mark as initialised }
result^.HashSetItem.Data:=self;
needstructdeflab:=is_implicit_pointer_object_type(def);
if not(tf_dwarf_only_local_labels in target_info.flags) then if not(tf_dwarf_only_local_labels in target_info.flags) then
begin begin
if (ds_dwarf_dbg_info_written in def.defstates) then if (ds_dwarf_dbg_info_written in def.defstates) then
begin begin
if not assigned(def.typesym) then if not assigned(def.typesym) then
internalerror(200610011); internalerror(200610011);
def.dwarf_lab:=current_asmdata.RefAsmSymbol(make_mangledname('DBG',def.owner,symname(def.typesym, true)),AT_DATA); result^.lab:=current_asmdata.RefAsmSymbol(make_mangledname('DBG',def.owner,symname(def.typesym, true)),AT_DATA);
def.dwarf_ref_lab:=current_asmdata.RefAsmSymbol(make_mangledname('DBGREF',def.owner,symname(def.typesym, true)),AT_DATA); result^.ref_lab:=current_asmdata.RefAsmSymbol(make_mangledname('DBGREF',def.owner,symname(def.typesym, true)),AT_DATA);
if is_class_or_interface_or_dispinterface(def) or is_objectpascal_helper(def) then if needstructdeflab then
tobjectdef(def).dwarf_struct_lab:=current_asmdata.RefAsmSymbol(make_mangledname('DBG2',def.owner,symname(def.typesym, true)),AT_DATA); result^.struct_lab:=current_asmdata.RefAsmSymbol(make_mangledname('DBG2',def.owner,symname(def.typesym, true)),AT_DATA);
def.dbg_state:=dbg_state_written; def.dbg_state:=dbg_state_written;
end end
else else
@ -945,20 +976,20 @@ implementation
(def.owner.symtabletype=globalsymtable) and (def.owner.symtabletype=globalsymtable) and
(def.owner.iscurrentunit) then (def.owner.iscurrentunit) then
begin begin
def.dwarf_lab:=current_asmdata.DefineAsmSymbol(make_mangledname('DBG',def.owner,symname(def.typesym, true)),AB_GLOBAL,AT_DATA); result^.lab:=current_asmdata.DefineAsmSymbol(make_mangledname('DBG',def.owner,symname(def.typesym, true)),AB_GLOBAL,AT_DATA);
def.dwarf_ref_lab:=current_asmdata.DefineAsmSymbol(make_mangledname('DBGREF',def.owner,symname(def.typesym, true)),AB_GLOBAL,AT_DATA); result^.ref_lab:=current_asmdata.DefineAsmSymbol(make_mangledname('DBGREF',def.owner,symname(def.typesym, true)),AB_GLOBAL,AT_DATA);
if is_class_or_interface_or_dispinterface(def) or is_objectpascal_helper(def) then if needstructdeflab then
tobjectdef(def).dwarf_struct_lab:=current_asmdata.DefineAsmSymbol(make_mangledname('DBG2',def.owner,symname(def.typesym, true)),AB_GLOBAL,AT_DATA); result^.struct_lab:=current_asmdata.DefineAsmSymbol(make_mangledname('DBG2',def.owner,symname(def.typesym, true)),AB_GLOBAL,AT_DATA);
include(def.defstates,ds_dwarf_dbg_info_written); include(def.defstates,ds_dwarf_dbg_info_written);
end end
else else
begin begin
{ The pointer typecast is needed to prevent a problem with range checking { The pointer typecast is needed to prevent a problem with range checking
on when the typecast is changed to 'as' } on when the typecast is changed to 'as' }
current_asmdata.getglobaldatalabel(TAsmLabel(pointer(def.dwarf_lab))); current_asmdata.getglobaldatalabel(TAsmLabel(pointer(result^.lab)));
current_asmdata.getglobaldatalabel(TAsmLabel(pointer(def.dwarf_ref_lab))); current_asmdata.getglobaldatalabel(TAsmLabel(pointer(result^.ref_lab)));
if is_implicit_pointer_object_type(def) then if needstructdeflab then
current_asmdata.getglobaldatalabel(TAsmLabel(pointer(tobjectdef(def).dwarf_struct_lab))); current_asmdata.getglobaldatalabel(TAsmLabel(pointer(result^.struct_lab)));
end; end;
end; end;
end end
@ -967,10 +998,10 @@ implementation
{ The pointer typecast is needed to prevent a problem with range checking { The pointer typecast is needed to prevent a problem with range checking
on when the typecast is changed to 'as' } on when the typecast is changed to 'as' }
{ addrlabel instead of datalabel because it must be a local one } { addrlabel instead of datalabel because it must be a local one }
current_asmdata.getaddrlabel(TAsmLabel(pointer(def.dwarf_lab))); current_asmdata.getaddrlabel(TAsmLabel(pointer(result^.lab)));
current_asmdata.getaddrlabel(TAsmLabel(pointer(def.dwarf_ref_lab))); current_asmdata.getaddrlabel(TAsmLabel(pointer(result^.ref_lab)));
if is_implicit_pointer_object_type(def) then if needstructdeflab then
current_asmdata.getaddrlabel(TAsmLabel(pointer(tobjectdef(def).dwarf_struct_lab))); current_asmdata.getaddrlabel(TAsmLabel(pointer(result^.struct_lab)));
end; end;
if def.dbg_state=dbg_state_used then if def.dbg_state=dbg_state_used then
deftowritelist.Add(def); deftowritelist.Add(def);
@ -980,20 +1011,17 @@ implementation
function TDebugInfoDwarf.def_dwarf_lab(def: tdef): tasmsymbol; function TDebugInfoDwarf.def_dwarf_lab(def: tdef): tasmsymbol;
begin begin
set_def_dwarf_labs(def); result:=get_def_dwarf_labs(def)^.lab;
result:=def.dwarf_lab;
end; end;
function TDebugInfoDwarf.def_dwarf_class_struct_lab(def: tobjectdef): tasmsymbol; function TDebugInfoDwarf.def_dwarf_class_struct_lab(def: tobjectdef): tasmsymbol;
begin begin
set_def_dwarf_labs(def); result:=get_def_dwarf_labs(def)^.struct_lab;
result:=def.dwarf_struct_lab;
end; end;
function TDebugInfoDwarf.def_dwarf_ref_lab(def: tdef): tasmsymbol; function TDebugInfoDwarf.def_dwarf_ref_lab(def: tdef): tasmsymbol;
begin begin
set_def_dwarf_labs(def); result:=get_def_dwarf_labs(def)^.ref_lab;
result:=def.dwarf_ref_lab;
end; end;
constructor TDebugInfoDwarf.Create; constructor TDebugInfoDwarf.Create;
@ -3117,6 +3145,15 @@ implementation
storefilepos:=current_filepos; storefilepos:=current_filepos;
current_filepos:=current_module.mainfilepos; current_filepos:=current_module.mainfilepos;
if assigned(dwarflabels) then
internalerror(2015100301);
{ one item per def, plus some extra space in case of nested types,
externally used types etc (it will grow further if necessary) }
i:=current_module.localsymtable.DefList.count*4;
if assigned(current_module.globalsymtable) then
inc(i,current_module.globalsymtable.DefList.count*2);
dwarflabels:=TDwarfLabHashSet.Create(i,true,false);
currabbrevnumber:=0; currabbrevnumber:=0;
defnumberlist:=TFPObjectList.create(false); defnumberlist:=TFPObjectList.create(false);
@ -3231,16 +3268,15 @@ implementation
{ end of abbrev table } { end of abbrev table }
current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_8bit(0)); current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_8bit(0));
{ reset all def labels } { reset all def debug states }
for i:=0 to defnumberlist.count-1 do for i:=0 to defnumberlist.count-1 do
begin begin
def := tdef(defnumberlist[i]); def := tdef(defnumberlist[i]);
if assigned(def) then if assigned(def) then
begin def.dbg_state:=dbg_state_unused;
def.dwarf_lab:=nil;
def.dbg_state:=dbg_state_unused;
end;
end; end;
dwarflabels.free;
dwarflabels:=nil;
defnumberlist.free; defnumberlist.free;
defnumberlist:=nil; defnumberlist:=nil;

View File

@ -376,7 +376,6 @@ interface
private private
fcurrent_dispid: longint; fcurrent_dispid: longint;
public public
dwarf_struct_lab : tasmsymbol;
childof : tobjectdef; childof : tobjectdef;
childofderef : tderef; childofderef : tderef;

View File

@ -53,10 +53,6 @@ interface
tdef = class(TDefEntry) tdef = class(TDefEntry)
typesym : tsym; { which type the definition was generated this def } typesym : tsym; { which type the definition was generated this def }
{ maybe it's useful to merge the dwarf and stabs debugging info with some hacking }
{ dwarf debugging }
dwarf_lab : tasmsymbol;
dwarf_ref_lab : tasmsymbol;
{ stabs debugging } { stabs debugging }
stab_number : word; stab_number : word;
dbg_state : tdefdbgstatus; dbg_state : tdefdbgstatus;