1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-04-30 18:23:20 -07:00
emacs/mps/design/prot.txt

203 lines
7.5 KiB
ReStructuredText

.. mode: -*- rst -*-
Memory protection
=================
:Tag: design.mps.prot
:Author: David Jones
:Date: 1997-04-02
:Status: complete design
:Revision: $Id$
:Copyright: See `Copyright and License`_.
:Index terms: pair: memory protection; design
Introduction
------------
_`.intro`: This is the design of the memory protection module.
_`.readership`: Any MPS developer; anyone porting the MPS to a new
platform.
_`.overview`: The memory protection module ensures that the mutator
sees a consistent view of memory during incremental collection, by
applying protection to areas of memory, ensuring that attempts to read
or write from those areas cause protection faults, and implementing
the means for the MPS to handle these faults.
Requirements
------------
_`.req.consistent`: Must ensure that the mutator sees a consistent
view of memory during incremental collection: in particular, the
mutator must never see objects in oldspace. (Otherwise there's no way
for the MPS to interface with uncooperative code.)
_`.req.prot.read`: Should allow collections to proceed incrementally,
by read-protecting pages that are not consistent from the mutator's
point of view. (This is the only way for the MPS to meet real-time
requirements on pause times.)
_`.req.prot.write`: Should allow the MPS to maintain remembered sets
for segments that it has scanned, by write-protecting pages in these
segments. (This improves performance by allowing the MPS to avoid
scanning these segments again.)
_`.req.fault.handle`: If the module implements protection, it must
also provide a mechanism for handling protection faults. (Otherwise
the MPS cannot take the correct action: that is, fixing references in
a read-protected segment, and discarding the remembered set from a
write-protected segment. See ``TraceSegAccess()``.)
Design
------
_`.sol.sync`: If memory protection is not available, the only way to
meet `.req.consistent`_ is to ensure that no protection is required,
by running the collector until it has no more incremental work to do.
(This makes it impossible to meet real-time requirements on pause
times, but may be the best that can be done.)
_`.sol.fault.handle`: The protection module handles protection faults
by decoding the context of the fault (see
design.mps.prmc.req.fault.addr_ and design.mps.prmc.req.fault.access_)
and calling ``ArenaAccess()``.
.. _design.mps.prmc.req.fault.addr: prmc#req-fault-addr
.. _design.mps.prmc.req.fault.access: prmc#req-fault-access
Interface
---------
``void ProtSetup(void)``
_`.if.setup`: Called exactly once (per process) as part of the
initialization of the first arena that is created. It must arrange for
the setup and initialization of any data structures or services that
are necessary in order to implement the memory protection module.
``Size ProtGranularity(void)``
_`.if.granularity`: Return the granularity of protection. The ``base``
and ``limit`` arguments to ``ProtSet()`` must be multiples of the
protection granularity.
``void ProtSet(Addr base, Addr limit, AccessSet mode)``
_`.if.set`: Set the protection of the range of memory between ``base``
(inclusive) and ``limit`` (exclusive) to *forbid* the specified modes.
The addresses ``base`` and ``limit`` are multiples of the protection
granularity. The ``mode`` parameter contains the ``AccessWRITE`` bit
if write accesses to the range are to be forbidden, and contains the
``AccessREAD`` bit if read accesses to the range are to be forbidden.
_`.if.set.read`: If the request is to forbid read accesses (that is,
``AccessREAD`` is set) then the implemntation may also forbid write
accesses, but read accesses must not be forbidden unless
``AccessREAD`` is set.
_`.if.set.noop`: ``ProtSet()`` is permitted to be a no-op if
``ProtSync()`` is implemented.
``void ProtSync(Arena arena)``
_`.if.sync`: Ensure that the actual protection (as determined by the
operating system) of every segment in the arena matches the segment's
protection mode (``seg->pm``).
_`.if.sync.noop`: ``ProtSync()`` is permitted to be a no-op if
``ProtSet()`` is implemented.
Implementations
---------------
_`.impl.an`: Generic implementation in ``protan.c``.
_`.impl.an.set`: ``ProtSet()`` does nothing.
_`.impl.an.sync`: ``ProtSync()`` has no way of changing the protection
of a segment, so it simulates faults on all segments that are supposed
to be protected, by calling ``TraceSegAccess()``, until it determines
that no segments require protection any more. This forces the trace to
proceed until it is completed, preventing incremental collection.
_`.impl.an.sync.issue`: This relies on the pool actually removing the
protection, otherwise there is an infinite loop here. This is
therefore not compatible with implementations of the protection
mutator context module that support single-stepping of accesses (see design.mps.prmc.req.fault.step_).
.. _design.mps.prmc.req.fault.step: prmc#req-fault-step
_`.impl.ix`: POSIX implementation. See design.mps.protix_.
.. _design.mps.protix: protix
_`.impl.w3`: Windows implementation.
_`.impl.xc`: macOS implementation.
Document History
----------------
- 1997-04-02 David Jones. Incomplete document.
- 2002-06-07 RB_ Converted from MMInfo database design document.
- 2013-05-23 GDR_ Converted to reStructuredText.
- 2014-10-23 GDR_ Move mutator context interface to design.mps.prmc_.
Bring design up to date.
.. _design.mps.prmc: prmc
.. _RB: http://www.ravenbrook.com/consultants/rb/
.. _GDR: http://www.ravenbrook.com/consultants/gdr/
Copyright and License
---------------------
Copyright © 2013-2018 Ravenbrook Limited <http://www.ravenbrook.com/>.
All rights reserved. This is an open source license. Contact
Ravenbrook for commercial licensing options.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
#. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
#. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
#. Redistributions in any form must be accompanied by information on how
to obtain complete source code for this software and any
accompanying software that uses this software. The source code must
either be included in the distribution or be available for no more than
the cost of distribution plus a nominal fee, and must be freely
redistributable under reasonable conditions. For an executable file,
complete source code means the source code for all modules it contains.
It does not include source code for modules or files that typically
accompany the major components of the operating system on which the
executable file runs.
**This software is provided by the copyright holders and contributors
"as is" and any express or implied warranties, including, but not
limited to, the implied warranties of merchantability, fitness for a
particular purpose, or non-infringement, are disclaimed. In no event
shall the copyright holders and contributors be liable for any direct,
indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or
services; loss of use, data, or profits; or business interruption)
however caused and on any theory of liability, whether in contract,
strict liability, or tort (including negligence or otherwise) arising in
any way out of the use of this software, even if advised of the
possibility of such damage.**