mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +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:
|
||||
|
||||
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() {
|
||||
InitRoots = true;
|
||||
}
|
||||
As a fallback, LLVM will automatically initialize each root to ``null``
|
||||
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
|
||||
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.
|
||||
Custom lowering of intrinsics
|
||||
------------------------------
|
||||
|
||||
Since LLVM does not yet compute liveness information, there is no means of
|
||||
distinguishing an uninitialized stack root from an initialized one. Therefore,
|
||||
this feature should be used by all GC plugins. It is enabled by default.
|
||||
|
||||
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
|
||||
For GCs which use barriers or unusual treatment of stack roots, the
|
||||
implementor is responsibly for providing a custom pass to lower the
|
||||
intrinsics with the desired semantics. If you have opted in to custom
|
||||
lowering of a particular intrinsic your pass **must** eliminate all
|
||||
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
|
||||
@ -884,62 +862,14 @@ without building a custom copy of LLVM.
|
||||
|
||||
.. _safe-points:
|
||||
|
||||
Generating safe points: ``NeededSafePoints``
|
||||
--------------------------------------------
|
||||
Generating safe points
|
||||
-----------------------
|
||||
|
||||
LLVM can compute four kinds of safe points:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
namespace GC {
|
||||
/// 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).
|
||||
LLVM provides support for associating stackmaps with the return address of
|
||||
a call. Any loop or return safepoints required by a given collector design
|
||||
can be modeled via calls to runtime routines, or potentially patchable call
|
||||
sequences. Using gcroot, all call instructions are inferred to be possible
|
||||
safepoints and will thus have an associated stackmap.
|
||||
|
||||
.. _assembly:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user