From edeff09e866077bb260c0ca44fdc82fda978602b Mon Sep 17 00:00:00 2001 From: valtermiari Date: Tue, 21 Mar 2023 13:11:58 +0100 Subject: [PATCH] Started skeleton for accurate GC --- src/Accurate_GC/Makefile | 5 +++ src/Accurate_GC/gc.cpp | 16 ++++++++ src/Accurate_GC/gc_printer.cpp | 16 ++++++++ src/Accurate_GC/shadow_stack.cpp | 63 ++++++++++++++++++++++++++++++++ 4 files changed, 100 insertions(+) create mode 100644 src/Accurate_GC/Makefile create mode 100644 src/Accurate_GC/gc.cpp create mode 100644 src/Accurate_GC/gc_printer.cpp create mode 100644 src/Accurate_GC/shadow_stack.cpp diff --git a/src/Accurate_GC/Makefile b/src/Accurate_GC/Makefile new file mode 100644 index 0000000..347e2dc --- /dev/null +++ b/src/Accurate_GC/Makefile @@ -0,0 +1,5 @@ +LEVEL := ../.. +LIBRARYNAME = GC +LOADABLE_MODULE = 1 + +include $(LEVEL)/Makefile.common \ No newline at end of file diff --git a/src/Accurate_GC/gc.cpp b/src/Accurate_GC/gc.cpp new file mode 100644 index 0000000..f4a8ca8 --- /dev/null +++ b/src/Accurate_GC/gc.cpp @@ -0,0 +1,16 @@ +/* // TODO: include these properly +#include "llvm/CodeGen/GCStrategy.h" +#include "llvm/CodeGen/GCMetadata.h" +#include "llvm/Support/Compiler.h" + +using namespace llvm; + +namespace { + class LLVM_LIBRARY_VISIBILITY GC : public GCStrategy { + public: + GC() {} + }; + + GCRegistry::Add + X("gc", "The bespoken garbage collector."); +} */ \ No newline at end of file diff --git a/src/Accurate_GC/gc_printer.cpp b/src/Accurate_GC/gc_printer.cpp new file mode 100644 index 0000000..361244f --- /dev/null +++ b/src/Accurate_GC/gc_printer.cpp @@ -0,0 +1,16 @@ +/* #include "llvm/CodeGen/GCMetadataPrinter.h" +#include "llvm/Support/Compiler.h" + +using namespace llvm; + +namespace { + class LLVM_LIBRARY_VISIBILITY GCPrinter : public GCMetadataPrinter { + public: + virtual void beginAssembly(AsmPrinter &AP); + + virtual void finishAssembly(AsmPrinter &AP); + }; + + GCMetadataPrinterRegistry::Add + X("gc", "The bespoken garbage collector."); +} */ \ No newline at end of file diff --git a/src/Accurate_GC/shadow_stack.cpp b/src/Accurate_GC/shadow_stack.cpp new file mode 100644 index 0000000..40cd4c3 --- /dev/null +++ b/src/Accurate_GC/shadow_stack.cpp @@ -0,0 +1,63 @@ +/* /// 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 +/// @llvm.gcroot is null. +struct FrameMap { + int NumRoots; //< Number of roots in stack frame. (int32_t) + int NumMeta; //< Number of metadata entries. May be < NumRoots. + const void *Meta[0]; //< Metadata for each root. +}; + +/// 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). + const FrameMap *Map; //< Pointer to constant FrameMap. + void *Roots[0]; //< Stack roots (in-place array). +}; + +/// 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; + +/// Calls Visitor(root, meta) for each GC root on the stack. +/// root and meta are exactly the values passed to +/// @llvm.gcroot. +/// +/// Visitor could be a function to recursively mark live objects. Or it +/// might copy them to another heap or generation. +/// +/// @param Visitor A function to invoke for every GC root on the stack. +void visitGCRoots(void (*Visitor)(void **Root, const void *Meta)) { + for (StackEntry *R = llvm_gc_root_chain; R; R = R->Next) { + unsigned i = 0; + + // For roots [0, NumMeta), the metadata pointer is in the FrameMap. + for (unsigned e = R->Map->NumMeta; i != e; ++i) + Visitor(&R->Roots[i], R->Map->Meta[i]); + + // For roots [NumMeta, NumRoots), the metadata pointer is null. + for (unsigned e = R->Map->NumRoots; i != e; ++i) + Visitor(&R->Roots[i], nullptr); + } +} + + // To access the stack map +void traverseStackMap() { + for (auto I = GCFunctionMetadata::roots_begin(), E = GCFunctionMetadata::end(); I != E; ++I) { + GCFunctionInfo *FI = *I; + unsigned FrameSize = FI->getFrameSize(); + size_t RootCount = FI->roots_size(); + + for (GCFunctionInfo::roots_iterator RI = FI->roots_begin(), + RE = FI->roots_end(); + RI != RE; ++RI) { + int RootNum = RI->Num; + int RootStackOffset = RI->StackOffset; + Constant *RootMetadata = RI->Metadata; + } + } +} */ \ No newline at end of file