diff --git a/compiler/arm/cgcpu.pas b/compiler/arm/cgcpu.pas index f76d815762..1bb698b2d7 100644 --- a/compiler/arm/cgcpu.pas +++ b/compiler/arm/cgcpu.pas @@ -3375,6 +3375,12 @@ unit cgcpu; imm1, imm2: DWord; begin LocalSize:=align(LocalSize,4); + if localsize>tarmprocinfo(current_procinfo).stackframesize then + begin + writeln(localsize); + writeln(tarmprocinfo(current_procinfo).stackframesize); + internalerror(2013040101); + end; { call instruction does not put anything on the stack } stackmisalignment:=0; if not(nostackframe) then diff --git a/compiler/arm/cpupi.pas b/compiler/arm/cpupi.pas index b148c0aec8..b35bbd6ee3 100644 --- a/compiler/arm/cpupi.pas +++ b/compiler/arm/cpupi.pas @@ -33,6 +33,11 @@ unit cpupi; type tarmprocinfo = class(tcgprocinfo) + { for arm thumb, we need to know the stackframe size before + starting procedure compilation, so this contains the stack frame size, the compiler + should assume + if this size is too little the procedure must be compiled again with a larger value } + stackframesize, floatregstart : aint; // procedure handle_body_start;override; // procedure after_pass1;override; @@ -48,11 +53,15 @@ unit cpupi; globals,systems, cpubase, tgobj, - symconst,paramgr, + symconst,symtype,symsym,paramgr, cgbase,cgutils, - cgobj; + cgobj, + defutil; procedure tarmprocinfo.set_first_temp_offset; + var + localsize : aint; + i : longint; begin { We allocate enough space to save all registers because we can't determine the necessary space because the used registers aren't known before @@ -84,6 +93,40 @@ unit cpupi; end else tg.setfirsttemp(maxpushedparasize); + + { estimate stack frame size } + if current_settings.cputype in cpu_thumb then + begin + stackframesize:=maxpushedparasize+32; + localsize:=0; + for i:=0 to procdef.localst.SymList.Count-1 do + if tsym(procdef.localst.SymList[i]).typ=localvarsym then + inc(localsize,tabstractnormalvarsym(procdef.localst.SymList[i]).getsize); + inc(stackframesize,localsize); + + localsize:=0; + for i:=0 to procdef.parast.SymList.Count-1 do + if tsym(procdef.parast.SymList[i]).typ=paravarsym then + if is_open_string(tabstractnormalvarsym(procdef.parast.SymList[i]).vardef) then + inc(localsize,256) + else + inc(localsize,tabstractnormalvarsym(procdef.parast.SymList[i]).getsize); + + inc(stackframesize,localsize); + + if pi_needs_implicit_finally in flags then + inc(stackframesize,40); + + if pi_uses_exceptions in flags then + inc(stackframesize,40); + + if procdef.proctypeoption in [potype_constructor] then + inc(stackframesize,40*2); + + inc(stackframesize,estimatedtempsize); + + stackframesize:=Align(stackframesize,8); + end; end; diff --git a/compiler/nbas.pas b/compiler/nbas.pas index a5f1f304cc..56c36e4e75 100644 --- a/compiler/nbas.pas +++ b/compiler/nbas.pas @@ -918,6 +918,7 @@ implementation firstpass(tempinfo^.withnode); if assigned(tempinfo^.tempinitcode) then firstpass(tempinfo^.tempinitcode); + inc(current_procinfo.estimatedtempsize,size);; end; diff --git a/compiler/ncgutil.pas b/compiler/ncgutil.pas index 28f4245232..ae5c46b0ac 100644 --- a/compiler/ncgutil.pas +++ b/compiler/ncgutil.pas @@ -392,15 +392,8 @@ implementation *****************************************************************************} procedure get_exception_temps(list:TAsmList;var t:texceptiontemps); - var - srsym : ttypesym; - begin - if jmp_buf_size=-1 then - begin - srsym:=search_system_type('JMP_BUF'); - jmp_buf_size:=srsym.typedef.size; - jmp_buf_align:=srsym.typedef.alignment; - end; + begin + get_jumpbuf_size; tg.GetTemp(list,EXCEPT_BUF_SIZE,sizeof(pint),tt_persistent,t.envbuf); tg.GetTemp(list,jmp_buf_size,jmp_buf_align,tt_persistent,t.jmpbuf); tg.GetTemp(list,sizeof(pint),sizeof(pint),tt_persistent,t.reasonbuf); diff --git a/compiler/ncnv.pas b/compiler/ncnv.pas index a16a483431..7e3ae73b71 100644 --- a/compiler/ncnv.pas +++ b/compiler/ncnv.pas @@ -2856,6 +2856,8 @@ implementation begin first_char_to_string:=nil; + if tstringdef(resultdef).stringtype=st_shortstring then + inc(current_procinfo.estimatedtempsize,256); expectloc:=LOC_REFERENCE; end; diff --git a/compiler/nflw.pas b/compiler/nflw.pas index 9992fc2a16..788f90f29f 100644 --- a/compiler/nflw.pas +++ b/compiler/nflw.pas @@ -1995,6 +1995,7 @@ implementation { else block } if assigned(t1) then firstpass(t1); + inc(current_procinfo.estimatedtempsize,get_jumpbuf_size*2); end; @@ -2051,6 +2052,8 @@ implementation if assigned(t1) then firstpass(t1); + + inc(current_procinfo.estimatedtempsize,get_jumpbuf_size); end; @@ -2067,7 +2070,6 @@ implementation end; end; - {***************************************************************************** TONNODE *****************************************************************************} diff --git a/compiler/procinfo.pas b/compiler/procinfo.pas index 4724c6dcf2..ec3b4c4323 100644 --- a/compiler/procinfo.pas +++ b/compiler/procinfo.pas @@ -125,6 +125,10 @@ unit procinfo; { max. of space need for parameters } maxpushedparasize : aint; + { some architectures need to know a stack size before the first compilation pass + estimatedtempsize contains an estimated value how big temps will get } + estimatedtempsize : aint; + { is this a constructor that calls another constructor on itself (either inherited, or another constructor of the same class)? Requires different entry code for some targets. } diff --git a/compiler/symtable.pas b/compiler/symtable.pas index a0405470c7..c898e5eb64 100644 --- a/compiler/symtable.pas +++ b/compiler/symtable.pas @@ -220,6 +220,7 @@ interface procedure hidesym(sym:TSymEntry); procedure duplicatesym(var hashedid:THashedIDString;dupsym,origsym:TSymEntry); function handle_generic_dummysym(sym:TSymEntry;var symoptions:tsymoptions):boolean; + function get_jumpbuf_size : longint; {*** Search ***} procedure addsymref(sym:tsym); @@ -2046,6 +2047,20 @@ implementation end; end; + + function get_jumpbuf_size : longint; + var + srsym : ttypesym; + begin + if jmp_buf_size=-1 then + begin + srsym:=search_system_type('JMP_BUF'); + jmp_buf_size:=srsym.typedef.size; + jmp_buf_align:=srsym.typedef.alignment; + end; + result:=jmp_buf_size; + end; + {***************************************************************************** Search *****************************************************************************}