diff docs/GarbageCollection.rst @ 148:63bd29f05246

merged
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 14 Aug 2019 19:46:37 +0900
parents c2174574ed3a
children
line wrap: on
line diff
--- a/docs/GarbageCollection.rst	Sun Dec 23 19:23:36 2018 +0900
+++ b/docs/GarbageCollection.rst	Wed Aug 14 19:46:37 2019 +0900
@@ -433,7 +433,7 @@
 
 .. code-block:: c++
 
-  /// @brief The map for a single function's stack frame.  One of these is
+  /// The map for a single function's stack frame.  One of these is
   ///        compiled as constant data into the executable for each function.
   ///
   /// Storage of metadata values is elided if the %metadata parameter to
@@ -444,7 +444,7 @@
     const void *Meta[0]; //< Metadata for each root.
   };
 
-  /// @brief A link in the dynamic shadow stack.  One of these is embedded in
+  /// A link in the dynamic shadow stack.  One of these is embedded in
   ///        the stack frame of each function on the call stack.
   struct StackEntry {
     StackEntry *Next;    //< Link to next stack entry (the caller's).
@@ -452,13 +452,13 @@
     void *Roots[0];      //< Stack roots (in-place array).
   };
 
-  /// @brief The head of the singly-linked list of StackEntries.  Functions push
+  /// The head of the singly-linked list of StackEntries.  Functions push
   ///        and pop onto this in their prologue and epilogue.
   ///
   /// Since there is only a global list, this technique is not threadsafe.
   StackEntry *llvm_gc_root_chain;
 
-  /// @brief Calls Visitor(root, meta) for each GC root on the stack.
+  /// Calls Visitor(root, meta) for each GC root on the stack.
   ///        root and meta are exactly the values passed to
   ///        @llvm.gcroot.
   ///
@@ -835,45 +835,23 @@
 
 .. _init-roots:
 
-Initializing roots to null: ``InitRoots``
------------------------------------------
-
-.. code-block:: c++
-
-  MyGC::MyGC() {
-    InitRoots = true;
-  }
+Initializing roots to null
+---------------------------
 
-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.
-
-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.
+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.
 
-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++
+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.
 
-  class MyGC : public GCStrategy {
-  public:
-    MyGC() {
-      CustomRoots = true;
-      CustomReadBarriers = true;
-      CustomWriteBarriers = true;
-    }
-  };
+Custom lowering of intrinsics
+------------------------------
 
-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 @@
 
 .. _safe-points:
 
-Generating safe points: ``NeededSafePoints``
---------------------------------------------
-
-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++
+Generating safe points
+-----------------------
 
-  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:
 
@@ -1032,7 +962,7 @@
 
       // Emit PointCount.
       OS.AddComment("safe point count");
-      AP.EmitInt32(MD.size());
+      AP.emitInt32(MD.size());
 
       // And each safe point...
       for (GCFunctionInfo::iterator PI = MD.begin(),
@@ -1049,18 +979,18 @@
 
       // Emit the stack frame size.
       OS.AddComment("stack frame size (in words)");
-      AP.EmitInt32(MD.getFrameSize() / IntPtrSize);
+      AP.emitInt32(MD.getFrameSize() / IntPtrSize);
 
       // Emit stack arity, i.e. the number of stacked arguments.
       unsigned RegisteredArgs = IntPtrSize == 4 ? 5 : 6;
       unsigned StackArity = MD.getFunction().arg_size() > RegisteredArgs ?
                             MD.getFunction().arg_size() - RegisteredArgs : 0;
       OS.AddComment("stack arity");
-      AP.EmitInt32(StackArity);
+      AP.emitInt32(StackArity);
 
       // Emit the number of live roots in the function.
       OS.AddComment("live root count");
-      AP.EmitInt32(MD.live_size(PI));
+      AP.emitInt32(MD.live_size(PI));
 
       // And for each live root...
       for (GCFunctionInfo::live_iterator LI = MD.live_begin(PI),
@@ -1068,7 +998,7 @@
                                          LI != LE; ++LI) {
         // Emit live root's offset within the stack frame.
         OS.AddComment("stack index (offset / wordsize)");
-        AP.EmitInt32(LI->StackOffset);
+        AP.emitInt32(LI->StackOffset);
       }
     }
   }