Studying note of GCC-3.4.6 source (68)

4.3.2. Construct exception context

Comes back from cxx_init, below init_asm_output prepares the file for outputting assemble code.

 

lang_dependent_init (continue)

 

4535   init_asm_output (name);

4536

4537   /* These create various _DECL nodes, so need to be called after the

4538     front end is initialized.  */

4539   init_eh ();

 

At configuring gcc, we can use --enable-sjlj-exceptions to force using C library setjmp and longjmp in exception handling, which is a quite out-of date facility. Now new chip usually gives consideration upon exception handling, for example offers special register. So, if it doesn’t enforce using setjmp/longjmp, the compiler would judge if it needs use setjmp/longjmp.

 

146  #ifndef MUST_USE_SJLJ_EXCEPTIONS                                                   in except.h

147  # if !(defined (EH_RETURN_DATA_REGNO)                 /

148         && (defined (IA64_UNWIND_INFO)                 /

149             || (DWARF2_UNWIND_INFO                     /

150              && (defined (EH_RETURN_HANDLER_RTX)       /

151                   || defined (HAVE_eh_return)))))

152  #  define MUST_USE_SJLJ_EXCEPTIONS     1

153  # else

154  #  define MUST_USE_SJLJ_EXCEPTIONS     0

155  # endif

156  #endif

 

Above, EH_RETURN_DATA_REGNO(N) is a C expression whose value is the Nth register number used for data by exception handlers, or `INVALID_REGNUM' if fewer than N registers are usable. For x86, it is registers of NO. 0~1 (i.e, AX, DX). And IA64_UNWIND_INFO is only defined for ia64 chip.

 

282  #if !defined (DWARF2_UNWIND_INFO) && defined (INCOMING_RETURN_ADDR_RTX)

283  #define DWARF2_UNWIND_INFO 1

284  #endif

 

INCOMING_RETURN_ADDR_RTX is a C expression whose value is RTL representing the location of the incoming return address at the beginning of any function, before the prologue. For x86, this location is on stack, the macro is defined. And EH_RETURN_HANDLER_RTX, if defined, is a C expression whose value is RTL representing a location in which to store the address of an exception handler to which we should return. x86 doesn’t define this macro, but defines HAVE_eh_return at configuration stage.

So to x86, MUST_USE_SJLJ_EXCEPTIONS is 0, means using setjmp/longjmp is not must.

 

158  #ifdef CONFIG_SJLJ_EXCEPTIONS                                                          in except.h

159  # if CONFIG_SJLJ_EXCEPTIONS == 1

160  #  define USING_SJLJ_EXCEPTIONS            1

161  # endif

162  # if CONFIG_SJLJ_EXCEPTIONS == 0

163  #  define USING_SJLJ_EXCEPTIONS            0

164  #  ifndef EH_RETURN_DATA_REGNO

165      #error "EH_RETURN_DATA_REGNO required"

166  #  endif

167  #  if !defined(EH_RETURN_HANDLER_RTX) && !defined(HAVE_eh_return)

168      #error "EH_RETURN_HANDLER_RTX or eh_return required"

169  #  endif

170  #  if !defined(DWARF2_UNWIND_INFO) && !defined(IA64_UNWIND_INFO)

171      #error "{DWARF2,IA64}_UNWIND_INFO required"

172  #  endif

173  # endif

174  #else

175  # define USING_SJLJ_EXCEPTIONS        MUST_USE_SJLJ_EXCEPTIONS

176  #endif

 

Macro CONFIG_SJLJ_EXCEPTIONS is set by configuration option --enable-sjlj-exceptions (or --disable-sjlj-exceptions). When inhibits using setjmp/longjmp, the compiler needs to check if it is feasible. Here, USING_SJLJ_EXCEPTIONS is defined by MUST_USE_SJLJ_EXCEPTIONS, both 0! Then below init_eh almost has nothing to do. The function majorly creates an important data structure SjLj_Function_Context for the mechanism using setjmp/longjmp. This structure at time of exception handling would be allocated upon stack, and in its definition, can see filed for maintainence -- prev. So the front-end needs know the definition for this maintanence.

 

54      struct SjLj_Function_Context                                                             in unwind-sjlj.c

55      {

56        /* This is the chain through all registered contexts. It is

57          filled in by _Unwind_SjLj_Register.  */

58        struct SjLj_Function_Context *prev;

59     

60        /* This is assigned in by the target function before every call

61          to the index of the call site in the lsda. It is assigned by

62          the personality routine to the landing pad index.  */

63        int call_site;

64     

65        /* This is how data is returned from the personality routine to

66          the target function's handler.  */

67        _Unwind_Word data[4];

68     

69        /* These are filled in once by the target function before any

70          exceptions are expected to be handled.  */

71        _Unwind_Personality_Fn personality;

72        void *lsda;

73     

74      #ifdef DONT_USE_BUILTIN_SETJMP

75        /* We don't know what sort of alignment requirements the system

76          jmp_buf has. We over estimated in except.c, and now we have

77          to match that here just in case the system *didn't* have more

78          restrictive requirements.  */

79        jmp_buf jbuf __attribute__((aligned));

80      #else

81        void *jbuf[];

82      #endif

83      };

 

It is excusable, because this context is passed to setjmp and longjmp (field jbuf). But in the other mechanism, every context is isolated, they don’t need know each other, and the processing and maintanence is provided by the runtime. No extra operation is required from the front-end. So no need tell the front-end about it.

 

366    void

367    init_eh (void)                                                                                         in except.c

368    {

369      if (! flag_exceptions)

370        return;

371   

372      type_to_runtime_map = htab_create_ggc (31, t2r_hash, t2r_eq, NULL);

373   

374     /* Create the SjLj_Function_Context structure. This should match

375        the definition in unwind-sjlj.c.  */

376      if (USING_SJLJ_EXCEPTIONS)

377      {

          ...

455      }

456    }

 

Regular it defines a group of exceptions, with base and serval derived classes. And at exception handling, there are usually a list of catch statements to filter the exception type to select out the matching handler. So compiler would create tinfo object for exception class automatically. But above, we have seen that if the class doesn’t define virtual functions, in its node there is no place to hold the tinfo object. As resolution, the front-end constructs type_to_runtime_map to bind exception classes with their tinfo objects.

 

你可能感兴趣的:(Studying note of GCC-3.4.6 source (68))