From d456ec2ffe5d95c0560fb631d29935d3e8c6d74b Mon Sep 17 00:00:00 2001 From: Jonas Maebe <jonas@freepascal.org> Date: Sat, 20 Aug 2011 07:50:41 +0000 Subject: [PATCH] + 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 - --- .gitattributes | 1 + compiler/aasmtai.pas | 116 ++++++++++++++++++++++++++-- compiler/agjasmin.pas | 23 ++++++ compiler/jvm/cputarg.pas | 4 +- compiler/jvm/dbgjasm.pas | 150 +++++++++++++++++++++++++++++++++++++ compiler/jvmdef.pas | 3 + compiler/psystem.pas | 2 + compiler/symsym.pas | 9 ++- compiler/systems.inc | 2 +- compiler/systems/i_jvm.pas | 2 +- 10 files changed, 301 insertions(+), 11 deletions(-) create mode 100644 compiler/jvm/dbgjasm.pas diff --git a/.gitattributes b/.gitattributes index 2a53a5cc17..0ae37537f4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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 diff --git a/compiler/aasmtai.pas b/compiler/aasmtai.pas index f9d8ffec23..df1380be5f 100644 --- a/compiler/aasmtai.pas +++ b/compiler/aasmtai.pas @@ -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. diff --git a/compiler/agjasmin.pas b/compiler/agjasmin.pas index a22315972e..e4384b8191 100644 --- a/compiler/agjasmin.pas +++ b/compiler/agjasmin.pas @@ -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; diff --git a/compiler/jvm/cputarg.pas b/compiler/jvm/cputarg.pas index 6ec20996c4..2cb543c6d4 100644 --- a/compiler/jvm/cputarg.pas +++ b/compiler/jvm/cputarg.pas @@ -57,9 +57,7 @@ implementation Debuginfo **************************************} - {$ifdef Dbgjvm} - ,dbgjvm - {$endif Dbgjvm} + ,dbgjasm ; diff --git a/compiler/jvm/dbgjasm.pas b/compiler/jvm/dbgjasm.pas new file mode 100644 index 0000000000..5156ce28f5 --- /dev/null +++ b/compiler/jvm/dbgjasm.pas @@ -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. diff --git a/compiler/jvmdef.pas b/compiler/jvmdef.pas index cec6b267ed..29440b72fd 100644 --- a/compiler/jvmdef.pas +++ b/compiler/jvmdef.pas @@ -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; diff --git a/compiler/psystem.pas b/compiler/psystem.pas index 8eafbd9ef8..d76ae3df70 100644 --- a/compiler/psystem.pas +++ b/compiler/psystem.pas @@ -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. diff --git a/compiler/symsym.pas b/compiler/symsym.pas index b5ee8c0262..bb8a7e9520 100644 --- a/compiler/symsym.pas +++ b/compiler/symsym.pas @@ -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; diff --git a/compiler/systems.inc b/compiler/systems.inc index c7b6ec0052..990ad234a2 100644 --- a/compiler/systems.inc +++ b/compiler/systems.inc @@ -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 diff --git a/compiler/systems/i_jvm.pas b/compiler/systems/i_jvm.pas index 502f5bd255..b66020cb5f 100644 --- a/compiler/systems/i_jvm.pas +++ b/compiler/systems/i_jvm.pas @@ -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 :