[vmkit-commits] [vmkit] r135877 - in /vmkit/trunk: Makefile Makefile.rules lib/Mvm/StaticGCPass/StaticGCPass.cpp lib/Mvm/StaticGCPrinter/ lib/Mvm/StaticGCPrinter/Makefile lib/Mvm/StaticGCPrinter/VmkitGCPrinter.cpp tools/precompiler/trainer/Makefile

Nicolas Geoffray nicolas.geoffray at lip6.fr
Sun Jul 24 09:24:19 PDT 2011


Author: geoffray
Date: Sun Jul 24 11:24:19 2011
New Revision: 135877

URL: http://llvm.org/viewvc/llvm-project?rev=135877&view=rev
Log:
Add a vmkit static GC, similar to ocaml, but that makes sure the frame names are mangled.


Added:
    vmkit/trunk/lib/Mvm/StaticGCPrinter/
    vmkit/trunk/lib/Mvm/StaticGCPrinter/Makefile
    vmkit/trunk/lib/Mvm/StaticGCPrinter/VmkitGCPrinter.cpp
Modified:
    vmkit/trunk/Makefile
    vmkit/trunk/Makefile.rules
    vmkit/trunk/lib/Mvm/StaticGCPass/StaticGCPass.cpp
    vmkit/trunk/tools/precompiler/trainer/Makefile

Modified: vmkit/trunk/Makefile
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/Makefile?rev=135877&r1=135876&r2=135877&view=diff
==============================================================================
--- vmkit/trunk/Makefile (original)
+++ vmkit/trunk/Makefile Sun Jul 24 11:24:19 2011
@@ -13,7 +13,7 @@
 
 # Top-Level vmkit Build Stages:
 #
-DIRS := lib/Mvm/StaticGCPass lib tools/vmjc mmtk tools/precompiler tools
+DIRS := lib/Mvm/StaticGCPass lib/Mvm/StaticGCPrinter lib tools/vmjc mmtk tools/precompiler tools
 
 EXTRA_DIST=include
 

Modified: vmkit/trunk/Makefile.rules
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/Makefile.rules?rev=135877&r1=135876&r2=135877&view=diff
==============================================================================
--- vmkit/trunk/Makefile.rules (original)
+++ vmkit/trunk/Makefile.rules Sun Jul 24 11:24:19 2011
@@ -78,7 +78,7 @@
 	$(Verb) $(LLVMLD) -r -o $(LibDir)/FinalMMTk.bc $(LibDir)/MMTKAlloc.bc $(JARNAME)-optimized.bc $(LibDir)/MMTKRuntime.bc
 	$(Verb) $(LOPT) $(LibDir)/FinalMMTk.bc -load=$(LibDir)/StaticGCPass$(SHLIBEXT) -std-compile-opts -StaticGCPass -o $(LibDir)/FinalMMTk.bc
 	$(Verb) $(MKDIR) $(ObjDir)
-	$(Verb) $(LLC) -disable-fp-elim $(LibDir)/FinalMMTk.bc -o $(ObjDir)/FinalMMTk.s
+	$(Verb) $(LLC) -disable-fp-elim -load=$(LibDir)/StaticGCPrinter$(SHLIBEXT) $(LibDir)/FinalMMTk.bc -o $(ObjDir)/FinalMMTk.s
 	$(Verb) $(Compile.C) $(ObjDir)/FinalMMTk.s -o $(ObjDir)/FinalMMTk.o
 	$(Verb) $(Archive) $(LibDir)/libFinalMMTk.a $(ObjDir)/FinalMMTk.o
 	$(Verb) $(Ranlib) $(LibDir)/libFinalMMTk.a
@@ -110,7 +110,7 @@
 
 $(ObjectsSWithGC): $(ObjDir)/%_gc.s: $(ObjDir)/%_gc.bc $(LLC)
 	$(Echo) "Compiling $*.bc to $*.s for $(BuildMode) build"
-	$(Verb) $(LLC) -disable-fp-elim $< -o $@
+	$(Verb) $(LLC) -disable-fp-elim -load=$(LibDir)/StaticGCPrinter$(SHLIBEXT) $< -o $@
 
 $(ObjectsWithGC): $(ObjDir)/%_gc.o: $(ObjDir)/%_gc.s $(ObjDir)/.dir
 	$(Echo) "Compiling $*.s for $(BuildMode) build" $(PIC_FLAG)

Modified: vmkit/trunk/lib/Mvm/StaticGCPass/StaticGCPass.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/StaticGCPass/StaticGCPass.cpp?rev=135877&r1=135876&r2=135877&view=diff
==============================================================================
--- vmkit/trunk/lib/Mvm/StaticGCPass/StaticGCPass.cpp (original)
+++ vmkit/trunk/lib/Mvm/StaticGCPass/StaticGCPass.cpp Sun Jul 24 11:24:19 2011
@@ -39,10 +39,6 @@
   RegisterPass<StaticGCPass> X("StaticGCPass",
                       "Add GC information in files compiled with llvm-gcc");
 
-static bool HasVmkitGC(Function* F) {
-  return !strcmp(F->getGC(), "vmkit");
-}
-
 bool StaticGCPass::runOnModule(Module& M) {
 
   Function* F = M.getFunction("__llvm_gcroot");
@@ -59,12 +55,8 @@
     if (Instruction* II = dyn_cast<Instruction>(*I)) {
       Function* F = II->getParent()->getParent();
       if (!F->hasGC()) {
-        F->setGC("ocaml");
-      } else if (HasVmkitGC(F)) {
-        F->clearGC();
-        F->setGC("ocaml");
+        F->setGC("vmkit");
       }
-      assert(F->hasGC());
     }
   }
 
@@ -75,7 +67,6 @@
                       "Functions using gc_root should not have static linkage.\n",
                       I->getName().data());
     }
-    if (I->hasGC() && HasVmkitGC(I)) I->setGC("ocaml");
   }
 
   if (error) abort();

Added: vmkit/trunk/lib/Mvm/StaticGCPrinter/Makefile
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/StaticGCPrinter/Makefile?rev=135877&view=auto
==============================================================================
--- vmkit/trunk/lib/Mvm/StaticGCPrinter/Makefile (added)
+++ vmkit/trunk/lib/Mvm/StaticGCPrinter/Makefile Sun Jul 24 11:24:19 2011
@@ -0,0 +1,15 @@
+##===- lib/Mvm/StaticGCPrinter/Makefile --------------------*- Makefile -*-===##
+#
+#                            The VMKit project
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../..
+LIBRARYNAME = StaticGCPrinter
+LOADABLE_MODULE = 1
+
+include $(LEVEL)/Makefile.common
+

Added: vmkit/trunk/lib/Mvm/StaticGCPrinter/VmkitGCPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/StaticGCPrinter/VmkitGCPrinter.cpp?rev=135877&view=auto
==============================================================================
--- vmkit/trunk/lib/Mvm/StaticGCPrinter/VmkitGCPrinter.cpp (added)
+++ vmkit/trunk/lib/Mvm/StaticGCPrinter/VmkitGCPrinter.cpp Sun Jul 24 11:24:19 2011
@@ -0,0 +1,197 @@
+//===-- VmkitGCPrinter.cpp - Vmkit frametable emitter ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements printing the assembly code for a Vmkit frametable.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/GCs.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/GCMetadataPrinter.h"
+#include "llvm/CodeGen/GCStrategy.h"
+#include "llvm/Module.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/Target/Mangler.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FormattedStream.h"
+#include <cctype>
+using namespace llvm;
+
+namespace {
+  class VmkitGC : public GCStrategy {
+  public:
+    VmkitGC();
+  };
+
+  class VmkitGCMetadataPrinter : public GCMetadataPrinter {
+  public:
+    void beginAssembly(AsmPrinter &AP);
+    void finishAssembly(AsmPrinter &AP);
+  };
+
+}
+
+
+static GCRegistry::Add<VmkitGC>
+X("vmkit", "VMKit GC for AOT-generated functions");
+
+
+static GCMetadataPrinterRegistry::Add<VmkitGCMetadataPrinter>
+Y("vmkit", "VMKit GC for AOT-generated functions");
+
+
+VmkitGC::VmkitGC() {
+  NeededSafePoints = 1 << GC::PostCall;
+  UsesMetadata = true;
+}
+
+
+static bool isAcceptableChar(char C) {
+  if ((C < 'a' || C > 'z') &&
+      (C < 'A' || C > 'Z') &&
+      (C < '0' || C > '9') &&
+      C != '_' && C != '$' && C != '@') {
+    return false;
+  }
+  return true;
+}
+
+static char HexDigit(int V) {
+  return V < 10 ? V+'0' : V+'A'-10;
+}
+
+static void MangleLetter(SmallVectorImpl<char> &OutName, unsigned char C) {
+  OutName.push_back('_');
+  OutName.push_back(HexDigit(C >> 4));
+  OutName.push_back(HexDigit(C & 15));
+  OutName.push_back('_');
+}
+
+
+static void EmitVmkitGlobal(const Module &M, AsmPrinter &AP, const char *Id) {
+  const std::string &MId = M.getModuleIdentifier();
+
+  std::string SymName;
+  SymName += "vmkit";
+  size_t Letter = SymName.size();
+  SymName.append(MId.begin(), std::find(MId.begin(), MId.end(), '.'));
+  SymName += "__";
+  SymName += Id;
+
+  // Capitalize the first letter of the module name.
+  SymName[Letter] = toupper(SymName[Letter]);
+
+  SmallString<128> TmpStr;
+  AP.Mang->getNameWithPrefix(TmpStr, SymName);
+
+  SmallString<128> FinalStr;
+  for (unsigned i = 0, e = TmpStr.size(); i != e; ++i) {
+    if (!isAcceptableChar(TmpStr[i])) {
+      MangleLetter(FinalStr, TmpStr[i]);
+    } else {
+      FinalStr.push_back(TmpStr[i]);
+    }
+  }
+
+  MCSymbol *Sym = AP.OutContext.GetOrCreateSymbol(FinalStr);
+
+  AP.OutStreamer.EmitSymbolAttribute(Sym, MCSA_Global);
+  AP.OutStreamer.EmitLabel(Sym);
+}
+
+void VmkitGCMetadataPrinter::beginAssembly(AsmPrinter &AP) {
+}
+
+/// emitAssembly - Print the frametable. The ocaml frametable format is thus:
+///
+///   extern "C" struct align(sizeof(intptr_t)) {
+///     uint16_t NumDescriptors;
+///     struct align(sizeof(intptr_t)) {
+///       void *ReturnAddress;
+///       uint16_t FrameSize;
+///       uint16_t NumLiveOffsets;
+///       uint16_t LiveOffsets[NumLiveOffsets];
+///     } Descriptors[NumDescriptors];
+///   } vmkit${module}__frametable;
+///
+/// Note that this precludes programs from stack frames larger than 64K
+/// (FrameSize and LiveOffsets would overflow). FrameTablePrinter will abort if
+/// either condition is detected in a function which uses the GC.
+///
+void VmkitGCMetadataPrinter::finishAssembly(AsmPrinter &AP) {
+  unsigned IntPtrSize = AP.TM.getTargetData()->getPointerSize();
+  AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getDataSection());
+  EmitVmkitGlobal(getModule(), AP, "frametable");
+
+  int NumDescriptors = 0;
+  for (iterator I = begin(), IE = end(); I != IE; ++I) {
+    GCFunctionInfo &FI = **I;
+    for (GCFunctionInfo::iterator J = FI.begin(), JE = FI.end(); J != JE; ++J) {
+      NumDescriptors++;
+    }
+  }
+
+  if (NumDescriptors >= 1<<16) {
+    // Very rude!
+    report_fatal_error(" Too much descriptor for vmkit GC");
+  }
+  AP.EmitInt16(NumDescriptors);
+  AP.EmitAlignment(IntPtrSize == 4 ? 2 : 3);
+
+  for (iterator I = begin(), IE = end(); I != IE; ++I) {
+    GCFunctionInfo &FI = **I;
+
+    uint64_t FrameSize = FI.getFrameSize();
+    if (FrameSize >= 1<<16) {
+      // Very rude!
+      report_fatal_error("Function '" + FI.getFunction().getName() +
+                         "' is too large for the vmkit GC! "
+                         "Frame size " + Twine(FrameSize) + ">= 65536.\n"
+                         "(" + Twine(uintptr_t(&FI)) + ")");
+    }
+
+    AP.OutStreamer.AddComment("live roots for " +
+                              Twine(FI.getFunction().getName()));
+    AP.OutStreamer.AddBlankLine();
+
+    for (GCFunctionInfo::iterator J = FI.begin(), JE = FI.end(); J != JE; ++J) {
+      size_t LiveCount = FI.live_size(J);
+      if (LiveCount >= 1<<16) {
+        // Very rude!
+        report_fatal_error("Function '" + FI.getFunction().getName() +
+                           "' is too large for the vmkit GC! "
+                           "Live root count "+Twine(LiveCount)+" >= 65536.");
+      }
+
+      AP.OutStreamer.EmitSymbolValue(J->Label, IntPtrSize, 0);
+      AP.EmitInt16(FrameSize);
+      AP.EmitInt16(LiveCount);
+
+      for (GCFunctionInfo::live_iterator K = FI.live_begin(J),
+                                         KE = FI.live_end(J); K != KE; ++K) {
+        if (K->StackOffset >= 1<<16) {
+          // Very rude!
+          report_fatal_error(
+                 "GC root stack offset is outside of fixed stack frame and out "
+                 "of range for vmkit GC!");
+        }
+        AP.EmitInt16(K->StackOffset);
+      }
+
+      AP.EmitAlignment(IntPtrSize == 4 ? 2 : 3);
+    }
+  }
+}

Modified: vmkit/trunk/tools/precompiler/trainer/Makefile
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/tools/precompiler/trainer/Makefile?rev=135877&r1=135876&r2=135877&view=diff
==============================================================================
--- vmkit/trunk/tools/precompiler/trainer/Makefile (original)
+++ vmkit/trunk/tools/precompiler/trainer/Makefile Sun Jul 24 11:24:19 2011
@@ -18,13 +18,13 @@
 
 PRECOMPILER := $(ToolDir)/precompiler$(EXEEXT)
 
-generated.bc: $(PRECOMPILER) HelloWorld.java $(LibDir)/StaticJ3GC$(SHLIBEXT) $(LibDir)/StaticGCPass$(SHLIBEXT)
+generated.bc: $(PRECOMPILER) HelloWorld.java $(LibDir)/StaticJ3GC$(SHLIBEXT) $(LibDir)/StaticGCPass$(SHLIBEXT) $(LibDir)/StaticGCPrinter$(SHLIBEXT)
 	$(Echo) "Building precompiled bootstrap code"
 	$(Verb) javac HelloWorld.java
 	$(Verb) $(PRECOMPILER) -cp $$PWD HelloWorld
 	$(Verb) $(MKDIR) $(ObjDir)
 	$(Verb) $(LOPT) generated.bc -load=$(LibDir)/StaticGCPass$(SHLIBEXT) -StaticGCPass -o $(LibDir)/Precompiled.bc
-	$(Verb) $(LLC) -O0 -fast-isel=false -load=$(LibDir)/StaticJ3GC$(SHLIBEXT) -disable-fp-elim $(LibDir)/Precompiled.bc -o $(ObjDir)/Precompiled.s
+	$(Verb) $(LLC) -O0 -fast-isel=false -load=$(LibDir)/StaticJ3GC$(SHLIBEXT) -load=$(LibDir)/StaticGCPrinter$(SHLIBEXT) -disable-fp-elim $(LibDir)/Precompiled.bc -o $(ObjDir)/Precompiled.s
 	$(Verb) $(Compile.C) $(ObjDir)/Precompiled.s -o $(ObjDir)/Precompiled.o
 	$(Verb) $(Archive) $(LibDir)/libPrecompiled.a $(ObjDir)/Precompiled.o
 	$(Verb) $(Ranlib) $(LibDir)/libPrecompiled.a





More information about the vmkit-commits mailing list