mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-14 07:20:35 -08:00
Part of making extension callbacks part of the public mps.
* Move type and macro declarations to the public header mps.h. * Move documentation to appropriate sections of manual. (cherry picked from commit b928fa236178fb1bdbe20442c3f53b8e8a545a4b)
This commit is contained in:
parent
e3accea56d
commit
bf20351ddb
3 changed files with 109 additions and 3 deletions
|
|
@ -120,6 +120,13 @@ typedef mps_addr_t (*mps_fmt_isfwd_t)(mps_addr_t);
|
|||
typedef void (*mps_fmt_pad_t)(mps_addr_t, size_t);
|
||||
typedef mps_addr_t (*mps_fmt_class_t)(mps_addr_t);
|
||||
|
||||
/* Callbacks indicating that the arena has extended or contracted.
|
||||
* These are used to register chunks with RtlInstallFunctionTableCallback
|
||||
* <https://docs.microsoft.com/en-gb/windows/win32/api/winnt/nf-winnt-rtlinstallfunctiontablecallback>
|
||||
* so that the client can unwind the stack through functions in the arena.
|
||||
*/
|
||||
typedef void (*mps_arena_extended_t)(mps_arena_t, mps_addr_t, size_t);
|
||||
typedef void (*mps_arena_contracted_t)(mps_arena_t, mps_addr_t, size_t);
|
||||
|
||||
/* Keyword argument lists */
|
||||
|
||||
|
|
@ -171,6 +178,12 @@ extern const struct mps_key_s _mps_key_ARENA_SIZE;
|
|||
extern const struct mps_key_s _mps_key_ARENA_ZONED;
|
||||
#define MPS_KEY_ARENA_ZONED (&_mps_key_ARENA_ZONED)
|
||||
#define MPS_KEY_ARENA_ZONED_FIELD b
|
||||
extern const struct mps_key_s _mps_key_arena_extended;
|
||||
#define MPS_KEY_ARENA_EXTENDED (&_mps_key_arena_extended)
|
||||
#define MPS_KEY_ARENA_EXTENDED_FIELD fun
|
||||
extern const struct mps_key_s _mps_key_arena_contracted;
|
||||
#define MPS_KEY_ARENA_CONTRACTED (&_mps_key_arena_contracted)
|
||||
#define MPS_KEY_ARENA_CONTRACTED_FIELD fun
|
||||
extern const struct mps_key_s _mps_key_FORMAT;
|
||||
#define MPS_KEY_FORMAT (&_mps_key_FORMAT)
|
||||
#define MPS_KEY_FORMAT_FIELD format
|
||||
|
|
|
|||
|
|
@ -47,6 +47,12 @@ New features
|
|||
:ref:`topic-scanning-protocol`. This allows the client program to
|
||||
safely update references in the visited objects.
|
||||
|
||||
#. A :term:`virtual memory arena` can now be configured to call
|
||||
functions when it acquires a new chunk of :term:`address space`,
|
||||
and when it returns a chunk of address space to the operation
|
||||
system. This is intended to support dynamic function tables in
|
||||
Windows. See :ref:`topic-arena-extension`.
|
||||
|
||||
|
||||
Interface changes
|
||||
.................
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ Client arenas
|
|||
* :c:macro:`MPS_KEY_ARENA_SIZE` (type :c:type:`size_t`) is its
|
||||
size.
|
||||
|
||||
It also accepts three optional keyword arguments:
|
||||
It also accepts five optional keyword arguments:
|
||||
|
||||
* :c:macro:`MPS_KEY_COMMIT_LIMIT` (type :c:type:`size_t`) is
|
||||
the maximum amount of memory, in :term:`bytes (1)`, that the MPS
|
||||
|
|
@ -159,6 +159,17 @@ Client arenas
|
|||
may pause the :term:`client program` for. See
|
||||
:c:func:`mps_arena_pause_time_set` for details.
|
||||
|
||||
* :c:macro:`MPS_KEY_ARENA_EXTENDED` (type :c:type:`mps_fun_t`) is
|
||||
a function that will be called when the arena is *extended*:
|
||||
that is, when it acquires a new chunk of address space from the
|
||||
operating system. See :ref:`topic-arena-extension` for details.
|
||||
|
||||
* :c:macro:`MPS_KEY_ARENA_CONTRACTED` (type :c:type:`mps_fun_t`)
|
||||
is a function that will be called when the arena is
|
||||
*contracted*: that is, when it finishes with a chunk of address
|
||||
space and returns it to the operating system. See
|
||||
:ref:`topic-arena-extension` for details.
|
||||
|
||||
For example::
|
||||
|
||||
MPS_ARGS_BEGIN(args) {
|
||||
|
|
@ -983,8 +994,8 @@ Arena introspection and debugging
|
|||
from MPS-managed memory, then it may attempt to re-enter the
|
||||
MPS, which will fail as the MPS is not re-entrant.
|
||||
|
||||
.. |RtlInstallFunctionTableCallback| replace:: ``RtlInstallFunctionTableCallback()``
|
||||
.. _RtlInstallFunctionTableCallback: https://msdn.microsoft.com/en-us/library/windows/desktop/ms680595(v=vs.85).aspx
|
||||
.. |RtlInstallFunctionTableCallback| replace:: :c:func:`RtlInstallFunctionTableCallback`
|
||||
.. _RtlInstallFunctionTableCallback: https://docs.microsoft.com/en-gb/windows/win32/api/winnt/nf-winnt-rtlinstallfunctiontablecallback
|
||||
|
||||
If this happens, in order to allow the debugger to finish
|
||||
decoding the call stack, the only remedy is to put the arena
|
||||
|
|
@ -1040,3 +1051,79 @@ Arena introspection and debugging
|
|||
:c:func:`mps_addr_pool`, and to find out which :term:`object
|
||||
format` describes the object at the address, use
|
||||
:c:func:`mps_addr_fmt`.
|
||||
|
||||
|
||||
.. index::
|
||||
single: arena extension callbacks; introduction
|
||||
single: extension callbacks; introduction
|
||||
single: arena contraction callbacks; introduction
|
||||
single: contraction callbacks; introduction
|
||||
|
||||
.. _topic-arena-extension:
|
||||
|
||||
Arena extension callbacks
|
||||
-------------------------
|
||||
|
||||
There are situations in which the :term:`client program` needs to be
|
||||
informed about the chunks of address space that an :term:`arena` is
|
||||
managing. To support this, the MPS allows the client program to
|
||||
specify two callback functions when creating a :term:`virtual memory
|
||||
arena`: one function is called when the arena is *extended* (that is,
|
||||
when it acquires a new chunk of address space from the operating
|
||||
system), and the other when the arena is *contracted* (that is, when
|
||||
it returns a chunk of address space to the operating system).
|
||||
|
||||
The use case that this feature is designed to support is debugging of
|
||||
dynamically generated code in 64-bit Windows. Microsoft's
|
||||
documentation for |RtlInstallFunctionTableCallback|_ says:
|
||||
|
||||
Function tables are used on 64-bit Windows to determine how to
|
||||
unwind or walk the stack. These tables are usually generated by
|
||||
the compiler and stored as part of the image. However,
|
||||
applications must provide the function table for dynamically
|
||||
generated code.
|
||||
|
||||
An application may install a dynamic function table by calling
|
||||
|RtlInstallFunctionTableCallback|_, passing the region of memory in
|
||||
which the dynamically generated functions can be found, and may later
|
||||
delete the table by calling |RtlDeleteFunctionTable|_.
|
||||
|
||||
.. |RtlDeleteFunctionTable| replace:: :c:func:`RtlDeleteFunctionTable`
|
||||
.. _RtlDeleteFunctionTable: https://docs.microsoft.com/en-gb/windows/win32/api/winnt/nf-winnt-rtldeletefunctiontable
|
||||
|
||||
So if the client program is storing dynamically generated functions in
|
||||
MPS-managed memory, then it could define callback functions that
|
||||
install and delete the function table callback for the dynamically
|
||||
generated code, like this::
|
||||
|
||||
void arena_extended(mps_arena_t arena, void *base, size_t size)
|
||||
{
|
||||
RtlInstallFunctionTableCallback(...);
|
||||
}
|
||||
|
||||
void arena_contracted(mps_arena_t arena, void *base, size_t size)
|
||||
{
|
||||
RtlDeleteFunctionTable(...);
|
||||
}
|
||||
|
||||
and then pass these two functions using :term:`keyword arguments` to
|
||||
:c:func:`mps_arena_create_k`::
|
||||
|
||||
MPS_ARGS_BEGIN(args) {
|
||||
MPS_ARGS_ADD(args, MPS_KEY_ARENA_EXTENDED, (mps_fun_t)arena_extended);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_ARENA_CONTRACTED, (mps_fun_t)arena_contracted);
|
||||
/* ... other keyword arguments ... */
|
||||
res = mps_arena_create_k(&arena, mps_arena_class_vm(), args);
|
||||
} MPS_ARGS_END(args);
|
||||
|
||||
The callback functions receive three arguments: ``arena`` (the arena
|
||||
being extended or contracted), ``base`` (the base address of the chunk
|
||||
of address space that has just been acquired from, or is about to be
|
||||
returned to, the operating system), and ``size`` (the size of the
|
||||
chunk, in bytes). They must not call any function in the MPS, and must
|
||||
not access any memory managed by the MPS.
|
||||
|
||||
.. note::
|
||||
|
||||
Arena extension callbacks are only supported by :term:`virtual
|
||||
memory arenas`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue