diff --git a/mps/design/index.txt b/mps/design/index.txt index 42fc7256df5..da38e0963a4 100644 --- a/mps/design/index.txt +++ b/mps/design/index.txt @@ -96,6 +96,7 @@ seg_ Segment data structure shield_ Shield sig_ Signatures in the MPS splay_ Splay trees +ss_ Stack and register scanning sso1al_ Stack scanner for Digital Unix / Alpha systems strategy_ Collection strategy telemetry_ Telemetry @@ -170,6 +171,7 @@ writef_ The WriteF function .. _shield: shield .. _sig: sig .. _splay: splay +.. _ss: ss .. _sso1al: sso1al .. _strategy: strategy .. _telemetry: telemetry diff --git a/mps/design/ss.txt b/mps/design/ss.txt new file mode 100644 index 00000000000..e7ef49ab09f --- /dev/null +++ b/mps/design/ss.txt @@ -0,0 +1,186 @@ +.. mode: -*- rst -*- + +Stack and register scanning +=========================== + +:Tag: design.mps.ss +:Author: Gareth Rees +:Date: 2014-10-22 +:Status: complete design +:Revision: $Id: //info.ravenbrook.com/project/mps/master/design/thread-manager.txt#7 $ +:Copyright: See `Copyright and License`_. +:Index terms: pair: stack and register scanning; design + + +Introduction +------------ + +_`.intro`: This document describes the design of the stack and +register scanning module. + +_`.readership`: Any MPS developer. + +_`.overview`: This module locates and scans references in the control +stack and registers of the *current* thread. + +_`.other`: The thread manager module is responsible for scanning the +control stack and registers of *other* threads. See +design.mps.thread-manager.if.scan_. + +.. _design.mps.thread-manager.if.scan: thread-manager#if.scan + + +Requirements +------------ + +_`.req.stack.top`: Must locate the top of the mutator's stack. (This +is needed to support conservative garbage collection of uncooperative +code, where references might be stored by mutator on its stack.) + +_`.req.stack.bottom.not`: There is no requirement to locate the bottom +of the stack. (The mutator supplies this as an argument to +``mps_root_create_reg``.) + +_`.req.registers`: Must locate and scan all references in the *root +registers*, the subset of registers which might contain references +that do not also appear on the stack. (This is needed to support +conservative garbage collection of uncooperative code, where +references might appear in registers.) + + +Design +------ + +_`.registers`: The root registers are the subset of the callee-save +registers that may contain pointers. + +_`.registers.not`: The caller-save registers will have been spilled +onto the stack by the time the MPS is entered, so will be scanned by +the stack scan. Floating-point registers and debugging registers do +not, as far as we are aware, contain pointers. + +_`.sol.stack.top`: Implementations find the top of the stack by +taking the address of a local variable. + +_`.sol.registers`: Implementations spill the root registers onto the +stack so that they can be scanned there. + +_`.sol.inner`: Having located the top of the stack (``stackTop``), and +spilled the root registers into the next ``n`` words, implementations +call the generic function ``StackScanInner(ss, stackBot, stackTop, +n)`` to actually do the scanning. + + +Interface +--------- + +``Res StackScan(ScanState ss, Addr *stackBot)`` + +_`.if.scan`: Scan the root registers of the current thread, and the +control stack between ``stackBot`` and the top of the stack, in the +context of the given scan state. Return ``ResOK`` if successful, or +another result code if not. + + +Issue +----- + +_`.issue.overscan`: This design leads to over-scanning, because by the +time ``StackScan()`` is called, there are several MPS functions on the +stack. The scan thus ends up scanning references that belong the MPS, +not to the mutator. See job003525_. + +.. _job003525: http://www.ravenbrook.com/project/mps/issue/job003525/ + + +Implementations +--------------- + +Generic implementation +...................... + +_`.impl.an`: In ``ssan.c``. + +_`.impl.an.registers`: This calls ``setjmp()`` with a stack-allocated +``jmp_buf`` to spill the registers onto the stack. The C standard +specifies that ``jmp_buf`` "is an array type suitable for holding the +information needed to restore a calling environment. The environment +of a call to the ``setjmp`` macro consists of information sufficient +for a call to the ``longjmp`` function to return execution to the +correct block and invocation of that block, were it called +recursively." Note that the C standard does not specify where the +callee-save registers appear in the ``jmp_buf``, so the whole buffer +must be scanned. + + +Unix implementation +................... + +_`.impl.ix`: In ``ssixi3.c`` and ``ssixi6.c``. + +_`.impl.ix.registers`: Assembler instructions are used to spill +exactly the callee-save registers. (Clang and GCC support a common +assembler syntax.) + + +Windows implementation +...................... + +_`.impl.w3`: In ``ssw3i3mv.c`` and ``ssw3i6mv.c``. + +_`.impl.w3.registers`: This implementation uses ``setjmp()`` with a +stack-allocated ``jmp_buf`` to spill the registers onto the stack, as +for `.impl.an.registers`_. However, we know the layout of the +``jmp_buf`` used by Microsoft C/C++, and so can scan exactly the +subset of registers we need. + + +Document History +---------------- + +- 2014-10-22 GDR_ Initial draft. + +.. _GDR: http://www.ravenbrook.com/consultants/gdr/ + + +Copyright and License +--------------------- + +Copyright © 2014 Ravenbrook Limited. 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.** diff --git a/mps/manual/source/design/index.rst b/mps/manual/source/design/index.rst index c9419e34806..30cba4c8dfd 100644 --- a/mps/manual/source/design/index.rst +++ b/mps/manual/source/design/index.rst @@ -25,6 +25,7 @@ Design ring sig splay + ss testthr thread-manager type diff --git a/mps/manual/source/topic/porting.rst b/mps/manual/source/topic/porting.rst index 09ec0d5778f..d8a0262efc3 100644 --- a/mps/manual/source/topic/porting.rst +++ b/mps/manual/source/topic/porting.rst @@ -60,7 +60,7 @@ usable. See :ref:`design-vm` for the design, and ``vm.h`` for the interface. There are implementations for POSIX in ``vmix.c``, and Windows in ``vmw3.c``. There is a generic implementation in - ``vman.c``, which fakes virtual memory by calling ``malloc``. + ``vman.c``, which fakes virtual memory by calling :c:func:`malloc`. #. The **memory protection** module applies :term:`protection` to areas of :term:`memory (2)`, ensuring that attempts to read or @@ -99,12 +99,12 @@ usable. #. The **stack and register scanning** module :term:`scans` the :term:`registers` and :term:`control stack` of a thread. - See :ref:`design-thread-manager` for the design, and ``ss.h`` for - the interface. There are implementations for POSIX on IA-32 in + See :ref:`design-ss` for the design, and ``ss.h`` for the + interface. There are implementations for POSIX on IA-32 in ``ssixi3.c`` and x86-64 in ``ssixi6.c``, and for Windows with Microsoft Visual C/C++ on IA-32 in ``ssw3i3mv.c`` and x86-64 in ``ssw3i6mv.c``. There is a generic implementation in ``ssan.c``, - which calls ``setjmp`` to spill the registers. + which calls :c:func:`setjmp` to spill the registers. Platform detection