Browse Source

Remember usage of checkpointer (-gc) option:
Use new cs_checkpointer_called moduleswitches set element.
Use new uf_checkpointer_called PPU flag (reusing obsolete uf_local_browser flag value)
Emit warning if compiled library/program has any code using checkpointer.

* ppu.pas: New constant: uf_checkpointer_called
* globtype.pas: New constant: cs_checkpointer_called
* fppu.pas: Set uf_checkpointer_called flag if cs_checkpointer_called is set in current_settings.module_switches
* i8086/n8086mem.pas: Include cs_checkpointer_called in current_settings.moduleswitches
* ncgmem.pas: Likewise.
* msg/errore.msg: Add new message saying that -gc and -Ur options are incompatible
Add description to -gc option, saying it is experimental.
Add warning at link time for program/library if checkpointer is used in any unit or main code.
* options.pas: if -gc and -Ur options are used, never enable checkpointer code,
instead output a warning that release is incompatible with -gc option.
* pmodules.pas: proc_program: Check all modules for uf_checkpointer_called flag,
emit a warning if checkpointer is used.
* utils/ppuutils/ppudump.pp: Add code for uf_codepointer_called option.

git-svn-id: trunk@34567 -

pierre 8 years ago
parent
commit
4d09dfca95

+ 2 - 0
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;

+ 3 - 1
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;
 

+ 1 - 0
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

+ 2 - 0
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

+ 14 - 2
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);
                     '-' :

+ 12 - 1
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 }

+ 1 - 0
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;

+ 2 - 2
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'),