diff --git a/compiler/fppu.pas b/compiler/fppu.pas index 7441a2d7c8..fd6839938f 100644 --- a/compiler/fppu.pas +++ b/compiler/fppu.pas @@ -1356,6 +1356,8 @@ var flags:=flags or uf_release; if assigned(localsymtable) then flags:=flags or uf_local_symtable; + if (cs_checkpointer_called in current_settings.moduleswitches) then + flags:=flags or uf_checkpointer_called; {$ifdef i8086} if current_settings.x86memorymodel in [mm_medium,mm_large,mm_huge] then flags:=flags or uf_i8086_far_code; diff --git a/compiler/globtype.pas b/compiler/globtype.pas index bd30034fe5..421fe44a72 100644 --- a/compiler/globtype.pas +++ b/compiler/globtype.pas @@ -178,7 +178,9 @@ interface cs_executable_stack, { i8086 specific } cs_huge_code, - cs_win16_smartcallbacks + cs_win16_smartcallbacks, + { Record usage of checkpointer experimental feature } + cs_checkpointer_called ); tmoduleswitches = set of tmoduleswitch; diff --git a/compiler/i8086/n8086mem.pas b/compiler/i8086/n8086mem.pas index 0c41bb49e9..65283e00d7 100644 --- a/compiler/i8086/n8086mem.pas +++ b/compiler/i8086/n8086mem.pas @@ -183,6 +183,7 @@ implementation hlcg.allocallcpuregisters(current_asmdata.CurrAsmList); hlcg.a_call_name(current_asmdata.CurrAsmList,pd,'FPC_CHECKPOINTER',[],nil,false); hlcg.deallocallcpuregisters(current_asmdata.CurrAsmList); + system.include(current_settings.moduleswitches,cs_checkpointer_called); end; end else diff --git a/compiler/ncgmem.pas b/compiler/ncgmem.pas index 9c01e53f63..6b63b2389e 100644 --- a/compiler/ncgmem.pas +++ b/compiler/ncgmem.pas @@ -319,6 +319,7 @@ implementation hlcg.allocallcpuregisters(current_asmdata.CurrAsmList); hlcg.a_call_name(current_asmdata.CurrAsmList,pd,'FPC_CHECKPOINTER',[@paraloc1],nil,false); hlcg.deallocallcpuregisters(current_asmdata.CurrAsmList); + include(current_settings.moduleswitches,cs_checkpointer_called); end; end; @@ -407,6 +408,7 @@ implementation hlcg.allocallcpuregisters(current_asmdata.CurrAsmList); hlcg.a_call_name(current_asmdata.CurrAsmList,pd,'FPC_CHECKPOINTER',[@paraloc1],nil,false); hlcg.deallocallcpuregisters(current_asmdata.CurrAsmList); + system.include(current_settings.moduleswitches,cs_checkpointer_called); end; end else diff --git a/compiler/options.pas b/compiler/options.pas index 1776c9f46a..62aa0c038b 100644 --- a/compiler/options.pas +++ b/compiler/options.pas @@ -1627,7 +1627,12 @@ begin if UnsetBool(More, j, opt, false) then exclude(init_settings.localswitches,cs_checkpointer) else if (target_info.system in systems_support_checkpointer) then - include(init_settings.localswitches,cs_checkpointer) + begin + if do_release then + Message(option_gc_incompatible_with_release_flag) + else + include(init_settings.localswitches,cs_checkpointer); + end else UnsupportedPara('-gc'); end; @@ -2090,7 +2095,14 @@ begin break; end; 'r' : - do_release:=true; + begin + do_release:=true; + if (cs_checkpointer in init_settings.localswitches) then + begin + Message(option_gc_incompatible_with_release_flag); + exclude(init_settings.localswitches,cs_checkpointer); + end; + end; 's' : include(init_settings.moduleswitches,cs_compilesystem); '-' : diff --git a/compiler/pmodules.pas b/compiler/pmodules.pas index 0d6fbbdd93..b3ec67658a 100644 --- a/compiler/pmodules.pas +++ b/compiler/pmodules.pas @@ -1822,6 +1822,7 @@ type main_procinfo : tcgprocinfo; force_init_final : boolean; resources_used : boolean; + program_uses_checkpointer : boolean; initname, program_name : ansistring; consume_semicolon_after_uses : boolean; @@ -2303,6 +2304,8 @@ type assembler startup files } if assigned(sysinitmod) then linker.AddModuleFiles(sysinitmod); + { Does any unit use checkpointer function } + program_uses_checkpointer:=false; { insert all .o files from all loaded units and unload the units, we don't need them anymore. Keep the current_module because that is still needed } @@ -2310,7 +2313,11 @@ type while assigned(hp) do begin if (hp<>sysinitmod) and (hp.flags and uf_in_library=0) then - linker.AddModuleFiles(hp); + begin + linker.AddModuleFiles(hp); + if (hp.flags and uf_checkpointer_called)<>0 then + program_uses_checkpointer:=true; + end; hp2:=tmodule(hp.next); if assigned(hp.package) then add_package_unit_ref(hp.package); @@ -2325,6 +2332,10 @@ type { free also unneeded units we didn't free before } if not needsymbolinfo then unloaded_units.Clear; + { Does any unit use checkpointer function } + if program_uses_checkpointer then + Message1(link_w_program_uses_checkpointer,current_module.modulename^); + { add all directly used packages as libraries } add_package_libs(linker); { finally we can create a executable } diff --git a/compiler/ppu.pas b/compiler/ppu.pas index 84c6e78267..ace264cf7c 100644 --- a/compiler/ppu.pas +++ b/compiler/ppu.pas @@ -55,6 +55,7 @@ const uf_static_linked = $000080; { the ppu can be linked static } uf_shared_linked = $000100; { the ppu can be linked shared } //uf_local_browser = $000200; + uf_checkpointer_called = $000200; { Unit uses experimental checkpointer test code } uf_no_link = $000400; { unit has no .o generated, but can still have external linking! } uf_has_resourcestrings = $000800; { unit has resource string section } uf_little_endian = $001000; diff --git a/compiler/utils/ppuutils/ppudump.pp b/compiler/utils/ppuutils/ppudump.pp index 1b517eedb9..e482d136e4 100644 --- a/compiler/utils/ppuutils/ppudump.pp +++ b/compiler/utils/ppuutils/ppudump.pp @@ -537,7 +537,7 @@ type str : string[30]; end; const - flagopts=31; + flagopts=32; flagopt : array[1..flagopts] of tflagopt=( (mask: $1 ;str:'init'), (mask: $2 ;str:'final'), @@ -548,7 +548,7 @@ const (mask: $40 ;str:'smart_linked'), (mask: $80 ;str:'static_linked'), (mask: $100 ;str:'shared_linked'), -// (mask: $200 ;str:'local_browser'), + (mask: $200 ;str:'uses_checkpointer'), (mask: $400 ;str:'no_link'), (mask: $800 ;str:'has_resources'), (mask: $1000 ;str:'little_endian'),