如何在LLVM中使用statepoint-example策略实现垃圾收集器?

问题描述 投票:0回答:1

我是 LLVM 新手,我正在尝试实现一个使用 statepoint API 的垃圾收集器。我已经阅读了所有文档,并且我想我对我前面的道路有所了解。然而,我对这是正确的道路没有信心。

我还没能在网上找到使用状态点示例策略的运行时实现。 LLVM 文档在

/llvm/runtime/
下的存储库中提到了示例,但它们似乎已经消失了。

以下是我对需要做什么的理解:

我想使用 statepoint API 而不是

gc_root
,因为文档建议在新项目中使用它。我明白我需要执行以下操作:

  1. 使用

    UseStatepoints = true
    声明自定义GC策略;和
    UseRS4GC = true
    或使用
    statepoint-example
    内置策略。我计划使用
    statepoint-example
    除非我遇到阻止我使用它的技术问题。

  2. 注释我的所有函数以使用 setGC 来使用此策略:

    #include <llvm/IR/IRBuilder.h>
    // ...
    Function *fn = Function::Create(prototype, Function::ExternalLinkage, function_name, 
    module.get());
    fn.setGC("statepoint-example");
    
  3. 使用RewriteStatepointsForGC转换过程将自动引入注释,例如

    @llvm.experimental.gc.statepoint
    @llvm.experimental.gc.relocate

  4. 使用

    PlaceSafepoints
    转换过程在安全点自动添加对
    safepoint_poll
    的调用。

  5. 我的 GC 应该有一个初始化阶段,该阶段在应用程序启动之前调用,并使用

    GCFunctionMetadata::roots_begin()
    中的
    end()
    GCMetadataPrinter
    来访问堆栈映射。堆栈映射应采用以下格式:

    Header {
        uint8  : Stack Map Version (current version is 3)
        uint8  : Reserved (expected to be 0)
        uint16 : Reserved (expected to be 0)
    }
    uint32 : NumFunctions
    uint32 : NumConstants
    uint32 : NumRecords
    StkSizeRecord[NumFunctions] {
        uint64 : Function Address
        uint64 : Stack Size (or UINT64_MAX if not statically known)
        uint64 : Record Count
    }
    Constants[NumConstants] {
        uint64 : LargeConstant
    }
    StkMapRecord[NumRecords] {
        uint64 : PatchPoint ID
        uint32 : Instruction Offset
        uint16 : Reserved (record flags)
        uint16 : NumLocations
        Location[NumLocations] {
            uint8  : Register | Direct | Indirect | Constant | ConstantIndex
            uint8  : Reserved (expected to be 0)
            uint16 : Location Size
            uint16 : Dwarf RegNum
            uint16 : Reserved (expected to be 0)
            int32  : Offset or SmallConstant
        }
        uint32 : Padding (only if required to align to 8 byte)
        uint16 : Padding
        uint16 : NumLiveOuts
        LiveOuts[NumLiveOuts]
            uint16 : Dwarf RegNum
            uint8  : Reserved
            uint8  : Size in Bytes
        }
        uint32 : Padding (only if required to align to 8 byte)
    

    然后,我可以将堆栈映射(可选)映射到易于 GC 使用的数据结构。

  6. 运行时应实现在安全点调用的函数

    safepoint_poll
    (步骤 4),并使用步骤 5 中收集的数据来检查是否需要垃圾收集过程。

有经验的人可以确认我是否走在正确的道路上吗?如果您知道我在哪里可以找到示例实现,那就太棒了。

谢谢!

c++ garbage-collection llvm
1个回答
0
投票

要使用Statepoint API,您必须创建一个“自定义垃圾收集(GC)策略;启用状态点和其他选项

class MyGC : public llvm::GCStrategy {
public:
    MyGC() {
        UseStatepoints = true;
        UseRS4GC = true;
    }
};

使用这些转换过程添加状态点和安全点。在 LLVM,您可以通过

PassManager
:

应用这些转换
llvm::legacy::PassManager PM;
PM.add(llvm::createRewriteStatepointsForGC());
PM.add(llvm::createPlaceSafepoints());
PM.run(*module);

LLVM 的源代码通常是您可以找到 GC 策略和状态点的最佳示例的地方。

使用来源:

我希望这个解决方案对您有所帮助,如果遇到其他问题,您可以告诉我

© www.soinside.com 2019 - 2024. All rights reserved.