gccint: Trampolines

1 
1 18.11 Trampolines for Nested Functions
1 ======================================
1 
1 A "trampoline" is a small piece of code that is created at run time when
1 the address of a nested function is taken.  It normally resides on the
1 stack, in the stack frame of the containing function.  These macros tell
1 GCC how to generate code to allocate and initialize a trampoline.
1 
1  The instructions in the trampoline must do two things: load a constant
1 address into the static chain register, and jump to the real address of
1 the nested function.  On CISC machines such as the m68k, this requires
1 two instructions, a move immediate and a jump.  Then the two addresses
1 exist in the trampoline as word-long immediate operands.  On RISC
1 machines, it is often necessary to load each address into a register in
1 two parts.  Then pieces of each address form separate immediate
1 operands.
1 
1  The code generated to initialize the trampoline must store the variable
1 parts--the static chain value and the function address--into the
1 immediate operands of the instructions.  On a CISC machine, this is
1 simply a matter of copying each address to a memory reference at the
1 proper offset from the start of the trampoline.  On a RISC machine, it
1 may be necessary to take out pieces of the address and store them
1 separately.
1 
1  -- Target Hook: void TARGET_ASM_TRAMPOLINE_TEMPLATE (FILE *F)
1      This hook is called by 'assemble_trampoline_template' to output, on
1      the stream F, assembler code for a block of data that contains the
1      constant parts of a trampoline.  This code should not include a
1      label--the label is taken care of automatically.
1 
1      If you do not define this hook, it means no template is needed for
1      the target.  Do not define this hook on systems where the block
1      move code to copy the trampoline into place would be larger than
1      the code to generate it on the spot.
1 
1  -- Macro: TRAMPOLINE_SECTION
1      Return the section into which the trampoline template is to be
1      placed (⇒Sections).  The default value is
1      'readonly_data_section'.
1 
1  -- Macro: TRAMPOLINE_SIZE
1      A C expression for the size in bytes of the trampoline, as an
1      integer.
1 
1  -- Macro: TRAMPOLINE_ALIGNMENT
1      Alignment required for trampolines, in bits.
1 
1      If you don't define this macro, the value of 'FUNCTION_ALIGNMENT'
1      is used for aligning trampolines.
1 
1  -- Target Hook: void TARGET_TRAMPOLINE_INIT (rtx M_TRAMP, tree FNDECL,
1           rtx STATIC_CHAIN)
1      This hook is called to initialize a trampoline.  M_TRAMP is an RTX
1      for the memory block for the trampoline; FNDECL is the
1      'FUNCTION_DECL' for the nested function; STATIC_CHAIN is an RTX for
1      the static chain value that should be passed to the function when
1      it is called.
1 
1      If the target defines 'TARGET_ASM_TRAMPOLINE_TEMPLATE', then the
1      first thing this hook should do is emit a block move into M_TRAMP
1      from the memory block returned by 'assemble_trampoline_template'.
1      Note that the block move need only cover the constant parts of the
1      trampoline.  If the target isolates the variable parts of the
1      trampoline to the end, not all 'TRAMPOLINE_SIZE' bytes need be
1      copied.
1 
1      If the target requires any other actions, such as flushing caches
1      or enabling stack execution, these actions should be performed
1      after initializing the trampoline proper.
1 
1  -- Target Hook: rtx TARGET_TRAMPOLINE_ADJUST_ADDRESS (rtx ADDR)
1      This hook should perform any machine-specific adjustment in the
1      address of the trampoline.  Its argument contains the address of
1      the memory block that was passed to 'TARGET_TRAMPOLINE_INIT'.  In
1      case the address to be used for a function call should be different
1      from the address at which the template was stored, the different
1      address should be returned; otherwise ADDR should be returned
1      unchanged.  If this hook is not defined, ADDR will be used for
1      function calls.
1 
1  -- Target Hook: int TARGET_CUSTOM_FUNCTION_DESCRIPTORS
1      This hook should be defined to a power of 2 if the target will
1      benefit from the use of custom descriptors for nested functions
1      instead of the standard trampolines.  Such descriptors are created
1      at run time on the stack and made up of data only, but they are
1      non-standard so the generated code must be prepared to deal with
1      them.  This hook should be defined to 0 if the target uses function
1      descriptors for its standard calling sequence, like for example
1      HP-PA or IA-64.  Using descriptors for nested functions eliminates
1      the need for trampolines that reside on the stack and require it to
1      be made executable.
1 
1      The value of the macro is used to parameterize the run-time
1      identification scheme implemented to distinguish descriptors from
1      function addresses: it gives the number of bytes by which their
1      address is misaligned compared with function addresses.  The value
1      of 1 will generally work, unless it is already reserved by the
1      target for another purpose, like for example on ARM.
1 
1  Implementing trampolines is difficult on many machines because they
1 have separate instruction and data caches.  Writing into a stack
1 location fails to clear the memory in the instruction cache, so when the
1 program jumps to that location, it executes the old contents.
1 
1  Here are two possible solutions.  One is to clear the relevant parts of
1 the instruction cache whenever a trampoline is set up.  The other is to
1 make all trampolines identical, by having them jump to a standard
1 subroutine.  The former technique makes trampoline execution faster; the
1 latter makes initialization faster.
1 
1  To clear the instruction cache when a trampoline is initialized, define
1 the following macro.
1 
1  -- Macro: CLEAR_INSN_CACHE (BEG, END)
1      If defined, expands to a C expression clearing the _instruction
1      cache_ in the specified interval.  The definition of this macro
1      would typically be a series of 'asm' statements.  Both BEG and END
1      are both pointer expressions.
1 
1  To use a standard subroutine, define the following macro.  In addition,
1 you must make sure that the instructions in a trampoline fill an entire
1 cache line with identical instructions, or else ensure that the
1 beginning of the trampoline code is always aligned at the same point in
1 its cache line.  Look in 'm68k.h' as a guide.
1 
1  -- Macro: TRANSFER_FROM_TRAMPOLINE
1      Define this macro if trampolines need a special subroutine to do
1      their work.  The macro should expand to a series of 'asm'
1      statements which will be compiled with GCC.  They go in a library
1      function named '__transfer_from_trampoline'.
1 
1      If you need to avoid executing the ordinary prologue code of a
1      compiled C function when you jump to the subroutine, you can do so
1      by placing a special label of your own in the assembler code.  Use
1      one 'asm' statement to generate an assembler label, and another to
1      make the label global.  Then trampolines can use that label to jump
1      directly to your special assembler code.
1