From 547a7afd32b44a0c0b116222728250a56b4ecca3 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 18 Oct 2013 23:09:06 +0000 Subject: [PATCH] Update to reflect current GC APIs and usage. The example code is taken from the Erlang GC implementation. llvm-svn: 193008 --- llvm/docs/GarbageCollection.rst | 110 ++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 62 deletions(-) diff --git a/llvm/docs/GarbageCollection.rst b/llvm/docs/GarbageCollection.rst index b722277..d78449e 100644 --- a/llvm/docs/GarbageCollection.rst +++ b/llvm/docs/GarbageCollection.rst @@ -523,7 +523,7 @@ extension): $ cat sample.ll define void @f() gc "mygc" { entry: - ret void + ret void } $ llvm-as < sample.ll | llc -load=MyGC.so @@ -896,11 +896,9 @@ in the JIT, nor using the object writers. namespace { class LLVM_LIBRARY_VISIBILITY MyGCPrinter : public GCMetadataPrinter { public: - virtual void beginAssembly(std::ostream &OS, AsmPrinter &AP, - const TargetAsmInfo &TAI); + virtual void beginAssembly(AsmPrinter &AP); - virtual void finishAssembly(std::ostream &OS, AsmPrinter &AP, - const TargetAsmInfo &TAI); + virtual void finishAssembly(AsmPrinter &AP); }; GCMetadataPrinterRegistry::Add @@ -920,85 +918,74 @@ map for the entire module, and may access the ``GCFunctionInfo`` using its own #include "llvm/Target/TargetAsmInfo.h" #include "llvm/Target/TargetMachine.h" - void MyGCPrinter::beginAssembly(std::ostream &OS, AsmPrinter &AP, - const TargetAsmInfo &TAI) { + void MyGCPrinter::beginAssembly(AsmPrinter &AP) { // Nothing to do. } - void MyGCPrinter::finishAssembly(std::ostream &OS, AsmPrinter &AP, - const TargetAsmInfo &TAI) { - // Set up for emitting addresses. - const char *AddressDirective; - int AddressAlignLog; - if (AP.TM.getDataLayout()->getPointerSize() == sizeof(int32_t)) { - AddressDirective = TAI.getData32bitsDirective(); - AddressAlignLog = 2; - } else { - AddressDirective = TAI.getData64bitsDirective(); - AddressAlignLog = 3; - } + void MyGCPrinter::finishAssembly(AsmPrinter &AP) { + MCStreamer &OS = AP.OutStreamer; + unsigned IntPtrSize = AP.TM.getDataLayout()->getPointerSize(); // Put this in the data section. - AP.SwitchToDataSection(TAI.getDataSection()); + OS.SwitchSection(AP.getObjFileLowering().getDataSection()); // For each function... for (iterator FI = begin(), FE = end(); FI != FE; ++FI) { GCFunctionInfo &MD = **FI; - // Emit this data structure: + // A compact GC layout. Emit this data structure: // // struct { // int32_t PointCount; - // struct { - // void *SafePointAddress; - // int32_t LiveCount; - // int32_t LiveOffsets[LiveCount]; - // } Points[PointCount]; + // void *SafePointAddress[PointCount]; + // int32_t StackFrameSize; // in words + // int32_t StackArity; + // int32_t LiveCount; + // int32_t LiveOffsets[LiveCount]; // } __gcmap_; // Align to address width. - AP.EmitAlignment(AddressAlignLog); - - // Emit the symbol by which the stack map entry can be found. - std::string Symbol; - Symbol += TAI.getGlobalPrefix(); - Symbol += "__gcmap_"; - Symbol += MD.getFunction().getName(); - if (const char *GlobalDirective = TAI.getGlobalDirective()) - OS << GlobalDirective << Symbol << "\n"; - OS << TAI.getGlobalPrefix() << Symbol << ":\n"; + AP.EmitAlignment(IntPtrSize == 4 ? 2 : 3); // Emit PointCount. + OS.AddComment("safe point count"); AP.EmitInt32(MD.size()); - AP.EOL("safe point count"); // And each safe point... for (GCFunctionInfo::iterator PI = MD.begin(), - PE = MD.end(); PI != PE; ++PI) { - // Align to address width. - AP.EmitAlignment(AddressAlignLog); - + PE = MD.end(); PI != PE; ++PI) { // Emit the address of the safe point. - OS << AddressDirective - << TAI.getPrivateGlobalPrefix() << "label" << PI->Num; - AP.EOL("safe point address"); - - // Emit the stack frame size. - AP.EmitInt32(MD.getFrameSize()); - AP.EOL("stack frame size"); - - // Emit the number of live roots in the function. - AP.EmitInt32(MD.live_size(PI)); - AP.EOL("live root count"); - - // And for each live root... - for (GCFunctionInfo::live_iterator LI = MD.live_begin(PI), - LE = MD.live_end(PI); - LI != LE; ++LI) { - // Print its offset within the stack frame. - AP.EmitInt32(LI->StackOffset); - AP.EOL("stack offset"); - } + OS.AddComment("safe point address"); + MCSymbol *Label = PI->Label; + AP.EmitLabelPlusOffset(Label/*Hi*/, 0/*Offset*/, 4/*Size*/); + } + + // Stack information never change in safe points! Only print info from the + // first call-site. + GCFunctionInfo::iterator PI = MD.begin(); + + // Emit the stack frame size. + OS.AddComment("stack frame size (in words)"); + 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); + + // Emit the number of live roots in the function. + OS.AddComment("live root count"); + AP.EmitInt32(MD.live_size(PI)); + + // And for each live root... + for (GCFunctionInfo::live_iterator LI = MD.live_begin(PI), + LE = MD.live_end(PI); + LI != LE; ++LI) { + // Emit live root's offset within the stack frame. + OS.AddComment("stack index (offset / wordsize)"); + AP.EmitInt32(LI->StackOffset); } } } @@ -1026,4 +1013,3 @@ programming. [Henderson2002] `Accurate Garbage Collection in an Uncooperative Environment `__ - -- 2.7.4