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

Ted Kremenek kremenek at apple.com
Wed Oct 31 17:57:37 PDT 2007


Author: kremenek
Date: Wed Oct 31 19:57:37 2007
New Revision: 43595

URL: http://llvm.org/viewvc/llvm-project?rev=43595&view=rev
Log:
Rewrote backpatcher.  Backpatcher now stores the "has final pointer"
flag in the **key** of the backpatch map, as opposed to the mapped
value which contains either the final pointer, or a pointer to a chain
of pointers that need to be backpatched.  The bit flag was moved to
the key because we were erroneously assuming that the backpatched
pointers would be at an alignment of >= 2 bytes, which obviously
doesn't work for character strings.  Now we just steal the bit from the key.

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=43595&r1=43594&r2=43595&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Bitcode/Deserialize.h (original)
+++ llvm/trunk/include/llvm/Bitcode/Deserialize.h Wed Oct 31 19:57:37 2007
@@ -30,54 +30,49 @@
   //===----------------------------------------------------------===//
   // Internal type definitions.
   //===----------------------------------------------------------===//
-
-  struct PtrIdInfo {
-    static inline unsigned getEmptyKey() { return ~((unsigned) 0x0); }
-    static inline unsigned getTombstoneKey() { return getEmptyKey()-1; }
-    static inline unsigned getHashValue(unsigned X) { return X; }
-    static inline bool isEqual(unsigned X, unsigned Y) { return X == Y; }
-    static inline bool isPod() { return true; }
-  };
   
   struct BPNode {
     BPNode* Next;
     uintptr_t& PtrRef;
+    
     BPNode(BPNode* n, uintptr_t& pref) 
       : Next(n), PtrRef(pref) {
         PtrRef = 0;
       }
   };
   
-  class BPatchEntry {
-    uintptr_t Ptr;
+  struct BPEntry { 
+    union { BPNode* Head; void* Ptr; };
+    
+    BPEntry() : Head(NULL) {}
+    
+    static inline bool isPod() { return true; }
+    
+    void SetPtr(BPNode*& FreeList, void* P);    
+  };  
+  
+  class BPKey {
+    unsigned Raw;
+    
   public:
+    BPKey(unsigned PtrId) : Raw(PtrId << 1) { assert (PtrId > 0); }
     
-    BPatchEntry() : Ptr(0x1) {}
-      
-    BPatchEntry(void* P) : Ptr(reinterpret_cast<uintptr_t>(P)) {}
-
-    bool hasFinalPtr() const { return Ptr & 0x1 ? false : true; }
-    void setFinalPtr(BPNode*& FreeList, const void* P);
-
-    BPNode* getBPNode() const {
-      assert (!hasFinalPtr());
-      return reinterpret_cast<BPNode*>(Ptr & ~0x1);
-    }
+    void MarkFinal() { Raw |= 0x1; }
+    bool hasFinalPtr() const { return Raw & 0x1 ? true : false; }
+    unsigned getID() const { return Raw >> 1; }
     
-    void setBPNode(BPNode* N) {
-      assert (!hasFinalPtr());
-      Ptr = reinterpret_cast<uintptr_t>(N) | 0x1;
+    static inline BPKey getEmptyKey() { return 0; }
+    static inline BPKey getTombstoneKey() { return 1; }
+    static inline unsigned getHashValue(const BPKey& K) { return K.Raw & ~0x1; }
+
+    static bool isEqual(const BPKey& K1, const BPKey& K2) {
+      return (K1.Raw ^ K2.Raw) & ~0x1 ? false : true;
     }
     
-    uintptr_t getFinalPtr() const {
-      assert (!(Ptr & 0x1) && "Backpatch pointer not yet deserialized.");
-      return Ptr;
-    }    
-
-    static inline bool isPod() { return true; }
+    static bool isPod() { return true; }
   };
-
-  typedef llvm::DenseMap<unsigned,BPatchEntry,PtrIdInfo,BPatchEntry> MapTy;
+  
+  typedef llvm::DenseMap<BPKey,BPEntry,BPKey,BPEntry> MapTy;
 
   //===----------------------------------------------------------===//
   // Internal data members.
@@ -162,6 +157,27 @@
   void ReadRecord();  
   bool inRecord();
   uintptr_t ReadInternalRefPtr();
+  
+  static inline bool HasFinalPtr(MapTy::value_type& V) {
+    return V.first.hasFinalPtr();
+  }
+  
+  static inline uintptr_t GetFinalPtr(MapTy::value_type& V) {
+    return reinterpret_cast<uintptr_t>(V.second.Ptr);
+  }
+  
+  static inline BPNode* GetBPNode(MapTy::value_type& V) {
+    return V.second.Head;
+  }
+    
+  static inline void SetBPNode(MapTy::value_type& V, BPNode* N) {
+    V.second.Head = N;
+  }
+  
+  void SetPtr(MapTy::value_type& V, const void* P) {
+    V.first.MarkFinal();
+    V.second.SetPtr(FreeList,const_cast<void*>(P));
+  }
 };
     
 } // end namespace llvm

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

==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp Wed Oct 31 19:57:37 2007
@@ -25,7 +25,7 @@
  
 #ifdef NDEBUG
   for (MapTy::iterator I=BPatchMap.begin(), E=BPatchMap.end(); I!=E; ++I)
-    assert (I->second.hasFinalPtr() &&
+    assert (I->first.hasFinalPtr() &&
             "Some pointers were not backpatched.");
 #endif
 }
@@ -99,9 +99,11 @@
 }
 
 void Deserializer::RegisterPtr(unsigned PtrId, const void* Ptr) {
-  BPatchEntry& E = BPatchMap[PtrId];
-  assert (!E.hasFinalPtr() && "Pointer already registered.");
-  E.setFinalPtr(FreeList,Ptr);
+  MapTy::value_type& E = BPatchMap.FindAndConstruct(BPKey(PtrId));
+  
+  assert (!HasFinalPtr(E) && "Pointer already registered.");
+
+  SetPtr(E,Ptr);
 }
 
 void Deserializer::ReadUIntPtr(uintptr_t& PtrRef) {
@@ -111,11 +113,11 @@
     PtrRef = 0;
     return;
   }  
+
+  MapTy::value_type& E = BPatchMap.FindAndConstruct(BPKey(PtrId));
   
-  BPatchEntry& E = BPatchMap[PtrId];
-  
-  if (E.hasFinalPtr())
-    PtrRef = E.getFinalPtr();
+  if (HasFinalPtr(E))
+    PtrRef = GetFinalPtr(E);
   else {
     // Register backpatch.  Check the freelist for a BPNode.
     BPNode* N;
@@ -127,8 +129,8 @@
     else // No available BPNode.  Allocate one.
       N = (BPNode*) Allocator.Allocate<BPNode>();
     
-    new (N) BPNode(E.getBPNode(),PtrRef);
-    E.setBPNode(N);
+    new (N) BPNode(GetBPNode(E),PtrRef);
+    SetBPNode(E,N);
   }
 }
 
@@ -137,32 +139,28 @@
   
   assert (PtrId != 0 && "References cannot refer the NULL address.");
 
-  BPatchEntry& E = BPatchMap[PtrId];
+  MapTy::value_type& E = BPatchMap.FindAndConstruct(BPKey(PtrId));
   
-  assert (E.hasFinalPtr() &&
+  assert (!HasFinalPtr(E) &&
           "Cannot backpatch references.  Object must be already deserialized.");
   
-  return E.getFinalPtr();
+  return GetFinalPtr(E);
 }
 
-void Deserializer::BPatchEntry::setFinalPtr(BPNode*& FreeList, const void* P) {
-  assert (!hasFinalPtr());
-  
-  // Perform backpatching.
-  
+void Deserializer::BPEntry::SetPtr(BPNode*& FreeList, void* P) {
   BPNode* Last = NULL;
   
-  for (BPNode* N = getBPNode() ; N != NULL; N = N->Next) {
+  for (BPNode* N = Head; N != NULL; N=N->Next) {
     Last = N;
     N->PtrRef |= reinterpret_cast<uintptr_t>(P);
   }
   
   if (Last) {
     Last->Next = FreeList;
-    FreeList = getBPNode();    
+    FreeList = Head;
   }
   
-  Ptr = reinterpret_cast<uintptr_t>(P);
+  Ptr = const_cast<void*>(P);
 }
 
 





More information about the llvm-commits mailing list