Mercurial > hg > CbC > CbC_llvm
comparison docs/GarbageCollection.rst @ 147:c2174574ed3a
LLVM 10
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 16:55:33 +0900 |
parents | 1172e4bd9c6f |
children |
comparison
equal
deleted
inserted
replaced
134:3a76565eade5 | 147:c2174574ed3a |
---|---|
431 so is very simple. (This code is heavily commented to help you understand the | 431 so is very simple. (This code is heavily commented to help you understand the |
432 data structure, but there are only 20 lines of meaningful code.) | 432 data structure, but there are only 20 lines of meaningful code.) |
433 | 433 |
434 .. code-block:: c++ | 434 .. code-block:: c++ |
435 | 435 |
436 /// @brief The map for a single function's stack frame. One of these is | 436 /// The map for a single function's stack frame. One of these is |
437 /// compiled as constant data into the executable for each function. | 437 /// compiled as constant data into the executable for each function. |
438 /// | 438 /// |
439 /// Storage of metadata values is elided if the %metadata parameter to | 439 /// Storage of metadata values is elided if the %metadata parameter to |
440 /// @llvm.gcroot is null. | 440 /// @llvm.gcroot is null. |
441 struct FrameMap { | 441 struct FrameMap { |
442 int32_t NumRoots; //< Number of roots in stack frame. | 442 int32_t NumRoots; //< Number of roots in stack frame. |
443 int32_t NumMeta; //< Number of metadata entries. May be < NumRoots. | 443 int32_t NumMeta; //< Number of metadata entries. May be < NumRoots. |
444 const void *Meta[0]; //< Metadata for each root. | 444 const void *Meta[0]; //< Metadata for each root. |
445 }; | 445 }; |
446 | 446 |
447 /// @brief A link in the dynamic shadow stack. One of these is embedded in | 447 /// A link in the dynamic shadow stack. One of these is embedded in |
448 /// the stack frame of each function on the call stack. | 448 /// the stack frame of each function on the call stack. |
449 struct StackEntry { | 449 struct StackEntry { |
450 StackEntry *Next; //< Link to next stack entry (the caller's). | 450 StackEntry *Next; //< Link to next stack entry (the caller's). |
451 const FrameMap *Map; //< Pointer to constant FrameMap. | 451 const FrameMap *Map; //< Pointer to constant FrameMap. |
452 void *Roots[0]; //< Stack roots (in-place array). | 452 void *Roots[0]; //< Stack roots (in-place array). |
453 }; | 453 }; |
454 | 454 |
455 /// @brief The head of the singly-linked list of StackEntries. Functions push | 455 /// The head of the singly-linked list of StackEntries. Functions push |
456 /// and pop onto this in their prologue and epilogue. | 456 /// and pop onto this in their prologue and epilogue. |
457 /// | 457 /// |
458 /// Since there is only a global list, this technique is not threadsafe. | 458 /// Since there is only a global list, this technique is not threadsafe. |
459 StackEntry *llvm_gc_root_chain; | 459 StackEntry *llvm_gc_root_chain; |
460 | 460 |
461 /// @brief Calls Visitor(root, meta) for each GC root on the stack. | 461 /// Calls Visitor(root, meta) for each GC root on the stack. |
462 /// root and meta are exactly the values passed to | 462 /// root and meta are exactly the values passed to |
463 /// @llvm.gcroot. | 463 /// @llvm.gcroot. |
464 /// | 464 /// |
465 /// Visitor could be a function to recursively mark live objects. Or it | 465 /// Visitor could be a function to recursively mark live objects. Or it |
466 /// might copy them to another heap or generation. | 466 /// might copy them to another heap or generation. |
833 custom lowering pass, LLVM will compute an empty stack map. This may be useful | 833 custom lowering pass, LLVM will compute an empty stack map. This may be useful |
834 for collector plugins which implement reference counting or a shadow stack. | 834 for collector plugins which implement reference counting or a shadow stack. |
835 | 835 |
836 .. _init-roots: | 836 .. _init-roots: |
837 | 837 |
838 Initializing roots to null: ``InitRoots`` | 838 Initializing roots to null |
839 ----------------------------------------- | 839 --------------------------- |
840 | 840 |
841 .. code-block:: c++ | 841 It is recommended that frontends initialize roots explicitly to avoid |
842 | 842 potentially confusing the optimizer. This prevents the GC from visiting |
843 MyGC::MyGC() { | 843 uninitialized pointers, which will almost certainly cause it to crash. |
844 InitRoots = true; | 844 |
845 } | 845 As a fallback, LLVM will automatically initialize each root to ``null`` |
846 | 846 upon entry to the function. Support for this mode in code generation is |
847 When set, LLVM will automatically initialize each root to ``null`` upon entry to | 847 largely a legacy detail to keep old collector implementations working. |
848 the function. This prevents the GC's sweep phase from visiting uninitialized | 848 |
849 pointers, which will almost certainly cause it to crash. This initialization | 849 Custom lowering of intrinsics |
850 occurs before custom lowering, so the two may be used together. | 850 ------------------------------ |
851 | 851 |
852 Since LLVM does not yet compute liveness information, there is no means of | 852 For GCs which use barriers or unusual treatment of stack roots, the |
853 distinguishing an uninitialized stack root from an initialized one. Therefore, | 853 implementor is responsibly for providing a custom pass to lower the |
854 this feature should be used by all GC plugins. It is enabled by default. | 854 intrinsics with the desired semantics. If you have opted in to custom |
855 | |
856 Custom lowering of intrinsics: ``CustomRoots``, ``CustomReadBarriers``, and ``CustomWriteBarriers`` | |
857 --------------------------------------------------------------------------------------------------- | |
858 | |
859 For GCs which use barriers or unusual treatment of stack roots, these | |
860 flags allow the collector to perform arbitrary transformations of the | |
861 LLVM IR: | |
862 | |
863 .. code-block:: c++ | |
864 | |
865 class MyGC : public GCStrategy { | |
866 public: | |
867 MyGC() { | |
868 CustomRoots = true; | |
869 CustomReadBarriers = true; | |
870 CustomWriteBarriers = true; | |
871 } | |
872 }; | |
873 | |
874 If any of these flags are set, LLVM suppresses its default lowering for | |
875 the corresponding intrinsics. Instead, you must provide a custom Pass | |
876 which lowers the intrinsics as desired. If you have opted in to custom | |
877 lowering of a particular intrinsic your pass **must** eliminate all | 855 lowering of a particular intrinsic your pass **must** eliminate all |
878 instances of the corresponding intrinsic in functions which opt in to | 856 instances of the corresponding intrinsic in functions which opt in to |
879 your GC. The best example of such a pass is the ShadowStackGC and it's | 857 your GC. The best example of such a pass is the ShadowStackGC and it's |
880 ShadowStackGCLowering pass. | 858 ShadowStackGCLowering pass. |
881 | 859 |
882 There is currently no way to register such a custom lowering pass | 860 There is currently no way to register such a custom lowering pass |
883 without building a custom copy of LLVM. | 861 without building a custom copy of LLVM. |
884 | 862 |
885 .. _safe-points: | 863 .. _safe-points: |
886 | 864 |
887 Generating safe points: ``NeededSafePoints`` | 865 Generating safe points |
888 -------------------------------------------- | 866 ----------------------- |
889 | 867 |
890 LLVM can compute four kinds of safe points: | 868 LLVM provides support for associating stackmaps with the return address of |
891 | 869 a call. Any loop or return safepoints required by a given collector design |
892 .. code-block:: c++ | 870 can be modeled via calls to runtime routines, or potentially patchable call |
893 | 871 sequences. Using gcroot, all call instructions are inferred to be possible |
894 namespace GC { | 872 safepoints and will thus have an associated stackmap. |
895 /// PointKind - The type of a collector-safe point. | |
896 /// | |
897 enum PointKind { | |
898 Loop, //< Instr is a loop (backwards branch). | |
899 Return, //< Instr is a return instruction. | |
900 PreCall, //< Instr is a call instruction. | |
901 PostCall //< Instr is the return address of a call. | |
902 }; | |
903 } | |
904 | |
905 A collector can request any combination of the four by setting the | |
906 ``NeededSafePoints`` mask: | |
907 | |
908 .. code-block:: c++ | |
909 | |
910 MyGC::MyGC() { | |
911 NeededSafePoints = 1 << GC::Loop | |
912 | 1 << GC::Return | |
913 | 1 << GC::PreCall | |
914 | 1 << GC::PostCall; | |
915 } | |
916 | |
917 It can then use the following routines to access safe points. | |
918 | |
919 .. code-block:: c++ | |
920 | |
921 for (iterator I = begin(), E = end(); I != E; ++I) { | |
922 GCFunctionInfo *MD = *I; | |
923 size_t PointCount = MD->size(); | |
924 | |
925 for (GCFunctionInfo::iterator PI = MD->begin(), | |
926 PE = MD->end(); PI != PE; ++PI) { | |
927 GC::PointKind PointKind = PI->Kind; | |
928 unsigned PointNum = PI->Num; | |
929 } | |
930 } | |
931 | |
932 Almost every collector requires ``PostCall`` safe points, since these correspond | |
933 to the moments when the function is suspended during a call to a subroutine. | |
934 | |
935 Threaded programs generally require ``Loop`` safe points to guarantee that the | |
936 application will reach a safe point within a bounded amount of time, even if it | |
937 is executing a long-running loop which contains no function calls. | |
938 | |
939 Threaded collectors may also require ``Return`` and ``PreCall`` safe points to | |
940 implement "stop the world" techniques using self-modifying code, where it is | |
941 important that the program not exit the function without reaching a safe point | |
942 (because only the topmost function has been patched). | |
943 | 873 |
944 .. _assembly: | 874 .. _assembly: |
945 | 875 |
946 Emitting assembly code: ``GCMetadataPrinter`` | 876 Emitting assembly code: ``GCMetadataPrinter`` |
947 --------------------------------------------- | 877 --------------------------------------------- |
1030 // Align to address width. | 960 // Align to address width. |
1031 AP.EmitAlignment(IntPtrSize == 4 ? 2 : 3); | 961 AP.EmitAlignment(IntPtrSize == 4 ? 2 : 3); |
1032 | 962 |
1033 // Emit PointCount. | 963 // Emit PointCount. |
1034 OS.AddComment("safe point count"); | 964 OS.AddComment("safe point count"); |
1035 AP.EmitInt32(MD.size()); | 965 AP.emitInt32(MD.size()); |
1036 | 966 |
1037 // And each safe point... | 967 // And each safe point... |
1038 for (GCFunctionInfo::iterator PI = MD.begin(), | 968 for (GCFunctionInfo::iterator PI = MD.begin(), |
1039 PE = MD.end(); PI != PE; ++PI) { | 969 PE = MD.end(); PI != PE; ++PI) { |
1040 // Emit the address of the safe point. | 970 // Emit the address of the safe point. |
1047 // first call-site. | 977 // first call-site. |
1048 GCFunctionInfo::iterator PI = MD.begin(); | 978 GCFunctionInfo::iterator PI = MD.begin(); |
1049 | 979 |
1050 // Emit the stack frame size. | 980 // Emit the stack frame size. |
1051 OS.AddComment("stack frame size (in words)"); | 981 OS.AddComment("stack frame size (in words)"); |
1052 AP.EmitInt32(MD.getFrameSize() / IntPtrSize); | 982 AP.emitInt32(MD.getFrameSize() / IntPtrSize); |
1053 | 983 |
1054 // Emit stack arity, i.e. the number of stacked arguments. | 984 // Emit stack arity, i.e. the number of stacked arguments. |
1055 unsigned RegisteredArgs = IntPtrSize == 4 ? 5 : 6; | 985 unsigned RegisteredArgs = IntPtrSize == 4 ? 5 : 6; |
1056 unsigned StackArity = MD.getFunction().arg_size() > RegisteredArgs ? | 986 unsigned StackArity = MD.getFunction().arg_size() > RegisteredArgs ? |
1057 MD.getFunction().arg_size() - RegisteredArgs : 0; | 987 MD.getFunction().arg_size() - RegisteredArgs : 0; |
1058 OS.AddComment("stack arity"); | 988 OS.AddComment("stack arity"); |
1059 AP.EmitInt32(StackArity); | 989 AP.emitInt32(StackArity); |
1060 | 990 |
1061 // Emit the number of live roots in the function. | 991 // Emit the number of live roots in the function. |
1062 OS.AddComment("live root count"); | 992 OS.AddComment("live root count"); |
1063 AP.EmitInt32(MD.live_size(PI)); | 993 AP.emitInt32(MD.live_size(PI)); |
1064 | 994 |
1065 // And for each live root... | 995 // And for each live root... |
1066 for (GCFunctionInfo::live_iterator LI = MD.live_begin(PI), | 996 for (GCFunctionInfo::live_iterator LI = MD.live_begin(PI), |
1067 LE = MD.live_end(PI); | 997 LE = MD.live_end(PI); |
1068 LI != LE; ++LI) { | 998 LI != LE; ++LI) { |
1069 // Emit live root's offset within the stack frame. | 999 // Emit live root's offset within the stack frame. |
1070 OS.AddComment("stack index (offset / wordsize)"); | 1000 OS.AddComment("stack index (offset / wordsize)"); |
1071 AP.EmitInt32(LI->StackOffset); | 1001 AP.emitInt32(LI->StackOffset); |
1072 } | 1002 } |
1073 } | 1003 } |
1074 } | 1004 } |
1075 | 1005 |
1076 References | 1006 References |