mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:12:47 +01:00
[GC docs] Update the gcroot documentation to reflect recent simplifcations to GCStrategy configurability
llvm-svn: 346702
This commit is contained in:
parent
8fecb1f475
commit
b158fed4ac
@ -835,45 +835,23 @@ for collector plugins which implement reference counting or a shadow stack.
|
|||||||
|
|
||||||
.. _init-roots:
|
.. _init-roots:
|
||||||
|
|
||||||
Initializing roots to null: ``InitRoots``
|
Initializing roots to null
|
||||||
-----------------------------------------
|
---------------------------
|
||||||
|
|
||||||
.. code-block:: c++
|
It is recommended that frontends initialize roots explicitly to avoid
|
||||||
|
potentially confusing the optimizer. This prevents the GC from visiting
|
||||||
|
uninitialized pointers, which will almost certainly cause it to crash.
|
||||||
|
|
||||||
MyGC::MyGC() {
|
As a fallback, LLVM will automatically initialize each root to ``null``
|
||||||
InitRoots = true;
|
upon entry to the function. Support for this mode in code generation is
|
||||||
}
|
largely a legacy detail to keep old collector implementations working.
|
||||||
|
|
||||||
When set, LLVM will automatically initialize each root to ``null`` upon entry to
|
Custom lowering of intrinsics
|
||||||
the function. This prevents the GC's sweep phase from visiting uninitialized
|
------------------------------
|
||||||
pointers, which will almost certainly cause it to crash. This initialization
|
|
||||||
occurs before custom lowering, so the two may be used together.
|
|
||||||
|
|
||||||
Since LLVM does not yet compute liveness information, there is no means of
|
For GCs which use barriers or unusual treatment of stack roots, the
|
||||||
distinguishing an uninitialized stack root from an initialized one. Therefore,
|
implementor is responsibly for providing a custom pass to lower the
|
||||||
this feature should be used by all GC plugins. It is enabled by default.
|
intrinsics with the desired semantics. If you have opted in to custom
|
||||||
|
|
||||||
Custom lowering of intrinsics: ``CustomRoots``, ``CustomReadBarriers``, and ``CustomWriteBarriers``
|
|
||||||
---------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
For GCs which use barriers or unusual treatment of stack roots, these
|
|
||||||
flags allow the collector to perform arbitrary transformations of the
|
|
||||||
LLVM IR:
|
|
||||||
|
|
||||||
.. code-block:: c++
|
|
||||||
|
|
||||||
class MyGC : public GCStrategy {
|
|
||||||
public:
|
|
||||||
MyGC() {
|
|
||||||
CustomRoots = true;
|
|
||||||
CustomReadBarriers = true;
|
|
||||||
CustomWriteBarriers = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
If any of these flags are set, LLVM suppresses its default lowering for
|
|
||||||
the corresponding intrinsics. Instead, you must provide a custom Pass
|
|
||||||
which lowers the intrinsics as desired. If you have opted in to custom
|
|
||||||
lowering of a particular intrinsic your pass **must** eliminate all
|
lowering of a particular intrinsic your pass **must** eliminate all
|
||||||
instances of the corresponding intrinsic in functions which opt in to
|
instances of the corresponding intrinsic in functions which opt in to
|
||||||
your GC. The best example of such a pass is the ShadowStackGC and it's
|
your GC. The best example of such a pass is the ShadowStackGC and it's
|
||||||
@ -884,62 +862,14 @@ without building a custom copy of LLVM.
|
|||||||
|
|
||||||
.. _safe-points:
|
.. _safe-points:
|
||||||
|
|
||||||
Generating safe points: ``NeededSafePoints``
|
Generating safe points
|
||||||
--------------------------------------------
|
-----------------------
|
||||||
|
|
||||||
LLVM can compute four kinds of safe points:
|
LLVM provides support for associating stackmaps with the return address of
|
||||||
|
a call. Any loop or return safepoints required by a given collector design
|
||||||
.. code-block:: c++
|
can be modeled via calls to runtime routines, or potentially patchable call
|
||||||
|
sequences. Using gcroot, all call instructions are inferred to be possible
|
||||||
namespace GC {
|
safepoints and will thus have an associated stackmap.
|
||||||
/// PointKind - The type of a collector-safe point.
|
|
||||||
///
|
|
||||||
enum PointKind {
|
|
||||||
Loop, //< Instr is a loop (backwards branch).
|
|
||||||
Return, //< Instr is a return instruction.
|
|
||||||
PreCall, //< Instr is a call instruction.
|
|
||||||
PostCall //< Instr is the return address of a call.
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
A collector can request any combination of the four by setting the
|
|
||||||
``NeededSafePoints`` mask:
|
|
||||||
|
|
||||||
.. code-block:: c++
|
|
||||||
|
|
||||||
MyGC::MyGC() {
|
|
||||||
NeededSafePoints = 1 << GC::Loop
|
|
||||||
| 1 << GC::Return
|
|
||||||
| 1 << GC::PreCall
|
|
||||||
| 1 << GC::PostCall;
|
|
||||||
}
|
|
||||||
|
|
||||||
It can then use the following routines to access safe points.
|
|
||||||
|
|
||||||
.. code-block:: c++
|
|
||||||
|
|
||||||
for (iterator I = begin(), E = end(); I != E; ++I) {
|
|
||||||
GCFunctionInfo *MD = *I;
|
|
||||||
size_t PointCount = MD->size();
|
|
||||||
|
|
||||||
for (GCFunctionInfo::iterator PI = MD->begin(),
|
|
||||||
PE = MD->end(); PI != PE; ++PI) {
|
|
||||||
GC::PointKind PointKind = PI->Kind;
|
|
||||||
unsigned PointNum = PI->Num;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Almost every collector requires ``PostCall`` safe points, since these correspond
|
|
||||||
to the moments when the function is suspended during a call to a subroutine.
|
|
||||||
|
|
||||||
Threaded programs generally require ``Loop`` safe points to guarantee that the
|
|
||||||
application will reach a safe point within a bounded amount of time, even if it
|
|
||||||
is executing a long-running loop which contains no function calls.
|
|
||||||
|
|
||||||
Threaded collectors may also require ``Return`` and ``PreCall`` safe points to
|
|
||||||
implement "stop the world" techniques using self-modifying code, where it is
|
|
||||||
important that the program not exit the function without reaching a safe point
|
|
||||||
(because only the topmost function has been patched).
|
|
||||||
|
|
||||||
.. _assembly:
|
.. _assembly:
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user