+ support for JVM local variable and parameter debug information

o self is encoded as "this" for javac compatibility
  + ait_jvar (for the above) and ait_jcatch (similar, for future try/catch
    support) classes
  + support for smallset JVM type encoding (as int)

git-svn-id: branches/jvmbackend@18354 -
This commit is contained in:
Jonas Maebe 2011-08-20 07:50:41 +00:00
parent b5e7989a06
commit d456ec2ffe
10 changed files with 301 additions and 11 deletions

1
.gitattributes vendored
View File

@ -215,6 +215,7 @@ compiler/jvm/cpunode.pas svneol=native#text/plain
compiler/jvm/cpupara.pas svneol=native#text/plain
compiler/jvm/cpupi.pas svneol=native#text/plain
compiler/jvm/cputarg.pas svneol=native#text/plain
compiler/jvm/dbgjasm.pas svneol=native#text/plain
compiler/jvm/hlcgcpu.pas svneol=native#text/plain
compiler/jvm/itcpujas.pas svneol=native#text/plain
compiler/jvm/jvmreg.dat svneol=native#text/plain

View File

@ -88,7 +88,10 @@ interface
ait_regalloc,
ait_tempalloc,
{ used to mark assembler blocks and inlined functions }
ait_marker
ait_marker,
{ JVM only }
ait_jvar, { debug information for a local variable }
ait_jcatch { exception catch clause }
);
taiconst_type = (
@ -174,7 +177,9 @@ interface
'cut',
'regalloc',
'tempalloc',
'marker'
'marker',
'jvar',
'jcatch'
);
type
@ -250,7 +255,8 @@ interface
a new ait type! }
SkipInstr = [ait_comment, ait_symbol,ait_section
,ait_stab, ait_function_name, ait_force_line
,ait_regalloc, ait_tempalloc, ait_symbol_end, ait_directive];
,ait_regalloc, ait_tempalloc, ait_symbol_end, ait_directive
,ait_jvar, ait_jcatch];
{ ait_* types which do not have line information (and hence which are of type
tai, otherwise, they are of type tailineinfo }
@ -258,12 +264,13 @@ interface
ait_regalloc,ait_tempalloc,
ait_stab,ait_function_name,
ait_cutobject,ait_marker,ait_align,ait_section,ait_comment,
ait_const,
ait_const,ait_directive,
{$ifdef arm}
ait_thumb_func,
{$endif arm}
ait_real_32bit,ait_real_64bit,ait_real_80bit,ait_comp_64bit,ait_real_128bit,
ait_symbol
ait_symbol,
ait_jvar,ait_jcatch
];
@ -666,6 +673,29 @@ interface
end;
tai_align_class = class of tai_align_abstract;
{ JVM variable live range description }
tai_jvar = class(tai)
stackslot: longint;
desc: pshortstring;
startlab,stoplab: tasmsymbol;
constructor Create(_stackslot: longint; const _desc: shortstring; _startlab, _stoplab: TAsmSymbol);
constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
procedure ppuwrite(ppufile:tcompilerppufile);override;
end;
tai_jvar_class = class of tai_jvar;
{ JVM exception catch description }
tai_jcatch = class(tai)
name: pshortstring;
startlab,stoplab,handlerlab: tasmsymbol;
constructor Create(const _name: shortstring; _startlab, _stoplab, _handlerlab: TAsmSymbol);
constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
procedure ppuwrite(ppufile:tcompilerppufile);override;
end;
tai_jcatch_class = class of tai_jcatch;
var
{ array with all class types for tais }
aiclass : taiclassarray;
@ -2454,4 +2484,80 @@ implementation
ppufile.putbyte(byte(use_op));
end;
{****************************************************************************
tai_jvar
****************************************************************************}
constructor tai_jvar.Create(_stackslot: longint; const _desc: shortstring; _startlab, _stoplab: TAsmSymbol);
begin
Inherited create;
typ:=ait_jvar;
stackslot:=_stackslot;
desc:=stringdup(_desc);
startlab:=_startlab;
stoplab:=_stoplab;
end;
constructor tai_jvar.ppuload(t: taitype; ppufile: tcompilerppufile);
begin
inherited ppuload(t, ppufile);
stackslot:=ppufile.getlongint;
desc:=stringdup(ppufile.getstring);
startlab:=ppufile.getasmsymbol;
stoplab:=ppufile.getasmsymbol;
end;
procedure tai_jvar.ppuwrite(ppufile: tcompilerppufile);
begin
inherited ppuwrite(ppufile);
ppufile.putlongint(stackslot);
ppufile.putstring(desc^);
ppufile.putasmsymbol(startlab);
ppufile.putasmsymbol(stoplab);
end;
{****************************************************************************
tai_jvar
****************************************************************************}
constructor tai_jcatch.Create(const _name: shortstring; _startlab, _stoplab, _handlerlab: TAsmSymbol);
begin
Inherited create;
typ:=ait_jcatch;
name:=stringdup(_name);
startlab:=_startlab;
startlab.increfs;
stoplab:=_stoplab;
stoplab.increfs;
handlerlab:=_handlerlab;
handlerlab.increfs;
end;
constructor tai_jcatch.ppuload(t: taitype; ppufile: tcompilerppufile);
begin
inherited ppuload(t, ppufile);
name:=stringdup(ppufile.getstring);
startlab:=ppufile.getasmsymbol;
startlab.increfs;
stoplab:=ppufile.getasmsymbol;
stoplab.increfs;
handlerlab:=ppufile.getasmsymbol;
handlerlab.increfs;
end;
procedure tai_jcatch.ppuwrite(ppufile: tcompilerppufile);
begin
inherited ppuwrite(ppufile);
ppufile.putstring(name^);
ppufile.putasmsymbol(startlab);
ppufile.putasmsymbol(stoplab);
ppufile.putasmsymbol(handlerlab);
end;
end.

View File

@ -381,6 +381,29 @@ implementation
AsmLn;
end;
ait_jvar:
begin
AsmWrite('.var ');
AsmWrite(tostr(tai_jvar(hp).stackslot));
AsmWrite(' is ');
AsmWrite(tai_jvar(hp).desc^);
AsmWrite(' from ');
AsmWrite(tai_jvar(hp).startlab.name);
AsmWrite(' to ');
AsmWriteLn(tai_jvar(hp).stoplab.name);
end;
ait_jcatch:
begin
AsmWrite('.catch ');
AsmWrite(tai_jcatch(hp).name^);
AsmWrite(' from ');
AsmWrite(tai_jcatch(hp).startlab.name);
AsmWrite(' to ');
AsmWrite(tai_jcatch(hp).stoplab.name);
AsmWrite(' using ');
AsmWriteLn(tai_jcatch(hp).handlerlab.name);
end;
else
internalerror(2010122707);
end;

View File

@ -57,9 +57,7 @@ implementation
Debuginfo
**************************************}
{$ifdef Dbgjvm}
,dbgjvm
{$endif Dbgjvm}
,dbgjasm
;

150
compiler/jvm/dbgjasm.pas Normal file
View File

@ -0,0 +1,150 @@
{
Copyright (c) 2003-2006 by Peter Vreman, Florian Klaempfl, and Jonas Maebe
This units contains support for Jasmin debug info generation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************
}
unit dbgjasm;
{$i fpcdefs.inc}
interface
uses
cclasses,globtype,
aasmbase,aasmtai,aasmdata,
symbase,symconst,symtype,symdef,symsym,
finput,
DbgBase;
type
{ TDebugInfoJasmin }
TDebugInfoJasmin=class(TDebugInfo)
protected
fcurrprocstart,
fcurrprocend: tasmsymbol;
procedure appendsym_localsym(list: TAsmList; sym: tabstractnormalvarsym);
procedure appendsym_paravar(list:TAsmList;sym:tparavarsym);override;
procedure appendsym_localvar(list:TAsmList;sym:tlocalvarsym);override;
procedure beforeappenddef(list:TAsmList;def:tdef);override;
procedure appendprocdef(list:TAsmList;def:tprocdef);override;
public
procedure inserttypeinfo;override;
procedure insertlineinfo(list:TAsmList);override;
end;
implementation
uses
sysutils,cutils,cfileutl,constexp,
version,globals,verbose,systems,
cpubase,cpuinfo,cgbase,paramgr,
fmodule,
defutil,symtable,ppu
;
{****************************************************************************
TDebugInfoJasmin
****************************************************************************}
procedure TDebugInfoJasmin.appendsym_localsym(list: TAsmList; sym: tabstractnormalvarsym);
var
jvar: tai_jvar;
proc: tprocdef;
begin
if tdef(sym.owner.defowner).typ<>procdef then
exit;
if not(sym.localloc.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
exit;
proc:=tprocdef(sym.owner.defowner);
jvar:=tai_jvar.create(sym.localloc.reference.offset,sym.jvmmangledbasename,fcurrprocstart,fcurrprocend);
proc.exprasmlist.InsertAfter(jvar,proc.procstarttai);
end;
procedure TDebugInfoJasmin.appendsym_paravar(list: TAsmList; sym: tparavarsym);
begin
appendsym_localsym(list,sym);
end;
procedure TDebugInfoJasmin.appendsym_localvar(list: TAsmList; sym: tlocalvarsym);
begin
appendsym_localsym(list,sym);
end;
procedure TDebugInfoJasmin.beforeappenddef(list: TAsmList; def: tdef);
begin
end;
procedure TDebugInfoJasmin.appendprocdef(list: TAsmList; def: tprocdef);
var
procstartlabel,
procendlabel : tasmlabel;
begin
{ insert debug information for local variables and parameters, but only
for routines implemented in the Pascal code }
if not assigned(def.procstarttai) then
exit;
current_asmdata.getlabel(procstartlabel,alt_dbgtype);
current_asmdata.getlabel(procendlabel,alt_dbgtype);
def.exprasmlist.insertafter(tai_label.create(procstartlabel),def.procstarttai);
def.exprasmlist.insertbefore(tai_label.create(procendlabel),def.procendtai);
fcurrprocstart:=procstartlabel;
fcurrprocend:=procendlabel;
write_symtable_parasyms(list,def.paras);
write_symtable_syms(list,def.localst);
end;
procedure TDebugInfoJasmin.inserttypeinfo;
begin
{ write all procedures and methods }
if assigned(current_module.globalsymtable) then
write_symtable_procdefs(nil,current_module.globalsymtable);
if assigned(current_module.localsymtable) then
write_symtable_procdefs(nil,current_module.localsymtable);
end;
procedure TDebugInfoJasmin.insertlineinfo(list: TAsmList);
begin
end;
{****************************************************************************
****************************************************************************}
const
dbg_jasmin_info : tdbginfo =
(
id : dbg_jasmin;
idtxt : 'JASMIN';
);
initialization
RegisterDebugInfo(dbg_jasmin_info,TDebugInfoJasmin);
end.

View File

@ -148,6 +148,9 @@ implementation
end;
setdef :
begin
if is_smallset(def) then
encodedstr:=encodedstr+'I'
else
{ will be hanlded via wrapping later, although wrapping may
happen at higher level }
result:=false;

View File

@ -625,6 +625,8 @@ implementation
aiclass[ait_regalloc]:=tai_regalloc;
aiclass[ait_tempalloc]:=tai_tempalloc;
aiclass[ait_marker]:=tai_marker;
aiclass[ait_jvar]:=tai_jvar;
aiclass[ait_jcatch]:=tai_jcatch;
end;
end.

View File

@ -1154,7 +1154,14 @@ implementation
begin
if not jvmtryencodetype(vardef,result,founderror) then
internalerror(2011011203);
result:=realname+' '+result;
if (typ=paravarsym) and
(vo_is_self in tparavarsym(self).varoptions) then
result:='this ' +result
else if (typ in [paravarsym,localvarsym]) and
([vo_is_funcret,vo_is_result] * tabstractnormalvarsym(self).varoptions <> []) then
result:='result '+result
else
result:=realname+' '+result;
end;

View File

@ -203,7 +203,7 @@
,res_single_file);
tdbg = (dbg_none
,dbg_stabs,dbg_dwarf2,dbg_dwarf3,dbg_dwarf4
,dbg_stabs,dbg_dwarf2,dbg_dwarf3,dbg_dwarf4,dbg_jasmin
);
tscripttype = (script_none

View File

@ -74,7 +74,7 @@ unit i_jvm;
linkextern : nil;
ar : ar_none;
res : res_none;
dbg : dbg_none;
dbg : dbg_jasmin;
script : script_unix;
endian : endian_big;
alignment :