diff options
-rw-r--r-- | include/llvm/Bitcode/Deserialize.h | 80 | ||||
-rw-r--r-- | lib/Bitcode/Reader/Deserialize.cpp | 40 |
2 files changed, 67 insertions, 53 deletions
diff --git a/include/llvm/Bitcode/Deserialize.h b/include/llvm/Bitcode/Deserialize.h index f883a5a..d7ad7c1 100644 --- a/include/llvm/Bitcode/Deserialize.h +++ b/include/llvm/Bitcode/Deserialize.h @@ -30,54 +30,49 @@ class Deserializer { //===----------------------------------------------------------===// // 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 @@ private: 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 diff --git a/lib/Bitcode/Reader/Deserialize.cpp b/lib/Bitcode/Reader/Deserialize.cpp index 9bc0f15..e5a4d18 100644 --- a/lib/Bitcode/Reader/Deserialize.cpp +++ b/lib/Bitcode/Reader/Deserialize.cpp @@ -25,7 +25,7 @@ Deserializer::~Deserializer() { #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::ReadCStr(std::vector<char>& buff, bool isNullTerm) { } 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 @@ void Deserializer::ReadUIntPtr(uintptr_t& PtrRef) { 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 @@ void Deserializer::ReadUIntPtr(uintptr_t& PtrRef) { 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 @@ uintptr_t Deserializer::ReadInternalRefPtr() { 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); } |