[llvm-commits] [llvm] r43422 - in /llvm/trunk: include/llvm/Bitcode/Deserialize.h lib/Bitcode/Reader/Deserialize.cpp

Ted Kremenek kremenek at apple.com
Sun Oct 28 14:18:01 PDT 2007


Author: kremenek
Date: Sun Oct 28 16:17:59 2007
New Revision: 43422

URL: http://llvm.org/viewvc/llvm-project?rev=43422&view=rev
Log:
Updated backpatching logic during object deserialization to perform
eager backpatching instead of waithing until all objects have been
deserialized.  This allows us to reduce the memory footprint needed
for backpatching.

Modified:
    llvm/trunk/include/llvm/Bitcode/Deserialize.h
    llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp

Modified: llvm/trunk/include/llvm/Bitcode/Deserialize.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Deserialize.h?rev=43422&r1=43421&r2=43422&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Bitcode/Deserialize.h (original)
+++ llvm/trunk/include/llvm/Bitcode/Deserialize.h Sun Oct 28 16:17:59 2007
@@ -26,11 +26,11 @@
 namespace llvm {
   
 class Deserializer {  
-  BitstreamReader& Stream;
-  SmallVector<uint64_t,10> Record;
-  unsigned RecIdx;
-  BumpPtrAllocator Allocator;
-  
+
+  //===----------------------------------------------------------===//
+  // Internal type definitions.
+  //===----------------------------------------------------------===//
+
   struct PtrIdInfo {
     static inline unsigned getEmptyKey() { return ~((unsigned) 0x0); }
     static inline unsigned getTombstoneKey() { return getEmptyKey()-1; }
@@ -39,26 +39,58 @@
     static inline bool isPod() { return true; }
   };
   
-  struct BPatchNode {
-    BPatchNode* const Next;
+  struct BPNode {
+    BPNode* Next;
     uintptr_t& PtrRef;
-    BPatchNode(BPatchNode* n, void*& pref) 
-      : Next(n), PtrRef(reinterpret_cast<uintptr_t&>(pref)) {
+    BPNode(BPNode* n, uintptr_t& pref) 
+      : Next(n), PtrRef(pref) {
         PtrRef = 0;
       }
   };
   
-  struct BPatchEntry {
-    BPatchNode* Head;
-    void* Ptr;    
-    BPatchEntry() : Head(NULL), Ptr(NULL) {}
+  class BPatchEntry {
+    uintptr_t Ptr;
+  public:
+    
+    BPatchEntry() : Ptr(0x1) {}
+      
+    BPatchEntry(void* P) : Ptr(reinterpret_cast<uintptr_t>(P)) {}
+
+    bool hasFinalPtr() const { return Ptr & 0x1 ? true : false; }
+    void setFinalPtr(BPNode*& FreeList, void* P);
+
+    BPNode* getBPNode() const {
+      assert (!hasFinalPtr());
+      return reinterpret_cast<BPNode*>(Ptr & ~0x1);
+    }
+    
+    void setBPNode(BPNode* N) {
+      assert (!hasFinalPtr());
+      Ptr = reinterpret_cast<uintptr_t>(N) | 0x1;
+    }
+    
+    uintptr_t getRawPtr() const { return Ptr; }
+
     static inline bool isPod() { return true; }
-  };  
-  
+  };
+
   typedef llvm::DenseMap<unsigned,BPatchEntry,PtrIdInfo,BPatchEntry> MapTy;
 
+  //===----------------------------------------------------------===//
+  // Internal data members.
+  //===----------------------------------------------------------===//
+  
+  BitstreamReader& Stream;
+  SmallVector<uint64_t,10> Record;
+  unsigned RecIdx;
+  BumpPtrAllocator Allocator;
+  BPNode* FreeList;
   MapTy BPatchMap;  
   
+  //===----------------------------------------------------------===//
+  // Public Interface.
+  //===----------------------------------------------------------===//
+  
 public:
   Deserializer(BitstreamReader& stream);
   ~Deserializer();
@@ -99,13 +131,15 @@
     return x;
   }
   
-  void ReadPtr(void*& PtrRef);
-  void ReadPtr(uintptr_t& PtrRef) { ReadPtr(reinterpret_cast<void*&>(PtrRef)); }
+  template <typename T>
+  void ReadPtr(T*& PtrRef) { ReadUIntPtr(reinterpret_cast<uintptr_t&>(PtrRef));}
+
+  void ReadPtr(uintptr_t& PtrRef) { ReadUIntPtr(PtrRef); }
+  
+  void ReadUIntPtr(uintptr_t& PtrRef);
   
   void RegisterPtr(unsigned PtrId, void* Ptr);
 
-
-  void BackpatchPointers();
 private:
   void ReadRecord();  
   bool inRecord();

Modified: llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp?rev=43422&r1=43421&r2=43422&view=diff

==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp Sun Oct 28 16:17:59 2007
@@ -16,14 +16,14 @@
 using namespace llvm;
 
 Deserializer::Deserializer(BitstreamReader& stream)
-  : Stream(stream), RecIdx(0) {
+  : Stream(stream), RecIdx(0), FreeList(NULL) {
 }
 
 Deserializer::~Deserializer() {
   assert (RecIdx >= Record.size() && 
           "Still scanning bitcode record when deserialization completed.");
   
-  BackpatchPointers();
+  assert (FreeList == NULL && "Some pointers were not backpatched.");
 }
 
 
@@ -96,11 +96,11 @@
 
 void Deserializer::RegisterPtr(unsigned PtrId,void* Ptr) {
   BPatchEntry& E = BPatchMap[PtrId];
-  assert (E.Ptr == NULL && "Pointer already registered.");
-  E.Ptr = Ptr;
+  assert (E.hasFinalPtr() && "Pointer already registered.");
+  E.setFinalPtr(FreeList,Ptr);
 }
 
-void Deserializer::ReadPtr(void*& PtrRef) {
+void Deserializer::ReadUIntPtr(uintptr_t& PtrRef) {
   unsigned PtrId = ReadInt();
   
   if (PtrId == 0) {
@@ -110,32 +110,46 @@
   
   BPatchEntry& E = BPatchMap[PtrId];
   
-  if (E.Ptr == NULL) {
-    // Register backpatch.
-    void* P = Allocator.Allocate<BPatchNode>();    
-    E.Head = new (P) BPatchNode(E.Head,PtrRef);
+  if (E.hasFinalPtr())
+    PtrRef = E.getRawPtr();
+  else {
+    // Register backpatch.  Check the freelist for a BPNode.
+    BPNode* N;
+
+    if (FreeList) {
+      N = FreeList;
+      FreeList = FreeList->Next;
+    }
+    else // No available BPNode.  Allocate one.
+      N = (BPNode*) Allocator.Allocate<BPNode>();
+    
+    new (N) BPNode(E.getBPNode(),PtrRef);
+    E.setBPNode(N);
   }
-  else
-    PtrRef = E.Ptr;
 }
 
-void Deserializer::BackpatchPointers() {
-  for (MapTy::iterator I=BPatchMap.begin(),E=BPatchMap.end(); I!=E; ++I) {
-    
-    BPatchEntry& Entry = I->second;
-    assert (Entry.Ptr && "No pointer found for backpatch.");
-    
-    for (BPatchNode* N = Entry.Head; N != NULL; N = N->Next)
-      // Bitwise-OR in the pointer to support "smart" pointers that use
-      // unused bits to store extra data.
-      N->PtrRef |= reinterpret_cast<uintptr_t>(Entry.Ptr);
-    
-    Entry.Head = NULL;
+
+void Deserializer::BPatchEntry::setFinalPtr(BPNode*& FreeList, void* P) {
+  assert (!hasFinalPtr());
+  
+  // Perform backpatching.
+  
+  BPNode* Last = NULL;
+  
+  for (BPNode* N = getBPNode() ; N != NULL; N = N->Next) {
+    Last = N;
+    N->PtrRef |= reinterpret_cast<uintptr_t>(P);
   }
   
-  Allocator.Reset();
+  if (Last) {
+    Last->Next = FreeList;
+    FreeList = getBPNode();    
+  }
+  
+  Ptr = reinterpret_cast<uintptr_t>(P);
 }
 
+
 #define INT_READ(TYPE)\
 void SerializeTrait<TYPE>::Read(Deserializer& D, TYPE& X) {\
   X = (TYPE) D.ReadInt(); }\





More information about the llvm-commits mailing list